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