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 ¤t_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 ¤t_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 ¤t_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 ¤t_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