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