1 /*-------------------------------------------------------------------------
2 * OpenGL Conformance Test Suite
3 * -----------------------------
5 * Copyright (c) 2015-2016 The Khronos Group Inc.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 */ /*-------------------------------------------------------------------*/
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 */ /*-------------------------------------------------------------------*/
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"
44 #ifndef GL_SPARSE_BUFFER_PAGE_SIZE_ARB
45 #define GL_SPARSE_BUFFER_PAGE_SIZE_ARB 0x82F8
47 #ifndef GL_SPARSE_STORAGE_BIT_ARB
48 #define GL_SPARSE_STORAGE_BIT_ARB 0x0400
55 * @param context Rendering context
56 * @param name Test name
57 * @param description Test description
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()")
66 /* Left blank intentionally */
69 /** Tears down any GL objects set up to run the test. */
70 void GetProgramivActiveUniformBlockMaxNameLengthTest::deinit()
72 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
76 gl.deleteShader(m_fs_id);
83 gl.deleteProgram(m_po_id);
90 gl.deleteShader(m_vs_id);
96 /** Stub init method */
97 void GetProgramivActiveUniformBlockMaxNameLengthTest::init()
99 /* Nothing to do here */
102 /** Initializes all GL objects required to run the test */
103 bool GetProgramivActiveUniformBlockMaxNameLengthTest::initTest()
105 glw::GLint compile_status = false;
106 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
107 glw::GLint link_status = false;
110 const char* fs_body = "#version 140\n"
124 const char* vs_body = "#version 140\n"
133 " gl_Position = temp2;\n"
136 m_po_id = gl.createProgram();
137 m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
138 m_vs_id = gl.createShader(GL_VERTEX_SHADER);
140 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() / glCreateShader() call(s) failed.");
142 gl.attachShader(m_po_id, m_fs_id);
143 gl.attachShader(m_po_id, m_vs_id);
145 GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call(s) failed.");
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 */
152 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call(s) failed.");
154 gl.compileShader(m_fs_id);
155 gl.compileShader(m_vs_id);
157 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call(s) failed.");
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<const unsigned int>(sizeof(shader_ids) / sizeof(shader_ids[0]));
163 for (unsigned int n_shader_id = 0; n_shader_id < n_shader_ids; ++n_shader_id)
165 gl.getShaderiv(shader_ids[n_shader_id], GL_COMPILE_STATUS, &compile_status);
167 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");
169 if (compile_status != GL_TRUE)
171 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Shader compilation failure"
172 << tcu::TestLog::EndMessage;
177 } /* for (all shader IDs) */
180 gl.linkProgram(m_po_id);
182 GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed.");
184 gl.getProgramiv(m_po_id, GL_LINK_STATUS, &link_status);
186 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed.");
188 if (link_status != GL_TRUE)
190 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program linking failure"
191 << tcu::TestLog::EndMessage;
201 /** Executes test iteration.
203 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
205 tcu::TestNode::IterateResult GetProgramivActiveUniformBlockMaxNameLengthTest::iterate()
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;
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)))
221 /* Set up the test program object */
229 gl.getProgramiv(m_po_id, GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &result_value);
231 error_code = gl.getError();
233 if (error_code != GL_NO_ERROR)
235 m_testCtx.getLog() << tcu::TestLog::Message << "glGetIntegerv() generated error [" << error_code
236 << "] for GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH" << tcu::TestLog::EndMessage;
240 else if (result_value != expected_result_value)
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;
251 m_testCtx.setTestResult(result ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, result ? "Pass" : "Fail");
258 * @param context Rendering context
259 * @param name Test name
260 * @param description Test description
262 InputVariablesCannotBeModifiedTest::InputVariablesCannotBeModifiedTest(deqp::Context& context)
263 : TestCase(context, "CommonBug_InputVariablesCannotBeModified", "Verifies that input variables cannot be modified.")
270 /* Left blank on purpose */
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
276 void InputVariablesCannotBeModifiedTest::deinit()
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,
282 const unsigned int n_so_id_ptrs = static_cast<const unsigned int>(sizeof(so_id_ptrs) / sizeof(so_id_ptrs[0]));
284 for (unsigned int n_so_id_ptr = 0; n_so_id_ptr < n_so_id_ptrs; ++n_so_id_ptr)
286 gl.deleteShader(*so_id_ptrs[n_so_id_ptr]);
287 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteShader() call failed.");
289 *so_id_ptrs[n_so_id_ptr] = 0;
290 } /* for (all created shader objects) */
293 /** Dummy init function */
294 void InputVariablesCannotBeModifiedTest::init()
296 /* Left blank on purpose */
299 /** Retrieves a literal corresponding to the test iteration enum.
301 * @param iteration Enum to retrieve the string for.
303 * @return Requested object.
305 std::string InputVariablesCannotBeModifiedTest::getIterationName(_test_iteration iteration) const
311 case TEST_ITERATION_INPUT_FS_VARIABLE:
312 result = "Fragment shader input variable";
314 case TEST_ITERATION_INPUT_FS_VARIABLE_IN_INPUT_BLOCK:
315 result = "Fragment shader input variable wrapped in an input block";
317 case TEST_ITERATION_INPUT_FS_VARIABLE_PASSED_TO_INOUT_FUNCTION_PARAMETER:
318 result = "Fragment shader input variable passed to an inout function parameter";
320 case TEST_ITERATION_INPUT_FS_VARIABLE_PASSED_TO_OUT_FUNCTION_PARAMETER:
321 result = "Fragment shader input variable passed to an out function parameter";
323 case TEST_ITERATION_INPUT_GS_VARIABLE:
324 result = "Geometry shader input variable";
326 case TEST_ITERATION_INPUT_GS_VARIABLE_IN_INPUT_BLOCK:
327 result = "Geometry shader input variable wrapped in an input block";
329 case TEST_ITERATION_INPUT_GS_VARIABLE_PASSED_TO_INOUT_FUNCTION_PARAMETER:
330 result = "Geometry shader input variable passed to an inout function parameter";
332 case TEST_ITERATION_INPUT_GS_VARIABLE_PASSED_TO_OUT_FUNCTION_PARAMETER:
333 result = "Geometry shader input variable passed to an out function parameter";
335 case TEST_ITERATION_INPUT_TC_VARIABLE_IN_INPUT_BLOCK:
336 result = "Tessellation control shader variable wrapped in an input block";
338 case TEST_ITERATION_INPUT_TC_VARIABLE_PASSED_TO_INOUT_FUNCTION_PARAMETER:
339 result = "Tessellation control shader variable passed to an inout function parameter";
341 case TEST_ITERATION_INPUT_TC_VARIABLE_PASSED_TO_OUT_FUNCTION_PARAMETER:
342 result = "Tessellation control shader variable passed to an out function parameter";
344 case TEST_ITERATION_INPUT_TE_PATCH_VARIABLE:
345 result = "Tessellation evaluation shader patch input variable";
347 case TEST_ITERATION_INPUT_TE_VARIABLE:
348 result = "Tessellation evaluation shader input variable";
350 case TEST_ITERATION_INPUT_TE_VARIABLE_IN_INPUT_BLOCK:
351 result = "Tessellation evaluation shader patch input variable wrapped in an input block";
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";
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";
359 case TEST_ITERATION_INPUT_VS_VARIABLE:
360 result = "Vertex shader input variable";
362 case TEST_ITERATION_INPUT_VS_VARIABLE_PASSED_TO_INOUT_FUNCTION_PARAMETER:
363 result = "Vertex shader input variable passed to an inout function parameter";
365 case TEST_ITERATION_INPUT_VS_VARIABLE_PASSED_TO_OUT_FUNCTION_PARAMETER:
366 result = "Vertex shader input variable passed to an out function parameter";
370 TCU_FAIL("Unrecognized test iteration type.");
371 } /* switch (iteration) */
376 /** Retrieves a vertex shader body for the user-specified iteration enum.
378 * @param iteration Iteration to retrieve the shader body for.
380 * @return Requested string object.
382 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
389 case TEST_ITERATION_INPUT_FS_VARIABLE:
391 *out_required_min_context_type_ptr = glu::ApiType::core(3, 1);
392 *out_target_shader_stage_ptr = SHADER_STAGE_FRAGMENT;
394 *out_body_ptr = "#version 140\n"
401 " data += vec4(1.0);\n"
408 case TEST_ITERATION_INPUT_FS_VARIABLE_IN_INPUT_BLOCK:
410 *out_required_min_context_type_ptr = glu::ApiType::core(4, 0);
411 *out_target_shader_stage_ptr = SHADER_STAGE_FRAGMENT;
413 *out_body_ptr = "#version 400\n"
424 " data += vec4(1.0);\n"
431 case TEST_ITERATION_INPUT_FS_VARIABLE_PASSED_TO_INOUT_FUNCTION_PARAMETER:
433 *out_required_min_context_type_ptr = glu::ApiType::core(3, 1);
434 *out_target_shader_stage_ptr = SHADER_STAGE_FRAGMENT;
436 *out_body_ptr = "#version 140\n"
441 "void testFunc(inout vec4 arg)\n"
443 " arg += vec4(1.0);\n"
456 case TEST_ITERATION_INPUT_FS_VARIABLE_PASSED_TO_OUT_FUNCTION_PARAMETER:
458 *out_required_min_context_type_ptr = glu::ApiType::core(3, 1);
459 *out_target_shader_stage_ptr = SHADER_STAGE_FRAGMENT;
461 *out_body_ptr = "#version 140\n"
466 "void testFunc(out vec4 arg)\n"
468 " arg = vec4(1.0);\n"
481 case TEST_ITERATION_INPUT_GS_VARIABLE:
483 *out_required_min_context_type_ptr = glu::ApiType::core(3, 2);
484 *out_target_shader_stage_ptr = SHADER_STAGE_GEOMETRY;
486 *out_body_ptr = "#version 150\n"
488 "layout(points) in;\n"
489 "layout(points, max_vertices = 1) out;\n"
495 " data[0] += vec4(1.0);\n"
496 " gl_Position = data[0];\n"
504 case TEST_ITERATION_INPUT_GS_VARIABLE_IN_INPUT_BLOCK:
506 *out_required_min_context_type_ptr = glu::ApiType::core(4, 0);
507 *out_target_shader_stage_ptr = SHADER_STAGE_GEOMETRY;
509 *out_body_ptr = "#version 400\n"
511 "layout(points) in;\n"
512 "layout(points, max_vertices = 1) out;\n"
521 " data[0] += vec4(1.0);\n"
522 " gl_Position = data[0];\n"
530 case TEST_ITERATION_INPUT_GS_VARIABLE_PASSED_TO_INOUT_FUNCTION_PARAMETER:
532 *out_required_min_context_type_ptr = glu::ApiType::core(3, 2);
533 *out_target_shader_stage_ptr = SHADER_STAGE_GEOMETRY;
535 *out_body_ptr = "#version 150\n"
537 "layout(points) in;\n"
538 "layout(points, max_vertices = 1) out;\n"
542 "void testFunc(inout vec4 arg)\n"
544 " arg += vec4(1.0);\n"
549 " testFunc(data[0]);\n"
551 " gl_Position = data[0];\n"
559 case TEST_ITERATION_INPUT_GS_VARIABLE_PASSED_TO_OUT_FUNCTION_PARAMETER:
561 *out_required_min_context_type_ptr = glu::ApiType::core(3, 2);
562 *out_target_shader_stage_ptr = SHADER_STAGE_GEOMETRY;
564 *out_body_ptr = "#version 150\n"
566 "layout(points) in;\n"
567 "layout(points, max_vertices = 1) out;\n"
571 "void testFunc(out vec4 arg)\n"
573 " arg = vec4(1.0);\n"
578 " testFunc(data[0]);\n"
580 " gl_Position = data[0];\n"
588 case TEST_ITERATION_INPUT_TC_VARIABLE:
590 *out_required_min_context_type_ptr = glu::ApiType::core(4, 0);
591 *out_target_shader_stage_ptr = SHADER_STAGE_TESSELLATION_CONTROL;
593 *out_body_ptr = "#version 400\n"
595 "layout(vertices = 4) out;\n"
602 " data[0] += vec4(1.0);\n"
603 " result = data[0];\n"
610 case TEST_ITERATION_INPUT_TC_VARIABLE_IN_INPUT_BLOCK:
612 *out_required_min_context_type_ptr = glu::ApiType::core(4, 0);
613 *out_target_shader_stage_ptr = SHADER_STAGE_TESSELLATION_CONTROL;
615 *out_body_ptr = "#version 400\n"
617 "layout(vertices = 4) out;\n"
624 "patch out vec4 result[];\n"
628 " inData[0].data += vec4(1.0);\n"
629 " result[gl_InvocationID] = inData[0].data;\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"
642 case TEST_ITERATION_INPUT_TC_VARIABLE_PASSED_TO_INOUT_FUNCTION_PARAMETER:
644 *out_required_min_context_type_ptr = glu::ApiType::core(4, 0);
645 *out_target_shader_stage_ptr = SHADER_STAGE_TESSELLATION_CONTROL;
647 *out_body_ptr = "#version 400\n"
649 "layout(vertices = 4) out;\n"
654 "void testFunc(inout vec4 arg)\n"
656 " arg += vec4(1.0);\n"
661 " testFunc(data[0]);\n"
663 " result = data[0];\n"
670 case TEST_ITERATION_INPUT_TC_VARIABLE_PASSED_TO_OUT_FUNCTION_PARAMETER:
672 *out_required_min_context_type_ptr = glu::ApiType::core(4, 0);
673 *out_target_shader_stage_ptr = SHADER_STAGE_TESSELLATION_CONTROL;
675 *out_body_ptr = "#version 400\n"
677 "layout(vertices = 4) out;\n"
682 "void testFunc(out vec4 arg)\n"
684 " arg = vec4(1.0);\n"
689 " testFunc(data[0]);\n"
691 " result = data[0];\n"
698 case TEST_ITERATION_INPUT_TE_PATCH_VARIABLE:
699 case TEST_ITERATION_INPUT_TE_VARIABLE:
701 std::stringstream body_sstream;
703 *out_required_min_context_type_ptr = glu::ApiType::core(4, 0);
704 *out_target_shader_stage_ptr = SHADER_STAGE_TESSELLATION_EVALUATION;
706 body_sstream << "#version 400\n"
708 "layout(triangles) in;\n"
710 << ((iteration == TEST_ITERATION_INPUT_TE_PATCH_VARIABLE) ? "patch " : "") << "in vec4 data[];\n"
711 << " out vec4 result;\n"
715 " data[0] += vec4(1.0);\n"
716 " gl_Position = data[0];\n"
719 *out_body_ptr = body_sstream.str();
723 case TEST_ITERATION_INPUT_TE_VARIABLE_IN_INPUT_BLOCK:
725 *out_required_min_context_type_ptr = glu::ApiType::core(4, 0);
726 *out_target_shader_stage_ptr = SHADER_STAGE_TESSELLATION_EVALUATION;
728 *out_body_ptr = "#version 400\n"
730 "layout(triangles) in;\n"
739 " inData[0].data += vec4(1.0);\n"
740 " gl_Position = inData[0].data;\n"
746 case TEST_ITERATION_INPUT_TE_VARIABLE_PASSED_TO_INOUT_FUNCTION_PARAMETER:
748 *out_required_min_context_type_ptr = glu::ApiType::core(4, 0);
749 *out_target_shader_stage_ptr = SHADER_STAGE_TESSELLATION_EVALUATION;
751 *out_body_ptr = "#version 400\n"
753 "layout(triangles) in;\n"
758 "void testFunc(inout vec4 arg)\n"
760 " arg += vec4(1.0);\n"
765 " testFunc(data[0]);\n"
767 " gl_Position = data[0];\n"
773 case TEST_ITERATION_INPUT_TE_VARIABLE_PASSED_TO_OUT_FUNCTION_PARAMETER:
775 *out_required_min_context_type_ptr = glu::ApiType::core(4, 0);
776 *out_target_shader_stage_ptr = SHADER_STAGE_TESSELLATION_EVALUATION;
778 *out_body_ptr = "#version 400\n"
780 "layout(triangles) in;\n"
785 "void testFunc(out vec4 arg)\n"
787 " arg = vec4(1.0);\n"
792 " testFunc(data[0]);\n"
794 " gl_Position = data[0];\n"
800 case TEST_ITERATION_INPUT_VS_VARIABLE:
802 *out_required_min_context_type_ptr = glu::ApiType::core(3, 1);
803 *out_target_shader_stage_ptr = SHADER_STAGE_VERTEX;
805 *out_body_ptr = "#version 140\n"
811 " data += vec4(1.0);\n"
812 " gl_Position = data;\n"
818 case TEST_ITERATION_INPUT_VS_VARIABLE_PASSED_TO_INOUT_FUNCTION_PARAMETER:
820 *out_required_min_context_type_ptr = glu::ApiType::core(3, 1);
821 *out_target_shader_stage_ptr = SHADER_STAGE_VERTEX;
823 *out_body_ptr = "#version 140\n"
827 "void testFunc(inout vec4 argument)\n"
829 " argument += vec4(1.0);\n"
836 " gl_Position = data;\n"
842 case TEST_ITERATION_INPUT_VS_VARIABLE_PASSED_TO_OUT_FUNCTION_PARAMETER:
844 *out_required_min_context_type_ptr = glu::ApiType::core(3, 1);
845 *out_target_shader_stage_ptr = SHADER_STAGE_VERTEX;
847 *out_body_ptr = "#version 140\n"
851 "void testFunc(out vec4 argument)\n"
853 " argument = vec4(1.0);\n"
860 " gl_Position = data;\n"
867 TCU_FAIL("Unrecognized test iteration type");
868 } /* switch (iteration) */
871 /** Executes test iteration.
873 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
875 tcu::TestNode::IterateResult InputVariablesCannotBeModifiedTest::iterate()
877 const glu::ContextType context_type = m_context.getRenderContext().getType();
878 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
881 /* Create shader objects */
882 if (glu::contextSupports(context_type, glu::ApiType::core(3, 2)))
884 m_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
887 if (glu::contextSupports(context_type, glu::ApiType::core(4, 0)))
889 m_tc_id = gl.createShader(GL_TESS_CONTROL_SHADER);
890 m_te_id = gl.createShader(GL_TESS_EVALUATION_SHADER);
893 m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
894 m_vs_id = gl.createShader(GL_VERTEX_SHADER);
896 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed.");
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++)
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;
909 getIterationData(static_cast<_test_iteration>(current_iteration), ¤t_iteration_min_context_type,
910 ¤t_iteration_shader_stage, ¤t_iteration_body);
912 current_iteration_body_raw_ptr = current_iteration_body.c_str();
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))
921 switch (current_iteration_shader_stage)
923 case SHADER_STAGE_FRAGMENT:
926 case SHADER_STAGE_GEOMETRY:
929 case SHADER_STAGE_TESSELLATION_CONTROL:
932 case SHADER_STAGE_TESSELLATION_EVALUATION:
935 case SHADER_STAGE_VERTEX:
941 TCU_FAIL("Unrecognized shader stage type");
943 } /* switch (current_iteration_shader_stage) */
945 DE_ASSERT(so_id != 0);
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.");
952 /* Try to compile the shader object. */
953 gl.compileShader(so_id);
954 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed.");
956 gl.getShaderiv(so_id, GL_COMPILE_STATUS, &compile_status);
957 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");
961 gl.getShaderInfoLog(so_id, 1024, NULL, temp);
963 if (compile_status == GL_TRUE)
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))
970 "was compiled successfully, even though it is invalid. Body:"
972 << current_iteration_body << "\n<<\n"
973 << tcu::TestLog::EndMessage;
977 } /* for (all test iterations) */
979 m_testCtx.setTestResult(result ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, result ? "Pass" : "Fail");
984 /** Returns a literal corresponding to the shader stage enum used by the test.
986 * @param stage Shader stage to use for the query.
988 * @return Requested string.
990 std::string InputVariablesCannotBeModifiedTest::getShaderStageName(_shader_stage stage) const
992 std::string result = "?!";
996 case SHADER_STAGE_FRAGMENT:
997 result = "fragment shader";
999 case SHADER_STAGE_GEOMETRY:
1000 result = "geometry shader";
1002 case SHADER_STAGE_TESSELLATION_CONTROL:
1003 result = "tessellation control shader";
1005 case SHADER_STAGE_TESSELLATION_EVALUATION:
1006 result = "tessellation evaluation shader";
1008 case SHADER_STAGE_VERTEX:
1009 result = "vertex shader";
1011 } /* switch (stage) */
1018 * @param context Rendering context
1019 * @param name Test name
1020 * @param description Test description
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.")
1028 /* Left blank on purpose */
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
1034 void InvalidUseCasesForAllNotFuncsAndExclMarkOpTest::deinit()
1036 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1040 gl.deleteShader(m_vs_id);
1046 /** Dummy init function */
1047 void InvalidUseCasesForAllNotFuncsAndExclMarkOpTest::init()
1049 /* Left blank on purpose */
1052 /** Retrieves a literal corresponding to the test iteration enum.
1054 * @param iteration Enum to retrieve the string for.
1056 * @return Requested object.
1058 std::string InvalidUseCasesForAllNotFuncsAndExclMarkOpTest::getIterationName(_test_iteration iteration) const
1064 case TEST_ITERATION_EXCL_MARK_OP_MUST_NOT_ACCEPT_BVEC2:
1065 result = "! operator must not accept bvec2 arg";
1067 case TEST_ITERATION_EXCL_MARK_OP_MUST_NOT_ACCEPT_BVEC3:
1068 result = "! operator must not accept bvec3 arg";
1070 case TEST_ITERATION_EXCL_MARK_OP_MUST_NOT_ACCEPT_BVEC4:
1071 result = "! operator must not accept bvec4 arg";
1073 case TEST_ITERATION_ALL_FUNC_MUST_NOT_ACCEPT_BOOL:
1074 result = "all() function must not accept bool arg";
1076 case TEST_ITERATION_NOT_FUNC_MUST_NOT_ACCEPT_BOOL:
1077 result = "not() function must not accept bool arg";
1081 TCU_FAIL("Unrecognized test iteration type.");
1083 } /* switch (iteration) */
1088 /** Retrieves a vertex shader body for the user-specified iteration enum.
1090 * @param iteration Iteration to retrieve the shader body for.
1092 * @return Requested string object.
1094 std::string InvalidUseCasesForAllNotFuncsAndExclMarkOpTest::getShaderBody(_test_iteration iteration) const
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:
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.
1109 std::stringstream result_sstream;
1110 std::string type_string;
1112 type_string = (iteration == TEST_ITERATION_EXCL_MARK_OP_MUST_NOT_ACCEPT_BVEC2) ?
1114 (iteration == TEST_ITERATION_EXCL_MARK_OP_MUST_NOT_ACCEPT_BVEC3) ? "bvec3" : "bvec4";
1116 result_sstream << "#version 140\n"
1121 << type_string << "(false))\n"
1123 " gl_Position = vec4(1.0, 2.0, 3.0, 4.0);\n"
1127 " gl_Position = vec4(2.0, 3.0, 4.0, 5.0);\n"
1131 result = result_sstream.str();
1135 case TEST_ITERATION_ALL_FUNC_MUST_NOT_ACCEPT_BOOL:
1136 case TEST_ITERATION_NOT_FUNC_MUST_NOT_ACCEPT_BOOL:
1138 std::string op_string;
1139 std::stringstream result_sstream;
1141 /* From GLSL spec, all() and not() functions are defined as:
1146 * where bvec is bvec2, bvec3 or bvec4.
1148 op_string = (iteration == TEST_ITERATION_ALL_FUNC_MUST_NOT_ACCEPT_BOOL) ? "all" : "not";
1150 result_sstream << "#version 140\n"
1154 " gl_Position = vec4("
1155 << op_string << "(false, true) ? 1.0 : 2.0);\n"
1158 result = result_sstream.str();
1163 TCU_FAIL("Unrecognized test iteration type");
1164 } /* switch (iteration) */
1169 /** Executes test iteration.
1171 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
1173 tcu::TestNode::IterateResult InvalidUseCasesForAllNotFuncsAndExclMarkOpTest::iterate()
1175 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1178 /* Create a vertex shader object */
1179 m_vs_id = gl.createShader(GL_VERTEX_SHADER);
1181 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed.");
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)
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;
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.");
1196 /* Try to compile the shader object. */
1197 gl.compileShader(m_vs_id);
1198 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed.");
1200 gl.getShaderiv(m_vs_id, GL_COMPILE_STATUS, &compile_status);
1201 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");
1203 if (compile_status == GL_TRUE)
1205 m_testCtx.getLog() << tcu::TestLog::Message << "The following vertex shader, used for test iteration ["
1206 << getIterationName(static_cast<_test_iteration>(current_iteration))
1208 "was compiled successfully, even though it is invalid. Body:"
1211 << tcu::TestLog::EndMessage;
1215 } /* for (all test iterations) */
1217 m_testCtx.setTestResult(result ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, result ? "Pass" : "Fail");
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")
1228 /* Left blank on purpose */
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
1234 void InvalidVSInputsTest::deinit()
1236 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1240 gl.deleteShader(m_vs_id);
1246 /** Dummy init function */
1247 void InvalidVSInputsTest::init()
1249 /* Left blank on purpose */
1252 /** Retrieves a literal corresponding to the test iteration enum.
1254 * @param iteration Enum to retrieve the string for.
1256 * @return Requested object.
1258 std::string InvalidVSInputsTest::getIterationName(_test_iteration iteration) const
1264 case TEST_ITERATION_INVALID_BOOL_INPUT:
1265 result = "Invalid bool input";
1267 case TEST_ITERATION_INVALID_BVEC2_INPUT:
1268 result = "Invalid bvec2 input";
1270 case TEST_ITERATION_INVALID_BVEC3_INPUT:
1271 result = "Invalid bvec3 input";
1273 case TEST_ITERATION_INVALID_BVEC4_INPUT:
1274 result = "Invalid bvec4 input";
1276 case TEST_ITERATION_INVALID_CENTROID_QUALIFIED_INPUT:
1277 result = "Invalid centroid-qualified input";
1279 case TEST_ITERATION_INVALID_PATCH_QUALIFIED_INPUT:
1280 result = "Invalid patch-qualified input";
1282 case TEST_ITERATION_INVALID_OPAQUE_TYPE_INPUT:
1283 result = "Invalid opaque type input";
1285 case TEST_ITERATION_INVALID_STRUCTURE_INPUT:
1286 result = "Invalid structure input";
1288 case TEST_ITERATION_INVALID_SAMPLE_QUALIFIED_INPUT:
1289 result = "Invalid sample-qualified input";
1293 TCU_FAIL("Unrecognized test iteration type.");
1294 } /* switch (iteration) */
1299 /** Retrieves a vertex shader body for the user-specified iteration enum.
1301 * @param iteration Iteration to retrieve the shader body for.
1303 * @return Requested string object.
1305 std::string InvalidVSInputsTest::getShaderBody(_test_iteration iteration) const
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:
1316 std::stringstream body_sstream;
1317 const char* type = (iteration == TEST_ITERATION_INVALID_BOOL_INPUT) ?
1319 (iteration == TEST_ITERATION_INVALID_BVEC2_INPUT) ?
1321 (iteration == TEST_ITERATION_INVALID_BVEC3_INPUT) ? "bvec3" : "bvec4";
1323 body_sstream << "#version 140\n"
1326 << type << " data;\n"
1332 result = body_sstream.str();
1336 case TEST_ITERATION_INVALID_OPAQUE_TYPE_INPUT:
1338 result = "#version 140\n"
1340 "in sampler2D data;\n"
1349 case TEST_ITERATION_INVALID_STRUCTURE_INPUT:
1351 result = "#version 140\n"
1365 case TEST_ITERATION_INVALID_CENTROID_QUALIFIED_INPUT:
1366 case TEST_ITERATION_INVALID_PATCH_QUALIFIED_INPUT:
1367 case TEST_ITERATION_INVALID_SAMPLE_QUALIFIED_INPUT:
1369 std::stringstream body_sstream;
1370 const char* qualifier = (iteration == TEST_ITERATION_INVALID_CENTROID_QUALIFIED_INPUT) ?
1372 (iteration == TEST_ITERATION_INVALID_PATCH_QUALIFIED_INPUT) ? "patch" : "sample";
1374 body_sstream << "#version 140\n"
1376 << qualifier << " in vec4 data;\n"
1382 result = body_sstream.str();
1387 TCU_FAIL("Unrecognized test iteration type");
1388 } /* switch (iteration) */
1393 /** Executes test iteration.
1395 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
1397 tcu::TestNode::IterateResult InvalidVSInputsTest::iterate()
1399 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1402 /* Create a vertex shader object */
1403 m_vs_id = gl.createShader(GL_VERTEX_SHADER);
1405 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed.");
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++)
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;
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.");
1420 /* Try to compile the shader object. */
1421 gl.compileShader(m_vs_id);
1422 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed.");
1424 gl.getShaderiv(m_vs_id, GL_COMPILE_STATUS, &compile_status);
1425 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");
1427 if (compile_status == GL_TRUE)
1429 m_testCtx.getLog() << tcu::TestLog::Message << "The following vertex shader, used for test iteration ["
1430 << getIterationName(static_cast<_test_iteration>(current_iteration))
1432 "was compiled successfully, even though it is invalid. Body:"
1435 << tcu::TestLog::EndMessage;
1439 } /* for (all test iterations) */
1441 m_testCtx.setTestResult(result ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, result ? "Pass" : "Fail");
1448 * @param context Rendering context
1449 * @param name Test name
1450 * @param description Test description
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.")
1459 /* Left blank on purpose */
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
1465 void ParenthesisInLayoutQualifierIntegerValuesTest::deinit()
1467 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1471 gl.deleteShader(m_cs_id);
1478 gl.deleteProgram(m_po_id);
1484 /** Dummy init function */
1485 void ParenthesisInLayoutQualifierIntegerValuesTest::init()
1487 /* Left blank on purpose */
1490 /** Executes test iteration.
1492 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
1494 tcu::TestNode::IterateResult ParenthesisInLayoutQualifierIntegerValuesTest::iterate()
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();
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));
1505 /* Prepare a compute shader program */
1506 static const char* cs_body_core = "\n"
1507 "layout(local_size_x = (4) ) in;\n"
1513 const char* cs_body_parts[] = { (!glu::contextSupports(context_type, glu::ApiType::core(4, 3))) ?
1514 "#version 420 core\n" :
1515 (!glu::contextSupports(context_type, glu::ApiType::core(4, 4))) ?
1516 "#version 430 core\n" :
1517 "#version 440 core\n",
1519 const unsigned int n_cs_body_parts =
1520 static_cast<const unsigned int>(sizeof(cs_body_parts) / sizeof(cs_body_parts[0]));
1522 if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_compute_shader"))
1527 m_cs_id = gl.createShader(GL_COMPUTE_SHADER);
1528 m_po_id = gl.createProgram();
1530 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() and/or glCraeteProgram() call(s) failed.");
1532 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
1534 gl.shaderSource(m_cs_id, n_cs_body_parts, cs_body_parts, DE_NULL); /* length */
1535 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
1537 /* Try to compile the shader object.
1539 * For GL contexts BEFORE 4.40, the test passes if either
1540 * the compilation or the linking process fails.
1542 * For GL contexts OF VERSION 4.40 or newer, the test passes
1543 * if both the compilation and the linking process succeed.
1545 * If GL_ARB_enhanced_layouts is supported, the latter holds for <= GL4.4 contexts.
1547 if (m_context.getContextInfo().isExtensionSupported("GL_ARB_enhanced_layouts"))
1549 expected_outcome = true;
1552 gl.compileShader(m_cs_id);
1553 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed.");
1555 gl.getShaderiv(m_cs_id, GL_COMPILE_STATUS, &compile_status);
1556 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");
1558 if (compile_status == GL_FALSE && !expected_outcome)
1563 gl.attachShader(m_po_id, m_cs_id);
1564 GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call failed.");
1566 gl.linkProgram(m_po_id);
1567 GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed.");
1569 gl.getProgramiv(m_po_id, GL_LINK_STATUS, &link_status);
1570 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed.");
1572 if (link_status == GL_FALSE && !expected_outcome)
1577 if (expected_outcome && (compile_status == GL_FALSE || link_status == GL_FALSE))
1579 m_testCtx.getLog() << tcu::TestLog::Message
1580 << "A compute program was expected to link successfully, but either the "
1581 "compilation and/or linking process has/have failed"
1582 << tcu::TestLog::EndMessage;
1586 else if (!expected_outcome && (compile_status == GL_TRUE && link_status == GL_TRUE))
1588 m_testCtx.getLog() << tcu::TestLog::Message
1589 << "A compute program was expected not to compile and link, but both processes "
1590 "have been executed successfully."
1591 << tcu::TestLog::EndMessage;
1597 m_testCtx.setTestResult(result ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, result ? "Pass" : "Fail");
1604 * @param context Rendering context
1605 * @param name Test name
1606 * @param description Test description
1608 PerVertexValidationTest::PerVertexValidationTest(deqp::Context& context)
1609 : TestCase(context, "CommonBug_PerVertexValidation",
1610 "Conformance test which verifies that various requirements regarding gl_PerVertex block re-declarations,"
1611 " as described by the spec, are followed by the implementation")
1624 /* Left blank on purpose */
1627 /** Deinitializes all GL objects created for the purpose of running the test,
1628 * as well as any client-side buffers allocated at initialization time
1630 void PerVertexValidationTest::deinit()
1632 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1634 /* Release the pipeline object */
1635 if (m_pipeline_id != 0)
1637 gl.deleteProgramPipelines(1, &m_pipeline_id);
1642 /* Release all dangling shader and shader program objects */
1646 /** Releases any allocated program and shader objects. */
1647 void PerVertexValidationTest::destroyPOsAndSOs()
1649 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1650 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 };
1651 glw::GLuint* so_id_ptrs[] = { &m_fs_id, &m_gs_id, &m_tc_id, &m_te_id, &m_vs_id };
1652 const unsigned int n_po_id_ptrs = static_cast<const unsigned int>(sizeof(po_id_ptrs) / sizeof(po_id_ptrs[0]));
1653 const unsigned int n_so_id_ptrs = static_cast<const unsigned int>(sizeof(so_id_ptrs) / sizeof(so_id_ptrs[0]));
1655 for (unsigned int n_po_id = 0; n_po_id < n_po_id_ptrs; ++n_po_id)
1657 glw::GLuint* po_id_ptr = po_id_ptrs[n_po_id];
1659 if (*po_id_ptr != 0)
1661 gl.deleteProgram(*po_id_ptr);
1665 } /* for (all shader program object ids) */
1667 for (unsigned int n_so_id = 0; n_so_id < n_so_id_ptrs; ++n_so_id)
1669 glw::GLuint* so_id_ptr = so_id_ptrs[n_so_id];
1671 if (*so_id_ptr != 0)
1673 gl.deleteShader(*so_id_ptr);
1677 } /* for (all shader object ids) */
1680 /** Tells whether the program pipeline validation process should fail for specified test iteration.
1682 * @return VALIDATION_RESULT_TRUE if the pipeline validation process should be positive,
1683 * VALIDATION_RESULT_FALSE if the validation should be negative
1684 * VALIDATION_RESULT_UNDEFINED when the validation result is not defined */
1685 PerVertexValidationTest::_validation PerVertexValidationTest::getProgramPipelineValidationExpectedResult(void) const
1687 /** All "undeclared in.." and "undeclared out.." test shaders are expected not to link successfully
1688 * when used as separate programs - which leaves pipeline in undefined state.
1689 * All "declaration mismatch" shaders should link, but the results are undefined.
1691 * Currently the test does not exercise any defined case
1693 return VALIDATION_RESULT_UNDEFINED;
1696 /** Returns a literal corresponding to the shader stage enum.
1698 * @param shader_stage Enum to return the string for.
1700 * @return As per description.
1702 std::string PerVertexValidationTest::getShaderStageName(_shader_stage shader_stage) const
1704 std::string result = "?!";
1706 switch (shader_stage)
1708 case SHADER_STAGE_FRAGMENT:
1709 result = "fragment shader";
1711 case SHADER_STAGE_GEOMETRY:
1712 result = "geometry shader";
1714 case SHADER_STAGE_TESSELLATION_CONTROL:
1715 result = "tessellation control shader";
1717 case SHADER_STAGE_TESSELLATION_EVALUATION:
1718 result = "tessellation evaluation shader";
1720 case SHADER_STAGE_VERTEX:
1721 result = "vertex shader";
1728 /** Returns a literal corresponding to the test iteration enum.
1730 * @param iteration Enum to return the string for.
1732 * @return As per description.
1734 std::string PerVertexValidationTest::getTestIterationName(_test_iteration iteration) const
1736 std::string result = "?!";
1740 case TEST_ITERATION_UNDECLARED_IN_PERVERTEX_GS_GL_CLIPDISTANCE_USAGE:
1741 result = "Input gl_ClipDistance usage in Geometry Shader without gl_PerVertex block redeclaration";
1743 case TEST_ITERATION_UNDECLARED_IN_PERVERTEX_GS_GL_CULLDISTANCE_USAGE:
1744 result = "Input gl_CullDistance usage in Geometry Shader without gl_PerVertex block redeclaration";
1746 case TEST_ITERATION_UNDECLARED_IN_PERVERTEX_GS_GL_POINTSIZE_USAGE:
1747 result = "Input gl_PointSize usage in a separable Geometry Shader without gl_PerVertex block redeclaration";
1749 case TEST_ITERATION_UNDECLARED_IN_PERVERTEX_GS_GL_POSITION_USAGE:
1750 result = "Input gl_Position usage in a separable Geometry Shader without gl_PerVertex block redeclaration";
1752 case TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TC_GL_CLIPDISTANCE_USAGE:
1753 result = "Input gl_ClipDistance usage in a separable Tessellation Control Shader without gl_PerVertex block "
1756 case TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TC_GL_CULLDISTANCE_USAGE:
1757 result = "Input gl_CullDistance usage in a separable Tessellation Control Shader without gl_PerVertex block "
1760 case TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TC_GL_POINTSIZE_USAGE:
1761 result = "Input gl_PointSize usage in a separable Tessellation Control Shader without gl_PerVertex block "
1764 case TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TC_GL_POSITION_USAGE:
1765 result = "Input gl_Position usage in a separable Tessellation Control Shader without gl_PerVertex block "
1768 case TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TE_GL_CLIPDISTANCE_USAGE:
1769 result = "Input gl_ClipDistance usage in a separable Tessellation Evaluation Shader without gl_PerVertex block "
1772 case TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TE_GL_CULLDISTANCE_USAGE:
1773 result = "Input gl_CullDistance usage in a separable Tessellation Evaluation Shader without gl_PerVertex block "
1776 case TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TE_GL_POINTSIZE_USAGE:
1777 result = "Input gl_PointSize usage in a separable Tessellation Evaluation Shader without gl_PerVertex block "
1780 case TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TE_GL_POSITION_USAGE:
1781 result = "Input gl_Position usage in a separable Tessellation Evaluation Shader without gl_PerVertex block "
1784 case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_GS_GL_CLIPDISTANCE_USAGE:
1785 result = "Output gl_ClipDistance usage in Geometry Shader without gl_PerVertex block redeclaration";
1787 case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_GS_GL_CULLDISTANCE_USAGE:
1788 result = "Output gl_CullDistance usage in Geometry Shader without gl_PerVertex block redeclaration";
1790 case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_GS_GL_POINTSIZE_USAGE:
1791 result = "Output gl_PointSize usage in a separable Geometry Shader without gl_PerVertex block redeclaration";
1793 case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_GS_GL_POSITION_USAGE:
1794 result = "Output gl_Position usage in a separable Geometry Shader without gl_PerVertex block redeclaration";
1796 case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TC_GL_CLIPDISTANCE_USAGE:
1797 result = "Output gl_ClipDistance usage in a separable Tessellation Control Shader without gl_PerVertex block "
1800 case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TC_GL_CULLDISTANCE_USAGE:
1801 result = "Output gl_CullDistance usage in a separable Tessellation Control Shader without gl_PerVertex block "
1804 case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TC_GL_POINTSIZE_USAGE:
1805 result = "Output gl_PointSize usage in a separable Tessellation Control Shader without gl_PerVertex block "
1808 case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TC_GL_POSITION_USAGE:
1809 result = "Output gl_Position usage in a separable Tessellation Control Shader without gl_PerVertex block "
1812 case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TE_GL_CLIPDISTANCE_USAGE:
1813 result = "Output gl_ClipDistance usage in a separable Tessellation Evaluation Shader without gl_PerVertex "
1814 "block redeclaration";
1816 case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TE_GL_CULLDISTANCE_USAGE:
1817 result = "Output gl_CullDistance usage in a separable Tessellation Evaluation Shader without gl_PerVertex "
1818 "block redeclaration";
1820 case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TE_GL_POINTSIZE_USAGE:
1821 result = "Output gl_PointSize usage in a separable Tessellation Evaluation Shader without gl_PerVertex block "
1824 case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TE_GL_POSITION_USAGE:
1825 result = "Output gl_Position usage in a separable Tessellation Evaluation Shader without gl_PerVertex block "
1828 case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_VS_GL_CLIPDISTANCE_USAGE:
1829 result = "Output gl_ClipDistance usage in a separable Vertex Shader without gl_PerVertex block redeclaration";
1831 case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_VS_GL_CULLDISTANCE_USAGE:
1832 result = "Output gl_CullDistance usage in a separable Vertex Shader without gl_PerVertex block redeclaration";
1834 case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_VS_GL_POINTSIZE_USAGE:
1835 result = "Output gl_PointSize usage in a separable Vertex Shader without gl_PerVertex block redeclaration";
1837 case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_VS_GL_POSITION_USAGE:
1838 result = "Output gl_Position usage in a separable Vertex Shader without gl_PerVertex block redeclaration";
1841 case TEST_ITERATION_PERVERTEX_DECLARATION_MISMATCH_GS_VS:
1842 result = "Geometry and Vertex Shaders use different gl_PerVertex block redeclaration";
1844 case TEST_ITERATION_PERVERTEX_DECLARATION_MISMATCH_GS_TC_TE_VS:
1845 result = "Geometry, Tessellation Control, Tessellation Evaluation and Vertex Shaders use a different "
1846 "gl_PerVertex block redeclaration";
1848 case TEST_ITERATION_PERVERTEX_DECLARATION_MISMATCH_TC_TE_VS:
1849 result = "Tesselation Control, Tessellation Evaluation and Vertex Shaders use a different gl_PerVertex block "
1853 case TEST_ITERATION_PERVERTEX_BLOCK_UNDEFINED:
1854 result = "No gl_PerVertex block defined in shader programs for all shader stages supported by the running "
1865 /** Returns shader bodies, minimum context type and a bitfield describing shader stages used for the
1866 * user-specified test iteration enum.
1868 * @param context_type Running context's type.
1869 * @param iteration Test iteration enum to return the properties for.
1870 * @param out_min_context_type_ptr Deref will be set to the minimum context type supported by the
1871 * specified test iteration.
1872 * @param out_used_shader_stages_ptr Deref will be set to a combination of _shader_stage enum values,
1873 * describing which shader stages are used by the test iteration.
1874 * @param out_gs_body_ptr Deref will be updated with the geometry shader body, if used by the
1876 * @param out_tc_body_ptr Deref will be updated with the tessellation control shader body, if
1877 * used by the test iteration.
1878 * @param out_te_body_ptr Deref will be updated with the tessellation evaluation shader body, if
1879 * used by the test iteration.
1880 * @param out_vs_body_ptr Deref will be updated with the vertex shader body, if used by the
1884 void PerVertexValidationTest::getTestIterationProperties(glu::ContextType context_type, _test_iteration iteration,
1885 glu::ContextType* out_min_context_type_ptr,
1886 _shader_stage* out_used_shader_stages_ptr,
1887 std::string* out_gs_body_ptr, std::string* out_tc_body_ptr,
1888 std::string* out_te_body_ptr,
1889 std::string* out_vs_body_ptr) const
1891 const bool include_cull_distance = glu::contextSupports(context_type, glu::ApiType::core(4, 5));
1895 case TEST_ITERATION_UNDECLARED_IN_PERVERTEX_GS_GL_CLIPDISTANCE_USAGE:
1896 case TEST_ITERATION_UNDECLARED_IN_PERVERTEX_GS_GL_CULLDISTANCE_USAGE:
1897 case TEST_ITERATION_UNDECLARED_IN_PERVERTEX_GS_GL_POINTSIZE_USAGE:
1898 case TEST_ITERATION_UNDECLARED_IN_PERVERTEX_GS_GL_POSITION_USAGE:
1899 case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_GS_GL_CLIPDISTANCE_USAGE:
1900 case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_GS_GL_CULLDISTANCE_USAGE:
1901 case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_GS_GL_POINTSIZE_USAGE:
1902 case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_GS_GL_POSITION_USAGE:
1904 const bool is_cull_distance_iteration =
1905 (iteration == TEST_ITERATION_UNDECLARED_IN_PERVERTEX_GS_GL_CULLDISTANCE_USAGE ||
1906 iteration == TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_GS_GL_CULLDISTANCE_USAGE);
1907 std::stringstream gs_body_sstream;
1909 *out_min_context_type_ptr = (is_cull_distance_iteration) ? glu::ContextType(4, 5, glu::PROFILE_CORE) :
1910 glu::ContextType(4, 1, glu::PROFILE_CORE);
1911 *out_used_shader_stages_ptr = (_shader_stage)(SHADER_STAGE_GEOMETRY | SHADER_STAGE_VERTEX);
1913 /* Form the geometry shader body */
1914 gs_body_sstream << ((!is_cull_distance_iteration) ? "#version 410\n" : "version 450\n")
1916 "layout(points) in;\n"
1917 "layout(points, max_vertices = 1) out;\n"
1922 gs_body_sstream << ((iteration != TEST_ITERATION_UNDECLARED_IN_PERVERTEX_GS_GL_CLIPDISTANCE_USAGE &&
1923 iteration != TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_GS_GL_CLIPDISTANCE_USAGE) ?
1924 "float gl_ClipDistance[];\n" :
1926 gs_body_sstream << ((iteration != TEST_ITERATION_UNDECLARED_IN_PERVERTEX_GS_GL_POINTSIZE_USAGE &&
1927 iteration != TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_GS_GL_POINTSIZE_USAGE) ?
1928 "float gl_PointSize;\n" :
1930 gs_body_sstream << ((iteration != TEST_ITERATION_UNDECLARED_IN_PERVERTEX_GS_GL_POSITION_USAGE &&
1931 iteration != TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_GS_GL_POSITION_USAGE) ?
1932 "vec4 gl_Position;\n" :
1935 if (include_cull_distance)
1937 gs_body_sstream << "float gl_CullDistance[];\n";
1940 gs_body_sstream << "} gl_in[];\n"
1942 "out gl_PerVertex\n"
1945 gs_body_sstream << ((iteration != TEST_ITERATION_UNDECLARED_IN_PERVERTEX_GS_GL_CLIPDISTANCE_USAGE &&
1946 iteration != TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_GS_GL_CLIPDISTANCE_USAGE) ?
1947 "float gl_ClipDistance[];\n" :
1949 gs_body_sstream << ((iteration != TEST_ITERATION_UNDECLARED_IN_PERVERTEX_GS_GL_POINTSIZE_USAGE &&
1950 iteration != TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_GS_GL_POINTSIZE_USAGE) ?
1951 "float gl_PointSize;\n" :
1953 gs_body_sstream << ((iteration != TEST_ITERATION_UNDECLARED_IN_PERVERTEX_GS_GL_POSITION_USAGE &&
1954 iteration != TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_GS_GL_POSITION_USAGE) ?
1955 "vec4 gl_Position;\n" :
1958 if (include_cull_distance)
1960 gs_body_sstream << "float gl_CullDistance[];\n";
1963 gs_body_sstream << "};\n"
1970 case TEST_ITERATION_UNDECLARED_IN_PERVERTEX_GS_GL_CLIPDISTANCE_USAGE:
1971 gs_body_sstream << "gl_Position = vec4(gl_in[0].gl_ClipDistance[0]);\n";
1973 case TEST_ITERATION_UNDECLARED_IN_PERVERTEX_GS_GL_CULLDISTANCE_USAGE:
1974 gs_body_sstream << "gl_Position = vec4(gl_in[0].gl_CullDistance[0]);\n";
1976 case TEST_ITERATION_UNDECLARED_IN_PERVERTEX_GS_GL_POINTSIZE_USAGE:
1977 gs_body_sstream << "gl_Position = vec4(gl_in[0].gl_PointSize);\n";
1979 case TEST_ITERATION_UNDECLARED_IN_PERVERTEX_GS_GL_POSITION_USAGE:
1980 gs_body_sstream << "gl_Position = gl_in[0].gl_Position;\n";
1982 case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_GS_GL_CLIPDISTANCE_USAGE:
1983 gs_body_sstream << "gl_ClipDistance[0] = gl_in[0].gl_Position.x;\n";
1985 case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_GS_GL_CULLDISTANCE_USAGE:
1986 gs_body_sstream << "gl_CullDistance[0] = gl_in[0].gl_Position.x;\n";
1988 case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_GS_GL_POINTSIZE_USAGE:
1989 gs_body_sstream << "gl_PointSize = gl_in[0].gl_Position.x;\n";
1991 case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_GS_GL_POSITION_USAGE:
1992 gs_body_sstream << "gl_Position = vec4(gl_in[0].gl_PointSize);\n";
1995 gs_body_sstream << "\n";
1997 } /* switch (iteration) */
1999 gs_body_sstream << " EmitVertex();\n"
2002 /* Store geometry & vertex shader bodies */
2003 *out_gs_body_ptr = gs_body_sstream.str();
2004 *out_vs_body_ptr = getVertexShaderBody(context_type, iteration);
2009 case TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TC_GL_CLIPDISTANCE_USAGE:
2010 case TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TC_GL_CULLDISTANCE_USAGE:
2011 case TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TC_GL_POINTSIZE_USAGE:
2012 case TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TC_GL_POSITION_USAGE:
2013 case TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TE_GL_CLIPDISTANCE_USAGE:
2014 case TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TE_GL_CULLDISTANCE_USAGE:
2015 case TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TE_GL_POINTSIZE_USAGE:
2016 case TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TE_GL_POSITION_USAGE:
2017 case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TC_GL_CLIPDISTANCE_USAGE:
2018 case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TC_GL_CULLDISTANCE_USAGE:
2019 case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TC_GL_POINTSIZE_USAGE:
2020 case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TC_GL_POSITION_USAGE:
2021 case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TE_GL_CLIPDISTANCE_USAGE:
2022 case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TE_GL_CULLDISTANCE_USAGE:
2023 case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TE_GL_POINTSIZE_USAGE:
2024 case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TE_GL_POSITION_USAGE:
2026 std::stringstream tc_sstream;
2027 std::stringstream te_sstream;
2029 const bool is_clip_distance_iteration =
2030 (iteration == TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TC_GL_CLIPDISTANCE_USAGE ||
2031 iteration == TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TE_GL_CLIPDISTANCE_USAGE ||
2032 iteration == TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TC_GL_CLIPDISTANCE_USAGE ||
2033 iteration == TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TE_GL_CLIPDISTANCE_USAGE);
2034 const bool is_cull_distance_iteration =
2035 (iteration == TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TC_GL_CULLDISTANCE_USAGE ||
2036 iteration == TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TE_GL_CULLDISTANCE_USAGE ||
2037 iteration == TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TC_GL_CULLDISTANCE_USAGE ||
2038 iteration == TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TE_GL_CULLDISTANCE_USAGE);
2039 const bool is_pointsize_iteration =
2040 (iteration == TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TC_GL_POINTSIZE_USAGE ||
2041 iteration == TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TE_GL_POINTSIZE_USAGE ||
2042 iteration == TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TC_GL_POINTSIZE_USAGE ||
2043 iteration == TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TE_GL_POINTSIZE_USAGE);
2044 const bool is_position_iteration = (iteration == TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TC_GL_POSITION_USAGE ||
2045 iteration == TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TE_GL_POSITION_USAGE ||
2046 iteration == TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TC_GL_POSITION_USAGE ||
2047 iteration == TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TE_GL_POSITION_USAGE);
2049 *out_min_context_type_ptr = (is_cull_distance_iteration) ? glu::ContextType(4, 5, glu::PROFILE_CORE) :
2050 glu::ContextType(4, 0, glu::PROFILE_CORE);
2051 *out_used_shader_stages_ptr = (_shader_stage)(SHADER_STAGE_TESSELLATION_CONTROL |
2052 SHADER_STAGE_TESSELLATION_EVALUATION | SHADER_STAGE_VERTEX);
2054 /* Form tessellation control & tessellation evaluation shader bodies */
2055 for (unsigned int n_iteration = 0; n_iteration < 2; ++n_iteration)
2057 const bool is_tc_stage = (n_iteration == 0);
2058 std::stringstream* current_sstream_ptr = (is_tc_stage) ? &tc_sstream : &te_sstream;
2060 *current_sstream_ptr << ((is_cull_distance_iteration) ? "#version 450 core\n" : "#version 410\n") << "\n";
2064 *current_sstream_ptr << "layout (vertices = 4) out;\n";
2068 *current_sstream_ptr << "layout (isolines) in;\n";
2071 *current_sstream_ptr << "\n"
2075 if (is_position_iteration)
2077 *current_sstream_ptr << "vec4 gl_Position;\n";
2080 if (!is_pointsize_iteration)
2082 *current_sstream_ptr << "float gl_PointSize\n";
2085 if (!is_clip_distance_iteration)
2087 *current_sstream_ptr << "float gl_ClipDistance[];\n";
2090 if (!is_cull_distance_iteration && include_cull_distance)
2092 *current_sstream_ptr << "float gl_CullDistance[];\n";
2095 *current_sstream_ptr << "} gl_in[gl_MaxPatchVertices];\n"
2097 "out gl_PerVertex\n"
2100 if (!is_position_iteration)
2102 *current_sstream_ptr << "vec4 gl_Position;\n";
2105 if (!is_pointsize_iteration)
2107 *current_sstream_ptr << "float gl_PointSize\n";
2110 if (!is_clip_distance_iteration)
2112 *current_sstream_ptr << "float gl_ClipDistance[];\n";
2115 if (!is_cull_distance_iteration && include_cull_distance)
2117 *current_sstream_ptr << "float gl_CullDistance[];\n";
2122 *current_sstream_ptr << "} gl_out[];\n";
2126 *current_sstream_ptr << "};\n";
2129 *current_sstream_ptr << "\n"
2135 *current_sstream_ptr << "gl_out[gl_InvocationID].";
2138 if (iteration == TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TC_GL_CLIPDISTANCE_USAGE ||
2139 iteration == TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TE_GL_CLIPDISTANCE_USAGE)
2141 *current_sstream_ptr << "gl_Position = vec4(gl_in[0].gl_ClipDistance[0]);\n";
2143 else if (iteration == TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TC_GL_CULLDISTANCE_USAGE ||
2144 iteration == TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TE_GL_CULLDISTANCE_USAGE)
2146 *current_sstream_ptr << "gl_Position = vec4(gl_in[0].gl_CullDistance[0]);\n";
2148 else if (iteration == TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TC_GL_POINTSIZE_USAGE ||
2149 iteration == TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TE_GL_POINTSIZE_USAGE)
2151 *current_sstream_ptr << "gl_Position = vec4(gl_in[0].gl_PointSize);\n";
2153 else if (iteration == TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TC_GL_POSITION_USAGE ||
2154 iteration == TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TE_GL_POSITION_USAGE)
2156 *current_sstream_ptr << "gl_Position = gl_in[0].gl_Position;\n";
2158 else if (iteration == TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TC_GL_CLIPDISTANCE_USAGE ||
2159 iteration == TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TE_GL_CLIPDISTANCE_USAGE)
2161 *current_sstream_ptr << "gl_ClipDistance[0] = gl_in[0].gl_Position.x;\n";
2163 else if (iteration == TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TC_GL_CULLDISTANCE_USAGE ||
2164 iteration == TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TE_GL_CULLDISTANCE_USAGE)
2166 *current_sstream_ptr << "gl_CullDistance[0] = gl_in[0].gl_Position.x;\n";
2168 else if (iteration == TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TC_GL_POINTSIZE_USAGE ||
2169 iteration == TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TE_GL_POINTSIZE_USAGE)
2171 *current_sstream_ptr << "gl_PointSize = gl_in[0].gl_Position.x;\n";
2173 else if (iteration == TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TC_GL_POSITION_USAGE ||
2174 iteration == TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TE_GL_POSITION_USAGE)
2176 *current_sstream_ptr << "gl_Position = vec4(gl_in[0].gl_PointSize);\n";
2179 tc_sstream << "}\n";
2180 } /* for (both TC and TE stages) */
2182 /* Store the bodies */
2183 *out_tc_body_ptr = tc_sstream.str();
2184 *out_te_body_ptr = te_sstream.str();
2185 *out_vs_body_ptr = getVertexShaderBody(context_type, iteration);
2190 case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_VS_GL_CLIPDISTANCE_USAGE:
2191 case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_VS_GL_CULLDISTANCE_USAGE:
2192 case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_VS_GL_POINTSIZE_USAGE:
2193 case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_VS_GL_POSITION_USAGE:
2195 const bool is_cull_distance_iteration =
2196 (iteration == TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_VS_GL_CULLDISTANCE_USAGE);
2198 *out_min_context_type_ptr = (is_cull_distance_iteration) ? glu::ContextType(4, 5, glu::PROFILE_CORE) :
2199 glu::ContextType(4, 1, glu::PROFILE_CORE);
2200 *out_used_shader_stages_ptr = (_shader_stage)(SHADER_STAGE_VERTEX);
2202 /* Determine what the main() body contents should be. */
2203 std::string vs_main_body;
2207 case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_VS_GL_CLIPDISTANCE_USAGE:
2208 vs_main_body = "gl_ClipDistance[0] = 1.0;";
2210 case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_VS_GL_CULLDISTANCE_USAGE:
2211 vs_main_body = "gl_CullDistance[0] = 2.0;";
2213 case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_VS_GL_POINTSIZE_USAGE:
2214 vs_main_body = "gl_PointSize = 1.0;";
2216 case TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_VS_GL_POSITION_USAGE:
2217 vs_main_body = "gl_Position = vec4(1.0f, 2.0, 3.0, 4.0);";
2224 /* Store the body */
2225 *out_vs_body_ptr = getVertexShaderBody(context_type, iteration, vs_main_body);
2230 case TEST_ITERATION_PERVERTEX_DECLARATION_MISMATCH_GS_VS:
2231 case TEST_ITERATION_PERVERTEX_DECLARATION_MISMATCH_GS_TC_TE_VS:
2232 case TEST_ITERATION_PERVERTEX_DECLARATION_MISMATCH_TC_TE_VS:
2234 *out_min_context_type_ptr = glu::ContextType(4, 1, glu::PROFILE_CORE);
2235 *out_used_shader_stages_ptr = SHADER_STAGE_VERTEX;
2237 if (iteration == TEST_ITERATION_PERVERTEX_DECLARATION_MISMATCH_GS_TC_TE_VS ||
2238 iteration == TEST_ITERATION_PERVERTEX_DECLARATION_MISMATCH_GS_VS)
2240 (int&)* out_used_shader_stages_ptr |= SHADER_STAGE_GEOMETRY;
2243 if (iteration == TEST_ITERATION_PERVERTEX_DECLARATION_MISMATCH_GS_TC_TE_VS ||
2244 iteration == TEST_ITERATION_PERVERTEX_DECLARATION_MISMATCH_TC_TE_VS)
2246 (int&)* out_used_shader_stages_ptr |=
2247 (_shader_stage)(SHADER_STAGE_TESSELLATION_CONTROL | SHADER_STAGE_TESSELLATION_EVALUATION);
2250 /* Shader bodies are predefined in this case. */
2251 *out_gs_body_ptr = "#version 410\n"
2253 "layout (points) in;\n"
2254 "layout (points, max_vertices = 4) out;\n"
2258 " float gl_ClipDistance[];\n"
2261 "out gl_PerVertex\n"
2263 " float gl_ClipDistance[];\n"
2268 " gl_ClipDistance[0] = 0.5;\n"
2271 *out_tc_body_ptr = "#version 410\n"
2273 "layout (vertices = 4) out;\n"
2277 " float gl_PointSize;\n"
2280 "out gl_PerVertex\n"
2282 " float gl_PointSize;\n"
2287 " gl_out[gl_InvocationID].gl_PointSize = gl_in[0].gl_PointSize + 1.0;\n"
2289 *out_te_body_ptr = "#version 410\n"
2291 "layout (isolines) in;\n"
2295 " float gl_PointSize;\n"
2296 " vec4 gl_Position;\n"
2297 "} gl_in[gl_MaxPatchVertices];\n"
2299 "out gl_PerVertex\n"
2301 " float gl_PointSize;\n"
2302 " vec4 gl_Position;\n"
2307 " gl_Position = vec4(gl_in[0].gl_PointSize) + gl_in[1].gl_Position;\n"
2309 *out_vs_body_ptr = "#version 410\n"
2311 "out gl_PerVertex\n"
2313 " vec4 gl_Position;\n"
2318 " gl_Position = vec4(2.0);\n"
2324 case TEST_ITERATION_PERVERTEX_BLOCK_UNDEFINED:
2326 *out_min_context_type_ptr = glu::ContextType(4, 1, glu::PROFILE_CORE);
2327 *out_used_shader_stages_ptr = SHADER_STAGE_VERTEX;
2329 if (glu::contextSupports(context_type, glu::ApiType::core(3, 2)))
2331 (int&)* out_used_shader_stages_ptr |= SHADER_STAGE_GEOMETRY;
2334 if (glu::contextSupports(context_type, glu::ApiType::core(4, 0)))
2336 (int&)* out_used_shader_stages_ptr |=
2337 SHADER_STAGE_TESSELLATION_CONTROL | SHADER_STAGE_TESSELLATION_EVALUATION;
2340 *out_gs_body_ptr = "#version 410\n"
2342 "layout (points) in;\n"
2343 "layout (points, max_vertices = 4) out;\n"
2347 " gl_Position = vec4(1.0, 2.0, 3.0, 4.0);\n"
2350 *out_tc_body_ptr = "#version 410\n"
2352 "layout(vertices = 4) out;\n"
2356 " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
2358 *out_te_body_ptr = "#version 410\n"
2360 "layout (isolines) in;\n"
2364 " gl_Position = gl_in[0].gl_Position;\n"
2366 *out_vs_body_ptr = "#version 410\n"
2370 " gl_Position = vec4(1.0, 2.0, 3.0, 4.0);\n"
2377 TCU_FAIL("Unrecognized test iteration");
2378 } /* switch (iteration) */
2381 /** Returns a dummy vertex shader body, with main() entry-point using code passed by
2382 * the @param main_body argument.
2384 * @param context_type Running rendering context's type.
2385 * @param iteration Test iteration to return the vertex shader body for.
2386 * @param main_body Body to use for the main() entry-point.
2388 * @return Requested object.
2390 std::string PerVertexValidationTest::getVertexShaderBody(glu::ContextType context_type, _test_iteration iteration,
2391 std::string main_body) const
2393 const bool include_clip_distance = (iteration != TEST_ITERATION_UNDECLARED_IN_PERVERTEX_GS_GL_CLIPDISTANCE_USAGE &&
2394 iteration != TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TC_GL_CLIPDISTANCE_USAGE &&
2395 iteration != TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TE_GL_CLIPDISTANCE_USAGE &&
2396 iteration != TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_GS_GL_CLIPDISTANCE_USAGE &&
2397 iteration != TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TC_GL_CLIPDISTANCE_USAGE &&
2398 iteration != TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TE_GL_CLIPDISTANCE_USAGE &&
2399 iteration != TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_VS_GL_CLIPDISTANCE_USAGE);
2400 const bool include_cull_distance = (iteration != TEST_ITERATION_UNDECLARED_IN_PERVERTEX_GS_GL_CULLDISTANCE_USAGE &&
2401 iteration != TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TC_GL_CULLDISTANCE_USAGE &&
2402 iteration != TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TE_GL_CULLDISTANCE_USAGE &&
2403 iteration != TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_GS_GL_CULLDISTANCE_USAGE &&
2404 iteration != TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TC_GL_CULLDISTANCE_USAGE &&
2405 iteration != TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TE_GL_CULLDISTANCE_USAGE &&
2406 iteration != TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_VS_GL_CULLDISTANCE_USAGE &&
2407 glu::contextSupports(context_type, glu::ApiType::core(4, 5)));
2408 const bool include_pointsize = (iteration != TEST_ITERATION_UNDECLARED_IN_PERVERTEX_GS_GL_POINTSIZE_USAGE &&
2409 iteration != TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TC_GL_POINTSIZE_USAGE &&
2410 iteration != TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TE_GL_POINTSIZE_USAGE &&
2411 iteration != TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_GS_GL_POINTSIZE_USAGE &&
2412 iteration != TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TC_GL_POINTSIZE_USAGE &&
2413 iteration != TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TE_GL_POINTSIZE_USAGE &&
2414 iteration != TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_VS_GL_POINTSIZE_USAGE);
2415 const bool include_position = (iteration != TEST_ITERATION_UNDECLARED_IN_PERVERTEX_GS_GL_POSITION_USAGE &&
2416 iteration != TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TC_GL_POSITION_USAGE &&
2417 iteration != TEST_ITERATION_UNDECLARED_IN_PERVERTEX_TE_GL_POSITION_USAGE &&
2418 iteration != TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_GS_GL_POSITION_USAGE &&
2419 iteration != TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TC_GL_POSITION_USAGE &&
2420 iteration != TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_TE_GL_POSITION_USAGE &&
2421 iteration != TEST_ITERATION_UNDECLARED_OUT_PERVERTEX_VS_GL_POSITION_USAGE);
2422 std::stringstream vs_body_sstream;
2424 vs_body_sstream << "#version " << ((include_cull_distance) ? "450" : "410") << "\n"
2429 vs_body_sstream << ((include_clip_distance) ? "float gl_ClipDistance[];\n" : "");
2430 vs_body_sstream << ((include_pointsize) ? "float gl_PointSize;\n" : "");
2431 vs_body_sstream << ((include_position) ? "vec4 gl_Position;\n" : "");
2432 vs_body_sstream << ((include_cull_distance) ? "float gl_CullDistance[];\n" : "");
2434 vs_body_sstream << "};\n"
2436 "out gl_PerVertex\n"
2439 vs_body_sstream << ((include_clip_distance) ? "float gl_ClipDistance[];\n" : "");
2440 vs_body_sstream << ((include_pointsize) ? "float gl_PointSize;\n" : "");
2441 vs_body_sstream << ((include_position) ? "vec4 gl_Position;\n" : "");
2442 vs_body_sstream << ((include_cull_distance) ? "float gl_CullDistance[];\n" : "");
2444 vs_body_sstream << "};\n"
2449 << main_body << "\n"
2452 return vs_body_sstream.str();
2455 /** Dummy init function */
2456 void PerVertexValidationTest::init()
2458 /* Left blank on purpose */
2461 /** Executes test iteration.
2463 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
2465 tcu::TestNode::IterateResult PerVertexValidationTest::iterate()
2467 const glu::ContextType context_type = m_context.getRenderContext().getType();
2468 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2471 /* Separable program objects went into core in GL 4.1 */
2472 if (!glu::contextSupports(context_type, glu::ApiType::core(4, 1)))
2474 throw tcu::NotSupportedError("Test implemented for OpenGL 4.1 contexts or newer.");
2477 /* Each test iteration is going to be executed in two different modes:
2479 * 1) Create separate shader programs for each stage. They should link just fine.
2480 * Then create a pipeline and attach to it all the programs. At this stage, the
2481 * validation should report failure.
2483 * 2) Create a single separate shader program, holding all stages. Try to link it.
2484 * This process should report failure.
2486 for (int test_iteration = static_cast<int>(TEST_ITERATION_FIRST);
2487 test_iteration != static_cast<int>(TEST_ITERATION_COUNT); test_iteration++)
2489 for (unsigned int n_test_mode = 0; n_test_mode < 2; ++n_test_mode)
2491 /* Skip the second iteration if any of the shaders is expected not to compile. */
2492 if (isShaderProgramLinkingFailureExpected(static_cast<_test_iteration>(test_iteration)))
2497 /* Execute the actual test iteration */
2498 switch (n_test_mode)
2501 result &= runPipelineObjectValidationTestMode(static_cast<_test_iteration>(test_iteration));
2504 result &= runSeparateShaderTestMode(static_cast<_test_iteration>(test_iteration));
2511 if (m_pipeline_id != 0)
2513 gl.deleteProgramPipelines(1, /* n */
2516 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteProgramPipelines() call failed");
2518 } /* for (both test modes) */
2519 } /* for (all test iterations) */
2520 m_testCtx.setTestResult(result ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, result ? "Pass" : "Fail");
2525 /** Tells whether the linking process should fail for specified test iteration.
2527 * @param iteration Test iteration to query.
2529 * @return true if the linking process should fail, false otherwise */
2530 bool PerVertexValidationTest::isShaderProgramLinkingFailureExpected(_test_iteration iteration) const
2532 /** All "undeclared in.." and "undeclared out.." test shaders are expected not to link successfully
2533 * when used as separate programs.
2534 * Shaders built as a part of the remaining test iterations should compile and link successfully
2535 * for separate programs implementing only a single shader stage. Later on, however, pipeline
2536 * objects built of these programs should fail to validate, as they use incompatible gl_PerVertex
2537 * block redeclarations.
2539 return (iteration < TEST_ITERATION_PERVERTEX_DECLARATION_MISMATCH_GS_VS) ||
2540 iteration == TEST_ITERATION_PERVERTEX_BLOCK_UNDEFINED;
2543 /** Runs the specified test iteration in the following mode:
2546 * A pipeline object is created and shader programs are attached to it. It is expected that validation
2550 * @param iteration Test iteration to execute.
2552 * @return true if the test passed, false otherwise.
2554 bool PerVertexValidationTest::runPipelineObjectValidationTestMode(_test_iteration iteration)
2556 const glu::ContextType context_type = m_context.getRenderContext().getType();
2557 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2558 bool result = false;
2560 const char* body_raw_ptr = NULL;
2561 glw::GLenum expected_result = getProgramPipelineValidationExpectedResult();
2562 std::string fs_body;
2563 std::string gs_body;
2564 glw::GLint link_status;
2565 glu::ContextType min_context_type;
2566 std::string tc_body;
2567 std::string te_body;
2568 _shader_stage used_shader_stages;
2569 glw::GLint validate_status;
2570 glw::GLint validate_expected_status;
2571 std::string vs_body;
2573 struct _shader_program
2575 std::string* body_ptr;
2576 glw::GLuint* po_id_ptr;
2577 _shader_stage shader_stage;
2578 glw::GLenum shader_stage_bit_gl;
2579 glw::GLenum shader_stage_gl;
2580 } shader_programs[] = {
2581 { &fs_body, &m_fs_po_id, SHADER_STAGE_FRAGMENT, GL_FRAGMENT_SHADER_BIT, GL_FRAGMENT_SHADER },
2582 { &gs_body, &m_gs_po_id, SHADER_STAGE_GEOMETRY, GL_GEOMETRY_SHADER_BIT, GL_GEOMETRY_SHADER },
2583 { &tc_body, &m_tc_po_id, SHADER_STAGE_TESSELLATION_CONTROL, GL_TESS_CONTROL_SHADER_BIT,
2584 GL_TESS_CONTROL_SHADER },
2585 { &te_body, &m_te_po_id, SHADER_STAGE_TESSELLATION_EVALUATION, GL_TESS_EVALUATION_SHADER_BIT,
2586 GL_TESS_EVALUATION_SHADER },
2587 { &vs_body, &m_vs_po_id, SHADER_STAGE_VERTEX, GL_VERTEX_SHADER_BIT, GL_VERTEX_SHADER },
2589 const unsigned int n_shader_programs =
2590 static_cast<const unsigned int>(sizeof(shader_programs) / sizeof(shader_programs[0]));
2592 /* Make sure the test iteration can actually be run under the running rendering context
2595 getTestIterationProperties(context_type, iteration, &min_context_type, &used_shader_stages, &gs_body, &tc_body,
2596 &te_body, &vs_body);
2598 if (!glu::contextSupports(context_type, min_context_type.getAPI()))
2605 /* Set up shader program objects. All shader bodies by themselves are valid, so all shaders should
2606 * link just fine. */
2607 for (unsigned int n_shader_program = 0; n_shader_program < n_shader_programs; ++n_shader_program)
2609 _shader_program& current_shader_program = shader_programs[n_shader_program];
2611 if ((used_shader_stages & current_shader_program.shader_stage) != 0)
2613 body_raw_ptr = current_shader_program.body_ptr->c_str();
2614 *current_shader_program.po_id_ptr =
2615 gl.createShaderProgramv(current_shader_program.shader_stage_gl, 1, /* count */
2618 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShaderProgramv() call failed.");
2620 gl.getProgramiv(*current_shader_program.po_id_ptr, GL_LINK_STATUS, &link_status);
2621 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed.");
2623 if (link_status != GL_TRUE)
2625 char info_log[4096];
2627 if (!isShaderProgramLinkingFailureExpected(iteration))
2629 gl.getProgramInfoLog(*current_shader_program.po_id_ptr, sizeof(info_log), DE_NULL, /* length */
2632 m_testCtx.getLog() << tcu::TestLog::Message << "The separate "
2633 << getShaderStageName(current_shader_program.shader_stage)
2635 "failed to link, even though the shader body is valid.\n"
2638 << *current_shader_program.body_ptr << "<<\nInfo log\n>>\n"
2639 << info_log << "<<\n"
2640 << tcu::TestLog::EndMessage;
2648 } /* if (link_status != GL_TRUE) */
2649 } /* for (all shader programs) */
2650 } /* for (all shader stages) */
2652 /* Now that all shader programs are ready, set up a test-specific pipeline object and validate it. */
2653 gl.genProgramPipelines(1, &m_pipeline_id);
2654 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenProgramPipelines() call failed.");
2656 gl.bindProgramPipeline(m_pipeline_id);
2657 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindProgramPipeline() call failed.");
2659 for (unsigned int n_shader_program = 0; n_shader_program < n_shader_programs; ++n_shader_program)
2661 _shader_program& current_shader_program = shader_programs[n_shader_program];
2663 if ((used_shader_stages & current_shader_program.shader_stage) != 0)
2665 gl.useProgramStages(m_pipeline_id, current_shader_program.shader_stage_bit_gl,
2666 *current_shader_program.po_id_ptr);
2667 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgramStages() call failed.");
2669 } /* for (all shader programs) */
2671 gl.validateProgramPipeline(m_pipeline_id);
2672 GLU_EXPECT_NO_ERROR(gl.getError(), "glValidateProgramPipeline() call failed.");
2674 gl.getProgramPipelineiv(m_pipeline_id, GL_VALIDATE_STATUS, &validate_status);
2675 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramPipelineiv() call failed.");
2677 if (VALIDATION_RESULT_UNDEFINED != expected_result)
2679 switch (expected_result)
2681 case VALIDATION_RESULT_FALSE:
2682 validate_expected_status = GL_FALSE;
2684 case VALIDATION_RESULT_TRUE:
2685 validate_expected_status = GL_TRUE;
2688 TCU_FAIL("Invalid enum");
2692 if (validate_status != validate_expected_status)
2694 tcu::MessageBuilder message = m_testCtx.getLog().message();
2696 if (GL_FALSE == validate_expected_status)
2698 message << "A pipeline object was validated successfully, even though one";
2702 message << "A pipeline object was validated negatively, even though none";
2705 message << " of the failure reasons given by spec was applicable.\n"
2707 "Fragment shader body:\n>>\n"
2708 << ((shader_programs[0].body_ptr->length() > 0) ? *shader_programs[0].body_ptr : "[not used]")
2709 << "\n<<\nGeometry shader body:\n>>\n"
2710 << ((shader_programs[1].body_ptr->length() > 0) ? *shader_programs[1].body_ptr : "[not used]")
2711 << "\n<<\nTessellation control shader body:\n>>\n"
2712 << ((shader_programs[2].body_ptr->length() > 0) ? *shader_programs[2].body_ptr : "[not used]")
2713 << "\n<<\nTessellation evaluation shader body:\n>>\n"
2714 << ((shader_programs[3].body_ptr->length() > 0) ? *shader_programs[3].body_ptr : "[not used]")
2715 << "\n<<\nVertex shader body:\n>>\n"
2716 << ((shader_programs[4].body_ptr->length() > 0) ? *shader_programs[4].body_ptr : "[not used]")
2717 << tcu::TestLog::EndMessage;
2718 } /* if (validate_status != validate_expected_status) */
2733 /** Runs the specified test iteration in the following mode:
2736 * A single separate shader program, to which all shader stages used by the test are attached, is linked.
2737 * It is expected the linking process should fail.
2740 * @param iteration Test iteration to execute.
2742 * @return true if the test passed, false otherwise.
2744 bool PerVertexValidationTest::runSeparateShaderTestMode(_test_iteration iteration)
2746 glw::GLint compile_status;
2747 glu::ContextType context_type = m_context.getRenderContext().getType();
2748 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2749 glw::GLint link_status;
2750 glu::ContextType min_context_type;
2751 bool result = false;
2752 _shader_stage used_shader_stages;
2754 std::string fs_body;
2755 std::string gs_body;
2756 std::string tc_body;
2757 std::string te_body;
2758 std::string vs_body;
2762 std::string* body_ptr;
2763 glw::GLuint* so_id_ptr;
2764 _shader_stage shader_stage;
2765 glw::GLenum shader_stage_bit_gl;
2766 glw::GLenum shader_stage_gl;
2767 } shaders[] = { { &fs_body, &m_fs_id, SHADER_STAGE_FRAGMENT, GL_FRAGMENT_SHADER_BIT, GL_FRAGMENT_SHADER },
2768 { &gs_body, &m_gs_id, SHADER_STAGE_GEOMETRY, GL_GEOMETRY_SHADER_BIT, GL_GEOMETRY_SHADER },
2769 { &tc_body, &m_tc_id, SHADER_STAGE_TESSELLATION_CONTROL, GL_TESS_CONTROL_SHADER_BIT,
2770 GL_TESS_CONTROL_SHADER },
2771 { &te_body, &m_te_id, SHADER_STAGE_TESSELLATION_EVALUATION, GL_TESS_EVALUATION_SHADER_BIT,
2772 GL_TESS_EVALUATION_SHADER },
2773 { &vs_body, &m_vs_id, SHADER_STAGE_VERTEX, GL_VERTEX_SHADER_BIT, GL_VERTEX_SHADER } };
2774 const unsigned int n_shaders = static_cast<const unsigned int>(sizeof(shaders) / sizeof(shaders[0]));
2776 /* Retrieve iteration properties */
2777 getTestIterationProperties(context_type, iteration, &min_context_type, &used_shader_stages, &gs_body, &tc_body,
2778 &te_body, &vs_body);
2780 if (!glu::contextSupports(context_type, min_context_type.getAPI()))
2787 /* Bake a single shader with separate programs defined for all shader stages defined by the iteration
2788 * and see what happens.
2790 * For simplicity, we re-use m_vs_po_id to store the program object ID.
2792 m_vs_po_id = gl.createProgram();
2794 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
2796 for (unsigned int n_shader = 0; n_shader < n_shaders; ++n_shader)
2798 const char* body_raw_ptr = DE_NULL;
2799 const std::string& current_body = *shaders[n_shader].body_ptr;
2800 const _shader_stage& current_shader_stage = shaders[n_shader].shader_stage;
2801 glw::GLuint& current_so_id = *shaders[n_shader].so_id_ptr;
2802 const glw::GLenum& current_so_type_gl = shaders[n_shader].shader_stage_gl;
2804 if ((used_shader_stages & current_shader_stage) != 0)
2806 body_raw_ptr = current_body.c_str();
2807 current_so_id = gl.createShader(current_so_type_gl);
2809 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed.");
2811 gl.shaderSource(current_so_id, 1, /* count */
2812 &body_raw_ptr, DE_NULL); /* length */
2813 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
2815 /* Ensure the shader compiled successfully. */
2816 gl.compileShader(current_so_id);
2818 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed.");
2820 gl.getShaderiv(current_so_id, GL_COMPILE_STATUS, &compile_status);
2821 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");
2823 if (compile_status != GL_TRUE)
2825 m_testCtx.getLog() << tcu::TestLog::Message << getShaderStageName(current_shader_stage)
2826 << " unexpectedly failed to compile.\n"
2828 << current_body << "\n<<\n"
2829 << tcu::TestLog::EndMessage;
2834 /* Attach the shader object to the test program object */
2835 gl.attachShader(m_vs_po_id, current_so_id);
2836 GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call failed.");
2837 } /* if ((used_shader_stages & current_shader_stage) != 0) */
2838 } /* for (all shader objects) */
2840 /* Mark the program as separable */
2841 gl.programParameteri(m_vs_po_id, GL_PROGRAM_SEPARABLE, GL_TRUE);
2842 GLU_EXPECT_NO_ERROR(gl.getError(), "glProgramParameteri() call failed.");
2844 /* Try to link the program and check the result. */
2845 gl.linkProgram(m_vs_po_id);
2846 GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed.");
2848 gl.getProgramiv(m_vs_po_id, GL_LINK_STATUS, &link_status);
2849 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed.");
2851 if (link_status == GL_TRUE)
2853 m_testCtx.getLog() << tcu::TestLog::Message
2854 << "Separable program, consisting of the following separate shaders, was linked "
2855 "successfully, despite incompatible or missing gl_PerVertex block re-declarations.\n"
2857 "Fragment shader program:\n>>\n"
2858 << ((fs_body.length() > 0) ? fs_body : "[not used]")
2859 << "\n<<\nGeometry shader program:\n>>\n"
2860 << ((gs_body.length() > 0) ? gs_body : "[not used]")
2861 << "\n<<\nTessellation control shader program:\n>>\n"
2862 << ((tc_body.length() > 0) ? tc_body : "[not used]")
2863 << "\n<<\nTessellation evaluation shader program:\n>>\n"
2864 << ((te_body.length() > 0) ? te_body : "[not used]") << "\n<<\nVertex shader program:\n>>\n"
2865 << ((vs_body.length() > 0) ? vs_body : "[not used]") << tcu::TestLog::EndMessage;
2868 } /* if (link_status == GL_TRUE) */
2875 m_testCtx.getLog() << tcu::TestLog::Message << "Failed test description: " << getTestIterationName(iteration)
2876 << tcu::TestLog::EndMessage;
2883 * @param context Rendering context
2884 * @param name Test name
2885 * @param description Test description
2887 ReservedNamesTest::ReservedNamesTest(deqp::Context& context)
2888 : TestCase(context, "CommonBug_ReservedNames",
2889 "Verifies that reserved variable names are rejected by the GL SL compiler"
2890 " at the compilation time.")
2901 memset(m_so_ids, 0, sizeof(m_so_ids));
2904 /** Deinitializes all GL objects created for the purpose of running the test,
2905 * as well as any client-side buffers allocated at initialization time
2907 void ReservedNamesTest::deinit()
2909 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2911 for (unsigned int n_so_id = 0; n_so_id < sizeof(m_so_ids) / sizeof(m_so_ids[0]); ++n_so_id)
2913 const glw::GLuint current_so_id = m_so_ids[n_so_id];
2915 if (current_so_id != 0)
2917 gl.deleteShader(current_so_id);
2919 } /* for (all usedshader object IDs) */
2922 /** Returns a literal corresponding to the specified @param language_feature value.
2924 * @param language_feature Enum to return the string object for.
2926 * @return As specified.
2928 std::string ReservedNamesTest::getLanguageFeatureName(_language_feature language_feature) const
2930 std::string result = "[?!]";
2932 switch (language_feature)
2934 case LANGUAGE_FEATURE_ATOMIC_COUNTER:
2935 result = "atomic counter";
2937 case LANGUAGE_FEATURE_ATTRIBUTE:
2938 result = "attribute";
2940 case LANGUAGE_FEATURE_CONSTANT:
2941 result = "constant";
2943 case LANGUAGE_FEATURE_FUNCTION_ARGUMENT_NAME:
2944 result = "function argument name";
2946 case LANGUAGE_FEATURE_FUNCTION_NAME:
2947 result = "function name";
2949 case LANGUAGE_FEATURE_INPUT:
2950 result = "input variable";
2952 case LANGUAGE_FEATURE_INPUT_BLOCK_INSTANCE_NAME:
2953 result = "input block instance name";
2955 case LANGUAGE_FEATURE_INPUT_BLOCK_MEMBER_NAME:
2956 result = "input block member name";
2958 case LANGUAGE_FEATURE_INPUT_BLOCK_NAME:
2959 result = "input block name";
2961 case LANGUAGE_FEATURE_OUTPUT:
2962 result = "output variable";
2964 case LANGUAGE_FEATURE_OUTPUT_BLOCK_INSTANCE_NAME:
2965 result = "output block instance name";
2967 case LANGUAGE_FEATURE_OUTPUT_BLOCK_MEMBER_NAME:
2968 result = "output block member name";
2970 case LANGUAGE_FEATURE_OUTPUT_BLOCK_NAME:
2971 result = "output block name";
2973 case LANGUAGE_FEATURE_SHADER_STORAGE_BLOCK_INSTANCE_NAME:
2974 result = "shader storage block instance name";
2976 case LANGUAGE_FEATURE_SHADER_STORAGE_BLOCK_MEMBER_NAME:
2977 result = "shader storage block member name";
2979 case LANGUAGE_FEATURE_SHADER_STORAGE_BLOCK_NAME:
2980 result = "shader storage block name";
2982 case LANGUAGE_FEATURE_SHARED_VARIABLE:
2983 result = "shared variable";
2985 case LANGUAGE_FEATURE_STRUCTURE_MEMBER:
2986 result = "structure member";
2988 case LANGUAGE_FEATURE_STRUCTURE_INSTANCE_NAME:
2989 result = "structure instance name";
2991 case LANGUAGE_FEATURE_STRUCTURE_NAME:
2992 result = "structure name";
2994 case LANGUAGE_FEATURE_SUBROUTINE_FUNCTION_NAME:
2995 result = "subroutine function name";
2997 case LANGUAGE_FEATURE_SUBROUTINE_TYPE:
2998 result = "subroutine type";
3000 case LANGUAGE_FEATURE_SUBROUTINE_UNIFORM:
3001 result = "subroutine uniform";
3003 case LANGUAGE_FEATURE_UNIFORM:
3006 case LANGUAGE_FEATURE_UNIFORM_BLOCK_INSTANCE_NAME:
3007 result = "uniform block instance name";
3009 case LANGUAGE_FEATURE_UNIFORM_BLOCK_MEMBER_NAME:
3010 result = "uniform block member name";
3012 case LANGUAGE_FEATURE_UNIFORM_BLOCK_NAME:
3013 result = "uniform block name";
3015 case LANGUAGE_FEATURE_VARIABLE:
3016 result = "variable";
3018 case LANGUAGE_FEATURE_VARYING:
3024 } /* switch (language_feature) */
3029 /** Returns keywords and reserved names, specific to the running context version. */
3030 std::vector<std::string> ReservedNamesTest::getReservedNames() const
3032 const glu::ContextType context_type = m_context.getRenderContext().getType();
3033 std::vector<std::string> result;
3035 const char** context_keywords = NULL;
3036 unsigned int context_n_keywords = 0;
3037 unsigned int context_n_reserved = 0;
3038 const char** context_reserved = NULL;
3040 /* Keywords and reserved names were taken straight from relevant shading language specification documents */
3041 static const char* keywords_gl31[] = {
3108 "samplerCubeShadow",
3111 "sampler1DArrayShadow",
3112 "sampler2DArrayShadow",
3126 "sampler2DRectShadow",
3133 static const char* keywords_gl32[] = {
3200 "samplerCubeShadow",
3203 "sampler1DArrayShadow",
3204 "sampler2DArrayShadow",
3218 "sampler2DRectShadow",
3228 "isampler2DMSArray",
3229 "usampler2DMSArray",
3231 static const char* keywords_gl33[] = {
3298 "samplerCubeShadow",
3301 "sampler1DArrayShadow",
3302 "sampler2DArrayShadow",
3316 "sampler2DRectShadow",
3326 "isampler2DMSArray",
3327 "usampler2DMSArray",
3329 static const char* keywords_gl40[] = {
3415 "samplerCubeShadow",
3418 "sampler1DArrayShadow",
3419 "sampler2DArrayShadow",
3433 "sampler2DRectShadow",
3443 "isampler2DMSArray",
3444 "usampler2DMSArray",
3446 "samplerCubeArrayShadow",
3447 "isamplerCubeArray",
3448 "usamplerCubeArray",
3450 static const char* keywords_gl41[] = {
3536 "samplerCubeShadow",
3539 "sampler1DArrayShadow",
3540 "sampler2DArrayShadow",
3554 "sampler2DRectShadow",
3564 "isampler2DMSArray",
3565 "usampler2DMSArray",
3567 "samplerCubeArrayShadow",
3568 "isamplerCubeArray",
3569 "usamplerCubeArray",
3571 static const char* keywords_gl42[] = {
3663 "samplerCubeShadow",
3666 "sampler1DArrayShadow",
3667 "sampler2DArrayShadow",
3681 "sampler2DRectShadow",
3691 "isampler2DMSArray",
3692 "usampler2DMSArray",
3694 "samplerCubeArrayShadow",
3695 "isamplerCubeArray",
3696 "usamplerCubeArray",
3731 static const char* keywords_gl43[] = {
3826 "samplerCubeShadow",
3829 "sampler1DArrayShadow",
3830 "sampler2DArrayShadow",
3844 "sampler2DRectShadow",
3854 "isampler2DMSArray",
3855 "usampler2DMSArray",
3857 "samplerCubeArrayShadow",
3858 "isamplerCubeArray",
3859 "usamplerCubeArray",
3894 static const char* keywords_gl44[] = {
3989 "samplerCubeShadow",
3992 "sampler1DArrayShadow",
3993 "sampler2DArrayShadow",
4007 "sampler2DRectShadow",
4017 "isampler2DMSArray",
4018 "usampler2DMSArray",
4020 "samplerCubeArrayShadow",
4021 "isamplerCubeArray",
4022 "usamplerCubeArray",
4057 static const char* keywords_gl45[] = {
4152 "samplerCubeShadow",
4155 "sampler1DArrayShadow",
4156 "sampler2DArrayShadow",
4170 "sampler2DRectShadow",
4180 "isampler2DMSArray",
4181 "usampler2DMSArray",
4183 "samplerCubeArrayShadow",
4184 "isamplerCubeArray",
4185 "usamplerCubeArray",
4220 static const char* reserved_gl31[] = {
4281 "image1DArrayShadow",
4282 "image2DArrayShadow",
4292 static const char* reserved_gl32[] = {
4353 "image1DArrayShadow",
4354 "image2DArrayShadow",
4364 static const char* reserved_gl33[] = {
4425 "image1DArrayShadow",
4426 "image2DArrayShadow",
4436 static const char* reserved_gl40[] = {
4493 "image1DArrayShadow",
4494 "image2DArrayShadow",
4504 static const char* reserved_gl41[] = {
4561 "image1DArrayShadow",
4562 "image2DArrayShadow",
4572 static const char* reserved_gl42[] = {
4573 "common", "partition", "active", "asm", "class", "union", "enum", "typedef", "template",
4574 "this", "packed", "resource", "goto", "inline", "noinline", "public", "static", "extern",
4575 "external", "interface", "long", "short", "half", "fixed", "unsigned", "superp", "input",
4576 "output", "hvec2", "hvec3", "hvec4", "fvec2", "fvec3", "fvec4", "sampler3DRect", "filter",
4577 "sizeof", "cast", "namespace", "using", "row_major",
4579 static const char* reserved_gl43[] = {
4580 "common", "partition", "active", "asm", "class", "union", "enum", "typedef", "template",
4581 "this", "packed", "resource", "goto", "inline", "noinline", "public", "static", "extern",
4582 "external", "interface", "long", "short", "half", "fixed", "unsigned", "superp", "input",
4583 "output", "hvec2", "hvec3", "hvec4", "fvec2", "fvec3", "fvec4", "sampler3DRect", "filter",
4584 "sizeof", "cast", "namespace", "using", "row_major",
4586 static const char* reserved_gl44[] = {
4587 "common", "partition", "active", "asm", "class", "union", "enum", "typedef",
4588 "template", "this", "resource", "goto", "inline", "noinline", "public", "static",
4589 "extern", "external", "interface", "long", "short", "half", "fixed", "unsigned",
4590 "superp", "input", "output", "hvec2", "hvec3", "hvec4", "fvec2", "fvec3",
4591 "fvec4", "sampler3DRect", "filter", "sizeof", "cast", "namespace", "using",
4593 static const char* reserved_gl45[] = {
4594 "common", "partition", "active", "asm", "class", "union", "enum", "typedef",
4595 "template", "this", "resource", "goto", "inline", "noinline", "public", "static",
4596 "extern", "external", "interface", "long", "short", "half", "fixed", "unsigned",
4597 "superp", "input", "output", "hvec2", "hvec3", "hvec4", "fvec2", "fvec3",
4598 "fvec4", "sampler3DRect", "filter", "sizeof", "cast", "namespace", "using",
4601 glu::ApiType apiType = context_type.getAPI();
4602 if (apiType == glu::ApiType::core(3, 1))
4604 context_keywords = keywords_gl31;
4605 context_reserved = reserved_gl31;
4606 context_n_keywords = static_cast<unsigned int>(sizeof(keywords_gl31) / sizeof(keywords_gl31[0]));
4607 context_n_reserved = static_cast<unsigned int>(sizeof(reserved_gl31) / sizeof(reserved_gl31[0]));
4609 else if (apiType == glu::ApiType::core(3, 2))
4611 context_keywords = keywords_gl32;
4612 context_reserved = reserved_gl32;
4613 context_n_keywords = static_cast<unsigned int>(sizeof(keywords_gl32) / sizeof(keywords_gl32[0]));
4614 context_n_reserved = static_cast<unsigned int>(sizeof(reserved_gl32) / sizeof(reserved_gl32[0]));
4616 else if (apiType == glu::ApiType::core(3, 3))
4618 context_keywords = keywords_gl33;
4619 context_reserved = reserved_gl33;
4620 context_n_keywords = static_cast<unsigned int>(sizeof(keywords_gl33) / sizeof(keywords_gl33[0]));
4621 context_n_reserved = static_cast<unsigned int>(sizeof(reserved_gl33) / sizeof(reserved_gl33[0]));
4623 else if (apiType == glu::ApiType::core(4, 0))
4625 context_keywords = keywords_gl40;
4626 context_reserved = reserved_gl40;
4627 context_n_keywords = static_cast<unsigned int>(sizeof(keywords_gl40) / sizeof(keywords_gl40[0]));
4628 context_n_reserved = static_cast<unsigned int>(sizeof(reserved_gl40) / sizeof(reserved_gl40[0]));
4630 else if (apiType == glu::ApiType::core(4, 1))
4632 context_keywords = keywords_gl41;
4633 context_reserved = reserved_gl41;
4634 context_n_keywords = static_cast<unsigned int>(sizeof(keywords_gl41) / sizeof(keywords_gl41[0]));
4635 context_n_reserved = static_cast<unsigned int>(sizeof(reserved_gl41) / sizeof(reserved_gl41[0]));
4637 else if (apiType == glu::ApiType::core(4, 2))
4639 context_keywords = keywords_gl42;
4640 context_reserved = reserved_gl42;
4641 context_n_keywords = static_cast<unsigned int>(sizeof(keywords_gl42) / sizeof(keywords_gl42[0]));
4642 context_n_reserved = static_cast<unsigned int>(sizeof(reserved_gl42) / sizeof(reserved_gl42[0]));
4644 else if (apiType == glu::ApiType::core(4, 3))
4646 context_keywords = keywords_gl43;
4647 context_reserved = reserved_gl43;
4648 context_n_keywords = static_cast<unsigned int>(sizeof(keywords_gl43) / sizeof(keywords_gl43[0]));
4649 context_n_reserved = static_cast<unsigned int>(sizeof(reserved_gl43) / sizeof(reserved_gl43[0]));
4651 else if (apiType == glu::ApiType::core(4, 4))
4653 context_keywords = keywords_gl44;
4654 context_reserved = reserved_gl44;
4655 context_n_keywords = static_cast<unsigned int>(sizeof(keywords_gl44) / sizeof(keywords_gl44[0]));
4656 context_n_reserved = static_cast<unsigned int>(sizeof(reserved_gl44) / sizeof(reserved_gl44[0]));
4658 else if (apiType == glu::ApiType::core(4, 5))
4660 context_keywords = keywords_gl45;
4661 context_reserved = reserved_gl45;
4662 context_n_keywords = static_cast<unsigned int>(sizeof(keywords_gl45) / sizeof(keywords_gl45[0]));
4663 context_n_reserved = static_cast<unsigned int>(sizeof(reserved_gl45) / sizeof(reserved_gl45[0]));
4667 TCU_FAIL("Unsupported GL context version - please implement.");
4670 for (unsigned int n_current_context_keyword = 0; n_current_context_keyword < context_n_keywords;
4671 ++n_current_context_keyword)
4673 const char* current_context_keyword = context_keywords[n_current_context_keyword];
4675 result.push_back(current_context_keyword);
4676 } /* for (all context keywords) */
4678 for (unsigned int n_current_context_reserved = 0; n_current_context_reserved < context_n_reserved;
4679 ++n_current_context_reserved)
4681 const char* current_context_reserved = context_reserved[n_current_context_reserved];
4683 result.push_back(current_context_reserved);
4684 } /* for (all context reserved names) */
4690 /** Returns a shader body to use for the test. The body is formed, according to the user-specified
4693 * @param shader_type Shader stage the shader body should be returned for.
4694 * @param language_feature Language feature to test.
4695 * @param invalid_name Name to use for the language feature instance. The string should come
4696 * from the list of keywords or reserved names, specific to the currently
4697 * running rendering context's version.
4699 * @return Requested shader body.
4701 std::string ReservedNamesTest::getShaderBody(_shader_type shader_type, _language_feature language_feature,
4702 const char* invalid_name) const
4704 std::stringstream body_sstream;
4705 const glu::ContextType context_type = m_context.getRenderContext().getType();
4707 /* Preamble: shader language version */
4708 body_sstream << "#version ";
4710 glu::ApiType apiType = context_type.getAPI();
4711 if (apiType == glu::ApiType::core(3, 1))
4712 body_sstream << "140";
4713 else if (apiType == glu::ApiType::core(3, 2))
4714 body_sstream << "150";
4715 else if (apiType == glu::ApiType::core(3, 3))
4716 body_sstream << "330";
4717 else if (apiType == glu::ApiType::core(4, 0))
4718 body_sstream << "400";
4719 else if (apiType == glu::ApiType::core(4, 1))
4720 body_sstream << "410";
4721 else if (apiType == glu::ApiType::core(4, 2))
4722 body_sstream << "420";
4723 else if (apiType == glu::ApiType::core(4, 3))
4724 body_sstream << "430";
4725 else if (apiType == glu::ApiType::core(4, 4))
4726 body_sstream << "440";
4727 else if (apiType == glu::ApiType::core(4, 5))
4728 body_sstream << "450";
4731 TCU_FAIL("Unsupported GL context version - please implement");
4734 body_sstream << "\n\n";
4736 /* Preamble: layout qualifiers - required for CS, TC and TE shader stages */
4737 if (shader_type == SHADER_TYPE_COMPUTE)
4739 body_sstream << "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n";
4741 else if (shader_type == SHADER_TYPE_TESS_CONTROL)
4743 body_sstream << "layout(vertices = 3) out;\n";
4745 else if (shader_type == SHADER_TYPE_TESS_EVALUATION)
4747 body_sstream << "layout(triangles) in;\n";
4750 body_sstream << "\n\n";
4752 /* Language feature: insert incorrectly named atomic counter declaration if needed */
4753 if (language_feature == LANGUAGE_FEATURE_ATOMIC_COUNTER)
4755 body_sstream << "layout(binding = 0, offset = 0) uniform atomic_uint " << invalid_name << ";\n";
4758 /* Language feature: insert incorrectly named attribute declaration if needed */
4759 if (language_feature == LANGUAGE_FEATURE_ATTRIBUTE)
4761 body_sstream << "attribute vec4 " << invalid_name << ";\n";
4764 /* Language feature: insert incorrectly name constant declaration if needed */
4765 if (language_feature == LANGUAGE_FEATURE_CONSTANT)
4767 body_sstream << "const vec4 " << invalid_name << " = vec4(2.0, 3.0, 4.0, 5.0);\n";
4770 /* Language feature: insert a function with incorrectly named argument if needed */
4771 if (language_feature == LANGUAGE_FEATURE_FUNCTION_ARGUMENT_NAME)
4773 body_sstream << "void test(in vec4 " << invalid_name << ")\n"
4778 /* Language feature: insert incorrectly named function if needed */
4779 if (language_feature == LANGUAGE_FEATURE_FUNCTION_NAME)
4781 body_sstream << "void " << invalid_name << "(in vec4 test)\n"
4786 /* Language feature: insert incorrectly named input variable if needed */
4787 if (language_feature == LANGUAGE_FEATURE_INPUT)
4789 body_sstream << "in vec4 " << invalid_name;
4791 if (shader_type == SHADER_TYPE_GEOMETRY || shader_type == SHADER_TYPE_TESS_CONTROL ||
4792 shader_type == SHADER_TYPE_TESS_EVALUATION)
4794 body_sstream << "[]";
4797 body_sstream << ";\n";
4800 /* Language feature: insert declaration of an incorrectly named input block instance if needed */
4801 if (language_feature == LANGUAGE_FEATURE_INPUT_BLOCK_INSTANCE_NAME)
4803 body_sstream << "in testBlock\n"
4809 if (shader_type == SHADER_TYPE_GEOMETRY || shader_type == SHADER_TYPE_TESS_CONTROL ||
4810 shader_type == SHADER_TYPE_TESS_EVALUATION)
4812 body_sstream << "[]";
4815 body_sstream << ";\n";
4818 /* Language feature: insert declaration of an input block holding an incorrectly named member variable */
4819 if (language_feature == LANGUAGE_FEATURE_INPUT_BLOCK_MEMBER_NAME)
4821 body_sstream << "in testBlock\n"
4824 << invalid_name << ";\n"
4825 "} testBlockInstance";
4827 if (shader_type == SHADER_TYPE_GEOMETRY || shader_type == SHADER_TYPE_TESS_CONTROL ||
4828 shader_type == SHADER_TYPE_TESS_EVALUATION)
4830 body_sstream << "[]";
4833 body_sstream << ";\n";
4836 /* Language feature: insert declaration of an incorrectly named input block */
4837 if (language_feature == LANGUAGE_FEATURE_INPUT_BLOCK_NAME)
4839 body_sstream << "in " << invalid_name << "\n"
4842 "} testBlockInstance";
4844 if (shader_type == SHADER_TYPE_GEOMETRY || shader_type == SHADER_TYPE_TESS_CONTROL ||
4845 shader_type == SHADER_TYPE_TESS_EVALUATION)
4847 body_sstream << "[]";
4850 body_sstream << ";\n";
4853 /* Language feature: insert incorrectly named output variable if needed */
4854 if (language_feature == LANGUAGE_FEATURE_OUTPUT)
4856 body_sstream << "out vec4 " << invalid_name;
4858 if (shader_type == SHADER_TYPE_TESS_CONTROL)
4860 body_sstream << "[]";
4863 body_sstream << ";\n";
4866 /* Language feature: insert declaration of an incorrectly named output block instance if needed */
4867 if (language_feature == LANGUAGE_FEATURE_OUTPUT_BLOCK_INSTANCE_NAME)
4869 body_sstream << "out testBlock\n"
4875 if (shader_type == SHADER_TYPE_TESS_CONTROL)
4877 body_sstream << "[]";
4880 body_sstream << ";\n";
4883 /* Language feature: insert declaration of an output block holding an incorrectly named member variable */
4884 if (language_feature == LANGUAGE_FEATURE_OUTPUT_BLOCK_MEMBER_NAME)
4886 body_sstream << "out testBlock\n"
4889 << invalid_name << ";\n"
4890 "} testBlockInstance";
4892 if (shader_type == SHADER_TYPE_TESS_CONTROL)
4894 body_sstream << "[]";
4897 body_sstream << ";\n";
4900 /* Language feature: insert declaration of an incorrectly named output block */
4901 if (language_feature == LANGUAGE_FEATURE_OUTPUT_BLOCK_NAME)
4903 body_sstream << "out " << invalid_name << "\n"
4906 "} testBlockInstance";
4908 if (shader_type == SHADER_TYPE_TESS_CONTROL)
4910 body_sstream << "[]";
4913 body_sstream << ";\n";
4916 /* Language feature: insert declaration of an incorrectly named shader storage block instance if needed */
4917 if (language_feature == LANGUAGE_FEATURE_SHADER_STORAGE_BLOCK_INSTANCE_NAME)
4919 body_sstream << "buffer testBlock\n"
4923 << invalid_name << ";\n";
4926 /* Language feature: insert declaration of a shader storage block holding an incorrectly named member variable */
4927 if (language_feature == LANGUAGE_FEATURE_SHADER_STORAGE_BLOCK_MEMBER_NAME)
4929 body_sstream << "buffer testBlock\n"
4932 << invalid_name << ";\n"
4936 /* Language feature: insert declaration of an incorrectly named shader storage block */
4937 if (language_feature == LANGUAGE_FEATURE_SHADER_STORAGE_BLOCK_NAME)
4939 body_sstream << "buffer " << invalid_name << "\n"
4945 /* Language feature: insert declaration of a subroutine function with invalid name */
4946 if (language_feature == LANGUAGE_FEATURE_SUBROUTINE_FUNCTION_NAME)
4948 body_sstream << "subroutine void exampleSubroutine(inout vec4 " << invalid_name
4951 "subroutine (exampleSubroutine) void invert(inout vec4 "
4952 << invalid_name << ")\n"
4955 << invalid_name << " += vec4(0.0, 1.0, 2.0, 3.0);\n"
4958 "subroutine uniform exampleSubroutine testSubroutine;\n";
4961 /* Language feature: insert declaration of a subroutine of incorrectly named type */
4962 if (language_feature == LANGUAGE_FEATURE_SUBROUTINE_TYPE)
4964 body_sstream << "subroutine void " << invalid_name << "(inout vec4 arg);\n"
4967 << invalid_name << ") void invert(inout vec4 arg)\n"
4969 " arg += vec4(0.0, 1.0, 2.0, 3.0);\n"
4972 "subroutine uniform "
4973 << invalid_name << " testSubroutine;\n";
4976 /* Language feature: insert declaration of a subroutine, followed by a declaration of
4977 * an incorrectly named subroutine uniform.
4979 if (language_feature == LANGUAGE_FEATURE_SUBROUTINE_UNIFORM)
4981 body_sstream << "subroutine void exampleSubroutine(inout vec4 arg);\n"
4983 "subroutine (exampleSubroutine) void invert(inout vec4 arg)\n"
4985 " arg += vec4(0.0, 1.0, 2.0, 3.0);\n"
4988 "subroutine uniform exampleSubroutine "
4989 << invalid_name << ";\n";
4992 /* Language feature: insert declaration of an incorrectly named uniform. */
4993 if (language_feature == LANGUAGE_FEATURE_UNIFORM)
4995 body_sstream << "uniform sampler2D " << invalid_name << ";\n";
4998 /* Language feature: insert declaration of an incorrectly named uniform block instance if needed */
4999 if (language_feature == LANGUAGE_FEATURE_UNIFORM_BLOCK_INSTANCE_NAME)
5001 body_sstream << "uniform testBlock\n"
5005 << invalid_name << ";\n";
5008 /* Language feature: insert declaration of an uniform block holding an incorrectly named member variable */
5009 if (language_feature == LANGUAGE_FEATURE_UNIFORM_BLOCK_MEMBER_NAME)
5011 body_sstream << "uniform testBlock\n"
5014 << invalid_name << ";\n"
5018 /* Language feature: insert declaration of an incorrectly named uniform block */
5019 if (language_feature == LANGUAGE_FEATURE_UNIFORM_BLOCK_NAME)
5021 body_sstream << "uniform " << invalid_name << "\n"
5027 /* Language feature: insert declaration of an incorrectly named varying */
5028 if (language_feature == LANGUAGE_FEATURE_VARYING)
5030 body_sstream << "varying vec4 " << invalid_name << ";\n";
5033 /* Start implementation of the main entry-point. */
5034 body_sstream << "void main()\n"
5037 /* Language feature: insert declaration of an incorrectly named shared variable. */
5038 if (language_feature == LANGUAGE_FEATURE_SHARED_VARIABLE)
5040 body_sstream << "shared vec4 " << invalid_name << ";\n";
5043 /* Language feature: insert declaration of a structure, whose instance name is incorrect */
5044 if (language_feature == LANGUAGE_FEATURE_STRUCTURE_INSTANCE_NAME)
5046 body_sstream << "struct\n"
5050 << invalid_name << ";\n";
5053 /* Language feature: insert declaration of a structure with one of its member variables being incorrectly named. */
5054 if (language_feature == LANGUAGE_FEATURE_STRUCTURE_MEMBER)
5056 body_sstream << "struct\n"
5059 << invalid_name << ";\n"
5060 "} testInstance;\n";
5063 /* Language feature: insert declaration of a structure whose name is incorrect */
5064 if (language_feature == LANGUAGE_FEATURE_STRUCTURE_NAME)
5066 body_sstream << "struct " << invalid_name << "{\n"
5071 /* Language feature: insert declaration of a variable with incorrect name. */
5072 if (language_feature == LANGUAGE_FEATURE_VARIABLE)
5074 body_sstream << "vec4 " << invalid_name << ";\n";
5077 /* Close the main entry-point implementation */
5078 body_sstream << "}\n";
5080 return body_sstream.str();
5083 /** Retrieves a literal corresponding to the user-specified shader type value.
5085 * @param shader_type Enum to return the string for.
5087 * @return As specified.
5089 std::string ReservedNamesTest::getShaderTypeName(_shader_type shader_type) const
5091 std::string result = "[?!]";
5093 switch (shader_type)
5095 case SHADER_TYPE_COMPUTE:
5096 result = "compute shader";
5098 case SHADER_TYPE_FRAGMENT:
5099 result = "fragment shader";
5101 case SHADER_TYPE_GEOMETRY:
5102 result = "geometry shader";
5104 case SHADER_TYPE_TESS_CONTROL:
5105 result = "tessellation control shader";
5107 case SHADER_TYPE_TESS_EVALUATION:
5108 result = "tessellation evaluation shader";
5110 case SHADER_TYPE_VERTEX:
5111 result = "vertex shader";
5116 } /* switch (shader_type) */
5121 /** Returns a vector of _language_feature enums, telling which language features are supported, given running context's
5122 * version and shader type, in which the features are planned to be used.
5124 * @param shader_type Shader stage the language features will be used in.
5126 * @return As specified.
5128 std::vector<ReservedNamesTest::_language_feature> ReservedNamesTest::getSupportedLanguageFeatures(
5129 _shader_type shader_type) const
5131 const glu::ContextType context_type = m_context.getRenderContext().getType();
5132 std::vector<_language_feature> result;
5134 /* Atomic counters are available, starting with GL 4.2. Availability for each shader stage
5135 * depends on the reported GL constant values, apart from CS & FS, for which AC support is guaranteed.
5137 if (glu::contextSupports(context_type, glu::ApiType::core(4, 2)))
5139 if (shader_type == SHADER_TYPE_COMPUTE || shader_type == SHADER_TYPE_FRAGMENT ||
5140 (shader_type == SHADER_TYPE_GEOMETRY && m_max_gs_acs > 0) ||
5141 (shader_type == SHADER_TYPE_TESS_CONTROL && m_max_tc_acs > 0) ||
5142 (shader_type == SHADER_TYPE_TESS_EVALUATION && m_max_te_acs > 0) ||
5143 (shader_type == SHADER_TYPE_VERTEX && m_max_vs_acs))
5145 result.push_back(LANGUAGE_FEATURE_ATOMIC_COUNTER);
5147 } /* if (context_type >= glu::CONTEXTTYPE_GL43_CORE) */
5149 /* Attributes are only supported until GL 4.1, for VS shader stage only. */
5150 if (shader_type == SHADER_TYPE_VERTEX && !glu::contextSupports(context_type, glu::ApiType::core(4, 2)))
5152 result.push_back(LANGUAGE_FEATURE_ATTRIBUTE);
5155 /* Constants are always supported */
5156 result.push_back(LANGUAGE_FEATURE_CONSTANT);
5158 /* Functions are supported in all GL SL versions for all shader types. */
5159 result.push_back(LANGUAGE_FEATURE_FUNCTION_ARGUMENT_NAME);
5160 result.push_back(LANGUAGE_FEATURE_FUNCTION_NAME);
5162 /* Inputs are supported in all GL SL versions for FS, GS, TC, TE and VS stages */
5163 if (shader_type == SHADER_TYPE_FRAGMENT || shader_type == SHADER_TYPE_GEOMETRY ||
5164 shader_type == SHADER_TYPE_TESS_CONTROL || shader_type == SHADER_TYPE_TESS_EVALUATION ||
5165 shader_type == SHADER_TYPE_VERTEX)
5167 result.push_back(LANGUAGE_FEATURE_INPUT);
5170 /* Input blocks are available, starting with GL 3.2 for FS, GS, TC and TE stages. */
5171 if ((shader_type == SHADER_TYPE_FRAGMENT || shader_type == SHADER_TYPE_GEOMETRY ||
5172 shader_type == SHADER_TYPE_TESS_CONTROL || shader_type == SHADER_TYPE_TESS_EVALUATION ||
5173 shader_type == SHADER_TYPE_VERTEX) &&
5174 glu::contextSupports(context_type, glu::ApiType::core(3, 2)))
5176 result.push_back(LANGUAGE_FEATURE_INPUT_BLOCK_INSTANCE_NAME);
5177 result.push_back(LANGUAGE_FEATURE_INPUT_BLOCK_MEMBER_NAME);
5178 result.push_back(LANGUAGE_FEATURE_INPUT_BLOCK_NAME);
5181 /* Outputs are supported in all GL SL versions for all shader stages expect CS */
5182 if (shader_type != SHADER_TYPE_COMPUTE)
5184 result.push_back(LANGUAGE_FEATURE_OUTPUT);
5187 /* Output blocks are available, starting with GL 3.2 for GS, TC, TE and VS stages. */
5188 if ((shader_type == SHADER_TYPE_GEOMETRY || shader_type == SHADER_TYPE_TESS_CONTROL ||
5189 shader_type == SHADER_TYPE_TESS_EVALUATION || shader_type == SHADER_TYPE_VERTEX) &&
5190 glu::contextSupports(context_type, glu::ApiType::core(3, 2)))
5192 result.push_back(LANGUAGE_FEATURE_OUTPUT_BLOCK_INSTANCE_NAME);
5193 result.push_back(LANGUAGE_FEATURE_OUTPUT_BLOCK_MEMBER_NAME);
5194 result.push_back(LANGUAGE_FEATURE_OUTPUT_BLOCK_NAME);
5197 /* Shader storage blocks are available, starting with GL 4.3. Availability for each shader stage
5198 * depends on the reported GL constant values, apart from CS, for which SSBO support is guaranteed.
5200 if (glu::contextSupports(context_type, glu::ApiType::core(4, 3)))
5202 if (shader_type == SHADER_TYPE_COMPUTE || (shader_type == SHADER_TYPE_FRAGMENT && m_max_fs_ssbos > 0) ||
5203 (shader_type == SHADER_TYPE_GEOMETRY && m_max_gs_ssbos > 0) ||
5204 (shader_type == SHADER_TYPE_TESS_CONTROL && m_max_tc_ssbos > 0) ||
5205 (shader_type == SHADER_TYPE_TESS_EVALUATION && m_max_te_ssbos > 0) ||
5206 (shader_type == SHADER_TYPE_VERTEX && m_max_vs_ssbos))
5208 result.push_back(LANGUAGE_FEATURE_SHADER_STORAGE_BLOCK_INSTANCE_NAME);
5209 result.push_back(LANGUAGE_FEATURE_SHADER_STORAGE_BLOCK_MEMBER_NAME);
5210 result.push_back(LANGUAGE_FEATURE_SHADER_STORAGE_BLOCK_NAME);
5212 } /* if (context_type >= glu::CONTEXTTYPE_GL43_CORE) */
5214 /* Shared variables are only supported for compute shaders */
5215 if (shader_type == SHADER_TYPE_COMPUTE)
5217 result.push_back(LANGUAGE_FEATURE_SHARED_VARIABLE);
5220 /* Structures are available everywhere, and so are structures. */
5221 result.push_back(LANGUAGE_FEATURE_STRUCTURE_INSTANCE_NAME);
5222 result.push_back(LANGUAGE_FEATURE_STRUCTURE_MEMBER);
5223 result.push_back(LANGUAGE_FEATURE_STRUCTURE_NAME);
5225 /* Subroutines are available, starting with GL 4.0, for all shader stages except CS */
5226 if (glu::contextSupports(context_type, glu::ApiType::core(4, 0)))
5228 if (shader_type != SHADER_TYPE_COMPUTE)
5230 result.push_back(LANGUAGE_FEATURE_SUBROUTINE_FUNCTION_NAME);
5231 result.push_back(LANGUAGE_FEATURE_SUBROUTINE_TYPE);
5232 result.push_back(LANGUAGE_FEATURE_SUBROUTINE_UNIFORM);
5234 } /* if (context_type >= glu::CONTEXTTYPE_GL40_CORE) */
5236 /* Uniform blocks and uniforms are available everywhere, for all shader stages except CS */
5237 if (shader_type != SHADER_TYPE_COMPUTE)
5239 result.push_back(LANGUAGE_FEATURE_UNIFORM_BLOCK_INSTANCE_NAME);
5240 result.push_back(LANGUAGE_FEATURE_UNIFORM_BLOCK_MEMBER_NAME);
5241 result.push_back(LANGUAGE_FEATURE_UNIFORM_BLOCK_NAME);
5243 result.push_back(LANGUAGE_FEATURE_UNIFORM);
5246 /* Variables are available, well, everywhere. */
5247 result.push_back(LANGUAGE_FEATURE_VARIABLE);
5249 /* Varyings are supported until GL 4.2 for FS and VS shader stages. Starting with GL 4.3,
5250 * they are no longer legal. */
5251 if ((shader_type == SHADER_TYPE_FRAGMENT || shader_type == SHADER_TYPE_VERTEX) &&
5252 !glu::contextSupports(context_type, glu::ApiType::core(4, 3)))
5254 result.push_back(LANGUAGE_FEATURE_VARYING);
5260 /** Returns a vector of _shader_type enums, telling which shader stages are supported
5261 * under running rendering context. For simplicity, the function ignores any extensions
5262 * which extend the core functionality
5264 * @return As specified.
5266 std::vector<ReservedNamesTest::_shader_type> ReservedNamesTest::getSupportedShaderTypes() const
5268 const glu::ContextType context_type = m_context.getRenderContext().getType();
5269 std::vector<_shader_type> result;
5271 /* CS: Available, starting with GL 4.3 */
5272 if (glu::contextSupports(context_type, glu::ApiType::core(4, 3)))
5274 result.push_back(SHADER_TYPE_COMPUTE);
5277 /* FS: Always supported */
5278 result.push_back(SHADER_TYPE_FRAGMENT);
5280 /* GS: Available, starting with GL 3.2 */
5281 if (glu::contextSupports(context_type, glu::ApiType::core(3, 2)))
5283 result.push_back(SHADER_TYPE_GEOMETRY);
5286 /* TC: Available, starting with GL 4.0 */
5287 /* TE: Available, starting with GL 4.0 */
5288 if (glu::contextSupports(context_type, glu::ApiType::core(4, 0)))
5290 result.push_back(SHADER_TYPE_TESS_CONTROL);
5291 result.push_back(SHADER_TYPE_TESS_EVALUATION);
5294 /* VS: Always supported */
5295 result.push_back(SHADER_TYPE_VERTEX);
5300 bool ReservedNamesTest::isStructAllowed(_shader_type shader_type, _language_feature language_feature) const
5302 bool structAllowed = false;
5304 if (language_feature == LANGUAGE_FEATURE_UNIFORM || language_feature == LANGUAGE_FEATURE_UNIFORM_BLOCK_NAME)
5309 switch (shader_type)
5311 case SHADER_TYPE_FRAGMENT:
5313 if (language_feature == LANGUAGE_FEATURE_INPUT_BLOCK_NAME)
5315 structAllowed = true;
5319 case SHADER_TYPE_GEOMETRY:
5320 case SHADER_TYPE_TESS_CONTROL:
5321 case SHADER_TYPE_TESS_EVALUATION:
5323 if (language_feature == LANGUAGE_FEATURE_OUTPUT_BLOCK_NAME)
5325 structAllowed = true;
5327 else if (language_feature == LANGUAGE_FEATURE_INPUT_BLOCK_NAME)
5329 structAllowed = true;
5333 case SHADER_TYPE_VERTEX:
5335 if (language_feature == LANGUAGE_FEATURE_OUTPUT_BLOCK_NAME)
5337 structAllowed = true;
5341 case SHADER_TYPE_COMPUTE:
5346 return structAllowed;
5349 /** Dummy init function */
5350 void ReservedNamesTest::init()
5352 /* Left blank on purpose */
5355 /** Executes test iteration.
5357 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
5359 tcu::TestNode::IterateResult ReservedNamesTest::iterate()
5361 glw::GLint compile_status = GL_TRUE;
5362 glu::ContextType context_type = m_context.getRenderContext().getType();
5363 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5364 std::vector<_language_feature> language_features;
5365 std::vector<std::string> reserved_names;
5367 std::vector<_shader_type> shader_types;
5369 /* Retrieve important GL constant values */
5370 if (glu::contextSupports(context_type, glu::ApiType::core(4, 2)))
5372 gl.getIntegerv(GL_MAX_GEOMETRY_ATOMIC_COUNTERS, &m_max_gs_acs);
5373 gl.getIntegerv(GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS, &m_max_tc_acs);
5374 gl.getIntegerv(GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS, &m_max_te_acs);
5375 gl.getIntegerv(GL_MAX_VERTEX_ATOMIC_COUNTERS, &m_max_vs_acs);
5378 if (glu::contextSupports(context_type, glu::ApiType::core(4, 3)))
5380 gl.getIntegerv(GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, &m_max_fs_ssbos);
5381 gl.getIntegerv(GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS, &m_max_gs_ssbos);
5382 gl.getIntegerv(GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS, &m_max_tc_ssbos);
5383 gl.getIntegerv(GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS, &m_max_te_ssbos);
5384 gl.getIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &m_max_vs_ssbos);
5386 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() call(s) failed.");
5389 /* Create the shader objects */
5390 if (glu::contextSupports(context_type, glu::ApiType::core(4, 0)))
5392 m_so_ids[SHADER_TYPE_TESS_CONTROL] = gl.createShader(GL_TESS_CONTROL_SHADER);
5393 m_so_ids[SHADER_TYPE_TESS_EVALUATION] = gl.createShader(GL_TESS_EVALUATION_SHADER);
5396 if (glu::contextSupports(context_type, glu::ApiType::core(4, 3)))
5398 m_so_ids[SHADER_TYPE_COMPUTE] = gl.createShader(GL_COMPUTE_SHADER);
5401 m_so_ids[SHADER_TYPE_FRAGMENT] = gl.createShader(GL_FRAGMENT_SHADER);
5402 m_so_ids[SHADER_TYPE_GEOMETRY] = gl.createShader(GL_GEOMETRY_SHADER);
5403 m_so_ids[SHADER_TYPE_VERTEX] = gl.createShader(GL_VERTEX_SHADER);
5405 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed.");
5407 /* Retrieve context version-specific data */
5408 reserved_names = getReservedNames();
5409 shader_types = getSupportedShaderTypes();
5411 /* Iterate over all supported shader stages.. */
5412 for (std::vector<_shader_type>::const_iterator shader_type_it = shader_types.begin();
5413 shader_type_it != shader_types.end(); ++shader_type_it)
5415 _shader_type current_shader_type = *shader_type_it;
5417 if (m_so_ids[current_shader_type] == 0)
5419 /* Skip stages not supported by the currently running context version. */
5423 language_features = getSupportedLanguageFeatures(current_shader_type);
5425 /* ..and all language features we can test for the running context */
5426 for (std::vector<_language_feature>::const_iterator language_feature_it = language_features.begin();
5427 language_feature_it != language_features.end(); ++language_feature_it)
5429 _language_feature current_language_feature = *language_feature_it;
5431 bool structAllowed = isStructAllowed(current_shader_type, current_language_feature);
5433 /* Finally, all the reserved names we need to test - loop over them at this point */
5434 for (std::vector<std::string>::const_iterator reserved_name_it = reserved_names.begin();
5435 reserved_name_it != reserved_names.end(); ++reserved_name_it)
5437 std::string current_invalid_name = *reserved_name_it;
5438 std::string so_body_string;
5439 const char* so_body_string_raw = NULL;
5441 // There are certain shader types that allow struct for in/out declarations
5442 if (structAllowed && current_invalid_name.compare("struct") == 0)
5447 /* Form the shader body */
5449 getShaderBody(current_shader_type, current_language_feature, current_invalid_name.c_str());
5450 so_body_string_raw = so_body_string.c_str();
5452 /* Try to compile the shader */
5453 gl.shaderSource(m_so_ids[current_shader_type], 1, /* count */
5454 &so_body_string_raw, NULL); /* length */
5455 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
5457 gl.compileShader(m_so_ids[current_shader_type]);
5458 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed.");
5460 gl.getShaderiv(m_so_ids[current_shader_type], GL_COMPILE_STATUS, &compile_status);
5461 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");
5463 /* Left for the debugging purposes for those in need .. */
5467 gl.getShaderInfoLog(m_so_ids[current_shader_type],
5472 m_testCtx.getLog() << tcu::TestLog::Message
5474 "-----------------------------\n"
5477 << so_body_string_raw
5484 << tcu::TestLog::EndMessage;
5487 if (compile_status != GL_FALSE)
5489 m_testCtx.getLog() << tcu::TestLog::Message << "A "
5490 << getLanguageFeatureName(current_language_feature) << " named ["
5491 << current_invalid_name << "]"
5492 << ", defined in " << getShaderTypeName(current_shader_type)
5493 << ", was accepted by the compiler, "
5494 "which is prohibited by the spec. Offending source code:\n"
5496 << so_body_string_raw << "\n<<\n\n"
5497 << tcu::TestLog::EndMessage;
5502 } /* for (all reserved names for the current context) */
5503 } /* for (all language features supported by the context) */
5504 } /* for (all shader types supported by the context) */
5506 m_testCtx.setTestResult(result ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, result ? "Pass" : "Fail");
5513 * @param context Rendering context
5514 * @param name Test name
5515 * @param description Test description
5517 SparseBuffersWithCopyOpsTest::SparseBuffersWithCopyOpsTest(deqp::Context& context)
5518 : TestCase(context, "CommonBug_SparseBuffersWithCopyOps",
5519 "Verifies sparse buffer functionality works correctly when CPU->GPU and GPU->GPU"
5520 " memory transfers are involved.")
5523 , m_clear_buffer(DE_NULL)
5525 , m_result_data_storage_size(0)
5526 , m_n_iterations_to_run(16)
5527 , m_n_pages_to_test(16)
5528 , m_virtual_bo_size(512 /* MB */ * 1024768)
5530 for (unsigned int n = 0; n < sizeof(m_reference_data) / sizeof(m_reference_data[0]); ++n)
5532 m_reference_data[n] = static_cast<unsigned char>(n);
5536 /** Deinitializes all GL objects created for the purpose of running the test,
5537 * as well as any client-side buffers allocated at initialization time
5539 void SparseBuffersWithCopyOpsTest::deinit()
5541 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5545 gl.deleteBuffers(1, &m_bo_id);
5550 if (m_bo_read_id != 0)
5552 gl.deleteBuffers(1, &m_bo_read_id);
5557 if (m_clear_buffer != DE_NULL)
5559 delete[] m_clear_buffer;
5561 m_clear_buffer = DE_NULL;
5565 /** Dummy init function */
5566 void SparseBuffersWithCopyOpsTest::init()
5568 /* Nothing to do here */
5571 /** Initializes all buffers and GL objects required to run the test. */
5572 bool SparseBuffersWithCopyOpsTest::initTest()
5574 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5577 /* Retrieve the platform-specific page size */
5578 gl.getIntegerv(GL_SPARSE_BUFFER_PAGE_SIZE_ARB, &m_page_size);
5580 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_SPARSE_BUFFER_PAGE_SIZE_ARB query");
5582 /* Retrieve the func ptr */
5583 if (gl.bufferPageCommitmentARB == NULL)
5585 m_testCtx.getLog() << tcu::TestLog::Message
5586 << "Could not retrieve function pointer for the glBufferPageCommitmentARB() entry-point."
5587 << tcu::TestLog::EndMessage;
5593 /* Set up the test sparse buffer object */
5594 gl.genBuffers(1, &m_bo_id);
5595 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed.");
5597 gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_id);
5598 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed.");
5600 gl.bufferStorage(GL_ARRAY_BUFFER, m_virtual_bo_size, DE_NULL, /* data */
5601 GL_DYNAMIC_STORAGE_BIT | GL_SPARSE_STORAGE_BIT_ARB);
5602 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferStorage() call failed.");
5604 /* Set up the buffer object that will be used to read the result data */
5605 m_result_data_storage_size = static_cast<unsigned int>(
5606 (m_page_size * m_n_pages_to_test / sizeof(m_reference_data)) * sizeof(m_reference_data));
5607 m_clear_buffer = new unsigned char[m_result_data_storage_size];
5609 memset(m_clear_buffer, 0, m_result_data_storage_size);
5611 gl.genBuffers(1, &m_bo_read_id);
5612 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed.");
5614 gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_bo_read_id);
5615 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed.");
5617 gl.bufferStorage(GL_ELEMENT_ARRAY_BUFFER, m_result_data_storage_size, NULL, /* data */
5618 GL_DYNAMIC_STORAGE_BIT | GL_MAP_READ_BIT);
5619 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferStorage() call failed.");
5625 /** Executes test iteration.
5627 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
5629 tcu::TestNode::IterateResult SparseBuffersWithCopyOpsTest::iterate()
5633 /* Execute the test */
5634 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5636 /* Only execute if we're dealing with an OpenGL implementation which supports both:
5638 * 1. GL_ARB_sparse_buffer extension
5639 * 2. GL_ARB_buffer_storage extension
5641 if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_buffer") ||
5642 !m_context.getContextInfo().isExtensionSupported("GL_ARB_buffer_storage"))
5647 /* Set up the test objects */
5654 for (unsigned int n_test_case = 0; n_test_case < 2; ++n_test_case)
5656 for (unsigned int n_iteration = 0; n_iteration < m_n_iterations_to_run; ++n_iteration)
5658 if (n_iteration != 0)
5660 gl.bufferPageCommitmentARB(GL_ARRAY_BUFFER, 0, /* offset */
5661 m_n_pages_to_test * m_page_size, GL_FALSE);
5662 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferPageCommitmentARB() call failed.");
5665 gl.bufferPageCommitmentARB(GL_ARRAY_BUFFER, 0, /* offset */
5666 m_page_size, GL_TRUE);
5667 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferPageCommitmentARB() call failed.");
5669 gl.bufferSubData(GL_ARRAY_BUFFER, 0, /* offset */
5670 sizeof(m_reference_data), m_reference_data);
5671 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferSubData() call failed.");
5673 for (unsigned int n_page = 0; n_page < m_n_pages_to_test; ++n_page)
5675 /* Try committing pages in a redundant manner. This is a legal behavior in light of
5676 * the GL_ARB_sparse_buffer spec */
5677 gl.bufferPageCommitmentARB(GL_ARRAY_BUFFER, n_page * m_page_size, m_page_size, GL_TRUE);
5678 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferPageCommitmentARB() call failed.");
5680 for (int copy_dst_page_offset = static_cast<int>((n_page == 0) ? sizeof(m_reference_data) : 0);
5681 copy_dst_page_offset < static_cast<int>(m_page_size);
5682 copy_dst_page_offset += static_cast<int>(sizeof(m_reference_data)))
5684 const int copy_src_page_offset =
5685 static_cast<const int>(copy_dst_page_offset - sizeof(m_reference_data));
5687 switch (n_test_case)
5691 gl.copyBufferSubData(GL_ARRAY_BUFFER, GL_ARRAY_BUFFER,
5692 n_page * m_page_size + copy_src_page_offset,
5693 n_page * m_page_size + copy_dst_page_offset, sizeof(m_reference_data));
5694 GLU_EXPECT_NO_ERROR(gl.getError(), "glCopyBufferSubData() call failed.");
5701 gl.bufferSubData(GL_ARRAY_BUFFER, n_page * m_page_size + copy_dst_page_offset,
5702 sizeof(m_reference_data), m_reference_data);
5703 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferSubData() call failed.");
5709 TCU_FAIL("Unrecognized test case index");
5710 } /* switch (n_test_case) */
5711 } /* for (all valid destination copy op offsets) */
5712 } /* for (all test pages) */
5714 /* Copy data from the sparse buffer to a mappable immutable buffer storage */
5715 gl.copyBufferSubData(GL_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER, 0, /* readOffset */
5716 0, /* writeOffset */
5717 m_result_data_storage_size);
5718 GLU_EXPECT_NO_ERROR(gl.getError(), "glCopyBufferSubData() call failed.");
5720 /* Map the data we have obtained */
5721 char* mapped_data = (char*)gl.mapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, /* offset */
5722 m_page_size * m_n_pages_to_test, GL_MAP_READ_BIT);
5724 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange() call failed.");
5726 /* Verify the data is valid */
5727 for (unsigned int n_temp_copy = 0; n_temp_copy < m_result_data_storage_size / sizeof(m_reference_data);
5730 const unsigned int cmp_offset = static_cast<const unsigned int>(n_temp_copy * sizeof(m_reference_data));
5732 if (memcmp(mapped_data + cmp_offset, m_reference_data, sizeof(m_reference_data)) != 0)
5734 m_testCtx.getLog() << tcu::TestLog::Message << "Invalid data found for page index "
5736 << (cmp_offset / m_page_size) << "]"
5739 << cmp_offset << "]." << tcu::TestLog::EndMessage;
5744 } /* for (all datasets) */
5747 gl.unmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
5748 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer() call failed.");
5750 /* Also, zero out the other buffer object we copy the result data to, in case
5751 * the glCopyBufferSubData() call does not modify it at all */
5752 gl.bufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, /* offset */
5753 m_result_data_storage_size, m_clear_buffer);
5754 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferSubData() call failed.");
5756 /* NOTE: This test passes fine on the misbehaving driver *if* the swapbuffers operation
5757 * issued as a part of the call below is not executed. */
5758 m_context.getRenderContext().postIterate();
5759 } /* for (all test iterations) */
5760 } /* for (all test cases) */
5763 m_testCtx.setTestResult(result ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, result ? "Pass" : "Fail");
5770 * @param context Rendering context.
5772 CommonBugsTests::CommonBugsTests(deqp::Context& context)
5773 : TestCaseGroup(context, "CommonBugs", "Contains conformance tests that verify various pieces of functionality"
5774 " which were found broken in public drivers.")
5778 /** Initializes the test group contents. */
5779 void CommonBugsTests::init()
5781 addChild(new GetProgramivActiveUniformBlockMaxNameLengthTest(m_context));
5782 addChild(new InputVariablesCannotBeModifiedTest(m_context));
5783 addChild(new InvalidUseCasesForAllNotFuncsAndExclMarkOpTest(m_context));
5784 addChild(new InvalidVSInputsTest(m_context));
5785 addChild(new ParenthesisInLayoutQualifierIntegerValuesTest(m_context));
5786 addChild(new PerVertexValidationTest(m_context));
5787 addChild(new ReservedNamesTest(m_context));
5788 addChild(new SparseBuffersWithCopyOpsTest(m_context));
5790 } /* glcts namespace */