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 #include "esextcGeometryShaderLinking.hpp"
24 
25 #include "gluDefs.hpp"
26 #include "glwEnums.hpp"
27 #include "glwFunctions.hpp"
28 #include "tcuTestLog.hpp"
29 #include <cstring>
30 
31 namespace glcts
32 {
33 
34 static const char *minimal_fs_code = "${VERSION}\n"
35                                      "\n"
36                                      "precision highp float;\n"
37                                      "\n"
38                                      "out vec4 result;\n"
39                                      "\n"
40                                      "void main()\n"
41                                      "{\n"
42                                      "    result = vec4(1.0);\n"
43                                      "}\n";
44 
45 static const char *minimal_gs_code = "${VERSION}\n"
46                                      "${GEOMETRY_SHADER_REQUIRE}\n"
47                                      "\n"
48                                      "layout (points)                   in;\n"
49                                      "layout (points, max_vertices = 1) out;\n"
50                                      "\n"
51                                      "${OUT_PER_VERTEX_DECL}"
52                                      "${IN_DATA_DECL}"
53                                      "\n"
54                                      "void main()\n"
55                                      "{\n"
56                                      "${POSITION_WITH_IN_DATA}"
57                                      "    EmitVertex();\n"
58                                      "}\n";
59 
60 static const char *minimal_vs_code = "${VERSION}\n"
61                                      "\n"
62                                      "${OUT_PER_VERTEX_DECL}"
63                                      "\n"
64                                      "void main()\n"
65                                      "{\n"
66                                      "    gl_Position = vec4(1.0, 0.0, 0.0, 1.0);\n"
67                                      "}\n";
68 
69 /** Constructor
70  *
71  * @param context       Test context
72  * @param extParams     Not used.
73  * @param name          Test case's name
74  * @param description   Test case's description
75  **/
GeometryShaderIncompleteProgramObjectsTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)76 GeometryShaderIncompleteProgramObjectsTest::GeometryShaderIncompleteProgramObjectsTest(Context &context,
77                                                                                        const ExtParameters &extParams,
78                                                                                        const char *name,
79                                                                                        const char *description)
80     : TestCaseBase(context, extParams, name, description)
81     , m_fs_id(0)
82     , m_gs_id(0)
83     , m_po_id(0)
84 {
85 }
86 
87 /** Deinitializes GLES objects created during the test. */
deinit()88 void GeometryShaderIncompleteProgramObjectsTest::deinit()
89 {
90     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
91 
92     if (m_fs_id != 0)
93     {
94         gl.deleteShader(m_fs_id);
95 
96         m_fs_id = 0;
97     }
98 
99     if (m_gs_id != 0)
100     {
101         gl.deleteShader(m_gs_id);
102 
103         m_gs_id = 0;
104     }
105 
106     if (m_po_id != 0)
107     {
108         gl.deleteProgram(m_po_id);
109 
110         m_po_id = 0;
111     }
112 
113     /* Release base class */
114     TestCaseBase::deinit();
115 }
116 
117 /** Initializes shader objects for the conformance test */
initShaderObjects()118 void GeometryShaderIncompleteProgramObjectsTest::initShaderObjects()
119 {
120     const glw::Functions &gl            = m_context.getRenderContext().getFunctions();
121     std::string specialized_fs_code     = specializeShader(1, &minimal_fs_code);
122     const char *specialized_fs_code_raw = specialized_fs_code.c_str();
123     std::string specialized_gs_code     = specializeShader(1, &minimal_gs_code);
124     const char *specialized_gs_code_raw = specialized_gs_code.c_str();
125 
126     m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
127     m_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
128 
129     GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed.");
130 
131     for (unsigned int n_shader_type = 0; n_shader_type < 2; /* fs, gs */
132          n_shader_type++)
133     {
134         glw::GLint compile_status = GL_FALSE;
135         const char *so_code       = (n_shader_type == 0) ? specialized_fs_code_raw : specialized_gs_code_raw;
136         glw::GLuint so_id         = (n_shader_type == 0) ? m_fs_id : m_gs_id;
137 
138         gl.shaderSource(so_id, 1,           /* count */
139                         &so_code, DE_NULL); /* length */
140 
141         GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed");
142 
143         gl.compileShader(so_id);
144         GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed");
145 
146         gl.getShaderiv(so_id, GL_COMPILE_STATUS, &compile_status);
147 
148         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed");
149 
150         if (compile_status != GL_TRUE)
151         {
152             TCU_FAIL("Shader compilation process failed.");
153         }
154     } /* for (both shader stages) */
155 }
156 
157 /** Initializes test runs, to be executed by the conformance test. */
initTestRuns()158 void GeometryShaderIncompleteProgramObjectsTest::initTestRuns()
159 {
160     /*                         use_fs| use_gs| use_separable_po
161      *                         ------|-------|-----------------*/
162     m_test_runs.push_back(_run(false, true, false));
163     m_test_runs.push_back(_run(false, true, true));
164     m_test_runs.push_back(_run(true, true, false));
165     m_test_runs.push_back(_run(true, true, true));
166 }
167 
168 /** Executes the test.
169  *
170  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
171  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
172  *  Note the function throws exception should an error occur!
173  **/
iterate()174 tcu::TestNode::IterateResult GeometryShaderIncompleteProgramObjectsTest::iterate()
175 {
176     bool result = true;
177 
178     /* This test should only run if EXT_geometry_shader is supported. */
179     if (!m_is_geometry_shader_extension_supported)
180     {
181         throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
182     }
183 
184     /* Initialize test runs */
185     initTestRuns();
186 
187     /* Set up shader objects */
188     initShaderObjects();
189 
190     /* Iterate over the test run set */
191     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
192 
193     for (unsigned int run_index = 0; run_index < m_test_runs.size(); ++run_index)
194     {
195         const _run &current_run = m_test_runs[run_index];
196 
197         /* Set up a program object */
198         m_po_id = gl.createProgram();
199         GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed");
200 
201         if (current_run.use_separable_po)
202         {
203             gl.programParameteri(m_po_id, GL_PROGRAM_SEPARABLE, GL_TRUE);
204             GLU_EXPECT_NO_ERROR(gl.getError(), "glProgramParameteri() call failed");
205         } /* if (current_run.use_separable_po) */
206 
207         if (current_run.use_fs)
208         {
209             gl.attachShader(m_po_id, m_fs_id);
210         }
211 
212         if (current_run.use_gs)
213         {
214             gl.attachShader(m_po_id, m_gs_id);
215         }
216 
217         GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call(s) failed");
218 
219         /* Try to link the PO */
220         gl.linkProgram(m_po_id);
221         GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed.");
222 
223         /* Verify the link status */
224         glw::GLint link_status = GL_FALSE;
225 
226         gl.getProgramiv(m_po_id, GL_LINK_STATUS, &link_status);
227         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed");
228 
229         if ((current_run.use_separable_po && link_status != GL_TRUE) ||
230             (!current_run.use_separable_po && link_status == GL_TRUE))
231         {
232             m_testCtx.getLog() << tcu::TestLog::Message << "Invalid link status reported for a "
233                                << ((current_run.use_separable_po) ? "separable" : "")
234                                << " program object, to which the following SOs were attached: "
235                                << "FS:" << ((current_run.use_fs) ? "YES" : "NO")
236                                << ", GS:" << ((current_run.use_gs) ? "YES" : "NO") << tcu::TestLog::EndMessage;
237 
238             result = false;
239         }
240 
241         /* Clean up for the next iteration */
242         gl.deleteProgram(m_po_id);
243         GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteProgram() call failed");
244     } /* for (all test runs) */
245 
246     if (result)
247     {
248         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
249     }
250     else
251     {
252         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
253     }
254 
255     return STOP;
256 }
257 
258 /** Constructor
259  *
260  * @param context       Test context
261  * @param extParams     Not used.
262  * @param name          Test case's name
263  * @param description   Test case's description
264  **/
GeometryShaderIncompleteGSTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)265 GeometryShaderIncompleteGSTest::GeometryShaderIncompleteGSTest(Context &context, const ExtParameters &extParams,
266                                                                const char *name, const char *description)
267     : TestCaseBase(context, extParams, name, description)
268     , m_fs_id(0)
269     , m_gs_id(0)
270     , m_po_id(0)
271     , m_vs_id(0)
272 {
273 }
274 
275 /** Deinitializes GLES objects created during the test. */
deinit()276 void GeometryShaderIncompleteGSTest::deinit()
277 {
278     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
279 
280     deinitSOs();
281 
282     if (m_po_id != 0)
283     {
284         gl.deleteProgram(m_po_id);
285 
286         m_po_id = 0;
287     }
288 
289     /* Release base class */
290     TestCaseBase::deinit();
291 }
292 
293 /** Deinitializes shader objects created for the conformance test. */
deinitSOs()294 void GeometryShaderIncompleteGSTest::deinitSOs()
295 {
296     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
297 
298     if (m_fs_id != 0)
299     {
300         gl.deleteShader(m_fs_id);
301 
302         m_fs_id = 0;
303     }
304 
305     if (m_gs_id != 0)
306     {
307         gl.deleteShader(m_gs_id);
308 
309         m_gs_id = 0;
310     }
311 
312     if (m_vs_id != 0)
313     {
314         gl.deleteShader(m_vs_id);
315 
316         m_vs_id = 0;
317     }
318 }
319 
320 /** Returns geometry shader's source code, built according to the test run's settings.
321  *
322  *  @param current_run Test run descriptor.
323  *
324  *  @return Requested string.
325  */
getGeometryShaderCode(const _run & current_run)326 std::string GeometryShaderIncompleteGSTest::getGeometryShaderCode(const _run &current_run)
327 {
328     std::stringstream gs_code_sstream;
329 
330     gs_code_sstream << "${VERSION}\n"
331                        "${GEOMETRY_SHADER_REQUIRE}\n"
332                        "\n";
333 
334     if (current_run.is_input_primitive_type_defined)
335     {
336         gs_code_sstream << "layout(points) in;\n";
337     }
338 
339     if (current_run.is_max_vertices_defined || current_run.is_output_primitive_type_defined)
340     {
341         gs_code_sstream << "layout(";
342 
343         if (current_run.is_max_vertices_defined)
344         {
345             gs_code_sstream << "max_vertices = 1";
346 
347             if (current_run.is_output_primitive_type_defined)
348             {
349                 gs_code_sstream << ", ";
350             }
351         } /* if (current_run.is_max_vertices_defined) */
352 
353         if (current_run.is_output_primitive_type_defined)
354         {
355             gs_code_sstream << "points";
356         }
357 
358         gs_code_sstream << ") out;\n";
359     }
360 
361     gs_code_sstream << "\n"
362                        "void main()\n"
363                        "{\n"
364                        "    gl_Position = gl_in[0].gl_Position;\n"
365                        "    EmitVertex();\n"
366                        "}\n";
367 
368     return gs_code_sstream.str();
369 }
370 
371 /** Initializes fragment / geometry / vertex shader objects, according to the test run descriptor.
372  *
373  *  @param current_run                      Test run descriptor.
374  *  @param out_has_fs_compiled_successfully Deref will be set to false, if FS has failed to compile
375  *                                          successfully. Otherwise, it will be set to true.
376  *  @param out_has_gs_compiled_successfully Deref will be set to false, if GS has failed to compile
377  *                                          successfully. Otherwise, it will be set to true.
378  *  @param out_has_vs_compiled_successfully Deref will be set to false, if VS has failed to compile
379  *                                          successfully. Otherwise, it will be set to true.
380  *
381  */
initShaderObjects(const _run & current_run,bool * out_has_fs_compiled_successfully,bool * out_has_gs_compiled_successfully,bool * out_has_vs_compiled_successfully)382 void GeometryShaderIncompleteGSTest::initShaderObjects(const _run &current_run, bool *out_has_fs_compiled_successfully,
383                                                        bool *out_has_gs_compiled_successfully,
384                                                        bool *out_has_vs_compiled_successfully)
385 {
386     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
387 
388     std::string specialized_fs_code = specializeShader(1, &minimal_fs_code);
389     std::string gs_code             = getGeometryShaderCode(current_run);
390     const char *gs_code_raw         = gs_code.c_str();
391     std::string specialized_gs_code = specializeShader(1, &gs_code_raw);
392     std::string specialized_vs_code = specializeShader(1, &minimal_vs_code);
393 
394     const char *specialized_fs_code_raw = specialized_fs_code.c_str();
395     const char *specialized_gs_code_raw = specialized_gs_code.c_str();
396     const char *specialized_vs_code_raw = specialized_vs_code.c_str();
397 
398     m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
399     m_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
400     m_vs_id = gl.createShader(GL_VERTEX_SHADER);
401 
402     GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed.");
403 
404     for (unsigned int n_shader_type = 0; n_shader_type < 3; /* fs, gs, vs */
405          n_shader_type++)
406     {
407         glw::GLint compile_status        = GL_FALSE;
408         bool *out_current_compile_result = (n_shader_type == 0) ? out_has_fs_compiled_successfully :
409                                            (n_shader_type == 1) ? out_has_gs_compiled_successfully :
410                                                                   out_has_vs_compiled_successfully;
411 
412         const char *so_code = (n_shader_type == 0) ? specialized_fs_code_raw :
413                               (n_shader_type == 1) ? specialized_gs_code_raw :
414                                                      specialized_vs_code_raw;
415 
416         glw::GLuint so_id = (n_shader_type == 0) ? m_fs_id : (n_shader_type == 1) ? m_gs_id : m_vs_id;
417 
418         gl.shaderSource(so_id, 1,           /* count */
419                         &so_code, DE_NULL); /* length */
420 
421         GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed");
422 
423         gl.compileShader(so_id);
424         GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed");
425 
426         gl.getShaderiv(so_id, GL_COMPILE_STATUS, &compile_status);
427         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed");
428 
429         *out_current_compile_result = (compile_status == GL_TRUE);
430     } /* for (both shader stages) */
431 }
432 
433 /** Initializes all test runs */
initTestRuns()434 void GeometryShaderIncompleteGSTest::initTestRuns()
435 {
436     /*                         input_primitive_defined | max_vertices_defined | output_primitive_defined
437      *                         ------------------------|----------------------|-------------------------*/
438     m_test_runs.push_back(_run(false, false, false));
439     m_test_runs.push_back(_run(false, false, true));
440     m_test_runs.push_back(_run(false, true, false));
441     m_test_runs.push_back(_run(true, true, false));
442     m_test_runs.push_back(_run(false, true, true));
443 }
444 
445 /** Executes the test.
446  *
447  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
448  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
449  *  Note the function throws exception should an error occur!
450  **/
iterate()451 tcu::TestNode::IterateResult GeometryShaderIncompleteGSTest::iterate()
452 {
453     bool result = true;
454 
455     /* This test should only run if EXT_geometry_shader is supported. */
456     if (!m_is_geometry_shader_extension_supported)
457     {
458         throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
459     }
460 
461     /* Initialize test runs */
462     initTestRuns();
463 
464     /* Iterate over the test run set */
465     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
466 
467     for (unsigned int run_index = 0; run_index < m_test_runs.size(); ++run_index)
468     {
469         const _run &current_run = m_test_runs[run_index];
470 
471         /* Release shader objects initialized in previous iterations */
472         deinitSOs();
473 
474         /* Set up shader objects */
475         bool has_fs_compiled = false;
476         bool has_gs_compiled = false;
477         bool has_vs_compiled = false;
478 
479         initShaderObjects(current_run, &has_fs_compiled, &has_gs_compiled, &has_vs_compiled);
480 
481         if (!has_fs_compiled || !has_vs_compiled)
482         {
483             m_testCtx.getLog() << tcu::TestLog::Message << "Minimal FS and/or minimal VS failed to compile"
484                                << tcu::TestLog::EndMessage;
485 
486             result = false;
487             break;
488         }
489 
490         /* Set up a program object */
491         m_po_id = gl.createProgram();
492         GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed");
493 
494         gl.attachShader(m_po_id, m_fs_id);
495         gl.attachShader(m_po_id, m_gs_id);
496         gl.attachShader(m_po_id, m_vs_id);
497 
498         GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call(s) failed");
499 
500         /* Try to link the PO */
501         gl.linkProgram(m_po_id);
502         GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed.");
503 
504         /* Verify the link status */
505         glw::GLint link_status = GL_FALSE;
506 
507         gl.getProgramiv(m_po_id, GL_LINK_STATUS, &link_status);
508         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed");
509 
510         if (link_status == GL_TRUE)
511         {
512             m_testCtx.getLog() << tcu::TestLog::Message
513                                << "PO with a malformed Geometry Shader was linked successfully."
514                                << " [input primitive type]:"
515                                << ((current_run.is_input_primitive_type_defined) ? "DEFINED" : "NOT DEFINED")
516                                << " [output primitive type]:"
517                                << ((current_run.is_output_primitive_type_defined) ? "DEFINED" : "NOT DEFINED")
518                                << " [max_vertices]:"
519                                << ((current_run.is_max_vertices_defined) ? "DEFINED" : "NOT DEFINED")
520                                << tcu::TestLog::EndMessage;
521 
522             result = false;
523         }
524 
525         /* Clean up for the next iteration */
526         gl.deleteProgram(m_po_id);
527         GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteProgram() call failed");
528     } /* for (all test runs) */
529 
530     if (result)
531     {
532         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
533     }
534     else
535     {
536         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
537     }
538 
539     return STOP;
540 }
541 
542 /** Constructor
543  *
544  * @param context       Test context
545  * @param extParams     Not used.
546  * @param name          Test case's name
547  * @param description   Test case's description
548  **/
GeometryShaderInvalidArrayedInputVariablesTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)549 GeometryShaderInvalidArrayedInputVariablesTest::GeometryShaderInvalidArrayedInputVariablesTest(
550     Context &context, const ExtParameters &extParams, const char *name, const char *description)
551     : TestCaseBase(context, extParams, name, description)
552     , m_fs_id(0)
553     , m_gs_id(0)
554     , m_po_id(0)
555     , m_vs_id(0)
556 {
557 }
558 
559 /** Deinitializes GLES objects created during the test. */
deinit()560 void GeometryShaderInvalidArrayedInputVariablesTest::deinit()
561 {
562     deinitSOs();
563 
564     /* Release the PO */
565     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
566 
567     if (m_po_id != 0)
568     {
569         gl.deleteProgram(m_po_id);
570 
571         m_po_id = 0;
572     }
573 
574     /* Release base class */
575     TestCaseBase::deinit();
576 }
577 
578 /** Deinitializes shader objects created for the conformance test. */
deinitSOs()579 void GeometryShaderInvalidArrayedInputVariablesTest::deinitSOs()
580 {
581     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
582 
583     if (m_fs_id != 0)
584     {
585         gl.deleteShader(m_fs_id);
586 
587         m_fs_id = 0;
588     }
589 
590     if (m_gs_id != 0)
591     {
592         gl.deleteShader(m_gs_id);
593 
594         m_gs_id = 0;
595     }
596 
597     if (m_vs_id != 0)
598     {
599         gl.deleteShader(m_vs_id);
600 
601         m_vs_id = 0;
602     }
603 }
604 
605 /** Returns test-specific geometry shader source code, built for caller-specified input primitive type.
606  *
607  *  @param gs_input_primitive_type Input primitive type to be used for the process.
608  *
609  *  @return Requested shader source code.
610  **/
getGSCode(glw::GLenum gs_input_primitive_type) const611 std::string GeometryShaderInvalidArrayedInputVariablesTest::getGSCode(glw::GLenum gs_input_primitive_type) const
612 {
613     std::stringstream code_sstream;
614     const unsigned int valid_array_size = getValidInputVariableArraySize(gs_input_primitive_type);
615 
616     code_sstream << "${VERSION}\n"
617                     "${GEOMETRY_SHADER_REQUIRE}\n"
618                     "\n"
619                     "layout ("
620                  << getInputPrimitiveTypeQualifier(gs_input_primitive_type)
621                  << ") in;\n"
622                     "layout (points, max_vertices = 1) out;\n"
623                     "\n"
624                     "in vec4 data["
625                  << (valid_array_size + 1)
626                  << "];\n"
627                     "\n"
628                     "void main()\n"
629                     "{\n"
630                     "    gl_Position = data["
631                  << valid_array_size
632                  << "];\n"
633                     "    EmitVertex();\n"
634                     "}\n";
635 
636     return code_sstream.str();
637 }
638 
639 /** Returns a string holding the ES SL layout qualifier corresponding to user-specified input primitive type
640  *  expressed as a GLenum value.
641  *
642  *  @param gs_input_primitive_type Geometry Shader's input primitive type, expressed as a GLenum value.
643  *
644  *  @return Requested string
645  */
getInputPrimitiveTypeQualifier(glw::GLenum gs_input_primitive_type) const646 std::string GeometryShaderInvalidArrayedInputVariablesTest::getInputPrimitiveTypeQualifier(
647     glw::GLenum gs_input_primitive_type) const
648 {
649     std::string result;
650 
651     switch (gs_input_primitive_type)
652     {
653     case GL_POINTS:
654         result = "points";
655         break;
656     case GL_LINES:
657         result = "lines";
658         break;
659     case GL_LINES_ADJACENCY:
660         result = "lines_adjacency";
661         break;
662     case GL_TRIANGLES:
663         result = "triangles";
664         break;
665     case GL_TRIANGLES_ADJACENCY:
666         result = "triangles_adjacency";
667         break;
668 
669     default:
670     {
671         DE_ASSERT(0);
672     }
673     } /* switch (gs_input_primitive_type) */
674 
675     return result;
676 }
677 
678 /** Retrieves a specialized version of the vertex shader to be used for the conformance test. */
getSpecializedVSCode() const679 std::string GeometryShaderInvalidArrayedInputVariablesTest::getSpecializedVSCode() const
680 {
681     std::string vs_code             = "${VERSION}\n"
682                                       "\n"
683                                       "out vec4 data;\n"
684                                       "\n"
685                                       "void main()\n"
686                                       "{\n"
687                                       "    data = vec4(gl_VertexID, 0, 0, 1);\n"
688                                       "}\n";
689     const char *vs_code_raw         = vs_code.c_str();
690     std::string specialized_vs_code = specializeShader(1, /* parts */
691                                                        &vs_code_raw);
692 
693     return specialized_vs_code;
694 }
695 
696 /** Returns array size that should be used for input variable declaration in GS, specific to
697  *  to the caller-specified input primitive type.
698  *
699  *  @param gs_input_primitive_type Input primitive type to use for the query.
700  *
701  *  @return Requested value.
702  */
getValidInputVariableArraySize(glw::GLenum gs_input_primitive_type) const703 glw::GLuint GeometryShaderInvalidArrayedInputVariablesTest::getValidInputVariableArraySize(
704     glw::GLenum gs_input_primitive_type) const
705 {
706     glw::GLuint result = 0;
707 
708     switch (gs_input_primitive_type)
709     {
710     case GL_POINTS:
711         result = 1;
712         break;
713     case GL_LINES:
714         result = 2;
715         break;
716     case GL_LINES_ADJACENCY:
717         result = 4;
718         break;
719     case GL_TRIANGLES:
720         result = 3;
721         break;
722     case GL_TRIANGLES_ADJACENCY:
723         result = 6;
724         break;
725 
726     default:
727     {
728         DE_ASSERT(0);
729     }
730     } /* switch (gs_input_primitive_type) */
731 
732     return result;
733 }
734 
735 /** Initializes fragment / geometry / vertex shader objects, according to the user-specified GS input primitive type.
736  *
737  *  @param gs_input_primitive_type          Input primitive type, to be used for GS.
738  *  @param out_has_fs_compiled_successfully Deref will be set to false, if FS has failed to compile
739  *                                          successfully. Otherwise, it will be set to true.
740  *  @param out_has_gs_compiled_successfully Deref will be set to false, if GS has failed to compile
741  *                                          successfully. Otherwise, it will be set to true.
742  *  @param out_has_vs_compiled_successfully Deref will be set to false, if VS has failed to compile
743  *                                          successfully. Otherwise, it will be set to true.
744  *
745  */
initShaderObjects(glw::GLenum gs_input_primitive_type,bool * out_has_fs_compiled_successfully,bool * out_has_gs_compiled_successfully,bool * out_has_vs_compiled_successfully)746 void GeometryShaderInvalidArrayedInputVariablesTest::initShaderObjects(glw::GLenum gs_input_primitive_type,
747                                                                        bool *out_has_fs_compiled_successfully,
748                                                                        bool *out_has_gs_compiled_successfully,
749                                                                        bool *out_has_vs_compiled_successfully)
750 {
751     const glw::Functions &gl            = m_context.getRenderContext().getFunctions();
752     std::string specialized_fs_code     = specializeShader(1, &minimal_fs_code);
753     const char *specialized_fs_code_raw = specialized_fs_code.c_str();
754     std::string gs_code                 = getGSCode(gs_input_primitive_type);
755     const char *gs_code_raw             = gs_code.c_str();
756     std::string specialized_gs_code     = specializeShader(1, &gs_code_raw);
757     const char *specialized_gs_code_raw = specialized_gs_code.c_str();
758     std::string specialized_vs_code     = getSpecializedVSCode();
759     const char *specialized_vs_code_raw = specialized_vs_code.c_str();
760 
761     m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
762     m_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
763     m_vs_id = gl.createShader(GL_VERTEX_SHADER);
764 
765     GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed.");
766 
767     for (unsigned int n_shader_type = 0; n_shader_type < 3; /* fs, gs, vs */
768          n_shader_type++)
769     {
770         glw::GLint compile_status = GL_FALSE;
771         bool *out_compile_result  = (n_shader_type == 0) ? out_has_fs_compiled_successfully :
772                                     (n_shader_type == 1) ? out_has_gs_compiled_successfully :
773                                                            out_has_vs_compiled_successfully;
774 
775         const char *so_code = (n_shader_type == 0) ? specialized_fs_code_raw :
776                               (n_shader_type == 1) ? specialized_gs_code_raw :
777                                                      specialized_vs_code_raw;
778 
779         glw::GLuint so_id = (n_shader_type == 0) ? m_fs_id : (n_shader_type == 1) ? m_gs_id : m_vs_id;
780 
781         gl.shaderSource(so_id, 1,           /* count */
782                         &so_code, DE_NULL); /* length */
783 
784         GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed");
785 
786         gl.compileShader(so_id);
787         GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed");
788 
789         gl.getShaderiv(so_id, GL_COMPILE_STATUS, &compile_status);
790         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed");
791 
792         *out_compile_result = (compile_status == GL_TRUE);
793     } /* for (both shader stages) */
794 }
795 
796 /** Executes the test.
797  *
798  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
799  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
800  *  Note the function throws exception should an error occur!
801  **/
iterate()802 tcu::TestNode::IterateResult GeometryShaderInvalidArrayedInputVariablesTest::iterate()
803 {
804     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
805     bool result              = true;
806 
807     /* This test should only run if EXT_geometry_shader is supported. */
808     if (!m_is_geometry_shader_extension_supported)
809     {
810         throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
811     }
812 
813     /* Iterate over all valid input primitive types */
814     const glw::GLenum input_primitive_types[]  = {GL_POINTS, GL_LINES, GL_LINES_ADJACENCY, GL_TRIANGLES,
815                                                   GL_TRIANGLES_ADJACENCY};
816     const unsigned int n_input_primitive_types = sizeof(input_primitive_types) / sizeof(input_primitive_types[0]);
817 
818     for (unsigned int n_input_primitive_type = 0; n_input_primitive_type < n_input_primitive_types;
819          ++n_input_primitive_type)
820     {
821         const glw::GLenum input_primitive_type = input_primitive_types[n_input_primitive_type];
822 
823         /* Release shader objects initialized in previous iterations */
824         deinitSOs();
825 
826         /* Set up shader objects */
827         bool has_fs_compiled = false;
828         bool has_gs_compiled = false;
829         bool has_vs_compiled = false;
830 
831         initShaderObjects(input_primitive_type, &has_fs_compiled, &has_gs_compiled, &has_vs_compiled);
832 
833         if (!has_fs_compiled || !has_gs_compiled || !has_vs_compiled)
834         {
835             m_testCtx.getLog()
836                 << tcu::TestLog::Message
837                 << "One of the shaders failed to compile (but shouldn't have). Shaders that failed to compile:"
838                 << ((!has_fs_compiled) ? "FS " : "") << ((!has_gs_compiled) ? "GS " : "")
839                 << ((!has_vs_compiled) ? "VS" : "") << ". Input primitive type: ["
840                 << getInputPrimitiveTypeQualifier(input_primitive_type) << "]" << tcu::TestLog::EndMessage;
841 
842             continue;
843         }
844 
845         /* Set up a program object */
846         m_po_id = gl.createProgram();
847         GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed");
848 
849         gl.attachShader(m_po_id, m_fs_id);
850         gl.attachShader(m_po_id, m_gs_id);
851         gl.attachShader(m_po_id, m_vs_id);
852 
853         GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call(s) failed");
854 
855         /* Try to link the PO */
856         gl.linkProgram(m_po_id);
857         GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed.");
858 
859         /* Verify the link status */
860         glw::GLint link_status = GL_FALSE;
861 
862         gl.getProgramiv(m_po_id, GL_LINK_STATUS, &link_status);
863         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed");
864 
865         if (link_status == GL_TRUE)
866         {
867             m_testCtx.getLog() << tcu::TestLog::Message << "A PO using a malformed GS has linked successfully. "
868                                << "Test input primitive type: " << getInputPrimitiveTypeQualifier(input_primitive_type)
869                                << tcu::TestLog::EndMessage;
870 
871             result = false;
872         }
873     } /* for (all input primitive types) */
874 
875     if (result)
876     {
877         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
878     }
879     else
880     {
881         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
882     }
883 
884     return STOP;
885 }
886 
887 /** Constructor
888  *
889  * @param context       Test context
890  * @param extParams     Not used.
891  * @param name          Test case's name
892  * @param description   Test case's description
893  **/
GeometryShaderVSGSVariableTypeMismatchTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)894 GeometryShaderVSGSVariableTypeMismatchTest::GeometryShaderVSGSVariableTypeMismatchTest(Context &context,
895                                                                                        const ExtParameters &extParams,
896                                                                                        const char *name,
897                                                                                        const char *description)
898     : TestCaseBase(context, extParams, name, description)
899     , m_fs_id(0)
900     , m_gs_id(0)
901     , m_po_id(0)
902     , m_vs_id(0)
903 {
904 }
905 
906 /** Deinitializes GLES objects created during the test. */
deinit()907 void GeometryShaderVSGSVariableTypeMismatchTest::deinit()
908 {
909     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
910 
911     if (m_fs_id != 0)
912     {
913         gl.deleteShader(m_fs_id);
914 
915         m_fs_id = 0;
916     }
917 
918     if (m_gs_id != 0)
919     {
920         gl.deleteShader(m_gs_id);
921 
922         m_gs_id = 0;
923     }
924 
925     if (m_po_id != 0)
926     {
927         gl.deleteProgram(m_po_id);
928 
929         m_po_id = 0;
930     }
931 
932     if (m_vs_id != 0)
933     {
934         gl.deleteShader(m_vs_id);
935 
936         m_vs_id = 0;
937     }
938 
939     /* Release base class */
940     TestCaseBase::deinit();
941 }
942 
943 /** Executes the test.
944  *
945  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
946  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
947  *  Note the function throws exception should an error occur!
948  **/
iterate()949 tcu::TestNode::IterateResult GeometryShaderVSGSVariableTypeMismatchTest::iterate()
950 {
951     bool has_shader_compilation_failed = true;
952     bool result                        = true;
953 
954     /* This test should only run if EXT_geometry_shader is supported. */
955     if (!m_is_geometry_shader_extension_supported)
956     {
957         throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
958     }
959 
960     /* Create a program object */
961     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
962 
963     m_po_id = gl.createProgram();
964 
965     GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
966 
967     /* Create shader objects */
968     m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
969     m_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
970     m_vs_id = gl.createShader(GL_VERTEX_SHADER);
971 
972     GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
973 
974     /* Try to link the test program object */
975     const char *gs_code_raw = "${VERSION}\n"
976                               "${GEOMETRY_SHADER_REQUIRE}\n"
977                               "\n"
978                               "layout (points)                   in;\n"
979                               "layout (points, max_vertices = 1) out;\n"
980                               "\n"
981                               "in vec4 test[];\n"
982                               "\n"
983                               "void main()\n"
984                               "{\n"
985                               "    gl_Position = test[0];\n"
986                               "    EmitVertex();\n"
987                               "}\n";
988 
989     const char *vs_code_raw = "${VERSION}\n"
990                               "\n"
991                               "out vec3 test;\n"
992                               "\n"
993                               "void main()\n"
994                               "{\n"
995                               "    test = vec3(gl_VertexID);\n"
996                               "}\n";
997 
998     std::string fs_code_specialized     = specializeShader(1, &minimal_fs_code);
999     const char *fs_code_specialized_raw = fs_code_specialized.c_str();
1000     std::string gs_code_specialized     = specializeShader(1, &gs_code_raw);
1001     const char *gs_code_specialized_raw = gs_code_specialized.c_str();
1002     std::string vs_code_specialized     = specializeShader(1, &vs_code_raw);
1003     const char *vs_code_specialized_raw = vs_code_specialized.c_str();
1004 
1005     if (TestCaseBase::buildProgram(m_po_id, m_gs_id, 1,                  /* n_sh1_body_parts */
1006                                    &gs_code_specialized_raw, m_vs_id, 1, /* n_sh2_body_parts */
1007                                    &vs_code_specialized_raw, m_fs_id, 1, /* n_sh3_body_parts */
1008                                    &fs_code_specialized_raw, &has_shader_compilation_failed))
1009     {
1010         m_testCtx.getLog() << tcu::TestLog::Message
1011                            << "Program object was linked successfully, whereas a failure was expected."
1012                            << tcu::TestLog::EndMessage;
1013 
1014         result = false;
1015     }
1016 
1017     if (has_shader_compilation_failed)
1018     {
1019         m_testCtx.getLog() << tcu::TestLog::Message << "Shader compilation failed unexpectedly."
1020                            << tcu::TestLog::EndMessage;
1021 
1022         result = false;
1023     }
1024 
1025     if (result)
1026     {
1027         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1028     }
1029     else
1030     {
1031         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1032     }
1033 
1034     return STOP;
1035 }
1036 
1037 /** Constructor
1038  *
1039  * @param context       Test context
1040  * @param extParams     Not used.
1041  * @param name          Test case's name
1042  * @param description   Test case's description
1043  **/
GeometryShaderVSGSVariableQualifierMismatchTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)1044 GeometryShaderVSGSVariableQualifierMismatchTest::GeometryShaderVSGSVariableQualifierMismatchTest(
1045     Context &context, const ExtParameters &extParams, const char *name, const char *description)
1046     : TestCaseBase(context, extParams, name, description)
1047     , m_fs_id(0)
1048     , m_gs_id(0)
1049     , m_po_id(0)
1050     , m_vs_id(0)
1051 {
1052 }
1053 
1054 /** Deinitializes GLES objects created during the test. */
deinit()1055 void GeometryShaderVSGSVariableQualifierMismatchTest::deinit()
1056 {
1057     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1058 
1059     if (m_fs_id != 0)
1060     {
1061         gl.deleteShader(m_fs_id);
1062 
1063         m_fs_id = 0;
1064     }
1065 
1066     if (m_gs_id != 0)
1067     {
1068         gl.deleteShader(m_gs_id);
1069 
1070         m_gs_id = 0;
1071     }
1072 
1073     if (m_po_id != 0)
1074     {
1075         gl.deleteProgram(m_po_id);
1076 
1077         m_po_id = 0;
1078     }
1079 
1080     if (m_vs_id != 0)
1081     {
1082         gl.deleteShader(m_vs_id);
1083 
1084         m_vs_id = 0;
1085     }
1086 
1087     /* Release base class */
1088     TestCaseBase::deinit();
1089 }
1090 
1091 /** Executes the test.
1092  *
1093  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
1094  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
1095  *  Note the function throws exception should an error occur!
1096  **/
iterate()1097 tcu::TestNode::IterateResult GeometryShaderVSGSVariableQualifierMismatchTest::iterate()
1098 {
1099     bool has_shader_compilation_failed = true;
1100     bool result                        = true;
1101 
1102     /* This test should only run if EXT_geometry_shader is supported. */
1103     if (!m_is_geometry_shader_extension_supported)
1104     {
1105         throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
1106     }
1107 
1108     /* Create a program object */
1109     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1110 
1111     m_po_id = gl.createProgram();
1112 
1113     GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
1114 
1115     /* Create shader objects */
1116     m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
1117     m_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
1118     m_vs_id = gl.createShader(GL_VERTEX_SHADER);
1119 
1120     GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
1121 
1122     /* Try to link the test program object */
1123     const char *gs_code_raw = "${VERSION}\n"
1124                               "${GEOMETRY_SHADER_REQUIRE}\n"
1125                               "\n"
1126                               "layout (points)                   in;\n"
1127                               "layout (points, max_vertices = 1) out;\n"
1128                               "\n"
1129                               "in flat vec4 test[];\n"
1130                               "\n"
1131                               "void main()\n"
1132                               "{\n"
1133                               "    gl_Position = test[0];\n"
1134                               "    EmitVertex();\n"
1135                               "}\n";
1136 
1137     const char *vs_code_raw = "${VERSION}\n"
1138                               "${GEOMETRY_SHADER_REQUIRE}\n"
1139                               "\n"
1140                               "out vec4 test;\n"
1141                               "\n"
1142                               "void main()\n"
1143                               "{\n"
1144                               "    test = vec4(gl_VertexID);\n"
1145                               "}\n";
1146 
1147     std::string fs_code_specialized     = specializeShader(1, &minimal_fs_code);
1148     const char *fs_code_specialized_raw = fs_code_specialized.c_str();
1149     std::string gs_code_specialized     = specializeShader(1, &gs_code_raw);
1150     const char *gs_code_specialized_raw = gs_code_specialized.c_str();
1151     std::string vs_code_specialized     = specializeShader(1, &vs_code_raw);
1152     const char *vs_code_specialized_raw = vs_code_specialized.c_str();
1153 
1154     bool buildSuccess = TestCaseBase::buildProgram(m_po_id, m_gs_id, 1,                  /* n_sh1_body_parts */
1155                                                    &gs_code_specialized_raw, m_vs_id, 1, /* n_sh2_body_parts */
1156                                                    &vs_code_specialized_raw, m_fs_id, 1, /* n_sh3_body_parts */
1157                                                    &fs_code_specialized_raw, &has_shader_compilation_failed);
1158 
1159     if (!buildSuccess && glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(3, 0)))
1160     {
1161         m_testCtx.getLog() << tcu::TestLog::Message << "Program object linking failed. Success was expected."
1162                            << tcu::TestLog::EndMessage;
1163 
1164         result = false;
1165     }
1166 
1167     if (buildSuccess && !glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(3, 0)))
1168     {
1169         m_testCtx.getLog() << tcu::TestLog::Message
1170                            << "Program object was linked successfully, whereas a failure was expected."
1171                            << tcu::TestLog::EndMessage;
1172         result = false;
1173     }
1174 
1175     if (has_shader_compilation_failed)
1176     {
1177         m_testCtx.getLog() << tcu::TestLog::Message << "Shader compilation failed unexpectedly."
1178                            << tcu::TestLog::EndMessage;
1179 
1180         result = false;
1181     }
1182 
1183     if (result)
1184     {
1185         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1186     }
1187     else
1188     {
1189         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1190     }
1191 
1192     return STOP;
1193 }
1194 
1195 /** Constructor
1196  *
1197  * @param context       Test context
1198  * @param extParams     Not used.
1199  * @param name          Test case's name
1200  * @param description   Test case's description
1201  **/
GeometryShaderVSGSArrayedVariableSizeMismatchTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)1202 GeometryShaderVSGSArrayedVariableSizeMismatchTest::GeometryShaderVSGSArrayedVariableSizeMismatchTest(
1203     Context &context, const ExtParameters &extParams, const char *name, const char *description)
1204     : TestCaseBase(context, extParams, name, description)
1205     , m_fs_id(0)
1206     , m_gs_id(0)
1207     , m_po_id(0)
1208     , m_vs_id(0)
1209 {
1210 }
1211 
1212 /** Deinitializes GLES objects created during the test. */
deinit()1213 void GeometryShaderVSGSArrayedVariableSizeMismatchTest::deinit()
1214 {
1215     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1216 
1217     if (m_fs_id != 0)
1218     {
1219         gl.deleteShader(m_fs_id);
1220 
1221         m_fs_id = 0;
1222     }
1223 
1224     if (m_gs_id != 0)
1225     {
1226         gl.deleteShader(m_gs_id);
1227 
1228         m_gs_id = 0;
1229     }
1230 
1231     if (m_po_id != 0)
1232     {
1233         gl.deleteProgram(m_po_id);
1234 
1235         m_po_id = 0;
1236     }
1237 
1238     if (m_vs_id != 0)
1239     {
1240         gl.deleteShader(m_vs_id);
1241 
1242         m_vs_id = 0;
1243     }
1244 
1245     /* Release base class */
1246     TestCaseBase::deinit();
1247 }
1248 
1249 /** Executes the test.
1250  *
1251  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
1252  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
1253  *  Note the function throws exception should an error occur!
1254  **/
iterate()1255 tcu::TestNode::IterateResult GeometryShaderVSGSArrayedVariableSizeMismatchTest::iterate()
1256 {
1257     bool has_shader_compilation_failed = true;
1258     bool result                        = true;
1259 
1260     /* This test should only run if EXT_geometry_shader is supported. */
1261     if (!m_is_geometry_shader_extension_supported)
1262     {
1263         throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
1264     }
1265 
1266     /* Create a program object */
1267     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1268 
1269     m_po_id = gl.createProgram();
1270 
1271     GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
1272 
1273     /* Create shader objects */
1274     m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
1275     m_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
1276     m_vs_id = gl.createShader(GL_VERTEX_SHADER);
1277 
1278     GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
1279 
1280     /* Try to link the test program object */
1281     const char *gs_code_raw = "${VERSION}\n"
1282                               "${GEOMETRY_SHADER_REQUIRE}\n"
1283                               "\n"
1284                               "layout (points)                   in;\n"
1285                               "layout (points, max_vertices = 1) out;\n"
1286                               "\n"
1287                               "in vec4 Color1[];\n"
1288                               "in vec4 Color2[2];\n"
1289                               "in vec4 Color3[3];\n"
1290                               "\n"
1291                               "void main()\n"
1292                               "{\n"
1293                               "    gl_Position = Color1[0] + Color2[1] + Color3[2];\n"
1294                               "    EmitVertex();\n"
1295                               "}\n";
1296 
1297     const char *vs_code_raw = "${VERSION}\n"
1298                               "${GEOMETRY_SHADER_REQUIRE}\n"
1299                               "\n"
1300                               "out vec4 Color1;\n"
1301                               "out vec4 Color2;\n"
1302                               "out vec4 Color3;\n"
1303                               "\n"
1304                               "void main()\n"
1305                               "{\n"
1306                               "    Color1 = vec4(gl_VertexID, 0.0,         0.0,         0.0);\n"
1307                               "    Color2 = vec4(0.0,         gl_VertexID, 0.0,         0.0);\n"
1308                               "    Color3 = vec4(0.0,         0.0,         gl_VertexID, 0.0);\n"
1309                               "}\n";
1310 
1311     std::string fs_code_specialized     = specializeShader(1, &minimal_fs_code);
1312     const char *fs_code_specialized_raw = fs_code_specialized.c_str();
1313     std::string gs_code_specialized     = specializeShader(1, &gs_code_raw);
1314     const char *gs_code_specialized_raw = gs_code_specialized.c_str();
1315     std::string vs_code_specialized     = specializeShader(1, &vs_code_raw);
1316     const char *vs_code_specialized_raw = vs_code_specialized.c_str();
1317 
1318     if (TestCaseBase::buildProgram(m_po_id, m_gs_id, 1,                  /* n_sh1_body_parts */
1319                                    &gs_code_specialized_raw, m_vs_id, 1, /* n_sh2_body_parts */
1320                                    &vs_code_specialized_raw, m_fs_id, 1, /* n_sh3_body_parts */
1321                                    &fs_code_specialized_raw, &has_shader_compilation_failed))
1322     {
1323         m_testCtx.getLog() << tcu::TestLog::Message
1324                            << "Program object was linked successfully, whereas a failure was expected."
1325                            << tcu::TestLog::EndMessage;
1326 
1327         result = false;
1328     }
1329 
1330     if (result)
1331     {
1332         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1333     }
1334     else
1335     {
1336         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1337     }
1338 
1339     return STOP;
1340 }
1341 
1342 /** Constructor
1343  *
1344  * @param context       Test context
1345  * @param extParams     Not used.
1346  * @param name          Test case's name
1347  * @param description   Test case's description
1348  **/
GeometryShaderFragCoordRedeclarationTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)1349 GeometryShaderFragCoordRedeclarationTest::GeometryShaderFragCoordRedeclarationTest(Context &context,
1350                                                                                    const ExtParameters &extParams,
1351                                                                                    const char *name,
1352                                                                                    const char *description)
1353     : TestCaseBase(context, extParams, name, description)
1354     , m_fs_id(0)
1355     , m_gs_id(0)
1356     , m_po_id(0)
1357     , m_vs_id(0)
1358 {
1359 }
1360 
1361 /** Deinitializes GLES objects created during the test. */
deinit()1362 void GeometryShaderFragCoordRedeclarationTest::deinit()
1363 {
1364     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1365 
1366     if (m_fs_id != 0)
1367     {
1368         gl.deleteShader(m_fs_id);
1369 
1370         m_fs_id = 0;
1371     }
1372 
1373     if (m_gs_id != 0)
1374     {
1375         gl.deleteShader(m_gs_id);
1376 
1377         m_gs_id = 0;
1378     }
1379 
1380     if (m_po_id != 0)
1381     {
1382         gl.deleteProgram(m_po_id);
1383 
1384         m_po_id = 0;
1385     }
1386 
1387     if (m_vs_id != 0)
1388     {
1389         gl.deleteShader(m_vs_id);
1390 
1391         m_vs_id = 0;
1392     }
1393 
1394     /* Release base class */
1395     TestCaseBase::deinit();
1396 }
1397 
1398 /** Executes the test.
1399  *
1400  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
1401  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
1402  *  Note the function throws exception should an error occur!
1403  **/
iterate()1404 tcu::TestNode::IterateResult GeometryShaderFragCoordRedeclarationTest::iterate()
1405 {
1406     bool has_shader_compilation_failed = true;
1407     bool result                        = true;
1408 
1409     /* This test should only run if EXT_geometry_shader is supported. */
1410     if (!m_is_geometry_shader_extension_supported)
1411     {
1412         throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
1413     }
1414 
1415     /* Create a program object */
1416     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1417 
1418     m_po_id = gl.createProgram();
1419 
1420     GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
1421 
1422     /* Create shader objects */
1423     m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
1424     m_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
1425     m_vs_id = gl.createShader(GL_VERTEX_SHADER);
1426 
1427     GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
1428 
1429     /* Try to link the test program object */
1430     const char *gs_code_raw = "${VERSION}\n"
1431                               "${GEOMETRY_SHADER_REQUIRE}\n"
1432                               "\n"
1433                               "layout (points)                   in;\n"
1434                               "layout (points, max_vertices = 1) out;\n"
1435                               "\n"
1436                               "in vec4 gl_FragCoord;\n"
1437                               "\n"
1438                               "void main()\n"
1439                               "{\n"
1440                               "    gl_Position = gl_FragCoord;\n"
1441                               "    EmitVertex();\n"
1442                               "}\n";
1443 
1444     std::string fs_code_specialized     = specializeShader(1, &minimal_fs_code);
1445     const char *fs_code_specialized_raw = fs_code_specialized.c_str();
1446     std::string gs_code_specialized     = specializeShader(1, &gs_code_raw);
1447     const char *gs_code_specialized_raw = gs_code_specialized.c_str();
1448     std::string vs_code_specialized     = specializeShader(1, &minimal_vs_code);
1449     const char *vs_code_specialized_raw = vs_code_specialized.c_str();
1450 
1451     if (TestCaseBase::buildProgram(m_po_id, m_gs_id, 1,                  /* n_sh1_body_parts */
1452                                    &gs_code_specialized_raw, m_vs_id, 1, /* n_sh2_body_parts */
1453                                    &vs_code_specialized_raw, m_fs_id, 1, /* n_sh3_body_parts */
1454                                    &fs_code_specialized_raw, &has_shader_compilation_failed))
1455     {
1456         m_testCtx.getLog() << tcu::TestLog::Message
1457                            << "Program object was linked successfully, whereas a failure was expected."
1458                            << tcu::TestLog::EndMessage;
1459 
1460         result = false;
1461     }
1462 
1463     if (result)
1464     {
1465         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1466     }
1467     else
1468     {
1469         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1470     }
1471 
1472     return STOP;
1473 }
1474 
1475 /** Constructor
1476  *
1477  * @param context       Test context
1478  * @param extParams     Not used.
1479  * @param name          Test case's name
1480  * @param description   Test case's description
1481  **/
GeometryShaderLocationAliasingTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)1482 GeometryShaderLocationAliasingTest::GeometryShaderLocationAliasingTest(Context &context, const ExtParameters &extParams,
1483                                                                        const char *name, const char *description)
1484     : TestCaseBase(context, extParams, name, description)
1485     , m_fs_id(0)
1486     , m_gs_id(0)
1487     , m_po_id(0)
1488     , m_vs_id(0)
1489 {
1490 }
1491 
1492 /** Deinitializes GLES objects created during the test. */
deinit()1493 void GeometryShaderLocationAliasingTest::deinit()
1494 {
1495     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1496 
1497     if (m_fs_id != 0)
1498     {
1499         gl.deleteShader(m_fs_id);
1500 
1501         m_fs_id = 0;
1502     }
1503 
1504     if (m_gs_id != 0)
1505     {
1506         gl.deleteShader(m_gs_id);
1507 
1508         m_gs_id = 0;
1509     }
1510 
1511     if (m_po_id != 0)
1512     {
1513         gl.deleteProgram(m_po_id);
1514 
1515         m_po_id = 0;
1516     }
1517 
1518     if (m_vs_id != 0)
1519     {
1520         gl.deleteShader(m_vs_id);
1521 
1522         m_vs_id = 0;
1523     }
1524 
1525     /* Release base class */
1526     TestCaseBase::deinit();
1527 }
1528 
1529 /** Executes the test.
1530  *
1531  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
1532  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
1533  *  Note the function throws exception should an error occur!
1534  **/
iterate()1535 tcu::TestNode::IterateResult GeometryShaderLocationAliasingTest::iterate()
1536 {
1537     bool has_program_link_succeeded = true;
1538     bool result                     = true;
1539 
1540     /* This test should only run if EXT_geometry_shader is supported. */
1541     if (!m_is_geometry_shader_extension_supported)
1542     {
1543         throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
1544     }
1545 
1546     /* Create a program object */
1547     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1548 
1549     m_po_id = gl.createProgram();
1550 
1551     GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
1552 
1553     /* Create shader objects */
1554     m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
1555     m_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
1556     m_vs_id = gl.createShader(GL_VERTEX_SHADER);
1557 
1558     GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
1559 
1560     /* Try to link the test program object */
1561     const char *gs_code_raw = "${VERSION}\n"
1562                               "${GEOMETRY_SHADER_REQUIRE}\n"
1563                               "\n"
1564                               "layout (points)                   in;\n"
1565                               "layout (points, max_vertices = 1) out;\n"
1566                               "\n"
1567                               "layout (location = 2) out vec4 test;\n"
1568                               "layout (location = 2) out vec4 test2;\n"
1569                               "\n"
1570                               "void main()\n"
1571                               "{\n"
1572                               "    gl_Position = gl_in[0].gl_Position;\n"
1573                               "    test = vec4(1.0, 0.0, 0.0, 1.0);\n"
1574                               "    test2 = vec4(1.0, 0.0, 0.0, 1.0);\n"
1575                               "    EmitVertex();\n"
1576                               "}\n";
1577 
1578     std::string fs_code_specialized     = specializeShader(1, &minimal_fs_code);
1579     const char *fs_code_specialized_raw = fs_code_specialized.c_str();
1580     std::string gs_code_specialized     = specializeShader(1, &gs_code_raw);
1581     const char *gs_code_specialized_raw = gs_code_specialized.c_str();
1582     std::string vs_code_specialized     = specializeShader(1, &minimal_vs_code);
1583     const char *vs_code_specialized_raw = vs_code_specialized.c_str();
1584 
1585     has_program_link_succeeded = TestCaseBase::buildProgram(
1586         m_po_id, m_gs_id, 1 /* n_sh1_body_parts */, &gs_code_specialized_raw, m_vs_id, 1 /* n_sh2_body_parts */,
1587         &vs_code_specialized_raw, m_fs_id, 1 /* n_sh3_body_parts */, &fs_code_specialized_raw, NULL);
1588     if (has_program_link_succeeded)
1589     {
1590         m_testCtx.getLog() << tcu::TestLog::Message
1591                            << "Program object was compiled and linked successfully, whereas a failure was expected."
1592                            << tcu::TestLog::EndMessage;
1593 
1594         result = false;
1595     }
1596 
1597     if (result)
1598     {
1599         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1600     }
1601     else
1602     {
1603         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1604     }
1605 
1606     return STOP;
1607 }
1608 
1609 /** Constructor
1610  *
1611  * @param context       Test context
1612  * @param extParams     Not used.
1613  * @param name          Test case's name
1614  * @param description   Test case's description
1615  **/
GeometryShaderMoreACsInGSThanSupportedTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)1616 GeometryShaderMoreACsInGSThanSupportedTest::GeometryShaderMoreACsInGSThanSupportedTest(Context &context,
1617                                                                                        const ExtParameters &extParams,
1618                                                                                        const char *name,
1619                                                                                        const char *description)
1620     : TestCaseBase(context, extParams, name, description)
1621     , m_fs_id(0)
1622     , m_gs_id(0)
1623     , m_po_id(0)
1624     , m_vs_id(0)
1625 {
1626 }
1627 
1628 /** Deinitializes GLES objects created during the test. */
deinit()1629 void GeometryShaderMoreACsInGSThanSupportedTest::deinit()
1630 {
1631     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1632 
1633     if (m_fs_id != 0)
1634     {
1635         gl.deleteShader(m_fs_id);
1636 
1637         m_fs_id = 0;
1638     }
1639 
1640     if (m_gs_id != 0)
1641     {
1642         gl.deleteShader(m_gs_id);
1643 
1644         m_gs_id = 0;
1645     }
1646 
1647     if (m_po_id != 0)
1648     {
1649         gl.deleteProgram(m_po_id);
1650 
1651         m_po_id = 0;
1652     }
1653 
1654     if (m_vs_id != 0)
1655     {
1656         gl.deleteShader(m_vs_id);
1657 
1658         m_vs_id = 0;
1659     }
1660 
1661     /* Release base class */
1662     TestCaseBase::deinit();
1663 }
1664 
1665 /* Retrieves test-specific geometry shader source code.
1666  *
1667  * @return Requested string.
1668  */
getGSCode()1669 std::string GeometryShaderMoreACsInGSThanSupportedTest::getGSCode()
1670 {
1671     std::stringstream code_sstream;
1672     const glw::Functions &gl    = m_context.getRenderContext().getFunctions();
1673     glw::GLint gl_max_ACs_value = 0;
1674 
1675     /* Retrieve GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT pname value */
1676     gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_ATOMIC_COUNTERS, &gl_max_ACs_value);
1677     GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT pname");
1678 
1679     /* Form the GS */
1680     code_sstream << "${VERSION}\n"
1681                     "${GEOMETRY_SHADER_REQUIRE}\n"
1682                     "\n"
1683                     "layout (points)                   in;\n"
1684                     "layout (points, max_vertices = 1) out;\n"
1685                     "\n";
1686 
1687     for (glw::GLint n_ac = 0; n_ac < (gl_max_ACs_value + 1); ++n_ac)
1688     {
1689         code_sstream << "layout(binding = 0) uniform atomic_uint counter" << n_ac << ";\n";
1690     }
1691 
1692     code_sstream << "\n"
1693                     "void main()\n"
1694                     "{\n";
1695 
1696     for (glw::GLint n_ac = 0; n_ac < (gl_max_ACs_value + 1); ++n_ac)
1697     {
1698         code_sstream << "    if ((gl_PrimitiveIDIn % " << (n_ac + 1) << ") == 0) atomicCounterIncrement(counter" << n_ac
1699                      << ");\n";
1700     }
1701 
1702     code_sstream << "\n"
1703                     "    gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n"
1704                     "    EmitVertex();\n"
1705                     "}\n";
1706 
1707     /* Form a specialized version of the GS source code */
1708     std::string gs_code             = code_sstream.str();
1709     const char *gs_code_raw         = gs_code.c_str();
1710     std::string gs_code_specialized = specializeShader(1, /* parts */
1711                                                        &gs_code_raw);
1712 
1713     return gs_code_specialized;
1714 }
1715 
1716 /** Executes the test.
1717  *
1718  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
1719  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
1720  *  Note the function throws exception should an error occur!
1721  **/
iterate()1722 tcu::TestNode::IterateResult GeometryShaderMoreACsInGSThanSupportedTest::iterate()
1723 {
1724     bool has_shader_compilation_failed = true;
1725     bool result                        = true;
1726 
1727     /* This test should only run if EXT_geometry_shader is supported. */
1728     if (!m_is_geometry_shader_extension_supported)
1729     {
1730         throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
1731     }
1732 
1733     /* Create a program object */
1734     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1735 
1736     m_po_id = gl.createProgram();
1737 
1738     GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
1739 
1740     /* Create shader objects */
1741     m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
1742     m_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
1743     m_vs_id = gl.createShader(GL_VERTEX_SHADER);
1744 
1745     GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
1746 
1747     /* Try to link the test program object */
1748     std::string fs_code_specialized     = specializeShader(1, &minimal_fs_code);
1749     const char *fs_code_specialized_raw = fs_code_specialized.c_str();
1750     std::string gs_code_specialized     = getGSCode();
1751     const char *gs_code_specialized_raw = gs_code_specialized.c_str();
1752     std::string vs_code_specialized     = specializeShader(1, &minimal_vs_code);
1753     const char *vs_code_specialized_raw = vs_code_specialized.c_str();
1754 
1755     if (TestCaseBase::buildProgram(m_po_id, m_gs_id, 1,                  /* n_sh1_body_parts */
1756                                    &gs_code_specialized_raw, m_vs_id, 1, /* n_sh2_body_parts */
1757                                    &vs_code_specialized_raw, m_fs_id, 1, /* n_sh3_body_parts */
1758                                    &fs_code_specialized_raw, &has_shader_compilation_failed))
1759     {
1760         m_testCtx.getLog() << tcu::TestLog::Message
1761                            << "Program object was linked successfully, whereas a failure was expected."
1762                            << tcu::TestLog::EndMessage;
1763 
1764         result = false;
1765     }
1766 
1767     if (result)
1768     {
1769         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1770     }
1771     else
1772     {
1773         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1774     }
1775 
1776     return STOP;
1777 }
1778 
1779 /** Constructor
1780  *
1781  * @param context       Test context
1782  * @param extParams     Not used.
1783  * @param name          Test case's name
1784  * @param description   Test case's description
1785  **/
GeometryShaderMoreACBsInGSThanSupportedTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)1786 GeometryShaderMoreACBsInGSThanSupportedTest::GeometryShaderMoreACBsInGSThanSupportedTest(Context &context,
1787                                                                                          const ExtParameters &extParams,
1788                                                                                          const char *name,
1789                                                                                          const char *description)
1790     : TestCaseBase(context, extParams, name, description)
1791     , m_fs_id(0)
1792     , m_gs_id(0)
1793     , m_po_id(0)
1794     , m_vs_id(0)
1795 {
1796 }
1797 
1798 /** Deinitializes GLES objects created during the test. */
deinit()1799 void GeometryShaderMoreACBsInGSThanSupportedTest::deinit()
1800 {
1801     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1802 
1803     if (m_fs_id != 0)
1804     {
1805         gl.deleteShader(m_fs_id);
1806 
1807         m_fs_id = 0;
1808     }
1809 
1810     if (m_gs_id != 0)
1811     {
1812         gl.deleteShader(m_gs_id);
1813 
1814         m_gs_id = 0;
1815     }
1816 
1817     if (m_po_id != 0)
1818     {
1819         gl.deleteProgram(m_po_id);
1820 
1821         m_po_id = 0;
1822     }
1823 
1824     if (m_vs_id != 0)
1825     {
1826         gl.deleteShader(m_vs_id);
1827 
1828         m_vs_id = 0;
1829     }
1830 
1831     /* Release base class */
1832     TestCaseBase::deinit();
1833 }
1834 
1835 /* Retrieves test-specific geometry shader source code.
1836  *
1837  * @return Requested string.
1838  */
getGSCode()1839 std::string GeometryShaderMoreACBsInGSThanSupportedTest::getGSCode()
1840 {
1841     std::stringstream code_sstream;
1842     const glw::Functions &gl     = m_context.getRenderContext().getFunctions();
1843     glw::GLint gl_max_ACBs_value = 0;
1844 
1845     /* Retrieve GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT pname value */
1846     gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS, &gl_max_ACBs_value);
1847     GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT pname");
1848 
1849     /* Form the GS */
1850     code_sstream << "${VERSION}\n"
1851                     "${GEOMETRY_SHADER_REQUIRE}\n"
1852                     "\n"
1853                     "layout (points)                   in;\n"
1854                     "layout (points, max_vertices = 1) out;\n"
1855                     "\n";
1856 
1857     for (glw::GLint n_acb = 0; n_acb < (gl_max_ACBs_value + 1); ++n_acb)
1858     {
1859         code_sstream << "layout(binding = " << n_acb << ") uniform atomic_uint counter" << n_acb << ";\n";
1860     }
1861 
1862     code_sstream << "\n"
1863                     "void main()\n"
1864                     "{\n";
1865 
1866     for (glw::GLint n_acb = 0; n_acb < (gl_max_ACBs_value + 1); ++n_acb)
1867     {
1868         code_sstream << "    if ((gl_PrimitiveIDIn % " << (n_acb + 1) << ") == 0) atomicCounterIncrement(counter"
1869                      << n_acb << ");\n";
1870     }
1871 
1872     code_sstream << "\n"
1873                     "    gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n"
1874                     "    EmitVertex();\n"
1875                     "}\n";
1876 
1877     /* Form a specialized version of the GS source code */
1878     std::string gs_code             = code_sstream.str();
1879     const char *gs_code_raw         = gs_code.c_str();
1880     std::string gs_code_specialized = specializeShader(1, /* parts */
1881                                                        &gs_code_raw);
1882 
1883     return gs_code_specialized;
1884 }
1885 
1886 /** Executes the test.
1887  *
1888  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
1889  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
1890  *  Note the function throws exception should an error occur!
1891  **/
iterate()1892 tcu::TestNode::IterateResult GeometryShaderMoreACBsInGSThanSupportedTest::iterate()
1893 {
1894     bool has_shader_compilation_failed = true;
1895     bool result                        = true;
1896 
1897     /* This test should only run if EXT_geometry_shader is supported. */
1898     if (!m_is_geometry_shader_extension_supported)
1899     {
1900         throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
1901     }
1902 
1903     /* Create a program object */
1904     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1905 
1906     m_po_id = gl.createProgram();
1907 
1908     GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
1909 
1910     /* Create shader objects */
1911     m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
1912     m_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
1913     m_vs_id = gl.createShader(GL_VERTEX_SHADER);
1914 
1915     GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
1916 
1917     /* Try to link the test program object */
1918     std::string fs_code_specialized     = specializeShader(1, &minimal_fs_code);
1919     const char *fs_code_specialized_raw = fs_code_specialized.c_str();
1920     std::string gs_code_specialized     = getGSCode();
1921     const char *gs_code_specialized_raw = gs_code_specialized.c_str();
1922     std::string vs_code_specialized     = specializeShader(1, &minimal_vs_code);
1923     const char *vs_code_specialized_raw = vs_code_specialized.c_str();
1924 
1925     if (TestCaseBase::buildProgram(m_po_id, m_gs_id, 1,                  /* n_sh1_body_parts */
1926                                    &gs_code_specialized_raw, m_vs_id, 1, /* n_sh2_body_parts */
1927                                    &vs_code_specialized_raw, m_fs_id, 1, /* n_sh3_body_parts */
1928                                    &fs_code_specialized_raw, &has_shader_compilation_failed))
1929     {
1930         m_testCtx.getLog() << tcu::TestLog::Message
1931                            << "Program object was linked successfully, whereas a failure was expected."
1932                            << tcu::TestLog::EndMessage;
1933 
1934         result = false;
1935     }
1936 
1937     if (result)
1938     {
1939         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1940     }
1941     else
1942     {
1943         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1944     }
1945 
1946     return STOP;
1947 }
1948 
1949 /** Constructor
1950  *
1951  * @param context       Test context
1952  * @param extParams     Not used.
1953  * @param name          Test case's name
1954  * @param description   Test case's description
1955  **/
GeometryShaderCompilationFailTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)1956 GeometryShaderCompilationFailTest::GeometryShaderCompilationFailTest(Context &context, const ExtParameters &extParams,
1957                                                                      const char *name, const char *description)
1958     : TestCaseBase(context, extParams, name, description)
1959     , m_fs_id(0)
1960     , m_gs_id(0)
1961     , m_po_id(0)
1962     , m_vs_id(0)
1963 {
1964 }
1965 
1966 /** Deinitializes GLES objects created during the test. */
deinit()1967 void GeometryShaderCompilationFailTest::deinit()
1968 {
1969     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1970 
1971     if (m_fs_id != 0)
1972     {
1973         gl.deleteShader(m_fs_id);
1974 
1975         m_fs_id = 0;
1976     }
1977 
1978     if (m_gs_id != 0)
1979     {
1980         gl.deleteShader(m_gs_id);
1981 
1982         m_gs_id = 0;
1983     }
1984 
1985     if (m_po_id != 0)
1986     {
1987         gl.deleteProgram(m_po_id);
1988 
1989         m_po_id = 0;
1990     }
1991 
1992     if (m_vs_id != 0)
1993     {
1994         gl.deleteShader(m_vs_id);
1995 
1996         m_vs_id = 0;
1997     }
1998 
1999     /* Release base class */
2000     TestCaseBase::deinit();
2001 }
2002 
2003 /** Executes the test.
2004  *
2005  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
2006  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
2007  *  Note the function throws exception should an error occur!
2008  **/
iterate()2009 tcu::TestNode::IterateResult GeometryShaderCompilationFailTest::iterate()
2010 {
2011     /* Define Vertex Shader's code for the purpose of this test. */
2012     const char *gs_code = "${VERSION}\n"
2013                           "${GEOMETRY_SHADER_REQUIRE}\n"
2014                           "\n"
2015                           "layout (points)                   in;\n"
2016                           "layout (points, max_vertices = 1) out;\n"
2017                           "\n"
2018                           "void main()\n"
2019                           "{\n"
2020                           "    gl_Position = gl_in[0].gl_Position;\n"
2021                           "    mitVertex();\n"
2022                           "}\n";
2023 
2024     bool has_shader_compilation_failed = true;
2025     bool result                        = true;
2026 
2027     /* This test should only run if EXT_geometry_shader is supported. */
2028     if (!m_is_geometry_shader_extension_supported)
2029     {
2030         throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
2031     }
2032 
2033     /* Create a program object */
2034     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2035 
2036     m_po_id = gl.createProgram();
2037 
2038     GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
2039 
2040     /* Create shader objects */
2041     m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
2042     m_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
2043     m_vs_id = gl.createShader(GL_VERTEX_SHADER);
2044 
2045     GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
2046 
2047     /* Try to link the test program object */
2048     std::string fs_code_specialized     = specializeShader(1, &minimal_fs_code);
2049     const char *fs_code_specialized_raw = fs_code_specialized.c_str();
2050 
2051     std::string gs_code_specialized     = specializeShader(1, &gs_code);
2052     const char *gs_code_specialized_raw = gs_code_specialized.c_str();
2053 
2054     std::string vs_code_specialized     = specializeShader(1, &minimal_vs_code);
2055     const char *vs_code_specialized_raw = vs_code_specialized.c_str();
2056 
2057     if (TestCaseBase::buildProgram(m_po_id, m_gs_id, 1,                  /* n_sh1_body_parts */
2058                                    &gs_code_specialized_raw, m_vs_id, 1, /* n_sh2_body_parts */
2059                                    &vs_code_specialized_raw, m_fs_id, 1, /* n_sh3_body_parts */
2060                                    &fs_code_specialized_raw, &has_shader_compilation_failed))
2061     {
2062         m_testCtx.getLog() << tcu::TestLog::Message
2063                            << "Program object was linked successfully, whereas a failure was expected."
2064                            << tcu::TestLog::EndMessage;
2065 
2066         result = false;
2067     }
2068 
2069     if (!has_shader_compilation_failed)
2070     {
2071         m_testCtx.getLog() << tcu::TestLog::Message << "Shader compilation succeeded, whereas a failure was expected."
2072                            << tcu::TestLog::EndMessage;
2073 
2074         result = false;
2075     }
2076 
2077     if (result)
2078     {
2079         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2080     }
2081     else
2082     {
2083         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2084     }
2085 
2086     return STOP;
2087 }
2088 
2089 /** Constructor
2090  *
2091  * @param context       Test context
2092  * @param extParams     Not used.
2093  * @param name          Test case's name
2094  * @param description   Test case's description
2095  **/
GeometryShaderMoreInputVerticesThanAvailableTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)2096 GeometryShaderMoreInputVerticesThanAvailableTest::GeometryShaderMoreInputVerticesThanAvailableTest(
2097     Context &context, const ExtParameters &extParams, const char *name, const char *description)
2098     : TestCaseBase(context, extParams, name, description)
2099     , m_fs_id(0)
2100     , m_gs_ids(NULL)
2101     , m_number_of_gs(5 /*taken from test spec*/)
2102     , m_po_ids(NULL)
2103     , m_vs_id(0)
2104     , m_vao_id(0)
2105 {
2106 }
2107 
2108 /** Deinitializes GLES objects created during the test. */
deinit()2109 void GeometryShaderMoreInputVerticesThanAvailableTest::deinit()
2110 {
2111     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2112 
2113     if (m_fs_id != 0)
2114     {
2115         gl.deleteShader(m_fs_id);
2116         m_fs_id = 0;
2117     }
2118 
2119     if (m_gs_ids != 0)
2120     {
2121         for (glw::GLuint i = 0; i < m_number_of_gs; ++i)
2122         {
2123             gl.deleteShader(m_gs_ids[i]);
2124             m_gs_ids[i] = 0;
2125         }
2126 
2127         delete[] m_gs_ids;
2128         m_gs_ids = NULL;
2129     }
2130 
2131     if (m_po_ids != 0)
2132     {
2133         for (glw::GLuint i = 0; i < m_number_of_gs; ++i)
2134         {
2135             gl.deleteProgram(m_po_ids[i]);
2136             m_po_ids[i] = 0;
2137         }
2138 
2139         delete[] m_po_ids;
2140         m_po_ids = NULL;
2141     }
2142 
2143     if (m_vs_id != 0)
2144     {
2145         gl.deleteShader(m_vs_id);
2146         m_vs_id = 0;
2147     }
2148 
2149     if (m_vao_id != 0)
2150     {
2151         gl.deleteVertexArrays(1, &m_vao_id);
2152         m_vao_id = 0;
2153     }
2154 
2155     /* Release base class */
2156     TestCaseBase::deinit();
2157 }
2158 
2159 /** Executes the test.
2160  *
2161  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
2162  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
2163  *  Note the function throws exception should an error occur!
2164  **/
iterate()2165 tcu::TestNode::IterateResult GeometryShaderMoreInputVerticesThanAvailableTest::iterate()
2166 {
2167     /* Define 5 Geometry Shaders for purpose of this test. */
2168     const char *gs_code_points = "${VERSION}\n"
2169                                  "${GEOMETRY_SHADER_REQUIRE}\n"
2170                                  "\n"
2171                                  "layout (points)                   in;\n"
2172                                  "layout (points, max_vertices = 1) out;\n"
2173                                  "\n"
2174                                  "void main()\n"
2175                                  "{\n"
2176                                  "    gl_Position = gl_in[1].gl_Position;\n"
2177                                  "    EmitVertex();\n"
2178                                  "}\n";
2179 
2180     const char *gs_code_lines = "${VERSION}\n"
2181                                 "${GEOMETRY_SHADER_REQUIRE}\n"
2182                                 "\n"
2183                                 "layout (lines)                    in;\n"
2184                                 "layout (points, max_vertices = 1) out;\n"
2185                                 "\n"
2186                                 "void main()\n"
2187                                 "{\n"
2188                                 "    gl_Position = gl_in[2].gl_Position;\n"
2189                                 "    EmitVertex();\n"
2190                                 "}\n";
2191 
2192     const char *gs_code_lines_adjacency = "${VERSION}\n"
2193                                           "${GEOMETRY_SHADER_REQUIRE}\n"
2194                                           "\n"
2195                                           "layout (lines_adjacency)          in;\n"
2196                                           "layout (points, max_vertices = 1) out;\n"
2197                                           "\n"
2198                                           "void main()\n"
2199                                           "{\n"
2200                                           "    gl_Position = gl_in[4].gl_Position;\n"
2201                                           "    EmitVertex();\n"
2202                                           "}\n";
2203 
2204     const char *gs_code_triangles = "${VERSION}\n"
2205                                     "${GEOMETRY_SHADER_REQUIRE}\n"
2206                                     "\n"
2207                                     "layout (triangles)                in;\n"
2208                                     "layout (points, max_vertices = 1) out;\n"
2209                                     "\n"
2210                                     "void main()\n"
2211                                     "{\n"
2212                                     "    gl_Position = gl_in[3].gl_Position;\n"
2213                                     "    EmitVertex();\n"
2214                                     "}\n";
2215 
2216     const char *gs_code_triangles_adjacency = "${VERSION}\n"
2217                                               "${GEOMETRY_SHADER_REQUIRE}\n"
2218                                               "\n"
2219                                               "layout (triangles_adjacency)      in;\n"
2220                                               "layout (points, max_vertices = 1) out;\n"
2221                                               "\n"
2222                                               "void main()\n"
2223                                               "{\n"
2224                                               "    gl_Position = gl_in[6].gl_Position;\n"
2225                                               "    EmitVertex();\n"
2226                                               "}\n";
2227 
2228     bool has_shader_compilation_failed = true;
2229     bool result                        = true;
2230 
2231     m_gs_ids = new glw::GLuint[m_number_of_gs];
2232     m_po_ids = new glw::GLuint[m_number_of_gs];
2233 
2234     /* This test should only run if EXT_geometry_shader is supported. */
2235     if (!m_is_geometry_shader_extension_supported)
2236     {
2237         throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
2238     }
2239 
2240     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2241 
2242     /* Create program objects & geometry shader objects. */
2243     for (glw::GLuint i = 0; i < m_number_of_gs; ++i)
2244     {
2245         m_gs_ids[i] = gl.createShader(GL_GEOMETRY_SHADER);
2246         GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
2247 
2248         m_po_ids[i] = gl.createProgram();
2249         GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
2250     }
2251 
2252     /* Create shader object. */
2253     m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
2254     m_vs_id = gl.createShader(GL_VERTEX_SHADER);
2255     GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
2256 
2257     /* Try to link the test program object */
2258     std::string fs_code_specialized     = specializeShader(1, &minimal_fs_code);
2259     const char *fs_code_specialized_raw = fs_code_specialized.c_str();
2260 
2261     std::string gs_codes_specialized[] = {specializeShader(1, &gs_code_points), specializeShader(1, &gs_code_lines),
2262                                           specializeShader(1, &gs_code_lines_adjacency),
2263                                           specializeShader(1, &gs_code_triangles),
2264                                           specializeShader(1, &gs_code_triangles_adjacency)};
2265 
2266     const char *gs_codes_specialized_raw[] = {gs_codes_specialized[0].c_str(), gs_codes_specialized[1].c_str(),
2267                                               gs_codes_specialized[2].c_str(), gs_codes_specialized[3].c_str(),
2268                                               gs_codes_specialized[4].c_str()};
2269 
2270     std::string vs_code_specialized     = specializeShader(1, &minimal_vs_code);
2271     const char *vs_code_specialized_raw = vs_code_specialized.c_str();
2272 
2273     for (glw::GLuint i = 0; i < m_number_of_gs; ++i)
2274     {
2275         if (TestCaseBase::buildProgram(m_po_ids[i], m_fs_id, 1,                  /* n_sh1_body_parts */
2276                                        &fs_code_specialized_raw, m_gs_ids[i], 1, /* n_sh2_body_parts */
2277                                        &gs_codes_specialized_raw[i], m_vs_id, 1, /* n_sh3_body_parts */
2278                                        &vs_code_specialized_raw, &has_shader_compilation_failed))
2279         {
2280             m_testCtx.getLog() << tcu::TestLog::Message << "Program object linking successful for i = "
2281                                << "[" << i << "], whereas a failure was expected." << tcu::TestLog::EndMessage;
2282 
2283             result = false;
2284             break;
2285         }
2286     }
2287 
2288     if (result)
2289     {
2290         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2291     }
2292     else
2293     {
2294         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2295     }
2296 
2297     return STOP;
2298 }
2299 
2300 /** Constructor
2301  *
2302  * @param context       Test context
2303  * @param extParams     Not used.
2304  * @param name          Test case's name
2305  * @param description   Test case's description
2306  **/
2307 GeometryShaderTransformFeedbackVertexAndGeometryShaderCaptureTest::
GeometryShaderTransformFeedbackVertexAndGeometryShaderCaptureTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)2308     GeometryShaderTransformFeedbackVertexAndGeometryShaderCaptureTest(Context &context, const ExtParameters &extParams,
2309                                                                       const char *name, const char *description)
2310     : TestCaseBase(context, extParams, name, description)
2311     , m_fs_id(0)
2312     , m_gs_id(0)
2313     , m_po_id(0)
2314     , m_vs_id(0)
2315 {
2316 }
2317 
2318 /** Deinitializes GLES objects created during the test. */
deinit()2319 void GeometryShaderTransformFeedbackVertexAndGeometryShaderCaptureTest::deinit()
2320 {
2321     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2322 
2323     if (m_fs_id != 0)
2324     {
2325         gl.deleteShader(m_fs_id);
2326         m_fs_id = 0;
2327     }
2328 
2329     if (m_gs_id != 0)
2330     {
2331         gl.deleteShader(m_gs_id);
2332         m_gs_id = 0;
2333     }
2334 
2335     if (m_po_id != 0)
2336     {
2337         gl.deleteProgram(m_po_id);
2338         m_po_id = 0;
2339     }
2340 
2341     if (m_vs_id != 0)
2342     {
2343         gl.deleteShader(m_vs_id);
2344         m_vs_id = 0;
2345     }
2346 
2347     /* Release base class */
2348     TestCaseBase::deinit();
2349 }
2350 
2351 /** Executes the test.
2352  *
2353  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
2354  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
2355  *  Note the function throws exception should an error occur!
2356  **/
iterate()2357 tcu::TestNode::IterateResult GeometryShaderTransformFeedbackVertexAndGeometryShaderCaptureTest::iterate()
2358 {
2359     /* Define Geometry Shader for purpose of this test. */
2360     const char *gs_code =
2361         "${VERSION}\n"
2362         "${GEOMETRY_SHADER_REQUIRE}\n"
2363         "\n"
2364         "layout (points)                   in;\n"
2365         "layout (points, max_vertices = 1) out;\n"
2366         "\n"
2367         "in int vertexID;\n"
2368         "out vec4 out_gs_1;\n"
2369         "\n"
2370         "void main()\n"
2371         "{\n"
2372         "    out_gs_1 = vec4(vertexID[0] * 2, vertexID[0] * 2 + 1, vertexID[0] * 2 + 2, vertexID[0] * 2 + 3);\n"
2373         "    gl_Position = vec4(0, 0, 0, 1);\n"
2374         "    EmitVertex();\n"
2375         "}\n";
2376 
2377     /* Define Vertex Shader for purpose of this test. */
2378     const char *vs_code = "${VERSION}\n"
2379                           "\n"
2380                           "flat out ivec4 out_vs_1;\n"
2381                           "flat out int vertexID;\n"
2382                           "\n"
2383                           "void main()\n"
2384                           "{\n"
2385                           "    vertexID = gl_VertexID;\n"
2386                           "    out_vs_1 = ivec4(gl_VertexID, gl_VertexID + 1, gl_VertexID + 2, gl_VertexID + 3);\n"
2387                           "    gl_Position = vec4(1.0, 0.0, 0.0, 1.0);\n"
2388                           "}\n";
2389 
2390     bool has_shader_compilation_failed = true;
2391     bool result                        = true;
2392 
2393     /* This test should only run if EXT_geometry_shader is supported. */
2394     if (!m_is_geometry_shader_extension_supported)
2395     {
2396         throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
2397     }
2398 
2399     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2400 
2401     /* Create program object. */
2402     m_po_id = gl.createProgram();
2403     GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call(s) failed.");
2404 
2405     /* Specify output variables to be captured. */
2406     const char *tf_varyings[] = {"out_vs_1", "out_gs_1"};
2407 
2408     gl.transformFeedbackVaryings(m_po_id, 2 /*count*/, tf_varyings, GL_INTERLEAVED_ATTRIBS);
2409     GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings() call(s) failed.");
2410 
2411     /* Create shader objects. */
2412     m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
2413     m_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
2414     m_vs_id = gl.createShader(GL_VERTEX_SHADER);
2415     GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
2416 
2417     /* Try to link the test program object */
2418     std::string fs_code_specialized     = specializeShader(1, &minimal_fs_code);
2419     const char *fs_code_specialized_raw = fs_code_specialized.c_str();
2420 
2421     std::string gs_code_specialized     = specializeShader(1, &gs_code);
2422     const char *gs_code_specialized_raw = fs_code_specialized.c_str();
2423 
2424     std::string vs_code_specialized     = specializeShader(1, &vs_code);
2425     const char *vs_code_specialized_raw = vs_code_specialized.c_str();
2426 
2427     if (TestCaseBase::buildProgram(m_po_id, m_fs_id, 1,                  /* n_sh1_body_parts */
2428                                    &fs_code_specialized_raw, m_gs_id, 1, /* n_sh2_body_parts */
2429                                    &gs_code_specialized_raw, m_vs_id, 1, /* n_sh3_body_parts */
2430                                    &vs_code_specialized_raw, &has_shader_compilation_failed))
2431     {
2432         m_testCtx.getLog() << tcu::TestLog::Message
2433                            << "Program object linking successful, whereas a failure was expected."
2434                            << tcu::TestLog::EndMessage;
2435 
2436         result = false;
2437     }
2438 
2439     if (result)
2440     {
2441         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2442     }
2443     else
2444     {
2445         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2446     }
2447 
2448     return STOP;
2449 }
2450 
2451 } // namespace glcts
2452