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