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 /** Empty init function */
init()294 void InputVariablesCannotBeModifiedTest::init()
295 {
296 /* Left blank on purpose */
297 }
298
299 /** Retrieves a literal corresponding to the test iteration enum.
300 *
301 * @param iteration Enum to retrieve the string for.
302 *
303 * @return Requested object.
304 **/
getIterationName(_test_iteration iteration) const305 std::string InputVariablesCannotBeModifiedTest::getIterationName(_test_iteration iteration) const
306 {
307 std::string result;
308
309 switch (iteration)
310 {
311 case TEST_ITERATION_INPUT_FS_VARIABLE:
312 result = "Fragment shader input variable";
313 break;
314 case TEST_ITERATION_INPUT_FS_VARIABLE_IN_INPUT_BLOCK:
315 result = "Fragment shader input variable wrapped in an input block";
316 break;
317 case TEST_ITERATION_INPUT_FS_VARIABLE_PASSED_TO_INOUT_FUNCTION_PARAMETER:
318 result = "Fragment shader input variable passed to an inout function parameter";
319 break;
320 case TEST_ITERATION_INPUT_FS_VARIABLE_PASSED_TO_OUT_FUNCTION_PARAMETER:
321 result = "Fragment shader input variable passed to an out function parameter";
322 break;
323 case TEST_ITERATION_INPUT_GS_VARIABLE:
324 result = "Geometry shader input variable";
325 break;
326 case TEST_ITERATION_INPUT_GS_VARIABLE_IN_INPUT_BLOCK:
327 result = "Geometry shader input variable wrapped in an input block";
328 break;
329 case TEST_ITERATION_INPUT_GS_VARIABLE_PASSED_TO_INOUT_FUNCTION_PARAMETER:
330 result = "Geometry shader input variable passed to an inout function parameter";
331 break;
332 case TEST_ITERATION_INPUT_GS_VARIABLE_PASSED_TO_OUT_FUNCTION_PARAMETER:
333 result = "Geometry shader input variable passed to an out function parameter";
334 break;
335 case TEST_ITERATION_INPUT_TC_VARIABLE_IN_INPUT_BLOCK:
336 result = "Tessellation control shader variable wrapped in an input block";
337 break;
338 case TEST_ITERATION_INPUT_TC_VARIABLE_PASSED_TO_INOUT_FUNCTION_PARAMETER:
339 result = "Tessellation control shader variable passed to an inout function parameter";
340 break;
341 case TEST_ITERATION_INPUT_TC_VARIABLE_PASSED_TO_OUT_FUNCTION_PARAMETER:
342 result = "Tessellation control shader variable passed to an out function parameter";
343 break;
344 case TEST_ITERATION_INPUT_TE_PATCH_VARIABLE:
345 result = "Tessellation evaluation shader patch input variable";
346 break;
347 case TEST_ITERATION_INPUT_TE_VARIABLE:
348 result = "Tessellation evaluation shader input variable";
349 break;
350 case TEST_ITERATION_INPUT_TE_VARIABLE_IN_INPUT_BLOCK:
351 result = "Tessellation evaluation shader patch input variable wrapped in an input block";
352 break;
353 case TEST_ITERATION_INPUT_TE_VARIABLE_PASSED_TO_INOUT_FUNCTION_PARAMETER:
354 result = "Tessellation evlauation shader patch input variable passed to an inout function parameter";
355 break;
356 case TEST_ITERATION_INPUT_TE_VARIABLE_PASSED_TO_OUT_FUNCTION_PARAMETER:
357 result = "Tessellation evaluation shader patch input variable passed to an out function parameter";
358 break;
359 case TEST_ITERATION_INPUT_VS_VARIABLE:
360 result = "Vertex shader input variable";
361 break;
362 case TEST_ITERATION_INPUT_VS_VARIABLE_PASSED_TO_INOUT_FUNCTION_PARAMETER:
363 result = "Vertex shader input variable passed to an inout function parameter";
364 break;
365 case TEST_ITERATION_INPUT_VS_VARIABLE_PASSED_TO_OUT_FUNCTION_PARAMETER:
366 result = "Vertex shader input variable passed to an out function parameter";
367 break;
368
369 default:
370 TCU_FAIL("Unrecognized test iteration type.");
371 } /* switch (iteration) */
372
373 return result;
374 }
375
376 /** Retrieves a vertex shader body for the user-specified iteration enum.
377 *
378 * @param iteration Iteration to retrieve the shader body for.
379 *
380 * @return Requested string object.
381 */
getIterationData(_test_iteration iteration,glu::ApiType * out_required_min_context_type_ptr,_shader_stage * out_target_shader_stage_ptr,std::string * out_body_ptr) const382 void InputVariablesCannotBeModifiedTest::getIterationData(_test_iteration iteration,
383 glu::ApiType* out_required_min_context_type_ptr,
384 _shader_stage* out_target_shader_stage_ptr,
385 std::string* out_body_ptr) const
386 {
387 switch (iteration)
388 {
389 case TEST_ITERATION_INPUT_FS_VARIABLE:
390 {
391 *out_required_min_context_type_ptr = glu::ApiType::core(3, 1);
392 *out_target_shader_stage_ptr = SHADER_STAGE_FRAGMENT;
393
394 *out_body_ptr = "#version 140\n"
395 "\n"
396 "in vec4 data;\n"
397 "out vec4 result;\n"
398 "\n"
399 "void main()\n"
400 "{\n"
401 " data += vec4(1.0);\n"
402 " result = data;\n"
403 "}\n";
404
405 break;
406 }
407
408 case TEST_ITERATION_INPUT_FS_VARIABLE_IN_INPUT_BLOCK:
409 {
410 *out_required_min_context_type_ptr = glu::ApiType::core(4, 0);
411 *out_target_shader_stage_ptr = SHADER_STAGE_FRAGMENT;
412
413 *out_body_ptr = "#version 400\n"
414 "\n"
415 "in inputBlock\n"
416 "{\n"
417 " vec4 data;\n"
418 "};\n"
419 "\n"
420 "out vec4 result;\n"
421 "\n"
422 "void main()\n"
423 "{\n"
424 " data += vec4(1.0);\n"
425 " result = data;\n"
426 "}\n";
427
428 break;
429 }
430
431 case TEST_ITERATION_INPUT_FS_VARIABLE_PASSED_TO_INOUT_FUNCTION_PARAMETER:
432 {
433 *out_required_min_context_type_ptr = glu::ApiType::core(3, 1);
434 *out_target_shader_stage_ptr = SHADER_STAGE_FRAGMENT;
435
436 *out_body_ptr = "#version 140\n"
437 "\n"
438 "in vec4 data;\n"
439 "out vec4 result;\n"
440 "\n"
441 "void testFunc(inout vec4 arg)\n"
442 "{\n"
443 " arg += vec4(1.0);\n"
444 "}\n"
445 "\n"
446 "void main()\n"
447 "{\n"
448 " testFunc(data);\n"
449 "\n"
450 " result = data;\n"
451 "}\n";
452
453 break;
454 }
455
456 case TEST_ITERATION_INPUT_FS_VARIABLE_PASSED_TO_OUT_FUNCTION_PARAMETER:
457 {
458 *out_required_min_context_type_ptr = glu::ApiType::core(3, 1);
459 *out_target_shader_stage_ptr = SHADER_STAGE_FRAGMENT;
460
461 *out_body_ptr = "#version 140\n"
462 "\n"
463 "in vec4 data;\n"
464 "out vec4 result;\n"
465 "\n"
466 "void testFunc(out vec4 arg)\n"
467 "{\n"
468 " arg = vec4(1.0);\n"
469 "}\n"
470 "\n"
471 "void main()\n"
472 "{\n"
473 " testFunc(data);\n"
474 "\n"
475 " result = data;\n"
476 "}\n";
477
478 break;
479 }
480
481 case TEST_ITERATION_INPUT_GS_VARIABLE:
482 {
483 *out_required_min_context_type_ptr = glu::ApiType::core(3, 2);
484 *out_target_shader_stage_ptr = SHADER_STAGE_GEOMETRY;
485
486 *out_body_ptr = "#version 150\n"
487 "\n"
488 "layout(points) in;\n"
489 "layout(points, max_vertices = 1) out;\n"
490 "\n"
491 "in vec4 data[];\n"
492 "\n"
493 "void main()\n"
494 "{\n"
495 " data[0] += vec4(1.0);\n"
496 " gl_Position = data[0];\n"
497 "\n"
498 " EmitVertex();\n"
499 "}\n";
500
501 break;
502 }
503
504 case TEST_ITERATION_INPUT_GS_VARIABLE_IN_INPUT_BLOCK:
505 {
506 *out_required_min_context_type_ptr = glu::ApiType::core(4, 0);
507 *out_target_shader_stage_ptr = SHADER_STAGE_GEOMETRY;
508
509 *out_body_ptr = "#version 400\n"
510 "\n"
511 "layout(points) in;\n"
512 "layout(points, max_vertices = 1) out;\n"
513 "\n"
514 "in inputBlock\n"
515 "{\n"
516 " vec4 data[];\n"
517 "};\n"
518 "\n"
519 "void main()\n"
520 "{\n"
521 " data[0] += vec4(1.0);\n"
522 " gl_Position = data[0];\n"
523 "\n"
524 " EmitVertex();\n"
525 "}\n";
526
527 break;
528 }
529
530 case TEST_ITERATION_INPUT_GS_VARIABLE_PASSED_TO_INOUT_FUNCTION_PARAMETER:
531 {
532 *out_required_min_context_type_ptr = glu::ApiType::core(3, 2);
533 *out_target_shader_stage_ptr = SHADER_STAGE_GEOMETRY;
534
535 *out_body_ptr = "#version 150\n"
536 "\n"
537 "layout(points) in;\n"
538 "layout(points, max_vertices = 1) out;\n"
539 "\n"
540 "in vec4 data[];\n"
541 "\n"
542 "void testFunc(inout vec4 arg)\n"
543 "{\n"
544 " arg += vec4(1.0);\n"
545 "}\n"
546 "\n"
547 "void main()\n"
548 "{\n"
549 " testFunc(data[0]);\n"
550 "\n"
551 " gl_Position = data[0];\n"
552 "\n"
553 " EmitVertex();\n"
554 "}\n";
555
556 break;
557 }
558
559 case TEST_ITERATION_INPUT_GS_VARIABLE_PASSED_TO_OUT_FUNCTION_PARAMETER:
560 {
561 *out_required_min_context_type_ptr = glu::ApiType::core(3, 2);
562 *out_target_shader_stage_ptr = SHADER_STAGE_GEOMETRY;
563
564 *out_body_ptr = "#version 150\n"
565 "\n"
566 "layout(points) in;\n"
567 "layout(points, max_vertices = 1) out;\n"
568 "\n"
569 "in vec4 data[];\n"
570 "\n"
571 "void testFunc(out vec4 arg)\n"
572 "{\n"
573 " arg = vec4(1.0);\n"
574 "}\n"
575 "\n"
576 "void main()\n"
577 "{\n"
578 " testFunc(data[0]);\n"
579 "\n"
580 " gl_Position = data[0];\n"
581 "\n"
582 " EmitVertex();\n"
583 "}\n";
584
585 break;
586 }
587
588 case TEST_ITERATION_INPUT_TC_VARIABLE:
589 {
590 *out_required_min_context_type_ptr = glu::ApiType::core(4, 0);
591 *out_target_shader_stage_ptr = SHADER_STAGE_TESSELLATION_CONTROL;
592
593 *out_body_ptr = "#version 400\n"
594 "\n"
595 "layout(vertices = 4) out;\n"
596 "\n"
597 "in vec4 data[];\n"
598 "out vec4 result;\n"
599 "\n"
600 "void main()\n"
601 "{\n"
602 " data[0] += vec4(1.0);\n"
603 " result = data[0];\n"
604 "\n"
605 "}\n";
606
607 break;
608 }
609
610 case TEST_ITERATION_INPUT_TC_VARIABLE_IN_INPUT_BLOCK:
611 {
612 *out_required_min_context_type_ptr = glu::ApiType::core(4, 0);
613 *out_target_shader_stage_ptr = SHADER_STAGE_TESSELLATION_CONTROL;
614
615 *out_body_ptr = "#version 400\n"
616 "\n"
617 "layout(vertices = 4) out;\n"
618 "\n"
619 "in inputBlock\n"
620 "{\n"
621 " vec4 data;\n"
622 "} inData[];\n"
623 "\n"
624 "patch out vec4 result[];\n"
625 "\n"
626 "void main()\n"
627 "{\n"
628 " inData[0].data += vec4(1.0);\n"
629 " result[gl_InvocationID] = inData[0].data;\n"
630 "\n"
631 " gl_TessLevelInner[0] = 1.0;\n"
632 " gl_TessLevelInner[1] = 1.0;\n"
633 " gl_TessLevelOuter[0] = 1.0;\n"
634 " gl_TessLevelOuter[1] = 1.0;\n"
635 " gl_TessLevelOuter[2] = 1.0;\n"
636 " gl_TessLevelOuter[3] = 1.0;\n"
637 "}\n";
638
639 break;
640 }
641
642 case TEST_ITERATION_INPUT_TC_VARIABLE_PASSED_TO_INOUT_FUNCTION_PARAMETER:
643 {
644 *out_required_min_context_type_ptr = glu::ApiType::core(4, 0);
645 *out_target_shader_stage_ptr = SHADER_STAGE_TESSELLATION_CONTROL;
646
647 *out_body_ptr = "#version 400\n"
648 "\n"
649 "layout(vertices = 4) out;\n"
650 "\n"
651 "in vec4 data[];\n"
652 "out vec4 result;\n"
653 "\n"
654 "void testFunc(inout vec4 arg)\n"
655 "{\n"
656 " arg += vec4(1.0);\n"
657 "}\n"
658 "\n"
659 "void main()\n"
660 "{\n"
661 " testFunc(data[0]);\n"
662 "\n"
663 " result = data[0];\n"
664 "\n"
665 "}\n";
666
667 break;
668 }
669
670 case TEST_ITERATION_INPUT_TC_VARIABLE_PASSED_TO_OUT_FUNCTION_PARAMETER:
671 {
672 *out_required_min_context_type_ptr = glu::ApiType::core(4, 0);
673 *out_target_shader_stage_ptr = SHADER_STAGE_TESSELLATION_CONTROL;
674
675 *out_body_ptr = "#version 400\n"
676 "\n"
677 "layout(vertices = 4) out;\n"
678 "\n"
679 "in vec4 data[];\n"
680 "out vec4 result;\n"
681 "\n"
682 "void testFunc(out vec4 arg)\n"
683 "{\n"
684 " arg = vec4(1.0);\n"
685 "}\n"
686 "\n"
687 "void main()\n"
688 "{\n"
689 " testFunc(data[0]);\n"
690 "\n"
691 " result = data[0];\n"
692 "\n"
693 "}\n";
694
695 break;
696 }
697
698 case TEST_ITERATION_INPUT_TE_PATCH_VARIABLE:
699 case TEST_ITERATION_INPUT_TE_VARIABLE:
700 {
701 std::stringstream body_sstream;
702
703 *out_required_min_context_type_ptr = glu::ApiType::core(4, 0);
704 *out_target_shader_stage_ptr = SHADER_STAGE_TESSELLATION_EVALUATION;
705
706 body_sstream << "#version 400\n"
707 "\n"
708 "layout(triangles) in;\n"
709 "\n"
710 << ((iteration == TEST_ITERATION_INPUT_TE_PATCH_VARIABLE) ? "patch " : "") << "in vec4 data[];\n"
711 << " out vec4 result;\n"
712 "\n"
713 "void main()\n"
714 "{\n"
715 " data[0] += vec4(1.0);\n"
716 " gl_Position = data[0];\n"
717 "}\n";
718
719 *out_body_ptr = body_sstream.str();
720 break;
721 }
722
723 case TEST_ITERATION_INPUT_TE_VARIABLE_IN_INPUT_BLOCK:
724 {
725 *out_required_min_context_type_ptr = glu::ApiType::core(4, 0);
726 *out_target_shader_stage_ptr = SHADER_STAGE_TESSELLATION_EVALUATION;
727
728 *out_body_ptr = "#version 400\n"
729 "\n"
730 "layout(triangles) in;\n"
731 "\n"
732 "in inputBlock\n"
733 "{\n"
734 " vec4 data;\n"
735 "} inData[];\n"
736 "\n"
737 "void main()\n"
738 "{\n"
739 " inData[0].data += vec4(1.0);\n"
740 " gl_Position = inData[0].data;\n"
741 "}\n";
742
743 break;
744 }
745
746 case TEST_ITERATION_INPUT_TE_VARIABLE_PASSED_TO_INOUT_FUNCTION_PARAMETER:
747 {
748 *out_required_min_context_type_ptr = glu::ApiType::core(4, 0);
749 *out_target_shader_stage_ptr = SHADER_STAGE_TESSELLATION_EVALUATION;
750
751 *out_body_ptr = "#version 400\n"
752 "\n"
753 "layout(triangles) in;\n"
754 "\n"
755 "in vec4 data[];\n"
756 "out vec4 result;\n"
757 "\n"
758 "void testFunc(inout vec4 arg)\n"
759 "{\n"
760 " arg += vec4(1.0);\n"
761 "}\n"
762 "\n"
763 "void main()\n"
764 "{\n"
765 " testFunc(data[0]);\n"
766 "\n"
767 " gl_Position = data[0];\n"
768 "}\n";
769
770 break;
771 }
772
773 case TEST_ITERATION_INPUT_TE_VARIABLE_PASSED_TO_OUT_FUNCTION_PARAMETER:
774 {
775 *out_required_min_context_type_ptr = glu::ApiType::core(4, 0);
776 *out_target_shader_stage_ptr = SHADER_STAGE_TESSELLATION_EVALUATION;
777
778 *out_body_ptr = "#version 400\n"
779 "\n"
780 "layout(triangles) in;\n"
781 "\n"
782 "in vec4 data[];\n"
783 "out vec4 result;\n"
784 "\n"
785 "void testFunc(out vec4 arg)\n"
786 "{\n"
787 " arg = vec4(1.0);\n"
788 "}\n"
789 "\n"
790 "void main()\n"
791 "{\n"
792 " testFunc(data[0]);\n"
793 "\n"
794 " gl_Position = data[0];\n"
795 "}\n";
796
797 break;
798 }
799
800 case TEST_ITERATION_INPUT_VS_VARIABLE:
801 {
802 *out_required_min_context_type_ptr = glu::ApiType::core(3, 1);
803 *out_target_shader_stage_ptr = SHADER_STAGE_VERTEX;
804
805 *out_body_ptr = "#version 140\n"
806 "\n"
807 "in vec4 data;\n"
808 "\n"
809 "void main()\n"
810 "{\n"
811 " data += vec4(1.0);\n"
812 " gl_Position = data;\n"
813 "}\n";
814
815 break;
816 }
817
818 case TEST_ITERATION_INPUT_VS_VARIABLE_PASSED_TO_INOUT_FUNCTION_PARAMETER:
819 {
820 *out_required_min_context_type_ptr = glu::ApiType::core(3, 1);
821 *out_target_shader_stage_ptr = SHADER_STAGE_VERTEX;
822
823 *out_body_ptr = "#version 140\n"
824 "\n"
825 "in vec4 data;\n"
826 "\n"
827 "void testFunc(inout vec4 argument)\n"
828 "{\n"
829 " argument += vec4(1.0);\n"
830 "}\n"
831 "\n"
832 "void main()\n"
833 "{\n"
834 " testFunc(data);\n"
835 "\n"
836 " gl_Position = data;\n"
837 "}\n";
838
839 break;
840 }
841
842 case TEST_ITERATION_INPUT_VS_VARIABLE_PASSED_TO_OUT_FUNCTION_PARAMETER:
843 {
844 *out_required_min_context_type_ptr = glu::ApiType::core(3, 1);
845 *out_target_shader_stage_ptr = SHADER_STAGE_VERTEX;
846
847 *out_body_ptr = "#version 140\n"
848 "\n"
849 "in vec4 data;\n"
850 "\n"
851 "void testFunc(out vec4 argument)\n"
852 "{\n"
853 " argument = vec4(1.0);\n"
854 "}\n"
855 "\n"
856 "void main()\n"
857 "{\n"
858 " testFunc(data);\n"
859 "\n"
860 " gl_Position = data;\n"
861 "}\n";
862
863 break;
864 }
865
866 default:
867 TCU_FAIL("Unrecognized test iteration type");
868 } /* switch (iteration) */
869 }
870
871 /** Executes test iteration.
872 *
873 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
874 */
iterate()875 tcu::TestNode::IterateResult InputVariablesCannotBeModifiedTest::iterate()
876 {
877 const glu::ContextType context_type = m_context.getRenderContext().getType();
878 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
879 bool result = true;
880
881 /* Create shader objects */
882 if (glu::contextSupports(context_type, glu::ApiType::core(3, 2)))
883 {
884 m_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
885 }
886
887 if (glu::contextSupports(context_type, glu::ApiType::core(4, 0)))
888 {
889 m_tc_id = gl.createShader(GL_TESS_CONTROL_SHADER);
890 m_te_id = gl.createShader(GL_TESS_EVALUATION_SHADER);
891 }
892
893 m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
894 m_vs_id = gl.createShader(GL_VERTEX_SHADER);
895
896 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed.");
897
898 /* Execute all test iterations.. */
899 for (int current_iteration = static_cast<int>(TEST_ITERATION_FIRST);
900 current_iteration < static_cast<int>(TEST_ITERATION_COUNT); current_iteration++)
901 {
902 glw::GLint compile_status = GL_FALSE;
903 std::string current_iteration_body;
904 const char* current_iteration_body_raw_ptr = NULL;
905 glu::ApiType current_iteration_min_context_type;
906 _shader_stage current_iteration_shader_stage;
907 glw::GLuint so_id = 0;
908
909 getIterationData(static_cast<_test_iteration>(current_iteration), ¤t_iteration_min_context_type,
910 ¤t_iteration_shader_stage, ¤t_iteration_body);
911
912 current_iteration_body_raw_ptr = current_iteration_body.c_str();
913
914 /* Determine shader ID for the iteration. If the shader stage is not supported
915 * for the running context, skip it. */
916 if (!glu::contextSupports(context_type, current_iteration_min_context_type))
917 {
918 continue;
919 }
920
921 switch (current_iteration_shader_stage)
922 {
923 case SHADER_STAGE_FRAGMENT:
924 so_id = m_fs_id;
925 break;
926 case SHADER_STAGE_GEOMETRY:
927 so_id = m_gs_id;
928 break;
929 case SHADER_STAGE_TESSELLATION_CONTROL:
930 so_id = m_tc_id;
931 break;
932 case SHADER_STAGE_TESSELLATION_EVALUATION:
933 so_id = m_te_id;
934 break;
935 case SHADER_STAGE_VERTEX:
936 so_id = m_vs_id;
937 break;
938
939 default:
940 {
941 TCU_FAIL("Unrecognized shader stage type");
942 }
943 } /* switch (current_iteration_shader_stage) */
944
945 DE_ASSERT(so_id != 0);
946
947 /* Assign the source code to the SO */
948 gl.shaderSource(so_id, 1, /* count */
949 ¤t_iteration_body_raw_ptr, DE_NULL); /* length */
950 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
951
952 /* Try to compile the shader object. */
953 gl.compileShader(so_id);
954 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed.");
955
956 gl.getShaderiv(so_id, GL_COMPILE_STATUS, &compile_status);
957 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");
958
959 char temp[1024];
960
961 gl.getShaderInfoLog(so_id, 1024, NULL, temp);
962
963 if (compile_status == GL_TRUE)
964 {
965 m_testCtx.getLog() << tcu::TestLog::Message << "The following "
966 << getShaderStageName(current_iteration_shader_stage)
967 << " shader, used for test iteration ["
968 << getIterationName(static_cast<_test_iteration>(current_iteration))
969 << "] "
970 "was compiled successfully, even though it is invalid. Body:"
971 "\n>>\n"
972 << current_iteration_body << "\n<<\n"
973 << tcu::TestLog::EndMessage;
974
975 result = false;
976 }
977 } /* for (all test iterations) */
978
979 m_testCtx.setTestResult(result ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, result ? "Pass" : "Fail");
980
981 return STOP;
982 }
983
984 /** Returns a literal corresponding to the shader stage enum used by the test.
985 *
986 * @param stage Shader stage to use for the query.
987 *
988 * @return Requested string.
989 **/
getShaderStageName(_shader_stage stage) const990 std::string InputVariablesCannotBeModifiedTest::getShaderStageName(_shader_stage stage) const
991 {
992 std::string result = "?!";
993
994 switch (stage)
995 {
996 case SHADER_STAGE_FRAGMENT:
997 result = "fragment shader";
998 break;
999 case SHADER_STAGE_GEOMETRY:
1000 result = "geometry shader";
1001 break;
1002 case SHADER_STAGE_TESSELLATION_CONTROL:
1003 result = "tessellation control shader";
1004 break;
1005 case SHADER_STAGE_TESSELLATION_EVALUATION:
1006 result = "tessellation evaluation shader";
1007 break;
1008 case SHADER_STAGE_VERTEX:
1009 result = "vertex shader";
1010 break;
1011 } /* switch (stage) */
1012
1013 return result;
1014 }
1015
1016 /** Constructor.
1017 *
1018 * @param context Rendering context
1019 * @param name Test name
1020 * @param description Test description
1021 */
InvalidUseCasesForAllNotFuncsAndExclMarkOpTest(deqp::Context & context)1022 InvalidUseCasesForAllNotFuncsAndExclMarkOpTest::InvalidUseCasesForAllNotFuncsAndExclMarkOpTest(deqp::Context& context)
1023 : deqp::TestCase(context, "CommonBug_InvalidUseCasesForAllNotFuncsAndExclMarkOp",
1024 "Verifies that ! operator does not accept bvec{2,3,4} arguments, "
1025 "all() and not() functions do not accept a bool argument.")
1026 , m_vs_id(0)
1027 {
1028 /* Left blank on purpose */
1029 }
1030
1031 /** Deinitializes all GL objects created for the purpose of running the test,
1032 * as well as any client-side buffers allocated at initialization time
1033 */
deinit()1034 void InvalidUseCasesForAllNotFuncsAndExclMarkOpTest::deinit()
1035 {
1036 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1037
1038 if (m_vs_id != 0)
1039 {
1040 gl.deleteShader(m_vs_id);
1041
1042 m_vs_id = 0;
1043 }
1044 }
1045
1046 /** Empty init function */
init()1047 void InvalidUseCasesForAllNotFuncsAndExclMarkOpTest::init()
1048 {
1049 /* Left blank on purpose */
1050 }
1051
1052 /** Retrieves a literal corresponding to the test iteration enum.
1053 *
1054 * @param iteration Enum to retrieve the string for.
1055 *
1056 * @return Requested object.
1057 **/
getIterationName(_test_iteration iteration) const1058 std::string InvalidUseCasesForAllNotFuncsAndExclMarkOpTest::getIterationName(_test_iteration iteration) const
1059 {
1060 std::string result;
1061
1062 switch (iteration)
1063 {
1064 case TEST_ITERATION_EXCL_MARK_OP_MUST_NOT_ACCEPT_BVEC2:
1065 result = "! operator must not accept bvec2 arg";
1066 break;
1067 case TEST_ITERATION_EXCL_MARK_OP_MUST_NOT_ACCEPT_BVEC3:
1068 result = "! operator must not accept bvec3 arg";
1069 break;
1070 case TEST_ITERATION_EXCL_MARK_OP_MUST_NOT_ACCEPT_BVEC4:
1071 result = "! operator must not accept bvec4 arg";
1072 break;
1073 case TEST_ITERATION_ALL_FUNC_MUST_NOT_ACCEPT_BOOL:
1074 result = "all() function must not accept bool arg";
1075 break;
1076 case TEST_ITERATION_NOT_FUNC_MUST_NOT_ACCEPT_BOOL:
1077 result = "not() function must not accept bool arg";
1078 break;
1079 default:
1080 {
1081 TCU_FAIL("Unrecognized test iteration type.");
1082 }
1083 } /* switch (iteration) */
1084
1085 return result;
1086 }
1087
1088 /** Retrieves a vertex shader body for the user-specified iteration enum.
1089 *
1090 * @param iteration Iteration to retrieve the shader body for.
1091 *
1092 * @return Requested string object.
1093 */
getShaderBody(_test_iteration iteration) const1094 std::string InvalidUseCasesForAllNotFuncsAndExclMarkOpTest::getShaderBody(_test_iteration iteration) const
1095 {
1096 std::string result;
1097
1098 switch (iteration)
1099 {
1100 case TEST_ITERATION_EXCL_MARK_OP_MUST_NOT_ACCEPT_BVEC2:
1101 case TEST_ITERATION_EXCL_MARK_OP_MUST_NOT_ACCEPT_BVEC3:
1102 case TEST_ITERATION_EXCL_MARK_OP_MUST_NOT_ACCEPT_BVEC4:
1103 {
1104 /* From GL SL spec:
1105 *
1106 * The logical unary operator not (!). It operates only on a Boolean expression and results in a Boolean
1107 * expression. To operate on a vector, use the built-in function not.
1108 */
1109 std::stringstream result_sstream;
1110 std::string type_string;
1111
1112 type_string = (iteration == TEST_ITERATION_EXCL_MARK_OP_MUST_NOT_ACCEPT_BVEC2) ?
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 /** Empty 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 /** Empty 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 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 /** Empty 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 }
2695
2696 if (validate_status != validate_expected_status)
2697 {
2698 tcu::MessageBuilder message = m_testCtx.getLog().message();
2699
2700 if (GL_FALSE == validate_expected_status)
2701 {
2702 message << "A pipeline object was validated successfully, even though one";
2703 }
2704 else
2705 {
2706 message << "A pipeline object was validated negatively, even though none";
2707 }
2708
2709 message << " of the failure reasons given by spec was applicable.\n"
2710 << "\n"
2711 "Fragment shader body:\n>>\n"
2712 << ((shader_programs[0].body_ptr->length() > 0) ? *shader_programs[0].body_ptr : "[not used]")
2713 << "\n<<\nGeometry shader body:\n>>\n"
2714 << ((shader_programs[1].body_ptr->length() > 0) ? *shader_programs[1].body_ptr : "[not used]")
2715 << "\n<<\nTessellation control shader body:\n>>\n"
2716 << ((shader_programs[2].body_ptr->length() > 0) ? *shader_programs[2].body_ptr : "[not used]")
2717 << "\n<<\nTessellation evaluation shader body:\n>>\n"
2718 << ((shader_programs[3].body_ptr->length() > 0) ? *shader_programs[3].body_ptr : "[not used]")
2719 << "\n<<\nVertex shader body:\n>>\n"
2720 << ((shader_programs[4].body_ptr->length() > 0) ? *shader_programs[4].body_ptr : "[not used]")
2721 << tcu::TestLog::EndMessage;
2722 } /* if (validate_status != validate_expected_status) */
2723 else
2724 {
2725 result = true;
2726 }
2727 }
2728 else
2729 {
2730 result = true;
2731 }
2732
2733 end:
2734 return result;
2735 }
2736
2737 /** Runs the specified test iteration in the following mode:
2738 *
2739 * >>
2740 * A single separate shader program, to which all shader stages used by the test are attached, is linked.
2741 * It is expected the linking process should fail.
2742 * <<
2743 *
2744 * @param iteration Test iteration to execute.
2745 *
2746 * @return true if the test passed, false otherwise.
2747 */
runSeparateShaderTestMode(_test_iteration iteration)2748 bool PerVertexValidationTest::runSeparateShaderTestMode(_test_iteration iteration)
2749 {
2750 glw::GLint compile_status;
2751 glu::ContextType context_type = m_context.getRenderContext().getType();
2752 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2753 glw::GLint link_status;
2754 glu::ContextType min_context_type;
2755 bool result = false;
2756 _shader_stage used_shader_stages;
2757
2758 std::string fs_body;
2759 std::string gs_body;
2760 std::string tc_body;
2761 std::string te_body;
2762 std::string vs_body;
2763
2764 struct _shader
2765 {
2766 std::string* body_ptr;
2767 glw::GLuint* so_id_ptr;
2768 _shader_stage shader_stage;
2769 glw::GLenum shader_stage_bit_gl;
2770 glw::GLenum shader_stage_gl;
2771 } shaders[] = { { &fs_body, &m_fs_id, SHADER_STAGE_FRAGMENT, GL_FRAGMENT_SHADER_BIT, GL_FRAGMENT_SHADER },
2772 { &gs_body, &m_gs_id, SHADER_STAGE_GEOMETRY, GL_GEOMETRY_SHADER_BIT, GL_GEOMETRY_SHADER },
2773 { &tc_body, &m_tc_id, SHADER_STAGE_TESSELLATION_CONTROL, GL_TESS_CONTROL_SHADER_BIT,
2774 GL_TESS_CONTROL_SHADER },
2775 { &te_body, &m_te_id, SHADER_STAGE_TESSELLATION_EVALUATION, GL_TESS_EVALUATION_SHADER_BIT,
2776 GL_TESS_EVALUATION_SHADER },
2777 { &vs_body, &m_vs_id, SHADER_STAGE_VERTEX, GL_VERTEX_SHADER_BIT, GL_VERTEX_SHADER } };
2778 const unsigned int n_shaders = static_cast<unsigned int>(sizeof(shaders) / sizeof(shaders[0]));
2779
2780 /* Retrieve iteration properties */
2781 getTestIterationProperties(context_type, iteration, &min_context_type, &used_shader_stages, &gs_body, &tc_body,
2782 &te_body, &vs_body);
2783
2784 if (!glu::contextSupports(context_type, min_context_type.getAPI()))
2785 {
2786 result = true;
2787
2788 goto end;
2789 }
2790
2791 /* Bake a single shader with separate programs defined for all shader stages defined by the iteration
2792 * and see what happens.
2793 *
2794 * For simplicity, we re-use m_vs_po_id to store the program object ID.
2795 */
2796 m_vs_po_id = gl.createProgram();
2797
2798 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
2799
2800 for (unsigned int n_shader = 0; n_shader < n_shaders; ++n_shader)
2801 {
2802 const char* body_raw_ptr = DE_NULL;
2803 const std::string& current_body = *shaders[n_shader].body_ptr;
2804 const _shader_stage& current_shader_stage = shaders[n_shader].shader_stage;
2805 glw::GLuint& current_so_id = *shaders[n_shader].so_id_ptr;
2806 const glw::GLenum& current_so_type_gl = shaders[n_shader].shader_stage_gl;
2807
2808 if ((used_shader_stages & current_shader_stage) != 0)
2809 {
2810 body_raw_ptr = current_body.c_str();
2811 current_so_id = gl.createShader(current_so_type_gl);
2812
2813 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed.");
2814
2815 gl.shaderSource(current_so_id, 1, /* count */
2816 &body_raw_ptr, DE_NULL); /* length */
2817 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
2818
2819 /* Ensure the shader compiled successfully. */
2820 gl.compileShader(current_so_id);
2821
2822 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed.");
2823
2824 gl.getShaderiv(current_so_id, GL_COMPILE_STATUS, &compile_status);
2825 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");
2826
2827 if (compile_status != GL_TRUE)
2828 {
2829 m_testCtx.getLog() << tcu::TestLog::Message << getShaderStageName(current_shader_stage)
2830 << " unexpectedly failed to compile.\n"
2831 "\nBody:\n>>\n"
2832 << current_body << "\n<<\n"
2833 << tcu::TestLog::EndMessage;
2834
2835 goto end;
2836 }
2837
2838 /* Attach the shader object to the test program object */
2839 gl.attachShader(m_vs_po_id, current_so_id);
2840 GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call failed.");
2841 } /* if ((used_shader_stages & current_shader_stage) != 0) */
2842 } /* for (all shader objects) */
2843
2844 /* Mark the program as separable */
2845 gl.programParameteri(m_vs_po_id, GL_PROGRAM_SEPARABLE, GL_TRUE);
2846 GLU_EXPECT_NO_ERROR(gl.getError(), "glProgramParameteri() call failed.");
2847
2848 /* Try to link the program and check the result. */
2849 gl.linkProgram(m_vs_po_id);
2850 GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed.");
2851
2852 gl.getProgramiv(m_vs_po_id, GL_LINK_STATUS, &link_status);
2853 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed.");
2854
2855 if (link_status == GL_TRUE)
2856 {
2857 m_testCtx.getLog() << tcu::TestLog::Message
2858 << "Separable program, consisting of the following separate shaders, was linked "
2859 "successfully, despite incompatible or missing gl_PerVertex block re-declarations.\n"
2860 "\n"
2861 "Fragment shader program:\n>>\n"
2862 << ((fs_body.length() > 0) ? fs_body : "[not used]")
2863 << "\n<<\nGeometry shader program:\n>>\n"
2864 << ((gs_body.length() > 0) ? gs_body : "[not used]")
2865 << "\n<<\nTessellation control shader program:\n>>\n"
2866 << ((tc_body.length() > 0) ? tc_body : "[not used]")
2867 << "\n<<\nTessellation evaluation shader program:\n>>\n"
2868 << ((te_body.length() > 0) ? te_body : "[not used]") << "\n<<\nVertex shader program:\n>>\n"
2869 << ((vs_body.length() > 0) ? vs_body : "[not used]") << tcu::TestLog::EndMessage;
2870
2871 goto end;
2872 } /* if (link_status == GL_TRUE) */
2873
2874 /* All done */
2875 result = true;
2876 end:
2877 if (!result)
2878 {
2879 m_testCtx.getLog() << tcu::TestLog::Message << "Failed test description: " << getTestIterationName(iteration)
2880 << tcu::TestLog::EndMessage;
2881 }
2882 return result;
2883 }
2884
2885 /** Constructor.
2886 *
2887 * @param context Rendering context
2888 * @param name Test name
2889 * @param description Test description
2890 */
ReservedNamesTest(deqp::Context & context)2891 ReservedNamesTest::ReservedNamesTest(deqp::Context& context)
2892 : TestCase(context, "CommonBug_ReservedNames",
2893 "Verifies that reserved variable names are rejected by the GL SL compiler"
2894 " at the compilation time.")
2895 , m_max_fs_ssbos(0)
2896 , m_max_gs_acs(0)
2897 , m_max_gs_ssbos(0)
2898 , m_max_tc_acs(0)
2899 , m_max_tc_ssbos(0)
2900 , m_max_te_acs(0)
2901 , m_max_te_ssbos(0)
2902 , m_max_vs_acs(0)
2903 , m_max_vs_ssbos(0)
2904 {
2905 memset(m_so_ids, 0, sizeof(m_so_ids));
2906 }
2907
2908 /** Deinitializes all GL objects created for the purpose of running the test,
2909 * as well as any client-side buffers allocated at initialization time
2910 */
deinit()2911 void ReservedNamesTest::deinit()
2912 {
2913 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2914
2915 for (unsigned int n_so_id = 0; n_so_id < sizeof(m_so_ids) / sizeof(m_so_ids[0]); ++n_so_id)
2916 {
2917 const glw::GLuint current_so_id = m_so_ids[n_so_id];
2918
2919 if (current_so_id != 0)
2920 {
2921 gl.deleteShader(current_so_id);
2922 }
2923 } /* for (all usedshader object IDs) */
2924 }
2925
2926 /** Returns a literal corresponding to the specified @param language_feature value.
2927 *
2928 * @param language_feature Enum to return the string object for.
2929 *
2930 * @return As specified.
2931 */
getLanguageFeatureName(_language_feature language_feature) const2932 std::string ReservedNamesTest::getLanguageFeatureName(_language_feature language_feature) const
2933 {
2934 std::string result = "[?!]";
2935
2936 switch (language_feature)
2937 {
2938 case LANGUAGE_FEATURE_ATOMIC_COUNTER:
2939 result = "atomic counter";
2940 break;
2941 case LANGUAGE_FEATURE_ATTRIBUTE:
2942 result = "attribute";
2943 break;
2944 case LANGUAGE_FEATURE_CONSTANT:
2945 result = "constant";
2946 break;
2947 case LANGUAGE_FEATURE_FUNCTION_ARGUMENT_NAME:
2948 result = "function argument name";
2949 break;
2950 case LANGUAGE_FEATURE_FUNCTION_NAME:
2951 result = "function name";
2952 break;
2953 case LANGUAGE_FEATURE_INPUT:
2954 result = "input variable";
2955 break;
2956 case LANGUAGE_FEATURE_INPUT_BLOCK_INSTANCE_NAME:
2957 result = "input block instance name";
2958 break;
2959 case LANGUAGE_FEATURE_INPUT_BLOCK_MEMBER_NAME:
2960 result = "input block member name";
2961 break;
2962 case LANGUAGE_FEATURE_INPUT_BLOCK_NAME:
2963 result = "input block name";
2964 break;
2965 case LANGUAGE_FEATURE_OUTPUT:
2966 result = "output variable";
2967 break;
2968 case LANGUAGE_FEATURE_OUTPUT_BLOCK_INSTANCE_NAME:
2969 result = "output block instance name";
2970 break;
2971 case LANGUAGE_FEATURE_OUTPUT_BLOCK_MEMBER_NAME:
2972 result = "output block member name";
2973 break;
2974 case LANGUAGE_FEATURE_OUTPUT_BLOCK_NAME:
2975 result = "output block name";
2976 break;
2977 case LANGUAGE_FEATURE_SHADER_STORAGE_BLOCK_INSTANCE_NAME:
2978 result = "shader storage block instance name";
2979 break;
2980 case LANGUAGE_FEATURE_SHADER_STORAGE_BLOCK_MEMBER_NAME:
2981 result = "shader storage block member name";
2982 break;
2983 case LANGUAGE_FEATURE_SHADER_STORAGE_BLOCK_NAME:
2984 result = "shader storage block name";
2985 break;
2986 case LANGUAGE_FEATURE_SHARED_VARIABLE:
2987 result = "shared variable";
2988 break;
2989 case LANGUAGE_FEATURE_STRUCTURE_MEMBER:
2990 result = "structure member";
2991 break;
2992 case LANGUAGE_FEATURE_STRUCTURE_INSTANCE_NAME:
2993 result = "structure instance name";
2994 break;
2995 case LANGUAGE_FEATURE_STRUCTURE_NAME:
2996 result = "structure name";
2997 break;
2998 case LANGUAGE_FEATURE_SUBROUTINE_FUNCTION_NAME:
2999 result = "subroutine function name";
3000 break;
3001 case LANGUAGE_FEATURE_SUBROUTINE_TYPE:
3002 result = "subroutine type";
3003 break;
3004 case LANGUAGE_FEATURE_SUBROUTINE_UNIFORM:
3005 result = "subroutine uniform";
3006 break;
3007 case LANGUAGE_FEATURE_UNIFORM:
3008 result = "uniform";
3009 break;
3010 case LANGUAGE_FEATURE_UNIFORM_BLOCK_INSTANCE_NAME:
3011 result = "uniform block instance name";
3012 break;
3013 case LANGUAGE_FEATURE_UNIFORM_BLOCK_MEMBER_NAME:
3014 result = "uniform block member name";
3015 break;
3016 case LANGUAGE_FEATURE_UNIFORM_BLOCK_NAME:
3017 result = "uniform block name";
3018 break;
3019 case LANGUAGE_FEATURE_VARIABLE:
3020 result = "variable";
3021 break;
3022 case LANGUAGE_FEATURE_VARYING:
3023 result = "varying";
3024 break;
3025 default:
3026 result = "unknown";
3027 break;
3028 } /* switch (language_feature) */
3029
3030 return result;
3031 }
3032
3033 /** Returns keywords and reserved names, specific to the running context version. */
getReservedNames() const3034 std::vector<std::string> ReservedNamesTest::getReservedNames() const
3035 {
3036 const glu::ContextType context_type = m_context.getRenderContext().getType();
3037 std::vector<std::string> result;
3038
3039 const char** context_keywords = NULL;
3040 unsigned int context_n_keywords = 0;
3041 unsigned int context_n_reserved = 0;
3042 const char** context_reserved = NULL;
3043
3044 /* Keywords and reserved names were taken straight from relevant shading language specification documents */
3045 static const char* keywords_gl31[] = {
3046 "attribute",
3047 "const",
3048 "uniform",
3049 "varying",
3050 "layout",
3051 "centroid",
3052 "flat",
3053 "smooth",
3054 "noperspective",
3055 "break",
3056 "continue",
3057 "do",
3058 "for",
3059 "while",
3060 "switch",
3061 "case",
3062 "default",
3063 "if",
3064 "else",
3065 "in",
3066 "out",
3067 "inout",
3068 "float",
3069 "int",
3070 "void",
3071 "bool",
3072 "true",
3073 "false",
3074 "invariant",
3075 "discard",
3076 "return",
3077 "mat2",
3078 "mat3",
3079 "mat4",
3080 "mat2x2",
3081 "mat2x3",
3082 "mat2x4",
3083 "mat3x2",
3084 "mat3x3",
3085 "mat3x4",
3086 "mat4x2",
3087 "mat4x3",
3088 "mat4x4",
3089 "vec2",
3090 "vec3",
3091 "vec4",
3092 "ivec2",
3093 "ivec3",
3094 "ivec4",
3095 "bvec2",
3096 "bvec3",
3097 "bvec4",
3098 "uint",
3099 "uvec2",
3100 "uvec3",
3101 "uvec4",
3102 "lowp",
3103 "mediump",
3104 "highp",
3105 "precision",
3106 "sampler1D",
3107 "sampler2D",
3108 "sampler3D",
3109 "samplerCube",
3110 "sampler1DShadow",
3111 "sampler2DShadow",
3112 "samplerCubeShadow",
3113 "sampler1DArray",
3114 "sampler2DArray",
3115 "sampler1DArrayShadow",
3116 "sampler2DArrayShadow",
3117 "isampler1D",
3118 "isampler2D",
3119 "isampler3D",
3120 "isamplerCube",
3121 "isampler1DArray",
3122 "isampler2DArray",
3123 "usampler1D",
3124 "usampler2D",
3125 "usampler3D",
3126 "usamplerCube",
3127 "usampler1DArray",
3128 "usampler2DArray",
3129 "sampler2DRect",
3130 "sampler2DRectShadow",
3131 "isampler2DRect",
3132 "usampler2DRect",
3133 "samplerBuffer",
3134 "isamplerBuffer",
3135 "usamplerBuffer",
3136 };
3137 static const char* keywords_gl32[] = {
3138 "attribute",
3139 "const",
3140 "uniform",
3141 "varying",
3142 "layout",
3143 "centroid",
3144 "flat",
3145 "smooth",
3146 "noperspective",
3147 "break",
3148 "continue",
3149 "do",
3150 "for",
3151 "while",
3152 "switch",
3153 "case",
3154 "default",
3155 "if",
3156 "else",
3157 "in",
3158 "out",
3159 "inout",
3160 "float",
3161 "int",
3162 "void",
3163 "bool",
3164 "true",
3165 "false",
3166 "invariant",
3167 "discard",
3168 "return",
3169 "mat2",
3170 "mat3",
3171 "mat4",
3172 "mat2x2",
3173 "mat2x3",
3174 "mat2x4",
3175 "mat3x2",
3176 "mat3x3",
3177 "mat3x4",
3178 "mat4x2",
3179 "mat4x3",
3180 "mat4x4",
3181 "vec2",
3182 "vec3",
3183 "vec4",
3184 "ivec2",
3185 "ivec3",
3186 "ivec4",
3187 "bvec2",
3188 "bvec3",
3189 "bvec4",
3190 "uint",
3191 "uvec2",
3192 "uvec3",
3193 "uvec4",
3194 "lowp",
3195 "mediump",
3196 "highp",
3197 "precision",
3198 "sampler1D",
3199 "sampler2D",
3200 "sampler3D",
3201 "samplerCube",
3202 "sampler1DShadow",
3203 "sampler2DShadow",
3204 "samplerCubeShadow",
3205 "sampler1DArray",
3206 "sampler2DArray",
3207 "sampler1DArrayShadow",
3208 "sampler2DArrayShadow",
3209 "isampler1D",
3210 "isampler2D",
3211 "isampler3D",
3212 "isamplerCube",
3213 "isampler1DArray",
3214 "isampler2DArray",
3215 "usampler1D",
3216 "usampler2D",
3217 "usampler3D",
3218 "usamplerCube",
3219 "usampler1DArray",
3220 "usampler2DArray",
3221 "sampler2DRect",
3222 "sampler2DRectShadow",
3223 "isampler2DRect",
3224 "usampler2DRect",
3225 "samplerBuffer",
3226 "isamplerBuffer",
3227 "usamplerBuffer",
3228 "sampler2DMS",
3229 "isampler2DMS",
3230 "usampler2DMS",
3231 "sampler2DMSArray",
3232 "isampler2DMSArray",
3233 "usampler2DMSArray",
3234 };
3235 static const char* keywords_gl33[] = {
3236 "attribute",
3237 "const",
3238 "uniform",
3239 "varying",
3240 "layout",
3241 "centroid",
3242 "flat",
3243 "smooth",
3244 "noperspective",
3245 "break",
3246 "continue",
3247 "do",
3248 "for",
3249 "while",
3250 "switch",
3251 "case",
3252 "default",
3253 "if",
3254 "else",
3255 "in",
3256 "out",
3257 "inout",
3258 "float",
3259 "int",
3260 "void",
3261 "bool",
3262 "true",
3263 "false",
3264 "invariant",
3265 "discard",
3266 "return",
3267 "mat2",
3268 "mat3",
3269 "mat4",
3270 "mat2x2",
3271 "mat2x3",
3272 "mat2x4",
3273 "mat3x2",
3274 "mat3x3",
3275 "mat3x4",
3276 "mat4x2",
3277 "mat4x3",
3278 "mat4x4",
3279 "vec2",
3280 "vec3",
3281 "vec4",
3282 "ivec2",
3283 "ivec3",
3284 "ivec4",
3285 "bvec2",
3286 "bvec3",
3287 "bvec4",
3288 "uint",
3289 "uvec2",
3290 "uvec3",
3291 "uvec4",
3292 "lowp",
3293 "mediump",
3294 "highp",
3295 "precision",
3296 "sampler1D",
3297 "sampler2D",
3298 "sampler3D",
3299 "samplerCube",
3300 "sampler1DShadow",
3301 "sampler2DShadow",
3302 "samplerCubeShadow",
3303 "sampler1DArray",
3304 "sampler2DArray",
3305 "sampler1DArrayShadow",
3306 "sampler2DArrayShadow",
3307 "isampler1D",
3308 "isampler2D",
3309 "isampler3D",
3310 "isamplerCube",
3311 "isampler1DArray",
3312 "isampler2DArray",
3313 "usampler1D",
3314 "usampler2D",
3315 "usampler3D",
3316 "usamplerCube",
3317 "usampler1DArray",
3318 "usampler2DArray",
3319 "sampler2DRect",
3320 "sampler2DRectShadow",
3321 "isampler2DRect",
3322 "usampler2DRect",
3323 "samplerBuffer",
3324 "isamplerBuffer",
3325 "usamplerBuffer",
3326 "sampler2DMS",
3327 "isampler2DMS",
3328 "usampler2DMS",
3329 "sampler2DMSArray",
3330 "isampler2DMSArray",
3331 "usampler2DMSArray",
3332 };
3333 static const char* keywords_gl40[] = {
3334 "attribute",
3335 "const",
3336 "uniform",
3337 "varying",
3338 "layout",
3339 "centroid",
3340 "flat",
3341 "smooth",
3342 "noperspective",
3343 "patch",
3344 "sample",
3345 "break",
3346 "continue",
3347 "do",
3348 "for",
3349 "while",
3350 "switch",
3351 "case",
3352 "default",
3353 "if",
3354 "else",
3355 "subroutine",
3356 "in",
3357 "out",
3358 "inout",
3359 "float",
3360 "double",
3361 "int",
3362 "void",
3363 "bool",
3364 "true",
3365 "false",
3366 "invariant",
3367 "discard",
3368 "return",
3369 "mat2",
3370 "mat3",
3371 "mat4",
3372 "dmat2",
3373 "dmat3",
3374 "dmat4",
3375 "mat2x2",
3376 "mat2x3",
3377 "mat2x4",
3378 "dmat2x2",
3379 "dmat2x3",
3380 "dmat2x4",
3381 "mat3x2",
3382 "mat3x3",
3383 "mat3x4",
3384 "dmat3x2",
3385 "dmat3x3",
3386 "dmat3x4",
3387 "mat4x2",
3388 "mat4x3",
3389 "mat4x4",
3390 "dmat4x2",
3391 "dmat4x3",
3392 "dmat4x4",
3393 "vec2",
3394 "vec3",
3395 "vec4",
3396 "ivec2",
3397 "ivec3",
3398 "ivec4",
3399 "bvec2",
3400 "bvec3",
3401 "bvec4",
3402 "dvec2",
3403 "dvec3",
3404 "dvec4",
3405 "uint",
3406 "uvec2",
3407 "uvec3",
3408 "uvec4",
3409 "lowp",
3410 "mediump",
3411 "highp",
3412 "precision",
3413 "sampler1D",
3414 "sampler2D",
3415 "sampler3D",
3416 "samplerCube",
3417 "sampler1DShadow",
3418 "sampler2DShadow",
3419 "samplerCubeShadow",
3420 "sampler1DArray",
3421 "sampler2DArray",
3422 "sampler1DArrayShadow",
3423 "sampler2DArrayShadow",
3424 "isampler1D",
3425 "isampler2D",
3426 "isampler3D",
3427 "isamplerCube",
3428 "isampler1DArray",
3429 "isampler2DArray",
3430 "usampler1D",
3431 "usampler2D",
3432 "usampler3D",
3433 "usamplerCube",
3434 "usampler1DArray",
3435 "usampler2DArray",
3436 "sampler2DRect",
3437 "sampler2DRectShadow",
3438 "isampler2DRect",
3439 "usampler2DRect",
3440 "samplerBuffer",
3441 "isamplerBuffer",
3442 "usamplerBuffer",
3443 "sampler2DMS",
3444 "isampler2DMS",
3445 "usampler2DMS",
3446 "sampler2DMSArray",
3447 "isampler2DMSArray",
3448 "usampler2DMSArray",
3449 "samplerCubeArray",
3450 "samplerCubeArrayShadow",
3451 "isamplerCubeArray",
3452 "usamplerCubeArray",
3453 };
3454 static const char* keywords_gl41[] = {
3455 "attribute",
3456 "const",
3457 "uniform",
3458 "varying",
3459 "layout",
3460 "centroid",
3461 "flat",
3462 "smooth",
3463 "noperspective",
3464 "patch",
3465 "sample",
3466 "break",
3467 "continue",
3468 "do",
3469 "for",
3470 "while",
3471 "switch",
3472 "case",
3473 "default",
3474 "if",
3475 "else",
3476 "subroutine",
3477 "in",
3478 "out",
3479 "inout",
3480 "float",
3481 "double",
3482 "int",
3483 "void",
3484 "bool",
3485 "true",
3486 "false",
3487 "invariant",
3488 "discard",
3489 "return",
3490 "mat2",
3491 "mat3",
3492 "mat4",
3493 "dmat2",
3494 "dmat3",
3495 "dmat4",
3496 "mat2x2",
3497 "mat2x3",
3498 "mat2x4",
3499 "dmat2x2",
3500 "dmat2x3",
3501 "dmat2x4",
3502 "mat3x2",
3503 "mat3x3",
3504 "mat3x4",
3505 "dmat3x2",
3506 "dmat3x3",
3507 "dmat3x4",
3508 "mat4x2",
3509 "mat4x3",
3510 "mat4x4",
3511 "dmat4x2",
3512 "dmat4x3",
3513 "dmat4x4",
3514 "vec2",
3515 "vec3",
3516 "vec4",
3517 "ivec2",
3518 "ivec3",
3519 "ivec4",
3520 "bvec2",
3521 "bvec3",
3522 "bvec4",
3523 "dvec2",
3524 "dvec3",
3525 "dvec4",
3526 "uint",
3527 "uvec2",
3528 "uvec3",
3529 "uvec4",
3530 "lowp",
3531 "mediump",
3532 "highp",
3533 "precision",
3534 "sampler1D",
3535 "sampler2D",
3536 "sampler3D",
3537 "samplerCube",
3538 "sampler1DShadow",
3539 "sampler2DShadow",
3540 "samplerCubeShadow",
3541 "sampler1DArray",
3542 "sampler2DArray",
3543 "sampler1DArrayShadow",
3544 "sampler2DArrayShadow",
3545 "isampler1D",
3546 "isampler2D",
3547 "isampler3D",
3548 "isamplerCube",
3549 "isampler1DArray",
3550 "isampler2DArray",
3551 "usampler1D",
3552 "usampler2D",
3553 "usampler3D",
3554 "usamplerCube",
3555 "usampler1DArray",
3556 "usampler2DArray",
3557 "sampler2DRect",
3558 "sampler2DRectShadow",
3559 "isampler2DRect",
3560 "usampler2DRect",
3561 "samplerBuffer",
3562 "isamplerBuffer",
3563 "usamplerBuffer",
3564 "sampler2DMS",
3565 "isampler2DMS",
3566 "usampler2DMS",
3567 "sampler2DMSArray",
3568 "isampler2DMSArray",
3569 "usampler2DMSArray",
3570 "samplerCubeArray",
3571 "samplerCubeArrayShadow",
3572 "isamplerCubeArray",
3573 "usamplerCubeArray",
3574 };
3575 static const char* keywords_gl42[] = {
3576 "attribute",
3577 "const",
3578 "uniform",
3579 "varying",
3580 "coherent",
3581 "volatile",
3582 "restrict",
3583 "readonly",
3584 "writeonly",
3585 "atomic_uint",
3586 "layout",
3587 "centroid",
3588 "flat",
3589 "smooth",
3590 "noperspective",
3591 "patch",
3592 "sample",
3593 "break",
3594 "continue",
3595 "do",
3596 "for",
3597 "while",
3598 "switch",
3599 "case",
3600 "default",
3601 "if",
3602 "else",
3603 "subroutine",
3604 "in",
3605 "out",
3606 "inout",
3607 "float",
3608 "double",
3609 "int",
3610 "void",
3611 "bool",
3612 "true",
3613 "false",
3614 "invariant",
3615 "discard",
3616 "return",
3617 "mat2",
3618 "mat3",
3619 "mat4",
3620 "dmat2",
3621 "dmat3",
3622 "dmat4",
3623 "mat2x2",
3624 "mat2x3",
3625 "mat2x4",
3626 "dmat2x2",
3627 "dmat2x3",
3628 "dmat2x4",
3629 "mat3x2",
3630 "mat3x3",
3631 "mat3x4",
3632 "dmat3x2",
3633 "dmat3x3",
3634 "dmat3x4",
3635 "mat4x2",
3636 "mat4x3",
3637 "mat4x4",
3638 "dmat4x2",
3639 "dmat4x3",
3640 "dmat4x4",
3641 "vec2",
3642 "vec3",
3643 "vec4",
3644 "ivec2",
3645 "ivec3",
3646 "ivec4",
3647 "bvec2",
3648 "bvec3",
3649 "bvec4",
3650 "dvec2",
3651 "dvec3",
3652 "dvec4",
3653 "uint",
3654 "uvec2",
3655 "uvec3",
3656 "uvec4",
3657 "lowp",
3658 "mediump",
3659 "highp",
3660 "precision",
3661 "sampler1D",
3662 "sampler2D",
3663 "sampler3D",
3664 "samplerCube",
3665 "sampler1DShadow",
3666 "sampler2DShadow",
3667 "samplerCubeShadow",
3668 "sampler1DArray",
3669 "sampler2DArray",
3670 "sampler1DArrayShadow",
3671 "sampler2DArrayShadow",
3672 "isampler1D",
3673 "isampler2D",
3674 "isampler3D",
3675 "isamplerCube",
3676 "isampler1DArray",
3677 "isampler2DArray",
3678 "usampler1D",
3679 "usampler2D",
3680 "usampler3D",
3681 "usamplerCube",
3682 "usampler1DArray",
3683 "usampler2DArray",
3684 "sampler2DRect",
3685 "sampler2DRectShadow",
3686 "isampler2DRect",
3687 "usampler2DRect",
3688 "samplerBuffer",
3689 "isamplerBuffer",
3690 "usamplerBuffer",
3691 "sampler2DMS",
3692 "isampler2DMS",
3693 "usampler2DMS",
3694 "sampler2DMSArray",
3695 "isampler2DMSArray",
3696 "usampler2DMSArray",
3697 "samplerCubeArray",
3698 "samplerCubeArrayShadow",
3699 "isamplerCubeArray",
3700 "usamplerCubeArray",
3701 "image1D",
3702 "iimage1D",
3703 "uimage1D",
3704 "image2D",
3705 "iimage2D",
3706 "uimage2D",
3707 "image3D",
3708 "iimage3D",
3709 "uimage3D",
3710 "image2DRect",
3711 "iimage2DRect",
3712 "uimage2DRect",
3713 "imageCube",
3714 "iimageCube",
3715 "uimageCube",
3716 "imageBuffer",
3717 "iimageBuffer",
3718 "uimageBuffer",
3719 "image1DArray",
3720 "iimage1DArray",
3721 "uimage1DArray",
3722 "image2DArray",
3723 "iimage2DArray",
3724 "uimage2DArray",
3725 "imageCubeArray",
3726 "iimageCubeArray",
3727 "uimageCubeArray",
3728 "image2DMS",
3729 "iimage2DMS",
3730 "uimage2DMS",
3731 "image2DMSArray",
3732 "iimage2DMSArray",
3733 "uimage2DMSArray",
3734 };
3735 static const char* keywords_gl43[] = {
3736 "attribute",
3737 "const",
3738 "uniform",
3739 "varying",
3740 "buffer",
3741 "shared",
3742 "coherent",
3743 "volatile",
3744 "restrict",
3745 "readonly",
3746 "writeonly",
3747 "atomic_uint",
3748 "layout",
3749 "centroid",
3750 "flat",
3751 "smooth",
3752 "noperspective",
3753 "patch",
3754 "sample",
3755 "break",
3756 "continue",
3757 "do",
3758 "for",
3759 "while",
3760 "switch",
3761 "case",
3762 "default",
3763 "if",
3764 "else",
3765 "subroutine",
3766 "in",
3767 "out",
3768 "inout",
3769 "float",
3770 "double",
3771 "int",
3772 "void",
3773 "bool",
3774 "true",
3775 "false",
3776 "invariant",
3777 "precise",
3778 "discard",
3779 "return",
3780 "mat2",
3781 "mat3",
3782 "mat4",
3783 "dmat2",
3784 "dmat3",
3785 "dmat4",
3786 "mat2x2",
3787 "mat2x3",
3788 "mat2x4",
3789 "dmat2x2",
3790 "dmat2x3",
3791 "dmat2x4",
3792 "mat3x2",
3793 "mat3x3",
3794 "mat3x4",
3795 "dmat3x2",
3796 "dmat3x3",
3797 "dmat3x4",
3798 "mat4x2",
3799 "mat4x3",
3800 "mat4x4",
3801 "dmat4x2",
3802 "dmat4x3",
3803 "dmat4x4",
3804 "vec2",
3805 "vec3",
3806 "vec4",
3807 "ivec2",
3808 "ivec3",
3809 "ivec4",
3810 "bvec2",
3811 "bvec3",
3812 "bvec4",
3813 "dvec2",
3814 "dvec3",
3815 "dvec4",
3816 "uint",
3817 "uvec2",
3818 "uvec3",
3819 "uvec4",
3820 "lowp",
3821 "mediump",
3822 "highp",
3823 "precision",
3824 "sampler1D",
3825 "sampler2D",
3826 "sampler3D",
3827 "samplerCube",
3828 "sampler1DShadow",
3829 "sampler2DShadow",
3830 "samplerCubeShadow",
3831 "sampler1DArray",
3832 "sampler2DArray",
3833 "sampler1DArrayShadow",
3834 "sampler2DArrayShadow",
3835 "isampler1D",
3836 "isampler2D",
3837 "isampler3D",
3838 "isamplerCube",
3839 "isampler1DArray",
3840 "isampler2DArray",
3841 "usampler1D",
3842 "usampler2D",
3843 "usampler3D",
3844 "usamplerCube",
3845 "usampler1DArray",
3846 "usampler2DArray",
3847 "sampler2DRect",
3848 "sampler2DRectShadow",
3849 "isampler2DRect",
3850 "usampler2DRect",
3851 "samplerBuffer",
3852 "isamplerBuffer",
3853 "usamplerBuffer",
3854 "sampler2DMS",
3855 "isampler2DMS",
3856 "usampler2DMS",
3857 "sampler2DMSArray",
3858 "isampler2DMSArray",
3859 "usampler2DMSArray",
3860 "samplerCubeArray",
3861 "samplerCubeArrayShadow",
3862 "isamplerCubeArray",
3863 "usamplerCubeArray",
3864 "image1D",
3865 "iimage1D",
3866 "uimage1D",
3867 "image2D",
3868 "iimage2D",
3869 "uimage2D",
3870 "image3D",
3871 "iimage3D",
3872 "uimage3D",
3873 "image2DRect",
3874 "iimage2DRect",
3875 "uimage2DRect",
3876 "imageCube",
3877 "iimageCube",
3878 "uimageCube",
3879 "imageBuffer",
3880 "iimageBuffer",
3881 "uimageBuffer",
3882 "image1DArray",
3883 "iimage1DArray",
3884 "uimage1DArray",
3885 "image2DArray",
3886 "iimage2DArray",
3887 "uimage2DArray",
3888 "imageCubeArray",
3889 "iimageCubeArray",
3890 "uimageCubeArray",
3891 "image2DMS",
3892 "iimage2DMS",
3893 "uimage2DMS",
3894 "image2DMSArray",
3895 "iimage2DMSArray",
3896 "uimage2DMSArray",
3897 };
3898 static const char* keywords_gl44[] = {
3899 "attribute",
3900 "const",
3901 "uniform",
3902 "varying",
3903 "buffer",
3904 "shared",
3905 "coherent",
3906 "volatile",
3907 "restrict",
3908 "readonly",
3909 "writeonly",
3910 "atomic_uint",
3911 "layout",
3912 "centroid",
3913 "flat",
3914 "smooth",
3915 "noperspective",
3916 "patch",
3917 "sample",
3918 "break",
3919 "continue",
3920 "do",
3921 "for",
3922 "while",
3923 "switch",
3924 "case",
3925 "default",
3926 "if",
3927 "else",
3928 "subroutine",
3929 "in",
3930 "out",
3931 "inout",
3932 "float",
3933 "double",
3934 "int",
3935 "void",
3936 "bool",
3937 "true",
3938 "false",
3939 "invariant",
3940 "precise",
3941 "discard",
3942 "return",
3943 "mat2",
3944 "mat3",
3945 "mat4",
3946 "dmat2",
3947 "dmat3",
3948 "dmat4",
3949 "mat2x2",
3950 "mat2x3",
3951 "mat2x4",
3952 "dmat2x2",
3953 "dmat2x3",
3954 "dmat2x4",
3955 "mat3x2",
3956 "mat3x3",
3957 "mat3x4",
3958 "dmat3x2",
3959 "dmat3x3",
3960 "dmat3x4",
3961 "mat4x2",
3962 "mat4x3",
3963 "mat4x4",
3964 "dmat4x2",
3965 "dmat4x3",
3966 "dmat4x4",
3967 "vec2",
3968 "vec3",
3969 "vec4",
3970 "ivec2",
3971 "ivec3",
3972 "ivec4",
3973 "bvec2",
3974 "bvec3",
3975 "bvec4",
3976 "dvec2",
3977 "dvec3",
3978 "dvec4",
3979 "uint",
3980 "uvec2",
3981 "uvec3",
3982 "uvec4",
3983 "lowp",
3984 "mediump",
3985 "highp",
3986 "precision",
3987 "sampler1D",
3988 "sampler2D",
3989 "sampler3D",
3990 "samplerCube",
3991 "sampler1DShadow",
3992 "sampler2DShadow",
3993 "samplerCubeShadow",
3994 "sampler1DArray",
3995 "sampler2DArray",
3996 "sampler1DArrayShadow",
3997 "sampler2DArrayShadow",
3998 "isampler1D",
3999 "isampler2D",
4000 "isampler3D",
4001 "isamplerCube",
4002 "isampler1DArray",
4003 "isampler2DArray",
4004 "usampler1D",
4005 "usampler2D",
4006 "usampler3D",
4007 "usamplerCube",
4008 "usampler1DArray",
4009 "usampler2DArray",
4010 "sampler2DRect",
4011 "sampler2DRectShadow",
4012 "isampler2DRect",
4013 "usampler2DRect",
4014 "samplerBuffer",
4015 "isamplerBuffer",
4016 "usamplerBuffer",
4017 "sampler2DMS",
4018 "isampler2DMS",
4019 "usampler2DMS",
4020 "sampler2DMSArray",
4021 "isampler2DMSArray",
4022 "usampler2DMSArray",
4023 "samplerCubeArray",
4024 "samplerCubeArrayShadow",
4025 "isamplerCubeArray",
4026 "usamplerCubeArray",
4027 "image1D",
4028 "iimage1D",
4029 "uimage1D",
4030 "image2D",
4031 "iimage2D",
4032 "uimage2D",
4033 "image3D",
4034 "iimage3D",
4035 "uimage3D",
4036 "image2DRect",
4037 "iimage2DRect",
4038 "uimage2DRect",
4039 "imageCube",
4040 "iimageCube",
4041 "uimageCube",
4042 "imageBuffer",
4043 "iimageBuffer",
4044 "uimageBuffer",
4045 "image1DArray",
4046 "iimage1DArray",
4047 "uimage1DArray",
4048 "image2DArray",
4049 "iimage2DArray",
4050 "uimage2DArray",
4051 "imageCubeArray",
4052 "iimageCubeArray",
4053 "uimageCubeArray",
4054 "image2DMS",
4055 "iimage2DMS",
4056 "uimage2DMS",
4057 "image2DMSArray",
4058 "iimage2DMSArray",
4059 "uimage2DMSArray",
4060 };
4061 static const char* keywords_gl45[] = {
4062 "attribute",
4063 "const",
4064 "uniform",
4065 "varying",
4066 "buffer",
4067 "shared",
4068 "coherent",
4069 "volatile",
4070 "restrict",
4071 "readonly",
4072 "writeonly",
4073 "atomic_uint",
4074 "layout",
4075 "centroid",
4076 "flat",
4077 "smooth",
4078 "noperspective",
4079 "patch",
4080 "sample",
4081 "break",
4082 "continue",
4083 "do",
4084 "for",
4085 "while",
4086 "switch",
4087 "case",
4088 "default",
4089 "if",
4090 "else",
4091 "subroutine",
4092 "in",
4093 "out",
4094 "inout",
4095 "float",
4096 "double",
4097 "int",
4098 "void",
4099 "bool",
4100 "true",
4101 "false",
4102 "invariant",
4103 "precise",
4104 "discard",
4105 "return",
4106 "mat2",
4107 "mat3",
4108 "mat4",
4109 "dmat2",
4110 "dmat3",
4111 "dmat4",
4112 "mat2x2",
4113 "mat2x3",
4114 "mat2x4",
4115 "dmat2x2",
4116 "dmat2x3",
4117 "dmat2x4",
4118 "mat3x2",
4119 "mat3x3",
4120 "mat3x4",
4121 "dmat3x2",
4122 "dmat3x3",
4123 "dmat3x4",
4124 "mat4x2",
4125 "mat4x3",
4126 "mat4x4",
4127 "dmat4x2",
4128 "dmat4x3",
4129 "dmat4x4",
4130 "vec2",
4131 "vec3",
4132 "vec4",
4133 "ivec2",
4134 "ivec3",
4135 "ivec4",
4136 "bvec2",
4137 "bvec3",
4138 "bvec4",
4139 "dvec2",
4140 "dvec3",
4141 "dvec4",
4142 "uint",
4143 "uvec2",
4144 "uvec3",
4145 "uvec4",
4146 "lowp",
4147 "mediump",
4148 "highp",
4149 "precision",
4150 "sampler1D",
4151 "sampler2D",
4152 "sampler3D",
4153 "samplerCube",
4154 "sampler1DShadow",
4155 "sampler2DShadow",
4156 "samplerCubeShadow",
4157 "sampler1DArray",
4158 "sampler2DArray",
4159 "sampler1DArrayShadow",
4160 "sampler2DArrayShadow",
4161 "isampler1D",
4162 "isampler2D",
4163 "isampler3D",
4164 "isamplerCube",
4165 "isampler1DArray",
4166 "isampler2DArray",
4167 "usampler1D",
4168 "usampler2D",
4169 "usampler3D",
4170 "usamplerCube",
4171 "usampler1DArray",
4172 "usampler2DArray",
4173 "sampler2DRect",
4174 "sampler2DRectShadow",
4175 "isampler2DRect",
4176 "usampler2DRect",
4177 "samplerBuffer",
4178 "isamplerBuffer",
4179 "usamplerBuffer",
4180 "sampler2DMS",
4181 "isampler2DMS",
4182 "usampler2DMS",
4183 "sampler2DMSArray",
4184 "isampler2DMSArray",
4185 "usampler2DMSArray",
4186 "samplerCubeArray",
4187 "samplerCubeArrayShadow",
4188 "isamplerCubeArray",
4189 "usamplerCubeArray",
4190 "image1D",
4191 "iimage1D",
4192 "uimage1D",
4193 "image2D",
4194 "iimage2D",
4195 "uimage2D",
4196 "image3D",
4197 "iimage3D",
4198 "uimage3D",
4199 "image2DRect",
4200 "iimage2DRect",
4201 "uimage2DRect",
4202 "imageCube",
4203 "iimageCube",
4204 "uimageCube",
4205 "imageBuffer",
4206 "iimageBuffer",
4207 "uimageBuffer",
4208 "image1DArray",
4209 "iimage1DArray",
4210 "uimage1DArray",
4211 "image2DArray",
4212 "iimage2DArray",
4213 "uimage2DArray",
4214 "imageCubeArray",
4215 "iimageCubeArray",
4216 "uimageCubeArray",
4217 "image2DMS",
4218 "iimage2DMS",
4219 "uimage2DMS",
4220 "image2DMSArray",
4221 "iimage2DMSArray",
4222 "uimage2DMSArray",
4223 };
4224 static const char* keywords_gl46[] = {
4225 "attribute",
4226 "const",
4227 "uniform",
4228 "varying",
4229 "buffer",
4230 "shared",
4231 "coherent",
4232 "volatile",
4233 "restrict",
4234 "readonly",
4235 "writeonly",
4236 "atomic_uint",
4237 "layout",
4238 "centroid",
4239 "flat",
4240 "smooth",
4241 "noperspective",
4242 "patch",
4243 "sample",
4244 "break",
4245 "continue",
4246 "do",
4247 "for",
4248 "while",
4249 "switch",
4250 "case",
4251 "default",
4252 "if",
4253 "else",
4254 "subroutine",
4255 "in",
4256 "out",
4257 "inout",
4258 "float",
4259 "double",
4260 "int",
4261 "void",
4262 "bool",
4263 "true",
4264 "false",
4265 "invariant",
4266 "precise",
4267 "discard",
4268 "return",
4269 "mat2",
4270 "mat3",
4271 "mat4",
4272 "dmat2",
4273 "dmat3",
4274 "dmat4",
4275 "mat2x2",
4276 "mat2x3",
4277 "mat2x4",
4278 "dmat2x2",
4279 "dmat2x3",
4280 "dmat2x4",
4281 "mat3x2",
4282 "mat3x3",
4283 "mat3x4",
4284 "dmat3x2",
4285 "dmat3x3",
4286 "dmat3x4",
4287 "mat4x2",
4288 "mat4x3",
4289 "mat4x4",
4290 "dmat4x2",
4291 "dmat4x3",
4292 "dmat4x4",
4293 "vec2",
4294 "vec3",
4295 "vec4",
4296 "ivec2",
4297 "ivec3",
4298 "ivec4",
4299 "bvec2",
4300 "bvec3",
4301 "bvec4",
4302 "dvec2",
4303 "dvec3",
4304 "dvec4",
4305 "uint",
4306 "uvec2",
4307 "uvec3",
4308 "uvec4",
4309 "lowp",
4310 "mediump",
4311 "highp",
4312 "precision",
4313 "sampler1D",
4314 "sampler2D",
4315 "sampler3D",
4316 "samplerCube",
4317 "sampler1DShadow",
4318 "sampler2DShadow",
4319 "samplerCubeShadow",
4320 "sampler1DArray",
4321 "sampler2DArray",
4322 "sampler1DArrayShadow",
4323 "sampler2DArrayShadow",
4324 "isampler1D",
4325 "isampler2D",
4326 "isampler3D",
4327 "isamplerCube",
4328 "isampler1DArray",
4329 "isampler2DArray",
4330 "usampler1D",
4331 "usampler2D",
4332 "usampler3D",
4333 "usamplerCube",
4334 "usampler1DArray",
4335 "usampler2DArray",
4336 "sampler2DRect",
4337 "sampler2DRectShadow",
4338 "isampler2DRect",
4339 "usampler2DRect",
4340 "samplerBuffer",
4341 "isamplerBuffer",
4342 "usamplerBuffer",
4343 "sampler2DMS",
4344 "isampler2DMS",
4345 "usampler2DMS",
4346 "sampler2DMSArray",
4347 "isampler2DMSArray",
4348 "usampler2DMSArray",
4349 "samplerCubeArray",
4350 "samplerCubeArrayShadow",
4351 "isamplerCubeArray",
4352 "usamplerCubeArray",
4353 "image1D",
4354 "iimage1D",
4355 "uimage1D",
4356 "image2D",
4357 "iimage2D",
4358 "uimage2D",
4359 "image3D",
4360 "iimage3D",
4361 "uimage3D",
4362 "image2DRect",
4363 "iimage2DRect",
4364 "uimage2DRect",
4365 "imageCube",
4366 "iimageCube",
4367 "uimageCube",
4368 "imageBuffer",
4369 "iimageBuffer",
4370 "uimageBuffer",
4371 "image1DArray",
4372 "iimage1DArray",
4373 "uimage1DArray",
4374 "image2DArray",
4375 "iimage2DArray",
4376 "uimage2DArray",
4377 "imageCubeArray",
4378 "iimageCubeArray",
4379 "uimageCubeArray",
4380 "image2DMS",
4381 "iimage2DMS",
4382 "uimage2DMS",
4383 "image2DMSArray",
4384 "iimage2DMSArray",
4385 "uimage2DMSArray",
4386 "struct"
4387 };
4388 static const char* reserved_gl31[] = {
4389 "common",
4390 "partition",
4391 "active",
4392 "asm",
4393 "class",
4394 "union",
4395 "enum",
4396 "typedef",
4397 "template",
4398 "this",
4399 "packed",
4400 "goto",
4401 "inline",
4402 "noinline",
4403 "volatile",
4404 "public",
4405 "static",
4406 "extern",
4407 "external",
4408 "interface",
4409 "long",
4410 "short",
4411 "double",
4412 "half",
4413 "fixed",
4414 "unsigned",
4415 "superp",
4416 "input",
4417 "output",
4418 "hvec2",
4419 "hvec3",
4420 "hvec4",
4421 "dvec2",
4422 "dvec3",
4423 "dvec4",
4424 "fvec2",
4425 "fvec3",
4426 "fvec4",
4427 "sampler3DRect",
4428 "filter",
4429 "image1D",
4430 "image2D",
4431 "image3D",
4432 "imageCube",
4433 "iimage1D",
4434 "iimage2D",
4435 "iimage3D",
4436 "iimageCube",
4437 "uimage1D",
4438 "uimage2D",
4439 "uimage3D",
4440 "uimageCube",
4441 "image1DArray",
4442 "image2DArray",
4443 "iimage1DArray",
4444 "iimage2DArray",
4445 "uimage1DArray",
4446 "uimage2DArray",
4447 "image1DShadow",
4448 "image2DShadow",
4449 "image1DArrayShadow",
4450 "image2DArrayShadow",
4451 "imageBuffer",
4452 "iimageBuffer",
4453 "uimageBuffer",
4454 "sizeof",
4455 "cast",
4456 "namespace",
4457 "using",
4458 "row_major",
4459 };
4460 static const char* reserved_gl32[] = {
4461 "common",
4462 "partition",
4463 "active",
4464 "asm",
4465 "class",
4466 "union",
4467 "enum",
4468 "typedef",
4469 "template",
4470 "this",
4471 "packed",
4472 "goto",
4473 "inline",
4474 "noinline",
4475 "volatile",
4476 "public",
4477 "static",
4478 "extern",
4479 "external",
4480 "interface",
4481 "long",
4482 "short",
4483 "double",
4484 "half",
4485 "fixed",
4486 "unsigned",
4487 "superp",
4488 "input",
4489 "output",
4490 "hvec2",
4491 "hvec3",
4492 "hvec4",
4493 "dvec2",
4494 "dvec3",
4495 "dvec4",
4496 "fvec2",
4497 "fvec3",
4498 "fvec4",
4499 "sampler3DRect",
4500 "filter",
4501 "image1D",
4502 "image2D",
4503 "image3D",
4504 "imageCube",
4505 "iimage1D",
4506 "iimage2D",
4507 "iimage3D",
4508 "iimageCube",
4509 "uimage1D",
4510 "uimage2D",
4511 "uimage3D",
4512 "uimageCube",
4513 "image1DArray",
4514 "image2DArray",
4515 "iimage1DArray",
4516 "iimage2DArray",
4517 "uimage1DArray",
4518 "uimage2DArray",
4519 "image1DShadow",
4520 "image2DShadow",
4521 "image1DArrayShadow",
4522 "image2DArrayShadow",
4523 "imageBuffer",
4524 "iimageBuffer",
4525 "uimageBuffer",
4526 "sizeof",
4527 "cast",
4528 "namespace",
4529 "using",
4530 "row_major",
4531 };
4532 static const char* reserved_gl33[] = {
4533 "common",
4534 "partition",
4535 "active",
4536 "asm",
4537 "class",
4538 "union",
4539 "enum",
4540 "typedef",
4541 "template",
4542 "this",
4543 "packed",
4544 "goto",
4545 "inline",
4546 "noinline",
4547 "volatile",
4548 "public",
4549 "static",
4550 "extern",
4551 "external",
4552 "interface",
4553 "long",
4554 "short",
4555 "double",
4556 "half",
4557 "fixed",
4558 "unsigned",
4559 "superp",
4560 "input",
4561 "output",
4562 "hvec2",
4563 "hvec3",
4564 "hvec4",
4565 "dvec2",
4566 "dvec3",
4567 "dvec4",
4568 "fvec2",
4569 "fvec3",
4570 "fvec4",
4571 "sampler3DRect",
4572 "filter",
4573 "image1D",
4574 "image2D",
4575 "image3D",
4576 "imageCube",
4577 "iimage1D",
4578 "iimage2D",
4579 "iimage3D",
4580 "iimageCube",
4581 "uimage1D",
4582 "uimage2D",
4583 "uimage3D",
4584 "uimageCube",
4585 "image1DArray",
4586 "image2DArray",
4587 "iimage1DArray",
4588 "iimage2DArray",
4589 "uimage1DArray",
4590 "uimage2DArray",
4591 "image1DShadow",
4592 "image2DShadow",
4593 "image1DArrayShadow",
4594 "image2DArrayShadow",
4595 "imageBuffer",
4596 "iimageBuffer",
4597 "uimageBuffer",
4598 "sizeof",
4599 "cast",
4600 "namespace",
4601 "using",
4602 "row_major",
4603 };
4604 static const char* reserved_gl40[] = {
4605 "common",
4606 "partition",
4607 "active",
4608 "asm",
4609 "class",
4610 "union",
4611 "enum",
4612 "typedef",
4613 "template",
4614 "this",
4615 "packed",
4616 "goto",
4617 "inline",
4618 "noinline",
4619 "volatile",
4620 "public",
4621 "static",
4622 "extern",
4623 "external",
4624 "interface",
4625 "long",
4626 "short",
4627 "half",
4628 "fixed",
4629 "unsigned",
4630 "superp",
4631 "input",
4632 "output",
4633 "hvec2",
4634 "hvec3",
4635 "hvec4",
4636 "fvec2",
4637 "fvec3",
4638 "fvec4",
4639 "sampler3DRect",
4640 "filter",
4641 "image1D",
4642 "image2D",
4643 "image3D",
4644 "imageCube",
4645 "iimage1D",
4646 "iimage2D",
4647 "iimage3D",
4648 "iimageCube",
4649 "uimage1D",
4650 "uimage2D",
4651 "uimage3D",
4652 "uimageCube",
4653 "image1DArray",
4654 "image2DArray",
4655 "iimage1DArray",
4656 "iimage2DArray",
4657 "uimage1DArray",
4658 "uimage2DArray",
4659 "image1DShadow",
4660 "image2DShadow",
4661 "image1DArrayShadow",
4662 "image2DArrayShadow",
4663 "imageBuffer",
4664 "iimageBuffer",
4665 "uimageBuffer",
4666 "sizeof",
4667 "cast",
4668 "namespace",
4669 "using",
4670 "row_major",
4671 };
4672 static const char* reserved_gl41[] = {
4673 "common",
4674 "partition",
4675 "active",
4676 "asm",
4677 "class",
4678 "union",
4679 "enum",
4680 "typedef",
4681 "template",
4682 "this",
4683 "packed",
4684 "goto",
4685 "inline",
4686 "noinline",
4687 "volatile",
4688 "public",
4689 "static",
4690 "extern",
4691 "external",
4692 "interface",
4693 "long",
4694 "short",
4695 "half",
4696 "fixed",
4697 "unsigned",
4698 "superp",
4699 "input",
4700 "output",
4701 "hvec2",
4702 "hvec3",
4703 "hvec4",
4704 "fvec2",
4705 "fvec3",
4706 "fvec4",
4707 "sampler3DRect",
4708 "filter",
4709 "image1D",
4710 "image2D",
4711 "image3D",
4712 "imageCube",
4713 "iimage1D",
4714 "iimage2D",
4715 "iimage3D",
4716 "iimageCube",
4717 "uimage1D",
4718 "uimage2D",
4719 "uimage3D",
4720 "uimageCube",
4721 "image1DArray",
4722 "image2DArray",
4723 "iimage1DArray",
4724 "iimage2DArray",
4725 "uimage1DArray",
4726 "uimage2DArray",
4727 "image1DShadow",
4728 "image2DShadow",
4729 "image1DArrayShadow",
4730 "image2DArrayShadow",
4731 "imageBuffer",
4732 "iimageBuffer",
4733 "uimageBuffer",
4734 "sizeof",
4735 "cast",
4736 "namespace",
4737 "using",
4738 "row_major",
4739 };
4740 static const char* reserved_gl42[] = {
4741 "common", "partition", "active", "asm", "class", "union", "enum", "typedef", "template",
4742 "this", "packed", "resource", "goto", "inline", "noinline", "public", "static", "extern",
4743 "external", "interface", "long", "short", "half", "fixed", "unsigned", "superp", "input",
4744 "output", "hvec2", "hvec3", "hvec4", "fvec2", "fvec3", "fvec4", "sampler3DRect", "filter",
4745 "sizeof", "cast", "namespace", "using", "row_major",
4746 };
4747 static const char* reserved_gl43[] = {
4748 "common", "partition", "active", "asm", "class", "union", "enum", "typedef", "template",
4749 "this", "packed", "resource", "goto", "inline", "noinline", "public", "static", "extern",
4750 "external", "interface", "long", "short", "half", "fixed", "unsigned", "superp", "input",
4751 "output", "hvec2", "hvec3", "hvec4", "fvec2", "fvec3", "fvec4", "sampler3DRect", "filter",
4752 "sizeof", "cast", "namespace", "using", "row_major",
4753 };
4754 static const char* reserved_gl44[] = {
4755 "common", "partition", "active", "asm", "class", "union", "enum", "typedef",
4756 "template", "this", "resource", "goto", "inline", "noinline", "public", "static",
4757 "extern", "external", "interface", "long", "short", "half", "fixed", "unsigned",
4758 "superp", "input", "output", "hvec2", "hvec3", "hvec4", "fvec2", "fvec3",
4759 "fvec4", "sampler3DRect", "filter", "sizeof", "cast", "namespace", "using",
4760 };
4761 static const char* reserved_gl45[] = {
4762 "common", "partition", "active", "asm", "class", "union", "enum", "typedef",
4763 "template", "this", "resource", "goto", "inline", "noinline", "public", "static",
4764 "extern", "external", "interface", "long", "short", "half", "fixed", "unsigned",
4765 "superp", "input", "output", "hvec2", "hvec3", "hvec4", "fvec2", "fvec3",
4766 "fvec4", "sampler3DRect", "filter", "sizeof", "cast", "namespace", "using",
4767 };
4768 static const char* reserved_gl46[] = {
4769 "common", "partition", "active", "asm", "class", "union", "enum", "typedef",
4770 "template", "this", "resource", "goto", "inline", "noinline", "public", "static",
4771 "extern", "external", "interface", "long", "short", "half", "fixed", "unsigned",
4772 "superp", "input", "output", "hvec2", "hvec3", "hvec4", "fvec2", "fvec3",
4773 "fvec4", "sampler3DRect", "filter", "sizeof", "cast", "namespace", "using",
4774 };
4775
4776 glu::ApiType apiType = context_type.getAPI();
4777 if (apiType == glu::ApiType::core(3, 1))
4778 {
4779 context_keywords = keywords_gl31;
4780 context_reserved = reserved_gl31;
4781 context_n_keywords = static_cast<unsigned int>(sizeof(keywords_gl31) / sizeof(keywords_gl31[0]));
4782 context_n_reserved = static_cast<unsigned int>(sizeof(reserved_gl31) / sizeof(reserved_gl31[0]));
4783 }
4784 else if (apiType == glu::ApiType::core(3, 2))
4785 {
4786 context_keywords = keywords_gl32;
4787 context_reserved = reserved_gl32;
4788 context_n_keywords = static_cast<unsigned int>(sizeof(keywords_gl32) / sizeof(keywords_gl32[0]));
4789 context_n_reserved = static_cast<unsigned int>(sizeof(reserved_gl32) / sizeof(reserved_gl32[0]));
4790 }
4791 else if (apiType == glu::ApiType::core(3, 3))
4792 {
4793 context_keywords = keywords_gl33;
4794 context_reserved = reserved_gl33;
4795 context_n_keywords = static_cast<unsigned int>(sizeof(keywords_gl33) / sizeof(keywords_gl33[0]));
4796 context_n_reserved = static_cast<unsigned int>(sizeof(reserved_gl33) / sizeof(reserved_gl33[0]));
4797 }
4798 else if (apiType == glu::ApiType::core(4, 0))
4799 {
4800 context_keywords = keywords_gl40;
4801 context_reserved = reserved_gl40;
4802 context_n_keywords = static_cast<unsigned int>(sizeof(keywords_gl40) / sizeof(keywords_gl40[0]));
4803 context_n_reserved = static_cast<unsigned int>(sizeof(reserved_gl40) / sizeof(reserved_gl40[0]));
4804 }
4805 else if (apiType == glu::ApiType::core(4, 1))
4806 {
4807 context_keywords = keywords_gl41;
4808 context_reserved = reserved_gl41;
4809 context_n_keywords = static_cast<unsigned int>(sizeof(keywords_gl41) / sizeof(keywords_gl41[0]));
4810 context_n_reserved = static_cast<unsigned int>(sizeof(reserved_gl41) / sizeof(reserved_gl41[0]));
4811 }
4812 else if (apiType == glu::ApiType::core(4, 2))
4813 {
4814 context_keywords = keywords_gl42;
4815 context_reserved = reserved_gl42;
4816 context_n_keywords = static_cast<unsigned int>(sizeof(keywords_gl42) / sizeof(keywords_gl42[0]));
4817 context_n_reserved = static_cast<unsigned int>(sizeof(reserved_gl42) / sizeof(reserved_gl42[0]));
4818 }
4819 else if (apiType == glu::ApiType::core(4, 3))
4820 {
4821 context_keywords = keywords_gl43;
4822 context_reserved = reserved_gl43;
4823 context_n_keywords = static_cast<unsigned int>(sizeof(keywords_gl43) / sizeof(keywords_gl43[0]));
4824 context_n_reserved = static_cast<unsigned int>(sizeof(reserved_gl43) / sizeof(reserved_gl43[0]));
4825 }
4826 else if (apiType == glu::ApiType::core(4, 4))
4827 {
4828 context_keywords = keywords_gl44;
4829 context_reserved = reserved_gl44;
4830 context_n_keywords = static_cast<unsigned int>(sizeof(keywords_gl44) / sizeof(keywords_gl44[0]));
4831 context_n_reserved = static_cast<unsigned int>(sizeof(reserved_gl44) / sizeof(reserved_gl44[0]));
4832 }
4833 else if (apiType == glu::ApiType::core(4, 5))
4834 {
4835 context_keywords = keywords_gl45;
4836 context_reserved = reserved_gl45;
4837 context_n_keywords = static_cast<unsigned int>(sizeof(keywords_gl45) / sizeof(keywords_gl45[0]));
4838 context_n_reserved = static_cast<unsigned int>(sizeof(reserved_gl45) / sizeof(reserved_gl45[0]));
4839 }
4840 else if (apiType == glu::ApiType::core(4, 6))
4841 {
4842 context_keywords = keywords_gl46;
4843 context_reserved = reserved_gl46;
4844 context_n_keywords = static_cast<unsigned int>(sizeof(keywords_gl46) / sizeof(keywords_gl46[0]));
4845 context_n_reserved = static_cast<unsigned int>(sizeof(reserved_gl46) / sizeof(reserved_gl46[0]));
4846 }
4847 else
4848 {
4849 TCU_FAIL("Unsupported GL context version - please implement.");
4850 }
4851
4852 for (unsigned int n_current_context_keyword = 0; n_current_context_keyword < context_n_keywords;
4853 ++n_current_context_keyword)
4854 {
4855 const char* current_context_keyword = context_keywords[n_current_context_keyword];
4856
4857 result.push_back(current_context_keyword);
4858 } /* for (all context keywords) */
4859
4860 for (unsigned int n_current_context_reserved = 0; n_current_context_reserved < context_n_reserved;
4861 ++n_current_context_reserved)
4862 {
4863 const char* current_context_reserved = context_reserved[n_current_context_reserved];
4864
4865 result.push_back(current_context_reserved);
4866 } /* for (all context reserved names) */
4867
4868 /* All done! */
4869 return result;
4870 }
4871
4872 /** Returns a shader body to use for the test. The body is formed, according to the user-specified
4873 * requirements.
4874 *
4875 * @param shader_type Shader stage the shader body should be returned for.
4876 * @param language_feature Language feature to test.
4877 * @param invalid_name Name to use for the language feature instance. The string should come
4878 * from the list of keywords or reserved names, specific to the currently
4879 * running rendering context's version.
4880 *
4881 * @return Requested shader body.
4882 */
getShaderBody(_shader_type shader_type,_language_feature language_feature,const char * invalid_name) const4883 std::string ReservedNamesTest::getShaderBody(_shader_type shader_type, _language_feature language_feature,
4884 const char* invalid_name) const
4885 {
4886 std::stringstream body_sstream;
4887 const glu::ContextType context_type = m_context.getRenderContext().getType();
4888
4889 /* Preamble: shader language version */
4890 body_sstream << "#version ";
4891
4892 glu::ApiType apiType = context_type.getAPI();
4893 if (apiType == glu::ApiType::core(3, 1))
4894 body_sstream << "140";
4895 else if (apiType == glu::ApiType::core(3, 2))
4896 body_sstream << "150";
4897 else if (apiType == glu::ApiType::core(3, 3))
4898 body_sstream << "330";
4899 else if (apiType == glu::ApiType::core(4, 0))
4900 body_sstream << "400";
4901 else if (apiType == glu::ApiType::core(4, 1))
4902 body_sstream << "410";
4903 else if (apiType == glu::ApiType::core(4, 2))
4904 body_sstream << "420";
4905 else if (apiType == glu::ApiType::core(4, 3))
4906 body_sstream << "430";
4907 else if (apiType == glu::ApiType::core(4, 4))
4908 body_sstream << "440";
4909 else if (apiType == glu::ApiType::core(4, 5))
4910 body_sstream << "450";
4911 else if (apiType == glu::ApiType::core(4, 6))
4912 body_sstream << "460";
4913 else
4914 {
4915 TCU_FAIL("Unsupported GL context version - please implement");
4916 }
4917
4918 body_sstream << "\n\n";
4919
4920 /* Preamble: layout qualifiers - required for CS, TC and TE shader stages */
4921 if (shader_type == SHADER_TYPE_COMPUTE)
4922 {
4923 body_sstream << "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n";
4924 }
4925 else if (shader_type == SHADER_TYPE_TESS_CONTROL)
4926 {
4927 body_sstream << "layout(vertices = 3) out;\n";
4928 }
4929 else if (shader_type == SHADER_TYPE_TESS_EVALUATION)
4930 {
4931 body_sstream << "layout(triangles) in;\n";
4932 }
4933
4934 body_sstream << "\n\n";
4935
4936 /* Language feature: insert incorrectly named atomic counter declaration if needed */
4937 if (language_feature == LANGUAGE_FEATURE_ATOMIC_COUNTER)
4938 {
4939 body_sstream << "layout(binding = 0, offset = 0) uniform atomic_uint " << invalid_name << ";\n";
4940 }
4941
4942 /* Language feature: insert incorrectly named attribute declaration if needed */
4943 if (language_feature == LANGUAGE_FEATURE_ATTRIBUTE)
4944 {
4945 body_sstream << "attribute vec4 " << invalid_name << ";\n";
4946 }
4947
4948 /* Language feature: insert incorrectly name constant declaration if needed */
4949 if (language_feature == LANGUAGE_FEATURE_CONSTANT)
4950 {
4951 body_sstream << "const vec4 " << invalid_name << " = vec4(2.0, 3.0, 4.0, 5.0);\n";
4952 }
4953
4954 /* Language feature: insert a function with incorrectly named argument if needed */
4955 if (language_feature == LANGUAGE_FEATURE_FUNCTION_ARGUMENT_NAME)
4956 {
4957 body_sstream << "void test(in vec4 " << invalid_name << ")\n"
4958 "{\n"
4959 "}\n";
4960 }
4961
4962 /* Language feature: insert incorrectly named function if needed */
4963 if (language_feature == LANGUAGE_FEATURE_FUNCTION_NAME)
4964 {
4965 body_sstream << "void " << invalid_name << "(in vec4 test)\n"
4966 "{\n"
4967 "}\n";
4968 }
4969
4970 /* Language feature: insert incorrectly named input variable if needed */
4971 if (language_feature == LANGUAGE_FEATURE_INPUT)
4972 {
4973 body_sstream << "in vec4 " << invalid_name;
4974
4975 if (shader_type == SHADER_TYPE_GEOMETRY || shader_type == SHADER_TYPE_TESS_CONTROL ||
4976 shader_type == SHADER_TYPE_TESS_EVALUATION)
4977 {
4978 body_sstream << "[]";
4979 }
4980
4981 body_sstream << ";\n";
4982 }
4983
4984 /* Language feature: insert declaration of an incorrectly named input block instance if needed */
4985 if (language_feature == LANGUAGE_FEATURE_INPUT_BLOCK_INSTANCE_NAME)
4986 {
4987 body_sstream << "in testBlock\n"
4988 "{\n"
4989 " vec4 test;\n"
4990 "} "
4991 << invalid_name;
4992
4993 if (shader_type == SHADER_TYPE_GEOMETRY || shader_type == SHADER_TYPE_TESS_CONTROL ||
4994 shader_type == SHADER_TYPE_TESS_EVALUATION)
4995 {
4996 body_sstream << "[]";
4997 }
4998
4999 body_sstream << ";\n";
5000 }
5001
5002 /* Language feature: insert declaration of an input block holding an incorrectly named member variable */
5003 if (language_feature == LANGUAGE_FEATURE_INPUT_BLOCK_MEMBER_NAME)
5004 {
5005 body_sstream << "in testBlock\n"
5006 "{\n"
5007 " vec4 "
5008 << invalid_name << ";\n"
5009 "} testBlockInstance";
5010
5011 if (shader_type == SHADER_TYPE_GEOMETRY || shader_type == SHADER_TYPE_TESS_CONTROL ||
5012 shader_type == SHADER_TYPE_TESS_EVALUATION)
5013 {
5014 body_sstream << "[]";
5015 }
5016
5017 body_sstream << ";\n";
5018 }
5019
5020 /* Language feature: insert declaration of an incorrectly named input block */
5021 if (language_feature == LANGUAGE_FEATURE_INPUT_BLOCK_NAME)
5022 {
5023 body_sstream << "in " << invalid_name << "\n"
5024 "{\n"
5025 " vec4 test;\n"
5026 "} testBlockInstance";
5027
5028 if (shader_type == SHADER_TYPE_GEOMETRY || shader_type == SHADER_TYPE_TESS_CONTROL ||
5029 shader_type == SHADER_TYPE_TESS_EVALUATION)
5030 {
5031 body_sstream << "[]";
5032 }
5033
5034 body_sstream << ";\n";
5035 }
5036
5037 /* Language feature: insert incorrectly named output variable if needed */
5038 if (language_feature == LANGUAGE_FEATURE_OUTPUT)
5039 {
5040 body_sstream << "out vec4 " << invalid_name;
5041
5042 if (shader_type == SHADER_TYPE_TESS_CONTROL)
5043 {
5044 body_sstream << "[]";
5045 }
5046
5047 body_sstream << ";\n";
5048 }
5049
5050 /* Language feature: insert declaration of an incorrectly named output block instance if needed */
5051 if (language_feature == LANGUAGE_FEATURE_OUTPUT_BLOCK_INSTANCE_NAME)
5052 {
5053 body_sstream << "out testBlock\n"
5054 "{\n"
5055 " vec4 test;\n"
5056 "} "
5057 << invalid_name;
5058
5059 if (shader_type == SHADER_TYPE_TESS_CONTROL)
5060 {
5061 body_sstream << "[]";
5062 }
5063
5064 body_sstream << ";\n";
5065 }
5066
5067 /* Language feature: insert declaration of an output block holding an incorrectly named member variable */
5068 if (language_feature == LANGUAGE_FEATURE_OUTPUT_BLOCK_MEMBER_NAME)
5069 {
5070 body_sstream << "out testBlock\n"
5071 "{\n"
5072 " vec4 "
5073 << invalid_name << ";\n"
5074 "} testBlockInstance";
5075
5076 if (shader_type == SHADER_TYPE_TESS_CONTROL)
5077 {
5078 body_sstream << "[]";
5079 }
5080
5081 body_sstream << ";\n";
5082 }
5083
5084 /* Language feature: insert declaration of an incorrectly named output block */
5085 if (language_feature == LANGUAGE_FEATURE_OUTPUT_BLOCK_NAME)
5086 {
5087 body_sstream << "out " << invalid_name << "\n"
5088 "{\n"
5089 " vec4 test;\n"
5090 "} testBlockInstance";
5091
5092 if (shader_type == SHADER_TYPE_TESS_CONTROL)
5093 {
5094 body_sstream << "[]";
5095 }
5096
5097 body_sstream << ";\n";
5098 }
5099
5100 /* Language feature: insert declaration of an incorrectly named shader storage block instance if needed */
5101 if (language_feature == LANGUAGE_FEATURE_SHADER_STORAGE_BLOCK_INSTANCE_NAME)
5102 {
5103 body_sstream << "buffer testBlock\n"
5104 "{\n"
5105 " vec4 test;\n"
5106 "} "
5107 << invalid_name << ";\n";
5108 }
5109
5110 /* Language feature: insert declaration of a shader storage block holding an incorrectly named member variable */
5111 if (language_feature == LANGUAGE_FEATURE_SHADER_STORAGE_BLOCK_MEMBER_NAME)
5112 {
5113 body_sstream << "buffer testBlock\n"
5114 "{\n"
5115 " vec4 "
5116 << invalid_name << ";\n"
5117 "};\n";
5118 }
5119
5120 /* Language feature: insert declaration of an incorrectly named shader storage block */
5121 if (language_feature == LANGUAGE_FEATURE_SHADER_STORAGE_BLOCK_NAME)
5122 {
5123 body_sstream << "buffer " << invalid_name << "\n"
5124 "{\n"
5125 " vec4 test;\n"
5126 "};\n";
5127 }
5128
5129 /* Language feature: insert declaration of a subroutine function with invalid name */
5130 if (language_feature == LANGUAGE_FEATURE_SUBROUTINE_FUNCTION_NAME)
5131 {
5132 body_sstream << "subroutine void exampleSubroutine(inout vec4 " << invalid_name
5133 << ");\n"
5134 "\n"
5135 "subroutine (exampleSubroutine) void invert(inout vec4 "
5136 << invalid_name << ")\n"
5137 "{\n"
5138 " "
5139 << invalid_name << " += vec4(0.0, 1.0, 2.0, 3.0);\n"
5140 "}\n"
5141 "\n"
5142 "subroutine uniform exampleSubroutine testSubroutine;\n";
5143 }
5144
5145 /* Language feature: insert declaration of a subroutine of incorrectly named type */
5146 if (language_feature == LANGUAGE_FEATURE_SUBROUTINE_TYPE)
5147 {
5148 body_sstream << "subroutine void " << invalid_name << "(inout vec4 arg);\n"
5149 "\n"
5150 "subroutine ("
5151 << invalid_name << ") void invert(inout vec4 arg)\n"
5152 "{\n"
5153 " arg += vec4(0.0, 1.0, 2.0, 3.0);\n"
5154 "}\n"
5155 "\n"
5156 "subroutine uniform "
5157 << invalid_name << " testSubroutine;\n";
5158 }
5159
5160 /* Language feature: insert declaration of a subroutine, followed by a declaration of
5161 * an incorrectly named subroutine uniform.
5162 */
5163 if (language_feature == LANGUAGE_FEATURE_SUBROUTINE_UNIFORM)
5164 {
5165 body_sstream << "subroutine void exampleSubroutine(inout vec4 arg);\n"
5166 "\n"
5167 "subroutine (exampleSubroutine) void invert(inout vec4 arg)\n"
5168 "{\n"
5169 " arg += vec4(0.0, 1.0, 2.0, 3.0);\n"
5170 "}\n"
5171 "\n"
5172 "subroutine uniform exampleSubroutine "
5173 << invalid_name << ";\n";
5174 }
5175
5176 /* Language feature: insert declaration of an incorrectly named uniform. */
5177 if (language_feature == LANGUAGE_FEATURE_UNIFORM)
5178 {
5179 body_sstream << "uniform sampler2D " << invalid_name << ";\n";
5180 }
5181
5182 /* Language feature: insert declaration of an incorrectly named uniform block instance if needed */
5183 if (language_feature == LANGUAGE_FEATURE_UNIFORM_BLOCK_INSTANCE_NAME)
5184 {
5185 body_sstream << "uniform testBlock\n"
5186 "{\n"
5187 " vec4 test;\n"
5188 "} "
5189 << invalid_name << ";\n";
5190 }
5191
5192 /* Language feature: insert declaration of an uniform block holding an incorrectly named member variable */
5193 if (language_feature == LANGUAGE_FEATURE_UNIFORM_BLOCK_MEMBER_NAME)
5194 {
5195 body_sstream << "uniform testBlock\n"
5196 "{\n"
5197 " vec4 "
5198 << invalid_name << ";\n"
5199 "};\n";
5200 }
5201
5202 /* Language feature: insert declaration of an incorrectly named uniform block */
5203 if (language_feature == LANGUAGE_FEATURE_UNIFORM_BLOCK_NAME)
5204 {
5205 body_sstream << "uniform " << invalid_name << "\n"
5206 "{\n"
5207 " vec4 test;\n"
5208 "};\n";
5209 }
5210
5211 /* Language feature: insert declaration of an incorrectly named varying */
5212 if (language_feature == LANGUAGE_FEATURE_VARYING)
5213 {
5214 body_sstream << "varying vec4 " << invalid_name << ";\n";
5215 }
5216
5217 /* Start implementation of the main entry-point. */
5218 body_sstream << "void main()\n"
5219 "{\n";
5220
5221 /* Language feature: insert declaration of an incorrectly named shared variable. */
5222 if (language_feature == LANGUAGE_FEATURE_SHARED_VARIABLE)
5223 {
5224 body_sstream << "shared vec4 " << invalid_name << ";\n";
5225 }
5226
5227 /* Language feature: insert declaration of a structure, whose instance name is incorrect */
5228 if (language_feature == LANGUAGE_FEATURE_STRUCTURE_INSTANCE_NAME)
5229 {
5230 body_sstream << "struct\n"
5231 "{\n"
5232 " vec4 test;\n"
5233 "} "
5234 << invalid_name << ";\n";
5235 }
5236
5237 /* Language feature: insert declaration of a structure with one of its member variables being incorrectly named. */
5238 if (language_feature == LANGUAGE_FEATURE_STRUCTURE_MEMBER)
5239 {
5240 body_sstream << "struct\n"
5241 "{\n"
5242 " vec4 "
5243 << invalid_name << ";\n"
5244 "} testInstance;\n";
5245 }
5246
5247 /* Language feature: insert declaration of a structure whose name is incorrect */
5248 if (language_feature == LANGUAGE_FEATURE_STRUCTURE_NAME)
5249 {
5250 body_sstream << "struct " << invalid_name << "{\n"
5251 " vec4 test;\n"
5252 << "};\n";
5253 }
5254
5255 /* Language feature: insert declaration of a variable with incorrect name. */
5256 if (language_feature == LANGUAGE_FEATURE_VARIABLE)
5257 {
5258 body_sstream << "vec4 " << invalid_name << ";\n";
5259 }
5260
5261 /* Close the main entry-point implementation */
5262 body_sstream << "}\n";
5263
5264 return body_sstream.str();
5265 }
5266
5267 /** Retrieves a literal corresponding to the user-specified shader type value.
5268 *
5269 * @param shader_type Enum to return the string for.
5270 *
5271 * @return As specified.
5272 */
getShaderTypeName(_shader_type shader_type) const5273 std::string ReservedNamesTest::getShaderTypeName(_shader_type shader_type) const
5274 {
5275 std::string result = "[?!]";
5276
5277 switch (shader_type)
5278 {
5279 case SHADER_TYPE_COMPUTE:
5280 result = "compute shader";
5281 break;
5282 case SHADER_TYPE_FRAGMENT:
5283 result = "fragment shader";
5284 break;
5285 case SHADER_TYPE_GEOMETRY:
5286 result = "geometry shader";
5287 break;
5288 case SHADER_TYPE_TESS_CONTROL:
5289 result = "tessellation control shader";
5290 break;
5291 case SHADER_TYPE_TESS_EVALUATION:
5292 result = "tessellation evaluation shader";
5293 break;
5294 case SHADER_TYPE_VERTEX:
5295 result = "vertex shader";
5296 break;
5297 default:
5298 result = "unknown";
5299 break;
5300 } /* switch (shader_type) */
5301
5302 return result;
5303 }
5304
5305 /** Returns a vector of _language_feature enums, telling which language features are supported, given running context's
5306 * version and shader type, in which the features are planned to be used.
5307 *
5308 * @param shader_type Shader stage the language features will be used in.
5309 *
5310 * @return As specified.
5311 **/
getSupportedLanguageFeatures(_shader_type shader_type) const5312 std::vector<ReservedNamesTest::_language_feature> ReservedNamesTest::getSupportedLanguageFeatures(
5313 _shader_type shader_type) const
5314 {
5315 const glu::ContextType context_type = m_context.getRenderContext().getType();
5316 std::vector<_language_feature> result;
5317
5318 /* Atomic counters are available, starting with GL 4.2. Availability for each shader stage
5319 * depends on the reported GL constant values, apart from CS & FS, for which AC support is guaranteed.
5320 */
5321 if (glu::contextSupports(context_type, glu::ApiType::core(4, 2)))
5322 {
5323 if (shader_type == SHADER_TYPE_COMPUTE || shader_type == SHADER_TYPE_FRAGMENT ||
5324 (shader_type == SHADER_TYPE_GEOMETRY && m_max_gs_acs > 0) ||
5325 (shader_type == SHADER_TYPE_TESS_CONTROL && m_max_tc_acs > 0) ||
5326 (shader_type == SHADER_TYPE_TESS_EVALUATION && m_max_te_acs > 0) ||
5327 (shader_type == SHADER_TYPE_VERTEX && m_max_vs_acs))
5328 {
5329 result.push_back(LANGUAGE_FEATURE_ATOMIC_COUNTER);
5330 }
5331 } /* if (context_type >= glu::CONTEXTTYPE_GL43_CORE) */
5332
5333 /* Attributes are only supported until GL 4.1, for VS shader stage only. */
5334 if (shader_type == SHADER_TYPE_VERTEX && !glu::contextSupports(context_type, glu::ApiType::core(4, 2)))
5335 {
5336 result.push_back(LANGUAGE_FEATURE_ATTRIBUTE);
5337 }
5338
5339 /* Constants are always supported */
5340 result.push_back(LANGUAGE_FEATURE_CONSTANT);
5341
5342 /* Functions are supported in all GL SL versions for all shader types. */
5343 result.push_back(LANGUAGE_FEATURE_FUNCTION_ARGUMENT_NAME);
5344 result.push_back(LANGUAGE_FEATURE_FUNCTION_NAME);
5345
5346 /* Inputs are supported in all GL SL versions for FS, GS, TC, TE and VS stages */
5347 if (shader_type == SHADER_TYPE_FRAGMENT || shader_type == SHADER_TYPE_GEOMETRY ||
5348 shader_type == SHADER_TYPE_TESS_CONTROL || shader_type == SHADER_TYPE_TESS_EVALUATION ||
5349 shader_type == SHADER_TYPE_VERTEX)
5350 {
5351 result.push_back(LANGUAGE_FEATURE_INPUT);
5352 }
5353
5354 /* Input blocks are available, starting with GL 3.2 for FS, GS, TC and TE stages. */
5355 if ((shader_type == SHADER_TYPE_FRAGMENT || shader_type == SHADER_TYPE_GEOMETRY ||
5356 shader_type == SHADER_TYPE_TESS_CONTROL || shader_type == SHADER_TYPE_TESS_EVALUATION ||
5357 shader_type == SHADER_TYPE_VERTEX) &&
5358 glu::contextSupports(context_type, glu::ApiType::core(3, 2)))
5359 {
5360 result.push_back(LANGUAGE_FEATURE_INPUT_BLOCK_INSTANCE_NAME);
5361 result.push_back(LANGUAGE_FEATURE_INPUT_BLOCK_MEMBER_NAME);
5362 result.push_back(LANGUAGE_FEATURE_INPUT_BLOCK_NAME);
5363 }
5364
5365 /* Outputs are supported in all GL SL versions for all shader stages expect CS */
5366 if (shader_type != SHADER_TYPE_COMPUTE)
5367 {
5368 result.push_back(LANGUAGE_FEATURE_OUTPUT);
5369 }
5370
5371 /* Output blocks are available, starting with GL 3.2 for GS, TC, TE and VS stages. */
5372 if ((shader_type == SHADER_TYPE_GEOMETRY || shader_type == SHADER_TYPE_TESS_CONTROL ||
5373 shader_type == SHADER_TYPE_TESS_EVALUATION || shader_type == SHADER_TYPE_VERTEX) &&
5374 glu::contextSupports(context_type, glu::ApiType::core(3, 2)))
5375 {
5376 result.push_back(LANGUAGE_FEATURE_OUTPUT_BLOCK_INSTANCE_NAME);
5377 result.push_back(LANGUAGE_FEATURE_OUTPUT_BLOCK_MEMBER_NAME);
5378 result.push_back(LANGUAGE_FEATURE_OUTPUT_BLOCK_NAME);
5379 }
5380
5381 /* Shader storage blocks are available, starting with GL 4.3. Availability for each shader stage
5382 * depends on the reported GL constant values, apart from CS, for which SSBO support is guaranteed.
5383 */
5384 if (glu::contextSupports(context_type, glu::ApiType::core(4, 3)))
5385 {
5386 if (shader_type == SHADER_TYPE_COMPUTE || (shader_type == SHADER_TYPE_FRAGMENT && m_max_fs_ssbos > 0) ||
5387 (shader_type == SHADER_TYPE_GEOMETRY && m_max_gs_ssbos > 0) ||
5388 (shader_type == SHADER_TYPE_TESS_CONTROL && m_max_tc_ssbos > 0) ||
5389 (shader_type == SHADER_TYPE_TESS_EVALUATION && m_max_te_ssbos > 0) ||
5390 (shader_type == SHADER_TYPE_VERTEX && m_max_vs_ssbos))
5391 {
5392 result.push_back(LANGUAGE_FEATURE_SHADER_STORAGE_BLOCK_INSTANCE_NAME);
5393 result.push_back(LANGUAGE_FEATURE_SHADER_STORAGE_BLOCK_MEMBER_NAME);
5394 result.push_back(LANGUAGE_FEATURE_SHADER_STORAGE_BLOCK_NAME);
5395 }
5396 } /* if (context_type >= glu::CONTEXTTYPE_GL43_CORE) */
5397
5398 /* Shared variables are only supported for compute shaders */
5399 if (shader_type == SHADER_TYPE_COMPUTE)
5400 {
5401 result.push_back(LANGUAGE_FEATURE_SHARED_VARIABLE);
5402 }
5403
5404 /* Structures are available everywhere, and so are structures. */
5405 result.push_back(LANGUAGE_FEATURE_STRUCTURE_INSTANCE_NAME);
5406 result.push_back(LANGUAGE_FEATURE_STRUCTURE_MEMBER);
5407 result.push_back(LANGUAGE_FEATURE_STRUCTURE_NAME);
5408
5409 /* Subroutines are available, starting with GL 4.0, for all shader stages except CS */
5410 if (glu::contextSupports(context_type, glu::ApiType::core(4, 0)))
5411 {
5412 if (shader_type != SHADER_TYPE_COMPUTE)
5413 {
5414 result.push_back(LANGUAGE_FEATURE_SUBROUTINE_FUNCTION_NAME);
5415 result.push_back(LANGUAGE_FEATURE_SUBROUTINE_TYPE);
5416 result.push_back(LANGUAGE_FEATURE_SUBROUTINE_UNIFORM);
5417 }
5418 } /* if (context_type >= glu::CONTEXTTYPE_GL40_CORE) */
5419
5420 /* Uniform blocks and uniforms are available everywhere, for all shader stages except CS */
5421 if (shader_type != SHADER_TYPE_COMPUTE)
5422 {
5423 result.push_back(LANGUAGE_FEATURE_UNIFORM_BLOCK_INSTANCE_NAME);
5424 result.push_back(LANGUAGE_FEATURE_UNIFORM_BLOCK_MEMBER_NAME);
5425 result.push_back(LANGUAGE_FEATURE_UNIFORM_BLOCK_NAME);
5426
5427 result.push_back(LANGUAGE_FEATURE_UNIFORM);
5428 }
5429
5430 /* Variables are available, well, everywhere. */
5431 result.push_back(LANGUAGE_FEATURE_VARIABLE);
5432
5433 /* Varyings are supported until GL 4.2 for FS and VS shader stages. Starting with GL 4.3,
5434 * they are no longer legal. */
5435 if ((shader_type == SHADER_TYPE_FRAGMENT || shader_type == SHADER_TYPE_VERTEX) &&
5436 !glu::contextSupports(context_type, glu::ApiType::core(4, 3)))
5437 {
5438 result.push_back(LANGUAGE_FEATURE_VARYING);
5439 }
5440
5441 return result;
5442 }
5443
5444 /** Returns a vector of _shader_type enums, telling which shader stages are supported
5445 * under running rendering context. For simplicity, the function ignores any extensions
5446 * which extend the core functionality
5447 *
5448 * @return As specified.
5449 */
getSupportedShaderTypes() const5450 std::vector<ReservedNamesTest::_shader_type> ReservedNamesTest::getSupportedShaderTypes() const
5451 {
5452 const glu::ContextType context_type = m_context.getRenderContext().getType();
5453 std::vector<_shader_type> result;
5454
5455 /* CS: Available, starting with GL 4.3 */
5456 if (glu::contextSupports(context_type, glu::ApiType::core(4, 3)))
5457 {
5458 result.push_back(SHADER_TYPE_COMPUTE);
5459 }
5460
5461 /* FS: Always supported */
5462 result.push_back(SHADER_TYPE_FRAGMENT);
5463
5464 /* GS: Available, starting with GL 3.2 */
5465 if (glu::contextSupports(context_type, glu::ApiType::core(3, 2)))
5466 {
5467 result.push_back(SHADER_TYPE_GEOMETRY);
5468 }
5469
5470 /* TC: Available, starting with GL 4.0 */
5471 /* TE: Available, starting with GL 4.0 */
5472 if (glu::contextSupports(context_type, glu::ApiType::core(4, 0)))
5473 {
5474 result.push_back(SHADER_TYPE_TESS_CONTROL);
5475 result.push_back(SHADER_TYPE_TESS_EVALUATION);
5476 }
5477
5478 /* VS: Always supported */
5479 result.push_back(SHADER_TYPE_VERTEX);
5480
5481 return result;
5482 }
5483
isStructAllowed(_shader_type shader_type,_language_feature language_feature) const5484 bool ReservedNamesTest::isStructAllowed(_shader_type shader_type, _language_feature language_feature) const
5485 {
5486 bool structAllowed = false;
5487
5488 if (language_feature == LANGUAGE_FEATURE_UNIFORM || language_feature == LANGUAGE_FEATURE_UNIFORM_BLOCK_NAME)
5489 {
5490 return true;
5491 }
5492
5493 switch (shader_type)
5494 {
5495 case SHADER_TYPE_FRAGMENT:
5496 {
5497 if (language_feature == LANGUAGE_FEATURE_INPUT_BLOCK_NAME)
5498 {
5499 structAllowed = true;
5500 }
5501 }
5502 break;
5503 case SHADER_TYPE_GEOMETRY:
5504 case SHADER_TYPE_TESS_CONTROL:
5505 case SHADER_TYPE_TESS_EVALUATION:
5506 {
5507 if (language_feature == LANGUAGE_FEATURE_OUTPUT_BLOCK_NAME)
5508 {
5509 structAllowed = true;
5510 }
5511 else if (language_feature == LANGUAGE_FEATURE_INPUT_BLOCK_NAME)
5512 {
5513 structAllowed = true;
5514 }
5515 }
5516 break;
5517 case SHADER_TYPE_VERTEX:
5518 {
5519 if (language_feature == LANGUAGE_FEATURE_OUTPUT_BLOCK_NAME)
5520 {
5521 structAllowed = true;
5522 }
5523 }
5524 break;
5525 case SHADER_TYPE_COMPUTE:
5526 default:
5527 break;
5528 }
5529
5530 return structAllowed;
5531 }
5532
5533 /** Empty init function */
init()5534 void ReservedNamesTest::init()
5535 {
5536 /* Left blank on purpose */
5537 }
5538
5539 /** Executes test iteration.
5540 *
5541 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
5542 */
iterate()5543 tcu::TestNode::IterateResult ReservedNamesTest::iterate()
5544 {
5545 glw::GLint compile_status = GL_TRUE;
5546 glu::ContextType context_type = m_context.getRenderContext().getType();
5547 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5548 std::vector<_language_feature> language_features;
5549 std::vector<std::string> reserved_names;
5550 bool result = true;
5551 std::vector<_shader_type> shader_types;
5552
5553 /* Retrieve important GL constant values */
5554 if (glu::contextSupports(context_type, glu::ApiType::core(4, 2)))
5555 {
5556 gl.getIntegerv(GL_MAX_GEOMETRY_ATOMIC_COUNTERS, &m_max_gs_acs);
5557 gl.getIntegerv(GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS, &m_max_tc_acs);
5558 gl.getIntegerv(GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS, &m_max_te_acs);
5559 gl.getIntegerv(GL_MAX_VERTEX_ATOMIC_COUNTERS, &m_max_vs_acs);
5560 }
5561
5562 if (glu::contextSupports(context_type, glu::ApiType::core(4, 3)))
5563 {
5564 gl.getIntegerv(GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, &m_max_fs_ssbos);
5565 gl.getIntegerv(GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS, &m_max_gs_ssbos);
5566 gl.getIntegerv(GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS, &m_max_tc_ssbos);
5567 gl.getIntegerv(GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS, &m_max_te_ssbos);
5568 gl.getIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &m_max_vs_ssbos);
5569
5570 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() call(s) failed.");
5571 }
5572
5573 /* Create the shader objects */
5574 if (glu::contextSupports(context_type, glu::ApiType::core(4, 0)))
5575 {
5576 m_so_ids[SHADER_TYPE_TESS_CONTROL] = gl.createShader(GL_TESS_CONTROL_SHADER);
5577 m_so_ids[SHADER_TYPE_TESS_EVALUATION] = gl.createShader(GL_TESS_EVALUATION_SHADER);
5578 }
5579
5580 if (glu::contextSupports(context_type, glu::ApiType::core(4, 3)))
5581 {
5582 m_so_ids[SHADER_TYPE_COMPUTE] = gl.createShader(GL_COMPUTE_SHADER);
5583 }
5584
5585 m_so_ids[SHADER_TYPE_FRAGMENT] = gl.createShader(GL_FRAGMENT_SHADER);
5586 m_so_ids[SHADER_TYPE_GEOMETRY] = gl.createShader(GL_GEOMETRY_SHADER);
5587 m_so_ids[SHADER_TYPE_VERTEX] = gl.createShader(GL_VERTEX_SHADER);
5588
5589 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed.");
5590
5591 /* Retrieve context version-specific data */
5592 reserved_names = getReservedNames();
5593 shader_types = getSupportedShaderTypes();
5594
5595 /* Iterate over all supported shader stages.. */
5596 for (std::vector<_shader_type>::const_iterator shader_type_it = shader_types.begin();
5597 shader_type_it != shader_types.end(); ++shader_type_it)
5598 {
5599 _shader_type current_shader_type = *shader_type_it;
5600
5601 if (m_so_ids[current_shader_type] == 0)
5602 {
5603 /* Skip stages not supported by the currently running context version. */
5604 continue;
5605 }
5606
5607 language_features = getSupportedLanguageFeatures(current_shader_type);
5608
5609 /* ..and all language features we can test for the running context */
5610 for (std::vector<_language_feature>::const_iterator language_feature_it = language_features.begin();
5611 language_feature_it != language_features.end(); ++language_feature_it)
5612 {
5613 _language_feature current_language_feature = *language_feature_it;
5614
5615 bool structAllowed = isStructAllowed(current_shader_type, current_language_feature);
5616
5617 /* Finally, all the reserved names we need to test - loop over them at this point */
5618 for (std::vector<std::string>::const_iterator reserved_name_it = reserved_names.begin();
5619 reserved_name_it != reserved_names.end(); ++reserved_name_it)
5620 {
5621 std::string current_invalid_name = *reserved_name_it;
5622 std::string so_body_string;
5623 const char* so_body_string_raw = NULL;
5624
5625 // There are certain shader types that allow struct for in/out declarations
5626 if (structAllowed && current_invalid_name.compare("struct") == 0)
5627 {
5628 continue;
5629 }
5630
5631 /* Form the shader body */
5632 so_body_string =
5633 getShaderBody(current_shader_type, current_language_feature, current_invalid_name.c_str());
5634 so_body_string_raw = so_body_string.c_str();
5635
5636 /* Try to compile the shader */
5637 gl.shaderSource(m_so_ids[current_shader_type], 1, /* count */
5638 &so_body_string_raw, NULL); /* length */
5639 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
5640
5641 gl.compileShader(m_so_ids[current_shader_type]);
5642 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed.");
5643
5644 gl.getShaderiv(m_so_ids[current_shader_type], GL_COMPILE_STATUS, &compile_status);
5645 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");
5646
5647 /* Left for the debugging purposes for those in need .. */
5648 #if 0
5649 char temp[4096];
5650
5651 gl.getShaderInfoLog(m_so_ids[current_shader_type],
5652 4096,
5653 NULL,
5654 temp);
5655
5656 m_testCtx.getLog() << tcu::TestLog::Message
5657 << "\n"
5658 "-----------------------------\n"
5659 "Shader:\n"
5660 ">>\n"
5661 << so_body_string_raw
5662 << "\n<<\n"
5663 "\n"
5664 "Info log:\n"
5665 ">>\n"
5666 << temp
5667 << "\n<<\n\n"
5668 << tcu::TestLog::EndMessage;
5669 #endif
5670
5671 if (compile_status != GL_FALSE)
5672 {
5673 m_testCtx.getLog() << tcu::TestLog::Message << "A "
5674 << getLanguageFeatureName(current_language_feature) << " named ["
5675 << current_invalid_name << "]"
5676 << ", defined in " << getShaderTypeName(current_shader_type)
5677 << ", was accepted by the compiler, "
5678 "which is prohibited by the spec. Offending source code:\n"
5679 ">>\n"
5680 << so_body_string_raw << "\n<<\n\n"
5681 << tcu::TestLog::EndMessage;
5682
5683 result = false;
5684 }
5685
5686 } /* for (all reserved names for the current context) */
5687 } /* for (all language features supported by the context) */
5688 } /* for (all shader types supported by the context) */
5689
5690 m_testCtx.setTestResult(result ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, result ? "Pass" : "Fail");
5691
5692 return STOP;
5693 }
5694
5695 /** Constructor.
5696 *
5697 * @param context Rendering context
5698 * @param name Test name
5699 * @param description Test description
5700 */
SparseBuffersWithCopyOpsTest(deqp::Context & context)5701 SparseBuffersWithCopyOpsTest::SparseBuffersWithCopyOpsTest(deqp::Context& context)
5702 : TestCase(context, "CommonBug_SparseBuffersWithCopyOps",
5703 "Verifies sparse buffer functionality works correctly when CPU->GPU and GPU->GPU"
5704 " memory transfers are involved.")
5705 , m_bo_id(0)
5706 , m_bo_read_id(0)
5707 , m_clear_buffer(DE_NULL)
5708 , m_page_size(0)
5709 , m_result_data_storage_size(0)
5710 , m_n_iterations_to_run(16)
5711 , m_n_pages_to_test(16)
5712 , m_virtual_bo_size(512 /* MB */ * 1024768)
5713 {
5714 for (unsigned int n = 0; n < sizeof(m_reference_data) / sizeof(m_reference_data[0]); ++n)
5715 {
5716 m_reference_data[n] = static_cast<unsigned char>(n);
5717 }
5718 }
5719
5720 /** Deinitializes all GL objects created for the purpose of running the test,
5721 * as well as any client-side buffers allocated at initialization time
5722 */
deinit()5723 void SparseBuffersWithCopyOpsTest::deinit()
5724 {
5725 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5726
5727 if (m_bo_id != 0)
5728 {
5729 gl.deleteBuffers(1, &m_bo_id);
5730
5731 m_bo_id = 0;
5732 }
5733
5734 if (m_bo_read_id != 0)
5735 {
5736 gl.deleteBuffers(1, &m_bo_read_id);
5737
5738 m_bo_read_id = 0;
5739 }
5740
5741 if (m_clear_buffer != DE_NULL)
5742 {
5743 delete[] m_clear_buffer;
5744
5745 m_clear_buffer = DE_NULL;
5746 }
5747 }
5748
5749 /** Empty init function */
init()5750 void SparseBuffersWithCopyOpsTest::init()
5751 {
5752 /* Nothing to do here */
5753 }
5754
5755 /** Initializes all buffers and GL objects required to run the test. */
initTest()5756 bool SparseBuffersWithCopyOpsTest::initTest()
5757 {
5758 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5759 bool result = true;
5760
5761 /* Retrieve the platform-specific page size */
5762 gl.getIntegerv(GL_SPARSE_BUFFER_PAGE_SIZE_ARB, &m_page_size);
5763
5764 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_SPARSE_BUFFER_PAGE_SIZE_ARB query");
5765
5766 /* Retrieve the func ptr */
5767 if (gl.bufferPageCommitmentARB == NULL)
5768 {
5769 m_testCtx.getLog() << tcu::TestLog::Message
5770 << "Could not retrieve function pointer for the glBufferPageCommitmentARB() entry-point."
5771 << tcu::TestLog::EndMessage;
5772
5773 result = false;
5774 goto end;
5775 }
5776
5777 /* Set up the test sparse buffer object */
5778 gl.genBuffers(1, &m_bo_id);
5779 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed.");
5780
5781 gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_id);
5782 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed.");
5783
5784 gl.bufferStorage(GL_ARRAY_BUFFER, m_virtual_bo_size, DE_NULL, /* data */
5785 GL_DYNAMIC_STORAGE_BIT | GL_SPARSE_STORAGE_BIT_ARB);
5786 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferStorage() call failed.");
5787
5788 /* Set up the buffer object that will be used to read the result data */
5789 m_result_data_storage_size = static_cast<unsigned int>(
5790 (m_page_size * m_n_pages_to_test / sizeof(m_reference_data)) * sizeof(m_reference_data));
5791 m_clear_buffer = new unsigned char[m_result_data_storage_size];
5792
5793 memset(m_clear_buffer, 0, m_result_data_storage_size);
5794
5795 gl.genBuffers(1, &m_bo_read_id);
5796 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed.");
5797
5798 gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_bo_read_id);
5799 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed.");
5800
5801 gl.bufferStorage(GL_ELEMENT_ARRAY_BUFFER, m_result_data_storage_size, NULL, /* data */
5802 GL_DYNAMIC_STORAGE_BIT | GL_MAP_READ_BIT);
5803 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferStorage() call failed.");
5804
5805 end:
5806 return result;
5807 }
5808
5809 /** Executes test iteration.
5810 *
5811 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
5812 */
iterate()5813 tcu::TestNode::IterateResult SparseBuffersWithCopyOpsTest::iterate()
5814 {
5815 bool result = true;
5816
5817 /* Execute the test */
5818 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5819
5820 /* Only execute if we're dealing with an OpenGL implementation which supports both:
5821 *
5822 * 1. GL_ARB_sparse_buffer extension
5823 * 2. GL_ARB_buffer_storage extension
5824 */
5825 if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_buffer") ||
5826 !m_context.getContextInfo().isExtensionSupported("GL_ARB_buffer_storage"))
5827 {
5828 goto end;
5829 }
5830
5831 /* Set up the test objects */
5832 if (!initTest())
5833 {
5834 result = false;
5835
5836 goto end;
5837 }
5838 for (unsigned int n_test_case = 0; n_test_case < 2; ++n_test_case)
5839 {
5840 for (unsigned int n_iteration = 0; n_iteration < m_n_iterations_to_run; ++n_iteration)
5841 {
5842 if (n_iteration != 0)
5843 {
5844 gl.bufferPageCommitmentARB(GL_ARRAY_BUFFER, 0, /* offset */
5845 m_n_pages_to_test * m_page_size, GL_FALSE);
5846 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferPageCommitmentARB() call failed.");
5847 }
5848
5849 gl.bufferPageCommitmentARB(GL_ARRAY_BUFFER, 0, /* offset */
5850 m_page_size, GL_TRUE);
5851 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferPageCommitmentARB() call failed.");
5852
5853 gl.bufferSubData(GL_ARRAY_BUFFER, 0, /* offset */
5854 sizeof(m_reference_data), m_reference_data);
5855 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferSubData() call failed.");
5856
5857 for (unsigned int n_page = 0; n_page < m_n_pages_to_test; ++n_page)
5858 {
5859 /* Try committing pages in a redundant manner. This is a legal behavior in light of
5860 * the GL_ARB_sparse_buffer spec */
5861 gl.bufferPageCommitmentARB(GL_ARRAY_BUFFER, n_page * m_page_size, m_page_size, GL_TRUE);
5862 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferPageCommitmentARB() call failed.");
5863
5864 for (int copy_dst_page_offset = static_cast<int>((n_page == 0) ? sizeof(m_reference_data) : 0);
5865 copy_dst_page_offset < static_cast<int>(m_page_size);
5866 copy_dst_page_offset += static_cast<int>(sizeof(m_reference_data)))
5867 {
5868 const int copy_src_page_offset =
5869 static_cast<int>(copy_dst_page_offset - sizeof(m_reference_data));
5870
5871 switch (n_test_case)
5872 {
5873 case 0:
5874 {
5875 gl.copyBufferSubData(GL_ARRAY_BUFFER, GL_ARRAY_BUFFER,
5876 n_page * m_page_size + copy_src_page_offset,
5877 n_page * m_page_size + copy_dst_page_offset, sizeof(m_reference_data));
5878 GLU_EXPECT_NO_ERROR(gl.getError(), "glCopyBufferSubData() call failed.");
5879
5880 break;
5881 }
5882
5883 case 1:
5884 {
5885 gl.bufferSubData(GL_ARRAY_BUFFER, n_page * m_page_size + copy_dst_page_offset,
5886 sizeof(m_reference_data), m_reference_data);
5887 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferSubData() call failed.");
5888
5889 break;
5890 }
5891
5892 default:
5893 TCU_FAIL("Unrecognized test case index");
5894 } /* switch (n_test_case) */
5895 } /* for (all valid destination copy op offsets) */
5896 } /* for (all test pages) */
5897
5898 /* Copy data from the sparse buffer to a mappable immutable buffer storage */
5899 gl.copyBufferSubData(GL_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER, 0, /* readOffset */
5900 0, /* writeOffset */
5901 m_result_data_storage_size);
5902 GLU_EXPECT_NO_ERROR(gl.getError(), "glCopyBufferSubData() call failed.");
5903
5904 /* Map the data we have obtained */
5905 char* mapped_data = (char*)gl.mapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, /* offset */
5906 m_page_size * m_n_pages_to_test, GL_MAP_READ_BIT);
5907
5908 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange() call failed.");
5909
5910 /* Verify the data is valid */
5911 for (unsigned int n_temp_copy = 0; n_temp_copy < m_result_data_storage_size / sizeof(m_reference_data);
5912 ++n_temp_copy)
5913 {
5914 const unsigned int cmp_offset = static_cast<unsigned int>(n_temp_copy * sizeof(m_reference_data));
5915
5916 if (memcmp(mapped_data + cmp_offset, m_reference_data, sizeof(m_reference_data)) != 0)
5917 {
5918 m_testCtx.getLog() << tcu::TestLog::Message << "Invalid data found for page index "
5919 "["
5920 << (cmp_offset / m_page_size) << "]"
5921 ", BO data offset:"
5922 "["
5923 << cmp_offset << "]." << tcu::TestLog::EndMessage;
5924
5925 result = false;
5926 goto end;
5927 }
5928 } /* for (all datasets) */
5929
5930 /* Clean up */
5931 gl.unmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
5932 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer() call failed.");
5933
5934 /* Also, zero out the other buffer object we copy the result data to, in case
5935 * the glCopyBufferSubData() call does not modify it at all */
5936 gl.bufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, /* offset */
5937 m_result_data_storage_size, m_clear_buffer);
5938 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferSubData() call failed.");
5939
5940 /* NOTE: This test passes fine on the misbehaving driver *if* the swapbuffers operation
5941 * issued as a part of the call below is not executed. */
5942 m_context.getRenderContext().postIterate();
5943 } /* for (all test iterations) */
5944 } /* for (all test cases) */
5945
5946 end:
5947 m_testCtx.setTestResult(result ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, result ? "Pass" : "Fail");
5948
5949 return STOP;
5950 }
5951
5952 /** Constructor.
5953 *
5954 * @param context Rendering context.
5955 */
CommonBugsTests(deqp::Context & context)5956 CommonBugsTests::CommonBugsTests(deqp::Context& context)
5957 : TestCaseGroup(context, "CommonBugs", "Contains conformance tests that verify various pieces of functionality"
5958 " which were found broken in public drivers.")
5959 {
5960 }
5961
5962 /** Initializes the test group contents. */
init()5963 void CommonBugsTests::init()
5964 {
5965 addChild(new GetProgramivActiveUniformBlockMaxNameLengthTest(m_context));
5966 addChild(new InputVariablesCannotBeModifiedTest(m_context));
5967 addChild(new InvalidUseCasesForAllNotFuncsAndExclMarkOpTest(m_context));
5968 addChild(new InvalidVSInputsTest(m_context));
5969 addChild(new ParenthesisInLayoutQualifierIntegerValuesTest(m_context));
5970 addChild(new PerVertexValidationTest(m_context));
5971 addChild(new ReservedNamesTest(m_context));
5972 addChild(new SparseBuffersWithCopyOpsTest(m_context));
5973 }
5974 } /* glcts namespace */
5975