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