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 */ /*-------------------------------------------------------------------*/
25 * \file gl4cEnhancedLayoutsTests.cpp
26 * \brief Implements conformance tests for "Enhanced Layouts" functionality.
27 */ /*-------------------------------------------------------------------*/
29 #include "gl4cEnhancedLayoutsTests.hpp"
31 #include "gluContextInfo.hpp"
32 #include "gluDefs.hpp"
33 #include "gluStrUtil.hpp"
34 #include "glwEnums.hpp"
35 #include "glwFunctions.hpp"
36 #include "tcuTestLog.hpp"
45 #define DEBUG_ENBALE_MESSAGE_CALLBACK 0
46 #define DEBUG_NEG_LOG_ERROR 0
47 #define DEBUG_REPLACE_TOKEN 0
48 #define DEBUG_REPEAT_TEST_CASE 0
49 #define DEBUG_REPEATED_TEST_CASE 0
51 /* Texture test base */
52 #define DEBUG_TTB_VERIFICATION_SNIPPET_STAGE 0
53 #define DEBUG_TTB_VERIFICATION_SNIPPET_VARIABLE 0
56 #define DEBUG_VERTEX_ATTRIB_LOCATIONS_TEST_VARIABLE 0
59 #define WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST 0
60 #define WRKARD_UNIFORMBLOCKMEMBERALIGNNONPOWEROF2TEST 0
61 #define WRKARD_UNIFORMBLOCKALIGNMENT 0
62 #define WRKARD_VARYINGLOCATIONSTEST 0
68 namespace EnhancedLayouts
72 /** Constants used by "random" generators **/
73 static const GLuint s_rand_start = 3;
74 static const GLuint s_rand_max = 16;
75 static const GLuint s_rand_max_half = s_rand_max / 2;
77 /** Seed used by "random" generators **/
78 static GLuint s_rand = s_rand_start;
80 /** Get "random" unsigned int value
84 static GLuint GetRandUint()
86 const GLuint rand = s_rand++;
88 if (s_rand_max <= s_rand)
90 s_rand = s_rand_start;
96 /** Get "random" int value
102 const GLint rand = GetRandUint() - s_rand_max_half;
107 /** Get "random" double value
111 GLdouble GetRandDouble()
113 const GLint rand = GetRandInt();
115 GLdouble result = (GLfloat)rand / (GLdouble)s_rand_max_half;
120 /** Get "random" float value
124 GLfloat GetRandFloat()
126 const GLint rand = GetRandInt();
128 GLfloat result = (GLfloat)rand / (GLfloat)s_rand_max_half;
133 /** String used by list routines **/
134 static const GLchar* const g_list = "LIST";
136 /** Type constants **/
137 const Type Type::_double = Type::GetType(Type::Double, 1, 1);
138 const Type Type::dmat2 = Type::GetType(Type::Double, 2, 2);
139 const Type Type::dmat2x3 = Type::GetType(Type::Double, 2, 3);
140 const Type Type::dmat2x4 = Type::GetType(Type::Double, 2, 4);
141 const Type Type::dmat3x2 = Type::GetType(Type::Double, 3, 2);
142 const Type Type::dmat3 = Type::GetType(Type::Double, 3, 3);
143 const Type Type::dmat3x4 = Type::GetType(Type::Double, 3, 4);
144 const Type Type::dmat4x2 = Type::GetType(Type::Double, 4, 2);
145 const Type Type::dmat4x3 = Type::GetType(Type::Double, 4, 3);
146 const Type Type::dmat4 = Type::GetType(Type::Double, 4, 4);
147 const Type Type::dvec2 = Type::GetType(Type::Double, 1, 2);
148 const Type Type::dvec3 = Type::GetType(Type::Double, 1, 3);
149 const Type Type::dvec4 = Type::GetType(Type::Double, 1, 4);
150 const Type Type::_int = Type::GetType(Type::Int, 1, 1);
151 const Type Type::ivec2 = Type::GetType(Type::Int, 1, 2);
152 const Type Type::ivec3 = Type::GetType(Type::Int, 1, 3);
153 const Type Type::ivec4 = Type::GetType(Type::Int, 1, 4);
154 const Type Type::_float = Type::GetType(Type::Float, 1, 1);
155 const Type Type::mat2 = Type::GetType(Type::Float, 2, 2);
156 const Type Type::mat2x3 = Type::GetType(Type::Float, 2, 3);
157 const Type Type::mat2x4 = Type::GetType(Type::Float, 2, 4);
158 const Type Type::mat3x2 = Type::GetType(Type::Float, 3, 2);
159 const Type Type::mat3 = Type::GetType(Type::Float, 3, 3);
160 const Type Type::mat3x4 = Type::GetType(Type::Float, 3, 4);
161 const Type Type::mat4x2 = Type::GetType(Type::Float, 4, 2);
162 const Type Type::mat4x3 = Type::GetType(Type::Float, 4, 3);
163 const Type Type::mat4 = Type::GetType(Type::Float, 4, 4);
164 const Type Type::vec2 = Type::GetType(Type::Float, 1, 2);
165 const Type Type::vec3 = Type::GetType(Type::Float, 1, 3);
166 const Type Type::vec4 = Type::GetType(Type::Float, 1, 4);
167 const Type Type::uint = Type::GetType(Type::Uint, 1, 1);
168 const Type Type::uvec2 = Type::GetType(Type::Uint, 1, 2);
169 const Type Type::uvec3 = Type::GetType(Type::Uint, 1, 3);
170 const Type Type::uvec4 = Type::GetType(Type::Uint, 1, 4);
172 /** Generate data for type. This routine follows STD140 rules
174 * @return Vector of bytes filled with data
176 std::vector<GLubyte> Type::GenerateData() const
178 const GLuint alignment = GetActualAlignment(0, false);
180 std::vector<GLubyte> data;
181 data.resize(alignment * m_n_columns);
183 for (GLuint column = 0; column < m_n_columns; ++column)
185 GLvoid* ptr = (GLvoid*)&data[column * alignment];
187 switch (m_basic_type)
191 GLdouble* d_ptr = (GLdouble*)ptr;
193 for (GLuint i = 0; i < m_n_rows; ++i)
195 d_ptr[i] = GetRandDouble();
201 GLfloat* f_ptr = (GLfloat*)ptr;
203 for (GLuint i = 0; i < m_n_rows; ++i)
205 f_ptr[i] = GetRandFloat();
211 GLint* i_ptr = (GLint*)ptr;
213 for (GLuint i = 0; i < m_n_rows; ++i)
215 i_ptr[i] = GetRandInt();
221 GLuint* ui_ptr = (GLuint*)ptr;
223 for (GLuint i = 0; i < m_n_rows; ++i)
225 ui_ptr[i] = GetRandUint();
235 /** Generate data for type. This routine packs data tightly.
237 * @return Vector of bytes filled with data
239 std::vector<GLubyte> Type::GenerateDataPacked() const
241 const GLuint basic_size = GetTypeSize(m_basic_type);
242 const GLuint n_elements = m_n_columns * m_n_rows;
243 const GLuint size = basic_size * n_elements;
245 std::vector<GLubyte> data;
248 GLvoid* ptr = (GLvoid*)&data[0];
250 switch (m_basic_type)
254 GLdouble* d_ptr = (GLdouble*)ptr;
256 for (GLuint i = 0; i < n_elements; ++i)
258 d_ptr[i] = GetRandDouble();
264 GLfloat* f_ptr = (GLfloat*)ptr;
266 for (GLuint i = 0; i < n_elements; ++i)
268 f_ptr[i] = GetRandFloat();
274 GLint* i_ptr = (GLint*)ptr;
276 for (GLuint i = 0; i < n_elements; ++i)
278 i_ptr[i] = GetRandInt();
284 GLuint* ui_ptr = (GLuint*)ptr;
286 for (GLuint i = 0; i < n_elements; ++i)
288 ui_ptr[i] = GetRandUint();
297 /** Calculate "actual alignment". It work under assumption that align value is valid
299 * @param align Requested alignment, eg with "align" qualifier
300 * @param is_array Selects if an array of type or single instance should be considered
302 * @return Calculated value
304 GLuint Type::GetActualAlignment(GLuint align, bool is_array) const
306 const GLuint base_alignment = GetBaseAlignment(is_array);
308 return std::max(align, base_alignment);
311 /** Align given ofset with specified alignment
313 * @param offset Offset
314 * @param alignment Alignment
316 * @return Calculated value
318 GLuint align(GLuint offset, GLuint alignment)
320 const GLuint rest = offset % alignment;
324 GLuint missing = alignment - rest;
331 /** Calculate "actual offset"
333 * @param start_offset Requested offset
334 * @param actual_alignment Actual alignemnt
336 * @return Calculated value
338 GLuint Type::GetActualOffset(GLuint start_offset, GLuint actual_alignment)
340 GLuint offset = align(start_offset, actual_alignment);
345 /** Calculate "base alignment" for given type
347 * @param is_array Select if array or single instance should be considered
349 * @return Calculated value
351 GLuint Type::GetBaseAlignment(bool is_array) const
368 GLuint N = GetTypeSize(m_basic_type);
369 GLuint alignment = N * elements;
371 if ((true == is_array) || (1 != m_n_columns))
373 alignment = align(alignment, 16 /* vec4 alignment */);
379 /** Returns string representing GLSL constructor of type with arguments provided in data
381 * @param data Array of values that will be used as construcotr arguments.
382 * It is interpreted as tightly packed array of type matching this type.
384 * @return String in form "Type(args)"
386 std::string Type::GetGLSLConstructor(const GLvoid* data) const
388 const GLchar* type = GetGLSLTypeName();
390 std::stringstream stream;
392 stream << type << "(";
394 /* Scalar or vector */
395 if (1 == m_n_columns)
397 for (GLuint row = 0; row < m_n_rows; ++row)
399 switch (m_basic_type)
402 stream << ((GLdouble*)data)[row];
405 stream << ((GLfloat*)data)[row];
408 stream << ((GLint*)data)[row];
411 stream << ((GLuint*)data)[row];
415 if (row + 1 != m_n_rows)
421 else /* Matrix: mat(vec(), vec() .. ) */
423 const GLuint basic_size = GetTypeSize(m_basic_type);
424 // Very indescoverable defect, the column stride should be calculated by rows, such as mat2x3, which is 2, columns 3 rows, its column stride should be 3 * sizeof(float)
425 const GLuint column_stride = m_n_rows * basic_size;
426 const Type column_type = GetType(m_basic_type, 1, m_n_rows);
428 for (GLuint column = 0; column < m_n_columns; ++column)
430 const GLuint column_offset = column * column_stride;
431 const GLvoid* column_data = (GLubyte*)data + column_offset;
433 stream << column_type.GetGLSLConstructor(column_data);
435 if (column + 1 != m_n_columns)
447 /** Get glsl name of the type
449 * @return Name of glsl type
451 const glw::GLchar* Type::GetGLSLTypeName() const
453 static const GLchar* float_lut[4][4] = {
454 { "float", "vec2", "vec3", "vec4" },
455 { 0, "mat2", "mat2x3", "mat2x4" },
456 { 0, "mat3x2", "mat3", "mat3x4" },
457 { 0, "mat4x2", "mat4x3", "mat4" },
460 static const GLchar* double_lut[4][4] = {
461 { "double", "dvec2", "dvec3", "dvec4" },
462 { 0, "dmat2", "dmat2x3", "dmat2x4" },
463 { 0, "dmat3x2", "dmat3", "dmat3x4" },
464 { 0, "dmat4x2", "dmat4x3", "dmat4" },
467 static const GLchar* int_lut[4] = { "int", "ivec2", "ivec3", "ivec4" };
469 static const GLchar* uint_lut[4] = { "uint", "uvec2", "uvec3", "uvec4" };
471 const GLchar* result = 0;
473 if ((1 > m_n_columns) || (1 > m_n_rows) || (4 < m_n_columns) || (4 < m_n_rows))
478 switch (m_basic_type)
481 result = float_lut[m_n_columns - 1][m_n_rows - 1];
484 result = double_lut[m_n_columns - 1][m_n_rows - 1];
487 result = int_lut[m_n_rows - 1];
490 result = uint_lut[m_n_rows - 1];
493 TCU_FAIL("Invliad enum");
499 /** Get number of locations required for the type
501 * @return Number of columns times:
502 * - 2 when type is double with 3 or 4 rows,
503 * - 1 otherwise or if it's a vertex shader input.
505 GLuint Type::GetLocations(bool is_vs_input) const
507 GLuint n_loc_per_column;
509 /* 1 or 2 doubles any for rest */
510 if ((2 >= m_n_rows) || (Double != m_basic_type) || is_vs_input)
512 n_loc_per_column = 1;
516 /* 3 and 4 doubles */
517 n_loc_per_column = 2;
520 return n_loc_per_column * m_n_columns;
523 /** Get size of the type in bytes.
524 * Note that this routine doesn't consider arrays and assumes
525 * column_major matrices.
528 * - If std140 packaging and matrix; number of columns * base alignment
529 * - Otherwise; number of elements * sizeof(base_type)
531 GLuint Type::GetSize(const bool is_std140) const
533 const GLuint basic_type_size = GetTypeSize(m_basic_type);
534 const GLuint n_elements = m_n_columns * m_n_rows;
536 if (is_std140 && m_n_columns > 1)
538 return m_n_columns * GetBaseAlignment(false);
541 return basic_type_size * n_elements;
544 /** Get GLenum representing the type
548 GLenum Type::GetTypeGLenum() const
550 static const GLenum float_lut[4][4] = {
551 { GL_FLOAT, GL_FLOAT_VEC2, GL_FLOAT_VEC3, GL_FLOAT_VEC4 },
552 { 0, GL_FLOAT_MAT2, GL_FLOAT_MAT2x3, GL_FLOAT_MAT2x4 },
553 { 0, GL_FLOAT_MAT3x2, GL_FLOAT_MAT3, GL_FLOAT_MAT3x4 },
554 { 0, GL_FLOAT_MAT4x2, GL_FLOAT_MAT4x3, GL_FLOAT_MAT4 },
557 static const GLenum double_lut[4][4] = {
558 { GL_DOUBLE, GL_DOUBLE_VEC2, GL_DOUBLE_VEC3, GL_DOUBLE_VEC4 },
559 { 0, GL_DOUBLE_MAT2, GL_DOUBLE_MAT2x3, GL_DOUBLE_MAT2x4 },
560 { 0, GL_DOUBLE_MAT3x2, GL_DOUBLE_MAT3, GL_DOUBLE_MAT3x4 },
561 { 0, GL_DOUBLE_MAT4x2, GL_DOUBLE_MAT4x3, GL_DOUBLE_MAT4 },
564 static const GLenum int_lut[4] = { GL_INT, GL_INT_VEC2, GL_INT_VEC3, GL_INT_VEC4 };
566 static const GLenum uint_lut[4] = { GL_UNSIGNED_INT, GL_UNSIGNED_INT_VEC2, GL_UNSIGNED_INT_VEC3,
567 GL_UNSIGNED_INT_VEC4 };
571 if ((1 > m_n_columns) || (1 > m_n_rows) || (4 < m_n_columns) || (4 < m_n_rows))
576 switch (m_basic_type)
579 result = float_lut[m_n_columns - 1][m_n_rows - 1];
582 result = double_lut[m_n_columns - 1][m_n_rows - 1];
585 result = int_lut[m_n_rows - 1];
588 result = uint_lut[m_n_rows - 1];
591 TCU_FAIL("Invliad enum");
597 /** Calculate the numbe of components consumed by a type
598 * according to 11.1.2.1 Output Variables
600 * @return Calculated number of components for the type
602 GLuint Type::GetNumComponents() const
604 // Rule 3 of Section 7.6.2.2
605 // If the member is a three-component vector with components consuming N
606 // basic machine units, the base alignment is 4N.
607 GLuint num_components = (m_n_rows == 3 ? 4 : m_n_rows) * m_n_columns;
609 if (m_basic_type == Double)
614 return num_components;
617 /** Calculate stride for the type according to std140 rules
619 * @param alignment Alignment of type
620 * @param n_columns Number of columns
621 * @param n_array_elements Number of elements in array
623 * @return Calculated value
625 GLuint Type::CalculateStd140Stride(GLuint alignment, GLuint n_columns, GLuint n_array_elements)
627 GLuint stride = alignment * n_columns;
628 if (0 != n_array_elements)
630 stride *= n_array_elements;
636 /** Check if glsl support matrices for specific basic type
638 * @param type Basic type
640 * @return true if matrices of <type> are supported, false otherwise
642 bool Type::DoesTypeSupportMatrix(TYPES type)
657 TCU_FAIL("Invliad enum");
663 /** Creates instance of Type
665 * @param basic_type Select basic type of instance
666 * @param n_columns Number of columns
667 * @param n_rows Number of rows
669 * @return Type instance
671 Type Type::GetType(TYPES basic_type, glw::GLuint n_columns, glw::GLuint n_rows)
673 Type type = { basic_type, n_columns, n_rows };
678 /** Get Size of given type in bytes
682 * @return Size of type
684 GLuint Type::GetTypeSize(TYPES type)
691 result = sizeof(GLfloat);
694 result = sizeof(GLdouble);
697 result = sizeof(GLint);
700 result = sizeof(GLuint);
703 TCU_FAIL("Invalid enum");
709 /** Get GLenum representing given type
713 * @return GLenum value
715 GLenum Type::GetTypeGLenum(TYPES type)
731 result = GL_UNSIGNED_INT;
734 TCU_FAIL("Invalid enum");
740 /** Get proper glUniformNdv routine for vectors with specified number of rows
742 * @param gl GL functions
743 * @param n_rows Number of rows
745 * @return Function address
747 uniformNdv getUniformNdv(const glw::Functions& gl, glw::GLuint n_rows)
749 uniformNdv result = 0;
754 result = gl.uniform1dv;
757 result = gl.uniform2dv;
760 result = gl.uniform3dv;
763 result = gl.uniform4dv;
766 TCU_FAIL("Invalid number of rows");
772 /** Get proper glUniformNfv routine for vectors with specified number of rows
774 * @param gl GL functions
775 * @param n_rows Number of rows
777 * @return Function address
779 uniformNfv getUniformNfv(const glw::Functions& gl, glw::GLuint n_rows)
781 uniformNfv result = 0;
786 result = gl.uniform1fv;
789 result = gl.uniform2fv;
792 result = gl.uniform3fv;
795 result = gl.uniform4fv;
798 TCU_FAIL("Invalid number of rows");
804 /** Get proper glUniformNiv routine for vectors with specified number of rows
806 * @param gl GL functions
807 * @param n_rows Number of rows
809 * @return Function address
811 uniformNiv getUniformNiv(const glw::Functions& gl, glw::GLuint n_rows)
813 uniformNiv result = 0;
818 result = gl.uniform1iv;
821 result = gl.uniform2iv;
824 result = gl.uniform3iv;
827 result = gl.uniform4iv;
830 TCU_FAIL("Invalid number of rows");
836 /** Get proper glUniformNuiv routine for vectors with specified number of rows
838 * @param gl GL functions
839 * @param n_rows Number of rows
841 * @return Function address
843 uniformNuiv getUniformNuiv(const glw::Functions& gl, glw::GLuint n_rows)
845 uniformNuiv result = 0;
850 result = gl.uniform1uiv;
853 result = gl.uniform2uiv;
856 result = gl.uniform3uiv;
859 result = gl.uniform4uiv;
862 TCU_FAIL("Invalid number of rows");
868 /** Get proper glUniformMatrixNdv routine for matrix with specified number of columns and rows
870 * @param gl GL functions
871 * @param n_rows Number of rows
873 * @return Function address
875 uniformMatrixNdv getUniformMatrixNdv(const glw::Functions& gl, glw::GLuint n_columns, glw::GLuint n_rows)
877 uniformMatrixNdv result = 0;
885 result = gl.uniformMatrix2dv;
888 result = gl.uniformMatrix2x3dv;
891 result = gl.uniformMatrix2x4dv;
894 TCU_FAIL("Invalid number of rows");
901 result = gl.uniformMatrix3x2dv;
904 result = gl.uniformMatrix3dv;
907 result = gl.uniformMatrix3x4dv;
910 TCU_FAIL("Invalid number of rows");
917 result = gl.uniformMatrix4x2dv;
920 result = gl.uniformMatrix4x3dv;
923 result = gl.uniformMatrix4dv;
926 TCU_FAIL("Invalid number of rows");
930 TCU_FAIL("Invalid number of columns");
936 /** Get proper glUniformMatrixNfv routine for vectors with specified number of columns and rows
938 * @param gl GL functions
939 * @param n_rows Number of rows
941 * @return Function address
943 uniformMatrixNfv getUniformMatrixNfv(const glw::Functions& gl, glw::GLuint n_columns, glw::GLuint n_rows)
945 uniformMatrixNfv result = 0;
953 result = gl.uniformMatrix2fv;
956 result = gl.uniformMatrix2x3fv;
959 result = gl.uniformMatrix2x4fv;
962 TCU_FAIL("Invalid number of rows");
969 result = gl.uniformMatrix3x2fv;
972 result = gl.uniformMatrix3fv;
975 result = gl.uniformMatrix3x4fv;
978 TCU_FAIL("Invalid number of rows");
985 result = gl.uniformMatrix4x2fv;
988 result = gl.uniformMatrix4x3fv;
991 result = gl.uniformMatrix4fv;
994 TCU_FAIL("Invalid number of rows");
998 TCU_FAIL("Invalid number of columns");
1004 bool verifyVarying(Program& program, const std::string& parent_name, const Variable::Descriptor& desc,
1005 std::stringstream& stream, bool is_input)
1007 GLint component = 0;
1009 GLenum interface = GL_PROGRAM_INPUT;
1012 if (false == is_input)
1014 interface = GL_PROGRAM_OUTPUT;
1017 const std::string& name = Utils::Variable::GetReference(parent_name, desc, Utils::Variable::BASIC, 0);
1021 index = program.GetResourceIndex(name, interface);
1023 program.GetResource(interface, index, GL_LOCATION, 1 /* size */, &location);
1024 program.GetResource(interface, index, GL_LOCATION_COMPONENT, 1 /* size */, &component);
1026 catch (std::exception& exc)
1028 stream << "Failed to query program for varying: " << desc.m_name << ". Reason: " << exc.what() << "\n";
1035 if (location != desc.m_expected_location)
1037 stream << "Attribute: " << desc.m_name << " - invalid location: " << location
1038 << " expected: " << desc.m_expected_location << std::endl;
1041 if (component != desc.m_expected_component)
1043 stream << "Attribute: " << desc.m_name << " - invalid component: " << component
1044 << " expected: " << desc.m_expected_component << std::endl;
1051 /** Query program resource for given variable and verify that everything is as expected
1053 * @param program Program object
1054 * @param variable Variable object
1055 * @param stream Stream that will be used to log any error
1056 * @param is_input Selects if varying is input or output
1058 * @return true if verification is positive, false otherwise
1060 bool checkVarying(Program& program, const Variable& variable, std::stringstream& stream, bool is_input)
1064 if (variable.IsBlock())
1066 Utils::Interface* interface = variable.m_descriptor.m_interface;
1067 const size_t n_members = interface->m_members.size();
1069 for (size_t i = 0; i < n_members; ++i)
1071 const Variable::Descriptor& member = interface->m_members[i];
1072 bool member_result = verifyVarying(program, interface->m_name, member, stream, is_input);
1074 if (false == member_result)
1081 To query the the location of struct member by glGetProgramResource, we need pass the variable name "gs_fs_output[0].single",
1082 but in original implementation, the test pass the name "Data.single", which can't get any valid result.
1087 layout (location = 0) in Data gs_fs_output[1];
1089 else if (variable.IsStruct())
1091 Utils::Interface* interface = variable.m_descriptor.m_interface;
1092 const size_t n_members = interface->m_members.size();
1093 std::string structVariable = variable.m_descriptor.m_name;
1094 // If struct variable is an array
1095 if (0 != variable.m_descriptor.m_n_array_elements)
1097 for (GLuint i = 0; i < variable.m_descriptor.m_n_array_elements; i++)
1100 sprintf(buffer, "%d", i);
1101 structVariable.append("[");
1102 structVariable.append(buffer);
1103 structVariable.append("]");
1104 for (size_t j = 0; j < n_members; ++j)
1106 const Variable::Descriptor& member = interface->m_members[j];
1107 bool member_result = verifyVarying(program, structVariable, member, stream, is_input);
1109 if (false == member_result)
1118 for (GLuint i = 0; i < n_members; ++i)
1120 const Variable::Descriptor& member = interface->m_members[i];
1121 bool member_result = verifyVarying(program, structVariable, member, stream, is_input);
1123 if (false == member_result)
1132 result = verifyVarying(program, "", variable.m_descriptor, stream, is_input);
1137 /** Query program resource for given variable and verify that everything is as expected
1139 * @param program Program object
1140 * @param variable Variable object
1141 * @param stream Stream that will be used to log any error
1143 * @return true if verification is positive, false otherwise
1145 bool checkUniform(Program& program, const Utils::Variable& variable, std::stringstream& stream)
1149 if (false == variable.IsBlock())
1151 TCU_FAIL("Not implemented");
1155 Utils::Interface* interface = variable.m_descriptor.m_interface;
1157 size_t size = interface->m_members.size();
1159 std::vector<GLuint> indices;
1160 std::vector<const char*> names;
1161 std::vector<std::string> names_str;
1162 std::vector<GLint> offsets;
1164 indices.resize(size);
1166 names_str.resize(size);
1167 offsets.resize(size);
1169 for (size_t i = 0; i < size; ++i)
1174 const std::string& name =
1175 Utils::Variable::GetReference(interface->m_name, interface->m_members[i], Utils::Variable::BASIC, 0);
1177 if (Utils::Variable::INTERFACE == interface->m_members[i].m_type)
1179 const std::string& member_name = Utils::Variable::GetReference(
1180 name, interface->m_members[i].m_interface->m_members[0], Utils::Variable::BASIC, 0);
1182 names_str[i] = member_name;
1186 names_str[i] = name;
1189 names[i] = names_str[i].c_str();
1194 program.GetUniformIndices(static_cast<glw::GLsizei>(size), &names[0], &indices[0]);
1195 program.GetActiveUniformsiv(static_cast<glw::GLsizei>(size), &indices[0], GL_UNIFORM_OFFSET, &offsets[0]);
1197 catch (std::exception& exc)
1199 stream << "Failed to query program for uniforms in block: " << variable.m_descriptor.m_name
1200 << ". Reason: " << exc.what() << "\n";
1205 for (size_t i = 0; i < size; ++i)
1207 Utils::Variable::Descriptor& desc = interface->m_members[i];
1209 if (offsets[i] != (GLint)desc.m_offset)
1211 stream << "Uniform: " << desc.m_name << " - invalid offset: " << offsets[i]
1212 << " expected: " << desc.m_offset << std::endl;
1221 /** Query program resource for given variable and verify that everything is as expected
1223 * @param program Program object
1224 * @param variable Variable object
1225 * @param stream Stream that will be used to log any error
1227 * @return true if verification is positive, false otherwise
1229 bool checkSSB(Program& program, const Utils::Variable& variable, std::stringstream& stream)
1233 if (false == variable.IsBlock())
1235 TCU_FAIL("Not implemented");
1239 Utils::Interface* interface = variable.m_descriptor.m_interface;
1241 size_t size = interface->m_members.size();
1243 for (size_t i = 0; i < size; ++i)
1246 std::string name_str = "";
1249 const std::string& name =
1250 Utils::Variable::GetReference(interface->m_name, interface->m_members[i], Utils::Variable::BASIC, 0);
1252 if (Utils::Variable::INTERFACE == interface->m_members[i].m_type)
1254 const std::string& member_name = Utils::Variable::GetReference(
1255 name, interface->m_members[i].m_interface->m_members[0], Utils::Variable::BASIC, 0);
1257 name_str = member_name;
1266 index = program.GetResourceIndex(name_str, GL_BUFFER_VARIABLE);
1268 program.GetResource(GL_BUFFER_VARIABLE, index, GL_OFFSET, 1, &offset);
1270 catch (std::exception& exc)
1272 stream << "Failed to query program for buffer variable: " << variable.m_descriptor.m_name
1273 << ". Reason: " << exc.what() << "\n";
1278 Utils::Variable::Descriptor& desc = interface->m_members[i];
1280 if (offset != (GLint)desc.m_offset)
1282 stream << "Uniform: " << desc.m_name << " - invalid offset: " << offset
1283 << " expected: " << desc.m_offset << std::endl;
1292 /** Query program resources at given stage and verifies results
1294 * @param program Program object
1295 * @param program_interface Definition of program interface
1296 * @param stage Stage to be verified
1297 * @param check_inputs Select if inputs should be verified
1298 * @param check_outputs Select if output should be verified
1299 * @param check_uniforms Select if uniforms should be verified
1300 * @param check_ssbs Select if buffers should be verified
1301 * @param stream Stream that will be used to log any error
1303 * @return true if verification is positive, false otherwise
1305 bool checkProgramStage(Program& program, const ProgramInterface& program_interface, Utils::Shader::STAGES stage,
1306 bool check_inputs, bool check_outputs, bool check_uniforms, bool check_ssbs,
1307 std::stringstream& stream)
1309 typedef Variable::PtrVector::const_iterator const_iterator;
1311 const ShaderInterface& interface = program_interface.GetShaderInterface(stage);
1316 if (true == check_inputs)
1318 const Variable::PtrVector& inputs = interface.m_inputs;
1320 for (const_iterator it = inputs.begin(); it != inputs.end(); ++it)
1322 if (false == checkVarying(program, **it, stream, true))
1330 if (true == check_outputs)
1332 const Variable::PtrVector& outputs = interface.m_outputs;
1334 for (const_iterator it = outputs.begin(); it != outputs.end(); ++it)
1336 if (false == checkVarying(program, **it, stream, false))
1344 if (true == check_uniforms)
1346 const Variable::PtrVector& uniforms = interface.m_uniforms;
1348 for (const_iterator it = uniforms.begin(); it != uniforms.end(); ++it)
1350 if (false == checkUniform(program, **it, stream))
1358 if (true == check_ssbs)
1360 const Variable::PtrVector& ssbs = interface.m_ssb_blocks;
1362 for (const_iterator it = ssbs.begin(); it != ssbs.end(); ++it)
1364 if (false == checkSSB(program, **it, stream))
1374 /** Query resources of monolithic compute program and verifies results
1376 * @param program Program object
1377 * @param program_interface Definition of program interface
1378 * @param stream Stream that will be used to log any error
1380 * @return true if verification is positive, false otherwise
1382 bool checkMonolithicComputeProgramInterface(Program& program, const ProgramInterface& program_interface,
1383 std::stringstream& stream)
1387 if (false == checkProgramStage(program, program_interface, Shader::COMPUTE, false, false, true, true, stream))
1396 /** Query resources of monolithic draw program and verifies results
1398 * @param program Program object
1399 * @param program_interface Definition of program interface
1400 * @param stream Stream that will be used to log any error
1402 * @return true if verification is positive, false otherwise
1404 bool checkMonolithicDrawProgramInterface(Program& program, const ProgramInterface& program_interface,
1405 std::stringstream& stream)
1409 if (false == checkProgramStage(program, program_interface, Shader::VERTEX, true, false, true, true, stream))
1418 /** Query resources of separable draw program and verifies results
1420 * @param program Program object
1421 * @param program_interface Definition of program interface
1422 * @param stream Stream that will be used to log any error
1424 * @return true if verification is positive, false otherwise
1426 bool checkSeparableDrawProgramInterface(Program& program, const ProgramInterface& program_interface,
1427 Utils::Shader::STAGES stage, std::stringstream& stream)
1431 if (false == checkProgramStage(program, program_interface, stage, true, true, true, true, stream))
1440 /** Check if extension is supported
1442 * @param context Test context
1443 * @param extension_name Name of extension
1445 * @return true if extension is supported, false otherwise
1447 bool isExtensionSupported(deqp::Context& context, const GLchar* extension_name)
1449 const std::vector<std::string>& extensions = context.getContextInfo().getExtensions();
1451 if (std::find(extensions.begin(), extensions.end(), extension_name) == extensions.end())
1459 /** Check if GL context meets version requirements
1461 * @param gl Functions
1462 * @param required_major Minimum required MAJOR_VERSION
1463 * @param required_minor Minimum required MINOR_VERSION
1465 * @return true if GL context version is at least as requested, false otherwise
1467 bool isGLVersionAtLeast(const Functions& gl, GLint required_major, GLint required_minor)
1469 glw::GLint major = 0;
1470 glw::GLint minor = 0;
1472 gl.getIntegerv(GL_MAJOR_VERSION, &major);
1473 gl.getIntegerv(GL_MINOR_VERSION, &minor);
1475 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
1477 if (major > required_major)
1479 /* Major is higher than required one */
1482 else if (major == required_major)
1484 if (minor >= required_minor)
1486 /* Major is equal to required one */
1487 /* Minor is higher than or equal to required one */
1492 /* Major is equal to required one */
1493 /* Minor is lower than required one */
1499 /* Major is lower than required one */
1504 /** Replace first occurance of <token> with <text> in <string> starting at <search_posistion>
1506 * @param token Token string
1507 * @param search_position Position at which find will start, it is updated to position at which replaced text ends
1508 * @param text String that will be used as replacement for <token>
1509 * @param string String to work on
1511 void replaceToken(const GLchar* token, size_t& search_position, const GLchar* text, std::string& string)
1513 const size_t text_length = strlen(text);
1514 const size_t token_length = strlen(token);
1515 const size_t token_position = string.find(token, search_position);
1517 #if DEBUG_REPLACE_TOKEN
1518 if (std::string::npos == token_position)
1520 string.append("\n\nInvalid token: ");
1521 string.append(token);
1523 TCU_FAIL(string.c_str());
1525 #endif /* DEBUG_REPLACE_TOKEN */
1527 string.replace(token_position, token_length, text, text_length);
1529 search_position = token_position + text_length;
1532 /** Replace all occurances of <token> with <text> in <string>
1534 * @param token Token string
1535 * @param text String that will be used as replacement for <token>
1536 * @param string String to work on
1538 void replaceAllTokens(const GLchar* token, const GLchar* text, std::string& string)
1540 const size_t text_length = strlen(text);
1541 const size_t token_length = strlen(token);
1543 size_t search_position = 0;
1547 const size_t token_position = string.find(token, search_position);
1549 if (std::string::npos == token_position)
1554 search_position = token_position + text_length;
1556 string.replace(token_position, token_length, text, text_length);
1560 /** Rounds up the value to the next power of 2.
1561 * This routine does not work for 0, see the url for explanations.
1563 * @param value Starting point
1565 * @return Calculated value
1567 glw::GLuint roundUpToPowerOf2(glw::GLuint value)
1569 /* Taken from: graphics.stanford.edu/~seander/bithacks.html */
1572 value |= value >> 1;
1573 value |= value >> 2;
1574 value |= value >> 4;
1575 value |= value >> 8;
1576 value |= value >> 16;
1583 /** Insert elements of list into string.
1584 * List in string is represented either by token "LIST" or "SEPARATORLIST".
1585 * If SEPARATORLIST is available, than SEPARATOR is replaced with <separator>.
1586 * LIST is replaced with <element>SEPARATORLIST
1588 * @param element Element to be inserted
1589 * @param separator Separator inserted between elements
1590 * @param search_position Position in string, where search for list should start
1591 * @param string String
1593 void insertElementOfList(const GLchar* element, const GLchar* separator, size_t& search_position, std::string& string)
1595 static const char* list = g_list;
1596 static const char* sep_list = "SEPARATORLIST";
1598 /* Try to get "list" positions */
1599 const size_t list_position = string.find(list, search_position);
1600 const size_t sep_list_position = string.find(sep_list, search_position);
1602 /* There is no list in string */
1603 if (std::string::npos == list_position)
1608 if (9 /* strlen(SEPARATOR) */ == list_position - sep_list_position)
1610 replaceToken("SEPARATOR", search_position, separator, string);
1613 /* Save search_position */
1614 const size_t start_position = search_position;
1616 /* Prepare new element */
1617 replaceToken("LIST", search_position, "ELEMENTSEPARATORLIST", string);
1619 /* Restore search_position */
1620 search_position = start_position;
1622 /* Replace element and separator */
1623 replaceToken("ELEMENT", search_position, element, string);
1626 /** Close list in string.
1627 * If SEPARATORLIST is available, than SEPARATOR is replaced with <separator>
1628 * LIST is replaced with ""
1630 * @param separator Separator inserted between elements
1631 * @param search_position Position in string, where search for list should start
1632 * @param string String
1634 void endList(const glw::GLchar* separator, size_t& search_position, std::string& string)
1636 const size_t sep_position = string.find("SEPARATOR", search_position);
1637 if (std::string::npos != sep_position)
1639 replaceToken("SEPARATOR", search_position, separator, string);
1642 replaceToken("LIST", search_position, "", string);
1645 /* Buffer constants */
1646 const GLuint Buffer::m_invalid_id = -1;
1650 * @param context CTS context.
1652 Buffer::Buffer(deqp::Context& context) : m_id(m_invalid_id), m_buffer(Array), m_context(context)
1664 /** Initialize buffer instance
1666 * @param buffer Buffer type
1667 * @param usage Buffer usage enum
1668 * @param size <size> parameter
1669 * @param data <data> parameter
1671 void Buffer::Init(BUFFERS buffer, USAGE usage, GLsizeiptr size, GLvoid* data)
1673 /* Delete previous buffer instance */
1678 const Functions& gl = m_context.getRenderContext().getFunctions();
1681 Bind(gl, m_id, m_buffer);
1682 Data(gl, m_buffer, usage, size, data);
1685 /** Release buffer instance
1688 void Buffer::Release()
1690 if (m_invalid_id != m_id)
1692 const Functions& gl = m_context.getRenderContext().getFunctions();
1694 gl.deleteBuffers(1, &m_id);
1695 m_id = m_invalid_id;
1699 /** Binds buffer to its target
1702 void Buffer::Bind() const
1704 const Functions& gl = m_context.getRenderContext().getFunctions();
1706 Bind(gl, m_id, m_buffer);
1709 /** Binds indexed buffer
1711 * @param index <index> parameter
1713 void Buffer::BindBase(GLuint index) const
1715 const Functions& gl = m_context.getRenderContext().getFunctions();
1717 BindBase(gl, m_id, m_buffer, index);
1720 /** Binds range of buffer
1722 * @param index <index> parameter
1723 * @param offset <offset> parameter
1724 * @param size <size> parameter
1726 void Buffer::BindRange(GLuint index, GLintptr offset, GLsizeiptr size) const
1728 const Functions& gl = m_context.getRenderContext().getFunctions();
1730 BindRange(gl, m_id, m_buffer, index, offset, size);
1733 /** Allocate memory for buffer and sends initial content
1735 * @param usage Buffer usage enum
1736 * @param size <size> parameter
1737 * @param data <data> parameter
1739 void Buffer::Data(USAGE usage, glw::GLsizeiptr size, glw::GLvoid* data)
1741 const Functions& gl = m_context.getRenderContext().getFunctions();
1743 Data(gl, m_buffer, usage, size, data);
1746 /** Maps contents of buffer into CPU space
1748 * @param access Requested access
1750 * @return Pointer to memory region available for CPU
1752 GLvoid* Buffer::Map(ACCESS access)
1754 const Functions& gl = m_context.getRenderContext().getFunctions();
1756 return Map(gl, m_buffer, access);
1759 /** Allocate memory for buffer and sends initial content
1761 * @param offset Offset in buffer
1762 * @param size <size> parameter
1763 * @param data <data> parameter
1765 void Buffer::SubData(glw::GLintptr offset, glw::GLsizeiptr size, glw::GLvoid* data)
1767 const Functions& gl = m_context.getRenderContext().getFunctions();
1769 SubData(gl, m_buffer, offset, size, data);
1772 /** Maps contents of buffer into CPU space
1774 void Buffer::UnMap()
1776 const Functions& gl = m_context.getRenderContext().getFunctions();
1778 return UnMap(gl, m_buffer);
1781 /** Bind buffer to given target
1783 * @param gl GL functions
1784 * @param id Id of buffer
1785 * @param buffer Buffer enum
1787 void Buffer::Bind(const Functions& gl, GLuint id, BUFFERS buffer)
1789 GLenum target = GetBufferGLenum(buffer);
1791 gl.bindBuffer(target, id);
1792 GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffer");
1795 /** Binds indexed buffer
1797 * @param gl GL functions
1798 * @param id Id of buffer
1799 * @param buffer Buffer enum
1800 * @param index <index> parameter
1802 void Buffer::BindBase(const Functions& gl, GLuint id, BUFFERS buffer, GLuint index)
1804 GLenum target = GetBufferGLenum(buffer);
1806 gl.bindBufferBase(target, index, id);
1807 GLU_EXPECT_NO_ERROR(gl.getError(), "BindBufferBase");
1810 /** Binds buffer range
1812 * @param gl GL functions
1813 * @param id Id of buffer
1814 * @param buffer Buffer enum
1815 * @param index <index> parameter
1816 * @param offset <offset> parameter
1817 * @param size <size> parameter
1819 void Buffer::BindRange(const Functions& gl, GLuint id, BUFFERS buffer, GLuint index, GLintptr offset, GLsizeiptr size)
1821 GLenum target = GetBufferGLenum(buffer);
1823 gl.bindBufferRange(target, index, id, offset, size);
1824 GLU_EXPECT_NO_ERROR(gl.getError(), "BindBufferRange");
1827 /** Allocate memory for buffer and sends initial content
1829 * @param gl GL functions
1830 * @param buffer Buffer enum
1831 * @param usage Buffer usage enum
1832 * @param size <size> parameter
1833 * @param data <data> parameter
1835 void Buffer::Data(const glw::Functions& gl, BUFFERS buffer, USAGE usage, glw::GLsizeiptr size, glw::GLvoid* data)
1837 GLenum target = GetBufferGLenum(buffer);
1838 GLenum gl_usage = GetUsageGLenum(usage);
1840 gl.bufferData(target, size, data, gl_usage);
1841 GLU_EXPECT_NO_ERROR(gl.getError(), "BufferData");
1844 /** Allocate memory for buffer and sends initial content
1846 * @param gl GL functions
1847 * @param buffer Buffer enum
1848 * @param offset Offset in buffer
1849 * @param size <size> parameter
1850 * @param data <data> parameter
1852 void Buffer::SubData(const glw::Functions& gl, BUFFERS buffer, glw::GLintptr offset, glw::GLsizeiptr size,
1855 GLenum target = GetBufferGLenum(buffer);
1857 gl.bufferSubData(target, offset, size, data);
1858 GLU_EXPECT_NO_ERROR(gl.getError(), "BufferSubData");
1863 * @param gl GL functions
1864 * @param out_id Id of buffer
1866 void Buffer::Generate(const Functions& gl, GLuint& out_id)
1868 GLuint id = m_invalid_id;
1870 gl.genBuffers(1, &id);
1871 GLU_EXPECT_NO_ERROR(gl.getError(), "GenBuffers");
1873 if (m_invalid_id == id)
1875 TCU_FAIL("Got invalid id");
1881 /** Maps buffer content
1883 * @param gl GL functions
1884 * @param buffer Buffer enum
1885 * @param access Access rights for mapped region
1887 * @return Mapped memory
1889 void* Buffer::Map(const Functions& gl, BUFFERS buffer, ACCESS access)
1891 GLenum target = GetBufferGLenum(buffer);
1892 GLenum gl_access = GetAccessGLenum(access);
1894 void* result = gl.mapBuffer(target, gl_access);
1895 GLU_EXPECT_NO_ERROR(gl.getError(), "MapBuffer");
1903 void Buffer::UnMap(const Functions& gl, BUFFERS buffer)
1905 GLenum target = GetBufferGLenum(buffer);
1907 gl.unmapBuffer(target);
1908 GLU_EXPECT_NO_ERROR(gl.getError(), "UnmapBuffer");
1911 /** Return GLenum representation of requested access
1913 * @param access Requested access
1915 * @return GLenum value
1917 GLenum Buffer::GetAccessGLenum(ACCESS access)
1924 result = GL_READ_ONLY;
1927 result = GL_WRITE_ONLY;
1930 result = GL_READ_WRITE;
1933 TCU_FAIL("Invalid enum");
1939 /** Return GLenum representation of requested buffer type
1941 * @param buffer Requested buffer type
1943 * @return GLenum value
1945 GLenum Buffer::GetBufferGLenum(BUFFERS buffer)
1952 result = GL_ARRAY_BUFFER;
1955 result = GL_ELEMENT_ARRAY_BUFFER;
1957 case Shader_Storage:
1958 result = GL_SHADER_STORAGE_BUFFER;
1961 result = GL_TEXTURE_BUFFER;
1963 case Transform_feedback:
1964 result = GL_TRANSFORM_FEEDBACK_BUFFER;
1967 result = GL_UNIFORM_BUFFER;
1970 TCU_FAIL("Invalid enum");
1976 /** Return GLenum representation of requested usage
1978 * @param usage Requested usage
1980 * @return GLenum value
1982 GLenum Buffer::GetUsageGLenum(USAGE usage)
1989 result = GL_DYNAMIC_COPY;
1992 result = GL_DYNAMIC_DRAW;
1995 result = GL_DYNAMIC_READ;
1998 result = GL_STATIC_COPY;
2001 result = GL_STATIC_DRAW;
2004 result = GL_STATIC_READ;
2007 result = GL_STREAM_COPY;
2010 result = GL_STREAM_DRAW;
2013 result = GL_STREAM_READ;
2016 TCU_FAIL("Invalid enum");
2022 /** Returns name of buffer target
2024 * @param buffer Target enum
2026 * @return Name of target
2028 const GLchar* Buffer::GetBufferName(BUFFERS buffer)
2030 const GLchar* name = 0;
2040 case Shader_Storage:
2041 name = "Shader_Storage";
2046 case Transform_feedback:
2047 name = "Transform_feedback";
2053 TCU_FAIL("Invalid enum");
2059 /* Framebuffer constants */
2060 const GLuint Framebuffer::m_invalid_id = -1;
2064 * @param context CTS context
2066 Framebuffer::Framebuffer(deqp::Context& context) : m_id(m_invalid_id), m_context(context)
2068 /* Nothing to be done here */
2074 Framebuffer::~Framebuffer()
2079 /** Initialize framebuffer instance
2082 void Framebuffer::Init()
2084 /* Delete previous instance */
2087 const Functions& gl = m_context.getRenderContext().getFunctions();
2092 /** Release framebuffer instance
2095 void Framebuffer::Release()
2097 if (m_invalid_id != m_id)
2099 const Functions& gl = m_context.getRenderContext().getFunctions();
2101 gl.deleteFramebuffers(1, &m_id);
2102 m_id = m_invalid_id;
2106 /** Attach texture to specified attachment
2108 * @param attachment Attachment
2109 * @param texture_id Texture id
2110 * @param width Texture width
2111 * @param height Texture height
2113 void Framebuffer::AttachTexture(GLenum attachment, GLuint texture_id, GLuint width, GLuint height)
2115 const Functions& gl = m_context.getRenderContext().getFunctions();
2117 AttachTexture(gl, attachment, texture_id, width, height);
2120 /** Binds framebuffer to DRAW_FRAMEBUFFER
2123 void Framebuffer::Bind()
2125 const Functions& gl = m_context.getRenderContext().getFunctions();
2130 /** Clear framebuffer
2132 * @param mask <mask> parameter of glClear. Decides which shall be cleared
2134 void Framebuffer::Clear(GLenum mask)
2136 const Functions& gl = m_context.getRenderContext().getFunctions();
2141 /** Specifies clear color
2143 * @param red Red channel
2144 * @param green Green channel
2145 * @param blue Blue channel
2146 * @param alpha Alpha channel
2148 void Framebuffer::ClearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
2150 const Functions& gl = m_context.getRenderContext().getFunctions();
2152 ClearColor(gl, red, green, blue, alpha);
2155 /** Attach texture to specified attachment
2157 * @param gl GL functions
2158 * @param attachment Attachment
2159 * @param texture_id Texture id
2160 * @param width Texture width
2161 * @param height Texture height
2163 void Framebuffer::AttachTexture(const Functions& gl, GLenum attachment, GLuint texture_id, GLuint width, GLuint height)
2165 gl.framebufferTexture(GL_DRAW_FRAMEBUFFER, attachment, texture_id, 0 /* level */);
2166 GLU_EXPECT_NO_ERROR(gl.getError(), "FramebufferTexture");
2168 gl.viewport(0 /* x */, 0 /* y */, width, height);
2169 GLU_EXPECT_NO_ERROR(gl.getError(), "Viewport");
2172 /** Binds framebuffer to DRAW_FRAMEBUFFER
2174 * @param gl GL functions
2175 * @param id ID of framebuffer
2177 void Framebuffer::Bind(const Functions& gl, GLuint id)
2179 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, id);
2180 GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer");
2183 /** Clear framebuffer
2185 * @param gl GL functions
2186 * @param mask <mask> parameter of glClear. Decides which shall be cleared
2188 void Framebuffer::Clear(const Functions& gl, GLenum mask)
2191 GLU_EXPECT_NO_ERROR(gl.getError(), "Clear");
2194 /** Specifies clear color
2196 * @param gl GL functions
2197 * @param red Red channel
2198 * @param green Green channel
2199 * @param blue Blue channel
2200 * @param alpha Alpha channel
2202 void Framebuffer::ClearColor(const Functions& gl, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
2204 gl.clearColor(red, green, blue, alpha);
2205 GLU_EXPECT_NO_ERROR(gl.getError(), "ClearColor");
2208 /** Generate framebuffer
2211 void Framebuffer::Generate(const Functions& gl, GLuint& out_id)
2213 GLuint id = m_invalid_id;
2215 gl.genFramebuffers(1, &id);
2216 GLU_EXPECT_NO_ERROR(gl.getError(), "GenFramebuffers");
2218 if (m_invalid_id == id)
2220 TCU_FAIL("Invalid id");
2226 /* Shader's constants */
2227 const GLuint Shader::m_invalid_id = 0;
2231 * @param context CTS context.
2233 Shader::Shader(deqp::Context& context) : m_id(m_invalid_id), m_context(context)
2235 /* Nothing to be done here */
2246 /** Initialize shader instance
2248 * @param stage Shader stage
2249 * @param source Source code
2251 void Shader::Init(STAGES stage, const std::string& source)
2253 if (true == source.empty())
2255 /* No source == no shader */
2259 /* Delete any previous shader */
2262 /* Create, set source and compile */
2263 const Functions& gl = m_context.getRenderContext().getFunctions();
2265 Create(gl, stage, m_id);
2266 Source(gl, m_id, source);
2272 catch (const CompilationException& exc)
2274 throw InvalidSourceException(exc.what(), source, stage);
2278 /** Release shader instance
2281 void Shader::Release()
2283 if (m_invalid_id != m_id)
2285 const Functions& gl = m_context.getRenderContext().getFunctions();
2287 gl.deleteShader(m_id);
2288 m_id = m_invalid_id;
2294 * @param gl GL functions
2295 * @param id Shader id
2297 void Shader::Compile(const Functions& gl, GLuint id)
2299 GLint status = GL_FALSE;
2302 gl.compileShader(id);
2303 GLU_EXPECT_NO_ERROR(gl.getError(), "CompileShader");
2305 /* Get compilation status */
2306 gl.getShaderiv(id, GL_COMPILE_STATUS, &status);
2307 GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");
2309 /* Log compilation error */
2310 if (GL_TRUE != status)
2312 glw::GLint length = 0;
2313 std::string message;
2315 /* Error log length */
2316 gl.getShaderiv(id, GL_INFO_LOG_LENGTH, &length);
2317 GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");
2319 /* Prepare storage */
2320 message.resize(length, 0);
2323 gl.getShaderInfoLog(id, length, 0, &message[0]);
2324 GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderInfoLog");
2326 throw CompilationException(message.c_str());
2332 * @param gl GL functions
2333 * @param stage Shader stage
2334 * @param out_id Shader id
2336 void Shader::Create(const Functions& gl, STAGES stage, GLuint& out_id)
2338 const GLenum shaderType = GetShaderStageGLenum(stage);
2339 const GLuint id = gl.createShader(shaderType);
2340 GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
2342 if (m_invalid_id == id)
2344 TCU_FAIL("Failed to create shader");
2350 /** Set shader's source code
2352 * @param gl GL functions
2353 * @param id Shader id
2354 * @param source Shader source code
2356 void Shader::Source(const Functions& gl, GLuint id, const std::string& source)
2358 const GLchar* code = source.c_str();
2360 gl.shaderSource(id, 1 /* count */, &code, 0 /* lengths */);
2361 GLU_EXPECT_NO_ERROR(gl.getError(), "ShaderSource");
2364 /** Get GLenum repesenting shader stage
2366 * @param stage Shader stage
2370 GLenum Shader::GetShaderStageGLenum(STAGES stage)
2377 result = GL_COMPUTE_SHADER;
2380 result = GL_FRAGMENT_SHADER;
2383 result = GL_GEOMETRY_SHADER;
2386 result = GL_TESS_CONTROL_SHADER;
2389 result = GL_TESS_EVALUATION_SHADER;
2392 result = GL_VERTEX_SHADER;
2395 TCU_FAIL("Invalid enum");
2401 /** Get string representing name of shader stage
2403 * @param stage Shader stage
2405 * @return String with name of shader stage
2407 const glw::GLchar* Shader::GetStageName(STAGES stage)
2409 const GLchar* result = 0;
2420 result = "tessellation control";
2423 result = "tessellation evaluation";
2426 result = "geometry";
2429 result = "fragment";
2432 TCU_FAIL("Invalid enum");
2438 /** Logs shader source
2440 * @param context CTS context
2441 * @param source Source of shader
2442 * @param stage Shader stage
2444 void Shader::LogSource(deqp::Context& context, const std::string& source, STAGES stage)
2446 /* Skip empty shaders */
2447 if (true == source.empty())
2452 context.getTestContext().getLog() << tcu::TestLog::Message
2453 << "Shader source. Stage: " << Shader::GetStageName(stage)
2454 << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(source);
2459 * @param message Compilation error message
2461 Shader::CompilationException::CompilationException(const GLchar* message)
2463 m_message = message;
2466 /** Returns error messages
2468 * @return Compilation error message
2470 const char* Shader::CompilationException::what() const throw()
2472 return m_message.c_str();
2477 * @param message Compilation error message
2479 Shader::InvalidSourceException::InvalidSourceException(const GLchar* error_message, const std::string& source,
2481 : m_message(error_message), m_source(source), m_stage(stage)
2485 /** Returns error messages
2487 * @return Compilation error message
2489 const char* Shader::InvalidSourceException::what() const throw()
2491 return "Compilation error";
2494 /** Logs error message and shader sources **/
2495 void Shader::InvalidSourceException::log(deqp::Context& context) const
2497 context.getTestContext().getLog() << tcu::TestLog::Message << "Failed to compile shader: " << m_message.c_str()
2498 << tcu::TestLog::EndMessage;
2500 LogSource(context, m_source, m_stage);
2503 /* Program constants */
2504 const GLuint Pipeline::m_invalid_id = 0;
2508 * @param context CTS context.
2510 Pipeline::Pipeline(deqp::Context& context) : m_id(m_invalid_id), m_context(context)
2512 /* Nothing to be done here */
2518 Pipeline::~Pipeline()
2523 /** Initialize pipline object
2526 void Pipeline::Init()
2530 const Functions& gl = m_context.getRenderContext().getFunctions();
2533 gl.genProgramPipelines(1, &m_id);
2534 GLU_EXPECT_NO_ERROR(gl.getError(), "GenProgramPipelines");
2537 /** Release pipeline object
2540 void Pipeline::Release()
2542 if (m_invalid_id != m_id)
2544 const Functions& gl = m_context.getRenderContext().getFunctions();
2547 gl.deleteProgramPipelines(1, &m_id);
2548 GLU_EXPECT_NO_ERROR(gl.getError(), "DeleteProgramPipelines");
2550 m_id = m_invalid_id;
2557 void Pipeline::Bind()
2559 const Functions& gl = m_context.getRenderContext().getFunctions();
2564 /** Set which stages should be active
2566 * @param program_id Id of program
2567 * @param stages Logical combination of enums representing stages
2569 void Pipeline::UseProgramStages(GLuint program_id, GLenum stages)
2571 const Functions& gl = m_context.getRenderContext().getFunctions();
2573 UseProgramStages(gl, m_id, program_id, stages);
2578 * @param gl Functiions
2579 * @param id Pipeline id
2581 void Pipeline::Bind(const Functions& gl, GLuint id)
2583 gl.bindProgramPipeline(id);
2584 GLU_EXPECT_NO_ERROR(gl.getError(), "BindProgramPipeline");
2587 /** Set which stages should be active
2589 * @param gl Functiions
2590 * @param id Pipeline id
2591 * @param program_id Id of program
2592 * @param stages Logical combination of enums representing stages
2594 void Pipeline::UseProgramStages(const Functions& gl, GLuint id, GLuint program_id, GLenum stages)
2596 gl.useProgramStages(id, stages, program_id);
2597 GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgramStages");
2600 /* Program constants */
2601 const GLuint Program::m_invalid_id = 0;
2605 * @param context CTS context.
2607 Program::Program(deqp::Context& context)
2608 : m_id(m_invalid_id)
2609 , m_compute(context)
2610 , m_fragment(context)
2611 , m_geometry(context)
2612 , m_tess_ctrl(context)
2613 , m_tess_eval(context)
2615 , m_context(context)
2617 /* Nothing to be done here */
2628 /** Initialize program instance
2630 * @param compute_shader Compute shader source code
2631 * @param fragment_shader Fragment shader source code
2632 * @param geometry_shader Geometry shader source code
2633 * @param tessellation_control_shader Tessellation control shader source code
2634 * @param tessellation_evaluation_shader Tessellation evaluation shader source code
2635 * @param vertex_shader Vertex shader source code
2636 * @param captured_varyings Vector of variables to be captured with transfrom feedback
2637 * @param capture_interleaved Select mode of transform feedback (separate or interleaved)
2638 * @param is_separable Selects if monolithic or separable program should be built. Defaults to false
2640 void Program::Init(const std::string& compute_shader, const std::string& fragment_shader,
2641 const std::string& geometry_shader, const std::string& tessellation_control_shader,
2642 const std::string& tessellation_evaluation_shader, const std::string& vertex_shader,
2643 const NameVector& captured_varyings, bool capture_interleaved, bool is_separable)
2645 /* Delete previous program */
2648 /* GL entry points */
2649 const Functions& gl = m_context.getRenderContext().getFunctions();
2651 /* Initialize shaders */
2652 m_compute.Init(Shader::COMPUTE, compute_shader);
2653 m_fragment.Init(Shader::FRAGMENT, fragment_shader);
2654 m_geometry.Init(Shader::GEOMETRY, geometry_shader);
2655 m_tess_ctrl.Init(Shader::TESS_CTRL, tessellation_control_shader);
2656 m_tess_eval.Init(Shader::TESS_EVAL, tessellation_evaluation_shader);
2657 m_vertex.Init(Shader::VERTEX, vertex_shader);
2659 /* Create program, set up transform feedback and attach shaders */
2661 Capture(gl, m_id, captured_varyings, capture_interleaved);
2662 Attach(gl, m_id, m_compute.m_id);
2663 Attach(gl, m_id, m_fragment.m_id);
2664 Attach(gl, m_id, m_geometry.m_id);
2665 Attach(gl, m_id, m_tess_ctrl.m_id);
2666 Attach(gl, m_id, m_tess_eval.m_id);
2667 Attach(gl, m_id, m_vertex.m_id);
2669 /* Set separable parameter */
2670 if (true == is_separable)
2672 gl.programParameteri(m_id, GL_PROGRAM_SEPARABLE, GL_TRUE);
2673 GLU_EXPECT_NO_ERROR(gl.getError(), "ProgramParameteri");
2681 catch (const LinkageException& exc)
2683 throw BuildException(exc.what(), compute_shader, fragment_shader, geometry_shader, tessellation_control_shader,
2684 tessellation_evaluation_shader, vertex_shader);
2688 /** Initialize program instance
2690 * @param compute_shader Compute shader source code
2691 * @param fragment_shader Fragment shader source code
2692 * @param geometry_shader Geometry shader source code
2693 * @param tessellation_control_shader Tessellation control shader source code
2694 * @param tessellation_evaluation_shader Tessellation evaluation shader source code
2695 * @param vertex_shader Vertex shader source code
2696 * @param is_separable Selects if monolithic or separable program should be built. Defaults to false
2698 void Program::Init(const std::string& compute_shader, const std::string& fragment_shader,
2699 const std::string& geometry_shader, const std::string& tessellation_control_shader,
2700 const std::string& tessellation_evaluation_shader, const std::string& vertex_shader,
2703 NameVector captured_varying;
2705 Init(compute_shader, fragment_shader, geometry_shader, tessellation_control_shader, tessellation_evaluation_shader,
2706 vertex_shader, captured_varying, true, is_separable);
2709 /** Release program instance
2712 void Program::Release()
2714 const Functions& gl = m_context.getRenderContext().getFunctions();
2716 if (m_invalid_id != m_id)
2718 Use(gl, m_invalid_id);
2720 gl.deleteProgram(m_id);
2721 m_id = m_invalid_id;
2724 m_compute.Release();
2725 m_fragment.Release();
2726 m_geometry.Release();
2727 m_tess_ctrl.Release();
2728 m_tess_eval.Release();
2732 /** Get <pname> for a set of active uniforms
2734 * @param count Number of indices
2735 * @param indices Indices of uniforms
2736 * @param pname Queired pname
2737 * @param params Array that will be filled with values of parameters
2739 void Program::GetActiveUniformsiv(GLsizei count, const GLuint* indices, GLenum pname, GLint* params) const
2741 const Functions& gl = m_context.getRenderContext().getFunctions();
2743 GetActiveUniformsiv(gl, m_id, count, indices, pname, params);
2746 /** Get location of attribute
2748 * @param name Name of attribute
2750 * @return Result of query
2752 glw::GLint Program::GetAttribLocation(const std::string& name) const
2754 const Functions& gl = m_context.getRenderContext().getFunctions();
2756 return GetAttribLocation(gl, m_id, name);
2761 * @param interface Interface to be queried
2762 * @param index Index of resource
2763 * @param property Property to be queried
2764 * @param buf_size Size of <params> buffer
2765 * @param params Results of query
2767 void Program::GetResource(GLenum interface, GLuint index, GLenum property, GLsizei buf_size, GLint* params) const
2769 const Functions& gl = m_context.getRenderContext().getFunctions();
2771 GetResource(gl, m_id, interface, index, property, buf_size, params);
2774 /** Query for index of resource
2776 * @param name Name of resource
2777 * @param interface Interface to be queried
2779 * @return Result of query
2781 glw::GLuint Program::GetResourceIndex(const std::string& name, GLenum interface) const
2783 const Functions& gl = m_context.getRenderContext().getFunctions();
2785 return GetResourceIndex(gl, m_id, name, interface);
2788 /** Get indices for a set of uniforms
2790 * @param count Count number of uniforms
2791 * @param names Names of uniforms
2792 * @param indices Buffer that will be filled with indices
2794 void Program::GetUniformIndices(GLsizei count, const GLchar** names, GLuint* indices) const
2796 const Functions& gl = m_context.getRenderContext().getFunctions();
2798 GetUniformIndices(gl, m_id, count, names, indices);
2801 /** Get uniform location
2803 * @param name Name of uniform
2805 * @return Results of query
2807 glw::GLint Program::GetUniformLocation(const std::string& name) const
2809 const Functions& gl = m_context.getRenderContext().getFunctions();
2811 return GetUniformLocation(gl, m_id, name);
2814 /** Set program as active
2817 void Program::Use() const
2819 const Functions& gl = m_context.getRenderContext().getFunctions();
2824 /** Attach shader to program
2826 * @param gl GL functions
2827 * @param program_id Id of program
2828 * @param shader_id Id of shader
2830 void Program::Attach(const Functions& gl, GLuint program_id, GLuint shader_id)
2833 if ((m_invalid_id == program_id) || (Shader::m_invalid_id == shader_id))
2838 gl.attachShader(program_id, shader_id);
2839 GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
2842 /** Set up captured varyings
2844 * @param gl GL functions
2845 * @param id Id of program
2846 * @param captured_varyings Vector of varyings
2847 * @param capture_interleaved Selects if interleaved or separate mode should be used
2849 void Program::Capture(const Functions& gl, GLuint id, const NameVector& captured_varyings, bool capture_interleaved)
2851 const size_t n_varyings = captured_varyings.size();
2853 if (0 == n_varyings)
2855 /* empty list, skip */
2859 std::vector<const GLchar*> varying_names;
2860 varying_names.resize(n_varyings);
2862 for (size_t i = 0; i < n_varyings; ++i)
2864 varying_names[i] = captured_varyings[i].c_str();
2868 if (true == capture_interleaved)
2870 mode = GL_INTERLEAVED_ATTRIBS;
2874 mode = GL_SEPARATE_ATTRIBS;
2877 gl.transformFeedbackVaryings(id, static_cast<GLsizei>(n_varyings), &varying_names[0], mode);
2878 GLU_EXPECT_NO_ERROR(gl.getError(), "TransformFeedbackVaryings");
2881 /** Create program instance
2883 * @param gl GL functions
2884 * @param out_id Id of program
2886 void Program::Create(const Functions& gl, GLuint& out_id)
2888 const GLuint id = gl.createProgram();
2889 GLU_EXPECT_NO_ERROR(gl.getError(), "CreateProgram");
2891 if (m_invalid_id == id)
2893 TCU_FAIL("Failed to create program");
2899 /** Get <pname> for a set of active uniforms
2901 * @param gl Functions
2902 * @param program_id Id of program
2903 * @param count Number of indices
2904 * @param indices Indices of uniforms
2905 * @param pname Queired pname
2906 * @param params Array that will be filled with values of parameters
2908 void Program::GetActiveUniformsiv(const Functions& gl, GLuint program_id, GLsizei count, const GLuint* indices,
2909 GLenum pname, GLint* params)
2911 gl.getActiveUniformsiv(program_id, count, indices, pname, params);
2912 GLU_EXPECT_NO_ERROR(gl.getError(), "GetActiveUniformsiv");
2915 /** Get indices for a set of uniforms
2917 * @param gl Functions
2918 * @param program_id Id of program
2919 * @param count Count number of uniforms
2920 * @param names Names of uniforms
2921 * @param indices Buffer that will be filled with indices
2923 void Program::GetUniformIndices(const Functions& gl, GLuint program_id, GLsizei count, const GLchar** names,
2926 gl.getUniformIndices(program_id, count, names, indices);
2927 GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformIndices");
2932 * @param gl GL functions
2933 * @param id Id of program
2935 void Program::Link(const Functions& gl, GLuint id)
2937 GLint status = GL_FALSE;
2940 GLU_EXPECT_NO_ERROR(gl.getError(), "LinkProgram");
2942 /* Get link status */
2943 gl.getProgramiv(id, GL_LINK_STATUS, &status);
2944 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");
2946 /* Log link error */
2947 if (GL_TRUE != status)
2949 glw::GLint length = 0;
2950 std::string message;
2952 /* Get error log length */
2953 gl.getProgramiv(id, GL_INFO_LOG_LENGTH, &length);
2954 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");
2956 message.resize(length, 0);
2959 gl.getProgramInfoLog(id, length, 0, &message[0]);
2960 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramInfoLog");
2962 throw LinkageException(message.c_str());
2966 /** Set generic uniform
2968 * @param gl Functions
2969 * @param type Type of uniform
2970 * @param count Length of array
2971 * @param location Location of uniform
2972 * @param data Data that will be used
2974 void Program::Uniform(const Functions& gl, const Type& type, GLsizei count, GLint location, const GLvoid* data)
2978 TCU_FAIL("Uniform is inactive");
2981 switch (type.m_basic_type)
2984 if (1 == type.m_n_columns)
2986 getUniformNdv(gl, type.m_n_rows)(location, count, (const GLdouble*)data);
2987 GLU_EXPECT_NO_ERROR(gl.getError(), "UniformNdv");
2991 getUniformMatrixNdv(gl, type.m_n_columns, type.m_n_rows)(location, count, false, (const GLdouble*)data);
2992 GLU_EXPECT_NO_ERROR(gl.getError(), "UniformMatrixNdv");
2996 if (1 == type.m_n_columns)
2998 getUniformNfv(gl, type.m_n_rows)(location, count, (const GLfloat*)data);
2999 GLU_EXPECT_NO_ERROR(gl.getError(), "UniformNfv");
3003 getUniformMatrixNfv(gl, type.m_n_columns, type.m_n_rows)(location, count, false, (const GLfloat*)data);
3004 GLU_EXPECT_NO_ERROR(gl.getError(), "UniformMatrixNfv");
3008 getUniformNiv(gl, type.m_n_rows)(location, count, (const GLint*)data);
3009 GLU_EXPECT_NO_ERROR(gl.getError(), "UniformNiv");
3012 getUniformNuiv(gl, type.m_n_rows)(location, count, (const GLuint*)data);
3013 GLU_EXPECT_NO_ERROR(gl.getError(), "UniformNuiv");
3016 TCU_FAIL("Invalid enum");
3022 * @param gl GL functions
3023 * @param id Id of program
3025 void Program::Use(const Functions& gl, GLuint id)
3028 GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram");
3031 /** Get location of attribute
3033 * @param gl GL functions
3034 * @param id Id of program
3035 * @param name Name of attribute
3037 * @return Location of attribute
3039 GLint Program::GetAttribLocation(const Functions& gl, GLuint id, const std::string& name)
3041 GLint location = gl.getAttribLocation(id, name.c_str());
3042 GLU_EXPECT_NO_ERROR(gl.getError(), "GetAttribLocation");
3049 * @param gl GL functions
3050 * @param id Id of program
3051 * @param interface Interface to be queried
3052 * @param index Index of resource
3053 * @param property Property to be queried
3054 * @param buf_size Size of <params> buffer
3055 * @param params Results of query
3057 void Program::GetResource(const Functions& gl, GLuint id, GLenum interface, GLuint index, GLenum property,
3058 GLsizei buf_size, GLint* params)
3060 gl.getProgramResourceiv(id, interface, index, 1 /* propCount */, &property, buf_size /* bufSize */, 0 /* length */,
3062 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramResourceiv");
3065 /** Get index of resource
3067 * @param gl GL functions
3068 * @param id Id of program
3069 * @param name Name of resource
3070 * @param interface Program interface to queried
3072 * @return Location of attribute
3074 GLuint Program::GetResourceIndex(const Functions& gl, GLuint id, const std::string& name, GLenum interface)
3076 GLuint index = gl.getProgramResourceIndex(id, interface, name.c_str());
3077 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramResourceIndex");
3082 /** Get location of attribute
3084 * @param gl GL functions
3085 * @param id Id of program
3086 * @param name Name of attribute
3088 * @return Location of uniform
3090 GLint Program::GetUniformLocation(const Functions& gl, GLuint id, const std::string& name)
3092 GLint location = gl.getUniformLocation(id, name.c_str());
3093 GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformLocation");
3100 * @param error_message Error message
3101 * @param compute_shader Source code for compute stage
3102 * @param fragment_shader Source code for fragment stage
3103 * @param geometry_shader Source code for geometry stage
3104 * @param tess_ctrl_shader Source code for tessellation control stage
3105 * @param tess_eval_shader Source code for tessellation evaluation stage
3106 * @param vertex_shader Source code for vertex stage
3108 Program::BuildException::BuildException(const glw::GLchar* error_message, const std::string compute_shader,
3109 const std::string fragment_shader, const std::string geometry_shader,
3110 const std::string tess_ctrl_shader, const std::string tess_eval_shader,
3111 const std::string vertex_shader)
3112 : m_error_message(error_message)
3113 , m_compute_shader(compute_shader)
3114 , m_fragment_shader(fragment_shader)
3115 , m_geometry_shader(geometry_shader)
3116 , m_tess_ctrl_shader(tess_ctrl_shader)
3117 , m_tess_eval_shader(tess_eval_shader)
3118 , m_vertex_shader(vertex_shader)
3122 /** Overwrites std::exception::what method
3124 * @return Message compossed from error message and shader sources
3126 const char* Program::BuildException::what() const throw()
3128 return "Failed to link program";
3131 /** Logs error message and shader sources **/
3132 void Program::BuildException::log(deqp::Context& context) const
3134 context.getTestContext().getLog() << tcu::TestLog::Message << "Link failure: " << m_error_message
3135 << tcu::TestLog::EndMessage;
3137 Shader::LogSource(context, m_vertex_shader, Shader::VERTEX);
3138 Shader::LogSource(context, m_tess_ctrl_shader, Shader::TESS_CTRL);
3139 Shader::LogSource(context, m_tess_eval_shader, Shader::TESS_EVAL);
3140 Shader::LogSource(context, m_geometry_shader, Shader::GEOMETRY);
3141 Shader::LogSource(context, m_fragment_shader, Shader::FRAGMENT);
3142 Shader::LogSource(context, m_compute_shader, Shader::COMPUTE);
3147 * @param message Linking error message
3149 Program::LinkageException::LinkageException(const glw::GLchar* message) : m_error_message(message)
3151 /* Nothing to be done */
3154 /** Returns error messages
3156 * @return Linking error message
3158 const char* Program::LinkageException::what() const throw()
3160 return m_error_message.c_str();
3163 /* Texture constants */
3164 const GLuint Texture::m_invalid_id = -1;
3168 * @param context CTS context.
3170 Texture::Texture(deqp::Context& context) : m_id(m_invalid_id), m_context(context), m_type(TEX_2D)
3172 /* Nothing to done here */
3183 /** Initialize texture instance
3185 * @param tex_type Type of texture
3186 * @param width Width of texture
3187 * @param height Height of texture
3188 * @param depth Depth of texture
3189 * @param internal_format Internal format of texture
3190 * @param format Format of texture data
3191 * @param type Type of texture data
3192 * @param data Texture data
3194 void Texture::Init(TYPES tex_type, GLuint width, GLuint height, GLuint depth, GLenum internal_format, GLenum format,
3195 GLenum type, GLvoid* data)
3197 const Functions& gl = m_context.getRenderContext().getFunctions();
3199 /* Delete previous texture */
3204 /* Generate, bind, allocate storage and upload data */
3206 Bind(gl, m_id, tex_type);
3207 Storage(gl, tex_type, width, height, depth, internal_format);
3208 Update(gl, tex_type, width, height, depth, format, type, data);
3211 /** Initialize buffer texture
3213 * @param internal_format Internal format of texture
3214 * @param buffer_id Id of buffer that will be used as data source
3216 void Texture::Init(GLenum internal_format, GLuint buffer_id)
3218 const Functions& gl = m_context.getRenderContext().getFunctions();
3220 /* Delete previous texture */
3223 m_type = TEX_BUFFER;
3225 /* Generate, bind and attach buffer */
3227 Bind(gl, m_id, TEX_BUFFER);
3228 TexBuffer(gl, buffer_id, internal_format);
3231 /** Release texture instance
3234 void Texture::Release()
3236 if (m_invalid_id != m_id)
3238 const Functions& gl = m_context.getRenderContext().getFunctions();
3240 gl.deleteTextures(1, &m_id);
3241 m_id = m_invalid_id;
3245 /** Bind texture to its target
3248 void Texture::Bind() const
3250 const Functions& gl = m_context.getRenderContext().getFunctions();
3252 Bind(gl, m_id, m_type);
3255 /** Get texture data
3257 * @param format Format of data
3258 * @param type Type of data
3259 * @param out_data Buffer for data
3261 void Texture::Get(GLenum format, GLenum type, GLvoid* out_data) const
3263 const Functions& gl = m_context.getRenderContext().getFunctions();
3265 Bind(gl, m_id, m_type);
3266 Get(gl, m_type, format, type, out_data);
3269 /** Bind texture to target
3271 * @param gl GL functions
3272 * @param id Id of texture
3273 * @param tex_type Type of texture
3275 void Texture::Bind(const Functions& gl, GLuint id, TYPES tex_type)
3277 GLenum target = GetTargetGLenum(tex_type);
3279 gl.bindTexture(target, id);
3280 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
3283 /** Generate texture instance
3285 * @param gl GL functions
3286 * @param out_id Id of texture
3288 void Texture::Generate(const Functions& gl, GLuint& out_id)
3290 GLuint id = m_invalid_id;
3292 gl.genTextures(1, &id);
3293 GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures");
3295 if (m_invalid_id == id)
3297 TCU_FAIL("Invalid id");
3303 /** Get texture data
3305 * @param gl GL functions
3306 * @param format Format of data
3307 * @param type Type of data
3308 * @param out_data Buffer for data
3310 void Texture::Get(const Functions& gl, TYPES tex_type, GLenum format, GLenum type, GLvoid* out_data)
3312 GLenum target = GetTargetGLenum(tex_type);
3314 if (TEX_CUBE != tex_type)
3316 gl.getTexImage(target, 0 /* level */, format, type, out_data);
3317 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexImage");
3324 if ((GL_RGBA != format) && (GL_UNSIGNED_BYTE != type))
3326 TCU_FAIL("Not implemented");
3329 GLuint texel_size = 4;
3331 gl.getTexLevelParameteriv(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0 /* level */, GL_TEXTURE_WIDTH, &width);
3332 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv");
3334 gl.getTexLevelParameteriv(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0 /* level */, GL_TEXTURE_HEIGHT, &height);
3335 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv");
3337 const GLuint image_size = width * height * texel_size;
3339 gl.getTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0 /* level */, format, type,
3340 (GLvoid*)((GLchar*)out_data + (image_size * 0)));
3341 gl.getTexImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0 /* level */, format, type,
3342 (GLvoid*)((GLchar*)out_data + (image_size * 1)));
3343 gl.getTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0 /* level */, format, type,
3344 (GLvoid*)((GLchar*)out_data + (image_size * 2)));
3345 gl.getTexImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0 /* level */, format, type,
3346 (GLvoid*)((GLchar*)out_data + (image_size * 3)));
3347 gl.getTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0 /* level */, format, type,
3348 (GLvoid*)((GLchar*)out_data + (image_size * 4)));
3349 gl.getTexImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0 /* level */, format, type,
3350 (GLvoid*)((GLchar*)out_data + (image_size * 5)));
3351 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexImage");
3355 /** Allocate storage for texture
3357 * @param gl GL functions
3358 * @param tex_type Type of texture
3359 * @param width Width of texture
3360 * @param height Height of texture
3361 * @param depth Depth of texture
3362 * @param internal_format Internal format of texture
3364 void Texture::Storage(const Functions& gl, TYPES tex_type, GLuint width, GLuint height, GLuint depth,
3365 GLenum internal_format)
3367 static const GLuint levels = 1;
3369 GLenum target = GetTargetGLenum(tex_type);
3374 gl.texStorage1D(target, levels, internal_format, width);
3375 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage1D");
3381 gl.texStorage2D(target, levels, internal_format, width, height);
3382 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2D");
3386 gl.texStorage3D(target, levels, internal_format, width, height, depth);
3387 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage3D");
3390 TCU_FAIL("Invliad enum");
3395 /** Attach buffer as source of texture buffer data
3397 * @param gl GL functions
3398 * @param internal_format Internal format of texture
3399 * @param buffer_id Id of buffer that will be used as data source
3401 void Texture::TexBuffer(const Functions& gl, GLenum internal_format, GLuint& buffer_id)
3403 gl.texBuffer(GL_TEXTURE_BUFFER, internal_format, buffer_id);
3404 GLU_EXPECT_NO_ERROR(gl.getError(), "TexBuffer");
3407 /** Update contents of texture
3409 * @param gl GL functions
3410 * @param tex_type Type of texture
3411 * @param width Width of texture
3412 * @param height Height of texture
3413 * @param format Format of data
3414 * @param type Type of data
3415 * @param data Buffer with image data
3417 void Texture::Update(const Functions& gl, TYPES tex_type, GLuint width, GLuint height, GLuint depth, GLenum format,
3418 GLenum type, GLvoid* data)
3420 static const GLuint level = 0;
3422 GLenum target = GetTargetGLenum(tex_type);
3427 gl.texSubImage1D(target, level, 0 /* x */, width, format, type, data);
3428 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage1D");
3433 gl.texSubImage2D(target, level, 0 /* x */, 0 /* y */, width, height, format, type, data);
3434 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2D");
3437 gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, level, 0 /* x */, 0 /* y */, width, height, format, type,
3439 gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, level, 0 /* x */, 0 /* y */, width, height, format, type,
3441 gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, level, 0 /* x */, 0 /* y */, width, height, format, type,
3443 gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, level, 0 /* x */, 0 /* y */, width, height, format, type,
3445 gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, level, 0 /* x */, 0 /* y */, width, height, format, type,
3447 gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, level, 0 /* x */, 0 /* y */, width, height, format, type,
3449 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2D");
3453 gl.texSubImage3D(target, level, 0 /* x */, 0 /* y */, 0 /* z */, width, height, depth, format, type, data);
3454 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage3D");
3457 TCU_FAIL("Invliad enum");
3462 /** Get target for given texture type
3464 * @param type Type of texture
3468 GLenum Texture::GetTargetGLenum(TYPES type)
3475 result = GL_TEXTURE_BUFFER;
3478 result = GL_TEXTURE_2D;
3481 result = GL_TEXTURE_RECTANGLE;
3484 result = GL_TEXTURE_2D_ARRAY;
3487 result = GL_TEXTURE_3D;
3490 result = GL_TEXTURE_CUBE_MAP;
3493 result = GL_TEXTURE_1D;
3496 result = GL_TEXTURE_1D_ARRAY;
3503 /* VertexArray constants */
3504 const GLuint VertexArray::m_invalid_id = -1;
3508 * @param context CTS context.
3510 VertexArray::VertexArray(deqp::Context& context) : m_id(m_invalid_id), m_context(context)
3517 VertexArray::~VertexArray()
3522 /** Initialize vertex array instance
3525 void VertexArray::Init()
3527 /* Delete previous instance */
3530 const Functions& gl = m_context.getRenderContext().getFunctions();
3535 /** Release vertex array object instance
3538 void VertexArray::Release()
3540 if (m_invalid_id != m_id)
3542 const Functions& gl = m_context.getRenderContext().getFunctions();
3544 gl.deleteVertexArrays(1, &m_id);
3546 m_id = m_invalid_id;
3550 /** Set attribute in VAO
3552 * @param index Index of attribute
3553 * @param type Type of attribute
3554 * @param n_array_elements Arary length
3555 * @param normalized Selectis if values should be normalized
3556 * @param stride Stride
3557 * @param pointer Pointer to data, or offset in buffer
3559 void VertexArray::Attribute(GLuint index, const Type& type, GLuint n_array_elements, GLboolean normalized,
3560 GLsizei stride, const GLvoid* pointer)
3562 const Functions& gl = m_context.getRenderContext().getFunctions();
3564 AttribPointer(gl, index, type, n_array_elements, normalized, stride, pointer);
3565 Enable(gl, index, type, n_array_elements);
3568 /** Binds Vertex array object
3571 void VertexArray::Bind()
3573 const Functions& gl = m_context.getRenderContext().getFunctions();
3578 /** Set attribute in VAO
3580 * @param gl Functions
3581 * @param index Index of attribute
3582 * @param type Type of attribute
3583 * @param n_array_elements Arary length
3584 * @param normalized Selectis if values should be normalized
3585 * @param stride Stride
3586 * @param pointer Pointer to data, or offset in buffer
3588 void VertexArray::AttribPointer(const Functions& gl, GLuint index, const Type& type, GLuint n_array_elements,
3589 GLboolean normalized, GLsizei stride, const GLvoid* pointer)
3591 const GLuint basic_type_size = Type::GetTypeSize(type.m_basic_type);
3592 const GLint size = (GLint)type.m_n_rows;
3593 const GLuint column_size = (GLuint)size * basic_type_size;
3594 const GLenum gl_type = Type::GetTypeGLenum(type.m_basic_type);
3598 /* If attribute is not an array */
3599 if (0 == n_array_elements)
3601 n_array_elements = 1;
3604 /* For each element in array */
3605 for (GLuint element = 0; element < n_array_elements; ++element)
3607 /* For each column in matrix */
3608 for (GLuint column = 1; column <= type.m_n_columns; ++column)
3610 /* Calculate offset */
3611 const GLvoid* ptr = (GLubyte*)pointer + offset;
3613 /* Set up attribute */
3614 switch (type.m_basic_type)
3617 gl.vertexAttribPointer(index, size, gl_type, normalized, stride, ptr);
3618 GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttribPointer");
3622 gl.vertexAttribIPointer(index, size, gl_type, stride, ptr);
3623 GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttribIPointer");
3626 gl.vertexAttribLPointer(index, size, gl_type, stride, ptr);
3627 GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttribLPointer");
3630 TCU_FAIL("Invalid enum");
3634 offset += column_size;
3640 /** Binds Vertex array object
3642 * @param gl GL functions
3643 * @param id ID of vertex array object
3645 void VertexArray::Bind(const glw::Functions& gl, glw::GLuint id)
3647 gl.bindVertexArray(id);
3648 GLU_EXPECT_NO_ERROR(gl.getError(), "BindVertexArray");
3651 /** Disable attribute in VAO
3653 * @param gl Functions
3654 * @param index Index of attribute
3655 * @param type Type of attribute
3656 * @param n_array_elements Arary length
3658 void VertexArray::Disable(const Functions& gl, GLuint index, const Type& type, GLuint n_array_elements)
3660 /* If attribute is not an array */
3661 if (0 == n_array_elements)
3663 n_array_elements = 1;
3666 /* For each element in array */
3667 for (GLuint element = 0; element < n_array_elements; ++element)
3669 /* For each column in matrix */
3670 for (GLuint column = 1; column <= type.m_n_columns; ++column)
3672 /* Enable attribute array */
3673 gl.disableVertexAttribArray(index);
3674 GLU_EXPECT_NO_ERROR(gl.getError(), "DisableVertexAttribArray");
3682 /** Set divisor for attribute
3684 * @param gl Functions
3685 * @param index Index of attribute
3686 * @param divisor New divisor value
3688 void VertexArray::Divisor(const Functions& gl, GLuint index, GLuint divisor)
3690 gl.vertexAttribDivisor(index, divisor);
3691 GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttribDivisor");
3694 /** Enables attribute in VAO
3696 * @param gl Functions
3697 * @param index Index of attribute
3698 * @param type Type of attribute
3699 * @param n_array_elements Arary length
3701 void VertexArray::Enable(const Functions& gl, GLuint index, const Type& type, GLuint n_array_elements)
3703 /* If attribute is not an array */
3704 if (0 == n_array_elements)
3706 n_array_elements = 1;
3709 /* For each element in array */
3710 for (GLuint element = 0; element < n_array_elements; ++element)
3712 /* For each column in matrix */
3713 for (GLuint column = 1; column <= type.m_n_columns; ++column)
3715 /* Enable attribute array */
3716 gl.enableVertexAttribArray(index);
3717 GLU_EXPECT_NO_ERROR(gl.getError(), "EnableVertexAttribArray");
3725 /** Generates Vertex array object
3727 * @param gl GL functions
3728 * @param out_id ID of vertex array object
3730 void VertexArray::Generate(const glw::Functions& gl, glw::GLuint& out_id)
3732 GLuint id = m_invalid_id;
3734 gl.genVertexArrays(1, &id);
3735 GLU_EXPECT_NO_ERROR(gl.getError(), "GenVertexArrays");
3737 if (m_invalid_id == id)
3739 TCU_FAIL("Invalid id");
3745 /* Constatns used by Variable */
3746 const GLint Variable::m_automatic_location = -1;
3748 /** Copy constructor
3751 Variable::Variable(const Variable& var)
3752 : m_data(var.m_data)
3753 , m_data_size(var.m_data_size)
3754 , m_descriptor(var.m_descriptor.m_name.c_str(), var.m_descriptor.m_qualifiers.c_str(),
3755 var.m_descriptor.m_expected_component, var.m_descriptor.m_expected_location,
3756 var.m_descriptor.m_builtin, var.m_descriptor.m_normalized, var.m_descriptor.m_n_array_elements,
3757 var.m_descriptor.m_expected_stride_of_element, var.m_descriptor.m_offset)
3758 , m_storage(var.m_storage)
3760 m_descriptor.m_type = var.m_descriptor.m_type;
3762 if (BUILTIN != var.m_descriptor.m_type)
3764 m_descriptor.m_interface = var.m_descriptor.m_interface;
3768 /** Get code that defines variable
3770 * @param flavour Provides info if variable is array or not
3772 * @return String with code
3774 std::string Variable::GetDefinition(FLAVOUR flavour) const
3776 return m_descriptor.GetDefinition(flavour, m_storage);
3779 /** Calcualtes stride of variable
3781 * @return Calculated value
3783 GLuint Variable::GetStride() const
3785 GLint variable_stride = 0;
3787 if (0 == m_descriptor.m_n_array_elements)
3789 variable_stride = m_descriptor.m_expected_stride_of_element;
3793 variable_stride = m_descriptor.m_expected_stride_of_element * m_descriptor.m_n_array_elements;
3796 return variable_stride;
3799 /** Check if variable is block
3801 * @return true if variable type is block, false otherwise
3803 bool Variable::IsBlock() const
3805 if (BUILTIN == m_descriptor.m_type)
3810 const Interface* interface = m_descriptor.m_interface;
3813 TCU_FAIL("Nullptr");
3816 return (Interface::BLOCK == interface->m_type);
3819 /** Check if variable is struct
3821 * @return true if variable type is struct, false otherwise
3823 bool Variable::IsStruct() const
3825 if (BUILTIN == m_descriptor.m_type)
3830 const Interface* interface = m_descriptor.m_interface;
3833 TCU_FAIL("Nullptr");
3836 return (Interface::STRUCT == interface->m_type);
3838 /** Get code that reference variable
3840 * @param parent_name Name of parent
3841 * @param variable Descriptor of variable
3842 * @param flavour Provides info about how variable should be referenced
3843 * @param array_index Index of array, ignored when variable is not array
3845 * @return String with code
3847 std::string Variable::GetReference(const std::string& parent_name, const Descriptor& variable, FLAVOUR flavour,
3853 if (false == parent_name.empty())
3857 name.append(variable.m_name);
3861 name = variable.m_name;
3867 case Utils::Variable::BASIC:
3870 case Utils::Variable::ARRAY:
3874 case Utils::Variable::INDEXED_BY_INVOCATION_ID:
3875 name.append("[gl_InvocationID]");
3879 /* Assumption that both variables have same lengths */
3880 if (0 != variable.m_n_array_elements)
3883 sprintf(buffer, "%d", array_index);
3885 name.append(buffer);
3892 /** Get "flavour" of varying
3894 * @param stage Stage of shader
3895 * @param direction Selects if varying is in or out
3899 Variable::FLAVOUR Variable::GetFlavour(Shader::STAGES stage, VARYING_DIRECTION direction)
3901 FLAVOUR result = BASIC;
3905 case Shader::GEOMETRY:
3906 case Shader::TESS_EVAL:
3907 if (INPUT == direction)
3912 case Shader::TESS_CTRL:
3913 result = INDEXED_BY_INVOCATION_ID;
3922 /** Constructor, for built-in types
3925 * @param qualifiers Qualifiers
3926 * @param expected_component Expected component of variable
3927 * @param expected_location Expected location
3929 * @param normalized Selects if data should be normalized
3930 * @param n_array_elements Length of array
3931 * @param expected_stride_of_element Expected stride of element
3932 * @param offset Offset
3934 Variable::Descriptor::Descriptor(const GLchar* name, const GLchar* qualifiers, GLint expected_component,
3935 GLint expected_location, const Type& type, GLboolean normalized,
3936 GLuint n_array_elements, GLint expected_stride_of_element, GLuint offset)
3937 : m_expected_component(expected_component)
3938 , m_expected_location(expected_location)
3939 , m_expected_stride_of_element(expected_stride_of_element)
3940 , m_n_array_elements(n_array_elements)
3942 , m_normalized(normalized)
3944 , m_qualifiers(qualifiers)
3950 /** Constructor, for interface types
3953 * @param qualifiers Qualifiers
3954 * @param expected_component Expected component of variable
3955 * @param expected_location Expected location
3956 * @param interface Interface of variable
3957 * @param n_array_elements Length of array
3958 * @param expected_stride_of_element Expected stride of element
3959 * @param offset Offset
3961 Variable::Descriptor::Descriptor(const GLchar* name, const GLchar* qualifiers, GLint expected_componenet,
3962 GLint expected_location, Interface* interface, GLuint n_array_elements,
3963 GLint expected_stride_of_element, GLuint offset)
3964 : m_expected_component(expected_componenet)
3965 , m_expected_location(expected_location)
3966 , m_expected_stride_of_element(expected_stride_of_element)
3967 , m_n_array_elements(n_array_elements)
3969 , m_normalized(GL_FALSE)
3971 , m_qualifiers(qualifiers)
3973 , m_interface(interface)
3977 /** Get definition of variable
3979 * @param flavour Flavour of variable
3980 * @param storage Storage used for variable
3982 * @return code with defintion
3984 std::string Variable::Descriptor::GetDefinition(FLAVOUR flavour, STORAGE storage) const
3986 static const GLchar* basic_template = "QUALIFIERS STORAGETYPE NAMEARRAY;";
3987 static const GLchar* array_template = "QUALIFIERS STORAGETYPE NAME[]ARRAY;";
3988 const GLchar* storage_str = 0;
3990 std::string definition;
3991 size_t position = 0;
3993 /* Select definition template */
3997 definition = basic_template;
4000 case INDEXED_BY_INVOCATION_ID:
4001 definition = array_template;
4004 TCU_FAIL("Invliad enum");
4008 if (BUILTIN != m_type)
4010 if (0 == m_interface)
4012 TCU_FAIL("Nullptr");
4017 if (true == m_qualifiers.empty())
4019 replaceToken("QUALIFIERS ", position, "", definition);
4023 replaceToken("QUALIFIERS", position, m_qualifiers.c_str(), definition);
4026 // According to spec: int, uint, and double type must always be declared with flat qualifier
4027 bool flat_qualifier = false;
4028 if (m_type != BUILTIN && m_interface != NULL)
4030 if (m_interface->m_members[0].m_builtin.m_basic_type == Utils::Type::Int ||
4031 m_interface->m_members[0].m_builtin.m_basic_type == Utils::Type::Uint ||
4032 m_interface->m_members[0].m_builtin.m_basic_type == Utils::Type::Double)
4034 flat_qualifier = true;
4041 storage_str = flat_qualifier ? "flat in " : "in ";
4043 case VARYING_OUTPUT:
4044 storage_str = "out ";
4047 storage_str = "uniform ";
4050 storage_str = "buffer ";
4056 TCU_FAIL("Invalid enum");
4060 replaceToken("STORAGE", position, storage_str, definition);
4063 if (BUILTIN == m_type)
4065 replaceToken("TYPE", position, m_builtin.GetGLSLTypeName(), definition);
4069 if (Interface::STRUCT == m_interface->m_type)
4071 replaceToken("TYPE", position, m_interface->m_name.c_str(), definition);
4075 const std::string& block_definition = m_interface->GetDefinition();
4077 replaceToken("TYPE", position, block_definition.c_str(), definition);
4082 replaceToken("NAME", position, m_name.c_str(), definition);
4085 if (0 == m_n_array_elements)
4087 replaceToken("ARRAY", position, "", definition);
4092 sprintf(buffer, "[%d]", m_n_array_elements);
4094 replaceToken("ARRAY", position, buffer, definition);
4101 /** Get definitions for variables collected in vector
4103 * @param vector Collection of variables
4104 * @param flavour Flavour of variables
4106 * @return Code with definitions
4108 std::string GetDefinitions(const Variable::PtrVector& vector, Variable::FLAVOUR flavour)
4110 std::string list = Utils::g_list;
4111 size_t position = 0;
4113 for (GLuint i = 0; i < vector.size(); ++i)
4115 Utils::insertElementOfList(vector[i]->GetDefinition(flavour).c_str(), "\n", position, list);
4118 Utils::endList("", position, list);
4123 /** Get definitions for interfaces collected in vector
4125 * @param vector Collection of interfaces
4127 * @return Code with definitions
4129 std::string GetDefinitions(const Interface::PtrVector& vector)
4131 std::string list = Utils::g_list;
4132 size_t position = 0;
4134 for (GLuint i = 0; i < vector.size(); ++i)
4136 Utils::insertElementOfList(vector[i]->GetDefinition().c_str(), "\n", position, list);
4139 Utils::endList("", position, list);
4147 * @param type Type of interface
4149 Interface::Interface(const GLchar* name, Interface::TYPE type) : m_name(name), m_type(type)
4153 /** Adds member to interface
4155 * @param member Descriptor of new member
4157 * @return Pointer to just created member
4159 Variable::Descriptor* Interface::AddMember(const Variable::Descriptor& member)
4161 m_members.push_back(member);
4163 return &m_members.back();
4166 /** Get definition of interface
4168 * @param Code with definition
4170 std::string Interface::GetDefinition() const
4172 std::string definition;
4173 size_t position = 0;
4175 const GLchar* member_list = " MEMBER_DEFINITION\nMEMBER_LIST";
4177 if (STRUCT == m_type)
4179 definition = "struct NAME {\nMEMBER_LIST};";
4183 definition = "NAME {\nMEMBER_LIST}";
4187 replaceToken("NAME", position, m_name.c_str(), definition);
4190 for (GLuint i = 0; i < m_members.size(); ++i)
4192 const size_t start_position = position;
4193 const std::string& member_definition = m_members[i].GetDefinition(Variable::BASIC, Variable::MEMBER);
4196 replaceToken("MEMBER_LIST", position, member_list, definition);
4198 /* Move back position */
4199 position = start_position;
4201 /* Member definition */
4202 replaceToken("MEMBER_DEFINITION", position, member_definition.c_str(), definition);
4205 /* Remove last member list */
4206 replaceToken("MEMBER_LIST", position, "", definition);
4212 /** Adds member of built-in type to interface
4215 * @param qualifiers Qualifiers
4216 * @param expected_component Expected component of variable
4217 * @param expected_location Expected location
4219 * @param normalized Selects if data should be normalized
4220 * @param n_array_elements Length of array
4221 * @param expected_stride_of_element Expected stride of element
4222 * @param offset Offset
4224 * @return Pointer to just created member
4226 Variable::Descriptor* Interface::Member(const GLchar* name, const GLchar* qualifiers, GLint expected_component,
4227 GLint expected_location, const Type& type, GLboolean normalized,
4228 GLuint n_array_elements, GLint expected_stride_of_element, GLuint offset)
4230 return AddMember(Variable::Descriptor(name, qualifiers, expected_component, expected_location, type, normalized,
4231 n_array_elements, expected_stride_of_element, offset));
4234 /** Adds member of interface type to interface
4237 * @param qualifiers Qualifiers
4238 * @param expected_component Expected component of variable
4239 * @param expected_location Expected location
4241 * @param normalized Selects if data should be normalized
4242 * @param n_array_elements Length of array
4243 * @param expected_stride_of_element Expected stride of element
4244 * @param offset Offset
4246 * @return Pointer to just created member
4248 Variable::Descriptor* Interface::Member(const GLchar* name, const GLchar* qualifiers, GLint expected_component,
4249 GLint expected_location, Interface* nterface, GLuint n_array_elements,
4250 GLint expected_stride_of_element, GLuint offset)
4252 return AddMember(Variable::Descriptor(name, qualifiers, expected_component, expected_location, nterface,
4253 n_array_elements, expected_stride_of_element, offset));
4256 /** Clears contents of vector of pointers
4258 * @tparam T Type of elements
4260 * @param vector Collection to be cleared
4262 template <typename T>
4263 void clearPtrVector(std::vector<T*>& vector)
4265 for (size_t i = 0; i < vector.size(); ++i)
4282 * @param stage Stage described by that interface
4284 ShaderInterface::ShaderInterface(Shader::STAGES stage) : m_stage(stage)
4286 /* Nothing to be done */
4289 /** Get definitions of globals
4291 * @return Code with definitions
4293 std::string ShaderInterface::GetDefinitionsGlobals() const
4298 /** Get definitions of inputs
4300 * @return Code with definitions
4302 std::string ShaderInterface::GetDefinitionsInputs() const
4304 Variable::FLAVOUR flavour = Variable::GetFlavour(m_stage, Variable::INPUT);
4306 return GetDefinitions(m_inputs, flavour);
4309 /** Get definitions of outputs
4311 * @return Code with definitions
4313 std::string ShaderInterface::GetDefinitionsOutputs() const
4315 Variable::FLAVOUR flavour = Variable::GetFlavour(m_stage, Variable::OUTPUT);
4317 return GetDefinitions(m_outputs, flavour);
4320 /** Get definitions of buffers
4322 * @return Code with definitions
4324 std::string ShaderInterface::GetDefinitionsSSBs() const
4326 return GetDefinitions(m_ssb_blocks, Variable::BASIC);
4329 /** Get definitions of uniforms
4331 * @return Code with definitions
4333 std::string ShaderInterface::GetDefinitionsUniforms() const
4335 return GetDefinitions(m_uniforms, Variable::BASIC);
4340 * @param in Input variable
4341 * @param out Output variable
4343 VaryingConnection::VaryingConnection(Variable* in, Variable* out) : m_in(in), m_out(out)
4345 /* NBothing to be done here */
4348 /** Adds new varying connection to given stage
4350 * @param stage Shader stage
4351 * @param in In varying
4352 * @param out Out varying
4354 void VaryingPassthrough::Add(Shader::STAGES stage, Variable* in, Variable* out)
4356 VaryingConnection::Vector& vector = Get(stage);
4358 vector.push_back(VaryingConnection(in, out));
4361 /** Get all passthrough connections for given stage
4363 * @param stage Shader stage
4365 * @return Vector of connections
4367 VaryingConnection::Vector& VaryingPassthrough::Get(Shader::STAGES stage)
4369 VaryingConnection::Vector* result = 0;
4373 case Shader::FRAGMENT:
4374 result = &m_fragment;
4376 case Shader::GEOMETRY:
4377 result = &m_geometry;
4379 case Shader::TESS_CTRL:
4380 result = &m_tess_ctrl;
4382 case Shader::TESS_EVAL:
4383 result = &m_tess_eval;
4385 case Shader::VERTEX:
4389 TCU_FAIL("Invalid enum");
4398 ProgramInterface::ProgramInterface()
4399 : m_compute(Shader::COMPUTE)
4400 , m_vertex(Shader::VERTEX)
4401 , m_tess_ctrl(Shader::TESS_CTRL)
4402 , m_tess_eval(Shader::TESS_EVAL)
4403 , m_geometry(Shader::GEOMETRY)
4404 , m_fragment(Shader::FRAGMENT)
4411 ProgramInterface::~ProgramInterface()
4413 clearPtrVector(m_blocks);
4414 clearPtrVector(m_structures);
4417 /** Adds new interface
4422 * @return Pointer to created interface
4424 Interface* ProgramInterface::AddInterface(const GLchar* name, Interface::TYPE type)
4426 Interface* interface = 0;
4428 if (Interface::STRUCT == type)
4430 interface = new Interface(name, type);
4432 m_structures.push_back(interface);
4436 interface = new Interface(name, type);
4438 m_blocks.push_back(interface);
4444 /** Adds new block interface
4448 * @return Pointer to created interface
4450 Interface* ProgramInterface::Block(const GLchar* name)
4452 return AddInterface(name, Interface::BLOCK);
4455 /** Get interface of given shader stage
4457 * @param stage Shader stage
4459 * @return Reference to stage interface
4461 ShaderInterface& ProgramInterface::GetShaderInterface(Shader::STAGES stage)
4463 ShaderInterface* interface = 0;
4467 case Shader::COMPUTE:
4468 interface = &m_compute;
4470 case Shader::FRAGMENT:
4471 interface = &m_fragment;
4473 case Shader::GEOMETRY:
4474 interface = &m_geometry;
4476 case Shader::TESS_CTRL:
4477 interface = &m_tess_ctrl;
4479 case Shader::TESS_EVAL:
4480 interface = &m_tess_eval;
4482 case Shader::VERTEX:
4483 interface = &m_vertex;
4486 TCU_FAIL("Invalid enum");
4492 /** Get interface of given shader stage
4494 * @param stage Shader stage
4496 * @return Reference to stage interface
4498 const ShaderInterface& ProgramInterface::GetShaderInterface(Shader::STAGES stage) const
4500 const ShaderInterface* interface = 0;
4504 case Shader::COMPUTE:
4505 interface = &m_compute;
4507 case Shader::FRAGMENT:
4508 interface = &m_fragment;
4510 case Shader::GEOMETRY:
4511 interface = &m_geometry;
4513 case Shader::TESS_CTRL:
4514 interface = &m_tess_ctrl;
4516 case Shader::TESS_EVAL:
4517 interface = &m_tess_eval;
4519 case Shader::VERTEX:
4520 interface = &m_vertex;
4523 TCU_FAIL("Invalid enum");
4529 /** Clone interface of Vertex shader stage to other stages
4530 * It creates matching inputs, outputs, uniforms and buffers in other stages.
4531 * There are no additional outputs for FRAGMENT shader generated.
4533 * @param varying_passthrough Collection of varyings connections
4535 void ProgramInterface::CloneVertexInterface(VaryingPassthrough& varying_passthrough)
4537 /* VS outputs >> TCS inputs >> TCS outputs >> .. >> FS inputs */
4538 for (size_t i = 0; i < m_vertex.m_outputs.size(); ++i)
4540 const Variable& vs_var = *m_vertex.m_outputs[i];
4541 const GLchar* prefix = GetStagePrefix(Shader::VERTEX, vs_var.m_storage);
4543 cloneVariableForStage(vs_var, Shader::TESS_CTRL, prefix, varying_passthrough);
4544 cloneVariableForStage(vs_var, Shader::TESS_EVAL, prefix, varying_passthrough);
4545 cloneVariableForStage(vs_var, Shader::GEOMETRY, prefix, varying_passthrough);
4546 cloneVariableForStage(vs_var, Shader::FRAGMENT, prefix, varying_passthrough);
4549 /* Copy uniforms from VS to other stages */
4550 for (size_t i = 0; i < m_vertex.m_uniforms.size(); ++i)
4552 Variable& vs_var = *m_vertex.m_uniforms[i];
4553 const GLchar* prefix = GetStagePrefix(Shader::VERTEX, vs_var.m_storage);
4555 cloneVariableForStage(vs_var, Shader::COMPUTE, prefix, varying_passthrough);
4556 cloneVariableForStage(vs_var, Shader::TESS_CTRL, prefix, varying_passthrough);
4557 cloneVariableForStage(vs_var, Shader::TESS_EVAL, prefix, varying_passthrough);
4558 cloneVariableForStage(vs_var, Shader::GEOMETRY, prefix, varying_passthrough);
4559 cloneVariableForStage(vs_var, Shader::FRAGMENT, prefix, varying_passthrough);
4561 /* Uniform blocks needs unique binding */
4562 if (true == vs_var.IsBlock())
4564 replaceBinding(vs_var, Shader::VERTEX);
4568 /* Copy SSBs from VS to other stages */
4569 for (size_t i = 0; i < m_vertex.m_ssb_blocks.size(); ++i)
4571 Variable& vs_var = *m_vertex.m_ssb_blocks[i];
4572 const GLchar* prefix = GetStagePrefix(Shader::VERTEX, vs_var.m_storage);
4574 cloneVariableForStage(vs_var, Shader::COMPUTE, prefix, varying_passthrough);
4575 cloneVariableForStage(vs_var, Shader::TESS_CTRL, prefix, varying_passthrough);
4576 cloneVariableForStage(vs_var, Shader::TESS_EVAL, prefix, varying_passthrough);
4577 cloneVariableForStage(vs_var, Shader::GEOMETRY, prefix, varying_passthrough);
4578 cloneVariableForStage(vs_var, Shader::FRAGMENT, prefix, varying_passthrough);
4580 /* SSBs blocks needs unique binding */
4581 if (true == vs_var.IsBlock())
4583 replaceBinding(vs_var, Shader::VERTEX);
4587 m_compute.m_globals = m_vertex.m_globals;
4588 m_fragment.m_globals = m_vertex.m_globals;
4589 m_geometry.m_globals = m_vertex.m_globals;
4590 m_tess_ctrl.m_globals = m_vertex.m_globals;
4591 m_tess_eval.m_globals = m_vertex.m_globals;
4594 /** Clone variable for specific stage
4596 * @param variable Variable
4597 * @param stage Requested stage
4598 * @param prefix Prefix used in variable name that is specific for original stage
4599 * @param varying_passthrough Collection of varyings connections
4601 void ProgramInterface::cloneVariableForStage(const Variable& variable, Shader::STAGES stage, const GLchar* prefix,
4602 VaryingPassthrough& varying_passthrough)
4604 switch (variable.m_storage)
4606 case Variable::VARYING_OUTPUT:
4608 Variable* in = cloneVariableForStage(variable, stage, Variable::VARYING_INPUT, prefix);
4610 if (Shader::FRAGMENT != stage)
4612 Variable* out = cloneVariableForStage(variable, stage, Variable::VARYING_OUTPUT, prefix);
4613 varying_passthrough.Add(stage, in, out);
4617 case Variable::UNIFORM:
4619 cloneVariableForStage(variable, stage, variable.m_storage, prefix);
4622 TCU_FAIL("Invalid enum");
4627 /** Clone variable for specific stage
4629 * @param variable Variable
4630 * @param stage Requested stage
4631 * @param storage Storage used by variable
4632 * @param prefix Prefix used in variable name that is specific for original stage
4634 * @return New variable
4636 Variable* ProgramInterface::cloneVariableForStage(const Variable& variable, Shader::STAGES stage,
4637 Variable::STORAGE storage, const GLchar* prefix)
4639 /* Initialize with original variable */
4640 Variable* var = new Variable(variable);
4643 TCU_FAIL("Memory allocation");
4646 /* Set up storage */
4647 var->m_storage = storage;
4650 std::string name = variable.m_descriptor.m_name;
4652 /* Prefix name with stage ID, empty means default block */
4653 if (false == name.empty())
4655 size_t position = 0;
4656 const GLchar* stage_prefix = GetStagePrefix(stage, storage);
4657 Utils::replaceToken(prefix, position, stage_prefix, name);
4659 var->m_descriptor.m_name = name;
4662 const bool is_block = variable.IsBlock();
4663 if (true == is_block)
4665 const Interface* interface = variable.m_descriptor.m_interface;
4667 Interface* block = CloneBlockForStage(*interface, stage, storage, prefix);
4669 var->m_descriptor.m_interface = block;
4672 /* Store variable */
4673 ShaderInterface& si = GetShaderInterface(stage);
4674 Variable* result = 0;
4678 case Variable::VARYING_INPUT:
4679 si.m_inputs.push_back(var);
4680 result = si.m_inputs.back();
4682 case Variable::VARYING_OUTPUT:
4683 si.m_outputs.push_back(var);
4684 result = si.m_outputs.back();
4686 case Variable::UNIFORM:
4687 /* Uniform blocks needs unique binding */
4688 if (true == is_block)
4690 replaceBinding(*var, stage);
4693 si.m_uniforms.push_back(var);
4694 result = si.m_uniforms.back();
4697 /* SSBs needs unique binding */
4698 if (true == is_block)
4700 replaceBinding(*var, stage);
4703 si.m_ssb_blocks.push_back(var);
4704 result = si.m_ssb_blocks.back();
4707 TCU_FAIL("Invalid enum");
4714 /** clone block to specific stage
4716 * @param block Block to be copied
4717 * @param stage Specific stage
4718 * @param storage Storage used by block
4719 * @param prefix Prefix used in block name
4721 * @return New interface
4723 Interface* ProgramInterface::CloneBlockForStage(const Interface& block, Shader::STAGES stage, Variable::STORAGE storage,
4724 const GLchar* prefix)
4727 std::string name = block.m_name;
4729 /* Prefix name with stage ID */
4730 size_t position = 0;
4731 const GLchar* stage_prefix = GetStagePrefix(stage, storage);
4732 Utils::replaceToken(prefix, position, stage_prefix, name);
4734 Interface* ptr = GetBlock(name.c_str());
4738 ptr = AddInterface(name.c_str(), Interface::BLOCK);
4741 ptr->m_members = block.m_members;
4746 /** Get stage specific prefix used in names
4748 * @param stage Stage
4749 * @param storage Storage class
4753 const GLchar* ProgramInterface::GetStagePrefix(Shader::STAGES stage, Variable::STORAGE storage)
4755 static const GLchar* lut[Shader::STAGE_MAX][Variable::STORAGE_MAX] = {
4756 /* IN OUT UNIFORM SSB MEMBER */
4757 /* CS */ { 0, 0, "cs_uni_", "cs_buf_", "" },
4758 /* VS */ { "in_vs_", "vs_tcs_", "vs_uni_", "vs_buf_", "" },
4759 /* TCS */ { "vs_tcs_", "tcs_tes_", "tcs_uni_", "tcs_buf_", "" },
4760 /* TES */ { "tcs_tes_", "tes_gs_", "tes_uni_", "tes_buf_", "" },
4761 /* GS */ { "tes_gs_", "gs_fs_", "gs_uni_", "gs_buf_", "" },
4762 /* FS */ { "gs_fs_", "fs_out_", "fs_uni_", "fs_buf_", "" },
4765 const GLchar* result = 0;
4767 result = lut[stage][storage];
4772 /** Get definitions of all structures used in program interface
4774 * @return String with code
4776 std::string ProgramInterface::GetDefinitionsStructures() const
4778 return GetDefinitions(m_structures);
4781 /** Get interface code for stage
4783 * @param stage Specific stage
4785 * @return String with code
4787 std::string ProgramInterface::GetInterfaceForStage(Shader::STAGES stage) const
4789 size_t position = 0;
4790 std::string interface = "/* Globals */\n"
4793 "/* Structures */\n"
4808 const ShaderInterface& si = GetShaderInterface(stage);
4810 const std::string& structures = GetDefinitionsStructures();
4812 const std::string& globals = si.GetDefinitionsGlobals();
4813 const std::string& inputs = si.GetDefinitionsInputs();
4814 const std::string& outputs = si.GetDefinitionsOutputs();
4815 const std::string& uniforms = si.GetDefinitionsUniforms();
4816 const std::string& ssbs = si.GetDefinitionsSSBs();
4818 replaceToken("GLOBALS", position, globals.c_str(), interface);
4819 replaceToken("STRUCTURES", position, structures.c_str(), interface);
4820 replaceToken("UNIFORMS", position, uniforms.c_str(), interface);
4821 replaceToken("INPUTS", position, inputs.c_str(), interface);
4822 replaceToken("OUTPUTS", position, outputs.c_str(), interface);
4823 replaceToken("STORAGE", position, ssbs.c_str(), interface);
4828 /** Functional object used in find_if algorithm, in search for interface of given name
4831 struct matchInterfaceName
4833 matchInterfaceName(const GLchar* name) : m_name(name)
4837 bool operator()(const Interface* interface)
4839 return 0 == interface->m_name.compare(m_name);
4842 const GLchar* m_name;
4845 /** Finds interface of given name in given vector of interfaces
4847 * @param vector Collection of interfaces
4848 * @param name Requested name
4850 * @return Pointer to interface if available, 0 otherwise
4852 static Interface* findInterfaceByName(Interface::PtrVector& vector, const GLchar* name)
4854 Interface::PtrVector::iterator it = std::find_if(vector.begin(), vector.end(), matchInterfaceName(name));
4856 if (vector.end() != it)
4866 /** Search for block of given name
4868 * @param name Name of block
4870 * @return Pointer to block or 0
4872 Interface* ProgramInterface::GetBlock(const GLchar* name)
4874 return findInterfaceByName(m_blocks, name);
4877 /** Search for structure of given name
4879 * @param name Name of structure
4881 * @return Pointer to structure or 0
4883 Interface* ProgramInterface::GetStructure(const GLchar* name)
4885 return findInterfaceByName(m_structures, name);
4888 /** Adds new sturcture to interface
4890 * @param name Name of structure
4892 * @return Created structure
4894 Interface* ProgramInterface::Structure(const GLchar* name)
4896 return AddInterface(name, Interface::STRUCT);
4899 /** Replace "BINDING" token in qualifiers string to value specific for given stage
4901 * @param variable Variable to modify
4902 * @param stage Requested stage
4904 void ProgramInterface::replaceBinding(Variable& variable, Shader::STAGES stage)
4907 sprintf(binding, "%d", stage);
4908 replaceAllTokens("BINDING", binding, variable.m_descriptor.m_qualifiers);
4910 } /* Utils namespace */
4912 /** Debuging procedure. Logs parameters.
4914 * @param source As specified in GL spec.
4915 * @param type As specified in GL spec.
4916 * @param id As specified in GL spec.
4917 * @param severity As specified in GL spec.
4919 * @param message As specified in GL spec.
4920 * @param info Pointer to instance of Context used by test.
4922 void GLW_APIENTRY debug_proc(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei /* length */,
4923 const GLchar* message, void* info)
4925 deqp::Context* ctx = (deqp::Context*)info;
4927 const GLchar* source_str = "Unknown";
4928 const GLchar* type_str = "Unknown";
4929 const GLchar* severity_str = "Unknown";
4933 case GL_DEBUG_SOURCE_API:
4936 case GL_DEBUG_SOURCE_APPLICATION:
4939 case GL_DEBUG_SOURCE_OTHER:
4942 case GL_DEBUG_SOURCE_SHADER_COMPILER:
4945 case GL_DEBUG_SOURCE_THIRD_PARTY:
4948 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
4957 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
4958 type_str = "DEPRECATED_BEHAVIOR";
4960 case GL_DEBUG_TYPE_ERROR:
4963 case GL_DEBUG_TYPE_MARKER:
4964 type_str = "MARKER";
4966 case GL_DEBUG_TYPE_OTHER:
4969 case GL_DEBUG_TYPE_PERFORMANCE:
4970 type_str = "PERFORMANCE";
4972 case GL_DEBUG_TYPE_POP_GROUP:
4973 type_str = "POP_GROUP";
4975 case GL_DEBUG_TYPE_PORTABILITY:
4976 type_str = "PORTABILITY";
4978 case GL_DEBUG_TYPE_PUSH_GROUP:
4979 type_str = "PUSH_GROUP";
4981 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
4982 type_str = "UNDEFINED_BEHAVIOR";
4990 case GL_DEBUG_SEVERITY_HIGH:
4993 case GL_DEBUG_SEVERITY_LOW:
4996 case GL_DEBUG_SEVERITY_MEDIUM:
4999 case GL_DEBUG_SEVERITY_NOTIFICATION:
5006 ctx->getTestContext().getLog() << tcu::TestLog::Message << "DEBUG_INFO: " << std::setw(3) << source_str << "|"
5007 << severity_str << "|" << std::setw(18) << type_str << "|" << std::setw(12) << id
5008 << ": " << message << tcu::TestLog::EndMessage;
5013 * @param context Test context
5014 * @param test_name Test name
5015 * @param test_description Test description
5017 TestBase::TestBase(deqp::Context& context, const GLchar* test_name, const GLchar* test_description)
5018 : TestCase(context, test_name, test_description)
5020 /* Nothing to be done here */
5025 * @return tcu::TestNode::STOP otherwise
5027 tcu::TestNode::IterateResult TestBase::iterate()
5031 #if DEBUG_ENBALE_MESSAGE_CALLBACK
5032 const Functions& gl = m_context.getRenderContext().getFunctions();
5034 gl.debugMessageCallback(debug_proc, &m_context);
5035 GLU_EXPECT_NO_ERROR(gl.getError(), "DebugMessageCallback");
5036 #endif /* DEBUG_ENBALE_MESSAGE_CALLBACK */
5041 test_result = test();
5043 catch (std::exception& exc)
5045 TCU_FAIL(exc.what());
5049 if (true == test_result)
5051 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
5055 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
5059 return tcu::TestNode::STOP;
5062 /** Get last input location available for given type at specific stage
5064 * @param stage Shader stage
5065 * @param type Input type
5066 * @param array_length Length of input array
5068 * @return Last location index
5070 GLint TestBase::getLastInputLocation(Utils::Shader::STAGES stage, const Utils::Type& type, GLuint array_length)
5072 GLint divide = 4; /* 4 components per location */
5075 GLint paramPrev = 0;
5076 GLenum pnamePrev = 0;
5081 case Utils::Shader::FRAGMENT:
5082 pname = GL_MAX_FRAGMENT_INPUT_COMPONENTS;
5083 pnamePrev = GL_MAX_GEOMETRY_OUTPUT_COMPONENTS;
5085 case Utils::Shader::GEOMETRY:
5086 pname = GL_MAX_GEOMETRY_INPUT_COMPONENTS;
5087 pnamePrev = GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS;
5089 case Utils::Shader::TESS_CTRL:
5090 pname = GL_MAX_TESS_CONTROL_INPUT_COMPONENTS;
5091 pnamePrev = GL_MAX_VERTEX_OUTPUT_COMPONENTS;
5093 case Utils::Shader::TESS_EVAL:
5094 pname = GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS;
5095 pnamePrev = GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS;
5097 case Utils::Shader::VERTEX:
5098 pname = GL_MAX_VERTEX_ATTRIBS;
5102 TCU_FAIL("Invalid enum");
5106 /* Zero means no array, but 1 slot is required */
5107 if (0 == array_length)
5113 const Functions& gl = m_context.getRenderContext().getFunctions();
5115 gl.getIntegerv(pname, ¶m);
5116 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
5119 gl.getIntegerv(pnamePrev, ¶mPrev);
5120 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
5122 /* Don't read from a location that doesn't exist in the previous stage */
5123 param = de::min(param, paramPrev);
5127 #if WRKARD_VARYINGLOCATIONSTEST
5129 const GLint n_avl_locations = 16;
5133 const GLint n_avl_locations = param / divide;
5137 const GLuint n_req_location = type.GetLocations(stage == Utils::Shader::VERTEX) * array_length;
5139 return n_avl_locations - n_req_location; /* last is max - 1 */
5142 /** Get last output location available for given type at specific stage
5144 * @param stage Shader stage
5145 * @param type Input type
5146 * @param array_length Length of input array
5148 * @return Last location index
5150 GLint TestBase::getLastOutputLocation(Utils::Shader::STAGES stage, const Utils::Type& type, GLuint array_length)
5154 GLint paramNext = 0;
5155 GLenum pnameNext = 0;
5160 case Utils::Shader::GEOMETRY:
5161 pname = GL_MAX_GEOMETRY_OUTPUT_COMPONENTS;
5162 pnameNext = GL_MAX_FRAGMENT_INPUT_COMPONENTS;
5164 case Utils::Shader::TESS_CTRL:
5165 pname = GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS;
5166 pnameNext = GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS;
5168 case Utils::Shader::TESS_EVAL:
5169 pname = GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS;
5170 pnameNext = GL_MAX_GEOMETRY_INPUT_COMPONENTS;
5172 case Utils::Shader::VERTEX:
5173 pname = GL_MAX_VERTEX_OUTPUT_COMPONENTS;
5174 pnameNext = GL_MAX_TESS_CONTROL_INPUT_COMPONENTS;
5177 TCU_FAIL("Invalid enum");
5181 /* Zero means no array, but 1 slot is required */
5182 if (0 == array_length)
5188 const Functions& gl = m_context.getRenderContext().getFunctions();
5190 gl.getIntegerv(pname, ¶m);
5191 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
5193 gl.getIntegerv(pnameNext, ¶mNext);
5194 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
5197 #if WRKARD_VARYINGLOCATIONSTEST
5199 const GLint n_avl_locations = 16;
5203 /* Don't write to a location that doesn't exist in the next stage */
5204 param = de::min(param, paramNext);
5206 const GLint n_avl_locations = param / 4; /* 4 components per location */
5210 const GLuint n_req_location = type.GetLocations() * array_length;
5212 return n_avl_locations - n_req_location; /* last is max - 1 */
5215 /** Basic implementation
5219 * @return Empty string
5221 std::string TestBase::getTestCaseName(GLuint /* test_case_index */)
5228 /** Basic implementation
5232 GLuint TestBase::getTestCaseNumber()
5237 /** Check if flat qualifier is required for given type, stage and storage
5239 * @param stage Shader stage
5240 * @param type Input type
5241 * @param storage Storage of variable
5243 * @return Last location index
5245 bool TestBase::isFlatRequired(Utils::Shader::STAGES stage, const Utils::Type& type,
5246 Utils::Variable::STORAGE storage) const
5248 /* Float types do not need flat at all */
5249 if (Utils::Type::Float == type.m_basic_type)
5254 /* Inputs to fragment shader */
5255 if ((Utils::Shader::FRAGMENT == stage) && (Utils::Variable::VARYING_INPUT == storage))
5260 /* Outputs from geometry shader */
5261 if ((Utils::Shader::FRAGMENT == stage) && (Utils::Variable::VARYING_OUTPUT == storage))
5269 /** Basic implementation of testInit method
5272 void TestBase::testInit()
5276 /** Calculate stride for interface
5278 * @param interface Interface
5280 * @return Calculated value
5282 GLuint TestBase::calculateStride(const Utils::Interface& interface) const
5284 const size_t n_members = interface.m_members.size();
5288 for (size_t i = 0; i < n_members; ++i)
5290 const Utils::Variable::Descriptor& member = interface.m_members[i];
5291 const GLuint member_offset = member.m_offset;
5292 const GLuint member_stride = member.m_expected_stride_of_element;
5293 const GLuint member_ends_at = member_offset + member_stride;
5295 stride = std::max(stride, member_ends_at);
5301 /** Generate data for interface. This routine is recursive
5303 * @param interface Interface
5304 * @param offset Offset in out_data
5305 * @param out_data Buffer to be filled
5307 void TestBase::generateData(const Utils::Interface& interface, GLuint offset, std::vector<GLubyte>& out_data) const
5309 const size_t n_members = interface.m_members.size();
5310 GLubyte* ptr = &out_data[offset];
5312 for (size_t i = 0; i < n_members; ++i)
5314 const Utils::Variable::Descriptor& member = interface.m_members[i];
5315 const GLuint member_offset = member.m_offset;
5316 const GLuint n_elements = (0 == member.m_n_array_elements) ? 1 : member.m_n_array_elements;
5318 for (GLuint element = 0; element < n_elements; ++element)
5320 const GLuint element_offset = element * member.m_expected_stride_of_element;
5321 const GLuint data_offfset = member_offset + element_offset;
5323 if (Utils::Variable::BUILTIN == member.m_type)
5325 const std::vector<GLubyte>& data = member.m_builtin.GenerateData();
5327 memcpy(ptr + data_offfset, &data[0], data.size());
5331 generateData(*member.m_interface, offset + data_offfset, out_data);
5337 /** Get type at index
5339 * @param index Index of requested type
5343 Utils::Type TestBase::getType(GLuint index) const
5350 type = Utils::Type::_double;
5353 type = Utils::Type::dmat2;
5356 type = Utils::Type::dmat2x3;
5359 type = Utils::Type::dmat2x4;
5362 type = Utils::Type::dmat3;
5365 type = Utils::Type::dmat3x2;
5368 type = Utils::Type::dmat3x4;
5371 type = Utils::Type::dmat4;
5374 type = Utils::Type::dmat4x2;
5377 type = Utils::Type::dmat4x3;
5380 type = Utils::Type::dvec2;
5383 type = Utils::Type::dvec3;
5386 type = Utils::Type::dvec4;
5389 type = Utils::Type::_float;
5392 type = Utils::Type::mat2;
5395 type = Utils::Type::mat2x3;
5398 type = Utils::Type::mat2x4;
5401 type = Utils::Type::mat3;
5404 type = Utils::Type::mat3x2;
5407 type = Utils::Type::mat3x4;
5410 type = Utils::Type::mat4;
5413 type = Utils::Type::mat4x2;
5416 type = Utils::Type::mat4x3;
5419 type = Utils::Type::vec2;
5422 type = Utils::Type::vec3;
5425 type = Utils::Type::vec4;
5428 type = Utils::Type::_int;
5431 type = Utils::Type::ivec2;
5434 type = Utils::Type::ivec3;
5437 type = Utils::Type::ivec4;
5440 type = Utils::Type::uint;
5443 type = Utils::Type::uvec2;
5446 type = Utils::Type::uvec3;
5449 type = Utils::Type::uvec4;
5452 TCU_FAIL("invalid enum");
5458 /** Get name of type at index
5460 * @param index Index of type
5464 std::string TestBase::getTypeName(GLuint index) const
5466 std::string name = getType(index).GetGLSLTypeName();
5471 /** Get number of types
5475 glw::GLuint TestBase::getTypesNumber() const
5482 * @return true if test pass, false otherwise
5484 bool TestBase::test()
5487 GLuint n_test_cases = 0;
5492 /* GL entry points */
5493 const Functions& gl = m_context.getRenderContext().getFunctions();
5495 /* Tessellation patch set up */
5496 gl.patchParameteri(GL_PATCH_VERTICES, 1);
5497 GLU_EXPECT_NO_ERROR(gl.getError(), "PatchParameteri");
5499 /* Get number of test cases */
5500 n_test_cases = getTestCaseNumber();
5502 #if DEBUG_REPEAT_TEST_CASE
5506 GLuint test_case = DEBUG_REPEATED_TEST_CASE;
5508 #else /* DEBUG_REPEAT_TEST_CASE */
5510 for (GLuint test_case = 0; test_case < n_test_cases; ++test_case)
5512 #endif /* DEBUG_REPEAT_TEST_CASE */
5514 bool case_result = true;
5517 if (false == testCase(test_case))
5519 case_result = false;
5523 if (false == case_result)
5525 const std::string& test_case_name = getTestCaseName(test_case);
5527 if (false == test_case_name.empty())
5529 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Test case (" << test_case_name
5530 << ") failed." << tcu::TestLog::EndMessage;
5534 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Test case (" << test_case
5535 << ") failed." << tcu::TestLog::EndMessage;
5546 /* Constants used by BufferTestBase */
5547 const GLuint BufferTestBase::bufferDescriptor::m_non_indexed = -1;
5551 * @param context Test context
5552 * @param test_name Name of test
5553 * @param test_description Description of test
5555 BufferTestBase::BufferTestBase(deqp::Context& context, const GLchar* test_name, const GLchar* test_description)
5556 : TestBase(context, test_name, test_description)
5560 /** Execute drawArrays for single vertex
5566 bool BufferTestBase::executeDrawCall(bool tesEnabled, GLuint /* test_case_index */)
5568 const Functions& gl = m_context.getRenderContext().getFunctions();
5570 gl.disable(GL_RASTERIZER_DISCARD);
5571 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
5573 gl.beginTransformFeedback(GL_POINTS);
5574 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
5576 // Only TES is existed, glDrawArray can use the parameter GL_PATCHES
5577 if (tesEnabled == false)
5579 gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */);
5583 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
5586 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
5588 gl.endTransformFeedback();
5589 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
5594 /** Get descriptors of buffers necessary for test
5599 void BufferTestBase::getBufferDescriptors(glw::GLuint /* test_case_index */,
5600 bufferDescriptor::Vector& /* out_descriptors */)
5602 /* Nothhing to be done */
5605 /** Get list of names of varyings that will be registered with TransformFeedbackVaryings
5610 void BufferTestBase::getCapturedVaryings(glw::GLuint /* test_case_index */,
5611 Utils::Program::NameVector& /* captured_varyings */,
5612 GLint* /* xfb_components */)
5614 /* Nothing to be done */
5617 /** Get body of main function for given shader stage
5621 * @param out_assignments Set to empty
5622 * @param out_calculations Set to empty
5624 void BufferTestBase::getShaderBody(glw::GLuint /* test_case_index */, Utils::Shader::STAGES /* stage */,
5625 std::string& out_assignments, std::string& out_calculations)
5627 out_assignments = "";
5628 out_calculations = "";
5631 /** Get interface of shader
5635 * @param out_interface Set to ""
5637 void BufferTestBase::getShaderInterface(glw::GLuint /* test_case_index */, Utils::Shader::STAGES /* stage */,
5638 std::string& out_interface)
5643 /** Get source code of shader
5645 * @param test_case_index Index of test case
5646 * @param stage Shader stage
5650 std::string BufferTestBase::getShaderSource(glw::GLuint test_case_index, Utils::Shader::STAGES stage)
5652 std::string assignments;
5653 std::string calculations;
5654 std::string interface;
5657 getShaderBody(test_case_index, stage, assignments, calculations);
5658 getShaderInterface(test_case_index, stage, interface);
5661 std::string source = getShaderTemplate(stage);
5664 size_t position = 0;
5665 Utils::replaceToken("INTERFACE", position, interface.c_str(), source);
5666 Utils::replaceToken("CALCULATIONS", position, calculations.c_str(), source);
5667 Utils::replaceToken("ASSIGNMENTS", position, assignments.c_str(), source);
5673 /** Inspects program to check if all resources are as expected
5681 bool BufferTestBase::inspectProgram(GLuint /* test_case_index */, Utils::Program& /* program */,
5682 std::stringstream& /* out_stream */)
5689 * @param test_case_index Id of test case
5691 * @return true if test case pass, false otherwise
5693 bool BufferTestBase::testCase(GLuint test_case_index)
5697 bufferCollection buffers;
5698 Utils::Program::NameVector captured_varyings;
5699 bufferDescriptor::Vector descriptors;
5700 Utils::Program program(m_context);
5701 Utils::VertexArray vao(m_context);
5703 /* Get captured varyings */
5704 GLint xfb_components;
5705 getCapturedVaryings(test_case_index, captured_varyings, &xfb_components);
5707 /* Don't generate shaders that try to capture more XFB components than the implementation's limit */
5708 if (captured_varyings.size() > 0)
5710 const Functions& gl = m_context.getRenderContext().getFunctions();
5712 GLint max_xfb_components;
5713 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_xfb_components);
5714 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
5716 if (xfb_components > max_xfb_components)
5720 /* Get shader sources */
5721 const std::string& fragment_shader = getShaderSource(test_case_index, Utils::Shader::FRAGMENT);
5722 const std::string& geometry_shader = getShaderSource(test_case_index, Utils::Shader::GEOMETRY);
5723 const std::string& tess_ctrl_shader = getShaderSource(test_case_index, Utils::Shader::TESS_CTRL);
5724 const std::string& tess_eval_shader = getShaderSource(test_case_index, Utils::Shader::TESS_EVAL);
5725 const std::string& vertex_shader = getShaderSource(test_case_index, Utils::Shader::VERTEX);
5727 /* Set up program */
5728 program.Init("" /* compute_shader */, fragment_shader, geometry_shader, tess_ctrl_shader, tess_eval_shader,
5729 vertex_shader, captured_varyings, true, false /* is_separable */);
5733 std::stringstream stream;
5734 if (false == inspectProgram(test_case_index, program, stream))
5736 m_context.getTestContext().getLog()
5737 << tcu::TestLog::Message
5738 << "Program inspection failed. Test case: " << getTestCaseName(test_case_index)
5739 << ". Reason: " << stream.str() << tcu::TestLog::EndMessage
5740 << tcu::TestLog::KernelSource(vertex_shader) << tcu::TestLog::KernelSource(tess_ctrl_shader)
5741 << tcu::TestLog::KernelSource(tess_eval_shader) << tcu::TestLog::KernelSource(geometry_shader)
5742 << tcu::TestLog::KernelSource(fragment_shader);
5750 /* Set up buffers */
5751 getBufferDescriptors(test_case_index, descriptors);
5753 prepareBuffers(descriptors, buffers);
5760 bool result = executeDrawCall((program.m_tess_eval.m_id != 0), test_case_index);
5763 m_context.getRenderContext().postIterate();
5766 if (false == result)
5768 m_context.getTestContext().getLog()
5769 << tcu::TestLog::KernelSource(vertex_shader) << tcu::TestLog::KernelSource(tess_ctrl_shader)
5770 << tcu::TestLog::KernelSource(tess_eval_shader) << tcu::TestLog::KernelSource(geometry_shader)
5771 << tcu::TestLog::KernelSource(fragment_shader);
5777 if (false == verifyBuffers(buffers))
5779 m_context.getTestContext().getLog()
5780 << tcu::TestLog::KernelSource(vertex_shader) << tcu::TestLog::KernelSource(tess_ctrl_shader)
5781 << tcu::TestLog::KernelSource(tess_eval_shader) << tcu::TestLog::KernelSource(geometry_shader)
5782 << tcu::TestLog::KernelSource(fragment_shader);
5787 catch (Utils::Shader::InvalidSourceException& exc)
5790 TCU_FAIL(exc.what());
5792 catch (Utils::Program::BuildException& exc)
5795 TCU_FAIL(exc.what());
5802 /** Verify contents of buffers
5804 * @param buffers Collection of buffers to be verified
5806 * @return true if everything is as expected, false otherwise
5808 bool BufferTestBase::verifyBuffers(bufferCollection& buffers)
5812 for (bufferCollection::Vector::iterator it = buffers.m_vector.begin(), end = buffers.m_vector.end(); end != it;
5815 bufferCollection::pair& pair = *it;
5816 Utils::Buffer* buffer = pair.m_buffer;
5817 bufferDescriptor* descriptor = pair.m_descriptor;
5818 size_t size = descriptor->m_expected_data.size();
5820 /* Skip buffers that have no expected data */
5826 /* Get pointer to contents of buffer */
5828 GLvoid* buffer_data = buffer->Map(Utils::Buffer::ReadOnly);
5830 /* Get pointer to expected data */
5831 GLvoid* expected_data = &descriptor->m_expected_data[0];
5834 int res = memcmp(buffer_data, expected_data, size);
5838 m_context.getTestContext().getLog()
5839 << tcu::TestLog::Message
5840 << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
5841 << ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
5846 /* Release buffer mapping */
5853 /** Unbinds all uniforms and xfb
5856 void BufferTestBase::cleanBuffers()
5858 const Functions& gl = m_context.getRenderContext().getFunctions();
5863 gl.getIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &max_uni);
5864 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_xfb);
5865 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
5867 for (GLint i = 0; i < max_uni; ++i)
5869 Utils::Buffer::BindBase(gl, 0, Utils::Buffer::Uniform, i);
5872 for (GLint i = 0; i < max_xfb; ++i)
5874 Utils::Buffer::BindBase(gl, 0, Utils::Buffer::Transform_feedback, i);
5878 /** Get template of shader for given stage
5880 * @param stage Stage
5882 * @return Template of shader source
5884 std::string BufferTestBase::getShaderTemplate(Utils::Shader::STAGES stage)
5886 static const GLchar* compute_shader_template = "#version 430 core\n"
5887 "#extension GL_ARB_enhanced_layouts : require\n"
5889 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
5891 "writeonly uniform uimage2D uni_image;\n"
5903 static const GLchar* fragment_shader_template = "#version 430 core\n"
5904 "#extension GL_ARB_enhanced_layouts : require\n"
5916 // max_vertices is set to 3 for the test case "xfb_vertex_streams" declares 3 streams in geometry shader,
5917 // according to spec, max_vertices should be no less than 3 if there are 3 streams in GS.
5918 static const GLchar* geometry_shader_template = "#version 430 core\n"
5919 "#extension GL_ARB_enhanced_layouts : require\n"
5921 "layout(points) in;\n"
5922 "layout(points, max_vertices = 3) out;\n"
5932 " gl_Position = vec4(0, 0, 0, 1);\n"
5937 static const GLchar* tess_ctrl_shader_template = "#version 430 core\n"
5938 "#extension GL_ARB_enhanced_layouts : require\n"
5940 "layout(vertices = 1) out;\n"
5950 " gl_TessLevelOuter[0] = 1.0;\n"
5951 " gl_TessLevelOuter[1] = 1.0;\n"
5952 " gl_TessLevelOuter[2] = 1.0;\n"
5953 " gl_TessLevelOuter[3] = 1.0;\n"
5954 " gl_TessLevelInner[0] = 1.0;\n"
5955 " gl_TessLevelInner[1] = 1.0;\n"
5959 static const GLchar* tess_eval_shader_template = "#version 430 core\n"
5960 "#extension GL_ARB_enhanced_layouts : require\n"
5962 "layout(isolines, point_mode) in;\n"
5974 static const GLchar* vertex_shader_template = "#version 430 core\n"
5975 "#extension GL_ARB_enhanced_layouts : require\n"
5987 const GLchar* result = 0;
5991 case Utils::Shader::COMPUTE:
5992 result = compute_shader_template;
5994 case Utils::Shader::FRAGMENT:
5995 result = fragment_shader_template;
5997 case Utils::Shader::GEOMETRY:
5998 result = geometry_shader_template;
6000 case Utils::Shader::TESS_CTRL:
6001 result = tess_ctrl_shader_template;
6003 case Utils::Shader::TESS_EVAL:
6004 result = tess_eval_shader_template;
6006 case Utils::Shader::VERTEX:
6007 result = vertex_shader_template;
6010 TCU_FAIL("Invalid enum");
6016 /** Prepare buffer according to descriptor
6018 * @param buffer Buffer to prepare
6019 * @param desc Descriptor
6021 void BufferTestBase::prepareBuffer(Utils::Buffer& buffer, bufferDescriptor& desc)
6023 GLsizeiptr size = 0;
6026 if (false == desc.m_initial_data.empty())
6028 size = desc.m_initial_data.size();
6029 data = &desc.m_initial_data[0];
6031 else if (false == desc.m_expected_data.empty())
6033 size = desc.m_expected_data.size();
6036 buffer.Init(desc.m_target, Utils::Buffer::StaticDraw, size, data);
6038 if (bufferDescriptor::m_non_indexed != desc.m_index)
6040 buffer.BindBase(desc.m_index);
6048 /** Prepare collection of buffer
6050 * @param descriptors Collection of descriptors
6051 * @param out_buffers Collection of buffers
6053 void BufferTestBase::prepareBuffers(bufferDescriptor::Vector& descriptors, bufferCollection& out_buffers)
6055 for (bufferDescriptor::Vector::iterator it = descriptors.begin(), end = descriptors.end(); end != it; ++it)
6057 bufferCollection::pair pair;
6059 pair.m_buffer = new Utils::Buffer(m_context);
6060 if (0 == pair.m_buffer)
6062 TCU_FAIL("Memory allocation failed");
6065 pair.m_descriptor = &(*it);
6067 prepareBuffer(*pair.m_buffer, *pair.m_descriptor);
6069 out_buffers.m_vector.push_back(pair);
6076 BufferTestBase::bufferCollection::~bufferCollection()
6078 for (Vector::iterator it = m_vector.begin(), end = m_vector.end(); end != it; ++it)
6080 if (0 != it->m_buffer)
6082 delete it->m_buffer;
6090 * @param context Test context
6091 * @param test_name Name of test
6092 * @param test_description Description of test
6094 NegativeTestBase::NegativeTestBase(deqp::Context& context, const GLchar* test_name, const GLchar* test_description)
6095 : TestBase(context, test_name, test_description)
6099 /** Selects if "compute" stage is relevant for test
6105 bool NegativeTestBase::isComputeRelevant(GLuint /* test_case_index */)
6110 /** Selects if compilation failure is expected result
6116 bool NegativeTestBase::isFailureExpected(GLuint /* test_case_index */)
6123 * @param test_case_index Id of test case
6125 * @return true if test case pass, false otherwise
6127 bool NegativeTestBase::testCase(GLuint test_case_index)
6129 bool test_case_result = true;
6132 if (true == isComputeRelevant(test_case_index))
6134 const std::string& cs_source = getShaderSource(test_case_index, Utils::Shader::COMPUTE);
6135 bool is_build_error = false;
6136 const bool is_failure_expected = isFailureExpected(test_case_index);
6137 Utils::Program program(m_context);
6141 program.Init(cs_source, "" /* fs */, "" /* gs */, "" /* tcs */, "" /* tes */, "" /* vs */,
6142 false /* separable */);
6144 catch (Utils::Shader::InvalidSourceException& exc)
6146 if (false == is_failure_expected)
6148 m_context.getTestContext().getLog()
6149 << tcu::TestLog::Message << "Unexpected error in shader compilation: " << tcu::TestLog::EndMessage;
6153 #if DEBUG_NEG_LOG_ERROR
6157 m_context.getTestContext().getLog()
6158 << tcu::TestLog::Message << "Error in shader compilation was expected, logged for verification: "
6159 << tcu::TestLog::EndMessage;
6163 #endif /* DEBUG_NEG_LOG_ERROR */
6165 is_build_error = true;
6167 catch (Utils::Program::BuildException& exc)
6169 if (false == is_failure_expected)
6171 m_context.getTestContext().getLog()
6172 << tcu::TestLog::Message << "Unexpected error in program linking: " << tcu::TestLog::EndMessage;
6176 #if DEBUG_NEG_LOG_ERROR
6180 m_context.getTestContext().getLog()
6181 << tcu::TestLog::Message
6182 << "Error in program linking was expected, logged for verification: " << tcu::TestLog::EndMessage;
6186 #endif /* DEBUG_NEG_LOG_ERROR */
6188 is_build_error = true;
6191 if (is_build_error != is_failure_expected)
6193 if (!is_build_error)
6195 m_context.getTestContext().getLog()
6196 << tcu::TestLog::Message << "Unexpected success: " << tcu::TestLog::EndMessage;
6197 Utils::Shader::LogSource(m_context, cs_source, Utils::Shader::COMPUTE);
6199 test_case_result = false;
6204 const std::string& fs_source = getShaderSource(test_case_index, Utils::Shader::FRAGMENT);
6205 const std::string& gs_source = getShaderSource(test_case_index, Utils::Shader::GEOMETRY);
6206 bool is_build_error = false;
6207 const bool is_failure_expected = isFailureExpected(test_case_index);
6208 Utils::Program program(m_context);
6209 const std::string& tcs_source = getShaderSource(test_case_index, Utils::Shader::TESS_CTRL);
6210 const std::string& tes_source = getShaderSource(test_case_index, Utils::Shader::TESS_EVAL);
6211 const std::string& vs_source = getShaderSource(test_case_index, Utils::Shader::VERTEX);
6215 program.Init("" /* cs */, fs_source, gs_source, tcs_source, tes_source, vs_source, false /* separable */);
6217 catch (Utils::Shader::InvalidSourceException& exc)
6219 if (false == is_failure_expected)
6221 m_context.getTestContext().getLog()
6222 << tcu::TestLog::Message << "Unexpected error in shader compilation: " << tcu::TestLog::EndMessage;
6226 #if DEBUG_NEG_LOG_ERROR
6230 m_context.getTestContext().getLog()
6231 << tcu::TestLog::Message << "Error in shader compilation was expected, logged for verification: "
6232 << tcu::TestLog::EndMessage;
6236 #endif /* DEBUG_NEG_LOG_ERROR */
6238 is_build_error = true;
6240 catch (Utils::Program::BuildException& exc)
6242 if (false == is_failure_expected)
6244 m_context.getTestContext().getLog()
6245 << tcu::TestLog::Message << "Unexpected error in program linking: " << tcu::TestLog::EndMessage;
6249 #if DEBUG_NEG_LOG_ERROR
6253 m_context.getTestContext().getLog()
6254 << tcu::TestLog::Message
6255 << "Error in program linking was expected, logged for verification: " << tcu::TestLog::EndMessage;
6259 #endif /* DEBUG_NEG_LOG_ERROR */
6261 is_build_error = true;
6264 if (is_build_error != is_failure_expected)
6266 if (!is_build_error)
6268 m_context.getTestContext().getLog()
6269 << tcu::TestLog::Message << "Unexpected success: " << tcu::TestLog::EndMessage;
6270 Utils::Shader::LogSource(m_context, vs_source, Utils::Shader::VERTEX);
6271 Utils::Shader::LogSource(m_context, tcs_source, Utils::Shader::TESS_CTRL);
6272 Utils::Shader::LogSource(m_context, tes_source, Utils::Shader::TESS_EVAL);
6273 Utils::Shader::LogSource(m_context, gs_source, Utils::Shader::GEOMETRY);
6274 Utils::Shader::LogSource(m_context, fs_source, Utils::Shader::FRAGMENT);
6276 test_case_result = false;
6280 return test_case_result;
6283 /* Constants used by TextureTestBase */
6284 const glw::GLuint TextureTestBase::m_width = 16;
6285 const glw::GLuint TextureTestBase::m_height = 16;
6289 * @param context Test context
6290 * @param test_name Name of test
6291 * @param test_description Description of test
6293 TextureTestBase::TextureTestBase(deqp::Context& context, const GLchar* test_name, const GLchar* test_description)
6294 : TestBase(context, test_name, test_description)
6298 /** Get locations for all inputs with automatic_location
6300 * @param program Program object
6301 * @param program_interface Interface of program
6303 void TextureTestBase::prepareAttribLocation(Utils::Program& program, Utils::ProgramInterface& program_interface)
6305 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
6307 Utils::Variable::PtrVector& inputs = si.m_inputs;
6309 for (Utils::Variable::PtrVector::iterator it = inputs.begin(); inputs.end() != it; ++it)
6311 /* Test does not specify location, query value and set */
6312 if (Utils::Variable::m_automatic_location == (*it)->m_descriptor.m_expected_location)
6314 GLuint index = program.GetResourceIndex((*it)->m_descriptor.m_name, GL_PROGRAM_INPUT);
6317 program.GetResource(GL_PROGRAM_INPUT, index, GL_LOCATION, 1 /* size */, &location);
6319 (*it)->m_descriptor.m_expected_location = location;
6324 /** Verifies contents of drawn image
6327 * @param color_0 Verified image
6329 * @return true if image is filled with 1, false otherwise
6331 bool TextureTestBase::checkResults(glw::GLuint /* test_case_index */, Utils::Texture& color_0)
6333 static const GLuint size = m_width * m_height;
6334 static const GLuint expected_color = 1;
6336 std::vector<GLuint> data;
6339 color_0.Get(GL_RED_INTEGER, GL_UNSIGNED_INT, &data[0]);
6341 for (GLuint i = 0; i < size; ++i)
6343 const GLuint color = data[i];
6345 if (expected_color != color)
6347 m_context.getTestContext().getLog() << tcu::TestLog::Message << "R32UI[" << i << "]:" << color
6348 << tcu::TestLog::EndMessage;
6356 /** Execute dispatch compute for 16x16x1
6360 void TextureTestBase::executeDispatchCall(GLuint /* test_case_index */)
6362 const Functions& gl = m_context.getRenderContext().getFunctions();
6364 gl.dispatchCompute(16 /* x */, 16 /* y */, 1 /* z */);
6365 GLU_EXPECT_NO_ERROR(gl.getError(), "DispatchCompute");
6368 /** Execute drawArrays for single vertex
6372 void TextureTestBase::executeDrawCall(GLuint /* test_case_index */)
6374 const Functions& gl = m_context.getRenderContext().getFunctions();
6376 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
6377 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
6380 /** Prepare code snippet that will pass in variables to out variables
6383 * @param varying_passthrough Collection of connections between in and out variables
6384 * @param stage Shader stage
6386 * @return Code that pass in variables to next stage
6388 std::string TextureTestBase::getPassSnippet(GLuint /* test_case_index */,
6389 Utils::VaryingPassthrough& varying_passthrough, Utils::Shader::STAGES stage)
6391 static const GLchar* separator = "\n ";
6393 /* Skip for compute shader */
6394 if (Utils::Shader::COMPUTE == stage)
6399 Utils::VaryingConnection::Vector& vector = varying_passthrough.Get(stage);
6401 std::string result = Utils::g_list;
6402 size_t position = 0;
6404 for (GLuint i = 0; i < vector.size(); ++i)
6407 Utils::VaryingConnection& connection = vector[i];
6409 Utils::Variable* in = connection.m_in;
6410 Utils::Variable* out = connection.m_out;
6412 Utils::Variable::FLAVOUR in_flavour = Utils::Variable::GetFlavour(stage, Utils::Variable::INPUT);
6413 Utils::Variable::FLAVOUR out_flavour = Utils::Variable::GetFlavour(stage, Utils::Variable::OUTPUT);
6415 const std::string passthrough =
6416 getVariablePassthrough("", in->m_descriptor, in_flavour, "", out->m_descriptor, out_flavour);
6418 Utils::insertElementOfList(passthrough.c_str(), separator, position, result);
6421 Utils::endList("", position, result);
6426 /** Basic implementation of method getProgramInterface
6432 void TextureTestBase::getProgramInterface(GLuint /* test_case_index */,
6433 Utils::ProgramInterface& /* program_interface */,
6434 Utils::VaryingPassthrough& /* varying_passthrough */)
6438 /** Prepare code snippet that will verify in and uniform variables
6441 * @param program_interface Interface of program
6442 * @param stage Shader stage
6444 * @return Code that verify variables
6446 std::string TextureTestBase::getVerificationSnippet(GLuint /* test_case_index */,
6447 Utils::ProgramInterface& program_interface,
6448 Utils::Shader::STAGES stage)
6450 static const GLchar* separator = " ||\n ";
6452 std::string verification = "if (LIST)\n"
6457 /* Get flavour of in and out variables */
6458 Utils::Variable::FLAVOUR in_flavour = Utils::Variable::GetFlavour(stage, Utils::Variable::INPUT);
6460 /* Get interface for shader stage */
6461 Utils::ShaderInterface& si = program_interface.GetShaderInterface(stage);
6463 /* There are no varialbes to verify */
6464 if ((0 == si.m_inputs.size()) && (0 == si.m_uniforms.size()) && (0 == si.m_ssb_blocks.size()))
6469 /* For each in variable insert verification code */
6470 size_t position = 0;
6472 for (GLuint i = 0; i < si.m_inputs.size(); ++i)
6474 const Utils::Variable& var = *si.m_inputs[i];
6475 const std::string& var_verification = getVariableVerification("", var.m_data, var.m_descriptor, in_flavour);
6477 Utils::insertElementOfList(var_verification.c_str(), separator, position, verification);
6480 /* For each unifrom variable insert verification code */
6481 for (GLuint i = 0; i < si.m_uniforms.size(); ++i)
6483 const Utils::Variable& var = *si.m_uniforms[i];
6484 const std::string& var_verification =
6485 getVariableVerification("", var.m_data, var.m_descriptor, Utils::Variable::BASIC);
6487 Utils::insertElementOfList(var_verification.c_str(), separator, position, verification);
6490 /* For each ssb variable insert verification code */
6491 for (GLuint i = 0; i < si.m_ssb_blocks.size(); ++i)
6493 const Utils::Variable& var = *si.m_ssb_blocks[i];
6494 const std::string& var_verification =
6495 getVariableVerification("", var.m_data, var.m_descriptor, Utils::Variable::BASIC);
6497 Utils::insertElementOfList(var_verification.c_str(), separator, position, verification);
6500 Utils::endList("", position, verification);
6502 #if DEBUG_TTB_VERIFICATION_SNIPPET_STAGE
6506 sprintf(buffer, "%d", stage + 10);
6507 Utils::replaceToken("0u", position, buffer, verification);
6510 #elif DEBUG_TTB_VERIFICATION_SNIPPET_VARIABLE
6512 if (Utils::Shader::VERTEX == stage)
6514 Utils::replaceToken("0u", position, "in_vs_first.x", verification);
6518 Utils::replaceToken("0u", position, "31u", verification);
6524 return verification;
6527 /** Selects if "compute" stage is relevant for test
6533 bool TextureTestBase::isComputeRelevant(GLuint /* test_case_index */)
6538 /** Selects if "draw" stages are relevant for test
6544 bool TextureTestBase::isDrawRelevant(GLuint /* test_case_index */)
6549 /** Prepare code that will do assignment of single in to single out
6551 * @param in_parent_name Name of parent in variable
6552 * @param in_variable Descriptor of in variable
6553 * @param in_flavour Flavoud of in variable
6554 * @param out_parent_name Name of parent out variable
6555 * @param out_variable Descriptor of out variable
6556 * @param out_flavour Flavoud of out variable
6558 * @return Code that does OUT = IN
6560 std::string TextureTestBase::getVariablePassthrough(const std::string& in_parent_name,
6561 const Utils::Variable::Descriptor& in_variable,
6562 Utils::Variable::FLAVOUR in_flavour,
6563 const std::string& out_parent_name,
6564 const Utils::Variable::Descriptor& out_variable,
6565 Utils::Variable::FLAVOUR out_flavour)
6569 GLuint member_index = 0;
6570 size_t position = 0;
6571 std::string result = Utils::g_list;
6572 static const GLchar* separator = ";\n ";
6574 /* For each member of each array element */
6577 const std::string in_name = Utils::Variable::GetReference(in_parent_name, in_variable, in_flavour, index);
6578 const std::string out_name = Utils::Variable::GetReference(out_parent_name, out_variable, out_flavour, index);
6579 std::string passthrough;
6581 /* Prepare verification */
6582 if (Utils::Variable::BUILTIN == in_variable.m_type)
6584 size_t pass_position = 0;
6586 passthrough = "OUT = IN;";
6588 Utils::replaceToken("OUT", pass_position, out_name.c_str(), passthrough);
6589 Utils::replaceToken("IN", pass_position, in_name.c_str(), passthrough);
6591 /* Increment index */
6596 const Utils::Interface* in_interface = in_variable.m_interface;
6597 const Utils::Interface* out_interface = out_variable.m_interface;
6599 if ((0 == in_interface) || (0 == out_interface))
6601 TCU_FAIL("Nullptr");
6604 const Utils::Variable::Descriptor& in_member = in_interface->m_members[member_index];
6605 const Utils::Variable::Descriptor& out_member = out_interface->m_members[member_index];
6607 passthrough = getVariablePassthrough(in_name, in_member, Utils::Variable::BASIC, out_name, out_member,
6608 Utils::Variable::BASIC);
6610 /* Increment member_index */
6613 /* Increment index and reset member_index if all members were processed */
6614 if (in_interface->m_members.size() == member_index)
6621 /* Check if loop should end */
6622 if ((index >= in_variable.m_n_array_elements) && (0 == member_index))
6627 Utils::insertElementOfList(passthrough.c_str(), separator, position, result);
6629 } while (true != done);
6631 Utils::endList("", position, result);
6637 /** Get verification of single variable
6639 * @param parent_name Name of parent variable
6640 * @param data Data that should be used as EXPECTED
6641 * @param variable Descriptor of variable
6642 * @param flavour Flavour of variable
6644 * @return Code that does (EXPECTED != VALUE) ||
6646 std::string TextureTestBase::getVariableVerification(const std::string& parent_name, const GLvoid* data,
6647 const Utils::Variable::Descriptor& variable,
6648 Utils::Variable::FLAVOUR flavour)
6650 static const GLchar* logic_op = " ||\n ";
6651 const GLuint n_elements = (0 == variable.m_n_array_elements) ? 1 : variable.m_n_array_elements;
6652 size_t position = 0;
6653 std::string result = Utils::g_list;
6654 GLint stride = variable.m_expected_stride_of_element;
6656 /* For each each array element */
6657 for (GLuint element = 0; element < n_elements; ++element)
6659 const std::string name = Utils::Variable::GetReference(parent_name, variable, flavour, element);
6661 /* Calculate data pointer */
6662 GLvoid* data_ptr = (GLvoid*)((GLubyte*)data + element * stride);
6664 /* Prepare verification */
6665 if (Utils::Variable::BUILTIN == variable.m_type)
6667 const std::string& expected = variable.m_builtin.GetGLSLConstructor(data_ptr);
6668 std::string verification;
6669 size_t verification_position = 0;
6671 verification = "(EXPECTED != NAME)";
6673 Utils::replaceToken("EXPECTED", verification_position, expected.c_str(), verification);
6674 Utils::replaceToken("NAME", verification_position, name.c_str(), verification);
6676 Utils::insertElementOfList(verification.c_str(), logic_op, position, result);
6680 const Utils::Interface* interface = variable.m_interface;
6684 TCU_FAIL("Nullptr");
6687 const GLuint n_members = static_cast<GLuint>(interface->m_members.size());
6689 /* for each member */
6690 for (GLuint member_index = 0; member_index < n_members; ++member_index)
6692 const Utils::Variable::Descriptor& member = interface->m_members[member_index];
6694 /* Get verification of member */
6695 const std::string& verification =
6696 getVariableVerification(name, (GLubyte*)data_ptr + member.m_offset, member, Utils::Variable::BASIC);
6698 Utils::insertElementOfList(verification.c_str(), logic_op, position, result);
6703 Utils::endList("", position, result);
6708 /** Prepare attributes, vertex array object and array buffer
6710 * @param test_case_index Index of test case
6711 * @param program_interface Interface of program
6712 * @param buffer Array buffer
6713 * @param vao Vertex array object
6715 void TextureTestBase::prepareAttributes(GLuint test_case_index, Utils::ProgramInterface& program_interface,
6716 Utils::Buffer& buffer, Utils::VertexArray& vao)
6718 bool use_component_qualifier = useComponentQualifier(test_case_index);
6720 /* Get shader interface */
6721 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
6723 /* Bind vao and buffer */
6727 /* Skip if there are no input variables in vertex shader */
6728 if (0 == si.m_inputs.size())
6733 const Functions& gl = m_context.getRenderContext().getFunctions();
6735 /* Calculate vertex stride and check */
6737 gl.getIntegerv(GL_MAX_VERTEX_ATTRIBS, &max_inputs);
6738 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
6740 /* dvec3/4 vertex inputs use a single location but require 2x16B slots */
6741 GLint max_slots = max_inputs * 2;
6743 /* Compute used slots */
6744 std::vector<GLint> slot_sizes;
6745 slot_sizes.resize(max_slots);
6746 std::fill(slot_sizes.begin(), slot_sizes.end(), 0);
6747 for (GLuint i = 0; i < si.m_inputs.size(); ++i)
6749 Utils::Variable& variable = *si.m_inputs[i];
6751 GLint variable_size = static_cast<GLuint>(variable.m_data_size);
6753 GLint base_slot = variable.m_descriptor.m_expected_location + variable.m_descriptor.m_offset / 16;
6754 GLint ends_at = variable.m_descriptor.m_offset % 16 + variable_size;
6756 GLint array_length = std::max(1u, variable.m_descriptor.m_n_array_elements);
6757 for (GLint loc = 0; loc < array_length; loc++) {
6758 GLint slot = base_slot + loc;
6759 slot_sizes[slot] = std::max(slot_sizes[slot], ends_at);
6763 /* Compute the offsets where we need to put vertex buffer data for each slot */
6764 std::vector<GLint> slot_offsets;
6765 slot_offsets.resize(max_slots);
6766 std::fill(slot_offsets.begin(), slot_offsets.end(), -1);
6767 GLint buffer_size = 0;
6768 for (GLint i = 0; i < max_slots; i++)
6770 if (slot_sizes[i] == 0)
6772 slot_offsets[i] = buffer_size;
6773 buffer_size += slot_sizes[i];
6776 /* Prepare buffer data and set up vao */
6777 std::vector<GLubyte> buffer_data;
6778 buffer_data.resize(buffer_size);
6780 GLubyte* ptr = &buffer_data[0];
6782 for (GLuint i = 0; i < si.m_inputs.size(); ++i)
6784 Utils::Variable& variable = *si.m_inputs[i];
6786 GLint base_slot = variable.m_descriptor.m_expected_location + variable.m_descriptor.m_offset / 16;
6787 GLint variable_offset = variable.m_descriptor.m_offset % 16;
6788 GLint array_length = std::max(1u, variable.m_descriptor.m_n_array_elements);
6789 for (GLint loc = 0; loc < array_length; loc++) {
6790 GLint slot = base_slot + loc;
6791 memcpy(ptr + slot_offsets[slot] + variable_offset, variable.m_data, variable.m_data_size);
6794 if (false == use_component_qualifier)
6796 vao.Attribute(variable.m_descriptor.m_expected_location, variable.m_descriptor.m_builtin,
6797 variable.m_descriptor.m_n_array_elements, variable.m_descriptor.m_normalized,
6798 variable.GetStride(), (GLvoid*)(intptr_t)(slot_offsets[base_slot] + variable_offset));
6800 else if (0 == variable.m_descriptor.m_expected_component)
6802 /* Components can only be applied to vectors.
6803 Assumption that test use all 4 components */
6804 const Utils::Type& type =
6805 Utils::Type::GetType(variable.m_descriptor.m_builtin.m_basic_type, 1 /* n_columns */, 4 /* n_rows */);
6807 vao.Attribute(variable.m_descriptor.m_expected_location, type, variable.m_descriptor.m_n_array_elements,
6808 variable.m_descriptor.m_normalized, variable.GetStride(),
6809 (GLvoid*)(intptr_t)(slot_offsets[base_slot] + variable_offset));
6814 buffer.Data(Utils::Buffer::StaticDraw, buffer_size, ptr);
6817 /** Get locations for all outputs with automatic_location
6819 * @param program Program object
6820 * @param program_interface Interface of program
6822 void TextureTestBase::prepareFragmentDataLoc(Utils::Program& program, Utils::ProgramInterface& program_interface)
6824 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
6825 Utils::Variable::PtrVector& outputs = si.m_outputs;
6827 for (Utils::Variable::PtrVector::iterator it = outputs.begin(); outputs.end() != it; ++it)
6829 /* Test does not specify location, query value and set */
6830 if (Utils::Variable::m_automatic_location == (*it)->m_descriptor.m_expected_location)
6832 GLuint index = program.GetResourceIndex((*it)->m_descriptor.m_name, GL_PROGRAM_OUTPUT);
6835 program.GetResource(GL_PROGRAM_OUTPUT, index, GL_LOCATION, 1 /* size */, &location);
6837 (*it)->m_descriptor.m_expected_location = location;
6842 /** Prepare framebuffer with single texture as color attachment
6844 * @param framebuffer Framebuffer
6845 * @param color_0_texture Texture that will used as color attachment
6847 void TextureTestBase::prepareFramebuffer(Utils::Framebuffer& framebuffer, Utils::Texture& color_0_texture)
6850 std::vector<GLuint> texture_data;
6851 texture_data.resize(m_width * m_height);
6853 for (GLuint i = 0; i < texture_data.size(); ++i)
6855 texture_data[i] = 0x20406080;
6858 /* Prepare texture */
6859 color_0_texture.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT,
6862 /* Prepare framebuffer */
6865 framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0, color_0_texture.m_id, m_width, m_height);
6867 framebuffer.ClearColor(0.0f, 0.0f, 0.0f, 0.0f);
6868 framebuffer.Clear(GL_COLOR_BUFFER_BIT);
6871 /** Prepare iamge unit for compute shader
6873 * @param location Uniform location
6874 * @param image_texture Texture that will used as color attachment
6876 void TextureTestBase::prepareImage(GLint location, Utils::Texture& image_texture) const
6878 static const GLuint image_unit = 0;
6880 std::vector<GLuint> texture_data;
6881 texture_data.resize(m_width * m_height);
6883 for (GLuint i = 0; i < texture_data.size(); ++i)
6885 texture_data[i] = 0x20406080;
6888 image_texture.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT,
6891 const Functions& gl = m_context.getRenderContext().getFunctions();
6893 gl.bindImageTexture(image_unit, image_texture.m_id, 0 /* level */, GL_FALSE /* layered */, 0 /* Layer */,
6894 GL_WRITE_ONLY, GL_R32UI);
6895 GLU_EXPECT_NO_ERROR(gl.getError(), "BindImageTexture");
6897 Utils::Program::Uniform(gl, Utils::Type::_int, 1 /* count */, location, &image_unit);
6900 /** Basic implementation
6903 * @param si Shader interface
6904 * @param program Program
6905 * @param cs_buffer Buffer for ssb blocks
6907 void TextureTestBase::prepareSSBs(GLuint /* test_case_index */, Utils::ShaderInterface& si, Utils::Program& program,
6908 Utils::Buffer& buffer)
6910 /* Skip if there are no input variables in vertex shader */
6911 if (0 == si.m_ssb_blocks.size())
6916 /* Calculate vertex stride */
6917 GLint ssbs_stride = 0;
6919 for (GLuint i = 0; i < si.m_ssb_blocks.size(); ++i)
6921 Utils::Variable& variable = *si.m_ssb_blocks[i];
6923 if (false == variable.IsBlock())
6928 GLint variable_stride = variable.GetStride();
6930 GLint ends_at = variable_stride + variable.m_descriptor.m_offset;
6932 ssbs_stride = std::max(ssbs_stride, ends_at);
6935 /* Set active program */
6940 buffer.Data(Utils::Buffer::StaticDraw, ssbs_stride, 0);
6942 /* Set up uniforms */
6943 for (GLuint i = 0; i < si.m_ssb_blocks.size(); ++i)
6945 Utils::Variable& variable = *si.m_ssb_blocks[i];
6947 /* prepareUnifor should work fine for ssb blocks */
6948 prepareUniform(program, variable, buffer);
6952 /** Basic implementation
6954 * @param test_case_index Test case index
6955 * @param program_interface Program interface
6956 * @param program Program
6957 * @param cs_buffer Buffer for compute shader stage
6959 void TextureTestBase::prepareSSBs(GLuint test_case_index, Utils::ProgramInterface& program_interface,
6960 Utils::Program& program, Utils::Buffer& cs_buffer)
6962 cs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
6964 Utils::ShaderInterface& cs = program_interface.GetShaderInterface(Utils::Shader::COMPUTE);
6966 prepareSSBs(test_case_index, cs, program, cs_buffer);
6968 cs_buffer.BindBase(Utils::Shader::COMPUTE);
6971 /** Basic implementation
6973 * @param test_case_index Test case index
6974 * @param program_interface Program interface
6975 * @param program Program
6976 * @param fs_buffer Buffer for fragment shader stage
6977 * @param gs_buffer Buffer for geometry shader stage
6978 * @param tcs_buffer Buffer for tessellation control shader stage
6979 * @param tes_buffer Buffer for tessellation evaluation shader stage
6980 * @param vs_buffer Buffer for vertex shader stage
6982 void TextureTestBase::prepareSSBs(GLuint test_case_index, Utils::ProgramInterface& program_interface,
6983 Utils::Program& program, Utils::Buffer& fs_buffer, Utils::Buffer& gs_buffer,
6984 Utils::Buffer& tcs_buffer, Utils::Buffer& tes_buffer, Utils::Buffer& vs_buffer)
6986 fs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
6987 gs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
6988 tcs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
6989 tes_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
6990 vs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
6992 Utils::ShaderInterface& fs = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
6993 Utils::ShaderInterface& gs = program_interface.GetShaderInterface(Utils::Shader::GEOMETRY);
6994 Utils::ShaderInterface& tcs = program_interface.GetShaderInterface(Utils::Shader::TESS_CTRL);
6995 Utils::ShaderInterface& tes = program_interface.GetShaderInterface(Utils::Shader::TESS_EVAL);
6996 Utils::ShaderInterface& vs = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
6998 prepareSSBs(test_case_index, fs, program, fs_buffer);
6999 prepareSSBs(test_case_index, gs, program, gs_buffer);
7000 prepareSSBs(test_case_index, tcs, program, tcs_buffer);
7001 prepareSSBs(test_case_index, tes, program, tes_buffer);
7002 prepareSSBs(test_case_index, vs, program, vs_buffer);
7004 fs_buffer.BindBase(Utils::Shader::FRAGMENT);
7005 gs_buffer.BindBase(Utils::Shader::GEOMETRY);
7006 tcs_buffer.BindBase(Utils::Shader::TESS_CTRL);
7007 tes_buffer.BindBase(Utils::Shader::TESS_EVAL);
7008 vs_buffer.BindBase(Utils::Shader::VERTEX);
7011 /** Updates buffer data with variable
7013 * @param program Program object
7014 * @param variable Variable
7015 * @param buffer Buffer
7017 void TextureTestBase::prepareUniform(Utils::Program& program, Utils::Variable& variable, Utils::Buffer& buffer)
7019 const Functions& gl = m_context.getRenderContext().getFunctions();
7021 GLsizei count = variable.m_descriptor.m_n_array_elements;
7027 if (Utils::Variable::BUILTIN == variable.m_descriptor.m_type)
7029 program.Uniform(gl, variable.m_descriptor.m_builtin, count, variable.m_descriptor.m_expected_location,
7034 const bool is_block = variable.IsBlock();
7036 if (false == is_block)
7038 TCU_FAIL("Not implemented");
7042 buffer.SubData(variable.m_descriptor.m_offset, variable.m_descriptor.m_expected_stride_of_element * count,
7048 /** Basic implementation
7051 * @param si Shader interface
7052 * @param program Program
7053 * @param cs_buffer Buffer for uniform blocks
7055 void TextureTestBase::prepareUniforms(GLuint /* test_case_index */, Utils::ShaderInterface& si, Utils::Program& program,
7056 Utils::Buffer& buffer)
7058 /* Skip if there are no input variables in vertex shader */
7059 if (0 == si.m_uniforms.size())
7064 /* Calculate vertex stride */
7065 GLint uniforms_stride = 0;
7067 for (GLuint i = 0; i < si.m_uniforms.size(); ++i)
7069 Utils::Variable& variable = *si.m_uniforms[i];
7071 if (false == variable.IsBlock())
7076 GLint variable_stride = variable.GetStride();
7078 GLint ends_at = variable_stride + variable.m_descriptor.m_offset;
7080 uniforms_stride = std::max(uniforms_stride, ends_at);
7083 /* Set active program */
7088 buffer.Data(Utils::Buffer::StaticDraw, uniforms_stride, 0);
7090 /* Set up uniforms */
7091 for (GLuint i = 0; i < si.m_uniforms.size(); ++i)
7093 Utils::Variable& variable = *si.m_uniforms[i];
7095 prepareUniform(program, variable, buffer);
7099 /** Basic implementation
7101 * @param test_case_index Test case index
7102 * @param program_interface Program interface
7103 * @param program Program
7104 * @param cs_buffer Buffer for compute shader stage
7106 void TextureTestBase::prepareUniforms(GLuint test_case_index, Utils::ProgramInterface& program_interface,
7107 Utils::Program& program, Utils::Buffer& cs_buffer)
7109 cs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7111 Utils::ShaderInterface& cs = program_interface.GetShaderInterface(Utils::Shader::COMPUTE);
7113 prepareUniforms(test_case_index, cs, program, cs_buffer);
7115 cs_buffer.BindBase(Utils::Shader::COMPUTE);
7118 /** Basic implementation
7120 * @param test_case_index Test case index
7121 * @param program_interface Program interface
7122 * @param program Program
7123 * @param fs_buffer Buffer for fragment shader stage
7124 * @param gs_buffer Buffer for geometry shader stage
7125 * @param tcs_buffer Buffer for tessellation control shader stage
7126 * @param tes_buffer Buffer for tessellation evaluation shader stage
7127 * @param vs_buffer Buffer for vertex shader stage
7129 void TextureTestBase::prepareUniforms(GLuint test_case_index, Utils::ProgramInterface& program_interface,
7130 Utils::Program& program, Utils::Buffer& fs_buffer, Utils::Buffer& gs_buffer,
7131 Utils::Buffer& tcs_buffer, Utils::Buffer& tes_buffer, Utils::Buffer& vs_buffer)
7133 fs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7134 gs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7135 tcs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7136 tes_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7137 vs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7139 Utils::ShaderInterface& fs = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
7140 Utils::ShaderInterface& gs = program_interface.GetShaderInterface(Utils::Shader::GEOMETRY);
7141 Utils::ShaderInterface& tcs = program_interface.GetShaderInterface(Utils::Shader::TESS_CTRL);
7142 Utils::ShaderInterface& tes = program_interface.GetShaderInterface(Utils::Shader::TESS_EVAL);
7143 Utils::ShaderInterface& vs = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
7145 prepareUniforms(test_case_index, fs, program, fs_buffer);
7146 prepareUniforms(test_case_index, gs, program, gs_buffer);
7147 prepareUniforms(test_case_index, tcs, program, tcs_buffer);
7148 prepareUniforms(test_case_index, tes, program, tes_buffer);
7149 prepareUniforms(test_case_index, vs, program, vs_buffer);
7151 fs_buffer.BindBase(Utils::Shader::FRAGMENT);
7152 gs_buffer.BindBase(Utils::Shader::GEOMETRY);
7153 tcs_buffer.BindBase(Utils::Shader::TESS_CTRL);
7154 tes_buffer.BindBase(Utils::Shader::TESS_EVAL);
7155 vs_buffer.BindBase(Utils::Shader::VERTEX);
7158 /** Basic implementation
7160 * @param test_case_index Test case index
7161 * @param program_interface Program interface
7162 * @param program Program
7163 * @param fs_buffer Buffer for fragment shader stage
7164 * @param gs_buffer Buffer for geometry shader stage
7165 * @param tcs_buffer Buffer for tessellation control shader stage
7166 * @param tes_buffer Buffer for tessellation evaluation shader stage
7167 * @param vs_buffer Buffer for vertex shader stage
7169 void TextureTestBase::prepareUniforms(GLuint test_case_index, Utils::ProgramInterface& program_interface,
7170 Utils::Program& fs_program, Utils::Program& gs_program,
7171 Utils::Program& tcs_program, Utils::Program& tes_program,
7172 Utils::Program& vs_program, Utils::Buffer& fs_buffer, Utils::Buffer& gs_buffer,
7173 Utils::Buffer& tcs_buffer, Utils::Buffer& tes_buffer, Utils::Buffer& vs_buffer)
7175 fs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7176 gs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7177 tcs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7178 tes_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7179 vs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7181 Utils::ShaderInterface& fs = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
7182 Utils::ShaderInterface& gs = program_interface.GetShaderInterface(Utils::Shader::GEOMETRY);
7183 Utils::ShaderInterface& tcs = program_interface.GetShaderInterface(Utils::Shader::TESS_CTRL);
7184 Utils::ShaderInterface& tes = program_interface.GetShaderInterface(Utils::Shader::TESS_EVAL);
7185 Utils::ShaderInterface& vs = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
7187 prepareUniforms(test_case_index, fs, fs_program, fs_buffer);
7188 fs_buffer.BindBase(Utils::Shader::FRAGMENT);
7190 prepareUniforms(test_case_index, gs, gs_program, gs_buffer);
7191 gs_buffer.BindBase(Utils::Shader::GEOMETRY);
7193 prepareUniforms(test_case_index, tcs, tcs_program, tcs_buffer);
7194 tcs_buffer.BindBase(Utils::Shader::TESS_CTRL);
7196 prepareUniforms(test_case_index, tes, tes_program, tes_buffer);
7197 tes_buffer.BindBase(Utils::Shader::TESS_EVAL);
7199 prepareUniforms(test_case_index, vs, vs_program, vs_buffer);
7200 vs_buffer.BindBase(Utils::Shader::VERTEX);
7203 /** Prepare source for shader
7205 * @param test_case_index Index of test case
7206 * @param program_interface Interface of program
7207 * @param varying_passthrough Collection of connection between in and out variables
7208 * @param stage Shader stage
7210 * @return Source of shader
7212 std::string TextureTestBase::getShaderSource(GLuint test_case_index, Utils::ProgramInterface& program_interface,
7213 Utils::VaryingPassthrough& varying_passthrough,
7214 Utils::Shader::STAGES stage)
7217 const GLchar* shader_template = getShaderTemplate(stage);
7218 const std::string& shader_interface = program_interface.GetInterfaceForStage(stage);
7220 const std::string& verification = getVerificationSnippet(test_case_index, program_interface, stage);
7222 const std::string& passthrough = getPassSnippet(test_case_index, varying_passthrough, stage);
7224 const GLchar* per_vertex = "";
7226 std::string source = shader_template;
7227 size_t position = 0;
7229 /* Replace tokens in template */
7230 if (Utils::Shader::GEOMETRY == stage)
7232 if (false == useMonolithicProgram(test_case_index))
7234 per_vertex = "out gl_PerVertex {\n"
7235 "vec4 gl_Position;\n"
7240 Utils::replaceToken("PERVERTEX", position, per_vertex, source);
7243 Utils::replaceToken("INTERFACE", position, shader_interface.c_str(), source);
7244 Utils::replaceToken("VERIFICATION", position, verification.c_str(), source);
7246 if (false == verification.empty())
7248 Utils::replaceAllTokens("ELSE", " else ", source);
7252 Utils::replaceAllTokens("ELSE", "", source);
7255 Utils::replaceAllTokens("PASSTHROUGH", passthrough.c_str(), source);
7261 /** Returns template of shader for given stage
7263 * @param stage Shade stage
7265 * @return Proper template
7267 const GLchar* TextureTestBase::getShaderTemplate(Utils::Shader::STAGES stage)
7270 static const GLchar* compute_shader_template =
7271 "#version 430 core\n"
7272 "#extension GL_ARB_enhanced_layouts : require\n"
7274 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
7276 "writeonly uniform uimage2D uni_image;\n"
7282 " uint result = 1u;\n"
7286 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), uvec4(result, 0, 0, 0));\n"
7290 static const GLchar* fragment_shader_template = "#version 430 core\n"
7291 "#extension GL_ARB_enhanced_layouts : require\n"
7293 "flat in uint gs_fs_result;\n"
7294 " out uint fs_out_result;\n"
7300 " uint result = 1u;\n"
7302 " if (1u != gs_fs_result)\n"
7304 " result = gs_fs_result;\n"
7308 " fs_out_result = result;\n"
7313 static const GLchar* geometry_shader_template =
7314 "#version 430 core\n"
7315 "#extension GL_ARB_enhanced_layouts : require\n"
7317 "layout(points) in;\n"
7318 "layout(triangle_strip, max_vertices = 4) out;\n"
7320 " in uint tes_gs_result[];\n"
7321 "flat out uint gs_fs_result;\n"
7323 "PERVERTEX" /* Separable programs require explicit declaration of gl_PerVertex */
7328 " uint result = 1u;\n"
7330 " if (1u != tes_gs_result[0])\n"
7332 " result = tes_gs_result[0];\n"
7336 " gs_fs_result = result;\n"
7338 " gl_Position = vec4(-1, -1, 0, 1);\n"
7340 " gs_fs_result = result;\n"
7342 " gl_Position = vec4(-1, 1, 0, 1);\n"
7344 " gs_fs_result = result;\n"
7346 " gl_Position = vec4(1, -1, 0, 1);\n"
7348 " gs_fs_result = result;\n"
7350 " gl_Position = vec4(1, 1, 0, 1);\n"
7355 static const GLchar* tess_ctrl_shader_template = "#version 430 core\n"
7356 "#extension GL_ARB_enhanced_layouts : require\n"
7358 "layout(vertices = 1) out;\n"
7360 "in uint vs_tcs_result[];\n"
7361 "out uint tcs_tes_result[];\n"
7367 " uint result = 1u;\n"
7369 " if (1u != vs_tcs_result[gl_InvocationID])\n"
7371 " result = vs_tcs_result[gl_InvocationID];\n"
7375 " tcs_tes_result[gl_InvocationID] = result;\n"
7379 " gl_TessLevelOuter[0] = 1.0;\n"
7380 " gl_TessLevelOuter[1] = 1.0;\n"
7381 " gl_TessLevelOuter[2] = 1.0;\n"
7382 " gl_TessLevelOuter[3] = 1.0;\n"
7383 " gl_TessLevelInner[0] = 1.0;\n"
7384 " gl_TessLevelInner[1] = 1.0;\n"
7388 static const GLchar* tess_eval_shader_template = "#version 430 core\n"
7389 "#extension GL_ARB_enhanced_layouts : require\n"
7391 "layout(isolines, point_mode) in;\n"
7393 "in uint tcs_tes_result[];\n"
7394 "out uint tes_gs_result;\n"
7400 " uint result = 1u;\n"
7402 " if (1 != tcs_tes_result[0])\n"
7404 " result = tcs_tes_result[0];\n"
7408 " tes_gs_result = result;\n"
7414 static const GLchar* vertex_shader_template = "#version 430 core\n"
7415 "#extension GL_ARB_enhanced_layouts : require\n"
7417 "out uint vs_tcs_result;\n"
7423 " uint result = 1u;\n"
7427 " vs_tcs_result = result;\n"
7433 const GLchar* result = 0;
7437 case Utils::Shader::COMPUTE:
7438 result = compute_shader_template;
7440 case Utils::Shader::FRAGMENT:
7441 result = fragment_shader_template;
7443 case Utils::Shader::GEOMETRY:
7444 result = geometry_shader_template;
7446 case Utils::Shader::TESS_CTRL:
7447 result = tess_ctrl_shader_template;
7449 case Utils::Shader::TESS_EVAL:
7450 result = tess_eval_shader_template;
7452 case Utils::Shader::VERTEX:
7453 result = vertex_shader_template;
7456 TCU_FAIL("Invalid enum");
7464 * @param test_case_index Id of test case
7466 * @return true if test case pass, false otherwise
7468 bool TextureTestBase::testCase(GLuint test_case_index)
7472 if (true == useMonolithicProgram(test_case_index))
7474 return testMonolithic(test_case_index);
7478 return testSeparable(test_case_index);
7481 catch (Utils::Shader::InvalidSourceException& exc)
7484 TCU_FAIL(exc.what());
7486 catch (Utils::Program::BuildException& exc)
7488 TCU_FAIL(exc.what());
7492 /** Runs "draw" test with monolithic program
7494 * @param test_case_index Id of test case
7496 bool TextureTestBase::testMonolithic(GLuint test_case_index)
7498 Utils::ProgramInterface program_interface;
7499 Utils::VaryingPassthrough varying_passthrough;
7502 const std::string& test_name = getTestCaseName(test_case_index);
7505 getProgramInterface(test_case_index, program_interface, varying_passthrough);
7509 if (true == isDrawRelevant(test_case_index))
7511 Utils::Buffer buffer_attr(m_context);
7512 Utils::Buffer buffer_ssb_fs(m_context);
7513 Utils::Buffer buffer_ssb_gs(m_context);
7514 Utils::Buffer buffer_ssb_tcs(m_context);
7515 Utils::Buffer buffer_ssb_tes(m_context);
7516 Utils::Buffer buffer_ssb_vs(m_context);
7517 Utils::Buffer buffer_u_fs(m_context);
7518 Utils::Buffer buffer_u_gs(m_context);
7519 Utils::Buffer buffer_u_tcs(m_context);
7520 Utils::Buffer buffer_u_tes(m_context);
7521 Utils::Buffer buffer_u_vs(m_context);
7522 Utils::Framebuffer framebuffer(m_context);
7523 Utils::Program program(m_context);
7524 Utils::Texture texture_fb(m_context);
7525 Utils::VertexArray vao(m_context);
7528 const std::string& fragment_shader =
7529 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::FRAGMENT);
7530 const std::string& geometry_shader =
7531 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::GEOMETRY);
7532 const std::string& tess_ctrl_shader =
7533 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::TESS_CTRL);
7534 const std::string& tess_eval_shader =
7535 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::TESS_EVAL);
7536 const std::string& vertex_shader =
7537 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::VERTEX);
7539 program.Init("" /* compute_shader */, fragment_shader, geometry_shader, tess_ctrl_shader, tess_eval_shader,
7540 vertex_shader, false /* is_separable */);
7543 prepareAttribLocation(program, program_interface);
7544 prepareFragmentDataLoc(program, program_interface);
7547 std::stringstream stream;
7548 if (false == Utils::checkMonolithicDrawProgramInterface(program, program_interface, stream))
7550 m_context.getTestContext().getLog()
7551 << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7552 << ". Inspection of draw program interface failed:\n"
7553 << stream.str() << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(vertex_shader)
7554 << tcu::TestLog::KernelSource(tess_ctrl_shader) << tcu::TestLog::KernelSource(tess_eval_shader)
7555 << tcu::TestLog::KernelSource(geometry_shader) << tcu::TestLog::KernelSource(fragment_shader);
7564 buffer_attr.Init(Utils::Buffer::Array, Utils::Buffer::StaticDraw, 0, 0);
7566 prepareAttributes(test_case_index, program_interface, buffer_attr, vao);
7569 prepareUniforms(test_case_index, program_interface, program, buffer_u_fs, buffer_u_gs, buffer_u_tcs,
7570 buffer_u_tes, buffer_u_vs);
7572 prepareSSBs(test_case_index, program_interface, program, buffer_ssb_fs, buffer_ssb_gs, buffer_ssb_tcs,
7573 buffer_ssb_tes, buffer_ssb_vs);
7576 prepareFramebuffer(framebuffer, texture_fb);
7579 executeDrawCall(test_case_index);
7582 m_context.getRenderContext().postIterate();
7586 if (false == checkResults(test_case_index, texture_fb))
7588 m_context.getTestContext().getLog()
7589 << tcu::TestLog::Message << "FAILURE. Test case: " << test_name << ". Draw - invalid results."
7590 << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(vertex_shader)
7591 << tcu::TestLog::KernelSource(tess_ctrl_shader) << tcu::TestLog::KernelSource(tess_eval_shader)
7592 << tcu::TestLog::KernelSource(geometry_shader) << tcu::TestLog::KernelSource(fragment_shader);
7599 if (true == isComputeRelevant(test_case_index))
7601 Utils::Buffer buffer_ssb_cs(m_context);
7602 Utils::Buffer buffer_u_cs(m_context);
7603 Utils::Program program(m_context);
7604 Utils::Texture texture_im(m_context);
7605 Utils::VertexArray vao(m_context);
7608 const std::string& compute_shader =
7609 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::COMPUTE);
7611 program.Init(compute_shader, "" /* fragment_shader */, "" /* geometry_shader */, "" /* tess_ctrl_shader */,
7612 "" /* tess_eval_shader */, "" /* vertex_shader */, false /* is_separable */);
7616 std::stringstream stream;
7618 if (false == Utils::checkMonolithicComputeProgramInterface(program, program_interface, stream))
7620 m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7621 << ". Inspection of compute program interface failed:\n"
7622 << stream.str() << tcu::TestLog::EndMessage;
7636 prepareUniforms(test_case_index, program_interface, program, buffer_u_cs);
7638 prepareSSBs(test_case_index, program_interface, program, buffer_ssb_cs);
7641 GLint image_location = program.GetUniformLocation("uni_image");
7642 prepareImage(image_location, texture_im);
7645 executeDispatchCall(test_case_index);
7648 m_context.getRenderContext().postIterate();
7652 if (false == checkResults(test_case_index, texture_im))
7654 m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7655 << ". Compute - invalid results." << tcu::TestLog::EndMessage
7656 << tcu::TestLog::KernelSource(compute_shader);
7665 /** Runs "draw" test with separable program
7667 * @param test_case_index Id of test case
7669 bool TextureTestBase::testSeparable(GLuint test_case_index)
7671 Utils::ProgramInterface program_interface;
7672 Utils::VaryingPassthrough varying_passthrough;
7675 const std::string& test_name = getTestCaseName(test_case_index);
7678 getProgramInterface(test_case_index, program_interface, varying_passthrough);
7682 if (true == isDrawRelevant(test_case_index))
7684 Utils::Buffer buffer_attr(m_context);
7685 Utils::Buffer buffer_u_fs(m_context);
7686 Utils::Buffer buffer_u_gs(m_context);
7687 Utils::Buffer buffer_u_tcs(m_context);
7688 Utils::Buffer buffer_u_tes(m_context);
7689 Utils::Buffer buffer_u_vs(m_context);
7690 Utils::Framebuffer framebuffer(m_context);
7691 Utils::Pipeline pipeline(m_context);
7692 Utils::Program program_fs(m_context);
7693 Utils::Program program_gs(m_context);
7694 Utils::Program program_tcs(m_context);
7695 Utils::Program program_tes(m_context);
7696 Utils::Program program_vs(m_context);
7697 Utils::Texture texture_fb(m_context);
7698 Utils::VertexArray vao(m_context);
7701 const std::string& fs =
7702 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::FRAGMENT);
7703 const std::string& gs =
7704 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::GEOMETRY);
7705 const std::string& tcs =
7706 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::TESS_CTRL);
7707 const std::string& tes =
7708 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::TESS_EVAL);
7709 const std::string& vs =
7710 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::VERTEX);
7712 program_fs.Init("" /*cs*/, fs, "" /*gs*/, "" /*tcs*/, "" /*tes*/, "" /*vs*/, true /* is_separable */);
7713 program_gs.Init("" /*cs*/, "" /*fs*/, gs, "" /*tcs*/, "" /*tes*/, "" /*vs*/, true /* is_separable */);
7714 program_tcs.Init("" /*cs*/, "" /*fs*/, "" /*gs*/, tcs, "" /*tes*/, "" /*vs*/, true /* is_separable */);
7715 program_tes.Init("" /*cs*/, "" /*fs*/, "" /*gs*/, "" /*tcs*/, tes, "" /*vs*/, true /* is_separable */);
7716 program_vs.Init("" /*cs*/, "" /*fs*/, "" /*gs*/, "" /*tcs*/, "" /*tes*/, vs, true /* is_separable */);
7719 prepareAttribLocation(program_vs, program_interface);
7720 prepareFragmentDataLoc(program_vs, program_interface);
7723 std::stringstream stream;
7725 Utils::checkSeparableDrawProgramInterface(program_vs, program_interface, Utils::Shader::VERTEX, stream)) ||
7726 (false == Utils::checkSeparableDrawProgramInterface(program_fs, program_interface, Utils::Shader::FRAGMENT,
7728 (false == Utils::checkSeparableDrawProgramInterface(program_gs, program_interface, Utils::Shader::GEOMETRY,
7730 (false == Utils::checkSeparableDrawProgramInterface(program_tcs, program_interface,
7731 Utils::Shader::TESS_CTRL, stream)) ||
7732 (false == Utils::checkSeparableDrawProgramInterface(program_tes, program_interface,
7733 Utils::Shader::TESS_EVAL, stream)))
7735 m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7736 << ". Inspection of separable draw program interface failed:\n"
7737 << stream.str() << tcu::TestLog::EndMessage
7738 << tcu::TestLog::KernelSource(vs) << tcu::TestLog::KernelSource(tcs)
7739 << tcu::TestLog::KernelSource(tes) << tcu::TestLog::KernelSource(gs)
7740 << tcu::TestLog::KernelSource(fs);
7747 pipeline.UseProgramStages(program_fs.m_id, GL_FRAGMENT_SHADER_BIT);
7748 pipeline.UseProgramStages(program_gs.m_id, GL_GEOMETRY_SHADER_BIT);
7749 pipeline.UseProgramStages(program_tcs.m_id, GL_TESS_CONTROL_SHADER_BIT);
7750 pipeline.UseProgramStages(program_tes.m_id, GL_TESS_EVALUATION_SHADER_BIT);
7751 pipeline.UseProgramStages(program_vs.m_id, GL_VERTEX_SHADER_BIT);
7756 buffer_attr.Init(Utils::Buffer::Array, Utils::Buffer::StaticDraw, 0, 0);
7758 prepareAttributes(test_case_index, program_interface, buffer_attr, vao);
7761 prepareUniforms(test_case_index, program_interface, program_fs, program_gs, program_tcs, program_tes,
7762 program_vs, buffer_u_fs, buffer_u_gs, buffer_u_tcs, buffer_u_tes, buffer_u_vs);
7764 Utils::Program::Use(m_context.getRenderContext().getFunctions(), Utils::Program::m_invalid_id);
7767 prepareFramebuffer(framebuffer, texture_fb);
7770 executeDrawCall(test_case_index);
7773 m_context.getRenderContext().postIterate();
7777 if (false == checkResults(test_case_index, texture_fb))
7779 m_context.getTestContext().getLog()
7780 << tcu::TestLog::Message << "FAILURE. Test case: " << test_name << ". Draw - invalid results."
7781 << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(vs) << tcu::TestLog::KernelSource(tcs)
7782 << tcu::TestLog::KernelSource(tes) << tcu::TestLog::KernelSource(gs) << tcu::TestLog::KernelSource(fs);
7789 if (true == isComputeRelevant(test_case_index))
7791 Utils::Buffer buffer_u_cs(m_context);
7792 Utils::Program program(m_context);
7793 Utils::Texture texture_im(m_context);
7794 Utils::VertexArray vao(m_context);
7797 const std::string& compute_shader =
7798 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::COMPUTE);
7800 program.Init(compute_shader, "" /* fragment_shader */, "" /* geometry_shader */, "" /* tess_ctrl_shader */,
7801 "" /* tess_eval_shader */, "" /* vertex_shader */, false /* is_separable */);
7805 std::stringstream stream;
7807 if (false == Utils::checkMonolithicComputeProgramInterface(program, program_interface, stream))
7809 m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7810 << ". Inspection of compute program interface failed:\n"
7811 << stream.str() << tcu::TestLog::EndMessage;
7825 prepareUniforms(test_case_index, program_interface, program, buffer_u_cs);
7828 GLint image_location = program.GetUniformLocation("uni_image");
7829 prepareImage(image_location, texture_im);
7832 executeDispatchCall(test_case_index);
7835 m_context.getRenderContext().postIterate();
7839 if (false == checkResults(test_case_index, texture_im))
7841 m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7842 << ". Compute - invalid results." << tcu::TestLog::EndMessage
7843 << tcu::TestLog::KernelSource(compute_shader);
7852 /** Basic implementation
7858 bool TextureTestBase::useComponentQualifier(glw::GLuint /* test_case_index */)
7863 /** Basic implementation
7869 bool TextureTestBase::useMonolithicProgram(GLuint /* test_case_index */)
7876 * @param context Test framework context
7878 APIConstantValuesTest::APIConstantValuesTest(deqp::Context& context)
7879 : TestCase(context, "api_constant_values", "Test verifies values of api constants")
7881 /* Nothing to be done here */
7886 * @return tcu::TestNode::STOP otherwise
7888 tcu::TestNode::IterateResult APIConstantValuesTest::iterate()
7890 static const GLuint expected_comp = 64;
7891 static const GLuint expected_xfb = 4;
7892 static const GLuint expected_sep = 4;
7896 bool test_result = true;
7898 const Functions& gl = m_context.getRenderContext().getFunctions();
7900 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_xfb);
7901 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
7902 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_comp);
7903 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
7904 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, &max_sep);
7905 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
7907 if (expected_xfb > (GLuint)max_xfb)
7909 m_context.getTestContext().getLog() << tcu::TestLog::Message
7910 << "Invalid GL_MAX_TRANSFORM_FEEDBACK_BUFFERS. Got " << max_xfb
7911 << " Expected at least " << expected_xfb << tcu::TestLog::EndMessage;
7913 test_result = false;
7916 if (expected_comp > (GLuint)max_comp)
7918 m_context.getTestContext().getLog()
7919 << tcu::TestLog::Message << "Invalid GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS. Got " << max_comp
7920 << " Expected at least " << expected_comp << tcu::TestLog::EndMessage;
7922 test_result = false;
7925 if (expected_sep > (GLuint)max_sep)
7927 m_context.getTestContext().getLog() << tcu::TestLog::Message
7928 << "Invalid GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS. Got " << max_comp
7929 << " Expected at least " << expected_comp << tcu::TestLog::EndMessage;
7931 test_result = false;
7935 if (true == test_result)
7937 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
7941 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
7945 return tcu::TestNode::STOP;
7950 * @param context Test framework context
7952 APIErrorsTest::APIErrorsTest(deqp::Context& context)
7953 : TestCase(context, "api_errors", "Test verifies errors reeturned by api")
7955 /* Nothing to be done here */
7960 * @return tcu::TestNode::STOP otherwise
7962 tcu::TestNode::IterateResult APIErrorsTest::iterate()
7967 Utils::Program program(m_context);
7968 bool test_result = true;
7970 const Functions& gl = m_context.getRenderContext().getFunctions();
7974 program.Init("" /* cs */, "#version 430 core\n"
7975 "#extension GL_ARB_enhanced_layouts : require\n"
7978 "out vec4 fs_out;\n"
7982 " fs_out = vs_fs;\n"
7985 "" /* gs */, "" /* tcs */, "" /* tes */, "#version 430 core\n"
7986 "#extension GL_ARB_enhanced_layouts : require\n"
7989 "layout (xfb_offset = 16) out vec4 vs_fs;\n"
7996 false /* separable */);
7998 catch (Utils::Shader::InvalidSourceException& exc)
8001 TCU_FAIL(exc.what());
8003 catch (Utils::Program::BuildException& exc)
8005 TCU_FAIL(exc.what());
8009 * - GetProgramInterfaceiv should generate INVALID_OPERATION when
8010 * <programInterface> is TRANSFORM_FEEDBACK_BUFFER and <pname> is one of the
8012 * * MAX_NAME_LENGTH,
8013 * * MAX_NUM_ACTIVE_VARIABLES;
8015 gl.getProgramInterfaceiv(program.m_id, GL_TRANSFORM_FEEDBACK_BUFFER, GL_MAX_NAME_LENGTH, ¶m);
8016 checkError(GL_INVALID_OPERATION, "GetProgramInterfaceiv(GL_TRANSFORM_FEEDBACK_BUFFER, GL_MAX_NAME_LENGTH)",
8020 * - GetProgramResourceIndex should generate INVALID_ENUM when
8021 * <programInterface> is TRANSFORM_FEEDBACK_BUFFER;
8023 gl.getProgramResourceIndex(program.m_id, GL_TRANSFORM_FEEDBACK_BUFFER, "0");
8024 checkError(GL_INVALID_ENUM, "GetProgramResourceIndex(GL_TRANSFORM_FEEDBACK_BUFFER)", test_result);
8026 * - GetProgramResourceName should generate INVALID_ENUM when
8027 * <programInterface> is TRANSFORM_FEEDBACK_BUFFER;
8029 gl.getProgramResourceName(program.m_id, GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, 64 /* bufSize */, &length,
8031 checkError(GL_INVALID_ENUM, "GetProgramResourceName(GL_TRANSFORM_FEEDBACK_BUFFER)", test_result);
8034 if (true == test_result)
8036 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
8040 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
8044 return tcu::TestNode::STOP;
8047 /** Check if error is the expected one.
8049 * @param expected_error Expected error
8050 * @param message Message to log in case of error
8051 * @param test_result Test result, set to false in case of invalid error
8053 void APIErrorsTest::checkError(GLenum expected_error, const GLchar* message, bool& test_result)
8055 const Functions& gl = m_context.getRenderContext().getFunctions();
8057 GLenum error = gl.getError();
8059 if (error != expected_error)
8061 m_context.getTestContext().getLog()
8062 << tcu::TestLog::Message << "Failure. Invalid error. Got " << glu::getErrorStr(error) << " expected "
8063 << glu::getErrorStr(expected_error) << " Msg: " << message << tcu::TestLog::EndMessage;
8065 test_result = false;
8071 * @param context Test framework context
8073 GLSLContantImmutablityTest::GLSLContantImmutablityTest(deqp::Context& context)
8074 : NegativeTestBase(context, "glsl_contant_immutablity", "Test verifies that glsl constants cannot be modified")
8076 /* Nothing to be done here */
8079 /** Source for given test case and stage
8081 * @param test_case_index Index of test case
8082 * @param stage Shader stage
8084 * @return Shader source
8086 std::string GLSLContantImmutablityTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
8088 static const GLchar* cs = "#version 430 core\n"
8089 "#extension GL_ARB_enhanced_layouts : require\n"
8091 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
8093 "writeonly uniform uimage2D uni_image;\n"
8097 " uint result = 1u;\n"
8100 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), uvec4(result, 0, 0, 0));\n"
8103 static const GLchar* fs = "#version 430 core\n"
8104 "#extension GL_ARB_enhanced_layouts : require\n"
8107 "out vec4 fs_out;\n"
8112 " fs_out = gs_fs;\n"
8115 static const GLchar* gs = "#version 430 core\n"
8116 "#extension GL_ARB_enhanced_layouts : require\n"
8118 "layout(points) in;\n"
8119 "layout(triangle_strip, max_vertices = 4) out;\n"
8121 "in vec4 tes_gs[];\n"
8127 " gs_fs = tes_gs[0];\n"
8128 " gl_Position = vec4(-1, -1, 0, 1);\n"
8130 " gs_fs = tes_gs[0];\n"
8131 " gl_Position = vec4(-1, 1, 0, 1);\n"
8133 " gs_fs = tes_gs[0];\n"
8134 " gl_Position = vec4(1, -1, 0, 1);\n"
8136 " gs_fs = tes_gs[0];\n"
8137 " gl_Position = vec4(1, 1, 0, 1);\n"
8141 static const GLchar* tcs = "#version 430 core\n"
8142 "#extension GL_ARB_enhanced_layouts : require\n"
8144 "layout(vertices = 1) out;\n"
8146 "in vec4 vs_tcs[];\n"
8147 "out vec4 tcs_tes[];\n"
8153 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
8155 " gl_TessLevelOuter[0] = 1.0;\n"
8156 " gl_TessLevelOuter[1] = 1.0;\n"
8157 " gl_TessLevelOuter[2] = 1.0;\n"
8158 " gl_TessLevelOuter[3] = 1.0;\n"
8159 " gl_TessLevelInner[0] = 1.0;\n"
8160 " gl_TessLevelInner[1] = 1.0;\n"
8163 static const GLchar* tes = "#version 430 core\n"
8164 "#extension GL_ARB_enhanced_layouts : require\n"
8166 "layout(isolines, point_mode) in;\n"
8168 "in vec4 tcs_tes[];\n"
8169 "out vec4 tes_gs;\n"
8174 " tes_gs = tcs_tes[0];\n"
8177 static const GLchar* vs = "#version 430 core\n"
8178 "#extension GL_ARB_enhanced_layouts : require\n"
8181 "out vec4 vs_tcs;\n"
8186 " vs_tcs = in_vs;\n"
8191 testCase& test_case = m_test_cases[test_case_index];
8193 if (Utils::Shader::COMPUTE == test_case.m_stage)
8195 size_t position = 0;
8199 Utils::replaceToken("CONSTANT", position, getConstantName(test_case.m_constant), source);
8203 std::string assignment = " CONSTANT = 3;\n";
8204 size_t position = 0;
8208 case Utils::Shader::FRAGMENT:
8211 case Utils::Shader::GEOMETRY:
8214 case Utils::Shader::TESS_CTRL:
8217 case Utils::Shader::TESS_EVAL:
8220 case Utils::Shader::VERTEX:
8224 TCU_FAIL("Invalid enum");
8227 if (test_case.m_stage == stage)
8229 Utils::replaceToken("CONSTANT", position, getConstantName(test_case.m_constant), assignment);
8237 Utils::replaceToken("ASSIGNMENT", position, assignment.c_str(), source);
8243 /** Get description of test case
8245 * @param test_case_index Index of test case
8247 * @return Constant name
8249 std::string GLSLContantImmutablityTest::getTestCaseName(GLuint test_case_index)
8251 std::string result = getConstantName(m_test_cases[test_case_index].m_constant);
8256 /** Get number of test cases
8258 * @return Number of test cases
8260 GLuint GLSLContantImmutablityTest::getTestCaseNumber()
8262 return static_cast<GLuint>(m_test_cases.size());
8265 /** Selects if "compute" stage is relevant for test
8267 * @param test_case_index Index of test case
8269 * @return true when tested stage is compute
8271 bool GLSLContantImmutablityTest::isComputeRelevant(GLuint test_case_index)
8273 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
8276 /** Prepare all test cases
8279 void GLSLContantImmutablityTest::testInit()
8281 for (GLuint constant = 0; constant < CONSTANTS_MAX; ++constant)
8283 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
8285 testCase test_case = { (CONSTANTS)constant, (Utils::Shader::STAGES)stage };
8287 m_test_cases.push_back(test_case);
8292 /** Get name of glsl constant
8294 * @param Constant id
8296 * @return Name of constant used in GLSL
8298 const GLchar* GLSLContantImmutablityTest::getConstantName(CONSTANTS constant)
8300 const GLchar* name = "";
8304 case GL_ARB_ENHANCED_LAYOUTS:
8305 name = "GL_ARB_enhanced_layouts";
8308 name = "gl_MaxTransformFeedbackBuffers";
8310 case GL_MAX_XFB_INT_COMP:
8311 name = "gl_MaxTransformFeedbackInterleavedComponents";
8314 TCU_FAIL("Invalid enum");
8322 * @param context Test framework context
8324 GLSLContantValuesTest::GLSLContantValuesTest(deqp::Context& context)
8325 : TextureTestBase(context, "glsl_contant_values", "Test verifies values of constant symbols")
8329 /** Selects if "compute" stage is relevant for test
8335 bool GLSLContantValuesTest::isComputeRelevant(GLuint /* test_case_index */)
8340 /** Prepare code snippet that will verify in and uniform variables
8344 * @param stage Shader stage
8346 * @return Code that verify variables
8348 std::string GLSLContantValuesTest::getVerificationSnippet(GLuint /* test_case_index */,
8349 Utils::ProgramInterface& /* program_interface */,
8350 Utils::Shader::STAGES stage)
8353 const Functions& gl = m_context.getRenderContext().getFunctions();
8355 GLint max_transform_feedback_buffers = 0;
8356 GLint max_transform_feedback_interleaved_components = 0;
8358 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_transform_feedback_buffers);
8359 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8360 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_transform_feedback_interleaved_components);
8361 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8363 std::string verification;
8365 if (Utils::Shader::VERTEX == stage)
8367 verification = "if (1 != GL_ARB_enhanced_layouts)\n"
8371 " else if (MAX_TRANSFORM_FEEDBACK_BUFFERS\n"
8372 " != gl_MaxTransformFeedbackBuffers)\n"
8376 " else if (MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS \n"
8377 " != gl_MaxTransformFeedbackInterleavedComponents)\n"
8382 size_t position = 0;
8385 sprintf(buffer, "%d", max_transform_feedback_buffers);
8386 Utils::replaceToken("MAX_TRANSFORM_FEEDBACK_BUFFERS", position, buffer, verification);
8388 sprintf(buffer, "%d", max_transform_feedback_interleaved_components);
8389 Utils::replaceToken("MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS", position, buffer, verification);
8396 return verification;
8401 * @param context Test framework context
8403 GLSLConstantIntegralExpressionTest::GLSLConstantIntegralExpressionTest(deqp::Context& context)
8404 : TextureTestBase(context, "glsl_constant_integral_expression",
8405 "Test verifies that symbols can be used as constant integral expressions")
8409 /** Get interface of program
8412 * @param program_interface Interface of program
8415 void GLSLConstantIntegralExpressionTest::getProgramInterface(GLuint /* test_case_index */,
8416 Utils::ProgramInterface& program_interface,
8417 Utils::VaryingPassthrough& /* varying_passthrough */)
8420 const Functions& gl = m_context.getRenderContext().getFunctions();
8422 GLint max_transform_feedback_buffers = 0;
8423 GLint max_transform_feedback_interleaved_components = 0;
8425 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_transform_feedback_buffers);
8426 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8427 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_transform_feedback_interleaved_components);
8428 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8430 GLuint gohan_div = std::max(1, max_transform_feedback_buffers / 16);
8431 GLuint goten_div = std::max(1, max_transform_feedback_interleaved_components / 16);
8433 m_gohan_length = max_transform_feedback_buffers / gohan_div;
8434 m_goten_length = max_transform_feedback_interleaved_components / goten_div;
8437 std::string globals = "uniform uint goku [GL_ARB_enhanced_layouts / 1];\n"
8438 "uniform uint gohan[gl_MaxTransformFeedbackBuffers / GOHAN_DIV];\n"
8439 "uniform uint goten[gl_MaxTransformFeedbackInterleavedComponents / GOTEN_DIV];\n";
8441 size_t position = 0;
8444 sprintf(buffer, "%d", gohan_div);
8445 Utils::replaceToken("GOHAN_DIV", position, buffer, globals);
8447 sprintf(buffer, "%d", goten_div);
8448 Utils::replaceToken("GOTEN_DIV", position, buffer, globals);
8450 program_interface.m_vertex.m_globals = globals;
8451 program_interface.m_tess_ctrl.m_globals = globals;
8452 program_interface.m_tess_eval.m_globals = globals;
8453 program_interface.m_geometry.m_globals = globals;
8454 program_interface.m_fragment.m_globals = globals;
8455 program_interface.m_compute.m_globals = globals;
8458 /** Prepare code snippet that will verify in and uniform variables
8464 * @return Code that verify variables
8466 std::string GLSLConstantIntegralExpressionTest::getVerificationSnippet(GLuint /* test_case_index */,
8467 Utils::ProgramInterface& /* program_interface */,
8468 Utils::Shader::STAGES /* stage */)
8470 std::string verification = "{\n"
8471 " uint goku_sum = 0;\n"
8472 " uint gohan_sum = 0;\n"
8473 " uint goten_sum = 0;\n"
8475 " for (uint i = 0u; i < goku.length(); ++i)\n"
8477 " goku_sum += goku[i];\n"
8480 " for (uint i = 0u; i < gohan.length(); ++i)\n"
8482 " gohan_sum += gohan[i];\n"
8485 " for (uint i = 0u; i < goten.length(); ++i)\n"
8487 " goten_sum += goten[i];\n"
8490 " if ( (1u != goku_sum) &&\n"
8491 " (EXPECTED_GOHAN_SUMu != gohan_sum) ||\n"
8492 " (EXPECTED_GOTEN_SUMu != goten_sum) )\n"
8498 size_t position = 0;
8501 sprintf(buffer, "%d", m_gohan_length);
8502 Utils::replaceToken("EXPECTED_GOHAN_SUM", position, buffer, verification);
8504 sprintf(buffer, "%d", m_goten_length);
8505 Utils::replaceToken("EXPECTED_GOTEN_SUM", position, buffer, verification);
8507 return verification;
8510 /** Prepare unifroms
8514 * @param program Program object
8517 void GLSLConstantIntegralExpressionTest::prepareUniforms(GLuint /* test_case_index */,
8518 Utils::ProgramInterface& /* program_interface */,
8519 Utils::Program& program, Utils::Buffer& /* cs_buffer */)
8521 static const GLuint uniform_data[16] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
8523 const Functions& gl = m_context.getRenderContext().getFunctions();
8525 GLint goku_location = program.GetUniformLocation("goku");
8526 GLint gohan_location = program.GetUniformLocation("gohan");
8527 GLint goten_location = program.GetUniformLocation("goten");
8529 program.Uniform(gl, Utils::Type::uint, 1 /* count */, goku_location, uniform_data);
8530 program.Uniform(gl, Utils::Type::uint, m_gohan_length, gohan_location, uniform_data);
8531 program.Uniform(gl, Utils::Type::uint, m_goten_length, goten_location, uniform_data);
8534 /** Prepare unifroms
8536 * @param test_case_index Pass as param to first implemetnation
8537 * @param program_interface Pass as param to first implemetnation
8538 * @param program Pass as param to first implemetnation
8543 * @param vs_buffer Pass as param to first implemetnation
8545 void GLSLConstantIntegralExpressionTest::prepareUniforms(GLuint test_case_index,
8546 Utils::ProgramInterface& program_interface,
8547 Utils::Program& program, Utils::Buffer& /* fs_buffer */,
8548 Utils::Buffer& /* gs_buffer */,
8549 Utils::Buffer& /* tcs_buffer */,
8550 Utils::Buffer& /* tes_buffer */, Utils::Buffer& vs_buffer)
8552 /* Call first implementation */
8553 prepareUniforms(test_case_index, program_interface, program, vs_buffer);
8558 * @param context Test framework context
8560 UniformBlockMemberOffsetAndAlignTest::UniformBlockMemberOffsetAndAlignTest(deqp::Context& context)
8561 : TextureTestBase(context, "uniform_block_member_offset_and_align",
8562 "Test verifies offsets and alignment of uniform buffer members")
8566 /** Get interface of program
8568 * @param test_case_index Test case index
8569 * @param program_interface Interface of program
8570 * @param varying_passthrough Collection of connections between in and out variables
8572 void UniformBlockMemberOffsetAndAlignTest::getProgramInterface(GLuint test_case_index,
8573 Utils::ProgramInterface& program_interface,
8574 Utils::VaryingPassthrough& varying_passthrough)
8576 std::string globals = "const int basic_size = BASIC_SIZE;\n"
8577 "const int type_align = TYPE_ALIGN;\n"
8578 "const int type_size = TYPE_SIZE;\n";
8580 Utils::Type type = getType(test_case_index);
8581 GLuint basic_size = Utils::Type::GetTypeSize(type.m_basic_type);
8582 const GLuint base_align = type.GetBaseAlignment(false);
8583 const GLuint array_align = type.GetBaseAlignment(true);
8584 const GLuint base_stride = Utils::Type::CalculateStd140Stride(base_align, type.m_n_columns, 0);
8585 const GLuint type_align = Utils::roundUpToPowerOf2(base_stride);
8587 /* Calculate offsets */
8588 const GLuint first_offset = 0;
8589 const GLuint second_offset = type.GetActualOffset(base_stride, basic_size / 2);
8591 #if WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST
8593 const GLuint third_offset = type.GetActualOffset(second_offset + base_stride, base_align);
8594 const GLuint fourth_offset = type.GetActualOffset(third_offset + base_stride, base_align);
8595 const GLuint fifth_offset = type.GetActualOffset(fourth_offset + base_stride, base_align);
8596 const GLuint sixth_offset = type.GetActualOffset(fifth_offset + base_stride, array_align);
8597 const GLuint seventh_offset = type.GetActualOffset(sixth_offset + base_stride, array_align);
8598 const GLuint eigth_offset = type.GetActualOffset(seventh_offset + base_stride, array_align);
8600 #else /* WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST */
8602 const GLuint third_offset = type.GetActualOffset(second_offset + base_stride, 2 * type_align);
8603 const GLuint fourth_offset = type.GetActualOffset(3 * type_align + base_stride, base_align);
8604 const GLuint fifth_offset = type.GetActualOffset(fourth_offset + base_stride, base_align);
8605 const GLuint sixth_offset = type.GetActualOffset(fifth_offset + base_stride, array_align);
8606 const GLuint seventh_offset = type.GetActualOffset(sixth_offset + base_stride, array_align);
8607 const GLuint eigth_offset = type.GetActualOffset(seventh_offset + base_stride, 8 * basic_size);
8609 #endif /* WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST */
8612 const std::vector<GLubyte>& first = type.GenerateData();
8613 const std::vector<GLubyte>& second = type.GenerateData();
8614 const std::vector<GLubyte>& third = type.GenerateData();
8615 const std::vector<GLubyte>& fourth = type.GenerateData();
8617 m_data.resize(eigth_offset + base_stride);
8618 GLubyte* ptr = &m_data[0];
8619 memcpy(ptr + first_offset, &first[0], first.size());
8620 memcpy(ptr + second_offset, &second[0], second.size());
8621 memcpy(ptr + third_offset, &third[0], third.size());
8622 memcpy(ptr + fourth_offset, &fourth[0], fourth.size());
8623 memcpy(ptr + fifth_offset, &fourth[0], fourth.size());
8624 memcpy(ptr + sixth_offset, &third[0], third.size());
8625 memcpy(ptr + seventh_offset, &second[0], second.size());
8626 memcpy(ptr + eigth_offset, &first[0], first.size());
8628 /* Prepare globals */
8629 size_t position = 0;
8632 sprintf(buffer, "%d", basic_size);
8633 Utils::replaceToken("BASIC_SIZE", position, buffer, globals);
8635 sprintf(buffer, "%d", type_align);
8636 Utils::replaceToken("TYPE_ALIGN", position, buffer, globals);
8638 sprintf(buffer, "%d", base_stride);
8639 Utils::replaceToken("TYPE_SIZE", position, buffer, globals);
8642 Utils::Interface* vs_uni_block = program_interface.Block("vs_uni_Block");
8644 vs_uni_block->Member("at_first_offset", "layout(offset = 0, align = 8 * basic_size)", 0 /* expected_component */,
8645 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
8648 vs_uni_block->Member("at_second_offset", "layout(offset = type_size, align = basic_size / 2)",
8649 0 /* expected_component */, 0 /* expected_location */, type, false /* normalized */,
8650 0 /* n_array_elements */, base_stride, second_offset);
8652 vs_uni_block->Member("at_third_offset", "layout(align = 2 * type_align)", 0 /* expected_component */,
8653 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
8656 vs_uni_block->Member("at_fourth_offset", "layout(offset = 3 * type_align + type_size)", 0 /* expected_component */,
8657 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
8660 vs_uni_block->Member("at_fifth_offset", "", 0 /* expected_component */, 0 /* expected_location */, type,
8661 false /* normalized */, 0 /* n_array_elements */, base_stride, fifth_offset);
8663 vs_uni_block->Member("at_sixth_offset", "", 0 /* expected_component */, 0 /* expected_location */, type,
8664 false /* normalized */, 2 /* n_array_elements */, array_align * 2, sixth_offset);
8666 vs_uni_block->Member("at_eigth_offset", "layout(align = 8 * basic_size)", 0 /* expected_component */,
8667 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
8670 Utils::ShaderInterface& vs_si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
8673 vs_si.m_globals = globals;
8675 /* Add uniform BLOCK */
8676 vs_si.Uniform("vs_uni_block", "layout (std140, binding = BINDING)", 0, 0, vs_uni_block, 0,
8677 static_cast<glw::GLint>(m_data.size()), 0, &m_data[0], m_data.size());
8680 program_interface.CloneVertexInterface(varying_passthrough);
8685 * @param test_case_index Index of test case
8687 * @return Name of type test in test_case_index
8689 std::string UniformBlockMemberOffsetAndAlignTest::getTestCaseName(glw::GLuint test_case_index)
8691 return getTypeName(test_case_index);
8694 /** Returns number of types to test
8696 * @return Number of types, 34
8698 glw::GLuint UniformBlockMemberOffsetAndAlignTest::getTestCaseNumber()
8700 return getTypesNumber();
8703 /** Prepare code snippet that will verify in and uniform variables
8707 * @param stage Shader stage
8709 * @return Code that verify variables
8711 std::string UniformBlockMemberOffsetAndAlignTest::getVerificationSnippet(
8712 GLuint /* test_case_index */, Utils::ProgramInterface& /* program_interface */, Utils::Shader::STAGES stage)
8714 std::string verification = "if ( (PREFIXblock.at_first_offset != PREFIXblock.at_eigth_offset ) ||\n"
8715 " (PREFIXblock.at_second_offset != PREFIXblock.at_sixth_offset[1]) ||\n"
8716 " (PREFIXblock.at_third_offset != PREFIXblock.at_sixth_offset[0]) ||\n"
8717 " (PREFIXblock.at_fourth_offset != PREFIXblock.at_fifth_offset ) )\n"
8722 const GLchar* prefix = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::UNIFORM);
8724 Utils::replaceAllTokens("PREFIX", prefix, verification);
8726 return verification;
8731 * @param context Test framework context
8733 UniformBlockLayoutQualifierConflictTest::UniformBlockLayoutQualifierConflictTest(deqp::Context& context)
8735 context, "uniform_block_layout_qualifier_conflict",
8736 "Test verifies that std140 is required when offset and/or align qualifiers are used with uniform block")
8738 /* Nothing to be done here */
8741 /** Source for given test case and stage
8743 * @param test_case_index Index of test case
8744 * @param stage Shader stage
8746 * @return Shader source
8748 std::string UniformBlockLayoutQualifierConflictTest::getShaderSource(GLuint test_case_index,
8749 Utils::Shader::STAGES stage)
8751 static const GLchar* cs = "#version 430 core\n"
8752 "#extension GL_ARB_enhanced_layouts : require\n"
8754 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
8756 "LAYOUTuniform Block {\n"
8757 " layout(offset = 16) vec4 boy;\n"
8758 " layout(align = 64) vec4 man;\n"
8761 "writeonly uniform image2D uni_image;\n"
8765 " vec4 result = uni_block.boy + uni_block.man;\n"
8767 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
8770 static const GLchar* fs = "#version 430 core\n"
8771 "#extension GL_ARB_enhanced_layouts : require\n"
8773 "LAYOUTuniform Block {\n"
8774 " layout(offset = 16) vec4 boy;\n"
8775 " layout(align = 64) vec4 man;\n"
8779 "out vec4 fs_out;\n"
8783 " fs_out = gs_fs + uni_block.boy + uni_block.man;\n"
8786 static const GLchar* gs = "#version 430 core\n"
8787 "#extension GL_ARB_enhanced_layouts : require\n"
8789 "layout(points) in;\n"
8790 "layout(triangle_strip, max_vertices = 4) out;\n"
8792 "LAYOUTuniform Block {\n"
8793 " layout(offset = 16) vec4 boy;\n"
8794 " layout(align = 64) vec4 man;\n"
8797 "in vec4 tes_gs[];\n"
8802 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
8803 " gl_Position = vec4(-1, -1, 0, 1);\n"
8805 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
8806 " gl_Position = vec4(-1, 1, 0, 1);\n"
8808 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
8809 " gl_Position = vec4(1, -1, 0, 1);\n"
8811 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
8812 " gl_Position = vec4(1, 1, 0, 1);\n"
8816 static const GLchar* tcs =
8817 "#version 430 core\n"
8818 "#extension GL_ARB_enhanced_layouts : require\n"
8820 "layout(vertices = 1) out;\n"
8822 "LAYOUTuniform Block {\n"
8823 " layout(offset = 16) vec4 boy;\n"
8824 " layout(align = 64) vec4 man;\n"
8827 "in vec4 vs_tcs[];\n"
8828 "out vec4 tcs_tes[];\n"
8833 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID] + uni_block.boy + uni_block.man;\n"
8835 " gl_TessLevelOuter[0] = 1.0;\n"
8836 " gl_TessLevelOuter[1] = 1.0;\n"
8837 " gl_TessLevelOuter[2] = 1.0;\n"
8838 " gl_TessLevelOuter[3] = 1.0;\n"
8839 " gl_TessLevelInner[0] = 1.0;\n"
8840 " gl_TessLevelInner[1] = 1.0;\n"
8843 static const GLchar* tes = "#version 430 core\n"
8844 "#extension GL_ARB_enhanced_layouts : require\n"
8846 "layout(isolines, point_mode) in;\n"
8848 "LAYOUTuniform Block {\n"
8849 " layout(offset = 16) vec4 boy;\n"
8850 " layout(align = 64) vec4 man;\n"
8853 "in vec4 tcs_tes[];\n"
8854 "out vec4 tes_gs;\n"
8858 " tes_gs = tcs_tes[0] + uni_block.boy + uni_block.man;\n"
8861 static const GLchar* vs = "#version 430 core\n"
8862 "#extension GL_ARB_enhanced_layouts : require\n"
8864 "LAYOUTuniform Block {\n"
8865 " layout(offset = 16) vec4 boy;\n"
8866 " layout(align = 64) vec4 man;\n"
8870 "out vec4 vs_tcs;\n"
8874 " vs_tcs = in_vs + uni_block.boy + uni_block.man;\n"
8878 std::string layout = "";
8879 size_t position = 0;
8880 testCase& test_case = m_test_cases[test_case_index];
8881 const GLchar* qualifier = getQualifierName(test_case.m_qualifier);
8884 if (0 != qualifier[0])
8886 size_t layout_position = 0;
8888 layout = "layout (QUALIFIER) ";
8890 Utils::replaceToken("QUALIFIER", layout_position, qualifier, layout);
8895 case Utils::Shader::COMPUTE:
8898 case Utils::Shader::FRAGMENT:
8901 case Utils::Shader::GEOMETRY:
8904 case Utils::Shader::TESS_CTRL:
8907 case Utils::Shader::TESS_EVAL:
8910 case Utils::Shader::VERTEX:
8914 TCU_FAIL("Invalid enum");
8917 if (test_case.m_stage == stage)
8919 Utils::replaceToken("LAYOUT", position, layout.c_str(), source);
8923 Utils::replaceToken("LAYOUT", position, "layout (std140) ", source);
8929 /** Get description of test case
8931 * @param test_case_index Index of test case
8933 * @return Qualifier name
8935 std::string UniformBlockLayoutQualifierConflictTest::getTestCaseName(GLuint test_case_index)
8937 std::string result = getQualifierName(m_test_cases[test_case_index].m_qualifier);
8942 /** Get number of test cases
8944 * @return Number of test cases
8946 GLuint UniformBlockLayoutQualifierConflictTest::getTestCaseNumber()
8948 return static_cast<GLuint>(m_test_cases.size());
8951 /** Selects if "compute" stage is relevant for test
8953 * @param test_case_index Index of test case
8955 * @return true when tested stage is compute
8957 bool UniformBlockLayoutQualifierConflictTest::isComputeRelevant(GLuint test_case_index)
8959 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
8962 /** Selects if compilation failure is expected result
8964 * @param test_case_index Index of test case
8966 * @return false for STD140 cases, true otherwise
8968 bool UniformBlockLayoutQualifierConflictTest::isFailureExpected(GLuint test_case_index)
8970 return (STD140 != m_test_cases[test_case_index].m_qualifier);
8973 /** Prepare all test cases
8976 void UniformBlockLayoutQualifierConflictTest::testInit()
8978 for (GLuint qualifier = 0; qualifier < QUALIFIERS_MAX; ++qualifier)
8980 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
8982 testCase test_case = { (QUALIFIERS)qualifier, (Utils::Shader::STAGES)stage };
8984 m_test_cases.push_back(test_case);
8989 /** Get name of glsl constant
8991 * @param Constant id
8993 * @return Name of constant used in GLSL
8995 const GLchar* UniformBlockLayoutQualifierConflictTest::getQualifierName(QUALIFIERS qualifier)
8997 const GLchar* name = "";
9014 TCU_FAIL("Invalid enum");
9022 * @param context Test framework context
9024 UniformBlockMemberInvalidOffsetAlignmentTest::UniformBlockMemberInvalidOffsetAlignmentTest(deqp::Context& context)
9025 : NegativeTestBase(context, "uniform_block_member_invalid_offset_alignment",
9026 "Test verifies that invalid alignment of offset qualifiers cause compilation failure")
9028 /* Nothing to be done here */
9033 * @param context Test framework context
9034 * @param name Test name
9035 * @param description Test description
9037 UniformBlockMemberInvalidOffsetAlignmentTest::UniformBlockMemberInvalidOffsetAlignmentTest(
9038 deqp::Context& context, const glw::GLchar* name, const glw::GLchar* description)
9039 : NegativeTestBase(context, name, description)
9041 /* Nothing to be done here */
9044 /** Source for given test case and stage
9046 * @param test_case_index Index of test case
9047 * @param stage Shader stage
9049 * @return Shader source
9051 std::string UniformBlockMemberInvalidOffsetAlignmentTest::getShaderSource(GLuint test_case_index,
9052 Utils::Shader::STAGES stage)
9054 static const GLchar* cs = "#version 430 core\n"
9055 "#extension GL_ARB_enhanced_layouts : require\n"
9057 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
9059 "layout (std140) uniform Block {\n"
9060 " layout (offset = OFFSET) TYPE member;\n"
9063 "writeonly uniform image2D uni_image;\n"
9067 " vec4 result = vec4(1, 0, 0.5, 1);\n"
9069 " if (TYPE(1) == block.member)\n"
9071 " result = vec4(1, 1, 1, 1);\n"
9074 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
9077 static const GLchar* fs = "#version 430 core\n"
9078 "#extension GL_ARB_enhanced_layouts : require\n"
9081 "out vec4 fs_out;\n"
9085 " fs_out = gs_fs;\n"
9088 static const GLchar* fs_tested = "#version 430 core\n"
9089 "#extension GL_ARB_enhanced_layouts : require\n"
9091 "layout (std140) uniform Block {\n"
9092 " layout (offset = OFFSET) TYPE member;\n"
9096 "out vec4 fs_out;\n"
9100 " if (TYPE(1) == block.member)\n"
9102 " fs_out = vec4(1, 1, 1, 1);\n"
9105 " fs_out += gs_fs;\n"
9108 static const GLchar* gs = "#version 430 core\n"
9109 "#extension GL_ARB_enhanced_layouts : require\n"
9111 "layout(points) in;\n"
9112 "layout(triangle_strip, max_vertices = 4) out;\n"
9114 "in vec4 tes_gs[];\n"
9119 " gs_fs = tes_gs[0];\n"
9120 " gl_Position = vec4(-1, -1, 0, 1);\n"
9122 " gs_fs = tes_gs[0];\n"
9123 " gl_Position = vec4(-1, 1, 0, 1);\n"
9125 " gs_fs = tes_gs[0];\n"
9126 " gl_Position = vec4(1, -1, 0, 1);\n"
9128 " gs_fs = tes_gs[0];\n"
9129 " gl_Position = vec4(1, 1, 0, 1);\n"
9133 static const GLchar* gs_tested = "#version 430 core\n"
9134 "#extension GL_ARB_enhanced_layouts : require\n"
9136 "layout(points) in;\n"
9137 "layout(triangle_strip, max_vertices = 4) out;\n"
9139 "layout (std140) uniform Block {\n"
9140 " layout (offset = OFFSET) TYPE member;\n"
9143 "in vec4 tes_gs[];\n"
9148 " if (TYPE(1) == block.member)\n"
9150 " gs_fs = vec4(1, 1, 1, 1);\n"
9153 " gs_fs += tes_gs[0];\n"
9154 " gl_Position = vec4(-1, -1, 0, 1);\n"
9156 " gs_fs += tes_gs[0];\n"
9157 " gl_Position = vec4(-1, 1, 0, 1);\n"
9159 " gs_fs += tes_gs[0];\n"
9160 " gl_Position = vec4(1, -1, 0, 1);\n"
9162 " gs_fs += tes_gs[0];\n"
9163 " gl_Position = vec4(1, 1, 0, 1);\n"
9167 static const GLchar* tcs = "#version 430 core\n"
9168 "#extension GL_ARB_enhanced_layouts : require\n"
9170 "layout(vertices = 1) out;\n"
9172 "in vec4 vs_tcs[];\n"
9173 "out vec4 tcs_tes[];\n"
9178 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
9180 " gl_TessLevelOuter[0] = 1.0;\n"
9181 " gl_TessLevelOuter[1] = 1.0;\n"
9182 " gl_TessLevelOuter[2] = 1.0;\n"
9183 " gl_TessLevelOuter[3] = 1.0;\n"
9184 " gl_TessLevelInner[0] = 1.0;\n"
9185 " gl_TessLevelInner[1] = 1.0;\n"
9188 static const GLchar* tcs_tested = "#version 430 core\n"
9189 "#extension GL_ARB_enhanced_layouts : require\n"
9191 "layout(vertices = 1) out;\n"
9193 "layout (std140) uniform Block {\n"
9194 " layout (offset = OFFSET) TYPE member;\n"
9197 "in vec4 vs_tcs[];\n"
9198 "out vec4 tcs_tes[];\n"
9202 " if (TYPE(1) == block.member)\n"
9204 " tcs_tes[gl_InvocationID] = vec4(1, 1, 1, 1);\n"
9208 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
9210 " gl_TessLevelOuter[0] = 1.0;\n"
9211 " gl_TessLevelOuter[1] = 1.0;\n"
9212 " gl_TessLevelOuter[2] = 1.0;\n"
9213 " gl_TessLevelOuter[3] = 1.0;\n"
9214 " gl_TessLevelInner[0] = 1.0;\n"
9215 " gl_TessLevelInner[1] = 1.0;\n"
9218 static const GLchar* tes = "#version 430 core\n"
9219 "#extension GL_ARB_enhanced_layouts : require\n"
9221 "layout(isolines, point_mode) in;\n"
9223 "in vec4 tcs_tes[];\n"
9224 "out vec4 tes_gs;\n"
9228 " tes_gs = tcs_tes[0];\n"
9231 static const GLchar* tes_tested = "#version 430 core\n"
9232 "#extension GL_ARB_enhanced_layouts : require\n"
9234 "layout(isolines, point_mode) in;\n"
9236 "layout (std140) uniform Block {\n"
9237 " layout (offset = OFFSET) TYPE member;\n"
9240 "in vec4 tcs_tes[];\n"
9241 "out vec4 tes_gs;\n"
9245 " if (TYPE(1) == block.member)\n"
9247 " tes_gs = vec4(1, 1, 1, 1);\n"
9250 " tes_gs += tcs_tes[0];\n"
9253 static const GLchar* vs = "#version 430 core\n"
9254 "#extension GL_ARB_enhanced_layouts : require\n"
9257 "out vec4 vs_tcs;\n"
9261 " vs_tcs = in_vs;\n"
9264 static const GLchar* vs_tested = "#version 430 core\n"
9265 "#extension GL_ARB_enhanced_layouts : require\n"
9267 "layout (std140) uniform Block {\n"
9268 " layout (offset = OFFSET) TYPE member;\n"
9272 "out vec4 vs_tcs;\n"
9276 " if (TYPE(1) == block.member)\n"
9278 " vs_tcs = vec4(1, 1, 1, 1);\n"
9281 " vs_tcs += in_vs;\n"
9286 testCase& test_case = m_test_cases[test_case_index];
9288 if (test_case.m_stage == stage)
9291 const GLuint offset = test_case.m_offset;
9292 size_t position = 0;
9293 const Utils::Type& type = test_case.m_type;
9294 const GLchar* type_name = type.GetGLSLTypeName();
9296 sprintf(buffer, "%d", offset);
9300 case Utils::Shader::COMPUTE:
9303 case Utils::Shader::FRAGMENT:
9306 case Utils::Shader::GEOMETRY:
9309 case Utils::Shader::TESS_CTRL:
9310 source = tcs_tested;
9312 case Utils::Shader::TESS_EVAL:
9313 source = tes_tested;
9315 case Utils::Shader::VERTEX:
9319 TCU_FAIL("Invalid enum");
9322 Utils::replaceToken("OFFSET", position, buffer, source);
9323 Utils::replaceToken("TYPE", position, type_name, source);
9324 Utils::replaceToken("TYPE", position, type_name, source);
9330 case Utils::Shader::FRAGMENT:
9333 case Utils::Shader::GEOMETRY:
9336 case Utils::Shader::TESS_CTRL:
9339 case Utils::Shader::TESS_EVAL:
9342 case Utils::Shader::VERTEX:
9346 TCU_FAIL("Invalid enum");
9353 /** Get description of test case
9355 * @param test_case_index Index of test case
9357 * @return Type name and offset
9359 std::string UniformBlockMemberInvalidOffsetAlignmentTest::getTestCaseName(GLuint test_case_index)
9361 std::stringstream stream;
9362 testCase& test_case = m_test_cases[test_case_index];
9364 stream << "Type: " << test_case.m_type.GetGLSLTypeName() << ", offset: " << test_case.m_offset;
9366 return stream.str();
9369 /** Get number of test cases
9371 * @return Number of test cases
9373 GLuint UniformBlockMemberInvalidOffsetAlignmentTest::getTestCaseNumber()
9375 return static_cast<GLuint>(m_test_cases.size());
9378 /** Get the maximum size for an uniform block
9380 * @return The maximum size in basic machine units of a uniform block.
9382 GLint UniformBlockMemberInvalidOffsetAlignmentTest::getMaxBlockSize()
9384 const Functions& gl = m_context.getRenderContext().getFunctions();
9387 gl.getIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &max_size);
9388 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
9393 /** Selects if "compute" stage is relevant for test
9395 * @param test_case_index Index of test case
9397 * @return true when tested stage is compute
9399 bool UniformBlockMemberInvalidOffsetAlignmentTest::isComputeRelevant(GLuint test_case_index)
9401 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
9404 /** Selects if compilation failure is expected result
9406 * @param test_case_index Index of test case
9408 * @return should_fail field from testCase
9410 bool UniformBlockMemberInvalidOffsetAlignmentTest::isFailureExpected(GLuint test_case_index)
9412 return m_test_cases[test_case_index].m_should_fail;
9415 /** Checks if stage is supported
9417 * @param stage ignored
9421 bool UniformBlockMemberInvalidOffsetAlignmentTest::isStageSupported(Utils::Shader::STAGES /* stage */)
9426 /** Prepare all test cases
9429 void UniformBlockMemberInvalidOffsetAlignmentTest::testInit()
9431 const GLuint n_types = getTypesNumber();
9432 bool stage_support[Utils::Shader::STAGE_MAX];
9434 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
9436 stage_support[stage] = isStageSupported((Utils::Shader::STAGES)stage);
9439 for (GLuint i = 0; i < n_types; ++i)
9441 const Utils::Type& type = getType(i);
9442 const GLuint alignment = type.GetBaseAlignment(false);
9443 const GLuint type_size = type.GetSize(true);
9444 const GLuint sec_to_end = getMaxBlockSize() - 2 * type_size;
9446 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
9448 if (false == stage_support[stage])
9453 for (GLuint offset = 0; offset <= type_size; ++offset)
9455 const GLuint modulo = offset % alignment;
9456 const bool is_aligned = (0 == modulo) ? true : false;
9457 const bool should_fail = !is_aligned;
9459 testCase test_case = { offset, should_fail, (Utils::Shader::STAGES)stage, type };
9461 m_test_cases.push_back(test_case);
9464 for (GLuint offset = sec_to_end; offset <= sec_to_end + type_size; ++offset)
9466 const GLuint modulo = offset % alignment;
9467 const bool is_aligned = (0 == modulo) ? true : false;
9468 const bool should_fail = !is_aligned;
9470 testCase test_case = { offset, should_fail, (Utils::Shader::STAGES)stage, type };
9472 m_test_cases.push_back(test_case);
9480 * @param context Test framework context
9482 UniformBlockMemberOverlappingOffsetsTest::UniformBlockMemberOverlappingOffsetsTest(deqp::Context& context)
9483 : NegativeTestBase(context, "uniform_block_member_overlapping_offsets",
9484 "Test verifies that overlapping offsets qualifiers cause compilation failure")
9486 /* Nothing to be done here */
9491 * @param context Test framework context
9492 * @param name Test name
9493 * @param description Test description
9495 UniformBlockMemberOverlappingOffsetsTest::UniformBlockMemberOverlappingOffsetsTest(deqp::Context& context,
9496 const glw::GLchar* name,
9497 const glw::GLchar* description)
9498 : NegativeTestBase(context, name, description)
9500 /* Nothing to be done here */
9503 /** Source for given test case and stage
9505 * @param test_case_index Index of test case
9506 * @param stage Shader stage
9508 * @return Shader source
9510 std::string UniformBlockMemberOverlappingOffsetsTest::getShaderSource(GLuint test_case_index,
9511 Utils::Shader::STAGES stage)
9513 static const GLchar* cs = "#version 430 core\n"
9514 "#extension GL_ARB_enhanced_layouts : require\n"
9516 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
9518 "layout (std140) uniform Block {\n"
9519 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9520 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9523 "writeonly uniform image2D uni_image;\n"
9527 " vec4 result = vec4(1, 0, 0.5, 1);\n"
9529 " if ((BOY_TYPE(1) == block.boy) ||\n"
9530 " (MAN_TYPE(0) == block.man) )\n"
9532 " result = vec4(1, 1, 1, 1);\n"
9535 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
9538 static const GLchar* fs = "#version 430 core\n"
9539 "#extension GL_ARB_enhanced_layouts : require\n"
9542 "out vec4 fs_out;\n"
9546 " fs_out = gs_fs;\n"
9549 static const GLchar* fs_tested = "#version 430 core\n"
9550 "#extension GL_ARB_enhanced_layouts : require\n"
9552 "layout (std140) uniform Block {\n"
9553 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9554 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9558 "out vec4 fs_out;\n"
9562 " if ((BOY_TYPE(1) == block.boy) ||\n"
9563 " (MAN_TYPE(0) == block.man) )\n"
9565 " fs_out = vec4(1, 1, 1, 1);\n"
9568 " fs_out += gs_fs;\n"
9571 static const GLchar* gs = "#version 430 core\n"
9572 "#extension GL_ARB_enhanced_layouts : require\n"
9574 "layout(points) in;\n"
9575 "layout(triangle_strip, max_vertices = 4) out;\n"
9577 "in vec4 tes_gs[];\n"
9582 " gs_fs = tes_gs[0];\n"
9583 " gl_Position = vec4(-1, -1, 0, 1);\n"
9585 " gs_fs = tes_gs[0];\n"
9586 " gl_Position = vec4(-1, 1, 0, 1);\n"
9588 " gs_fs = tes_gs[0];\n"
9589 " gl_Position = vec4(1, -1, 0, 1);\n"
9591 " gs_fs = tes_gs[0];\n"
9592 " gl_Position = vec4(1, 1, 0, 1);\n"
9596 static const GLchar* gs_tested = "#version 430 core\n"
9597 "#extension GL_ARB_enhanced_layouts : require\n"
9599 "layout(points) in;\n"
9600 "layout(triangle_strip, max_vertices = 4) out;\n"
9602 "layout (std140) uniform Block {\n"
9603 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9604 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9607 "in vec4 tes_gs[];\n"
9612 " if ((BOY_TYPE(1) == block.boy) ||\n"
9613 " (MAN_TYPE(0) == block.man) )\n"
9615 " gs_fs = vec4(1, 1, 1, 1);\n"
9618 " gs_fs += tes_gs[0];\n"
9619 " gl_Position = vec4(-1, -1, 0, 1);\n"
9621 " gs_fs += tes_gs[0];\n"
9622 " gl_Position = vec4(-1, 1, 0, 1);\n"
9624 " gs_fs += tes_gs[0];\n"
9625 " gl_Position = vec4(1, -1, 0, 1);\n"
9627 " gs_fs += tes_gs[0];\n"
9628 " gl_Position = vec4(1, 1, 0, 1);\n"
9632 static const GLchar* tcs = "#version 430 core\n"
9633 "#extension GL_ARB_enhanced_layouts : require\n"
9635 "layout(vertices = 1) out;\n"
9637 "in vec4 vs_tcs[];\n"
9638 "out vec4 tcs_tes[];\n"
9643 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
9645 " gl_TessLevelOuter[0] = 1.0;\n"
9646 " gl_TessLevelOuter[1] = 1.0;\n"
9647 " gl_TessLevelOuter[2] = 1.0;\n"
9648 " gl_TessLevelOuter[3] = 1.0;\n"
9649 " gl_TessLevelInner[0] = 1.0;\n"
9650 " gl_TessLevelInner[1] = 1.0;\n"
9653 static const GLchar* tcs_tested = "#version 430 core\n"
9654 "#extension GL_ARB_enhanced_layouts : require\n"
9656 "layout(vertices = 1) out;\n"
9658 "layout (std140) uniform Block {\n"
9659 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9660 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9663 "in vec4 vs_tcs[];\n"
9664 "out vec4 tcs_tes[];\n"
9668 " if ((BOY_TYPE(1) == block.boy) ||\n"
9669 " (MAN_TYPE(0) == block.man) )\n"
9671 " tcs_tes[gl_InvocationID] = vec4(1, 1, 1, 1);\n"
9675 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
9677 " gl_TessLevelOuter[0] = 1.0;\n"
9678 " gl_TessLevelOuter[1] = 1.0;\n"
9679 " gl_TessLevelOuter[2] = 1.0;\n"
9680 " gl_TessLevelOuter[3] = 1.0;\n"
9681 " gl_TessLevelInner[0] = 1.0;\n"
9682 " gl_TessLevelInner[1] = 1.0;\n"
9685 static const GLchar* tes = "#version 430 core\n"
9686 "#extension GL_ARB_enhanced_layouts : require\n"
9688 "layout(isolines, point_mode) in;\n"
9690 "in vec4 tcs_tes[];\n"
9691 "out vec4 tes_gs;\n"
9695 " tes_gs = tcs_tes[0];\n"
9698 static const GLchar* tes_tested = "#version 430 core\n"
9699 "#extension GL_ARB_enhanced_layouts : require\n"
9701 "layout(isolines, point_mode) in;\n"
9703 "layout (std140) uniform Block {\n"
9704 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9705 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9708 "in vec4 tcs_tes[];\n"
9709 "out vec4 tes_gs;\n"
9713 " if ((BOY_TYPE(1) == block.boy) ||\n"
9714 " (MAN_TYPE(0) == block.man) )\n"
9716 " tes_gs = vec4(1, 1, 1, 1);\n"
9719 " tes_gs += tcs_tes[0];\n"
9722 static const GLchar* vs = "#version 430 core\n"
9723 "#extension GL_ARB_enhanced_layouts : require\n"
9726 "out vec4 vs_tcs;\n"
9730 " vs_tcs = in_vs;\n"
9733 static const GLchar* vs_tested = "#version 430 core\n"
9734 "#extension GL_ARB_enhanced_layouts : require\n"
9736 "layout (std140) uniform Block {\n"
9737 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9738 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9742 "out vec4 vs_tcs;\n"
9746 " if ((BOY_TYPE(1) == block.boy) ||\n"
9747 " (MAN_TYPE(0) == block.man) )\n"
9749 " vs_tcs = vec4(1, 1, 1, 1);\n"
9752 " vs_tcs += in_vs;\n"
9757 testCase& test_case = m_test_cases[test_case_index];
9759 if (test_case.m_stage == stage)
9762 const GLuint boy_offset = test_case.m_boy_offset;
9763 const Utils::Type& boy_type = test_case.m_boy_type;
9764 const GLchar* boy_type_name = boy_type.GetGLSLTypeName();
9765 const GLuint man_offset = test_case.m_man_offset;
9766 const Utils::Type& man_type = test_case.m_man_type;
9767 const GLchar* man_type_name = man_type.GetGLSLTypeName();
9768 size_t position = 0;
9772 case Utils::Shader::COMPUTE:
9775 case Utils::Shader::FRAGMENT:
9778 case Utils::Shader::GEOMETRY:
9781 case Utils::Shader::TESS_CTRL:
9782 source = tcs_tested;
9784 case Utils::Shader::TESS_EVAL:
9785 source = tes_tested;
9787 case Utils::Shader::VERTEX:
9791 TCU_FAIL("Invalid enum");
9794 sprintf(buffer, "%d", boy_offset);
9795 Utils::replaceToken("BOY_OFFSET", position, buffer, source);
9796 Utils::replaceToken("BOY_TYPE", position, boy_type_name, source);
9797 sprintf(buffer, "%d", man_offset);
9798 Utils::replaceToken("MAN_OFFSET", position, buffer, source);
9799 Utils::replaceToken("MAN_TYPE", position, man_type_name, source);
9800 Utils::replaceToken("BOY_TYPE", position, boy_type_name, source);
9801 Utils::replaceToken("MAN_TYPE", position, man_type_name, source);
9807 case Utils::Shader::FRAGMENT:
9810 case Utils::Shader::GEOMETRY:
9813 case Utils::Shader::TESS_CTRL:
9816 case Utils::Shader::TESS_EVAL:
9819 case Utils::Shader::VERTEX:
9823 TCU_FAIL("Invalid enum");
9830 /** Get description of test case
9832 * @param test_case_index Index of test case
9834 * @return Type name and offset
9836 std::string UniformBlockMemberOverlappingOffsetsTest::getTestCaseName(GLuint test_case_index)
9838 std::stringstream stream;
9839 testCase& test_case = m_test_cases[test_case_index];
9841 stream << "Type: " << test_case.m_boy_type.GetGLSLTypeName() << ", offset: " << test_case.m_boy_offset
9842 << ". Type: " << test_case.m_man_type.GetGLSLTypeName() << ", offset: " << test_case.m_man_offset;
9844 return stream.str();
9847 /** Get number of test cases
9849 * @return Number of test cases
9851 GLuint UniformBlockMemberOverlappingOffsetsTest::getTestCaseNumber()
9853 return static_cast<GLuint>(m_test_cases.size());
9856 /** Selects if "compute" stage is relevant for test
9858 * @param test_case_index Index of test case
9860 * @return true when tested stage is compute
9862 bool UniformBlockMemberOverlappingOffsetsTest::isComputeRelevant(GLuint test_case_index)
9864 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
9867 /** Checks if stage is supported
9869 * @param stage ignored
9873 bool UniformBlockMemberOverlappingOffsetsTest::isStageSupported(Utils::Shader::STAGES /* stage */)
9878 /** Prepare all test cases
9881 void UniformBlockMemberOverlappingOffsetsTest::testInit()
9883 const GLuint n_types = getTypesNumber();
9884 bool stage_support[Utils::Shader::STAGE_MAX];
9886 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
9888 stage_support[stage] = isStageSupported((Utils::Shader::STAGES)stage);
9891 for (GLuint i = 0; i < n_types; ++i)
9893 const Utils::Type& boy_type = getType(i);
9894 const GLuint boy_size = boy_type.GetActualAlignment(1 /* align */, false /* is_array*/);
9896 for (GLuint j = 0; j < n_types; ++j)
9898 const Utils::Type& man_type = getType(j);
9899 const GLuint man_align = man_type.GetBaseAlignment(false);
9900 const GLuint man_size = man_type.GetActualAlignment(1 /* align */, false /* is_array*/);
9902 const GLuint boy_offset = lcm(boy_size, man_size);
9903 const GLuint man_after_start = boy_offset + 1;
9904 const GLuint man_after_off = man_type.GetActualOffset(man_after_start, man_size);
9905 const GLuint man_before_start = boy_offset - man_align;
9906 const GLuint man_before_off = man_type.GetActualOffset(man_before_start, man_size);
9908 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
9910 if (false == stage_support[stage])
9915 if ((boy_offset > man_before_off) && (boy_offset < man_before_off + man_size))
9917 testCase test_case = { boy_offset, boy_type, man_before_off, man_type,
9918 (Utils::Shader::STAGES)stage };
9920 m_test_cases.push_back(test_case);
9923 if ((boy_offset < man_after_off) && (boy_offset + boy_size > man_after_off))
9925 testCase test_case = { boy_offset, boy_type, man_after_off, man_type,
9926 (Utils::Shader::STAGES)stage };
9928 m_test_cases.push_back(test_case);
9931 /* Boy offset, should be fine for both types */
9932 testCase test_case = { boy_offset, boy_type, boy_offset, man_type, (Utils::Shader::STAGES)stage };
9934 m_test_cases.push_back(test_case);
9940 /** Find greatest common divisor for a and b
9942 * @param a A argument
9943 * @param b B argument
9945 * @return Found gcd value
9947 GLuint UniformBlockMemberOverlappingOffsetsTest::gcd(GLuint a, GLuint b)
9949 if ((0 != a) && (0 == b))
9955 GLuint greater = std::max(a, b);
9956 GLuint lesser = std::min(a, b);
9958 return gcd(lesser, greater % lesser);
9962 /** Find lowest common multiple for a and b
9964 * @param a A argument
9965 * @param b B argument
9967 * @return Found gcd value
9969 GLuint UniformBlockMemberOverlappingOffsetsTest::lcm(GLuint a, GLuint b)
9971 return (a * b) / gcd(a, b);
9976 * @param context Test framework context
9978 UniformBlockMemberAlignNonPowerOf2Test::UniformBlockMemberAlignNonPowerOf2Test(deqp::Context& context)
9979 : NegativeTestBase(context, "uniform_block_member_align_non_power_of_2",
9980 "Test verifies that align qualifier requires value that is a power of 2")
9982 /* Nothing to be done here */
9987 * @param context Test framework context
9988 * @param name Test name
9989 * @param description Test description
9991 UniformBlockMemberAlignNonPowerOf2Test::UniformBlockMemberAlignNonPowerOf2Test(deqp::Context& context,
9992 const glw::GLchar* name,
9993 const glw::GLchar* description)
9994 : NegativeTestBase(context, name, description)
9996 /* Nothing to be done here */
9999 /** Source for given test case and stage
10001 * @param test_case_index Index of test case
10002 * @param stage Shader stage
10004 * @return Shader source
10006 std::string UniformBlockMemberAlignNonPowerOf2Test::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
10008 static const GLchar* cs = "#version 430 core\n"
10009 "#extension GL_ARB_enhanced_layouts : require\n"
10011 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
10013 "layout (std140) uniform Block {\n"
10015 " layout (align = ALIGN) TYPE man;\n"
10018 "writeonly uniform image2D uni_image;\n"
10022 " vec4 result = vec4(1, 0, 0.5, 1);\n"
10024 " if (TYPE(0) == block.man)\n"
10026 " result = vec4(1, 1, 1, 1) - block.boy;\n"
10029 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
10032 static const GLchar* fs = "#version 430 core\n"
10033 "#extension GL_ARB_enhanced_layouts : require\n"
10036 "out vec4 fs_out;\n"
10040 " fs_out = gs_fs;\n"
10043 static const GLchar* fs_tested = "#version 430 core\n"
10044 "#extension GL_ARB_enhanced_layouts : require\n"
10046 "layout (std140) uniform Block {\n"
10048 " layout (align = ALIGN) TYPE man;\n"
10052 "out vec4 fs_out;\n"
10056 " if (TYPE(0) == block.man)\n"
10058 " fs_out = block.boy;\n"
10061 " fs_out += gs_fs;\n"
10064 static const GLchar* gs = "#version 430 core\n"
10065 "#extension GL_ARB_enhanced_layouts : require\n"
10067 "layout(points) in;\n"
10068 "layout(triangle_strip, max_vertices = 4) out;\n"
10070 "in vec4 tes_gs[];\n"
10071 "out vec4 gs_fs;\n"
10075 " gs_fs = tes_gs[0];\n"
10076 " gl_Position = vec4(-1, -1, 0, 1);\n"
10078 " gs_fs = tes_gs[0];\n"
10079 " gl_Position = vec4(-1, 1, 0, 1);\n"
10081 " gs_fs = tes_gs[0];\n"
10082 " gl_Position = vec4(1, -1, 0, 1);\n"
10084 " gs_fs = tes_gs[0];\n"
10085 " gl_Position = vec4(1, 1, 0, 1);\n"
10089 static const GLchar* gs_tested = "#version 430 core\n"
10090 "#extension GL_ARB_enhanced_layouts : require\n"
10092 "layout(points) in;\n"
10093 "layout(triangle_strip, max_vertices = 4) out;\n"
10095 "layout (std140) uniform Block {\n"
10097 " layout (align = ALIGN) TYPE man;\n"
10100 "in vec4 tes_gs[];\n"
10101 "out vec4 gs_fs;\n"
10105 " if (TYPE(0) == block.man)\n"
10107 " gs_fs = block.boy;\n"
10110 " gs_fs += tes_gs[0];\n"
10111 " gl_Position = vec4(-1, -1, 0, 1);\n"
10113 " gs_fs += tes_gs[0];\n"
10114 " gl_Position = vec4(-1, 1, 0, 1);\n"
10116 " gs_fs += tes_gs[0];\n"
10117 " gl_Position = vec4(1, -1, 0, 1);\n"
10119 " gs_fs += tes_gs[0];\n"
10120 " gl_Position = vec4(1, 1, 0, 1);\n"
10124 static const GLchar* tcs = "#version 430 core\n"
10125 "#extension GL_ARB_enhanced_layouts : require\n"
10127 "layout(vertices = 1) out;\n"
10129 "in vec4 vs_tcs[];\n"
10130 "out vec4 tcs_tes[];\n"
10135 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
10137 " gl_TessLevelOuter[0] = 1.0;\n"
10138 " gl_TessLevelOuter[1] = 1.0;\n"
10139 " gl_TessLevelOuter[2] = 1.0;\n"
10140 " gl_TessLevelOuter[3] = 1.0;\n"
10141 " gl_TessLevelInner[0] = 1.0;\n"
10142 " gl_TessLevelInner[1] = 1.0;\n"
10145 static const GLchar* tcs_tested = "#version 430 core\n"
10146 "#extension GL_ARB_enhanced_layouts : require\n"
10148 "layout(vertices = 1) out;\n"
10150 "layout (std140) uniform Block {\n"
10152 " layout (align = ALIGN) TYPE man;\n"
10155 "in vec4 vs_tcs[];\n"
10156 "out vec4 tcs_tes[];\n"
10160 " if (TYPE(0) == block.man)\n"
10162 " tcs_tes[gl_InvocationID] = block.boy;\n"
10166 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
10168 " gl_TessLevelOuter[0] = 1.0;\n"
10169 " gl_TessLevelOuter[1] = 1.0;\n"
10170 " gl_TessLevelOuter[2] = 1.0;\n"
10171 " gl_TessLevelOuter[3] = 1.0;\n"
10172 " gl_TessLevelInner[0] = 1.0;\n"
10173 " gl_TessLevelInner[1] = 1.0;\n"
10176 static const GLchar* tes = "#version 430 core\n"
10177 "#extension GL_ARB_enhanced_layouts : require\n"
10179 "layout(isolines, point_mode) in;\n"
10181 "in vec4 tcs_tes[];\n"
10182 "out vec4 tes_gs;\n"
10186 " tes_gs = tcs_tes[0];\n"
10189 static const GLchar* tes_tested = "#version 430 core\n"
10190 "#extension GL_ARB_enhanced_layouts : require\n"
10192 "layout(isolines, point_mode) in;\n"
10194 "layout (std140) uniform Block {\n"
10196 " layout (align = ALIGN) TYPE man;\n"
10199 "in vec4 tcs_tes[];\n"
10200 "out vec4 tes_gs;\n"
10204 " if (TYPE(0) == block.man)\n"
10206 " tes_gs = block.boy;\n"
10209 " tes_gs += tcs_tes[0];\n"
10212 static const GLchar* vs = "#version 430 core\n"
10213 "#extension GL_ARB_enhanced_layouts : require\n"
10216 "out vec4 vs_tcs;\n"
10220 " vs_tcs = in_vs;\n"
10223 static const GLchar* vs_tested = "#version 430 core\n"
10224 "#extension GL_ARB_enhanced_layouts : require\n"
10226 "layout (std140) uniform Block {\n"
10228 " layout (align = ALIGN) TYPE man;\n"
10232 "out vec4 vs_tcs;\n"
10236 " if (TYPE(0) == block.man)\n"
10238 " vs_tcs = block.boy;\n"
10241 " vs_tcs += in_vs;\n"
10245 std::string source;
10246 testCase& test_case = m_test_cases[test_case_index];
10248 if (test_case.m_stage == stage)
10251 const GLuint alignment = test_case.m_alignment;
10252 const Utils::Type& type = test_case.m_type;
10253 const GLchar* type_name = type.GetGLSLTypeName();
10254 size_t position = 0;
10258 case Utils::Shader::COMPUTE:
10261 case Utils::Shader::FRAGMENT:
10262 source = fs_tested;
10264 case Utils::Shader::GEOMETRY:
10265 source = gs_tested;
10267 case Utils::Shader::TESS_CTRL:
10268 source = tcs_tested;
10270 case Utils::Shader::TESS_EVAL:
10271 source = tes_tested;
10273 case Utils::Shader::VERTEX:
10274 source = vs_tested;
10277 TCU_FAIL("Invalid enum");
10280 sprintf(buffer, "%d", alignment);
10281 Utils::replaceToken("ALIGN", position, buffer, source);
10282 Utils::replaceToken("TYPE", position, type_name, source);
10283 Utils::replaceToken("TYPE", position, type_name, source);
10289 case Utils::Shader::FRAGMENT:
10292 case Utils::Shader::GEOMETRY:
10295 case Utils::Shader::TESS_CTRL:
10298 case Utils::Shader::TESS_EVAL:
10301 case Utils::Shader::VERTEX:
10305 TCU_FAIL("Invalid enum");
10312 /** Get description of test case
10314 * @param test_case_index Index of test case
10316 * @return Type name and offset
10318 std::string UniformBlockMemberAlignNonPowerOf2Test::getTestCaseName(GLuint test_case_index)
10320 std::stringstream stream;
10321 testCase& test_case = m_test_cases[test_case_index];
10323 stream << "Type: " << test_case.m_type.GetGLSLTypeName() << ", align: " << test_case.m_alignment;
10325 return stream.str();
10328 /** Get number of test cases
10330 * @return Number of test cases
10332 GLuint UniformBlockMemberAlignNonPowerOf2Test::getTestCaseNumber()
10334 return static_cast<GLuint>(m_test_cases.size());
10337 /** Selects if "compute" stage is relevant for test
10339 * @param test_case_index Index of test case
10341 * @return true when tested stage is compute
10343 bool UniformBlockMemberAlignNonPowerOf2Test::isComputeRelevant(GLuint test_case_index)
10345 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
10348 /** Checks if stage is supported
10354 bool UniformBlockMemberAlignNonPowerOf2Test::isStageSupported(Utils::Shader::STAGES /* stage */)
10359 /** Selects if compilation failure is expected result
10361 * @param test_case_index Index of test case
10363 * @return should_fail field from testCase
10365 bool UniformBlockMemberAlignNonPowerOf2Test::isFailureExpected(GLuint test_case_index)
10367 return m_test_cases[test_case_index].m_should_fail;
10370 /** Prepare all test cases
10373 void UniformBlockMemberAlignNonPowerOf2Test::testInit()
10375 static const GLuint dmat4_size = 128;
10376 const GLuint n_types = getTypesNumber();
10377 bool stage_support[Utils::Shader::STAGE_MAX];
10379 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
10381 stage_support[stage] = isStageSupported((Utils::Shader::STAGES)stage);
10384 for (GLuint j = 0; j < n_types; ++j)
10386 const Utils::Type& type = getType(j);
10388 for (GLuint align = 0; align <= dmat4_size; ++align)
10391 #if WRKARD_UNIFORMBLOCKMEMBERALIGNNONPOWEROF2TEST
10393 const bool should_fail = (0 == align) ? false : !isPowerOf2(align);
10395 #else /* WRKARD_UNIFORMBLOCKMEMBERALIGNNONPOWEROF2TEST */
10397 const bool should_fail = !isPowerOf2(align);
10399 #endif /* WRKARD_UNIFORMBLOCKMEMBERALIGNNONPOWEROF2TEST */
10401 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
10403 if (false == stage_support[stage])
10408 testCase test_case = { align, type, should_fail, (Utils::Shader::STAGES)stage };
10410 m_test_cases.push_back(test_case);
10416 /** Check if value is power of 2
10418 * @param val Tested value
10420 * @return true if val is power of 2, false otherwise
10422 bool UniformBlockMemberAlignNonPowerOf2Test::isPowerOf2(GLuint val)
10429 return (0 == (val & (val - 1)));
10434 * @param context Test framework context
10436 UniformBlockAlignmentTest::UniformBlockAlignmentTest(deqp::Context& context)
10437 : TextureTestBase(context, "uniform_block_alignment", "Test verifies offset and alignment of uniform buffer")
10441 /** Get interface of program
10444 * @param program_interface Interface of program
10445 * @param varying_passthrough Collection of connections between in and out variables
10447 void UniformBlockAlignmentTest::getProgramInterface(GLuint /* test_case_index */,
10448 Utils::ProgramInterface& program_interface,
10449 Utils::VaryingPassthrough& varying_passthrough)
10451 static const Utils::Type vec4 = Utils::Type::vec4;
10453 #if WRKARD_UNIFORMBLOCKALIGNMENT
10455 static const GLuint block_align = 16;
10457 #else /* WRKARD_UNIFORMBLOCKALIGNMENT */
10459 static const GLuint block_align = 64;
10461 #endif /* WRKARD_UNIFORMBLOCKALIGNMENT */
10463 static const GLuint vec4_stride = 16;
10464 static const GLuint data_stride = vec4_stride * 2; /* one vec4 + one scalar aligned to 16 */
10466 /*Fixed a test issue, the fifth_offset should be calculated by block_align, instead of fifth_align, according to spec, the actual
10467 alignment of a member will be the greater of the specified alignment and the base aligment for the member type
10469 const GLuint first_offset = 0; /* vec4 at 0 */
10470 const GLuint second_offset = Utils::Type::GetActualOffset(first_offset + vec4_stride, block_align); /* Data at 32 */
10471 const GLuint third_offset =
10472 Utils::Type::GetActualOffset(second_offset + data_stride, block_align); /* Data[2] at 64 */
10473 const GLuint fourth_offset =
10474 Utils::Type::GetActualOffset(third_offset + data_stride * 2, block_align); /* vec4[3] at 96 */
10475 const GLuint fifth_offset =
10476 Utils::Type::GetActualOffset(fourth_offset + vec4_stride * 3, block_align); /* vec4[2] at 160 */
10477 const GLuint sixth_offset =
10478 Utils::Type::GetActualOffset(fifth_offset + vec4_stride * 2, block_align); /* Data at 192 */
10480 Utils::Interface* structure = program_interface.Structure("Data");
10482 structure->Member("vector", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::vec4,
10483 false /* normalized */, 0 /* n_array_elements */, Utils::Type::vec4.GetSize(), 0 /* offset */);
10485 structure->Member("scalar", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::_float,
10486 false /* normalized */, 0 /* n_array_elements */, Utils::Type::_float.GetSize(),
10487 Utils::Type::vec4.GetSize() /* offset */);
10489 /* Prepare Block */
10490 Utils::Interface* vs_uni_block = program_interface.Block("vs_uni_Block");
10492 vs_uni_block->Member("first", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::vec4,
10493 false /* normalized */, 0 /* n_array_elements */, vec4_stride, first_offset /* offset */);
10495 vs_uni_block->Member("second", "", 0 /* expected_component */, 0 /* expected_location */, structure,
10496 0 /* n_array_elements */, data_stride, second_offset);
10498 vs_uni_block->Member("third", "", 0 /* expected_component */, 0 /* expected_location */, structure,
10499 2 /* n_array_elements */, data_stride, third_offset);
10501 vs_uni_block->Member("fourth", "", 0 /* expected_component */, 0 /* expected_location */, vec4,
10502 false /* normalized */, 3 /* n_array_elements */, vec4_stride, fourth_offset);
10504 vs_uni_block->Member("fifth", "layout(align = 64)", 0 /* expected_component */, 0 /* expected_location */, vec4,
10505 false /* normalized */, 2 /* n_array_elements */, vec4_stride, fifth_offset);
10507 vs_uni_block->Member("sixth", "", 0 /* expected_component */, 0 /* expected_location */, structure,
10508 0 /* n_array_elements */, data_stride, sixth_offset);
10510 const GLuint stride = calculateStride(*vs_uni_block);
10511 m_data.resize(stride);
10512 generateData(*vs_uni_block, 0, m_data);
10514 Utils::ShaderInterface& vs_si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
10516 /* Add uniform BLOCK */
10517 #if WRKARD_UNIFORMBLOCKALIGNMENT
10518 vs_si.Uniform("vs_uni_block", "layout (std140, binding = BINDING)", 0, 0, vs_uni_block, 0,
10519 static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
10520 #else /* WRKARD_UNIFORMBLOCKALIGNMENT */
10521 vs_si.Uniform("vs_uni_block", "layout (std140, binding = BINDING, align = 64)", 0, 0, vs_uni_block, 0,
10522 static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
10523 #endif /* WRKARD_UNIFORMBLOCKALIGNMENT */
10525 program_interface.CloneVertexInterface(varying_passthrough);
10530 * @param context Test framework context
10532 SSBMemberOffsetAndAlignTest::SSBMemberOffsetAndAlignTest(deqp::Context& context)
10533 : TextureTestBase(context, "ssb_member_offset_and_align",
10534 "Test verifies offsets and alignment of storage buffer members")
10538 /** Get interface of program
10540 * @param test_case_index Test case index
10541 * @param program_interface Interface of program
10542 * @param varying_passthrough Collection of connections between in and out variables
10544 void SSBMemberOffsetAndAlignTest::getProgramInterface(GLuint test_case_index,
10545 Utils::ProgramInterface& program_interface,
10546 Utils::VaryingPassthrough& varying_passthrough)
10548 std::string globals = "const int basic_size = BASIC_SIZE;\n"
10549 "const int type_align = TYPE_ALIGN;\n"
10550 "const int type_size = TYPE_SIZE;\n";
10552 Utils::Type type = getType(test_case_index);
10553 GLuint basic_size = Utils::Type::GetTypeSize(type.m_basic_type);
10554 const GLuint base_align = type.GetBaseAlignment(false);
10555 const GLuint array_align = type.GetBaseAlignment(true);
10556 const GLuint base_stride = Utils::Type::CalculateStd140Stride(base_align, type.m_n_columns, 0);
10557 const GLuint type_align = Utils::roundUpToPowerOf2(base_stride);
10559 /* Calculate offsets */
10560 const GLuint first_offset = 0;
10561 const GLuint second_offset = type.GetActualOffset(base_stride, basic_size / 2);
10563 #if WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST
10565 const GLuint third_offset = type.GetActualOffset(second_offset + base_stride, base_align);
10566 const GLuint fourth_offset = type.GetActualOffset(third_offset + base_stride, base_align);
10567 const GLuint fifth_offset = type.GetActualOffset(fourth_offset + base_stride, base_align);
10568 const GLuint sixth_offset = type.GetActualOffset(fifth_offset + base_stride, array_align);
10569 const GLuint seventh_offset = type.GetActualOffset(sixth_offset + base_stride, array_align);
10570 const GLuint eigth_offset = type.GetActualOffset(seventh_offset + base_stride, array_align);
10572 #else /* WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST */
10574 const GLuint third_offset = type.GetActualOffset(second_offset + base_stride, 2 * type_align);
10575 const GLuint fourth_offset = type.GetActualOffset(3 * type_align + base_stride, base_align);
10576 const GLuint fifth_offset = type.GetActualOffset(fourth_offset + base_stride, base_align);
10577 const GLuint sixth_offset = type.GetActualOffset(fifth_offset + base_stride, array_align);
10578 const GLuint seventh_offset = type.GetActualOffset(sixth_offset + base_stride, array_align);
10579 const GLuint eigth_offset = type.GetActualOffset(seventh_offset + base_stride, 8 * basic_size);
10581 #endif /* WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST */
10584 const std::vector<GLubyte>& first = type.GenerateData();
10585 const std::vector<GLubyte>& second = type.GenerateData();
10586 const std::vector<GLubyte>& third = type.GenerateData();
10587 const std::vector<GLubyte>& fourth = type.GenerateData();
10589 m_data.resize(eigth_offset + base_stride);
10590 GLubyte* ptr = &m_data[0];
10591 memcpy(ptr + first_offset, &first[0], first.size());
10592 memcpy(ptr + second_offset, &second[0], second.size());
10593 memcpy(ptr + third_offset, &third[0], third.size());
10594 memcpy(ptr + fourth_offset, &fourth[0], fourth.size());
10595 memcpy(ptr + fifth_offset, &fourth[0], fourth.size());
10596 memcpy(ptr + sixth_offset, &third[0], third.size());
10597 memcpy(ptr + seventh_offset, &second[0], second.size());
10598 memcpy(ptr + eigth_offset, &first[0], first.size());
10600 /* Prepare globals */
10601 size_t position = 0;
10604 sprintf(buffer, "%d", basic_size);
10605 Utils::replaceToken("BASIC_SIZE", position, buffer, globals);
10607 sprintf(buffer, "%d", type_align);
10608 Utils::replaceToken("TYPE_ALIGN", position, buffer, globals);
10610 sprintf(buffer, "%d", base_stride);
10611 Utils::replaceToken("TYPE_SIZE", position, buffer, globals);
10613 /* Prepare Block */
10614 Utils::Interface* vs_buf_block = program_interface.Block("vs_buf_Block");
10616 vs_buf_block->Member("at_first_offset", "layout(offset = 0, align = 8 * basic_size)", 0 /* expected_component */,
10617 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
10620 vs_buf_block->Member("at_second_offset", "layout(offset = type_size, align = basic_size / 2)",
10621 0 /* expected_component */, 0 /* expected_location */, type, false /* normalized */,
10622 0 /* n_array_elements */, base_stride, second_offset);
10624 vs_buf_block->Member("at_third_offset", "layout(align = 2 * type_align)", 0 /* expected_component */,
10625 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
10628 vs_buf_block->Member("at_fourth_offset", "layout(offset = 3 * type_align + type_size)", 0 /* expected_component */,
10629 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
10632 vs_buf_block->Member("at_fifth_offset", "", 0 /* expected_component */, 0 /* expected_location */, type,
10633 false /* normalized */, 0 /* n_array_elements */, base_stride, fifth_offset);
10635 vs_buf_block->Member("at_sixth_offset", "", 0 /* expected_component */, 0 /* expected_location */, type,
10636 false /* normalized */, 2 /* n_array_elements */, array_align * 2, sixth_offset);
10638 vs_buf_block->Member("at_eigth_offset", "layout(align = 8 * basic_size)", 0 /* expected_component */,
10639 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
10642 Utils::ShaderInterface& vs_si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
10645 vs_si.m_globals = globals;
10647 /* Add uniform BLOCK */
10648 vs_si.SSB("vs_buf_block", "layout (std140, binding = BINDING)", 0, 0, vs_buf_block, 0,
10649 static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
10652 program_interface.CloneVertexInterface(varying_passthrough);
10657 * @param test_case_index Index of test case
10659 * @return Name of type test in test_case_index
10661 std::string SSBMemberOffsetAndAlignTest::getTestCaseName(glw::GLuint test_case_index)
10663 return getTypeName(test_case_index);
10666 /** Returns number of types to test
10668 * @return Number of types, 34
10670 glw::GLuint SSBMemberOffsetAndAlignTest::getTestCaseNumber()
10672 return getTypesNumber();
10675 /** Prepare code snippet that will verify in and uniform variables
10679 * @param stage Shader stage
10681 * @return Code that verify variables
10683 std::string SSBMemberOffsetAndAlignTest::getVerificationSnippet(GLuint /* test_case_index */,
10684 Utils::ProgramInterface& /* program_interface */,
10685 Utils::Shader::STAGES stage)
10687 std::string verification = "if ( (PREFIXblock.at_first_offset != PREFIXblock.at_eigth_offset ) ||\n"
10688 " (PREFIXblock.at_second_offset != PREFIXblock.at_sixth_offset[1]) ||\n"
10689 " (PREFIXblock.at_third_offset != PREFIXblock.at_sixth_offset[0]) ||\n"
10690 " (PREFIXblock.at_fourth_offset != PREFIXblock.at_fifth_offset ) )\n"
10695 const GLchar* prefix = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::SSB);
10697 Utils::replaceAllTokens("PREFIX", prefix, verification);
10699 return verification;
10702 /** Selects if "draw" stages are relevant for test
10706 * @return true if all stages support shader storage buffers, false otherwise
10708 bool SSBMemberOffsetAndAlignTest::isDrawRelevant(GLuint /* test_case_index */)
10710 const Functions& gl = m_context.getRenderContext().getFunctions();
10711 GLint gs_supported_buffers = 0;
10712 GLint tcs_supported_buffers = 0;
10713 GLint tes_supported_buffers = 0;
10714 GLint vs_supported_buffers = 0;
10716 gl.getIntegerv(GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS, &gs_supported_buffers);
10717 gl.getIntegerv(GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS, &tcs_supported_buffers);
10718 gl.getIntegerv(GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS, &tes_supported_buffers);
10719 gl.getIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &vs_supported_buffers);
10721 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
10723 return ((1 <= gs_supported_buffers) && (1 <= tcs_supported_buffers) && (1 <= tes_supported_buffers) &&
10724 (1 <= vs_supported_buffers));
10729 * @param context Test framework context
10731 SSBLayoutQualifierConflictTest::SSBLayoutQualifierConflictTest(deqp::Context& context)
10732 : NegativeTestBase(context, "ssb_layout_qualifier_conflict", "Test verifies that std140 or std430 is required when "
10733 "offset and/or align qualifiers are used with storage "
10736 /* Nothing to be done here */
10739 /** Source for given test case and stage
10741 * @param test_case_index Index of test case
10742 * @param stage Shader stage
10744 * @return Shader source
10746 std::string SSBLayoutQualifierConflictTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
10748 static const GLchar* cs = "#version 430 core\n"
10749 "#extension GL_ARB_enhanced_layouts : require\n"
10751 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
10753 "layout (QUALIFIERbinding = BINDING) buffer cs_Block {\n"
10754 " layout(offset = 16) vec4 boy;\n"
10755 " layout(align = 64) vec4 man;\n"
10758 "writeonly uniform image2D uni_image;\n"
10762 " vec4 result = uni_block.boy + uni_block.man;\n"
10764 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
10767 static const GLchar* fs = "#version 430 core\n"
10768 "#extension GL_ARB_enhanced_layouts : require\n"
10770 "layout (QUALIFIERbinding = BINDING) buffer Block {\n"
10771 " layout(offset = 16) vec4 boy;\n"
10772 " layout(align = 64) vec4 man;\n"
10776 "out vec4 fs_out;\n"
10780 " fs_out = gs_fs + uni_block.boy + uni_block.man;\n"
10783 static const GLchar* gs = "#version 430 core\n"
10784 "#extension GL_ARB_enhanced_layouts : require\n"
10786 "layout(points) in;\n"
10787 "layout(triangle_strip, max_vertices = 4) out;\n"
10789 "layout (QUALIFIERbinding = BINDING) buffer gs_Block {\n"
10790 " layout(offset = 16) vec4 boy;\n"
10791 " layout(align = 64) vec4 man;\n"
10794 "in vec4 tes_gs[];\n"
10795 "out vec4 gs_fs;\n"
10799 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
10800 " gl_Position = vec4(-1, -1, 0, 1);\n"
10802 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
10803 " gl_Position = vec4(-1, 1, 0, 1);\n"
10805 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
10806 " gl_Position = vec4(1, -1, 0, 1);\n"
10808 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
10809 " gl_Position = vec4(1, 1, 0, 1);\n"
10813 static const GLchar* tcs =
10814 "#version 430 core\n"
10815 "#extension GL_ARB_enhanced_layouts : require\n"
10817 "layout(vertices = 1) out;\n"
10819 "layout (QUALIFIERbinding = BINDING) buffer tcs_Block {\n"
10820 " layout(offset = 16) vec4 boy;\n"
10821 " layout(align = 64) vec4 man;\n"
10824 "in vec4 vs_tcs[];\n"
10825 "out vec4 tcs_tes[];\n"
10830 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID] + uni_block.boy + uni_block.man;\n"
10832 " gl_TessLevelOuter[0] = 1.0;\n"
10833 " gl_TessLevelOuter[1] = 1.0;\n"
10834 " gl_TessLevelOuter[2] = 1.0;\n"
10835 " gl_TessLevelOuter[3] = 1.0;\n"
10836 " gl_TessLevelInner[0] = 1.0;\n"
10837 " gl_TessLevelInner[1] = 1.0;\n"
10840 static const GLchar* tes = "#version 430 core\n"
10841 "#extension GL_ARB_enhanced_layouts : require\n"
10843 "layout(isolines, point_mode) in;\n"
10845 "layout (QUALIFIERbinding = BINDING) buffer tes_Block {\n"
10846 " layout(offset = 16) vec4 boy;\n"
10847 " layout(align = 64) vec4 man;\n"
10850 "in vec4 tcs_tes[];\n"
10851 "out vec4 tes_gs;\n"
10855 " tes_gs = tcs_tes[0] + uni_block.boy + uni_block.man;\n"
10858 static const GLchar* vs = "#version 430 core\n"
10859 "#extension GL_ARB_enhanced_layouts : require\n"
10861 "layout (QUALIFIERbinding = BINDING) buffer vs_Block {\n"
10862 " layout(offset = 16) vec4 boy;\n"
10863 " layout(align = 64) vec4 man;\n"
10867 "out vec4 vs_tcs;\n"
10871 " vs_tcs = in_vs + uni_block.boy + uni_block.man;\n"
10876 size_t position = 0;
10877 std::string source;
10878 testCase& test_case = m_test_cases[test_case_index];
10879 std::string qualifier = getQualifierName(test_case.m_qualifier);
10881 if (false == qualifier.empty())
10883 qualifier.append(", ");
10886 sprintf(buffer, "%d", stage);
10890 case Utils::Shader::COMPUTE:
10893 case Utils::Shader::FRAGMENT:
10896 case Utils::Shader::GEOMETRY:
10899 case Utils::Shader::TESS_CTRL:
10902 case Utils::Shader::TESS_EVAL:
10905 case Utils::Shader::VERTEX:
10909 TCU_FAIL("Invalid enum");
10912 if (test_case.m_stage == stage)
10914 Utils::replaceToken("QUALIFIER", position, qualifier.c_str(), source);
10918 Utils::replaceToken("QUALIFIER", position, "std140, ", source);
10921 Utils::replaceToken("BINDING", position, buffer, source);
10926 /** Get description of test case
10928 * @param test_case_index Index of test case
10930 * @return Qualifier name
10932 std::string SSBLayoutQualifierConflictTest::getTestCaseName(GLuint test_case_index)
10934 std::string result = getQualifierName(m_test_cases[test_case_index].m_qualifier);
10939 /** Get number of test cases
10941 * @return Number of test cases
10943 GLuint SSBLayoutQualifierConflictTest::getTestCaseNumber()
10945 return static_cast<GLuint>(m_test_cases.size());
10948 /** Selects if "compute" stage is relevant for test
10950 * @param test_case_index Index of test case
10952 * @return true when tested stage is compute
10954 bool SSBLayoutQualifierConflictTest::isComputeRelevant(GLuint test_case_index)
10956 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
10959 /** Selects if compilation failure is expected result
10961 * @param test_case_index Index of test case
10963 * @return false for STD140 and STD430 cases, true otherwise
10965 bool SSBLayoutQualifierConflictTest::isFailureExpected(GLuint test_case_index)
10967 const QUALIFIERS qualifier = m_test_cases[test_case_index].m_qualifier;
10969 return !((STD140 == qualifier) || (STD430 == qualifier));
10972 /** Checks if stage is supported
10974 * @param stage Shader stage
10976 * @return true if supported, false otherwise
10978 bool SSBLayoutQualifierConflictTest::isStageSupported(Utils::Shader::STAGES stage)
10980 const Functions& gl = m_context.getRenderContext().getFunctions();
10981 GLint max_supported_buffers = 0;
10986 case Utils::Shader::COMPUTE:
10987 pname = GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS;
10989 case Utils::Shader::FRAGMENT:
10990 pname = GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS;
10992 case Utils::Shader::GEOMETRY:
10993 pname = GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS;
10995 case Utils::Shader::TESS_CTRL:
10996 pname = GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS;
10998 case Utils::Shader::TESS_EVAL:
10999 pname = GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS;
11001 case Utils::Shader::VERTEX:
11002 pname = GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS;
11005 TCU_FAIL("Invalid enum");
11008 gl.getIntegerv(pname, &max_supported_buffers);
11009 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
11011 return 1 <= max_supported_buffers;
11014 /** Prepare all test cases
11017 void SSBLayoutQualifierConflictTest::testInit()
11019 bool stage_support[Utils::Shader::STAGE_MAX];
11021 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
11023 stage_support[stage] = isStageSupported((Utils::Shader::STAGES)stage);
11026 for (GLuint qualifier = 0; qualifier < QUALIFIERS_MAX; ++qualifier)
11028 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
11030 if (false == stage_support[stage])
11035 testCase test_case = { (QUALIFIERS)qualifier, (Utils::Shader::STAGES)stage };
11037 m_test_cases.push_back(test_case);
11042 /** Get name of glsl constant
11044 * @param Constant id
11046 * @return Name of constant used in GLSL
11048 const GLchar* SSBLayoutQualifierConflictTest::getQualifierName(QUALIFIERS qualifier)
11050 const GLchar* name = "";
11070 TCU_FAIL("Invalid enum");
11078 * @param context Test framework context
11080 SSBMemberInvalidOffsetAlignmentTest::SSBMemberInvalidOffsetAlignmentTest(deqp::Context& context)
11081 : UniformBlockMemberInvalidOffsetAlignmentTest(
11082 context, "ssb_member_invalid_offset_alignment",
11083 "Test verifies that invalid alignment of offset qualifiers cause compilation failure")
11085 /* Nothing to be done here */
11088 /** Get the maximum size for a shader storage block
11090 * @return The maximum size in basic machine units of a shader storage block.
11092 GLint SSBMemberInvalidOffsetAlignmentTest::getMaxBlockSize()
11094 const Functions& gl = m_context.getRenderContext().getFunctions();
11095 GLint max_size = 0;
11097 gl.getIntegerv(GL_MAX_SHADER_STORAGE_BLOCK_SIZE, &max_size);
11098 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
11103 /** Source for given test case and stage
11105 * @param test_case_index Index of test case
11106 * @param stage Shader stage
11108 * @return Shader source
11110 std::string SSBMemberInvalidOffsetAlignmentTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
11112 static const GLchar* cs = "#version 430 core\n"
11113 "#extension GL_ARB_enhanced_layouts : require\n"
11115 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
11117 "layout (std140) buffer Block {\n"
11118 " layout (offset = OFFSET) TYPE member;\n"
11121 "writeonly uniform image2D uni_image;\n"
11125 " vec4 result = vec4(1, 0, 0.5, 1);\n"
11127 " if (TYPE(1) == block.member)\n"
11129 " result = vec4(1, 1, 1, 1);\n"
11132 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
11135 static const GLchar* fs = "#version 430 core\n"
11136 "#extension GL_ARB_enhanced_layouts : require\n"
11139 "out vec4 fs_out;\n"
11143 " fs_out = gs_fs;\n"
11146 static const GLchar* fs_tested = "#version 430 core\n"
11147 "#extension GL_ARB_enhanced_layouts : require\n"
11149 "layout (std140) buffer Block {\n"
11150 " layout (offset = OFFSET) TYPE member;\n"
11154 "out vec4 fs_out;\n"
11158 " if (TYPE(1) == block.member)\n"
11160 " fs_out = vec4(1, 1, 1, 1);\n"
11163 " fs_out += gs_fs;\n"
11166 static const GLchar* gs = "#version 430 core\n"
11167 "#extension GL_ARB_enhanced_layouts : require\n"
11169 "layout(points) in;\n"
11170 "layout(triangle_strip, max_vertices = 4) out;\n"
11172 "in vec4 tes_gs[];\n"
11173 "out vec4 gs_fs;\n"
11177 " gs_fs = tes_gs[0];\n"
11178 " gl_Position = vec4(-1, -1, 0, 1);\n"
11180 " gs_fs = tes_gs[0];\n"
11181 " gl_Position = vec4(-1, 1, 0, 1);\n"
11183 " gs_fs = tes_gs[0];\n"
11184 " gl_Position = vec4(1, -1, 0, 1);\n"
11186 " gs_fs = tes_gs[0];\n"
11187 " gl_Position = vec4(1, 1, 0, 1);\n"
11191 static const GLchar* gs_tested = "#version 430 core\n"
11192 "#extension GL_ARB_enhanced_layouts : require\n"
11194 "layout(points) in;\n"
11195 "layout(triangle_strip, max_vertices = 4) out;\n"
11197 "layout (std140) buffer Block {\n"
11198 " layout (offset = OFFSET) TYPE member;\n"
11201 "in vec4 tes_gs[];\n"
11202 "out vec4 gs_fs;\n"
11206 " if (TYPE(1) == block.member)\n"
11208 " gs_fs = vec4(1, 1, 1, 1);\n"
11211 " gs_fs += tes_gs[0];\n"
11212 " gl_Position = vec4(-1, -1, 0, 1);\n"
11214 " gs_fs += tes_gs[0];\n"
11215 " gl_Position = vec4(-1, 1, 0, 1);\n"
11217 " gs_fs += tes_gs[0];\n"
11218 " gl_Position = vec4(1, -1, 0, 1);\n"
11220 " gs_fs += tes_gs[0];\n"
11221 " gl_Position = vec4(1, 1, 0, 1);\n"
11225 static const GLchar* tcs = "#version 430 core\n"
11226 "#extension GL_ARB_enhanced_layouts : require\n"
11228 "layout(vertices = 1) out;\n"
11230 "in vec4 vs_tcs[];\n"
11231 "out vec4 tcs_tes[];\n"
11236 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
11238 " gl_TessLevelOuter[0] = 1.0;\n"
11239 " gl_TessLevelOuter[1] = 1.0;\n"
11240 " gl_TessLevelOuter[2] = 1.0;\n"
11241 " gl_TessLevelOuter[3] = 1.0;\n"
11242 " gl_TessLevelInner[0] = 1.0;\n"
11243 " gl_TessLevelInner[1] = 1.0;\n"
11246 static const GLchar* tcs_tested = "#version 430 core\n"
11247 "#extension GL_ARB_enhanced_layouts : require\n"
11249 "layout(vertices = 1) out;\n"
11251 "layout (std140) buffer Block {\n"
11252 " layout (offset = OFFSET) TYPE member;\n"
11255 "in vec4 vs_tcs[];\n"
11256 "out vec4 tcs_tes[];\n"
11260 " if (TYPE(1) == block.member)\n"
11262 " tcs_tes[gl_InvocationID] = vec4(1, 1, 1, 1);\n"
11266 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
11268 " gl_TessLevelOuter[0] = 1.0;\n"
11269 " gl_TessLevelOuter[1] = 1.0;\n"
11270 " gl_TessLevelOuter[2] = 1.0;\n"
11271 " gl_TessLevelOuter[3] = 1.0;\n"
11272 " gl_TessLevelInner[0] = 1.0;\n"
11273 " gl_TessLevelInner[1] = 1.0;\n"
11276 static const GLchar* tes = "#version 430 core\n"
11277 "#extension GL_ARB_enhanced_layouts : require\n"
11279 "layout(isolines, point_mode) in;\n"
11281 "in vec4 tcs_tes[];\n"
11282 "out vec4 tes_gs;\n"
11286 " tes_gs = tcs_tes[0];\n"
11289 static const GLchar* tes_tested = "#version 430 core\n"
11290 "#extension GL_ARB_enhanced_layouts : require\n"
11292 "layout(isolines, point_mode) in;\n"
11294 "layout (std140) buffer Block {\n"
11295 " layout (offset = OFFSET) TYPE member;\n"
11298 "in vec4 tcs_tes[];\n"
11299 "out vec4 tes_gs;\n"
11303 " if (TYPE(1) == block.member)\n"
11305 " tes_gs = vec4(1, 1, 1, 1);\n"
11308 " tes_gs += tcs_tes[0];\n"
11311 static const GLchar* vs = "#version 430 core\n"
11312 "#extension GL_ARB_enhanced_layouts : require\n"
11315 "out vec4 vs_tcs;\n"
11319 " vs_tcs = in_vs;\n"
11322 static const GLchar* vs_tested = "#version 430 core\n"
11323 "#extension GL_ARB_enhanced_layouts : require\n"
11325 "layout (std140) buffer Block {\n"
11326 " layout (offset = OFFSET) TYPE member;\n"
11330 "out vec4 vs_tcs;\n"
11334 " if (TYPE(1) == block.member)\n"
11336 " vs_tcs = vec4(1, 1, 1, 1);\n"
11339 " vs_tcs += in_vs;\n"
11343 std::string source;
11344 testCase& test_case = m_test_cases[test_case_index];
11346 if (test_case.m_stage == stage)
11349 const GLuint offset = test_case.m_offset;
11350 size_t position = 0;
11351 const Utils::Type& type = test_case.m_type;
11352 const GLchar* type_name = type.GetGLSLTypeName();
11354 sprintf(buffer, "%d", offset);
11358 case Utils::Shader::COMPUTE:
11361 case Utils::Shader::FRAGMENT:
11362 source = fs_tested;
11364 case Utils::Shader::GEOMETRY:
11365 source = gs_tested;
11367 case Utils::Shader::TESS_CTRL:
11368 source = tcs_tested;
11370 case Utils::Shader::TESS_EVAL:
11371 source = tes_tested;
11373 case Utils::Shader::VERTEX:
11374 source = vs_tested;
11377 TCU_FAIL("Invalid enum");
11380 Utils::replaceToken("OFFSET", position, buffer, source);
11381 Utils::replaceToken("TYPE", position, type_name, source);
11382 Utils::replaceToken("TYPE", position, type_name, source);
11388 case Utils::Shader::FRAGMENT:
11391 case Utils::Shader::GEOMETRY:
11394 case Utils::Shader::TESS_CTRL:
11397 case Utils::Shader::TESS_EVAL:
11400 case Utils::Shader::VERTEX:
11404 TCU_FAIL("Invalid enum");
11411 /** Checks if stage is supported
11413 * @param stage Shader stage
11415 * @return true if supported, false otherwise
11417 bool SSBMemberInvalidOffsetAlignmentTest::isStageSupported(Utils::Shader::STAGES stage)
11419 const Functions& gl = m_context.getRenderContext().getFunctions();
11420 GLint max_supported_buffers = 0;
11425 case Utils::Shader::COMPUTE:
11426 pname = GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS;
11428 case Utils::Shader::FRAGMENT:
11429 pname = GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS;
11431 case Utils::Shader::GEOMETRY:
11432 pname = GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS;
11434 case Utils::Shader::TESS_CTRL:
11435 pname = GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS;
11437 case Utils::Shader::TESS_EVAL:
11438 pname = GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS;
11440 case Utils::Shader::VERTEX:
11441 pname = GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS;
11444 TCU_FAIL("Invalid enum");
11447 gl.getIntegerv(pname, &max_supported_buffers);
11448 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
11450 return 1 <= max_supported_buffers;
11455 * @param context Test framework context
11457 SSBMemberOverlappingOffsetsTest::SSBMemberOverlappingOffsetsTest(deqp::Context& context)
11458 : UniformBlockMemberOverlappingOffsetsTest(
11459 context, "ssb_member_overlapping_offsets",
11460 "Test verifies that overlapping offsets qualifiers cause compilation failure")
11462 /* Nothing to be done here */
11465 /** Source for given test case and stage
11467 * @param test_case_index Index of test case
11468 * @param stage Shader stage
11470 * @return Shader source
11472 std::string SSBMemberOverlappingOffsetsTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
11474 static const GLchar* cs = "#version 430 core\n"
11475 "#extension GL_ARB_enhanced_layouts : require\n"
11477 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
11479 "layout (std140) buffer Block {\n"
11480 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11481 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11484 "writeonly uniform image2D uni_image;\n"
11488 " vec4 result = vec4(1, 0, 0.5, 1);\n"
11490 " if ((BOY_TYPE(1) == block.boy) ||\n"
11491 " (MAN_TYPE(0) == block.man) )\n"
11493 " result = vec4(1, 1, 1, 1);\n"
11496 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
11499 static const GLchar* fs = "#version 430 core\n"
11500 "#extension GL_ARB_enhanced_layouts : require\n"
11503 "out vec4 fs_out;\n"
11507 " fs_out = gs_fs;\n"
11510 static const GLchar* fs_tested = "#version 430 core\n"
11511 "#extension GL_ARB_enhanced_layouts : require\n"
11513 "layout (std140) buffer Block {\n"
11514 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11515 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11519 "out vec4 fs_out;\n"
11523 " if ((BOY_TYPE(1) == block.boy) ||\n"
11524 " (MAN_TYPE(0) == block.man) )\n"
11526 " fs_out = vec4(1, 1, 1, 1);\n"
11529 " fs_out += gs_fs;\n"
11532 static const GLchar* gs = "#version 430 core\n"
11533 "#extension GL_ARB_enhanced_layouts : require\n"
11535 "layout(points) in;\n"
11536 "layout(triangle_strip, max_vertices = 4) out;\n"
11538 "in vec4 tes_gs[];\n"
11539 "out vec4 gs_fs;\n"
11543 " gs_fs = tes_gs[0];\n"
11544 " gl_Position = vec4(-1, -1, 0, 1);\n"
11546 " gs_fs = tes_gs[0];\n"
11547 " gl_Position = vec4(-1, 1, 0, 1);\n"
11549 " gs_fs = tes_gs[0];\n"
11550 " gl_Position = vec4(1, -1, 0, 1);\n"
11552 " gs_fs = tes_gs[0];\n"
11553 " gl_Position = vec4(1, 1, 0, 1);\n"
11557 static const GLchar* gs_tested = "#version 430 core\n"
11558 "#extension GL_ARB_enhanced_layouts : require\n"
11560 "layout(points) in;\n"
11561 "layout(triangle_strip, max_vertices = 4) out;\n"
11563 "layout (std140) buffer Block {\n"
11564 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11565 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11568 "in vec4 tes_gs[];\n"
11569 "out vec4 gs_fs;\n"
11573 " if ((BOY_TYPE(1) == block.boy) ||\n"
11574 " (MAN_TYPE(0) == block.man) )\n"
11576 " gs_fs = vec4(1, 1, 1, 1);\n"
11579 " gs_fs += tes_gs[0];\n"
11580 " gl_Position = vec4(-1, -1, 0, 1);\n"
11582 " gs_fs += tes_gs[0];\n"
11583 " gl_Position = vec4(-1, 1, 0, 1);\n"
11585 " gs_fs += tes_gs[0];\n"
11586 " gl_Position = vec4(1, -1, 0, 1);\n"
11588 " gs_fs += tes_gs[0];\n"
11589 " gl_Position = vec4(1, 1, 0, 1);\n"
11593 static const GLchar* tcs = "#version 430 core\n"
11594 "#extension GL_ARB_enhanced_layouts : require\n"
11596 "layout(vertices = 1) out;\n"
11598 "in vec4 vs_tcs[];\n"
11599 "out vec4 tcs_tes[];\n"
11604 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
11606 " gl_TessLevelOuter[0] = 1.0;\n"
11607 " gl_TessLevelOuter[1] = 1.0;\n"
11608 " gl_TessLevelOuter[2] = 1.0;\n"
11609 " gl_TessLevelOuter[3] = 1.0;\n"
11610 " gl_TessLevelInner[0] = 1.0;\n"
11611 " gl_TessLevelInner[1] = 1.0;\n"
11614 static const GLchar* tcs_tested = "#version 430 core\n"
11615 "#extension GL_ARB_enhanced_layouts : require\n"
11617 "layout(vertices = 1) out;\n"
11619 "layout (std140) buffer Block {\n"
11620 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11621 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11624 "in vec4 vs_tcs[];\n"
11625 "out vec4 tcs_tes[];\n"
11629 " if ((BOY_TYPE(1) == block.boy) ||\n"
11630 " (MAN_TYPE(0) == block.man) )\n"
11632 " tcs_tes[gl_InvocationID] = vec4(1, 1, 1, 1);\n"
11636 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
11638 " gl_TessLevelOuter[0] = 1.0;\n"
11639 " gl_TessLevelOuter[1] = 1.0;\n"
11640 " gl_TessLevelOuter[2] = 1.0;\n"
11641 " gl_TessLevelOuter[3] = 1.0;\n"
11642 " gl_TessLevelInner[0] = 1.0;\n"
11643 " gl_TessLevelInner[1] = 1.0;\n"
11646 static const GLchar* tes = "#version 430 core\n"
11647 "#extension GL_ARB_enhanced_layouts : require\n"
11649 "layout(isolines, point_mode) in;\n"
11651 "in vec4 tcs_tes[];\n"
11652 "out vec4 tes_gs;\n"
11656 " tes_gs = tcs_tes[0];\n"
11659 static const GLchar* tes_tested = "#version 430 core\n"
11660 "#extension GL_ARB_enhanced_layouts : require\n"
11662 "layout(isolines, point_mode) in;\n"
11664 "layout (std140) buffer Block {\n"
11665 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11666 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11669 "in vec4 tcs_tes[];\n"
11670 "out vec4 tes_gs;\n"
11674 " if ((BOY_TYPE(1) == block.boy) ||\n"
11675 " (MAN_TYPE(0) == block.man) )\n"
11677 " tes_gs = vec4(1, 1, 1, 1);\n"
11680 " tes_gs += tcs_tes[0];\n"
11683 static const GLchar* vs = "#version 430 core\n"
11684 "#extension GL_ARB_enhanced_layouts : require\n"
11687 "out vec4 vs_tcs;\n"
11691 " vs_tcs = in_vs;\n"
11694 static const GLchar* vs_tested = "#version 430 core\n"
11695 "#extension GL_ARB_enhanced_layouts : require\n"
11697 "layout (std140) buffer Block {\n"
11698 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11699 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11703 "out vec4 vs_tcs;\n"
11707 " if ((BOY_TYPE(1) == block.boy) ||\n"
11708 " (MAN_TYPE(0) == block.man) )\n"
11710 " vs_tcs = vec4(1, 1, 1, 1);\n"
11713 " vs_tcs += in_vs;\n"
11717 std::string source;
11718 testCase& test_case = m_test_cases[test_case_index];
11720 if (test_case.m_stage == stage)
11723 const GLuint boy_offset = test_case.m_boy_offset;
11724 const Utils::Type& boy_type = test_case.m_boy_type;
11725 const GLchar* boy_type_name = boy_type.GetGLSLTypeName();
11726 const GLuint man_offset = test_case.m_man_offset;
11727 const Utils::Type& man_type = test_case.m_man_type;
11728 const GLchar* man_type_name = man_type.GetGLSLTypeName();
11729 size_t position = 0;
11733 case Utils::Shader::COMPUTE:
11736 case Utils::Shader::FRAGMENT:
11737 source = fs_tested;
11739 case Utils::Shader::GEOMETRY:
11740 source = gs_tested;
11742 case Utils::Shader::TESS_CTRL:
11743 source = tcs_tested;
11745 case Utils::Shader::TESS_EVAL:
11746 source = tes_tested;
11748 case Utils::Shader::VERTEX:
11749 source = vs_tested;
11752 TCU_FAIL("Invalid enum");
11755 sprintf(buffer, "%d", boy_offset);
11756 Utils::replaceToken("BOY_OFFSET", position, buffer, source);
11757 Utils::replaceToken("BOY_TYPE", position, boy_type_name, source);
11758 sprintf(buffer, "%d", man_offset);
11759 Utils::replaceToken("MAN_OFFSET", position, buffer, source);
11760 Utils::replaceToken("MAN_TYPE", position, man_type_name, source);
11761 Utils::replaceToken("BOY_TYPE", position, boy_type_name, source);
11762 Utils::replaceToken("MAN_TYPE", position, man_type_name, source);
11768 case Utils::Shader::FRAGMENT:
11771 case Utils::Shader::GEOMETRY:
11774 case Utils::Shader::TESS_CTRL:
11777 case Utils::Shader::TESS_EVAL:
11780 case Utils::Shader::VERTEX:
11784 TCU_FAIL("Invalid enum");
11791 /** Checks if stage is supported
11793 * @param stage Shader stage
11795 * @return true if supported, false otherwise
11797 bool SSBMemberOverlappingOffsetsTest::isStageSupported(Utils::Shader::STAGES stage)
11799 const Functions& gl = m_context.getRenderContext().getFunctions();
11800 GLint max_supported_buffers = 0;
11805 case Utils::Shader::COMPUTE:
11806 pname = GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS;
11808 case Utils::Shader::FRAGMENT:
11809 pname = GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS;
11811 case Utils::Shader::GEOMETRY:
11812 pname = GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS;
11814 case Utils::Shader::TESS_CTRL:
11815 pname = GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS;
11817 case Utils::Shader::TESS_EVAL:
11818 pname = GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS;
11820 case Utils::Shader::VERTEX:
11821 pname = GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS;
11824 TCU_FAIL("Invalid enum");
11827 gl.getIntegerv(pname, &max_supported_buffers);
11828 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
11830 return 1 <= max_supported_buffers;
11835 * @param context Test framework context
11837 SSBMemberAlignNonPowerOf2Test::SSBMemberAlignNonPowerOf2Test(deqp::Context& context)
11838 : UniformBlockMemberAlignNonPowerOf2Test(context, "ssb_member_align_non_power_of_2",
11839 "Test verifies that align qualifier requires value that is a power of 2")
11841 /* Nothing to be done here */
11844 /** Source for given test case and stage
11846 * @param test_case_index Index of test case
11847 * @param stage Shader stage
11849 * @return Shader source
11851 std::string SSBMemberAlignNonPowerOf2Test::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
11853 static const GLchar* cs = "#version 430 core\n"
11854 "#extension GL_ARB_enhanced_layouts : require\n"
11856 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
11858 "layout (std140) buffer Block {\n"
11860 " layout (align = ALIGN) TYPE man;\n"
11863 "writeonly uniform image2D uni_image;\n"
11867 " vec4 result = vec4(1, 0, 0.5, 1);\n"
11869 " if (TYPE(0) == block.man)\n"
11871 " result = vec4(1, 1, 1, 1) - block.boy;\n"
11874 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
11877 static const GLchar* fs = "#version 430 core\n"
11878 "#extension GL_ARB_enhanced_layouts : require\n"
11881 "out vec4 fs_out;\n"
11885 " fs_out = gs_fs;\n"
11888 static const GLchar* fs_tested = "#version 430 core\n"
11889 "#extension GL_ARB_enhanced_layouts : require\n"
11891 "layout (std140) buffer Block {\n"
11893 " layout (align = ALIGN) TYPE man;\n"
11897 "out vec4 fs_out;\n"
11901 " if (TYPE(0) == block.man)\n"
11903 " fs_out = block.boy;\n"
11906 " fs_out += gs_fs;\n"
11909 static const GLchar* gs = "#version 430 core\n"
11910 "#extension GL_ARB_enhanced_layouts : require\n"
11912 "layout(points) in;\n"
11913 "layout(triangle_strip, max_vertices = 4) out;\n"
11915 "in vec4 tes_gs[];\n"
11916 "out vec4 gs_fs;\n"
11920 " gs_fs = tes_gs[0];\n"
11921 " gl_Position = vec4(-1, -1, 0, 1);\n"
11923 " gs_fs = tes_gs[0];\n"
11924 " gl_Position = vec4(-1, 1, 0, 1);\n"
11926 " gs_fs = tes_gs[0];\n"
11927 " gl_Position = vec4(1, -1, 0, 1);\n"
11929 " gs_fs = tes_gs[0];\n"
11930 " gl_Position = vec4(1, 1, 0, 1);\n"
11934 static const GLchar* gs_tested = "#version 430 core\n"
11935 "#extension GL_ARB_enhanced_layouts : require\n"
11937 "layout(points) in;\n"
11938 "layout(triangle_strip, max_vertices = 4) out;\n"
11940 "layout (std140) buffer Block {\n"
11942 " layout (align = ALIGN) TYPE man;\n"
11945 "in vec4 tes_gs[];\n"
11946 "out vec4 gs_fs;\n"
11950 " if (TYPE(0) == block.man)\n"
11952 " gs_fs = block.boy;\n"
11955 " gs_fs += tes_gs[0];\n"
11956 " gl_Position = vec4(-1, -1, 0, 1);\n"
11958 " gs_fs += tes_gs[0];\n"
11959 " gl_Position = vec4(-1, 1, 0, 1);\n"
11961 " gs_fs += tes_gs[0];\n"
11962 " gl_Position = vec4(1, -1, 0, 1);\n"
11964 " gs_fs += tes_gs[0];\n"
11965 " gl_Position = vec4(1, 1, 0, 1);\n"
11969 static const GLchar* tcs = "#version 430 core\n"
11970 "#extension GL_ARB_enhanced_layouts : require\n"
11972 "layout(vertices = 1) out;\n"
11974 "in vec4 vs_tcs[];\n"
11975 "out vec4 tcs_tes[];\n"
11980 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
11982 " gl_TessLevelOuter[0] = 1.0;\n"
11983 " gl_TessLevelOuter[1] = 1.0;\n"
11984 " gl_TessLevelOuter[2] = 1.0;\n"
11985 " gl_TessLevelOuter[3] = 1.0;\n"
11986 " gl_TessLevelInner[0] = 1.0;\n"
11987 " gl_TessLevelInner[1] = 1.0;\n"
11990 static const GLchar* tcs_tested = "#version 430 core\n"
11991 "#extension GL_ARB_enhanced_layouts : require\n"
11993 "layout(vertices = 1) out;\n"
11995 "layout (std140) buffer Block {\n"
11997 " layout (align = ALIGN) TYPE man;\n"
12000 "in vec4 vs_tcs[];\n"
12001 "out vec4 tcs_tes[];\n"
12005 " if (TYPE(0) == block.man)\n"
12007 " tcs_tes[gl_InvocationID] = block.boy;\n"
12011 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
12013 " gl_TessLevelOuter[0] = 1.0;\n"
12014 " gl_TessLevelOuter[1] = 1.0;\n"
12015 " gl_TessLevelOuter[2] = 1.0;\n"
12016 " gl_TessLevelOuter[3] = 1.0;\n"
12017 " gl_TessLevelInner[0] = 1.0;\n"
12018 " gl_TessLevelInner[1] = 1.0;\n"
12021 static const GLchar* tes = "#version 430 core\n"
12022 "#extension GL_ARB_enhanced_layouts : require\n"
12024 "layout(isolines, point_mode) in;\n"
12026 "in vec4 tcs_tes[];\n"
12027 "out vec4 tes_gs;\n"
12031 " tes_gs = tcs_tes[0];\n"
12034 static const GLchar* tes_tested = "#version 430 core\n"
12035 "#extension GL_ARB_enhanced_layouts : require\n"
12037 "layout(isolines, point_mode) in;\n"
12039 "layout (std140) buffer Block {\n"
12041 " layout (align = ALIGN) TYPE man;\n"
12044 "in vec4 tcs_tes[];\n"
12045 "out vec4 tes_gs;\n"
12049 " if (TYPE(0) == block.man)\n"
12051 " tes_gs = block.boy;\n"
12054 " tes_gs += tcs_tes[0];\n"
12057 static const GLchar* vs = "#version 430 core\n"
12058 "#extension GL_ARB_enhanced_layouts : require\n"
12061 "out vec4 vs_tcs;\n"
12065 " vs_tcs = in_vs;\n"
12068 static const GLchar* vs_tested = "#version 430 core\n"
12069 "#extension GL_ARB_enhanced_layouts : require\n"
12071 "layout (std140) buffer Block {\n"
12073 " layout (align = ALIGN) TYPE man;\n"
12077 "out vec4 vs_tcs;\n"
12081 " if (TYPE(0) == block.man)\n"
12083 " vs_tcs = block.boy;\n"
12086 " vs_tcs += in_vs;\n"
12090 std::string source;
12091 testCase& test_case = m_test_cases[test_case_index];
12093 if (test_case.m_stage == stage)
12096 const GLuint alignment = test_case.m_alignment;
12097 const Utils::Type& type = test_case.m_type;
12098 const GLchar* type_name = type.GetGLSLTypeName();
12099 size_t position = 0;
12103 case Utils::Shader::COMPUTE:
12106 case Utils::Shader::FRAGMENT:
12107 source = fs_tested;
12109 case Utils::Shader::GEOMETRY:
12110 source = gs_tested;
12112 case Utils::Shader::TESS_CTRL:
12113 source = tcs_tested;
12115 case Utils::Shader::TESS_EVAL:
12116 source = tes_tested;
12118 case Utils::Shader::VERTEX:
12119 source = vs_tested;
12122 TCU_FAIL("Invalid enum");
12125 sprintf(buffer, "%d", alignment);
12126 Utils::replaceToken("ALIGN", position, buffer, source);
12127 Utils::replaceToken("TYPE", position, type_name, source);
12128 Utils::replaceToken("TYPE", position, type_name, source);
12134 case Utils::Shader::FRAGMENT:
12137 case Utils::Shader::GEOMETRY:
12140 case Utils::Shader::TESS_CTRL:
12143 case Utils::Shader::TESS_EVAL:
12146 case Utils::Shader::VERTEX:
12150 TCU_FAIL("Invalid enum");
12157 /** Checks if stage is supported
12159 * @param stage Shader stage
12161 * @return true if supported, false otherwise
12163 bool SSBMemberAlignNonPowerOf2Test::isStageSupported(Utils::Shader::STAGES stage)
12165 const Functions& gl = m_context.getRenderContext().getFunctions();
12166 GLint max_supported_buffers = 0;
12171 case Utils::Shader::COMPUTE:
12172 pname = GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS;
12174 case Utils::Shader::FRAGMENT:
12175 pname = GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS;
12177 case Utils::Shader::GEOMETRY:
12178 pname = GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS;
12180 case Utils::Shader::TESS_CTRL:
12181 pname = GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS;
12183 case Utils::Shader::TESS_EVAL:
12184 pname = GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS;
12186 case Utils::Shader::VERTEX:
12187 pname = GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS;
12190 TCU_FAIL("Invalid enum");
12193 gl.getIntegerv(pname, &max_supported_buffers);
12194 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
12196 return 1 <= max_supported_buffers;
12201 * @param context Test framework context
12203 SSBAlignmentTest::SSBAlignmentTest(deqp::Context& context)
12204 : TextureTestBase(context, "ssb_alignment", "Test verifies offset and alignment of ssb buffer")
12208 /** Get interface of program
12211 * @param program_interface Interface of program
12212 * @param varying_passthrough Collection of connections between in and out variables
12214 void SSBAlignmentTest::getProgramInterface(GLuint /* test_case_index */, Utils::ProgramInterface& program_interface,
12215 Utils::VaryingPassthrough& varying_passthrough)
12217 static const Utils::Type vec4 = Utils::Type::vec4;
12219 #if WRKARD_UNIFORMBLOCKALIGNMENT
12221 static const GLuint block_align = 16;
12223 #else /* WRKARD_UNIFORMBLOCKALIGNMENT */
12225 static const GLuint block_align = 64;
12227 #endif /* WRKARD_UNIFORMBLOCKALIGNMENT */
12229 static const GLuint fifth_align = 16;
12230 static const GLuint vec4_stride = 16;
12231 static const GLuint data_stride = vec4_stride * 2; /* one vec4 + one scalar aligned to 16 */
12233 const GLuint first_offset = 0; /* vec4 at 0 */
12234 const GLuint second_offset = Utils::Type::GetActualOffset(first_offset + vec4_stride, block_align); /* Data at 32 */
12235 const GLuint third_offset =
12236 Utils::Type::GetActualOffset(second_offset + data_stride, block_align); /* Data[2] at 64 */
12237 const GLuint fourth_offset =
12238 Utils::Type::GetActualOffset(third_offset + data_stride * 2, block_align); /* vec4[3] at 96 */
12239 const GLuint fifth_offset =
12240 Utils::Type::GetActualOffset(fourth_offset + vec4_stride * 3, fifth_align); /* vec4[2] at 160 */
12241 const GLuint sixth_offset =
12242 Utils::Type::GetActualOffset(fifth_offset + vec4_stride * 2, block_align); /* Data at 192 */
12244 Utils::Interface* structure = program_interface.Structure("Data");
12246 structure->Member("vector", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::vec4,
12247 false /* normalized */, 0 /* n_array_elements */, Utils::Type::vec4.GetSize(), 0 /* offset */);
12249 structure->Member("scalar", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::_float,
12250 false /* normalized */, 0 /* n_array_elements */, Utils::Type::_float.GetSize(),
12251 Utils::Type::vec4.GetSize() /* offset */);
12253 /* Prepare Block */
12254 Utils::Interface* vs_buf_Block = program_interface.Block("vs_buf_Block");
12256 vs_buf_Block->Member("first", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::vec4,
12257 false /* normalized */, 0 /* n_array_elements */, vec4_stride, first_offset /* offset */);
12259 vs_buf_Block->Member("second", "", 0 /* expected_component */, 0 /* expected_location */, structure,
12260 0 /* n_array_elements */, data_stride, second_offset);
12262 vs_buf_Block->Member("third", "", 0 /* expected_component */, 0 /* expected_location */, structure,
12263 2 /* n_array_elements */, data_stride, third_offset);
12265 vs_buf_Block->Member("fourth", "", 0 /* expected_component */, 0 /* expected_location */, vec4,
12266 false /* normalized */, 3 /* n_array_elements */, vec4_stride, fourth_offset);
12268 vs_buf_Block->Member("fifth", "layout(align = 16)", 0 /* expected_component */, 0 /* expected_location */, vec4,
12269 false /* normalized */, 2 /* n_array_elements */, vec4_stride, fifth_offset);
12271 vs_buf_Block->Member("sixth", "", 0 /* expected_component */, 0 /* expected_location */, structure,
12272 0 /* n_array_elements */, data_stride, sixth_offset);
12274 const GLuint stride = calculateStride(*vs_buf_Block);
12275 m_data.resize(stride);
12276 generateData(*vs_buf_Block, 0, m_data);
12278 Utils::ShaderInterface& vs_si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
12280 /* Add uniform BLOCK */
12281 #if WRKARD_UNIFORMBLOCKALIGNMENT
12282 vs_si.SSB("vs_buf_block", "layout (std140, binding = BINDING)", 0, 0, vs_buf_Block, 0,
12283 static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
12284 #else /* WRKARD_UNIFORMBLOCKALIGNMENT */
12285 vs_si.SSB("vs_buf_block", "layout (std140, binding = BINDING, align = 64)", 0, 0, vs_buf_Block, 0,
12286 static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
12287 #endif /* WRKARD_UNIFORMBLOCKALIGNMENT */
12289 program_interface.CloneVertexInterface(varying_passthrough);
12292 /** Selects if "draw" stages are relevant for test
12296 * @return true if all stages support shader storage buffers, false otherwise
12298 bool SSBAlignmentTest::isDrawRelevant(GLuint /* test_case_index */)
12300 const Functions& gl = m_context.getRenderContext().getFunctions();
12301 GLint gs_supported_buffers = 0;
12302 GLint tcs_supported_buffers = 0;
12303 GLint tes_supported_buffers = 0;
12304 GLint vs_supported_buffers = 0;
12306 gl.getIntegerv(GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS, &gs_supported_buffers);
12307 gl.getIntegerv(GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS, &tcs_supported_buffers);
12308 gl.getIntegerv(GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS, &tes_supported_buffers);
12309 gl.getIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &vs_supported_buffers);
12311 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
12313 return ((1 <= gs_supported_buffers) && (1 <= tcs_supported_buffers) && (1 <= tes_supported_buffers) &&
12314 (1 <= vs_supported_buffers));
12319 * @param context Test framework context
12321 VaryingLocationsTest::VaryingLocationsTest(deqp::Context& context)
12322 : TextureTestBase(context, "varying_locations", "Test verifies that input and output locations are respected")
12328 * @param context Test context
12329 * @param test_name Name of test
12330 * @param test_description Description of test
12332 VaryingLocationsTest::VaryingLocationsTest(deqp::Context& context, const glw::GLchar* test_name,
12333 const glw::GLchar* test_description)
12334 : TextureTestBase(context, test_name, test_description)
12338 /** Get interface of program
12340 * @param test_case_index Test case
12341 * @param program_interface Interface of program
12342 * @param varying_passthrough Collection of connections between in and out variables
12344 void VaryingLocationsTest::getProgramInterface(GLuint test_case_index, Utils::ProgramInterface& program_interface,
12345 Utils::VaryingPassthrough& varying_passthrough)
12347 const Utils::Type type = getType(test_case_index);
12349 m_first_data = type.GenerateDataPacked();
12350 m_last_data = type.GenerateDataPacked();
12352 prepareShaderStage(Utils::Shader::FRAGMENT, type, program_interface, varying_passthrough);
12353 prepareShaderStage(Utils::Shader::GEOMETRY, type, program_interface, varying_passthrough);
12354 prepareShaderStage(Utils::Shader::TESS_CTRL, type, program_interface, varying_passthrough);
12355 prepareShaderStage(Utils::Shader::TESS_EVAL, type, program_interface, varying_passthrough);
12356 prepareShaderStage(Utils::Shader::VERTEX, type, program_interface, varying_passthrough);
12361 * @param test_case_index Index of test case
12363 * @return Name of type test in test_case_index
12365 std::string VaryingLocationsTest::getTestCaseName(glw::GLuint test_case_index)
12367 return getTypeName(test_case_index);
12370 /** Returns number of types to test
12372 * @return Number of types, 34
12374 glw::GLuint VaryingLocationsTest::getTestCaseNumber()
12376 return getTypesNumber();
12379 /** Selects if "compute" stage is relevant for test
12385 bool VaryingLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
12394 std::string VaryingLocationsTest::prepareGlobals(GLint last_in_loc, GLint last_out_loc)
12397 std::string globals = "const uint first_input_location = 0u;\n"
12398 "const uint first_output_location = 0u;\n"
12399 "const uint last_input_location = LAST_INPUTu;\n"
12400 "const uint last_output_location = LAST_OUTPUTu;\n";
12401 size_t position = 100; /* Skip first part */
12403 sprintf(buffer, "%d", last_in_loc);
12404 Utils::replaceToken("LAST_INPUT", position, buffer, globals);
12406 sprintf(buffer, "%d", last_out_loc);
12407 Utils::replaceToken("LAST_OUTPUT", position, buffer, globals);
12415 void VaryingLocationsTest::prepareShaderStage(Utils::Shader::STAGES stage, const Utils::Type& type,
12416 Utils::ProgramInterface& program_interface,
12417 Utils::VaryingPassthrough& varying_passthrough)
12419 const GLuint array_length = 1;
12420 const GLuint first_in_loc = 0;
12421 const GLuint first_out_loc = 0;
12422 const GLuint last_in_loc = getLastInputLocation(stage, type, array_length);
12423 size_t position = 0;
12425 const GLchar* prefix_in = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::VARYING_INPUT);
12427 const GLchar* prefix_out = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::VARYING_OUTPUT);
12429 const GLchar* qual_first_in = "layout (location = first_input_location)";
12430 const GLchar* qual_first_out = "layout (location = first_output_location)";
12431 const GLchar* qual_last_in = "layout (location = last_input_location)";
12432 const GLchar* qual_last_out = "layout (location = last_output_location)";
12434 Utils::ShaderInterface& si = program_interface.GetShaderInterface(stage);
12435 const GLuint type_size = type.GetSize();
12437 std::string first_in_name = "PREFIXfirst";
12438 std::string first_out_name = "PREFIXfirst";
12439 std::string last_in_name = "PREFIXlast";
12440 std::string last_out_name = "PREFIXlast";
12442 Utils::replaceToken("PREFIX", position, prefix_in, first_in_name);
12444 Utils::replaceToken("PREFIX", position, prefix_out, first_out_name);
12446 Utils::replaceToken("PREFIX", position, prefix_in, last_in_name);
12448 Utils::replaceToken("PREFIX", position, prefix_out, last_out_name);
12450 if (Utils::Shader::FRAGMENT == stage)
12452 qual_first_in = "layout (location = first_input_location) flat";
12453 qual_last_in = "layout (location = last_input_location) flat";
12455 if (Utils::Shader::GEOMETRY == stage)
12457 qual_first_out = "layout (location = first_output_location) flat";
12458 qual_last_out = "layout (location = last_output_location) flat";
12461 Utils::Variable* first_in = si.Input(
12462 first_in_name.c_str(), qual_first_in /* qualifiers */, 0 /* expected_componenet */,
12463 first_in_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */, 0u /* n_array_elements */,
12464 0u /* stride */, 0u /* offset */, (GLvoid*)&m_first_data[0] /* data */, m_first_data.size() /* data_size */);
12466 Utils::Variable* last_in =
12467 si.Input(last_in_name.c_str(), qual_last_in /* qualifiers */, 0 /* expected_componenet */,
12468 last_in_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12469 0u /* n_array_elements */, 0u /* stride */, type_size /* offset */,
12470 (GLvoid*)&m_last_data[0] /* data */, m_last_data.size() /* data_size */);
12472 if (Utils::Shader::FRAGMENT != stage)
12474 const GLuint last_out_loc = getLastOutputLocation(stage, type, array_length);
12476 Utils::Variable* first_out =
12477 si.Output(first_out_name.c_str(), qual_first_out /* qualifiers */, 0 /* expected_componenet */,
12478 first_out_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12479 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)&m_first_data[0] /* data */,
12480 m_first_data.size() /* data_size */);
12482 Utils::Variable* last_out = si.Output(
12483 last_out_name.c_str(), qual_last_out /* qualifiers */, 0 /* expected_componenet */,
12484 last_out_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */, 0u /* n_array_elements */,
12485 0u /* stride */, 0u /* offset */, (GLvoid*)&m_last_data[0] /* data */, m_last_data.size() /* data_size */);
12487 si.m_globals = prepareGlobals(last_in_loc, last_out_loc);
12489 varying_passthrough.Add(stage, first_in, first_out);
12490 varying_passthrough.Add(stage, last_in, last_out);
12494 /* No outputs for fragment shader, so last_output_location can be 0 */
12495 si.m_globals = prepareGlobals(last_in_loc, 0);
12499 /** This test should be run with separable programs
12505 bool VaryingLocationsTest::useMonolithicProgram(GLuint /* test_case_index */)
12510 /* Constants used by VertexAttribLocationsTest */
12511 const GLuint VertexAttribLocationsTest::m_base_vertex = 4;
12512 const GLuint VertexAttribLocationsTest::m_base_instance = 2;
12513 const GLuint VertexAttribLocationsTest::m_loc_vertex = 2;
12514 const GLuint VertexAttribLocationsTest::m_loc_instance = 5;
12515 const GLuint VertexAttribLocationsTest::m_n_instances = 4;
12519 * @param context Test framework context
12521 VertexAttribLocationsTest::VertexAttribLocationsTest(deqp::Context& context)
12522 : TextureTestBase(context, "vertex_attrib_locations",
12523 "Test verifies that attribute locations are respected by drawing operations")
12527 /** Execute proper draw command for test case
12529 * @param test_case_index Index of test case
12531 void VertexAttribLocationsTest::executeDrawCall(GLuint test_case_index)
12533 const Functions& gl = m_context.getRenderContext().getFunctions();
12535 switch (test_case_index)
12538 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
12539 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
12541 case DRAWARRAYSINSTANCED:
12542 gl.drawArraysInstanced(GL_PATCHES, 0 /* first */, 1 /* count */, m_n_instances);
12543 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArraysInstanced");
12546 gl.drawElements(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL);
12547 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElements");
12549 case DRAWELEMENTSBASEVERTEX:
12550 gl.drawElementsBaseVertex(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL, m_base_vertex);
12551 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsBaseVertex");
12553 case DRAWELEMENTSINSTANCED:
12554 gl.drawElementsInstanced(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL, m_n_instances);
12555 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsInstanced");
12557 case DRAWELEMENTSINSTANCEDBASEINSTANCE:
12558 gl.drawElementsInstancedBaseInstance(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL, m_n_instances,
12560 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsInstancedBaseInstance");
12562 case DRAWELEMENTSINSTANCEDBASEVERTEX:
12563 gl.drawElementsInstancedBaseVertex(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL, m_n_instances,
12565 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsInstancedBaseVertex");
12567 case DRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCE:
12568 gl.drawElementsInstancedBaseVertexBaseInstance(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL,
12569 m_n_instances, m_base_vertex, m_base_instance);
12570 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsInstancedBaseVertexBaseInstance");
12573 TCU_FAIL("Invalid enum");
12577 /** Get interface of program
12580 * @param program_interface Interface of program
12583 void VertexAttribLocationsTest::getProgramInterface(GLuint /* test_case_index */,
12584 Utils::ProgramInterface& program_interface,
12585 Utils::VaryingPassthrough& /* varying_passthrough */)
12587 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
12590 si.m_globals = "const uint vertex_index_location = 2;\n"
12591 "const uint instance_index_location = 5;\n";
12594 si.Input("vertex_index" /* name */, "layout (location = vertex_index_location)" /* qualifiers */,
12595 0 /* expected_componenet */, m_loc_vertex /* expected_location */, Utils::Type::uint /* type */,
12596 GL_FALSE /* normalized */, 0u /* n_array_elements */, 16 /* stride */, 0u /* offset */,
12597 (GLvoid*)0 /* data */, 0 /* data_size */);
12598 si.Input("instance_index" /* name */, "layout (location = instance_index_location)" /* qualifiers */,
12599 0 /* expected_componenet */, m_loc_instance /* expected_location */, Utils::Type::uint /* type */,
12600 GL_FALSE /* normalized */, 0u /* n_array_elements */, 16 /* stride */, 16u /* offset */,
12601 (GLvoid*)0 /* data */, 0 /* data_size */);
12604 /** Get name of test case
12606 * @param test_case_index Index of test case
12608 * @return Name of test case
12610 std::string VertexAttribLocationsTest::getTestCaseName(glw::GLuint test_case_index)
12612 std::string result;
12614 switch (test_case_index)
12617 result = "DrawArrays";
12619 case DRAWARRAYSINSTANCED:
12620 result = "DrawArraysInstanced";
12623 result = "DrawElements";
12625 case DRAWELEMENTSBASEVERTEX:
12626 result = "DrawElementsBaseVertex";
12628 case DRAWELEMENTSINSTANCED:
12629 result = "DrawElementsInstanced";
12631 case DRAWELEMENTSINSTANCEDBASEINSTANCE:
12632 result = "DrawElementsInstancedBaseInstance";
12634 case DRAWELEMENTSINSTANCEDBASEVERTEX:
12635 result = "DrawElementsInstancedBaseVertex";
12637 case DRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCE:
12638 result = "DrawElementsInstancedBaseVertexBaseInstance";
12641 TCU_FAIL("Invalid enum");
12647 /** Get number of test cases
12649 * @return Number of test cases
12651 GLuint VertexAttribLocationsTest::getTestCaseNumber()
12653 return TESTCASES_MAX;
12656 /** Prepare code snippet that will verify in and uniform variables
12660 * @param stage Shader stage
12662 * @return Code that verify variables
12664 std::string VertexAttribLocationsTest::getVerificationSnippet(GLuint /* test_case_index */,
12665 Utils::ProgramInterface& /* program_interface */,
12666 Utils::Shader::STAGES stage)
12668 std::string verification;
12670 if (Utils::Shader::VERTEX == stage)
12673 #if DEBUG_VERTEX_ATTRIB_LOCATIONS_TEST_VARIABLE
12675 verification = "if (gl_InstanceID != instance_index)\n"
12679 " else if (gl_VertexID != vertex_index)\n"
12686 verification = "if ((gl_VertexID != vertex_index) ||\n"
12687 " (gl_InstanceID != instance_index) )\n"
12699 return verification;
12702 /** Selects if "compute" stage is relevant for test
12708 bool VertexAttribLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
12713 /** Prepare attributes, vertex array object and array buffer
12716 * @param ignored Interface of program
12717 * @param buffer Array buffer
12718 * @param vao Vertex array object
12720 void VertexAttribLocationsTest::prepareAttributes(GLuint test_case_index /* test_case_index */,
12721 Utils::ProgramInterface& /* program_interface */,
12722 Utils::Buffer& buffer, Utils::VertexArray& vao)
12724 static const GLuint vertex_index_data[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
12725 static const GLuint instance_index_data[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
12727 std::vector<GLuint> buffer_data;
12728 buffer_data.resize(8 + 8); /* vertex_index_data + instance_index_data */
12730 GLubyte* ptr = (GLubyte*)&buffer_data[0];
12733 When case index >=2, the test calls glDrawElement*(), such as glDrawElementsBaseVertex(), glDrawElementsInstanced(), glDrawElementsInstancedBaseInstance() and so on,
12734 So we need to change the buffer type as GL_ELEMENT_ARRAY_BUFFER
12736 if (test_case_index >= 2)
12738 buffer.m_buffer = Utils::Buffer::Element;
12743 vao.Attribute(m_loc_vertex /* vertex_index */, Utils::Type::uint, 0 /* array_elements */, false /* normalized */,
12744 0 /* stride */, 0 /* offset */);
12746 vao.Attribute(m_loc_instance /* instance_index */, Utils::Type::uint, 0 /* array_elements */,
12747 false /* normalized */, 0 /* stride */, (GLvoid*)sizeof(vertex_index_data) /* offset */);
12748 // when test_case_index is 5 or 7, the draw call is glDrawElementsInstancedBaseInstance, glDrawElementsInstancedBaseVertexBaseInstance
12749 // the instancecount is 4, the baseinstance is 2, the divisor should be set 2
12750 bool isBaseInstanced = (test_case_index == DRAWELEMENTSINSTANCEDBASEINSTANCE ||
12751 test_case_index == DRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCE);
12752 vao.Divisor(m_context.getRenderContext().getFunctions() /* gl */, m_loc_instance /* instance_index */,
12753 isBaseInstanced ? 2 : 1 /* divisor. 1 - advance once per instance */);
12755 memcpy(ptr + 0, vertex_index_data, sizeof(vertex_index_data));
12756 memcpy(ptr + sizeof(vertex_index_data), instance_index_data, sizeof(instance_index_data));
12758 buffer.Data(Utils::Buffer::StaticDraw, buffer_data.size() * sizeof(GLuint), ptr);
12761 /** This test should be run with separable programs
12767 bool VertexAttribLocationsTest::useMonolithicProgram(GLuint /* test_case_index */)
12774 * @param context Test framework context
12776 VaryingArrayLocationsTest::VaryingArrayLocationsTest(deqp::Context& context)
12777 : VaryingLocationsTest(context, "varying_array_locations",
12778 "Test verifies that input and output locations are respected for arrays")
12785 void VaryingArrayLocationsTest::prepareShaderStage(Utils::Shader::STAGES stage, const Utils::Type& type,
12786 Utils::ProgramInterface& program_interface,
12787 Utils::VaryingPassthrough& varying_passthrough)
12789 const GLuint array_length = 1u;
12790 const GLuint first_in_loc = 0;
12791 const GLuint first_out_loc = 0;
12792 const GLuint last_in_loc = getLastInputLocation(stage, type, array_length);
12793 size_t position = 0;
12795 const GLchar* prefix_in = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::VARYING_INPUT);
12797 const GLchar* prefix_out = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::VARYING_OUTPUT);
12799 const GLchar* qual_first_in = "layout (location = first_input_location)";
12800 const GLchar* qual_first_out = "layout (location = first_output_location)";
12801 const GLchar* qual_last_in = "layout (location = last_input_location)";
12802 const GLchar* qual_last_out = "layout (location = last_output_location)";
12804 Utils::ShaderInterface& si = program_interface.GetShaderInterface(stage);
12805 const GLuint type_size = type.GetSize();
12807 std::string first_in_name = "PREFIXfirst";
12808 std::string first_out_name = "PREFIXfirst";
12809 std::string last_in_name = "PREFIXlast";
12810 std::string last_out_name = "PREFIXlast";
12812 Utils::replaceToken("PREFIX", position, prefix_in, first_in_name);
12814 Utils::replaceToken("PREFIX", position, prefix_out, first_out_name);
12816 Utils::replaceToken("PREFIX", position, prefix_in, last_in_name);
12818 Utils::replaceToken("PREFIX", position, prefix_out, last_out_name);
12820 if (Utils::Shader::FRAGMENT == stage)
12822 qual_first_in = "layout (location = first_input_location) flat";
12823 qual_last_in = "layout (location = last_input_location) flat";
12825 if (Utils::Shader::GEOMETRY == stage)
12827 qual_first_out = "layout (location = first_output_location) flat";
12828 qual_last_out = "layout (location = last_output_location) flat";
12831 Utils::Variable* first_in =
12832 si.Input(first_in_name.c_str(), qual_first_in /* qualifiers */, 0 /* expected_componenet */,
12833 first_in_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12834 array_length /* n_array_elements */, 0u /* stride */, 0u /* offset */,
12835 (GLvoid*)&m_first_data[0] /* data */, m_first_data.size() /* data_size */);
12837 Utils::Variable* last_in =
12838 si.Input(last_in_name.c_str(), qual_last_in /* qualifiers */, 0 /* expected_componenet */,
12839 last_in_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12840 array_length /* n_array_elements */, 0u /* stride */, type_size /* offset */,
12841 (GLvoid*)&m_last_data[0] /* data */, m_last_data.size() /* data_size */);
12843 if (Utils::Shader::FRAGMENT != stage)
12845 const GLuint last_out_loc = getLastOutputLocation(stage, type, array_length);
12847 Utils::Variable* first_out =
12848 si.Output(first_out_name.c_str(), qual_first_out /* qualifiers */, 0 /* expected_componenet */,
12849 first_out_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12850 array_length /* n_array_elements */, 0u /* stride */, 0u /* offset */,
12851 (GLvoid*)&m_first_data[0] /* data */, m_first_data.size() /* data_size */);
12853 Utils::Variable* last_out =
12854 si.Output(last_out_name.c_str(), qual_last_out /* qualifiers */, 0 /* expected_componenet */,
12855 last_out_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12856 array_length /* n_array_elements */, 0u /* stride */, 0u /* offset */,
12857 (GLvoid*)&m_last_data[0] /* data */, m_last_data.size() /* data_size */);
12859 si.m_globals = prepareGlobals(last_in_loc, last_out_loc);
12861 varying_passthrough.Add(stage, first_in, first_out);
12862 varying_passthrough.Add(stage, last_in, last_out);
12866 /* No outputs for fragment shader, so last_output_location can be 0 */
12867 si.m_globals = prepareGlobals(last_in_loc, 0);
12873 * @param context Test framework context
12875 VaryingStructureLocationsTest::VaryingStructureLocationsTest(deqp::Context& context)
12876 : TextureTestBase(context, "varying_structure_locations",
12877 "Test verifies that locations are respected when structures are used as in and out ")
12881 /** Prepare code snippet that will pass in variables to out variables
12884 * @param varying_passthrough Collection of connections between in and out variables
12885 * @param stage Shader stage
12887 * @return Code that pass in variables to next stage
12889 std::string VaryingStructureLocationsTest::getPassSnippet(GLuint /* test_case_index */,
12890 Utils::VaryingPassthrough& varying_passthrough,
12891 Utils::Shader::STAGES stage)
12893 std::string result;
12895 if (Utils::Shader::VERTEX != stage)
12897 result = TextureTestBase::getPassSnippet(0, varying_passthrough, stage);
12901 result = " vs_tcs_output[0].single = vs_in_single[0];\n"
12902 " vs_tcs_output[0].array[0] = vs_in_array[0];\n";
12908 /** Get interface of program
12910 * @param test_case_index Test case
12911 * @param program_interface Interface of program
12912 * @param varying_passthrough Collection of connections between in and out variables
12914 void VaryingStructureLocationsTest::getProgramInterface(GLuint test_case_index,
12915 Utils::ProgramInterface& program_interface,
12916 Utils::VaryingPassthrough& varying_passthrough)
12918 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
12919 const Utils::Type type = getType(test_case_index);
12922 // We should call GenerateDataPacked() to generate data, which can make sure the data in shader is correct
12923 m_single_data = type.GenerateDataPacked();
12924 m_array_data = type.GenerateDataPacked();
12926 m_data.resize(m_single_data.size() + m_array_data.size());
12927 GLubyte* ptr = (GLubyte*)&m_data[0];
12928 memcpy(ptr, &m_single_data[0], m_single_data.size());
12929 memcpy(ptr + m_single_data.size(), &m_array_data[0], m_array_data.size());
12931 Utils::Interface* structure = program_interface.Structure("Data");
12933 structure->Member("single", "" /* qualifiers */, 0 /* component */, 0 /* location */, type, false /* normalized */,
12934 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */);
12936 // the second struct member 's location should not be 0, it is based on by how many the locations the first struct member consumed.
12937 structure->Member("array", "" /* qualifiers */, 0 /* component */, type.GetLocations() /* location */, type,
12938 false /* normalized */, 1u /* n_array_elements */, 0u /* stride */, type.GetSize() /* offset */);
12940 si.Input("vs_in_single", "layout (location = 0)", 0 /* component */, 0 /* location */, type, false /* normalized */,
12941 1u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)&m_single_data[0] /* data */,
12942 m_single_data.size() /* data_size */);
12944 si.Input("vs_in_array", "layout (location = 8)", 0 /* component */, 8 /* location */, type, false /* normalized */,
12945 1u /* n_array_elements */, 0u /* stride */, type.GetSize() /* offset */,
12946 (GLvoid*)&m_array_data[0] /* data */, m_array_data.size() /* data_size */);
12948 si.Output("vs_tcs_output", "layout (location = 0)", 0 /* component */, 0 /* location */, structure,
12949 1u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)&m_data[0] /* data */,
12950 m_data.size() /* data_size */);
12952 program_interface.CloneVertexInterface(varying_passthrough);
12957 * @param test_case_index Index of test case
12959 * @return Name of type test in test_case_index
12961 std::string VaryingStructureLocationsTest::getTestCaseName(glw::GLuint test_case_index)
12963 return getTypeName(test_case_index);
12966 /** Returns number of types to test
12968 * @return Number of types, 34
12970 glw::GLuint VaryingStructureLocationsTest::getTestCaseNumber()
12972 return getTypesNumber();
12975 /** Selects if "compute" stage is relevant for test
12981 bool VaryingStructureLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
12986 /** This test should be run with separable programs
12992 bool VaryingStructureLocationsTest::useMonolithicProgram(GLuint /* test_case_index */)
12999 * @param context Test context
13000 * @param test_name Name of test
13001 * @param test_description Description of test
13003 VaryingStructureMemberLocationTest::VaryingStructureMemberLocationTest(deqp::Context& context)
13004 : NegativeTestBase(context, "varying_structure_member_location",
13005 "Test verifies that compiler does not allow location qualifier on member of strucure")
13009 /** Source for given test case and stage
13011 * @param test_case_index Index of test case
13012 * @param stage Shader stage
13014 * @return Shader source
13016 std::string VaryingStructureMemberLocationTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
13018 static const GLchar* struct_definition = "struct Data {\n"
13020 " layout (location = 4) vec4 goten;\n"
13022 static const GLchar* input_var = "in Data data;\n";
13023 static const GLchar* output_var = "out Data data;\n";
13024 static const GLchar* input_use = " result += data.gohan + data.goten;\n";
13025 static const GLchar* output_use = " data.gohan = result / 2;\n"
13026 " data.goten = result / 4 - data.gohan;\n";
13027 static const GLchar* fs = "#version 430 core\n"
13028 "#extension GL_ARB_enhanced_layouts : require\n"
13031 "out vec4 fs_out;\n"
13035 " fs_out = gs_fs;\n"
13038 static const GLchar* fs_tested = "#version 430 core\n"
13039 "#extension GL_ARB_enhanced_layouts : require\n"
13041 "STRUCT_DEFINITION"
13043 "VARIABLE_DEFINITION"
13046 "out vec4 fs_out;\n"
13050 " vec4 result = gs_fs;\n"
13054 " fs_out += result;\n"
13057 static const GLchar* gs = "#version 430 core\n"
13058 "#extension GL_ARB_enhanced_layouts : require\n"
13060 "layout(points) in;\n"
13061 "layout(triangle_strip, max_vertices = 4) out;\n"
13063 "in vec4 tes_gs[];\n"
13064 "out vec4 gs_fs;\n"
13068 " gs_fs = tes_gs[0];\n"
13069 " gl_Position = vec4(-1, -1, 0, 1);\n"
13071 " gs_fs = tes_gs[0];\n"
13072 " gl_Position = vec4(-1, 1, 0, 1);\n"
13074 " gs_fs = tes_gs[0];\n"
13075 " gl_Position = vec4(1, -1, 0, 1);\n"
13077 " gs_fs = tes_gs[0];\n"
13078 " gl_Position = vec4(1, 1, 0, 1);\n"
13082 static const GLchar* gs_tested = "#version 430 core\n"
13083 "#extension GL_ARB_enhanced_layouts : require\n"
13085 "layout(points) in;\n"
13086 "layout(triangle_strip, max_vertices = 4) out;\n"
13088 "STRUCT_DEFINITION"
13090 "VARIABLE_DEFINITION"
13092 "in vec4 tes_gs[];\n"
13093 "out vec4 gs_fs;\n"
13097 " vec4 result = tes_gs[0];\n"
13101 " gs_fs = result;\n"
13102 " gl_Position = vec4(-1, -1, 0, 1);\n"
13104 " gs_fs = result;\n"
13105 " gl_Position = vec4(-1, 1, 0, 1);\n"
13107 " gs_fs = result;\n"
13108 " gl_Position = vec4(1, -1, 0, 1);\n"
13110 " gs_fs = result;\n"
13111 " gl_Position = vec4(1, 1, 0, 1);\n"
13115 static const GLchar* tcs = "#version 430 core\n"
13116 "#extension GL_ARB_enhanced_layouts : require\n"
13118 "layout(vertices = 1) out;\n"
13120 "in vec4 vs_tcs[];\n"
13121 "out vec4 tcs_tes[];\n"
13126 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
13128 " gl_TessLevelOuter[0] = 1.0;\n"
13129 " gl_TessLevelOuter[1] = 1.0;\n"
13130 " gl_TessLevelOuter[2] = 1.0;\n"
13131 " gl_TessLevelOuter[3] = 1.0;\n"
13132 " gl_TessLevelInner[0] = 1.0;\n"
13133 " gl_TessLevelInner[1] = 1.0;\n"
13136 static const GLchar* tcs_tested = "#version 430 core\n"
13137 "#extension GL_ARB_enhanced_layouts : require\n"
13139 "layout(vertices = 1) out;\n"
13141 "STRUCT_DEFINITION"
13143 "VARIABLE_DEFINITION"
13145 "in vec4 vs_tcs[];\n"
13146 "out vec4 tcs_tes[];\n"
13150 " vec4 result = vs_tcs[gl_InvocationID];\n"
13154 " tcs_tes[gl_InvocationID] = result;\n"
13156 " gl_TessLevelOuter[0] = 1.0;\n"
13157 " gl_TessLevelOuter[1] = 1.0;\n"
13158 " gl_TessLevelOuter[2] = 1.0;\n"
13159 " gl_TessLevelOuter[3] = 1.0;\n"
13160 " gl_TessLevelInner[0] = 1.0;\n"
13161 " gl_TessLevelInner[1] = 1.0;\n"
13164 static const GLchar* tes = "#version 430 core\n"
13165 "#extension GL_ARB_enhanced_layouts : require\n"
13167 "layout(isolines, point_mode) in;\n"
13169 "in vec4 tcs_tes[];\n"
13170 "out vec4 tes_gs;\n"
13174 " tes_gs = tcs_tes[0];\n"
13177 static const GLchar* tes_tested = "#version 430 core\n"
13178 "#extension GL_ARB_enhanced_layouts : require\n"
13180 "layout(isolines, point_mode) in;\n"
13182 "STRUCT_DEFINITION"
13184 "VARIABLE_DEFINITION"
13186 "in vec4 tcs_tes[];\n"
13187 "out vec4 tes_gs;\n"
13191 " vec4 result = tcs_tes[0];\n"
13195 " tes_gs += result;\n"
13198 static const GLchar* vs = "#version 430 core\n"
13199 "#extension GL_ARB_enhanced_layouts : require\n"
13202 "out vec4 vs_tcs;\n"
13206 " vs_tcs = in_vs;\n"
13209 static const GLchar* vs_tested = "#version 430 core\n"
13210 "#extension GL_ARB_enhanced_layouts : require\n"
13212 "STRUCT_DEFINITION"
13214 "VARIABLE_DEFINITION"
13217 "out vec4 vs_tcs;\n"
13221 " vec4 result = in_vs;\n"
13225 " vs_tcs += result;\n"
13229 std::string source;
13230 testCase& test_case = m_test_cases[test_case_index];
13231 const GLchar* var_definition = 0;
13232 const GLchar* var_use = 0;
13234 if (true == test_case.m_is_input)
13236 var_definition = input_var;
13237 var_use = input_use;
13241 var_definition = output_var;
13242 var_use = output_use;
13245 if (test_case.m_stage == stage)
13247 size_t position = 0;
13251 case Utils::Shader::FRAGMENT:
13252 source = fs_tested;
13254 case Utils::Shader::GEOMETRY:
13255 source = gs_tested;
13257 case Utils::Shader::TESS_CTRL:
13258 source = tcs_tested;
13260 case Utils::Shader::TESS_EVAL:
13261 source = tes_tested;
13263 case Utils::Shader::VERTEX:
13264 source = vs_tested;
13267 TCU_FAIL("Invalid enum");
13270 Utils::replaceToken("STRUCT_DEFINITION", position, struct_definition, source);
13271 Utils::replaceToken("VARIABLE_DEFINITION", position, var_definition, source);
13272 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
13278 case Utils::Shader::FRAGMENT:
13281 case Utils::Shader::GEOMETRY:
13284 case Utils::Shader::TESS_CTRL:
13287 case Utils::Shader::TESS_EVAL:
13290 case Utils::Shader::VERTEX:
13294 TCU_FAIL("Invalid enum");
13301 /** Get description of test case
13303 * @param test_case_index Index of test case
13305 * @return Test case description
13307 std::string VaryingStructureMemberLocationTest::getTestCaseName(GLuint test_case_index)
13309 std::stringstream stream;
13310 testCase& test_case = m_test_cases[test_case_index];
13312 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", direction: ";
13314 if (true == test_case.m_is_input)
13320 stream << "output";
13323 return stream.str();
13326 /** Get number of test cases
13328 * @return Number of test cases
13330 GLuint VaryingStructureMemberLocationTest::getTestCaseNumber()
13332 return static_cast<GLuint>(m_test_cases.size());
13335 /** Selects if "compute" stage is relevant for test
13341 bool VaryingStructureMemberLocationTest::isComputeRelevant(GLuint /* test_case_index */)
13346 /** Prepare all test cases
13349 void VaryingStructureMemberLocationTest::testInit()
13351 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
13353 if (Utils::Shader::COMPUTE == stage)
13358 testCase test_case_in = { true, (Utils::Shader::STAGES)stage };
13359 testCase test_case_out = { false, (Utils::Shader::STAGES)stage };
13361 m_test_cases.push_back(test_case_in);
13363 if (Utils::Shader::FRAGMENT != stage)
13365 m_test_cases.push_back(test_case_out);
13372 * @param context Test framework context
13374 VaryingBlockLocationsTest::VaryingBlockLocationsTest(deqp::Context& context)
13375 : TextureTestBase(context, "varying_block_locations",
13376 "Test verifies that locations are respected when blocks are used as in and out ")
13380 /** Prepare code snippet that will pass in variables to out variables
13383 * @param varying_passthrough Collection of connections between in and out variables
13384 * @param stage Shader stage
13386 * @return Code that pass in variables to next stage
13388 std::string VaryingBlockLocationsTest::getPassSnippet(GLuint /* test_case_index */,
13389 Utils::VaryingPassthrough& varying_passthrough,
13390 Utils::Shader::STAGES stage)
13392 std::string result;
13394 if (Utils::Shader::VERTEX != stage)
13396 result = TextureTestBase::getPassSnippet(0, varying_passthrough, stage);
13400 result = "vs_tcs_block.third = vs_in_third;\n"
13401 " vs_tcs_block.fourth = vs_in_fourth;\n"
13402 " vs_tcs_block.fifth = vs_in_fifth;\n";
13408 /** Get interface of program
13411 * @param program_interface Interface of program
13412 * @param varying_passthrough Collection of connections between in and out variables
13414 void VaryingBlockLocationsTest::getProgramInterface(GLuint /* test_case_index */,
13415 Utils::ProgramInterface& program_interface,
13416 Utils::VaryingPassthrough& varying_passthrough)
13418 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
13419 const Utils::Type vec4 = Utils::Type::vec4;
13422 m_third_data = vec4.GenerateData();
13423 m_fourth_data = vec4.GenerateData();
13424 m_fifth_data = vec4.GenerateData();
13426 /* Memory layout is different from location layout */
13427 const GLuint fifth_offset = 0u;
13428 const GLuint third_offset = static_cast<GLuint>(fifth_offset + m_fifth_data.size());
13429 const GLuint fourth_offset = static_cast<GLuint>(third_offset + m_fourth_data.size());
13431 m_data.resize(fourth_offset + m_fourth_data.size());
13432 GLubyte* ptr = (GLubyte*)&m_data[0];
13433 memcpy(ptr + third_offset, &m_third_data[0], m_third_data.size());
13434 memcpy(ptr + fourth_offset, &m_fourth_data[0], m_fourth_data.size());
13435 memcpy(ptr + fifth_offset, &m_fifth_data[0], m_fifth_data.size());
13437 Utils::Interface* block = program_interface.Block("vs_tcs_Block");
13439 block->Member("fifth", "" /* qualifiers */, 0 /* component */, 4 /* location */, vec4, false /* normalized */,
13440 0u /* n_array_elements */, 0u /* stride */, fifth_offset /* offset */);
13442 block->Member("third", "layout (location = 2)" /* qualifiers */, 0 /* component */, 2 /* location */, vec4,
13443 false /* normalized */, 0u /* n_array_elements */, 0u /* stride */, third_offset /* offset */);
13445 block->Member("fourth", "" /* qualifiers */, 0 /* component */, 3 /* location */, vec4, false /* normalized */,
13446 0u /* n_array_elements */, 0u /* stride */, fourth_offset /* offset */);
13448 si.Output("vs_tcs_block", "layout (location = 4)", 0 /* component */, 4 /* location */, block,
13449 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)&m_data[0] /* data */,
13450 m_data.size() /* data_size */);
13452 si.Input("vs_in_third", "layout (location = 0)", 0 /* component */, 0 /* location */, vec4, false /* normalized */,
13453 0u /* n_array_elements */, 0u /* stride */, third_offset /* offset */,
13454 (GLvoid*)&m_third_data[0] /* data */, m_third_data.size() /* data_size */);
13456 si.Input("vs_in_fourth", "layout (location = 1)", 0 /* component */, 1 /* location */, vec4, false /* normalized */,
13457 0u /* n_array_elements */, 0u /* stride */, fourth_offset /* offset */,
13458 (GLvoid*)&m_fourth_data[0] /* data */, m_fourth_data.size() /* data_size */);
13460 si.Input("vs_in_fifth", "layout (location = 2)", 0 /* component */, 2 /* location */, vec4, false /* normalized */,
13461 0u /* n_array_elements */, 0u /* stride */, fifth_offset /* offset */,
13462 (GLvoid*)&m_fifth_data[0] /* data */, m_fifth_data.size() /* data_size */);
13464 program_interface.CloneVertexInterface(varying_passthrough);
13467 /** Selects if "compute" stage is relevant for test
13473 bool VaryingBlockLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
13478 /** This test should be run with separable programs
13484 bool VaryingBlockLocationsTest::useMonolithicProgram(GLuint /* test_case_index */)
13491 * @param context Test framework context
13493 VaryingBlockMemberLocationsTest::VaryingBlockMemberLocationsTest(deqp::Context& context)
13494 : NegativeTestBase(
13495 context, "varying_block_member_locations",
13496 "Test verifies that compilation error is reported when not all members of block are qualified with location")
13500 /** Source for given test case and stage
13502 * @param test_case_index Index of test case
13503 * @param stage Shader stage
13505 * @return Shader source
13507 std::string VaryingBlockMemberLocationsTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
13509 static const GLchar* block_definition_all = "Goku {\n"
13510 " layout (location = 2) vec4 gohan;\n"
13511 " layout (location = 4) vec4 goten;\n"
13512 " layout (location = 6) vec4 chichi;\n"
13514 static const GLchar* block_definition_default = "Goku {\n"
13519 static const GLchar* block_definition_one = "Goku {\n"
13521 " layout (location = 4) vec4 goten;\n"
13524 static const GLchar* input_use = " result += gokuINDEX.gohan + gokuINDEX.goten + gokuINDEX.chichi;\n";
13525 static const GLchar* output_use = " gokuINDEX.gohan = result / 2;\n"
13526 " gokuINDEX.goten = result / 4 - gokuINDEX.gohan;\n"
13527 " gokuINDEX.chichi = result / 8 - gokuINDEX.goten;\n";
13528 static const GLchar* fs = "#version 430 core\n"
13529 "#extension GL_ARB_enhanced_layouts : require\n"
13532 "out vec4 fs_out;\n"
13536 " fs_out = gs_fs;\n"
13539 static const GLchar* fs_tested = "#version 430 core\n"
13540 "#extension GL_ARB_enhanced_layouts : require\n"
13542 "DIRECTION BLOCK_DEFINITION"
13545 "out vec4 fs_out;\n"
13549 " vec4 result = gs_fs;\n"
13553 " fs_out = result;\n"
13556 static const GLchar* gs = "#version 430 core\n"
13557 "#extension GL_ARB_enhanced_layouts : require\n"
13559 "layout(points) in;\n"
13560 "layout(triangle_strip, max_vertices = 4) out;\n"
13562 "in vec4 tes_gs[];\n"
13563 "out vec4 gs_fs;\n"
13567 " gs_fs = tes_gs[0];\n"
13568 " gl_Position = vec4(-1, -1, 0, 1);\n"
13570 " gs_fs = tes_gs[0];\n"
13571 " gl_Position = vec4(-1, 1, 0, 1);\n"
13573 " gs_fs = tes_gs[0];\n"
13574 " gl_Position = vec4(1, -1, 0, 1);\n"
13576 " gs_fs = tes_gs[0];\n"
13577 " gl_Position = vec4(1, 1, 0, 1);\n"
13581 static const GLchar* gs_tested = "#version 430 core\n"
13582 "#extension GL_ARB_enhanced_layouts : require\n"
13584 "layout(points) in;\n"
13585 "layout(triangle_strip, max_vertices = 4) out;\n"
13587 "DIRECTION BLOCK_DEFINITION"
13589 "in vec4 tes_gs[];\n"
13590 "out vec4 gs_fs;\n"
13594 " vec4 result = tes_gs[0];\n"
13598 " gs_fs = result;\n"
13599 " gl_Position = vec4(-1, -1, 0, 1);\n"
13601 " gs_fs = result;\n"
13602 " gl_Position = vec4(-1, 1, 0, 1);\n"
13604 " gs_fs = result;\n"
13605 " gl_Position = vec4(1, -1, 0, 1);\n"
13607 " gs_fs = result;\n"
13608 " gl_Position = vec4(1, 1, 0, 1);\n"
13612 static const GLchar* tcs = "#version 430 core\n"
13613 "#extension GL_ARB_enhanced_layouts : require\n"
13615 "layout(vertices = 1) out;\n"
13617 "in vec4 vs_tcs[];\n"
13618 "out vec4 tcs_tes[];\n"
13623 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
13625 " gl_TessLevelOuter[0] = 1.0;\n"
13626 " gl_TessLevelOuter[1] = 1.0;\n"
13627 " gl_TessLevelOuter[2] = 1.0;\n"
13628 " gl_TessLevelOuter[3] = 1.0;\n"
13629 " gl_TessLevelInner[0] = 1.0;\n"
13630 " gl_TessLevelInner[1] = 1.0;\n"
13633 static const GLchar* tcs_tested = "#version 430 core\n"
13634 "#extension GL_ARB_enhanced_layouts : require\n"
13636 "layout(vertices = 1) out;\n"
13638 "DIRECTION BLOCK_DEFINITION"
13640 "in vec4 vs_tcs[];\n"
13641 "out vec4 tcs_tes[];\n"
13645 " vec4 result = vs_tcs[gl_InvocationID];\n"
13649 " tcs_tes[gl_InvocationID] = result;\n"
13651 " gl_TessLevelOuter[0] = 1.0;\n"
13652 " gl_TessLevelOuter[1] = 1.0;\n"
13653 " gl_TessLevelOuter[2] = 1.0;\n"
13654 " gl_TessLevelOuter[3] = 1.0;\n"
13655 " gl_TessLevelInner[0] = 1.0;\n"
13656 " gl_TessLevelInner[1] = 1.0;\n"
13659 static const GLchar* tes = "#version 430 core\n"
13660 "#extension GL_ARB_enhanced_layouts : require\n"
13662 "layout(isolines, point_mode) in;\n"
13664 "in vec4 tcs_tes[];\n"
13665 "out vec4 tes_gs;\n"
13669 " tes_gs = tcs_tes[0];\n"
13672 static const GLchar* tes_tested = "#version 430 core\n"
13673 "#extension GL_ARB_enhanced_layouts : require\n"
13675 "layout(isolines, point_mode) in;\n"
13677 "DIRECTION BLOCK_DEFINITION"
13679 "in vec4 tcs_tes[];\n"
13680 "out vec4 tes_gs;\n"
13684 " vec4 result = tcs_tes[0];\n"
13688 " tes_gs = result;\n"
13691 static const GLchar* vs = "#version 430 core\n"
13692 "#extension GL_ARB_enhanced_layouts : require\n"
13695 "out vec4 vs_tcs;\n"
13699 " vs_tcs = in_vs;\n"
13702 static const GLchar* vs_tested = "#version 430 core\n"
13703 "#extension GL_ARB_enhanced_layouts : require\n"
13705 "DIRECTION BLOCK_DEFINITION"
13708 "out vec4 vs_tcs;\n"
13712 " vec4 result = in_vs;\n"
13716 " vs_tcs = result;\n"
13720 static const GLchar* shaders_in[6][6] = { /* cs */ { 0, 0, 0, 0, 0, 0 },
13721 /* vs */ { 0, vs_tested, tcs, tes, gs, fs },
13722 /* tcs */ { 0, vs_tested, tcs_tested, tes, gs, fs },
13723 /* tes */ { 0, vs, tcs_tested, tes_tested, gs, fs },
13724 /* gs */ { 0, vs, tcs, tes_tested, gs_tested, fs },
13725 /* fs */ { 0, vs, tcs, tes, gs_tested, fs_tested } };
13727 static const GLchar* shaders_out[6][6] = { /* cs */ { 0, 0, 0, 0, 0, 0 },
13728 /* vs */ { 0, vs_tested, tcs_tested, tes, gs, fs },
13729 /* tcs */ { 0, vs, tcs_tested, tes_tested, gs, fs },
13730 /* tes */ { 0, vs, tcs, tes_tested, gs_tested, fs },
13731 /* gs */ { 0, vs, tcs, tes, gs_tested, fs_tested },
13732 /* fs */ { 0, 0, 0, 0, 0, 0 } };
13734 static const bool require_modifications_in[6][6] = {
13735 /* cs */ { false, false, false, false, false, false },
13736 /* vs */ { false, true, false, false, false, false },
13737 /* tcs */ { false, true, true, false, false, false },
13738 /* tes */ { false, false, true, true, false, false },
13739 /* gs */ { false, false, false, true, true, false },
13740 /* fs */ { false, false, false, false, true, true }
13743 static const bool require_modifications_out[6][6] = {
13744 /* cs */ { false, false, false, false, false, false },
13745 /* vs */ { false, true, true, false, false, false },
13746 /* tcs */ { false, false, true, true, false, false },
13747 /* tes */ { false, false, false, true, true, false },
13748 /* gs */ { false, false, false, false, true, true },
13749 /* fs */ { false, false, false, false, false, false }
13752 const GLchar* array = "";
13753 const GLchar* direction = "out";
13754 const GLchar* index = "";
13755 bool require_modifications = false;
13756 std::string source;
13757 testCase& test_case = m_test_cases[test_case_index];
13758 const GLchar* var_use = output_use;
13760 if (true == test_case.m_is_input)
13762 require_modifications = require_modifications_in[test_case.m_stage][stage];
13763 source = shaders_in[test_case.m_stage][stage];
13765 if (test_case.m_stage == stage)
13768 var_use = input_use;
13773 require_modifications = require_modifications_out[test_case.m_stage][stage];
13774 source = shaders_out[test_case.m_stage][stage];
13776 if (test_case.m_stage != stage)
13779 var_use = input_use;
13783 const GLchar* definition = test_case.m_qualify_all ? block_definition_all
13784 : block_definition_default;
13786 if (test_case.m_stage == stage)
13788 if (true == test_case.m_qualify_all)
13790 definition = block_definition_all;
13794 definition = block_definition_one;
13798 // Geometry shader inputs, tessellation control shader inputs and outputs, and tessellation evaluation
13799 // inputs all have an additional level of arrayness relative to other shader inputs and outputs.
13802 case Utils::Shader::FRAGMENT:
13804 case Utils::Shader::TESS_CTRL:
13806 index = "[gl_InvocationID]";
13808 // geometry shader's input must have one more dimension than tessellation evaluation shader's output,
13809 // the GS input block is an array, so the DS output can't be declared as an array
13810 case Utils::Shader::GEOMETRY:
13811 case Utils::Shader::TESS_EVAL:
13813 if (std::string(direction) == std::string("in")) // match HS output and DS input
13818 else // match DS output and GS input
13825 case Utils::Shader::VERTEX:
13828 TCU_FAIL("Invalid enum");
13831 if (true == require_modifications)
13833 size_t position = 0;
13836 Utils::replaceToken("DIRECTION", position, direction, source);
13838 Utils::replaceToken("BLOCK_DEFINITION", position, definition, source);
13840 Utils::replaceToken("ARRAY", position, array, source);
13841 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
13843 Utils::replaceAllTokens("INDEX", index, source);
13849 case Utils::Shader::FRAGMENT:
13852 case Utils::Shader::GEOMETRY:
13855 case Utils::Shader::TESS_CTRL:
13858 case Utils::Shader::TESS_EVAL:
13861 case Utils::Shader::VERTEX:
13865 TCU_FAIL("Invalid enum");
13872 /** Get description of test case
13874 * @param test_case_index Index of test case
13876 * @return Test case description
13878 std::string VaryingBlockMemberLocationsTest::getTestCaseName(GLuint test_case_index)
13880 std::stringstream stream;
13881 testCase& test_case = m_test_cases[test_case_index];
13883 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", direction: ";
13885 if (true == test_case.m_is_input)
13891 stream << "output";
13894 if (true == test_case.m_qualify_all)
13896 stream << ", all members qualified";
13900 stream << ", not all members qualified";
13903 return stream.str();
13906 /** Get number of test cases
13908 * @return Number of test cases
13910 GLuint VaryingBlockMemberLocationsTest::getTestCaseNumber()
13912 return static_cast<GLuint>(m_test_cases.size());
13915 /** Selects if "compute" stage is relevant for test
13921 bool VaryingBlockMemberLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
13926 /** Selects if compilation failure is expected result
13928 * @param test_case_index Index of test case
13930 * @return false when all members are qualified, true otherwise
13932 bool VaryingBlockMemberLocationsTest::isFailureExpected(GLuint test_case_index)
13934 return (true != m_test_cases[test_case_index].m_qualify_all);
13937 /** Prepare all test cases
13940 void VaryingBlockMemberLocationsTest::testInit()
13942 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
13944 if (Utils::Shader::COMPUTE == stage)
13949 testCase test_case_in_all = { true, true, (Utils::Shader::STAGES)stage };
13950 testCase test_case_in_one = { true, false, (Utils::Shader::STAGES)stage };
13951 testCase test_case_out_all = { false, true, (Utils::Shader::STAGES)stage };
13952 testCase test_case_out_one = { false, false, (Utils::Shader::STAGES)stage };
13954 if (Utils::Shader::VERTEX != stage)
13956 m_test_cases.push_back(test_case_in_all);
13957 m_test_cases.push_back(test_case_in_one);
13960 if (Utils::Shader::FRAGMENT != stage)
13962 m_test_cases.push_back(test_case_out_all);
13963 m_test_cases.push_back(test_case_out_one);
13970 * @param context Test framework context
13972 VaryingBlockAutomaticMemberLocationsTest::VaryingBlockAutomaticMemberLocationsTest(deqp::Context& context)
13973 : NegativeTestBase(
13974 context, "varying_block_automatic_member_locations",
13975 "Test verifies that compiler assigns subsequent locations to block members, even if this causes errors")
13979 /** Source for given test case and stage
13981 * @param test_case_index Index of test case
13982 * @param stage Shader stage
13984 * @return Shader source
13986 std::string VaryingBlockAutomaticMemberLocationsTest::getShaderSource(GLuint test_case_index,
13987 Utils::Shader::STAGES stage)
13989 static const GLchar* block_definition = "layout (location = 2) DIRECTION DBZ {\n"
13991 " vec4 gohan[4];\n"
13993 " layout (location = 1) vec4 chichi;\n"
13996 static const GLchar* input_use = " result += dbzINDEX.goku + dbzINDEX.gohan[0] + dbzINDEX.gohan[1] + "
13997 "dbzINDEX.gohan[3] + dbzINDEX.gohan[2] + dbzINDEX.goten + dbzINDEX.chichi + "
13999 static const GLchar* output_use = " dbzINDEX.goku = result;\n"
14000 " dbzINDEX.gohan[0] = result / 2;\n"
14001 " dbzINDEX.gohan[1] = result / 2.25;\n"
14002 " dbzINDEX.gohan[2] = result / 2.5;\n"
14003 " dbzINDEX.gohan[3] = result / 2.75;\n"
14004 " dbzINDEX.goten = result / 4 - dbzINDEX.gohan[0] - dbzINDEX.gohan[1] - "
14005 "dbzINDEX.gohan[2] - dbzINDEX.gohan[3];\n"
14006 " dbzINDEX.chichi = result / 8 - dbzINDEX.goten;\n"
14007 " dbzINDEX.pan = result / 16 - dbzINDEX.chichi;\n";
14008 static const GLchar* fs = "#version 430 core\n"
14009 "#extension GL_ARB_enhanced_layouts : require\n"
14012 "out vec4 fs_out;\n"
14016 " fs_out = gs_fs;\n"
14019 static const GLchar* fs_tested = "#version 430 core\n"
14020 "#extension GL_ARB_enhanced_layouts : require\n"
14025 "out vec4 fs_out;\n"
14029 " vec4 result = gs_fs;\n"
14033 " fs_out += result;\n"
14036 static const GLchar* gs = "#version 430 core\n"
14037 "#extension GL_ARB_enhanced_layouts : require\n"
14039 "layout(points) in;\n"
14040 "layout(triangle_strip, max_vertices = 4) out;\n"
14042 "in vec4 tes_gs[];\n"
14043 "out vec4 gs_fs;\n"
14047 " gs_fs = tes_gs[0];\n"
14048 " gl_Position = vec4(-1, -1, 0, 1);\n"
14050 " gs_fs = tes_gs[0];\n"
14051 " gl_Position = vec4(-1, 1, 0, 1);\n"
14053 " gs_fs = tes_gs[0];\n"
14054 " gl_Position = vec4(1, -1, 0, 1);\n"
14056 " gs_fs = tes_gs[0];\n"
14057 " gl_Position = vec4(1, 1, 0, 1);\n"
14061 static const GLchar* gs_tested = "#version 430 core\n"
14062 "#extension GL_ARB_enhanced_layouts : require\n"
14064 "layout(points) in;\n"
14065 "layout(triangle_strip, max_vertices = 4) out;\n"
14069 "in vec4 tes_gs[];\n"
14070 "out vec4 gs_fs;\n"
14074 " vec4 result = tes_gs[0];\n"
14078 " gs_fs = result;\n"
14079 " gl_Position = vec4(-1, -1, 0, 1);\n"
14081 " gs_fs = result;\n"
14082 " gl_Position = vec4(-1, 1, 0, 1);\n"
14084 " gs_fs = result;\n"
14085 " gl_Position = vec4(1, -1, 0, 1);\n"
14087 " gs_fs = result;\n"
14088 " gl_Position = vec4(1, 1, 0, 1);\n"
14092 static const GLchar* tcs = "#version 430 core\n"
14093 "#extension GL_ARB_enhanced_layouts : require\n"
14095 "layout(vertices = 1) out;\n"
14097 "in vec4 vs_tcs[];\n"
14098 "out vec4 tcs_tes[];\n"
14103 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
14105 " gl_TessLevelOuter[0] = 1.0;\n"
14106 " gl_TessLevelOuter[1] = 1.0;\n"
14107 " gl_TessLevelOuter[2] = 1.0;\n"
14108 " gl_TessLevelOuter[3] = 1.0;\n"
14109 " gl_TessLevelInner[0] = 1.0;\n"
14110 " gl_TessLevelInner[1] = 1.0;\n"
14113 static const GLchar* tcs_tested = "#version 430 core\n"
14114 "#extension GL_ARB_enhanced_layouts : require\n"
14116 "layout(vertices = 1) out;\n"
14120 "in vec4 vs_tcs[];\n"
14121 "out vec4 tcs_tes[];\n"
14125 " vec4 result = vs_tcs[gl_InvocationID];\n"
14129 " tcs_tes[gl_InvocationID] = result;\n"
14131 " gl_TessLevelOuter[0] = 1.0;\n"
14132 " gl_TessLevelOuter[1] = 1.0;\n"
14133 " gl_TessLevelOuter[2] = 1.0;\n"
14134 " gl_TessLevelOuter[3] = 1.0;\n"
14135 " gl_TessLevelInner[0] = 1.0;\n"
14136 " gl_TessLevelInner[1] = 1.0;\n"
14139 static const GLchar* tes = "#version 430 core\n"
14140 "#extension GL_ARB_enhanced_layouts : require\n"
14142 "layout(isolines, point_mode) in;\n"
14144 "in vec4 tcs_tes[];\n"
14145 "out vec4 tes_gs;\n"
14149 " tes_gs = tcs_tes[0];\n"
14152 static const GLchar* tes_tested = "#version 430 core\n"
14153 "#extension GL_ARB_enhanced_layouts : require\n"
14155 "layout(isolines, point_mode) in;\n"
14159 "in vec4 tcs_tes[];\n"
14160 "out vec4 tes_gs;\n"
14164 " vec4 result = tcs_tes[0];\n"
14168 " tes_gs += result;\n"
14171 static const GLchar* vs = "#version 430 core\n"
14172 "#extension GL_ARB_enhanced_layouts : require\n"
14175 "out vec4 vs_tcs;\n"
14179 " vs_tcs = in_vs;\n"
14182 static const GLchar* vs_tested = "#version 430 core\n"
14183 "#extension GL_ARB_enhanced_layouts : require\n"
14188 "out vec4 vs_tcs;\n"
14192 " vec4 result = in_vs;\n"
14196 " vs_tcs += result;\n"
14200 const GLchar* array = "";
14201 const GLchar* direction = "out";
14202 const GLchar* index = "";
14203 std::string source;
14204 testCase& test_case = m_test_cases[test_case_index];
14205 const GLchar* var_use = output_use;
14207 if (true == test_case.m_is_input)
14210 var_use = input_use;
14213 if (test_case.m_stage == stage)
14215 size_t position = 0;
14220 case Utils::Shader::FRAGMENT:
14221 source = fs_tested;
14223 case Utils::Shader::GEOMETRY:
14224 source = gs_tested;
14228 case Utils::Shader::TESS_CTRL:
14229 source = tcs_tested;
14231 index = "[gl_InvocationID]";
14233 case Utils::Shader::TESS_EVAL:
14234 source = tes_tested;
14238 case Utils::Shader::VERTEX:
14239 source = vs_tested;
14242 TCU_FAIL("Invalid enum");
14246 Utils::replaceToken("BLOCK_DEFINITION", position, block_definition, source);
14248 Utils::replaceToken("DIRECTION", position, direction, source);
14249 Utils::replaceToken("ARRAY", position, array, source);
14250 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
14252 Utils::replaceAllTokens("INDEX", index, source);
14258 case Utils::Shader::FRAGMENT:
14261 case Utils::Shader::GEOMETRY:
14264 case Utils::Shader::TESS_CTRL:
14267 case Utils::Shader::TESS_EVAL:
14270 case Utils::Shader::VERTEX:
14274 TCU_FAIL("Invalid enum");
14281 /** Get description of test case
14283 * @param test_case_index Index of test case
14285 * @return Test case description
14287 std::string VaryingBlockAutomaticMemberLocationsTest::getTestCaseName(GLuint test_case_index)
14289 std::stringstream stream;
14290 testCase& test_case = m_test_cases[test_case_index];
14292 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", direction: ";
14294 if (true == test_case.m_is_input)
14300 stream << "output";
14303 return stream.str();
14306 /** Get number of test cases
14308 * @return Number of test cases
14310 GLuint VaryingBlockAutomaticMemberLocationsTest::getTestCaseNumber()
14312 return static_cast<GLuint>(m_test_cases.size());
14315 /** Selects if "compute" stage is relevant for test
14321 bool VaryingBlockAutomaticMemberLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
14326 /** Prepare all test cases
14329 void VaryingBlockAutomaticMemberLocationsTest::testInit()
14331 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
14333 if (Utils::Shader::COMPUTE == stage)
14338 testCase test_case_in = { true, (Utils::Shader::STAGES)stage };
14339 testCase test_case_out = { false, (Utils::Shader::STAGES)stage };
14341 if (Utils::Shader::VERTEX != stage)
14343 m_test_cases.push_back(test_case_in);
14346 if (Utils::Shader::FRAGMENT != stage)
14348 m_test_cases.push_back(test_case_out);
14355 * @param context Test framework context
14357 VaryingLocationLimitTest::VaryingLocationLimitTest(deqp::Context& context)
14358 : NegativeTestBase(context, "varying_location_limit",
14359 "Test verifies that compiler reports error when location qualifier exceed limits")
14363 /** Source for given test case and stage
14365 * @param test_case_index Index of test case
14366 * @param stage Shader stage
14368 * @return Shader source
14370 std::string VaryingLocationLimitTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
14372 static const GLchar* var_definition = "layout (location = LAST + 1) FLAT DIRECTION TYPE gokuARRAY;\n";
14373 static const GLchar* input_use = " if (TYPE(0) == gokuINDEX)\n"
14375 " result += vec4(1, 0.5, 0.25, 0.125);\n"
14377 static const GLchar* output_use = " gokuINDEX = TYPE(0);\n"
14378 " if (vec4(0) == result)\n"
14380 " gokuINDEX = TYPE(1);\n"
14382 static const GLchar* fs = "#version 430 core\n"
14383 "#extension GL_ARB_enhanced_layouts : require\n"
14386 "out vec4 fs_out;\n"
14390 " fs_out = gs_fs;\n"
14393 static const GLchar* fs_tested = "#version 430 core\n"
14394 "#extension GL_ARB_enhanced_layouts : require\n"
14399 "out vec4 fs_out;\n"
14403 " vec4 result = gs_fs;\n"
14407 " fs_out += result;\n"
14410 static const GLchar* gs = "#version 430 core\n"
14411 "#extension GL_ARB_enhanced_layouts : require\n"
14413 "layout(points) in;\n"
14414 "layout(triangle_strip, max_vertices = 4) out;\n"
14416 "in vec4 tes_gs[];\n"
14417 "out vec4 gs_fs;\n"
14421 " gs_fs = tes_gs[0];\n"
14422 " gl_Position = vec4(-1, -1, 0, 1);\n"
14424 " gs_fs = tes_gs[0];\n"
14425 " gl_Position = vec4(-1, 1, 0, 1);\n"
14427 " gs_fs = tes_gs[0];\n"
14428 " gl_Position = vec4(1, -1, 0, 1);\n"
14430 " gs_fs = tes_gs[0];\n"
14431 " gl_Position = vec4(1, 1, 0, 1);\n"
14435 static const GLchar* gs_tested = "#version 430 core\n"
14436 "#extension GL_ARB_enhanced_layouts : require\n"
14438 "layout(points) in;\n"
14439 "layout(triangle_strip, max_vertices = 4) out;\n"
14443 "in vec4 tes_gs[];\n"
14444 "out vec4 gs_fs;\n"
14448 " vec4 result = tes_gs[0];\n"
14452 " gs_fs = result;\n"
14453 " gl_Position = vec4(-1, -1, 0, 1);\n"
14455 " gs_fs = result;\n"
14456 " gl_Position = vec4(-1, 1, 0, 1);\n"
14458 " gs_fs = result;\n"
14459 " gl_Position = vec4(1, -1, 0, 1);\n"
14461 " gs_fs = result;\n"
14462 " gl_Position = vec4(1, 1, 0, 1);\n"
14466 static const GLchar* tcs = "#version 430 core\n"
14467 "#extension GL_ARB_enhanced_layouts : require\n"
14469 "layout(vertices = 1) out;\n"
14471 "in vec4 vs_tcs[];\n"
14472 "out vec4 tcs_tes[];\n"
14477 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
14479 " gl_TessLevelOuter[0] = 1.0;\n"
14480 " gl_TessLevelOuter[1] = 1.0;\n"
14481 " gl_TessLevelOuter[2] = 1.0;\n"
14482 " gl_TessLevelOuter[3] = 1.0;\n"
14483 " gl_TessLevelInner[0] = 1.0;\n"
14484 " gl_TessLevelInner[1] = 1.0;\n"
14487 static const GLchar* tcs_tested = "#version 430 core\n"
14488 "#extension GL_ARB_enhanced_layouts : require\n"
14490 "layout(vertices = 1) out;\n"
14494 "in vec4 vs_tcs[];\n"
14495 "out vec4 tcs_tes[];\n"
14499 " vec4 result = vs_tcs[gl_InvocationID];\n"
14503 " tcs_tes[gl_InvocationID] = result;\n"
14505 " gl_TessLevelOuter[0] = 1.0;\n"
14506 " gl_TessLevelOuter[1] = 1.0;\n"
14507 " gl_TessLevelOuter[2] = 1.0;\n"
14508 " gl_TessLevelOuter[3] = 1.0;\n"
14509 " gl_TessLevelInner[0] = 1.0;\n"
14510 " gl_TessLevelInner[1] = 1.0;\n"
14513 static const GLchar* tes = "#version 430 core\n"
14514 "#extension GL_ARB_enhanced_layouts : require\n"
14516 "layout(isolines, point_mode) in;\n"
14518 "in vec4 tcs_tes[];\n"
14519 "out vec4 tes_gs;\n"
14523 " tes_gs = tcs_tes[0];\n"
14526 static const GLchar* tes_tested = "#version 430 core\n"
14527 "#extension GL_ARB_enhanced_layouts : require\n"
14529 "layout(isolines, point_mode) in;\n"
14533 "in vec4 tcs_tes[];\n"
14534 "out vec4 tes_gs;\n"
14538 " vec4 result = tcs_tes[0];\n"
14542 " tes_gs += result;\n"
14545 static const GLchar* vs = "#version 430 core\n"
14546 "#extension GL_ARB_enhanced_layouts : require\n"
14549 "out vec4 vs_tcs;\n"
14553 " vs_tcs = in_vs;\n"
14556 static const GLchar* vs_tested = "#version 430 core\n"
14557 "#extension GL_ARB_enhanced_layouts : require\n"
14562 "out vec4 vs_tcs;\n"
14566 " vec4 result = in_vs;\n"
14570 " vs_tcs += result;\n"
14574 std::string source;
14575 testCase& test_case = m_test_cases[test_case_index];
14577 if (test_case.m_stage == stage)
14579 const GLchar* array = "";
14581 const GLchar* direction = "in ";
14582 const GLchar* flat = "";
14583 const GLchar* index = "";
14584 GLuint last = getLastInputLocation(stage, test_case.m_type, 0);
14585 size_t position = 0;
14587 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
14588 Utils::Variable::STORAGE storage = Utils::Variable::VARYING_INPUT;
14589 const GLchar* var_use = input_use;
14591 if (false == test_case.m_is_input)
14594 last = getLastOutputLocation(stage, test_case.m_type, 0);
14595 storage = Utils::Variable::VARYING_OUTPUT;
14596 var_use = output_use;
14599 if (true == isFlatRequired(stage, test_case.m_type, storage))
14604 sprintf(buffer, "%d", last);
14608 case Utils::Shader::FRAGMENT:
14609 source = fs_tested;
14611 case Utils::Shader::GEOMETRY:
14612 source = gs_tested;
14616 case Utils::Shader::TESS_CTRL:
14617 source = tcs_tested;
14619 index = "[gl_InvocationID]";
14621 case Utils::Shader::TESS_EVAL:
14622 source = tes_tested;
14626 case Utils::Shader::VERTEX:
14627 source = vs_tested;
14630 TCU_FAIL("Invalid enum");
14634 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
14636 Utils::replaceToken("LAST", position, buffer, source);
14637 Utils::replaceToken("FLAT", position, flat, source);
14638 Utils::replaceToken("DIRECTION", position, direction, source);
14639 Utils::replaceToken("ARRAY", position, array, source);
14640 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
14642 Utils::replaceAllTokens("TYPE", type_name, source);
14643 Utils::replaceAllTokens("INDEX", index, source);
14649 case Utils::Shader::FRAGMENT:
14652 case Utils::Shader::GEOMETRY:
14655 case Utils::Shader::TESS_CTRL:
14658 case Utils::Shader::TESS_EVAL:
14661 case Utils::Shader::VERTEX:
14665 TCU_FAIL("Invalid enum");
14672 /** Get description of test case
14674 * @param test_case_index Index of test case
14676 * @return Test case description
14678 std::string VaryingLocationLimitTest::getTestCaseName(GLuint test_case_index)
14680 std::stringstream stream;
14681 testCase& test_case = m_test_cases[test_case_index];
14683 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
14684 << " type: " << test_case.m_type.GetGLSLTypeName() << ", direction: ";
14686 if (true == test_case.m_is_input)
14692 stream << "output";
14695 return stream.str();
14698 /** Get number of test cases
14700 * @return Number of test cases
14702 GLuint VaryingLocationLimitTest::getTestCaseNumber()
14704 return static_cast<GLuint>(m_test_cases.size());
14707 /** Selects if "compute" stage is relevant for test
14713 bool VaryingLocationLimitTest::isComputeRelevant(GLuint /* test_case_index */)
14718 /** Prepare all test cases
14721 void VaryingLocationLimitTest::testInit()
14723 const GLuint n_types = getTypesNumber();
14725 for (GLuint i = 0; i < n_types; ++i)
14727 const Utils::Type& type = getType(i);
14729 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
14731 if (Utils::Shader::COMPUTE == stage)
14736 testCase test_case_in = { true, type, (Utils::Shader::STAGES)stage };
14737 testCase test_case_out = { false, type, (Utils::Shader::STAGES)stage };
14739 m_test_cases.push_back(test_case_in);
14741 if (Utils::Shader::FRAGMENT != stage)
14743 m_test_cases.push_back(test_case_out);
14751 * @param context Test framework context
14753 VaryingComponentsTest::VaryingComponentsTest(deqp::Context& context)
14754 : VaryingLocationsTest(context, "varying_components",
14755 "Test verifies that input and output components are respected")
14761 * @param context Test framework context
14762 * @param test_name Name of test
14763 * @param test_description Description of test
14765 VaryingComponentsTest::VaryingComponentsTest(deqp::Context& context, const glw::GLchar* test_name,
14766 const glw::GLchar* test_description)
14767 : VaryingLocationsTest(context, test_name, test_description)
14771 /** Get interface of program
14773 * @param test_case_index Test case
14774 * @param program_interface Interface of program
14775 * @param varying_passthrough Collection of connections between in and out variables
14777 void VaryingComponentsTest::getProgramInterface(GLuint test_case_index, Utils::ProgramInterface& program_interface,
14778 Utils::VaryingPassthrough& varying_passthrough)
14780 GLuint array_length = getArrayLength();
14781 const testCase& test_case = m_test_cases[test_case_index];
14782 const Utils::Type vector_type = Utils::Type::GetType(test_case.m_type, 1, 4);
14783 Utils::ShaderInterface si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
14785 /* Zero means no array, however we still need at least 1 slot of data */
14786 if (0 == array_length)
14791 /* Generate data */
14792 const std::vector<GLubyte>& data = vector_type.GenerateDataPacked();
14793 const size_t data_size = data.size();
14795 /* Prepare data for variables */
14796 m_data.resize(array_length * data_size);
14798 GLubyte* dst = &m_data[0];
14799 const GLubyte* src = &data[0];
14801 for (GLuint i = 0; i < array_length; ++i)
14803 memcpy(dst + data_size * i, src, data_size);
14806 /* Prepare interface for each stage */
14807 prepareShaderStage(Utils::Shader::FRAGMENT, vector_type, program_interface, test_case, varying_passthrough);
14808 prepareShaderStage(Utils::Shader::GEOMETRY, vector_type, program_interface, test_case, varying_passthrough);
14809 prepareShaderStage(Utils::Shader::TESS_CTRL, vector_type, program_interface, test_case, varying_passthrough);
14810 prepareShaderStage(Utils::Shader::TESS_EVAL, vector_type, program_interface, test_case, varying_passthrough);
14811 prepareShaderStage(Utils::Shader::VERTEX, vector_type, program_interface, test_case, varying_passthrough);
14816 * @param test_case_index Index of test case
14818 * @return Name of type test in test_case_index
14820 std::string VaryingComponentsTest::getTestCaseName(glw::GLuint test_case_index)
14824 const testCase& test_case = m_test_cases[test_case_index];
14828 switch (test_case.m_type)
14830 case Utils::Type::Double:
14831 name.append(Utils::Type::_double.GetGLSLTypeName());
14833 case Utils::Type::Float:
14834 name.append(Utils::Type::_float.GetGLSLTypeName());
14836 case Utils::Type::Int:
14837 name.append(Utils::Type::_int.GetGLSLTypeName());
14839 case Utils::Type::Uint:
14840 name.append(Utils::Type::uint.GetGLSLTypeName());
14844 name.append(", layout: ");
14846 switch (test_case.m_layout)
14849 name.append("GVEC4");
14852 name.append("SCALAR_GVEC3");
14855 name.append("GVEC3_SCALAR");
14858 name.append("GVEC2_GVEC2");
14860 case GVEC2_SCALAR_SCALAR:
14861 name.append("GVEC2_SCALAR_SCALAR");
14863 case SCALAR_GVEC2_SCALAR:
14864 name.append("SCALAR_GVEC2_SCALAR");
14866 case SCALAR_SCALAR_GVEC2:
14867 name.append("SCALAR_SCALAR_GVEC2");
14869 case SCALAR_SCALAR_SCALAR_SCALAR:
14870 name.append("SCALAR_SCALAR_SCALAR_SCALAR");
14877 /** Returns number of types to test
14879 * @return Number of types, 34
14881 glw::GLuint VaryingComponentsTest::getTestCaseNumber()
14883 return static_cast<GLuint>(m_test_cases.size());
14886 /* Prepare test cases */
14887 void VaryingComponentsTest::testInit()
14889 // FIXME: add tests for doubles, which have specific rules
14891 m_test_cases.push_back(testCase(GVEC4, Utils::Type::Float));
14892 m_test_cases.push_back(testCase(SCALAR_GVEC3, Utils::Type::Float));
14893 m_test_cases.push_back(testCase(GVEC3_SCALAR, Utils::Type::Float));
14894 m_test_cases.push_back(testCase(GVEC2_GVEC2, Utils::Type::Float));
14895 m_test_cases.push_back(testCase(GVEC2_SCALAR_SCALAR, Utils::Type::Float));
14896 m_test_cases.push_back(testCase(SCALAR_GVEC2_SCALAR, Utils::Type::Float));
14897 m_test_cases.push_back(testCase(SCALAR_SCALAR_GVEC2, Utils::Type::Float));
14898 m_test_cases.push_back(testCase(SCALAR_SCALAR_SCALAR_SCALAR, Utils::Type::Float));
14900 m_test_cases.push_back(testCase(GVEC4, Utils::Type::Int));
14901 m_test_cases.push_back(testCase(SCALAR_GVEC3, Utils::Type::Int));
14902 m_test_cases.push_back(testCase(GVEC3_SCALAR, Utils::Type::Int));
14903 m_test_cases.push_back(testCase(GVEC2_GVEC2, Utils::Type::Int));
14904 m_test_cases.push_back(testCase(GVEC2_SCALAR_SCALAR, Utils::Type::Int));
14905 m_test_cases.push_back(testCase(SCALAR_GVEC2_SCALAR, Utils::Type::Int));
14906 m_test_cases.push_back(testCase(SCALAR_SCALAR_GVEC2, Utils::Type::Int));
14907 m_test_cases.push_back(testCase(SCALAR_SCALAR_SCALAR_SCALAR, Utils::Type::Int));
14909 m_test_cases.push_back(testCase(GVEC4, Utils::Type::Uint));
14910 m_test_cases.push_back(testCase(SCALAR_GVEC3, Utils::Type::Uint));
14911 m_test_cases.push_back(testCase(GVEC3_SCALAR, Utils::Type::Uint));
14912 m_test_cases.push_back(testCase(GVEC2_GVEC2, Utils::Type::Uint));
14913 m_test_cases.push_back(testCase(GVEC2_SCALAR_SCALAR, Utils::Type::Uint));
14914 m_test_cases.push_back(testCase(SCALAR_GVEC2_SCALAR, Utils::Type::Uint));
14915 m_test_cases.push_back(testCase(SCALAR_SCALAR_GVEC2, Utils::Type::Uint));
14916 m_test_cases.push_back(testCase(SCALAR_SCALAR_SCALAR_SCALAR, Utils::Type::Uint));
14919 /** Inform that test use components
14925 bool VaryingComponentsTest::useComponentQualifier(glw::GLuint /* test_case_index */)
14930 /** Get length of arrays that should be used during test
14932 * @return 0u - no array at all
14934 GLuint VaryingComponentsTest::getArrayLength()
14939 std::string VaryingComponentsTest::prepareGlobals(GLuint last_in_location, GLuint last_out_location)
14941 std::string globals = VaryingLocationsTest::prepareGlobals(last_in_location, last_out_location);
14943 globals.append("const uint comp_x = 0u;\n"
14944 "const uint comp_y = 1u;\n"
14945 "const uint comp_z = 2u;\n"
14946 "const uint comp_w = 3u;\n");
14954 std::string VaryingComponentsTest::prepareName(const glw::GLchar* name, glw::GLint location, glw::GLint component,
14955 Utils::Shader::STAGES stage, Utils::Variable::STORAGE storage)
14958 std::string result = "PREFIXNAME_lLOCATION_cCOMPONENT";
14959 size_t position = 0;
14960 const GLchar* prefix = Utils::ProgramInterface::GetStagePrefix(stage, storage);
14962 Utils::replaceToken("PREFIX", position, prefix, result);
14963 Utils::replaceToken("NAME", position, name, result);
14965 sprintf(buffer, "%d", location);
14966 Utils::replaceToken("LOCATION", position, buffer, result);
14968 sprintf(buffer, "%d", component);
14969 Utils::replaceToken("COMPONENT", position, buffer, result);
14974 std::string VaryingComponentsTest::prepareQualifiers(const glw::GLchar* location, const glw::GLchar* component,
14975 const glw::GLchar* interpolation)
14977 size_t position = 0;
14978 std::string qualifiers = "layout (location = LOCATION, component = COMPONENT) INTERPOLATION";
14980 Utils::replaceToken("LOCATION", position, location, qualifiers);
14981 Utils::replaceToken("COMPONENT", position, component, qualifiers);
14982 Utils::replaceToken("INTERPOLATION", position, interpolation, qualifiers);
14990 void VaryingComponentsTest::prepareShaderStage(Utils::Shader::STAGES stage, const Utils::Type& vector_type,
14991 Utils::ProgramInterface& program_interface, const testCase& test_case,
14992 Utils::VaryingPassthrough& varying_passthrough)
14994 const GLuint array_length = getArrayLength();
14995 const Utils::Type& basic_type = Utils::Type::GetType(vector_type.m_basic_type, 1 /* n_cols */, 1 /* n_rows */);
14996 descriptor desc_in[8];
14997 descriptor desc_out[8];
14998 const GLuint first_in_loc = 0;
14999 const GLuint first_out_loc = 0;
15000 const GLchar* interpolation = "";
15001 const GLuint last_in_loc = getLastInputLocation(stage, vector_type, array_length);
15002 GLuint last_out_loc = 0;
15004 Utils::ShaderInterface& si = program_interface.GetShaderInterface(stage);
15006 /* Select interpolation */
15007 if ((Utils::Shader::FRAGMENT == stage) || (Utils::Shader::GEOMETRY == stage))
15009 interpolation = " flat";
15012 if (Utils::Shader::FRAGMENT != stage)
15014 last_out_loc = getLastOutputLocation(stage, vector_type, array_length);
15017 switch (test_case.m_layout)
15021 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 4, "gvec4");
15022 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 4, "gvec4");
15024 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 4, "gvec4");
15025 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 4, "gvec4");
15029 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "scalar");
15030 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "scalar");
15031 desc_in[2].assign(1, "comp_y", first_in_loc, "first_input_location", 3, "gvec3");
15032 desc_in[3].assign(1, "comp_y", last_in_loc, "last_input_location", 3, "gvec3");
15034 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "scalar");
15035 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "scalar");
15036 desc_out[2].assign(1, "comp_y", first_out_loc, "first_output_location", 3, "gvec3");
15037 desc_out[3].assign(1, "comp_y", last_out_loc, "last_output_location", 3, "gvec3");
15041 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 3, "gvec3");
15042 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 3, "gvec3");
15043 desc_in[2].assign(3, "comp_w", first_in_loc, "first_input_location", 1, "scalar");
15044 desc_in[3].assign(3, "comp_w", last_in_loc, "last_input_location", 1, "scalar");
15046 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 3, "gvec3");
15047 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 3, "gvec3");
15048 desc_out[2].assign(3, "comp_w", first_out_loc, "first_output_location", 1, "scalar");
15049 desc_out[3].assign(3, "comp_w", last_out_loc, "last_output_location", 1, "scalar");
15053 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 2, "gvec2");
15054 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 2, "gvec2");
15055 desc_in[2].assign(2, "comp_z", first_in_loc, "first_input_location", 2, "gvec2");
15056 desc_in[3].assign(2, "comp_z", last_in_loc, "last_input_location", 2, "gvec2");
15058 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 2, "gvec2");
15059 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 2, "gvec2");
15060 desc_out[2].assign(2, "comp_z", first_out_loc, "first_output_location", 2, "gvec2");
15061 desc_out[3].assign(2, "comp_z", last_out_loc, "last_output_location", 2, "gvec2");
15063 case GVEC2_SCALAR_SCALAR:
15065 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 2, "gvec2");
15066 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 2, "gvec2");
15067 desc_in[2].assign(2, "comp_z", first_in_loc, "first_input_location", 1, "scalar");
15068 desc_in[3].assign(2, "comp_z", last_in_loc, "last_input_location", 1, "scalar");
15069 desc_in[4].assign(3, "comp_w", first_in_loc, "first_input_location", 1, "scalar");
15070 desc_in[5].assign(3, "comp_w", last_in_loc, "last_input_location", 1, "scalar");
15072 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 2, "gvec2");
15073 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 2, "gvec2");
15074 desc_out[2].assign(2, "comp_z", first_out_loc, "first_output_location", 1, "scalar");
15075 desc_out[3].assign(2, "comp_z", last_out_loc, "last_output_location", 1, "scalar");
15076 desc_out[4].assign(3, "comp_w", first_out_loc, "first_output_location", 1, "scalar");
15077 desc_out[5].assign(3, "comp_w", last_out_loc, "last_output_location", 1, "scalar");
15079 case SCALAR_GVEC2_SCALAR:
15081 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "scalar");
15082 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "scalar");
15083 desc_in[2].assign(1, "comp_y", first_in_loc, "first_input_location", 2, "gvec2");
15084 desc_in[3].assign(1, "comp_y", last_in_loc, "last_input_location", 2, "gvec2");
15085 desc_in[4].assign(3, "comp_w", first_in_loc, "first_input_location", 1, "scalar");
15086 desc_in[5].assign(3, "comp_w", last_in_loc, "last_input_location", 1, "scalar");
15088 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "scalar");
15089 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "scalar");
15090 desc_out[2].assign(1, "comp_y", first_out_loc, "first_output_location", 2, "gvec2");
15091 desc_out[3].assign(1, "comp_y", last_out_loc, "last_output_location", 2, "gvec2");
15092 desc_out[4].assign(3, "comp_w", first_out_loc, "first_output_location", 1, "scalar");
15093 desc_out[5].assign(3, "comp_w", last_out_loc, "last_output_location", 1, "scalar");
15095 case SCALAR_SCALAR_GVEC2:
15097 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "scalar");
15098 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "scalar");
15099 desc_in[2].assign(1, "comp_y", first_in_loc, "first_input_location", 1, "scalar");
15100 desc_in[3].assign(1, "comp_y", last_in_loc, "last_input_location", 1, "scalar");
15101 desc_in[4].assign(2, "comp_z", first_in_loc, "first_input_location", 2, "gvec2");
15102 desc_in[5].assign(2, "comp_z", last_in_loc, "last_input_location", 2, "gvec2");
15104 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "scalar");
15105 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "scalar");
15106 desc_out[2].assign(1, "comp_y", first_out_loc, "first_output_location", 1, "scalar");
15107 desc_out[3].assign(1, "comp_y", last_out_loc, "last_output_location", 1, "scalar");
15108 desc_out[4].assign(2, "comp_z", first_out_loc, "first_output_location", 2, "gvec2");
15109 desc_out[5].assign(2, "comp_z", last_out_loc, "last_output_location", 2, "gvec2");
15111 case SCALAR_SCALAR_SCALAR_SCALAR:
15113 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "scalar");
15114 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "scalar");
15115 desc_in[2].assign(1, "comp_y", first_in_loc, "first_input_location", 1, "scalar");
15116 desc_in[3].assign(1, "comp_y", last_in_loc, "last_input_location", 1, "scalar");
15117 desc_in[4].assign(2, "comp_z", first_in_loc, "first_input_location", 1, "scalar");
15118 desc_in[5].assign(2, "comp_z", last_in_loc, "last_input_location", 1, "scalar");
15119 desc_in[6].assign(3, "comp_w", first_in_loc, "first_input_location", 1, "scalar");
15120 desc_in[7].assign(3, "comp_w", last_in_loc, "last_input_location", 1, "scalar");
15122 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "scalar");
15123 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "scalar");
15124 desc_out[2].assign(1, "comp_y", first_out_loc, "first_output_location", 1, "scalar");
15125 desc_out[3].assign(1, "comp_y", last_out_loc, "last_output_location", 1, "scalar");
15126 desc_out[4].assign(2, "comp_z", first_out_loc, "first_output_location", 1, "scalar");
15127 desc_out[5].assign(2, "comp_z", last_out_loc, "last_output_location", 1, "scalar");
15128 desc_out[6].assign(3, "comp_w", first_out_loc, "first_output_location", 1, "scalar");
15129 desc_out[7].assign(3, "comp_w", last_out_loc, "last_output_location", 1, "scalar");
15133 for (GLuint i = 0; i < n_desc; ++i)
15135 const descriptor& in_desc = desc_in[i];
15137 Utils::Variable* in =
15138 prepareVarying(basic_type, in_desc, interpolation, si, stage, Utils::Variable::VARYING_INPUT);
15140 if (Utils::Shader::FRAGMENT != stage)
15142 const descriptor& out_desc = desc_out[i];
15144 Utils::Variable* out =
15145 prepareVarying(basic_type, out_desc, interpolation, si, stage, Utils::Variable::VARYING_OUTPUT);
15147 varying_passthrough.Add(stage, in, out);
15151 si.m_globals = prepareGlobals(last_in_loc, last_out_loc);
15157 Utils::Variable* VaryingComponentsTest::prepareVarying(const Utils::Type& basic_type, const descriptor& desc,
15158 const GLchar* interpolation, Utils::ShaderInterface& si,
15159 Utils::Shader::STAGES stage, Utils::Variable::STORAGE storage)
15161 const GLuint array_length = getArrayLength();
15162 const GLuint component_size = basic_type.GetSize();
15163 const std::string& name = prepareName(desc.m_name, desc.m_location, desc.m_component, stage, storage);
15164 const GLuint offset = desc.m_component * component_size;
15165 const std::string& qual = prepareQualifiers(desc.m_location_str, desc.m_component_str, interpolation);
15166 const GLuint size = desc.m_n_rows * component_size;
15167 const Utils::Type& type = Utils::Type::GetType(basic_type.m_basic_type, 1 /* n_columns */, desc.m_n_rows);
15168 Utils::Variable* var = 0;
15170 if (Utils::Variable::VARYING_INPUT == storage)
15172 var = si.Input(name.c_str(), qual.c_str() /* qualifiers */, desc.m_component /* expected_componenet */,
15173 desc.m_location /* expected_location */, type, /* built_in_type */
15174 GL_FALSE /* normalized */, array_length /* n_array_elements */, 0u /* stride */,
15175 offset /* offset */, (GLvoid*)&m_data[offset] /* data */, size /* data_size */);
15179 var = si.Output(name.c_str(), qual.c_str() /* qualifiers */, desc.m_component /* expected_componenet */,
15180 desc.m_location /* expected_location */, type, /* built_in_type */
15181 GL_FALSE /* normalized */, array_length /* n_array_elements */, 0u /* stride */,
15182 offset /* offset */, (GLvoid*)&m_data[offset] /* data */, size /* data_size */);
15188 void VaryingComponentsTest::descriptor::assign(glw::GLint component, const glw::GLchar* component_str,
15189 glw::GLint location, const glw::GLchar* location_str, glw::GLuint n_rows,
15190 const glw::GLchar* name)
15192 m_component = component;
15193 m_component_str = component_str;
15194 m_location = location;
15195 m_location_str = location_str;
15200 VaryingComponentsTest::testCase::testCase(COMPONENTS_LAYOUT layout, Utils::Type::TYPES type)
15201 : m_layout(layout), m_type(type)
15207 * @param context Test framework context
15209 VaryingArrayComponentsTest::VaryingArrayComponentsTest(deqp::Context& context)
15210 : VaryingComponentsTest(context, "varying_array_components",
15211 "Test verifies that input and output components are respected for arrays")
15215 /** Get length of arrays that should be used during test
15219 GLuint VaryingArrayComponentsTest::getArrayLength()
15226 * @param context Test framework context
15228 VaryingExceedingComponentsTest::VaryingExceedingComponentsTest(deqp::Context& context)
15229 : NegativeTestBase(context, "varying_exceeding_components",
15230 "Test verifies that compiler reports error when component qualifier exceed limits")
15234 /** Source for given test case and stage
15236 * @param test_case_index Index of test case
15237 * @param stage Shader stage
15239 * @return Shader source
15241 std::string VaryingExceedingComponentsTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
15243 static const GLchar* var_definition_arr =
15244 "layout (location = 1, component = COMPONENT) flat DIRECTION TYPE gokuARRAY[1];\n";
15245 static const GLchar* var_definition_one =
15246 "layout (location = 1, component = COMPONENT) flat DIRECTION TYPE gokuARRAY;\n";
15247 static const GLchar* input_use_arr = " if (TYPE(0) == gokuINDEX[0])\n"
15249 " result += vec4(1, 0.5, 0.25, 0.125);\n"
15251 static const GLchar* input_use_one = " if (TYPE(0) == gokuINDEX)\n"
15253 " result += vec4(1, 0.5, 0.25, 0.125);\n"
15255 static const GLchar* output_use_arr = " gokuINDEX[0] = TYPE(0);\n"
15256 " if (vec4(0) == result)\n"
15258 " gokuINDEX[0] = TYPE(1);\n"
15260 static const GLchar* output_use_one = " gokuINDEX = TYPE(0);\n"
15261 " if (vec4(0) == result)\n"
15263 " gokuINDEX = TYPE(1);\n"
15265 static const GLchar* fs = "#version 430 core\n"
15266 "#extension GL_ARB_enhanced_layouts : require\n"
15269 "out vec4 fs_out;\n"
15273 " fs_out = gs_fs;\n"
15276 static const GLchar* fs_tested = "#version 430 core\n"
15277 "#extension GL_ARB_enhanced_layouts : require\n"
15282 "out vec4 fs_out;\n"
15286 " vec4 result = gs_fs;\n"
15290 " fs_out += result;\n"
15293 static const GLchar* gs = "#version 430 core\n"
15294 "#extension GL_ARB_enhanced_layouts : require\n"
15296 "layout(points) in;\n"
15297 "layout(triangle_strip, max_vertices = 4) out;\n"
15299 "in vec4 tes_gs[];\n"
15300 "out vec4 gs_fs;\n"
15304 " gs_fs = tes_gs[0];\n"
15305 " gl_Position = vec4(-1, -1, 0, 1);\n"
15307 " gs_fs = tes_gs[0];\n"
15308 " gl_Position = vec4(-1, 1, 0, 1);\n"
15310 " gs_fs = tes_gs[0];\n"
15311 " gl_Position = vec4(1, -1, 0, 1);\n"
15313 " gs_fs = tes_gs[0];\n"
15314 " gl_Position = vec4(1, 1, 0, 1);\n"
15318 static const GLchar* gs_tested = "#version 430 core\n"
15319 "#extension GL_ARB_enhanced_layouts : require\n"
15321 "layout(points) in;\n"
15322 "layout(triangle_strip, max_vertices = 4) out;\n"
15326 "in vec4 tes_gs[];\n"
15327 "out vec4 gs_fs;\n"
15331 " vec4 result = tes_gs[0];\n"
15335 " gs_fs = result;\n"
15336 " gl_Position = vec4(-1, -1, 0, 1);\n"
15338 " gs_fs = result;\n"
15339 " gl_Position = vec4(-1, 1, 0, 1);\n"
15341 " gs_fs = result;\n"
15342 " gl_Position = vec4(1, -1, 0, 1);\n"
15344 " gs_fs = result;\n"
15345 " gl_Position = vec4(1, 1, 0, 1);\n"
15349 static const GLchar* tcs = "#version 430 core\n"
15350 "#extension GL_ARB_enhanced_layouts : require\n"
15352 "layout(vertices = 1) out;\n"
15354 "in vec4 vs_tcs[];\n"
15355 "out vec4 tcs_tes[];\n"
15360 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
15362 " gl_TessLevelOuter[0] = 1.0;\n"
15363 " gl_TessLevelOuter[1] = 1.0;\n"
15364 " gl_TessLevelOuter[2] = 1.0;\n"
15365 " gl_TessLevelOuter[3] = 1.0;\n"
15366 " gl_TessLevelInner[0] = 1.0;\n"
15367 " gl_TessLevelInner[1] = 1.0;\n"
15370 static const GLchar* tcs_tested = "#version 430 core\n"
15371 "#extension GL_ARB_enhanced_layouts : require\n"
15373 "layout(vertices = 1) out;\n"
15377 "in vec4 vs_tcs[];\n"
15378 "out vec4 tcs_tes[];\n"
15382 " vec4 result = vs_tcs[gl_InvocationID];\n"
15386 " tcs_tes[gl_InvocationID] = result;\n"
15388 " gl_TessLevelOuter[0] = 1.0;\n"
15389 " gl_TessLevelOuter[1] = 1.0;\n"
15390 " gl_TessLevelOuter[2] = 1.0;\n"
15391 " gl_TessLevelOuter[3] = 1.0;\n"
15392 " gl_TessLevelInner[0] = 1.0;\n"
15393 " gl_TessLevelInner[1] = 1.0;\n"
15396 static const GLchar* tes = "#version 430 core\n"
15397 "#extension GL_ARB_enhanced_layouts : require\n"
15399 "layout(isolines, point_mode) in;\n"
15401 "in vec4 tcs_tes[];\n"
15402 "out vec4 tes_gs;\n"
15406 " tes_gs = tcs_tes[0];\n"
15409 static const GLchar* tes_tested = "#version 430 core\n"
15410 "#extension GL_ARB_enhanced_layouts : require\n"
15412 "layout(isolines, point_mode) in;\n"
15416 "in vec4 tcs_tes[];\n"
15417 "out vec4 tes_gs;\n"
15421 " vec4 result = tcs_tes[0];\n"
15425 " tes_gs += result;\n"
15428 static const GLchar* vs = "#version 430 core\n"
15429 "#extension GL_ARB_enhanced_layouts : require\n"
15432 "out vec4 vs_tcs;\n"
15436 " vs_tcs = in_vs;\n"
15439 static const GLchar* vs_tested = "#version 430 core\n"
15440 "#extension GL_ARB_enhanced_layouts : require\n"
15445 "out vec4 vs_tcs;\n"
15449 " vec4 result = in_vs;\n"
15453 " vs_tcs += result;\n"
15457 std::string source;
15458 testCase& test_case = m_test_cases[test_case_index];
15460 if (test_case.m_stage == stage)
15462 const GLchar* array = "";
15464 const GLchar* var_definition = 0;
15465 const GLchar* direction = "in ";
15466 const GLchar* index = "";
15467 size_t position = 0;
15469 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
15470 const GLchar* var_use = 0;
15472 if (false == test_case.m_is_input)
15476 if (false == test_case.m_is_array)
15478 var_definition = var_definition_one;
15479 var_use = output_use_one;
15483 var_definition = var_definition_arr;
15484 var_use = output_use_arr;
15489 if (false == test_case.m_is_array)
15491 var_definition = var_definition_one;
15492 var_use = input_use_one;
15496 var_definition = var_definition_arr;
15497 var_use = input_use_arr;
15501 sprintf(buffer, "%d", test_case.m_component);
15505 case Utils::Shader::FRAGMENT:
15506 source = fs_tested;
15508 case Utils::Shader::GEOMETRY:
15509 source = gs_tested;
15513 case Utils::Shader::TESS_CTRL:
15514 source = tcs_tested;
15516 index = "[gl_InvocationID]";
15518 case Utils::Shader::TESS_EVAL:
15519 source = tes_tested;
15523 case Utils::Shader::VERTEX:
15524 source = vs_tested;
15527 TCU_FAIL("Invalid enum");
15531 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
15533 Utils::replaceToken("COMPONENT", position, buffer, source);
15534 Utils::replaceToken("DIRECTION", position, direction, source);
15535 Utils::replaceToken("ARRAY", position, array, source);
15536 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
15538 Utils::replaceAllTokens("TYPE", type_name, source);
15539 Utils::replaceAllTokens("INDEX", index, source);
15545 case Utils::Shader::FRAGMENT:
15548 case Utils::Shader::GEOMETRY:
15551 case Utils::Shader::TESS_CTRL:
15554 case Utils::Shader::TESS_EVAL:
15557 case Utils::Shader::VERTEX:
15561 TCU_FAIL("Invalid enum");
15568 /** Get description of test case
15570 * @param test_case_index Index of test case
15572 * @return Test case description
15574 std::string VaryingExceedingComponentsTest::getTestCaseName(GLuint test_case_index)
15576 std::stringstream stream;
15577 testCase& test_case = m_test_cases[test_case_index];
15579 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
15580 << " type: " << test_case.m_type.GetGLSLTypeName();
15582 if (true == test_case.m_is_array)
15587 stream << ", direction: ";
15589 if (true == test_case.m_is_input)
15595 stream << "output";
15598 stream << ", component: " << test_case.m_component;
15600 return stream.str();
15603 /** Get number of test cases
15605 * @return Number of test cases
15607 GLuint VaryingExceedingComponentsTest::getTestCaseNumber()
15609 return static_cast<GLuint>(m_test_cases.size());
15612 /** Selects if "compute" stage is relevant for test
15618 bool VaryingExceedingComponentsTest::isComputeRelevant(GLuint /* test_case_index */)
15623 /** Prepare all test cases
15626 void VaryingExceedingComponentsTest::testInit()
15628 static const GLuint n_components_per_location = 4;
15629 const GLuint n_types = getTypesNumber();
15631 for (GLuint i = 0; i < n_types; ++i)
15633 const Utils::Type& type = getType(i);
15634 const GLuint n_req_components = type.m_n_rows;
15635 const GLuint valid_component = n_components_per_location - n_req_components;
15636 const GLuint invalid_component = valid_component + 1;
15638 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
15640 if (Utils::Shader::COMPUTE == stage)
15645 /* Component cannot be used for matrices */
15646 if (1 != type.m_n_columns)
15651 testCase test_case_in_arr = { invalid_component, true, true, (Utils::Shader::STAGES)stage, type };
15652 testCase test_case_in_one = { invalid_component, true, false, (Utils::Shader::STAGES)stage, type };
15653 testCase test_case_out_arr = { invalid_component, false, true, (Utils::Shader::STAGES)stage, type };
15654 testCase test_case_out_one = { invalid_component, false, false, (Utils::Shader::STAGES)stage, type };
15656 m_test_cases.push_back(test_case_in_arr);
15657 m_test_cases.push_back(test_case_in_one);
15659 if (Utils::Shader::FRAGMENT != stage)
15661 m_test_cases.push_back(test_case_out_arr);
15662 m_test_cases.push_back(test_case_out_one);
15670 * @param context Test framework context
15672 VaryingComponentWithoutLocationTest::VaryingComponentWithoutLocationTest(deqp::Context& context)
15673 : NegativeTestBase(context, "varying_component_without_location",
15674 "Test verifies that compiler reports error when component qualifier is used without location")
15678 /** Source for given test case and stage
15680 * @param test_case_index Index of test case
15681 * @param stage Shader stage
15683 * @return Shader source
15685 std::string VaryingComponentWithoutLocationTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
15687 static const GLchar* var_definition = "layout (component = COMPONENT) FLAT DIRECTION TYPE gokuARRAY;\n";
15688 static const GLchar* input_use = " if (TYPE(0) == gokuINDEX)\n"
15690 " result += vec4(1, 0.5, 0.25, 0.125);\n"
15692 static const GLchar* output_use = " gokuINDEX = TYPE(0);\n"
15693 " if (vec4(0) == result)\n"
15695 " gokuINDEX = TYPE(1);\n"
15697 static const GLchar* fs = "#version 430 core\n"
15698 "#extension GL_ARB_enhanced_layouts : require\n"
15701 "out vec4 fs_out;\n"
15705 " fs_out = gs_fs;\n"
15708 static const GLchar* fs_tested = "#version 430 core\n"
15709 "#extension GL_ARB_enhanced_layouts : require\n"
15714 "out vec4 fs_out;\n"
15718 " vec4 result = gs_fs;\n"
15722 " fs_out = result;\n"
15725 static const GLchar* gs = "#version 430 core\n"
15726 "#extension GL_ARB_enhanced_layouts : require\n"
15728 "layout(points) in;\n"
15729 "layout(triangle_strip, max_vertices = 4) out;\n"
15731 "in vec4 tes_gs[];\n"
15732 "out vec4 gs_fs;\n"
15736 " gs_fs = tes_gs[0];\n"
15737 " gl_Position = vec4(-1, -1, 0, 1);\n"
15739 " gs_fs = tes_gs[0];\n"
15740 " gl_Position = vec4(-1, 1, 0, 1);\n"
15742 " gs_fs = tes_gs[0];\n"
15743 " gl_Position = vec4(1, -1, 0, 1);\n"
15745 " gs_fs = tes_gs[0];\n"
15746 " gl_Position = vec4(1, 1, 0, 1);\n"
15750 static const GLchar* gs_tested = "#version 430 core\n"
15751 "#extension GL_ARB_enhanced_layouts : require\n"
15753 "layout(points) in;\n"
15754 "layout(triangle_strip, max_vertices = 4) out;\n"
15758 "in vec4 tes_gs[];\n"
15759 "out vec4 gs_fs;\n"
15763 " vec4 result = tes_gs[0];\n"
15767 " gs_fs = result;\n"
15768 " gl_Position = vec4(-1, -1, 0, 1);\n"
15770 " gs_fs = result;\n"
15771 " gl_Position = vec4(-1, 1, 0, 1);\n"
15773 " gs_fs = result;\n"
15774 " gl_Position = vec4(1, -1, 0, 1);\n"
15776 " gs_fs = result;\n"
15777 " gl_Position = vec4(1, 1, 0, 1);\n"
15781 static const GLchar* tcs = "#version 430 core\n"
15782 "#extension GL_ARB_enhanced_layouts : require\n"
15784 "layout(vertices = 1) out;\n"
15786 "in vec4 vs_tcs[];\n"
15787 "out vec4 tcs_tes[];\n"
15792 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
15794 " gl_TessLevelOuter[0] = 1.0;\n"
15795 " gl_TessLevelOuter[1] = 1.0;\n"
15796 " gl_TessLevelOuter[2] = 1.0;\n"
15797 " gl_TessLevelOuter[3] = 1.0;\n"
15798 " gl_TessLevelInner[0] = 1.0;\n"
15799 " gl_TessLevelInner[1] = 1.0;\n"
15802 static const GLchar* tcs_tested = "#version 430 core\n"
15803 "#extension GL_ARB_enhanced_layouts : require\n"
15805 "layout(vertices = 1) out;\n"
15809 "in vec4 vs_tcs[];\n"
15810 "out vec4 tcs_tes[];\n"
15814 " vec4 result = vs_tcs[gl_InvocationID];\n"
15818 " tcs_tes[gl_InvocationID] = result;\n"
15820 " gl_TessLevelOuter[0] = 1.0;\n"
15821 " gl_TessLevelOuter[1] = 1.0;\n"
15822 " gl_TessLevelOuter[2] = 1.0;\n"
15823 " gl_TessLevelOuter[3] = 1.0;\n"
15824 " gl_TessLevelInner[0] = 1.0;\n"
15825 " gl_TessLevelInner[1] = 1.0;\n"
15828 static const GLchar* tes = "#version 430 core\n"
15829 "#extension GL_ARB_enhanced_layouts : require\n"
15831 "layout(isolines, point_mode) in;\n"
15833 "in vec4 tcs_tes[];\n"
15834 "out vec4 tes_gs;\n"
15838 " tes_gs = tcs_tes[0];\n"
15841 static const GLchar* tes_tested = "#version 430 core\n"
15842 "#extension GL_ARB_enhanced_layouts : require\n"
15844 "layout(isolines, point_mode) in;\n"
15848 "in vec4 tcs_tes[];\n"
15849 "out vec4 tes_gs;\n"
15853 " vec4 result = tcs_tes[0];\n"
15857 " tes_gs = result;\n"
15860 static const GLchar* vs = "#version 430 core\n"
15861 "#extension GL_ARB_enhanced_layouts : require\n"
15864 "out vec4 vs_tcs;\n"
15868 " vs_tcs = in_vs;\n"
15871 static const GLchar* vs_tested = "#version 430 core\n"
15872 "#extension GL_ARB_enhanced_layouts : require\n"
15877 "out vec4 vs_tcs;\n"
15881 " vec4 result = in_vs;\n"
15885 " vs_tcs = result;\n"
15889 std::string source;
15890 testCase& test_case = m_test_cases[test_case_index];
15892 if (test_case.m_stage == stage)
15894 const GLchar* array = "";
15896 const GLchar* direction = "in ";
15897 const GLchar* index = "";
15898 size_t position = 0;
15900 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
15901 const GLchar* var_use = input_use;
15902 const GLchar* flat = "flat";
15904 if (false == test_case.m_is_input)
15907 var_use = output_use;
15910 sprintf(buffer, "%d", test_case.m_component);
15914 case Utils::Shader::FRAGMENT:
15915 source = fs_tested;
15917 case Utils::Shader::GEOMETRY:
15918 source = gs_tested;
15922 case Utils::Shader::TESS_CTRL:
15923 source = tcs_tested;
15925 index = "[gl_InvocationID]";
15927 case Utils::Shader::TESS_EVAL:
15928 source = tes_tested;
15932 case Utils::Shader::VERTEX:
15933 source = vs_tested;
15937 TCU_FAIL("Invalid enum");
15941 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
15943 Utils::replaceToken("COMPONENT", position, buffer, source);
15944 Utils::replaceToken("FLAT", position, flat, source);
15945 Utils::replaceToken("DIRECTION", position, direction, source);
15946 Utils::replaceToken("ARRAY", position, array, source);
15947 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
15949 Utils::replaceAllTokens("TYPE", type_name, source);
15950 Utils::replaceAllTokens("INDEX", index, source);
15956 case Utils::Shader::FRAGMENT:
15959 case Utils::Shader::GEOMETRY:
15962 case Utils::Shader::TESS_CTRL:
15965 case Utils::Shader::TESS_EVAL:
15968 case Utils::Shader::VERTEX:
15972 TCU_FAIL("Invalid enum");
15979 /** Get description of test case
15981 * @param test_case_index Index of test case
15983 * @return Test case description
15985 std::string VaryingComponentWithoutLocationTest::getTestCaseName(GLuint test_case_index)
15987 std::stringstream stream;
15988 testCase& test_case = m_test_cases[test_case_index];
15990 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
15991 << " type: " << test_case.m_type.GetGLSLTypeName() << ", direction: ";
15993 if (true == test_case.m_is_input)
15999 stream << "output";
16002 stream << ", component: " << test_case.m_component;
16004 return stream.str();
16007 /** Get number of test cases
16009 * @return Number of test cases
16011 GLuint VaryingComponentWithoutLocationTest::getTestCaseNumber()
16013 return static_cast<GLuint>(m_test_cases.size());
16016 /** Selects if "compute" stage is relevant for test
16022 bool VaryingComponentWithoutLocationTest::isComputeRelevant(GLuint /* test_case_index */)
16027 /** Prepare all test cases
16030 void VaryingComponentWithoutLocationTest::testInit()
16032 static const GLuint n_components_per_location = 4;
16033 const GLuint n_types = getTypesNumber();
16035 for (GLuint i = 0; i < n_types; ++i)
16037 const Utils::Type& type = getType(i);
16038 const GLuint n_req_components = type.m_n_rows;
16039 const GLuint valid_component = n_components_per_location - n_req_components;
16041 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
16043 if (Utils::Shader::COMPUTE == stage)
16048 /* Component cannot be used for matrices */
16049 if (1 != type.m_n_columns)
16054 testCase test_case_in = { valid_component, true, (Utils::Shader::STAGES)stage, type };
16055 testCase test_case_out = { valid_component, false, (Utils::Shader::STAGES)stage, type };
16057 m_test_cases.push_back(test_case_in);
16059 if (Utils::Shader::FRAGMENT != stage)
16061 m_test_cases.push_back(test_case_out);
16069 * @param context Test framework context
16071 VaryingComponentOfInvalidTypeTest::VaryingComponentOfInvalidTypeTest(deqp::Context& context)
16072 : NegativeTestBase(context, "varying_component_of_invalid_type",
16073 "Test verifies that compiler reports error when component qualifier is used for invalid type")
16077 /** Source for given test case and stage
16079 * @param test_case_index Index of test case
16080 * @param stage Shader stage
16082 * @return Shader source
16084 std::string VaryingComponentOfInvalidTypeTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
16086 static const GLchar* block_definition_arr = "layout (location = 1, component = COMPONENT) flat DIRECTION Goku {\n"
16088 "} gokuARRAY[1];\n";
16089 static const GLchar* block_definition_one = "layout (location = 1, component = COMPONENT) flat DIRECTION Goku {\n"
16092 static const GLchar* matrix_definition_arr =
16093 "layout (location = 1, component = COMPONENT) flat DIRECTION TYPE gokuARRAY[1];\n";
16094 static const GLchar* matrix_definition_one =
16095 "layout (location = 1, component = COMPONENT) flat DIRECTION TYPE gokuARRAY;\n";
16096 static const GLchar* struct_definition_arr =
16101 "layout (location = 1, component = COMPONENT) flat DIRECTION Goku gokuARRAY[1];\n";
16102 static const GLchar* struct_definition_one =
16107 "layout (location = 1, component = COMPONENT) flat DIRECTION Goku gokuARRAY;\n";
16108 static const GLchar* matrix_input_use_arr = " if (TYPE(0) == gokuINDEX[0])\n"
16110 " result += vec4(1, 0.5, 0.25, 0.125);\n"
16112 static const GLchar* matrix_input_use_one = " if (TYPE(0) == gokuINDEX)\n"
16114 " result += vec4(1, 0.5, 0.25, 0.125);\n"
16116 static const GLchar* matrix_output_use_arr = " gokuINDEX[0] = TYPE(0);\n"
16117 " if (vec4(0) == result)\n"
16119 " gokuINDEX[0] = TYPE(1);\n"
16121 static const GLchar* matrix_output_use_one = " gokuINDEX = TYPE(0);\n"
16122 " if (vec4(0) == result)\n"
16124 " gokuINDEX = TYPE(1);\n"
16126 static const GLchar* member_input_use_arr = " if (TYPE(0) == gokuINDEX[0].member)\n"
16128 " result += vec4(1, 0.5, 0.25, 0.125);\n"
16130 static const GLchar* member_input_use_one = " if (TYPE(0) == gokuINDEX.member)\n"
16132 " result += vec4(1, 0.5, 0.25, 0.125);\n"
16134 static const GLchar* member_output_use_arr = " gokuINDEX[0].member = TYPE(0);\n"
16135 " if (vec4(0) == result)\n"
16137 " gokuINDEX[0].member = TYPE(1);\n"
16139 static const GLchar* member_output_use_one = " gokuINDEX.member = TYPE(0);\n"
16140 " if (vec4(0) == result)\n"
16142 " gokuINDEX.member = TYPE(1);\n"
16144 static const GLchar* fs = "#version 430 core\n"
16145 "#extension GL_ARB_enhanced_layouts : require\n"
16148 "out vec4 fs_out;\n"
16152 " fs_out = gs_fs;\n"
16155 static const GLchar* fs_tested = "#version 430 core\n"
16156 "#extension GL_ARB_enhanced_layouts : require\n"
16161 "out vec4 fs_out;\n"
16165 " vec4 result = gs_fs;\n"
16169 " fs_out += result;\n"
16172 static const GLchar* gs = "#version 430 core\n"
16173 "#extension GL_ARB_enhanced_layouts : require\n"
16175 "layout(points) in;\n"
16176 "layout(triangle_strip, max_vertices = 4) out;\n"
16178 "in vec4 tes_gs[];\n"
16179 "out vec4 gs_fs;\n"
16183 " gs_fs = tes_gs[0];\n"
16184 " gl_Position = vec4(-1, -1, 0, 1);\n"
16186 " gs_fs = tes_gs[0];\n"
16187 " gl_Position = vec4(-1, 1, 0, 1);\n"
16189 " gs_fs = tes_gs[0];\n"
16190 " gl_Position = vec4(1, -1, 0, 1);\n"
16192 " gs_fs = tes_gs[0];\n"
16193 " gl_Position = vec4(1, 1, 0, 1);\n"
16197 static const GLchar* gs_tested = "#version 430 core\n"
16198 "#extension GL_ARB_enhanced_layouts : require\n"
16200 "layout(points) in;\n"
16201 "layout(triangle_strip, max_vertices = 4) out;\n"
16205 "in vec4 tes_gs[];\n"
16206 "out vec4 gs_fs;\n"
16210 " vec4 result = tes_gs[0];\n"
16214 " gs_fs = result;\n"
16215 " gl_Position = vec4(-1, -1, 0, 1);\n"
16217 " gs_fs = result;\n"
16218 " gl_Position = vec4(-1, 1, 0, 1);\n"
16220 " gs_fs = result;\n"
16221 " gl_Position = vec4(1, -1, 0, 1);\n"
16223 " gs_fs = result;\n"
16224 " gl_Position = vec4(1, 1, 0, 1);\n"
16228 static const GLchar* tcs = "#version 430 core\n"
16229 "#extension GL_ARB_enhanced_layouts : require\n"
16231 "layout(vertices = 1) out;\n"
16233 "in vec4 vs_tcs[];\n"
16234 "out vec4 tcs_tes[];\n"
16239 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
16241 " gl_TessLevelOuter[0] = 1.0;\n"
16242 " gl_TessLevelOuter[1] = 1.0;\n"
16243 " gl_TessLevelOuter[2] = 1.0;\n"
16244 " gl_TessLevelOuter[3] = 1.0;\n"
16245 " gl_TessLevelInner[0] = 1.0;\n"
16246 " gl_TessLevelInner[1] = 1.0;\n"
16249 static const GLchar* tcs_tested = "#version 430 core\n"
16250 "#extension GL_ARB_enhanced_layouts : require\n"
16252 "layout(vertices = 1) out;\n"
16256 "in vec4 vs_tcs[];\n"
16257 "out vec4 tcs_tes[];\n"
16261 " vec4 result = vs_tcs[gl_InvocationID];\n"
16265 " tcs_tes[gl_InvocationID] = result;\n"
16267 " gl_TessLevelOuter[0] = 1.0;\n"
16268 " gl_TessLevelOuter[1] = 1.0;\n"
16269 " gl_TessLevelOuter[2] = 1.0;\n"
16270 " gl_TessLevelOuter[3] = 1.0;\n"
16271 " gl_TessLevelInner[0] = 1.0;\n"
16272 " gl_TessLevelInner[1] = 1.0;\n"
16275 static const GLchar* tes = "#version 430 core\n"
16276 "#extension GL_ARB_enhanced_layouts : require\n"
16278 "layout(isolines, point_mode) in;\n"
16280 "in vec4 tcs_tes[];\n"
16281 "out vec4 tes_gs;\n"
16285 " tes_gs = tcs_tes[0];\n"
16288 static const GLchar* tes_tested = "#version 430 core\n"
16289 "#extension GL_ARB_enhanced_layouts : require\n"
16291 "layout(isolines, point_mode) in;\n"
16295 "in vec4 tcs_tes[];\n"
16296 "out vec4 tes_gs;\n"
16300 " vec4 result = tcs_tes[0];\n"
16304 " tes_gs += result;\n"
16307 static const GLchar* vs = "#version 430 core\n"
16308 "#extension GL_ARB_enhanced_layouts : require\n"
16311 "out vec4 vs_tcs;\n"
16315 " vs_tcs = in_vs;\n"
16318 static const GLchar* vs_tested = "#version 430 core\n"
16319 "#extension GL_ARB_enhanced_layouts : require\n"
16324 "out vec4 vs_tcs;\n"
16328 " vec4 result = in_vs;\n"
16332 " vs_tcs += result;\n"
16336 std::string source;
16337 testCase& test_case = m_test_cases[test_case_index];
16339 if (test_case.m_stage == stage)
16341 const GLchar* array = "";
16343 const GLchar* var_definition = 0;
16344 const GLchar* direction = "in ";
16345 const GLchar* index = "";
16346 size_t position = 0;
16348 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
16349 const GLchar* var_use = 0;
16351 if (false == test_case.m_is_input)
16355 if (false == test_case.m_is_array)
16357 switch (test_case.m_case)
16360 var_definition = block_definition_one;
16361 var_use = member_output_use_one;
16364 var_definition = matrix_definition_one;
16365 var_use = matrix_output_use_one;
16368 var_definition = struct_definition_one;
16369 var_use = member_output_use_one;
16372 TCU_FAIL("Invalid enum");
16377 switch (test_case.m_case)
16380 var_definition = block_definition_arr;
16381 var_use = member_output_use_arr;
16384 var_definition = matrix_definition_arr;
16385 var_use = matrix_output_use_arr;
16388 var_definition = struct_definition_arr;
16389 var_use = member_output_use_arr;
16392 TCU_FAIL("Invalid enum");
16398 if (false == test_case.m_is_array)
16400 switch (test_case.m_case)
16403 var_definition = block_definition_one;
16404 var_use = member_input_use_one;
16407 var_definition = matrix_definition_one;
16408 var_use = matrix_input_use_one;
16411 var_definition = struct_definition_one;
16412 var_use = member_input_use_one;
16415 TCU_FAIL("Invalid enum");
16420 switch (test_case.m_case)
16423 var_definition = block_definition_arr;
16424 var_use = member_input_use_arr;
16427 var_definition = matrix_definition_arr;
16428 var_use = matrix_input_use_arr;
16431 var_definition = struct_definition_arr;
16432 var_use = member_input_use_arr;
16435 TCU_FAIL("Invalid enum");
16440 sprintf(buffer, "%d", test_case.m_component);
16444 case Utils::Shader::FRAGMENT:
16445 source = fs_tested;
16447 case Utils::Shader::GEOMETRY:
16448 source = gs_tested;
16452 case Utils::Shader::TESS_CTRL:
16453 source = tcs_tested;
16455 index = "[gl_InvocationID]";
16457 case Utils::Shader::TESS_EVAL:
16458 source = tes_tested;
16462 case Utils::Shader::VERTEX:
16463 source = vs_tested;
16466 TCU_FAIL("Invalid enum");
16470 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
16472 Utils::replaceToken("COMPONENT", position, buffer, source);
16473 Utils::replaceToken("DIRECTION", position, direction, source);
16474 Utils::replaceToken("ARRAY", position, array, source);
16475 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
16477 Utils::replaceAllTokens("TYPE", type_name, source);
16478 Utils::replaceAllTokens("INDEX", index, source);
16484 case Utils::Shader::FRAGMENT:
16487 case Utils::Shader::GEOMETRY:
16490 case Utils::Shader::TESS_CTRL:
16493 case Utils::Shader::TESS_EVAL:
16496 case Utils::Shader::VERTEX:
16500 TCU_FAIL("Invalid enum");
16507 /** Get description of test case
16509 * @param test_case_index Index of test case
16511 * @return Test case description
16513 std::string VaryingComponentOfInvalidTypeTest::getTestCaseName(GLuint test_case_index)
16515 std::stringstream stream;
16516 testCase& test_case = m_test_cases[test_case_index];
16518 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
16519 << " type: " << test_case.m_type.GetGLSLTypeName();
16521 if (true == test_case.m_is_array)
16526 stream << ", direction: ";
16528 if (true == test_case.m_is_input)
16534 stream << "output";
16537 stream << ", component: " << test_case.m_component;
16539 return stream.str();
16542 /** Get number of test cases
16544 * @return Number of test cases
16546 GLuint VaryingComponentOfInvalidTypeTest::getTestCaseNumber()
16548 return static_cast<GLuint>(m_test_cases.size());
16551 /** Selects if "compute" stage is relevant for test
16557 bool VaryingComponentOfInvalidTypeTest::isComputeRelevant(GLuint /* test_case_index */)
16562 /** Prepare all test cases
16565 void VaryingComponentOfInvalidTypeTest::testInit()
16567 static const GLuint n_components_per_location = 4;
16568 const GLuint n_types = getTypesNumber();
16570 for (GLuint i = 0; i < n_types; ++i)
16572 const Utils::Type& type = getType(i);
16573 const GLuint n_req_components = type.m_n_rows;
16574 const GLuint valid_component = n_components_per_location - n_req_components;
16576 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
16578 if (Utils::Shader::COMPUTE == stage)
16583 /* Use different CASE for matrices */
16584 if (1 != type.m_n_columns)
16586 testCase test_case_in_arr = { MATRIX, valid_component, true, true, (Utils::Shader::STAGES)stage, type };
16587 testCase test_case_in_one = {
16588 MATRIX, valid_component, false, true, (Utils::Shader::STAGES)stage, type
16590 testCase test_case_out_arr = {
16591 MATRIX, valid_component, true, false, (Utils::Shader::STAGES)stage, type
16593 testCase test_case_out_one = {
16594 MATRIX, valid_component, false, false, (Utils::Shader::STAGES)stage, type
16597 m_test_cases.push_back(test_case_in_arr);
16598 m_test_cases.push_back(test_case_in_one);
16600 if (Utils::Shader::FRAGMENT != stage)
16602 m_test_cases.push_back(test_case_out_arr);
16603 m_test_cases.push_back(test_case_out_one);
16608 for (GLuint c = BLOCK; c < MAX_CASES; ++c)
16610 testCase test_case_in_arr = { (CASES)c, valid_component, true, true, (Utils::Shader::STAGES)stage,
16612 testCase test_case_in_one = { (CASES)c, valid_component, false, true, (Utils::Shader::STAGES)stage,
16614 testCase test_case_out_arr = { (CASES)c, valid_component, true, false, (Utils::Shader::STAGES)stage,
16616 testCase test_case_out_one = {
16617 (CASES)c, valid_component, false, false, (Utils::Shader::STAGES)stage, type
16620 if (Utils::Shader::VERTEX != stage)
16622 m_test_cases.push_back(test_case_in_arr);
16623 m_test_cases.push_back(test_case_in_one);
16626 if (Utils::Shader::FRAGMENT != stage)
16628 m_test_cases.push_back(test_case_out_arr);
16629 m_test_cases.push_back(test_case_out_one);
16639 * @param context Test framework context
16641 InputComponentAliasingTest::InputComponentAliasingTest(deqp::Context& context)
16642 : NegativeTestBase(context, "input_component_aliasing",
16643 "Test verifies that compiler reports component aliasing as error")
16647 /** Source for given test case and stage
16649 * @param test_case_index Index of test case
16650 * @param stage Shader stage
16652 * @return Shader source
16654 std::string InputComponentAliasingTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
16656 static const GLchar* var_definition = "layout (location = 1, component = COMPONENT) FLAT in TYPE gohanARRAY;\n"
16657 "layout (location = 1, component = COMPONENT) FLAT in TYPE gotenARRAY;\n";
16658 static const GLchar* test_one = " if (TYPE(0) == gohanINDEX)\n"
16660 " result += vec4(1, 0.5, 0.25, 0.125);\n"
16662 static const GLchar* fs = "#version 430 core\n"
16663 "#extension GL_ARB_enhanced_layouts : require\n"
16666 "out vec4 fs_out;\n"
16670 " fs_out = gs_fs;\n"
16673 static const GLchar* fs_tested = "#version 430 core\n"
16674 "#extension GL_ARB_enhanced_layouts : require\n"
16679 "out vec4 fs_out;\n"
16683 " vec4 result = gs_fs;\n"
16687 " fs_out += result;\n"
16690 static const GLchar* gs = "#version 430 core\n"
16691 "#extension GL_ARB_enhanced_layouts : require\n"
16693 "layout(points) in;\n"
16694 "layout(triangle_strip, max_vertices = 4) out;\n"
16696 "in vec4 tes_gs[];\n"
16697 "out vec4 gs_fs;\n"
16701 " gs_fs = tes_gs[0];\n"
16702 " gl_Position = vec4(-1, -1, 0, 1);\n"
16704 " gs_fs = tes_gs[0];\n"
16705 " gl_Position = vec4(-1, 1, 0, 1);\n"
16707 " gs_fs = tes_gs[0];\n"
16708 " gl_Position = vec4(1, -1, 0, 1);\n"
16710 " gs_fs = tes_gs[0];\n"
16711 " gl_Position = vec4(1, 1, 0, 1);\n"
16715 static const GLchar* gs_tested = "#version 430 core\n"
16716 "#extension GL_ARB_enhanced_layouts : require\n"
16718 "layout(points) in;\n"
16719 "layout(triangle_strip, max_vertices = 4) out;\n"
16723 "in vec4 tes_gs[];\n"
16724 "out vec4 gs_fs;\n"
16728 " vec4 result = tes_gs[0];\n"
16732 " gs_fs = result;\n"
16733 " gl_Position = vec4(-1, -1, 0, 1);\n"
16735 " gs_fs = result;\n"
16736 " gl_Position = vec4(-1, 1, 0, 1);\n"
16738 " gs_fs = result;\n"
16739 " gl_Position = vec4(1, -1, 0, 1);\n"
16741 " gs_fs = result;\n"
16742 " gl_Position = vec4(1, 1, 0, 1);\n"
16746 static const GLchar* tcs = "#version 430 core\n"
16747 "#extension GL_ARB_enhanced_layouts : require\n"
16749 "layout(vertices = 1) out;\n"
16751 "in vec4 vs_tcs[];\n"
16752 "out vec4 tcs_tes[];\n"
16757 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
16759 " gl_TessLevelOuter[0] = 1.0;\n"
16760 " gl_TessLevelOuter[1] = 1.0;\n"
16761 " gl_TessLevelOuter[2] = 1.0;\n"
16762 " gl_TessLevelOuter[3] = 1.0;\n"
16763 " gl_TessLevelInner[0] = 1.0;\n"
16764 " gl_TessLevelInner[1] = 1.0;\n"
16767 static const GLchar* tcs_tested = "#version 430 core\n"
16768 "#extension GL_ARB_enhanced_layouts : require\n"
16770 "layout(vertices = 1) out;\n"
16774 "in vec4 vs_tcs[];\n"
16775 "out vec4 tcs_tes[];\n"
16779 " vec4 result = vs_tcs[gl_InvocationID];\n"
16783 " tcs_tes[gl_InvocationID] = result;\n"
16785 " gl_TessLevelOuter[0] = 1.0;\n"
16786 " gl_TessLevelOuter[1] = 1.0;\n"
16787 " gl_TessLevelOuter[2] = 1.0;\n"
16788 " gl_TessLevelOuter[3] = 1.0;\n"
16789 " gl_TessLevelInner[0] = 1.0;\n"
16790 " gl_TessLevelInner[1] = 1.0;\n"
16793 static const GLchar* tes = "#version 430 core\n"
16794 "#extension GL_ARB_enhanced_layouts : require\n"
16796 "layout(isolines, point_mode) in;\n"
16798 "in vec4 tcs_tes[];\n"
16799 "out vec4 tes_gs;\n"
16803 " tes_gs = tcs_tes[0];\n"
16806 static const GLchar* tes_tested = "#version 430 core\n"
16807 "#extension GL_ARB_enhanced_layouts : require\n"
16809 "layout(isolines, point_mode) in;\n"
16813 "in vec4 tcs_tes[];\n"
16814 "out vec4 tes_gs;\n"
16818 " vec4 result = tcs_tes[0];\n"
16822 " tes_gs += result;\n"
16825 static const GLchar* vs = "#version 430 core\n"
16826 "#extension GL_ARB_enhanced_layouts : require\n"
16829 "out vec4 vs_tcs;\n"
16833 " vs_tcs = in_vs;\n"
16836 static const GLchar* vs_tested = "#version 430 core\n"
16837 "#extension GL_ARB_enhanced_layouts : require\n"
16842 "out vec4 vs_tcs;\n"
16846 " vec4 result = in_vs;\n"
16850 " vs_tcs += result;\n"
16854 std::string source;
16855 testCase& test_case = m_test_cases[test_case_index];
16857 if (test_case.m_stage == stage)
16859 const GLchar* array = "";
16860 GLchar buffer_gohan[16];
16861 GLchar buffer_goten[16];
16862 const GLchar* flat = "";
16863 const GLchar* index = "";
16864 const bool is_flat_req = isFlatRequired(stage, test_case.m_type, Utils::Variable::VARYING_INPUT);
16865 size_t position = 0;
16867 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
16868 const GLchar* var_use = test_one;
16870 if (true == is_flat_req)
16875 sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
16876 sprintf(buffer_goten, "%d", test_case.m_component_goten);
16880 case Utils::Shader::FRAGMENT:
16881 source = fs_tested;
16883 case Utils::Shader::GEOMETRY:
16884 source = gs_tested;
16888 case Utils::Shader::TESS_CTRL:
16889 source = tcs_tested;
16891 index = "[gl_InvocationID]";
16893 case Utils::Shader::TESS_EVAL:
16894 source = tes_tested;
16898 case Utils::Shader::VERTEX:
16899 source = vs_tested;
16902 TCU_FAIL("Invalid enum");
16906 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
16908 Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
16909 Utils::replaceToken("ARRAY", position, array, source);
16910 Utils::replaceToken("COMPONENT", position, buffer_goten, source);
16911 Utils::replaceToken("ARRAY", position, array, source);
16912 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
16914 Utils::replaceAllTokens("FLAT", flat, source);
16915 Utils::replaceAllTokens("TYPE", type_name, source);
16916 Utils::replaceAllTokens("INDEX", index, source);
16922 case Utils::Shader::FRAGMENT:
16925 case Utils::Shader::GEOMETRY:
16928 case Utils::Shader::TESS_CTRL:
16931 case Utils::Shader::TESS_EVAL:
16934 case Utils::Shader::VERTEX:
16938 TCU_FAIL("Invalid enum");
16945 /** Get description of test case
16947 * @param test_case_index Index of test case
16949 * @return Test case description
16951 std::string InputComponentAliasingTest::getTestCaseName(GLuint test_case_index)
16953 std::stringstream stream;
16954 testCase& test_case = m_test_cases[test_case_index];
16956 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
16957 << " type: " << test_case.m_type.GetGLSLTypeName() << ", components: " << test_case.m_component_gohan
16958 << " & " << test_case.m_component_goten;
16960 return stream.str();
16963 /** Get number of test cases
16965 * @return Number of test cases
16967 GLuint InputComponentAliasingTest::getTestCaseNumber()
16969 return static_cast<GLuint>(m_test_cases.size());
16972 /** Selects if "compute" stage is relevant for test
16978 bool InputComponentAliasingTest::isComputeRelevant(GLuint /* test_case_index */)
16983 /** Selects if compilation failure is expected result
16985 * @param test_case_index Index of test case
16987 * @return false for VS that use only single variable, true otherwise
16989 bool InputComponentAliasingTest::isFailureExpected(GLuint test_case_index)
16991 testCase& test_case = m_test_cases[test_case_index];
16993 return (Utils::Shader::VERTEX != test_case.m_stage);
16996 /** Prepare all test cases
16999 void InputComponentAliasingTest::testInit()
17001 const GLuint n_types = getTypesNumber();
17003 for (GLuint i = 0; i < n_types; ++i)
17005 const Utils::Type& type = getType(i);
17006 const bool use_double = (Utils::Type::Double == type.m_basic_type);
17007 const GLuint n_components_per_location = use_double ? 2 : 4;
17008 const GLuint n_req_components = type.m_n_rows;
17009 const GLint valid_component = (GLint)n_components_per_location - (GLint)n_req_components;
17010 const GLuint component_size = use_double ? 2 : 1;
17011 /* Skip matrices */
17012 if (1 != type.m_n_columns)
17016 /* Skip dvec3/dvec4 which doesn't support the component qualifier */
17017 if (valid_component < 0)
17022 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
17024 if (Utils::Shader::COMPUTE == stage)
17029 for (GLuint gohan = 0; gohan <= (GLuint)valid_component; ++gohan)
17031 const GLint first_aliasing = gohan - n_req_components + 1;
17032 const GLint last_aliasing = gohan + n_req_components - 1;
17034 const GLuint goten_start = std::max(0, first_aliasing);
17035 const GLuint goten_stop = std::min(valid_component, last_aliasing);
17037 for (GLuint goten = goten_start; goten <= goten_stop; ++goten)
17039 testCase test_case = { gohan * component_size, goten * component_size, (Utils::Shader::STAGES)stage,
17042 m_test_cases.push_back(test_case);
17051 * @param context Test framework context
17053 OutputComponentAliasingTest::OutputComponentAliasingTest(deqp::Context& context)
17054 : NegativeTestBase(context, "output_component_aliasing",
17055 "Test verifies that compiler reports component aliasing as error")
17059 /** Source for given test case and stage
17061 * @param test_case_index Index of test case
17062 * @param stage Shader stage
17064 * @return Shader source
17066 std::string OutputComponentAliasingTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
17068 static const GLchar* var_definition = "layout (location = 1, component = COMPONENT) flat out TYPE gohanARRAY;\n"
17069 "layout (location = 1, component = COMPONENT) flat out TYPE gotenARRAY;\n";
17070 static const GLchar* l_test = " gohanINDEX = TYPE(1);\n"
17071 " gotenINDEX = TYPE(0);\n";
17072 static const GLchar* fs = "#version 430 core\n"
17073 "#extension GL_ARB_enhanced_layouts : require\n"
17076 "out vec4 fs_out;\n"
17080 " fs_out = gs_fs;\n"
17083 static const GLchar* fs_tested = "#version 430 core\n"
17084 "#extension GL_ARB_enhanced_layouts : require\n"
17089 "out vec4 fs_out;\n"
17093 " vec4 result = gs_fs;\n"
17097 " fs_out += result;\n"
17100 static const GLchar* gs = "#version 430 core\n"
17101 "#extension GL_ARB_enhanced_layouts : require\n"
17103 "layout(points) in;\n"
17104 "layout(triangle_strip, max_vertices = 4) out;\n"
17106 "in vec4 tes_gs[];\n"
17107 "out vec4 gs_fs;\n"
17111 " gs_fs = tes_gs[0];\n"
17112 " gl_Position = vec4(-1, -1, 0, 1);\n"
17114 " gs_fs = tes_gs[0];\n"
17115 " gl_Position = vec4(-1, 1, 0, 1);\n"
17117 " gs_fs = tes_gs[0];\n"
17118 " gl_Position = vec4(1, -1, 0, 1);\n"
17120 " gs_fs = tes_gs[0];\n"
17121 " gl_Position = vec4(1, 1, 0, 1);\n"
17125 static const GLchar* gs_tested = "#version 430 core\n"
17126 "#extension GL_ARB_enhanced_layouts : require\n"
17128 "layout(points) in;\n"
17129 "layout(triangle_strip, max_vertices = 4) out;\n"
17133 "in vec4 tes_gs[];\n"
17134 "out vec4 gs_fs;\n"
17138 " vec4 result = tes_gs[0];\n"
17142 " gs_fs = result;\n"
17143 " gl_Position = vec4(-1, -1, 0, 1);\n"
17145 " gs_fs = result;\n"
17146 " gl_Position = vec4(-1, 1, 0, 1);\n"
17148 " gs_fs = result;\n"
17149 " gl_Position = vec4(1, -1, 0, 1);\n"
17151 " gs_fs = result;\n"
17152 " gl_Position = vec4(1, 1, 0, 1);\n"
17156 static const GLchar* tcs = "#version 430 core\n"
17157 "#extension GL_ARB_enhanced_layouts : require\n"
17159 "layout(vertices = 1) out;\n"
17161 "in vec4 vs_tcs[];\n"
17162 "out vec4 tcs_tes[];\n"
17167 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
17169 " gl_TessLevelOuter[0] = 1.0;\n"
17170 " gl_TessLevelOuter[1] = 1.0;\n"
17171 " gl_TessLevelOuter[2] = 1.0;\n"
17172 " gl_TessLevelOuter[3] = 1.0;\n"
17173 " gl_TessLevelInner[0] = 1.0;\n"
17174 " gl_TessLevelInner[1] = 1.0;\n"
17177 static const GLchar* tcs_tested = "#version 430 core\n"
17178 "#extension GL_ARB_enhanced_layouts : require\n"
17180 "layout(vertices = 1) out;\n"
17184 "in vec4 vs_tcs[];\n"
17185 "out vec4 tcs_tes[];\n"
17189 " vec4 result = vs_tcs[gl_InvocationID];\n"
17193 " tcs_tes[gl_InvocationID] = result;\n"
17195 " gl_TessLevelOuter[0] = 1.0;\n"
17196 " gl_TessLevelOuter[1] = 1.0;\n"
17197 " gl_TessLevelOuter[2] = 1.0;\n"
17198 " gl_TessLevelOuter[3] = 1.0;\n"
17199 " gl_TessLevelInner[0] = 1.0;\n"
17200 " gl_TessLevelInner[1] = 1.0;\n"
17203 static const GLchar* tes = "#version 430 core\n"
17204 "#extension GL_ARB_enhanced_layouts : require\n"
17206 "layout(isolines, point_mode) in;\n"
17208 "in vec4 tcs_tes[];\n"
17209 "out vec4 tes_gs;\n"
17213 " tes_gs = tcs_tes[0];\n"
17216 static const GLchar* tes_tested = "#version 430 core\n"
17217 "#extension GL_ARB_enhanced_layouts : require\n"
17219 "layout(isolines, point_mode) in;\n"
17223 "in vec4 tcs_tes[];\n"
17224 "out vec4 tes_gs;\n"
17228 " vec4 result = tcs_tes[0];\n"
17232 " tes_gs += result;\n"
17235 static const GLchar* vs = "#version 430 core\n"
17236 "#extension GL_ARB_enhanced_layouts : require\n"
17239 "out vec4 vs_tcs;\n"
17243 " vs_tcs = in_vs;\n"
17246 static const GLchar* vs_tested = "#version 430 core\n"
17247 "#extension GL_ARB_enhanced_layouts : require\n"
17252 "out vec4 vs_tcs;\n"
17256 " vec4 result = in_vs;\n"
17260 " vs_tcs += result;\n"
17264 std::string source;
17265 testCase& test_case = m_test_cases[test_case_index];
17267 if (test_case.m_stage == stage)
17269 const GLchar* array = "";
17270 GLchar buffer_gohan[16];
17271 GLchar buffer_goten[16];
17272 const GLchar* index = "";
17273 size_t position = 0;
17275 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
17277 sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
17278 sprintf(buffer_goten, "%d", test_case.m_component_goten);
17282 case Utils::Shader::FRAGMENT:
17283 source = fs_tested;
17285 case Utils::Shader::GEOMETRY:
17286 source = gs_tested;
17290 case Utils::Shader::TESS_CTRL:
17291 source = tcs_tested;
17293 index = "[gl_InvocationID]";
17295 case Utils::Shader::TESS_EVAL:
17296 source = tes_tested;
17300 case Utils::Shader::VERTEX:
17301 source = vs_tested;
17304 TCU_FAIL("Invalid enum");
17308 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
17310 Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
17311 Utils::replaceToken("ARRAY", position, array, source);
17312 Utils::replaceToken("COMPONENT", position, buffer_goten, source);
17313 Utils::replaceToken("ARRAY", position, array, source);
17314 Utils::replaceToken("VARIABLE_USE", position, l_test, source);
17316 Utils::replaceAllTokens("TYPE", type_name, source);
17317 Utils::replaceAllTokens("INDEX", index, source);
17323 case Utils::Shader::FRAGMENT:
17326 case Utils::Shader::GEOMETRY:
17329 case Utils::Shader::TESS_CTRL:
17332 case Utils::Shader::TESS_EVAL:
17335 case Utils::Shader::VERTEX:
17339 TCU_FAIL("Invalid enum");
17346 /** Get description of test case
17348 * @param test_case_index Index of test case
17350 * @return Test case description
17352 std::string OutputComponentAliasingTest::getTestCaseName(GLuint test_case_index)
17354 std::stringstream stream;
17355 testCase& test_case = m_test_cases[test_case_index];
17357 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
17358 << " type: " << test_case.m_type.GetGLSLTypeName() << ", components: " << test_case.m_component_gohan
17359 << " & " << test_case.m_component_goten;
17361 return stream.str();
17364 /** Get number of test cases
17366 * @return Number of test cases
17368 GLuint OutputComponentAliasingTest::getTestCaseNumber()
17370 return static_cast<GLuint>(m_test_cases.size());
17373 /** Selects if "compute" stage is relevant for test
17379 bool OutputComponentAliasingTest::isComputeRelevant(GLuint /* test_case_index */)
17384 /** Prepare all test cases
17387 void OutputComponentAliasingTest::testInit()
17389 static const GLuint n_components_per_location = 4;
17390 const GLuint n_types = getTypesNumber();
17392 for (GLuint i = 0; i < n_types; ++i)
17394 const Utils::Type& type = getType(i);
17395 const GLuint n_req_components = type.m_n_rows;
17396 const GLuint valid_component = n_components_per_location - n_req_components;
17398 /* Skip matrices */
17399 if (1 != type.m_n_columns)
17404 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
17406 if (Utils::Shader::COMPUTE == stage)
17411 if ((Utils::Shader::FRAGMENT == stage) && (Utils::Type::Double == type.m_basic_type))
17416 for (GLuint gohan = 0; gohan <= valid_component; ++gohan)
17418 const GLint first_aliasing = gohan - n_req_components + 1;
17419 const GLint last_aliasing = gohan + n_req_components - 1;
17421 const GLuint goten_start = std::max(0, first_aliasing);
17422 const GLuint goten_stop = std::min((GLint)valid_component, last_aliasing);
17424 for (GLuint goten = goten_start; goten <= goten_stop; ++goten)
17426 testCase test_case = { gohan, goten, (Utils::Shader::STAGES)stage, type };
17428 m_test_cases.push_back(test_case);
17437 * @param context Test framework context
17439 VaryingLocationAliasingWithMixedTypesTest::VaryingLocationAliasingWithMixedTypesTest(deqp::Context& context)
17440 : NegativeTestBase(context, "varying_location_aliasing_with_mixed_types",
17441 "Test verifies that compiler reports error when float/int types are mixed at one location")
17445 /** Source for given test case and stage
17447 * @param test_case_index Index of test case
17448 * @param stage Shader stage
17450 * @return Shader source
17452 std::string VaryingLocationAliasingWithMixedTypesTest::getShaderSource(GLuint test_case_index,
17453 Utils::Shader::STAGES stage)
17455 static const GLchar* var_definition =
17456 "layout (location = 1, component = COMPONENT) FLAT DIRECTION TYPE gohanARRAY;\n"
17457 "layout (location = 1, component = COMPONENT) FLAT DIRECTION TYPE gotenARRAY;\n";
17458 static const GLchar* input_use = " if ((TYPE(0) == gohanINDEX) &&\n"
17459 " (TYPE(1) == gotenINDEX) )\n"
17461 " result += vec4(1, 0.5, 0.25, 0.125);\n"
17463 static const GLchar* output_use = " gohanINDEX = TYPE(0);\n"
17464 " gotenINDEX = TYPE(1);\n"
17465 " if (vec4(0) == result)\n"
17467 " gohanINDEX = TYPE(1);\n"
17468 " gotenINDEX = TYPE(0);\n"
17470 static const GLchar* fs = "#version 430 core\n"
17471 "#extension GL_ARB_enhanced_layouts : require\n"
17474 "out vec4 fs_out;\n"
17478 " fs_out = gs_fs;\n"
17481 static const GLchar* fs_tested = "#version 430 core\n"
17482 "#extension GL_ARB_enhanced_layouts : require\n"
17487 "out vec4 fs_out;\n"
17491 " vec4 result = gs_fs;\n"
17495 " fs_out += result;\n"
17498 static const GLchar* gs = "#version 430 core\n"
17499 "#extension GL_ARB_enhanced_layouts : require\n"
17501 "layout(points) in;\n"
17502 "layout(triangle_strip, max_vertices = 4) out;\n"
17504 "in vec4 tes_gs[];\n"
17505 "out vec4 gs_fs;\n"
17509 " gs_fs = tes_gs[0];\n"
17510 " gl_Position = vec4(-1, -1, 0, 1);\n"
17512 " gs_fs = tes_gs[0];\n"
17513 " gl_Position = vec4(-1, 1, 0, 1);\n"
17515 " gs_fs = tes_gs[0];\n"
17516 " gl_Position = vec4(1, -1, 0, 1);\n"
17518 " gs_fs = tes_gs[0];\n"
17519 " gl_Position = vec4(1, 1, 0, 1);\n"
17523 static const GLchar* gs_tested = "#version 430 core\n"
17524 "#extension GL_ARB_enhanced_layouts : require\n"
17526 "layout(points) in;\n"
17527 "layout(triangle_strip, max_vertices = 4) out;\n"
17531 "in vec4 tes_gs[];\n"
17532 "out vec4 gs_fs;\n"
17536 " vec4 result = tes_gs[0];\n"
17540 " gs_fs = result;\n"
17541 " gl_Position = vec4(-1, -1, 0, 1);\n"
17543 " gs_fs = result;\n"
17544 " gl_Position = vec4(-1, 1, 0, 1);\n"
17546 " gs_fs = result;\n"
17547 " gl_Position = vec4(1, -1, 0, 1);\n"
17549 " gs_fs = result;\n"
17550 " gl_Position = vec4(1, 1, 0, 1);\n"
17554 static const GLchar* tcs = "#version 430 core\n"
17555 "#extension GL_ARB_enhanced_layouts : require\n"
17557 "layout(vertices = 1) out;\n"
17559 "in vec4 vs_tcs[];\n"
17560 "out vec4 tcs_tes[];\n"
17565 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
17567 " gl_TessLevelOuter[0] = 1.0;\n"
17568 " gl_TessLevelOuter[1] = 1.0;\n"
17569 " gl_TessLevelOuter[2] = 1.0;\n"
17570 " gl_TessLevelOuter[3] = 1.0;\n"
17571 " gl_TessLevelInner[0] = 1.0;\n"
17572 " gl_TessLevelInner[1] = 1.0;\n"
17575 static const GLchar* tcs_tested = "#version 430 core\n"
17576 "#extension GL_ARB_enhanced_layouts : require\n"
17578 "layout(vertices = 1) out;\n"
17582 "in vec4 vs_tcs[];\n"
17583 "out vec4 tcs_tes[];\n"
17587 " vec4 result = vs_tcs[gl_InvocationID];\n"
17591 " tcs_tes[gl_InvocationID] = result;\n"
17593 " gl_TessLevelOuter[0] = 1.0;\n"
17594 " gl_TessLevelOuter[1] = 1.0;\n"
17595 " gl_TessLevelOuter[2] = 1.0;\n"
17596 " gl_TessLevelOuter[3] = 1.0;\n"
17597 " gl_TessLevelInner[0] = 1.0;\n"
17598 " gl_TessLevelInner[1] = 1.0;\n"
17601 static const GLchar* tes = "#version 430 core\n"
17602 "#extension GL_ARB_enhanced_layouts : require\n"
17604 "layout(isolines, point_mode) in;\n"
17606 "in vec4 tcs_tes[];\n"
17607 "out vec4 tes_gs;\n"
17611 " tes_gs = tcs_tes[0];\n"
17614 static const GLchar* tes_tested = "#version 430 core\n"
17615 "#extension GL_ARB_enhanced_layouts : require\n"
17617 "layout(isolines, point_mode) in;\n"
17621 "in vec4 tcs_tes[];\n"
17622 "out vec4 tes_gs;\n"
17626 " vec4 result = tcs_tes[0];\n"
17630 " tes_gs += result;\n"
17633 static const GLchar* vs = "#version 430 core\n"
17634 "#extension GL_ARB_enhanced_layouts : require\n"
17637 "out vec4 vs_tcs;\n"
17641 " vs_tcs = in_vs;\n"
17644 static const GLchar* vs_tested = "#version 430 core\n"
17645 "#extension GL_ARB_enhanced_layouts : require\n"
17650 "out vec4 vs_tcs;\n"
17654 " vec4 result = in_vs;\n"
17658 " vs_tcs += result;\n"
17662 std::string source;
17663 testCase& test_case = m_test_cases[test_case_index];
17665 if (test_case.m_stage == stage)
17667 const GLchar* array = "";
17668 GLchar buffer_gohan[16];
17669 GLchar buffer_goten[16];
17670 const GLchar* direction = "in ";
17671 const GLchar* flat_gohan = "";
17672 const GLchar* flat_goten = "";
17673 const GLchar* index = "";
17674 size_t position = 0;
17676 const GLchar* type_gohan_name = test_case.m_type_gohan.GetGLSLTypeName();
17677 const GLchar* type_goten_name = test_case.m_type_goten.GetGLSLTypeName();
17678 Utils::Variable::STORAGE storage = Utils::Variable::VARYING_INPUT;
17679 const GLchar* var_use = input_use;
17681 if (false == test_case.m_is_input)
17684 storage = Utils::Variable::VARYING_OUTPUT;
17685 var_use = output_use;
17688 if (true == isFlatRequired(stage, test_case.m_type_gohan, storage))
17690 flat_gohan = "flat";
17693 if (true == isFlatRequired(stage, test_case.m_type_goten, storage))
17695 flat_goten = "flat";
17698 sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
17699 sprintf(buffer_goten, "%d", test_case.m_component_goten);
17703 case Utils::Shader::FRAGMENT:
17704 source = fs_tested;
17706 case Utils::Shader::GEOMETRY:
17707 source = gs_tested;
17711 case Utils::Shader::TESS_CTRL:
17712 source = tcs_tested;
17714 index = "[gl_InvocationID]";
17716 case Utils::Shader::TESS_EVAL:
17717 source = tes_tested;
17721 case Utils::Shader::VERTEX:
17722 source = vs_tested;
17725 TCU_FAIL("Invalid enum");
17729 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
17731 Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
17732 Utils::replaceToken("FLAT", position, flat_gohan, source);
17733 Utils::replaceToken("DIRECTION", position, direction, source);
17734 Utils::replaceToken("TYPE", position, type_gohan_name, source);
17735 Utils::replaceToken("ARRAY", position, array, source);
17736 Utils::replaceToken("COMPONENT", position, buffer_goten, source);
17737 Utils::replaceToken("FLAT", position, flat_goten, source);
17738 Utils::replaceToken("DIRECTION", position, direction, source);
17739 Utils::replaceToken("TYPE", position, type_goten_name, source);
17740 Utils::replaceToken("ARRAY", position, array, source);
17743 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
17745 if (true == test_case.m_is_input)
17747 Utils::replaceToken("TYPE", position, type_gohan_name, source);
17748 Utils::replaceToken("TYPE", position, type_goten_name, source);
17752 Utils::replaceToken("TYPE", position, type_gohan_name, source);
17753 Utils::replaceToken("TYPE", position, type_goten_name, source);
17754 Utils::replaceToken("TYPE", position, type_gohan_name, source);
17755 Utils::replaceToken("TYPE", position, type_goten_name, source);
17758 Utils::replaceAllTokens("INDEX", index, source);
17764 case Utils::Shader::FRAGMENT:
17767 case Utils::Shader::GEOMETRY:
17770 case Utils::Shader::TESS_CTRL:
17773 case Utils::Shader::TESS_EVAL:
17776 case Utils::Shader::VERTEX:
17780 TCU_FAIL("Invalid enum");
17787 /** Get description of test case
17789 * @param test_case_index Index of test case
17791 * @return Test case description
17793 std::string VaryingLocationAliasingWithMixedTypesTest::getTestCaseName(GLuint test_case_index)
17795 std::stringstream stream;
17796 testCase& test_case = m_test_cases[test_case_index];
17798 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", "
17799 << test_case.m_type_gohan.GetGLSLTypeName() << " at " << test_case.m_component_gohan << ", "
17800 << test_case.m_type_goten.GetGLSLTypeName() << " at " << test_case.m_component_goten << ". Direction: ";
17802 if (true == test_case.m_is_input)
17808 stream << "output";
17811 return stream.str();
17814 /** Get number of test cases
17816 * @return Number of test cases
17818 GLuint VaryingLocationAliasingWithMixedTypesTest::getTestCaseNumber()
17820 return static_cast<GLuint>(m_test_cases.size());
17823 /** Selects if "compute" stage is relevant for test
17829 bool VaryingLocationAliasingWithMixedTypesTest::isComputeRelevant(GLuint /* test_case_index */)
17834 /** Prepare all test cases
17837 void VaryingLocationAliasingWithMixedTypesTest::testInit()
17839 static const GLuint n_components_per_location = 4;
17840 const GLuint n_types = getTypesNumber();
17842 for (GLuint i = 0; i < n_types; ++i)
17844 const Utils::Type& type_gohan = getType(i);
17845 const bool is_float_type_gohan = isFloatType(type_gohan);
17847 /* Skip matrices */
17848 if (1 != type_gohan.m_n_columns)
17853 for (GLuint j = 0; j < n_types; ++j)
17855 const Utils::Type& type_goten = getType(j);
17856 const bool is_float_type_goten = isFloatType(type_goten);
17858 /* Skip matrices */
17859 if (1 != type_goten.m_n_columns)
17864 /* Skip valid combinations */
17865 if (is_float_type_gohan == is_float_type_goten)
17870 const GLuint n_req_components_gohan = type_gohan.m_n_rows;
17871 const GLuint n_req_components_goten = type_goten.m_n_rows;
17872 const GLuint valid_component_gohan = n_components_per_location - n_req_components_gohan;
17873 const GLuint valid_component_goten = n_components_per_location - n_req_components_goten;
17875 /* Skip pairs that cannot fit into one location */
17876 if (n_components_per_location < (n_req_components_gohan + n_req_components_goten))
17881 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
17883 /* Skip compute shader */
17884 if (Utils::Shader::COMPUTE == stage)
17889 for (GLuint gohan = 0; gohan <= valid_component_gohan; ++gohan)
17891 const GLint first_aliasing = gohan - n_req_components_goten + 1;
17892 const GLint last_aliasing = gohan + n_req_components_gohan - 1;
17894 const GLuint goten_lower_limit = std::max(0, first_aliasing);
17895 const GLuint goten_upper_limit = last_aliasing + 1;
17897 /* Compoennets before gohan */
17898 for (GLuint goten = 0; goten < goten_lower_limit; ++goten)
17900 testCase test_case_in = { gohan, goten, true, (Utils::Shader::STAGES)stage,
17901 type_gohan, type_goten };
17902 testCase test_case_out = { gohan, goten, false, (Utils::Shader::STAGES)stage,
17903 type_gohan, type_goten };
17905 if (Utils::Shader::VERTEX != stage)
17906 m_test_cases.push_back(test_case_in);
17908 /* Skip double outputs in fragment shader */
17909 if ((Utils::Shader::FRAGMENT != stage) || ((Utils::Type::Double != type_gohan.m_basic_type) &&
17910 (Utils::Type::Double != type_goten.m_basic_type)))
17912 m_test_cases.push_back(test_case_out);
17916 /* Components after gohan */
17917 for (GLuint goten = goten_upper_limit; goten <= valid_component_goten; ++goten)
17919 testCase test_case_in = { gohan, goten, true, (Utils::Shader::STAGES)stage,
17920 type_gohan, type_goten };
17921 testCase test_case_out = { gohan, goten, false, (Utils::Shader::STAGES)stage,
17922 type_gohan, type_goten };
17924 if (Utils::Shader::VERTEX != stage)
17925 m_test_cases.push_back(test_case_in);
17927 /* Skip double outputs in fragment shader */
17928 if ((Utils::Shader::FRAGMENT != stage) || ((Utils::Type::Double != type_gohan.m_basic_type) &&
17929 (Utils::Type::Double != type_goten.m_basic_type)))
17931 m_test_cases.push_back(test_case_out);
17940 /** Check if given type is float
17942 * @param type Type in question
17944 * @return true if tpye is float, false otherwise
17946 bool VaryingLocationAliasingWithMixedTypesTest::isFloatType(const Utils::Type& type)
17948 bool is_float = false;
17950 if ((Utils::Type::Double == type.m_basic_type) || (Utils::Type::Float == type.m_basic_type))
17960 * @param context Test framework context
17962 VaryingLocationAliasingWithMixedInterpolationTest::VaryingLocationAliasingWithMixedInterpolationTest(
17963 deqp::Context& context)
17964 : NegativeTestBase(
17965 context, "varying_location_aliasing_with_mixed_interpolation",
17966 "Test verifies that compiler reports error when interpolation qualifiers are mixed at one location")
17970 /** Source for given test case and stage
17972 * @param test_case_index Index of test case
17973 * @param stage Shader stage
17975 * @return Shader source
17977 std::string VaryingLocationAliasingWithMixedInterpolationTest::getShaderSource(GLuint test_case_index,
17978 Utils::Shader::STAGES stage)
17980 static const GLchar* var_definition =
17981 "layout (location = 1, component = COMPONENT) INTERPOLATION DIRECTION TYPE gohanARRAY;\n"
17982 "layout (location = 1, component = COMPONENT) INTERPOLATION DIRECTION TYPE gotenARRAY;\n";
17983 static const GLchar* input_use = " if ((TYPE(0) == gohanINDEX) &&\n"
17984 " (TYPE(1) == gotenINDEX) )\n"
17986 " result += vec4(1, 0.5, 0.25, 0.125);\n"
17988 static const GLchar* output_use = " gohanINDEX = TYPE(0);\n"
17989 " gotenINDEX = TYPE(1);\n"
17990 " if (vec4(0) == result)\n"
17992 " gohanINDEX = TYPE(1);\n"
17993 " gotenINDEX = TYPE(0);\n"
17995 static const GLchar* fs = "#version 430 core\n"
17996 "#extension GL_ARB_enhanced_layouts : require\n"
17999 "out vec4 fs_out;\n"
18003 " fs_out = gs_fs;\n"
18006 static const GLchar* fs_tested = "#version 430 core\n"
18007 "#extension GL_ARB_enhanced_layouts : require\n"
18012 "out vec4 fs_out;\n"
18016 " vec4 result = gs_fs;\n"
18020 " fs_out = result;\n"
18023 static const GLchar* gs = "#version 430 core\n"
18024 "#extension GL_ARB_enhanced_layouts : require\n"
18026 "layout(points) in;\n"
18027 "layout(triangle_strip, max_vertices = 4) out;\n"
18029 "in vec4 tes_gs[];\n"
18030 "out vec4 gs_fs;\n"
18034 " gs_fs = tes_gs[0];\n"
18035 " gl_Position = vec4(-1, -1, 0, 1);\n"
18037 " gs_fs = tes_gs[0];\n"
18038 " gl_Position = vec4(-1, 1, 0, 1);\n"
18040 " gs_fs = tes_gs[0];\n"
18041 " gl_Position = vec4(1, -1, 0, 1);\n"
18043 " gs_fs = tes_gs[0];\n"
18044 " gl_Position = vec4(1, 1, 0, 1);\n"
18048 static const GLchar* gs_tested = "#version 430 core\n"
18049 "#extension GL_ARB_enhanced_layouts : require\n"
18051 "layout(points) in;\n"
18052 "layout(triangle_strip, max_vertices = 4) out;\n"
18056 "in vec4 tes_gs[];\n"
18057 "out vec4 gs_fs;\n"
18061 " vec4 result = tes_gs[0];\n"
18065 " gs_fs = result;\n"
18066 " gl_Position = vec4(-1, -1, 0, 1);\n"
18068 " gs_fs = result;\n"
18069 " gl_Position = vec4(-1, 1, 0, 1);\n"
18071 " gs_fs = result;\n"
18072 " gl_Position = vec4(1, -1, 0, 1);\n"
18074 " gs_fs = result;\n"
18075 " gl_Position = vec4(1, 1, 0, 1);\n"
18079 static const GLchar* tcs = "#version 430 core\n"
18080 "#extension GL_ARB_enhanced_layouts : require\n"
18082 "layout(vertices = 1) out;\n"
18084 "in vec4 vs_tcs[];\n"
18085 "out vec4 tcs_tes[];\n"
18090 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
18092 " gl_TessLevelOuter[0] = 1.0;\n"
18093 " gl_TessLevelOuter[1] = 1.0;\n"
18094 " gl_TessLevelOuter[2] = 1.0;\n"
18095 " gl_TessLevelOuter[3] = 1.0;\n"
18096 " gl_TessLevelInner[0] = 1.0;\n"
18097 " gl_TessLevelInner[1] = 1.0;\n"
18100 static const GLchar* tcs_tested = "#version 430 core\n"
18101 "#extension GL_ARB_enhanced_layouts : require\n"
18103 "layout(vertices = 1) out;\n"
18107 "in vec4 vs_tcs[];\n"
18108 "out vec4 tcs_tes[];\n"
18112 " vec4 result = vs_tcs[gl_InvocationID];\n"
18116 " tcs_tes[gl_InvocationID] = result;\n"
18118 " gl_TessLevelOuter[0] = 1.0;\n"
18119 " gl_TessLevelOuter[1] = 1.0;\n"
18120 " gl_TessLevelOuter[2] = 1.0;\n"
18121 " gl_TessLevelOuter[3] = 1.0;\n"
18122 " gl_TessLevelInner[0] = 1.0;\n"
18123 " gl_TessLevelInner[1] = 1.0;\n"
18126 static const GLchar* tes = "#version 430 core\n"
18127 "#extension GL_ARB_enhanced_layouts : require\n"
18129 "layout(isolines, point_mode) in;\n"
18131 "in vec4 tcs_tes[];\n"
18132 "out vec4 tes_gs;\n"
18136 " tes_gs = tcs_tes[0];\n"
18139 static const GLchar* tes_tested = "#version 430 core\n"
18140 "#extension GL_ARB_enhanced_layouts : require\n"
18142 "layout(isolines, point_mode) in;\n"
18146 "in vec4 tcs_tes[];\n"
18147 "out vec4 tes_gs;\n"
18151 " vec4 result = tcs_tes[0];\n"
18155 " tes_gs += result;\n"
18158 static const GLchar* vs = "#version 430 core\n"
18159 "#extension GL_ARB_enhanced_layouts : require\n"
18162 "out vec4 vs_tcs;\n"
18166 " vs_tcs = in_vs;\n"
18169 static const GLchar* vs_tested = "#version 430 core\n"
18170 "#extension GL_ARB_enhanced_layouts : require\n"
18175 "out vec4 vs_tcs;\n"
18179 " vec4 result = in_vs;\n"
18183 " vs_tcs += result;\n"
18187 std::string source;
18188 testCase& test_case = m_test_cases[test_case_index];
18190 if (test_case.m_stage == stage)
18192 const GLchar* array = "";
18193 GLchar buffer_gohan[16];
18194 GLchar buffer_goten[16];
18195 const GLchar* direction = "in ";
18196 const GLchar* index = "";
18197 const GLchar* int_gohan = getInterpolationQualifier(test_case.m_interpolation_gohan);
18198 const GLchar* int_goten = getInterpolationQualifier(test_case.m_interpolation_goten);
18199 size_t position = 0;
18201 const GLchar* type_gohan_name = test_case.m_type_gohan.GetGLSLTypeName();
18202 const GLchar* type_goten_name = test_case.m_type_goten.GetGLSLTypeName();
18203 const GLchar* var_use = input_use;
18205 if (false == test_case.m_is_input)
18209 var_use = output_use;
18212 sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
18213 sprintf(buffer_goten, "%d", test_case.m_component_goten);
18217 case Utils::Shader::FRAGMENT:
18218 source = fs_tested;
18220 case Utils::Shader::GEOMETRY:
18221 source = gs_tested;
18225 case Utils::Shader::TESS_CTRL:
18226 source = tcs_tested;
18228 index = "[gl_InvocationID]";
18230 case Utils::Shader::TESS_EVAL:
18231 source = tes_tested;
18235 case Utils::Shader::VERTEX:
18236 source = vs_tested;
18239 TCU_FAIL("Invalid enum");
18243 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
18245 Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
18246 Utils::replaceToken("INTERPOLATION", position, int_gohan, source);
18247 Utils::replaceToken("DIRECTION", position, direction, source);
18248 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18249 Utils::replaceToken("ARRAY", position, array, source);
18250 Utils::replaceToken("COMPONENT", position, buffer_goten, source);
18251 Utils::replaceToken("INTERPOLATION", position, int_goten, source);
18252 Utils::replaceToken("DIRECTION", position, direction, source);
18253 Utils::replaceToken("TYPE", position, type_goten_name, source);
18254 Utils::replaceToken("ARRAY", position, array, source);
18257 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
18259 if (true == test_case.m_is_input)
18261 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18262 Utils::replaceToken("TYPE", position, type_goten_name, source);
18266 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18267 Utils::replaceToken("TYPE", position, type_goten_name, source);
18268 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18269 Utils::replaceToken("TYPE", position, type_goten_name, source);
18272 Utils::replaceAllTokens("INDEX", index, source);
18278 case Utils::Shader::FRAGMENT:
18281 case Utils::Shader::GEOMETRY:
18284 case Utils::Shader::TESS_CTRL:
18287 case Utils::Shader::TESS_EVAL:
18290 case Utils::Shader::VERTEX:
18294 TCU_FAIL("Invalid enum");
18301 /** Get description of test case
18303 * @param test_case_index Index of test case
18305 * @return Test case description
18307 std::string VaryingLocationAliasingWithMixedInterpolationTest::getTestCaseName(GLuint test_case_index)
18309 std::stringstream stream;
18310 testCase& test_case = m_test_cases[test_case_index];
18312 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", "
18313 << getInterpolationQualifier(test_case.m_interpolation_gohan) << " "
18314 << test_case.m_type_gohan.GetGLSLTypeName() << " at " << test_case.m_component_gohan << ", "
18315 << getInterpolationQualifier(test_case.m_interpolation_goten) << " "
18316 << test_case.m_type_goten.GetGLSLTypeName() << " at " << test_case.m_component_goten << ". Direction: ";
18318 if (true == test_case.m_is_input)
18324 stream << "output";
18327 return stream.str();
18330 /** Get number of test cases
18332 * @return Number of test cases
18334 GLuint VaryingLocationAliasingWithMixedInterpolationTest::getTestCaseNumber()
18336 return static_cast<GLuint>(m_test_cases.size());
18339 /** Selects if "compute" stage is relevant for test
18345 bool VaryingLocationAliasingWithMixedInterpolationTest::isComputeRelevant(GLuint /* test_case_index */)
18350 /** Prepare all test cases
18353 void VaryingLocationAliasingWithMixedInterpolationTest::testInit()
18355 static const GLuint n_components_per_location = 4;
18356 const GLuint n_types = getTypesNumber();
18358 for (GLuint i = 0; i < n_types; ++i)
18360 const Utils::Type& type_gohan = getType(i);
18361 const bool is_float_type_gohan = isFloatType(type_gohan);
18363 /* Skip matrices */
18364 if (1 != type_gohan.m_n_columns)
18369 for (GLuint j = 0; j < n_types; ++j)
18371 const Utils::Type& type_goten = getType(j);
18372 const bool is_float_type_goten = isFloatType(type_goten);
18374 /* Skip matrices */
18375 if (1 != type_goten.m_n_columns)
18380 /* Skip invalid combinations */
18381 if (is_float_type_gohan != is_float_type_goten)
18386 const GLuint n_req_components_gohan = type_gohan.m_n_rows;
18387 const GLuint n_req_components_goten = type_goten.m_n_rows;
18389 /* Skip pairs that cannot fit into one location */
18390 if (n_components_per_location < (n_req_components_gohan + n_req_components_goten))
18395 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
18397 /* Skip compute shader */
18398 if (Utils::Shader::COMPUTE == stage)
18403 const GLuint gohan = 0;
18404 const GLuint goten = gohan + n_req_components_gohan;
18406 for (GLuint int_gohan = 0; int_gohan < INTERPOLATION_MAX; ++int_gohan)
18408 for (GLuint int_goten = 0; int_goten < INTERPOLATION_MAX; ++int_goten)
18410 const bool is_gohan_double = (Utils::Type::Double == type_gohan.m_basic_type) ? true : false;
18411 const bool is_goten_double = (Utils::Type::Double == type_goten.m_basic_type) ? true : false;
18412 const bool is_gohan_flat = (FLAT == int_gohan) ? true : false;
18413 const bool is_goten_flat = (FLAT == int_goten) ? true : false;
18414 const bool is_gohan_accepted_as_fs_in =
18415 (is_gohan_double && is_gohan_flat) || (!is_gohan_double);
18416 const bool is_goten_accepted_as_fs_in =
18417 (is_goten_double && is_goten_flat) || (!is_goten_double);
18418 const bool is_comb_accepted_as_fs_in = is_gohan_accepted_as_fs_in && is_goten_accepted_as_fs_in;
18420 /* Skip when both are the same */
18421 if (int_gohan == int_goten)
18426 testCase test_case_in = { gohan,
18428 (INTERPOLATIONS)int_gohan,
18429 (INTERPOLATIONS)int_goten,
18431 (Utils::Shader::STAGES)stage,
18435 testCase test_case_out = { gohan,
18437 (INTERPOLATIONS)int_gohan,
18438 (INTERPOLATIONS)int_goten,
18440 (Utils::Shader::STAGES)stage,
18446 * fragment shader when not flat double is used
18448 if ((Utils::Shader::VERTEX != stage) &&
18449 ((Utils::Shader::FRAGMENT != stage) || (true == is_comb_accepted_as_fs_in)))
18451 m_test_cases.push_back(test_case_in);
18454 /* Skip outputs in fragment shader */
18455 if (Utils::Shader::FRAGMENT != stage)
18457 m_test_cases.push_back(test_case_out);
18466 /** Get interpolation qualifier
18468 * @param interpolation Enumeration
18470 * @return GLSL qualifier
18472 const GLchar* VaryingLocationAliasingWithMixedInterpolationTest::getInterpolationQualifier(INTERPOLATIONS interpolation)
18474 const GLchar* result = 0;
18476 switch (interpolation)
18484 case NO_PERSPECTIVE:
18485 result = "noperspective";
18488 TCU_FAIL("Invalid enum");
18494 /** Check if given type is float
18496 * @param type Type in question
18498 * @return true if tpye is float, false otherwise
18500 bool VaryingLocationAliasingWithMixedInterpolationTest::isFloatType(const Utils::Type& type)
18502 bool is_float = false;
18504 if ((Utils::Type::Double == type.m_basic_type) || (Utils::Type::Float == type.m_basic_type))
18514 * @param context Test framework context
18516 VaryingLocationAliasingWithMixedAuxiliaryStorageTest::VaryingLocationAliasingWithMixedAuxiliaryStorageTest(
18517 deqp::Context& context)
18518 : NegativeTestBase(
18519 context, "varying_location_aliasing_with_mixed_auxiliary_storage",
18520 "Test verifies that compiler reports error when auxiliary storage qualifiers are mixed at one location")
18524 /** Source for given test case and stage
18526 * @param test_case_index Index of test case
18527 * @param stage Shader stage
18529 * @return Shader source
18531 std::string VaryingLocationAliasingWithMixedAuxiliaryStorageTest::getShaderSource(GLuint test_case_index,
18532 Utils::Shader::STAGES stage)
18534 static const GLchar* var_definition =
18535 "layout (location = 1, component = COMPONENT) AUX INTERPOLATION DIRECTION TYPE gohanARRAY;\n"
18536 "layout (location = 1, component = COMPONENT) AUX INTERPOLATION DIRECTION TYPE gotenARRAY;\n";
18537 static const GLchar* input_use = " if ((TYPE(0) == gohanINDEX_GOHAN) &&\n"
18538 " (TYPE(1) == gotenINDEX_GOTEN) )\n"
18540 " result += vec4(1, 0.5, 0.25, 0.125);\n"
18542 static const GLchar* output_use = " gohanINDEX_GOHAN = TYPE(0);\n"
18543 " gotenINDEX_GOTEN = TYPE(1);\n"
18544 " if (vec4(0) == result)\n"
18546 " gohanINDEX_GOHAN = TYPE(1);\n"
18547 " gotenINDEX_GOTEN = TYPE(0);\n"
18549 static const GLchar* fs = "#version 430 core\n"
18550 "#extension GL_ARB_enhanced_layouts : require\n"
18553 "out vec4 fs_out;\n"
18557 " fs_out = gs_fs;\n"
18560 static const GLchar* fs_tested = "#version 430 core\n"
18561 "#extension GL_ARB_enhanced_layouts : require\n"
18566 "out vec4 fs_out;\n"
18570 " vec4 result = gs_fs;\n"
18574 " fs_out = result;\n"
18577 static const GLchar* gs = "#version 430 core\n"
18578 "#extension GL_ARB_enhanced_layouts : require\n"
18580 "layout(points) in;\n"
18581 "layout(triangle_strip, max_vertices = 4) out;\n"
18583 "in vec4 tes_gs[];\n"
18584 "out vec4 gs_fs;\n"
18588 " gs_fs = tes_gs[0];\n"
18589 " gl_Position = vec4(-1, -1, 0, 1);\n"
18591 " gs_fs = tes_gs[0];\n"
18592 " gl_Position = vec4(-1, 1, 0, 1);\n"
18594 " gs_fs = tes_gs[0];\n"
18595 " gl_Position = vec4(1, -1, 0, 1);\n"
18597 " gs_fs = tes_gs[0];\n"
18598 " gl_Position = vec4(1, 1, 0, 1);\n"
18602 static const GLchar* gs_tested = "#version 430 core\n"
18603 "#extension GL_ARB_enhanced_layouts : require\n"
18605 "layout(points) in;\n"
18606 "layout(triangle_strip, max_vertices = 4) out;\n"
18610 "in vec4 tes_gs[];\n"
18611 "out vec4 gs_fs;\n"
18615 " vec4 result = tes_gs[0];\n"
18619 " gs_fs = result;\n"
18620 " gl_Position = vec4(-1, -1, 0, 1);\n"
18622 " gs_fs = result;\n"
18623 " gl_Position = vec4(-1, 1, 0, 1);\n"
18625 " gs_fs = result;\n"
18626 " gl_Position = vec4(1, -1, 0, 1);\n"
18628 " gs_fs = result;\n"
18629 " gl_Position = vec4(1, 1, 0, 1);\n"
18633 static const GLchar* tcs = "#version 430 core\n"
18634 "#extension GL_ARB_enhanced_layouts : require\n"
18636 "layout(vertices = 1) out;\n"
18638 "in vec4 vs_tcs[];\n"
18639 "out vec4 tcs_tes[];\n"
18644 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
18646 " gl_TessLevelOuter[0] = 1.0;\n"
18647 " gl_TessLevelOuter[1] = 1.0;\n"
18648 " gl_TessLevelOuter[2] = 1.0;\n"
18649 " gl_TessLevelOuter[3] = 1.0;\n"
18650 " gl_TessLevelInner[0] = 1.0;\n"
18651 " gl_TessLevelInner[1] = 1.0;\n"
18654 static const GLchar* tcs_tested = "#version 430 core\n"
18655 "#extension GL_ARB_enhanced_layouts : require\n"
18657 "layout(vertices = 1) out;\n"
18661 "in vec4 vs_tcs[];\n"
18662 "out vec4 tcs_tes[];\n"
18666 " vec4 result = vs_tcs[gl_InvocationID];\n"
18670 " tcs_tes[gl_InvocationID] = result;\n"
18672 " gl_TessLevelOuter[0] = 1.0;\n"
18673 " gl_TessLevelOuter[1] = 1.0;\n"
18674 " gl_TessLevelOuter[2] = 1.0;\n"
18675 " gl_TessLevelOuter[3] = 1.0;\n"
18676 " gl_TessLevelInner[0] = 1.0;\n"
18677 " gl_TessLevelInner[1] = 1.0;\n"
18680 static const GLchar* tes = "#version 430 core\n"
18681 "#extension GL_ARB_enhanced_layouts : require\n"
18683 "layout(isolines, point_mode) in;\n"
18685 "in vec4 tcs_tes[];\n"
18686 "out vec4 tes_gs;\n"
18690 " tes_gs = tcs_tes[0];\n"
18693 static const GLchar* tes_tested = "#version 430 core\n"
18694 "#extension GL_ARB_enhanced_layouts : require\n"
18696 "layout(isolines, point_mode) in;\n"
18700 "in vec4 tcs_tes[];\n"
18701 "out vec4 tes_gs;\n"
18705 " vec4 result = tcs_tes[0];\n"
18709 " tes_gs += result;\n"
18712 static const GLchar* vs = "#version 430 core\n"
18713 "#extension GL_ARB_enhanced_layouts : require\n"
18716 "out vec4 vs_tcs;\n"
18720 " vs_tcs = in_vs;\n"
18723 static const GLchar* vs_tested = "#version 430 core\n"
18724 "#extension GL_ARB_enhanced_layouts : require\n"
18729 "out vec4 vs_tcs;\n"
18733 " vec4 result = in_vs;\n"
18737 " vs_tcs += result;\n"
18741 std::string source;
18742 testCase& test_case = m_test_cases[test_case_index];
18744 if (test_case.m_stage == stage)
18746 const GLchar* array_gohan = "";
18747 const GLchar* array_goten = "";
18748 const GLchar* aux_gohan = getAuxiliaryQualifier(test_case.m_aux_gohan);
18749 const GLchar* aux_goten = getAuxiliaryQualifier(test_case.m_aux_goten);
18750 GLchar buffer_gohan[16];
18751 GLchar buffer_goten[16];
18752 const GLchar* direction = "in ";
18753 const GLchar* index_gohan = "";
18754 const GLchar* index_goten = "";
18755 const GLchar* int_gohan = test_case.m_int_gohan;
18756 const GLchar* int_goten = test_case.m_int_goten;
18757 size_t position = 0;
18759 const GLchar* type_gohan_name = test_case.m_type_gohan.GetGLSLTypeName();
18760 const GLchar* type_goten_name = test_case.m_type_goten.GetGLSLTypeName();
18761 const GLchar* var_use = input_use;
18763 if (false == test_case.m_is_input)
18767 var_use = output_use;
18770 sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
18771 sprintf(buffer_goten, "%d", test_case.m_component_goten);
18775 case Utils::Shader::FRAGMENT:
18776 source = fs_tested;
18778 case Utils::Shader::GEOMETRY:
18779 source = gs_tested;
18780 array_gohan = "[]";
18781 index_gohan = "[0]";
18782 array_goten = "[]";
18783 index_goten = "[0]";
18785 case Utils::Shader::TESS_CTRL:
18786 source = tcs_tested;
18787 if (PATCH != test_case.m_aux_gohan)
18789 array_gohan = "[]";
18790 index_gohan = "[gl_InvocationID]";
18792 if (PATCH != test_case.m_aux_goten)
18794 array_goten = "[]";
18795 index_goten = "[gl_InvocationID]";
18798 case Utils::Shader::TESS_EVAL:
18799 source = tes_tested;
18800 array_gohan = "[]";
18801 index_gohan = "[0]";
18802 array_goten = "[]";
18803 index_goten = "[0]";
18805 case Utils::Shader::VERTEX:
18806 source = vs_tested;
18809 TCU_FAIL("Invalid enum");
18813 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
18815 Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
18816 Utils::replaceToken("AUX", position, aux_gohan, source);
18817 Utils::replaceToken("INTERPOLATION", position, int_gohan, source);
18818 Utils::replaceToken("DIRECTION", position, direction, source);
18819 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18820 Utils::replaceToken("ARRAY", position, array_gohan, source);
18821 Utils::replaceToken("COMPONENT", position, buffer_goten, source);
18822 Utils::replaceToken("AUX", position, aux_goten, source);
18823 Utils::replaceToken("INTERPOLATION", position, int_goten, source);
18824 Utils::replaceToken("DIRECTION", position, direction, source);
18825 Utils::replaceToken("TYPE", position, type_goten_name, source);
18826 Utils::replaceToken("ARRAY", position, array_goten, source);
18829 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
18831 if (true == test_case.m_is_input)
18833 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18834 Utils::replaceToken("TYPE", position, type_goten_name, source);
18838 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18839 Utils::replaceToken("TYPE", position, type_goten_name, source);
18840 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18841 Utils::replaceToken("TYPE", position, type_goten_name, source);
18844 Utils::replaceAllTokens("INDEX_GOHAN", index_gohan, source);
18845 Utils::replaceAllTokens("INDEX_GOTEN", index_goten, source);
18851 case Utils::Shader::FRAGMENT:
18854 case Utils::Shader::GEOMETRY:
18857 case Utils::Shader::TESS_CTRL:
18860 case Utils::Shader::TESS_EVAL:
18863 case Utils::Shader::VERTEX:
18867 TCU_FAIL("Invalid enum");
18874 /** Get description of test case
18876 * @param test_case_index Index of test case
18878 * @return Test case description
18880 std::string VaryingLocationAliasingWithMixedAuxiliaryStorageTest::getTestCaseName(GLuint test_case_index)
18882 std::stringstream stream;
18883 testCase& test_case = m_test_cases[test_case_index];
18885 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", "
18886 << getAuxiliaryQualifier(test_case.m_aux_gohan) << " " << test_case.m_type_gohan.GetGLSLTypeName() << " at "
18887 << test_case.m_component_gohan << ", " << getAuxiliaryQualifier(test_case.m_aux_goten) << " "
18888 << test_case.m_type_goten.GetGLSLTypeName() << " at " << test_case.m_component_goten << ". Direction: ";
18890 if (true == test_case.m_is_input)
18896 stream << "output";
18899 return stream.str();
18902 /** Get number of test cases
18904 * @return Number of test cases
18906 GLuint VaryingLocationAliasingWithMixedAuxiliaryStorageTest::getTestCaseNumber()
18908 return static_cast<GLuint>(m_test_cases.size());
18911 /** Selects if "compute" stage is relevant for test
18917 bool VaryingLocationAliasingWithMixedAuxiliaryStorageTest::isComputeRelevant(GLuint /* test_case_index */)
18922 /** Prepare all test cases
18925 void VaryingLocationAliasingWithMixedAuxiliaryStorageTest::testInit()
18927 static const GLuint n_components_per_location = 4;
18928 const GLuint n_types = getTypesNumber();
18930 for (GLuint i = 0; i < n_types; ++i)
18932 const Utils::Type& type_gohan = getType(i);
18933 const bool is_float_type_gohan = isFloatType(type_gohan);
18935 /* Skip matrices */
18936 if (1 != type_gohan.m_n_columns)
18941 for (GLuint j = 0; j < n_types; ++j)
18943 const Utils::Type& type_goten = getType(j);
18944 const bool is_flat_req_gohan = (Utils::Type::Float == type_gohan.m_basic_type) ? false : true;
18945 const bool is_flat_req_goten = (Utils::Type::Float == type_goten.m_basic_type) ? false : true;
18946 const bool is_float_type_goten = isFloatType(type_goten);
18948 /* Skip matrices */
18949 if (1 != type_goten.m_n_columns)
18954 /* Skip invalid combinations */
18955 if (is_float_type_gohan != is_float_type_goten)
18960 const GLuint n_req_components_gohan = type_gohan.m_n_rows;
18961 const GLuint n_req_components_goten = type_goten.m_n_rows;
18963 /* Skip pairs that cannot fit into one location */
18964 if (n_components_per_location < (n_req_components_gohan + n_req_components_goten))
18969 const GLuint gohan = 0;
18970 const GLuint goten = gohan + n_req_components_gohan;
18972 const GLchar* fs_int_gohan = is_flat_req_gohan ? "flat" : "";
18973 const GLchar* fs_int_goten = is_flat_req_goten ? "flat" : "";
18975 testCase test_case_tcs_np = { gohan, goten, NONE, PATCH, "", "", false, Utils::Shader::TESS_CTRL,
18976 type_gohan, type_goten };
18978 testCase test_case_tcs_pn = { gohan, goten, PATCH, NONE, "", "", false, Utils::Shader::TESS_CTRL,
18979 type_gohan, type_goten };
18981 testCase test_case_tes_np = { gohan, goten, NONE, PATCH, "", "", true, Utils::Shader::TESS_EVAL,
18982 type_gohan, type_goten };
18984 testCase test_case_tes_pn = { gohan, goten, PATCH, NONE, "", "", true, Utils::Shader::TESS_EVAL,
18985 type_gohan, type_goten };
18987 testCase test_case_fs_nc = { gohan, goten, NONE, CENTROID,
18988 fs_int_gohan, fs_int_goten, true, Utils::Shader::FRAGMENT,
18989 type_gohan, type_goten };
18991 testCase test_case_fs_cn = { gohan, goten, CENTROID, NONE,
18992 fs_int_gohan, fs_int_goten, true, Utils::Shader::FRAGMENT,
18993 type_gohan, type_goten };
18995 testCase test_case_fs_ns = { gohan, goten, NONE, SAMPLE,
18996 fs_int_gohan, fs_int_goten, true, Utils::Shader::FRAGMENT,
18997 type_gohan, type_goten };
18999 testCase test_case_fs_sn = { gohan, goten, SAMPLE, NONE,
19000 fs_int_gohan, fs_int_goten, true, Utils::Shader::FRAGMENT,
19001 type_gohan, type_goten };
19003 testCase test_case_fs_cs = { gohan, goten, CENTROID, SAMPLE,
19004 fs_int_gohan, fs_int_goten, true, Utils::Shader::FRAGMENT,
19005 type_gohan, type_goten };
19007 testCase test_case_fs_sc = { gohan, goten, SAMPLE, CENTROID,
19008 fs_int_gohan, fs_int_goten, true, Utils::Shader::FRAGMENT,
19009 type_gohan, type_goten };
19011 m_test_cases.push_back(test_case_tcs_np);
19012 m_test_cases.push_back(test_case_tcs_pn);
19013 m_test_cases.push_back(test_case_tes_np);
19014 m_test_cases.push_back(test_case_tes_pn);
19015 m_test_cases.push_back(test_case_fs_nc);
19016 m_test_cases.push_back(test_case_fs_cn);
19017 m_test_cases.push_back(test_case_fs_ns);
19018 m_test_cases.push_back(test_case_fs_sn);
19019 m_test_cases.push_back(test_case_fs_cs);
19020 m_test_cases.push_back(test_case_fs_sc);
19025 /** Get auxiliary storage qualifier
19027 * @param aux Enumeration
19029 * @return GLSL qualifier
19031 const GLchar* VaryingLocationAliasingWithMixedAuxiliaryStorageTest::getAuxiliaryQualifier(AUXILIARIES aux)
19033 const GLchar* result = 0;
19044 result = "centroid";
19050 TCU_FAIL("Invalid enum");
19056 /** Check if given type is float
19058 * @param type Type in question
19060 * @return true if tpye is float, false otherwise
19062 bool VaryingLocationAliasingWithMixedAuxiliaryStorageTest::isFloatType(const Utils::Type& type)
19064 bool is_float = false;
19066 if ((Utils::Type::Double == type.m_basic_type) || (Utils::Type::Float == type.m_basic_type))
19074 /* Constants used by VertexAttribLocationAPITest */
19075 const GLuint VertexAttribLocationAPITest::m_goten_location = 6;
19079 * @param context Test framework context
19081 VertexAttribLocationAPITest::VertexAttribLocationAPITest(deqp::Context& context)
19082 : TextureTestBase(context, "vertex_attrib_location_api",
19083 "Test verifies that attribute locations API works as expected")
19087 /** Does BindAttribLocation for "goten" and relink program
19089 * @param program Program object
19090 * @param program_interface Interface of program
19092 void VertexAttribLocationAPITest::prepareAttribLocation(Utils::Program& program,
19093 Utils::ProgramInterface& program_interface)
19095 const Functions& gl = m_context.getRenderContext().getFunctions();
19097 gl.bindAttribLocation(program.m_id, m_goten_location, "goten");
19098 GLU_EXPECT_NO_ERROR(gl.getError(), "BindAttribLocation");
19100 program.Link(gl, program.m_id);
19102 /* We still need to get locations for gohan and chichi */
19103 TextureTestBase::prepareAttribLocation(program, program_interface);
19106 /** Get interface of program
19109 * @param program_interface Interface of program
19112 void VertexAttribLocationAPITest::getProgramInterface(GLuint /* test_case_index */,
19113 Utils::ProgramInterface& program_interface,
19114 Utils::VaryingPassthrough& /* varying_passthrough */)
19116 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
19117 const Utils::Type& type = Utils::Type::vec4;
19118 const GLuint type_size = type.GetSize();
19121 const GLuint chichi_offset = 0;
19122 const GLuint goten_offset = chichi_offset + type_size;
19123 const GLuint gohan_offset = goten_offset + type_size;
19124 const GLuint goku_offset = gohan_offset + type_size;
19127 const GLuint goku_location = 2;
19128 const GLuint goten_location = m_goten_location;
19130 /* Generate data */
19131 m_goku_data = type.GenerateDataPacked();
19132 m_gohan_data = type.GenerateDataPacked();
19133 m_goten_data = type.GenerateDataPacked();
19134 m_chichi_data = type.GenerateDataPacked();
19137 si.m_globals = "const uint GOKU_LOCATION = 2;\n";
19140 si.Input("goku" /* name */, "layout (location = GOKU_LOCATION)" /* qualifiers */, 0 /* expected_componenet */,
19141 goku_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19142 0u /* n_array_elements */, 0u /* stride */, goku_offset /* offset */, (GLvoid*)&m_goku_data[0] /* data */,
19143 m_goku_data.size() /* data_size */);
19145 si.Input("gohan" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19146 Utils::Variable::m_automatic_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19147 0u /* n_array_elements */, 0u /* stride */, gohan_offset /* offset */,
19148 (GLvoid*)&m_gohan_data[0] /* data */, m_gohan_data.size() /* data_size */);
19150 si.Input("goten" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19151 goten_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19152 0u /* n_array_elements */, 0u /* stride */, goten_offset /* offset */,
19153 (GLvoid*)&m_goten_data[0] /* data */, m_goten_data.size() /* data_size */);
19155 si.Input("chichi" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19156 Utils::Variable::m_automatic_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19157 0u /* n_array_elements */, 0u /* stride */, chichi_offset /* offset */,
19158 (GLvoid*)&m_chichi_data[0] /* data */, m_chichi_data.size() /* data_size */);
19161 /** Selects if "compute" stage is relevant for test
19167 bool VertexAttribLocationAPITest::isComputeRelevant(GLuint /* test_case_index */)
19172 /* Constants used by FragmentDataLocationAPITest */
19173 const GLuint FragmentDataLocationAPITest::m_goten_location = 6;
19177 * @param context Test framework context
19179 FragmentDataLocationAPITest::FragmentDataLocationAPITest(deqp::Context& context)
19180 : TextureTestBase(context, "fragment_data_location_api",
19181 "Test verifies that fragment data locations API works as expected")
19185 , m_chichi(context)
19189 /** Verifies contents of drawn images
19194 * @return true if images are filled with expected values, false otherwise
19196 bool FragmentDataLocationAPITest::checkResults(glw::GLuint /* test_case_index */, Utils::Texture& /* color_0 */)
19198 static const GLuint size = m_width * m_height;
19199 static const GLuint expected_goku = 0xff000000;
19200 static const GLuint expected_gohan = 0xff0000ff;
19201 static const GLuint expected_goten = 0xff00ff00;
19202 static const GLuint expected_chichi = 0xffff0000;
19204 std::vector<GLuint> data;
19207 m_goku.Get(GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
19209 for (GLuint i = 0; i < size; ++i)
19211 const GLuint color = data[i];
19213 if (expected_goku != color)
19215 m_context.getTestContext().getLog() << tcu::TestLog::Message << "RGBA8[" << i << "]:" << color
19216 << tcu::TestLog::EndMessage;
19221 m_gohan.Get(GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
19223 for (GLuint i = 0; i < size; ++i)
19225 const GLuint color = data[i];
19227 if (expected_gohan != color)
19229 m_context.getTestContext().getLog() << tcu::TestLog::Message << "RGBA8[" << i << "]:" << color
19230 << tcu::TestLog::EndMessage;
19235 m_goten.Get(GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
19237 for (GLuint i = 0; i < size; ++i)
19239 const GLuint color = data[i];
19241 if (expected_goten != color)
19243 m_context.getTestContext().getLog() << tcu::TestLog::Message << "RGBA8[" << i << "]:" << color
19244 << tcu::TestLog::EndMessage;
19249 m_chichi.Get(GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
19251 for (GLuint i = 0; i < size; ++i)
19253 const GLuint color = data[i];
19255 if (expected_chichi != color)
19257 m_context.getTestContext().getLog() << tcu::TestLog::Message << "RGBA8[" << i << "]:" << color
19258 << tcu::TestLog::EndMessage;
19266 /** Prepare code snippet that will set out variables
19270 * @param stage Shader stage
19272 * @return Code that pass in variables to next stage
19274 std::string FragmentDataLocationAPITest::getPassSnippet(GLuint /* test_case_index */,
19275 Utils::VaryingPassthrough& /* varying_passthrough */,
19276 Utils::Shader::STAGES stage)
19278 std::string result;
19280 /* Skip for compute shader */
19281 if (Utils::Shader::FRAGMENT != stage)
19287 result = "chichi = vec4(0, 0, 1, 1);\n"
19288 " goku = vec4(0, 0, 0, 1);\n"
19289 " goten = vec4(0, 1, 0, 1);\n"
19290 " gohan = vec4(1, 0, 0, 1);\n";
19296 /** Get interface of program
19299 * @param program_interface Interface of program
19302 void FragmentDataLocationAPITest::getProgramInterface(GLuint /* test_case_index */,
19303 Utils::ProgramInterface& program_interface,
19304 Utils::VaryingPassthrough& /* varying_passthrough */)
19306 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
19307 const Utils::Type& type = Utils::Type::vec4;
19310 m_goku_location = 2;
19313 si.m_globals = "const uint GOKU_LOCATION = 2;\n";
19316 si.Output("goku" /* name */, "layout (location = GOKU_LOCATION)" /* qualifiers */, 0 /* expected_componenet */,
19317 m_goku_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19318 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)0 /* data */, 0u /* data_size */);
19320 si.Output("gohan" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19321 Utils::Variable::m_automatic_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19322 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)0 /* data */, 0u /* data_size */);
19324 si.Output("goten" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19325 m_goten_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19326 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)0 /* data */, 0u /* data_size */);
19328 si.Output("chichi" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19329 Utils::Variable::m_automatic_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19330 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)0 /* data */, 0u /* data_size */);
19333 /** Selects if "compute" stage is relevant for test
19339 bool FragmentDataLocationAPITest::isComputeRelevant(GLuint /* test_case_index */)
19344 /** Get locations for all outputs with automatic_location
19346 * @param program Program object
19347 * @param program_interface Interface of program
19349 void FragmentDataLocationAPITest::prepareFragmentDataLoc(Utils::Program& program,
19350 Utils::ProgramInterface& program_interface)
19352 /* Bind location of goten */
19353 const Functions& gl = m_context.getRenderContext().getFunctions();
19355 gl.bindFragDataLocation(program.m_id, m_goten_location, "goten");
19356 GLU_EXPECT_NO_ERROR(gl.getError(), "BindFragDataLocation");
19358 program.Link(gl, program.m_id);
19360 /* Prepare locations for gohan and chichi */
19361 TextureTestBase::prepareFragmentDataLoc(program, program_interface);
19363 /* Get all locations */
19364 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
19366 Utils::Variable::PtrVector& outputs = si.m_outputs;
19368 for (Utils::Variable::PtrVector::iterator it = outputs.begin(); outputs.end() != it; ++it)
19370 const Utils::Variable::Descriptor& desc = (*it)->m_descriptor;
19372 if (0 == desc.m_name.compare("gohan"))
19374 m_gohan_location = desc.m_expected_location;
19376 else if (0 == desc.m_name.compare("chichi"))
19378 m_chichi_location = desc.m_expected_location;
19381 /* Locations of goku and goten are fixed */
19385 /** Prepare framebuffer with single texture as color attachment
19387 * @param framebuffer Framebuffer
19388 * @param color_0_texture Texture that will used as color attachment
19390 void FragmentDataLocationAPITest::prepareFramebuffer(Utils::Framebuffer& framebuffer, Utils::Texture& color_0_texture)
19392 /* Let parent prepare its stuff */
19393 TextureTestBase::prepareFramebuffer(framebuffer, color_0_texture);
19396 std::vector<GLuint> texture_data;
19397 texture_data.resize(m_width * m_height);
19399 for (GLuint i = 0; i < texture_data.size(); ++i)
19401 texture_data[i] = 0x20406080;
19404 /* Prepare textures */
19405 m_goku.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]);
19407 m_gohan.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]);
19409 m_goten.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]);
19411 m_chichi.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]);
19413 /* Attach textures to framebuffer */
19414 framebuffer.Bind();
19415 framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0 + m_goku_location, m_goku.m_id, m_width, m_height);
19416 framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0 + m_gohan_location, m_gohan.m_id, m_width, m_height);
19417 framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0 + m_goten_location, m_goten.m_id, m_width, m_height);
19418 framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0 + m_chichi_location, m_chichi.m_id, m_width, m_height);
19420 /* Set up drawbuffers */
19421 const Functions& gl = m_context.getRenderContext().getFunctions();
19422 // The fragment shader can have more than 4 color outputs, but it only care about 4 (goku, gohan, goten, chichi).
19423 // We will first initialize all draw buffers to NONE and then set the real value for the 4 outputs we care about
19424 GLint maxDrawBuffers = 0;
19425 gl.getIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
19427 std::vector<GLenum> buffers(maxDrawBuffers, GL_NONE);
19428 buffers[m_chichi_location] = GLenum(GL_COLOR_ATTACHMENT0 + m_chichi_location);
19429 buffers[m_goten_location] = GLenum(GL_COLOR_ATTACHMENT0 + m_goten_location);
19430 buffers[m_goku_location] = GLenum(GL_COLOR_ATTACHMENT0 + m_goku_location);
19431 buffers[m_gohan_location] = GLenum(GL_COLOR_ATTACHMENT0 + m_gohan_location);
19433 gl.drawBuffers(maxDrawBuffers, buffers.data());
19434 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawBuffers");
19439 * @param context Test framework context
19441 XFBInputTest::XFBInputTest(deqp::Context& context)
19442 : NegativeTestBase(context, "xfb_input",
19443 "Test verifies that compiler reports error when xfb qualifiers are used with input")
19447 /** Source for given test case and stage
19449 * @param test_case_index Index of test case
19450 * @param stage Shader stage
19452 * @return Shader source
19454 std::string XFBInputTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
19456 static const GLchar* buffer_var_definition = "layout (xfb_buffer = 2) in vec4 gohanARRAY;\n";
19457 static const GLchar* offset_var_definition = "layout (xfb_offset = 16) in vec4 gohanARRAY;\n";
19458 static const GLchar* stride_var_definition = "layout (xfb_stride = 32) in vec4 gohanARRAY;\n";
19459 static const GLchar* input_use = " result += gohanINDEX;\n";
19460 static const GLchar* fs = "#version 430 core\n"
19461 "#extension GL_ARB_enhanced_layouts : require\n"
19464 "out vec4 fs_out;\n"
19468 " fs_out = gs_fs;\n"
19471 static const GLchar* fs_tested = "#version 430 core\n"
19472 "#extension GL_ARB_enhanced_layouts : require\n"
19477 "out vec4 fs_out;\n"
19481 " vec4 result = gs_fs;\n"
19485 " fs_out = result;\n"
19488 static const GLchar* gs = "#version 430 core\n"
19489 "#extension GL_ARB_enhanced_layouts : require\n"
19491 "layout(points) in;\n"
19492 "layout(triangle_strip, max_vertices = 4) out;\n"
19494 "in vec4 tes_gs[];\n"
19495 "out vec4 gs_fs;\n"
19499 " gs_fs = tes_gs[0];\n"
19500 " gl_Position = vec4(-1, -1, 0, 1);\n"
19502 " gs_fs = tes_gs[0];\n"
19503 " gl_Position = vec4(-1, 1, 0, 1);\n"
19505 " gs_fs = tes_gs[0];\n"
19506 " gl_Position = vec4(1, -1, 0, 1);\n"
19508 " gs_fs = tes_gs[0];\n"
19509 " gl_Position = vec4(1, 1, 0, 1);\n"
19513 static const GLchar* gs_tested = "#version 430 core\n"
19514 "#extension GL_ARB_enhanced_layouts : require\n"
19516 "layout(points) in;\n"
19517 "layout(triangle_strip, max_vertices = 4) out;\n"
19521 "in vec4 tes_gs[];\n"
19522 "out vec4 gs_fs;\n"
19526 " vec4 result = tes_gs[0];\n"
19530 " gs_fs = result;\n"
19531 " gl_Position = vec4(-1, -1, 0, 1);\n"
19533 " gs_fs = result;\n"
19534 " gl_Position = vec4(-1, 1, 0, 1);\n"
19536 " gs_fs = result;\n"
19537 " gl_Position = vec4(1, -1, 0, 1);\n"
19539 " gs_fs = result;\n"
19540 " gl_Position = vec4(1, 1, 0, 1);\n"
19544 static const GLchar* tcs = "#version 430 core\n"
19545 "#extension GL_ARB_enhanced_layouts : require\n"
19547 "layout(vertices = 1) out;\n"
19549 "in vec4 vs_tcs[];\n"
19550 "out vec4 tcs_tes[];\n"
19555 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
19557 " gl_TessLevelOuter[0] = 1.0;\n"
19558 " gl_TessLevelOuter[1] = 1.0;\n"
19559 " gl_TessLevelOuter[2] = 1.0;\n"
19560 " gl_TessLevelOuter[3] = 1.0;\n"
19561 " gl_TessLevelInner[0] = 1.0;\n"
19562 " gl_TessLevelInner[1] = 1.0;\n"
19565 static const GLchar* tcs_tested = "#version 430 core\n"
19566 "#extension GL_ARB_enhanced_layouts : require\n"
19568 "layout(vertices = 1) out;\n"
19572 "in vec4 vs_tcs[];\n"
19573 "out vec4 tcs_tes[];\n"
19577 " vec4 result = vs_tcs[gl_InvocationID];\n"
19581 " tcs_tes[gl_InvocationID] = result;\n"
19583 " gl_TessLevelOuter[0] = 1.0;\n"
19584 " gl_TessLevelOuter[1] = 1.0;\n"
19585 " gl_TessLevelOuter[2] = 1.0;\n"
19586 " gl_TessLevelOuter[3] = 1.0;\n"
19587 " gl_TessLevelInner[0] = 1.0;\n"
19588 " gl_TessLevelInner[1] = 1.0;\n"
19591 static const GLchar* tes = "#version 430 core\n"
19592 "#extension GL_ARB_enhanced_layouts : require\n"
19594 "layout(isolines, point_mode) in;\n"
19596 "in vec4 tcs_tes[];\n"
19597 "out vec4 tes_gs;\n"
19601 " tes_gs = tcs_tes[0];\n"
19604 static const GLchar* tes_tested = "#version 430 core\n"
19605 "#extension GL_ARB_enhanced_layouts : require\n"
19607 "layout(isolines, point_mode) in;\n"
19611 "in vec4 tcs_tes[];\n"
19612 "out vec4 tes_gs;\n"
19616 " vec4 result = tcs_tes[0];\n"
19620 " tes_gs += result;\n"
19623 static const GLchar* vs = "#version 430 core\n"
19624 "#extension GL_ARB_enhanced_layouts : require\n"
19627 "out vec4 vs_tcs;\n"
19631 " vs_tcs = in_vs;\n"
19634 static const GLchar* vs_tested = "#version 430 core\n"
19635 "#extension GL_ARB_enhanced_layouts : require\n"
19640 "out vec4 vs_tcs;\n"
19644 " vec4 result = in_vs;\n"
19648 " vs_tcs += result;\n"
19652 std::string source;
19653 testCase& test_case = m_test_cases[test_case_index];
19655 if (test_case.m_stage == stage)
19657 const GLchar* array = "";
19658 const GLchar* index = "";
19659 size_t position = 0;
19661 const GLchar* var_definition = 0;
19662 const GLchar* var_use = input_use;
19664 switch (test_case.m_qualifier)
19667 var_definition = buffer_var_definition;
19670 var_definition = offset_var_definition;
19673 var_definition = stride_var_definition;
19676 TCU_FAIL("Invalid enum");
19681 case Utils::Shader::FRAGMENT:
19682 source = fs_tested;
19684 case Utils::Shader::GEOMETRY:
19685 source = gs_tested;
19689 case Utils::Shader::TESS_CTRL:
19690 source = tcs_tested;
19692 index = "[gl_InvocationID]";
19694 case Utils::Shader::TESS_EVAL:
19695 source = tes_tested;
19699 case Utils::Shader::VERTEX:
19700 source = vs_tested;
19703 TCU_FAIL("Invalid enum");
19707 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
19709 Utils::replaceToken("ARRAY", position, array, source);
19710 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
19712 Utils::replaceAllTokens("INDEX", index, source);
19718 case Utils::Shader::FRAGMENT:
19721 case Utils::Shader::GEOMETRY:
19724 case Utils::Shader::TESS_CTRL:
19727 case Utils::Shader::TESS_EVAL:
19730 case Utils::Shader::VERTEX:
19734 TCU_FAIL("Invalid enum");
19741 /** Get description of test case
19743 * @param test_case_index Index of test case
19745 * @return Test case description
19747 std::string XFBInputTest::getTestCaseName(GLuint test_case_index)
19749 std::stringstream stream;
19750 testCase& test_case = m_test_cases[test_case_index];
19752 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", qualifier: ";
19754 switch (test_case.m_qualifier)
19757 stream << "xfb_buffer";
19760 stream << "xfb_offset";
19763 stream << "xfb_stride";
19766 TCU_FAIL("Invalid enum");
19769 return stream.str();
19772 /** Get number of test cases
19774 * @return Number of test cases
19776 GLuint XFBInputTest::getTestCaseNumber()
19778 return static_cast<GLuint>(m_test_cases.size());
19781 /** Selects if "compute" stage is relevant for test
19787 bool XFBInputTest::isComputeRelevant(GLuint /* test_case_index */)
19792 /** Prepare all test cases
19795 void XFBInputTest::testInit()
19797 for (GLuint qualifier = 0; qualifier < QUALIFIERS_MAX; ++qualifier)
19799 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
19801 if (Utils::Shader::COMPUTE == stage)
19806 testCase test_case = { (QUALIFIERS)qualifier, (Utils::Shader::STAGES)stage };
19808 m_test_cases.push_back(test_case);
19813 /* Constants used by XFBAllStagesTest */
19814 const GLuint XFBAllStagesTest::m_gs_index = 3;
19818 * @param context Test context
19820 XFBAllStagesTest::XFBAllStagesTest(deqp::Context& context)
19821 : BufferTestBase(context, "xfb_all_stages",
19822 "Test verifies that only last stage in vertex processing can output to transform feedback")
19824 /* Nothing to be done here */
19827 /** Get descriptors of buffers necessary for test
19830 * @param out_descriptors Descriptors of buffers used by test
19832 void XFBAllStagesTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
19833 bufferDescriptor::Vector& out_descriptors)
19835 static const GLuint n_stages = 4;
19836 const Utils::Type& vec4 = Utils::Type::vec4;
19841 /* Test uses single uniform and xfb per stage + uniform for fragment shader */
19842 out_descriptors.resize(n_stages * 2 + 1);
19845 for (GLuint i = 0; i < n_stages; ++i)
19847 /* Get references */
19848 bufferDescriptor& uniform = out_descriptors[i + 0];
19849 bufferDescriptor& xfb = out_descriptors[i + n_stages];
19852 uniform.m_index = i;
19856 uniform.m_target = Utils::Buffer::Uniform;
19857 xfb.m_target = Utils::Buffer::Transform_feedback;
19860 const tcu::Vec4 var(Utils::GetRandFloat(), Utils::GetRandFloat(), Utils::GetRandFloat(), Utils::GetRandFloat());
19864 uniform.m_initial_data.resize(vec4.GetSize());
19865 memcpy(&uniform.m_initial_data[0], var.getPtr(), vec4.GetSize());
19867 xfb.m_initial_data = vec4.GenerateDataPacked();
19869 if (m_gs_index != i)
19871 xfb.m_expected_data = xfb.m_initial_data;
19875 xfb.m_expected_data.resize(vec4.GetSize());
19876 memcpy(&xfb.m_expected_data[0], sum.getPtr(), vec4.GetSize());
19882 /* Get reference */
19883 bufferDescriptor& uniform = out_descriptors[n_stages * 2];
19886 uniform.m_index = n_stages;
19889 uniform.m_target = Utils::Buffer::Uniform;
19892 const tcu::Vec4 var(Utils::GetRandFloat(), Utils::GetRandFloat(), Utils::GetRandFloat(), Utils::GetRandFloat());
19894 uniform.m_initial_data.resize(vec4.GetSize());
19895 memcpy(&uniform.m_initial_data[0], var.getPtr(), vec4.GetSize());
19899 /** Get body of main function for given shader stage
19902 * @param stage Shader stage
19903 * @param out_assignments Set to empty
19904 * @param out_calculations Set to empty
19906 void XFBAllStagesTest::getShaderBody(glw::GLuint /* test_case_index */, Utils::Shader::STAGES stage,
19907 std::string& out_assignments, std::string& out_calculations)
19909 out_calculations = "";
19911 static const GLchar* vs = " vs_tcs = uni_vs;\n";
19912 static const GLchar* tcs = " tcs_tes[gl_InvocationID] = uni_tcs + vs_tcs[gl_InvocationID];\n";
19913 static const GLchar* tes = " tes_gs = uni_tes + tcs_tes[0];\n";
19914 static const GLchar* gs = " gs_fs = uni_gs + tes_gs[0];\n";
19915 static const GLchar* fs = " fs_out = uni_fs + gs_fs;\n";
19917 const GLchar* assignments = 0;
19920 case Utils::Shader::FRAGMENT:
19923 case Utils::Shader::GEOMETRY:
19926 case Utils::Shader::TESS_CTRL:
19929 case Utils::Shader::TESS_EVAL:
19932 case Utils::Shader::VERTEX:
19936 TCU_FAIL("Invalid enum");
19939 out_assignments = assignments;
19942 /** Get interface of shader
19945 * @param stage Shader stage
19946 * @param out_interface Set to ""
19948 void XFBAllStagesTest::getShaderInterface(glw::GLuint /* test_case_index */, Utils::Shader::STAGES stage,
19949 std::string& out_interface)
19951 static const GLchar* vs = "layout(xfb_buffer = 0, xfb_offset = 0) out vec4 vs_tcs;\n"
19952 "layout(binding = 0) uniform vs_block {\n"
19955 static const GLchar* tcs = " in vec4 vs_tcs[];\n"
19956 "layout(xfb_buffer = 1, xfb_offset = 0) out vec4 tcs_tes[1];\n"
19957 "layout(binding = 1) uniform tcs_block {\n"
19960 static const GLchar* tes = " in vec4 tcs_tes[];\n"
19961 "layout(xfb_buffer = 2, xfb_offset = 0) out vec4 tes_gs;\n"
19962 "layout(binding = 2) uniform tes_block {\n"
19965 static const GLchar* gs = " in vec4 tes_gs[];\n"
19966 "layout(xfb_buffer = 3, xfb_offset = 0) out vec4 gs_fs;\n"
19967 "layout(binding = 3) uniform gs_block {\n"
19970 static const GLchar* fs = " in vec4 gs_fs;\n"
19971 " out vec4 fs_out;\n"
19972 "layout(binding = 4) uniform fs_block {\n"
19976 const GLchar* interface = 0;
19979 case Utils::Shader::FRAGMENT:
19982 case Utils::Shader::GEOMETRY:
19985 case Utils::Shader::TESS_CTRL:
19988 case Utils::Shader::TESS_EVAL:
19991 case Utils::Shader::VERTEX:
19995 TCU_FAIL("Invalid enum");
19998 out_interface = interface;
20001 /* Constants used by XFBStrideOfEmptyListTest */
20002 const GLuint XFBStrideOfEmptyListTest::m_stride = 64;
20006 * @param context Test context
20008 XFBStrideOfEmptyListTest::XFBStrideOfEmptyListTest(deqp::Context& context)
20010 context, "xfb_stride_of_empty_list",
20011 "Test verifies correct behavior when xfb_stride qualifier is specified but no xfb_offset is specified")
20013 /* Nothing to be done here */
20016 /** Execute drawArrays for single vertex
20018 * @param test_case_index Index of test case
20020 * @return true if proper error is reported
20022 bool XFBStrideOfEmptyListTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
20024 const Functions& gl = m_context.getRenderContext().getFunctions();
20025 bool result = true;
20028 gl.disable(GL_RASTERIZER_DISCARD);
20029 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
20031 gl.beginTransformFeedback(GL_POINTS);
20032 GLenum error = gl.getError();
20033 switch (test_case_index)
20036 if (GL_NO_ERROR != error)
20038 gl.endTransformFeedback();
20039 GLU_EXPECT_NO_ERROR(error, "BeginTransformFeedback");
20042 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
20043 error = gl.getError();
20045 gl.endTransformFeedback();
20046 GLU_EXPECT_NO_ERROR(error, "DrawArrays");
20047 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
20051 case FIRST_MISSING:
20052 if (GL_NO_ERROR == error)
20054 gl.endTransformFeedback();
20057 if (GL_INVALID_OPERATION != error)
20059 m_context.getTestContext().getLog()
20060 << tcu::TestLog::Message << "XFB at index 0, that is written by GS, is missing. It was expected that "
20061 "INVALID_OPERATION will generated by BeginTransformFeedback. Got: "
20062 << glu::getErrorStr(error) << tcu::TestLog::EndMessage;
20069 case SECOND_MISSING:
20070 if (GL_NO_ERROR != error)
20072 gl.endTransformFeedback();
20073 GLU_EXPECT_NO_ERROR(error, "BeginTransformFeedback");
20076 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
20077 error = gl.getError();
20079 gl.endTransformFeedback();
20080 GLU_EXPECT_NO_ERROR(error, "DrawArrays");
20081 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
20090 /** Get descriptors of buffers necessary for test
20092 * @param test_case_index Index of test case
20093 * @param out_descriptors Descriptors of buffers used by test
20095 void XFBStrideOfEmptyListTest::getBufferDescriptors(glw::GLuint test_case_index,
20096 bufferDescriptor::Vector& out_descriptors)
20098 switch (test_case_index)
20102 /* Test needs single uniform and two xfbs */
20103 out_descriptors.resize(3);
20105 /* Get references */
20106 bufferDescriptor& uniform = out_descriptors[0];
20107 bufferDescriptor& xfb_0 = out_descriptors[1];
20108 bufferDescriptor& xfb_1 = out_descriptors[2];
20111 uniform.m_index = 0;
20116 uniform.m_target = Utils::Buffer::Uniform;
20117 xfb_0.m_target = Utils::Buffer::Transform_feedback;
20118 xfb_1.m_target = Utils::Buffer::Transform_feedback;
20121 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20123 xfb_0.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20124 xfb_0.m_expected_data = uniform.m_initial_data;
20126 /* Data, contents are the same as no modification is expected */
20127 xfb_1.m_initial_data.resize(m_stride);
20128 xfb_1.m_expected_data.resize(m_stride);
20130 for (GLuint i = 0; i < m_stride; ++i)
20132 xfb_1.m_initial_data[0] = (glw::GLubyte)i;
20133 xfb_1.m_expected_data[0] = (glw::GLubyte)i;
20139 case FIRST_MISSING:
20141 /* Test needs single uniform and two xfbs */
20142 out_descriptors.resize(2);
20144 /* Get references */
20145 bufferDescriptor& uniform = out_descriptors[0];
20146 bufferDescriptor& xfb_1 = out_descriptors[1];
20149 uniform.m_index = 0;
20153 uniform.m_target = Utils::Buffer::Uniform;
20154 xfb_1.m_target = Utils::Buffer::Transform_feedback;
20157 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20159 /* Draw call will not be executed, contents does not matter */
20160 xfb_1.m_initial_data.resize(m_stride);
20165 case SECOND_MISSING:
20167 /* Test needs single uniform and two xfbs */
20168 out_descriptors.resize(2);
20170 /* Get references */
20171 bufferDescriptor& uniform = out_descriptors[0];
20172 bufferDescriptor& xfb_0 = out_descriptors[1];
20175 uniform.m_index = 0;
20179 uniform.m_target = Utils::Buffer::Uniform;
20180 xfb_0.m_target = Utils::Buffer::Transform_feedback;
20183 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20185 xfb_0.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20186 xfb_0.m_expected_data = uniform.m_initial_data;
20193 /** Get body of main function for given shader stage
20196 * @param stage Shader stage
20197 * @param out_assignments Set to empty
20198 * @param out_calculations Set to empty
20200 void XFBStrideOfEmptyListTest::getShaderBody(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
20201 std::string& out_assignments, std::string& out_calculations)
20203 out_calculations = "";
20205 static const GLchar* gs = " gs_fs = uni_gs;\n";
20206 static const GLchar* fs = " fs_out = vec4(gs_fs);\n";
20208 const GLchar* assignments = "";
20211 case Utils::Shader::FRAGMENT:
20214 case Utils::Shader::GEOMETRY:
20221 out_assignments = assignments;
20224 /** Get interface of shader
20227 * @param stage Shader stage
20228 * @param out_interface Set to ""
20230 void XFBStrideOfEmptyListTest::getShaderInterface(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
20231 std::string& out_interface)
20233 static const GLchar* gs = "layout (xfb_buffer = 0, xfb_offset = 0) out vec4 gs_fs;\n"
20234 "layout (xfb_buffer = 1, xfb_stride = 64) out;\n"
20236 "layout (binding = 0) uniform gs_block {\n"
20239 static const GLchar* fs = "in vec4 gs_fs;\n"
20240 "out vec4 fs_out;\n";
20244 case Utils::Shader::FRAGMENT:
20245 out_interface = fs;
20247 case Utils::Shader::GEOMETRY:
20248 out_interface = gs;
20251 out_interface = "";
20256 /** Returns buffer details in human readable form.
20258 * @param test_case_index Index of test case
20260 * @return Case description
20262 std::string XFBStrideOfEmptyListTest::getTestCaseName(GLuint test_case_index)
20264 std::string result;
20266 switch (test_case_index)
20269 result = "Valid case";
20271 case FIRST_MISSING:
20272 result = "Missing xfb at index 0";
20274 case SECOND_MISSING:
20275 result = "Missing xfb at index 1";
20278 TCU_FAIL("Invalid enum");
20284 /** Get number of test cases
20288 GLuint XFBStrideOfEmptyListTest::getTestCaseNumber()
20293 /* Constants used by XFBStrideOfEmptyListTest */
20294 const GLuint XFBStrideOfEmptyListAndAPITest::m_stride = 64;
20298 * @param context Test context
20300 XFBStrideOfEmptyListAndAPITest::XFBStrideOfEmptyListAndAPITest(deqp::Context& context)
20301 : BufferTestBase(context, "xfb_stride_of_empty_list_and_api",
20302 "Test verifies that xfb_stride qualifier is not overriden by API")
20304 /* Nothing to be done here */
20307 /** Execute drawArrays for single vertex
20309 * @param test_case_index Index of test case
20311 * @return true if proper error is reported
20313 bool XFBStrideOfEmptyListAndAPITest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
20315 const Functions& gl = m_context.getRenderContext().getFunctions();
20316 bool result = true;
20319 gl.disable(GL_RASTERIZER_DISCARD);
20320 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
20322 gl.beginTransformFeedback(GL_POINTS);
20323 GLenum error = gl.getError();
20324 switch (test_case_index)
20327 if (GL_NO_ERROR != error)
20329 gl.endTransformFeedback();
20330 GLU_EXPECT_NO_ERROR(error, "BeginTransformFeedback");
20333 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
20334 error = gl.getError();
20336 gl.endTransformFeedback();
20337 GLU_EXPECT_NO_ERROR(error, "DrawArrays");
20338 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
20342 case FIRST_MISSING:
20343 if (GL_NO_ERROR != error)
20345 gl.endTransformFeedback();
20346 GLU_EXPECT_NO_ERROR(error, "BeginTransformFeedback");
20349 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
20350 error = gl.getError();
20352 gl.endTransformFeedback();
20353 GLU_EXPECT_NO_ERROR(error, "DrawArrays");
20354 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
20358 case SECOND_MISSING:
20359 if (GL_NO_ERROR == error)
20361 gl.endTransformFeedback();
20364 if (GL_INVALID_OPERATION != error)
20366 m_context.getTestContext().getLog()
20367 << tcu::TestLog::Message << "XFB at index 1, that is declared as empty, is missing. It was expected "
20368 "that INVALID_OPERATION will generated by BeginTransformFeedback. Got: "
20369 << glu::getErrorStr(error) << tcu::TestLog::EndMessage;
20381 /** Get descriptors of buffers necessary for test
20383 * @param test_case_index Index of test case
20384 * @param out_descriptors Descriptors of buffers used by test
20386 void XFBStrideOfEmptyListAndAPITest::getBufferDescriptors(glw::GLuint test_case_index,
20387 bufferDescriptor::Vector& out_descriptors)
20389 switch (test_case_index)
20393 /* Test needs single uniform and two xfbs */
20394 out_descriptors.resize(3);
20396 /* Get references */
20397 bufferDescriptor& uniform = out_descriptors[0];
20398 bufferDescriptor& xfb_0 = out_descriptors[1];
20399 bufferDescriptor& xfb_1 = out_descriptors[2];
20402 uniform.m_index = 0;
20407 uniform.m_target = Utils::Buffer::Uniform;
20408 xfb_0.m_target = Utils::Buffer::Transform_feedback;
20409 xfb_1.m_target = Utils::Buffer::Transform_feedback;
20412 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20414 /* Data, contents are the same as no modification is expected */
20415 xfb_0.m_initial_data.resize(m_stride);
20416 xfb_0.m_expected_data.resize(m_stride);
20418 for (GLuint i = 0; i < m_stride; ++i)
20420 xfb_0.m_initial_data[0] = (glw::GLubyte)i;
20421 xfb_0.m_expected_data[0] = (glw::GLubyte)i;
20424 xfb_1.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20425 xfb_1.m_expected_data = uniform.m_initial_data;
20430 case FIRST_MISSING:
20432 /* Test needs single uniform and two xfbs */
20433 out_descriptors.resize(2);
20435 /* Get references */
20436 bufferDescriptor& uniform = out_descriptors[0];
20437 bufferDescriptor& xfb_1 = out_descriptors[1];
20440 uniform.m_index = 0;
20444 uniform.m_target = Utils::Buffer::Uniform;
20445 xfb_1.m_target = Utils::Buffer::Transform_feedback;
20448 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20450 /* Data, contents are the same as no modification is expected */
20451 xfb_1.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20452 xfb_1.m_expected_data = uniform.m_initial_data;
20457 case SECOND_MISSING:
20459 /* Test needs single uniform and two xfbs */
20460 out_descriptors.resize(2);
20462 /* Get references */
20463 bufferDescriptor& uniform = out_descriptors[0];
20464 bufferDescriptor& xfb_0 = out_descriptors[1];
20467 uniform.m_index = 0;
20471 uniform.m_target = Utils::Buffer::Uniform;
20472 xfb_0.m_target = Utils::Buffer::Transform_feedback;
20475 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20477 /* Draw call will not be executed, contents does not matter */
20478 xfb_0.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20485 /** Get list of names of varyings that will be registered with TransformFeedbackVaryings
20488 * @param captured_varyings Vector of varying names to be captured
20490 void XFBStrideOfEmptyListAndAPITest::getCapturedVaryings(glw::GLuint /* test_case_index */,
20491 Utils::Program::NameVector& captured_varyings,
20492 GLint* xfb_components)
20494 captured_varyings.push_back("gs_fs1");
20495 captured_varyings.push_back("gs_fs2");
20496 *xfb_components = 4;
20499 /** Get body of main function for given shader stage
20502 * @param stage Shader stage
20503 * @param out_assignments Set to empty
20504 * @param out_calculations Set to empty
20506 void XFBStrideOfEmptyListAndAPITest::getShaderBody(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
20507 std::string& out_assignments, std::string& out_calculations)
20509 out_calculations = "";
20511 static const GLchar* gs = " gs_fs1 = -uni_gs;\n"
20512 " gs_fs2 = uni_gs;\n";
20513 static const GLchar* fs = " fs_out = vec4(gs_fs2);\n";
20515 const GLchar* assignments = "";
20518 case Utils::Shader::FRAGMENT:
20521 case Utils::Shader::GEOMETRY:
20528 out_assignments = assignments;
20531 /** Get interface of shader
20534 * @param stage Shader stage
20535 * @param out_interface Set to ""
20537 void XFBStrideOfEmptyListAndAPITest::getShaderInterface(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
20538 std::string& out_interface)
20540 static const GLchar* gs = "layout (xfb_buffer = 0, xfb_stride = 64) out vec4 gs_fs1;\n"
20541 "layout (xfb_buffer = 1, xfb_offset = 0) out vec4 gs_fs2;\n"
20543 "layout(binding = 0) uniform gs_block {\n"
20546 static const GLchar* fs = "in vec4 gs_fs2;\n"
20547 "out vec4 fs_out;\n";
20551 case Utils::Shader::FRAGMENT:
20552 out_interface = fs;
20554 case Utils::Shader::GEOMETRY:
20555 out_interface = gs;
20558 out_interface = "";
20563 /** Returns buffer details in human readable form.
20565 * @param test_case_index Index of test case
20567 * @return Case description
20569 std::string XFBStrideOfEmptyListAndAPITest::getTestCaseName(GLuint test_case_index)
20571 std::string result;
20573 switch (test_case_index)
20576 result = "Valid case";
20578 case FIRST_MISSING:
20579 result = "Missing xfb at index 0";
20581 case SECOND_MISSING:
20582 result = "Missing xfb at index 1";
20585 TCU_FAIL("Invalid enum");
20591 /** Get number of test cases
20595 GLuint XFBStrideOfEmptyListAndAPITest::getTestCaseNumber()
20602 * @param context Test framework context
20604 XFBTooSmallStrideTest::XFBTooSmallStrideTest(deqp::Context& context)
20605 : NegativeTestBase(context, "xfb_too_small_stride",
20606 "Test verifies that compiler reports error when xfb_stride sets not enough space")
20610 /** Source for given test case and stage
20612 * @param test_case_index Index of test case
20613 * @param stage Shader stage
20615 * @return Shader source
20617 std::string XFBTooSmallStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
20619 static const GLchar* array_var_definition = "layout (xfb_buffer = 0, xfb_stride = 32) out;\n"
20621 "layout (xfb_offset = 16) out vec4 gohanARRAY[4];\n";
20622 static const GLchar* block_var_definition = "layout (xfb_buffer = 0, xfb_stride = 32) out;\n"
20624 "layout (xfb_offset = 0) out Goku {\n"
20629 static const GLchar* offset_var_definition = "layout (xfb_buffer = 0, xfb_stride = 40) out;\n"
20631 "layout (xfb_offset = 32) out vec4 gohanARRAY;\n";
20632 // The test considers gohan overflows the buffer 0, but according to spec, it is valid to declare the variable with qualifier "layout (xfb_offset = 16, xfb_stride = 32) out vec4 gohan;"
20633 // To make the shader failed to compile, change xfb_stride to a value that is smaller than 32
20634 static const GLchar* stride_var_definition = "layout (xfb_buffer = 0, xfb_stride = 28) out;\n"
20636 "layout (xfb_offset = 16, xfb_stride = 28) out vec4 gohanARRAY;\n";
20637 static const GLchar* array_use = " gohanINDEX[0] = result / 2;\n"
20638 " gohanINDEX[1] = result / 4;\n"
20639 " gohanINDEX[2] = result / 6;\n"
20640 " gohanINDEX[3] = result / 8;\n";
20641 static const GLchar* block_use = " gokuINDEX.gohan = result / 2;\n"
20642 " gokuINDEX.goten = result / 4;\n"
20643 " gokuINDEX.chichi = result / 6;\n";
20644 static const GLchar* output_use = "gohanINDEX = result / 4;\n";
20645 static const GLchar* fs = "#version 430 core\n"
20646 "#extension GL_ARB_enhanced_layouts : require\n"
20649 "out vec4 fs_out;\n"
20653 " fs_out = gs_fs;\n"
20656 static const GLchar* gs_tested = "#version 430 core\n"
20657 "#extension GL_ARB_enhanced_layouts : require\n"
20659 "layout(points) in;\n"
20660 "layout(triangle_strip, max_vertices = 4) out;\n"
20664 "in vec4 tes_gs[];\n"
20665 "out vec4 gs_fs;\n"
20669 " vec4 result = tes_gs[0];\n"
20673 " gs_fs = result;\n"
20674 " gl_Position = vec4(-1, -1, 0, 1);\n"
20676 " gs_fs = result;\n"
20677 " gl_Position = vec4(-1, 1, 0, 1);\n"
20679 " gs_fs = result;\n"
20680 " gl_Position = vec4(1, -1, 0, 1);\n"
20682 " gs_fs = result;\n"
20683 " gl_Position = vec4(1, 1, 0, 1);\n"
20687 static const GLchar* tcs = "#version 430 core\n"
20688 "#extension GL_ARB_enhanced_layouts : require\n"
20690 "layout(vertices = 1) out;\n"
20692 "in vec4 vs_tcs[];\n"
20693 "out vec4 tcs_tes[];\n"
20698 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
20700 " gl_TessLevelOuter[0] = 1.0;\n"
20701 " gl_TessLevelOuter[1] = 1.0;\n"
20702 " gl_TessLevelOuter[2] = 1.0;\n"
20703 " gl_TessLevelOuter[3] = 1.0;\n"
20704 " gl_TessLevelInner[0] = 1.0;\n"
20705 " gl_TessLevelInner[1] = 1.0;\n"
20708 static const GLchar* tcs_tested = "#version 430 core\n"
20709 "#extension GL_ARB_enhanced_layouts : require\n"
20711 "layout(vertices = 1) out;\n"
20715 "in vec4 vs_tcs[];\n"
20716 "out vec4 tcs_tes[];\n"
20720 " vec4 result = vs_tcs[gl_InvocationID];\n"
20724 " tcs_tes[gl_InvocationID] = result;\n"
20726 " gl_TessLevelOuter[0] = 1.0;\n"
20727 " gl_TessLevelOuter[1] = 1.0;\n"
20728 " gl_TessLevelOuter[2] = 1.0;\n"
20729 " gl_TessLevelOuter[3] = 1.0;\n"
20730 " gl_TessLevelInner[0] = 1.0;\n"
20731 " gl_TessLevelInner[1] = 1.0;\n"
20734 static const GLchar* tes_tested = "#version 430 core\n"
20735 "#extension GL_ARB_enhanced_layouts : require\n"
20737 "layout(isolines, point_mode) in;\n"
20741 "in vec4 tcs_tes[];\n"
20742 "out vec4 tes_gs;\n"
20746 " vec4 result = tcs_tes[0];\n"
20750 " tes_gs += result;\n"
20753 static const GLchar* vs = "#version 430 core\n"
20754 "#extension GL_ARB_enhanced_layouts : require\n"
20757 "out vec4 vs_tcs;\n"
20761 " vs_tcs = in_vs;\n"
20764 static const GLchar* vs_tested = "#version 430 core\n"
20765 "#extension GL_ARB_enhanced_layouts : require\n"
20770 "out vec4 vs_tcs;\n"
20774 " vec4 result = in_vs;\n"
20778 " vs_tcs += result;\n"
20782 std::string source;
20783 testCase& test_case = m_test_cases[test_case_index];
20785 if (test_case.m_stage == stage)
20787 const GLchar* array = "";
20788 const GLchar* index = "";
20789 size_t position = 0;
20791 const GLchar* var_definition = 0;
20792 const GLchar* var_use = 0;
20794 switch (test_case.m_case)
20797 var_definition = offset_var_definition;
20798 var_use = output_use;
20801 var_definition = stride_var_definition;
20802 var_use = output_use;
20805 var_definition = block_var_definition;
20806 var_use = block_use;
20809 var_definition = array_var_definition;
20810 var_use = array_use;
20813 TCU_FAIL("Invalid enum");
20818 case Utils::Shader::GEOMETRY:
20819 source = gs_tested;
20823 case Utils::Shader::TESS_CTRL:
20824 source = tcs_tested;
20826 index = "[gl_InvocationID]";
20828 case Utils::Shader::TESS_EVAL:
20829 source = tes_tested;
20833 case Utils::Shader::VERTEX:
20834 source = vs_tested;
20837 TCU_FAIL("Invalid enum");
20841 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
20843 Utils::replaceToken("ARRAY", position, array, source);
20844 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
20846 Utils::replaceAllTokens("INDEX", index, source);
20850 switch (test_case.m_stage)
20852 case Utils::Shader::GEOMETRY:
20855 case Utils::Shader::FRAGMENT:
20858 case Utils::Shader::VERTEX:
20865 case Utils::Shader::TESS_CTRL:
20868 case Utils::Shader::FRAGMENT:
20871 case Utils::Shader::VERTEX:
20878 case Utils::Shader::TESS_EVAL:
20881 case Utils::Shader::FRAGMENT:
20884 case Utils::Shader::TESS_CTRL:
20887 case Utils::Shader::VERTEX:
20894 case Utils::Shader::VERTEX:
20897 case Utils::Shader::FRAGMENT:
20905 TCU_FAIL("Invalid enum");
20913 /** Get description of test case
20915 * @param test_case_index Index of test case
20917 * @return Test case description
20919 std::string XFBTooSmallStrideTest::getTestCaseName(GLuint test_case_index)
20921 std::stringstream stream;
20922 testCase& test_case = m_test_cases[test_case_index];
20924 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", case: ";
20926 switch (test_case.m_case)
20929 stream << "buffer stride: 40, vec4 offset: 32";
20932 stream << "buffer stride: 32, vec4 off 16 stride: 32";
20935 stream << "buffer stride: 32, block 3xvec4 offset 0";
20938 stream << "buffer stride: 32, vec4[4] offset 16";
20941 TCU_FAIL("Invalid enum");
20944 return stream.str();
20947 /** Get number of test cases
20949 * @return Number of test cases
20951 GLuint XFBTooSmallStrideTest::getTestCaseNumber()
20953 return static_cast<GLuint>(m_test_cases.size());
20956 /** Selects if "compute" stage is relevant for test
20962 bool XFBTooSmallStrideTest::isComputeRelevant(GLuint /* test_case_index */)
20967 /** Prepare all test cases
20970 void XFBTooSmallStrideTest::testInit()
20972 for (GLuint c = 0; c < CASE_MAX; ++c)
20974 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
20977 It is invalid to define transform feedback output in TCS, according to spec:
20978 The data captured in transform feedback mode depends on the active programs on each of the shader stages.
20979 If a program is active for the geometry shader stage, transform feedback captures the vertices of each
20980 primitive emitted by the geometry shader. Otherwise, if a program is active for the tessellation evaluation
20981 shader stage, transform feedback captures each primitive produced by the tessellation primitive generator,
20982 whose vertices are processed by the tessellation evaluation shader. Otherwise, transform feedback captures
20983 each primitive processed by the vertex shader.
20985 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
20986 (Utils::Shader::FRAGMENT == stage))
20991 testCase test_case = { (CASES)c, (Utils::Shader::STAGES)stage };
20993 m_test_cases.push_back(test_case);
21000 * @param context Test framework context
21002 XFBVariableStrideTest::XFBVariableStrideTest(deqp::Context& context)
21003 : NegativeTestBase(context, "xfb_variable_stride", "Test verifies that stride qualifier is respected")
21007 /** Source for given test case and stage
21009 * @param test_case_index Index of test case
21010 * @param stage Shader stage
21012 * @return Shader source
21014 std::string XFBVariableStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
21016 static const GLchar* invalid_var_definition =
21017 "const uint type_size = SIZE;\n"
21019 "layout (xfb_offset = 0, xfb_stride = 2 * type_size) out TYPE gokuARRAY;\n"
21020 "layout (xfb_offset = type_size) out TYPE vegetaARRAY;\n";
21021 static const GLchar* valid_var_definition =
21022 "const uint type_size = SIZE;\n"
21024 "layout (xfb_offset = 0, xfb_stride = 2 * type_size) out TYPE gokuARRAY;\n";
21025 static const GLchar* invalid_use = " gokuINDEX = TYPE(1);\n"
21026 " vegetaINDEX = TYPE(0);\n"
21027 " if (vec4(0) == result)\n"
21029 " gokuINDEX = TYPE(0);\n"
21030 " vegetaINDEX = TYPE(1);\n"
21032 static const GLchar* valid_use = " gokuINDEX = TYPE(1);\n"
21033 " if (vec4(0) == result)\n"
21035 " gokuINDEX = TYPE(0);\n"
21037 static const GLchar* fs = "#version 430 core\n"
21038 "#extension GL_ARB_enhanced_layouts : require\n"
21040 "in vec4 any_fs;\n"
21041 "out vec4 fs_out;\n"
21045 " fs_out = any_fs;\n"
21048 static const GLchar* gs_tested = "#version 430 core\n"
21049 "#extension GL_ARB_enhanced_layouts : require\n"
21051 "layout(points) in;\n"
21052 "layout(triangle_strip, max_vertices = 4) out;\n"
21056 "in vec4 vs_any[];\n"
21057 "out vec4 any_fs;\n"
21061 " vec4 result = vs_any[0];\n"
21065 " any_fs = result;\n"
21066 " gl_Position = vec4(-1, -1, 0, 1);\n"
21068 " any_fs = result;\n"
21069 " gl_Position = vec4(-1, 1, 0, 1);\n"
21071 " any_fs = result;\n"
21072 " gl_Position = vec4(1, -1, 0, 1);\n"
21074 " any_fs = result;\n"
21075 " gl_Position = vec4(1, 1, 0, 1);\n"
21079 static const GLchar* tcs = "#version 430 core\n"
21080 "#extension GL_ARB_enhanced_layouts : require\n"
21082 "layout(vertices = 1) out;\n"
21084 "in vec4 vs_any[];\n"
21085 "out vec4 tcs_tes[];\n"
21090 " tcs_tes[gl_InvocationID] = vs_any[gl_InvocationID];\n"
21092 " gl_TessLevelOuter[0] = 1.0;\n"
21093 " gl_TessLevelOuter[1] = 1.0;\n"
21094 " gl_TessLevelOuter[2] = 1.0;\n"
21095 " gl_TessLevelOuter[3] = 1.0;\n"
21096 " gl_TessLevelInner[0] = 1.0;\n"
21097 " gl_TessLevelInner[1] = 1.0;\n"
21100 static const GLchar* tcs_tested = "#version 430 core\n"
21101 "#extension GL_ARB_enhanced_layouts : require\n"
21103 "layout(vertices = 1) out;\n"
21107 "in vec4 vs_any[];\n"
21108 "out vec4 any_fs[];\n"
21112 " vec4 result = vs_any[gl_InvocationID];\n"
21116 " any_fs[gl_InvocationID] = result;\n"
21118 " gl_TessLevelOuter[0] = 1.0;\n"
21119 " gl_TessLevelOuter[1] = 1.0;\n"
21120 " gl_TessLevelOuter[2] = 1.0;\n"
21121 " gl_TessLevelOuter[3] = 1.0;\n"
21122 " gl_TessLevelInner[0] = 1.0;\n"
21123 " gl_TessLevelInner[1] = 1.0;\n"
21126 static const GLchar* tes_tested = "#version 430 core\n"
21127 "#extension GL_ARB_enhanced_layouts : require\n"
21129 "layout(isolines, point_mode) in;\n"
21133 "in vec4 tcs_tes[];\n"
21134 "out vec4 any_fs;\n"
21138 " vec4 result = tcs_tes[0];\n"
21142 " any_fs = result;\n"
21145 static const GLchar* vs = "#version 430 core\n"
21146 "#extension GL_ARB_enhanced_layouts : require\n"
21149 "out vec4 vs_any;\n"
21153 " vs_any = in_vs;\n"
21156 static const GLchar* vs_tested = "#version 430 core\n"
21157 "#extension GL_ARB_enhanced_layouts : require\n"
21162 "out vec4 any_fs;\n"
21166 " vec4 result = in_vs;\n"
21170 " any_fs = result;\n"
21174 std::string source;
21175 testCase& test_case = m_test_cases[test_case_index];
21177 if (test_case.m_stage == stage)
21179 const GLchar* array = "";
21181 const GLchar* index = "";
21182 size_t position = 0;
21184 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
21185 const GLchar* var_definition = 0;
21186 const GLchar* var_use = 0;
21188 sprintf(buffer, "%d", test_case.m_type.GetSize());
21190 switch (test_case.m_case)
21193 var_definition = valid_var_definition;
21194 var_use = valid_use;
21197 var_definition = invalid_var_definition;
21198 var_use = invalid_use;
21201 TCU_FAIL("Invalid enum");
21206 case Utils::Shader::GEOMETRY:
21207 source = gs_tested;
21211 case Utils::Shader::TESS_CTRL:
21212 source = tcs_tested;
21214 index = "[gl_InvocationID]";
21216 case Utils::Shader::TESS_EVAL:
21217 source = tes_tested;
21221 case Utils::Shader::VERTEX:
21222 source = vs_tested;
21225 TCU_FAIL("Invalid enum");
21229 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
21231 Utils::replaceToken("SIZE", position, buffer, source);
21232 Utils::replaceToken("ARRAY", position, array, source);
21233 if (INVALID == test_case.m_case)
21235 Utils::replaceToken("ARRAY", position, array, source);
21237 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
21239 Utils::replaceAllTokens("TYPE", type_name, source);
21240 Utils::replaceAllTokens("INDEX", index, source);
21244 switch (test_case.m_stage)
21246 case Utils::Shader::GEOMETRY:
21249 case Utils::Shader::FRAGMENT:
21252 case Utils::Shader::VERTEX:
21259 case Utils::Shader::TESS_CTRL:
21262 case Utils::Shader::FRAGMENT:
21265 case Utils::Shader::VERTEX:
21272 case Utils::Shader::TESS_EVAL:
21275 case Utils::Shader::FRAGMENT:
21278 case Utils::Shader::TESS_CTRL:
21281 case Utils::Shader::VERTEX:
21288 case Utils::Shader::VERTEX:
21291 case Utils::Shader::FRAGMENT:
21299 TCU_FAIL("Invalid enum");
21307 /** Get description of test case
21309 * @param test_case_index Index of test case
21311 * @return Test case description
21313 std::string XFBVariableStrideTest::getTestCaseName(GLuint test_case_index)
21315 std::stringstream stream;
21316 testCase& test_case = m_test_cases[test_case_index];
21318 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
21319 << ", type: " << test_case.m_type.GetGLSLTypeName() << ", case: ";
21321 switch (test_case.m_case)
21327 stream << "invalid";
21330 TCU_FAIL("Invalid enum");
21333 return stream.str();
21336 /** Get number of test cases
21338 * @return Number of test cases
21340 GLuint XFBVariableStrideTest::getTestCaseNumber()
21342 return static_cast<GLuint>(m_test_cases.size());
21345 /** Selects if "compute" stage is relevant for test
21351 bool XFBVariableStrideTest::isComputeRelevant(GLuint /* test_case_index */)
21356 /** Selects if compilation failure is expected result
21358 * @param test_case_index Index of test case
21362 bool XFBVariableStrideTest::isFailureExpected(GLuint test_case_index)
21364 testCase& test_case = m_test_cases[test_case_index];
21366 return (INVALID == test_case.m_case);
21369 /** Prepare all test cases
21372 void XFBVariableStrideTest::testInit()
21374 const GLuint n_types = getTypesNumber();
21376 for (GLuint i = 0; i < n_types; ++i)
21378 const Utils::Type& type = getType(i);
21381 Some of the cases are declared as following are considered as invalid,
21382 but accoring to spec, the following declaration is valid: shaders in the
21383 transform feedback capturing mode have an initial global default of layout(xfb_buffer=0) out,
21384 so for the first variable's declaration, the xfb_stride = 16 is applied on buffer 0, for the
21385 second variable, its buffer is also inherited from global buffer 0, and its offset does not overflows
21388 The xfb_stride is the memory width of given buffer, not for variable even though xfb_stride
21389 is declared on the variable. It seems that the writter of this case misunderstand the concept of
21390 xfb_stride, because spec describes that xfb_stride can be declared multiple times for the same buffer,
21391 it is a compile or link-time error to have different values specified for the stride for the same buffer.
21394 layout (xfb_offset = 0, xfb_stride = 2 * type_size) out double goku;
21395 layout (xfb_offset = type_size) out double vegeta;
21397 // all the shaders are valid, so remove the following loop(it contains CASE_MAX is enum of valid and invalid)
21398 // for (GLuint c = 0; c < CASE_MAX; ++c)
21400 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
21402 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
21403 (Utils::Shader::FRAGMENT == stage))
21408 testCase test_case = { (CASES)VALID, (Utils::Shader::STAGES)stage, type };
21410 m_test_cases.push_back(test_case);
21418 * @param context Test framework context
21420 XFBBlockStrideTest::XFBBlockStrideTest(deqp::Context& context)
21421 : TestBase(context, "xfb_block_stride", "Test verifies that stride qualifier is respected for blocks")
21425 /** Source for given test case and stage
21427 * @param test_case_index Index of test case
21428 * @param stage Shader stage
21430 * @return Shader source
21432 std::string XFBBlockStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
21434 static const GLchar* var_definition = "layout (xfb_offset = 0, xfb_stride = 128) out Goku {\n"
21439 static const GLchar* var_use = " gokuINDEX.gohan = vec4(1, 0, 0, 0);\n"
21440 " gokuINDEX.goten = vec4(0, 0, 1, 0);\n"
21441 " gokuINDEX.chichi = vec4(0, 1, 0, 0);\n"
21442 " if (vec4(0) == result)\n"
21444 " gokuINDEX.gohan = vec4(0, 1, 1, 1);\n"
21445 " gokuINDEX.goten = vec4(1, 1, 0, 1);\n"
21446 " gokuINDEX.chichi = vec4(1, 0, 1, 1);\n"
21448 static const GLchar* gs_tested =
21449 "#version 430 core\n"
21450 "#extension GL_ARB_enhanced_layouts : require\n"
21452 "layout(points) in;\n"
21453 "layout(triangle_strip, max_vertices = 4) out;\n"
21457 "out gl_PerVertex \n"
21459 " vec4 gl_Position; \n" // gl_Position must be redeclared in separable program mode
21461 "in vec4 tes_gs[];\n"
21462 "out vec4 gs_fs;\n"
21466 " vec4 result = tes_gs[0];\n"
21470 " gs_fs = result;\n"
21471 " gl_Position = vec4(-1, -1, 0, 1);\n"
21473 " gs_fs = result;\n"
21474 " gl_Position = vec4(-1, 1, 0, 1);\n"
21476 " gs_fs = result;\n"
21477 " gl_Position = vec4(1, -1, 0, 1);\n"
21479 " gs_fs = result;\n"
21480 " gl_Position = vec4(1, 1, 0, 1);\n"
21484 static const GLchar* tcs = "#version 430 core\n"
21485 "#extension GL_ARB_enhanced_layouts : require\n"
21487 "layout(vertices = 1) out;\n"
21489 "in vec4 vs_tcs[];\n"
21490 "out vec4 tcs_tes[];\n"
21495 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
21497 " gl_TessLevelOuter[0] = 1.0;\n"
21498 " gl_TessLevelOuter[1] = 1.0;\n"
21499 " gl_TessLevelOuter[2] = 1.0;\n"
21500 " gl_TessLevelOuter[3] = 1.0;\n"
21501 " gl_TessLevelInner[0] = 1.0;\n"
21502 " gl_TessLevelInner[1] = 1.0;\n"
21506 static const GLchar* tcs_tested =
21507 "#version 430 core\n"
21508 "#extension GL_ARB_enhanced_layouts : require\n"
21510 "layout(vertices = 1) out;\n"
21514 "in vec4 vs_tcs[];\n"
21515 "out vec4 tcs_tes[];\n"
21519 " vec4 result = vs_tcs[gl_InvocationID];\n"
21523 " tcs_tes[gl_InvocationID] = result;\n"
21525 " gl_TessLevelOuter[0] = 1.0;\n"
21526 " gl_TessLevelOuter[1] = 1.0;\n"
21527 " gl_TessLevelOuter[2] = 1.0;\n"
21528 " gl_TessLevelOuter[3] = 1.0;\n"
21529 " gl_TessLevelInner[0] = 1.0;\n"
21530 " gl_TessLevelInner[1] = 1.0;\n"
21534 static const GLchar* tes_tested = "#version 430 core\n"
21535 "#extension GL_ARB_enhanced_layouts : require\n"
21537 "layout(isolines, point_mode) in;\n"
21541 "in vec4 tcs_tes[];\n"
21542 "out vec4 tes_gs;\n"
21546 " vec4 result = tcs_tes[0];\n"
21550 " tes_gs += result;\n"
21553 static const GLchar* vs = "#version 430 core\n"
21554 "#extension GL_ARB_enhanced_layouts : require\n"
21557 "out vec4 vs_tcs;\n"
21561 " vs_tcs = in_vs;\n"
21564 static const GLchar* vs_tested = "#version 430 core\n"
21565 "#extension GL_ARB_enhanced_layouts : require\n"
21570 "out vec4 vs_tcs;\n"
21574 " vec4 result = in_vs;\n"
21578 " vs_tcs += result;\n"
21582 std::string source;
21583 Utils::Shader::STAGES test_case = m_test_cases[test_case_index];
21585 if (test_case == stage)
21587 const GLchar* array = "";
21588 const GLchar* index = "";
21589 size_t position = 0;
21591 // It is a compile time error to apply xfb_offset to the declaration of an unsized array(GLSL4.5 spec: Page73)
21592 // change array = "[]" to "[1]"
21595 case Utils::Shader::GEOMETRY:
21596 source = gs_tested;
21601 It is invalid to define transform feedback output in HS
21604 case Utils::Shader::TESS_CTRL:
21605 source = tcs_tested;
21607 index = "[gl_InvocationID]";
21610 case Utils::Shader::TESS_EVAL:
21611 source = tes_tested;
21615 case Utils::Shader::VERTEX:
21616 source = vs_tested;
21619 TCU_FAIL("Invalid enum");
21623 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
21625 Utils::replaceToken("ARRAY", position, array, source);
21626 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
21628 Utils::replaceAllTokens("INDEX", index, source);
21634 case Utils::Shader::GEOMETRY:
21637 case Utils::Shader::VERTEX:
21644 case Utils::Shader::TESS_CTRL:
21647 case Utils::Shader::VERTEX:
21654 case Utils::Shader::TESS_EVAL:
21657 case Utils::Shader::TESS_CTRL:
21660 case Utils::Shader::VERTEX:
21667 case Utils::Shader::VERTEX:
21671 TCU_FAIL("Invalid enum");
21679 /** Get description of test case
21681 * @param test_case_index Index of test case
21683 * @return Test case description
21685 std::string XFBBlockStrideTest::getTestCaseName(GLuint test_case_index)
21687 std::stringstream stream;
21689 stream << "Stage: " << Utils::Shader::GetStageName(m_test_cases[test_case_index]);
21691 return stream.str();
21694 /** Get number of test cases
21696 * @return Number of test cases
21698 GLuint XFBBlockStrideTest::getTestCaseNumber()
21700 return static_cast<GLuint>(m_test_cases.size());
21703 /** Inspects program for xfb stride
21705 * @param program Program to query
21707 * @return true if query results match expected values, false otherwise
21709 bool XFBBlockStrideTest::inspectProgram(Utils::Program& program)
21713 program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE,
21714 1 /* buf_size */, &stride);
21716 return (128 == stride);
21721 * @param test_case_index Id of test case
21723 * @return true if test case pass, false otherwise
21725 bool XFBBlockStrideTest::testCase(GLuint test_case_index)
21727 const std::string& gs_source = getShaderSource(test_case_index, Utils::Shader::GEOMETRY);
21728 Utils::Program program(m_context);
21729 const std::string& tcs_source = getShaderSource(test_case_index, Utils::Shader::TESS_CTRL);
21730 const std::string& tes_source = getShaderSource(test_case_index, Utils::Shader::TESS_EVAL);
21731 bool test_case_result = true;
21732 const std::string& vs_source = getShaderSource(test_case_index, Utils::Shader::VERTEX);
21734 program.Init("" /* cs */, "", gs_source, tcs_source, tes_source, vs_source, true /* separable */);
21736 test_case_result = inspectProgram(program);
21738 return test_case_result;
21741 /** Prepare all test cases
21744 void XFBBlockStrideTest::testInit()
21746 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
21748 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
21749 (Utils::Shader::FRAGMENT == stage))
21754 m_test_cases.push_back((Utils::Shader::STAGES)stage);
21760 * @param context Test context
21762 XFBBlockMemberStrideTest::XFBBlockMemberStrideTest(deqp::Context& context)
21763 : BufferTestBase(context, "xfb_block_member_stride",
21764 "Test verifies that xfb_stride qualifier is respected for block member")
21766 /* Nothing to be done here */
21769 /** Get descriptors of buffers necessary for test
21772 * @param out_descriptors Descriptors of buffers used by test
21774 void XFBBlockMemberStrideTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
21775 bufferDescriptor::Vector& out_descriptors)
21777 const Utils::Type& vec4 = Utils::Type::vec4;
21779 /* Test needs single uniform and xfb */
21780 out_descriptors.resize(2);
21782 /* Get references */
21783 bufferDescriptor& uniform = out_descriptors[0];
21784 bufferDescriptor& xfb = out_descriptors[1];
21787 uniform.m_index = 0;
21791 uniform.m_target = Utils::Buffer::Uniform;
21792 xfb.m_target = Utils::Buffer::Transform_feedback;
21795 static const GLuint vec4_size = 16;
21796 const std::vector<GLubyte>& gohan_data = vec4.GenerateDataPacked();
21797 const std::vector<GLubyte>& goten_data = vec4.GenerateDataPacked();
21798 const std::vector<GLubyte>& chichi_data = vec4.GenerateDataPacked();
21801 uniform.m_initial_data.resize(3 * vec4_size);
21802 memcpy(&uniform.m_initial_data[0] + 0, &gohan_data[0], vec4_size);
21803 memcpy(&uniform.m_initial_data[0] + vec4_size, &goten_data[0], vec4_size);
21804 memcpy(&uniform.m_initial_data[0] + 2 * vec4_size, &chichi_data[0], vec4_size);
21807 xfb.m_initial_data.resize(4 * vec4_size);
21808 xfb.m_expected_data.resize(4 * vec4_size);
21810 for (GLuint i = 0; i < 4 * vec4_size; ++i)
21812 xfb.m_initial_data[i] = (glw::GLubyte)i;
21813 xfb.m_expected_data[i] = (glw::GLubyte)i;
21816 // the xfb_offset of "chichi" should be 32
21817 memcpy(&xfb.m_expected_data[0] + 0, &gohan_data[0], vec4_size);
21818 memcpy(&xfb.m_expected_data[0] + vec4_size, &goten_data[0], vec4_size);
21819 memcpy(&xfb.m_expected_data[0] + 2 * vec4_size, &chichi_data[0], vec4_size);
21822 /** Get body of main function for given shader stage
21825 * @param stage Shader stage
21826 * @param out_assignments Set to empty
21827 * @param out_calculations Set to empty
21829 void XFBBlockMemberStrideTest::getShaderBody(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
21830 std::string& out_assignments, std::string& out_calculations)
21832 out_calculations = "";
21834 static const GLchar* gs = " gohan = uni_gohan;\n"
21835 " goten = uni_goten;\n"
21836 " chichi = uni_chichi;\n";
21837 static const GLchar* fs = " fs_out = gohan + goten + chichi;\n";
21839 const GLchar* assignments = "";
21842 case Utils::Shader::FRAGMENT:
21845 case Utils::Shader::GEOMETRY:
21852 out_assignments = assignments;
21855 /** Get interface of shader
21858 * @param stage Shader stage
21859 * @param out_interface Set to ""
21861 void XFBBlockMemberStrideTest::getShaderInterface(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
21862 std::string& out_interface)
21864 static const GLchar* gs = "layout (xfb_buffer = 0, xfb_offset = 0) out Goku {\n"
21866 " layout (xfb_stride = 48) vec4 goten;\n"
21869 "layout(binding = 0) uniform gs_block {\n"
21870 " vec4 uni_gohan;\n"
21871 " vec4 uni_goten;\n"
21872 " vec4 uni_chichi;\n"
21874 static const GLchar* fs = "in Goku {\n"
21879 "out vec4 fs_out;\n";
21883 case Utils::Shader::FRAGMENT:
21884 out_interface = fs;
21886 case Utils::Shader::GEOMETRY:
21887 out_interface = gs;
21890 out_interface = "";
21895 /** Inspects program to check if all resources are as expected
21898 * @param program Program instance
21899 * @param out_stream Error message
21901 * @return true if everything is ok, false otherwise
21903 bool XFBBlockMemberStrideTest::inspectProgram(GLuint /* test_case_index*/, Utils::Program& program,
21904 std::stringstream& out_stream)
21906 const GLuint gohan_id = program.GetResourceIndex("gohan", GL_TRANSFORM_FEEDBACK_VARYING);
21907 const GLuint goten_id = program.GetResourceIndex("goten", GL_TRANSFORM_FEEDBACK_VARYING);
21908 const GLuint chichi_id = program.GetResourceIndex("chichi", GL_TRANSFORM_FEEDBACK_VARYING);
21910 GLint gohan_offset = 0;
21911 GLint goten_offset = 0;
21912 GLint chichi_offset = 0;
21914 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, gohan_id, GL_OFFSET, 1, &gohan_offset);
21915 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, goten_id, GL_OFFSET, 1, &goten_offset);
21916 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, chichi_id, GL_OFFSET, 1, &chichi_offset);
21918 // the xfb_offset of "chichi" should be 32
21919 if ((0 != gohan_offset) || (16 != goten_offset) || (32 != chichi_offset))
21921 out_stream << "Got wrong offset: [" << gohan_offset << ", " << goten_offset << ", " << chichi_offset
21922 << "] expected: [0, 16, 32]";
21931 * @param context Test framework context
21933 XFBDuplicatedStrideTest::XFBDuplicatedStrideTest(deqp::Context& context)
21934 : NegativeTestBase(context, "xfb_duplicated_stride",
21935 "Test verifies that compiler reports error when conflicting stride qualifiers are used")
21939 /** Source for given test case and stage
21941 * @param test_case_index Index of test case
21942 * @param stage Shader stage
21944 * @return Shader source
21946 std::string XFBDuplicatedStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
21948 static const GLchar* invalid_var_definition = "const uint valid_stride = 64;\n"
21949 "const uint conflicting_stride = 128;\n"
21951 "layout (xfb_buffer = 0, xfb_stride = valid_stride) out;\n"
21952 "layout (xfb_buffer = 0, xfb_stride = conflicting_stride) out;\n";
21953 static const GLchar* valid_var_definition = "const uint valid_stride = 64;\n"
21955 "layout (xfb_buffer = 0, xfb_stride = valid_stride) out;\n"
21956 "layout (xfb_buffer = 0, xfb_stride = valid_stride) out;\n";
21957 static const GLchar* fs = "#version 430 core\n"
21958 "#extension GL_ARB_enhanced_layouts : require\n"
21960 "in vec4 any_fs;\n"
21961 "out vec4 fs_out;\n"
21965 " fs_out = any_fs;\n"
21968 static const GLchar* gs_tested = "#version 430 core\n"
21969 "#extension GL_ARB_enhanced_layouts : require\n"
21971 "layout(points) in;\n"
21972 "layout(triangle_strip, max_vertices = 4) out;\n"
21976 "in vec4 vs_any[];\n"
21977 "out vec4 any_fs;\n"
21981 " vec4 result = vs_any[0];\n"
21985 " any_fs = result;\n"
21986 " gl_Position = vec4(-1, -1, 0, 1);\n"
21988 " any_fs = result;\n"
21989 " gl_Position = vec4(-1, 1, 0, 1);\n"
21991 " any_fs = result;\n"
21992 " gl_Position = vec4(1, -1, 0, 1);\n"
21994 " any_fs = result;\n"
21995 " gl_Position = vec4(1, 1, 0, 1);\n"
21999 static const GLchar* tcs = "#version 430 core\n"
22000 "#extension GL_ARB_enhanced_layouts : require\n"
22002 "layout(vertices = 1) out;\n"
22004 "in vec4 vs_any[];\n"
22005 "out vec4 tcs_tes[];\n"
22010 " tcs_tes[gl_InvocationID] = vs_any[gl_InvocationID];\n"
22012 " gl_TessLevelOuter[0] = 1.0;\n"
22013 " gl_TessLevelOuter[1] = 1.0;\n"
22014 " gl_TessLevelOuter[2] = 1.0;\n"
22015 " gl_TessLevelOuter[3] = 1.0;\n"
22016 " gl_TessLevelInner[0] = 1.0;\n"
22017 " gl_TessLevelInner[1] = 1.0;\n"
22020 static const GLchar* tcs_tested = "#version 430 core\n"
22021 "#extension GL_ARB_enhanced_layouts : require\n"
22023 "layout(vertices = 1) out;\n"
22027 "in vec4 vs_any[];\n"
22028 "out vec4 any_fs[];\n"
22032 " vec4 result = vs_any[gl_InvocationID];\n"
22036 " any_fs[gl_InvocationID] = result;\n"
22038 " gl_TessLevelOuter[0] = 1.0;\n"
22039 " gl_TessLevelOuter[1] = 1.0;\n"
22040 " gl_TessLevelOuter[2] = 1.0;\n"
22041 " gl_TessLevelOuter[3] = 1.0;\n"
22042 " gl_TessLevelInner[0] = 1.0;\n"
22043 " gl_TessLevelInner[1] = 1.0;\n"
22046 static const GLchar* tes_tested = "#version 430 core\n"
22047 "#extension GL_ARB_enhanced_layouts : require\n"
22049 "layout(isolines, point_mode) in;\n"
22053 "in vec4 tcs_tes[];\n"
22054 "out vec4 any_fs;\n"
22058 " vec4 result = tcs_tes[0];\n"
22062 " any_fs = result;\n"
22065 static const GLchar* vs = "#version 430 core\n"
22066 "#extension GL_ARB_enhanced_layouts : require\n"
22069 "out vec4 vs_any;\n"
22073 " vs_any = in_vs;\n"
22076 static const GLchar* vs_tested = "#version 430 core\n"
22077 "#extension GL_ARB_enhanced_layouts : require\n"
22082 "out vec4 any_fs;\n"
22086 " vec4 result = in_vs;\n"
22090 " any_fs += result;\n"
22094 std::string source;
22095 testCase& test_case = m_test_cases[test_case_index];
22097 if (test_case.m_stage == stage)
22099 size_t position = 0;
22100 const GLchar* var_definition = 0;
22101 const GLchar* var_use = "";
22103 switch (test_case.m_case)
22106 var_definition = valid_var_definition;
22109 var_definition = invalid_var_definition;
22112 TCU_FAIL("Invalid enum");
22117 case Utils::Shader::GEOMETRY:
22118 source = gs_tested;
22120 case Utils::Shader::TESS_CTRL:
22121 source = tcs_tested;
22123 case Utils::Shader::TESS_EVAL:
22124 source = tes_tested;
22126 case Utils::Shader::VERTEX:
22127 source = vs_tested;
22130 TCU_FAIL("Invalid enum");
22133 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
22134 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
22138 switch (test_case.m_stage)
22140 case Utils::Shader::GEOMETRY:
22143 case Utils::Shader::FRAGMENT:
22146 case Utils::Shader::VERTEX:
22153 case Utils::Shader::TESS_CTRL:
22156 case Utils::Shader::FRAGMENT:
22159 case Utils::Shader::VERTEX:
22166 case Utils::Shader::TESS_EVAL:
22169 case Utils::Shader::FRAGMENT:
22172 case Utils::Shader::TESS_CTRL:
22175 case Utils::Shader::VERTEX:
22182 case Utils::Shader::VERTEX:
22185 case Utils::Shader::FRAGMENT:
22193 TCU_FAIL("Invalid enum");
22201 /** Get description of test case
22203 * @param test_case_index Index of test case
22205 * @return Test case description
22207 std::string XFBDuplicatedStrideTest::getTestCaseName(GLuint test_case_index)
22209 std::stringstream stream;
22210 testCase& test_case = m_test_cases[test_case_index];
22212 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", case: ";
22214 switch (test_case.m_case)
22220 stream << "invalid";
22223 TCU_FAIL("Invalid enum");
22226 return stream.str();
22229 /** Get number of test cases
22231 * @return Number of test cases
22233 GLuint XFBDuplicatedStrideTest::getTestCaseNumber()
22235 return static_cast<GLuint>(m_test_cases.size());
22238 /** Selects if "compute" stage is relevant for test
22244 bool XFBDuplicatedStrideTest::isComputeRelevant(GLuint /* test_case_index */)
22249 /** Selects if compilation failure is expected result
22251 * @param test_case_index Index of test case
22255 bool XFBDuplicatedStrideTest::isFailureExpected(GLuint test_case_index)
22257 testCase& test_case = m_test_cases[test_case_index];
22259 return (INVALID == test_case.m_case);
22262 /** Prepare all test cases
22265 void XFBDuplicatedStrideTest::testInit()
22267 for (GLuint c = 0; c < CASE_MAX; ++c)
22269 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
22271 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
22272 (Utils::Shader::FRAGMENT == stage))
22277 testCase test_case = { (CASES)c, (Utils::Shader::STAGES)stage };
22279 m_test_cases.push_back(test_case);
22286 * @param context Test framework context
22288 XFBGetProgramResourceAPITest::XFBGetProgramResourceAPITest(deqp::Context& context)
22289 : TestBase(context, "xfb_get_program_resource_api",
22290 "Test verifies that get program resource reports correct results for XFB")
22294 /** Source for given test case and stage
22296 * @param test_case_index Index of test case
22297 * @param stage Shader stage
22299 * @return Shader source
22301 std::string XFBGetProgramResourceAPITest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
22303 static const GLchar* api_var_definition = "out TYPE b0_v1ARRAY;\n"
22304 "out TYPE b1_v1ARRAY;\n"
22305 "out TYPE b0_v3ARRAY;\n"
22306 "out TYPE b0_v0ARRAY;\n";
22307 static const GLchar* xfb_var_definition =
22308 "const uint type_size = SIZE;\n"
22310 "layout (xfb_buffer = 1, xfb_stride = 4 * type_size) out;\n"
22312 "layout (xfb_buffer = 0, xfb_offset = 1 * type_size) out TYPE b0_v1ARRAY;\n"
22313 "layout (xfb_buffer = 1, xfb_offset = 1 * type_size) out TYPE b1_v1ARRAY;\n"
22314 "layout (xfb_buffer = 0, xfb_offset = 3 * type_size) out TYPE b0_v3ARRAY;\n"
22315 "layout (xfb_buffer = 0, xfb_offset = 0 * type_size) out TYPE b0_v0ARRAY;\n";
22316 static const GLchar* var_use = " b0_v1INDEX = TYPE(0);\n"
22317 " b1_v1INDEX = TYPE(1);\n"
22318 " b0_v3INDEX = TYPE(0);\n"
22319 " b0_v0INDEX = TYPE(1);\n"
22320 " if (vec4(0) == result)\n"
22322 " b0_v1INDEX = TYPE(1);\n"
22323 " b1_v1INDEX = TYPE(0);\n"
22324 " b0_v3INDEX = TYPE(1);\n"
22325 " b0_v0INDEX = TYPE(0);\n"
22327 static const GLchar* gs_tested =
22328 "#version 430 core\n"
22329 "#extension GL_ARB_enhanced_layouts : require\n"
22331 "layout(points) in;\n"
22332 "layout(triangle_strip, max_vertices = 4) out;\n"
22336 "out gl_PerVertex \n"
22338 " vec4 gl_Position; \n" // gl_Position must be redeclared in separable program mode
22340 "in vec4 tes_gs[];\n"
22341 "out vec4 gs_fs;\n"
22345 " vec4 result = tes_gs[0];\n"
22349 " gs_fs = result;\n"
22350 " gl_Position = vec4(-1, -1, 0, 1);\n"
22352 " gs_fs = result;\n"
22353 " gl_Position = vec4(-1, 1, 0, 1);\n"
22355 " gs_fs = result;\n"
22356 " gl_Position = vec4(1, -1, 0, 1);\n"
22358 " gs_fs = result;\n"
22359 " gl_Position = vec4(1, 1, 0, 1);\n"
22364 static const GLchar* tcs_tested =
22365 "#version 430 core\n"
22366 "#extension GL_ARB_enhanced_layouts : require\n"
22368 "layout(vertices = 1) out;\n"
22372 "in vec4 vs_tcs[];\n"
22373 "out vec4 tcs_tes[];\n"
22377 " vec4 result = vs_tcs[gl_InvocationID];\n"
22381 " tcs_tes[gl_InvocationID] = result;\n"
22383 " gl_TessLevelOuter[0] = 1.0;\n"
22384 " gl_TessLevelOuter[1] = 1.0;\n"
22385 " gl_TessLevelOuter[2] = 1.0;\n"
22386 " gl_TessLevelOuter[3] = 1.0;\n"
22387 " gl_TessLevelInner[0] = 1.0;\n"
22388 " gl_TessLevelInner[1] = 1.0;\n"
22392 static const GLchar* tes_tested = "#version 430 core\n"
22393 "#extension GL_ARB_enhanced_layouts : require\n"
22395 "layout(isolines, point_mode) in;\n"
22399 "in vec4 tcs_tes[];\n"
22400 "out vec4 tes_gs;\n"
22404 " vec4 result = tcs_tes[0];\n"
22408 " tes_gs = result;\n"
22411 static const GLchar* vs_tested = "#version 430 core\n"
22412 "#extension GL_ARB_enhanced_layouts : require\n"
22417 "out vec4 vs_tcs;\n"
22421 " vec4 result = in_vs;\n"
22425 " vs_tcs = result;\n"
22429 std::string source;
22430 const test_Case& test_case = m_test_cases[test_case_index];
22432 if (test_case.m_stage == stage)
22434 const GLchar* array = "";
22436 const GLchar* index = "";
22437 size_t position = 0;
22439 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
22440 const GLchar* var_definition = 0;
22442 sprintf(buffer, "%d", test_case.m_type.GetSize());
22444 if (XFB == test_case.m_case)
22446 var_definition = xfb_var_definition;
22450 var_definition = api_var_definition;
22453 // It is a compile time error to apply xfb_offset to the declaration of an unsized array(GLSL4.5 spec: Page73)
22454 // change array = "[]" to "[1]"
22457 case Utils::Shader::GEOMETRY:
22458 source = gs_tested;
22462 // It is invalid to output transform feedback varyings in tessellation control shader
22464 case Utils::Shader::TESS_CTRL:
22465 source = tcs_tested;
22467 index = "[gl_InvocationID]";
22470 case Utils::Shader::TESS_EVAL:
22471 source = tes_tested;
22475 case Utils::Shader::VERTEX:
22476 source = vs_tested;
22479 TCU_FAIL("Invalid enum");
22483 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
22484 if (XFB == test_case.m_case)
22487 Utils::replaceToken("SIZE", position, buffer, source);
22489 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
22491 Utils::replaceAllTokens("ARRAY", array, source);
22492 Utils::replaceAllTokens("INDEX", index, source);
22493 Utils::replaceAllTokens("TYPE", type_name, source);
22503 /** Get description of test case
22505 * @param test_case_index Index of test case
22507 * @return Test case description
22509 std::string XFBGetProgramResourceAPITest::getTestCaseName(GLuint test_case_index)
22511 std::stringstream stream;
22512 const test_Case& test_case = m_test_cases[test_case_index];
22514 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
22515 << ", type: " << test_case.m_type.GetGLSLTypeName() << ", case: ";
22517 switch (test_case.m_case)
22520 stream << "interleaved";
22523 stream << "separated";
22529 TCU_FAIL("Invalid enum");
22532 return stream.str();
22535 /** Get number of test cases
22537 * @return Number of test cases
22539 GLuint XFBGetProgramResourceAPITest::getTestCaseNumber()
22541 return static_cast<GLuint>(m_test_cases.size());
22544 /** Inspects program for offset, buffer index, buffer stride and type
22546 * @param test_case_index Index of test case
22547 * @param program Program to query
22549 * @return true if query results match expected values, false otherwise
22551 bool XFBGetProgramResourceAPITest::inspectProgram(glw::GLuint test_case_index, Utils::Program& program)
22553 GLint b0_stride = 0;
22554 GLint b1_stride = 0;
22555 GLint b0_v0_buf = 0;
22556 GLint b0_v0_offset = 0;
22557 GLint b0_v0_type = 0;
22558 GLint b0_v1_buf = 0;
22559 GLint b0_v1_offset = 0;
22560 GLint b0_v1_type = 0;
22561 GLint b0_v3_buf = 0;
22562 GLint b0_v3_offset = 0;
22563 GLint b0_v3_type = 0;
22564 GLint b1_v1_buf = 0;
22565 GLint b1_v1_offset = 0;
22566 GLint b1_v1_type = 0;
22567 const test_Case& test_case = m_test_cases[test_case_index];
22568 const GLenum type_enum = test_case.m_type.GetTypeGLenum();
22569 const GLint type_size = test_case.m_type.GetSize();
22571 GLuint b0_v0_index = program.GetResourceIndex("b0_v0", GL_TRANSFORM_FEEDBACK_VARYING);
22572 GLuint b0_v1_index = program.GetResourceIndex("b0_v1", GL_TRANSFORM_FEEDBACK_VARYING);
22573 GLuint b0_v3_index = program.GetResourceIndex("b0_v3", GL_TRANSFORM_FEEDBACK_VARYING);
22574 GLuint b1_v1_index = program.GetResourceIndex("b1_v1", GL_TRANSFORM_FEEDBACK_VARYING);
22576 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v0_index, GL_OFFSET, 1 /* buf_size */, &b0_v0_offset);
22577 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v1_index, GL_OFFSET, 1 /* buf_size */, &b0_v1_offset);
22578 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v3_index, GL_OFFSET, 1 /* buf_size */, &b0_v3_offset);
22579 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b1_v1_index, GL_OFFSET, 1 /* buf_size */, &b1_v1_offset);
22581 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v0_index, GL_TYPE, 1 /* buf_size */, &b0_v0_type);
22582 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v1_index, GL_TYPE, 1 /* buf_size */, &b0_v1_type);
22583 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v3_index, GL_TYPE, 1 /* buf_size */, &b0_v3_type);
22584 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b1_v1_index, GL_TYPE, 1 /* buf_size */, &b1_v1_type);
22586 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v0_index, GL_TRANSFORM_FEEDBACK_BUFFER_INDEX,
22587 1 /* buf_size */, &b0_v0_buf);
22588 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v1_index, GL_TRANSFORM_FEEDBACK_BUFFER_INDEX,
22589 1 /* buf_size */, &b0_v1_buf);
22590 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v3_index, GL_TRANSFORM_FEEDBACK_BUFFER_INDEX,
22591 1 /* buf_size */, &b0_v3_buf);
22592 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b1_v1_index, GL_TRANSFORM_FEEDBACK_BUFFER_INDEX,
22593 1 /* buf_size */, &b1_v1_buf);
22595 program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, b0_v0_buf, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE, 1 /* buf_size */,
22597 program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, b1_v1_buf, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE, 1 /* buf_size */,
22600 if (SEPARATED != test_case.m_case)
22602 return (((GLint)(4 * type_size) == b0_stride) && ((GLint)(4 * type_size) == b1_stride) &&
22603 ((GLint)(0) == b0_v0_buf) && ((GLint)(0 * type_size) == b0_v0_offset) &&
22604 ((GLint)(type_enum) == b0_v0_type) && ((GLint)(0) == b0_v1_buf) &&
22605 ((GLint)(1 * type_size) == b0_v1_offset) && ((GLint)(type_enum) == b0_v1_type) &&
22606 ((GLint)(0) == b0_v3_buf) && ((GLint)(3 * type_size) == b0_v3_offset) &&
22607 ((GLint)(type_enum) == b0_v3_type) && ((GLint)(1) == b1_v1_buf) &&
22608 ((GLint)(1 * type_size) == b1_v1_offset) && ((GLint)(type_enum) == b1_v1_type));
22612 return (((GLint)(1 * type_size) == b0_stride) && ((GLint)(1 * type_size) == b1_stride) &&
22613 ((GLint)(0) == b0_v0_buf) && ((GLint)(0) == b0_v0_offset) && ((GLint)(type_enum) == b0_v0_type) &&
22614 ((GLint)(1) == b0_v1_buf) && ((GLint)(0) == b0_v1_offset) && ((GLint)(type_enum) == b0_v1_type) &&
22615 ((GLint)(2) == b0_v3_buf) && ((GLint)(0) == b0_v3_offset) && ((GLint)(type_enum) == b0_v3_type) &&
22616 ((GLint)(3) == b1_v1_buf) && ((GLint)(0) == b1_v1_offset) && ((GLint)(type_enum) == b1_v1_type));
22620 /** Insert gl_SkipComponents
22622 * @param num_components How many gl_SkipComponents1 need to be inserted
22623 * @param varyings The transform feedback varyings string vector
22626 void XFBGetProgramResourceAPITest::insertSkipComponents(int num_components, Utils::Program::NameVector& varyings)
22628 int num_component_4 = num_components / 4;
22629 int num_component_1 = num_components % 4;
22630 for (int i = 0; i < num_component_4; i++)
22632 varyings.push_back("gl_SkipComponents4");
22634 switch (num_component_1)
22637 varyings.push_back("gl_SkipComponents1");
22640 varyings.push_back("gl_SkipComponents2");
22643 varyings.push_back("gl_SkipComponents3");
22652 * @param test_case_index Id of test case
22654 * @return true if test case pass, false otherwise
22656 bool XFBGetProgramResourceAPITest::testCase(GLuint test_case_index)
22658 const std::string& gs_source = getShaderSource(test_case_index, Utils::Shader::GEOMETRY);
22659 Utils::Program program(m_context);
22660 const std::string& tcs_source = getShaderSource(test_case_index, Utils::Shader::TESS_CTRL);
22661 const std::string& tes_source = getShaderSource(test_case_index, Utils::Shader::TESS_EVAL);
22662 const test_Case& test_case = m_test_cases[test_case_index];
22663 bool test_case_result = true;
22664 const std::string& vs_source = getShaderSource(test_case_index, Utils::Shader::VERTEX);
22666 // According to spec: gl_SkipComponents1 ~ gl_SkipComponents4 is treated as specifying a one- to four-component floating point output variables with undefined values.
22667 // No data will be recorded for such strings, but the offset assigned to the next variable in varyings and the stride of the assigned bingding point will be affected.
22669 if (INTERLEAVED == test_case.m_case)
22672 layout (xfb_buffer = 0, xfb_offset = 1 * type_size) out type b0_v1;
22673 layout (xfb_buffer = 1, xfb_offset = 1 * type_size) out type b1_v1;
22674 layout (xfb_buffer = 0, xfb_offset = 3 * type_size) out type b0_v3;
22675 layout (xfb_buffer = 0, xfb_offset = 0 * type_size) out type b0_v0;
22677 Note: the type can be float, double, mat2, mat3x2, dmat2, dmat3x2..., so to make the each variable of "captured_varyings" has the same xfb_offset with the above shaders,
22678 we need to calculate how many "gl_SkipComponents" need to be inserted.
22680 Utils::Program::NameVector captured_varyings;
22681 captured_varyings.push_back("b0_v0");
22682 captured_varyings.push_back("b0_v1");
22683 // Compute how many gl_SkipComponents to be inserted
22684 int numComponents = test_case.m_type.GetSize() / 4;
22685 insertSkipComponents(numComponents, captured_varyings);
22686 captured_varyings.push_back("b0_v3");
22687 captured_varyings.push_back("gl_NextBuffer");
22688 insertSkipComponents(numComponents, captured_varyings);
22689 captured_varyings.push_back("b1_v1");
22690 insertSkipComponents(numComponents * 2, captured_varyings);
22692 program.Init("" /* cs */, "", gs_source, tcs_source, tes_source, vs_source, captured_varyings, true,
22693 true /* separable */);
22695 else if (SEPARATED == test_case.m_case)
22697 Utils::Program::NameVector captured_varyings;
22699 captured_varyings.push_back("b0_v0");
22700 captured_varyings.push_back("b0_v1");
22701 captured_varyings.push_back("b0_v3");
22702 captured_varyings.push_back("b1_v1");
22704 program.Init("" /* cs */, "", gs_source, tcs_source, tes_source, vs_source, captured_varyings, false,
22705 true /* separable */);
22710 program.Init("" /* cs */, "", gs_source, tcs_source, tes_source, vs_source, true /* separable */);
22713 test_case_result = inspectProgram(test_case_index, program);
22715 return test_case_result;
22718 /** Prepare all test cases
22721 void XFBGetProgramResourceAPITest::testInit()
22723 const Functions& gl = m_context.getRenderContext().getFunctions();
22724 const GLuint n_types = getTypesNumber();
22728 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_xfb_int);
22729 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
22731 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, &max_xfb_sep);
22732 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
22734 GLint max_varyings;
22735 gl.getIntegerv(GL_MAX_VARYING_COMPONENTS, &max_varyings);
22737 for (GLuint i = 0; i < n_types; ++i)
22739 // When i == 7, the type is dmat4, i == 9 the type is dmat4x3, the number of output components exceeds the maximum value that AMD's driver supported,
22740 // the MAX_VARYING_COMPONENTS is 32 in our driver, but when the variable type is dmat4 or dmat4x3, the number of output component is 33, to make the
22741 // shader valid, we can either skip the dmat4, dmat4x3 or query the implementation-dependent value MAX_VARYING_COMPONENTS before generating the shader
22742 // to guarantee the number of varying not exceeded.
22744 layout (xfb_buffer = 1, xfb_stride = 4 * type_size) out;
22745 layout (xfb_buffer = 0, xfb_offset = 1 * type_size) out type b0_v1;
22746 layout (xfb_buffer = 1, xfb_offset = 1 * type_size) out type b1_v1;
22747 layout (xfb_buffer = 0, xfb_offset = 3 * type_size) out type b0_v3;
22748 layout (xfb_buffer = 0, xfb_offset = 0 * type_size) out type b0_v0;
22752 if (i == 7 || i == 9)
22754 const Utils::Type& type = getType(i);
22755 if (4 * type.GetNumComponents() + 4 > (GLuint)max_varyings)
22759 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
22762 It is invalid to define transform feedback output in HS
22764 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
22765 (Utils::Shader::FRAGMENT == stage))
22770 test_Case test_case_int = { INTERLEAVED, (Utils::Shader::STAGES)stage, type };
22771 test_Case test_case_sep = { SEPARATED, (Utils::Shader::STAGES)stage, type };
22772 test_Case test_case_xfb = { XFB, (Utils::Shader::STAGES)stage, type };
22774 if ((int)type.GetSize() <= max_xfb_int)
22776 m_test_cases.push_back(test_case_xfb);
22777 m_test_cases.push_back(test_case_int);
22780 if ((int)type.GetSize() <= max_xfb_sep)
22782 m_test_cases.push_back(test_case_sep);
22790 * @param context Test context
22792 XFBOverrideQualifiersWithAPITest::XFBOverrideQualifiersWithAPITest(deqp::Context& context)
22793 : BufferTestBase(context, "xfb_override_qualifiers_with_api",
22794 "Test verifies that xfb_offset qualifier is not overriden with API")
22796 /* Nothing to be done here */
22799 /** Get descriptors of buffers necessary for test
22801 * @param test_case_index Index of test case
22802 * @param out_descriptors Descriptors of buffers used by test
22804 void XFBOverrideQualifiersWithAPITest::getBufferDescriptors(glw::GLuint test_case_index,
22805 bufferDescriptor::Vector& out_descriptors)
22807 const Utils::Type& type = getType(test_case_index);
22809 /* Test needs single uniform and xfb */
22810 out_descriptors.resize(2);
22812 /* Get references */
22813 bufferDescriptor& uniform = out_descriptors[0];
22814 bufferDescriptor& xfb = out_descriptors[1];
22817 uniform.m_index = 0;
22821 uniform.m_target = Utils::Buffer::Uniform;
22822 xfb.m_target = Utils::Buffer::Transform_feedback;
22825 const GLuint gen_start = Utils::s_rand;
22826 const std::vector<GLubyte>& vegeta_data = type.GenerateData();
22827 const std::vector<GLubyte>& trunks_data = type.GenerateData();
22828 const std::vector<GLubyte>& goku_data = type.GenerateData();
22830 Utils::s_rand = gen_start;
22831 const std::vector<GLubyte>& vegeta_data_pck = type.GenerateDataPacked();
22832 type.GenerateDataPacked(); // generate the data for trunks
22833 const std::vector<GLubyte>& goku_data_pck = type.GenerateDataPacked();
22835 const GLuint type_size = static_cast<GLuint>(vegeta_data.size());
22836 const GLuint type_size_pck = static_cast<GLuint>(vegeta_data_pck.size());
22839 uniform.m_initial_data.resize(3 * type_size);
22840 memcpy(&uniform.m_initial_data[0] + 0, &vegeta_data[0], type_size);
22841 memcpy(&uniform.m_initial_data[0] + type_size, &trunks_data[0], type_size);
22842 memcpy(&uniform.m_initial_data[0] + 2 * type_size, &goku_data[0], type_size);
22845 xfb.m_initial_data.resize(3 * type_size_pck);
22846 xfb.m_expected_data.resize(3 * type_size_pck);
22848 for (GLuint i = 0; i < 3 * type_size_pck; ++i)
22850 xfb.m_initial_data[i] = (glw::GLubyte)i;
22851 xfb.m_expected_data[i] = (glw::GLubyte)i;
22854 memcpy(&xfb.m_expected_data[0] + 0, &goku_data_pck[0], type_size_pck);
22855 memcpy(&xfb.m_expected_data[0] + 2 * type_size_pck, &vegeta_data_pck[0], type_size_pck);
22858 /** Get list of names of varyings that will be registered with TransformFeedbackVaryings
22861 * @param captured_varyings List of names
22863 void XFBOverrideQualifiersWithAPITest::getCapturedVaryings(glw::GLuint test_case_index,
22864 Utils::Program::NameVector& captured_varyings,
22865 GLint* xfb_components)
22867 captured_varyings.resize(1);
22869 captured_varyings[0] = "trunks";
22871 /* The test captures 3 varyings of type 'type' */
22872 Utils::Type type = getType(test_case_index);
22873 GLint type_size = type.GetSize(false);
22874 *xfb_components = 3 * type_size / 4;
22877 /** Get body of main function for given shader stage
22879 * @param test_case_index Index of test case
22880 * @param stage Shader stage
22881 * @param out_assignments Set to empty
22882 * @param out_calculations Set to empty
22884 void XFBOverrideQualifiersWithAPITest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
22885 std::string& out_assignments, std::string& out_calculations)
22887 out_calculations = "";
22889 static const GLchar* gs = " vegeta = uni_vegeta;\n"
22890 " trunks = uni_trunks;\n"
22891 " goku = uni_goku;\n";
22892 static const GLchar* fs = " fs_out = vec4(0);\n"
22893 " if (TYPE(1) == goku + trunks + vegeta)\n"
22895 " fs_out = vec4(1);\n"
22898 const GLchar* assignments = "";
22901 case Utils::Shader::FRAGMENT:
22904 case Utils::Shader::GEOMETRY:
22911 out_assignments = assignments;
22913 if (Utils::Shader::FRAGMENT == stage)
22915 const Utils::Type& type = getType(test_case_index);
22917 Utils::replaceAllTokens("TYPE", type.GetGLSLTypeName(), out_assignments);
22921 /** Get interface of shader
22923 * @param test_case_index Index of test case
22924 * @param stage Shader stage
22925 * @param out_interface Set to ""
22927 void XFBOverrideQualifiersWithAPITest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
22928 std::string& out_interface)
22930 static const GLchar* gs = "const uint sizeof_type = SIZE;\n"
22932 "layout (xfb_offset = 2 * sizeof_type) flat out TYPE vegeta;\n"
22933 " flat out TYPE trunks;\n"
22934 "layout (xfb_offset = 0) flat out TYPE goku;\n"
22937 There is no packing qualifier for uniform block gs_block, according to spec, it should be "shared" by default,
22938 the definition equals to "layout(binding=0, shared)", if the block is declared as shared, each block member will
22939 not be packed, and each block member's layout in memory is implementation dependent, so we can't use the API
22940 glBufferData() to update the UBO directly, we need to query each block member's offset first, then upload the
22941 data to the corresponding offset, otherwise we can't get the correct data from UBO; to make the test passed,
22942 we need to add the qualifier std140, and change the declaration as layout(binding=0, std140), which can make
22943 sure all the block members are packed and the application can upload the data by glBufferData() directly.
22945 "layout(binding = 0, std140) uniform gs_block {\n"
22946 " TYPE uni_vegeta;\n"
22947 " TYPE uni_trunks;\n"
22948 " TYPE uni_goku;\n"
22950 static const GLchar* fs = "flat in TYPE vegeta;\n"
22951 "flat in TYPE trunks;\n"
22952 "flat in TYPE goku;\n"
22954 "out vec4 fs_out;\n";
22956 const Utils::Type& type = getType(test_case_index);
22960 case Utils::Shader::FRAGMENT:
22961 out_interface = fs;
22963 case Utils::Shader::GEOMETRY:
22964 out_interface = gs;
22967 out_interface = "";
22971 if (Utils::Shader::GEOMETRY == stage)
22974 size_t position = 0;
22975 const GLuint type_size = type.GetSize();
22977 sprintf(buffer, "%d", type_size);
22979 Utils::replaceToken("SIZE", position, buffer, out_interface);
22982 Utils::replaceAllTokens("TYPE", type.GetGLSLTypeName(), out_interface);
22987 * @param test_case_index Index of test case
22989 * @return Name of type test in test_case_index
22991 std::string XFBOverrideQualifiersWithAPITest::getTestCaseName(glw::GLuint test_case_index)
22993 return getTypeName(test_case_index);
22996 /** Returns number of types to test
22998 * @return Number of types, 34
23000 glw::GLuint XFBOverrideQualifiersWithAPITest::getTestCaseNumber()
23002 return getTypesNumber();
23005 /** Inspects program to check if all resources are as expected
23007 * @param test_case_index Index of test case
23008 * @param program Program instance
23009 * @param out_stream Error message
23011 * @return true if everything is ok, false otherwise
23013 bool XFBOverrideQualifiersWithAPITest::inspectProgram(GLuint test_case_index, Utils::Program& program,
23014 std::stringstream& out_stream)
23017 const Utils::Type& type = getType(test_case_index);
23018 const GLuint type_size = type.GetSize(false);
23020 program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE,
23021 1 /* buf_size */, &stride);
23023 if ((GLint)(3 * type_size) != stride)
23025 out_stream << "Stride is: " << stride << " expected: " << (3 * type_size);
23035 * @param context Test context
23037 XFBVertexStreamsTest::XFBVertexStreamsTest(deqp::Context& context)
23038 : BufferTestBase(context, "xfb_vertex_streams",
23039 "Test verifies that xfb qualifier works with multiple output streams")
23041 /* Nothing to be done here */
23044 /** Get descriptors of buffers necessary for test
23047 * @param out_descriptors Descriptors of buffers used by test
23049 void XFBVertexStreamsTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
23050 bufferDescriptor::Vector& out_descriptors)
23052 const Utils::Type& type = Utils::Type::vec4;
23054 /* Test needs single uniform and three xfbs */
23055 out_descriptors.resize(4);
23057 /* Get references */
23058 bufferDescriptor& uniform = out_descriptors[0];
23059 bufferDescriptor& xfb_1 = out_descriptors[1];
23060 bufferDescriptor& xfb_2 = out_descriptors[2];
23061 bufferDescriptor& xfb_3 = out_descriptors[3];
23064 uniform.m_index = 0;
23070 uniform.m_target = Utils::Buffer::Uniform;
23071 xfb_1.m_target = Utils::Buffer::Transform_feedback;
23072 xfb_2.m_target = Utils::Buffer::Transform_feedback;
23073 xfb_3.m_target = Utils::Buffer::Transform_feedback;
23076 const std::vector<GLubyte>& goku_data = type.GenerateData();
23077 const std::vector<GLubyte>& gohan_data = type.GenerateData();
23078 const std::vector<GLubyte>& goten_data = type.GenerateData();
23079 const std::vector<GLubyte>& picolo_data = type.GenerateData();
23080 const std::vector<GLubyte>& vegeta_data = type.GenerateData();
23081 const std::vector<GLubyte>& bulma_data = type.GenerateData();
23083 const GLuint type_size = static_cast<GLuint>(vegeta_data.size());
23086 uniform.m_initial_data.resize(6 * type_size);
23087 memcpy(&uniform.m_initial_data[0] + 0, &goku_data[0], type_size);
23088 memcpy(&uniform.m_initial_data[0] + type_size, &gohan_data[0], type_size);
23089 memcpy(&uniform.m_initial_data[0] + 2 * type_size, &goten_data[0], type_size);
23090 memcpy(&uniform.m_initial_data[0] + 3 * type_size, &picolo_data[0], type_size);
23091 memcpy(&uniform.m_initial_data[0] + 4 * type_size, &vegeta_data[0], type_size);
23092 memcpy(&uniform.m_initial_data[0] + 5 * type_size, &bulma_data[0], type_size);
23095 static const GLuint xfb_stride = 64;
23096 xfb_1.m_initial_data.resize(xfb_stride);
23097 xfb_1.m_expected_data.resize(xfb_stride);
23098 xfb_2.m_initial_data.resize(xfb_stride);
23099 xfb_2.m_expected_data.resize(xfb_stride);
23100 xfb_3.m_initial_data.resize(xfb_stride);
23101 xfb_3.m_expected_data.resize(xfb_stride);
23103 for (GLuint i = 0; i < xfb_stride; ++i)
23105 xfb_1.m_initial_data[i] = (glw::GLubyte)i;
23106 xfb_1.m_expected_data[i] = (glw::GLubyte)i;
23107 xfb_2.m_initial_data[i] = (glw::GLubyte)i;
23108 xfb_2.m_expected_data[i] = (glw::GLubyte)i;
23109 xfb_3.m_initial_data[i] = (glw::GLubyte)i;
23110 xfb_3.m_expected_data[i] = (glw::GLubyte)i;
23113 memcpy(&xfb_1.m_expected_data[0] + 48, &goku_data[0], type_size);
23114 memcpy(&xfb_1.m_expected_data[0] + 32, &gohan_data[0], type_size);
23115 memcpy(&xfb_1.m_expected_data[0] + 16, &goten_data[0], type_size);
23116 memcpy(&xfb_3.m_expected_data[0] + 48, &picolo_data[0], type_size);
23117 memcpy(&xfb_3.m_expected_data[0] + 32, &vegeta_data[0], type_size);
23118 memcpy(&xfb_2.m_expected_data[0] + 32, &bulma_data[0], type_size);
23121 /** Get body of main function for given shader stage
23124 * @param stage Shader stage
23125 * @param out_assignments Set to empty
23126 * @param out_calculations Set to empty
23128 void XFBVertexStreamsTest::getShaderBody(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
23129 std::string& out_assignments, std::string& out_calculations)
23131 out_calculations = "";
23133 // the shader declares the output variables with different "stream" qualifier, to make the data can export to
23134 // each stream, we must call the function EmitStreamVertex() and EndStreamPrimitive() to make each vertex emitted
23135 // by the GS is assigned to specific stream.
23136 static const GLchar* gs = " goku = uni_goku;\n"
23137 " gohan = uni_gohan;\n"
23138 " goten = uni_goten;\n"
23139 " EmitStreamVertex(0);\n"
23140 " EndStreamPrimitive(0);\n"
23141 " picolo = uni_picolo;\n"
23142 " vegeta = uni_vegeta;\n"
23143 " EmitStreamVertex(1);\n"
23144 " EndStreamPrimitive(1);\n"
23145 " bulma = uni_bulma;\n"
23146 " EmitStreamVertex(2);\n"
23147 " EndStreamPrimitive(2);\n";
23149 static const GLchar* fs = " fs_out = gohan + goku + goten;\n";
23151 const GLchar* assignments = "";
23154 case Utils::Shader::FRAGMENT:
23157 case Utils::Shader::GEOMETRY:
23164 out_assignments = assignments;
23167 /** Get interface of shader
23170 * @param stage Shader stage
23171 * @param out_interface Set to ""
23173 void XFBVertexStreamsTest::getShaderInterface(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
23174 std::string& out_interface)
23176 static const GLchar* gs = "layout (xfb_buffer = 1, xfb_stride = 64) out;\n"
23177 "layout (xfb_buffer = 2, xfb_stride = 64) out;\n"
23178 "layout (xfb_buffer = 3, xfb_stride = 64) out;\n"
23180 "layout (stream = 0, xfb_buffer = 1, xfb_offset = 48) out vec4 goku;\n"
23181 "layout (stream = 0, xfb_buffer = 1, xfb_offset = 32) out vec4 gohan;\n"
23182 "layout (stream = 0, xfb_buffer = 1, xfb_offset = 16) out vec4 goten;\n"
23183 "layout (stream = 1, xfb_buffer = 3, xfb_offset = 48) out vec4 picolo;\n"
23184 "layout (stream = 1, xfb_buffer = 3, xfb_offset = 32) out vec4 vegeta;\n"
23185 "layout (stream = 2, xfb_buffer = 2, xfb_offset = 32) out vec4 bulma;\n"
23187 "layout(binding = 0) uniform gs_block {\n"
23188 " vec4 uni_goku;\n"
23189 " vec4 uni_gohan;\n"
23190 " vec4 uni_goten;\n"
23191 " vec4 uni_picolo;\n"
23192 " vec4 uni_vegeta;\n"
23193 " vec4 uni_bulma;\n"
23196 Fixed incorrect usage of in/out qualifier, the following variable should be input symbols for fragment shader
23198 static const GLchar* fs = "in vec4 goku;\n"
23202 "out vec4 fs_out;\n";
23206 case Utils::Shader::FRAGMENT:
23207 out_interface = fs;
23209 case Utils::Shader::GEOMETRY:
23210 out_interface = gs;
23213 out_interface = "";
23220 * @param context Test framework context
23222 XFBMultipleVertexStreamsTest::XFBMultipleVertexStreamsTest(deqp::Context& context)
23223 : NegativeTestBase(
23224 context, "xfb_multiple_vertex_streams",
23225 "Test verifies that compiler reports error when multiple streams are captured with same xfb_buffer")
23229 /** Source for given test case and stage
23232 * @param stage Shader stage
23234 * @return Shader source
23236 std::string XFBMultipleVertexStreamsTest::getShaderSource(GLuint /* test_case_index */, Utils::Shader::STAGES stage)
23238 static const GLchar* var_definition = "const uint valid_stride = 64;\n"
23240 "layout (xfb_buffer = 1, xfb_stride = valid_stride) out;\n"
23241 "layout (xfb_buffer = 3, xfb_stride = valid_stride) out;\n"
23244 "layout (stream = 0, xfb_buffer = 1, xfb_offset = 48) out vec4 goku;\n"
23245 "layout (stream = 1, xfb_buffer = 1, xfb_offset = 32) out vec4 gohan;\n"
23246 "layout (stream = 2, xfb_buffer = 1, xfb_offset = 16) out vec4 goten;\n";
23247 static const GLchar* var_use = " goku = result / 2;\n"
23248 " gohan = result / 4;\n"
23249 " goten = result / 6;\n";
23250 static const GLchar* fs = "#version 430 core\n"
23251 "#extension GL_ARB_enhanced_layouts : require\n"
23255 "out vec4 fs_out;\n"
23259 " fs_out = gs_fs + goku;\n"
23262 static const GLchar* gs = "#version 430 core\n"
23263 "#extension GL_ARB_enhanced_layouts : require\n"
23265 "layout(points) in;\n"
23266 "layout(triangle_strip, max_vertices = 4) out;\n"
23270 "in vec4 tes_gs[];\n"
23271 "out vec4 gs_fs;\n"
23275 " vec4 result = tes_gs[0];\n"
23279 " gs_fs = result;\n"
23280 " gl_Position = vec4(-1, -1, 0, 1);\n"
23282 " gs_fs = result;\n"
23283 " gl_Position = vec4(-1, 1, 0, 1);\n"
23285 " gs_fs = result;\n"
23286 " gl_Position = vec4(1, -1, 0, 1);\n"
23288 " gs_fs = result;\n"
23289 " gl_Position = vec4(1, 1, 0, 1);\n"
23293 static const GLchar* vs = "#version 430 core\n"
23294 "#extension GL_ARB_enhanced_layouts : require\n"
23297 "out vec4 vs_tcs;\n"
23301 " vs_tcs = in_vs;\n"
23305 std::string source;
23307 if (Utils::Shader::GEOMETRY == stage)
23309 size_t position = 0;
23313 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
23314 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
23320 case Utils::Shader::FRAGMENT:
23323 case Utils::Shader::VERTEX:
23334 /** Selects if "compute" stage is relevant for test
23340 bool XFBMultipleVertexStreamsTest::isComputeRelevant(GLuint /* test_case_index */)
23347 * @param context Test framework context
23349 XFBExceedBufferLimitTest::XFBExceedBufferLimitTest(deqp::Context& context)
23350 : NegativeTestBase(context, "xfb_exceed_buffer_limit",
23351 "Test verifies that compiler reports error when xfb_buffer qualifier exceeds limit")
23355 /** Source for given test case and stage
23357 * @param test_case_index Index of test case
23358 * @param stage Shader stage
23360 * @return Shader source
23362 std::string XFBExceedBufferLimitTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
23364 static const GLchar* block_var_definition = "const uint buffer_index = BUFFER;\n"
23366 "layout (xfb_buffer = buffer_index, xfb_offset = 0) out Goku {\n"
23369 static const GLchar* global_var_definition = "const uint buffer_index = BUFFER;\n"
23371 "layout (xfb_buffer = buffer_index) out;\n";
23372 static const GLchar* vector_var_definition = "const uint buffer_index = BUFFER;\n"
23374 "layout (xfb_buffer = buffer_index) out vec4 gokuARRAY;\n";
23375 static const GLchar* block_use = " gokuINDEX.member = result / 2;\n";
23376 static const GLchar* global_use = "";
23377 static const GLchar* vector_use = " gokuINDEX = result / 2;\n";
23378 static const GLchar* fs = "#version 430 core\n"
23379 "#extension GL_ARB_enhanced_layouts : require\n"
23382 "out vec4 fs_out;\n"
23386 " fs_out = gs_fs;\n"
23389 static const GLchar* gs_tested = "#version 430 core\n"
23390 "#extension GL_ARB_enhanced_layouts : require\n"
23392 "layout(points) in;\n"
23393 "layout(triangle_strip, max_vertices = 4) out;\n"
23397 "in vec4 tes_gs[];\n"
23398 "out vec4 gs_fs;\n"
23402 " vec4 result = tes_gs[0];\n"
23406 " gs_fs = result;\n"
23407 " gl_Position = vec4(-1, -1, 0, 1);\n"
23409 " gs_fs = result;\n"
23410 " gl_Position = vec4(-1, 1, 0, 1);\n"
23412 " gs_fs = result;\n"
23413 " gl_Position = vec4(1, -1, 0, 1);\n"
23415 " gs_fs = result;\n"
23416 " gl_Position = vec4(1, 1, 0, 1);\n"
23420 static const GLchar* tcs = "#version 430 core\n"
23421 "#extension GL_ARB_enhanced_layouts : require\n"
23423 "layout(vertices = 1) out;\n"
23425 "in vec4 vs_tcs[];\n"
23426 "out vec4 tcs_tes[];\n"
23431 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
23433 " gl_TessLevelOuter[0] = 1.0;\n"
23434 " gl_TessLevelOuter[1] = 1.0;\n"
23435 " gl_TessLevelOuter[2] = 1.0;\n"
23436 " gl_TessLevelOuter[3] = 1.0;\n"
23437 " gl_TessLevelInner[0] = 1.0;\n"
23438 " gl_TessLevelInner[1] = 1.0;\n"
23441 static const GLchar* tcs_tested = "#version 430 core\n"
23442 "#extension GL_ARB_enhanced_layouts : require\n"
23444 "layout(vertices = 1) out;\n"
23448 "in vec4 vs_tcs[];\n"
23449 "out vec4 tcs_tes[];\n"
23453 " vec4 result = vs_tcs[gl_InvocationID];\n"
23457 " tcs_tes[gl_InvocationID] = result;\n"
23459 " gl_TessLevelOuter[0] = 1.0;\n"
23460 " gl_TessLevelOuter[1] = 1.0;\n"
23461 " gl_TessLevelOuter[2] = 1.0;\n"
23462 " gl_TessLevelOuter[3] = 1.0;\n"
23463 " gl_TessLevelInner[0] = 1.0;\n"
23464 " gl_TessLevelInner[1] = 1.0;\n"
23467 static const GLchar* tes_tested = "#version 430 core\n"
23468 "#extension GL_ARB_enhanced_layouts : require\n"
23470 "layout(isolines, point_mode) in;\n"
23474 "in vec4 tcs_tes[];\n"
23475 "out vec4 tes_gs;\n"
23479 " vec4 result = tcs_tes[0];\n"
23483 " tes_gs += result;\n"
23486 static const GLchar* vs = "#version 430 core\n"
23487 "#extension GL_ARB_enhanced_layouts : require\n"
23490 "out vec4 vs_tcs;\n"
23494 " vs_tcs = in_vs;\n"
23497 static const GLchar* vs_tested = "#version 430 core\n"
23498 "#extension GL_ARB_enhanced_layouts : require\n"
23503 "out vec4 vs_tcs;\n"
23507 " vec4 result = in_vs;\n"
23511 " vs_tcs = result;\n"
23515 std::string source;
23516 testCase& test_case = m_test_cases[test_case_index];
23518 if (test_case.m_stage == stage)
23520 const GLchar* array = "";
23522 const Functions& gl = m_context.getRenderContext().getFunctions();
23523 const GLchar* index = "";
23524 GLint max_n_xfb = 0;
23525 size_t position = 0;
23527 const GLchar* var_definition = 0;
23528 const GLchar* var_use = 0;
23530 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_n_xfb);
23531 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
23533 sprintf(buffer, "%d", max_n_xfb);
23535 switch (test_case.m_case)
23538 var_definition = block_var_definition;
23539 var_use = block_use;
23542 var_definition = global_var_definition;
23543 var_use = global_use;
23546 var_definition = vector_var_definition;
23547 var_use = vector_use;
23550 TCU_FAIL("Invalid enum");
23555 case Utils::Shader::GEOMETRY:
23556 source = gs_tested;
23560 case Utils::Shader::TESS_CTRL:
23561 source = tcs_tested;
23563 index = "[gl_InvocationID]";
23565 case Utils::Shader::TESS_EVAL:
23566 source = tes_tested;
23570 case Utils::Shader::VERTEX:
23571 source = vs_tested;
23574 TCU_FAIL("Invalid enum");
23578 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
23580 Utils::replaceToken("BUFFER", position, buffer, source);
23581 if (GLOBAL != test_case.m_case)
23583 Utils::replaceToken("ARRAY", position, array, source);
23585 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
23587 Utils::replaceAllTokens("INDEX", index, source);
23591 switch (test_case.m_stage)
23593 case Utils::Shader::GEOMETRY:
23596 case Utils::Shader::FRAGMENT:
23599 case Utils::Shader::VERTEX:
23606 case Utils::Shader::TESS_CTRL:
23609 case Utils::Shader::FRAGMENT:
23612 case Utils::Shader::VERTEX:
23619 case Utils::Shader::TESS_EVAL:
23622 case Utils::Shader::FRAGMENT:
23625 case Utils::Shader::TESS_CTRL:
23628 case Utils::Shader::VERTEX:
23635 case Utils::Shader::VERTEX:
23638 case Utils::Shader::FRAGMENT:
23646 TCU_FAIL("Invalid enum");
23654 /** Get description of test case
23656 * @param test_case_index Index of test case
23658 * @return Test case description
23660 std::string XFBExceedBufferLimitTest::getTestCaseName(GLuint test_case_index)
23662 std::stringstream stream;
23663 testCase& test_case = m_test_cases[test_case_index];
23665 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", case: ";
23667 switch (test_case.m_case)
23673 stream << "GLOBAL";
23676 stream << "VECTOR";
23679 TCU_FAIL("Invalid enum");
23682 return stream.str();
23685 /** Get number of test cases
23687 * @return Number of test cases
23689 GLuint XFBExceedBufferLimitTest::getTestCaseNumber()
23691 return static_cast<GLuint>(m_test_cases.size());
23694 /** Selects if "compute" stage is relevant for test
23700 bool XFBExceedBufferLimitTest::isComputeRelevant(GLuint /* test_case_index */)
23705 /** Prepare all test cases
23708 void XFBExceedBufferLimitTest::testInit()
23710 for (GLuint c = 0; c < CASE_MAX; ++c)
23712 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
23714 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
23715 (Utils::Shader::FRAGMENT == stage))
23720 testCase test_case = { (CASES)c, (Utils::Shader::STAGES)stage };
23722 m_test_cases.push_back(test_case);
23729 * @param context Test framework context
23731 XFBExceedOffsetLimitTest::XFBExceedOffsetLimitTest(deqp::Context& context)
23732 : NegativeTestBase(context, "xfb_exceed_offset_limit",
23733 "Test verifies that compiler reports error when xfb_offset qualifier exceeds limit")
23737 /** Source for given test case and stage
23739 * @param test_case_index Index of test case
23740 * @param stage Shader stage
23742 * @return Shader source
23744 std::string XFBExceedOffsetLimitTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
23746 static const GLchar* block_var_definition = "const uint max_size = SIZE;\n"
23748 "layout (xfb_buffer = 0, xfb_offset = max_size + 16) out Goku {\n"
23751 static const GLchar* global_var_definition = "const uint max_size = SIZE;\n"
23753 "layout (xfb_buffer = 0, xfb_stride = max_size + 16) out;\n";
23754 static const GLchar* vector_var_definition =
23755 "const uint max_size = SIZE;\n"
23757 "layout (xfb_buffer = 0, xfb_offset = max_size + 16) out vec4 gokuARRAY;\n";
23758 static const GLchar* block_use = " gokuINDEX.member = result / 2;\n";
23759 static const GLchar* global_use = "";
23760 static const GLchar* vector_use = " gokuINDEX = result / 2;\n";
23761 static const GLchar* fs = "#version 430 core\n"
23762 "#extension GL_ARB_enhanced_layouts : require\n"
23765 "out vec4 fs_out;\n"
23769 " fs_out = gs_fs;\n"
23772 static const GLchar* gs_tested = "#version 430 core\n"
23773 "#extension GL_ARB_enhanced_layouts : require\n"
23775 "layout(points) in;\n"
23776 "layout(triangle_strip, max_vertices = 4) out;\n"
23780 "in vec4 tes_gs[];\n"
23781 "out vec4 gs_fs;\n"
23785 " vec4 result = tes_gs[0];\n"
23789 " gs_fs = result;\n"
23790 " gl_Position = vec4(-1, -1, 0, 1);\n"
23792 " gs_fs = result;\n"
23793 " gl_Position = vec4(-1, 1, 0, 1);\n"
23795 " gs_fs = result;\n"
23796 " gl_Position = vec4(1, -1, 0, 1);\n"
23798 " gs_fs = result;\n"
23799 " gl_Position = vec4(1, 1, 0, 1);\n"
23803 static const GLchar* tcs = "#version 430 core\n"
23804 "#extension GL_ARB_enhanced_layouts : require\n"
23806 "layout(vertices = 1) out;\n"
23808 "in vec4 vs_tcs[];\n"
23809 "out vec4 tcs_tes[];\n"
23814 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
23816 " gl_TessLevelOuter[0] = 1.0;\n"
23817 " gl_TessLevelOuter[1] = 1.0;\n"
23818 " gl_TessLevelOuter[2] = 1.0;\n"
23819 " gl_TessLevelOuter[3] = 1.0;\n"
23820 " gl_TessLevelInner[0] = 1.0;\n"
23821 " gl_TessLevelInner[1] = 1.0;\n"
23824 static const GLchar* tcs_tested = "#version 430 core\n"
23825 "#extension GL_ARB_enhanced_layouts : require\n"
23827 "layout(vertices = 1) out;\n"
23831 "in vec4 vs_tcs[];\n"
23832 "out vec4 tcs_tes[];\n"
23836 " vec4 result = vs_tcs[gl_InvocationID];\n"
23840 " tcs_tes[gl_InvocationID] = result;\n"
23842 " gl_TessLevelOuter[0] = 1.0;\n"
23843 " gl_TessLevelOuter[1] = 1.0;\n"
23844 " gl_TessLevelOuter[2] = 1.0;\n"
23845 " gl_TessLevelOuter[3] = 1.0;\n"
23846 " gl_TessLevelInner[0] = 1.0;\n"
23847 " gl_TessLevelInner[1] = 1.0;\n"
23850 static const GLchar* tes_tested = "#version 430 core\n"
23851 "#extension GL_ARB_enhanced_layouts : require\n"
23853 "layout(isolines, point_mode) in;\n"
23857 "in vec4 tcs_tes[];\n"
23858 "out vec4 tes_gs;\n"
23862 " vec4 result = tcs_tes[0];\n"
23866 " tes_gs += result;\n"
23869 static const GLchar* vs = "#version 430 core\n"
23870 "#extension GL_ARB_enhanced_layouts : require\n"
23873 "out vec4 vs_tcs;\n"
23877 " vs_tcs = in_vs;\n"
23880 static const GLchar* vs_tested = "#version 430 core\n"
23881 "#extension GL_ARB_enhanced_layouts : require\n"
23886 "out vec4 vs_tcs;\n"
23890 " vec4 result = in_vs;\n"
23894 " vs_tcs = result;\n"
23898 std::string source;
23899 testCase& test_case = m_test_cases[test_case_index];
23901 if (test_case.m_stage == stage)
23903 const GLchar* array = "";
23905 const Functions& gl = m_context.getRenderContext().getFunctions();
23906 const GLchar* index = "";
23907 GLint max_n_xfb_comp = 0;
23908 GLint max_n_xfb_bytes = 0;
23909 size_t position = 0;
23911 const GLchar* var_definition = 0;
23912 const GLchar* var_use = 0;
23914 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_n_xfb_comp);
23915 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
23917 max_n_xfb_bytes = max_n_xfb_comp * 4;
23919 sprintf(buffer, "%d", max_n_xfb_bytes);
23921 switch (test_case.m_case)
23924 var_definition = block_var_definition;
23925 var_use = block_use;
23928 var_definition = global_var_definition;
23929 var_use = global_use;
23932 var_definition = vector_var_definition;
23933 var_use = vector_use;
23936 TCU_FAIL("Invalid enum");
23938 // It is a compile time error to apply xfb_offset to the declaration of an unsized array(GLSL4.5 spec: Page73)
23939 // change array = "[]" to "[1]"
23942 case Utils::Shader::GEOMETRY:
23943 source = gs_tested;
23947 case Utils::Shader::TESS_CTRL:
23948 source = tcs_tested;
23950 index = "[gl_InvocationID]";
23952 case Utils::Shader::TESS_EVAL:
23953 source = tes_tested;
23957 case Utils::Shader::VERTEX:
23958 source = vs_tested;
23961 TCU_FAIL("Invalid enum");
23965 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
23967 Utils::replaceToken("SIZE", position, buffer, source);
23968 if (GLOBAL != test_case.m_case)
23970 Utils::replaceToken("ARRAY", position, array, source);
23972 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
23974 Utils::replaceAllTokens("INDEX", index, source);
23978 switch (test_case.m_stage)
23980 case Utils::Shader::GEOMETRY:
23983 case Utils::Shader::FRAGMENT:
23986 case Utils::Shader::VERTEX:
23993 case Utils::Shader::TESS_CTRL:
23996 case Utils::Shader::FRAGMENT:
23999 case Utils::Shader::VERTEX:
24006 case Utils::Shader::TESS_EVAL:
24009 case Utils::Shader::FRAGMENT:
24012 case Utils::Shader::TESS_CTRL:
24015 case Utils::Shader::VERTEX:
24022 case Utils::Shader::VERTEX:
24025 case Utils::Shader::FRAGMENT:
24033 TCU_FAIL("Invalid enum");
24041 /** Get description of test case
24043 * @param test_case_index Index of test case
24045 * @return Test case description
24047 std::string XFBExceedOffsetLimitTest::getTestCaseName(GLuint test_case_index)
24049 std::stringstream stream;
24050 testCase& test_case = m_test_cases[test_case_index];
24052 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", case: ";
24054 switch (test_case.m_case)
24060 stream << "GLOBAL";
24063 stream << "VECTOR";
24066 TCU_FAIL("Invalid enum");
24069 return stream.str();
24072 /** Get number of test cases
24074 * @return Number of test cases
24076 GLuint XFBExceedOffsetLimitTest::getTestCaseNumber()
24078 return static_cast<GLuint>(m_test_cases.size());
24081 /** Selects if "compute" stage is relevant for test
24087 bool XFBExceedOffsetLimitTest::isComputeRelevant(GLuint /* test_case_index */)
24092 /** Prepare all test cases
24095 void XFBExceedOffsetLimitTest::testInit()
24097 for (GLuint c = 0; c < CASE_MAX; ++c)
24099 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
24101 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
24102 (Utils::Shader::FRAGMENT == stage))
24107 testCase test_case = { (CASES)c, (Utils::Shader::STAGES)stage };
24109 m_test_cases.push_back(test_case);
24116 * @param context Test context
24118 XFBGlobalBufferTest::XFBGlobalBufferTest(deqp::Context& context)
24119 : BufferTestBase(context, "xfb_global_buffer", "Test verifies that global xfb_buffer qualifier is respected")
24121 /* Nothing to be done here */
24124 /** Get descriptors of buffers necessary for test
24126 * @param test_case_index Index of test case
24127 * @param out_descriptors Descriptors of buffers used by test
24129 void XFBGlobalBufferTest::getBufferDescriptors(glw::GLuint test_case_index, bufferDescriptor::Vector& out_descriptors)
24131 // the function "getType(test_case_index)" can't return correct data type, so change code as following:
24132 const Utils::Type& type = m_test_cases[test_case_index].m_type;
24134 /* Test needs single uniform and two xfbs */
24135 out_descriptors.resize(3);
24137 /* Get references */
24138 bufferDescriptor& uniform = out_descriptors[0];
24139 bufferDescriptor& xfb_1 = out_descriptors[1];
24140 bufferDescriptor& xfb_3 = out_descriptors[2];
24143 uniform.m_index = 0;
24148 uniform.m_target = Utils::Buffer::Uniform;
24149 xfb_1.m_target = Utils::Buffer::Transform_feedback;
24150 xfb_3.m_target = Utils::Buffer::Transform_feedback;
24153 const GLuint gen_start = Utils::s_rand;
24154 const std::vector<GLubyte>& chichi_data = type.GenerateData();
24155 const std::vector<GLubyte>& bulma_data = type.GenerateData();
24156 const std::vector<GLubyte>& trunks_data = type.GenerateData();
24157 const std::vector<GLubyte>& bra_data = type.GenerateData();
24158 const std::vector<GLubyte>& gohan_data = type.GenerateData();
24159 const std::vector<GLubyte>& goten_data = type.GenerateData();
24161 Utils::s_rand = gen_start;
24162 const std::vector<GLubyte>& chichi_data_pck = type.GenerateDataPacked();
24163 const std::vector<GLubyte>& bulma_data_pck = type.GenerateDataPacked();
24164 const std::vector<GLubyte>& trunks_data_pck = type.GenerateDataPacked();
24165 const std::vector<GLubyte>& bra_data_pck = type.GenerateDataPacked();
24166 const std::vector<GLubyte>& gohan_data_pck = type.GenerateDataPacked();
24167 const std::vector<GLubyte>& goten_data_pck = type.GenerateDataPacked();
24169 const GLuint type_size = static_cast<GLuint>(chichi_data.size());
24170 const GLuint type_size_pck = static_cast<GLuint>(chichi_data_pck.size());
24173 uniform.m_initial_data.resize(6 * type_size);
24174 memcpy(&uniform.m_initial_data[0] + 0, &chichi_data[0], type_size);
24175 memcpy(&uniform.m_initial_data[0] + type_size, &bulma_data[0], type_size);
24176 memcpy(&uniform.m_initial_data[0] + 2 * type_size, &trunks_data[0], type_size);
24177 memcpy(&uniform.m_initial_data[0] + 3 * type_size, &bra_data[0], type_size);
24178 memcpy(&uniform.m_initial_data[0] + 4 * type_size, &gohan_data[0], type_size);
24179 memcpy(&uniform.m_initial_data[0] + 5 * type_size, &goten_data[0], type_size);
24182 xfb_1.m_initial_data.resize(3 * type_size_pck);
24183 xfb_1.m_expected_data.resize(3 * type_size_pck);
24184 xfb_3.m_initial_data.resize(3 * type_size_pck);
24185 xfb_3.m_expected_data.resize(3 * type_size_pck);
24187 for (GLuint i = 0; i < 3 * type_size_pck; ++i)
24189 xfb_1.m_initial_data[i] = (glw::GLubyte)i;
24190 xfb_1.m_expected_data[i] = (glw::GLubyte)i;
24191 xfb_3.m_initial_data[i] = (glw::GLubyte)i;
24192 xfb_3.m_expected_data[i] = (glw::GLubyte)i;
24195 memcpy(&xfb_3.m_expected_data[0] + 2 * type_size_pck, &chichi_data_pck[0], type_size_pck);
24196 memcpy(&xfb_1.m_expected_data[0] + 0 * type_size_pck, &bulma_data_pck[0], type_size_pck);
24197 memcpy(&xfb_1.m_expected_data[0] + 1 * type_size_pck, &trunks_data_pck[0], type_size_pck);
24198 memcpy(&xfb_1.m_expected_data[0] + 2 * type_size_pck, &bra_data_pck[0], type_size_pck);
24199 memcpy(&xfb_3.m_expected_data[0] + 0 * type_size_pck, &gohan_data_pck[0], type_size_pck);
24200 memcpy(&xfb_3.m_expected_data[0] + 1 * type_size_pck, &goten_data_pck[0], type_size_pck);
24203 /** Source for given test case and stage
24205 * @param test_case_index Index of test case
24206 * @param stage Shader stage
24208 * @return Shader source
24210 std::string XFBGlobalBufferTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
24212 static const GLchar* fs =
24213 "#version 430 core\n"
24214 "#extension GL_ARB_enhanced_layouts : require\n"
24216 "flat in TYPE chichi;\n"
24217 "flat in TYPE bulma;\n"
24219 " flat TYPE trunk;\n"
24220 " flat TYPE bra;\n"
24223 " flat TYPE gohan;\n"
24224 " flat TYPE goten;\n"
24227 "out vec4 fs_out;\n"
24231 " fs_out = vec4(1);\n"
24232 " if (TYPE(1) != chichi + bulma + vegeta.trunk + vegeta.bra + goku.gohan + goku.goten)\n"
24234 " fs_out = vec4(0);\n"
24239 static const GLchar* gs = "#version 430 core\n"
24240 "#extension GL_ARB_enhanced_layouts : require\n"
24242 "layout(points) in;\n"
24243 "layout(points, max_vertices = 1) out;\n"
24254 static const GLchar* tcs = "#version 430 core\n"
24255 "#extension GL_ARB_enhanced_layouts : require\n"
24257 "layout(vertices = 1) out;\n"
24262 " gl_TessLevelOuter[0] = 1.0;\n"
24263 " gl_TessLevelOuter[1] = 1.0;\n"
24264 " gl_TessLevelOuter[2] = 1.0;\n"
24265 " gl_TessLevelOuter[3] = 1.0;\n"
24266 " gl_TessLevelInner[0] = 1.0;\n"
24267 " gl_TessLevelInner[1] = 1.0;\n"
24271 static const GLchar* tes = "#version 430 core\n"
24272 "#extension GL_ARB_enhanced_layouts : require\n"
24274 "layout(isolines, point_mode) in;\n"
24284 static const GLchar* vs = "#version 430 core\n"
24285 "#extension GL_ARB_enhanced_layouts : require\n"
24292 static const GLchar* vs_tested = "#version 430 core\n"
24293 "#extension GL_ARB_enhanced_layouts : require\n"
24303 std::string source;
24304 const _testCase& test_case = m_test_cases[test_case_index];
24305 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
24307 if (test_case.m_stage == stage)
24309 std::string assignments = " chichi = uni_chichi;\n"
24310 " bulma = uni_bulma;\n"
24311 " vegeta.trunk = uni_trunk;\n"
24312 " vegeta.bra = uni_bra;\n"
24313 " goku.gohan = uni_gohan;\n"
24314 " goku.goten = uni_goten;\n";
24316 std::string interface = "layout (xfb_buffer = 3) out;\n"
24318 "const uint type_size = SIZE;\n"
24320 "layout ( xfb_offset = 2 * type_size) flat out TYPE chichi;\n"
24321 "layout (xfb_buffer = 1, xfb_offset = 0) flat out TYPE bulma;\n"
24322 "layout (xfb_buffer = 1, xfb_offset = 1 * type_size) out Vegeta {\n"
24323 " flat TYPE trunk;\n"
24324 " flat TYPE bra;\n"
24326 "layout ( xfb_offset = 0) out Goku {\n"
24327 " flat TYPE gohan;\n"
24328 " flat TYPE goten;\n"
24331 // Uniform block must be declared with std140, otherwise each block member is not packed
24332 "layout(binding = 0, std140) uniform block {\n"
24333 " TYPE uni_chichi;\n"
24334 " TYPE uni_bulma;\n"
24335 " TYPE uni_trunk;\n"
24337 " TYPE uni_gohan;\n"
24338 " TYPE uni_goten;\n"
24341 /* Prepare interface string */
24344 size_t position = 0;
24345 const GLuint type_size = test_case.m_type.GetSize();
24347 sprintf(buffer, "%d", type_size);
24349 Utils::replaceToken("SIZE", position, buffer, interface);
24350 Utils::replaceAllTokens("TYPE", type_name, interface);
24355 case Utils::Shader::GEOMETRY:
24358 case Utils::Shader::TESS_EVAL:
24361 case Utils::Shader::VERTEX:
24362 source = vs_tested;
24365 TCU_FAIL("Invalid enum");
24368 /* Replace tokens */
24370 size_t position = 0;
24372 Utils::replaceToken("INTERFACE", position, interface.c_str(), source);
24373 Utils::replaceToken("ASSIGNMENTS", position, assignments.c_str(), source);
24378 switch (test_case.m_stage)
24380 case Utils::Shader::GEOMETRY:
24383 case Utils::Shader::FRAGMENT:
24385 Utils::replaceAllTokens("TYPE", type_name, source);
24387 case Utils::Shader::VERTEX:
24394 case Utils::Shader::TESS_EVAL:
24397 case Utils::Shader::FRAGMENT:
24399 Utils::replaceAllTokens("TYPE", type_name, source);
24401 case Utils::Shader::TESS_CTRL:
24404 case Utils::Shader::VERTEX:
24411 case Utils::Shader::VERTEX:
24414 case Utils::Shader::FRAGMENT:
24416 Utils::replaceAllTokens("TYPE", type_name, source);
24423 TCU_FAIL("Invalid enum");
24431 /** Get name of test case
24433 * @param test_case_index Index of test case
24435 * @return Name of case
24437 std::string XFBGlobalBufferTest::getTestCaseName(GLuint test_case_index)
24440 const _testCase& test_case = m_test_cases[test_case_index];
24442 name = "Tested stage: ";
24443 name.append(Utils::Shader::GetStageName(test_case.m_stage));
24444 name.append(". Tested type: ");
24445 name.append(test_case.m_type.GetGLSLTypeName());
24450 /** Get number of cases
24452 * @return Number of test cases
24454 GLuint XFBGlobalBufferTest::getTestCaseNumber()
24456 return static_cast<GLuint>(m_test_cases.size());
24459 /** Prepare set of test cases
24462 void XFBGlobalBufferTest::testInit()
24464 GLuint n_types = getTypesNumber();
24466 for (GLuint i = 0; i < n_types; ++i)
24468 const Utils::Type& type = getType(i);
24470 When the tfx varying is the following type, the number of output exceeds the gl_MaxVaryingComponents, which will
24471 cause a link time error.
24473 if (strcmp(type.GetGLSLTypeName(), "dmat3") == 0 || strcmp(type.GetGLSLTypeName(), "dmat4") == 0 ||
24474 strcmp(type.GetGLSLTypeName(), "dmat3x4") == 0 || strcmp(type.GetGLSLTypeName(), "dmat4x3") == 0)
24478 const _testCase test_cases[] = { { Utils::Shader::VERTEX, type },
24479 { Utils::Shader::GEOMETRY, type },
24480 { Utils::Shader::TESS_EVAL, type } };
24482 m_test_cases.push_back(test_cases[0]);
24483 m_test_cases.push_back(test_cases[1]);
24484 m_test_cases.push_back(test_cases[2]);
24490 * @param context Test context
24492 XFBStrideTest::XFBStrideTest(deqp::Context& context)
24493 : BufferTestBase(context, "xfb_stride", "Test verifies that correct stride is used for all types")
24495 /* Nothing to be done here */
24498 /** Execute drawArrays for single vertex
24500 * @param test_case_index
24504 bool XFBStrideTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
24506 const Functions& gl = m_context.getRenderContext().getFunctions();
24507 GLenum primitive_type = GL_PATCHES;
24508 const testCase& test_case = m_test_cases[test_case_index];
24510 if (Utils::Shader::VERTEX == test_case.m_stage)
24512 primitive_type = GL_POINTS;
24515 gl.disable(GL_RASTERIZER_DISCARD);
24516 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
24518 gl.beginTransformFeedback(GL_POINTS);
24519 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
24521 gl.drawArrays(primitive_type, 0 /* first */, 2 /* count */);
24522 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
24524 gl.endTransformFeedback();
24525 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
24530 /** Get descriptors of buffers necessary for test
24532 * @param test_case_index Index of test case
24533 * @param out_descriptors Descriptors of buffers used by test
24535 void XFBStrideTest::getBufferDescriptors(GLuint test_case_index, bufferDescriptor::Vector& out_descriptors)
24537 const testCase& test_case = m_test_cases[test_case_index];
24538 const Utils::Type& type = test_case.m_type;
24540 /* Test needs single uniform and xfb */
24541 out_descriptors.resize(2);
24543 /* Get references */
24544 bufferDescriptor& uniform = out_descriptors[0];
24545 bufferDescriptor& xfb = out_descriptors[1];
24548 uniform.m_index = 0;
24552 uniform.m_target = Utils::Buffer::Uniform;
24553 xfb.m_target = Utils::Buffer::Transform_feedback;
24556 const GLuint rand_start = Utils::s_rand;
24557 const std::vector<GLubyte>& uniform_data = type.GenerateData();
24559 Utils::s_rand = rand_start;
24560 const std::vector<GLubyte>& xfb_data = type.GenerateDataPacked();
24562 const GLuint uni_type_size = static_cast<GLuint>(uniform_data.size());
24563 const GLuint xfb_type_size = static_cast<GLuint>(xfb_data.size());
24565 Note: If xfb varying output from vertex shader, the variable "goku" will only output once to transform feedback buffer,
24566 if xfb varying output from TES or GS, because the input primitive type in TES is defined as "layout(isolines, point_mode) in;",
24567 the primitive type is line which make the variable "goku" will output twice to transform feedback buffer, so for vertex shader
24568 only one valid data should be initialized in xfb.m_expected_data
24570 const GLuint xfb_data_size = (test_case.m_stage == Utils::Shader::VERTEX) ? xfb_type_size : xfb_type_size * 2;
24572 uniform.m_initial_data.resize(uni_type_size);
24573 memcpy(&uniform.m_initial_data[0] + 0 * uni_type_size, &uniform_data[0], uni_type_size);
24576 xfb.m_initial_data.resize(xfb_data_size);
24577 xfb.m_expected_data.resize(xfb_data_size);
24579 for (GLuint i = 0; i < xfb_data_size; ++i)
24581 xfb.m_initial_data[i] = (glw::GLubyte)i;
24582 xfb.m_expected_data[i] = (glw::GLubyte)i;
24585 if (test_case.m_stage == Utils::Shader::VERTEX)
24587 memcpy(&xfb.m_expected_data[0] + 0 * xfb_type_size, &xfb_data[0], xfb_type_size);
24591 memcpy(&xfb.m_expected_data[0] + 0 * xfb_type_size, &xfb_data[0], xfb_type_size);
24592 memcpy(&xfb.m_expected_data[0] + 1 * xfb_type_size, &xfb_data[0], xfb_type_size);
24596 /** Get body of main function for given shader stage
24598 * @param test_case_index Index of test case
24599 * @param stage Shader stage
24600 * @param out_assignments Set to empty
24601 * @param out_calculations Set to empty
24603 void XFBStrideTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage, std::string& out_assignments,
24604 std::string& out_calculations)
24606 const testCase& test_case = m_test_cases[test_case_index];
24608 out_calculations = "";
24610 static const GLchar* vs_tes_gs = " goku = uni_goku;\n";
24611 static const GLchar* fs = " fs_out = vec4(1, 0.25, 0.5, 0.75);\n"
24612 " if (TYPE(0) == goku)\n"
24614 " fs_out = vec4(1, 0.75, 0.5, 0.5);\n"
24617 const GLchar* assignments = "";
24619 if (test_case.m_stage == stage)
24623 case Utils::Shader::GEOMETRY:
24624 assignments = vs_tes_gs;
24626 case Utils::Shader::TESS_EVAL:
24627 assignments = vs_tes_gs;
24629 case Utils::Shader::VERTEX:
24630 assignments = vs_tes_gs;
24633 TCU_FAIL("Invalid enum");
24640 case Utils::Shader::FRAGMENT:
24643 case Utils::Shader::GEOMETRY:
24644 case Utils::Shader::TESS_CTRL:
24645 case Utils::Shader::TESS_EVAL:
24646 case Utils::Shader::VERTEX:
24649 TCU_FAIL("Invalid enum");
24653 out_assignments = assignments;
24655 if (Utils::Shader::FRAGMENT == stage)
24657 Utils::replaceAllTokens("TYPE", test_case.m_type.GetGLSLTypeName(), out_assignments);
24661 /** Get interface of shader
24663 * @param test_case_index Index of test case
24664 * @param stage Shader stage
24665 * @param out_interface Set to ""
24667 void XFBStrideTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage, std::string& out_interface)
24669 static const GLchar* vs_tes_gs = "layout (xfb_offset = 0) FLAT out TYPE goku;\n"
24671 "layout(std140, binding = 0) uniform Goku {\n"
24672 " TYPE uni_goku;\n"
24674 static const GLchar* fs = "FLAT in TYPE goku;\n"
24676 "out vec4 fs_out;\n";
24678 const testCase& test_case = m_test_cases[test_case_index];
24679 const GLchar* interface = "";
24680 const GLchar* flat = "";
24682 if (test_case.m_stage == stage)
24686 case Utils::Shader::GEOMETRY:
24687 interface = vs_tes_gs;
24689 case Utils::Shader::TESS_EVAL:
24690 interface = vs_tes_gs;
24692 case Utils::Shader::VERTEX:
24693 interface = vs_tes_gs;
24696 TCU_FAIL("Invalid enum");
24703 case Utils::Shader::FRAGMENT:
24706 case Utils::Shader::GEOMETRY:
24707 case Utils::Shader::TESS_CTRL:
24708 case Utils::Shader::TESS_EVAL:
24709 case Utils::Shader::VERTEX:
24712 TCU_FAIL("Invalid enum");
24716 out_interface = interface;
24718 if (Utils::Type::Float != test_case.m_type.m_basic_type)
24723 Utils::replaceAllTokens("FLAT", flat, out_interface);
24724 Utils::replaceAllTokens("TYPE", test_case.m_type.GetGLSLTypeName(), out_interface);
24727 /** Get source code of shader
24729 * @param test_case_index Index of test case
24730 * @param stage Shader stage
24734 std::string XFBStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
24736 std::string source;
24737 const testCase& test_case = m_test_cases[test_case_index];
24739 switch (test_case.m_stage)
24741 case Utils::Shader::VERTEX:
24744 case Utils::Shader::FRAGMENT:
24745 case Utils::Shader::VERTEX:
24746 source = BufferTestBase::getShaderSource(test_case_index, stage);
24753 case Utils::Shader::TESS_EVAL:
24756 case Utils::Shader::FRAGMENT:
24757 case Utils::Shader::TESS_CTRL:
24758 case Utils::Shader::TESS_EVAL:
24759 case Utils::Shader::VERTEX:
24760 source = BufferTestBase::getShaderSource(test_case_index, stage);
24767 case Utils::Shader::GEOMETRY:
24768 source = BufferTestBase::getShaderSource(test_case_index, stage);
24772 TCU_FAIL("Invalid enum");
24780 /** Get name of test case
24782 * @param test_case_index Index of test case
24784 * @return Name of tested stage
24786 std::string XFBStrideTest::getTestCaseName(glw::GLuint test_case_index)
24788 std::stringstream stream;
24789 const testCase& test_case = m_test_cases[test_case_index];
24791 stream << "Type: " << test_case.m_type.GetGLSLTypeName()
24792 << ", stage: " << Utils::Shader::GetStageName(test_case.m_stage);
24794 return stream.str();
24797 /** Returns number of test cases
24801 glw::GLuint XFBStrideTest::getTestCaseNumber()
24803 return static_cast<GLuint>(m_test_cases.size());
24806 /** Prepare all test cases
24809 void XFBStrideTest::testInit()
24811 const GLuint n_types = getTypesNumber();
24813 for (GLuint i = 0; i < n_types; ++i)
24815 const Utils::Type& type = getType(i);
24817 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
24819 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::FRAGMENT == stage) ||
24820 (Utils::Shader::TESS_CTRL == stage))
24825 testCase test_case = { (Utils::Shader::STAGES)stage, type };
24827 m_test_cases.push_back(test_case);
24834 * @param context Test framework context
24836 XFBBlockMemberBufferTest::XFBBlockMemberBufferTest(deqp::Context& context)
24837 : NegativeTestBase(
24838 context, "xfb_block_member_buffer",
24839 "Test verifies that compiler reports error when block member has different xfb_buffer qualifier than buffer")
24843 /** Source for given test case and stage
24845 * @param test_case_index Index of test case
24846 * @param stage Shader stage
24848 * @return Shader source
24850 std::string XFBBlockMemberBufferTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
24852 static const GLchar* var_definition = "layout (xfb_offset = 0) out Goku {\n"
24854 " layout (xfb_buffer = 1) vec4 goten;\n"
24856 static const GLchar* var_use = " gokuINDEX.gohan = result / 2;\n"
24857 " gokuINDEX.goten = result / 4;\n";
24858 static const GLchar* fs = "#version 430 core\n"
24859 "#extension GL_ARB_enhanced_layouts : require\n"
24862 "out vec4 fs_out;\n"
24866 " fs_out = gs_fs;\n"
24869 static const GLchar* gs_tested = "#version 430 core\n"
24870 "#extension GL_ARB_enhanced_layouts : require\n"
24872 "layout(points) in;\n"
24873 "layout(triangle_strip, max_vertices = 4) out;\n"
24877 "in vec4 tes_gs[];\n"
24878 "out vec4 gs_fs;\n"
24882 " vec4 result = tes_gs[0];\n"
24886 " gs_fs = result;\n"
24887 " gl_Position = vec4(-1, -1, 0, 1);\n"
24889 " gs_fs = result;\n"
24890 " gl_Position = vec4(-1, 1, 0, 1);\n"
24892 " gs_fs = result;\n"
24893 " gl_Position = vec4(1, -1, 0, 1);\n"
24895 " gs_fs = result;\n"
24896 " gl_Position = vec4(1, 1, 0, 1);\n"
24900 static const GLchar* tcs = "#version 430 core\n"
24901 "#extension GL_ARB_enhanced_layouts : require\n"
24903 "layout(vertices = 1) out;\n"
24905 "in vec4 vs_tcs[];\n"
24906 "out vec4 tcs_tes[];\n"
24911 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
24913 " gl_TessLevelOuter[0] = 1.0;\n"
24914 " gl_TessLevelOuter[1] = 1.0;\n"
24915 " gl_TessLevelOuter[2] = 1.0;\n"
24916 " gl_TessLevelOuter[3] = 1.0;\n"
24917 " gl_TessLevelInner[0] = 1.0;\n"
24918 " gl_TessLevelInner[1] = 1.0;\n"
24921 static const GLchar* tcs_tested = "#version 430 core\n"
24922 "#extension GL_ARB_enhanced_layouts : require\n"
24924 "layout(vertices = 1) out;\n"
24928 "in vec4 vs_tcs[];\n"
24929 "out vec4 tcs_tes[];\n"
24933 " vec4 result = vs_tcs[gl_InvocationID];\n"
24937 " tcs_tes[gl_InvocationID] = result;\n"
24939 " gl_TessLevelOuter[0] = 1.0;\n"
24940 " gl_TessLevelOuter[1] = 1.0;\n"
24941 " gl_TessLevelOuter[2] = 1.0;\n"
24942 " gl_TessLevelOuter[3] = 1.0;\n"
24943 " gl_TessLevelInner[0] = 1.0;\n"
24944 " gl_TessLevelInner[1] = 1.0;\n"
24947 static const GLchar* tes_tested = "#version 430 core\n"
24948 "#extension GL_ARB_enhanced_layouts : require\n"
24950 "layout(isolines, point_mode) in;\n"
24954 "in vec4 tcs_tes[];\n"
24955 "out vec4 tes_gs;\n"
24959 " vec4 result = tcs_tes[0];\n"
24963 " tes_gs += result;\n"
24966 static const GLchar* vs = "#version 430 core\n"
24967 "#extension GL_ARB_enhanced_layouts : require\n"
24970 "out vec4 vs_tcs;\n"
24974 " vs_tcs = in_vs;\n"
24977 static const GLchar* vs_tested = "#version 430 core\n"
24978 "#extension GL_ARB_enhanced_layouts : require\n"
24983 "out vec4 vs_tcs;\n"
24987 " vec4 result = in_vs;\n"
24991 " vs_tcs = result;\n"
24995 std::string source;
24996 testCase& test_case = m_test_cases[test_case_index];
24998 if (test_case.m_stage == stage)
25000 const GLchar* array = "";
25001 const GLchar* index = "";
25002 size_t position = 0;
25006 case Utils::Shader::GEOMETRY:
25007 source = gs_tested;
25011 case Utils::Shader::TESS_CTRL:
25012 source = tcs_tested;
25014 index = "[gl_InvocationID]";
25016 case Utils::Shader::TESS_EVAL:
25017 source = tes_tested;
25021 case Utils::Shader::VERTEX:
25022 source = vs_tested;
25025 TCU_FAIL("Invalid enum");
25028 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
25030 Utils::replaceToken("ARRAY", position, array, source);
25031 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
25033 Utils::replaceAllTokens("INDEX", index, source);
25037 switch (test_case.m_stage)
25039 case Utils::Shader::GEOMETRY:
25042 case Utils::Shader::FRAGMENT:
25045 case Utils::Shader::VERTEX:
25052 case Utils::Shader::TESS_CTRL:
25055 case Utils::Shader::FRAGMENT:
25058 case Utils::Shader::VERTEX:
25065 case Utils::Shader::TESS_EVAL:
25068 case Utils::Shader::FRAGMENT:
25071 case Utils::Shader::TESS_CTRL:
25074 case Utils::Shader::VERTEX:
25081 case Utils::Shader::VERTEX:
25084 case Utils::Shader::FRAGMENT:
25092 TCU_FAIL("Invalid enum");
25100 /** Get description of test case
25102 * @param test_case_index Index of test case
25104 * @return Test case description
25106 std::string XFBBlockMemberBufferTest::getTestCaseName(GLuint test_case_index)
25108 std::stringstream stream;
25109 testCase& test_case = m_test_cases[test_case_index];
25111 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage);
25113 return stream.str();
25116 /** Get number of test cases
25118 * @return Number of test cases
25120 GLuint XFBBlockMemberBufferTest::getTestCaseNumber()
25122 return static_cast<GLuint>(m_test_cases.size());
25125 /** Selects if "compute" stage is relevant for test
25131 bool XFBBlockMemberBufferTest::isComputeRelevant(GLuint /* test_case_index */)
25136 /** Prepare all test cases
25139 void XFBBlockMemberBufferTest::testInit()
25141 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
25143 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
25144 (Utils::Shader::FRAGMENT == stage))
25149 testCase test_case = { (Utils::Shader::STAGES)stage };
25151 m_test_cases.push_back(test_case);
25157 * @param context Test framework context
25159 XFBOutputOverlappingTest::XFBOutputOverlappingTest(deqp::Context& context)
25160 : NegativeTestBase(context, "xfb_output_overlapping",
25161 "Test verifies that compiler reports error when two xfb qualified outputs overlap")
25165 /** Source for given test case and stage
25167 * @param test_case_index Index of test case
25168 * @param stage Shader stage
25170 * @return Shader source
25172 std::string XFBOutputOverlappingTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
25174 static const GLchar* var_definition = "layout (xfb_offset = OFFSET) out TYPE gohanARRAY;\n"
25175 "layout (xfb_offset = OFFSET) out TYPE gotenARRAY;\n";
25176 static const GLchar* var_use = " gohanINDEX = TYPE(0);\n"
25177 " gotenINDEX = TYPE(1);\n"
25178 " if (vec4(0) == result)\n"
25180 " gohanINDEX = TYPE(1);\n"
25181 " gotenINDEX = TYPE(0);\n"
25183 static const GLchar* fs = "#version 430 core\n"
25184 "#extension GL_ARB_enhanced_layouts : require\n"
25187 "out vec4 fs_out;\n"
25191 " fs_out = gs_fs;\n"
25194 static const GLchar* gs_tested = "#version 430 core\n"
25195 "#extension GL_ARB_enhanced_layouts : require\n"
25197 "layout(points) in;\n"
25198 "layout(triangle_strip, max_vertices = 4) out;\n"
25202 "in vec4 tes_gs[];\n"
25203 "out vec4 gs_fs;\n"
25207 " vec4 result = tes_gs[0];\n"
25211 " gs_fs = result;\n"
25212 " gl_Position = vec4(-1, -1, 0, 1);\n"
25214 " gs_fs = result;\n"
25215 " gl_Position = vec4(-1, 1, 0, 1);\n"
25217 " gs_fs = result;\n"
25218 " gl_Position = vec4(1, -1, 0, 1);\n"
25220 " gs_fs = result;\n"
25221 " gl_Position = vec4(1, 1, 0, 1);\n"
25225 static const GLchar* tcs = "#version 430 core\n"
25226 "#extension GL_ARB_enhanced_layouts : require\n"
25228 "layout(vertices = 1) out;\n"
25230 "in vec4 vs_tcs[];\n"
25231 "out vec4 tcs_tes[];\n"
25236 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
25238 " gl_TessLevelOuter[0] = 1.0;\n"
25239 " gl_TessLevelOuter[1] = 1.0;\n"
25240 " gl_TessLevelOuter[2] = 1.0;\n"
25241 " gl_TessLevelOuter[3] = 1.0;\n"
25242 " gl_TessLevelInner[0] = 1.0;\n"
25243 " gl_TessLevelInner[1] = 1.0;\n"
25246 static const GLchar* tcs_tested = "#version 430 core\n"
25247 "#extension GL_ARB_enhanced_layouts : require\n"
25249 "layout(vertices = 1) out;\n"
25253 "in vec4 vs_tcs[];\n"
25254 "out vec4 tcs_tes[];\n"
25258 " vec4 result = vs_tcs[gl_InvocationID];\n"
25262 " tcs_tes[gl_InvocationID] = result;\n"
25264 " gl_TessLevelOuter[0] = 1.0;\n"
25265 " gl_TessLevelOuter[1] = 1.0;\n"
25266 " gl_TessLevelOuter[2] = 1.0;\n"
25267 " gl_TessLevelOuter[3] = 1.0;\n"
25268 " gl_TessLevelInner[0] = 1.0;\n"
25269 " gl_TessLevelInner[1] = 1.0;\n"
25272 static const GLchar* tes_tested = "#version 430 core\n"
25273 "#extension GL_ARB_enhanced_layouts : require\n"
25275 "layout(isolines, point_mode) in;\n"
25279 "in vec4 tcs_tes[];\n"
25280 "out vec4 tes_gs;\n"
25284 " vec4 result = tcs_tes[0];\n"
25288 " tes_gs += result;\n"
25291 static const GLchar* vs = "#version 430 core\n"
25292 "#extension GL_ARB_enhanced_layouts : require\n"
25295 "out vec4 vs_tcs;\n"
25299 " vs_tcs = in_vs;\n"
25302 static const GLchar* vs_tested = "#version 430 core\n"
25303 "#extension GL_ARB_enhanced_layouts : require\n"
25308 "out vec4 vs_tcs;\n"
25312 " vec4 result = in_vs;\n"
25316 " vs_tcs = result;\n"
25320 std::string source;
25321 testCase& test_case = m_test_cases[test_case_index];
25323 if (test_case.m_stage == stage)
25325 const GLchar* array = "";
25326 GLchar buffer_gohan[16];
25327 GLchar buffer_goten[16];
25328 const GLchar* index = "";
25329 size_t position = 0;
25330 size_t position_start = 0;
25331 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
25333 sprintf(buffer_gohan, "%d", test_case.m_offset_gohan);
25334 sprintf(buffer_goten, "%d", test_case.m_offset_goten);
25338 case Utils::Shader::GEOMETRY:
25339 source = gs_tested;
25343 case Utils::Shader::TESS_CTRL:
25344 source = tcs_tested;
25346 index = "[gl_InvocationID]";
25348 case Utils::Shader::TESS_EVAL:
25349 source = tes_tested;
25353 case Utils::Shader::VERTEX:
25354 source = vs_tested;
25357 TCU_FAIL("Invalid enum");
25360 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
25362 Utils::replaceToken("OFFSET", position, buffer_gohan, source);
25363 Utils::replaceToken("TYPE", position, type_name, source);
25364 Utils::replaceToken("ARRAY", position, array, source);
25365 Utils::replaceToken("OFFSET", position, buffer_goten, source);
25366 Utils::replaceToken("TYPE", position, type_name, source);
25367 Utils::replaceToken("ARRAY", position, array, source);
25368 position_start = position;
25369 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
25370 position = position_start;
25371 Utils::replaceToken("INDEX", position, index, source);
25372 Utils::replaceToken("TYPE", position, type_name, source);
25373 Utils::replaceToken("INDEX", position, index, source);
25374 Utils::replaceToken("TYPE", position, type_name, source);
25375 Utils::replaceToken("INDEX", position, index, source);
25376 Utils::replaceToken("TYPE", position, type_name, source);
25377 Utils::replaceToken("INDEX", position, index, source);
25378 Utils::replaceToken("TYPE", position, type_name, source);
25382 switch (test_case.m_stage)
25384 case Utils::Shader::GEOMETRY:
25387 case Utils::Shader::FRAGMENT:
25390 case Utils::Shader::VERTEX:
25397 case Utils::Shader::TESS_CTRL:
25400 case Utils::Shader::FRAGMENT:
25403 case Utils::Shader::VERTEX:
25410 case Utils::Shader::TESS_EVAL:
25413 case Utils::Shader::FRAGMENT:
25416 case Utils::Shader::TESS_CTRL:
25419 case Utils::Shader::VERTEX:
25426 case Utils::Shader::VERTEX:
25429 case Utils::Shader::FRAGMENT:
25437 TCU_FAIL("Invalid enum");
25445 /** Get description of test case
25447 * @param test_case_index Index of test case
25449 * @return Test case description
25451 std::string XFBOutputOverlappingTest::getTestCaseName(GLuint test_case_index)
25453 std::stringstream stream;
25454 testCase& test_case = m_test_cases[test_case_index];
25456 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
25457 << ", type: " << test_case.m_type.GetGLSLTypeName() << ", offsets: " << test_case.m_offset_gohan << " & "
25458 << test_case.m_offset_goten;
25460 return stream.str();
25463 /** Get number of test cases
25465 * @return Number of test cases
25467 GLuint XFBOutputOverlappingTest::getTestCaseNumber()
25469 return static_cast<GLuint>(m_test_cases.size());
25472 /** Selects if "compute" stage is relevant for test
25478 bool XFBOutputOverlappingTest::isComputeRelevant(GLuint /* test_case_index */)
25483 /** Prepare all test cases
25486 void XFBOutputOverlappingTest::testInit()
25488 const GLuint n_types = getTypesNumber();
25490 for (GLuint i = 0; i < n_types; ++i)
25492 const Utils::Type& type = getType(i);
25493 const GLuint base_alingment = Utils::Type::GetTypeSize(type.m_basic_type);
25495 /* Skip scalars, not applicable as:
25497 * The offset must be a multiple of the size of the first component of the first
25498 * qualified variable or block member, or a compile-time error results.
25500 if ((1 == type.m_n_columns) && (1 == type.m_n_rows))
25505 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
25507 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
25508 (Utils::Shader::FRAGMENT == stage))
25513 testCase test_case = { 0 /* gohan offset */, base_alingment /* goten_offset */,
25514 (Utils::Shader::STAGES)stage, type };
25516 m_test_cases.push_back(test_case);
25523 * @param context Test framework context
25525 XFBInvalidOffsetAlignmentTest::XFBInvalidOffsetAlignmentTest(deqp::Context& context)
25526 : NegativeTestBase(context, "xfb_invalid_offset_alignment",
25527 "Test verifies that compiler reports error when xfb_offset has invalid alignment")
25531 /** Source for given test case and stage
25533 * @param test_case_index Index of test case
25534 * @param stage Shader stage
25536 * @return Shader source
25538 std::string XFBInvalidOffsetAlignmentTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
25540 static const GLchar* var_definition = "layout (xfb_offset = OFFSET) out TYPE gohanARRAY;\n";
25541 static const GLchar* var_use = " gohanINDEX = TYPE(0);\n"
25542 " if (vec4(0) == result)\n"
25544 " gohanINDEX = TYPE(1);\n"
25546 static const GLchar* fs = "#version 430 core\n"
25547 "#extension GL_ARB_enhanced_layouts : require\n"
25550 "out vec4 fs_out;\n"
25554 " fs_out = gs_fs;\n"
25557 static const GLchar* gs_tested = "#version 430 core\n"
25558 "#extension GL_ARB_enhanced_layouts : require\n"
25560 "layout(points) in;\n"
25561 "layout(triangle_strip, max_vertices = 4) out;\n"
25565 "in vec4 tes_gs[];\n"
25566 "out vec4 gs_fs;\n"
25570 " vec4 result = tes_gs[0];\n"
25574 " gs_fs = result;\n"
25575 " gl_Position = vec4(-1, -1, 0, 1);\n"
25577 " gs_fs = result;\n"
25578 " gl_Position = vec4(-1, 1, 0, 1);\n"
25580 " gs_fs = result;\n"
25581 " gl_Position = vec4(1, -1, 0, 1);\n"
25583 " gs_fs = result;\n"
25584 " gl_Position = vec4(1, 1, 0, 1);\n"
25588 static const GLchar* tcs = "#version 430 core\n"
25589 "#extension GL_ARB_enhanced_layouts : require\n"
25591 "layout(vertices = 1) out;\n"
25593 "in vec4 vs_tcs[];\n"
25594 "out vec4 tcs_tes[];\n"
25599 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
25601 " gl_TessLevelOuter[0] = 1.0;\n"
25602 " gl_TessLevelOuter[1] = 1.0;\n"
25603 " gl_TessLevelOuter[2] = 1.0;\n"
25604 " gl_TessLevelOuter[3] = 1.0;\n"
25605 " gl_TessLevelInner[0] = 1.0;\n"
25606 " gl_TessLevelInner[1] = 1.0;\n"
25609 static const GLchar* tcs_tested = "#version 430 core\n"
25610 "#extension GL_ARB_enhanced_layouts : require\n"
25612 "layout(vertices = 1) out;\n"
25616 "in vec4 vs_tcs[];\n"
25617 "out vec4 tcs_tes[];\n"
25621 " vec4 result = vs_tcs[gl_InvocationID];\n"
25625 " tcs_tes[gl_InvocationID] = result;\n"
25627 " gl_TessLevelOuter[0] = 1.0;\n"
25628 " gl_TessLevelOuter[1] = 1.0;\n"
25629 " gl_TessLevelOuter[2] = 1.0;\n"
25630 " gl_TessLevelOuter[3] = 1.0;\n"
25631 " gl_TessLevelInner[0] = 1.0;\n"
25632 " gl_TessLevelInner[1] = 1.0;\n"
25635 static const GLchar* tes_tested = "#version 430 core\n"
25636 "#extension GL_ARB_enhanced_layouts : require\n"
25638 "layout(isolines, point_mode) in;\n"
25642 "in vec4 tcs_tes[];\n"
25643 "out vec4 tes_gs;\n"
25647 " vec4 result = tcs_tes[0];\n"
25651 " tes_gs += result;\n"
25654 static const GLchar* vs = "#version 430 core\n"
25655 "#extension GL_ARB_enhanced_layouts : require\n"
25658 "out vec4 vs_tcs;\n"
25662 " vs_tcs = in_vs;\n"
25665 static const GLchar* vs_tested = "#version 430 core\n"
25666 "#extension GL_ARB_enhanced_layouts : require\n"
25671 "out vec4 vs_tcs;\n"
25675 " vec4 result = in_vs;\n"
25679 " vs_tcs = result;\n"
25683 std::string source;
25684 testCase& test_case = m_test_cases[test_case_index];
25686 if (test_case.m_stage == stage)
25688 const GLchar* array = "";
25690 const GLchar* index = "";
25691 size_t position = 0;
25692 size_t position_start = 0;
25693 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
25695 sprintf(buffer, "%d", test_case.m_offset);
25699 case Utils::Shader::GEOMETRY:
25700 source = gs_tested;
25704 case Utils::Shader::TESS_CTRL:
25705 source = tcs_tested;
25707 index = "[gl_InvocationID]";
25709 case Utils::Shader::TESS_EVAL:
25710 source = tes_tested;
25714 case Utils::Shader::VERTEX:
25715 source = vs_tested;
25718 TCU_FAIL("Invalid enum");
25721 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
25723 Utils::replaceToken("OFFSET", position, buffer, source);
25724 Utils::replaceToken("TYPE", position, type_name, source);
25725 Utils::replaceToken("ARRAY", position, array, source);
25726 position_start = position;
25727 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
25728 position = position_start;
25729 Utils::replaceToken("INDEX", position, index, source);
25730 Utils::replaceToken("TYPE", position, type_name, source);
25731 Utils::replaceToken("INDEX", position, index, source);
25732 Utils::replaceToken("TYPE", position, type_name, source);
25736 switch (test_case.m_stage)
25738 case Utils::Shader::GEOMETRY:
25741 case Utils::Shader::FRAGMENT:
25744 case Utils::Shader::VERTEX:
25751 case Utils::Shader::TESS_CTRL:
25754 case Utils::Shader::FRAGMENT:
25757 case Utils::Shader::VERTEX:
25764 case Utils::Shader::TESS_EVAL:
25767 case Utils::Shader::FRAGMENT:
25770 case Utils::Shader::TESS_CTRL:
25773 case Utils::Shader::VERTEX:
25780 case Utils::Shader::VERTEX:
25783 case Utils::Shader::FRAGMENT:
25791 TCU_FAIL("Invalid enum");
25799 /** Get description of test case
25801 * @param test_case_index Index of test case
25803 * @return Test case description
25805 std::string XFBInvalidOffsetAlignmentTest::getTestCaseName(GLuint test_case_index)
25807 std::stringstream stream;
25808 testCase& test_case = m_test_cases[test_case_index];
25810 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
25811 << ", type: " << test_case.m_type.GetGLSLTypeName() << ", offset: " << test_case.m_offset;
25813 return stream.str();
25816 /** Get number of test cases
25818 * @return Number of test cases
25820 GLuint XFBInvalidOffsetAlignmentTest::getTestCaseNumber()
25822 return static_cast<GLuint>(m_test_cases.size());
25825 /** Selects if "compute" stage is relevant for test
25831 bool XFBInvalidOffsetAlignmentTest::isComputeRelevant(GLuint /* test_case_index */)
25836 /** Prepare all test cases
25839 void XFBInvalidOffsetAlignmentTest::testInit()
25841 const GLuint n_types = getTypesNumber();
25843 for (GLuint i = 0; i < n_types; ++i)
25845 const Utils::Type& type = getType(i);
25846 const GLuint base_alingment = Utils::Type::GetTypeSize(type.m_basic_type);
25848 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
25850 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
25851 (Utils::Shader::FRAGMENT == stage))
25856 for (GLuint offset = base_alingment + 1; offset < 2 * base_alingment; ++offset)
25858 testCase test_case = { offset, (Utils::Shader::STAGES)stage, type };
25860 m_test_cases.push_back(test_case);
25868 * @param context Test context
25870 XFBCaptureInactiveOutputVariableTest::XFBCaptureInactiveOutputVariableTest(deqp::Context& context)
25871 : BufferTestBase(context, "xfb_capture_inactive_output_variable",
25872 "Test verifies that inactive variables are captured")
25874 /* Nothing to be done here */
25877 /** Execute drawArrays for single vertex
25879 * @param test_case_index
25883 bool XFBCaptureInactiveOutputVariableTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
25885 const Functions& gl = m_context.getRenderContext().getFunctions();
25886 GLenum primitive_type = GL_PATCHES;
25888 if (TEST_VS == test_case_index)
25890 primitive_type = GL_POINTS;
25893 gl.disable(GL_RASTERIZER_DISCARD);
25894 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
25896 gl.beginTransformFeedback(GL_POINTS);
25897 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
25899 gl.drawArrays(primitive_type, 0 /* first */, 1 /* count */);
25900 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
25902 gl.endTransformFeedback();
25903 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
25908 /** Get descriptors of buffers necessary for test
25911 * @param out_descriptors Descriptors of buffers used by test
25913 void XFBCaptureInactiveOutputVariableTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
25914 bufferDescriptor::Vector& out_descriptors)
25916 const Utils::Type& type = Utils::Type::vec4;
25918 /* Test needs single uniform and xfb */
25919 out_descriptors.resize(2);
25921 /* Get references */
25922 bufferDescriptor& uniform = out_descriptors[0];
25923 bufferDescriptor& xfb = out_descriptors[1];
25926 uniform.m_index = 0;
25930 uniform.m_target = Utils::Buffer::Uniform;
25931 xfb.m_target = Utils::Buffer::Transform_feedback;
25934 const std::vector<GLubyte>& gohan_data = type.GenerateData();
25935 const std::vector<GLubyte>& goten_data = type.GenerateData();
25937 const GLuint type_size = static_cast<GLuint>(gohan_data.size());
25940 uniform.m_initial_data.resize(2 * type_size);
25941 memcpy(&uniform.m_initial_data[0] + 0, &gohan_data[0], type_size);
25942 memcpy(&uniform.m_initial_data[0] + type_size, &goten_data[0], type_size);
25945 xfb.m_initial_data.resize(3 * type_size);
25946 xfb.m_expected_data.resize(3 * type_size);
25948 for (GLuint i = 0; i < 3 * type_size; ++i)
25950 xfb.m_initial_data[i] = (glw::GLubyte)i;
25951 xfb.m_expected_data[i] = (glw::GLubyte)i;
25954 memcpy(&xfb.m_expected_data[0] + 2 * type_size, &gohan_data[0], type_size);
25955 memcpy(&xfb.m_expected_data[0] + 0 * type_size, &goten_data[0], type_size);
25958 /** Get body of main function for given shader stage
25960 * @param test_case_index Index of test case
25961 * @param stage Shader stage
25962 * @param out_assignments Set to empty
25963 * @param out_calculations Set to empty
25965 void XFBCaptureInactiveOutputVariableTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
25966 std::string& out_assignments, std::string& out_calculations)
25968 out_calculations = "";
25970 static const GLchar* vs_tes_gs = " goten = uni_goten;\n"
25971 " gohan = uni_gohan;\n";
25972 static const GLchar* fs = " fs_out = goku + gohan + goten;\n";
25974 const GLchar* assignments = "";
25978 case Utils::Shader::FRAGMENT:
25982 case Utils::Shader::GEOMETRY:
25983 if (TEST_GS == test_case_index)
25985 assignments = vs_tes_gs;
25989 case Utils::Shader::TESS_CTRL:
25992 case Utils::Shader::TESS_EVAL:
25993 if (TEST_TES == test_case_index)
25995 assignments = vs_tes_gs;
25999 case Utils::Shader::VERTEX:
26000 if (TEST_VS == test_case_index)
26002 assignments = vs_tes_gs;
26007 TCU_FAIL("Invalid enum");
26010 out_assignments = assignments;
26013 /** Get interface of shader
26015 * @param test_case_index Index of test case
26016 * @param stage Shader stage
26017 * @param out_interface Set to ""
26019 void XFBCaptureInactiveOutputVariableTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
26020 std::string& out_interface)
26022 static const GLchar* vs_tes_gs = "const uint sizeof_type = 16;\n"
26024 "layout (xfb_offset = 1 * sizeof_type) out vec4 goku;\n"
26025 "layout (xfb_offset = 2 * sizeof_type) out vec4 gohan;\n"
26026 "layout (xfb_offset = 0 * sizeof_type) out vec4 goten;\n"
26028 "layout(binding = 0) uniform block {\n"
26029 " vec4 uni_gohan;\n"
26030 " vec4 uni_goten;\n"
26032 static const GLchar* fs = "in vec4 goku;\n"
26035 "out vec4 fs_out;\n";
26037 const GLchar* interface = "";
26041 case Utils::Shader::FRAGMENT:
26045 case Utils::Shader::GEOMETRY:
26046 if (TEST_GS == test_case_index)
26048 interface = vs_tes_gs;
26052 case Utils::Shader::TESS_CTRL:
26055 case Utils::Shader::TESS_EVAL:
26056 if (TEST_TES == test_case_index)
26058 interface = vs_tes_gs;
26062 case Utils::Shader::VERTEX:
26063 if (TEST_VS == test_case_index)
26065 interface = vs_tes_gs;
26070 TCU_FAIL("Invalid enum");
26073 out_interface = interface;
26076 /** Get source code of shader
26078 * @param test_case_index Index of test case
26079 * @param stage Shader stage
26083 std::string XFBCaptureInactiveOutputVariableTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
26085 std::string source;
26087 switch (test_case_index)
26092 case Utils::Shader::FRAGMENT:
26093 case Utils::Shader::VERTEX:
26094 source = BufferTestBase::getShaderSource(test_case_index, stage);
26104 case Utils::Shader::FRAGMENT:
26105 case Utils::Shader::TESS_CTRL:
26106 case Utils::Shader::TESS_EVAL:
26107 case Utils::Shader::VERTEX:
26108 source = BufferTestBase::getShaderSource(test_case_index, stage);
26116 source = BufferTestBase::getShaderSource(test_case_index, stage);
26120 TCU_FAIL("Invalid enum");
26128 /** Get name of test case
26130 * @param test_case_index Index of test case
26132 * @return Name of tested stage
26134 std::string XFBCaptureInactiveOutputVariableTest::getTestCaseName(glw::GLuint test_case_index)
26136 const GLchar* name = 0;
26138 switch (test_case_index)
26144 name = "tessellation evaluation";
26150 TCU_FAIL("Invalid enum");
26156 /** Returns number of test cases
26160 glw::GLuint XFBCaptureInactiveOutputVariableTest::getTestCaseNumber()
26165 /** Inspects program to check if all resources are as expected
26168 * @param program Program instance
26169 * @param out_stream Error message
26171 * @return true if everything is ok, false otherwise
26173 bool XFBCaptureInactiveOutputVariableTest::inspectProgram(GLuint /* test_case_index */, Utils::Program& program,
26174 std::stringstream& out_stream)
26177 const Utils::Type& type = Utils::Type::vec4;
26178 const GLuint type_size = type.GetSize();
26180 program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE,
26181 1 /* buf_size */, &stride);
26183 if ((GLint)(3 * type_size) != stride)
26185 out_stream << "Stride is: " << stride << " expected: " << (3 * type_size);
26193 /** Verify contents of buffers
26195 * @param buffers Collection of buffers to be verified
26197 * @return true if everything is as expected, false otherwise
26199 bool XFBCaptureInactiveOutputVariableTest::verifyBuffers(bufferCollection& buffers)
26201 bool result = true;
26203 bufferCollection::pair& pair = buffers.m_vector[1] /* xfb */;
26204 Utils::Buffer* buffer = pair.m_buffer;
26205 bufferDescriptor* descriptor = pair.m_descriptor;
26207 /* Get pointer to contents of buffer */
26209 GLubyte* buffer_data = (GLubyte*)buffer->Map(Utils::Buffer::ReadOnly);
26211 /* Get pointer to expected data */
26212 GLubyte* expected_data = (GLubyte*)&descriptor->m_expected_data[0];
26215 static const GLuint vec4_size = 16;
26217 int res_gohan = memcmp(buffer_data + 2 * vec4_size, expected_data + 2 * vec4_size, vec4_size);
26218 int res_goten = memcmp(buffer_data + 0 * vec4_size, expected_data + 0 * vec4_size, vec4_size);
26220 if ((0 != res_gohan) || (0 != res_goten))
26222 m_context.getTestContext().getLog()
26223 << tcu::TestLog::Message << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
26224 << ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
26229 /* Release buffer mapping */
26237 * @param context Test context
26239 XFBCaptureInactiveOutputComponentTest::XFBCaptureInactiveOutputComponentTest(deqp::Context& context)
26240 : BufferTestBase(context, "xfb_capture_inactive_output_component",
26241 "Test verifies that inactive components are not modified")
26243 /* Nothing to be done here */
26246 /** Execute drawArrays for single vertex
26248 * @param test_case_index
26252 bool XFBCaptureInactiveOutputComponentTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
26254 const Functions& gl = m_context.getRenderContext().getFunctions();
26255 GLenum primitive_type = GL_PATCHES;
26257 if (TEST_VS == test_case_index)
26259 primitive_type = GL_POINTS;
26262 gl.disable(GL_RASTERIZER_DISCARD);
26263 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
26265 gl.beginTransformFeedback(GL_POINTS);
26266 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
26268 gl.drawArrays(primitive_type, 0 /* first */, 1 /* count */);
26269 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
26271 gl.endTransformFeedback();
26272 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
26277 /** Get descriptors of buffers necessary for test
26280 * @param out_descriptors Descriptors of buffers used by test
26282 void XFBCaptureInactiveOutputComponentTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
26283 bufferDescriptor::Vector& out_descriptors)
26285 const Utils::Type& type = Utils::Type::vec4;
26287 /* Test needs single uniform and xfb */
26288 out_descriptors.resize(2);
26290 /* Get references */
26291 bufferDescriptor& uniform = out_descriptors[0];
26292 bufferDescriptor& xfb = out_descriptors[1];
26295 uniform.m_index = 0;
26299 uniform.m_target = Utils::Buffer::Uniform;
26300 xfb.m_target = Utils::Buffer::Transform_feedback;
26303 const std::vector<GLubyte>& goku_data = type.GenerateData();
26304 const std::vector<GLubyte>& gohan_data = type.GenerateData();
26305 const std::vector<GLubyte>& goten_data = type.GenerateData();
26306 const std::vector<GLubyte>& chichi_data = type.GenerateData();
26307 const std::vector<GLubyte>& vegeta_data = type.GenerateData();
26308 const std::vector<GLubyte>& trunks_data = type.GenerateData();
26309 const std::vector<GLubyte>& bra_data = type.GenerateData();
26310 const std::vector<GLubyte>& bulma_data = type.GenerateData();
26312 const GLuint comp_size = Utils::Type::GetTypeSize(type.m_basic_type);
26313 const GLuint type_size = static_cast<GLuint>(gohan_data.size());
26316 uniform.m_initial_data.resize(8 * type_size);
26317 memcpy(&uniform.m_initial_data[0] + 0 * type_size, &goku_data[0], type_size);
26318 memcpy(&uniform.m_initial_data[0] + 1 * type_size, &gohan_data[0], type_size);
26319 memcpy(&uniform.m_initial_data[0] + 2 * type_size, &goten_data[0], type_size);
26320 memcpy(&uniform.m_initial_data[0] + 3 * type_size, &chichi_data[0], type_size);
26321 memcpy(&uniform.m_initial_data[0] + 4 * type_size, &vegeta_data[0], type_size);
26322 memcpy(&uniform.m_initial_data[0] + 5 * type_size, &trunks_data[0], type_size);
26323 memcpy(&uniform.m_initial_data[0] + 6 * type_size, &bra_data[0], type_size);
26324 memcpy(&uniform.m_initial_data[0] + 7 * type_size, &bulma_data[0], type_size);
26327 xfb.m_initial_data.resize(8 * type_size);
26328 xfb.m_expected_data.resize(8 * type_size);
26330 for (GLuint i = 0; i < 8 * type_size; ++i)
26332 xfb.m_initial_data[i] = (glw::GLubyte)i;
26333 xfb.m_expected_data[i] = (glw::GLubyte)i;
26336 /* goku - x, z - 32 */
26337 memcpy(&xfb.m_expected_data[0] + 2 * type_size + 0 * comp_size, &goku_data[0] + 0 * comp_size, comp_size);
26338 memcpy(&xfb.m_expected_data[0] + 2 * type_size + 2 * comp_size, &goku_data[0] + 2 * comp_size, comp_size);
26340 /* gohan - y, w - 0 */
26341 memcpy(&xfb.m_expected_data[0] + 0 * type_size + 1 * comp_size, &gohan_data[0] + 1 * comp_size, comp_size);
26342 memcpy(&xfb.m_expected_data[0] + 0 * type_size + 3 * comp_size, &gohan_data[0] + 3 * comp_size, comp_size);
26344 /* goten - x, y - 16 */
26345 memcpy(&xfb.m_expected_data[0] + 1 * type_size + 0 * comp_size, &goten_data[0] + 0 * comp_size, comp_size);
26346 memcpy(&xfb.m_expected_data[0] + 1 * type_size + 1 * comp_size, &goten_data[0] + 1 * comp_size, comp_size);
26348 /* chichi - z, w - 48 */
26349 memcpy(&xfb.m_expected_data[0] + 3 * type_size + 2 * comp_size, &chichi_data[0] + 2 * comp_size, comp_size);
26350 memcpy(&xfb.m_expected_data[0] + 3 * type_size + 3 * comp_size, &chichi_data[0] + 3 * comp_size, comp_size);
26352 /* vegeta - x - 112 */
26353 memcpy(&xfb.m_expected_data[0] + 7 * type_size + 0 * comp_size, &vegeta_data[0] + 0 * comp_size, comp_size);
26355 /* trunks - y - 96 */
26356 memcpy(&xfb.m_expected_data[0] + 6 * type_size + 1 * comp_size, &trunks_data[0] + 1 * comp_size, comp_size);
26359 memcpy(&xfb.m_expected_data[0] + 5 * type_size + 2 * comp_size, &bra_data[0] + 2 * comp_size, comp_size);
26361 /* bulma - w - 64 */
26362 memcpy(&xfb.m_expected_data[0] + 4 * type_size + 3 * comp_size, &bulma_data[0] + 3 * comp_size, comp_size);
26365 /** Get body of main function for given shader stage
26367 * @param test_case_index Index of test case
26368 * @param stage Shader stage
26369 * @param out_assignments Set to empty
26370 * @param out_calculations Set to empty
26372 void XFBCaptureInactiveOutputComponentTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
26373 std::string& out_assignments, std::string& out_calculations)
26375 out_calculations = "";
26377 static const GLchar* vs_tes_gs = " goku.x = uni_goku.x ;\n"
26378 " goku.z = uni_goku.z ;\n"
26379 " gohan.y = uni_gohan.y ;\n"
26380 " gohan.w = uni_gohan.w ;\n"
26381 " goten.x = uni_goten.x ;\n"
26382 " goten.y = uni_goten.y ;\n"
26383 " chichi.z = uni_chichi.z ;\n"
26384 " chichi.w = uni_chichi.w ;\n"
26385 " vegeta.x = uni_vegeta.x ;\n"
26386 " trunks.y = uni_trunks.y ;\n"
26387 " bra.z = uni_bra.z ;\n"
26388 " bulma.w = uni_bulma.w ;\n";
26389 static const GLchar* fs = " fs_out = goku + gohan + goten + chichi + vegeta + trunks + bra + bulma;\n";
26391 const GLchar* assignments = "";
26395 case Utils::Shader::FRAGMENT:
26399 case Utils::Shader::GEOMETRY:
26400 if (TEST_GS == test_case_index)
26402 assignments = vs_tes_gs;
26406 case Utils::Shader::TESS_CTRL:
26409 case Utils::Shader::TESS_EVAL:
26410 if (TEST_TES == test_case_index)
26412 assignments = vs_tes_gs;
26416 case Utils::Shader::VERTEX:
26417 if (TEST_VS == test_case_index)
26419 assignments = vs_tes_gs;
26424 TCU_FAIL("Invalid enum");
26427 out_assignments = assignments;
26430 /** Get interface of shader
26432 * @param test_case_index Index of test case
26433 * @param stage Shader stage
26434 * @param out_interface Set to ""
26436 void XFBCaptureInactiveOutputComponentTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
26437 std::string& out_interface)
26439 static const GLchar* vs_tes_gs = "const uint sizeof_type = 16;\n"
26441 "layout (xfb_offset = 2 * sizeof_type) out vec4 goku;\n"
26442 "layout (xfb_offset = 0 * sizeof_type) out vec4 gohan;\n"
26443 "layout (xfb_offset = 1 * sizeof_type) out vec4 goten;\n"
26444 "layout (xfb_offset = 3 * sizeof_type) out vec4 chichi;\n"
26445 "layout (xfb_offset = 7 * sizeof_type) out vec4 vegeta;\n"
26446 "layout (xfb_offset = 6 * sizeof_type) out vec4 trunks;\n"
26447 "layout (xfb_offset = 5 * sizeof_type) out vec4 bra;\n"
26448 "layout (xfb_offset = 4 * sizeof_type) out vec4 bulma;\n"
26450 "layout(binding = 0) uniform block {\n"
26451 " vec4 uni_goku;\n"
26452 " vec4 uni_gohan;\n"
26453 " vec4 uni_goten;\n"
26454 " vec4 uni_chichi;\n"
26455 " vec4 uni_vegeta;\n"
26456 " vec4 uni_trunks;\n"
26458 " vec4 uni_bulma;\n"
26460 static const GLchar* fs = "in vec4 vegeta;\n"
26461 "in vec4 trunks;\n"
26467 "in vec4 chichi;\n"
26469 "out vec4 fs_out;\n";
26471 const GLchar* interface = "";
26475 case Utils::Shader::FRAGMENT:
26479 case Utils::Shader::GEOMETRY:
26480 if (TEST_GS == test_case_index)
26482 interface = vs_tes_gs;
26486 case Utils::Shader::TESS_CTRL:
26489 case Utils::Shader::TESS_EVAL:
26490 if (TEST_TES == test_case_index)
26492 interface = vs_tes_gs;
26496 case Utils::Shader::VERTEX:
26497 if (TEST_VS == test_case_index)
26499 interface = vs_tes_gs;
26504 TCU_FAIL("Invalid enum");
26507 out_interface = interface;
26510 /** Get source code of shader
26512 * @param test_case_index Index of test case
26513 * @param stage Shader stage
26517 std::string XFBCaptureInactiveOutputComponentTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
26519 std::string source;
26521 switch (test_case_index)
26526 case Utils::Shader::FRAGMENT:
26527 case Utils::Shader::VERTEX:
26528 source = BufferTestBase::getShaderSource(test_case_index, stage);
26538 case Utils::Shader::FRAGMENT:
26539 case Utils::Shader::TESS_CTRL:
26540 case Utils::Shader::TESS_EVAL:
26541 case Utils::Shader::VERTEX:
26542 source = BufferTestBase::getShaderSource(test_case_index, stage);
26550 source = BufferTestBase::getShaderSource(test_case_index, stage);
26554 TCU_FAIL("Invalid enum");
26562 /** Get name of test case
26564 * @param test_case_index Index of test case
26566 * @return Name of tested stage
26568 std::string XFBCaptureInactiveOutputComponentTest::getTestCaseName(glw::GLuint test_case_index)
26570 const GLchar* name = 0;
26572 switch (test_case_index)
26578 name = "tessellation evaluation";
26584 TCU_FAIL("Invalid enum");
26590 /** Returns number of test cases
26594 glw::GLuint XFBCaptureInactiveOutputComponentTest::getTestCaseNumber()
26599 /** Verify contents of buffers
26601 * @param buffers Collection of buffers to be verified
26603 * @return true if everything is as expected, false otherwise
26605 bool XFBCaptureInactiveOutputComponentTest::verifyBuffers(bufferCollection& buffers)
26607 bool result = true;
26609 bufferCollection::pair& pair = buffers.m_vector[1] /* xfb */;
26610 Utils::Buffer* buffer = pair.m_buffer;
26611 bufferDescriptor* descriptor = pair.m_descriptor;
26613 /* Get pointer to contents of buffer */
26615 GLubyte* buffer_data = (GLubyte*)buffer->Map(Utils::Buffer::ReadOnly);
26617 /* Get pointer to expected data */
26618 GLubyte* expected_data = (GLubyte*)&descriptor->m_expected_data[0];
26621 static const GLuint comp_size = 4;
26622 static const GLuint vec4_size = 16;
26625 memcmp(buffer_data + 2 * vec4_size + 0 * comp_size, expected_data + 2 * vec4_size + 0 * comp_size, comp_size);
26627 memcmp(buffer_data + 2 * vec4_size + 2 * comp_size, expected_data + 2 * vec4_size + 2 * comp_size, comp_size);
26630 memcmp(buffer_data + 0 * vec4_size + 1 * comp_size, expected_data + 0 * vec4_size + 1 * comp_size, comp_size);
26632 memcmp(buffer_data + 0 * vec4_size + 3 * comp_size, expected_data + 0 * vec4_size + 3 * comp_size, comp_size);
26635 memcmp(buffer_data + 1 * vec4_size + 0 * comp_size, expected_data + 1 * vec4_size + 0 * comp_size, comp_size);
26637 memcmp(buffer_data + 1 * vec4_size + 1 * comp_size, expected_data + 1 * vec4_size + 1 * comp_size, comp_size);
26640 memcmp(buffer_data + 3 * vec4_size + 2 * comp_size, expected_data + 3 * vec4_size + 2 * comp_size, comp_size);
26642 memcmp(buffer_data + 3 * vec4_size + 3 * comp_size, expected_data + 3 * vec4_size + 3 * comp_size, comp_size);
26645 memcmp(buffer_data + 7 * vec4_size + 0 * comp_size, expected_data + 7 * vec4_size + 0 * comp_size, comp_size);
26648 memcmp(buffer_data + 6 * vec4_size + 1 * comp_size, expected_data + 6 * vec4_size + 1 * comp_size, comp_size);
26651 memcmp(buffer_data + 5 * vec4_size + 2 * comp_size, expected_data + 5 * vec4_size + 2 * comp_size, comp_size);
26654 memcmp(buffer_data + 4 * vec4_size + 3 * comp_size, expected_data + 4 * vec4_size + 3 * comp_size, comp_size);
26656 if ((0 != res_goku_x) || (0 != res_goku_z) || (0 != res_gohan_y) || (0 != res_gohan_w) || (0 != res_goten_x) ||
26657 (0 != res_goten_y) || (0 != res_chichi_z) || (0 != res_chichi_w) || (0 != res_vegeta_x) ||
26658 (0 != res_trunks_y) || (0 != res_bra_z) || (0 != res_bulma_w))
26660 m_context.getTestContext().getLog()
26661 << tcu::TestLog::Message << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
26662 << ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
26667 /* Release buffer mapping */
26675 * @param context Test context
26677 XFBCaptureInactiveOutputBlockMemberTest::XFBCaptureInactiveOutputBlockMemberTest(deqp::Context& context)
26678 : BufferTestBase(context, "xfb_capture_inactive_output_block_member",
26679 "Test verifies that inactive block members are captured")
26681 /* Nothing to be done here */
26684 /** Execute drawArrays for single vertex
26686 * @param test_case_index
26690 bool XFBCaptureInactiveOutputBlockMemberTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
26692 const Functions& gl = m_context.getRenderContext().getFunctions();
26693 GLenum primitive_type = GL_PATCHES;
26695 if (TEST_VS == test_case_index)
26697 primitive_type = GL_POINTS;
26700 gl.disable(GL_RASTERIZER_DISCARD);
26701 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
26703 gl.beginTransformFeedback(GL_POINTS);
26704 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
26706 gl.drawArrays(primitive_type, 0 /* first */, 1 /* count */);
26707 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
26709 gl.endTransformFeedback();
26710 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
26715 /** Get descriptors of buffers necessary for test
26718 * @param out_descriptors Descriptors of buffers used by test
26720 void XFBCaptureInactiveOutputBlockMemberTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
26721 bufferDescriptor::Vector& out_descriptors)
26723 const Utils::Type& type = Utils::Type::vec4;
26725 /* Test needs single uniform and xfb */
26726 out_descriptors.resize(2);
26728 /* Get references */
26729 bufferDescriptor& uniform = out_descriptors[0];
26730 bufferDescriptor& xfb = out_descriptors[1];
26733 uniform.m_index = 0;
26737 uniform.m_target = Utils::Buffer::Uniform;
26738 xfb.m_target = Utils::Buffer::Transform_feedback;
26741 const std::vector<GLubyte>& gohan_data = type.GenerateData();
26742 const std::vector<GLubyte>& chichi_data = type.GenerateData();
26744 const GLuint type_size = static_cast<GLuint>(gohan_data.size());
26747 uniform.m_initial_data.resize(2 * type_size);
26748 memcpy(&uniform.m_initial_data[0] + 0, &gohan_data[0], type_size);
26749 memcpy(&uniform.m_initial_data[0] + type_size, &chichi_data[0], type_size);
26752 xfb.m_initial_data.resize(4 * type_size);
26753 xfb.m_expected_data.resize(4 * type_size);
26755 for (GLuint i = 0; i < 4 * type_size; ++i)
26757 xfb.m_initial_data[i] = (glw::GLubyte)i;
26758 xfb.m_expected_data[i] = (glw::GLubyte)i;
26761 memcpy(&xfb.m_expected_data[0] + 1 * type_size, &gohan_data[0], type_size);
26762 memcpy(&xfb.m_expected_data[0] + 3 * type_size, &chichi_data[0], type_size);
26765 /** Get body of main function for given shader stage
26767 * @param test_case_index Index of test case
26768 * @param stage Shader stage
26769 * @param out_assignments Set to empty
26770 * @param out_calculations Set to empty
26772 void XFBCaptureInactiveOutputBlockMemberTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
26773 std::string& out_assignments, std::string& out_calculations)
26775 out_calculations = "";
26777 static const GLchar* vs_tes_gs = " chichi = uni_chichi;\n"
26778 " gohan = uni_gohan;\n";
26779 static const GLchar* fs = " fs_out = goten + gohan + chichi;\n";
26781 const GLchar* assignments = "";
26785 case Utils::Shader::FRAGMENT:
26789 case Utils::Shader::GEOMETRY:
26790 if (TEST_GS == test_case_index)
26792 assignments = vs_tes_gs;
26796 case Utils::Shader::TESS_CTRL:
26799 case Utils::Shader::TESS_EVAL:
26800 if (TEST_TES == test_case_index)
26802 assignments = vs_tes_gs;
26806 case Utils::Shader::VERTEX:
26807 if (TEST_VS == test_case_index)
26809 assignments = vs_tes_gs;
26814 TCU_FAIL("Invalid enum");
26817 out_assignments = assignments;
26820 /** Get interface of shader
26822 * @param test_case_index Index of test case
26823 * @param stage Shader stage
26824 * @param out_interface Set to ""
26826 void XFBCaptureInactiveOutputBlockMemberTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
26827 std::string& out_interface)
26829 static const GLchar* vs_tes_gs = "const uint sizeof_type = 16;\n"
26831 "layout (xfb_offset = 1 * sizeof_type) out Goku {\n"
26837 "layout(binding = 0) uniform block {\n"
26838 " vec4 uni_gohan;\n"
26839 " vec4 uni_chichi;\n"
26841 static const GLchar* fs = "in Goku {\n"
26846 "out vec4 fs_out;\n";
26848 const GLchar* interface = "";
26852 case Utils::Shader::FRAGMENT:
26856 case Utils::Shader::GEOMETRY:
26857 if (TEST_GS == test_case_index)
26859 interface = vs_tes_gs;
26863 case Utils::Shader::TESS_CTRL:
26866 case Utils::Shader::TESS_EVAL:
26867 if (TEST_TES == test_case_index)
26869 interface = vs_tes_gs;
26873 case Utils::Shader::VERTEX:
26874 if (TEST_VS == test_case_index)
26876 interface = vs_tes_gs;
26881 TCU_FAIL("Invalid enum");
26884 out_interface = interface;
26887 /** Get source code of shader
26889 * @param test_case_index Index of test case
26890 * @param stage Shader stage
26894 std::string XFBCaptureInactiveOutputBlockMemberTest::getShaderSource(GLuint test_case_index,
26895 Utils::Shader::STAGES stage)
26897 std::string source;
26899 switch (test_case_index)
26904 case Utils::Shader::FRAGMENT:
26905 case Utils::Shader::VERTEX:
26906 source = BufferTestBase::getShaderSource(test_case_index, stage);
26916 case Utils::Shader::FRAGMENT:
26917 case Utils::Shader::TESS_CTRL:
26918 case Utils::Shader::TESS_EVAL:
26919 case Utils::Shader::VERTEX:
26920 source = BufferTestBase::getShaderSource(test_case_index, stage);
26928 source = BufferTestBase::getShaderSource(test_case_index, stage);
26932 TCU_FAIL("Invalid enum");
26940 /** Get name of test case
26942 * @param test_case_index Index of test case
26944 * @return Name of tested stage
26946 std::string XFBCaptureInactiveOutputBlockMemberTest::getTestCaseName(glw::GLuint test_case_index)
26948 const GLchar* name = 0;
26950 switch (test_case_index)
26956 name = "tessellation evaluation";
26962 TCU_FAIL("Invalid enum");
26968 /** Returns number of test cases
26972 glw::GLuint XFBCaptureInactiveOutputBlockMemberTest::getTestCaseNumber()
26977 /** Verify contents of buffers
26979 * @param buffers Collection of buffers to be verified
26981 * @return true if everything is as expected, false otherwise
26983 bool XFBCaptureInactiveOutputBlockMemberTest::verifyBuffers(bufferCollection& buffers)
26985 bool result = true;
26987 bufferCollection::pair& pair = buffers.m_vector[1] /* xfb */;
26988 Utils::Buffer* buffer = pair.m_buffer;
26989 bufferDescriptor* descriptor = pair.m_descriptor;
26991 /* Get pointer to contents of buffer */
26993 GLubyte* buffer_data = (GLubyte*)buffer->Map(Utils::Buffer::ReadOnly);
26995 /* Get pointer to expected data */
26996 GLubyte* expected_data = (GLubyte*)&descriptor->m_expected_data[0];
26999 static const GLuint vec4_size = 16;
27001 int res_before = memcmp(buffer_data, expected_data, vec4_size);
27002 int res_gohan = memcmp(buffer_data + 1 * vec4_size, expected_data + 1 * vec4_size, vec4_size);
27003 int res_chichi = memcmp(buffer_data + 3 * vec4_size, expected_data + 3 * vec4_size, vec4_size);
27005 if ((0 != res_before) || (0 != res_gohan) || (0 != res_chichi))
27007 m_context.getTestContext().getLog()
27008 << tcu::TestLog::Message << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
27009 << ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
27014 /* Release buffer mapping */
27022 * @param context Test context
27024 XFBCaptureStructTest::XFBCaptureStructTest(deqp::Context& context)
27025 : BufferTestBase(context, "xfb_capture_struct", "Test verifies that inactive structure members are captured")
27027 /* Nothing to be done here */
27030 /** Execute drawArrays for single vertex
27032 * @param test_case_index
27036 bool XFBCaptureStructTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
27038 const Functions& gl = m_context.getRenderContext().getFunctions();
27039 GLenum primitive_type = GL_PATCHES;
27041 if (TEST_VS == test_case_index)
27043 primitive_type = GL_POINTS;
27046 gl.disable(GL_RASTERIZER_DISCARD);
27047 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
27049 gl.beginTransformFeedback(GL_POINTS);
27050 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
27052 gl.drawArrays(primitive_type, 0 /* first */, 1 /* count */);
27053 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
27055 gl.endTransformFeedback();
27056 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
27061 /** Get descriptors of buffers necessary for test
27064 * @param out_descriptors Descriptors of buffers used by test
27066 void XFBCaptureStructTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
27067 bufferDescriptor::Vector& out_descriptors)
27069 const Utils::Type& type = Utils::Type::vec4;
27071 /* Test needs single uniform and xfb */
27072 out_descriptors.resize(2);
27074 /* Get references */
27075 bufferDescriptor& uniform = out_descriptors[0];
27076 bufferDescriptor& xfb = out_descriptors[1];
27079 uniform.m_index = 0;
27083 uniform.m_target = Utils::Buffer::Uniform;
27084 xfb.m_target = Utils::Buffer::Transform_feedback;
27087 const std::vector<GLubyte>& gohan_data = type.GenerateData();
27088 const std::vector<GLubyte>& chichi_data = type.GenerateData();
27090 const GLuint type_size = static_cast<GLuint>(gohan_data.size());
27093 uniform.m_initial_data.resize(2 * type_size);
27094 memcpy(&uniform.m_initial_data[0] + 0, &gohan_data[0], type_size);
27095 memcpy(&uniform.m_initial_data[0] + type_size, &chichi_data[0], type_size);
27098 xfb.m_initial_data.resize(4 * type_size);
27099 xfb.m_expected_data.resize(4 * type_size);
27101 for (GLuint i = 0; i < 4 * type_size; ++i)
27103 xfb.m_initial_data[i] = (glw::GLubyte)i;
27104 xfb.m_expected_data[i] = (glw::GLubyte)i;
27107 memcpy(&xfb.m_expected_data[0] + 1 * type_size, &gohan_data[0], type_size);
27108 memcpy(&xfb.m_expected_data[0] + 3 * type_size, &chichi_data[0], type_size);
27111 /** Get body of main function for given shader stage
27113 * @param test_case_index Index of test case
27114 * @param stage Shader stage
27115 * @param out_assignments Set to empty
27116 * @param out_calculations Set to empty
27118 void XFBCaptureStructTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
27119 std::string& out_assignments, std::string& out_calculations)
27121 out_calculations = "";
27123 static const GLchar* vs_tes_gs = " goku.chichi = uni_chichi;\n"
27124 " goku.gohan = uni_gohan;\n";
27125 static const GLchar* fs = " fs_out = goku.goten + goku.gohan + goku.chichi;\n";
27127 const GLchar* assignments = "";
27131 case Utils::Shader::FRAGMENT:
27135 case Utils::Shader::GEOMETRY:
27136 if (TEST_GS == test_case_index)
27138 assignments = vs_tes_gs;
27142 case Utils::Shader::TESS_CTRL:
27145 case Utils::Shader::TESS_EVAL:
27146 if (TEST_TES == test_case_index)
27148 assignments = vs_tes_gs;
27152 case Utils::Shader::VERTEX:
27153 if (TEST_VS == test_case_index)
27155 assignments = vs_tes_gs;
27160 TCU_FAIL("Invalid enum");
27163 out_assignments = assignments;
27166 /** Get interface of shader
27168 * @param test_case_index Index of test case
27169 * @param stage Shader stage
27170 * @param out_interface Set to ""
27172 void XFBCaptureStructTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
27173 std::string& out_interface)
27175 static const GLchar* vs_tes_gs = "const uint sizeof_type = 16;\n"
27183 "layout (xfb_offset = sizeof_type) out Goku goku;\n"
27185 "layout(binding = 0, std140) uniform block {\n"
27186 " vec4 uni_gohan;\n"
27187 " vec4 uni_chichi;\n"
27189 static const GLchar* fs = "struct Goku {\n"
27197 "out vec4 fs_out;\n";
27199 const GLchar* interface = "";
27203 case Utils::Shader::FRAGMENT:
27207 case Utils::Shader::GEOMETRY:
27208 if (TEST_GS == test_case_index)
27210 interface = vs_tes_gs;
27214 case Utils::Shader::TESS_CTRL:
27217 case Utils::Shader::TESS_EVAL:
27218 if (TEST_TES == test_case_index)
27220 interface = vs_tes_gs;
27224 case Utils::Shader::VERTEX:
27225 if (TEST_VS == test_case_index)
27227 interface = vs_tes_gs;
27232 TCU_FAIL("Invalid enum");
27235 out_interface = interface;
27238 /** Get source code of shader
27240 * @param test_case_index Index of test case
27241 * @param stage Shader stage
27245 std::string XFBCaptureStructTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
27247 std::string source;
27249 switch (test_case_index)
27254 case Utils::Shader::FRAGMENT:
27255 case Utils::Shader::VERTEX:
27256 source = BufferTestBase::getShaderSource(test_case_index, stage);
27266 case Utils::Shader::FRAGMENT:
27267 case Utils::Shader::TESS_CTRL:
27268 case Utils::Shader::TESS_EVAL:
27269 case Utils::Shader::VERTEX:
27270 source = BufferTestBase::getShaderSource(test_case_index, stage);
27278 source = BufferTestBase::getShaderSource(test_case_index, stage);
27282 TCU_FAIL("Invalid enum");
27290 /** Get name of test case
27292 * @param test_case_index Index of test case
27294 * @return Name of tested stage
27296 std::string XFBCaptureStructTest::getTestCaseName(glw::GLuint test_case_index)
27298 const GLchar* name = 0;
27300 switch (test_case_index)
27306 name = "tessellation evaluation";
27312 TCU_FAIL("Invalid enum");
27318 /** Returns number of test cases
27322 glw::GLuint XFBCaptureStructTest::getTestCaseNumber()
27327 /** Verify contents of buffers
27329 * @param buffers Collection of buffers to be verified
27331 * @return true if everything is as expected, false otherwise
27333 bool XFBCaptureStructTest::verifyBuffers(bufferCollection& buffers)
27335 bool result = true;
27337 bufferCollection::pair& pair = buffers.m_vector[1] /* xfb */;
27338 Utils::Buffer* buffer = pair.m_buffer;
27339 bufferDescriptor* descriptor = pair.m_descriptor;
27341 /* Get pointer to contents of buffer */
27343 GLubyte* buffer_data = (GLubyte*)buffer->Map(Utils::Buffer::ReadOnly);
27345 /* Get pointer to expected data */
27346 GLubyte* expected_data = (GLubyte*)&descriptor->m_expected_data[0];
27349 static const GLuint vec4_size = 16;
27351 int res_before = memcmp(buffer_data, expected_data, vec4_size);
27352 int res_gohan = memcmp(buffer_data + 1 * vec4_size, expected_data + 1 * vec4_size, vec4_size);
27353 int res_chichi = memcmp(buffer_data + 3 * vec4_size, expected_data + 3 * vec4_size, vec4_size);
27355 if ((0 != res_before) || (0 != res_gohan) || (0 != res_chichi))
27357 m_context.getTestContext().getLog()
27358 << tcu::TestLog::Message << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
27359 << ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
27364 /* Release buffer mapping */
27372 * @param context Test framework context
27374 XFBCaptureUnsizedArrayTest::XFBCaptureUnsizedArrayTest(deqp::Context& context)
27375 : NegativeTestBase(context, "xfb_capture_unsized_array",
27376 "Test verifies that compiler reports error when unsized array is qualified with xfb_offset")
27380 /** Source for given test case and stage
27382 * @param test_case_index Index of test case
27383 * @param stage Shader stage
27385 * @return Shader source
27387 std::string XFBCaptureUnsizedArrayTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
27389 static const GLchar* var_definition = "layout (xfb_offset = 0) out vec4 gokuARRAY[];\n";
27390 static const GLchar* var_use = " gokuINDEX[0] = result / 2;\n";
27391 static const GLchar* fs = "#version 430 core\n"
27392 "#extension GL_ARB_enhanced_layouts : require\n"
27395 "out vec4 fs_out;\n"
27399 " fs_out = gs_fs;\n"
27402 static const GLchar* gs_tested = "#version 430 core\n"
27403 "#extension GL_ARB_enhanced_layouts : require\n"
27405 "layout(points) in;\n"
27406 "layout(triangle_strip, max_vertices = 4) out;\n"
27410 "in vec4 tes_gs[];\n"
27411 "out vec4 gs_fs;\n"
27415 " vec4 result = tes_gs[0];\n"
27419 " gs_fs = result;\n"
27420 " gl_Position = vec4(-1, -1, 0, 1);\n"
27422 " gs_fs = result;\n"
27423 " gl_Position = vec4(-1, 1, 0, 1);\n"
27425 " gs_fs = result;\n"
27426 " gl_Position = vec4(1, -1, 0, 1);\n"
27428 " gs_fs = result;\n"
27429 " gl_Position = vec4(1, 1, 0, 1);\n"
27433 static const GLchar* tcs = "#version 430 core\n"
27434 "#extension GL_ARB_enhanced_layouts : require\n"
27436 "layout(vertices = 1) out;\n"
27438 "in vec4 vs_tcs[];\n"
27439 "out vec4 tcs_tes[];\n"
27444 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
27446 " gl_TessLevelOuter[0] = 1.0;\n"
27447 " gl_TessLevelOuter[1] = 1.0;\n"
27448 " gl_TessLevelOuter[2] = 1.0;\n"
27449 " gl_TessLevelOuter[3] = 1.0;\n"
27450 " gl_TessLevelInner[0] = 1.0;\n"
27451 " gl_TessLevelInner[1] = 1.0;\n"
27454 static const GLchar* tcs_tested = "#version 430 core\n"
27455 "#extension GL_ARB_enhanced_layouts : require\n"
27457 "layout(vertices = 1) out;\n"
27461 "in vec4 vs_tcs[];\n"
27462 "out vec4 tcs_tes[];\n"
27466 " vec4 result = vs_tcs[gl_InvocationID];\n"
27470 " tcs_tes[gl_InvocationID] = result;\n"
27472 " gl_TessLevelOuter[0] = 1.0;\n"
27473 " gl_TessLevelOuter[1] = 1.0;\n"
27474 " gl_TessLevelOuter[2] = 1.0;\n"
27475 " gl_TessLevelOuter[3] = 1.0;\n"
27476 " gl_TessLevelInner[0] = 1.0;\n"
27477 " gl_TessLevelInner[1] = 1.0;\n"
27480 static const GLchar* tes_tested = "#version 430 core\n"
27481 "#extension GL_ARB_enhanced_layouts : require\n"
27483 "layout(isolines, point_mode) in;\n"
27487 "in vec4 tcs_tes[];\n"
27488 "out vec4 tes_gs;\n"
27492 " vec4 result = tcs_tes[0];\n"
27496 " tes_gs += result;\n"
27499 static const GLchar* vs = "#version 430 core\n"
27500 "#extension GL_ARB_enhanced_layouts : require\n"
27503 "out vec4 vs_tcs;\n"
27507 " vs_tcs = in_vs;\n"
27510 static const GLchar* vs_tested = "#version 430 core\n"
27511 "#extension GL_ARB_enhanced_layouts : require\n"
27516 "out vec4 vs_tcs;\n"
27520 " vec4 result = in_vs;\n"
27524 " vs_tcs = result;\n"
27528 std::string source;
27529 testCase& test_case = m_test_cases[test_case_index];
27531 if (test_case.m_stage == stage)
27533 const GLchar* array = "";
27534 const GLchar* index = "";
27535 size_t position = 0;
27539 case Utils::Shader::GEOMETRY:
27540 source = gs_tested;
27544 case Utils::Shader::TESS_CTRL:
27545 source = tcs_tested;
27547 index = "[gl_InvocationID]";
27549 case Utils::Shader::TESS_EVAL:
27550 source = tes_tested;
27554 case Utils::Shader::VERTEX:
27555 source = vs_tested;
27558 TCU_FAIL("Invalid enum");
27561 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
27563 Utils::replaceToken("ARRAY", position, array, source);
27564 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
27566 Utils::replaceAllTokens("INDEX", index, source);
27570 switch (test_case.m_stage)
27572 case Utils::Shader::GEOMETRY:
27575 case Utils::Shader::FRAGMENT:
27578 case Utils::Shader::VERTEX:
27585 case Utils::Shader::TESS_CTRL:
27588 case Utils::Shader::FRAGMENT:
27591 case Utils::Shader::VERTEX:
27598 case Utils::Shader::TESS_EVAL:
27601 case Utils::Shader::FRAGMENT:
27604 case Utils::Shader::TESS_CTRL:
27607 case Utils::Shader::VERTEX:
27614 case Utils::Shader::VERTEX:
27617 case Utils::Shader::FRAGMENT:
27625 TCU_FAIL("Invalid enum");
27633 /** Get description of test case
27635 * @param test_case_index Index of test case
27637 * @return Test case description
27639 std::string XFBCaptureUnsizedArrayTest::getTestCaseName(GLuint test_case_index)
27641 std::stringstream stream;
27642 testCase& test_case = m_test_cases[test_case_index];
27644 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage);
27646 return stream.str();
27649 /** Get number of test cases
27651 * @return Number of test cases
27653 GLuint XFBCaptureUnsizedArrayTest::getTestCaseNumber()
27655 return static_cast<GLuint>(m_test_cases.size());
27658 /** Selects if "compute" stage is relevant for test
27664 bool XFBCaptureUnsizedArrayTest::isComputeRelevant(GLuint /* test_case_index */)
27669 /** Prepare all test cases
27672 void XFBCaptureUnsizedArrayTest::testInit()
27674 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
27676 /* Not aplicable for */
27677 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::FRAGMENT == stage) ||
27678 (Utils::Shader::GEOMETRY == stage) || (Utils::Shader::TESS_EVAL == stage))
27683 testCase test_case = { (Utils::Shader::STAGES)stage };
27685 m_test_cases.push_back(test_case);
27688 } /* EnhancedLayouts namespace */
27692 * @param context Rendering context.
27694 EnhancedLayoutsTests::EnhancedLayoutsTests(deqp::Context& context)
27695 : TestCaseGroup(context, "enhanced_layouts", "Verifies \"enhanced layouts\" functionality")
27697 /* Left blank on purpose */
27700 /** Initializes a texture_storage_multisample test group.
27703 void EnhancedLayoutsTests::init(void)
27705 addChild(new EnhancedLayouts::APIConstantValuesTest(m_context));
27706 addChild(new EnhancedLayouts::APIErrorsTest(m_context));
27707 addChild(new EnhancedLayouts::GLSLContantValuesTest(m_context));
27708 addChild(new EnhancedLayouts::GLSLContantImmutablityTest(m_context));
27709 addChild(new EnhancedLayouts::GLSLConstantIntegralExpressionTest(m_context));
27710 addChild(new EnhancedLayouts::UniformBlockLayoutQualifierConflictTest(m_context));
27711 addChild(new EnhancedLayouts::SSBMemberInvalidOffsetAlignmentTest(m_context));
27712 addChild(new EnhancedLayouts::SSBMemberOverlappingOffsetsTest(m_context));
27713 addChild(new EnhancedLayouts::VaryingExceedingComponentsTest(m_context));
27714 addChild(new EnhancedLayouts::VaryingComponentOfInvalidTypeTest(m_context));
27715 addChild(new EnhancedLayouts::OutputComponentAliasingTest(m_context));
27716 addChild(new EnhancedLayouts::VertexAttribLocationAPITest(m_context));
27717 addChild(new EnhancedLayouts::XFBInputTest(m_context));
27718 addChild(new EnhancedLayouts::XFBAllStagesTest(m_context));
27719 addChild(new EnhancedLayouts::XFBCaptureInactiveOutputVariableTest(m_context));
27720 addChild(new EnhancedLayouts::XFBCaptureInactiveOutputComponentTest(m_context));
27721 addChild(new EnhancedLayouts::XFBCaptureInactiveOutputBlockMemberTest(m_context));
27722 addChild(new EnhancedLayouts::XFBStrideTest(m_context));
27724 addChild(new EnhancedLayouts::UniformBlockMemberOffsetAndAlignTest(m_context));
27725 addChild(new EnhancedLayouts::UniformBlockMemberInvalidOffsetAlignmentTest(m_context));
27726 addChild(new EnhancedLayouts::UniformBlockMemberOverlappingOffsetsTest(m_context));
27727 addChild(new EnhancedLayouts::UniformBlockMemberAlignNonPowerOf2Test(m_context));
27728 addChild(new EnhancedLayouts::SSBLayoutQualifierConflictTest(m_context));
27729 addChild(new EnhancedLayouts::SSBMemberAlignNonPowerOf2Test(m_context));
27730 addChild(new EnhancedLayouts::SSBAlignmentTest(m_context));
27731 addChild(new EnhancedLayouts::VaryingStructureMemberLocationTest(m_context));
27732 addChild(new EnhancedLayouts::VaryingBlockAutomaticMemberLocationsTest(m_context));
27733 addChild(new EnhancedLayouts::VaryingComponentWithoutLocationTest(m_context));
27734 addChild(new EnhancedLayouts::InputComponentAliasingTest(m_context));
27735 addChild(new EnhancedLayouts::VaryingLocationAliasingWithMixedTypesTest(m_context));
27736 addChild(new EnhancedLayouts::VaryingLocationAliasingWithMixedInterpolationTest(m_context));
27737 addChild(new EnhancedLayouts::VaryingLocationAliasingWithMixedAuxiliaryStorageTest(m_context));
27738 addChild(new EnhancedLayouts::XFBStrideOfEmptyListTest(m_context));
27739 addChild(new EnhancedLayouts::XFBStrideOfEmptyListAndAPITest(m_context));
27740 addChild(new EnhancedLayouts::XFBTooSmallStrideTest(m_context));
27741 addChild(new EnhancedLayouts::XFBBlockMemberStrideTest(m_context));
27742 addChild(new EnhancedLayouts::XFBDuplicatedStrideTest(m_context));
27743 addChild(new EnhancedLayouts::XFBGetProgramResourceAPITest(m_context));
27744 addChild(new EnhancedLayouts::XFBMultipleVertexStreamsTest(m_context));
27745 addChild(new EnhancedLayouts::XFBExceedBufferLimitTest(m_context));
27746 addChild(new EnhancedLayouts::XFBExceedOffsetLimitTest(m_context));
27747 addChild(new EnhancedLayouts::XFBBlockMemberBufferTest(m_context));
27748 addChild(new EnhancedLayouts::XFBOutputOverlappingTest(m_context));
27749 addChild(new EnhancedLayouts::XFBInvalidOffsetAlignmentTest(m_context));
27750 addChild(new EnhancedLayouts::XFBCaptureStructTest(m_context));
27751 addChild(new EnhancedLayouts::XFBCaptureUnsizedArrayTest(m_context));
27752 addChild(new EnhancedLayouts::UniformBlockAlignmentTest(m_context));
27753 addChild(new EnhancedLayouts::SSBMemberOffsetAndAlignTest(m_context));
27754 addChild(new EnhancedLayouts::VertexAttribLocationsTest(m_context));
27755 addChild(new EnhancedLayouts::VaryingLocationsTest(m_context));
27756 addChild(new EnhancedLayouts::VaryingArrayLocationsTest(m_context));
27757 addChild(new EnhancedLayouts::VaryingStructureLocationsTest(m_context));
27758 addChild(new EnhancedLayouts::VaryingBlockLocationsTest(m_context));
27759 addChild(new EnhancedLayouts::VaryingBlockMemberLocationsTest(m_context));
27760 addChild(new EnhancedLayouts::XFBVariableStrideTest(m_context));
27761 addChild(new EnhancedLayouts::XFBBlockStrideTest(m_context));
27762 addChild(new EnhancedLayouts::XFBOverrideQualifiersWithAPITest(m_context));
27763 addChild(new EnhancedLayouts::XFBVertexStreamsTest(m_context));
27764 addChild(new EnhancedLayouts::XFBGlobalBufferTest(m_context));
27765 addChild(new EnhancedLayouts::FragmentDataLocationAPITest(m_context));
27766 addChild(new EnhancedLayouts::VaryingLocationLimitTest(m_context));
27767 addChild(new EnhancedLayouts::VaryingComponentsTest(m_context));
27768 addChild(new EnhancedLayouts::VaryingArrayComponentsTest(m_context));
27771 } /* gl4cts namespace */