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