• 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 /** Dummy 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 /** Dummy 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 /** Dummy 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 /** Dummy 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 dummy 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 /** Dummy 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 			break;
2695 		}
2696 
2697 		if (validate_status != validate_expected_status)
2698 		{
2699 			tcu::MessageBuilder message = m_testCtx.getLog().message();
2700 
2701 			if (GL_FALSE == validate_expected_status)
2702 			{
2703 				message << "A pipeline object was validated successfully, even though one";
2704 			}
2705 			else
2706 			{
2707 				message << "A pipeline object was validated negatively, even though none";
2708 			}
2709 
2710 			message << " of the failure reasons given by spec was applicable.\n"
2711 					<< "\n"
2712 					   "Fragment shader body:\n>>\n"
2713 					<< ((shader_programs[0].body_ptr->length() > 0) ? *shader_programs[0].body_ptr : "[not used]")
2714 					<< "\n<<\nGeometry shader body:\n>>\n"
2715 					<< ((shader_programs[1].body_ptr->length() > 0) ? *shader_programs[1].body_ptr : "[not used]")
2716 					<< "\n<<\nTessellation control shader body:\n>>\n"
2717 					<< ((shader_programs[2].body_ptr->length() > 0) ? *shader_programs[2].body_ptr : "[not used]")
2718 					<< "\n<<\nTessellation evaluation shader body:\n>>\n"
2719 					<< ((shader_programs[3].body_ptr->length() > 0) ? *shader_programs[3].body_ptr : "[not used]")
2720 					<< "\n<<\nVertex shader body:\n>>\n"
2721 					<< ((shader_programs[4].body_ptr->length() > 0) ? *shader_programs[4].body_ptr : "[not used]")
2722 					<< tcu::TestLog::EndMessage;
2723 		} /* if (validate_status != validate_expected_status) */
2724 		else
2725 		{
2726 			result = true;
2727 		}
2728 	}
2729 	else
2730 	{
2731 		result = true;
2732 	}
2733 
2734 end:
2735 	return result;
2736 }
2737 
2738 /** Runs the specified test iteration in the following mode:
2739  *
2740  *  >>
2741  *  A single separate shader program, to which all shader stages used by the test are attached, is linked.
2742  *  It is expected the linking process should fail.
2743  *  <<
2744  *
2745  *  @param iteration Test iteration to execute.
2746  *
2747  *  @return true if the test passed, false otherwise.
2748  */
runSeparateShaderTestMode(_test_iteration iteration)2749 bool PerVertexValidationTest::runSeparateShaderTestMode(_test_iteration iteration)
2750 {
2751 	glw::GLint			  compile_status;
2752 	glu::ContextType	  context_type = m_context.getRenderContext().getType();
2753 	const glw::Functions& gl		   = m_context.getRenderContext().getFunctions();
2754 	glw::GLint			  link_status;
2755 	glu::ContextType	  min_context_type;
2756 	bool				  result = false;
2757 	_shader_stage		  used_shader_stages;
2758 
2759 	std::string fs_body;
2760 	std::string gs_body;
2761 	std::string tc_body;
2762 	std::string te_body;
2763 	std::string vs_body;
2764 
2765 	struct _shader
2766 	{
2767 		std::string*  body_ptr;
2768 		glw::GLuint*  so_id_ptr;
2769 		_shader_stage shader_stage;
2770 		glw::GLenum   shader_stage_bit_gl;
2771 		glw::GLenum   shader_stage_gl;
2772 	} shaders[] = { { &fs_body, &m_fs_id, SHADER_STAGE_FRAGMENT, GL_FRAGMENT_SHADER_BIT, GL_FRAGMENT_SHADER },
2773 					{ &gs_body, &m_gs_id, SHADER_STAGE_GEOMETRY, GL_GEOMETRY_SHADER_BIT, GL_GEOMETRY_SHADER },
2774 					{ &tc_body, &m_tc_id, SHADER_STAGE_TESSELLATION_CONTROL, GL_TESS_CONTROL_SHADER_BIT,
2775 					  GL_TESS_CONTROL_SHADER },
2776 					{ &te_body, &m_te_id, SHADER_STAGE_TESSELLATION_EVALUATION, GL_TESS_EVALUATION_SHADER_BIT,
2777 					  GL_TESS_EVALUATION_SHADER },
2778 					{ &vs_body, &m_vs_id, SHADER_STAGE_VERTEX, GL_VERTEX_SHADER_BIT, GL_VERTEX_SHADER } };
2779 	const unsigned int n_shaders = static_cast<unsigned int>(sizeof(shaders) / sizeof(shaders[0]));
2780 
2781 	/* Retrieve iteration properties */
2782 	getTestIterationProperties(context_type, iteration, &min_context_type, &used_shader_stages, &gs_body, &tc_body,
2783 							   &te_body, &vs_body);
2784 
2785 	if (!glu::contextSupports(context_type, min_context_type.getAPI()))
2786 	{
2787 		result = true;
2788 
2789 		goto end;
2790 	}
2791 
2792 	/* Bake a single shader with separate programs defined for all shader stages defined by the iteration
2793 	 * and see what happens.
2794 	 *
2795 	 * For simplicity, we re-use m_vs_po_id to store the program object ID.
2796 	 */
2797 	m_vs_po_id = gl.createProgram();
2798 
2799 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
2800 
2801 	for (unsigned int n_shader = 0; n_shader < n_shaders; ++n_shader)
2802 	{
2803 		const char*			 body_raw_ptr		  = DE_NULL;
2804 		const std::string&   current_body		  = *shaders[n_shader].body_ptr;
2805 		const _shader_stage& current_shader_stage = shaders[n_shader].shader_stage;
2806 		glw::GLuint&		 current_so_id		  = *shaders[n_shader].so_id_ptr;
2807 		const glw::GLenum&   current_so_type_gl   = shaders[n_shader].shader_stage_gl;
2808 
2809 		if ((used_shader_stages & current_shader_stage) != 0)
2810 		{
2811 			body_raw_ptr  = current_body.c_str();
2812 			current_so_id = gl.createShader(current_so_type_gl);
2813 
2814 			GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed.");
2815 
2816 			gl.shaderSource(current_so_id, 1,		 /* count */
2817 							&body_raw_ptr, DE_NULL); /* length */
2818 			GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
2819 
2820 			/* Ensure the shader compiled successfully. */
2821 			gl.compileShader(current_so_id);
2822 
2823 			GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed.");
2824 
2825 			gl.getShaderiv(current_so_id, GL_COMPILE_STATUS, &compile_status);
2826 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");
2827 
2828 			if (compile_status != GL_TRUE)
2829 			{
2830 				m_testCtx.getLog() << tcu::TestLog::Message << getShaderStageName(current_shader_stage)
2831 								   << " unexpectedly failed to compile.\n"
2832 									  "\nBody:\n>>\n"
2833 								   << current_body << "\n<<\n"
2834 								   << tcu::TestLog::EndMessage;
2835 
2836 				goto end;
2837 			}
2838 
2839 			/* Attach the shader object to the test program object */
2840 			gl.attachShader(m_vs_po_id, current_so_id);
2841 			GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call failed.");
2842 		} /* if ((used_shader_stages & current_shader_stage) != 0) */
2843 	}	 /* for (all shader objects) */
2844 
2845 	/* Mark the program as separable */
2846 	gl.programParameteri(m_vs_po_id, GL_PROGRAM_SEPARABLE, GL_TRUE);
2847 	GLU_EXPECT_NO_ERROR(gl.getError(), "glProgramParameteri() call failed.");
2848 
2849 	/* Try to link the program and check the result. */
2850 	gl.linkProgram(m_vs_po_id);
2851 	GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed.");
2852 
2853 	gl.getProgramiv(m_vs_po_id, GL_LINK_STATUS, &link_status);
2854 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed.");
2855 
2856 	if (link_status == GL_TRUE)
2857 	{
2858 		m_testCtx.getLog() << tcu::TestLog::Message
2859 						   << "Separable program, consisting of the following separate shaders, was linked "
2860 							  "successfully, despite incompatible or missing gl_PerVertex block re-declarations.\n"
2861 							  "\n"
2862 							  "Fragment shader program:\n>>\n"
2863 						   << ((fs_body.length() > 0) ? fs_body : "[not used]")
2864 						   << "\n<<\nGeometry shader program:\n>>\n"
2865 						   << ((gs_body.length() > 0) ? gs_body : "[not used]")
2866 						   << "\n<<\nTessellation control shader program:\n>>\n"
2867 						   << ((tc_body.length() > 0) ? tc_body : "[not used]")
2868 						   << "\n<<\nTessellation evaluation shader program:\n>>\n"
2869 						   << ((te_body.length() > 0) ? te_body : "[not used]") << "\n<<\nVertex shader program:\n>>\n"
2870 						   << ((vs_body.length() > 0) ? vs_body : "[not used]") << tcu::TestLog::EndMessage;
2871 
2872 		goto end;
2873 	} /* if (link_status == GL_TRUE) */
2874 
2875 	/* All done */
2876 	result = true;
2877 end:
2878 	if (!result)
2879 	{
2880 		m_testCtx.getLog() << tcu::TestLog::Message << "Failed test description: " << getTestIterationName(iteration)
2881 						   << tcu::TestLog::EndMessage;
2882 	}
2883 	return result;
2884 }
2885 
2886 /** Constructor.
2887  *
2888  *  @param context     Rendering context
2889  *  @param name        Test name
2890  *  @param description Test description
2891  */
ReservedNamesTest(deqp::Context & context)2892 ReservedNamesTest::ReservedNamesTest(deqp::Context& context)
2893 	: TestCase(context, "CommonBug_ReservedNames",
2894 			   "Verifies that reserved variable names are rejected by the GL SL compiler"
2895 			   " at the compilation time.")
2896 	, m_max_fs_ssbos(0)
2897 	, m_max_gs_acs(0)
2898 	, m_max_gs_ssbos(0)
2899 	, m_max_tc_acs(0)
2900 	, m_max_tc_ssbos(0)
2901 	, m_max_te_acs(0)
2902 	, m_max_te_ssbos(0)
2903 	, m_max_vs_acs(0)
2904 	, m_max_vs_ssbos(0)
2905 {
2906 	memset(m_so_ids, 0, sizeof(m_so_ids));
2907 }
2908 
2909 /** Deinitializes all GL objects created for the purpose of running the test,
2910  *  as well as any client-side buffers allocated at initialization time
2911  */
deinit()2912 void ReservedNamesTest::deinit()
2913 {
2914 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2915 
2916 	for (unsigned int n_so_id = 0; n_so_id < sizeof(m_so_ids) / sizeof(m_so_ids[0]); ++n_so_id)
2917 	{
2918 		const glw::GLuint current_so_id = m_so_ids[n_so_id];
2919 
2920 		if (current_so_id != 0)
2921 		{
2922 			gl.deleteShader(current_so_id);
2923 		}
2924 	} /* for (all usedshader object IDs) */
2925 }
2926 
2927 /** Returns a literal corresponding to the specified @param language_feature value.
2928  *
2929  *  @param language_feature Enum to return the string object for.
2930  *
2931  *  @return As specified.
2932  */
getLanguageFeatureName(_language_feature language_feature) const2933 std::string ReservedNamesTest::getLanguageFeatureName(_language_feature language_feature) const
2934 {
2935 	std::string result = "[?!]";
2936 
2937 	switch (language_feature)
2938 	{
2939 	case LANGUAGE_FEATURE_ATOMIC_COUNTER:
2940 		result = "atomic counter";
2941 		break;
2942 	case LANGUAGE_FEATURE_ATTRIBUTE:
2943 		result = "attribute";
2944 		break;
2945 	case LANGUAGE_FEATURE_CONSTANT:
2946 		result = "constant";
2947 		break;
2948 	case LANGUAGE_FEATURE_FUNCTION_ARGUMENT_NAME:
2949 		result = "function argument name";
2950 		break;
2951 	case LANGUAGE_FEATURE_FUNCTION_NAME:
2952 		result = "function name";
2953 		break;
2954 	case LANGUAGE_FEATURE_INPUT:
2955 		result = "input variable";
2956 		break;
2957 	case LANGUAGE_FEATURE_INPUT_BLOCK_INSTANCE_NAME:
2958 		result = "input block instance name";
2959 		break;
2960 	case LANGUAGE_FEATURE_INPUT_BLOCK_MEMBER_NAME:
2961 		result = "input block member name";
2962 		break;
2963 	case LANGUAGE_FEATURE_INPUT_BLOCK_NAME:
2964 		result = "input block name";
2965 		break;
2966 	case LANGUAGE_FEATURE_OUTPUT:
2967 		result = "output variable";
2968 		break;
2969 	case LANGUAGE_FEATURE_OUTPUT_BLOCK_INSTANCE_NAME:
2970 		result = "output block instance name";
2971 		break;
2972 	case LANGUAGE_FEATURE_OUTPUT_BLOCK_MEMBER_NAME:
2973 		result = "output block member name";
2974 		break;
2975 	case LANGUAGE_FEATURE_OUTPUT_BLOCK_NAME:
2976 		result = "output block name";
2977 		break;
2978 	case LANGUAGE_FEATURE_SHADER_STORAGE_BLOCK_INSTANCE_NAME:
2979 		result = "shader storage block instance name";
2980 		break;
2981 	case LANGUAGE_FEATURE_SHADER_STORAGE_BLOCK_MEMBER_NAME:
2982 		result = "shader storage block member name";
2983 		break;
2984 	case LANGUAGE_FEATURE_SHADER_STORAGE_BLOCK_NAME:
2985 		result = "shader storage block name";
2986 		break;
2987 	case LANGUAGE_FEATURE_SHARED_VARIABLE:
2988 		result = "shared variable";
2989 		break;
2990 	case LANGUAGE_FEATURE_STRUCTURE_MEMBER:
2991 		result = "structure member";
2992 		break;
2993 	case LANGUAGE_FEATURE_STRUCTURE_INSTANCE_NAME:
2994 		result = "structure instance name";
2995 		break;
2996 	case LANGUAGE_FEATURE_STRUCTURE_NAME:
2997 		result = "structure name";
2998 		break;
2999 	case LANGUAGE_FEATURE_SUBROUTINE_FUNCTION_NAME:
3000 		result = "subroutine function name";
3001 		break;
3002 	case LANGUAGE_FEATURE_SUBROUTINE_TYPE:
3003 		result = "subroutine type";
3004 		break;
3005 	case LANGUAGE_FEATURE_SUBROUTINE_UNIFORM:
3006 		result = "subroutine uniform";
3007 		break;
3008 	case LANGUAGE_FEATURE_UNIFORM:
3009 		result = "uniform";
3010 		break;
3011 	case LANGUAGE_FEATURE_UNIFORM_BLOCK_INSTANCE_NAME:
3012 		result = "uniform block instance name";
3013 		break;
3014 	case LANGUAGE_FEATURE_UNIFORM_BLOCK_MEMBER_NAME:
3015 		result = "uniform block member name";
3016 		break;
3017 	case LANGUAGE_FEATURE_UNIFORM_BLOCK_NAME:
3018 		result = "uniform block name";
3019 		break;
3020 	case LANGUAGE_FEATURE_VARIABLE:
3021 		result = "variable";
3022 		break;
3023 	case LANGUAGE_FEATURE_VARYING:
3024 		result = "varying";
3025 		break;
3026 	default:
3027 		result = "unknown";
3028 		break;
3029 	} /* switch (language_feature) */
3030 
3031 	return result;
3032 }
3033 
3034 /** Returns keywords and reserved names, specific to the running context version. */
getReservedNames() const3035 std::vector<std::string> ReservedNamesTest::getReservedNames() const
3036 {
3037 	const glu::ContextType   context_type = m_context.getRenderContext().getType();
3038 	std::vector<std::string> result;
3039 
3040 	const char** context_keywords   = NULL;
3041 	unsigned int context_n_keywords = 0;
3042 	unsigned int context_n_reserved = 0;
3043 	const char** context_reserved   = NULL;
3044 
3045 	/* Keywords and reserved names were taken straight from relevant shading language specification documents */
3046 	static const char* keywords_gl31[] = {
3047 		"attribute",
3048 		"const",
3049 		"uniform",
3050 		"varying",
3051 		"layout",
3052 		"centroid",
3053 		"flat",
3054 		"smooth",
3055 		"noperspective",
3056 		"break",
3057 		"continue",
3058 		"do",
3059 		"for",
3060 		"while",
3061 		"switch",
3062 		"case",
3063 		"default",
3064 		"if",
3065 		"else",
3066 		"in",
3067 		"out",
3068 		"inout",
3069 		"float",
3070 		"int",
3071 		"void",
3072 		"bool",
3073 		"true",
3074 		"false",
3075 		"invariant",
3076 		"discard",
3077 		"return",
3078 		"mat2",
3079 		"mat3",
3080 		"mat4",
3081 		"mat2x2",
3082 		"mat2x3",
3083 		"mat2x4",
3084 		"mat3x2",
3085 		"mat3x3",
3086 		"mat3x4",
3087 		"mat4x2",
3088 		"mat4x3",
3089 		"mat4x4",
3090 		"vec2",
3091 		"vec3",
3092 		"vec4",
3093 		"ivec2",
3094 		"ivec3",
3095 		"ivec4",
3096 		"bvec2",
3097 		"bvec3",
3098 		"bvec4",
3099 		"uint",
3100 		"uvec2",
3101 		"uvec3",
3102 		"uvec4",
3103 		"lowp",
3104 		"mediump",
3105 		"highp",
3106 		"precision",
3107 		"sampler1D",
3108 		"sampler2D",
3109 		"sampler3D",
3110 		"samplerCube",
3111 		"sampler1DShadow",
3112 		"sampler2DShadow",
3113 		"samplerCubeShadow",
3114 		"sampler1DArray",
3115 		"sampler2DArray",
3116 		"sampler1DArrayShadow",
3117 		"sampler2DArrayShadow",
3118 		"isampler1D",
3119 		"isampler2D",
3120 		"isampler3D",
3121 		"isamplerCube",
3122 		"isampler1DArray",
3123 		"isampler2DArray",
3124 		"usampler1D",
3125 		"usampler2D",
3126 		"usampler3D",
3127 		"usamplerCube",
3128 		"usampler1DArray",
3129 		"usampler2DArray",
3130 		"sampler2DRect",
3131 		"sampler2DRectShadow",
3132 		"isampler2DRect",
3133 		"usampler2DRect",
3134 		"samplerBuffer",
3135 		"isamplerBuffer",
3136 		"usamplerBuffer",
3137 	};
3138 	static const char* keywords_gl32[] = {
3139 		"attribute",
3140 		"const",
3141 		"uniform",
3142 		"varying",
3143 		"layout",
3144 		"centroid",
3145 		"flat",
3146 		"smooth",
3147 		"noperspective",
3148 		"break",
3149 		"continue",
3150 		"do",
3151 		"for",
3152 		"while",
3153 		"switch",
3154 		"case",
3155 		"default",
3156 		"if",
3157 		"else",
3158 		"in",
3159 		"out",
3160 		"inout",
3161 		"float",
3162 		"int",
3163 		"void",
3164 		"bool",
3165 		"true",
3166 		"false",
3167 		"invariant",
3168 		"discard",
3169 		"return",
3170 		"mat2",
3171 		"mat3",
3172 		"mat4",
3173 		"mat2x2",
3174 		"mat2x3",
3175 		"mat2x4",
3176 		"mat3x2",
3177 		"mat3x3",
3178 		"mat3x4",
3179 		"mat4x2",
3180 		"mat4x3",
3181 		"mat4x4",
3182 		"vec2",
3183 		"vec3",
3184 		"vec4",
3185 		"ivec2",
3186 		"ivec3",
3187 		"ivec4",
3188 		"bvec2",
3189 		"bvec3",
3190 		"bvec4",
3191 		"uint",
3192 		"uvec2",
3193 		"uvec3",
3194 		"uvec4",
3195 		"lowp",
3196 		"mediump",
3197 		"highp",
3198 		"precision",
3199 		"sampler1D",
3200 		"sampler2D",
3201 		"sampler3D",
3202 		"samplerCube",
3203 		"sampler1DShadow",
3204 		"sampler2DShadow",
3205 		"samplerCubeShadow",
3206 		"sampler1DArray",
3207 		"sampler2DArray",
3208 		"sampler1DArrayShadow",
3209 		"sampler2DArrayShadow",
3210 		"isampler1D",
3211 		"isampler2D",
3212 		"isampler3D",
3213 		"isamplerCube",
3214 		"isampler1DArray",
3215 		"isampler2DArray",
3216 		"usampler1D",
3217 		"usampler2D",
3218 		"usampler3D",
3219 		"usamplerCube",
3220 		"usampler1DArray",
3221 		"usampler2DArray",
3222 		"sampler2DRect",
3223 		"sampler2DRectShadow",
3224 		"isampler2DRect",
3225 		"usampler2DRect",
3226 		"samplerBuffer",
3227 		"isamplerBuffer",
3228 		"usamplerBuffer",
3229 		"sampler2DMS",
3230 		"isampler2DMS",
3231 		"usampler2DMS",
3232 		"sampler2DMSArray",
3233 		"isampler2DMSArray",
3234 		"usampler2DMSArray",
3235 	};
3236 	static const char* keywords_gl33[] = {
3237 		"attribute",
3238 		"const",
3239 		"uniform",
3240 		"varying",
3241 		"layout",
3242 		"centroid",
3243 		"flat",
3244 		"smooth",
3245 		"noperspective",
3246 		"break",
3247 		"continue",
3248 		"do",
3249 		"for",
3250 		"while",
3251 		"switch",
3252 		"case",
3253 		"default",
3254 		"if",
3255 		"else",
3256 		"in",
3257 		"out",
3258 		"inout",
3259 		"float",
3260 		"int",
3261 		"void",
3262 		"bool",
3263 		"true",
3264 		"false",
3265 		"invariant",
3266 		"discard",
3267 		"return",
3268 		"mat2",
3269 		"mat3",
3270 		"mat4",
3271 		"mat2x2",
3272 		"mat2x3",
3273 		"mat2x4",
3274 		"mat3x2",
3275 		"mat3x3",
3276 		"mat3x4",
3277 		"mat4x2",
3278 		"mat4x3",
3279 		"mat4x4",
3280 		"vec2",
3281 		"vec3",
3282 		"vec4",
3283 		"ivec2",
3284 		"ivec3",
3285 		"ivec4",
3286 		"bvec2",
3287 		"bvec3",
3288 		"bvec4",
3289 		"uint",
3290 		"uvec2",
3291 		"uvec3",
3292 		"uvec4",
3293 		"lowp",
3294 		"mediump",
3295 		"highp",
3296 		"precision",
3297 		"sampler1D",
3298 		"sampler2D",
3299 		"sampler3D",
3300 		"samplerCube",
3301 		"sampler1DShadow",
3302 		"sampler2DShadow",
3303 		"samplerCubeShadow",
3304 		"sampler1DArray",
3305 		"sampler2DArray",
3306 		"sampler1DArrayShadow",
3307 		"sampler2DArrayShadow",
3308 		"isampler1D",
3309 		"isampler2D",
3310 		"isampler3D",
3311 		"isamplerCube",
3312 		"isampler1DArray",
3313 		"isampler2DArray",
3314 		"usampler1D",
3315 		"usampler2D",
3316 		"usampler3D",
3317 		"usamplerCube",
3318 		"usampler1DArray",
3319 		"usampler2DArray",
3320 		"sampler2DRect",
3321 		"sampler2DRectShadow",
3322 		"isampler2DRect",
3323 		"usampler2DRect",
3324 		"samplerBuffer",
3325 		"isamplerBuffer",
3326 		"usamplerBuffer",
3327 		"sampler2DMS",
3328 		"isampler2DMS",
3329 		"usampler2DMS",
3330 		"sampler2DMSArray",
3331 		"isampler2DMSArray",
3332 		"usampler2DMSArray",
3333 	};
3334 	static const char* keywords_gl40[] = {
3335 		"attribute",
3336 		"const",
3337 		"uniform",
3338 		"varying",
3339 		"layout",
3340 		"centroid",
3341 		"flat",
3342 		"smooth",
3343 		"noperspective",
3344 		"patch",
3345 		"sample",
3346 		"break",
3347 		"continue",
3348 		"do",
3349 		"for",
3350 		"while",
3351 		"switch",
3352 		"case",
3353 		"default",
3354 		"if",
3355 		"else",
3356 		"subroutine",
3357 		"in",
3358 		"out",
3359 		"inout",
3360 		"float",
3361 		"double",
3362 		"int",
3363 		"void",
3364 		"bool",
3365 		"true",
3366 		"false",
3367 		"invariant",
3368 		"discard",
3369 		"return",
3370 		"mat2",
3371 		"mat3",
3372 		"mat4",
3373 		"dmat2",
3374 		"dmat3",
3375 		"dmat4",
3376 		"mat2x2",
3377 		"mat2x3",
3378 		"mat2x4",
3379 		"dmat2x2",
3380 		"dmat2x3",
3381 		"dmat2x4",
3382 		"mat3x2",
3383 		"mat3x3",
3384 		"mat3x4",
3385 		"dmat3x2",
3386 		"dmat3x3",
3387 		"dmat3x4",
3388 		"mat4x2",
3389 		"mat4x3",
3390 		"mat4x4",
3391 		"dmat4x2",
3392 		"dmat4x3",
3393 		"dmat4x4",
3394 		"vec2",
3395 		"vec3",
3396 		"vec4",
3397 		"ivec2",
3398 		"ivec3",
3399 		"ivec4",
3400 		"bvec2",
3401 		"bvec3",
3402 		"bvec4",
3403 		"dvec2",
3404 		"dvec3",
3405 		"dvec4",
3406 		"uint",
3407 		"uvec2",
3408 		"uvec3",
3409 		"uvec4",
3410 		"lowp",
3411 		"mediump",
3412 		"highp",
3413 		"precision",
3414 		"sampler1D",
3415 		"sampler2D",
3416 		"sampler3D",
3417 		"samplerCube",
3418 		"sampler1DShadow",
3419 		"sampler2DShadow",
3420 		"samplerCubeShadow",
3421 		"sampler1DArray",
3422 		"sampler2DArray",
3423 		"sampler1DArrayShadow",
3424 		"sampler2DArrayShadow",
3425 		"isampler1D",
3426 		"isampler2D",
3427 		"isampler3D",
3428 		"isamplerCube",
3429 		"isampler1DArray",
3430 		"isampler2DArray",
3431 		"usampler1D",
3432 		"usampler2D",
3433 		"usampler3D",
3434 		"usamplerCube",
3435 		"usampler1DArray",
3436 		"usampler2DArray",
3437 		"sampler2DRect",
3438 		"sampler2DRectShadow",
3439 		"isampler2DRect",
3440 		"usampler2DRect",
3441 		"samplerBuffer",
3442 		"isamplerBuffer",
3443 		"usamplerBuffer",
3444 		"sampler2DMS",
3445 		"isampler2DMS",
3446 		"usampler2DMS",
3447 		"sampler2DMSArray",
3448 		"isampler2DMSArray",
3449 		"usampler2DMSArray",
3450 		"samplerCubeArray",
3451 		"samplerCubeArrayShadow",
3452 		"isamplerCubeArray",
3453 		"usamplerCubeArray",
3454 	};
3455 	static const char* keywords_gl41[] = {
3456 		"attribute",
3457 		"const",
3458 		"uniform",
3459 		"varying",
3460 		"layout",
3461 		"centroid",
3462 		"flat",
3463 		"smooth",
3464 		"noperspective",
3465 		"patch",
3466 		"sample",
3467 		"break",
3468 		"continue",
3469 		"do",
3470 		"for",
3471 		"while",
3472 		"switch",
3473 		"case",
3474 		"default",
3475 		"if",
3476 		"else",
3477 		"subroutine",
3478 		"in",
3479 		"out",
3480 		"inout",
3481 		"float",
3482 		"double",
3483 		"int",
3484 		"void",
3485 		"bool",
3486 		"true",
3487 		"false",
3488 		"invariant",
3489 		"discard",
3490 		"return",
3491 		"mat2",
3492 		"mat3",
3493 		"mat4",
3494 		"dmat2",
3495 		"dmat3",
3496 		"dmat4",
3497 		"mat2x2",
3498 		"mat2x3",
3499 		"mat2x4",
3500 		"dmat2x2",
3501 		"dmat2x3",
3502 		"dmat2x4",
3503 		"mat3x2",
3504 		"mat3x3",
3505 		"mat3x4",
3506 		"dmat3x2",
3507 		"dmat3x3",
3508 		"dmat3x4",
3509 		"mat4x2",
3510 		"mat4x3",
3511 		"mat4x4",
3512 		"dmat4x2",
3513 		"dmat4x3",
3514 		"dmat4x4",
3515 		"vec2",
3516 		"vec3",
3517 		"vec4",
3518 		"ivec2",
3519 		"ivec3",
3520 		"ivec4",
3521 		"bvec2",
3522 		"bvec3",
3523 		"bvec4",
3524 		"dvec2",
3525 		"dvec3",
3526 		"dvec4",
3527 		"uint",
3528 		"uvec2",
3529 		"uvec3",
3530 		"uvec4",
3531 		"lowp",
3532 		"mediump",
3533 		"highp",
3534 		"precision",
3535 		"sampler1D",
3536 		"sampler2D",
3537 		"sampler3D",
3538 		"samplerCube",
3539 		"sampler1DShadow",
3540 		"sampler2DShadow",
3541 		"samplerCubeShadow",
3542 		"sampler1DArray",
3543 		"sampler2DArray",
3544 		"sampler1DArrayShadow",
3545 		"sampler2DArrayShadow",
3546 		"isampler1D",
3547 		"isampler2D",
3548 		"isampler3D",
3549 		"isamplerCube",
3550 		"isampler1DArray",
3551 		"isampler2DArray",
3552 		"usampler1D",
3553 		"usampler2D",
3554 		"usampler3D",
3555 		"usamplerCube",
3556 		"usampler1DArray",
3557 		"usampler2DArray",
3558 		"sampler2DRect",
3559 		"sampler2DRectShadow",
3560 		"isampler2DRect",
3561 		"usampler2DRect",
3562 		"samplerBuffer",
3563 		"isamplerBuffer",
3564 		"usamplerBuffer",
3565 		"sampler2DMS",
3566 		"isampler2DMS",
3567 		"usampler2DMS",
3568 		"sampler2DMSArray",
3569 		"isampler2DMSArray",
3570 		"usampler2DMSArray",
3571 		"samplerCubeArray",
3572 		"samplerCubeArrayShadow",
3573 		"isamplerCubeArray",
3574 		"usamplerCubeArray",
3575 	};
3576 	static const char* keywords_gl42[] = {
3577 		"attribute",
3578 		"const",
3579 		"uniform",
3580 		"varying",
3581 		"coherent",
3582 		"volatile",
3583 		"restrict",
3584 		"readonly",
3585 		"writeonly",
3586 		"atomic_uint",
3587 		"layout",
3588 		"centroid",
3589 		"flat",
3590 		"smooth",
3591 		"noperspective",
3592 		"patch",
3593 		"sample",
3594 		"break",
3595 		"continue",
3596 		"do",
3597 		"for",
3598 		"while",
3599 		"switch",
3600 		"case",
3601 		"default",
3602 		"if",
3603 		"else",
3604 		"subroutine",
3605 		"in",
3606 		"out",
3607 		"inout",
3608 		"float",
3609 		"double",
3610 		"int",
3611 		"void",
3612 		"bool",
3613 		"true",
3614 		"false",
3615 		"invariant",
3616 		"discard",
3617 		"return",
3618 		"mat2",
3619 		"mat3",
3620 		"mat4",
3621 		"dmat2",
3622 		"dmat3",
3623 		"dmat4",
3624 		"mat2x2",
3625 		"mat2x3",
3626 		"mat2x4",
3627 		"dmat2x2",
3628 		"dmat2x3",
3629 		"dmat2x4",
3630 		"mat3x2",
3631 		"mat3x3",
3632 		"mat3x4",
3633 		"dmat3x2",
3634 		"dmat3x3",
3635 		"dmat3x4",
3636 		"mat4x2",
3637 		"mat4x3",
3638 		"mat4x4",
3639 		"dmat4x2",
3640 		"dmat4x3",
3641 		"dmat4x4",
3642 		"vec2",
3643 		"vec3",
3644 		"vec4",
3645 		"ivec2",
3646 		"ivec3",
3647 		"ivec4",
3648 		"bvec2",
3649 		"bvec3",
3650 		"bvec4",
3651 		"dvec2",
3652 		"dvec3",
3653 		"dvec4",
3654 		"uint",
3655 		"uvec2",
3656 		"uvec3",
3657 		"uvec4",
3658 		"lowp",
3659 		"mediump",
3660 		"highp",
3661 		"precision",
3662 		"sampler1D",
3663 		"sampler2D",
3664 		"sampler3D",
3665 		"samplerCube",
3666 		"sampler1DShadow",
3667 		"sampler2DShadow",
3668 		"samplerCubeShadow",
3669 		"sampler1DArray",
3670 		"sampler2DArray",
3671 		"sampler1DArrayShadow",
3672 		"sampler2DArrayShadow",
3673 		"isampler1D",
3674 		"isampler2D",
3675 		"isampler3D",
3676 		"isamplerCube",
3677 		"isampler1DArray",
3678 		"isampler2DArray",
3679 		"usampler1D",
3680 		"usampler2D",
3681 		"usampler3D",
3682 		"usamplerCube",
3683 		"usampler1DArray",
3684 		"usampler2DArray",
3685 		"sampler2DRect",
3686 		"sampler2DRectShadow",
3687 		"isampler2DRect",
3688 		"usampler2DRect",
3689 		"samplerBuffer",
3690 		"isamplerBuffer",
3691 		"usamplerBuffer",
3692 		"sampler2DMS",
3693 		"isampler2DMS",
3694 		"usampler2DMS",
3695 		"sampler2DMSArray",
3696 		"isampler2DMSArray",
3697 		"usampler2DMSArray",
3698 		"samplerCubeArray",
3699 		"samplerCubeArrayShadow",
3700 		"isamplerCubeArray",
3701 		"usamplerCubeArray",
3702 		"image1D",
3703 		"iimage1D",
3704 		"uimage1D",
3705 		"image2D",
3706 		"iimage2D",
3707 		"uimage2D",
3708 		"image3D",
3709 		"iimage3D",
3710 		"uimage3D",
3711 		"image2DRect",
3712 		"iimage2DRect",
3713 		"uimage2DRect",
3714 		"imageCube",
3715 		"iimageCube",
3716 		"uimageCube",
3717 		"imageBuffer",
3718 		"iimageBuffer",
3719 		"uimageBuffer",
3720 		"image1DArray",
3721 		"iimage1DArray",
3722 		"uimage1DArray",
3723 		"image2DArray",
3724 		"iimage2DArray",
3725 		"uimage2DArray",
3726 		"imageCubeArray",
3727 		"iimageCubeArray",
3728 		"uimageCubeArray",
3729 		"image2DMS",
3730 		"iimage2DMS",
3731 		"uimage2DMS",
3732 		"image2DMSArray",
3733 		"iimage2DMSArray",
3734 		"uimage2DMSArray",
3735 	};
3736 	static const char* keywords_gl43[] = {
3737 		"attribute",
3738 		"const",
3739 		"uniform",
3740 		"varying",
3741 		"buffer",
3742 		"shared",
3743 		"coherent",
3744 		"volatile",
3745 		"restrict",
3746 		"readonly",
3747 		"writeonly",
3748 		"atomic_uint",
3749 		"layout",
3750 		"centroid",
3751 		"flat",
3752 		"smooth",
3753 		"noperspective",
3754 		"patch",
3755 		"sample",
3756 		"break",
3757 		"continue",
3758 		"do",
3759 		"for",
3760 		"while",
3761 		"switch",
3762 		"case",
3763 		"default",
3764 		"if",
3765 		"else",
3766 		"subroutine",
3767 		"in",
3768 		"out",
3769 		"inout",
3770 		"float",
3771 		"double",
3772 		"int",
3773 		"void",
3774 		"bool",
3775 		"true",
3776 		"false",
3777 		"invariant",
3778 		"precise",
3779 		"discard",
3780 		"return",
3781 		"mat2",
3782 		"mat3",
3783 		"mat4",
3784 		"dmat2",
3785 		"dmat3",
3786 		"dmat4",
3787 		"mat2x2",
3788 		"mat2x3",
3789 		"mat2x4",
3790 		"dmat2x2",
3791 		"dmat2x3",
3792 		"dmat2x4",
3793 		"mat3x2",
3794 		"mat3x3",
3795 		"mat3x4",
3796 		"dmat3x2",
3797 		"dmat3x3",
3798 		"dmat3x4",
3799 		"mat4x2",
3800 		"mat4x3",
3801 		"mat4x4",
3802 		"dmat4x2",
3803 		"dmat4x3",
3804 		"dmat4x4",
3805 		"vec2",
3806 		"vec3",
3807 		"vec4",
3808 		"ivec2",
3809 		"ivec3",
3810 		"ivec4",
3811 		"bvec2",
3812 		"bvec3",
3813 		"bvec4",
3814 		"dvec2",
3815 		"dvec3",
3816 		"dvec4",
3817 		"uint",
3818 		"uvec2",
3819 		"uvec3",
3820 		"uvec4",
3821 		"lowp",
3822 		"mediump",
3823 		"highp",
3824 		"precision",
3825 		"sampler1D",
3826 		"sampler2D",
3827 		"sampler3D",
3828 		"samplerCube",
3829 		"sampler1DShadow",
3830 		"sampler2DShadow",
3831 		"samplerCubeShadow",
3832 		"sampler1DArray",
3833 		"sampler2DArray",
3834 		"sampler1DArrayShadow",
3835 		"sampler2DArrayShadow",
3836 		"isampler1D",
3837 		"isampler2D",
3838 		"isampler3D",
3839 		"isamplerCube",
3840 		"isampler1DArray",
3841 		"isampler2DArray",
3842 		"usampler1D",
3843 		"usampler2D",
3844 		"usampler3D",
3845 		"usamplerCube",
3846 		"usampler1DArray",
3847 		"usampler2DArray",
3848 		"sampler2DRect",
3849 		"sampler2DRectShadow",
3850 		"isampler2DRect",
3851 		"usampler2DRect",
3852 		"samplerBuffer",
3853 		"isamplerBuffer",
3854 		"usamplerBuffer",
3855 		"sampler2DMS",
3856 		"isampler2DMS",
3857 		"usampler2DMS",
3858 		"sampler2DMSArray",
3859 		"isampler2DMSArray",
3860 		"usampler2DMSArray",
3861 		"samplerCubeArray",
3862 		"samplerCubeArrayShadow",
3863 		"isamplerCubeArray",
3864 		"usamplerCubeArray",
3865 		"image1D",
3866 		"iimage1D",
3867 		"uimage1D",
3868 		"image2D",
3869 		"iimage2D",
3870 		"uimage2D",
3871 		"image3D",
3872 		"iimage3D",
3873 		"uimage3D",
3874 		"image2DRect",
3875 		"iimage2DRect",
3876 		"uimage2DRect",
3877 		"imageCube",
3878 		"iimageCube",
3879 		"uimageCube",
3880 		"imageBuffer",
3881 		"iimageBuffer",
3882 		"uimageBuffer",
3883 		"image1DArray",
3884 		"iimage1DArray",
3885 		"uimage1DArray",
3886 		"image2DArray",
3887 		"iimage2DArray",
3888 		"uimage2DArray",
3889 		"imageCubeArray",
3890 		"iimageCubeArray",
3891 		"uimageCubeArray",
3892 		"image2DMS",
3893 		"iimage2DMS",
3894 		"uimage2DMS",
3895 		"image2DMSArray",
3896 		"iimage2DMSArray",
3897 		"uimage2DMSArray",
3898 	};
3899 	static const char* keywords_gl44[] = {
3900 		"attribute",
3901 		"const",
3902 		"uniform",
3903 		"varying",
3904 		"buffer",
3905 		"shared",
3906 		"coherent",
3907 		"volatile",
3908 		"restrict",
3909 		"readonly",
3910 		"writeonly",
3911 		"atomic_uint",
3912 		"layout",
3913 		"centroid",
3914 		"flat",
3915 		"smooth",
3916 		"noperspective",
3917 		"patch",
3918 		"sample",
3919 		"break",
3920 		"continue",
3921 		"do",
3922 		"for",
3923 		"while",
3924 		"switch",
3925 		"case",
3926 		"default",
3927 		"if",
3928 		"else",
3929 		"subroutine",
3930 		"in",
3931 		"out",
3932 		"inout",
3933 		"float",
3934 		"double",
3935 		"int",
3936 		"void",
3937 		"bool",
3938 		"true",
3939 		"false",
3940 		"invariant",
3941 		"precise",
3942 		"discard",
3943 		"return",
3944 		"mat2",
3945 		"mat3",
3946 		"mat4",
3947 		"dmat2",
3948 		"dmat3",
3949 		"dmat4",
3950 		"mat2x2",
3951 		"mat2x3",
3952 		"mat2x4",
3953 		"dmat2x2",
3954 		"dmat2x3",
3955 		"dmat2x4",
3956 		"mat3x2",
3957 		"mat3x3",
3958 		"mat3x4",
3959 		"dmat3x2",
3960 		"dmat3x3",
3961 		"dmat3x4",
3962 		"mat4x2",
3963 		"mat4x3",
3964 		"mat4x4",
3965 		"dmat4x2",
3966 		"dmat4x3",
3967 		"dmat4x4",
3968 		"vec2",
3969 		"vec3",
3970 		"vec4",
3971 		"ivec2",
3972 		"ivec3",
3973 		"ivec4",
3974 		"bvec2",
3975 		"bvec3",
3976 		"bvec4",
3977 		"dvec2",
3978 		"dvec3",
3979 		"dvec4",
3980 		"uint",
3981 		"uvec2",
3982 		"uvec3",
3983 		"uvec4",
3984 		"lowp",
3985 		"mediump",
3986 		"highp",
3987 		"precision",
3988 		"sampler1D",
3989 		"sampler2D",
3990 		"sampler3D",
3991 		"samplerCube",
3992 		"sampler1DShadow",
3993 		"sampler2DShadow",
3994 		"samplerCubeShadow",
3995 		"sampler1DArray",
3996 		"sampler2DArray",
3997 		"sampler1DArrayShadow",
3998 		"sampler2DArrayShadow",
3999 		"isampler1D",
4000 		"isampler2D",
4001 		"isampler3D",
4002 		"isamplerCube",
4003 		"isampler1DArray",
4004 		"isampler2DArray",
4005 		"usampler1D",
4006 		"usampler2D",
4007 		"usampler3D",
4008 		"usamplerCube",
4009 		"usampler1DArray",
4010 		"usampler2DArray",
4011 		"sampler2DRect",
4012 		"sampler2DRectShadow",
4013 		"isampler2DRect",
4014 		"usampler2DRect",
4015 		"samplerBuffer",
4016 		"isamplerBuffer",
4017 		"usamplerBuffer",
4018 		"sampler2DMS",
4019 		"isampler2DMS",
4020 		"usampler2DMS",
4021 		"sampler2DMSArray",
4022 		"isampler2DMSArray",
4023 		"usampler2DMSArray",
4024 		"samplerCubeArray",
4025 		"samplerCubeArrayShadow",
4026 		"isamplerCubeArray",
4027 		"usamplerCubeArray",
4028 		"image1D",
4029 		"iimage1D",
4030 		"uimage1D",
4031 		"image2D",
4032 		"iimage2D",
4033 		"uimage2D",
4034 		"image3D",
4035 		"iimage3D",
4036 		"uimage3D",
4037 		"image2DRect",
4038 		"iimage2DRect",
4039 		"uimage2DRect",
4040 		"imageCube",
4041 		"iimageCube",
4042 		"uimageCube",
4043 		"imageBuffer",
4044 		"iimageBuffer",
4045 		"uimageBuffer",
4046 		"image1DArray",
4047 		"iimage1DArray",
4048 		"uimage1DArray",
4049 		"image2DArray",
4050 		"iimage2DArray",
4051 		"uimage2DArray",
4052 		"imageCubeArray",
4053 		"iimageCubeArray",
4054 		"uimageCubeArray",
4055 		"image2DMS",
4056 		"iimage2DMS",
4057 		"uimage2DMS",
4058 		"image2DMSArray",
4059 		"iimage2DMSArray",
4060 		"uimage2DMSArray",
4061 	};
4062 	static const char* keywords_gl45[] = {
4063 		"attribute",
4064 		"const",
4065 		"uniform",
4066 		"varying",
4067 		"buffer",
4068 		"shared",
4069 		"coherent",
4070 		"volatile",
4071 		"restrict",
4072 		"readonly",
4073 		"writeonly",
4074 		"atomic_uint",
4075 		"layout",
4076 		"centroid",
4077 		"flat",
4078 		"smooth",
4079 		"noperspective",
4080 		"patch",
4081 		"sample",
4082 		"break",
4083 		"continue",
4084 		"do",
4085 		"for",
4086 		"while",
4087 		"switch",
4088 		"case",
4089 		"default",
4090 		"if",
4091 		"else",
4092 		"subroutine",
4093 		"in",
4094 		"out",
4095 		"inout",
4096 		"float",
4097 		"double",
4098 		"int",
4099 		"void",
4100 		"bool",
4101 		"true",
4102 		"false",
4103 		"invariant",
4104 		"precise",
4105 		"discard",
4106 		"return",
4107 		"mat2",
4108 		"mat3",
4109 		"mat4",
4110 		"dmat2",
4111 		"dmat3",
4112 		"dmat4",
4113 		"mat2x2",
4114 		"mat2x3",
4115 		"mat2x4",
4116 		"dmat2x2",
4117 		"dmat2x3",
4118 		"dmat2x4",
4119 		"mat3x2",
4120 		"mat3x3",
4121 		"mat3x4",
4122 		"dmat3x2",
4123 		"dmat3x3",
4124 		"dmat3x4",
4125 		"mat4x2",
4126 		"mat4x3",
4127 		"mat4x4",
4128 		"dmat4x2",
4129 		"dmat4x3",
4130 		"dmat4x4",
4131 		"vec2",
4132 		"vec3",
4133 		"vec4",
4134 		"ivec2",
4135 		"ivec3",
4136 		"ivec4",
4137 		"bvec2",
4138 		"bvec3",
4139 		"bvec4",
4140 		"dvec2",
4141 		"dvec3",
4142 		"dvec4",
4143 		"uint",
4144 		"uvec2",
4145 		"uvec3",
4146 		"uvec4",
4147 		"lowp",
4148 		"mediump",
4149 		"highp",
4150 		"precision",
4151 		"sampler1D",
4152 		"sampler2D",
4153 		"sampler3D",
4154 		"samplerCube",
4155 		"sampler1DShadow",
4156 		"sampler2DShadow",
4157 		"samplerCubeShadow",
4158 		"sampler1DArray",
4159 		"sampler2DArray",
4160 		"sampler1DArrayShadow",
4161 		"sampler2DArrayShadow",
4162 		"isampler1D",
4163 		"isampler2D",
4164 		"isampler3D",
4165 		"isamplerCube",
4166 		"isampler1DArray",
4167 		"isampler2DArray",
4168 		"usampler1D",
4169 		"usampler2D",
4170 		"usampler3D",
4171 		"usamplerCube",
4172 		"usampler1DArray",
4173 		"usampler2DArray",
4174 		"sampler2DRect",
4175 		"sampler2DRectShadow",
4176 		"isampler2DRect",
4177 		"usampler2DRect",
4178 		"samplerBuffer",
4179 		"isamplerBuffer",
4180 		"usamplerBuffer",
4181 		"sampler2DMS",
4182 		"isampler2DMS",
4183 		"usampler2DMS",
4184 		"sampler2DMSArray",
4185 		"isampler2DMSArray",
4186 		"usampler2DMSArray",
4187 		"samplerCubeArray",
4188 		"samplerCubeArrayShadow",
4189 		"isamplerCubeArray",
4190 		"usamplerCubeArray",
4191 		"image1D",
4192 		"iimage1D",
4193 		"uimage1D",
4194 		"image2D",
4195 		"iimage2D",
4196 		"uimage2D",
4197 		"image3D",
4198 		"iimage3D",
4199 		"uimage3D",
4200 		"image2DRect",
4201 		"iimage2DRect",
4202 		"uimage2DRect",
4203 		"imageCube",
4204 		"iimageCube",
4205 		"uimageCube",
4206 		"imageBuffer",
4207 		"iimageBuffer",
4208 		"uimageBuffer",
4209 		"image1DArray",
4210 		"iimage1DArray",
4211 		"uimage1DArray",
4212 		"image2DArray",
4213 		"iimage2DArray",
4214 		"uimage2DArray",
4215 		"imageCubeArray",
4216 		"iimageCubeArray",
4217 		"uimageCubeArray",
4218 		"image2DMS",
4219 		"iimage2DMS",
4220 		"uimage2DMS",
4221 		"image2DMSArray",
4222 		"iimage2DMSArray",
4223 		"uimage2DMSArray",
4224 	};
4225 	static const char* keywords_gl46[] = {
4226 		"attribute",
4227 		"const",
4228 		"uniform",
4229 		"varying",
4230 		"buffer",
4231 		"shared",
4232 		"coherent",
4233 		"volatile",
4234 		"restrict",
4235 		"readonly",
4236 		"writeonly",
4237 		"atomic_uint",
4238 		"layout",
4239 		"centroid",
4240 		"flat",
4241 		"smooth",
4242 		"noperspective",
4243 		"patch",
4244 		"sample",
4245 		"break",
4246 		"continue",
4247 		"do",
4248 		"for",
4249 		"while",
4250 		"switch",
4251 		"case",
4252 		"default",
4253 		"if",
4254 		"else",
4255 		"subroutine",
4256 		"in",
4257 		"out",
4258 		"inout",
4259 		"float",
4260 		"double",
4261 		"int",
4262 		"void",
4263 		"bool",
4264 		"true",
4265 		"false",
4266 		"invariant",
4267 		"precise",
4268 		"discard",
4269 		"return",
4270 		"mat2",
4271 		"mat3",
4272 		"mat4",
4273 		"dmat2",
4274 		"dmat3",
4275 		"dmat4",
4276 		"mat2x2",
4277 		"mat2x3",
4278 		"mat2x4",
4279 		"dmat2x2",
4280 		"dmat2x3",
4281 		"dmat2x4",
4282 		"mat3x2",
4283 		"mat3x3",
4284 		"mat3x4",
4285 		"dmat3x2",
4286 		"dmat3x3",
4287 		"dmat3x4",
4288 		"mat4x2",
4289 		"mat4x3",
4290 		"mat4x4",
4291 		"dmat4x2",
4292 		"dmat4x3",
4293 		"dmat4x4",
4294 		"vec2",
4295 		"vec3",
4296 		"vec4",
4297 		"ivec2",
4298 		"ivec3",
4299 		"ivec4",
4300 		"bvec2",
4301 		"bvec3",
4302 		"bvec4",
4303 		"dvec2",
4304 		"dvec3",
4305 		"dvec4",
4306 		"uint",
4307 		"uvec2",
4308 		"uvec3",
4309 		"uvec4",
4310 		"lowp",
4311 		"mediump",
4312 		"highp",
4313 		"precision",
4314 		"sampler1D",
4315 		"sampler2D",
4316 		"sampler3D",
4317 		"samplerCube",
4318 		"sampler1DShadow",
4319 		"sampler2DShadow",
4320 		"samplerCubeShadow",
4321 		"sampler1DArray",
4322 		"sampler2DArray",
4323 		"sampler1DArrayShadow",
4324 		"sampler2DArrayShadow",
4325 		"isampler1D",
4326 		"isampler2D",
4327 		"isampler3D",
4328 		"isamplerCube",
4329 		"isampler1DArray",
4330 		"isampler2DArray",
4331 		"usampler1D",
4332 		"usampler2D",
4333 		"usampler3D",
4334 		"usamplerCube",
4335 		"usampler1DArray",
4336 		"usampler2DArray",
4337 		"sampler2DRect",
4338 		"sampler2DRectShadow",
4339 		"isampler2DRect",
4340 		"usampler2DRect",
4341 		"samplerBuffer",
4342 		"isamplerBuffer",
4343 		"usamplerBuffer",
4344 		"sampler2DMS",
4345 		"isampler2DMS",
4346 		"usampler2DMS",
4347 		"sampler2DMSArray",
4348 		"isampler2DMSArray",
4349 		"usampler2DMSArray",
4350 		"samplerCubeArray",
4351 		"samplerCubeArrayShadow",
4352 		"isamplerCubeArray",
4353 		"usamplerCubeArray",
4354 		"image1D",
4355 		"iimage1D",
4356 		"uimage1D",
4357 		"image2D",
4358 		"iimage2D",
4359 		"uimage2D",
4360 		"image3D",
4361 		"iimage3D",
4362 		"uimage3D",
4363 		"image2DRect",
4364 		"iimage2DRect",
4365 		"uimage2DRect",
4366 		"imageCube",
4367 		"iimageCube",
4368 		"uimageCube",
4369 		"imageBuffer",
4370 		"iimageBuffer",
4371 		"uimageBuffer",
4372 		"image1DArray",
4373 		"iimage1DArray",
4374 		"uimage1DArray",
4375 		"image2DArray",
4376 		"iimage2DArray",
4377 		"uimage2DArray",
4378 		"imageCubeArray",
4379 		"iimageCubeArray",
4380 		"uimageCubeArray",
4381 		"image2DMS",
4382 		"iimage2DMS",
4383 		"uimage2DMS",
4384 		"image2DMSArray",
4385 		"iimage2DMSArray",
4386 		"uimage2DMSArray",
4387 		"struct"
4388 	};
4389 	static const char* reserved_gl31[] = {
4390 		"common",
4391 		"partition",
4392 		"active",
4393 		"asm",
4394 		"class",
4395 		"union",
4396 		"enum",
4397 		"typedef",
4398 		"template",
4399 		"this",
4400 		"packed",
4401 		"goto",
4402 		"inline",
4403 		"noinline",
4404 		"volatile",
4405 		"public",
4406 		"static",
4407 		"extern",
4408 		"external",
4409 		"interface",
4410 		"long",
4411 		"short",
4412 		"double",
4413 		"half",
4414 		"fixed",
4415 		"unsigned",
4416 		"superp",
4417 		"input",
4418 		"output",
4419 		"hvec2",
4420 		"hvec3",
4421 		"hvec4",
4422 		"dvec2",
4423 		"dvec3",
4424 		"dvec4",
4425 		"fvec2",
4426 		"fvec3",
4427 		"fvec4",
4428 		"sampler3DRect",
4429 		"filter",
4430 		"image1D",
4431 		"image2D",
4432 		"image3D",
4433 		"imageCube",
4434 		"iimage1D",
4435 		"iimage2D",
4436 		"iimage3D",
4437 		"iimageCube",
4438 		"uimage1D",
4439 		"uimage2D",
4440 		"uimage3D",
4441 		"uimageCube",
4442 		"image1DArray",
4443 		"image2DArray",
4444 		"iimage1DArray",
4445 		"iimage2DArray",
4446 		"uimage1DArray",
4447 		"uimage2DArray",
4448 		"image1DShadow",
4449 		"image2DShadow",
4450 		"image1DArrayShadow",
4451 		"image2DArrayShadow",
4452 		"imageBuffer",
4453 		"iimageBuffer",
4454 		"uimageBuffer",
4455 		"sizeof",
4456 		"cast",
4457 		"namespace",
4458 		"using",
4459 		"row_major",
4460 	};
4461 	static const char* reserved_gl32[] = {
4462 		"common",
4463 		"partition",
4464 		"active",
4465 		"asm",
4466 		"class",
4467 		"union",
4468 		"enum",
4469 		"typedef",
4470 		"template",
4471 		"this",
4472 		"packed",
4473 		"goto",
4474 		"inline",
4475 		"noinline",
4476 		"volatile",
4477 		"public",
4478 		"static",
4479 		"extern",
4480 		"external",
4481 		"interface",
4482 		"long",
4483 		"short",
4484 		"double",
4485 		"half",
4486 		"fixed",
4487 		"unsigned",
4488 		"superp",
4489 		"input",
4490 		"output",
4491 		"hvec2",
4492 		"hvec3",
4493 		"hvec4",
4494 		"dvec2",
4495 		"dvec3",
4496 		"dvec4",
4497 		"fvec2",
4498 		"fvec3",
4499 		"fvec4",
4500 		"sampler3DRect",
4501 		"filter",
4502 		"image1D",
4503 		"image2D",
4504 		"image3D",
4505 		"imageCube",
4506 		"iimage1D",
4507 		"iimage2D",
4508 		"iimage3D",
4509 		"iimageCube",
4510 		"uimage1D",
4511 		"uimage2D",
4512 		"uimage3D",
4513 		"uimageCube",
4514 		"image1DArray",
4515 		"image2DArray",
4516 		"iimage1DArray",
4517 		"iimage2DArray",
4518 		"uimage1DArray",
4519 		"uimage2DArray",
4520 		"image1DShadow",
4521 		"image2DShadow",
4522 		"image1DArrayShadow",
4523 		"image2DArrayShadow",
4524 		"imageBuffer",
4525 		"iimageBuffer",
4526 		"uimageBuffer",
4527 		"sizeof",
4528 		"cast",
4529 		"namespace",
4530 		"using",
4531 		"row_major",
4532 	};
4533 	static const char* reserved_gl33[] = {
4534 		"common",
4535 		"partition",
4536 		"active",
4537 		"asm",
4538 		"class",
4539 		"union",
4540 		"enum",
4541 		"typedef",
4542 		"template",
4543 		"this",
4544 		"packed",
4545 		"goto",
4546 		"inline",
4547 		"noinline",
4548 		"volatile",
4549 		"public",
4550 		"static",
4551 		"extern",
4552 		"external",
4553 		"interface",
4554 		"long",
4555 		"short",
4556 		"double",
4557 		"half",
4558 		"fixed",
4559 		"unsigned",
4560 		"superp",
4561 		"input",
4562 		"output",
4563 		"hvec2",
4564 		"hvec3",
4565 		"hvec4",
4566 		"dvec2",
4567 		"dvec3",
4568 		"dvec4",
4569 		"fvec2",
4570 		"fvec3",
4571 		"fvec4",
4572 		"sampler3DRect",
4573 		"filter",
4574 		"image1D",
4575 		"image2D",
4576 		"image3D",
4577 		"imageCube",
4578 		"iimage1D",
4579 		"iimage2D",
4580 		"iimage3D",
4581 		"iimageCube",
4582 		"uimage1D",
4583 		"uimage2D",
4584 		"uimage3D",
4585 		"uimageCube",
4586 		"image1DArray",
4587 		"image2DArray",
4588 		"iimage1DArray",
4589 		"iimage2DArray",
4590 		"uimage1DArray",
4591 		"uimage2DArray",
4592 		"image1DShadow",
4593 		"image2DShadow",
4594 		"image1DArrayShadow",
4595 		"image2DArrayShadow",
4596 		"imageBuffer",
4597 		"iimageBuffer",
4598 		"uimageBuffer",
4599 		"sizeof",
4600 		"cast",
4601 		"namespace",
4602 		"using",
4603 		"row_major",
4604 	};
4605 	static const char* reserved_gl40[] = {
4606 		"common",
4607 		"partition",
4608 		"active",
4609 		"asm",
4610 		"class",
4611 		"union",
4612 		"enum",
4613 		"typedef",
4614 		"template",
4615 		"this",
4616 		"packed",
4617 		"goto",
4618 		"inline",
4619 		"noinline",
4620 		"volatile",
4621 		"public",
4622 		"static",
4623 		"extern",
4624 		"external",
4625 		"interface",
4626 		"long",
4627 		"short",
4628 		"half",
4629 		"fixed",
4630 		"unsigned",
4631 		"superp",
4632 		"input",
4633 		"output",
4634 		"hvec2",
4635 		"hvec3",
4636 		"hvec4",
4637 		"fvec2",
4638 		"fvec3",
4639 		"fvec4",
4640 		"sampler3DRect",
4641 		"filter",
4642 		"image1D",
4643 		"image2D",
4644 		"image3D",
4645 		"imageCube",
4646 		"iimage1D",
4647 		"iimage2D",
4648 		"iimage3D",
4649 		"iimageCube",
4650 		"uimage1D",
4651 		"uimage2D",
4652 		"uimage3D",
4653 		"uimageCube",
4654 		"image1DArray",
4655 		"image2DArray",
4656 		"iimage1DArray",
4657 		"iimage2DArray",
4658 		"uimage1DArray",
4659 		"uimage2DArray",
4660 		"image1DShadow",
4661 		"image2DShadow",
4662 		"image1DArrayShadow",
4663 		"image2DArrayShadow",
4664 		"imageBuffer",
4665 		"iimageBuffer",
4666 		"uimageBuffer",
4667 		"sizeof",
4668 		"cast",
4669 		"namespace",
4670 		"using",
4671 		"row_major",
4672 	};
4673 	static const char* reserved_gl41[] = {
4674 		"common",
4675 		"partition",
4676 		"active",
4677 		"asm",
4678 		"class",
4679 		"union",
4680 		"enum",
4681 		"typedef",
4682 		"template",
4683 		"this",
4684 		"packed",
4685 		"goto",
4686 		"inline",
4687 		"noinline",
4688 		"volatile",
4689 		"public",
4690 		"static",
4691 		"extern",
4692 		"external",
4693 		"interface",
4694 		"long",
4695 		"short",
4696 		"half",
4697 		"fixed",
4698 		"unsigned",
4699 		"superp",
4700 		"input",
4701 		"output",
4702 		"hvec2",
4703 		"hvec3",
4704 		"hvec4",
4705 		"fvec2",
4706 		"fvec3",
4707 		"fvec4",
4708 		"sampler3DRect",
4709 		"filter",
4710 		"image1D",
4711 		"image2D",
4712 		"image3D",
4713 		"imageCube",
4714 		"iimage1D",
4715 		"iimage2D",
4716 		"iimage3D",
4717 		"iimageCube",
4718 		"uimage1D",
4719 		"uimage2D",
4720 		"uimage3D",
4721 		"uimageCube",
4722 		"image1DArray",
4723 		"image2DArray",
4724 		"iimage1DArray",
4725 		"iimage2DArray",
4726 		"uimage1DArray",
4727 		"uimage2DArray",
4728 		"image1DShadow",
4729 		"image2DShadow",
4730 		"image1DArrayShadow",
4731 		"image2DArrayShadow",
4732 		"imageBuffer",
4733 		"iimageBuffer",
4734 		"uimageBuffer",
4735 		"sizeof",
4736 		"cast",
4737 		"namespace",
4738 		"using",
4739 		"row_major",
4740 	};
4741 	static const char* reserved_gl42[] = {
4742 		"common",   "partition", "active",	"asm",   "class",		"union",	"enum",		"typedef",		 "template",
4743 		"this",		"packed",	"resource",  "goto",  "inline",	"noinline", "public",   "static",		 "extern",
4744 		"external", "interface", "long",	  "short", "half",		"fixed",	"unsigned", "superp",		 "input",
4745 		"output",   "hvec2",	 "hvec3",	 "hvec4", "fvec2",		"fvec3",	"fvec4",	"sampler3DRect", "filter",
4746 		"sizeof",   "cast",		 "namespace", "using", "row_major",
4747 	};
4748 	static const char* reserved_gl43[] = {
4749 		"common",   "partition", "active",	"asm",   "class",		"union",	"enum",		"typedef",		 "template",
4750 		"this",		"packed",	"resource",  "goto",  "inline",	"noinline", "public",   "static",		 "extern",
4751 		"external", "interface", "long",	  "short", "half",		"fixed",	"unsigned", "superp",		 "input",
4752 		"output",   "hvec2",	 "hvec3",	 "hvec4", "fvec2",		"fvec3",	"fvec4",	"sampler3DRect", "filter",
4753 		"sizeof",   "cast",		 "namespace", "using", "row_major",
4754 	};
4755 	static const char* reserved_gl44[] = {
4756 		"common",   "partition",	 "active",	"asm",	"class",  "union",	 "enum",   "typedef",
4757 		"template", "this",			 "resource",  "goto",   "inline", "noinline",  "public", "static",
4758 		"extern",   "external",		 "interface", "long",   "short",  "half",	  "fixed",  "unsigned",
4759 		"superp",   "input",		 "output",	"hvec2",  "hvec3",  "hvec4",	 "fvec2",  "fvec3",
4760 		"fvec4",	"sampler3DRect", "filter",	"sizeof", "cast",   "namespace", "using",
4761 	};
4762 	static const char* reserved_gl45[] = {
4763 		"common",   "partition",	 "active",	"asm",	"class",  "union",	 "enum",   "typedef",
4764 		"template", "this",			 "resource",  "goto",   "inline", "noinline",  "public", "static",
4765 		"extern",   "external",		 "interface", "long",   "short",  "half",	  "fixed",  "unsigned",
4766 		"superp",   "input",		 "output",	"hvec2",  "hvec3",  "hvec4",	 "fvec2",  "fvec3",
4767 		"fvec4",	"sampler3DRect", "filter",	"sizeof", "cast",   "namespace", "using",
4768 	};
4769 	static const char* reserved_gl46[] = {
4770 		"common",   "partition",	 "active",	"asm",	"class",  "union",	 "enum",   "typedef",
4771 		"template", "this",			 "resource",  "goto",   "inline", "noinline",  "public", "static",
4772 		"extern",   "external",		 "interface", "long",   "short",  "half",	  "fixed",  "unsigned",
4773 		"superp",   "input",		 "output",	"hvec2",  "hvec3",  "hvec4",	 "fvec2",  "fvec3",
4774 		"fvec4",	"sampler3DRect", "filter",	"sizeof", "cast",   "namespace", "using",
4775 	};
4776 
4777 	glu::ApiType apiType = context_type.getAPI();
4778 	if (apiType == glu::ApiType::core(3, 1))
4779 	{
4780 		context_keywords   = keywords_gl31;
4781 		context_reserved   = reserved_gl31;
4782 		context_n_keywords = static_cast<unsigned int>(sizeof(keywords_gl31) / sizeof(keywords_gl31[0]));
4783 		context_n_reserved = static_cast<unsigned int>(sizeof(reserved_gl31) / sizeof(reserved_gl31[0]));
4784 	}
4785 	else if (apiType == glu::ApiType::core(3, 2))
4786 	{
4787 		context_keywords   = keywords_gl32;
4788 		context_reserved   = reserved_gl32;
4789 		context_n_keywords = static_cast<unsigned int>(sizeof(keywords_gl32) / sizeof(keywords_gl32[0]));
4790 		context_n_reserved = static_cast<unsigned int>(sizeof(reserved_gl32) / sizeof(reserved_gl32[0]));
4791 	}
4792 	else if (apiType == glu::ApiType::core(3, 3))
4793 	{
4794 		context_keywords   = keywords_gl33;
4795 		context_reserved   = reserved_gl33;
4796 		context_n_keywords = static_cast<unsigned int>(sizeof(keywords_gl33) / sizeof(keywords_gl33[0]));
4797 		context_n_reserved = static_cast<unsigned int>(sizeof(reserved_gl33) / sizeof(reserved_gl33[0]));
4798 	}
4799 	else if (apiType == glu::ApiType::core(4, 0))
4800 	{
4801 		context_keywords   = keywords_gl40;
4802 		context_reserved   = reserved_gl40;
4803 		context_n_keywords = static_cast<unsigned int>(sizeof(keywords_gl40) / sizeof(keywords_gl40[0]));
4804 		context_n_reserved = static_cast<unsigned int>(sizeof(reserved_gl40) / sizeof(reserved_gl40[0]));
4805 	}
4806 	else if (apiType == glu::ApiType::core(4, 1))
4807 	{
4808 		context_keywords   = keywords_gl41;
4809 		context_reserved   = reserved_gl41;
4810 		context_n_keywords = static_cast<unsigned int>(sizeof(keywords_gl41) / sizeof(keywords_gl41[0]));
4811 		context_n_reserved = static_cast<unsigned int>(sizeof(reserved_gl41) / sizeof(reserved_gl41[0]));
4812 	}
4813 	else if (apiType == glu::ApiType::core(4, 2))
4814 	{
4815 		context_keywords   = keywords_gl42;
4816 		context_reserved   = reserved_gl42;
4817 		context_n_keywords = static_cast<unsigned int>(sizeof(keywords_gl42) / sizeof(keywords_gl42[0]));
4818 		context_n_reserved = static_cast<unsigned int>(sizeof(reserved_gl42) / sizeof(reserved_gl42[0]));
4819 	}
4820 	else if (apiType == glu::ApiType::core(4, 3))
4821 	{
4822 		context_keywords   = keywords_gl43;
4823 		context_reserved   = reserved_gl43;
4824 		context_n_keywords = static_cast<unsigned int>(sizeof(keywords_gl43) / sizeof(keywords_gl43[0]));
4825 		context_n_reserved = static_cast<unsigned int>(sizeof(reserved_gl43) / sizeof(reserved_gl43[0]));
4826 	}
4827 	else if (apiType == glu::ApiType::core(4, 4))
4828 	{
4829 		context_keywords   = keywords_gl44;
4830 		context_reserved   = reserved_gl44;
4831 		context_n_keywords = static_cast<unsigned int>(sizeof(keywords_gl44) / sizeof(keywords_gl44[0]));
4832 		context_n_reserved = static_cast<unsigned int>(sizeof(reserved_gl44) / sizeof(reserved_gl44[0]));
4833 	}
4834 	else if (apiType == glu::ApiType::core(4, 5))
4835 	{
4836 		context_keywords   = keywords_gl45;
4837 		context_reserved   = reserved_gl45;
4838 		context_n_keywords = static_cast<unsigned int>(sizeof(keywords_gl45) / sizeof(keywords_gl45[0]));
4839 		context_n_reserved = static_cast<unsigned int>(sizeof(reserved_gl45) / sizeof(reserved_gl45[0]));
4840 	}
4841 	else if (apiType == glu::ApiType::core(4, 6))
4842 	{
4843 		context_keywords   = keywords_gl46;
4844 		context_reserved   = reserved_gl46;
4845 		context_n_keywords = static_cast<unsigned int>(sizeof(keywords_gl46) / sizeof(keywords_gl46[0]));
4846 		context_n_reserved = static_cast<unsigned int>(sizeof(reserved_gl46) / sizeof(reserved_gl46[0]));
4847 	}
4848 	else
4849 	{
4850 		TCU_FAIL("Unsupported GL context version - please implement.");
4851 	}
4852 
4853 	for (unsigned int n_current_context_keyword = 0; n_current_context_keyword < context_n_keywords;
4854 		 ++n_current_context_keyword)
4855 	{
4856 		const char* current_context_keyword = context_keywords[n_current_context_keyword];
4857 
4858 		result.push_back(current_context_keyword);
4859 	} /* for (all context keywords) */
4860 
4861 	for (unsigned int n_current_context_reserved = 0; n_current_context_reserved < context_n_reserved;
4862 		 ++n_current_context_reserved)
4863 	{
4864 		const char* current_context_reserved = context_reserved[n_current_context_reserved];
4865 
4866 		result.push_back(current_context_reserved);
4867 	} /* for (all context reserved names) */
4868 
4869 	/* All done! */
4870 	return result;
4871 }
4872 
4873 /** Returns a shader body to use for the test. The body is formed, according to the user-specified
4874  *  requirements.
4875  *
4876  *  @param shader_type      Shader stage the shader body should be returned for.
4877  *  @param language_feature Language feature to test.
4878  *  @param invalid_name     Name to use for the language feature instance. The string should come
4879  *                          from the list of keywords or reserved names, specific to the currently
4880  *                          running rendering context's version.
4881  *
4882  *  @return Requested shader body.
4883  */
getShaderBody(_shader_type shader_type,_language_feature language_feature,const char * invalid_name) const4884 std::string ReservedNamesTest::getShaderBody(_shader_type shader_type, _language_feature language_feature,
4885 											 const char* invalid_name) const
4886 {
4887 	std::stringstream	  body_sstream;
4888 	const glu::ContextType context_type = m_context.getRenderContext().getType();
4889 
4890 	/* Preamble: shader language version */
4891 	body_sstream << "#version ";
4892 
4893 	glu::ApiType apiType = context_type.getAPI();
4894 	if (apiType == glu::ApiType::core(3, 1))
4895 		body_sstream << "140";
4896 	else if (apiType == glu::ApiType::core(3, 2))
4897 		body_sstream << "150";
4898 	else if (apiType == glu::ApiType::core(3, 3))
4899 		body_sstream << "330";
4900 	else if (apiType == glu::ApiType::core(4, 0))
4901 		body_sstream << "400";
4902 	else if (apiType == glu::ApiType::core(4, 1))
4903 		body_sstream << "410";
4904 	else if (apiType == glu::ApiType::core(4, 2))
4905 		body_sstream << "420";
4906 	else if (apiType == glu::ApiType::core(4, 3))
4907 		body_sstream << "430";
4908 	else if (apiType == glu::ApiType::core(4, 4))
4909 		body_sstream << "440";
4910 	else if (apiType == glu::ApiType::core(4, 5))
4911 		body_sstream << "450";
4912 	else if (apiType == glu::ApiType::core(4, 6))
4913 		body_sstream << "460";
4914 	else
4915 	{
4916 		TCU_FAIL("Unsupported GL context version - please implement");
4917 	}
4918 
4919 	body_sstream << "\n\n";
4920 
4921 	/* Preamble: layout qualifiers - required for CS, TC and TE shader stages */
4922 	if (shader_type == SHADER_TYPE_COMPUTE)
4923 	{
4924 		body_sstream << "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n";
4925 	}
4926 	else if (shader_type == SHADER_TYPE_TESS_CONTROL)
4927 	{
4928 		body_sstream << "layout(vertices = 3) out;\n";
4929 	}
4930 	else if (shader_type == SHADER_TYPE_TESS_EVALUATION)
4931 	{
4932 		body_sstream << "layout(triangles) in;\n";
4933 	}
4934 
4935 	body_sstream << "\n\n";
4936 
4937 	/* Language feature: insert incorrectly named atomic counter declaration if needed */
4938 	if (language_feature == LANGUAGE_FEATURE_ATOMIC_COUNTER)
4939 	{
4940 		body_sstream << "layout(binding = 0, offset = 0) uniform atomic_uint " << invalid_name << ";\n";
4941 	}
4942 
4943 	/* Language feature: insert incorrectly named attribute declaration if needed */
4944 	if (language_feature == LANGUAGE_FEATURE_ATTRIBUTE)
4945 	{
4946 		body_sstream << "attribute vec4 " << invalid_name << ";\n";
4947 	}
4948 
4949 	/* Language feature: insert incorrectly name constant declaration if needed */
4950 	if (language_feature == LANGUAGE_FEATURE_CONSTANT)
4951 	{
4952 		body_sstream << "const vec4 " << invalid_name << " = vec4(2.0, 3.0, 4.0, 5.0);\n";
4953 	}
4954 
4955 	/* Language feature: insert a function with incorrectly named argument if needed */
4956 	if (language_feature == LANGUAGE_FEATURE_FUNCTION_ARGUMENT_NAME)
4957 	{
4958 		body_sstream << "void test(in vec4 " << invalid_name << ")\n"
4959 																"{\n"
4960 																"}\n";
4961 	}
4962 
4963 	/* Language feature: insert incorrectly named function if needed */
4964 	if (language_feature == LANGUAGE_FEATURE_FUNCTION_NAME)
4965 	{
4966 		body_sstream << "void " << invalid_name << "(in vec4 test)\n"
4967 												   "{\n"
4968 												   "}\n";
4969 	}
4970 
4971 	/* Language feature: insert incorrectly named input variable if needed */
4972 	if (language_feature == LANGUAGE_FEATURE_INPUT)
4973 	{
4974 		body_sstream << "in vec4 " << invalid_name;
4975 
4976 		if (shader_type == SHADER_TYPE_GEOMETRY || shader_type == SHADER_TYPE_TESS_CONTROL ||
4977 			shader_type == SHADER_TYPE_TESS_EVALUATION)
4978 		{
4979 			body_sstream << "[]";
4980 		}
4981 
4982 		body_sstream << ";\n";
4983 	}
4984 
4985 	/* Language feature: insert declaration of an incorrectly named input block instance if needed */
4986 	if (language_feature == LANGUAGE_FEATURE_INPUT_BLOCK_INSTANCE_NAME)
4987 	{
4988 		body_sstream << "in testBlock\n"
4989 						"{\n"
4990 						"    vec4 test;\n"
4991 						"} "
4992 					 << invalid_name;
4993 
4994 		if (shader_type == SHADER_TYPE_GEOMETRY || shader_type == SHADER_TYPE_TESS_CONTROL ||
4995 			shader_type == SHADER_TYPE_TESS_EVALUATION)
4996 		{
4997 			body_sstream << "[]";
4998 		}
4999 
5000 		body_sstream << ";\n";
5001 	}
5002 
5003 	/* Language feature: insert declaration of an input block holding an incorrectly named member variable */
5004 	if (language_feature == LANGUAGE_FEATURE_INPUT_BLOCK_MEMBER_NAME)
5005 	{
5006 		body_sstream << "in testBlock\n"
5007 						"{\n"
5008 						"    vec4 "
5009 					 << invalid_name << ";\n"
5010 										"} testBlockInstance";
5011 
5012 		if (shader_type == SHADER_TYPE_GEOMETRY || shader_type == SHADER_TYPE_TESS_CONTROL ||
5013 			shader_type == SHADER_TYPE_TESS_EVALUATION)
5014 		{
5015 			body_sstream << "[]";
5016 		}
5017 
5018 		body_sstream << ";\n";
5019 	}
5020 
5021 	/* Language feature: insert declaration of an incorrectly named input block */
5022 	if (language_feature == LANGUAGE_FEATURE_INPUT_BLOCK_NAME)
5023 	{
5024 		body_sstream << "in " << invalid_name << "\n"
5025 												 "{\n"
5026 												 "    vec4 test;\n"
5027 												 "} testBlockInstance";
5028 
5029 		if (shader_type == SHADER_TYPE_GEOMETRY || shader_type == SHADER_TYPE_TESS_CONTROL ||
5030 			shader_type == SHADER_TYPE_TESS_EVALUATION)
5031 		{
5032 			body_sstream << "[]";
5033 		}
5034 
5035 		body_sstream << ";\n";
5036 	}
5037 
5038 	/* Language feature: insert incorrectly named output variable if needed */
5039 	if (language_feature == LANGUAGE_FEATURE_OUTPUT)
5040 	{
5041 		body_sstream << "out vec4 " << invalid_name;
5042 
5043 		if (shader_type == SHADER_TYPE_TESS_CONTROL)
5044 		{
5045 			body_sstream << "[]";
5046 		}
5047 
5048 		body_sstream << ";\n";
5049 	}
5050 
5051 	/* Language feature: insert declaration of an incorrectly named output block instance if needed */
5052 	if (language_feature == LANGUAGE_FEATURE_OUTPUT_BLOCK_INSTANCE_NAME)
5053 	{
5054 		body_sstream << "out testBlock\n"
5055 						"{\n"
5056 						"    vec4 test;\n"
5057 						"} "
5058 					 << invalid_name;
5059 
5060 		if (shader_type == SHADER_TYPE_TESS_CONTROL)
5061 		{
5062 			body_sstream << "[]";
5063 		}
5064 
5065 		body_sstream << ";\n";
5066 	}
5067 
5068 	/* Language feature: insert declaration of an output block holding an incorrectly named member variable */
5069 	if (language_feature == LANGUAGE_FEATURE_OUTPUT_BLOCK_MEMBER_NAME)
5070 	{
5071 		body_sstream << "out testBlock\n"
5072 						"{\n"
5073 						"    vec4 "
5074 					 << invalid_name << ";\n"
5075 										"} testBlockInstance";
5076 
5077 		if (shader_type == SHADER_TYPE_TESS_CONTROL)
5078 		{
5079 			body_sstream << "[]";
5080 		}
5081 
5082 		body_sstream << ";\n";
5083 	}
5084 
5085 	/* Language feature: insert declaration of an incorrectly named output block */
5086 	if (language_feature == LANGUAGE_FEATURE_OUTPUT_BLOCK_NAME)
5087 	{
5088 		body_sstream << "out " << invalid_name << "\n"
5089 												  "{\n"
5090 												  "    vec4 test;\n"
5091 												  "} testBlockInstance";
5092 
5093 		if (shader_type == SHADER_TYPE_TESS_CONTROL)
5094 		{
5095 			body_sstream << "[]";
5096 		}
5097 
5098 		body_sstream << ";\n";
5099 	}
5100 
5101 	/* Language feature: insert declaration of an incorrectly named shader storage block instance if needed */
5102 	if (language_feature == LANGUAGE_FEATURE_SHADER_STORAGE_BLOCK_INSTANCE_NAME)
5103 	{
5104 		body_sstream << "buffer testBlock\n"
5105 						"{\n"
5106 						"    vec4 test;\n"
5107 						"} "
5108 					 << invalid_name << ";\n";
5109 	}
5110 
5111 	/* Language feature: insert declaration of a shader storage block holding an incorrectly named member variable */
5112 	if (language_feature == LANGUAGE_FEATURE_SHADER_STORAGE_BLOCK_MEMBER_NAME)
5113 	{
5114 		body_sstream << "buffer testBlock\n"
5115 						"{\n"
5116 						"    vec4 "
5117 					 << invalid_name << ";\n"
5118 										"};\n";
5119 	}
5120 
5121 	/* Language feature: insert declaration of an incorrectly named shader storage block */
5122 	if (language_feature == LANGUAGE_FEATURE_SHADER_STORAGE_BLOCK_NAME)
5123 	{
5124 		body_sstream << "buffer " << invalid_name << "\n"
5125 													 "{\n"
5126 													 "    vec4 test;\n"
5127 													 "};\n";
5128 	}
5129 
5130 	/* Language feature: insert declaration of a subroutine function with invalid name */
5131 	if (language_feature == LANGUAGE_FEATURE_SUBROUTINE_FUNCTION_NAME)
5132 	{
5133 		body_sstream << "subroutine void exampleSubroutine(inout vec4 " << invalid_name
5134 					 << ");\n"
5135 						"\n"
5136 						"subroutine (exampleSubroutine) void invert(inout vec4 "
5137 					 << invalid_name << ")\n"
5138 										"{\n"
5139 										"    "
5140 					 << invalid_name << " += vec4(0.0, 1.0, 2.0, 3.0);\n"
5141 										"}\n"
5142 										"\n"
5143 										"subroutine uniform exampleSubroutine testSubroutine;\n";
5144 	}
5145 
5146 	/* Language feature: insert declaration of a subroutine of incorrectly named type */
5147 	if (language_feature == LANGUAGE_FEATURE_SUBROUTINE_TYPE)
5148 	{
5149 		body_sstream << "subroutine void " << invalid_name << "(inout vec4 arg);\n"
5150 															  "\n"
5151 															  "subroutine ("
5152 					 << invalid_name << ") void invert(inout vec4 arg)\n"
5153 										"{\n"
5154 										"    arg += vec4(0.0, 1.0, 2.0, 3.0);\n"
5155 										"}\n"
5156 										"\n"
5157 										"subroutine uniform "
5158 					 << invalid_name << " testSubroutine;\n";
5159 	}
5160 
5161 	/* Language feature: insert declaration of a subroutine, followed by a declaration of
5162 	 *                   an incorrectly named subroutine uniform.
5163 	 */
5164 	if (language_feature == LANGUAGE_FEATURE_SUBROUTINE_UNIFORM)
5165 	{
5166 		body_sstream << "subroutine void exampleSubroutine(inout vec4 arg);\n"
5167 						"\n"
5168 						"subroutine (exampleSubroutine) void invert(inout vec4 arg)\n"
5169 						"{\n"
5170 						"    arg += vec4(0.0, 1.0, 2.0, 3.0);\n"
5171 						"}\n"
5172 						"\n"
5173 						"subroutine uniform exampleSubroutine "
5174 					 << invalid_name << ";\n";
5175 	}
5176 
5177 	/* Language feature: insert declaration of an incorrectly named uniform. */
5178 	if (language_feature == LANGUAGE_FEATURE_UNIFORM)
5179 	{
5180 		body_sstream << "uniform sampler2D " << invalid_name << ";\n";
5181 	}
5182 
5183 	/* Language feature: insert declaration of an incorrectly named uniform block instance if needed */
5184 	if (language_feature == LANGUAGE_FEATURE_UNIFORM_BLOCK_INSTANCE_NAME)
5185 	{
5186 		body_sstream << "uniform testBlock\n"
5187 						"{\n"
5188 						"    vec4 test;\n"
5189 						"} "
5190 					 << invalid_name << ";\n";
5191 	}
5192 
5193 	/* Language feature: insert declaration of an uniform block holding an incorrectly named member variable */
5194 	if (language_feature == LANGUAGE_FEATURE_UNIFORM_BLOCK_MEMBER_NAME)
5195 	{
5196 		body_sstream << "uniform testBlock\n"
5197 						"{\n"
5198 						"    vec4 "
5199 					 << invalid_name << ";\n"
5200 										"};\n";
5201 	}
5202 
5203 	/* Language feature: insert declaration of an incorrectly named uniform block */
5204 	if (language_feature == LANGUAGE_FEATURE_UNIFORM_BLOCK_NAME)
5205 	{
5206 		body_sstream << "uniform " << invalid_name << "\n"
5207 													  "{\n"
5208 													  "    vec4 test;\n"
5209 													  "};\n";
5210 	}
5211 
5212 	/* Language feature: insert declaration of an incorrectly named varying */
5213 	if (language_feature == LANGUAGE_FEATURE_VARYING)
5214 	{
5215 		body_sstream << "varying vec4 " << invalid_name << ";\n";
5216 	}
5217 
5218 	/* Start implementation of the main entry-point. */
5219 	body_sstream << "void main()\n"
5220 					"{\n";
5221 
5222 	/* Language feature: insert declaration of an incorrectly named shared variable. */
5223 	if (language_feature == LANGUAGE_FEATURE_SHARED_VARIABLE)
5224 	{
5225 		body_sstream << "shared vec4 " << invalid_name << ";\n";
5226 	}
5227 
5228 	/* Language feature: insert declaration of a structure, whose instance name is incorrect */
5229 	if (language_feature == LANGUAGE_FEATURE_STRUCTURE_INSTANCE_NAME)
5230 	{
5231 		body_sstream << "struct\n"
5232 						"{\n"
5233 						"    vec4 test;\n"
5234 						"} "
5235 					 << invalid_name << ";\n";
5236 	}
5237 
5238 	/* Language feature: insert declaration of a structure with one of its member variables being incorrectly named. */
5239 	if (language_feature == LANGUAGE_FEATURE_STRUCTURE_MEMBER)
5240 	{
5241 		body_sstream << "struct\n"
5242 						"{\n"
5243 						"    vec4 "
5244 					 << invalid_name << ";\n"
5245 										"} testInstance;\n";
5246 	}
5247 
5248 	/* Language feature: insert declaration of a structure whose name is incorrect */
5249 	if (language_feature == LANGUAGE_FEATURE_STRUCTURE_NAME)
5250 	{
5251 		body_sstream << "struct " << invalid_name << "{\n"
5252 													 "    vec4 test;\n"
5253 					 << "};\n";
5254 	}
5255 
5256 	/* Language feature: insert declaration of a variable with incorrect name. */
5257 	if (language_feature == LANGUAGE_FEATURE_VARIABLE)
5258 	{
5259 		body_sstream << "vec4 " << invalid_name << ";\n";
5260 	}
5261 
5262 	/* Close the main entry-point implementation */
5263 	body_sstream << "}\n";
5264 
5265 	return body_sstream.str();
5266 }
5267 
5268 /** Retrieves a literal corresponding to the user-specified shader type value.
5269  *
5270  *  @param shader_type Enum to return the string for.
5271  *
5272  *  @return As specified.
5273  */
getShaderTypeName(_shader_type shader_type) const5274 std::string ReservedNamesTest::getShaderTypeName(_shader_type shader_type) const
5275 {
5276 	std::string result = "[?!]";
5277 
5278 	switch (shader_type)
5279 	{
5280 	case SHADER_TYPE_COMPUTE:
5281 		result = "compute shader";
5282 		break;
5283 	case SHADER_TYPE_FRAGMENT:
5284 		result = "fragment shader";
5285 		break;
5286 	case SHADER_TYPE_GEOMETRY:
5287 		result = "geometry shader";
5288 		break;
5289 	case SHADER_TYPE_TESS_CONTROL:
5290 		result = "tessellation control shader";
5291 		break;
5292 	case SHADER_TYPE_TESS_EVALUATION:
5293 		result = "tessellation evaluation shader";
5294 		break;
5295 	case SHADER_TYPE_VERTEX:
5296 		result = "vertex shader";
5297 		break;
5298 	default:
5299 		result = "unknown";
5300 		break;
5301 	} /* switch (shader_type) */
5302 
5303 	return result;
5304 }
5305 
5306 /** Returns a vector of _language_feature enums, telling which language features are supported, given running context's
5307  *  version and shader type, in which the features are planned to be used.
5308  *
5309  *  @param shader_type Shader stage the language features will be used in.
5310  *
5311  *  @return As specified.
5312  **/
getSupportedLanguageFeatures(_shader_type shader_type) const5313 std::vector<ReservedNamesTest::_language_feature> ReservedNamesTest::getSupportedLanguageFeatures(
5314 	_shader_type shader_type) const
5315 {
5316 	const glu::ContextType		   context_type = m_context.getRenderContext().getType();
5317 	std::vector<_language_feature> result;
5318 
5319 	/* Atomic counters are available, starting with GL 4.2. Availability for each shader stage
5320 	 * depends on the reported GL constant values, apart from CS & FS, for which AC support is guaranteed.
5321 	 */
5322 	if (glu::contextSupports(context_type, glu::ApiType::core(4, 2)))
5323 	{
5324 		if (shader_type == SHADER_TYPE_COMPUTE || shader_type == SHADER_TYPE_FRAGMENT ||
5325 			(shader_type == SHADER_TYPE_GEOMETRY && m_max_gs_acs > 0) ||
5326 			(shader_type == SHADER_TYPE_TESS_CONTROL && m_max_tc_acs > 0) ||
5327 			(shader_type == SHADER_TYPE_TESS_EVALUATION && m_max_te_acs > 0) ||
5328 			(shader_type == SHADER_TYPE_VERTEX && m_max_vs_acs))
5329 		{
5330 			result.push_back(LANGUAGE_FEATURE_ATOMIC_COUNTER);
5331 		}
5332 	} /* if (context_type >= glu::CONTEXTTYPE_GL43_CORE) */
5333 
5334 	/* Attributes are only supported until GL 4.1, for VS shader stage only. */
5335 	if (shader_type == SHADER_TYPE_VERTEX && !glu::contextSupports(context_type, glu::ApiType::core(4, 2)))
5336 	{
5337 		result.push_back(LANGUAGE_FEATURE_ATTRIBUTE);
5338 	}
5339 
5340 	/* Constants are always supported */
5341 	result.push_back(LANGUAGE_FEATURE_CONSTANT);
5342 
5343 	/* Functions are supported in all GL SL versions for all shader types. */
5344 	result.push_back(LANGUAGE_FEATURE_FUNCTION_ARGUMENT_NAME);
5345 	result.push_back(LANGUAGE_FEATURE_FUNCTION_NAME);
5346 
5347 	/* Inputs are supported in all GL SL versions for FS, GS, TC, TE and VS stages */
5348 	if (shader_type == SHADER_TYPE_FRAGMENT || shader_type == SHADER_TYPE_GEOMETRY ||
5349 		shader_type == SHADER_TYPE_TESS_CONTROL || shader_type == SHADER_TYPE_TESS_EVALUATION ||
5350 		shader_type == SHADER_TYPE_VERTEX)
5351 	{
5352 		result.push_back(LANGUAGE_FEATURE_INPUT);
5353 	}
5354 
5355 	/* Input blocks are available, starting with GL 3.2 for FS, GS, TC and TE stages. */
5356 	if ((shader_type == SHADER_TYPE_FRAGMENT || shader_type == SHADER_TYPE_GEOMETRY ||
5357 		 shader_type == SHADER_TYPE_TESS_CONTROL || shader_type == SHADER_TYPE_TESS_EVALUATION ||
5358 		 shader_type == SHADER_TYPE_VERTEX) &&
5359 		glu::contextSupports(context_type, glu::ApiType::core(3, 2)))
5360 	{
5361 		result.push_back(LANGUAGE_FEATURE_INPUT_BLOCK_INSTANCE_NAME);
5362 		result.push_back(LANGUAGE_FEATURE_INPUT_BLOCK_MEMBER_NAME);
5363 		result.push_back(LANGUAGE_FEATURE_INPUT_BLOCK_NAME);
5364 	}
5365 
5366 	/* Outputs are supported in all GL SL versions for all shader stages expect CS */
5367 	if (shader_type != SHADER_TYPE_COMPUTE)
5368 	{
5369 		result.push_back(LANGUAGE_FEATURE_OUTPUT);
5370 	}
5371 
5372 	/* Output blocks are available, starting with GL 3.2 for GS, TC, TE and VS stages. */
5373 	if ((shader_type == SHADER_TYPE_GEOMETRY || shader_type == SHADER_TYPE_TESS_CONTROL ||
5374 		 shader_type == SHADER_TYPE_TESS_EVALUATION || shader_type == SHADER_TYPE_VERTEX) &&
5375 		glu::contextSupports(context_type, glu::ApiType::core(3, 2)))
5376 	{
5377 		result.push_back(LANGUAGE_FEATURE_OUTPUT_BLOCK_INSTANCE_NAME);
5378 		result.push_back(LANGUAGE_FEATURE_OUTPUT_BLOCK_MEMBER_NAME);
5379 		result.push_back(LANGUAGE_FEATURE_OUTPUT_BLOCK_NAME);
5380 	}
5381 
5382 	/* Shader storage blocks are available, starting with GL 4.3. Availability for each shader stage
5383 	 * depends on the reported GL constant values, apart from CS, for which SSBO support is guaranteed.
5384 	 */
5385 	if (glu::contextSupports(context_type, glu::ApiType::core(4, 3)))
5386 	{
5387 		if (shader_type == SHADER_TYPE_COMPUTE || (shader_type == SHADER_TYPE_FRAGMENT && m_max_fs_ssbos > 0) ||
5388 			(shader_type == SHADER_TYPE_GEOMETRY && m_max_gs_ssbos > 0) ||
5389 			(shader_type == SHADER_TYPE_TESS_CONTROL && m_max_tc_ssbos > 0) ||
5390 			(shader_type == SHADER_TYPE_TESS_EVALUATION && m_max_te_ssbos > 0) ||
5391 			(shader_type == SHADER_TYPE_VERTEX && m_max_vs_ssbos))
5392 		{
5393 			result.push_back(LANGUAGE_FEATURE_SHADER_STORAGE_BLOCK_INSTANCE_NAME);
5394 			result.push_back(LANGUAGE_FEATURE_SHADER_STORAGE_BLOCK_MEMBER_NAME);
5395 			result.push_back(LANGUAGE_FEATURE_SHADER_STORAGE_BLOCK_NAME);
5396 		}
5397 	} /* if (context_type >= glu::CONTEXTTYPE_GL43_CORE) */
5398 
5399 	/* Shared variables are only supported for compute shaders */
5400 	if (shader_type == SHADER_TYPE_COMPUTE)
5401 	{
5402 		result.push_back(LANGUAGE_FEATURE_SHARED_VARIABLE);
5403 	}
5404 
5405 	/* Structures are available everywhere, and so are structures. */
5406 	result.push_back(LANGUAGE_FEATURE_STRUCTURE_INSTANCE_NAME);
5407 	result.push_back(LANGUAGE_FEATURE_STRUCTURE_MEMBER);
5408 	result.push_back(LANGUAGE_FEATURE_STRUCTURE_NAME);
5409 
5410 	/* Subroutines are available, starting with GL 4.0, for all shader stages except CS */
5411 	if (glu::contextSupports(context_type, glu::ApiType::core(4, 0)))
5412 	{
5413 		if (shader_type != SHADER_TYPE_COMPUTE)
5414 		{
5415 			result.push_back(LANGUAGE_FEATURE_SUBROUTINE_FUNCTION_NAME);
5416 			result.push_back(LANGUAGE_FEATURE_SUBROUTINE_TYPE);
5417 			result.push_back(LANGUAGE_FEATURE_SUBROUTINE_UNIFORM);
5418 		}
5419 	} /* if (context_type >= glu::CONTEXTTYPE_GL40_CORE) */
5420 
5421 	/* Uniform blocks and uniforms are available everywhere, for all shader stages except CS */
5422 	if (shader_type != SHADER_TYPE_COMPUTE)
5423 	{
5424 		result.push_back(LANGUAGE_FEATURE_UNIFORM_BLOCK_INSTANCE_NAME);
5425 		result.push_back(LANGUAGE_FEATURE_UNIFORM_BLOCK_MEMBER_NAME);
5426 		result.push_back(LANGUAGE_FEATURE_UNIFORM_BLOCK_NAME);
5427 
5428 		result.push_back(LANGUAGE_FEATURE_UNIFORM);
5429 	}
5430 
5431 	/* Variables are available, well, everywhere. */
5432 	result.push_back(LANGUAGE_FEATURE_VARIABLE);
5433 
5434 	/* Varyings are supported until GL 4.2 for FS and VS shader stages. Starting with GL 4.3,
5435 	 * they are no longer legal. */
5436 	if ((shader_type == SHADER_TYPE_FRAGMENT || shader_type == SHADER_TYPE_VERTEX) &&
5437 		!glu::contextSupports(context_type, glu::ApiType::core(4, 3)))
5438 	{
5439 		result.push_back(LANGUAGE_FEATURE_VARYING);
5440 	}
5441 
5442 	return result;
5443 }
5444 
5445 /** Returns a vector of _shader_type enums, telling which shader stages are supported
5446  *  under running rendering context. For simplicity, the function ignores any extensions
5447  *  which extend the core functionality
5448  *
5449  * @return As specified.
5450  */
getSupportedShaderTypes() const5451 std::vector<ReservedNamesTest::_shader_type> ReservedNamesTest::getSupportedShaderTypes() const
5452 {
5453 	const glu::ContextType	context_type = m_context.getRenderContext().getType();
5454 	std::vector<_shader_type> result;
5455 
5456 	/* CS: Available, starting with GL 4.3 */
5457 	if (glu::contextSupports(context_type, glu::ApiType::core(4, 3)))
5458 	{
5459 		result.push_back(SHADER_TYPE_COMPUTE);
5460 	}
5461 
5462 	/* FS: Always supported */
5463 	result.push_back(SHADER_TYPE_FRAGMENT);
5464 
5465 	/* GS: Available, starting with GL 3.2 */
5466 	if (glu::contextSupports(context_type, glu::ApiType::core(3, 2)))
5467 	{
5468 		result.push_back(SHADER_TYPE_GEOMETRY);
5469 	}
5470 
5471 	/* TC: Available, starting with GL 4.0 */
5472 	/* TE: Available, starting with GL 4.0 */
5473 	if (glu::contextSupports(context_type, glu::ApiType::core(4, 0)))
5474 	{
5475 		result.push_back(SHADER_TYPE_TESS_CONTROL);
5476 		result.push_back(SHADER_TYPE_TESS_EVALUATION);
5477 	}
5478 
5479 	/* VS: Always supported */
5480 	result.push_back(SHADER_TYPE_VERTEX);
5481 
5482 	return result;
5483 }
5484 
isStructAllowed(_shader_type shader_type,_language_feature language_feature) const5485 bool ReservedNamesTest::isStructAllowed(_shader_type shader_type, _language_feature language_feature) const
5486 {
5487 	bool structAllowed = false;
5488 
5489 	if (language_feature == LANGUAGE_FEATURE_UNIFORM || language_feature == LANGUAGE_FEATURE_UNIFORM_BLOCK_NAME)
5490 	{
5491 		return true;
5492 	}
5493 
5494 	switch (shader_type)
5495 	{
5496 	case SHADER_TYPE_FRAGMENT:
5497 	{
5498 		if (language_feature == LANGUAGE_FEATURE_INPUT_BLOCK_NAME)
5499 		{
5500 			structAllowed = true;
5501 		}
5502 	}
5503 	break;
5504 	case SHADER_TYPE_GEOMETRY:
5505 	case SHADER_TYPE_TESS_CONTROL:
5506 	case SHADER_TYPE_TESS_EVALUATION:
5507 	{
5508 		if (language_feature == LANGUAGE_FEATURE_OUTPUT_BLOCK_NAME)
5509 		{
5510 			structAllowed = true;
5511 		}
5512 		else if (language_feature == LANGUAGE_FEATURE_INPUT_BLOCK_NAME)
5513 		{
5514 			structAllowed = true;
5515 		}
5516 	}
5517 	break;
5518 	case SHADER_TYPE_VERTEX:
5519 	{
5520 		if (language_feature == LANGUAGE_FEATURE_OUTPUT_BLOCK_NAME)
5521 		{
5522 			structAllowed = true;
5523 		}
5524 	}
5525 	break;
5526 	case SHADER_TYPE_COMPUTE:
5527 	default:
5528 		break;
5529 	}
5530 
5531 	return structAllowed;
5532 }
5533 
5534 /** Dummy init function */
init()5535 void ReservedNamesTest::init()
5536 {
5537 	/* Left blank on purpose */
5538 }
5539 
5540 /** Executes test iteration.
5541  *
5542  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
5543  */
iterate()5544 tcu::TestNode::IterateResult ReservedNamesTest::iterate()
5545 {
5546 	glw::GLint					   compile_status = GL_TRUE;
5547 	glu::ContextType			   context_type   = m_context.getRenderContext().getType();
5548 	const glw::Functions&		   gl			  = m_context.getRenderContext().getFunctions();
5549 	std::vector<_language_feature> language_features;
5550 	std::vector<std::string>	   reserved_names;
5551 	bool						   result = true;
5552 	std::vector<_shader_type>	  shader_types;
5553 
5554 	/* Retrieve important GL constant values */
5555 	if (glu::contextSupports(context_type, glu::ApiType::core(4, 2)))
5556 	{
5557 		gl.getIntegerv(GL_MAX_GEOMETRY_ATOMIC_COUNTERS, &m_max_gs_acs);
5558 		gl.getIntegerv(GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS, &m_max_tc_acs);
5559 		gl.getIntegerv(GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS, &m_max_te_acs);
5560 		gl.getIntegerv(GL_MAX_VERTEX_ATOMIC_COUNTERS, &m_max_vs_acs);
5561 	}
5562 
5563 	if (glu::contextSupports(context_type, glu::ApiType::core(4, 3)))
5564 	{
5565 		gl.getIntegerv(GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, &m_max_fs_ssbos);
5566 		gl.getIntegerv(GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS, &m_max_gs_ssbos);
5567 		gl.getIntegerv(GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS, &m_max_tc_ssbos);
5568 		gl.getIntegerv(GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS, &m_max_te_ssbos);
5569 		gl.getIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &m_max_vs_ssbos);
5570 
5571 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() call(s) failed.");
5572 	}
5573 
5574 	/* Create the shader objects */
5575 	if (glu::contextSupports(context_type, glu::ApiType::core(4, 0)))
5576 	{
5577 		m_so_ids[SHADER_TYPE_TESS_CONTROL]	= gl.createShader(GL_TESS_CONTROL_SHADER);
5578 		m_so_ids[SHADER_TYPE_TESS_EVALUATION] = gl.createShader(GL_TESS_EVALUATION_SHADER);
5579 	}
5580 
5581 	if (glu::contextSupports(context_type, glu::ApiType::core(4, 3)))
5582 	{
5583 		m_so_ids[SHADER_TYPE_COMPUTE] = gl.createShader(GL_COMPUTE_SHADER);
5584 	}
5585 
5586 	m_so_ids[SHADER_TYPE_FRAGMENT] = gl.createShader(GL_FRAGMENT_SHADER);
5587 	m_so_ids[SHADER_TYPE_GEOMETRY] = gl.createShader(GL_GEOMETRY_SHADER);
5588 	m_so_ids[SHADER_TYPE_VERTEX]   = gl.createShader(GL_VERTEX_SHADER);
5589 
5590 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed.");
5591 
5592 	/* Retrieve context version-specific data */
5593 	reserved_names = getReservedNames();
5594 	shader_types   = getSupportedShaderTypes();
5595 
5596 	/* Iterate over all supported shader stages.. */
5597 	for (std::vector<_shader_type>::const_iterator shader_type_it = shader_types.begin();
5598 		 shader_type_it != shader_types.end(); ++shader_type_it)
5599 	{
5600 		_shader_type current_shader_type = *shader_type_it;
5601 
5602 		if (m_so_ids[current_shader_type] == 0)
5603 		{
5604 			/* Skip stages not supported by the currently running context version. */
5605 			continue;
5606 		}
5607 
5608 		language_features = getSupportedLanguageFeatures(current_shader_type);
5609 
5610 		/* ..and all language features we can test for the running context */
5611 		for (std::vector<_language_feature>::const_iterator language_feature_it = language_features.begin();
5612 			 language_feature_it != language_features.end(); ++language_feature_it)
5613 		{
5614 			_language_feature current_language_feature = *language_feature_it;
5615 
5616 			bool structAllowed = isStructAllowed(current_shader_type, current_language_feature);
5617 
5618 			/* Finally, all the reserved names we need to test - loop over them at this point */
5619 			for (std::vector<std::string>::const_iterator reserved_name_it = reserved_names.begin();
5620 				 reserved_name_it != reserved_names.end(); ++reserved_name_it)
5621 			{
5622 				std::string current_invalid_name = *reserved_name_it;
5623 				std::string so_body_string;
5624 				const char* so_body_string_raw = NULL;
5625 
5626 				// There are certain shader types that allow struct for in/out declarations
5627 				if (structAllowed && current_invalid_name.compare("struct") == 0)
5628 				{
5629 					continue;
5630 				}
5631 
5632 				/* Form the shader body */
5633 				so_body_string =
5634 					getShaderBody(current_shader_type, current_language_feature, current_invalid_name.c_str());
5635 				so_body_string_raw = so_body_string.c_str();
5636 
5637 				/* Try to compile the shader */
5638 				gl.shaderSource(m_so_ids[current_shader_type], 1, /* count */
5639 								&so_body_string_raw, NULL);		  /* length */
5640 				GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
5641 
5642 				gl.compileShader(m_so_ids[current_shader_type]);
5643 				GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed.");
5644 
5645 				gl.getShaderiv(m_so_ids[current_shader_type], GL_COMPILE_STATUS, &compile_status);
5646 				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");
5647 
5648 /* Left for the debugging purposes for those in need .. */
5649 #if 0
5650 				char temp[4096];
5651 
5652 				gl.getShaderInfoLog(m_so_ids[current_shader_type],
5653 					4096,
5654 					NULL,
5655 					temp);
5656 
5657 				m_testCtx.getLog() << tcu::TestLog::Message
5658 					<< "\n"
5659 					"-----------------------------\n"
5660 					"Shader:\n"
5661 					">>\n"
5662 					<< so_body_string_raw
5663 					<< "\n<<\n"
5664 					"\n"
5665 					"Info log:\n"
5666 					">>\n"
5667 					<< temp
5668 					<< "\n<<\n\n"
5669 					<< tcu::TestLog::EndMessage;
5670 #endif
5671 
5672 				if (compile_status != GL_FALSE)
5673 				{
5674 					m_testCtx.getLog() << tcu::TestLog::Message << "A "
5675 									   << getLanguageFeatureName(current_language_feature) << " named ["
5676 									   << current_invalid_name << "]"
5677 									   << ", defined in " << getShaderTypeName(current_shader_type)
5678 									   << ", was accepted by the compiler, "
5679 										  "which is prohibited by the spec. Offending source code:\n"
5680 										  ">>\n"
5681 									   << so_body_string_raw << "\n<<\n\n"
5682 									   << tcu::TestLog::EndMessage;
5683 
5684 					result = false;
5685 				}
5686 
5687 			} /* for (all reserved names for the current context) */
5688 		}	 /* for (all language features supported by the context) */
5689 	}		  /* for (all shader types supported by the context) */
5690 
5691 	m_testCtx.setTestResult(result ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, result ? "Pass" : "Fail");
5692 
5693 	return STOP;
5694 }
5695 
5696 /** Constructor.
5697  *
5698  *  @param context     Rendering context
5699  *  @param name        Test name
5700  *  @param description Test description
5701  */
SparseBuffersWithCopyOpsTest(deqp::Context & context)5702 SparseBuffersWithCopyOpsTest::SparseBuffersWithCopyOpsTest(deqp::Context& context)
5703 	: TestCase(context, "CommonBug_SparseBuffersWithCopyOps",
5704 			   "Verifies sparse buffer functionality works correctly when CPU->GPU and GPU->GPU"
5705 			   " memory transfers are involved.")
5706 	, m_bo_id(0)
5707 	, m_bo_read_id(0)
5708 	, m_clear_buffer(DE_NULL)
5709 	, m_page_size(0)
5710 	, m_result_data_storage_size(0)
5711 	, m_n_iterations_to_run(16)
5712 	, m_n_pages_to_test(16)
5713 	, m_virtual_bo_size(512 /* MB */ * 1024768)
5714 {
5715 	for (unsigned int n = 0; n < sizeof(m_reference_data) / sizeof(m_reference_data[0]); ++n)
5716 	{
5717 		m_reference_data[n] = static_cast<unsigned char>(n);
5718 	}
5719 }
5720 
5721 /** Deinitializes all GL objects created for the purpose of running the test,
5722  *  as well as any client-side buffers allocated at initialization time
5723  */
deinit()5724 void SparseBuffersWithCopyOpsTest::deinit()
5725 {
5726 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5727 
5728 	if (m_bo_id != 0)
5729 	{
5730 		gl.deleteBuffers(1, &m_bo_id);
5731 
5732 		m_bo_id = 0;
5733 	}
5734 
5735 	if (m_bo_read_id != 0)
5736 	{
5737 		gl.deleteBuffers(1, &m_bo_read_id);
5738 
5739 		m_bo_read_id = 0;
5740 	}
5741 
5742 	if (m_clear_buffer != DE_NULL)
5743 	{
5744 		delete[] m_clear_buffer;
5745 
5746 		m_clear_buffer = DE_NULL;
5747 	}
5748 }
5749 
5750 /** Dummy init function */
init()5751 void SparseBuffersWithCopyOpsTest::init()
5752 {
5753 	/* Nothing to do here */
5754 }
5755 
5756 /** Initializes all buffers and GL objects required to run the test. */
initTest()5757 bool SparseBuffersWithCopyOpsTest::initTest()
5758 {
5759 	const glw::Functions& gl	 = m_context.getRenderContext().getFunctions();
5760 	bool				  result = true;
5761 
5762 	/* Retrieve the platform-specific page size */
5763 	gl.getIntegerv(GL_SPARSE_BUFFER_PAGE_SIZE_ARB, &m_page_size);
5764 
5765 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_SPARSE_BUFFER_PAGE_SIZE_ARB query");
5766 
5767 	/* Retrieve the func ptr */
5768 	if (gl.bufferPageCommitmentARB == NULL)
5769 	{
5770 		m_testCtx.getLog() << tcu::TestLog::Message
5771 						   << "Could not retrieve function pointer for the glBufferPageCommitmentARB() entry-point."
5772 						   << tcu::TestLog::EndMessage;
5773 
5774 		result = false;
5775 		goto end;
5776 	}
5777 
5778 	/* Set up the test sparse buffer object */
5779 	gl.genBuffers(1, &m_bo_id);
5780 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed.");
5781 
5782 	gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_id);
5783 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed.");
5784 
5785 	gl.bufferStorage(GL_ARRAY_BUFFER, m_virtual_bo_size, DE_NULL, /* data */
5786 					 GL_DYNAMIC_STORAGE_BIT | GL_SPARSE_STORAGE_BIT_ARB);
5787 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferStorage() call failed.");
5788 
5789 	/* Set up the buffer object that will be used to read the result data */
5790 	m_result_data_storage_size = static_cast<unsigned int>(
5791 		(m_page_size * m_n_pages_to_test / sizeof(m_reference_data)) * sizeof(m_reference_data));
5792 	m_clear_buffer = new unsigned char[m_result_data_storage_size];
5793 
5794 	memset(m_clear_buffer, 0, m_result_data_storage_size);
5795 
5796 	gl.genBuffers(1, &m_bo_read_id);
5797 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed.");
5798 
5799 	gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_bo_read_id);
5800 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed.");
5801 
5802 	gl.bufferStorage(GL_ELEMENT_ARRAY_BUFFER, m_result_data_storage_size, NULL, /* data */
5803 					 GL_DYNAMIC_STORAGE_BIT | GL_MAP_READ_BIT);
5804 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferStorage() call failed.");
5805 
5806 end:
5807 	return result;
5808 }
5809 
5810 /** Executes test iteration.
5811  *
5812  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
5813  */
iterate()5814 tcu::TestNode::IterateResult SparseBuffersWithCopyOpsTest::iterate()
5815 {
5816 	bool result = true;
5817 
5818 	/* Execute the test */
5819 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5820 
5821 	/* Only execute if we're dealing with an OpenGL implementation which supports both:
5822 	 *
5823 	 * 1. GL_ARB_sparse_buffer extension
5824 	 * 2. GL_ARB_buffer_storage extension
5825 	 */
5826 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_buffer") ||
5827 		!m_context.getContextInfo().isExtensionSupported("GL_ARB_buffer_storage"))
5828 	{
5829 		goto end;
5830 	}
5831 
5832 	/* Set up the test objects */
5833 	if (!initTest())
5834 	{
5835 		result = false;
5836 
5837 		goto end;
5838 	}
5839 	for (unsigned int n_test_case = 0; n_test_case < 2; ++n_test_case)
5840 	{
5841 		for (unsigned int n_iteration = 0; n_iteration < m_n_iterations_to_run; ++n_iteration)
5842 		{
5843 			if (n_iteration != 0)
5844 			{
5845 				gl.bufferPageCommitmentARB(GL_ARRAY_BUFFER, 0, /* offset */
5846 										   m_n_pages_to_test * m_page_size, GL_FALSE);
5847 				GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferPageCommitmentARB() call failed.");
5848 			}
5849 
5850 			gl.bufferPageCommitmentARB(GL_ARRAY_BUFFER, 0, /* offset */
5851 									   m_page_size, GL_TRUE);
5852 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferPageCommitmentARB() call failed.");
5853 
5854 			gl.bufferSubData(GL_ARRAY_BUFFER, 0, /* offset */
5855 							 sizeof(m_reference_data), m_reference_data);
5856 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferSubData() call failed.");
5857 
5858 			for (unsigned int n_page = 0; n_page < m_n_pages_to_test; ++n_page)
5859 			{
5860 				/* Try committing pages in a redundant manner. This is a legal behavior in light of
5861 				 * the GL_ARB_sparse_buffer spec */
5862 				gl.bufferPageCommitmentARB(GL_ARRAY_BUFFER, n_page * m_page_size, m_page_size, GL_TRUE);
5863 				GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferPageCommitmentARB() call failed.");
5864 
5865 				for (int copy_dst_page_offset = static_cast<int>((n_page == 0) ? sizeof(m_reference_data) : 0);
5866 					 copy_dst_page_offset < static_cast<int>(m_page_size);
5867 					 copy_dst_page_offset += static_cast<int>(sizeof(m_reference_data)))
5868 				{
5869 					const int copy_src_page_offset =
5870 						static_cast<int>(copy_dst_page_offset - sizeof(m_reference_data));
5871 
5872 					switch (n_test_case)
5873 					{
5874 					case 0:
5875 					{
5876 						gl.copyBufferSubData(GL_ARRAY_BUFFER, GL_ARRAY_BUFFER,
5877 											 n_page * m_page_size + copy_src_page_offset,
5878 											 n_page * m_page_size + copy_dst_page_offset, sizeof(m_reference_data));
5879 						GLU_EXPECT_NO_ERROR(gl.getError(), "glCopyBufferSubData() call failed.");
5880 
5881 						break;
5882 					}
5883 
5884 					case 1:
5885 					{
5886 						gl.bufferSubData(GL_ARRAY_BUFFER, n_page * m_page_size + copy_dst_page_offset,
5887 										 sizeof(m_reference_data), m_reference_data);
5888 						GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferSubData() call failed.");
5889 
5890 						break;
5891 					}
5892 
5893 					default:
5894 						TCU_FAIL("Unrecognized test case index");
5895 					} /* switch (n_test_case) */
5896 				}	 /* for (all valid destination copy op offsets) */
5897 			}		  /* for (all test pages) */
5898 
5899 			/* Copy data from the sparse buffer to a mappable immutable buffer storage */
5900 			gl.copyBufferSubData(GL_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER, 0, /* readOffset */
5901 								 0,											  /* writeOffset */
5902 								 m_result_data_storage_size);
5903 			GLU_EXPECT_NO_ERROR(gl.getError(), "glCopyBufferSubData() call failed.");
5904 
5905 			/* Map the data we have obtained */
5906 			char* mapped_data = (char*)gl.mapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, /* offset */
5907 														 m_page_size * m_n_pages_to_test, GL_MAP_READ_BIT);
5908 
5909 			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange() call failed.");
5910 
5911 			/* Verify the data is valid */
5912 			for (unsigned int n_temp_copy = 0; n_temp_copy < m_result_data_storage_size / sizeof(m_reference_data);
5913 				 ++n_temp_copy)
5914 			{
5915 				const unsigned int cmp_offset = static_cast<unsigned int>(n_temp_copy * sizeof(m_reference_data));
5916 
5917 				if (memcmp(mapped_data + cmp_offset, m_reference_data, sizeof(m_reference_data)) != 0)
5918 				{
5919 					m_testCtx.getLog() << tcu::TestLog::Message << "Invalid data found for page index "
5920 																   "["
5921 									   << (cmp_offset / m_page_size) << "]"
5922 																		", BO data offset:"
5923 																		"["
5924 									   << cmp_offset << "]." << tcu::TestLog::EndMessage;
5925 
5926 					result = false;
5927 					goto end;
5928 				}
5929 			} /* for (all datasets) */
5930 
5931 			/* Clean up */
5932 			gl.unmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
5933 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer() call failed.");
5934 
5935 			/* Also, zero out the other buffer object we copy the result data to, in case
5936 			 * the glCopyBufferSubData() call does not modify it at all */
5937 			gl.bufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, /* offset */
5938 							 m_result_data_storage_size, m_clear_buffer);
5939 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferSubData() call failed.");
5940 
5941 			/* NOTE: This test passes fine on the misbehaving driver *if* the swapbuffers operation
5942 			 *       issued as a part of the call below is not executed. */
5943 			m_context.getRenderContext().postIterate();
5944 		} /* for (all test iterations) */
5945 	}	 /* for (all test cases) */
5946 
5947 end:
5948 	m_testCtx.setTestResult(result ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, result ? "Pass" : "Fail");
5949 
5950 	return STOP;
5951 }
5952 
5953 /** Constructor.
5954  *
5955  *  @param context Rendering context.
5956  */
CommonBugsTests(deqp::Context & context)5957 CommonBugsTests::CommonBugsTests(deqp::Context& context)
5958 	: TestCaseGroup(context, "CommonBugs", "Contains conformance tests that verify various pieces of functionality"
5959 										   " which were found broken in public drivers.")
5960 {
5961 }
5962 
5963 /** Initializes the test group contents. */
init()5964 void CommonBugsTests::init()
5965 {
5966 	addChild(new GetProgramivActiveUniformBlockMaxNameLengthTest(m_context));
5967 	addChild(new InputVariablesCannotBeModifiedTest(m_context));
5968 	addChild(new InvalidUseCasesForAllNotFuncsAndExclMarkOpTest(m_context));
5969 	addChild(new InvalidVSInputsTest(m_context));
5970 	addChild(new ParenthesisInLayoutQualifierIntegerValuesTest(m_context));
5971 	addChild(new PerVertexValidationTest(m_context));
5972 	addChild(new ReservedNamesTest(m_context));
5973 	addChild(new SparseBuffersWithCopyOpsTest(m_context));
5974 }
5975 } /* glcts namespace */
5976