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