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,
505 GLuint Type::GetLocations() 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))
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. Note that this routine assumes tightly packing
525 * @return Formula Number of columns * number of rows * sizeof(base_type)
527 GLuint Type::GetSize() const
529 const GLuint basic_type_size = GetTypeSize(m_basic_type);
530 const GLuint n_elements = m_n_columns * m_n_rows;
532 return basic_type_size * n_elements;
535 /** Get GLenum representing the type
539 GLenum Type::GetTypeGLenum() const
541 static const GLenum float_lut[4][4] = {
542 { GL_FLOAT, GL_FLOAT_VEC2, GL_FLOAT_VEC3, GL_FLOAT_VEC4 },
543 { 0, GL_FLOAT_MAT2, GL_FLOAT_MAT2x3, GL_FLOAT_MAT2x4 },
544 { 0, GL_FLOAT_MAT3x2, GL_FLOAT_MAT3, GL_FLOAT_MAT3x4 },
545 { 0, GL_FLOAT_MAT4x2, GL_FLOAT_MAT4x3, GL_FLOAT_MAT4 },
548 static const GLenum double_lut[4][4] = {
549 { GL_DOUBLE, GL_DOUBLE_VEC2, GL_DOUBLE_VEC3, GL_DOUBLE_VEC4 },
550 { 0, GL_DOUBLE_MAT2, GL_DOUBLE_MAT2x3, GL_DOUBLE_MAT2x4 },
551 { 0, GL_DOUBLE_MAT3x2, GL_DOUBLE_MAT3, GL_DOUBLE_MAT3x4 },
552 { 0, GL_DOUBLE_MAT4x2, GL_DOUBLE_MAT4x3, GL_DOUBLE_MAT4 },
555 static const GLenum int_lut[4] = { GL_INT, GL_INT_VEC2, GL_INT_VEC3, GL_INT_VEC4 };
557 static const GLenum uint_lut[4] = { GL_UNSIGNED_INT, GL_UNSIGNED_INT_VEC2, GL_UNSIGNED_INT_VEC3,
558 GL_UNSIGNED_INT_VEC4 };
562 if ((1 > m_n_columns) || (1 > m_n_rows) || (4 < m_n_columns) || (4 < m_n_rows))
567 switch (m_basic_type)
570 result = float_lut[m_n_columns - 1][m_n_rows - 1];
573 result = double_lut[m_n_columns - 1][m_n_rows - 1];
576 result = int_lut[m_n_rows - 1];
579 result = uint_lut[m_n_rows - 1];
582 TCU_FAIL("Invliad enum");
588 /** Calculate the numbe of components consumed by a type
589 * according to 11.1.2.1 Output Variables
591 * @return Calculated number of components for the type
593 GLuint Type::GetNumComponents() const
595 // Rule 3 of Section 7.6.2.2
596 // If the member is a three-component vector with components consuming N
597 // basic machine units, the base alignment is 4N.
598 GLuint num_components = (m_n_rows == 3 ? 4 : m_n_rows) * m_n_columns;
600 if (m_basic_type == Double)
605 return num_components;
608 /** Calculate stride for the type according to std140 rules
610 * @param alignment Alignment of type
611 * @param n_columns Number of columns
612 * @param n_array_elements Number of elements in array
614 * @return Calculated value
616 GLuint Type::CalculateStd140Stride(GLuint alignment, GLuint n_columns, GLuint n_array_elements)
618 GLuint stride = alignment * n_columns;
619 if (0 != n_array_elements)
621 stride *= n_array_elements;
627 /** Check if glsl support matrices for specific basic type
629 * @param type Basic type
631 * @return true if matrices of <type> are supported, false otherwise
633 bool Type::DoesTypeSupportMatrix(TYPES type)
648 TCU_FAIL("Invliad enum");
654 /** Creates instance of Type
656 * @param basic_type Select basic type of instance
657 * @param n_columns Number of columns
658 * @param n_rows Number of rows
660 * @return Type instance
662 Type Type::GetType(TYPES basic_type, glw::GLuint n_columns, glw::GLuint n_rows)
664 Type type = { basic_type, n_columns, n_rows };
669 /** Get Size of given type in bytes
673 * @return Size of type
675 GLuint Type::GetTypeSize(TYPES type)
682 result = sizeof(GLfloat);
685 result = sizeof(GLdouble);
688 result = sizeof(GLint);
691 result = sizeof(GLuint);
694 TCU_FAIL("Invalid enum");
700 /** Get GLenum representing given type
704 * @return GLenum value
706 GLenum Type::GetTypeGLenum(TYPES type)
722 result = GL_UNSIGNED_INT;
725 TCU_FAIL("Invalid enum");
731 /** Get proper glUniformNdv routine for vectors with specified number of rows
733 * @param gl GL functions
734 * @param n_rows Number of rows
736 * @return Function address
738 uniformNdv getUniformNdv(const glw::Functions& gl, glw::GLuint n_rows)
740 uniformNdv result = 0;
745 result = gl.uniform1dv;
748 result = gl.uniform2dv;
751 result = gl.uniform3dv;
754 result = gl.uniform4dv;
757 TCU_FAIL("Invalid number of rows");
763 /** Get proper glUniformNfv routine for vectors with specified number of rows
765 * @param gl GL functions
766 * @param n_rows Number of rows
768 * @return Function address
770 uniformNfv getUniformNfv(const glw::Functions& gl, glw::GLuint n_rows)
772 uniformNfv result = 0;
777 result = gl.uniform1fv;
780 result = gl.uniform2fv;
783 result = gl.uniform3fv;
786 result = gl.uniform4fv;
789 TCU_FAIL("Invalid number of rows");
795 /** Get proper glUniformNiv routine for vectors with specified number of rows
797 * @param gl GL functions
798 * @param n_rows Number of rows
800 * @return Function address
802 uniformNiv getUniformNiv(const glw::Functions& gl, glw::GLuint n_rows)
804 uniformNiv result = 0;
809 result = gl.uniform1iv;
812 result = gl.uniform2iv;
815 result = gl.uniform3iv;
818 result = gl.uniform4iv;
821 TCU_FAIL("Invalid number of rows");
827 /** Get proper glUniformNuiv routine for vectors with specified number of rows
829 * @param gl GL functions
830 * @param n_rows Number of rows
832 * @return Function address
834 uniformNuiv getUniformNuiv(const glw::Functions& gl, glw::GLuint n_rows)
836 uniformNuiv result = 0;
841 result = gl.uniform1uiv;
844 result = gl.uniform2uiv;
847 result = gl.uniform3uiv;
850 result = gl.uniform4uiv;
853 TCU_FAIL("Invalid number of rows");
859 /** Get proper glUniformMatrixNdv routine for matrix with specified number of columns and rows
861 * @param gl GL functions
862 * @param n_rows Number of rows
864 * @return Function address
866 uniformMatrixNdv getUniformMatrixNdv(const glw::Functions& gl, glw::GLuint n_columns, glw::GLuint n_rows)
868 uniformMatrixNdv result = 0;
876 result = gl.uniformMatrix2dv;
879 result = gl.uniformMatrix2x3dv;
882 result = gl.uniformMatrix2x4dv;
885 TCU_FAIL("Invalid number of rows");
892 result = gl.uniformMatrix3x2dv;
895 result = gl.uniformMatrix3dv;
898 result = gl.uniformMatrix3x4dv;
901 TCU_FAIL("Invalid number of rows");
908 result = gl.uniformMatrix4x2dv;
911 result = gl.uniformMatrix4x3dv;
914 result = gl.uniformMatrix4dv;
917 TCU_FAIL("Invalid number of rows");
921 TCU_FAIL("Invalid number of columns");
927 /** Get proper glUniformMatrixNfv routine for vectors with specified number of columns and rows
929 * @param gl GL functions
930 * @param n_rows Number of rows
932 * @return Function address
934 uniformMatrixNfv getUniformMatrixNfv(const glw::Functions& gl, glw::GLuint n_columns, glw::GLuint n_rows)
936 uniformMatrixNfv result = 0;
944 result = gl.uniformMatrix2fv;
947 result = gl.uniformMatrix2x3fv;
950 result = gl.uniformMatrix2x4fv;
953 TCU_FAIL("Invalid number of rows");
960 result = gl.uniformMatrix3x2fv;
963 result = gl.uniformMatrix3fv;
966 result = gl.uniformMatrix3x4fv;
969 TCU_FAIL("Invalid number of rows");
976 result = gl.uniformMatrix4x2fv;
979 result = gl.uniformMatrix4x3fv;
982 result = gl.uniformMatrix4fv;
985 TCU_FAIL("Invalid number of rows");
989 TCU_FAIL("Invalid number of columns");
995 bool verifyVarying(Program& program, const std::string& parent_name, const Variable::Descriptor& desc,
996 std::stringstream& stream, bool is_input)
1000 GLenum interface = GL_PROGRAM_INPUT;
1003 if (false == is_input)
1005 interface = GL_PROGRAM_OUTPUT;
1008 const std::string& name = Utils::Variable::GetReference(parent_name, desc, Utils::Variable::BASIC, 0);
1012 index = program.GetResourceIndex(name, interface);
1014 program.GetResource(interface, index, GL_LOCATION, 1 /* size */, &location);
1015 program.GetResource(interface, index, GL_LOCATION_COMPONENT, 1 /* size */, &component);
1017 catch (std::exception& exc)
1019 stream << "Failed to query program for varying: " << desc.m_name << ". Reason: " << exc.what() << "\n";
1026 if (location != desc.m_expected_location)
1028 stream << "Attribute: " << desc.m_name << " - invalid location: " << location
1029 << " expected: " << desc.m_expected_location << std::endl;
1032 if (component != desc.m_expected_component)
1034 stream << "Attribute: " << desc.m_name << " - invalid component: " << component
1035 << " expected: " << desc.m_expected_component << std::endl;
1042 /** Query program resource for given variable and verify that everything is as expected
1044 * @param program Program object
1045 * @param variable Variable object
1046 * @param stream Stream that will be used to log any error
1047 * @param is_input Selects if varying is input or output
1049 * @return true if verification is positive, false otherwise
1051 bool checkVarying(Program& program, const Variable& variable, std::stringstream& stream, bool is_input)
1055 if (variable.IsBlock())
1057 Utils::Interface* interface = variable.m_descriptor.m_interface;
1058 const size_t n_members = interface->m_members.size();
1060 for (size_t i = 0; i < n_members; ++i)
1062 const Variable::Descriptor& member = interface->m_members[i];
1063 bool member_result = verifyVarying(program, interface->m_name, member, stream, is_input);
1065 if (false == member_result)
1072 To query the the location of struct member by glGetProgramResource, we need pass the variable name "gs_fs_output[0].single",
1073 but in original implementation, the test pass the name "Data.single", which can't get any valid result.
1078 layout (location = 0) in Data gs_fs_output[1];
1080 else if (variable.IsStruct())
1082 Utils::Interface* interface = variable.m_descriptor.m_interface;
1083 const size_t n_members = interface->m_members.size();
1084 std::string structVariable = variable.m_descriptor.m_name;
1085 // If struct variable is an array
1086 if (0 != variable.m_descriptor.m_n_array_elements)
1088 for (GLuint i = 0; i < variable.m_descriptor.m_n_array_elements; i++)
1091 sprintf(buffer, "%d", i);
1092 structVariable.append("[");
1093 structVariable.append(buffer);
1094 structVariable.append("]");
1095 for (size_t j = 0; j < n_members; ++j)
1097 const Variable::Descriptor& member = interface->m_members[j];
1098 bool member_result = verifyVarying(program, structVariable, member, stream, is_input);
1100 if (false == member_result)
1109 for (GLuint i = 0; i < n_members; ++i)
1111 const Variable::Descriptor& member = interface->m_members[i];
1112 bool member_result = verifyVarying(program, structVariable, member, stream, is_input);
1114 if (false == member_result)
1123 result = verifyVarying(program, "", variable.m_descriptor, stream, is_input);
1128 /** Query program resource for given variable and verify that everything is as expected
1130 * @param program Program object
1131 * @param variable Variable object
1132 * @param stream Stream that will be used to log any error
1134 * @return true if verification is positive, false otherwise
1136 bool checkUniform(Program& program, const Utils::Variable& variable, std::stringstream& stream)
1140 if (false == variable.IsBlock())
1142 TCU_FAIL("Not implemented");
1146 Utils::Interface* interface = variable.m_descriptor.m_interface;
1148 size_t size = interface->m_members.size();
1150 std::vector<GLuint> indices;
1151 std::vector<const char*> names;
1152 std::vector<std::string> names_str;
1153 std::vector<GLint> offsets;
1155 indices.resize(size);
1157 names_str.resize(size);
1158 offsets.resize(size);
1160 for (size_t i = 0; i < size; ++i)
1165 const std::string& name =
1166 Utils::Variable::GetReference(interface->m_name, interface->m_members[i], Utils::Variable::BASIC, 0);
1168 if (Utils::Variable::INTERFACE == interface->m_members[i].m_type)
1170 const std::string& member_name = Utils::Variable::GetReference(
1171 name, interface->m_members[i].m_interface->m_members[0], Utils::Variable::BASIC, 0);
1173 names_str[i] = member_name;
1177 names_str[i] = name;
1180 names[i] = names_str[i].c_str();
1185 program.GetUniformIndices(static_cast<glw::GLsizei>(size), &names[0], &indices[0]);
1186 program.GetActiveUniformsiv(static_cast<glw::GLsizei>(size), &indices[0], GL_UNIFORM_OFFSET, &offsets[0]);
1188 catch (std::exception& exc)
1190 stream << "Failed to query program for uniforms in block: " << variable.m_descriptor.m_name
1191 << ". Reason: " << exc.what() << "\n";
1196 for (size_t i = 0; i < size; ++i)
1198 Utils::Variable::Descriptor& desc = interface->m_members[i];
1200 if (offsets[i] != (GLint)desc.m_offset)
1202 stream << "Uniform: " << desc.m_name << " - invalid offset: " << offsets[i]
1203 << " expected: " << desc.m_offset << std::endl;
1212 /** Query program resource for given variable and verify that everything is as expected
1214 * @param program Program object
1215 * @param variable Variable object
1216 * @param stream Stream that will be used to log any error
1218 * @return true if verification is positive, false otherwise
1220 bool checkSSB(Program& program, const Utils::Variable& variable, std::stringstream& stream)
1224 if (false == variable.IsBlock())
1226 TCU_FAIL("Not implemented");
1230 Utils::Interface* interface = variable.m_descriptor.m_interface;
1232 size_t size = interface->m_members.size();
1234 for (size_t i = 0; i < size; ++i)
1237 std::string name_str = "";
1240 const std::string& name =
1241 Utils::Variable::GetReference(interface->m_name, interface->m_members[i], Utils::Variable::BASIC, 0);
1243 if (Utils::Variable::INTERFACE == interface->m_members[i].m_type)
1245 const std::string& member_name = Utils::Variable::GetReference(
1246 name, interface->m_members[i].m_interface->m_members[0], Utils::Variable::BASIC, 0);
1248 name_str = member_name;
1257 index = program.GetResourceIndex(name_str, GL_BUFFER_VARIABLE);
1259 program.GetResource(GL_BUFFER_VARIABLE, index, GL_OFFSET, 1, &offset);
1261 catch (std::exception& exc)
1263 stream << "Failed to query program for buffer variable: " << variable.m_descriptor.m_name
1264 << ". Reason: " << exc.what() << "\n";
1269 Utils::Variable::Descriptor& desc = interface->m_members[i];
1271 if (offset != (GLint)desc.m_offset)
1273 stream << "Uniform: " << desc.m_name << " - invalid offset: " << offset
1274 << " expected: " << desc.m_offset << std::endl;
1283 /** Query program resources at given stage and verifies results
1285 * @param program Program object
1286 * @param program_interface Definition of program interface
1287 * @param stage Stage to be verified
1288 * @param check_inputs Select if inputs should be verified
1289 * @param check_outputs Select if output should be verified
1290 * @param check_uniforms Select if uniforms should be verified
1291 * @param check_ssbs Select if buffers should be verified
1292 * @param stream Stream that will be used to log any error
1294 * @return true if verification is positive, false otherwise
1296 bool checkProgramStage(Program& program, const ProgramInterface& program_interface, Utils::Shader::STAGES stage,
1297 bool check_inputs, bool check_outputs, bool check_uniforms, bool check_ssbs,
1298 std::stringstream& stream)
1300 typedef Variable::PtrVector::const_iterator const_iterator;
1302 const ShaderInterface& interface = program_interface.GetShaderInterface(stage);
1307 if (true == check_inputs)
1309 const Variable::PtrVector& inputs = interface.m_inputs;
1311 for (const_iterator it = inputs.begin(); it != inputs.end(); ++it)
1313 if (false == checkVarying(program, **it, stream, true))
1321 if (true == check_outputs)
1323 const Variable::PtrVector& outputs = interface.m_outputs;
1325 for (const_iterator it = outputs.begin(); it != outputs.end(); ++it)
1327 if (false == checkVarying(program, **it, stream, false))
1335 if (true == check_uniforms)
1337 const Variable::PtrVector& uniforms = interface.m_uniforms;
1339 for (const_iterator it = uniforms.begin(); it != uniforms.end(); ++it)
1341 if (false == checkUniform(program, **it, stream))
1349 if (true == check_ssbs)
1351 const Variable::PtrVector& ssbs = interface.m_ssb_blocks;
1353 for (const_iterator it = ssbs.begin(); it != ssbs.end(); ++it)
1355 if (false == checkSSB(program, **it, stream))
1365 /** Query resources of monolithic compute program and verifies results
1367 * @param program Program object
1368 * @param program_interface Definition of program interface
1369 * @param stream Stream that will be used to log any error
1371 * @return true if verification is positive, false otherwise
1373 bool checkMonolithicComputeProgramInterface(Program& program, const ProgramInterface& program_interface,
1374 std::stringstream& stream)
1378 if (false == checkProgramStage(program, program_interface, Shader::COMPUTE, false, false, true, true, stream))
1387 /** Query resources of monolithic draw program and verifies results
1389 * @param program Program object
1390 * @param program_interface Definition of program interface
1391 * @param stream Stream that will be used to log any error
1393 * @return true if verification is positive, false otherwise
1395 bool checkMonolithicDrawProgramInterface(Program& program, const ProgramInterface& program_interface,
1396 std::stringstream& stream)
1400 if (false == checkProgramStage(program, program_interface, Shader::VERTEX, true, false, true, true, stream))
1409 /** Query resources of separable draw program and verifies results
1411 * @param program Program object
1412 * @param program_interface Definition of program interface
1413 * @param stream Stream that will be used to log any error
1415 * @return true if verification is positive, false otherwise
1417 bool checkSeparableDrawProgramInterface(Program& program, const ProgramInterface& program_interface,
1418 Utils::Shader::STAGES stage, std::stringstream& stream)
1422 if (false == checkProgramStage(program, program_interface, stage, true, true, true, true, stream))
1431 /** Check if extension is supported
1433 * @param context Test context
1434 * @param extension_name Name of extension
1436 * @return true if extension is supported, false otherwise
1438 bool isExtensionSupported(deqp::Context& context, const GLchar* extension_name)
1440 const std::vector<std::string>& extensions = context.getContextInfo().getExtensions();
1442 if (std::find(extensions.begin(), extensions.end(), extension_name) == extensions.end())
1450 /** Check if GL context meets version requirements
1452 * @param gl Functions
1453 * @param required_major Minimum required MAJOR_VERSION
1454 * @param required_minor Minimum required MINOR_VERSION
1456 * @return true if GL context version is at least as requested, false otherwise
1458 bool isGLVersionAtLeast(const Functions& gl, GLint required_major, GLint required_minor)
1460 glw::GLint major = 0;
1461 glw::GLint minor = 0;
1463 gl.getIntegerv(GL_MAJOR_VERSION, &major);
1464 gl.getIntegerv(GL_MINOR_VERSION, &minor);
1466 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
1468 if (major > required_major)
1470 /* Major is higher than required one */
1473 else if (major == required_major)
1475 if (minor >= required_minor)
1477 /* Major is equal to required one */
1478 /* Minor is higher than or equal to required one */
1483 /* Major is equal to required one */
1484 /* Minor is lower than required one */
1490 /* Major is lower than required one */
1495 /** Replace first occurance of <token> with <text> in <string> starting at <search_posistion>
1497 * @param token Token string
1498 * @param search_position Position at which find will start, it is updated to position at which replaced text ends
1499 * @param text String that will be used as replacement for <token>
1500 * @param string String to work on
1502 void replaceToken(const GLchar* token, size_t& search_position, const GLchar* text, std::string& string)
1504 const size_t text_length = strlen(text);
1505 const size_t token_length = strlen(token);
1506 const size_t token_position = string.find(token, search_position);
1508 #if DEBUG_REPLACE_TOKEN
1509 if (std::string::npos == token_position)
1511 string.append("\n\nInvalid token: ");
1512 string.append(token);
1514 TCU_FAIL(string.c_str());
1516 #endif /* DEBUG_REPLACE_TOKEN */
1518 string.replace(token_position, token_length, text, text_length);
1520 search_position = token_position + text_length;
1523 /** Replace all occurances of <token> with <text> in <string>
1525 * @param token Token string
1526 * @param text String that will be used as replacement for <token>
1527 * @param string String to work on
1529 void replaceAllTokens(const GLchar* token, const GLchar* text, std::string& string)
1531 const size_t text_length = strlen(text);
1532 const size_t token_length = strlen(token);
1534 size_t search_position = 0;
1538 const size_t token_position = string.find(token, search_position);
1540 if (std::string::npos == token_position)
1545 search_position = token_position + text_length;
1547 string.replace(token_position, token_length, text, text_length);
1551 /** Rounds up the value to the next power of 2.
1552 * This routine does not work for 0, see the url for explanations.
1554 * @param value Starting point
1556 * @return Calculated value
1558 glw::GLuint roundUpToPowerOf2(glw::GLuint value)
1560 /* Taken from: graphics.stanford.edu/~seander/bithacks.html */
1563 value |= value >> 1;
1564 value |= value >> 2;
1565 value |= value >> 4;
1566 value |= value >> 8;
1567 value |= value >> 16;
1574 /** Insert elements of list into string.
1575 * List in string is represented either by token "LIST" or "SEPARATORLIST".
1576 * If SEPARATORLIST is available, than SEPARATOR is replaced with <separator>.
1577 * LIST is replaced with <element>SEPARATORLIST
1579 * @param element Element to be inserted
1580 * @param separator Separator inserted between elements
1581 * @param search_position Position in string, where search for list should start
1582 * @param string String
1584 void insertElementOfList(const GLchar* element, const GLchar* separator, size_t& search_position, std::string& string)
1586 static const char* list = g_list;
1587 static const char* sep_list = "SEPARATORLIST";
1589 /* Try to get "list" positions */
1590 const size_t list_position = string.find(list, search_position);
1591 const size_t sep_list_position = string.find(sep_list, search_position);
1593 /* There is no list in string */
1594 if (std::string::npos == list_position)
1599 if (9 /* strlen(SEPARATOR) */ == list_position - sep_list_position)
1601 replaceToken("SEPARATOR", search_position, separator, string);
1604 /* Save search_position */
1605 const size_t start_position = search_position;
1607 /* Prepare new element */
1608 replaceToken("LIST", search_position, "ELEMENTSEPARATORLIST", string);
1610 /* Restore search_position */
1611 search_position = start_position;
1613 /* Replace element and separator */
1614 replaceToken("ELEMENT", search_position, element, string);
1617 /** Close list in string.
1618 * If SEPARATORLIST is available, than SEPARATOR is replaced with <separator>
1619 * LIST is replaced with ""
1621 * @param separator Separator inserted between elements
1622 * @param search_position Position in string, where search for list should start
1623 * @param string String
1625 void endList(const glw::GLchar* separator, size_t& search_position, std::string& string)
1627 const size_t sep_position = string.find("SEPARATOR", search_position);
1628 if (std::string::npos != sep_position)
1630 replaceToken("SEPARATOR", search_position, separator, string);
1633 replaceToken("LIST", search_position, "", string);
1636 /* Buffer constants */
1637 const GLuint Buffer::m_invalid_id = -1;
1641 * @param context CTS context.
1643 Buffer::Buffer(deqp::Context& context) : m_id(m_invalid_id), m_buffer(Array), m_context(context)
1655 /** Initialize buffer instance
1657 * @param buffer Buffer type
1658 * @param usage Buffer usage enum
1659 * @param size <size> parameter
1660 * @param data <data> parameter
1662 void Buffer::Init(BUFFERS buffer, USAGE usage, GLsizeiptr size, GLvoid* data)
1664 /* Delete previous buffer instance */
1669 const Functions& gl = m_context.getRenderContext().getFunctions();
1672 Bind(gl, m_id, m_buffer);
1673 Data(gl, m_buffer, usage, size, data);
1676 /** Release buffer instance
1679 void Buffer::Release()
1681 if (m_invalid_id != m_id)
1683 const Functions& gl = m_context.getRenderContext().getFunctions();
1685 gl.deleteBuffers(1, &m_id);
1686 m_id = m_invalid_id;
1690 /** Binds buffer to its target
1693 void Buffer::Bind() const
1695 const Functions& gl = m_context.getRenderContext().getFunctions();
1697 Bind(gl, m_id, m_buffer);
1700 /** Binds indexed buffer
1702 * @param index <index> parameter
1704 void Buffer::BindBase(GLuint index) const
1706 const Functions& gl = m_context.getRenderContext().getFunctions();
1708 BindBase(gl, m_id, m_buffer, index);
1711 /** Binds range of buffer
1713 * @param index <index> parameter
1714 * @param offset <offset> parameter
1715 * @param size <size> parameter
1717 void Buffer::BindRange(GLuint index, GLintptr offset, GLsizeiptr size) const
1719 const Functions& gl = m_context.getRenderContext().getFunctions();
1721 BindRange(gl, m_id, m_buffer, index, offset, size);
1724 /** Allocate memory for buffer and sends initial content
1726 * @param usage Buffer usage enum
1727 * @param size <size> parameter
1728 * @param data <data> parameter
1730 void Buffer::Data(USAGE usage, glw::GLsizeiptr size, glw::GLvoid* data)
1732 const Functions& gl = m_context.getRenderContext().getFunctions();
1734 Data(gl, m_buffer, usage, size, data);
1737 /** Maps contents of buffer into CPU space
1739 * @param access Requested access
1741 * @return Pointer to memory region available for CPU
1743 GLvoid* Buffer::Map(ACCESS access)
1745 const Functions& gl = m_context.getRenderContext().getFunctions();
1747 return Map(gl, m_buffer, access);
1750 /** Allocate memory for buffer and sends initial content
1752 * @param offset Offset in buffer
1753 * @param size <size> parameter
1754 * @param data <data> parameter
1756 void Buffer::SubData(glw::GLintptr offset, glw::GLsizeiptr size, glw::GLvoid* data)
1758 const Functions& gl = m_context.getRenderContext().getFunctions();
1760 SubData(gl, m_buffer, offset, size, data);
1763 /** Maps contents of buffer into CPU space
1765 void Buffer::UnMap()
1767 const Functions& gl = m_context.getRenderContext().getFunctions();
1769 return UnMap(gl, m_buffer);
1772 /** Bind buffer to given target
1774 * @param gl GL functions
1775 * @param id Id of buffer
1776 * @param buffer Buffer enum
1778 void Buffer::Bind(const Functions& gl, GLuint id, BUFFERS buffer)
1780 GLenum target = GetBufferGLenum(buffer);
1782 gl.bindBuffer(target, id);
1783 GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffer");
1786 /** Binds indexed buffer
1788 * @param gl GL functions
1789 * @param id Id of buffer
1790 * @param buffer Buffer enum
1791 * @param index <index> parameter
1793 void Buffer::BindBase(const Functions& gl, GLuint id, BUFFERS buffer, GLuint index)
1795 GLenum target = GetBufferGLenum(buffer);
1797 gl.bindBufferBase(target, index, id);
1798 GLU_EXPECT_NO_ERROR(gl.getError(), "BindBufferBase");
1801 /** Binds buffer range
1803 * @param gl GL functions
1804 * @param id Id of buffer
1805 * @param buffer Buffer enum
1806 * @param index <index> parameter
1807 * @param offset <offset> parameter
1808 * @param size <size> parameter
1810 void Buffer::BindRange(const Functions& gl, GLuint id, BUFFERS buffer, GLuint index, GLintptr offset, GLsizeiptr size)
1812 GLenum target = GetBufferGLenum(buffer);
1814 gl.bindBufferRange(target, index, id, offset, size);
1815 GLU_EXPECT_NO_ERROR(gl.getError(), "BindBufferRange");
1818 /** Allocate memory for buffer and sends initial content
1820 * @param gl GL functions
1821 * @param buffer Buffer enum
1822 * @param usage Buffer usage enum
1823 * @param size <size> parameter
1824 * @param data <data> parameter
1826 void Buffer::Data(const glw::Functions& gl, BUFFERS buffer, USAGE usage, glw::GLsizeiptr size, glw::GLvoid* data)
1828 GLenum target = GetBufferGLenum(buffer);
1829 GLenum gl_usage = GetUsageGLenum(usage);
1831 gl.bufferData(target, size, data, gl_usage);
1832 GLU_EXPECT_NO_ERROR(gl.getError(), "BufferData");
1835 /** Allocate memory for buffer and sends initial content
1837 * @param gl GL functions
1838 * @param buffer Buffer enum
1839 * @param offset Offset in buffer
1840 * @param size <size> parameter
1841 * @param data <data> parameter
1843 void Buffer::SubData(const glw::Functions& gl, BUFFERS buffer, glw::GLintptr offset, glw::GLsizeiptr size,
1846 GLenum target = GetBufferGLenum(buffer);
1848 gl.bufferSubData(target, offset, size, data);
1849 GLU_EXPECT_NO_ERROR(gl.getError(), "BufferSubData");
1854 * @param gl GL functions
1855 * @param out_id Id of buffer
1857 void Buffer::Generate(const Functions& gl, GLuint& out_id)
1859 GLuint id = m_invalid_id;
1861 gl.genBuffers(1, &id);
1862 GLU_EXPECT_NO_ERROR(gl.getError(), "GenBuffers");
1864 if (m_invalid_id == id)
1866 TCU_FAIL("Got invalid id");
1872 /** Maps buffer content
1874 * @param gl GL functions
1875 * @param buffer Buffer enum
1876 * @param access Access rights for mapped region
1878 * @return Mapped memory
1880 void* Buffer::Map(const Functions& gl, BUFFERS buffer, ACCESS access)
1882 GLenum target = GetBufferGLenum(buffer);
1883 GLenum gl_access = GetAccessGLenum(access);
1885 void* result = gl.mapBuffer(target, gl_access);
1886 GLU_EXPECT_NO_ERROR(gl.getError(), "MapBuffer");
1894 void Buffer::UnMap(const Functions& gl, BUFFERS buffer)
1896 GLenum target = GetBufferGLenum(buffer);
1898 gl.unmapBuffer(target);
1899 GLU_EXPECT_NO_ERROR(gl.getError(), "UnmapBuffer");
1902 /** Return GLenum representation of requested access
1904 * @param access Requested access
1906 * @return GLenum value
1908 GLenum Buffer::GetAccessGLenum(ACCESS access)
1915 result = GL_READ_ONLY;
1918 result = GL_WRITE_ONLY;
1921 result = GL_READ_WRITE;
1924 TCU_FAIL("Invalid enum");
1930 /** Return GLenum representation of requested buffer type
1932 * @param buffer Requested buffer type
1934 * @return GLenum value
1936 GLenum Buffer::GetBufferGLenum(BUFFERS buffer)
1943 result = GL_ARRAY_BUFFER;
1946 result = GL_ELEMENT_ARRAY_BUFFER;
1948 case Shader_Storage:
1949 result = GL_SHADER_STORAGE_BUFFER;
1952 result = GL_TEXTURE_BUFFER;
1954 case Transform_feedback:
1955 result = GL_TRANSFORM_FEEDBACK_BUFFER;
1958 result = GL_UNIFORM_BUFFER;
1961 TCU_FAIL("Invalid enum");
1967 /** Return GLenum representation of requested usage
1969 * @param usage Requested usage
1971 * @return GLenum value
1973 GLenum Buffer::GetUsageGLenum(USAGE usage)
1980 result = GL_DYNAMIC_COPY;
1983 result = GL_DYNAMIC_DRAW;
1986 result = GL_DYNAMIC_READ;
1989 result = GL_STATIC_COPY;
1992 result = GL_STATIC_DRAW;
1995 result = GL_STATIC_READ;
1998 result = GL_STREAM_COPY;
2001 result = GL_STREAM_DRAW;
2004 result = GL_STREAM_READ;
2007 TCU_FAIL("Invalid enum");
2013 /** Returns name of buffer target
2015 * @param buffer Target enum
2017 * @return Name of target
2019 const GLchar* Buffer::GetBufferName(BUFFERS buffer)
2021 const GLchar* name = 0;
2031 case Shader_Storage:
2032 name = "Shader_Storage";
2037 case Transform_feedback:
2038 name = "Transform_feedback";
2044 TCU_FAIL("Invalid enum");
2050 /* Framebuffer constants */
2051 const GLuint Framebuffer::m_invalid_id = -1;
2055 * @param context CTS context
2057 Framebuffer::Framebuffer(deqp::Context& context) : m_id(m_invalid_id), m_context(context)
2059 /* Nothing to be done here */
2065 Framebuffer::~Framebuffer()
2070 /** Initialize framebuffer instance
2073 void Framebuffer::Init()
2075 /* Delete previous instance */
2078 const Functions& gl = m_context.getRenderContext().getFunctions();
2083 /** Release framebuffer instance
2086 void Framebuffer::Release()
2088 if (m_invalid_id != m_id)
2090 const Functions& gl = m_context.getRenderContext().getFunctions();
2092 gl.deleteFramebuffers(1, &m_id);
2093 m_id = m_invalid_id;
2097 /** Attach texture to specified attachment
2099 * @param attachment Attachment
2100 * @param texture_id Texture id
2101 * @param width Texture width
2102 * @param height Texture height
2104 void Framebuffer::AttachTexture(GLenum attachment, GLuint texture_id, GLuint width, GLuint height)
2106 const Functions& gl = m_context.getRenderContext().getFunctions();
2108 AttachTexture(gl, attachment, texture_id, width, height);
2111 /** Binds framebuffer to DRAW_FRAMEBUFFER
2114 void Framebuffer::Bind()
2116 const Functions& gl = m_context.getRenderContext().getFunctions();
2121 /** Clear framebuffer
2123 * @param mask <mask> parameter of glClear. Decides which shall be cleared
2125 void Framebuffer::Clear(GLenum mask)
2127 const Functions& gl = m_context.getRenderContext().getFunctions();
2132 /** Specifies clear color
2134 * @param red Red channel
2135 * @param green Green channel
2136 * @param blue Blue channel
2137 * @param alpha Alpha channel
2139 void Framebuffer::ClearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
2141 const Functions& gl = m_context.getRenderContext().getFunctions();
2143 ClearColor(gl, red, green, blue, alpha);
2146 /** Attach texture to specified attachment
2148 * @param gl GL functions
2149 * @param attachment Attachment
2150 * @param texture_id Texture id
2151 * @param width Texture width
2152 * @param height Texture height
2154 void Framebuffer::AttachTexture(const Functions& gl, GLenum attachment, GLuint texture_id, GLuint width, GLuint height)
2156 gl.framebufferTexture(GL_DRAW_FRAMEBUFFER, attachment, texture_id, 0 /* level */);
2157 GLU_EXPECT_NO_ERROR(gl.getError(), "FramebufferTexture");
2159 gl.viewport(0 /* x */, 0 /* y */, width, height);
2160 GLU_EXPECT_NO_ERROR(gl.getError(), "Viewport");
2163 /** Binds framebuffer to DRAW_FRAMEBUFFER
2165 * @param gl GL functions
2166 * @param id ID of framebuffer
2168 void Framebuffer::Bind(const Functions& gl, GLuint id)
2170 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, id);
2171 GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer");
2174 /** Clear framebuffer
2176 * @param gl GL functions
2177 * @param mask <mask> parameter of glClear. Decides which shall be cleared
2179 void Framebuffer::Clear(const Functions& gl, GLenum mask)
2182 GLU_EXPECT_NO_ERROR(gl.getError(), "Clear");
2185 /** Specifies clear color
2187 * @param gl GL functions
2188 * @param red Red channel
2189 * @param green Green channel
2190 * @param blue Blue channel
2191 * @param alpha Alpha channel
2193 void Framebuffer::ClearColor(const Functions& gl, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
2195 gl.clearColor(red, green, blue, alpha);
2196 GLU_EXPECT_NO_ERROR(gl.getError(), "ClearColor");
2199 /** Generate framebuffer
2202 void Framebuffer::Generate(const Functions& gl, GLuint& out_id)
2204 GLuint id = m_invalid_id;
2206 gl.genFramebuffers(1, &id);
2207 GLU_EXPECT_NO_ERROR(gl.getError(), "GenFramebuffers");
2209 if (m_invalid_id == id)
2211 TCU_FAIL("Invalid id");
2217 /* Shader's constants */
2218 const GLuint Shader::m_invalid_id = 0;
2222 * @param context CTS context.
2224 Shader::Shader(deqp::Context& context) : m_id(m_invalid_id), m_context(context)
2226 /* Nothing to be done here */
2237 /** Initialize shader instance
2239 * @param stage Shader stage
2240 * @param source Source code
2242 void Shader::Init(STAGES stage, const std::string& source)
2244 if (true == source.empty())
2246 /* No source == no shader */
2250 /* Delete any previous shader */
2253 /* Create, set source and compile */
2254 const Functions& gl = m_context.getRenderContext().getFunctions();
2256 Create(gl, stage, m_id);
2257 Source(gl, m_id, source);
2263 catch (const CompilationException& exc)
2265 throw InvalidSourceException(exc.what(), source, stage);
2269 /** Release shader instance
2272 void Shader::Release()
2274 if (m_invalid_id != m_id)
2276 const Functions& gl = m_context.getRenderContext().getFunctions();
2278 gl.deleteShader(m_id);
2279 m_id = m_invalid_id;
2285 * @param gl GL functions
2286 * @param id Shader id
2288 void Shader::Compile(const Functions& gl, GLuint id)
2290 GLint status = GL_FALSE;
2293 gl.compileShader(id);
2294 GLU_EXPECT_NO_ERROR(gl.getError(), "CompileShader");
2296 /* Get compilation status */
2297 gl.getShaderiv(id, GL_COMPILE_STATUS, &status);
2298 GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");
2300 /* Log compilation error */
2301 if (GL_TRUE != status)
2303 glw::GLint length = 0;
2304 std::string message;
2306 /* Error log length */
2307 gl.getShaderiv(id, GL_INFO_LOG_LENGTH, &length);
2308 GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");
2310 /* Prepare storage */
2311 message.resize(length, 0);
2314 gl.getShaderInfoLog(id, length, 0, &message[0]);
2315 GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderInfoLog");
2317 throw CompilationException(message.c_str());
2323 * @param gl GL functions
2324 * @param stage Shader stage
2325 * @param out_id Shader id
2327 void Shader::Create(const Functions& gl, STAGES stage, GLuint& out_id)
2329 const GLenum shaderType = GetShaderStageGLenum(stage);
2330 const GLuint id = gl.createShader(shaderType);
2331 GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
2333 if (m_invalid_id == id)
2335 TCU_FAIL("Failed to create shader");
2341 /** Set shader's source code
2343 * @param gl GL functions
2344 * @param id Shader id
2345 * @param source Shader source code
2347 void Shader::Source(const Functions& gl, GLuint id, const std::string& source)
2349 const GLchar* code = source.c_str();
2351 gl.shaderSource(id, 1 /* count */, &code, 0 /* lengths */);
2352 GLU_EXPECT_NO_ERROR(gl.getError(), "ShaderSource");
2355 /** Get GLenum repesenting shader stage
2357 * @param stage Shader stage
2361 GLenum Shader::GetShaderStageGLenum(STAGES stage)
2368 result = GL_COMPUTE_SHADER;
2371 result = GL_FRAGMENT_SHADER;
2374 result = GL_GEOMETRY_SHADER;
2377 result = GL_TESS_CONTROL_SHADER;
2380 result = GL_TESS_EVALUATION_SHADER;
2383 result = GL_VERTEX_SHADER;
2386 TCU_FAIL("Invalid enum");
2392 /** Get string representing name of shader stage
2394 * @param stage Shader stage
2396 * @return String with name of shader stage
2398 const glw::GLchar* Shader::GetStageName(STAGES stage)
2400 const GLchar* result = 0;
2411 result = "tessellation control";
2414 result = "tessellation evaluation";
2417 result = "geometry";
2420 result = "fragment";
2423 TCU_FAIL("Invalid enum");
2429 /** Logs shader source
2431 * @param context CTS context
2432 * @param source Source of shader
2433 * @param stage Shader stage
2435 void Shader::LogSource(deqp::Context& context, const std::string& source, STAGES stage)
2437 /* Skip empty shaders */
2438 if (true == source.empty())
2443 context.getTestContext().getLog() << tcu::TestLog::Message
2444 << "Shader source. Stage: " << Shader::GetStageName(stage)
2445 << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(source);
2450 * @param message Compilation error message
2452 Shader::CompilationException::CompilationException(const GLchar* message)
2454 m_message = message;
2457 /** Returns error messages
2459 * @return Compilation error message
2461 const char* Shader::CompilationException::what() const throw()
2463 return m_message.c_str();
2468 * @param message Compilation error message
2470 Shader::InvalidSourceException::InvalidSourceException(const GLchar* error_message, const std::string& source,
2472 : m_message(error_message), m_source(source), m_stage(stage)
2476 /** Returns error messages
2478 * @return Compilation error message
2480 const char* Shader::InvalidSourceException::what() const throw()
2482 return "Compilation error";
2485 /** Logs error message and shader sources **/
2486 void Shader::InvalidSourceException::log(deqp::Context& context) const
2488 context.getTestContext().getLog() << tcu::TestLog::Message << "Failed to compile shader: " << m_message.c_str()
2489 << tcu::TestLog::EndMessage;
2491 LogSource(context, m_source, m_stage);
2494 /* Program constants */
2495 const GLuint Pipeline::m_invalid_id = 0;
2499 * @param context CTS context.
2501 Pipeline::Pipeline(deqp::Context& context) : m_id(m_invalid_id), m_context(context)
2503 /* Nothing to be done here */
2509 Pipeline::~Pipeline()
2514 /** Initialize pipline object
2517 void Pipeline::Init()
2521 const Functions& gl = m_context.getRenderContext().getFunctions();
2524 gl.genProgramPipelines(1, &m_id);
2525 GLU_EXPECT_NO_ERROR(gl.getError(), "GenProgramPipelines");
2528 /** Release pipeline object
2531 void Pipeline::Release()
2533 if (m_invalid_id != m_id)
2535 const Functions& gl = m_context.getRenderContext().getFunctions();
2538 gl.deleteProgramPipelines(1, &m_id);
2539 GLU_EXPECT_NO_ERROR(gl.getError(), "DeleteProgramPipelines");
2541 m_id = m_invalid_id;
2548 void Pipeline::Bind()
2550 const Functions& gl = m_context.getRenderContext().getFunctions();
2555 /** Set which stages should be active
2557 * @param program_id Id of program
2558 * @param stages Logical combination of enums representing stages
2560 void Pipeline::UseProgramStages(GLuint program_id, GLenum stages)
2562 const Functions& gl = m_context.getRenderContext().getFunctions();
2564 UseProgramStages(gl, m_id, program_id, stages);
2569 * @param gl Functiions
2570 * @param id Pipeline id
2572 void Pipeline::Bind(const Functions& gl, GLuint id)
2574 gl.bindProgramPipeline(id);
2575 GLU_EXPECT_NO_ERROR(gl.getError(), "BindProgramPipeline");
2578 /** Set which stages should be active
2580 * @param gl Functiions
2581 * @param id Pipeline id
2582 * @param program_id Id of program
2583 * @param stages Logical combination of enums representing stages
2585 void Pipeline::UseProgramStages(const Functions& gl, GLuint id, GLuint program_id, GLenum stages)
2587 gl.useProgramStages(id, stages, program_id);
2588 GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgramStages");
2591 /* Program constants */
2592 const GLuint Program::m_invalid_id = 0;
2596 * @param context CTS context.
2598 Program::Program(deqp::Context& context)
2599 : m_id(m_invalid_id)
2600 , m_compute(context)
2601 , m_fragment(context)
2602 , m_geometry(context)
2603 , m_tess_ctrl(context)
2604 , m_tess_eval(context)
2606 , m_context(context)
2608 /* Nothing to be done here */
2619 /** Initialize program instance
2621 * @param compute_shader Compute shader source code
2622 * @param fragment_shader Fragment shader source code
2623 * @param geometry_shader Geometry shader source code
2624 * @param tessellation_control_shader Tessellation control shader source code
2625 * @param tessellation_evaluation_shader Tessellation evaluation shader source code
2626 * @param vertex_shader Vertex shader source code
2627 * @param captured_varyings Vector of variables to be captured with transfrom feedback
2628 * @param capture_interleaved Select mode of transform feedback (separate or interleaved)
2629 * @param is_separable Selects if monolithic or separable program should be built. Defaults to false
2631 void Program::Init(const std::string& compute_shader, const std::string& fragment_shader,
2632 const std::string& geometry_shader, const std::string& tessellation_control_shader,
2633 const std::string& tessellation_evaluation_shader, const std::string& vertex_shader,
2634 const NameVector& captured_varyings, bool capture_interleaved, bool is_separable)
2636 /* Delete previous program */
2639 /* GL entry points */
2640 const Functions& gl = m_context.getRenderContext().getFunctions();
2642 /* Initialize shaders */
2643 m_compute.Init(Shader::COMPUTE, compute_shader);
2644 m_fragment.Init(Shader::FRAGMENT, fragment_shader);
2645 m_geometry.Init(Shader::GEOMETRY, geometry_shader);
2646 m_tess_ctrl.Init(Shader::TESS_CTRL, tessellation_control_shader);
2647 m_tess_eval.Init(Shader::TESS_EVAL, tessellation_evaluation_shader);
2648 m_vertex.Init(Shader::VERTEX, vertex_shader);
2650 /* Create program, set up transform feedback and attach shaders */
2652 Capture(gl, m_id, captured_varyings, capture_interleaved);
2653 Attach(gl, m_id, m_compute.m_id);
2654 Attach(gl, m_id, m_fragment.m_id);
2655 Attach(gl, m_id, m_geometry.m_id);
2656 Attach(gl, m_id, m_tess_ctrl.m_id);
2657 Attach(gl, m_id, m_tess_eval.m_id);
2658 Attach(gl, m_id, m_vertex.m_id);
2660 /* Set separable parameter */
2661 if (true == is_separable)
2663 gl.programParameteri(m_id, GL_PROGRAM_SEPARABLE, GL_TRUE);
2664 GLU_EXPECT_NO_ERROR(gl.getError(), "ProgramParameteri");
2672 catch (const LinkageException& exc)
2674 throw BuildException(exc.what(), compute_shader, fragment_shader, geometry_shader, tessellation_control_shader,
2675 tessellation_evaluation_shader, vertex_shader);
2679 /** Initialize program instance
2681 * @param compute_shader Compute shader source code
2682 * @param fragment_shader Fragment shader source code
2683 * @param geometry_shader Geometry shader source code
2684 * @param tessellation_control_shader Tessellation control shader source code
2685 * @param tessellation_evaluation_shader Tessellation evaluation shader source code
2686 * @param vertex_shader Vertex shader source code
2687 * @param is_separable Selects if monolithic or separable program should be built. Defaults to false
2689 void Program::Init(const std::string& compute_shader, const std::string& fragment_shader,
2690 const std::string& geometry_shader, const std::string& tessellation_control_shader,
2691 const std::string& tessellation_evaluation_shader, const std::string& vertex_shader,
2694 NameVector captured_varying;
2696 Init(compute_shader, fragment_shader, geometry_shader, tessellation_control_shader, tessellation_evaluation_shader,
2697 vertex_shader, captured_varying, true, is_separable);
2700 /** Release program instance
2703 void Program::Release()
2705 const Functions& gl = m_context.getRenderContext().getFunctions();
2707 if (m_invalid_id != m_id)
2709 Use(gl, m_invalid_id);
2711 gl.deleteProgram(m_id);
2712 m_id = m_invalid_id;
2715 m_compute.Release();
2716 m_fragment.Release();
2717 m_geometry.Release();
2718 m_tess_ctrl.Release();
2719 m_tess_eval.Release();
2723 /** Get <pname> for a set of active uniforms
2725 * @param count Number of indices
2726 * @param indices Indices of uniforms
2727 * @param pname Queired pname
2728 * @param params Array that will be filled with values of parameters
2730 void Program::GetActiveUniformsiv(GLsizei count, const GLuint* indices, GLenum pname, GLint* params) const
2732 const Functions& gl = m_context.getRenderContext().getFunctions();
2734 GetActiveUniformsiv(gl, m_id, count, indices, pname, params);
2737 /** Get location of attribute
2739 * @param name Name of attribute
2741 * @return Result of query
2743 glw::GLint Program::GetAttribLocation(const std::string& name) const
2745 const Functions& gl = m_context.getRenderContext().getFunctions();
2747 return GetAttribLocation(gl, m_id, name);
2752 * @param interface Interface to be queried
2753 * @param index Index of resource
2754 * @param property Property to be queried
2755 * @param buf_size Size of <params> buffer
2756 * @param params Results of query
2758 void Program::GetResource(GLenum interface, GLuint index, GLenum property, GLsizei buf_size, GLint* params) const
2760 const Functions& gl = m_context.getRenderContext().getFunctions();
2762 GetResource(gl, m_id, interface, index, property, buf_size, params);
2765 /** Query for index of resource
2767 * @param name Name of resource
2768 * @param interface Interface to be queried
2770 * @return Result of query
2772 glw::GLuint Program::GetResourceIndex(const std::string& name, GLenum interface) const
2774 const Functions& gl = m_context.getRenderContext().getFunctions();
2776 return GetResourceIndex(gl, m_id, name, interface);
2779 /** Get indices for a set of uniforms
2781 * @param count Count number of uniforms
2782 * @param names Names of uniforms
2783 * @param indices Buffer that will be filled with indices
2785 void Program::GetUniformIndices(GLsizei count, const GLchar** names, GLuint* indices) const
2787 const Functions& gl = m_context.getRenderContext().getFunctions();
2789 GetUniformIndices(gl, m_id, count, names, indices);
2792 /** Get uniform location
2794 * @param name Name of uniform
2796 * @return Results of query
2798 glw::GLint Program::GetUniformLocation(const std::string& name) const
2800 const Functions& gl = m_context.getRenderContext().getFunctions();
2802 return GetUniformLocation(gl, m_id, name);
2805 /** Set program as active
2808 void Program::Use() const
2810 const Functions& gl = m_context.getRenderContext().getFunctions();
2815 /** Attach shader to program
2817 * @param gl GL functions
2818 * @param program_id Id of program
2819 * @param shader_id Id of shader
2821 void Program::Attach(const Functions& gl, GLuint program_id, GLuint shader_id)
2824 if ((m_invalid_id == program_id) || (Shader::m_invalid_id == shader_id))
2829 gl.attachShader(program_id, shader_id);
2830 GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
2833 /** Set up captured varyings
2835 * @param gl GL functions
2836 * @param id Id of program
2837 * @param captured_varyings Vector of varyings
2838 * @param capture_interleaved Selects if interleaved or separate mode should be used
2840 void Program::Capture(const Functions& gl, GLuint id, const NameVector& captured_varyings, bool capture_interleaved)
2842 const size_t n_varyings = captured_varyings.size();
2844 if (0 == n_varyings)
2846 /* empty list, skip */
2850 std::vector<const GLchar*> varying_names;
2851 varying_names.resize(n_varyings);
2853 for (size_t i = 0; i < n_varyings; ++i)
2855 varying_names[i] = captured_varyings[i].c_str();
2859 if (true == capture_interleaved)
2861 mode = GL_INTERLEAVED_ATTRIBS;
2865 mode = GL_SEPARATE_ATTRIBS;
2868 gl.transformFeedbackVaryings(id, static_cast<GLsizei>(n_varyings), &varying_names[0], mode);
2869 GLU_EXPECT_NO_ERROR(gl.getError(), "TransformFeedbackVaryings");
2872 /** Create program instance
2874 * @param gl GL functions
2875 * @param out_id Id of program
2877 void Program::Create(const Functions& gl, GLuint& out_id)
2879 const GLuint id = gl.createProgram();
2880 GLU_EXPECT_NO_ERROR(gl.getError(), "CreateProgram");
2882 if (m_invalid_id == id)
2884 TCU_FAIL("Failed to create program");
2890 /** Get <pname> for a set of active uniforms
2892 * @param gl Functions
2893 * @param program_id Id of program
2894 * @param count Number of indices
2895 * @param indices Indices of uniforms
2896 * @param pname Queired pname
2897 * @param params Array that will be filled with values of parameters
2899 void Program::GetActiveUniformsiv(const Functions& gl, GLuint program_id, GLsizei count, const GLuint* indices,
2900 GLenum pname, GLint* params)
2902 gl.getActiveUniformsiv(program_id, count, indices, pname, params);
2903 GLU_EXPECT_NO_ERROR(gl.getError(), "GetActiveUniformsiv");
2906 /** Get indices for a set of uniforms
2908 * @param gl Functions
2909 * @param program_id Id of program
2910 * @param count Count number of uniforms
2911 * @param names Names of uniforms
2912 * @param indices Buffer that will be filled with indices
2914 void Program::GetUniformIndices(const Functions& gl, GLuint program_id, GLsizei count, const GLchar** names,
2917 gl.getUniformIndices(program_id, count, names, indices);
2918 GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformIndices");
2923 * @param gl GL functions
2924 * @param id Id of program
2926 void Program::Link(const Functions& gl, GLuint id)
2928 GLint status = GL_FALSE;
2931 GLU_EXPECT_NO_ERROR(gl.getError(), "LinkProgram");
2933 /* Get link status */
2934 gl.getProgramiv(id, GL_LINK_STATUS, &status);
2935 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");
2937 /* Log link error */
2938 if (GL_TRUE != status)
2940 glw::GLint length = 0;
2941 std::string message;
2943 /* Get error log length */
2944 gl.getProgramiv(id, GL_INFO_LOG_LENGTH, &length);
2945 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");
2947 message.resize(length, 0);
2950 gl.getProgramInfoLog(id, length, 0, &message[0]);
2951 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramInfoLog");
2953 throw LinkageException(message.c_str());
2957 /** Set generic uniform
2959 * @param gl Functions
2960 * @param type Type of uniform
2961 * @param count Length of array
2962 * @param location Location of uniform
2963 * @param data Data that will be used
2965 void Program::Uniform(const Functions& gl, const Type& type, GLsizei count, GLint location, const GLvoid* data)
2969 TCU_FAIL("Uniform is inactive");
2972 switch (type.m_basic_type)
2975 if (1 == type.m_n_columns)
2977 getUniformNdv(gl, type.m_n_rows)(location, count, (const GLdouble*)data);
2978 GLU_EXPECT_NO_ERROR(gl.getError(), "UniformNdv");
2982 getUniformMatrixNdv(gl, type.m_n_columns, type.m_n_rows)(location, count, false, (const GLdouble*)data);
2983 GLU_EXPECT_NO_ERROR(gl.getError(), "UniformMatrixNdv");
2987 if (1 == type.m_n_columns)
2989 getUniformNfv(gl, type.m_n_rows)(location, count, (const GLfloat*)data);
2990 GLU_EXPECT_NO_ERROR(gl.getError(), "UniformNfv");
2994 getUniformMatrixNfv(gl, type.m_n_columns, type.m_n_rows)(location, count, false, (const GLfloat*)data);
2995 GLU_EXPECT_NO_ERROR(gl.getError(), "UniformMatrixNfv");
2999 getUniformNiv(gl, type.m_n_rows)(location, count, (const GLint*)data);
3000 GLU_EXPECT_NO_ERROR(gl.getError(), "UniformNiv");
3003 getUniformNuiv(gl, type.m_n_rows)(location, count, (const GLuint*)data);
3004 GLU_EXPECT_NO_ERROR(gl.getError(), "UniformNuiv");
3007 TCU_FAIL("Invalid enum");
3013 * @param gl GL functions
3014 * @param id Id of program
3016 void Program::Use(const Functions& gl, GLuint id)
3019 GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram");
3022 /** Get location of attribute
3024 * @param gl GL functions
3025 * @param id Id of program
3026 * @param name Name of attribute
3028 * @return Location of attribute
3030 GLint Program::GetAttribLocation(const Functions& gl, GLuint id, const std::string& name)
3032 GLint location = gl.getAttribLocation(id, name.c_str());
3033 GLU_EXPECT_NO_ERROR(gl.getError(), "GetAttribLocation");
3040 * @param gl GL functions
3041 * @param id Id of program
3042 * @param interface Interface to be queried
3043 * @param index Index of resource
3044 * @param property Property to be queried
3045 * @param buf_size Size of <params> buffer
3046 * @param params Results of query
3048 void Program::GetResource(const Functions& gl, GLuint id, GLenum interface, GLuint index, GLenum property,
3049 GLsizei buf_size, GLint* params)
3051 gl.getProgramResourceiv(id, interface, index, 1 /* propCount */, &property, buf_size /* bufSize */, 0 /* length */,
3053 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramResourceiv");
3056 /** Get index of resource
3058 * @param gl GL functions
3059 * @param id Id of program
3060 * @param name Name of resource
3061 * @param interface Program interface to queried
3063 * @return Location of attribute
3065 GLuint Program::GetResourceIndex(const Functions& gl, GLuint id, const std::string& name, GLenum interface)
3067 GLuint index = gl.getProgramResourceIndex(id, interface, name.c_str());
3068 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramResourceIndex");
3073 /** Get location of attribute
3075 * @param gl GL functions
3076 * @param id Id of program
3077 * @param name Name of attribute
3079 * @return Location of uniform
3081 GLint Program::GetUniformLocation(const Functions& gl, GLuint id, const std::string& name)
3083 GLint location = gl.getUniformLocation(id, name.c_str());
3084 GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformLocation");
3091 * @param error_message Error message
3092 * @param compute_shader Source code for compute stage
3093 * @param fragment_shader Source code for fragment stage
3094 * @param geometry_shader Source code for geometry stage
3095 * @param tess_ctrl_shader Source code for tessellation control stage
3096 * @param tess_eval_shader Source code for tessellation evaluation stage
3097 * @param vertex_shader Source code for vertex stage
3099 Program::BuildException::BuildException(const glw::GLchar* error_message, const std::string compute_shader,
3100 const std::string fragment_shader, const std::string geometry_shader,
3101 const std::string tess_ctrl_shader, const std::string tess_eval_shader,
3102 const std::string vertex_shader)
3103 : m_error_message(error_message)
3104 , m_compute_shader(compute_shader)
3105 , m_fragment_shader(fragment_shader)
3106 , m_geometry_shader(geometry_shader)
3107 , m_tess_ctrl_shader(tess_ctrl_shader)
3108 , m_tess_eval_shader(tess_eval_shader)
3109 , m_vertex_shader(vertex_shader)
3113 /** Overwrites std::exception::what method
3115 * @return Message compossed from error message and shader sources
3117 const char* Program::BuildException::what() const throw()
3119 return "Failed to link program";
3122 /** Logs error message and shader sources **/
3123 void Program::BuildException::log(deqp::Context& context) const
3125 context.getTestContext().getLog() << tcu::TestLog::Message << "Link failure: " << m_error_message
3126 << tcu::TestLog::EndMessage;
3128 Shader::LogSource(context, m_vertex_shader, Shader::VERTEX);
3129 Shader::LogSource(context, m_tess_ctrl_shader, Shader::TESS_CTRL);
3130 Shader::LogSource(context, m_tess_eval_shader, Shader::TESS_EVAL);
3131 Shader::LogSource(context, m_geometry_shader, Shader::GEOMETRY);
3132 Shader::LogSource(context, m_fragment_shader, Shader::FRAGMENT);
3133 Shader::LogSource(context, m_compute_shader, Shader::COMPUTE);
3138 * @param message Linking error message
3140 Program::LinkageException::LinkageException(const glw::GLchar* message) : m_error_message(message)
3142 /* Nothing to be done */
3145 /** Returns error messages
3147 * @return Linking error message
3149 const char* Program::LinkageException::what() const throw()
3151 return m_error_message.c_str();
3154 /* Texture constants */
3155 const GLuint Texture::m_invalid_id = -1;
3159 * @param context CTS context.
3161 Texture::Texture(deqp::Context& context) : m_id(m_invalid_id), m_context(context), m_type(TEX_2D)
3163 /* Nothing to done here */
3174 /** Initialize texture instance
3176 * @param tex_type Type of texture
3177 * @param width Width of texture
3178 * @param height Height of texture
3179 * @param depth Depth of texture
3180 * @param internal_format Internal format of texture
3181 * @param format Format of texture data
3182 * @param type Type of texture data
3183 * @param data Texture data
3185 void Texture::Init(TYPES tex_type, GLuint width, GLuint height, GLuint depth, GLenum internal_format, GLenum format,
3186 GLenum type, GLvoid* data)
3188 const Functions& gl = m_context.getRenderContext().getFunctions();
3190 /* Delete previous texture */
3195 /* Generate, bind, allocate storage and upload data */
3197 Bind(gl, m_id, tex_type);
3198 Storage(gl, tex_type, width, height, depth, internal_format);
3199 Update(gl, tex_type, width, height, depth, format, type, data);
3202 /** Initialize buffer texture
3204 * @param internal_format Internal format of texture
3205 * @param buffer_id Id of buffer that will be used as data source
3207 void Texture::Init(GLenum internal_format, GLuint buffer_id)
3209 const Functions& gl = m_context.getRenderContext().getFunctions();
3211 /* Delete previous texture */
3214 m_type = TEX_BUFFER;
3216 /* Generate, bind and attach buffer */
3218 Bind(gl, m_id, TEX_BUFFER);
3219 TexBuffer(gl, buffer_id, internal_format);
3222 /** Release texture instance
3225 void Texture::Release()
3227 if (m_invalid_id != m_id)
3229 const Functions& gl = m_context.getRenderContext().getFunctions();
3231 gl.deleteTextures(1, &m_id);
3232 m_id = m_invalid_id;
3236 /** Bind texture to its target
3239 void Texture::Bind() const
3241 const Functions& gl = m_context.getRenderContext().getFunctions();
3243 Bind(gl, m_id, m_type);
3246 /** Get texture data
3248 * @param format Format of data
3249 * @param type Type of data
3250 * @param out_data Buffer for data
3252 void Texture::Get(GLenum format, GLenum type, GLvoid* out_data) const
3254 const Functions& gl = m_context.getRenderContext().getFunctions();
3256 Bind(gl, m_id, m_type);
3257 Get(gl, m_type, format, type, out_data);
3260 /** Bind texture to target
3262 * @param gl GL functions
3263 * @param id Id of texture
3264 * @param tex_type Type of texture
3266 void Texture::Bind(const Functions& gl, GLuint id, TYPES tex_type)
3268 GLenum target = GetTargetGLenum(tex_type);
3270 gl.bindTexture(target, id);
3271 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
3274 /** Generate texture instance
3276 * @param gl GL functions
3277 * @param out_id Id of texture
3279 void Texture::Generate(const Functions& gl, GLuint& out_id)
3281 GLuint id = m_invalid_id;
3283 gl.genTextures(1, &id);
3284 GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures");
3286 if (m_invalid_id == id)
3288 TCU_FAIL("Invalid id");
3294 /** Get texture data
3296 * @param gl GL functions
3297 * @param format Format of data
3298 * @param type Type of data
3299 * @param out_data Buffer for data
3301 void Texture::Get(const Functions& gl, TYPES tex_type, GLenum format, GLenum type, GLvoid* out_data)
3303 GLenum target = GetTargetGLenum(tex_type);
3305 if (TEX_CUBE != tex_type)
3307 gl.getTexImage(target, 0 /* level */, format, type, out_data);
3308 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexImage");
3315 if ((GL_RGBA != format) && (GL_UNSIGNED_BYTE != type))
3317 TCU_FAIL("Not implemented");
3320 GLuint texel_size = 4;
3322 gl.getTexLevelParameteriv(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0 /* level */, GL_TEXTURE_WIDTH, &width);
3323 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv");
3325 gl.getTexLevelParameteriv(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0 /* level */, GL_TEXTURE_HEIGHT, &height);
3326 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv");
3328 const GLuint image_size = width * height * texel_size;
3330 gl.getTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0 /* level */, format, type,
3331 (GLvoid*)((GLchar*)out_data + (image_size * 0)));
3332 gl.getTexImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0 /* level */, format, type,
3333 (GLvoid*)((GLchar*)out_data + (image_size * 1)));
3334 gl.getTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0 /* level */, format, type,
3335 (GLvoid*)((GLchar*)out_data + (image_size * 2)));
3336 gl.getTexImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0 /* level */, format, type,
3337 (GLvoid*)((GLchar*)out_data + (image_size * 3)));
3338 gl.getTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0 /* level */, format, type,
3339 (GLvoid*)((GLchar*)out_data + (image_size * 4)));
3340 gl.getTexImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0 /* level */, format, type,
3341 (GLvoid*)((GLchar*)out_data + (image_size * 5)));
3342 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexImage");
3346 /** Allocate storage for texture
3348 * @param gl GL functions
3349 * @param tex_type Type of texture
3350 * @param width Width of texture
3351 * @param height Height of texture
3352 * @param depth Depth of texture
3353 * @param internal_format Internal format of texture
3355 void Texture::Storage(const Functions& gl, TYPES tex_type, GLuint width, GLuint height, GLuint depth,
3356 GLenum internal_format)
3358 static const GLuint levels = 1;
3360 GLenum target = GetTargetGLenum(tex_type);
3365 gl.texStorage1D(target, levels, internal_format, width);
3366 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage1D");
3372 gl.texStorage2D(target, levels, internal_format, width, height);
3373 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2D");
3377 gl.texStorage3D(target, levels, internal_format, width, height, depth);
3378 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage3D");
3381 TCU_FAIL("Invliad enum");
3386 /** Attach buffer as source of texture buffer data
3388 * @param gl GL functions
3389 * @param internal_format Internal format of texture
3390 * @param buffer_id Id of buffer that will be used as data source
3392 void Texture::TexBuffer(const Functions& gl, GLenum internal_format, GLuint& buffer_id)
3394 gl.texBuffer(GL_TEXTURE_BUFFER, internal_format, buffer_id);
3395 GLU_EXPECT_NO_ERROR(gl.getError(), "TexBuffer");
3398 /** Update contents of texture
3400 * @param gl GL functions
3401 * @param tex_type Type of texture
3402 * @param width Width of texture
3403 * @param height Height of texture
3404 * @param format Format of data
3405 * @param type Type of data
3406 * @param data Buffer with image data
3408 void Texture::Update(const Functions& gl, TYPES tex_type, GLuint width, GLuint height, GLuint depth, GLenum format,
3409 GLenum type, GLvoid* data)
3411 static const GLuint level = 0;
3413 GLenum target = GetTargetGLenum(tex_type);
3418 gl.texSubImage1D(target, level, 0 /* x */, width, format, type, data);
3419 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage1D");
3424 gl.texSubImage2D(target, level, 0 /* x */, 0 /* y */, width, height, format, type, data);
3425 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2D");
3428 gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, level, 0 /* x */, 0 /* y */, width, height, format, type,
3430 gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, level, 0 /* x */, 0 /* y */, width, height, format, type,
3432 gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, level, 0 /* x */, 0 /* y */, width, height, format, type,
3434 gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, level, 0 /* x */, 0 /* y */, width, height, format, type,
3436 gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, level, 0 /* x */, 0 /* y */, width, height, format, type,
3438 gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, level, 0 /* x */, 0 /* y */, width, height, format, type,
3440 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2D");
3444 gl.texSubImage3D(target, level, 0 /* x */, 0 /* y */, 0 /* z */, width, height, depth, format, type, data);
3445 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage3D");
3448 TCU_FAIL("Invliad enum");
3453 /** Get target for given texture type
3455 * @param type Type of texture
3459 GLenum Texture::GetTargetGLenum(TYPES type)
3466 result = GL_TEXTURE_BUFFER;
3469 result = GL_TEXTURE_2D;
3472 result = GL_TEXTURE_RECTANGLE;
3475 result = GL_TEXTURE_2D_ARRAY;
3478 result = GL_TEXTURE_3D;
3481 result = GL_TEXTURE_CUBE_MAP;
3484 result = GL_TEXTURE_1D;
3487 result = GL_TEXTURE_1D_ARRAY;
3494 /* VertexArray constants */
3495 const GLuint VertexArray::m_invalid_id = -1;
3499 * @param context CTS context.
3501 VertexArray::VertexArray(deqp::Context& context) : m_id(m_invalid_id), m_context(context)
3508 VertexArray::~VertexArray()
3513 /** Initialize vertex array instance
3516 void VertexArray::Init()
3518 /* Delete previous instance */
3521 const Functions& gl = m_context.getRenderContext().getFunctions();
3526 /** Release vertex array object instance
3529 void VertexArray::Release()
3531 if (m_invalid_id != m_id)
3533 const Functions& gl = m_context.getRenderContext().getFunctions();
3535 gl.deleteVertexArrays(1, &m_id);
3537 m_id = m_invalid_id;
3541 /** Set attribute in VAO
3543 * @param index Index of attribute
3544 * @param type Type of attribute
3545 * @param n_array_elements Arary length
3546 * @param normalized Selectis if values should be normalized
3547 * @param stride Stride
3548 * @param pointer Pointer to data, or offset in buffer
3550 void VertexArray::Attribute(GLuint index, const Type& type, GLuint n_array_elements, GLboolean normalized,
3551 GLsizei stride, const GLvoid* pointer)
3553 const Functions& gl = m_context.getRenderContext().getFunctions();
3555 AttribPointer(gl, index, type, n_array_elements, normalized, stride, pointer);
3556 Enable(gl, index, type, n_array_elements);
3559 /** Binds Vertex array object
3562 void VertexArray::Bind()
3564 const Functions& gl = m_context.getRenderContext().getFunctions();
3569 /** Set attribute in VAO
3571 * @param gl Functions
3572 * @param index Index of attribute
3573 * @param type Type of attribute
3574 * @param n_array_elements Arary length
3575 * @param normalized Selectis if values should be normalized
3576 * @param stride Stride
3577 * @param pointer Pointer to data, or offset in buffer
3579 void VertexArray::AttribPointer(const Functions& gl, GLuint index, const Type& type, GLuint n_array_elements,
3580 GLboolean normalized, GLsizei stride, const GLvoid* pointer)
3582 const GLuint basic_type_size = Type::GetTypeSize(type.m_basic_type);
3583 const GLint size = (GLint)type.m_n_rows;
3584 const GLuint column_size = (GLuint)size * basic_type_size;
3585 const GLenum gl_type = Type::GetTypeGLenum(type.m_basic_type);
3589 /* If attribute is not an array */
3590 if (0 == n_array_elements)
3592 n_array_elements = 1;
3595 /* For each element in array */
3596 for (GLuint element = 0; element < n_array_elements; ++element)
3598 /* For each column in matrix */
3599 for (GLuint column = 1; column <= type.m_n_columns; ++column)
3601 /* Calculate offset */
3602 const GLvoid* ptr = (GLubyte*)pointer + offset;
3604 /* Set up attribute */
3605 switch (type.m_basic_type)
3608 gl.vertexAttribPointer(index, size, gl_type, normalized, stride, ptr);
3609 GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttribPointer");
3613 gl.vertexAttribIPointer(index, size, gl_type, stride, ptr);
3614 GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttribIPointer");
3617 gl.vertexAttribLPointer(index, size, gl_type, stride, ptr);
3618 GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttribLPointer");
3621 TCU_FAIL("Invalid enum");
3625 offset += column_size;
3631 /** Binds Vertex array object
3633 * @param gl GL functions
3634 * @param id ID of vertex array object
3636 void VertexArray::Bind(const glw::Functions& gl, glw::GLuint id)
3638 gl.bindVertexArray(id);
3639 GLU_EXPECT_NO_ERROR(gl.getError(), "BindVertexArray");
3642 /** Disable attribute in VAO
3644 * @param gl Functions
3645 * @param index Index of attribute
3646 * @param type Type of attribute
3647 * @param n_array_elements Arary length
3649 void VertexArray::Disable(const Functions& gl, GLuint index, const Type& type, GLuint n_array_elements)
3651 /* If attribute is not an array */
3652 if (0 == n_array_elements)
3654 n_array_elements = 1;
3657 /* For each element in array */
3658 for (GLuint element = 0; element < n_array_elements; ++element)
3660 /* For each column in matrix */
3661 for (GLuint column = 1; column <= type.m_n_columns; ++column)
3663 /* Enable attribute array */
3664 gl.disableVertexAttribArray(index);
3665 GLU_EXPECT_NO_ERROR(gl.getError(), "DisableVertexAttribArray");
3673 /** Set divisor for attribute
3675 * @param gl Functions
3676 * @param index Index of attribute
3677 * @param divisor New divisor value
3679 void VertexArray::Divisor(const Functions& gl, GLuint index, GLuint divisor)
3681 gl.vertexAttribDivisor(index, divisor);
3682 GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttribDivisor");
3685 /** Enables attribute in VAO
3687 * @param gl Functions
3688 * @param index Index of attribute
3689 * @param type Type of attribute
3690 * @param n_array_elements Arary length
3692 void VertexArray::Enable(const Functions& gl, GLuint index, const Type& type, GLuint n_array_elements)
3694 /* If attribute is not an array */
3695 if (0 == n_array_elements)
3697 n_array_elements = 1;
3700 /* For each element in array */
3701 for (GLuint element = 0; element < n_array_elements; ++element)
3703 /* For each column in matrix */
3704 for (GLuint column = 1; column <= type.m_n_columns; ++column)
3706 /* Enable attribute array */
3707 gl.enableVertexAttribArray(index);
3708 GLU_EXPECT_NO_ERROR(gl.getError(), "EnableVertexAttribArray");
3716 /** Generates Vertex array object
3718 * @param gl GL functions
3719 * @param out_id ID of vertex array object
3721 void VertexArray::Generate(const glw::Functions& gl, glw::GLuint& out_id)
3723 GLuint id = m_invalid_id;
3725 gl.genVertexArrays(1, &id);
3726 GLU_EXPECT_NO_ERROR(gl.getError(), "GenVertexArrays");
3728 if (m_invalid_id == id)
3730 TCU_FAIL("Invalid id");
3736 /* Constatns used by Variable */
3737 const GLint Variable::m_automatic_location = -1;
3739 /** Copy constructor
3742 Variable::Variable(const Variable& var)
3743 : m_data(var.m_data)
3744 , m_data_size(var.m_data_size)
3745 , m_descriptor(var.m_descriptor.m_name.c_str(), var.m_descriptor.m_qualifiers.c_str(),
3746 var.m_descriptor.m_expected_component, var.m_descriptor.m_expected_location,
3747 var.m_descriptor.m_builtin, var.m_descriptor.m_normalized, var.m_descriptor.m_n_array_elements,
3748 var.m_descriptor.m_expected_stride_of_element, var.m_descriptor.m_offset)
3749 , m_storage(var.m_storage)
3751 m_descriptor.m_type = var.m_descriptor.m_type;
3753 if (BUILTIN != var.m_descriptor.m_type)
3755 m_descriptor.m_interface = var.m_descriptor.m_interface;
3759 /** Get code that defines variable
3761 * @param flavour Provides info if variable is array or not
3763 * @return String with code
3765 std::string Variable::GetDefinition(FLAVOUR flavour) const
3767 return m_descriptor.GetDefinition(flavour, m_storage);
3770 /** Calcualtes stride of variable
3772 * @return Calculated value
3774 GLuint Variable::GetStride() const
3776 GLint variable_stride = 0;
3778 if (0 == m_descriptor.m_n_array_elements)
3780 variable_stride = m_descriptor.m_expected_stride_of_element;
3784 variable_stride = m_descriptor.m_expected_stride_of_element * m_descriptor.m_n_array_elements;
3787 return variable_stride;
3790 /** Check if variable is block
3792 * @return true if variable type is block, false otherwise
3794 bool Variable::IsBlock() const
3796 if (BUILTIN == m_descriptor.m_type)
3801 const Interface* interface = m_descriptor.m_interface;
3804 TCU_FAIL("Nullptr");
3807 return (Interface::BLOCK == interface->m_type);
3810 /** Check if variable is struct
3812 * @return true if variable type is struct, false otherwise
3814 bool Variable::IsStruct() const
3816 if (BUILTIN == m_descriptor.m_type)
3821 const Interface* interface = m_descriptor.m_interface;
3824 TCU_FAIL("Nullptr");
3827 return (Interface::STRUCT == interface->m_type);
3829 /** Get code that reference variable
3831 * @param parent_name Name of parent
3832 * @param variable Descriptor of variable
3833 * @param flavour Provides info about how variable should be referenced
3834 * @param array_index Index of array, ignored when variable is not array
3836 * @return String with code
3838 std::string Variable::GetReference(const std::string& parent_name, const Descriptor& variable, FLAVOUR flavour,
3844 if (false == parent_name.empty())
3848 name.append(variable.m_name);
3852 name = variable.m_name;
3858 case Utils::Variable::BASIC:
3861 case Utils::Variable::ARRAY:
3865 case Utils::Variable::INDEXED_BY_INVOCATION_ID:
3866 name.append("[gl_InvocationID]");
3870 /* Assumption that both variables have same lengths */
3871 if (0 != variable.m_n_array_elements)
3874 sprintf(buffer, "%d", array_index);
3876 name.append(buffer);
3883 /** Get "flavour" of varying
3885 * @param stage Stage of shader
3886 * @param direction Selects if varying is in or out
3890 Variable::FLAVOUR Variable::GetFlavour(Shader::STAGES stage, VARYING_DIRECTION direction)
3892 FLAVOUR result = BASIC;
3896 case Shader::GEOMETRY:
3897 case Shader::TESS_EVAL:
3898 if (INPUT == direction)
3903 case Shader::TESS_CTRL:
3904 result = INDEXED_BY_INVOCATION_ID;
3913 /** Constructor, for built-in types
3916 * @param qualifiers Qualifiers
3917 * @param expected_component Expected component of variable
3918 * @param expected_location Expected location
3920 * @param normalized Selects if data should be normalized
3921 * @param n_array_elements Length of array
3922 * @param expected_stride_of_element Expected stride of element
3923 * @param offset Offset
3925 Variable::Descriptor::Descriptor(const GLchar* name, const GLchar* qualifiers, GLint expected_component,
3926 GLint expected_location, const Type& type, GLboolean normalized,
3927 GLuint n_array_elements, GLint expected_stride_of_element, GLuint offset)
3928 : m_expected_component(expected_component)
3929 , m_expected_location(expected_location)
3930 , m_expected_stride_of_element(expected_stride_of_element)
3931 , m_n_array_elements(n_array_elements)
3933 , m_normalized(normalized)
3935 , m_qualifiers(qualifiers)
3941 /** Constructor, for interface types
3944 * @param qualifiers Qualifiers
3945 * @param expected_component Expected component of variable
3946 * @param expected_location Expected location
3947 * @param interface Interface of variable
3948 * @param n_array_elements Length of array
3949 * @param expected_stride_of_element Expected stride of element
3950 * @param offset Offset
3952 Variable::Descriptor::Descriptor(const GLchar* name, const GLchar* qualifiers, GLint expected_componenet,
3953 GLint expected_location, Interface* interface, GLuint n_array_elements,
3954 GLint expected_stride_of_element, GLuint offset)
3955 : m_expected_component(expected_componenet)
3956 , m_expected_location(expected_location)
3957 , m_expected_stride_of_element(expected_stride_of_element)
3958 , m_n_array_elements(n_array_elements)
3960 , m_normalized(GL_FALSE)
3962 , m_qualifiers(qualifiers)
3964 , m_interface(interface)
3968 /** Get definition of variable
3970 * @param flavour Flavour of variable
3971 * @param storage Storage used for variable
3973 * @return code with defintion
3975 std::string Variable::Descriptor::GetDefinition(FLAVOUR flavour, STORAGE storage) const
3977 static const GLchar* basic_template = "QUALIFIERS STORAGETYPE NAMEARRAY;";
3978 static const GLchar* array_template = "QUALIFIERS STORAGETYPE NAME[]ARRAY;";
3979 const GLchar* storage_str = 0;
3981 std::string definition;
3982 size_t position = 0;
3984 /* Select definition template */
3988 definition = basic_template;
3991 case INDEXED_BY_INVOCATION_ID:
3992 definition = array_template;
3995 TCU_FAIL("Invliad enum");
3999 if (BUILTIN != m_type)
4001 if (0 == m_interface)
4003 TCU_FAIL("Nullptr");
4008 if (true == m_qualifiers.empty())
4010 replaceToken("QUALIFIERS ", position, "", definition);
4014 replaceToken("QUALIFIERS", position, m_qualifiers.c_str(), definition);
4017 // According to spec: integer or unsigned integer type must always be declared with flat qualifier
4018 bool flat_qualifier = false;
4019 if (m_type != BUILTIN && m_interface != NULL)
4021 if (m_interface->m_members[0].m_builtin.m_basic_type == Utils::Type::Int ||
4022 m_interface->m_members[0].m_builtin.m_basic_type == Utils::Type::Uint)
4024 flat_qualifier = true;
4031 storage_str = flat_qualifier ? "flat in " : "in ";
4033 case VARYING_OUTPUT:
4034 storage_str = "out ";
4037 storage_str = "uniform ";
4040 storage_str = "buffer ";
4046 TCU_FAIL("Invalid enum");
4050 replaceToken("STORAGE", position, storage_str, definition);
4053 if (BUILTIN == m_type)
4055 replaceToken("TYPE", position, m_builtin.GetGLSLTypeName(), definition);
4059 if (Interface::STRUCT == m_interface->m_type)
4061 replaceToken("TYPE", position, m_interface->m_name.c_str(), definition);
4065 const std::string& block_definition = m_interface->GetDefinition();
4067 replaceToken("TYPE", position, block_definition.c_str(), definition);
4072 replaceToken("NAME", position, m_name.c_str(), definition);
4075 if (0 == m_n_array_elements)
4077 replaceToken("ARRAY", position, "", definition);
4082 sprintf(buffer, "[%d]", m_n_array_elements);
4084 replaceToken("ARRAY", position, buffer, definition);
4091 /** Get definitions for variables collected in vector
4093 * @param vector Collection of variables
4094 * @param flavour Flavour of variables
4096 * @return Code with definitions
4098 std::string GetDefinitions(const Variable::PtrVector& vector, Variable::FLAVOUR flavour)
4100 std::string list = Utils::g_list;
4101 size_t position = 0;
4103 for (GLuint i = 0; i < vector.size(); ++i)
4105 Utils::insertElementOfList(vector[i]->GetDefinition(flavour).c_str(), "\n", position, list);
4108 Utils::endList("", position, list);
4113 /** Get definitions for interfaces collected in vector
4115 * @param vector Collection of interfaces
4117 * @return Code with definitions
4119 std::string GetDefinitions(const Interface::PtrVector& vector)
4121 std::string list = Utils::g_list;
4122 size_t position = 0;
4124 for (GLuint i = 0; i < vector.size(); ++i)
4126 Utils::insertElementOfList(vector[i]->GetDefinition().c_str(), "\n", position, list);
4129 Utils::endList("", position, list);
4137 * @param type Type of interface
4139 Interface::Interface(const GLchar* name, Interface::TYPE type) : m_name(name), m_type(type)
4143 /** Adds member to interface
4145 * @param member Descriptor of new member
4147 * @return Pointer to just created member
4149 Variable::Descriptor* Interface::AddMember(const Variable::Descriptor& member)
4151 m_members.push_back(member);
4153 return &m_members.back();
4156 /** Get definition of interface
4158 * @param Code with definition
4160 std::string Interface::GetDefinition() const
4162 std::string definition;
4163 size_t position = 0;
4165 const GLchar* member_list = " MEMBER_DEFINITION\nMEMBER_LIST";
4167 if (STRUCT == m_type)
4169 definition = "struct NAME {\nMEMBER_LIST};";
4173 definition = "NAME {\nMEMBER_LIST}";
4177 replaceToken("NAME", position, m_name.c_str(), definition);
4180 for (GLuint i = 0; i < m_members.size(); ++i)
4182 const size_t start_position = position;
4183 const std::string& member_definition = m_members[i].GetDefinition(Variable::BASIC, Variable::MEMBER);
4186 replaceToken("MEMBER_LIST", position, member_list, definition);
4188 /* Move back position */
4189 position = start_position;
4191 /* Member definition */
4192 replaceToken("MEMBER_DEFINITION", position, member_definition.c_str(), definition);
4195 /* Remove last member list */
4196 replaceToken("MEMBER_LIST", position, "", definition);
4202 /** Adds member of built-in type to interface
4205 * @param qualifiers Qualifiers
4206 * @param expected_component Expected component of variable
4207 * @param expected_location Expected location
4209 * @param normalized Selects if data should be normalized
4210 * @param n_array_elements Length of array
4211 * @param expected_stride_of_element Expected stride of element
4212 * @param offset Offset
4214 * @return Pointer to just created member
4216 Variable::Descriptor* Interface::Member(const GLchar* name, const GLchar* qualifiers, GLint expected_component,
4217 GLint expected_location, const Type& type, GLboolean normalized,
4218 GLuint n_array_elements, GLint expected_stride_of_element, GLuint offset)
4220 return AddMember(Variable::Descriptor(name, qualifiers, expected_component, expected_location, type, normalized,
4221 n_array_elements, expected_stride_of_element, offset));
4224 /** Adds member of interface type to interface
4227 * @param qualifiers Qualifiers
4228 * @param expected_component Expected component of variable
4229 * @param expected_location Expected location
4231 * @param normalized Selects if data should be normalized
4232 * @param n_array_elements Length of array
4233 * @param expected_stride_of_element Expected stride of element
4234 * @param offset Offset
4236 * @return Pointer to just created member
4238 Variable::Descriptor* Interface::Member(const GLchar* name, const GLchar* qualifiers, GLint expected_component,
4239 GLint expected_location, Interface* nterface, GLuint n_array_elements,
4240 GLint expected_stride_of_element, GLuint offset)
4242 return AddMember(Variable::Descriptor(name, qualifiers, expected_component, expected_location, nterface,
4243 n_array_elements, expected_stride_of_element, offset));
4246 /** Clears contents of vector of pointers
4248 * @tparam T Type of elements
4250 * @param vector Collection to be cleared
4252 template <typename T>
4253 void clearPtrVector(std::vector<T*>& vector)
4255 for (size_t i = 0; i < vector.size(); ++i)
4272 * @param stage Stage described by that interface
4274 ShaderInterface::ShaderInterface(Shader::STAGES stage) : m_stage(stage)
4276 /* Nothing to be done */
4279 /** Get definitions of globals
4281 * @return Code with definitions
4283 std::string ShaderInterface::GetDefinitionsGlobals() const
4288 /** Get definitions of inputs
4290 * @return Code with definitions
4292 std::string ShaderInterface::GetDefinitionsInputs() const
4294 Variable::FLAVOUR flavour = Variable::GetFlavour(m_stage, Variable::INPUT);
4296 return GetDefinitions(m_inputs, flavour);
4299 /** Get definitions of outputs
4301 * @return Code with definitions
4303 std::string ShaderInterface::GetDefinitionsOutputs() const
4305 Variable::FLAVOUR flavour = Variable::GetFlavour(m_stage, Variable::OUTPUT);
4307 return GetDefinitions(m_outputs, flavour);
4310 /** Get definitions of buffers
4312 * @return Code with definitions
4314 std::string ShaderInterface::GetDefinitionsSSBs() const
4316 return GetDefinitions(m_ssb_blocks, Variable::BASIC);
4319 /** Get definitions of uniforms
4321 * @return Code with definitions
4323 std::string ShaderInterface::GetDefinitionsUniforms() const
4325 return GetDefinitions(m_uniforms, Variable::BASIC);
4330 * @param in Input variable
4331 * @param out Output variable
4333 VaryingConnection::VaryingConnection(Variable* in, Variable* out) : m_in(in), m_out(out)
4335 /* NBothing to be done here */
4338 /** Adds new varying connection to given stage
4340 * @param stage Shader stage
4341 * @param in In varying
4342 * @param out Out varying
4344 void VaryingPassthrough::Add(Shader::STAGES stage, Variable* in, Variable* out)
4346 VaryingConnection::Vector& vector = Get(stage);
4348 vector.push_back(VaryingConnection(in, out));
4351 /** Get all passthrough connections for given stage
4353 * @param stage Shader stage
4355 * @return Vector of connections
4357 VaryingConnection::Vector& VaryingPassthrough::Get(Shader::STAGES stage)
4359 VaryingConnection::Vector* result = 0;
4363 case Shader::FRAGMENT:
4364 result = &m_fragment;
4366 case Shader::GEOMETRY:
4367 result = &m_geometry;
4369 case Shader::TESS_CTRL:
4370 result = &m_tess_ctrl;
4372 case Shader::TESS_EVAL:
4373 result = &m_tess_eval;
4375 case Shader::VERTEX:
4379 TCU_FAIL("Invalid enum");
4388 ProgramInterface::ProgramInterface()
4389 : m_compute(Shader::COMPUTE)
4390 , m_vertex(Shader::VERTEX)
4391 , m_tess_ctrl(Shader::TESS_CTRL)
4392 , m_tess_eval(Shader::TESS_EVAL)
4393 , m_geometry(Shader::GEOMETRY)
4394 , m_fragment(Shader::FRAGMENT)
4401 ProgramInterface::~ProgramInterface()
4403 clearPtrVector(m_blocks);
4404 clearPtrVector(m_structures);
4407 /** Adds new interface
4412 * @return Pointer to created interface
4414 Interface* ProgramInterface::AddInterface(const GLchar* name, Interface::TYPE type)
4416 Interface* interface = 0;
4418 if (Interface::STRUCT == type)
4420 interface = new Interface(name, type);
4422 m_structures.push_back(interface);
4426 interface = new Interface(name, type);
4428 m_blocks.push_back(interface);
4434 /** Adds new block interface
4438 * @return Pointer to created interface
4440 Interface* ProgramInterface::Block(const GLchar* name)
4442 return AddInterface(name, Interface::BLOCK);
4445 /** Get interface of given shader stage
4447 * @param stage Shader stage
4449 * @return Reference to stage interface
4451 ShaderInterface& ProgramInterface::GetShaderInterface(Shader::STAGES stage)
4453 ShaderInterface* interface = 0;
4457 case Shader::COMPUTE:
4458 interface = &m_compute;
4460 case Shader::FRAGMENT:
4461 interface = &m_fragment;
4463 case Shader::GEOMETRY:
4464 interface = &m_geometry;
4466 case Shader::TESS_CTRL:
4467 interface = &m_tess_ctrl;
4469 case Shader::TESS_EVAL:
4470 interface = &m_tess_eval;
4472 case Shader::VERTEX:
4473 interface = &m_vertex;
4476 TCU_FAIL("Invalid enum");
4482 /** Get interface of given shader stage
4484 * @param stage Shader stage
4486 * @return Reference to stage interface
4488 const ShaderInterface& ProgramInterface::GetShaderInterface(Shader::STAGES stage) const
4490 const ShaderInterface* interface = 0;
4494 case Shader::COMPUTE:
4495 interface = &m_compute;
4497 case Shader::FRAGMENT:
4498 interface = &m_fragment;
4500 case Shader::GEOMETRY:
4501 interface = &m_geometry;
4503 case Shader::TESS_CTRL:
4504 interface = &m_tess_ctrl;
4506 case Shader::TESS_EVAL:
4507 interface = &m_tess_eval;
4509 case Shader::VERTEX:
4510 interface = &m_vertex;
4513 TCU_FAIL("Invalid enum");
4519 /** Clone interface of Vertex shader stage to other stages
4520 * It creates matching inputs, outputs, uniforms and buffers in other stages.
4521 * There are no additional outputs for FRAGMENT shader generated.
4523 * @param varying_passthrough Collection of varyings connections
4525 void ProgramInterface::CloneVertexInterface(VaryingPassthrough& varying_passthrough)
4527 /* VS outputs >> TCS inputs >> TCS outputs >> .. >> FS inputs */
4528 for (size_t i = 0; i < m_vertex.m_outputs.size(); ++i)
4530 const Variable& vs_var = *m_vertex.m_outputs[i];
4531 const GLchar* prefix = GetStagePrefix(Shader::VERTEX, vs_var.m_storage);
4533 cloneVariableForStage(vs_var, Shader::TESS_CTRL, prefix, varying_passthrough);
4534 cloneVariableForStage(vs_var, Shader::TESS_EVAL, prefix, varying_passthrough);
4535 cloneVariableForStage(vs_var, Shader::GEOMETRY, prefix, varying_passthrough);
4536 cloneVariableForStage(vs_var, Shader::FRAGMENT, prefix, varying_passthrough);
4539 /* Copy uniforms from VS to other stages */
4540 for (size_t i = 0; i < m_vertex.m_uniforms.size(); ++i)
4542 Variable& vs_var = *m_vertex.m_uniforms[i];
4543 const GLchar* prefix = GetStagePrefix(Shader::VERTEX, vs_var.m_storage);
4545 cloneVariableForStage(vs_var, Shader::COMPUTE, prefix, varying_passthrough);
4546 cloneVariableForStage(vs_var, Shader::TESS_CTRL, prefix, varying_passthrough);
4547 cloneVariableForStage(vs_var, Shader::TESS_EVAL, prefix, varying_passthrough);
4548 cloneVariableForStage(vs_var, Shader::GEOMETRY, prefix, varying_passthrough);
4549 cloneVariableForStage(vs_var, Shader::FRAGMENT, prefix, varying_passthrough);
4551 /* Uniform blocks needs unique binding */
4552 if (true == vs_var.IsBlock())
4554 replaceBinding(vs_var, Shader::VERTEX);
4558 /* Copy SSBs from VS to other stages */
4559 for (size_t i = 0; i < m_vertex.m_ssb_blocks.size(); ++i)
4561 Variable& vs_var = *m_vertex.m_ssb_blocks[i];
4562 const GLchar* prefix = GetStagePrefix(Shader::VERTEX, vs_var.m_storage);
4564 cloneVariableForStage(vs_var, Shader::COMPUTE, prefix, varying_passthrough);
4565 cloneVariableForStage(vs_var, Shader::TESS_CTRL, prefix, varying_passthrough);
4566 cloneVariableForStage(vs_var, Shader::TESS_EVAL, prefix, varying_passthrough);
4567 cloneVariableForStage(vs_var, Shader::GEOMETRY, prefix, varying_passthrough);
4568 cloneVariableForStage(vs_var, Shader::FRAGMENT, prefix, varying_passthrough);
4570 /* SSBs blocks needs unique binding */
4571 if (true == vs_var.IsBlock())
4573 replaceBinding(vs_var, Shader::VERTEX);
4577 m_compute.m_globals = m_vertex.m_globals;
4578 m_fragment.m_globals = m_vertex.m_globals;
4579 m_geometry.m_globals = m_vertex.m_globals;
4580 m_tess_ctrl.m_globals = m_vertex.m_globals;
4581 m_tess_eval.m_globals = m_vertex.m_globals;
4584 /** Clone variable for specific stage
4586 * @param variable Variable
4587 * @param stage Requested stage
4588 * @param prefix Prefix used in variable name that is specific for original stage
4589 * @param varying_passthrough Collection of varyings connections
4591 void ProgramInterface::cloneVariableForStage(const Variable& variable, Shader::STAGES stage, const GLchar* prefix,
4592 VaryingPassthrough& varying_passthrough)
4594 switch (variable.m_storage)
4596 case Variable::VARYING_OUTPUT:
4598 Variable* in = cloneVariableForStage(variable, stage, Variable::VARYING_INPUT, prefix);
4600 if (Shader::FRAGMENT != stage)
4602 Variable* out = cloneVariableForStage(variable, stage, Variable::VARYING_OUTPUT, prefix);
4603 varying_passthrough.Add(stage, in, out);
4607 case Variable::UNIFORM:
4609 cloneVariableForStage(variable, stage, variable.m_storage, prefix);
4612 TCU_FAIL("Invalid enum");
4617 /** Clone variable for specific stage
4619 * @param variable Variable
4620 * @param stage Requested stage
4621 * @param storage Storage used by variable
4622 * @param prefix Prefix used in variable name that is specific for original stage
4624 * @return New variable
4626 Variable* ProgramInterface::cloneVariableForStage(const Variable& variable, Shader::STAGES stage,
4627 Variable::STORAGE storage, const GLchar* prefix)
4629 /* Initialize with original variable */
4630 Variable* var = new Variable(variable);
4633 TCU_FAIL("Memory allocation");
4636 /* Set up storage */
4637 var->m_storage = storage;
4640 std::string name = variable.m_descriptor.m_name;
4642 /* Prefix name with stage ID, empty means default block */
4643 if (false == name.empty())
4645 size_t position = 0;
4646 const GLchar* stage_prefix = GetStagePrefix(stage, storage);
4647 Utils::replaceToken(prefix, position, stage_prefix, name);
4649 var->m_descriptor.m_name = name;
4652 const bool is_block = variable.IsBlock();
4653 if (true == is_block)
4655 const Interface* interface = variable.m_descriptor.m_interface;
4657 Interface* block = CloneBlockForStage(*interface, stage, storage, prefix);
4659 var->m_descriptor.m_interface = block;
4662 /* Store variable */
4663 ShaderInterface& si = GetShaderInterface(stage);
4664 Variable* result = 0;
4668 case Variable::VARYING_INPUT:
4669 si.m_inputs.push_back(var);
4670 result = si.m_inputs.back();
4672 case Variable::VARYING_OUTPUT:
4673 si.m_outputs.push_back(var);
4674 result = si.m_outputs.back();
4676 case Variable::UNIFORM:
4677 /* Uniform blocks needs unique binding */
4678 if (true == is_block)
4680 replaceBinding(*var, stage);
4683 si.m_uniforms.push_back(var);
4684 result = si.m_uniforms.back();
4687 /* SSBs needs unique binding */
4688 if (true == is_block)
4690 replaceBinding(*var, stage);
4693 si.m_ssb_blocks.push_back(var);
4694 result = si.m_ssb_blocks.back();
4697 TCU_FAIL("Invalid enum");
4704 /** clone block to specific stage
4706 * @param block Block to be copied
4707 * @param stage Specific stage
4708 * @param storage Storage used by block
4709 * @param prefix Prefix used in block name
4711 * @return New interface
4713 Interface* ProgramInterface::CloneBlockForStage(const Interface& block, Shader::STAGES stage, Variable::STORAGE storage,
4714 const GLchar* prefix)
4717 std::string name = block.m_name;
4719 /* Prefix name with stage ID */
4720 size_t position = 0;
4721 const GLchar* stage_prefix = GetStagePrefix(stage, storage);
4722 Utils::replaceToken(prefix, position, stage_prefix, name);
4724 Interface* ptr = GetBlock(name.c_str());
4728 ptr = AddInterface(name.c_str(), Interface::BLOCK);
4731 ptr->m_members = block.m_members;
4736 /** Get stage specific prefix used in names
4738 * @param stage Stage
4739 * @param storage Storage class
4743 const GLchar* ProgramInterface::GetStagePrefix(Shader::STAGES stage, Variable::STORAGE storage)
4745 static const GLchar* lut[Shader::STAGE_MAX][Variable::STORAGE_MAX] = {
4746 /* IN OUT UNIFORM SSB MEMBER */
4747 /* CS */ { 0, 0, "cs_uni_", "cs_buf_", "" },
4748 /* VS */ { "in_vs_", "vs_tcs_", "vs_uni_", "vs_buf_", "" },
4749 /* TCS */ { "vs_tcs_", "tcs_tes_", "tcs_uni_", "tcs_buf_", "" },
4750 /* TES */ { "tcs_tes_", "tes_gs_", "tes_uni_", "tes_buf_", "" },
4751 /* GS */ { "tes_gs_", "gs_fs_", "gs_uni_", "gs_buf_", "" },
4752 /* FS */ { "gs_fs_", "fs_out_", "fs_uni_", "fs_buf_", "" },
4755 const GLchar* result = 0;
4757 result = lut[stage][storage];
4762 /** Get definitions of all structures used in program interface
4764 * @return String with code
4766 std::string ProgramInterface::GetDefinitionsStructures() const
4768 return GetDefinitions(m_structures);
4771 /** Get interface code for stage
4773 * @param stage Specific stage
4775 * @return String with code
4777 std::string ProgramInterface::GetInterfaceForStage(Shader::STAGES stage) const
4779 size_t position = 0;
4780 std::string interface = "/* Globals */\n"
4783 "/* Structures */\n"
4798 const ShaderInterface& si = GetShaderInterface(stage);
4800 const std::string& structures = GetDefinitionsStructures();
4802 const std::string& globals = si.GetDefinitionsGlobals();
4803 const std::string& inputs = si.GetDefinitionsInputs();
4804 const std::string& outputs = si.GetDefinitionsOutputs();
4805 const std::string& uniforms = si.GetDefinitionsUniforms();
4806 const std::string& ssbs = si.GetDefinitionsSSBs();
4808 replaceToken("GLOBALS", position, globals.c_str(), interface);
4809 replaceToken("STRUCTURES", position, structures.c_str(), interface);
4810 replaceToken("UNIFORMS", position, uniforms.c_str(), interface);
4811 replaceToken("INPUTS", position, inputs.c_str(), interface);
4812 replaceToken("OUTPUTS", position, outputs.c_str(), interface);
4813 replaceToken("STORAGE", position, ssbs.c_str(), interface);
4818 /** Functional object used in find_if algorithm, in search for interface of given name
4821 struct matchInterfaceName
4823 matchInterfaceName(const GLchar* name) : m_name(name)
4827 bool operator()(const Interface* interface)
4829 return 0 == interface->m_name.compare(m_name);
4832 const GLchar* m_name;
4835 /** Finds interface of given name in given vector of interfaces
4837 * @param vector Collection of interfaces
4838 * @param name Requested name
4840 * @return Pointer to interface if available, 0 otherwise
4842 static Interface* findInterfaceByName(Interface::PtrVector& vector, const GLchar* name)
4844 Interface::PtrVector::iterator it = std::find_if(vector.begin(), vector.end(), matchInterfaceName(name));
4846 if (vector.end() != it)
4856 /** Search for block of given name
4858 * @param name Name of block
4860 * @return Pointer to block or 0
4862 Interface* ProgramInterface::GetBlock(const GLchar* name)
4864 return findInterfaceByName(m_blocks, name);
4867 /** Search for structure of given name
4869 * @param name Name of structure
4871 * @return Pointer to structure or 0
4873 Interface* ProgramInterface::GetStructure(const GLchar* name)
4875 return findInterfaceByName(m_structures, name);
4878 /** Adds new sturcture to interface
4880 * @param name Name of structure
4882 * @return Created structure
4884 Interface* ProgramInterface::Structure(const GLchar* name)
4886 return AddInterface(name, Interface::STRUCT);
4889 /** Replace "BINDING" token in qualifiers string to value specific for given stage
4891 * @param variable Variable to modify
4892 * @param stage Requested stage
4894 void ProgramInterface::replaceBinding(Variable& variable, Shader::STAGES stage)
4897 sprintf(binding, "%d", stage);
4898 replaceAllTokens("BINDING", binding, variable.m_descriptor.m_qualifiers);
4900 } /* Utils namespace */
4902 /** Debuging procedure. Logs parameters.
4904 * @param source As specified in GL spec.
4905 * @param type As specified in GL spec.
4906 * @param id As specified in GL spec.
4907 * @param severity As specified in GL spec.
4909 * @param message As specified in GL spec.
4910 * @param info Pointer to instance of Context used by test.
4912 void GLW_APIENTRY debug_proc(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei /* length */,
4913 const GLchar* message, void* info)
4915 deqp::Context* ctx = (deqp::Context*)info;
4917 const GLchar* source_str = "Unknown";
4918 const GLchar* type_str = "Unknown";
4919 const GLchar* severity_str = "Unknown";
4923 case GL_DEBUG_SOURCE_API:
4926 case GL_DEBUG_SOURCE_APPLICATION:
4929 case GL_DEBUG_SOURCE_OTHER:
4932 case GL_DEBUG_SOURCE_SHADER_COMPILER:
4935 case GL_DEBUG_SOURCE_THIRD_PARTY:
4938 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
4947 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
4948 type_str = "DEPRECATED_BEHAVIOR";
4950 case GL_DEBUG_TYPE_ERROR:
4953 case GL_DEBUG_TYPE_MARKER:
4954 type_str = "MARKER";
4956 case GL_DEBUG_TYPE_OTHER:
4959 case GL_DEBUG_TYPE_PERFORMANCE:
4960 type_str = "PERFORMANCE";
4962 case GL_DEBUG_TYPE_POP_GROUP:
4963 type_str = "POP_GROUP";
4965 case GL_DEBUG_TYPE_PORTABILITY:
4966 type_str = "PORTABILITY";
4968 case GL_DEBUG_TYPE_PUSH_GROUP:
4969 type_str = "PUSH_GROUP";
4971 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
4972 type_str = "UNDEFINED_BEHAVIOR";
4980 case GL_DEBUG_SEVERITY_HIGH:
4983 case GL_DEBUG_SEVERITY_LOW:
4986 case GL_DEBUG_SEVERITY_MEDIUM:
4989 case GL_DEBUG_SEVERITY_NOTIFICATION:
4996 ctx->getTestContext().getLog() << tcu::TestLog::Message << "DEBUG_INFO: " << std::setw(3) << source_str << "|"
4997 << severity_str << "|" << std::setw(18) << type_str << "|" << std::setw(12) << id
4998 << ": " << message << tcu::TestLog::EndMessage;
5003 * @param context Test context
5004 * @param test_name Test name
5005 * @param test_description Test description
5007 TestBase::TestBase(deqp::Context& context, const GLchar* test_name, const GLchar* test_description)
5008 : TestCase(context, test_name, test_description)
5010 /* Nothing to be done here */
5015 * @return tcu::TestNode::STOP otherwise
5017 tcu::TestNode::IterateResult TestBase::iterate()
5021 #if DEBUG_ENBALE_MESSAGE_CALLBACK
5022 const Functions& gl = m_context.getRenderContext().getFunctions();
5024 gl.debugMessageCallback(debug_proc, &m_context);
5025 GLU_EXPECT_NO_ERROR(gl.getError(), "DebugMessageCallback");
5026 #endif /* DEBUG_ENBALE_MESSAGE_CALLBACK */
5031 test_result = test();
5033 catch (std::exception& exc)
5035 TCU_FAIL(exc.what());
5039 if (true == test_result)
5041 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
5045 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
5049 return tcu::TestNode::STOP;
5052 /** Get last input location available for given type at specific stage
5054 * @param stage Shader stage
5055 * @param type Input type
5056 * @param array_length Length of input array
5058 * @return Last location index
5060 GLint TestBase::getLastInputLocation(Utils::Shader::STAGES stage, const Utils::Type& type, GLuint array_length)
5062 GLint divide = 4; /* 4 components per location */
5069 case Utils::Shader::FRAGMENT:
5070 pname = GL_MAX_FRAGMENT_INPUT_COMPONENTS;
5072 case Utils::Shader::GEOMETRY:
5073 pname = GL_MAX_GEOMETRY_INPUT_COMPONENTS;
5075 case Utils::Shader::TESS_CTRL:
5076 pname = GL_MAX_TESS_CONTROL_INPUT_COMPONENTS;
5078 case Utils::Shader::TESS_EVAL:
5079 pname = GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS;
5081 case Utils::Shader::VERTEX:
5082 pname = GL_MAX_VERTEX_ATTRIBS;
5086 TCU_FAIL("Invalid enum");
5090 /* Zero means no array, but 1 slot is required */
5091 if (0 == array_length)
5097 const Functions& gl = m_context.getRenderContext().getFunctions();
5099 gl.getIntegerv(pname, ¶m);
5100 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
5103 #if WRKARD_VARYINGLOCATIONSTEST
5105 const GLint n_avl_locations = 16;
5109 const GLint n_avl_locations = param / divide;
5113 const GLuint n_req_location = type.GetLocations() * array_length;
5115 return n_avl_locations - n_req_location; /* last is max - 1 */
5118 /** Get last input location available for given type at specific stage
5120 * @param stage Shader stage
5121 * @param type Input type
5122 * @param array_length Length of input array
5124 * @return Last location index
5126 GLint TestBase::getLastOutputLocation(Utils::Shader::STAGES stage, const Utils::Type& type, GLuint array_length)
5134 case Utils::Shader::GEOMETRY:
5135 pname = GL_MAX_GEOMETRY_OUTPUT_COMPONENTS;
5137 case Utils::Shader::TESS_CTRL:
5138 pname = GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS;
5140 case Utils::Shader::TESS_EVAL:
5141 pname = GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS;
5143 case Utils::Shader::VERTEX:
5144 pname = GL_MAX_VERTEX_OUTPUT_COMPONENTS;
5147 TCU_FAIL("Invalid enum");
5151 /* Zero means no array, but 1 slot is required */
5152 if (0 == array_length)
5158 const Functions& gl = m_context.getRenderContext().getFunctions();
5160 gl.getIntegerv(pname, ¶m);
5161 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
5164 #if WRKARD_VARYINGLOCATIONSTEST
5166 const GLint n_avl_locations = 16;
5170 const GLint n_avl_locations = param / 4; /* 4 components per location */
5174 const GLuint n_req_location = type.GetLocations() * array_length;
5176 return n_avl_locations - n_req_location; /* last is max - 1 */
5179 /** Basic implementation
5183 * @return Empty string
5185 std::string TestBase::getTestCaseName(GLuint /* test_case_index */)
5192 /** Basic implementation
5196 GLuint TestBase::getTestCaseNumber()
5201 /** Check if flat qualifier is required for given type, stage and storage
5203 * @param stage Shader stage
5204 * @param type Input type
5205 * @param storage Storage of variable
5207 * @return Last location index
5209 bool TestBase::isFlatRequired(Utils::Shader::STAGES stage, const Utils::Type& type,
5210 Utils::Variable::STORAGE storage) const
5212 /* Float types do not need flat at all */
5213 if (Utils::Type::Float == type.m_basic_type)
5218 /* Inputs to fragment shader */
5219 if ((Utils::Shader::FRAGMENT == stage) && (Utils::Variable::VARYING_INPUT == storage))
5224 /* Outputs from geometry shader */
5225 if ((Utils::Shader::FRAGMENT == stage) && (Utils::Variable::VARYING_OUTPUT == storage))
5233 /** Basic implementation of testInit method
5236 void TestBase::testInit()
5240 /** Calculate stride for interface
5242 * @param interface Interface
5244 * @return Calculated value
5246 GLuint TestBase::calculateStride(const Utils::Interface& interface) const
5248 const size_t n_members = interface.m_members.size();
5252 for (size_t i = 0; i < n_members; ++i)
5254 const Utils::Variable::Descriptor& member = interface.m_members[i];
5255 const GLuint member_offset = member.m_offset;
5256 const GLuint member_stride = member.m_expected_stride_of_element;
5257 const GLuint member_ends_at = member_offset + member_stride;
5259 stride = std::max(stride, member_ends_at);
5265 /** Generate data for interface. This routine is recursive
5267 * @param interface Interface
5268 * @param offset Offset in out_data
5269 * @param out_data Buffer to be filled
5271 void TestBase::generateData(const Utils::Interface& interface, GLuint offset, std::vector<GLubyte>& out_data) const
5273 const size_t n_members = interface.m_members.size();
5274 GLubyte* ptr = &out_data[offset];
5276 for (size_t i = 0; i < n_members; ++i)
5278 const Utils::Variable::Descriptor& member = interface.m_members[i];
5279 const GLuint member_offset = member.m_offset;
5280 const GLuint n_elements = (0 == member.m_n_array_elements) ? 1 : member.m_n_array_elements;
5282 for (GLuint element = 0; element < n_elements; ++element)
5284 const GLuint element_offset = element * member.m_expected_stride_of_element;
5285 const GLuint data_offfset = member_offset + element_offset;
5287 if (Utils::Variable::BUILTIN == member.m_type)
5289 const std::vector<GLubyte>& data = member.m_builtin.GenerateData();
5291 memcpy(ptr + data_offfset, &data[0], data.size());
5295 generateData(*member.m_interface, offset + data_offfset, out_data);
5301 /** Get type at index
5303 * @param index Index of requested type
5307 Utils::Type TestBase::getType(GLuint index) const
5314 type = Utils::Type::_double;
5317 type = Utils::Type::dmat2;
5320 type = Utils::Type::dmat2x3;
5323 type = Utils::Type::dmat2x4;
5326 type = Utils::Type::dmat3;
5329 type = Utils::Type::dmat3x2;
5332 type = Utils::Type::dmat3x4;
5335 type = Utils::Type::dmat4;
5338 type = Utils::Type::dmat4x2;
5341 type = Utils::Type::dmat4x3;
5344 type = Utils::Type::dvec2;
5347 type = Utils::Type::dvec3;
5350 type = Utils::Type::dvec4;
5353 type = Utils::Type::_float;
5356 type = Utils::Type::mat2;
5359 type = Utils::Type::mat2x3;
5362 type = Utils::Type::mat2x4;
5365 type = Utils::Type::mat3;
5368 type = Utils::Type::mat3x2;
5371 type = Utils::Type::mat3x4;
5374 type = Utils::Type::mat4;
5377 type = Utils::Type::mat4x2;
5380 type = Utils::Type::mat4x3;
5383 type = Utils::Type::vec2;
5386 type = Utils::Type::vec3;
5389 type = Utils::Type::vec4;
5392 type = Utils::Type::_int;
5395 type = Utils::Type::ivec2;
5398 type = Utils::Type::ivec3;
5401 type = Utils::Type::ivec4;
5404 type = Utils::Type::uint;
5407 type = Utils::Type::uvec2;
5410 type = Utils::Type::uvec3;
5413 type = Utils::Type::uvec4;
5416 TCU_FAIL("invalid enum");
5422 /** Get name of type at index
5424 * @param index Index of type
5428 std::string TestBase::getTypeName(GLuint index) const
5430 std::string name = getType(index).GetGLSLTypeName();
5435 /** Get number of types
5439 glw::GLuint TestBase::getTypesNumber() const
5446 * @return true if test pass, false otherwise
5448 bool TestBase::test()
5451 GLuint n_test_cases = 0;
5456 /* GL entry points */
5457 const Functions& gl = m_context.getRenderContext().getFunctions();
5459 /* Tessellation patch set up */
5460 gl.patchParameteri(GL_PATCH_VERTICES, 1);
5461 GLU_EXPECT_NO_ERROR(gl.getError(), "PatchParameteri");
5463 /* Get number of test cases */
5464 n_test_cases = getTestCaseNumber();
5466 #if DEBUG_REPEAT_TEST_CASE
5470 GLuint test_case = DEBUG_REPEATED_TEST_CASE;
5472 #else /* DEBUG_REPEAT_TEST_CASE */
5474 for (GLuint test_case = 0; test_case < n_test_cases; ++test_case)
5477 #endif /* DEBUG_REPEAT_TEST_CASE */
5479 bool case_result = true;
5482 if (false == testCase(test_case))
5484 case_result = false;
5488 if (false == case_result)
5490 const std::string& test_case_name = getTestCaseName(test_case);
5492 if (false == test_case_name.empty())
5494 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Test case (" << test_case_name
5495 << ") failed." << tcu::TestLog::EndMessage;
5499 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Test case (" << test_case
5500 << ") failed." << tcu::TestLog::EndMessage;
5511 /* Constants used by BufferTestBase */
5512 const GLuint BufferTestBase::bufferDescriptor::m_non_indexed = -1;
5516 * @param context Test context
5517 * @param test_name Name of test
5518 * @param test_description Description of test
5520 BufferTestBase::BufferTestBase(deqp::Context& context, const GLchar* test_name, const GLchar* test_description)
5521 : TestBase(context, test_name, test_description)
5525 /** Execute drawArrays for single vertex
5531 bool BufferTestBase::executeDrawCall(bool tesEnabled, GLuint /* test_case_index */)
5533 const Functions& gl = m_context.getRenderContext().getFunctions();
5535 gl.disable(GL_RASTERIZER_DISCARD);
5536 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
5538 gl.beginTransformFeedback(GL_POINTS);
5539 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
5541 // Only TES is existed, glDrawArray can use the parameter GL_PATCHES
5542 if (tesEnabled == false)
5544 gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */);
5548 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
5551 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
5553 gl.endTransformFeedback();
5554 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
5559 /** Get descriptors of buffers necessary for test
5564 void BufferTestBase::getBufferDescriptors(glw::GLuint /* test_case_index */,
5565 bufferDescriptor::Vector& /* out_descriptors */)
5567 /* Nothhing to be done */
5570 /** Get list of names of varyings that will be registered with TransformFeedbackVaryings
5575 void BufferTestBase::getCapturedVaryings(glw::GLuint /* test_case_index */,
5576 Utils::Program::NameVector& /* captured_varyings */)
5578 /* Nothing to be done */
5581 /** Get body of main function for given shader stage
5585 * @param out_assignments Set to empty
5586 * @param out_calculations Set to empty
5588 void BufferTestBase::getShaderBody(glw::GLuint /* test_case_index */, Utils::Shader::STAGES /* stage */,
5589 std::string& out_assignments, std::string& out_calculations)
5591 out_assignments = "";
5592 out_calculations = "";
5595 /** Get interface of shader
5599 * @param out_interface Set to ""
5601 void BufferTestBase::getShaderInterface(glw::GLuint /* test_case_index */, Utils::Shader::STAGES /* stage */,
5602 std::string& out_interface)
5607 /** Get source code of shader
5609 * @param test_case_index Index of test case
5610 * @param stage Shader stage
5614 std::string BufferTestBase::getShaderSource(glw::GLuint test_case_index, Utils::Shader::STAGES stage)
5616 std::string assignments;
5617 std::string calculations;
5618 std::string interface;
5621 getShaderBody(test_case_index, stage, assignments, calculations);
5622 getShaderInterface(test_case_index, stage, interface);
5625 std::string source = getShaderTemplate(stage);
5628 size_t position = 0;
5629 Utils::replaceToken("INTERFACE", position, interface.c_str(), source);
5630 Utils::replaceToken("CALCULATIONS", position, calculations.c_str(), source);
5631 Utils::replaceToken("ASSIGNMENTS", position, assignments.c_str(), source);
5637 /** Inspects program to check if all resources are as expected
5645 bool BufferTestBase::inspectProgram(GLuint /* test_case_index */, Utils::Program& /* program */,
5646 std::stringstream& /* out_stream */)
5653 * @param test_case_index Id of test case
5655 * @return true if test case pass, false otherwise
5657 bool BufferTestBase::testCase(GLuint test_case_index)
5661 bufferCollection buffers;
5662 Utils::Program::NameVector captured_varyings;
5663 bufferDescriptor::Vector descriptors;
5664 Utils::Program program(m_context);
5665 Utils::VertexArray vao(m_context);
5667 /* Get captured varyings */
5668 getCapturedVaryings(test_case_index, captured_varyings);
5670 /* Get shader sources */
5671 const std::string& fragment_shader = getShaderSource(test_case_index, Utils::Shader::FRAGMENT);
5672 const std::string& geometry_shader = getShaderSource(test_case_index, Utils::Shader::GEOMETRY);
5673 const std::string& tess_ctrl_shader = getShaderSource(test_case_index, Utils::Shader::TESS_CTRL);
5674 const std::string& tess_eval_shader = getShaderSource(test_case_index, Utils::Shader::TESS_EVAL);
5675 const std::string& vertex_shader = getShaderSource(test_case_index, Utils::Shader::VERTEX);
5677 /* Set up program */
5678 program.Init("" /* compute_shader */, fragment_shader, geometry_shader, tess_ctrl_shader, tess_eval_shader,
5679 vertex_shader, captured_varyings, true, false /* is_separable */);
5683 std::stringstream stream;
5684 if (false == inspectProgram(test_case_index, program, stream))
5686 m_context.getTestContext().getLog()
5687 << tcu::TestLog::Message
5688 << "Program inspection failed. Test case: " << getTestCaseName(test_case_index)
5689 << ". Reason: " << stream.str() << tcu::TestLog::EndMessage
5690 << tcu::TestLog::KernelSource(vertex_shader) << tcu::TestLog::KernelSource(tess_ctrl_shader)
5691 << tcu::TestLog::KernelSource(tess_eval_shader) << tcu::TestLog::KernelSource(geometry_shader)
5692 << tcu::TestLog::KernelSource(fragment_shader);
5700 /* Set up buffers */
5701 getBufferDescriptors(test_case_index, descriptors);
5703 prepareBuffers(descriptors, buffers);
5710 bool result = executeDrawCall((program.m_tess_eval.m_id != 0), test_case_index);
5713 m_context.getRenderContext().postIterate();
5716 if (false == result)
5718 m_context.getTestContext().getLog()
5719 << tcu::TestLog::KernelSource(vertex_shader) << tcu::TestLog::KernelSource(tess_ctrl_shader)
5720 << tcu::TestLog::KernelSource(tess_eval_shader) << tcu::TestLog::KernelSource(geometry_shader)
5721 << tcu::TestLog::KernelSource(fragment_shader);
5727 if (false == verifyBuffers(buffers))
5729 m_context.getTestContext().getLog()
5730 << tcu::TestLog::KernelSource(vertex_shader) << tcu::TestLog::KernelSource(tess_ctrl_shader)
5731 << tcu::TestLog::KernelSource(tess_eval_shader) << tcu::TestLog::KernelSource(geometry_shader)
5732 << tcu::TestLog::KernelSource(fragment_shader);
5737 catch (Utils::Shader::InvalidSourceException& exc)
5740 TCU_FAIL(exc.what());
5742 catch (Utils::Program::BuildException& exc)
5745 TCU_FAIL(exc.what());
5752 /** Verify contents of buffers
5754 * @param buffers Collection of buffers to be verified
5756 * @return true if everything is as expected, false otherwise
5758 bool BufferTestBase::verifyBuffers(bufferCollection& buffers)
5762 for (bufferCollection::Vector::iterator it = buffers.m_vector.begin(), end = buffers.m_vector.end(); end != it;
5765 bufferCollection::pair& pair = *it;
5766 Utils::Buffer* buffer = pair.m_buffer;
5767 bufferDescriptor* descriptor = pair.m_descriptor;
5768 size_t size = descriptor->m_expected_data.size();
5770 /* Skip buffers that have no expected data */
5776 /* Get pointer to contents of buffer */
5778 GLvoid* buffer_data = buffer->Map(Utils::Buffer::ReadOnly);
5780 /* Get pointer to expected data */
5781 GLvoid* expected_data = &descriptor->m_expected_data[0];
5784 int res = memcmp(buffer_data, expected_data, size);
5788 m_context.getTestContext().getLog()
5789 << tcu::TestLog::Message
5790 << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
5791 << ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
5796 /* Release buffer mapping */
5803 /** Unbinds all uniforms and xfb
5806 void BufferTestBase::cleanBuffers()
5808 const Functions& gl = m_context.getRenderContext().getFunctions();
5813 gl.getIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &max_uni);
5814 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_xfb);
5815 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
5817 for (GLint i = 0; i < max_uni; ++i)
5819 Utils::Buffer::BindBase(gl, 0, Utils::Buffer::Uniform, i);
5822 for (GLint i = 0; i < max_xfb; ++i)
5824 Utils::Buffer::BindBase(gl, 0, Utils::Buffer::Transform_feedback, i);
5828 /** Get template of shader for given stage
5830 * @param stage Stage
5832 * @return Template of shader source
5834 std::string BufferTestBase::getShaderTemplate(Utils::Shader::STAGES stage)
5836 static const GLchar* compute_shader_template = "#version 430 core\n"
5837 "#extension GL_ARB_enhanced_layouts : require\n"
5839 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
5841 "writeonly uniform uimage2D uni_image;\n"
5853 static const GLchar* fragment_shader_template = "#version 430 core\n"
5854 "#extension GL_ARB_enhanced_layouts : require\n"
5866 // max_vertices is set to 3 for the test case "xfb_vertex_streams" declares 3 streams in geometry shader,
5867 // according to spec, max_vertices should be no less than 3 if there are 3 streams in GS.
5868 static const GLchar* geometry_shader_template = "#version 430 core\n"
5869 "#extension GL_ARB_enhanced_layouts : require\n"
5871 "layout(points) in;\n"
5872 "layout(points, max_vertices = 3) out;\n"
5882 " gl_Position = vec4(0, 0, 0, 1);\n"
5887 static const GLchar* tess_ctrl_shader_template = "#version 430 core\n"
5888 "#extension GL_ARB_enhanced_layouts : require\n"
5890 "layout(vertices = 1) out;\n"
5900 " gl_TessLevelOuter[0] = 1.0;\n"
5901 " gl_TessLevelOuter[1] = 1.0;\n"
5902 " gl_TessLevelOuter[2] = 1.0;\n"
5903 " gl_TessLevelOuter[3] = 1.0;\n"
5904 " gl_TessLevelInner[0] = 1.0;\n"
5905 " gl_TessLevelInner[1] = 1.0;\n"
5909 static const GLchar* tess_eval_shader_template = "#version 430 core\n"
5910 "#extension GL_ARB_enhanced_layouts : require\n"
5912 "layout(isolines, point_mode) in;\n"
5924 static const GLchar* vertex_shader_template = "#version 430 core\n"
5925 "#extension GL_ARB_enhanced_layouts : require\n"
5937 const GLchar* result = 0;
5941 case Utils::Shader::COMPUTE:
5942 result = compute_shader_template;
5944 case Utils::Shader::FRAGMENT:
5945 result = fragment_shader_template;
5947 case Utils::Shader::GEOMETRY:
5948 result = geometry_shader_template;
5950 case Utils::Shader::TESS_CTRL:
5951 result = tess_ctrl_shader_template;
5953 case Utils::Shader::TESS_EVAL:
5954 result = tess_eval_shader_template;
5956 case Utils::Shader::VERTEX:
5957 result = vertex_shader_template;
5960 TCU_FAIL("Invalid enum");
5966 /** Prepare buffer according to descriptor
5968 * @param buffer Buffer to prepare
5969 * @param desc Descriptor
5971 void BufferTestBase::prepareBuffer(Utils::Buffer& buffer, bufferDescriptor& desc)
5973 GLsizeiptr size = 0;
5976 if (false == desc.m_initial_data.empty())
5978 size = desc.m_initial_data.size();
5979 data = &desc.m_initial_data[0];
5981 else if (false == desc.m_expected_data.empty())
5983 size = desc.m_expected_data.size();
5986 buffer.Init(desc.m_target, Utils::Buffer::StaticDraw, size, data);
5988 if (bufferDescriptor::m_non_indexed != desc.m_index)
5990 buffer.BindBase(desc.m_index);
5998 /** Prepare collection of buffer
6000 * @param descriptors Collection of descriptors
6001 * @param out_buffers Collection of buffers
6003 void BufferTestBase::prepareBuffers(bufferDescriptor::Vector& descriptors, bufferCollection& out_buffers)
6005 for (bufferDescriptor::Vector::iterator it = descriptors.begin(), end = descriptors.end(); end != it; ++it)
6007 bufferCollection::pair pair;
6009 pair.m_buffer = new Utils::Buffer(m_context);
6010 if (0 == pair.m_buffer)
6012 TCU_FAIL("Memory allocation failed");
6015 pair.m_descriptor = &(*it);
6017 prepareBuffer(*pair.m_buffer, *pair.m_descriptor);
6019 out_buffers.m_vector.push_back(pair);
6026 BufferTestBase::bufferCollection::~bufferCollection()
6028 for (Vector::iterator it = m_vector.begin(), end = m_vector.end(); end != it; ++it)
6030 if (0 != it->m_buffer)
6032 delete it->m_buffer;
6040 * @param context Test context
6041 * @param test_name Name of test
6042 * @param test_description Description of test
6044 NegativeTestBase::NegativeTestBase(deqp::Context& context, const GLchar* test_name, const GLchar* test_description)
6045 : TestBase(context, test_name, test_description)
6049 /** Selects if "compute" stage is relevant for test
6055 bool NegativeTestBase::isComputeRelevant(GLuint /* test_case_index */)
6060 /** Selects if compilation failure is expected result
6066 bool NegativeTestBase::isFailureExpected(GLuint /* test_case_index */)
6073 * @param test_case_index Id of test case
6075 * @return true if test case pass, false otherwise
6077 bool NegativeTestBase::testCase(GLuint test_case_index)
6079 bool test_case_result = true;
6082 if (true == isComputeRelevant(test_case_index))
6084 const std::string& cs_source = getShaderSource(test_case_index, Utils::Shader::COMPUTE);
6085 bool is_build_error = false;
6086 const bool is_failure_expected = isFailureExpected(test_case_index);
6087 Utils::Program program(m_context);
6091 program.Init(cs_source, "" /* fs */, "" /* gs */, "" /* tcs */, "" /* tes */, "" /* vs */,
6092 false /* separable */);
6094 catch (Utils::Shader::InvalidSourceException& exc)
6096 if (false == is_failure_expected)
6098 m_context.getTestContext().getLog()
6099 << tcu::TestLog::Message << "Unexpected error in shader compilation: " << tcu::TestLog::EndMessage;
6103 #if DEBUG_NEG_LOG_ERROR
6107 m_context.getTestContext().getLog()
6108 << tcu::TestLog::Message << "Error in shader compilation was expected, logged for verification: "
6109 << tcu::TestLog::EndMessage;
6113 #endif /* DEBUG_NEG_LOG_ERROR */
6115 is_build_error = true;
6117 catch (Utils::Program::BuildException& exc)
6119 if (false == is_failure_expected)
6121 m_context.getTestContext().getLog()
6122 << tcu::TestLog::Message << "Unexpected error in program linking: " << tcu::TestLog::EndMessage;
6126 #if DEBUG_NEG_LOG_ERROR
6130 m_context.getTestContext().getLog()
6131 << tcu::TestLog::Message
6132 << "Error in program linking was expected, logged for verification: " << tcu::TestLog::EndMessage;
6136 #endif /* DEBUG_NEG_LOG_ERROR */
6138 is_build_error = true;
6141 if (is_build_error != is_failure_expected)
6143 if (!is_build_error)
6145 m_context.getTestContext().getLog()
6146 << tcu::TestLog::Message << "Unexpected success: " << tcu::TestLog::EndMessage;
6147 Utils::Shader::LogSource(m_context, cs_source, Utils::Shader::COMPUTE);
6149 test_case_result = false;
6154 const std::string& fs_source = getShaderSource(test_case_index, Utils::Shader::FRAGMENT);
6155 const std::string& gs_source = getShaderSource(test_case_index, Utils::Shader::GEOMETRY);
6156 bool is_build_error = false;
6157 const bool is_failure_expected = isFailureExpected(test_case_index);
6158 Utils::Program program(m_context);
6159 const std::string& tcs_source = getShaderSource(test_case_index, Utils::Shader::TESS_CTRL);
6160 const std::string& tes_source = getShaderSource(test_case_index, Utils::Shader::TESS_EVAL);
6161 const std::string& vs_source = getShaderSource(test_case_index, Utils::Shader::VERTEX);
6165 program.Init("" /* cs */, fs_source, gs_source, tcs_source, tes_source, vs_source, false /* separable */);
6167 catch (Utils::Shader::InvalidSourceException& exc)
6169 if (false == is_failure_expected)
6171 m_context.getTestContext().getLog()
6172 << tcu::TestLog::Message << "Unexpected error in shader compilation: " << tcu::TestLog::EndMessage;
6176 #if DEBUG_NEG_LOG_ERROR
6180 m_context.getTestContext().getLog()
6181 << tcu::TestLog::Message << "Error in shader compilation was expected, logged for verification: "
6182 << tcu::TestLog::EndMessage;
6186 #endif /* DEBUG_NEG_LOG_ERROR */
6188 is_build_error = true;
6190 catch (Utils::Program::BuildException& exc)
6192 if (false == is_failure_expected)
6194 m_context.getTestContext().getLog()
6195 << tcu::TestLog::Message << "Unexpected error in program linking: " << tcu::TestLog::EndMessage;
6199 #if DEBUG_NEG_LOG_ERROR
6203 m_context.getTestContext().getLog()
6204 << tcu::TestLog::Message
6205 << "Error in program linking was expected, logged for verification: " << tcu::TestLog::EndMessage;
6209 #endif /* DEBUG_NEG_LOG_ERROR */
6211 is_build_error = true;
6214 if (is_build_error != is_failure_expected)
6216 if (!is_build_error)
6218 m_context.getTestContext().getLog()
6219 << tcu::TestLog::Message << "Unexpected success: " << tcu::TestLog::EndMessage;
6220 Utils::Shader::LogSource(m_context, vs_source, Utils::Shader::VERTEX);
6221 Utils::Shader::LogSource(m_context, tcs_source, Utils::Shader::TESS_CTRL);
6222 Utils::Shader::LogSource(m_context, tes_source, Utils::Shader::TESS_EVAL);
6223 Utils::Shader::LogSource(m_context, gs_source, Utils::Shader::GEOMETRY);
6224 Utils::Shader::LogSource(m_context, fs_source, Utils::Shader::FRAGMENT);
6226 test_case_result = false;
6230 return test_case_result;
6233 /* Constants used by TextureTestBase */
6234 const glw::GLuint TextureTestBase::m_width = 16;
6235 const glw::GLuint TextureTestBase::m_height = 16;
6239 * @param context Test context
6240 * @param test_name Name of test
6241 * @param test_description Description of test
6243 TextureTestBase::TextureTestBase(deqp::Context& context, const GLchar* test_name, const GLchar* test_description)
6244 : TestBase(context, test_name, test_description)
6248 /** Get locations for all inputs with automatic_location
6250 * @param program Program object
6251 * @param program_interface Interface of program
6253 void TextureTestBase::prepareAttribLocation(Utils::Program& program, Utils::ProgramInterface& program_interface)
6255 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
6257 Utils::Variable::PtrVector& inputs = si.m_inputs;
6259 for (Utils::Variable::PtrVector::iterator it = inputs.begin(); inputs.end() != it; ++it)
6261 /* Test does not specify location, query value and set */
6262 if (Utils::Variable::m_automatic_location == (*it)->m_descriptor.m_expected_location)
6264 GLuint index = program.GetResourceIndex((*it)->m_descriptor.m_name, GL_PROGRAM_INPUT);
6267 program.GetResource(GL_PROGRAM_INPUT, index, GL_LOCATION, 1 /* size */, &location);
6269 (*it)->m_descriptor.m_expected_location = location;
6274 /** Verifies contents of drawn image
6277 * @param color_0 Verified image
6279 * @return true if image is filled with 1, false otherwise
6281 bool TextureTestBase::checkResults(glw::GLuint /* test_case_index */, Utils::Texture& color_0)
6283 static const GLuint size = m_width * m_height;
6284 static const GLuint expected_color = 1;
6286 std::vector<GLuint> data;
6289 color_0.Get(GL_RED_INTEGER, GL_UNSIGNED_INT, &data[0]);
6291 for (GLuint i = 0; i < size; ++i)
6293 const GLuint color = data[i];
6295 if (expected_color != color)
6297 m_context.getTestContext().getLog() << tcu::TestLog::Message << "R32UI[" << i << "]:" << color
6298 << tcu::TestLog::EndMessage;
6306 /** Execute dispatch compute for 16x16x1
6310 void TextureTestBase::executeDispatchCall(GLuint /* test_case_index */)
6312 const Functions& gl = m_context.getRenderContext().getFunctions();
6314 gl.dispatchCompute(16 /* x */, 16 /* y */, 1 /* z */);
6315 GLU_EXPECT_NO_ERROR(gl.getError(), "DispatchCompute");
6318 /** Execute drawArrays for single vertex
6322 void TextureTestBase::executeDrawCall(GLuint /* test_case_index */)
6324 const Functions& gl = m_context.getRenderContext().getFunctions();
6326 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
6327 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
6330 /** Prepare code snippet that will pass in variables to out variables
6333 * @param varying_passthrough Collection of connections between in and out variables
6334 * @param stage Shader stage
6336 * @return Code that pass in variables to next stage
6338 std::string TextureTestBase::getPassSnippet(GLuint /* test_case_index */,
6339 Utils::VaryingPassthrough& varying_passthrough, Utils::Shader::STAGES stage)
6341 static const GLchar* separator = "\n ";
6343 /* Skip for compute shader */
6344 if (Utils::Shader::COMPUTE == stage)
6349 Utils::VaryingConnection::Vector& vector = varying_passthrough.Get(stage);
6351 std::string result = Utils::g_list;
6352 size_t position = 0;
6354 for (GLuint i = 0; i < vector.size(); ++i)
6357 Utils::VaryingConnection& connection = vector[i];
6359 Utils::Variable* in = connection.m_in;
6360 Utils::Variable* out = connection.m_out;
6362 Utils::Variable::FLAVOUR in_flavour = Utils::Variable::GetFlavour(stage, Utils::Variable::INPUT);
6363 Utils::Variable::FLAVOUR out_flavour = Utils::Variable::GetFlavour(stage, Utils::Variable::OUTPUT);
6365 const std::string passthrough =
6366 getVariablePassthrough("", in->m_descriptor, in_flavour, "", out->m_descriptor, out_flavour);
6368 Utils::insertElementOfList(passthrough.c_str(), separator, position, result);
6371 Utils::endList("", position, result);
6376 /** Basic implementation of method getProgramInterface
6382 void TextureTestBase::getProgramInterface(GLuint /* test_case_index */,
6383 Utils::ProgramInterface& /* program_interface */,
6384 Utils::VaryingPassthrough& /* varying_passthrough */)
6388 /** Prepare code snippet that will verify in and uniform variables
6391 * @param program_interface Interface of program
6392 * @param stage Shader stage
6394 * @return Code that verify variables
6396 std::string TextureTestBase::getVerificationSnippet(GLuint /* test_case_index */,
6397 Utils::ProgramInterface& program_interface,
6398 Utils::Shader::STAGES stage)
6400 static const GLchar* separator = " ||\n ";
6402 std::string verification = "if (LIST)\n"
6407 /* Get flavour of in and out variables */
6408 Utils::Variable::FLAVOUR in_flavour = Utils::Variable::GetFlavour(stage, Utils::Variable::INPUT);
6410 /* Get interface for shader stage */
6411 Utils::ShaderInterface& si = program_interface.GetShaderInterface(stage);
6413 /* There are no varialbes to verify */
6414 if ((0 == si.m_inputs.size()) && (0 == si.m_uniforms.size()) && (0 == si.m_ssb_blocks.size()))
6419 /* For each in variable insert verification code */
6420 size_t position = 0;
6422 for (GLuint i = 0; i < si.m_inputs.size(); ++i)
6424 const Utils::Variable& var = *si.m_inputs[i];
6425 const std::string& var_verification = getVariableVerifcation("", var.m_data, var.m_descriptor, in_flavour);
6427 Utils::insertElementOfList(var_verification.c_str(), separator, position, verification);
6430 /* For each unifrom variable insert verification code */
6431 for (GLuint i = 0; i < si.m_uniforms.size(); ++i)
6433 const Utils::Variable& var = *si.m_uniforms[i];
6434 const std::string& var_verification =
6435 getVariableVerifcation("", var.m_data, var.m_descriptor, Utils::Variable::BASIC);
6437 Utils::insertElementOfList(var_verification.c_str(), separator, position, verification);
6440 /* For each ssb variable insert verification code */
6441 for (GLuint i = 0; i < si.m_ssb_blocks.size(); ++i)
6443 const Utils::Variable& var = *si.m_ssb_blocks[i];
6444 const std::string& var_verification =
6445 getVariableVerifcation("", var.m_data, var.m_descriptor, Utils::Variable::BASIC);
6447 Utils::insertElementOfList(var_verification.c_str(), separator, position, verification);
6450 Utils::endList("", position, verification);
6452 #if DEBUG_TTB_VERIFICATION_SNIPPET_STAGE
6456 sprintf(buffer, "%d", stage + 10);
6457 Utils::replaceToken("0u", position, buffer, verification);
6460 #elif DEBUG_TTB_VERIFICATION_SNIPPET_VARIABLE
6462 if (Utils::Shader::VERTEX == stage)
6464 Utils::replaceToken("0u", position, "in_vs_first.x", verification);
6468 Utils::replaceToken("0u", position, "31u", verification);
6474 return verification;
6477 /** Selects if "compute" stage is relevant for test
6483 bool TextureTestBase::isComputeRelevant(GLuint /* test_case_index */)
6488 /** Selects if "draw" stages are relevant for test
6494 bool TextureTestBase::isDrawRelevant(GLuint /* test_case_index */)
6499 /** Prepare code that will do assignment of single in to single out
6501 * @param in_parent_name Name of parent in variable
6502 * @param in_variable Descriptor of in variable
6503 * @param in_flavour Flavoud of in variable
6504 * @param out_parent_name Name of parent out variable
6505 * @param out_variable Descriptor of out variable
6506 * @param out_flavour Flavoud of out variable
6508 * @return Code that does OUT = IN
6510 std::string TextureTestBase::getVariablePassthrough(const std::string& in_parent_name,
6511 const Utils::Variable::Descriptor& in_variable,
6512 Utils::Variable::FLAVOUR in_flavour,
6513 const std::string& out_parent_name,
6514 const Utils::Variable::Descriptor& out_variable,
6515 Utils::Variable::FLAVOUR out_flavour)
6519 GLuint member_index = 0;
6520 size_t position = 0;
6521 std::string result = Utils::g_list;
6522 static const GLchar* separator = ";\n ";
6524 /* For each member of each array element */
6527 const std::string in_name = Utils::Variable::GetReference(in_parent_name, in_variable, in_flavour, index);
6528 const std::string out_name = Utils::Variable::GetReference(out_parent_name, out_variable, out_flavour, index);
6529 std::string passthrough;
6531 /* Prepare verification */
6532 if (Utils::Variable::BUILTIN == in_variable.m_type)
6534 size_t pass_position = 0;
6536 passthrough = "OUT = IN;";
6538 Utils::replaceToken("OUT", pass_position, out_name.c_str(), passthrough);
6539 Utils::replaceToken("IN", pass_position, in_name.c_str(), passthrough);
6541 /* Increment index */
6546 const Utils::Interface* in_interface = in_variable.m_interface;
6547 const Utils::Interface* out_interface = out_variable.m_interface;
6549 if ((0 == in_interface) || (0 == out_interface))
6551 TCU_FAIL("Nullptr");
6554 const Utils::Variable::Descriptor& in_member = in_interface->m_members[member_index];
6555 const Utils::Variable::Descriptor& out_member = out_interface->m_members[member_index];
6557 passthrough = getVariablePassthrough(in_name, in_member, Utils::Variable::BASIC, out_name, out_member,
6558 Utils::Variable::BASIC);
6560 /* Increment member_index */
6563 /* Increment index and reset member_index if all members were processed */
6564 if (in_interface->m_members.size() == member_index)
6571 /* Check if loop should end */
6572 if ((index >= in_variable.m_n_array_elements) && (0 == member_index))
6577 Utils::insertElementOfList(passthrough.c_str(), separator, position, result);
6579 } while (true != done);
6581 Utils::endList("", position, result);
6587 /** Get verification of single variable
6589 * @param parent_name Name of parent variable
6590 * @param data Data that should be used as EXPECTED
6591 * @param variable Descriptor of variable
6592 * @param flavour Flavour of variable
6594 * @return Code that does (EXPECTED != VALUE) ||
6596 std::string TextureTestBase::getVariableVerifcation(const std::string& parent_name, const GLvoid* data,
6597 const Utils::Variable::Descriptor& variable,
6598 Utils::Variable::FLAVOUR flavour)
6600 static const GLchar* logic_op = " ||\n ";
6601 const GLuint n_elements = (0 == variable.m_n_array_elements) ? 1 : variable.m_n_array_elements;
6602 size_t position = 0;
6603 std::string result = Utils::g_list;
6604 GLint stride = variable.m_expected_stride_of_element;
6606 /* For each each array element */
6607 for (GLuint element = 0; element < n_elements; ++element)
6609 const std::string name = Utils::Variable::GetReference(parent_name, variable, flavour, element);
6611 /* Calculate data pointer */
6612 GLvoid* data_ptr = (GLvoid*)((GLubyte*)data + element * stride);
6614 /* Prepare verification */
6615 if (Utils::Variable::BUILTIN == variable.m_type)
6617 const std::string& expected = variable.m_builtin.GetGLSLConstructor(data_ptr);
6618 std::string verification;
6619 size_t verification_position = 0;
6621 verification = "(EXPECTED != NAME)";
6623 Utils::replaceToken("EXPECTED", verification_position, expected.c_str(), verification);
6624 Utils::replaceToken("NAME", verification_position, name.c_str(), verification);
6626 Utils::insertElementOfList(verification.c_str(), logic_op, position, result);
6630 const Utils::Interface* interface = variable.m_interface;
6634 TCU_FAIL("Nullptr");
6637 const GLuint n_members = static_cast<GLuint>(interface->m_members.size());
6639 /* for each member */
6640 for (GLuint member_index = 0; member_index < n_members; ++member_index)
6642 const Utils::Variable::Descriptor& member = interface->m_members[member_index];
6644 /* Get verification of member */
6645 const std::string& verification =
6646 getVariableVerifcation(name, (GLubyte*)data_ptr + member.m_offset, member, Utils::Variable::BASIC);
6648 Utils::insertElementOfList(verification.c_str(), logic_op, position, result);
6653 Utils::endList("", position, result);
6658 /** Prepare attributes, vertex array object and array buffer
6660 * @param test_case_index Index of test case
6661 * @param program_interface Interface of program
6662 * @param buffer Array buffer
6663 * @param vao Vertex array object
6665 void TextureTestBase::prepareAttributes(GLuint test_case_index, Utils::ProgramInterface& program_interface,
6666 Utils::Buffer& buffer, Utils::VertexArray& vao)
6668 bool use_component_qualifier = useComponentQualifier(test_case_index);
6670 /* Get shader interface */
6671 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
6673 /* Bind vao and buffer */
6677 /* Skip if there are no input variables in vertex shader */
6678 if (0 == si.m_inputs.size())
6683 /* Calculate vertex stride and check */
6684 GLint vertex_stride = 0;
6686 for (GLuint i = 0; i < si.m_inputs.size(); ++i)
6688 Utils::Variable& variable = *si.m_inputs[i];
6690 GLint variable_size = static_cast<GLuint>(variable.m_data_size);
6692 GLint ends_at = variable_size + variable.m_descriptor.m_offset;
6694 vertex_stride = std::max(vertex_stride, ends_at);
6697 /* Prepare buffer data and set up vao */
6698 std::vector<GLubyte> buffer_data;
6699 buffer_data.resize(vertex_stride);
6701 GLubyte* ptr = &buffer_data[0];
6703 for (GLuint i = 0; i < si.m_inputs.size(); ++i)
6705 Utils::Variable& variable = *si.m_inputs[i];
6707 memcpy(ptr + variable.m_descriptor.m_offset, variable.m_data, variable.m_data_size);
6709 if (false == use_component_qualifier)
6711 vao.Attribute(variable.m_descriptor.m_expected_location, variable.m_descriptor.m_builtin,
6712 variable.m_descriptor.m_n_array_elements, variable.m_descriptor.m_normalized,
6713 variable.GetStride(), (GLvoid*)(intptr_t)variable.m_descriptor.m_offset);
6715 else if (0 == variable.m_descriptor.m_expected_component)
6717 /* Components can only be applied to vectors.
6718 Assumption that test use all 4 components */
6719 const Utils::Type& type =
6720 Utils::Type::GetType(variable.m_descriptor.m_builtin.m_basic_type, 1 /* n_columns */, 4 /* n_rows */);
6722 vao.Attribute(variable.m_descriptor.m_expected_location, type, variable.m_descriptor.m_n_array_elements,
6723 variable.m_descriptor.m_normalized, variable.GetStride(),
6724 (GLvoid*)(intptr_t)variable.m_descriptor.m_offset);
6729 buffer.Data(Utils::Buffer::StaticDraw, vertex_stride, ptr);
6732 /** Get locations for all outputs with automatic_location
6734 * @param program Program object
6735 * @param program_interface Interface of program
6737 void TextureTestBase::prepareFragmentDataLoc(Utils::Program& program, Utils::ProgramInterface& program_interface)
6739 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
6740 Utils::Variable::PtrVector& outputs = si.m_outputs;
6742 for (Utils::Variable::PtrVector::iterator it = outputs.begin(); outputs.end() != it; ++it)
6744 /* Test does not specify location, query value and set */
6745 if (Utils::Variable::m_automatic_location == (*it)->m_descriptor.m_expected_location)
6747 GLuint index = program.GetResourceIndex((*it)->m_descriptor.m_name, GL_PROGRAM_OUTPUT);
6750 program.GetResource(GL_PROGRAM_OUTPUT, index, GL_LOCATION, 1 /* size */, &location);
6752 (*it)->m_descriptor.m_expected_location = location;
6757 /** Prepare framebuffer with single texture as color attachment
6759 * @param framebuffer Framebuffer
6760 * @param color_0_texture Texture that will used as color attachment
6762 void TextureTestBase::prepareFramebuffer(Utils::Framebuffer& framebuffer, Utils::Texture& color_0_texture)
6765 std::vector<GLuint> texture_data;
6766 texture_data.resize(m_width * m_height);
6768 for (GLuint i = 0; i < texture_data.size(); ++i)
6770 texture_data[i] = 0x20406080;
6773 /* Prepare texture */
6774 color_0_texture.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT,
6777 /* Prepare framebuffer */
6780 framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0, color_0_texture.m_id, m_width, m_height);
6782 framebuffer.ClearColor(0.0f, 0.0f, 0.0f, 0.0f);
6783 framebuffer.Clear(GL_COLOR_BUFFER_BIT);
6786 /** Prepare iamge unit for compute shader
6788 * @param location Uniform location
6789 * @param image_texture Texture that will used as color attachment
6791 void TextureTestBase::prepareImage(GLint location, Utils::Texture& image_texture) const
6793 static const GLuint image_unit = 0;
6795 std::vector<GLuint> texture_data;
6796 texture_data.resize(m_width * m_height);
6798 for (GLuint i = 0; i < texture_data.size(); ++i)
6800 texture_data[i] = 0x20406080;
6803 image_texture.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT,
6806 const Functions& gl = m_context.getRenderContext().getFunctions();
6808 gl.bindImageTexture(image_unit, image_texture.m_id, 0 /* level */, GL_FALSE /* layered */, 0 /* Layer */,
6809 GL_WRITE_ONLY, GL_R32UI);
6810 GLU_EXPECT_NO_ERROR(gl.getError(), "BindImageTexture");
6812 Utils::Program::Uniform(gl, Utils::Type::_int, 1 /* count */, location, &image_unit);
6815 /** Basic implementation
6818 * @param si Shader interface
6819 * @param program Program
6820 * @param cs_buffer Buffer for ssb blocks
6822 void TextureTestBase::prepareSSBs(GLuint /* test_case_index */, Utils::ShaderInterface& si, Utils::Program& program,
6823 Utils::Buffer& buffer)
6825 /* Skip if there are no input variables in vertex shader */
6826 if (0 == si.m_ssb_blocks.size())
6831 /* Calculate vertex stride */
6832 GLint ssbs_stride = 0;
6834 for (GLuint i = 0; i < si.m_ssb_blocks.size(); ++i)
6836 Utils::Variable& variable = *si.m_ssb_blocks[i];
6838 if (false == variable.IsBlock())
6843 GLint variable_stride = variable.GetStride();
6845 GLint ends_at = variable_stride + variable.m_descriptor.m_offset;
6847 ssbs_stride = std::max(ssbs_stride, ends_at);
6850 /* Set active program */
6855 buffer.Data(Utils::Buffer::StaticDraw, ssbs_stride, 0);
6857 /* Set up uniforms */
6858 for (GLuint i = 0; i < si.m_ssb_blocks.size(); ++i)
6860 Utils::Variable& variable = *si.m_ssb_blocks[i];
6862 /* prepareUnifor should work fine for ssb blocks */
6863 prepareUniform(program, variable, buffer);
6867 /** Basic implementation
6869 * @param test_case_index Test case index
6870 * @param program_interface Program interface
6871 * @param program Program
6872 * @param cs_buffer Buffer for compute shader stage
6874 void TextureTestBase::prepareSSBs(GLuint test_case_index, Utils::ProgramInterface& program_interface,
6875 Utils::Program& program, Utils::Buffer& cs_buffer)
6877 cs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
6879 Utils::ShaderInterface& cs = program_interface.GetShaderInterface(Utils::Shader::COMPUTE);
6881 prepareSSBs(test_case_index, cs, program, cs_buffer);
6883 cs_buffer.BindBase(Utils::Shader::COMPUTE);
6886 /** Basic implementation
6888 * @param test_case_index Test case index
6889 * @param program_interface Program interface
6890 * @param program Program
6891 * @param fs_buffer Buffer for fragment shader stage
6892 * @param gs_buffer Buffer for geometry shader stage
6893 * @param tcs_buffer Buffer for tessellation control shader stage
6894 * @param tes_buffer Buffer for tessellation evaluation shader stage
6895 * @param vs_buffer Buffer for vertex shader stage
6897 void TextureTestBase::prepareSSBs(GLuint test_case_index, Utils::ProgramInterface& program_interface,
6898 Utils::Program& program, Utils::Buffer& fs_buffer, Utils::Buffer& gs_buffer,
6899 Utils::Buffer& tcs_buffer, Utils::Buffer& tes_buffer, Utils::Buffer& vs_buffer)
6901 fs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
6902 gs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
6903 tcs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
6904 tes_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
6905 vs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
6907 Utils::ShaderInterface& fs = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
6908 Utils::ShaderInterface& gs = program_interface.GetShaderInterface(Utils::Shader::GEOMETRY);
6909 Utils::ShaderInterface& tcs = program_interface.GetShaderInterface(Utils::Shader::TESS_CTRL);
6910 Utils::ShaderInterface& tes = program_interface.GetShaderInterface(Utils::Shader::TESS_EVAL);
6911 Utils::ShaderInterface& vs = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
6913 prepareSSBs(test_case_index, fs, program, fs_buffer);
6914 prepareSSBs(test_case_index, gs, program, gs_buffer);
6915 prepareSSBs(test_case_index, tcs, program, tcs_buffer);
6916 prepareSSBs(test_case_index, tes, program, tes_buffer);
6917 prepareSSBs(test_case_index, vs, program, vs_buffer);
6919 fs_buffer.BindBase(Utils::Shader::FRAGMENT);
6920 gs_buffer.BindBase(Utils::Shader::GEOMETRY);
6921 tcs_buffer.BindBase(Utils::Shader::TESS_CTRL);
6922 tes_buffer.BindBase(Utils::Shader::TESS_EVAL);
6923 vs_buffer.BindBase(Utils::Shader::VERTEX);
6926 /** Updates buffer data with variable
6928 * @param program Program object
6929 * @param variable Variable
6930 * @param buffer Buffer
6932 void TextureTestBase::prepareUniform(Utils::Program& program, Utils::Variable& variable, Utils::Buffer& buffer)
6934 const Functions& gl = m_context.getRenderContext().getFunctions();
6936 GLsizei count = variable.m_descriptor.m_n_array_elements;
6942 if (Utils::Variable::BUILTIN == variable.m_descriptor.m_type)
6944 program.Uniform(gl, variable.m_descriptor.m_builtin, count, variable.m_descriptor.m_expected_location,
6949 const bool is_block = variable.IsBlock();
6951 if (false == is_block)
6953 TCU_FAIL("Not implemented");
6957 buffer.SubData(variable.m_descriptor.m_offset, variable.m_descriptor.m_expected_stride_of_element * count,
6963 /** Basic implementation
6966 * @param si Shader interface
6967 * @param program Program
6968 * @param cs_buffer Buffer for uniform blocks
6970 void TextureTestBase::prepareUniforms(GLuint /* test_case_index */, Utils::ShaderInterface& si, Utils::Program& program,
6971 Utils::Buffer& buffer)
6973 /* Skip if there are no input variables in vertex shader */
6974 if (0 == si.m_uniforms.size())
6979 /* Calculate vertex stride */
6980 GLint uniforms_stride = 0;
6982 for (GLuint i = 0; i < si.m_uniforms.size(); ++i)
6984 Utils::Variable& variable = *si.m_uniforms[i];
6986 if (false == variable.IsBlock())
6991 GLint variable_stride = variable.GetStride();
6993 GLint ends_at = variable_stride + variable.m_descriptor.m_offset;
6995 uniforms_stride = std::max(uniforms_stride, ends_at);
6998 /* Set active program */
7003 buffer.Data(Utils::Buffer::StaticDraw, uniforms_stride, 0);
7005 /* Set up uniforms */
7006 for (GLuint i = 0; i < si.m_uniforms.size(); ++i)
7008 Utils::Variable& variable = *si.m_uniforms[i];
7010 prepareUniform(program, variable, buffer);
7014 /** Basic implementation
7016 * @param test_case_index Test case index
7017 * @param program_interface Program interface
7018 * @param program Program
7019 * @param cs_buffer Buffer for compute shader stage
7021 void TextureTestBase::prepareUniforms(GLuint test_case_index, Utils::ProgramInterface& program_interface,
7022 Utils::Program& program, Utils::Buffer& cs_buffer)
7024 cs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7026 Utils::ShaderInterface& cs = program_interface.GetShaderInterface(Utils::Shader::COMPUTE);
7028 prepareUniforms(test_case_index, cs, program, cs_buffer);
7030 cs_buffer.BindBase(Utils::Shader::COMPUTE);
7033 /** Basic implementation
7035 * @param test_case_index Test case index
7036 * @param program_interface Program interface
7037 * @param program Program
7038 * @param fs_buffer Buffer for fragment shader stage
7039 * @param gs_buffer Buffer for geometry shader stage
7040 * @param tcs_buffer Buffer for tessellation control shader stage
7041 * @param tes_buffer Buffer for tessellation evaluation shader stage
7042 * @param vs_buffer Buffer for vertex shader stage
7044 void TextureTestBase::prepareUniforms(GLuint test_case_index, Utils::ProgramInterface& program_interface,
7045 Utils::Program& program, Utils::Buffer& fs_buffer, Utils::Buffer& gs_buffer,
7046 Utils::Buffer& tcs_buffer, Utils::Buffer& tes_buffer, Utils::Buffer& vs_buffer)
7048 fs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7049 gs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7050 tcs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7051 tes_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7052 vs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7054 Utils::ShaderInterface& fs = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
7055 Utils::ShaderInterface& gs = program_interface.GetShaderInterface(Utils::Shader::GEOMETRY);
7056 Utils::ShaderInterface& tcs = program_interface.GetShaderInterface(Utils::Shader::TESS_CTRL);
7057 Utils::ShaderInterface& tes = program_interface.GetShaderInterface(Utils::Shader::TESS_EVAL);
7058 Utils::ShaderInterface& vs = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
7060 prepareUniforms(test_case_index, fs, program, fs_buffer);
7061 prepareUniforms(test_case_index, gs, program, gs_buffer);
7062 prepareUniforms(test_case_index, tcs, program, tcs_buffer);
7063 prepareUniforms(test_case_index, tes, program, tes_buffer);
7064 prepareUniforms(test_case_index, vs, program, vs_buffer);
7066 fs_buffer.BindBase(Utils::Shader::FRAGMENT);
7067 gs_buffer.BindBase(Utils::Shader::GEOMETRY);
7068 tcs_buffer.BindBase(Utils::Shader::TESS_CTRL);
7069 tes_buffer.BindBase(Utils::Shader::TESS_EVAL);
7070 vs_buffer.BindBase(Utils::Shader::VERTEX);
7073 /** Basic implementation
7075 * @param test_case_index Test case index
7076 * @param program_interface Program interface
7077 * @param program Program
7078 * @param fs_buffer Buffer for fragment shader stage
7079 * @param gs_buffer Buffer for geometry shader stage
7080 * @param tcs_buffer Buffer for tessellation control shader stage
7081 * @param tes_buffer Buffer for tessellation evaluation shader stage
7082 * @param vs_buffer Buffer for vertex shader stage
7084 void TextureTestBase::prepareUniforms(GLuint test_case_index, Utils::ProgramInterface& program_interface,
7085 Utils::Program& fs_program, Utils::Program& gs_program,
7086 Utils::Program& tcs_program, Utils::Program& tes_program,
7087 Utils::Program& vs_program, Utils::Buffer& fs_buffer, Utils::Buffer& gs_buffer,
7088 Utils::Buffer& tcs_buffer, Utils::Buffer& tes_buffer, Utils::Buffer& vs_buffer)
7090 fs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7091 gs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7092 tcs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7093 tes_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7094 vs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7096 Utils::ShaderInterface& fs = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
7097 Utils::ShaderInterface& gs = program_interface.GetShaderInterface(Utils::Shader::GEOMETRY);
7098 Utils::ShaderInterface& tcs = program_interface.GetShaderInterface(Utils::Shader::TESS_CTRL);
7099 Utils::ShaderInterface& tes = program_interface.GetShaderInterface(Utils::Shader::TESS_EVAL);
7100 Utils::ShaderInterface& vs = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
7102 prepareUniforms(test_case_index, fs, fs_program, fs_buffer);
7103 fs_buffer.BindBase(Utils::Shader::FRAGMENT);
7105 prepareUniforms(test_case_index, gs, gs_program, gs_buffer);
7106 gs_buffer.BindBase(Utils::Shader::GEOMETRY);
7108 prepareUniforms(test_case_index, tcs, tcs_program, tcs_buffer);
7109 tcs_buffer.BindBase(Utils::Shader::TESS_CTRL);
7111 prepareUniforms(test_case_index, tes, tes_program, tes_buffer);
7112 tes_buffer.BindBase(Utils::Shader::TESS_EVAL);
7114 prepareUniforms(test_case_index, vs, vs_program, vs_buffer);
7115 vs_buffer.BindBase(Utils::Shader::VERTEX);
7118 /** Prepare source for shader
7120 * @param test_case_index Index of test case
7121 * @param program_interface Interface of program
7122 * @param varying_passthrough Collection of connection between in and out variables
7123 * @param stage Shader stage
7125 * @return Source of shader
7127 std::string TextureTestBase::getShaderSource(GLuint test_case_index, Utils::ProgramInterface& program_interface,
7128 Utils::VaryingPassthrough& varying_passthrough,
7129 Utils::Shader::STAGES stage)
7132 const GLchar* shader_template = getShaderTemplate(stage);
7133 const std::string& shader_interface = program_interface.GetInterfaceForStage(stage);
7135 const std::string& verification = getVerificationSnippet(test_case_index, program_interface, stage);
7137 const std::string& passthrough = getPassSnippet(test_case_index, varying_passthrough, stage);
7139 const GLchar* per_vertex = "";
7141 std::string source = shader_template;
7142 size_t position = 0;
7144 /* Replace tokens in template */
7145 if (Utils::Shader::GEOMETRY == stage)
7147 if (false == useMonolithicProgram(test_case_index))
7149 per_vertex = "out gl_PerVertex {\n"
7150 "vec4 gl_Position;\n"
7155 Utils::replaceToken("PERVERTEX", position, per_vertex, source);
7158 Utils::replaceToken("INTERFACE", position, shader_interface.c_str(), source);
7159 Utils::replaceToken("VERIFICATION", position, verification.c_str(), source);
7161 if (false == verification.empty())
7163 Utils::replaceAllTokens("ELSE", " else ", source);
7167 Utils::replaceAllTokens("ELSE", "", source);
7170 Utils::replaceAllTokens("PASSTHROUGH", passthrough.c_str(), source);
7176 /** Returns template of shader for given stage
7178 * @param stage Shade stage
7180 * @return Proper template
7182 const GLchar* TextureTestBase::getShaderTemplate(Utils::Shader::STAGES stage)
7185 static const GLchar* compute_shader_template =
7186 "#version 430 core\n"
7187 "#extension GL_ARB_enhanced_layouts : require\n"
7189 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
7191 "writeonly uniform uimage2D uni_image;\n"
7197 " uint result = 1u;\n"
7201 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), uvec4(result, 0, 0, 0));\n"
7205 static const GLchar* fragment_shader_template = "#version 430 core\n"
7206 "#extension GL_ARB_enhanced_layouts : require\n"
7208 "flat in uint gs_fs_result;\n"
7209 " out uint fs_out_result;\n"
7215 " uint result = 1u;\n"
7217 " if (1u != gs_fs_result)\n"
7219 " result = gs_fs_result;\n"
7223 " fs_out_result = result;\n"
7228 static const GLchar* geometry_shader_template =
7229 "#version 430 core\n"
7230 "#extension GL_ARB_enhanced_layouts : require\n"
7232 "layout(points) in;\n"
7233 "layout(triangle_strip, max_vertices = 4) out;\n"
7235 " in uint tes_gs_result[];\n"
7236 "flat out uint gs_fs_result;\n"
7238 "PERVERTEX" /* Separable programs require explicit declaration of gl_PerVertex */
7243 " uint result = 1u;\n"
7245 " if (1u != tes_gs_result[0])\n"
7247 " result = tes_gs_result[0];\n"
7251 " gs_fs_result = result;\n"
7253 " gl_Position = vec4(-1, -1, 0, 1);\n"
7255 " gs_fs_result = result;\n"
7257 " gl_Position = vec4(-1, 1, 0, 1);\n"
7259 " gs_fs_result = result;\n"
7261 " gl_Position = vec4(1, -1, 0, 1);\n"
7263 " gs_fs_result = result;\n"
7265 " gl_Position = vec4(1, 1, 0, 1);\n"
7270 static const GLchar* tess_ctrl_shader_template = "#version 430 core\n"
7271 "#extension GL_ARB_enhanced_layouts : require\n"
7273 "layout(vertices = 1) out;\n"
7275 "in uint vs_tcs_result[];\n"
7276 "out uint tcs_tes_result[];\n"
7282 " uint result = 1u;\n"
7284 " if (1u != vs_tcs_result[gl_InvocationID])\n"
7286 " result = vs_tcs_result[gl_InvocationID];\n"
7290 " tcs_tes_result[gl_InvocationID] = result;\n"
7294 " gl_TessLevelOuter[0] = 1.0;\n"
7295 " gl_TessLevelOuter[1] = 1.0;\n"
7296 " gl_TessLevelOuter[2] = 1.0;\n"
7297 " gl_TessLevelOuter[3] = 1.0;\n"
7298 " gl_TessLevelInner[0] = 1.0;\n"
7299 " gl_TessLevelInner[1] = 1.0;\n"
7303 static const GLchar* tess_eval_shader_template = "#version 430 core\n"
7304 "#extension GL_ARB_enhanced_layouts : require\n"
7306 "layout(isolines, point_mode) in;\n"
7308 "in uint tcs_tes_result[];\n"
7309 "out uint tes_gs_result;\n"
7315 " uint result = 1u;\n"
7317 " if (1 != tcs_tes_result[0])\n"
7319 " result = tcs_tes_result[0];\n"
7323 " tes_gs_result = result;\n"
7329 static const GLchar* vertex_shader_template = "#version 430 core\n"
7330 "#extension GL_ARB_enhanced_layouts : require\n"
7332 "out uint vs_tcs_result;\n"
7338 " uint result = 1u;\n"
7342 " vs_tcs_result = result;\n"
7348 const GLchar* result = 0;
7352 case Utils::Shader::COMPUTE:
7353 result = compute_shader_template;
7355 case Utils::Shader::FRAGMENT:
7356 result = fragment_shader_template;
7358 case Utils::Shader::GEOMETRY:
7359 result = geometry_shader_template;
7361 case Utils::Shader::TESS_CTRL:
7362 result = tess_ctrl_shader_template;
7364 case Utils::Shader::TESS_EVAL:
7365 result = tess_eval_shader_template;
7367 case Utils::Shader::VERTEX:
7368 result = vertex_shader_template;
7371 TCU_FAIL("Invalid enum");
7379 * @param test_case_index Id of test case
7381 * @return true if test case pass, false otherwise
7383 bool TextureTestBase::testCase(GLuint test_case_index)
7387 if (true == useMonolithicProgram(test_case_index))
7389 return testMonolithic(test_case_index);
7393 return testSeparable(test_case_index);
7396 catch (Utils::Shader::InvalidSourceException& exc)
7399 TCU_FAIL(exc.what());
7401 catch (Utils::Program::BuildException& exc)
7403 TCU_FAIL(exc.what());
7407 /** Runs "draw" test with monolithic program
7409 * @param test_case_index Id of test case
7411 bool TextureTestBase::testMonolithic(GLuint test_case_index)
7413 Utils::ProgramInterface program_interface;
7414 Utils::VaryingPassthrough varying_passthrough;
7417 const std::string& test_name = getTestCaseName(test_case_index);
7420 getProgramInterface(test_case_index, program_interface, varying_passthrough);
7424 if (true == isDrawRelevant(test_case_index))
7426 Utils::Buffer buffer_attr(m_context);
7427 Utils::Buffer buffer_ssb_fs(m_context);
7428 Utils::Buffer buffer_ssb_gs(m_context);
7429 Utils::Buffer buffer_ssb_tcs(m_context);
7430 Utils::Buffer buffer_ssb_tes(m_context);
7431 Utils::Buffer buffer_ssb_vs(m_context);
7432 Utils::Buffer buffer_u_fs(m_context);
7433 Utils::Buffer buffer_u_gs(m_context);
7434 Utils::Buffer buffer_u_tcs(m_context);
7435 Utils::Buffer buffer_u_tes(m_context);
7436 Utils::Buffer buffer_u_vs(m_context);
7437 Utils::Framebuffer framebuffer(m_context);
7438 Utils::Program program(m_context);
7439 Utils::Texture texture_fb(m_context);
7440 Utils::VertexArray vao(m_context);
7443 const std::string& fragment_shader =
7444 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::FRAGMENT);
7445 const std::string& geometry_shader =
7446 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::GEOMETRY);
7447 const std::string& tess_ctrl_shader =
7448 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::TESS_CTRL);
7449 const std::string& tess_eval_shader =
7450 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::TESS_EVAL);
7451 const std::string& vertex_shader =
7452 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::VERTEX);
7454 program.Init("" /* compute_shader */, fragment_shader, geometry_shader, tess_ctrl_shader, tess_eval_shader,
7455 vertex_shader, false /* is_separable */);
7458 prepareAttribLocation(program, program_interface);
7459 prepareFragmentDataLoc(program, program_interface);
7462 std::stringstream stream;
7463 if (false == Utils::checkMonolithicDrawProgramInterface(program, program_interface, stream))
7465 m_context.getTestContext().getLog()
7466 << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7467 << ". Inspection of draw program interface failed:\n"
7468 << stream.str() << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(vertex_shader)
7469 << tcu::TestLog::KernelSource(tess_ctrl_shader) << tcu::TestLog::KernelSource(tess_eval_shader)
7470 << tcu::TestLog::KernelSource(geometry_shader) << tcu::TestLog::KernelSource(fragment_shader);
7479 buffer_attr.Init(Utils::Buffer::Array, Utils::Buffer::StaticDraw, 0, 0);
7481 prepareAttributes(test_case_index, program_interface, buffer_attr, vao);
7484 prepareUniforms(test_case_index, program_interface, program, buffer_u_fs, buffer_u_gs, buffer_u_tcs,
7485 buffer_u_tes, buffer_u_vs);
7487 prepareSSBs(test_case_index, program_interface, program, buffer_ssb_fs, buffer_ssb_gs, buffer_ssb_tcs,
7488 buffer_ssb_tes, buffer_ssb_vs);
7491 prepareFramebuffer(framebuffer, texture_fb);
7494 executeDrawCall(test_case_index);
7497 m_context.getRenderContext().postIterate();
7501 if (false == checkResults(test_case_index, texture_fb))
7503 m_context.getTestContext().getLog()
7504 << tcu::TestLog::Message << "FAILURE. Test case: " << test_name << ". Draw - invalid results."
7505 << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(vertex_shader)
7506 << tcu::TestLog::KernelSource(tess_ctrl_shader) << tcu::TestLog::KernelSource(tess_eval_shader)
7507 << tcu::TestLog::KernelSource(geometry_shader) << tcu::TestLog::KernelSource(fragment_shader);
7514 if (true == isComputeRelevant(test_case_index))
7516 Utils::Buffer buffer_ssb_cs(m_context);
7517 Utils::Buffer buffer_u_cs(m_context);
7518 Utils::Program program(m_context);
7519 Utils::Texture texture_im(m_context);
7520 Utils::VertexArray vao(m_context);
7523 const std::string& compute_shader =
7524 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::COMPUTE);
7526 program.Init(compute_shader, "" /* fragment_shader */, "" /* geometry_shader */, "" /* tess_ctrl_shader */,
7527 "" /* tess_eval_shader */, "" /* vertex_shader */, false /* is_separable */);
7531 std::stringstream stream;
7533 if (false == Utils::checkMonolithicComputeProgramInterface(program, program_interface, stream))
7535 m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7536 << ". Inspection of compute program interface failed:\n"
7537 << stream.str() << tcu::TestLog::EndMessage;
7551 prepareUniforms(test_case_index, program_interface, program, buffer_u_cs);
7553 prepareSSBs(test_case_index, program_interface, program, buffer_ssb_cs);
7556 GLint image_location = program.GetUniformLocation("uni_image");
7557 prepareImage(image_location, texture_im);
7560 executeDispatchCall(test_case_index);
7563 m_context.getRenderContext().postIterate();
7567 if (false == checkResults(test_case_index, texture_im))
7569 m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7570 << ". Compute - invalid results." << tcu::TestLog::EndMessage
7571 << tcu::TestLog::KernelSource(compute_shader);
7580 /** Runs "draw" test with separable program
7582 * @param test_case_index Id of test case
7584 bool TextureTestBase::testSeparable(GLuint test_case_index)
7586 Utils::ProgramInterface program_interface;
7587 Utils::VaryingPassthrough varying_passthrough;
7590 const std::string& test_name = getTestCaseName(test_case_index);
7593 getProgramInterface(test_case_index, program_interface, varying_passthrough);
7597 if (true == isDrawRelevant(test_case_index))
7599 Utils::Buffer buffer_attr(m_context);
7600 Utils::Buffer buffer_u_fs(m_context);
7601 Utils::Buffer buffer_u_gs(m_context);
7602 Utils::Buffer buffer_u_tcs(m_context);
7603 Utils::Buffer buffer_u_tes(m_context);
7604 Utils::Buffer buffer_u_vs(m_context);
7605 Utils::Framebuffer framebuffer(m_context);
7606 Utils::Pipeline pipeline(m_context);
7607 Utils::Program program_fs(m_context);
7608 Utils::Program program_gs(m_context);
7609 Utils::Program program_tcs(m_context);
7610 Utils::Program program_tes(m_context);
7611 Utils::Program program_vs(m_context);
7612 Utils::Texture texture_fb(m_context);
7613 Utils::VertexArray vao(m_context);
7616 const std::string& fs =
7617 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::FRAGMENT);
7618 const std::string& gs =
7619 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::GEOMETRY);
7620 const std::string& tcs =
7621 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::TESS_CTRL);
7622 const std::string& tes =
7623 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::TESS_EVAL);
7624 const std::string& vs =
7625 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::VERTEX);
7627 program_fs.Init("" /*cs*/, fs, "" /*gs*/, "" /*tcs*/, "" /*tes*/, "" /*vs*/, true /* is_separable */);
7628 program_gs.Init("" /*cs*/, "" /*fs*/, gs, "" /*tcs*/, "" /*tes*/, "" /*vs*/, true /* is_separable */);
7629 program_tcs.Init("" /*cs*/, "" /*fs*/, "" /*gs*/, tcs, "" /*tes*/, "" /*vs*/, true /* is_separable */);
7630 program_tes.Init("" /*cs*/, "" /*fs*/, "" /*gs*/, "" /*tcs*/, tes, "" /*vs*/, true /* is_separable */);
7631 program_vs.Init("" /*cs*/, "" /*fs*/, "" /*gs*/, "" /*tcs*/, "" /*tes*/, vs, true /* is_separable */);
7634 prepareAttribLocation(program_vs, program_interface);
7635 prepareFragmentDataLoc(program_vs, program_interface);
7638 std::stringstream stream;
7640 Utils::checkSeparableDrawProgramInterface(program_vs, program_interface, Utils::Shader::VERTEX, stream)) ||
7641 (false == Utils::checkSeparableDrawProgramInterface(program_fs, program_interface, Utils::Shader::FRAGMENT,
7643 (false == Utils::checkSeparableDrawProgramInterface(program_gs, program_interface, Utils::Shader::GEOMETRY,
7645 (false == Utils::checkSeparableDrawProgramInterface(program_tcs, program_interface,
7646 Utils::Shader::TESS_CTRL, stream)) ||
7647 (false == Utils::checkSeparableDrawProgramInterface(program_tes, program_interface,
7648 Utils::Shader::TESS_EVAL, stream)))
7650 m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7651 << ". Inspection of separable draw program interface failed:\n"
7652 << stream.str() << tcu::TestLog::EndMessage
7653 << tcu::TestLog::KernelSource(vs) << tcu::TestLog::KernelSource(tcs)
7654 << tcu::TestLog::KernelSource(tes) << tcu::TestLog::KernelSource(gs)
7655 << tcu::TestLog::KernelSource(fs);
7662 pipeline.UseProgramStages(program_fs.m_id, GL_FRAGMENT_SHADER_BIT);
7663 pipeline.UseProgramStages(program_gs.m_id, GL_GEOMETRY_SHADER_BIT);
7664 pipeline.UseProgramStages(program_tcs.m_id, GL_TESS_CONTROL_SHADER_BIT);
7665 pipeline.UseProgramStages(program_tes.m_id, GL_TESS_EVALUATION_SHADER_BIT);
7666 pipeline.UseProgramStages(program_vs.m_id, GL_VERTEX_SHADER_BIT);
7671 buffer_attr.Init(Utils::Buffer::Array, Utils::Buffer::StaticDraw, 0, 0);
7673 prepareAttributes(test_case_index, program_interface, buffer_attr, vao);
7676 prepareUniforms(test_case_index, program_interface, program_fs, program_gs, program_tcs, program_tes,
7677 program_vs, buffer_u_fs, buffer_u_gs, buffer_u_tcs, buffer_u_tes, buffer_u_vs);
7679 Utils::Program::Use(m_context.getRenderContext().getFunctions(), Utils::Program::m_invalid_id);
7682 prepareFramebuffer(framebuffer, texture_fb);
7685 executeDrawCall(test_case_index);
7688 m_context.getRenderContext().postIterate();
7692 if (false == checkResults(test_case_index, texture_fb))
7694 m_context.getTestContext().getLog()
7695 << tcu::TestLog::Message << "FAILURE. Test case: " << test_name << ". Draw - invalid results."
7696 << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(vs) << tcu::TestLog::KernelSource(tcs)
7697 << tcu::TestLog::KernelSource(tes) << tcu::TestLog::KernelSource(gs) << tcu::TestLog::KernelSource(fs);
7704 if (true == isComputeRelevant(test_case_index))
7706 Utils::Buffer buffer_u_cs(m_context);
7707 Utils::Program program(m_context);
7708 Utils::Texture texture_im(m_context);
7709 Utils::VertexArray vao(m_context);
7712 const std::string& compute_shader =
7713 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::COMPUTE);
7715 program.Init(compute_shader, "" /* fragment_shader */, "" /* geometry_shader */, "" /* tess_ctrl_shader */,
7716 "" /* tess_eval_shader */, "" /* vertex_shader */, false /* is_separable */);
7720 std::stringstream stream;
7722 if (false == Utils::checkMonolithicComputeProgramInterface(program, program_interface, stream))
7724 m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7725 << ". Inspection of compute program interface failed:\n"
7726 << stream.str() << tcu::TestLog::EndMessage;
7740 prepareUniforms(test_case_index, program_interface, program, buffer_u_cs);
7743 GLint image_location = program.GetUniformLocation("uni_image");
7744 prepareImage(image_location, texture_im);
7747 executeDispatchCall(test_case_index);
7750 m_context.getRenderContext().postIterate();
7754 if (false == checkResults(test_case_index, texture_im))
7756 m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7757 << ". Compute - invalid results." << tcu::TestLog::EndMessage
7758 << tcu::TestLog::KernelSource(compute_shader);
7767 /** Basic implementation
7773 bool TextureTestBase::useComponentQualifier(glw::GLuint /* test_case_index */)
7778 /** Basic implementation
7784 bool TextureTestBase::useMonolithicProgram(GLuint /* test_case_index */)
7791 * @param context Test framework context
7793 APIConstantValuesTest::APIConstantValuesTest(deqp::Context& context)
7794 : TestCase(context, "api_constant_values", "Test verifies values of api constants")
7796 /* Nothing to be done here */
7801 * @return tcu::TestNode::STOP otherwise
7803 tcu::TestNode::IterateResult APIConstantValuesTest::iterate()
7805 static const GLuint expected_comp = 64;
7806 static const GLuint expected_xfb = 4;
7807 static const GLuint expected_sep = 4;
7811 bool test_result = true;
7813 const Functions& gl = m_context.getRenderContext().getFunctions();
7815 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_xfb);
7816 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
7817 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_comp);
7818 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
7819 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, &max_sep);
7820 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
7822 if (expected_xfb > (GLuint)max_xfb)
7824 m_context.getTestContext().getLog() << tcu::TestLog::Message
7825 << "Invalid GL_MAX_TRANSFORM_FEEDBACK_BUFFERS. Got " << max_xfb
7826 << " Expected at least " << expected_xfb << tcu::TestLog::EndMessage;
7828 test_result = false;
7831 if (expected_comp > (GLuint)max_comp)
7833 m_context.getTestContext().getLog()
7834 << tcu::TestLog::Message << "Invalid GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS. Got " << max_comp
7835 << " Expected at least " << expected_comp << tcu::TestLog::EndMessage;
7837 test_result = false;
7840 if (expected_sep > (GLuint)max_sep)
7842 m_context.getTestContext().getLog() << tcu::TestLog::Message
7843 << "Invalid GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS. Got " << max_comp
7844 << " Expected at least " << expected_comp << tcu::TestLog::EndMessage;
7846 test_result = false;
7850 if (true == test_result)
7852 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
7856 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
7860 return tcu::TestNode::STOP;
7865 * @param context Test framework context
7867 APIErrorsTest::APIErrorsTest(deqp::Context& context)
7868 : TestCase(context, "api_errors", "Test verifies errors reeturned by api")
7870 /* Nothing to be done here */
7875 * @return tcu::TestNode::STOP otherwise
7877 tcu::TestNode::IterateResult APIErrorsTest::iterate()
7882 Utils::Program program(m_context);
7883 bool test_result = true;
7885 const Functions& gl = m_context.getRenderContext().getFunctions();
7889 program.Init("" /* cs */, "#version 430 core\n"
7890 "#extension GL_ARB_enhanced_layouts : require\n"
7893 "out vec4 fs_out;\n"
7897 " fs_out = vs_fs;\n"
7900 "" /* gs */, "" /* tcs */, "" /* tes */, "#version 430 core\n"
7901 "#extension GL_ARB_enhanced_layouts : require\n"
7904 "layout (xfb_offset = 16) out vec4 vs_fs;\n"
7911 false /* separable */);
7913 catch (Utils::Shader::InvalidSourceException& exc)
7916 TCU_FAIL(exc.what());
7918 catch (Utils::Program::BuildException& exc)
7920 TCU_FAIL(exc.what());
7924 * - GetProgramInterfaceiv should generate INVALID_OPERATION when
7925 * <programInterface> is TRANSFORM_FEEDBACK_BUFFER and <pname> is one of the
7927 * * MAX_NAME_LENGTH,
7928 * * MAX_NUM_ACTIVE_VARIABLES;
7930 gl.getProgramInterfaceiv(program.m_id, GL_TRANSFORM_FEEDBACK_BUFFER, GL_MAX_NAME_LENGTH, ¶m);
7931 checkError(GL_INVALID_OPERATION, "GetProgramInterfaceiv(GL_TRANSFORM_FEEDBACK_BUFFER, GL_MAX_NAME_LENGTH)",
7935 * - GetProgramResourceIndex should generate INVALID_ENUM when
7936 * <programInterface> is TRANSFORM_FEEDBACK_BUFFER;
7938 gl.getProgramResourceIndex(program.m_id, GL_TRANSFORM_FEEDBACK_BUFFER, "0");
7939 checkError(GL_INVALID_ENUM, "GetProgramResourceIndex(GL_TRANSFORM_FEEDBACK_BUFFER)", test_result);
7941 * - GetProgramResourceName should generate INVALID_ENUM when
7942 * <programInterface> is TRANSFORM_FEEDBACK_BUFFER;
7944 gl.getProgramResourceName(program.m_id, GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, 64 /* bufSize */, &length,
7946 checkError(GL_INVALID_ENUM, "GetProgramResourceName(GL_TRANSFORM_FEEDBACK_BUFFER)", test_result);
7949 if (true == test_result)
7951 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
7955 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
7959 return tcu::TestNode::STOP;
7962 /** Check if error is the expected one.
7964 * @param expected_error Expected error
7965 * @param message Message to log in case of error
7966 * @param test_result Test result, set to false in case of invalid error
7968 void APIErrorsTest::checkError(GLenum expected_error, const GLchar* message, bool& test_result)
7970 const Functions& gl = m_context.getRenderContext().getFunctions();
7972 GLenum error = gl.getError();
7974 if (error != expected_error)
7976 m_context.getTestContext().getLog()
7977 << tcu::TestLog::Message << "Failure. Invalid error. Got " << glu::getErrorStr(error) << " expected "
7978 << glu::getErrorStr(expected_error) << " Msg: " << message << tcu::TestLog::EndMessage;
7980 test_result = false;
7986 * @param context Test framework context
7988 GLSLContantImmutablityTest::GLSLContantImmutablityTest(deqp::Context& context)
7989 : NegativeTestBase(context, "glsl_contant_immutablity", "Test verifies that glsl constants cannot be modified")
7991 /* Nothing to be done here */
7994 /** Source for given test case and stage
7996 * @param test_case_index Index of test case
7997 * @param stage Shader stage
7999 * @return Shader source
8001 std::string GLSLContantImmutablityTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
8003 static const GLchar* cs = "#version 430 core\n"
8004 "#extension GL_ARB_enhanced_layouts : require\n"
8006 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
8008 "writeonly uniform uimage2D uni_image;\n"
8012 " uint result = 1u;\n"
8015 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), uvec4(result, 0, 0, 0));\n"
8018 static const GLchar* fs = "#version 430 core\n"
8019 "#extension GL_ARB_enhanced_layouts : require\n"
8022 "out vec4 fs_out;\n"
8027 " fs_out = gs_fs;\n"
8030 static const GLchar* gs = "#version 430 core\n"
8031 "#extension GL_ARB_enhanced_layouts : require\n"
8033 "layout(points) in;\n"
8034 "layout(triangle_strip, max_vertices = 4) out;\n"
8036 "in vec4 tes_gs[];\n"
8042 " gs_fs = tes_gs[0];\n"
8043 " gl_Position = vec4(-1, -1, 0, 1);\n"
8045 " gs_fs = tes_gs[0];\n"
8046 " gl_Position = vec4(-1, 1, 0, 1);\n"
8048 " gs_fs = tes_gs[0];\n"
8049 " gl_Position = vec4(1, -1, 0, 1);\n"
8051 " gs_fs = tes_gs[0];\n"
8052 " gl_Position = vec4(1, 1, 0, 1);\n"
8056 static const GLchar* tcs = "#version 430 core\n"
8057 "#extension GL_ARB_enhanced_layouts : require\n"
8059 "layout(vertices = 1) out;\n"
8061 "in vec4 vs_tcs[];\n"
8062 "out vec4 tcs_tes[];\n"
8068 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
8070 " gl_TessLevelOuter[0] = 1.0;\n"
8071 " gl_TessLevelOuter[1] = 1.0;\n"
8072 " gl_TessLevelOuter[2] = 1.0;\n"
8073 " gl_TessLevelOuter[3] = 1.0;\n"
8074 " gl_TessLevelInner[0] = 1.0;\n"
8075 " gl_TessLevelInner[1] = 1.0;\n"
8078 static const GLchar* tes = "#version 430 core\n"
8079 "#extension GL_ARB_enhanced_layouts : require\n"
8081 "layout(isolines, point_mode) in;\n"
8083 "in vec4 tcs_tes[];\n"
8084 "out vec4 tes_gs;\n"
8089 " tes_gs = tcs_tes[0];\n"
8092 static const GLchar* vs = "#version 430 core\n"
8093 "#extension GL_ARB_enhanced_layouts : require\n"
8096 "out vec4 vs_tcs;\n"
8101 " vs_tcs = in_vs;\n"
8106 testCase& test_case = m_test_cases[test_case_index];
8108 if (Utils::Shader::COMPUTE == test_case.m_stage)
8110 size_t position = 0;
8114 Utils::replaceToken("CONSTANT", position, getConstantName(test_case.m_constant), source);
8118 std::string assignment = " CONSTANT = 3;\n";
8119 size_t position = 0;
8123 case Utils::Shader::FRAGMENT:
8126 case Utils::Shader::GEOMETRY:
8129 case Utils::Shader::TESS_CTRL:
8132 case Utils::Shader::TESS_EVAL:
8135 case Utils::Shader::VERTEX:
8139 TCU_FAIL("Invalid enum");
8142 if (test_case.m_stage == stage)
8144 Utils::replaceToken("CONSTANT", position, getConstantName(test_case.m_constant), assignment);
8152 Utils::replaceToken("ASSIGNMENT", position, assignment.c_str(), source);
8158 /** Get description of test case
8160 * @param test_case_index Index of test case
8162 * @return Constant name
8164 std::string GLSLContantImmutablityTest::getTestCaseName(GLuint test_case_index)
8166 std::string result = getConstantName(m_test_cases[test_case_index].m_constant);
8171 /** Get number of test cases
8173 * @return Number of test cases
8175 GLuint GLSLContantImmutablityTest::getTestCaseNumber()
8177 return static_cast<GLuint>(m_test_cases.size());
8180 /** Selects if "compute" stage is relevant for test
8182 * @param test_case_index Index of test case
8184 * @return true when tested stage is compute
8186 bool GLSLContantImmutablityTest::isComputeRelevant(GLuint test_case_index)
8188 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
8191 /** Prepare all test cases
8194 void GLSLContantImmutablityTest::testInit()
8196 for (GLuint constant = 0; constant < CONSTANTS_MAX; ++constant)
8198 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
8200 testCase test_case = { (CONSTANTS)constant, (Utils::Shader::STAGES)stage };
8202 m_test_cases.push_back(test_case);
8207 /** Get name of glsl constant
8209 * @param Constant id
8211 * @return Name of constant used in GLSL
8213 const GLchar* GLSLContantImmutablityTest::getConstantName(CONSTANTS constant)
8215 const GLchar* name = "";
8219 case GL_ARB_ENHANCED_LAYOUTS:
8220 name = "GL_ARB_enhanced_layouts";
8223 name = "gl_MaxTransformFeedbackBuffers";
8225 case GL_MAX_XFB_INT_COMP:
8226 name = "gl_MaxTransformFeedbackInterleavedComponents";
8229 TCU_FAIL("Invalid enum");
8237 * @param context Test framework context
8239 GLSLContantValuesTest::GLSLContantValuesTest(deqp::Context& context)
8240 : TextureTestBase(context, "glsl_contant_values", "Test verifies values of constant symbols")
8244 /** Selects if "compute" stage is relevant for test
8250 bool GLSLContantValuesTest::isComputeRelevant(GLuint /* test_case_index */)
8255 /** Prepare code snippet that will verify in and uniform variables
8259 * @param stage Shader stage
8261 * @return Code that verify variables
8263 std::string GLSLContantValuesTest::getVerificationSnippet(GLuint /* test_case_index */,
8264 Utils::ProgramInterface& /* program_interface */,
8265 Utils::Shader::STAGES stage)
8268 const Functions& gl = m_context.getRenderContext().getFunctions();
8270 GLint max_transform_feedback_buffers = 0;
8271 GLint max_transform_feedback_interleaved_components = 0;
8273 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_transform_feedback_buffers);
8274 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8275 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_transform_feedback_interleaved_components);
8276 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8278 std::string verification;
8280 if (Utils::Shader::VERTEX == stage)
8282 verification = "if (1 != GL_ARB_enhanced_layouts)\n"
8286 " else if (MAX_TRANSFORM_FEEDBACK_BUFFERS\n"
8287 " != gl_MaxTransformFeedbackBuffers)\n"
8291 " else if (MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS \n"
8292 " != gl_MaxTransformFeedbackInterleavedComponents)\n"
8297 size_t position = 0;
8300 sprintf(buffer, "%d", max_transform_feedback_buffers);
8301 Utils::replaceToken("MAX_TRANSFORM_FEEDBACK_BUFFERS", position, buffer, verification);
8303 sprintf(buffer, "%d", max_transform_feedback_interleaved_components);
8304 Utils::replaceToken("MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS", position, buffer, verification);
8311 return verification;
8316 * @param context Test framework context
8318 GLSLConstantIntegralExpressionTest::GLSLConstantIntegralExpressionTest(deqp::Context& context)
8319 : TextureTestBase(context, "glsl_constant_integral_expression",
8320 "Test verifies that symbols can be used as constant integral expressions")
8324 /** Get interface of program
8327 * @param program_interface Interface of program
8330 void GLSLConstantIntegralExpressionTest::getProgramInterface(GLuint /* test_case_index */,
8331 Utils::ProgramInterface& program_interface,
8332 Utils::VaryingPassthrough& /* varying_passthrough */)
8335 const Functions& gl = m_context.getRenderContext().getFunctions();
8337 GLint max_transform_feedback_buffers = 0;
8338 GLint max_transform_feedback_interleaved_components = 0;
8340 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_transform_feedback_buffers);
8341 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8342 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_transform_feedback_interleaved_components);
8343 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8345 GLuint gohan_div = std::max(1, max_transform_feedback_buffers / 16);
8346 GLuint goten_div = std::max(1, max_transform_feedback_interleaved_components / 16);
8348 m_gohan_length = max_transform_feedback_buffers / gohan_div;
8349 m_goten_length = max_transform_feedback_interleaved_components / goten_div;
8352 std::string globals = "uniform uint goku [GL_ARB_enhanced_layouts / 1];\n"
8353 "uniform uint gohan[gl_MaxTransformFeedbackBuffers / GOHAN_DIV];\n"
8354 "uniform uint goten[gl_MaxTransformFeedbackInterleavedComponents / GOTEN_DIV];\n";
8356 size_t position = 0;
8359 sprintf(buffer, "%d", gohan_div);
8360 Utils::replaceToken("GOHAN_DIV", position, buffer, globals);
8362 sprintf(buffer, "%d", goten_div);
8363 Utils::replaceToken("GOTEN_DIV", position, buffer, globals);
8365 program_interface.m_vertex.m_globals = globals;
8366 program_interface.m_tess_ctrl.m_globals = globals;
8367 program_interface.m_tess_eval.m_globals = globals;
8368 program_interface.m_geometry.m_globals = globals;
8369 program_interface.m_fragment.m_globals = globals;
8370 program_interface.m_compute.m_globals = globals;
8373 /** Prepare code snippet that will verify in and uniform variables
8379 * @return Code that verify variables
8381 std::string GLSLConstantIntegralExpressionTest::getVerificationSnippet(GLuint /* test_case_index */,
8382 Utils::ProgramInterface& /* program_interface */,
8383 Utils::Shader::STAGES /* stage */)
8385 std::string verification = "{\n"
8386 " uint goku_sum = 0;\n"
8387 " uint gohan_sum = 0;\n"
8388 " uint goten_sum = 0;\n"
8390 " for (uint i = 0u; i < goku.length(); ++i)\n"
8392 " goku_sum += goku[i];\n"
8395 " for (uint i = 0u; i < gohan.length(); ++i)\n"
8397 " gohan_sum += gohan[i];\n"
8400 " for (uint i = 0u; i < goten.length(); ++i)\n"
8402 " goten_sum += goten[i];\n"
8405 " if ( (1u != goku_sum) &&\n"
8406 " (EXPECTED_GOHAN_SUMu != gohan_sum) ||\n"
8407 " (EXPECTED_GOTEN_SUMu != goten_sum) )\n"
8413 size_t position = 0;
8416 sprintf(buffer, "%d", m_gohan_length);
8417 Utils::replaceToken("EXPECTED_GOHAN_SUM", position, buffer, verification);
8419 sprintf(buffer, "%d", m_goten_length);
8420 Utils::replaceToken("EXPECTED_GOTEN_SUM", position, buffer, verification);
8422 return verification;
8425 /** Prepare unifroms
8429 * @param program Program object
8432 void GLSLConstantIntegralExpressionTest::prepareUniforms(GLuint /* test_case_index */,
8433 Utils::ProgramInterface& /* program_interface */,
8434 Utils::Program& program, Utils::Buffer& /* cs_buffer */)
8436 static const GLuint uniform_data[16] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
8438 const Functions& gl = m_context.getRenderContext().getFunctions();
8440 GLint goku_location = program.GetUniformLocation("goku");
8441 GLint gohan_location = program.GetUniformLocation("gohan");
8442 GLint goten_location = program.GetUniformLocation("goten");
8444 program.Uniform(gl, Utils::Type::uint, 1 /* count */, goku_location, uniform_data);
8445 program.Uniform(gl, Utils::Type::uint, m_gohan_length, gohan_location, uniform_data);
8446 program.Uniform(gl, Utils::Type::uint, m_goten_length, goten_location, uniform_data);
8449 /** Prepare unifroms
8451 * @param test_case_index Pass as param to first implemetnation
8452 * @param program_interface Pass as param to first implemetnation
8453 * @param program Pass as param to first implemetnation
8458 * @param vs_buffer Pass as param to first implemetnation
8460 void GLSLConstantIntegralExpressionTest::prepareUniforms(GLuint test_case_index,
8461 Utils::ProgramInterface& program_interface,
8462 Utils::Program& program, Utils::Buffer& /* fs_buffer */,
8463 Utils::Buffer& /* gs_buffer */,
8464 Utils::Buffer& /* tcs_buffer */,
8465 Utils::Buffer& /* tes_buffer */, Utils::Buffer& vs_buffer)
8467 /* Call first implementation */
8468 prepareUniforms(test_case_index, program_interface, program, vs_buffer);
8473 * @param context Test framework context
8475 UniformBlockMemberOffsetAndAlignTest::UniformBlockMemberOffsetAndAlignTest(deqp::Context& context)
8476 : TextureTestBase(context, "uniform_block_member_offset_and_align",
8477 "Test verifies offsets and alignment of uniform buffer members")
8481 /** Get interface of program
8483 * @param test_case_index Test case index
8484 * @param program_interface Interface of program
8485 * @param varying_passthrough Collection of connections between in and out variables
8487 void UniformBlockMemberOffsetAndAlignTest::getProgramInterface(GLuint test_case_index,
8488 Utils::ProgramInterface& program_interface,
8489 Utils::VaryingPassthrough& varying_passthrough)
8491 std::string globals = "const int basic_size = BASIC_SIZE;\n"
8492 "const int type_align = TYPE_ALIGN;\n"
8493 "const int type_size = TYPE_SIZE;\n";
8495 Utils::Type type = getType(test_case_index);
8496 GLuint basic_size = Utils::Type::GetTypeSize(type.m_basic_type);
8497 const GLuint base_align = type.GetBaseAlignment(false);
8498 const GLuint array_align = type.GetBaseAlignment(true);
8499 const GLuint base_stride = Utils::Type::CalculateStd140Stride(base_align, type.m_n_columns, 0);
8500 const GLuint type_align = Utils::roundUpToPowerOf2(base_stride);
8502 /* Calculate offsets */
8503 const GLuint first_offset = 0;
8504 const GLuint second_offset = type.GetActualOffset(base_stride, basic_size / 2);
8506 #if WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST
8508 const GLuint third_offset = type.GetActualOffset(second_offset + base_stride, base_align);
8509 const GLuint fourth_offset = type.GetActualOffset(third_offset + base_stride, base_align);
8510 const GLuint fifth_offset = type.GetActualOffset(fourth_offset + base_stride, base_align);
8511 const GLuint sixth_offset = type.GetActualOffset(fifth_offset + base_stride, array_align);
8512 const GLuint seventh_offset = type.GetActualOffset(sixth_offset + base_stride, array_align);
8513 const GLuint eigth_offset = type.GetActualOffset(seventh_offset + base_stride, array_align);
8515 #else /* WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST */
8517 const GLuint third_offset = type.GetActualOffset(second_offset + base_stride, 2 * type_align);
8518 const GLuint fourth_offset = type.GetActualOffset(3 * type_align + base_stride, base_align);
8519 const GLuint fifth_offset = type.GetActualOffset(fourth_offset + base_stride, base_align);
8520 const GLuint sixth_offset = type.GetActualOffset(fifth_offset + base_stride, array_align);
8521 const GLuint seventh_offset = type.GetActualOffset(sixth_offset + base_stride, array_align);
8522 const GLuint eigth_offset = type.GetActualOffset(seventh_offset + base_stride, 8 * basic_size);
8524 #endif /* WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST */
8527 const std::vector<GLubyte>& first = type.GenerateData();
8528 const std::vector<GLubyte>& second = type.GenerateData();
8529 const std::vector<GLubyte>& third = type.GenerateData();
8530 const std::vector<GLubyte>& fourth = type.GenerateData();
8532 m_data.resize(eigth_offset + base_stride);
8533 GLubyte* ptr = &m_data[0];
8534 memcpy(ptr + first_offset, &first[0], first.size());
8535 memcpy(ptr + second_offset, &second[0], second.size());
8536 memcpy(ptr + third_offset, &third[0], third.size());
8537 memcpy(ptr + fourth_offset, &fourth[0], fourth.size());
8538 memcpy(ptr + fifth_offset, &fourth[0], fourth.size());
8539 memcpy(ptr + sixth_offset, &third[0], third.size());
8540 memcpy(ptr + seventh_offset, &second[0], second.size());
8541 memcpy(ptr + eigth_offset, &first[0], first.size());
8543 /* Prepare globals */
8544 size_t position = 0;
8547 sprintf(buffer, "%d", basic_size);
8548 Utils::replaceToken("BASIC_SIZE", position, buffer, globals);
8550 sprintf(buffer, "%d", type_align);
8551 Utils::replaceToken("TYPE_ALIGN", position, buffer, globals);
8553 sprintf(buffer, "%d", base_stride);
8554 Utils::replaceToken("TYPE_SIZE", position, buffer, globals);
8557 Utils::Interface* vs_uni_block = program_interface.Block("vs_uni_Block");
8559 vs_uni_block->Member("at_first_offset", "layout(offset = 0, align = 8 * basic_size)", 0 /* expected_component */,
8560 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
8563 vs_uni_block->Member("at_second_offset", "layout(offset = type_size, align = basic_size / 2)",
8564 0 /* expected_component */, 0 /* expected_location */, type, false /* normalized */,
8565 0 /* n_array_elements */, base_stride, second_offset);
8567 vs_uni_block->Member("at_third_offset", "layout(align = 2 * type_align)", 0 /* expected_component */,
8568 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
8571 vs_uni_block->Member("at_fourth_offset", "layout(offset = 3 * type_align + type_size)", 0 /* expected_component */,
8572 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
8575 vs_uni_block->Member("at_fifth_offset", "", 0 /* expected_component */, 0 /* expected_location */, type,
8576 false /* normalized */, 0 /* n_array_elements */, base_stride, fifth_offset);
8578 vs_uni_block->Member("at_sixth_offset", "", 0 /* expected_component */, 0 /* expected_location */, type,
8579 false /* normalized */, 2 /* n_array_elements */, array_align * 2, sixth_offset);
8581 vs_uni_block->Member("at_eigth_offset", "layout(align = 8 * basic_size)", 0 /* expected_component */,
8582 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
8585 Utils::ShaderInterface& vs_si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
8588 vs_si.m_globals = globals;
8590 /* Add uniform BLOCK */
8591 vs_si.Uniform("vs_uni_block", "layout (std140, binding = BINDING)", 0, 0, vs_uni_block, 0,
8592 static_cast<glw::GLint>(m_data.size()), 0, &m_data[0], m_data.size());
8595 program_interface.CloneVertexInterface(varying_passthrough);
8600 * @param test_case_index Index of test case
8602 * @return Name of type test in test_case_index
8604 std::string UniformBlockMemberOffsetAndAlignTest::getTestCaseName(glw::GLuint test_case_index)
8606 return getTypeName(test_case_index);
8609 /** Returns number of types to test
8611 * @return Number of types, 34
8613 glw::GLuint UniformBlockMemberOffsetAndAlignTest::getTestCaseNumber()
8615 return getTypesNumber();
8618 /** Prepare code snippet that will verify in and uniform variables
8622 * @param stage Shader stage
8624 * @return Code that verify variables
8626 std::string UniformBlockMemberOffsetAndAlignTest::getVerificationSnippet(
8627 GLuint /* test_case_index */, Utils::ProgramInterface& /* program_interface */, Utils::Shader::STAGES stage)
8629 std::string verification = "if ( (PREFIXblock.at_first_offset != PREFIXblock.at_eigth_offset ) ||\n"
8630 " (PREFIXblock.at_second_offset != PREFIXblock.at_sixth_offset[1]) ||\n"
8631 " (PREFIXblock.at_third_offset != PREFIXblock.at_sixth_offset[0]) ||\n"
8632 " (PREFIXblock.at_fourth_offset != PREFIXblock.at_fifth_offset ) )\n"
8637 const GLchar* prefix = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::UNIFORM);
8639 Utils::replaceAllTokens("PREFIX", prefix, verification);
8641 return verification;
8646 * @param context Test framework context
8648 UniformBlockLayoutQualifierConflictTest::UniformBlockLayoutQualifierConflictTest(deqp::Context& context)
8650 context, "uniform_block_layout_qualifier_conflict",
8651 "Test verifies that std140 is required when offset and/or align qualifiers are used with uniform block")
8653 /* Nothing to be done here */
8656 /** Source for given test case and stage
8658 * @param test_case_index Index of test case
8659 * @param stage Shader stage
8661 * @return Shader source
8663 std::string UniformBlockLayoutQualifierConflictTest::getShaderSource(GLuint test_case_index,
8664 Utils::Shader::STAGES stage)
8666 static const GLchar* cs = "#version 430 core\n"
8667 "#extension GL_ARB_enhanced_layouts : require\n"
8669 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
8671 "LAYOUTuniform Block {\n"
8672 " layout(offset = 16) vec4 boy;\n"
8673 " layout(align = 64) vec4 man;\n"
8676 "writeonly uniform image2D uni_image;\n"
8680 " vec4 result = uni_block.boy + uni_block.man;\n"
8682 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
8685 static const GLchar* fs = "#version 430 core\n"
8686 "#extension GL_ARB_enhanced_layouts : require\n"
8688 "LAYOUTuniform Block {\n"
8689 " layout(offset = 16) vec4 boy;\n"
8690 " layout(align = 64) vec4 man;\n"
8694 "out vec4 fs_out;\n"
8698 " fs_out = gs_fs + uni_block.boy + uni_block.man;\n"
8701 static const GLchar* gs = "#version 430 core\n"
8702 "#extension GL_ARB_enhanced_layouts : require\n"
8704 "layout(points) in;\n"
8705 "layout(triangle_strip, max_vertices = 4) out;\n"
8707 "LAYOUTuniform Block {\n"
8708 " layout(offset = 16) vec4 boy;\n"
8709 " layout(align = 64) vec4 man;\n"
8712 "in vec4 tes_gs[];\n"
8717 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
8718 " gl_Position = vec4(-1, -1, 0, 1);\n"
8720 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
8721 " gl_Position = vec4(-1, 1, 0, 1);\n"
8723 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
8724 " gl_Position = vec4(1, -1, 0, 1);\n"
8726 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
8727 " gl_Position = vec4(1, 1, 0, 1);\n"
8731 static const GLchar* tcs =
8732 "#version 430 core\n"
8733 "#extension GL_ARB_enhanced_layouts : require\n"
8735 "layout(vertices = 1) out;\n"
8737 "LAYOUTuniform Block {\n"
8738 " layout(offset = 16) vec4 boy;\n"
8739 " layout(align = 64) vec4 man;\n"
8742 "in vec4 vs_tcs[];\n"
8743 "out vec4 tcs_tes[];\n"
8748 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID] + uni_block.boy + uni_block.man;\n"
8750 " gl_TessLevelOuter[0] = 1.0;\n"
8751 " gl_TessLevelOuter[1] = 1.0;\n"
8752 " gl_TessLevelOuter[2] = 1.0;\n"
8753 " gl_TessLevelOuter[3] = 1.0;\n"
8754 " gl_TessLevelInner[0] = 1.0;\n"
8755 " gl_TessLevelInner[1] = 1.0;\n"
8758 static const GLchar* tes = "#version 430 core\n"
8759 "#extension GL_ARB_enhanced_layouts : require\n"
8761 "layout(isolines, point_mode) in;\n"
8763 "LAYOUTuniform Block {\n"
8764 " layout(offset = 16) vec4 boy;\n"
8765 " layout(align = 64) vec4 man;\n"
8768 "in vec4 tcs_tes[];\n"
8769 "out vec4 tes_gs;\n"
8773 " tes_gs = tcs_tes[0] + uni_block.boy + uni_block.man;\n"
8776 static const GLchar* vs = "#version 430 core\n"
8777 "#extension GL_ARB_enhanced_layouts : require\n"
8779 "LAYOUTuniform Block {\n"
8780 " layout(offset = 16) vec4 boy;\n"
8781 " layout(align = 64) vec4 man;\n"
8785 "out vec4 vs_tcs;\n"
8789 " vs_tcs = in_vs + uni_block.boy + uni_block.man;\n"
8793 std::string layout = "";
8794 size_t position = 0;
8795 testCase& test_case = m_test_cases[test_case_index];
8796 const GLchar* qualifier = getQualifierName(test_case.m_qualifier);
8799 if (0 != qualifier[0])
8801 size_t layout_position = 0;
8803 layout = "layout (QUALIFIER) ";
8805 Utils::replaceToken("QUALIFIER", layout_position, qualifier, layout);
8810 case Utils::Shader::COMPUTE:
8813 case Utils::Shader::FRAGMENT:
8816 case Utils::Shader::GEOMETRY:
8819 case Utils::Shader::TESS_CTRL:
8822 case Utils::Shader::TESS_EVAL:
8825 case Utils::Shader::VERTEX:
8829 TCU_FAIL("Invalid enum");
8832 if (test_case.m_stage == stage)
8834 Utils::replaceToken("LAYOUT", position, layout.c_str(), source);
8838 Utils::replaceToken("LAYOUT", position, "layout (std140) ", source);
8844 /** Get description of test case
8846 * @param test_case_index Index of test case
8848 * @return Qualifier name
8850 std::string UniformBlockLayoutQualifierConflictTest::getTestCaseName(GLuint test_case_index)
8852 std::string result = getQualifierName(m_test_cases[test_case_index].m_qualifier);
8857 /** Get number of test cases
8859 * @return Number of test cases
8861 GLuint UniformBlockLayoutQualifierConflictTest::getTestCaseNumber()
8863 return static_cast<GLuint>(m_test_cases.size());
8866 /** Selects if "compute" stage is relevant for test
8868 * @param test_case_index Index of test case
8870 * @return true when tested stage is compute
8872 bool UniformBlockLayoutQualifierConflictTest::isComputeRelevant(GLuint test_case_index)
8874 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
8877 /** Selects if compilation failure is expected result
8879 * @param test_case_index Index of test case
8881 * @return false for STD140 cases, true otherwise
8883 bool UniformBlockLayoutQualifierConflictTest::isFailureExpected(GLuint test_case_index)
8885 return (STD140 != m_test_cases[test_case_index].m_qualifier);
8888 /** Prepare all test cases
8891 void UniformBlockLayoutQualifierConflictTest::testInit()
8893 for (GLuint qualifier = 0; qualifier < QUALIFIERS_MAX; ++qualifier)
8895 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
8897 testCase test_case = { (QUALIFIERS)qualifier, (Utils::Shader::STAGES)stage };
8899 m_test_cases.push_back(test_case);
8904 /** Get name of glsl constant
8906 * @param Constant id
8908 * @return Name of constant used in GLSL
8910 const GLchar* UniformBlockLayoutQualifierConflictTest::getQualifierName(QUALIFIERS qualifier)
8912 const GLchar* name = "";
8929 TCU_FAIL("Invalid enum");
8937 * @param context Test framework context
8939 UniformBlockMemberInvalidOffsetAlignmentTest::UniformBlockMemberInvalidOffsetAlignmentTest(deqp::Context& context)
8940 : NegativeTestBase(context, "uniform_block_member_invalid_offset_alignment",
8941 "Test verifies that invalid alignment of offset qualifiers cause compilation failure")
8943 /* Nothing to be done here */
8948 * @param context Test framework context
8949 * @param name Test name
8950 * @param description Test description
8952 UniformBlockMemberInvalidOffsetAlignmentTest::UniformBlockMemberInvalidOffsetAlignmentTest(
8953 deqp::Context& context, const glw::GLchar* name, const glw::GLchar* description)
8954 : NegativeTestBase(context, name, description)
8956 /* Nothing to be done here */
8959 /** Source for given test case and stage
8961 * @param test_case_index Index of test case
8962 * @param stage Shader stage
8964 * @return Shader source
8966 std::string UniformBlockMemberInvalidOffsetAlignmentTest::getShaderSource(GLuint test_case_index,
8967 Utils::Shader::STAGES stage)
8969 static const GLchar* cs = "#version 430 core\n"
8970 "#extension GL_ARB_enhanced_layouts : require\n"
8972 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
8974 "layout (std140) uniform Block {\n"
8975 " layout (offset = OFFSET) TYPE member;\n"
8978 "writeonly uniform image2D uni_image;\n"
8982 " vec4 result = vec4(1, 0, 0.5, 1);\n"
8984 " if (TYPE(1) == block.member)\n"
8986 " result = vec4(1, 1, 1, 1);\n"
8989 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
8992 static const GLchar* fs = "#version 430 core\n"
8993 "#extension GL_ARB_enhanced_layouts : require\n"
8996 "out vec4 fs_out;\n"
9000 " fs_out = gs_fs;\n"
9003 static const GLchar* fs_tested = "#version 430 core\n"
9004 "#extension GL_ARB_enhanced_layouts : require\n"
9006 "layout (std140) uniform Block {\n"
9007 " layout (offset = OFFSET) TYPE member;\n"
9011 "out vec4 fs_out;\n"
9015 " if (TYPE(1) == block.member)\n"
9017 " fs_out = vec4(1, 1, 1, 1);\n"
9020 " fs_out += gs_fs;\n"
9023 static const GLchar* gs = "#version 430 core\n"
9024 "#extension GL_ARB_enhanced_layouts : require\n"
9026 "layout(points) in;\n"
9027 "layout(triangle_strip, max_vertices = 4) out;\n"
9029 "in vec4 tes_gs[];\n"
9034 " gs_fs = tes_gs[0];\n"
9035 " gl_Position = vec4(-1, -1, 0, 1);\n"
9037 " gs_fs = tes_gs[0];\n"
9038 " gl_Position = vec4(-1, 1, 0, 1);\n"
9040 " gs_fs = tes_gs[0];\n"
9041 " gl_Position = vec4(1, -1, 0, 1);\n"
9043 " gs_fs = tes_gs[0];\n"
9044 " gl_Position = vec4(1, 1, 0, 1);\n"
9048 static const GLchar* gs_tested = "#version 430 core\n"
9049 "#extension GL_ARB_enhanced_layouts : require\n"
9051 "layout(points) in;\n"
9052 "layout(triangle_strip, max_vertices = 4) out;\n"
9054 "layout (std140) uniform Block {\n"
9055 " layout (offset = OFFSET) TYPE member;\n"
9058 "in vec4 tes_gs[];\n"
9063 " if (TYPE(1) == block.member)\n"
9065 " gs_fs = vec4(1, 1, 1, 1);\n"
9068 " gs_fs += tes_gs[0];\n"
9069 " gl_Position = vec4(-1, -1, 0, 1);\n"
9071 " gs_fs += tes_gs[0];\n"
9072 " gl_Position = vec4(-1, 1, 0, 1);\n"
9074 " gs_fs += tes_gs[0];\n"
9075 " gl_Position = vec4(1, -1, 0, 1);\n"
9077 " gs_fs += tes_gs[0];\n"
9078 " gl_Position = vec4(1, 1, 0, 1);\n"
9082 static const GLchar* tcs = "#version 430 core\n"
9083 "#extension GL_ARB_enhanced_layouts : require\n"
9085 "layout(vertices = 1) out;\n"
9087 "in vec4 vs_tcs[];\n"
9088 "out vec4 tcs_tes[];\n"
9093 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
9095 " gl_TessLevelOuter[0] = 1.0;\n"
9096 " gl_TessLevelOuter[1] = 1.0;\n"
9097 " gl_TessLevelOuter[2] = 1.0;\n"
9098 " gl_TessLevelOuter[3] = 1.0;\n"
9099 " gl_TessLevelInner[0] = 1.0;\n"
9100 " gl_TessLevelInner[1] = 1.0;\n"
9103 static const GLchar* tcs_tested = "#version 430 core\n"
9104 "#extension GL_ARB_enhanced_layouts : require\n"
9106 "layout(vertices = 1) out;\n"
9108 "layout (std140) uniform Block {\n"
9109 " layout (offset = OFFSET) TYPE member;\n"
9112 "in vec4 vs_tcs[];\n"
9113 "out vec4 tcs_tes[];\n"
9117 " if (TYPE(1) == block.member)\n"
9119 " tcs_tes[gl_InvocationID] = vec4(1, 1, 1, 1);\n"
9123 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
9125 " gl_TessLevelOuter[0] = 1.0;\n"
9126 " gl_TessLevelOuter[1] = 1.0;\n"
9127 " gl_TessLevelOuter[2] = 1.0;\n"
9128 " gl_TessLevelOuter[3] = 1.0;\n"
9129 " gl_TessLevelInner[0] = 1.0;\n"
9130 " gl_TessLevelInner[1] = 1.0;\n"
9133 static const GLchar* tes = "#version 430 core\n"
9134 "#extension GL_ARB_enhanced_layouts : require\n"
9136 "layout(isolines, point_mode) in;\n"
9138 "in vec4 tcs_tes[];\n"
9139 "out vec4 tes_gs;\n"
9143 " tes_gs = tcs_tes[0];\n"
9146 static const GLchar* tes_tested = "#version 430 core\n"
9147 "#extension GL_ARB_enhanced_layouts : require\n"
9149 "layout(isolines, point_mode) in;\n"
9151 "layout (std140) uniform Block {\n"
9152 " layout (offset = OFFSET) TYPE member;\n"
9155 "in vec4 tcs_tes[];\n"
9156 "out vec4 tes_gs;\n"
9160 " if (TYPE(1) == block.member)\n"
9162 " tes_gs = vec4(1, 1, 1, 1);\n"
9165 " tes_gs += tcs_tes[0];\n"
9168 static const GLchar* vs = "#version 430 core\n"
9169 "#extension GL_ARB_enhanced_layouts : require\n"
9172 "out vec4 vs_tcs;\n"
9176 " vs_tcs = in_vs;\n"
9179 static const GLchar* vs_tested = "#version 430 core\n"
9180 "#extension GL_ARB_enhanced_layouts : require\n"
9182 "layout (std140) uniform Block {\n"
9183 " layout (offset = OFFSET) TYPE member;\n"
9187 "out vec4 vs_tcs;\n"
9191 " if (TYPE(1) == block.member)\n"
9193 " vs_tcs = vec4(1, 1, 1, 1);\n"
9196 " vs_tcs += in_vs;\n"
9201 testCase& test_case = m_test_cases[test_case_index];
9203 if (test_case.m_stage == stage)
9206 const GLuint offset = test_case.m_offset;
9207 size_t position = 0;
9208 const Utils::Type& type = test_case.m_type;
9209 const GLchar* type_name = type.GetGLSLTypeName();
9211 sprintf(buffer, "%d", offset);
9215 case Utils::Shader::COMPUTE:
9218 case Utils::Shader::FRAGMENT:
9221 case Utils::Shader::GEOMETRY:
9224 case Utils::Shader::TESS_CTRL:
9225 source = tcs_tested;
9227 case Utils::Shader::TESS_EVAL:
9228 source = tes_tested;
9230 case Utils::Shader::VERTEX:
9234 TCU_FAIL("Invalid enum");
9237 Utils::replaceToken("OFFSET", position, buffer, source);
9238 Utils::replaceToken("TYPE", position, type_name, source);
9239 Utils::replaceToken("TYPE", position, type_name, source);
9245 case Utils::Shader::FRAGMENT:
9248 case Utils::Shader::GEOMETRY:
9251 case Utils::Shader::TESS_CTRL:
9254 case Utils::Shader::TESS_EVAL:
9257 case Utils::Shader::VERTEX:
9261 TCU_FAIL("Invalid enum");
9268 /** Get description of test case
9270 * @param test_case_index Index of test case
9272 * @return Type name and offset
9274 std::string UniformBlockMemberInvalidOffsetAlignmentTest::getTestCaseName(GLuint test_case_index)
9276 std::stringstream stream;
9277 testCase& test_case = m_test_cases[test_case_index];
9279 stream << "Type: " << test_case.m_type.GetGLSLTypeName() << ", offset: " << test_case.m_offset;
9281 return stream.str();
9284 /** Get number of test cases
9286 * @return Number of test cases
9288 GLuint UniformBlockMemberInvalidOffsetAlignmentTest::getTestCaseNumber()
9290 return static_cast<GLuint>(m_test_cases.size());
9293 /** Selects if "compute" stage is relevant for test
9295 * @param test_case_index Index of test case
9297 * @return true when tested stage is compute
9299 bool UniformBlockMemberInvalidOffsetAlignmentTest::isComputeRelevant(GLuint test_case_index)
9301 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
9304 /** Selects if compilation failure is expected result
9306 * @param test_case_index Index of test case
9308 * @return should_fail field from testCase
9310 bool UniformBlockMemberInvalidOffsetAlignmentTest::isFailureExpected(GLuint test_case_index)
9312 return m_test_cases[test_case_index].m_should_fail;
9315 /** Checks if stage is supported
9317 * @param stage ignored
9321 bool UniformBlockMemberInvalidOffsetAlignmentTest::isStageSupported(Utils::Shader::STAGES /* stage */)
9326 /** Prepare all test cases
9329 void UniformBlockMemberInvalidOffsetAlignmentTest::testInit()
9331 const Functions& gl = m_context.getRenderContext().getFunctions();
9333 const GLuint n_types = getTypesNumber();
9334 bool stage_support[Utils::Shader::STAGE_MAX];
9336 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
9338 stage_support[stage] = isStageSupported((Utils::Shader::STAGES)stage);
9341 gl.getIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &max_size);
9342 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
9344 for (GLuint i = 0; i < n_types; ++i)
9346 const Utils::Type& type = getType(i);
9347 const GLuint alignment = type.GetBaseAlignment(false);
9348 const GLuint type_size = type.GetSize();
9349 const GLuint sec_to_end = max_size - 2 * type_size;
9351 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
9353 if (false == stage_support[stage])
9358 for (GLuint offset = 0; offset <= type_size; ++offset)
9360 const GLuint modulo = offset % alignment;
9361 const bool is_aligned = (0 == modulo) ? true : false;
9362 const bool should_fail = !is_aligned;
9364 testCase test_case = { offset, should_fail, (Utils::Shader::STAGES)stage, type };
9366 m_test_cases.push_back(test_case);
9369 for (GLuint offset = sec_to_end; offset <= sec_to_end + type_size; ++offset)
9371 const GLuint modulo = offset % alignment;
9372 const bool is_aligned = (0 == modulo) ? true : false;
9373 const bool should_fail = !is_aligned;
9375 testCase test_case = { offset, should_fail, (Utils::Shader::STAGES)stage, type };
9377 m_test_cases.push_back(test_case);
9385 * @param context Test framework context
9387 UniformBlockMemberOverlappingOffsetsTest::UniformBlockMemberOverlappingOffsetsTest(deqp::Context& context)
9388 : NegativeTestBase(context, "uniform_block_member_overlapping_offsets",
9389 "Test verifies that overlapping offsets qualifiers cause compilation failure")
9391 /* Nothing to be done here */
9396 * @param context Test framework context
9397 * @param name Test name
9398 * @param description Test description
9400 UniformBlockMemberOverlappingOffsetsTest::UniformBlockMemberOverlappingOffsetsTest(deqp::Context& context,
9401 const glw::GLchar* name,
9402 const glw::GLchar* description)
9403 : NegativeTestBase(context, name, description)
9405 /* Nothing to be done here */
9408 /** Source for given test case and stage
9410 * @param test_case_index Index of test case
9411 * @param stage Shader stage
9413 * @return Shader source
9415 std::string UniformBlockMemberOverlappingOffsetsTest::getShaderSource(GLuint test_case_index,
9416 Utils::Shader::STAGES stage)
9418 static const GLchar* cs = "#version 430 core\n"
9419 "#extension GL_ARB_enhanced_layouts : require\n"
9421 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
9423 "layout (std140) uniform Block {\n"
9424 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9425 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9428 "writeonly uniform image2D uni_image;\n"
9432 " vec4 result = vec4(1, 0, 0.5, 1);\n"
9434 " if ((BOY_TYPE(1) == block.boy) ||\n"
9435 " (MAN_TYPE(0) == block.man) )\n"
9437 " result = vec4(1, 1, 1, 1);\n"
9440 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
9443 static const GLchar* fs = "#version 430 core\n"
9444 "#extension GL_ARB_enhanced_layouts : require\n"
9447 "out vec4 fs_out;\n"
9451 " fs_out = gs_fs;\n"
9454 static const GLchar* fs_tested = "#version 430 core\n"
9455 "#extension GL_ARB_enhanced_layouts : require\n"
9457 "layout (std140) uniform Block {\n"
9458 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9459 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9463 "out vec4 fs_out;\n"
9467 " if ((BOY_TYPE(1) == block.boy) ||\n"
9468 " (MAN_TYPE(0) == block.man) )\n"
9470 " fs_out = vec4(1, 1, 1, 1);\n"
9473 " fs_out += gs_fs;\n"
9476 static const GLchar* gs = "#version 430 core\n"
9477 "#extension GL_ARB_enhanced_layouts : require\n"
9479 "layout(points) in;\n"
9480 "layout(triangle_strip, max_vertices = 4) out;\n"
9482 "in vec4 tes_gs[];\n"
9487 " gs_fs = tes_gs[0];\n"
9488 " gl_Position = vec4(-1, -1, 0, 1);\n"
9490 " gs_fs = tes_gs[0];\n"
9491 " gl_Position = vec4(-1, 1, 0, 1);\n"
9493 " gs_fs = tes_gs[0];\n"
9494 " gl_Position = vec4(1, -1, 0, 1);\n"
9496 " gs_fs = tes_gs[0];\n"
9497 " gl_Position = vec4(1, 1, 0, 1);\n"
9501 static const GLchar* gs_tested = "#version 430 core\n"
9502 "#extension GL_ARB_enhanced_layouts : require\n"
9504 "layout(points) in;\n"
9505 "layout(triangle_strip, max_vertices = 4) out;\n"
9507 "layout (std140) uniform Block {\n"
9508 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9509 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9512 "in vec4 tes_gs[];\n"
9517 " if ((BOY_TYPE(1) == block.boy) ||\n"
9518 " (MAN_TYPE(0) == block.man) )\n"
9520 " gs_fs = vec4(1, 1, 1, 1);\n"
9523 " gs_fs += tes_gs[0];\n"
9524 " gl_Position = vec4(-1, -1, 0, 1);\n"
9526 " gs_fs += tes_gs[0];\n"
9527 " gl_Position = vec4(-1, 1, 0, 1);\n"
9529 " gs_fs += tes_gs[0];\n"
9530 " gl_Position = vec4(1, -1, 0, 1);\n"
9532 " gs_fs += tes_gs[0];\n"
9533 " gl_Position = vec4(1, 1, 0, 1);\n"
9537 static const GLchar* tcs = "#version 430 core\n"
9538 "#extension GL_ARB_enhanced_layouts : require\n"
9540 "layout(vertices = 1) out;\n"
9542 "in vec4 vs_tcs[];\n"
9543 "out vec4 tcs_tes[];\n"
9548 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
9550 " gl_TessLevelOuter[0] = 1.0;\n"
9551 " gl_TessLevelOuter[1] = 1.0;\n"
9552 " gl_TessLevelOuter[2] = 1.0;\n"
9553 " gl_TessLevelOuter[3] = 1.0;\n"
9554 " gl_TessLevelInner[0] = 1.0;\n"
9555 " gl_TessLevelInner[1] = 1.0;\n"
9558 static const GLchar* tcs_tested = "#version 430 core\n"
9559 "#extension GL_ARB_enhanced_layouts : require\n"
9561 "layout(vertices = 1) out;\n"
9563 "layout (std140) uniform Block {\n"
9564 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9565 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9568 "in vec4 vs_tcs[];\n"
9569 "out vec4 tcs_tes[];\n"
9573 " if ((BOY_TYPE(1) == block.boy) ||\n"
9574 " (MAN_TYPE(0) == block.man) )\n"
9576 " tcs_tes[gl_InvocationID] = vec4(1, 1, 1, 1);\n"
9580 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
9582 " gl_TessLevelOuter[0] = 1.0;\n"
9583 " gl_TessLevelOuter[1] = 1.0;\n"
9584 " gl_TessLevelOuter[2] = 1.0;\n"
9585 " gl_TessLevelOuter[3] = 1.0;\n"
9586 " gl_TessLevelInner[0] = 1.0;\n"
9587 " gl_TessLevelInner[1] = 1.0;\n"
9590 static const GLchar* tes = "#version 430 core\n"
9591 "#extension GL_ARB_enhanced_layouts : require\n"
9593 "layout(isolines, point_mode) in;\n"
9595 "in vec4 tcs_tes[];\n"
9596 "out vec4 tes_gs;\n"
9600 " tes_gs = tcs_tes[0];\n"
9603 static const GLchar* tes_tested = "#version 430 core\n"
9604 "#extension GL_ARB_enhanced_layouts : require\n"
9606 "layout(isolines, point_mode) in;\n"
9608 "layout (std140) uniform Block {\n"
9609 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9610 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9613 "in vec4 tcs_tes[];\n"
9614 "out vec4 tes_gs;\n"
9618 " if ((BOY_TYPE(1) == block.boy) ||\n"
9619 " (MAN_TYPE(0) == block.man) )\n"
9621 " tes_gs = vec4(1, 1, 1, 1);\n"
9624 " tes_gs += tcs_tes[0];\n"
9627 static const GLchar* vs = "#version 430 core\n"
9628 "#extension GL_ARB_enhanced_layouts : require\n"
9631 "out vec4 vs_tcs;\n"
9635 " vs_tcs = in_vs;\n"
9638 static const GLchar* vs_tested = "#version 430 core\n"
9639 "#extension GL_ARB_enhanced_layouts : require\n"
9641 "layout (std140) uniform Block {\n"
9642 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9643 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9647 "out vec4 vs_tcs;\n"
9651 " if ((BOY_TYPE(1) == block.boy) ||\n"
9652 " (MAN_TYPE(0) == block.man) )\n"
9654 " vs_tcs = vec4(1, 1, 1, 1);\n"
9657 " vs_tcs += in_vs;\n"
9662 testCase& test_case = m_test_cases[test_case_index];
9664 if (test_case.m_stage == stage)
9667 const GLuint boy_offset = test_case.m_boy_offset;
9668 const Utils::Type& boy_type = test_case.m_boy_type;
9669 const GLchar* boy_type_name = boy_type.GetGLSLTypeName();
9670 const GLuint man_offset = test_case.m_man_offset;
9671 const Utils::Type& man_type = test_case.m_man_type;
9672 const GLchar* man_type_name = man_type.GetGLSLTypeName();
9673 size_t position = 0;
9677 case Utils::Shader::COMPUTE:
9680 case Utils::Shader::FRAGMENT:
9683 case Utils::Shader::GEOMETRY:
9686 case Utils::Shader::TESS_CTRL:
9687 source = tcs_tested;
9689 case Utils::Shader::TESS_EVAL:
9690 source = tes_tested;
9692 case Utils::Shader::VERTEX:
9696 TCU_FAIL("Invalid enum");
9699 sprintf(buffer, "%d", boy_offset);
9700 Utils::replaceToken("BOY_OFFSET", position, buffer, source);
9701 Utils::replaceToken("BOY_TYPE", position, boy_type_name, source);
9702 sprintf(buffer, "%d", man_offset);
9703 Utils::replaceToken("MAN_OFFSET", position, buffer, source);
9704 Utils::replaceToken("MAN_TYPE", position, man_type_name, source);
9705 Utils::replaceToken("BOY_TYPE", position, boy_type_name, source);
9706 Utils::replaceToken("MAN_TYPE", position, man_type_name, source);
9712 case Utils::Shader::FRAGMENT:
9715 case Utils::Shader::GEOMETRY:
9718 case Utils::Shader::TESS_CTRL:
9721 case Utils::Shader::TESS_EVAL:
9724 case Utils::Shader::VERTEX:
9728 TCU_FAIL("Invalid enum");
9735 /** Get description of test case
9737 * @param test_case_index Index of test case
9739 * @return Type name and offset
9741 std::string UniformBlockMemberOverlappingOffsetsTest::getTestCaseName(GLuint test_case_index)
9743 std::stringstream stream;
9744 testCase& test_case = m_test_cases[test_case_index];
9746 stream << "Type: " << test_case.m_boy_type.GetGLSLTypeName() << ", offset: " << test_case.m_boy_offset
9747 << ". Type: " << test_case.m_man_type.GetGLSLTypeName() << ", offset: " << test_case.m_man_offset;
9749 return stream.str();
9752 /** Get number of test cases
9754 * @return Number of test cases
9756 GLuint UniformBlockMemberOverlappingOffsetsTest::getTestCaseNumber()
9758 return static_cast<GLuint>(m_test_cases.size());
9761 /** Selects if "compute" stage is relevant for test
9763 * @param test_case_index Index of test case
9765 * @return true when tested stage is compute
9767 bool UniformBlockMemberOverlappingOffsetsTest::isComputeRelevant(GLuint test_case_index)
9769 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
9772 /** Checks if stage is supported
9774 * @param stage ignored
9778 bool UniformBlockMemberOverlappingOffsetsTest::isStageSupported(Utils::Shader::STAGES /* stage */)
9783 /** Prepare all test cases
9786 void UniformBlockMemberOverlappingOffsetsTest::testInit()
9788 const GLuint n_types = getTypesNumber();
9789 bool stage_support[Utils::Shader::STAGE_MAX];
9791 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
9793 stage_support[stage] = isStageSupported((Utils::Shader::STAGES)stage);
9796 for (GLuint i = 0; i < n_types; ++i)
9798 const Utils::Type& boy_type = getType(i);
9799 const GLuint boy_size = boy_type.GetActualAlignment(1 /* align */, false /* is_array*/);
9801 for (GLuint j = 0; j < n_types; ++j)
9803 const Utils::Type& man_type = getType(j);
9804 const GLuint man_align = man_type.GetBaseAlignment(false);
9805 const GLuint man_size = man_type.GetActualAlignment(1 /* align */, false /* is_array*/);
9807 const GLuint boy_offset = lcm(boy_size, man_size);
9808 const GLuint man_after_start = boy_offset + 1;
9809 const GLuint man_after_off = man_type.GetActualOffset(man_after_start, man_size);
9810 const GLuint man_before_start = boy_offset - man_align;
9811 const GLuint man_before_off = man_type.GetActualOffset(man_before_start, man_size);
9813 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
9815 if (false == stage_support[stage])
9820 if ((boy_offset > man_before_off) && (boy_offset < man_before_off + man_size))
9822 testCase test_case = { boy_offset, boy_type, man_before_off, man_type,
9823 (Utils::Shader::STAGES)stage };
9825 m_test_cases.push_back(test_case);
9828 if ((boy_offset < man_after_off) && (boy_offset + boy_size > man_after_off))
9830 testCase test_case = { boy_offset, boy_type, man_after_off, man_type,
9831 (Utils::Shader::STAGES)stage };
9833 m_test_cases.push_back(test_case);
9836 /* Boy offset, should be fine for both types */
9837 testCase test_case = { boy_offset, boy_type, boy_offset, man_type, (Utils::Shader::STAGES)stage };
9839 m_test_cases.push_back(test_case);
9845 /** Find greatest common divisor for a and b
9847 * @param a A argument
9848 * @param b B argument
9850 * @return Found gcd value
9852 GLuint UniformBlockMemberOverlappingOffsetsTest::gcd(GLuint a, GLuint b)
9854 if ((0 != a) && (0 == b))
9860 GLuint greater = std::max(a, b);
9861 GLuint lesser = std::min(a, b);
9863 return gcd(lesser, greater % lesser);
9867 /** Find lowest common multiple for a and b
9869 * @param a A argument
9870 * @param b B argument
9872 * @return Found gcd value
9874 GLuint UniformBlockMemberOverlappingOffsetsTest::lcm(GLuint a, GLuint b)
9876 return (a * b) / gcd(a, b);
9881 * @param context Test framework context
9883 UniformBlockMemberAlignNonPowerOf2Test::UniformBlockMemberAlignNonPowerOf2Test(deqp::Context& context)
9884 : NegativeTestBase(context, "uniform_block_member_align_non_power_of_2",
9885 "Test verifies that align qualifier requires value that is a power of 2")
9887 /* Nothing to be done here */
9892 * @param context Test framework context
9893 * @param name Test name
9894 * @param description Test description
9896 UniformBlockMemberAlignNonPowerOf2Test::UniformBlockMemberAlignNonPowerOf2Test(deqp::Context& context,
9897 const glw::GLchar* name,
9898 const glw::GLchar* description)
9899 : NegativeTestBase(context, name, description)
9901 /* Nothing to be done here */
9904 /** Source for given test case and stage
9906 * @param test_case_index Index of test case
9907 * @param stage Shader stage
9909 * @return Shader source
9911 std::string UniformBlockMemberAlignNonPowerOf2Test::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
9913 static const GLchar* cs = "#version 430 core\n"
9914 "#extension GL_ARB_enhanced_layouts : require\n"
9916 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
9918 "layout (std140) uniform Block {\n"
9920 " layout (align = ALIGN) TYPE man;\n"
9923 "writeonly uniform image2D uni_image;\n"
9927 " vec4 result = vec4(1, 0, 0.5, 1);\n"
9929 " if (TYPE(0) == block.man)\n"
9931 " result = vec4(1, 1, 1, 1) - block.boy;\n"
9934 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
9937 static const GLchar* fs = "#version 430 core\n"
9938 "#extension GL_ARB_enhanced_layouts : require\n"
9941 "out vec4 fs_out;\n"
9945 " fs_out = gs_fs;\n"
9948 static const GLchar* fs_tested = "#version 430 core\n"
9949 "#extension GL_ARB_enhanced_layouts : require\n"
9951 "layout (std140) uniform Block {\n"
9953 " layout (align = ALIGN) TYPE man;\n"
9957 "out vec4 fs_out;\n"
9961 " if (TYPE(0) == block.man)\n"
9963 " fs_out = block.boy;\n"
9966 " fs_out += gs_fs;\n"
9969 static const GLchar* gs = "#version 430 core\n"
9970 "#extension GL_ARB_enhanced_layouts : require\n"
9972 "layout(points) in;\n"
9973 "layout(triangle_strip, max_vertices = 4) out;\n"
9975 "in vec4 tes_gs[];\n"
9980 " gs_fs = tes_gs[0];\n"
9981 " gl_Position = vec4(-1, -1, 0, 1);\n"
9983 " gs_fs = tes_gs[0];\n"
9984 " gl_Position = vec4(-1, 1, 0, 1);\n"
9986 " gs_fs = tes_gs[0];\n"
9987 " gl_Position = vec4(1, -1, 0, 1);\n"
9989 " gs_fs = tes_gs[0];\n"
9990 " gl_Position = vec4(1, 1, 0, 1);\n"
9994 static const GLchar* gs_tested = "#version 430 core\n"
9995 "#extension GL_ARB_enhanced_layouts : require\n"
9997 "layout(points) in;\n"
9998 "layout(triangle_strip, max_vertices = 4) out;\n"
10000 "layout (std140) uniform Block {\n"
10002 " layout (align = ALIGN) TYPE man;\n"
10005 "in vec4 tes_gs[];\n"
10006 "out vec4 gs_fs;\n"
10010 " if (TYPE(0) == block.man)\n"
10012 " gs_fs = block.boy;\n"
10015 " gs_fs += tes_gs[0];\n"
10016 " gl_Position = vec4(-1, -1, 0, 1);\n"
10018 " gs_fs += tes_gs[0];\n"
10019 " gl_Position = vec4(-1, 1, 0, 1);\n"
10021 " gs_fs += tes_gs[0];\n"
10022 " gl_Position = vec4(1, -1, 0, 1);\n"
10024 " gs_fs += tes_gs[0];\n"
10025 " gl_Position = vec4(1, 1, 0, 1);\n"
10029 static const GLchar* tcs = "#version 430 core\n"
10030 "#extension GL_ARB_enhanced_layouts : require\n"
10032 "layout(vertices = 1) out;\n"
10034 "in vec4 vs_tcs[];\n"
10035 "out vec4 tcs_tes[];\n"
10040 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
10042 " gl_TessLevelOuter[0] = 1.0;\n"
10043 " gl_TessLevelOuter[1] = 1.0;\n"
10044 " gl_TessLevelOuter[2] = 1.0;\n"
10045 " gl_TessLevelOuter[3] = 1.0;\n"
10046 " gl_TessLevelInner[0] = 1.0;\n"
10047 " gl_TessLevelInner[1] = 1.0;\n"
10050 static const GLchar* tcs_tested = "#version 430 core\n"
10051 "#extension GL_ARB_enhanced_layouts : require\n"
10053 "layout(vertices = 1) out;\n"
10055 "layout (std140) uniform Block {\n"
10057 " layout (align = ALIGN) TYPE man;\n"
10060 "in vec4 vs_tcs[];\n"
10061 "out vec4 tcs_tes[];\n"
10065 " if (TYPE(0) == block.man)\n"
10067 " tcs_tes[gl_InvocationID] = block.boy;\n"
10071 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
10073 " gl_TessLevelOuter[0] = 1.0;\n"
10074 " gl_TessLevelOuter[1] = 1.0;\n"
10075 " gl_TessLevelOuter[2] = 1.0;\n"
10076 " gl_TessLevelOuter[3] = 1.0;\n"
10077 " gl_TessLevelInner[0] = 1.0;\n"
10078 " gl_TessLevelInner[1] = 1.0;\n"
10081 static const GLchar* tes = "#version 430 core\n"
10082 "#extension GL_ARB_enhanced_layouts : require\n"
10084 "layout(isolines, point_mode) in;\n"
10086 "in vec4 tcs_tes[];\n"
10087 "out vec4 tes_gs;\n"
10091 " tes_gs = tcs_tes[0];\n"
10094 static const GLchar* tes_tested = "#version 430 core\n"
10095 "#extension GL_ARB_enhanced_layouts : require\n"
10097 "layout(isolines, point_mode) in;\n"
10099 "layout (std140) uniform Block {\n"
10101 " layout (align = ALIGN) TYPE man;\n"
10104 "in vec4 tcs_tes[];\n"
10105 "out vec4 tes_gs;\n"
10109 " if (TYPE(0) == block.man)\n"
10111 " tes_gs = block.boy;\n"
10114 " tes_gs += tcs_tes[0];\n"
10117 static const GLchar* vs = "#version 430 core\n"
10118 "#extension GL_ARB_enhanced_layouts : require\n"
10121 "out vec4 vs_tcs;\n"
10125 " vs_tcs = in_vs;\n"
10128 static const GLchar* vs_tested = "#version 430 core\n"
10129 "#extension GL_ARB_enhanced_layouts : require\n"
10131 "layout (std140) uniform Block {\n"
10133 " layout (align = ALIGN) TYPE man;\n"
10137 "out vec4 vs_tcs;\n"
10141 " if (TYPE(0) == block.man)\n"
10143 " vs_tcs = block.boy;\n"
10146 " vs_tcs += in_vs;\n"
10150 std::string source;
10151 testCase& test_case = m_test_cases[test_case_index];
10153 if (test_case.m_stage == stage)
10156 const GLuint alignment = test_case.m_alignment;
10157 const Utils::Type& type = test_case.m_type;
10158 const GLchar* type_name = type.GetGLSLTypeName();
10159 size_t position = 0;
10163 case Utils::Shader::COMPUTE:
10166 case Utils::Shader::FRAGMENT:
10167 source = fs_tested;
10169 case Utils::Shader::GEOMETRY:
10170 source = gs_tested;
10172 case Utils::Shader::TESS_CTRL:
10173 source = tcs_tested;
10175 case Utils::Shader::TESS_EVAL:
10176 source = tes_tested;
10178 case Utils::Shader::VERTEX:
10179 source = vs_tested;
10182 TCU_FAIL("Invalid enum");
10185 sprintf(buffer, "%d", alignment);
10186 Utils::replaceToken("ALIGN", position, buffer, source);
10187 Utils::replaceToken("TYPE", position, type_name, source);
10188 Utils::replaceToken("TYPE", position, type_name, source);
10194 case Utils::Shader::FRAGMENT:
10197 case Utils::Shader::GEOMETRY:
10200 case Utils::Shader::TESS_CTRL:
10203 case Utils::Shader::TESS_EVAL:
10206 case Utils::Shader::VERTEX:
10210 TCU_FAIL("Invalid enum");
10217 /** Get description of test case
10219 * @param test_case_index Index of test case
10221 * @return Type name and offset
10223 std::string UniformBlockMemberAlignNonPowerOf2Test::getTestCaseName(GLuint test_case_index)
10225 std::stringstream stream;
10226 testCase& test_case = m_test_cases[test_case_index];
10228 stream << "Type: " << test_case.m_type.GetGLSLTypeName() << ", align: " << test_case.m_alignment;
10230 return stream.str();
10233 /** Get number of test cases
10235 * @return Number of test cases
10237 GLuint UniformBlockMemberAlignNonPowerOf2Test::getTestCaseNumber()
10239 return static_cast<GLuint>(m_test_cases.size());
10242 /** Selects if "compute" stage is relevant for test
10244 * @param test_case_index Index of test case
10246 * @return true when tested stage is compute
10248 bool UniformBlockMemberAlignNonPowerOf2Test::isComputeRelevant(GLuint test_case_index)
10250 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
10253 /** Checks if stage is supported
10259 bool UniformBlockMemberAlignNonPowerOf2Test::isStageSupported(Utils::Shader::STAGES /* stage */)
10264 /** Selects if compilation failure is expected result
10266 * @param test_case_index Index of test case
10268 * @return should_fail field from testCase
10270 bool UniformBlockMemberAlignNonPowerOf2Test::isFailureExpected(GLuint test_case_index)
10272 return m_test_cases[test_case_index].m_should_fail;
10275 /** Prepare all test cases
10278 void UniformBlockMemberAlignNonPowerOf2Test::testInit()
10280 static const GLuint dmat4_size = 128;
10281 const GLuint n_types = getTypesNumber();
10282 bool stage_support[Utils::Shader::STAGE_MAX];
10284 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
10286 stage_support[stage] = isStageSupported((Utils::Shader::STAGES)stage);
10289 for (GLuint j = 0; j < n_types; ++j)
10291 const Utils::Type& type = getType(j);
10293 for (GLuint align = 0; align <= dmat4_size; ++align)
10296 #if WRKARD_UNIFORMBLOCKMEMBERALIGNNONPOWEROF2TEST
10298 const bool should_fail = (0 == align) ? false : !isPowerOf2(align);
10300 #else /* WRKARD_UNIFORMBLOCKMEMBERALIGNNONPOWEROF2TEST */
10302 const bool should_fail = !isPowerOf2(align);
10304 #endif /* WRKARD_UNIFORMBLOCKMEMBERALIGNNONPOWEROF2TEST */
10306 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
10308 if (false == stage_support[stage])
10313 testCase test_case = { align, type, should_fail, (Utils::Shader::STAGES)stage };
10315 m_test_cases.push_back(test_case);
10321 /** Check if value is power of 2
10323 * @param val Tested value
10325 * @return true if val is power of 2, false otherwise
10327 bool UniformBlockMemberAlignNonPowerOf2Test::isPowerOf2(GLuint val)
10334 return (0 == (val & (val - 1)));
10339 * @param context Test framework context
10341 UniformBlockAlignmentTest::UniformBlockAlignmentTest(deqp::Context& context)
10342 : TextureTestBase(context, "uniform_block_alignment", "Test verifies offset and alignment of uniform buffer")
10346 /** Get interface of program
10349 * @param program_interface Interface of program
10350 * @param varying_passthrough Collection of connections between in and out variables
10352 void UniformBlockAlignmentTest::getProgramInterface(GLuint /* test_case_index */,
10353 Utils::ProgramInterface& program_interface,
10354 Utils::VaryingPassthrough& varying_passthrough)
10356 static const Utils::Type vec4 = Utils::Type::vec4;
10358 #if WRKARD_UNIFORMBLOCKALIGNMENT
10360 static const GLuint block_align = 16;
10362 #else /* WRKARD_UNIFORMBLOCKALIGNMENT */
10364 static const GLuint block_align = 64;
10366 #endif /* WRKARD_UNIFORMBLOCKALIGNMENT */
10368 static const GLuint vec4_stride = 16;
10369 static const GLuint data_stride = vec4_stride * 2; /* one vec4 + one scalar aligned to 16 */
10371 /*Fixed a test issue, the fifth_offset should be calculated by block_align, instead of fifth_align, according to spec, the actual
10372 alignment of a member will be the greater of the specified alignment and the base aligment for the member type
10374 const GLuint first_offset = 0; /* vec4 at 0 */
10375 const GLuint second_offset = Utils::Type::GetActualOffset(first_offset + vec4_stride, block_align); /* Data at 32 */
10376 const GLuint third_offset =
10377 Utils::Type::GetActualOffset(second_offset + data_stride, block_align); /* Data[2] at 64 */
10378 const GLuint fourth_offset =
10379 Utils::Type::GetActualOffset(third_offset + data_stride * 2, block_align); /* vec4[3] at 96 */
10380 const GLuint fifth_offset =
10381 Utils::Type::GetActualOffset(fourth_offset + vec4_stride * 3, block_align); /* vec4[2] at 160 */
10382 const GLuint sixth_offset =
10383 Utils::Type::GetActualOffset(fifth_offset + vec4_stride * 2, block_align); /* Data at 192 */
10385 Utils::Interface* structure = program_interface.Structure("Data");
10387 structure->Member("vector", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::vec4,
10388 false /* normalized */, 0 /* n_array_elements */, Utils::Type::vec4.GetSize(), 0 /* offset */);
10390 structure->Member("scalar", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::_float,
10391 false /* normalized */, 0 /* n_array_elements */, Utils::Type::_float.GetSize(),
10392 Utils::Type::vec4.GetSize() /* offset */);
10394 /* Prepare Block */
10395 Utils::Interface* vs_uni_block = program_interface.Block("vs_uni_Block");
10397 vs_uni_block->Member("first", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::vec4,
10398 false /* normalized */, 0 /* n_array_elements */, vec4_stride, first_offset /* offset */);
10400 vs_uni_block->Member("second", "", 0 /* expected_component */, 0 /* expected_location */, structure,
10401 0 /* n_array_elements */, data_stride, second_offset);
10403 vs_uni_block->Member("third", "", 0 /* expected_component */, 0 /* expected_location */, structure,
10404 2 /* n_array_elements */, data_stride, third_offset);
10406 vs_uni_block->Member("fourth", "", 0 /* expected_component */, 0 /* expected_location */, vec4,
10407 false /* normalized */, 3 /* n_array_elements */, vec4_stride, fourth_offset);
10409 vs_uni_block->Member("fifth", "layout(align = 64)", 0 /* expected_component */, 0 /* expected_location */, vec4,
10410 false /* normalized */, 2 /* n_array_elements */, vec4_stride, fifth_offset);
10412 vs_uni_block->Member("sixth", "", 0 /* expected_component */, 0 /* expected_location */, structure,
10413 0 /* n_array_elements */, data_stride, sixth_offset);
10415 const GLuint stride = calculateStride(*vs_uni_block);
10416 m_data.resize(stride);
10417 generateData(*vs_uni_block, 0, m_data);
10419 Utils::ShaderInterface& vs_si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
10421 /* Add uniform BLOCK */
10422 #if WRKARD_UNIFORMBLOCKALIGNMENT
10423 vs_si.Uniform("vs_uni_block", "layout (std140, binding = BINDING)", 0, 0, vs_uni_block, 0,
10424 static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
10425 #else /* WRKARD_UNIFORMBLOCKALIGNMENT */
10426 vs_si.Uniform("vs_uni_block", "layout (std140, binding = BINDING, align = 64)", 0, 0, vs_uni_block, 0,
10427 static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
10428 #endif /* WRKARD_UNIFORMBLOCKALIGNMENT */
10430 program_interface.CloneVertexInterface(varying_passthrough);
10435 * @param context Test framework context
10437 SSBMemberOffsetAndAlignTest::SSBMemberOffsetAndAlignTest(deqp::Context& context)
10438 : TextureTestBase(context, "ssb_member_offset_and_align",
10439 "Test verifies offsets and alignment of storage buffer members")
10443 /** Get interface of program
10445 * @param test_case_index Test case index
10446 * @param program_interface Interface of program
10447 * @param varying_passthrough Collection of connections between in and out variables
10449 void SSBMemberOffsetAndAlignTest::getProgramInterface(GLuint test_case_index,
10450 Utils::ProgramInterface& program_interface,
10451 Utils::VaryingPassthrough& varying_passthrough)
10453 std::string globals = "const int basic_size = BASIC_SIZE;\n"
10454 "const int type_align = TYPE_ALIGN;\n"
10455 "const int type_size = TYPE_SIZE;\n";
10457 Utils::Type type = getType(test_case_index);
10458 GLuint basic_size = Utils::Type::GetTypeSize(type.m_basic_type);
10459 const GLuint base_align = type.GetBaseAlignment(false);
10460 const GLuint array_align = type.GetBaseAlignment(true);
10461 const GLuint base_stride = Utils::Type::CalculateStd140Stride(base_align, type.m_n_columns, 0);
10462 const GLuint type_align = Utils::roundUpToPowerOf2(base_stride);
10464 /* Calculate offsets */
10465 const GLuint first_offset = 0;
10466 const GLuint second_offset = type.GetActualOffset(base_stride, basic_size / 2);
10468 #if WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST
10470 const GLuint third_offset = type.GetActualOffset(second_offset + base_stride, base_align);
10471 const GLuint fourth_offset = type.GetActualOffset(third_offset + base_stride, base_align);
10472 const GLuint fifth_offset = type.GetActualOffset(fourth_offset + base_stride, base_align);
10473 const GLuint sixth_offset = type.GetActualOffset(fifth_offset + base_stride, array_align);
10474 const GLuint seventh_offset = type.GetActualOffset(sixth_offset + base_stride, array_align);
10475 const GLuint eigth_offset = type.GetActualOffset(seventh_offset + base_stride, array_align);
10477 #else /* WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST */
10479 const GLuint third_offset = type.GetActualOffset(second_offset + base_stride, 2 * type_align);
10480 const GLuint fourth_offset = type.GetActualOffset(3 * type_align + base_stride, base_align);
10481 const GLuint fifth_offset = type.GetActualOffset(fourth_offset + base_stride, base_align);
10482 const GLuint sixth_offset = type.GetActualOffset(fifth_offset + base_stride, array_align);
10483 const GLuint seventh_offset = type.GetActualOffset(sixth_offset + base_stride, array_align);
10484 const GLuint eigth_offset = type.GetActualOffset(seventh_offset + base_stride, 8 * basic_size);
10486 #endif /* WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST */
10489 const std::vector<GLubyte>& first = type.GenerateData();
10490 const std::vector<GLubyte>& second = type.GenerateData();
10491 const std::vector<GLubyte>& third = type.GenerateData();
10492 const std::vector<GLubyte>& fourth = type.GenerateData();
10494 m_data.resize(eigth_offset + base_stride);
10495 GLubyte* ptr = &m_data[0];
10496 memcpy(ptr + first_offset, &first[0], first.size());
10497 memcpy(ptr + second_offset, &second[0], second.size());
10498 memcpy(ptr + third_offset, &third[0], third.size());
10499 memcpy(ptr + fourth_offset, &fourth[0], fourth.size());
10500 memcpy(ptr + fifth_offset, &fourth[0], fourth.size());
10501 memcpy(ptr + sixth_offset, &third[0], third.size());
10502 memcpy(ptr + seventh_offset, &second[0], second.size());
10503 memcpy(ptr + eigth_offset, &first[0], first.size());
10505 /* Prepare globals */
10506 size_t position = 0;
10509 sprintf(buffer, "%d", basic_size);
10510 Utils::replaceToken("BASIC_SIZE", position, buffer, globals);
10512 sprintf(buffer, "%d", type_align);
10513 Utils::replaceToken("TYPE_ALIGN", position, buffer, globals);
10515 sprintf(buffer, "%d", base_stride);
10516 Utils::replaceToken("TYPE_SIZE", position, buffer, globals);
10518 /* Prepare Block */
10519 Utils::Interface* vs_buf_block = program_interface.Block("vs_buf_Block");
10521 vs_buf_block->Member("at_first_offset", "layout(offset = 0, align = 8 * basic_size)", 0 /* expected_component */,
10522 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
10525 vs_buf_block->Member("at_second_offset", "layout(offset = type_size, align = basic_size / 2)",
10526 0 /* expected_component */, 0 /* expected_location */, type, false /* normalized */,
10527 0 /* n_array_elements */, base_stride, second_offset);
10529 vs_buf_block->Member("at_third_offset", "layout(align = 2 * type_align)", 0 /* expected_component */,
10530 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
10533 vs_buf_block->Member("at_fourth_offset", "layout(offset = 3 * type_align + type_size)", 0 /* expected_component */,
10534 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
10537 vs_buf_block->Member("at_fifth_offset", "", 0 /* expected_component */, 0 /* expected_location */, type,
10538 false /* normalized */, 0 /* n_array_elements */, base_stride, fifth_offset);
10540 vs_buf_block->Member("at_sixth_offset", "", 0 /* expected_component */, 0 /* expected_location */, type,
10541 false /* normalized */, 2 /* n_array_elements */, array_align * 2, sixth_offset);
10543 vs_buf_block->Member("at_eigth_offset", "layout(align = 8 * basic_size)", 0 /* expected_component */,
10544 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
10547 Utils::ShaderInterface& vs_si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
10550 vs_si.m_globals = globals;
10552 /* Add uniform BLOCK */
10553 vs_si.SSB("vs_buf_block", "layout (std140, binding = BINDING)", 0, 0, vs_buf_block, 0,
10554 static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
10557 program_interface.CloneVertexInterface(varying_passthrough);
10562 * @param test_case_index Index of test case
10564 * @return Name of type test in test_case_index
10566 std::string SSBMemberOffsetAndAlignTest::getTestCaseName(glw::GLuint test_case_index)
10568 return getTypeName(test_case_index);
10571 /** Returns number of types to test
10573 * @return Number of types, 34
10575 glw::GLuint SSBMemberOffsetAndAlignTest::getTestCaseNumber()
10577 return getTypesNumber();
10580 /** Prepare code snippet that will verify in and uniform variables
10584 * @param stage Shader stage
10586 * @return Code that verify variables
10588 std::string SSBMemberOffsetAndAlignTest::getVerificationSnippet(GLuint /* test_case_index */,
10589 Utils::ProgramInterface& /* program_interface */,
10590 Utils::Shader::STAGES stage)
10592 std::string verification = "if ( (PREFIXblock.at_first_offset != PREFIXblock.at_eigth_offset ) ||\n"
10593 " (PREFIXblock.at_second_offset != PREFIXblock.at_sixth_offset[1]) ||\n"
10594 " (PREFIXblock.at_third_offset != PREFIXblock.at_sixth_offset[0]) ||\n"
10595 " (PREFIXblock.at_fourth_offset != PREFIXblock.at_fifth_offset ) )\n"
10600 const GLchar* prefix = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::SSB);
10602 Utils::replaceAllTokens("PREFIX", prefix, verification);
10604 return verification;
10607 /** Selects if "draw" stages are relevant for test
10611 * @return true if all stages support shader storage buffers, false otherwise
10613 bool SSBMemberOffsetAndAlignTest::isDrawRelevant(GLuint /* test_case_index */)
10615 const Functions& gl = m_context.getRenderContext().getFunctions();
10616 GLint gs_supported_buffers = 0;
10617 GLint tcs_supported_buffers = 0;
10618 GLint tes_supported_buffers = 0;
10619 GLint vs_supported_buffers = 0;
10621 gl.getIntegerv(GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS, &gs_supported_buffers);
10622 gl.getIntegerv(GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS, &tcs_supported_buffers);
10623 gl.getIntegerv(GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS, &tes_supported_buffers);
10624 gl.getIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &vs_supported_buffers);
10626 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
10628 return ((1 <= gs_supported_buffers) && (1 <= tcs_supported_buffers) && (1 <= tes_supported_buffers) &&
10629 (1 <= vs_supported_buffers));
10634 * @param context Test framework context
10636 SSBLayoutQualifierConflictTest::SSBLayoutQualifierConflictTest(deqp::Context& context)
10637 : NegativeTestBase(context, "ssb_layout_qualifier_conflict", "Test verifies that std140 or std430 is required when "
10638 "offset and/or align qualifiers are used with storage "
10641 /* Nothing to be done here */
10644 /** Source for given test case and stage
10646 * @param test_case_index Index of test case
10647 * @param stage Shader stage
10649 * @return Shader source
10651 std::string SSBLayoutQualifierConflictTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
10653 static const GLchar* cs = "#version 430 core\n"
10654 "#extension GL_ARB_enhanced_layouts : require\n"
10656 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
10658 "layout (QUALIFIERbinding = BINDING) buffer cs_Block {\n"
10659 " layout(offset = 16) vec4 boy;\n"
10660 " layout(align = 64) vec4 man;\n"
10663 "writeonly uniform image2D uni_image;\n"
10667 " vec4 result = uni_block.boy + uni_block.man;\n"
10669 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
10672 static const GLchar* fs = "#version 430 core\n"
10673 "#extension GL_ARB_enhanced_layouts : require\n"
10675 "layout (QUALIFIERbinding = BINDING) buffer Block {\n"
10676 " layout(offset = 16) vec4 boy;\n"
10677 " layout(align = 64) vec4 man;\n"
10681 "out vec4 fs_out;\n"
10685 " fs_out = gs_fs + uni_block.boy + uni_block.man;\n"
10688 static const GLchar* gs = "#version 430 core\n"
10689 "#extension GL_ARB_enhanced_layouts : require\n"
10691 "layout(points) in;\n"
10692 "layout(triangle_strip, max_vertices = 4) out;\n"
10694 "layout (QUALIFIERbinding = BINDING) buffer gs_Block {\n"
10695 " layout(offset = 16) vec4 boy;\n"
10696 " layout(align = 64) vec4 man;\n"
10699 "in vec4 tes_gs[];\n"
10700 "out vec4 gs_fs;\n"
10704 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
10705 " gl_Position = vec4(-1, -1, 0, 1);\n"
10707 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
10708 " gl_Position = vec4(-1, 1, 0, 1);\n"
10710 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
10711 " gl_Position = vec4(1, -1, 0, 1);\n"
10713 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
10714 " gl_Position = vec4(1, 1, 0, 1);\n"
10718 static const GLchar* tcs =
10719 "#version 430 core\n"
10720 "#extension GL_ARB_enhanced_layouts : require\n"
10722 "layout(vertices = 1) out;\n"
10724 "layout (QUALIFIERbinding = BINDING) buffer tcs_Block {\n"
10725 " layout(offset = 16) vec4 boy;\n"
10726 " layout(align = 64) vec4 man;\n"
10729 "in vec4 vs_tcs[];\n"
10730 "out vec4 tcs_tes[];\n"
10735 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID] + uni_block.boy + uni_block.man;\n"
10737 " gl_TessLevelOuter[0] = 1.0;\n"
10738 " gl_TessLevelOuter[1] = 1.0;\n"
10739 " gl_TessLevelOuter[2] = 1.0;\n"
10740 " gl_TessLevelOuter[3] = 1.0;\n"
10741 " gl_TessLevelInner[0] = 1.0;\n"
10742 " gl_TessLevelInner[1] = 1.0;\n"
10745 static const GLchar* tes = "#version 430 core\n"
10746 "#extension GL_ARB_enhanced_layouts : require\n"
10748 "layout(isolines, point_mode) in;\n"
10750 "layout (QUALIFIERbinding = BINDING) buffer tes_Block {\n"
10751 " layout(offset = 16) vec4 boy;\n"
10752 " layout(align = 64) vec4 man;\n"
10755 "in vec4 tcs_tes[];\n"
10756 "out vec4 tes_gs;\n"
10760 " tes_gs = tcs_tes[0] + uni_block.boy + uni_block.man;\n"
10763 static const GLchar* vs = "#version 430 core\n"
10764 "#extension GL_ARB_enhanced_layouts : require\n"
10766 "layout (QUALIFIERbinding = BINDING) buffer vs_Block {\n"
10767 " layout(offset = 16) vec4 boy;\n"
10768 " layout(align = 64) vec4 man;\n"
10772 "out vec4 vs_tcs;\n"
10776 " vs_tcs = in_vs + uni_block.boy + uni_block.man;\n"
10781 size_t position = 0;
10782 std::string source;
10783 testCase& test_case = m_test_cases[test_case_index];
10784 std::string qualifier = getQualifierName(test_case.m_qualifier);
10786 if (false == qualifier.empty())
10788 qualifier.append(", ");
10791 sprintf(buffer, "%d", stage);
10795 case Utils::Shader::COMPUTE:
10798 case Utils::Shader::FRAGMENT:
10801 case Utils::Shader::GEOMETRY:
10804 case Utils::Shader::TESS_CTRL:
10807 case Utils::Shader::TESS_EVAL:
10810 case Utils::Shader::VERTEX:
10814 TCU_FAIL("Invalid enum");
10817 if (test_case.m_stage == stage)
10819 Utils::replaceToken("QUALIFIER", position, qualifier.c_str(), source);
10823 Utils::replaceToken("QUALIFIER", position, "std140, ", source);
10826 Utils::replaceToken("BINDING", position, buffer, source);
10831 /** Get description of test case
10833 * @param test_case_index Index of test case
10835 * @return Qualifier name
10837 std::string SSBLayoutQualifierConflictTest::getTestCaseName(GLuint test_case_index)
10839 std::string result = getQualifierName(m_test_cases[test_case_index].m_qualifier);
10844 /** Get number of test cases
10846 * @return Number of test cases
10848 GLuint SSBLayoutQualifierConflictTest::getTestCaseNumber()
10850 return static_cast<GLuint>(m_test_cases.size());
10853 /** Selects if "compute" stage is relevant for test
10855 * @param test_case_index Index of test case
10857 * @return true when tested stage is compute
10859 bool SSBLayoutQualifierConflictTest::isComputeRelevant(GLuint test_case_index)
10861 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
10864 /** Selects if compilation failure is expected result
10866 * @param test_case_index Index of test case
10868 * @return false for STD140 and STD430 cases, true otherwise
10870 bool SSBLayoutQualifierConflictTest::isFailureExpected(GLuint test_case_index)
10872 const QUALIFIERS qualifier = m_test_cases[test_case_index].m_qualifier;
10874 return !((STD140 == qualifier) || (STD430 == qualifier));
10877 /** Checks if stage is supported
10879 * @param stage Shader stage
10881 * @return true if supported, false otherwise
10883 bool SSBLayoutQualifierConflictTest::isStageSupported(Utils::Shader::STAGES stage)
10885 const Functions& gl = m_context.getRenderContext().getFunctions();
10886 GLint max_supported_buffers = 0;
10891 case Utils::Shader::COMPUTE:
10892 pname = GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS;
10894 case Utils::Shader::FRAGMENT:
10895 pname = GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS;
10897 case Utils::Shader::GEOMETRY:
10898 pname = GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS;
10900 case Utils::Shader::TESS_CTRL:
10901 pname = GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS;
10903 case Utils::Shader::TESS_EVAL:
10904 pname = GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS;
10906 case Utils::Shader::VERTEX:
10907 pname = GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS;
10910 TCU_FAIL("Invalid enum");
10913 gl.getIntegerv(pname, &max_supported_buffers);
10914 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
10916 return 1 <= max_supported_buffers;
10919 /** Prepare all test cases
10922 void SSBLayoutQualifierConflictTest::testInit()
10924 bool stage_support[Utils::Shader::STAGE_MAX];
10926 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
10928 stage_support[stage] = isStageSupported((Utils::Shader::STAGES)stage);
10931 for (GLuint qualifier = 0; qualifier < QUALIFIERS_MAX; ++qualifier)
10933 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
10935 if (false == stage_support[stage])
10940 testCase test_case = { (QUALIFIERS)qualifier, (Utils::Shader::STAGES)stage };
10942 m_test_cases.push_back(test_case);
10947 /** Get name of glsl constant
10949 * @param Constant id
10951 * @return Name of constant used in GLSL
10953 const GLchar* SSBLayoutQualifierConflictTest::getQualifierName(QUALIFIERS qualifier)
10955 const GLchar* name = "";
10975 TCU_FAIL("Invalid enum");
10983 * @param context Test framework context
10985 SSBMemberInvalidOffsetAlignmentTest::SSBMemberInvalidOffsetAlignmentTest(deqp::Context& context)
10986 : UniformBlockMemberInvalidOffsetAlignmentTest(
10987 context, "ssb_member_invalid_offset_alignment",
10988 "Test verifies that invalid alignment of offset qualifiers cause compilation failure")
10990 /* Nothing to be done here */
10993 /** Source for given test case and stage
10995 * @param test_case_index Index of test case
10996 * @param stage Shader stage
10998 * @return Shader source
11000 std::string SSBMemberInvalidOffsetAlignmentTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
11002 static const GLchar* cs = "#version 430 core\n"
11003 "#extension GL_ARB_enhanced_layouts : require\n"
11005 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
11007 "layout (std140) buffer Block {\n"
11008 " layout (offset = OFFSET) TYPE member;\n"
11011 "writeonly uniform image2D uni_image;\n"
11015 " vec4 result = vec4(1, 0, 0.5, 1);\n"
11017 " if (TYPE(1) == block.member)\n"
11019 " result = vec4(1, 1, 1, 1);\n"
11022 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
11025 static const GLchar* fs = "#version 430 core\n"
11026 "#extension GL_ARB_enhanced_layouts : require\n"
11029 "out vec4 fs_out;\n"
11033 " fs_out = gs_fs;\n"
11036 static const GLchar* fs_tested = "#version 430 core\n"
11037 "#extension GL_ARB_enhanced_layouts : require\n"
11039 "layout (std140) buffer Block {\n"
11040 " layout (offset = OFFSET) TYPE member;\n"
11044 "out vec4 fs_out;\n"
11048 " if (TYPE(1) == block.member)\n"
11050 " fs_out = vec4(1, 1, 1, 1);\n"
11053 " fs_out += gs_fs;\n"
11056 static const GLchar* gs = "#version 430 core\n"
11057 "#extension GL_ARB_enhanced_layouts : require\n"
11059 "layout(points) in;\n"
11060 "layout(triangle_strip, max_vertices = 4) out;\n"
11062 "in vec4 tes_gs[];\n"
11063 "out vec4 gs_fs;\n"
11067 " gs_fs = tes_gs[0];\n"
11068 " gl_Position = vec4(-1, -1, 0, 1);\n"
11070 " gs_fs = tes_gs[0];\n"
11071 " gl_Position = vec4(-1, 1, 0, 1);\n"
11073 " gs_fs = tes_gs[0];\n"
11074 " gl_Position = vec4(1, -1, 0, 1);\n"
11076 " gs_fs = tes_gs[0];\n"
11077 " gl_Position = vec4(1, 1, 0, 1);\n"
11081 static const GLchar* gs_tested = "#version 430 core\n"
11082 "#extension GL_ARB_enhanced_layouts : require\n"
11084 "layout(points) in;\n"
11085 "layout(triangle_strip, max_vertices = 4) out;\n"
11087 "layout (std140) buffer Block {\n"
11088 " layout (offset = OFFSET) TYPE member;\n"
11091 "in vec4 tes_gs[];\n"
11092 "out vec4 gs_fs;\n"
11096 " if (TYPE(1) == block.member)\n"
11098 " gs_fs = vec4(1, 1, 1, 1);\n"
11101 " gs_fs += tes_gs[0];\n"
11102 " gl_Position = vec4(-1, -1, 0, 1);\n"
11104 " gs_fs += tes_gs[0];\n"
11105 " gl_Position = vec4(-1, 1, 0, 1);\n"
11107 " gs_fs += tes_gs[0];\n"
11108 " gl_Position = vec4(1, -1, 0, 1);\n"
11110 " gs_fs += tes_gs[0];\n"
11111 " gl_Position = vec4(1, 1, 0, 1);\n"
11115 static const GLchar* tcs = "#version 430 core\n"
11116 "#extension GL_ARB_enhanced_layouts : require\n"
11118 "layout(vertices = 1) out;\n"
11120 "in vec4 vs_tcs[];\n"
11121 "out vec4 tcs_tes[];\n"
11126 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
11128 " gl_TessLevelOuter[0] = 1.0;\n"
11129 " gl_TessLevelOuter[1] = 1.0;\n"
11130 " gl_TessLevelOuter[2] = 1.0;\n"
11131 " gl_TessLevelOuter[3] = 1.0;\n"
11132 " gl_TessLevelInner[0] = 1.0;\n"
11133 " gl_TessLevelInner[1] = 1.0;\n"
11136 static const GLchar* tcs_tested = "#version 430 core\n"
11137 "#extension GL_ARB_enhanced_layouts : require\n"
11139 "layout(vertices = 1) out;\n"
11141 "layout (std140) buffer Block {\n"
11142 " layout (offset = OFFSET) TYPE member;\n"
11145 "in vec4 vs_tcs[];\n"
11146 "out vec4 tcs_tes[];\n"
11150 " if (TYPE(1) == block.member)\n"
11152 " tcs_tes[gl_InvocationID] = vec4(1, 1, 1, 1);\n"
11156 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
11158 " gl_TessLevelOuter[0] = 1.0;\n"
11159 " gl_TessLevelOuter[1] = 1.0;\n"
11160 " gl_TessLevelOuter[2] = 1.0;\n"
11161 " gl_TessLevelOuter[3] = 1.0;\n"
11162 " gl_TessLevelInner[0] = 1.0;\n"
11163 " gl_TessLevelInner[1] = 1.0;\n"
11166 static const GLchar* tes = "#version 430 core\n"
11167 "#extension GL_ARB_enhanced_layouts : require\n"
11169 "layout(isolines, point_mode) in;\n"
11171 "in vec4 tcs_tes[];\n"
11172 "out vec4 tes_gs;\n"
11176 " tes_gs = tcs_tes[0];\n"
11179 static const GLchar* tes_tested = "#version 430 core\n"
11180 "#extension GL_ARB_enhanced_layouts : require\n"
11182 "layout(isolines, point_mode) in;\n"
11184 "layout (std140) buffer Block {\n"
11185 " layout (offset = OFFSET) TYPE member;\n"
11188 "in vec4 tcs_tes[];\n"
11189 "out vec4 tes_gs;\n"
11193 " if (TYPE(1) == block.member)\n"
11195 " tes_gs = vec4(1, 1, 1, 1);\n"
11198 " tes_gs += tcs_tes[0];\n"
11201 static const GLchar* vs = "#version 430 core\n"
11202 "#extension GL_ARB_enhanced_layouts : require\n"
11205 "out vec4 vs_tcs;\n"
11209 " vs_tcs = in_vs;\n"
11212 static const GLchar* vs_tested = "#version 430 core\n"
11213 "#extension GL_ARB_enhanced_layouts : require\n"
11215 "layout (std140) buffer Block {\n"
11216 " layout (offset = OFFSET) TYPE member;\n"
11220 "out vec4 vs_tcs;\n"
11224 " if (TYPE(1) == block.member)\n"
11226 " vs_tcs = vec4(1, 1, 1, 1);\n"
11229 " vs_tcs += in_vs;\n"
11233 std::string source;
11234 testCase& test_case = m_test_cases[test_case_index];
11236 if (test_case.m_stage == stage)
11239 const GLuint offset = test_case.m_offset;
11240 size_t position = 0;
11241 const Utils::Type& type = test_case.m_type;
11242 const GLchar* type_name = type.GetGLSLTypeName();
11244 sprintf(buffer, "%d", offset);
11248 case Utils::Shader::COMPUTE:
11251 case Utils::Shader::FRAGMENT:
11252 source = fs_tested;
11254 case Utils::Shader::GEOMETRY:
11255 source = gs_tested;
11257 case Utils::Shader::TESS_CTRL:
11258 source = tcs_tested;
11260 case Utils::Shader::TESS_EVAL:
11261 source = tes_tested;
11263 case Utils::Shader::VERTEX:
11264 source = vs_tested;
11267 TCU_FAIL("Invalid enum");
11270 Utils::replaceToken("OFFSET", position, buffer, source);
11271 Utils::replaceToken("TYPE", position, type_name, source);
11272 Utils::replaceToken("TYPE", position, type_name, source);
11278 case Utils::Shader::FRAGMENT:
11281 case Utils::Shader::GEOMETRY:
11284 case Utils::Shader::TESS_CTRL:
11287 case Utils::Shader::TESS_EVAL:
11290 case Utils::Shader::VERTEX:
11294 TCU_FAIL("Invalid enum");
11301 /** Checks if stage is supported
11303 * @param stage Shader stage
11305 * @return true if supported, false otherwise
11307 bool SSBMemberInvalidOffsetAlignmentTest::isStageSupported(Utils::Shader::STAGES stage)
11309 const Functions& gl = m_context.getRenderContext().getFunctions();
11310 GLint max_supported_buffers = 0;
11315 case Utils::Shader::COMPUTE:
11316 pname = GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS;
11318 case Utils::Shader::FRAGMENT:
11319 pname = GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS;
11321 case Utils::Shader::GEOMETRY:
11322 pname = GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS;
11324 case Utils::Shader::TESS_CTRL:
11325 pname = GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS;
11327 case Utils::Shader::TESS_EVAL:
11328 pname = GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS;
11330 case Utils::Shader::VERTEX:
11331 pname = GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS;
11334 TCU_FAIL("Invalid enum");
11337 gl.getIntegerv(pname, &max_supported_buffers);
11338 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
11340 return 1 <= max_supported_buffers;
11345 * @param context Test framework context
11347 SSBMemberOverlappingOffsetsTest::SSBMemberOverlappingOffsetsTest(deqp::Context& context)
11348 : UniformBlockMemberOverlappingOffsetsTest(
11349 context, "ssb_member_overlapping_offsets",
11350 "Test verifies that overlapping offsets qualifiers cause compilation failure")
11352 /* Nothing to be done here */
11355 /** Source for given test case and stage
11357 * @param test_case_index Index of test case
11358 * @param stage Shader stage
11360 * @return Shader source
11362 std::string SSBMemberOverlappingOffsetsTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
11364 static const GLchar* cs = "#version 430 core\n"
11365 "#extension GL_ARB_enhanced_layouts : require\n"
11367 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
11369 "layout (std140) buffer Block {\n"
11370 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11371 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11374 "writeonly uniform image2D uni_image;\n"
11378 " vec4 result = vec4(1, 0, 0.5, 1);\n"
11380 " if ((BOY_TYPE(1) == block.boy) ||\n"
11381 " (MAN_TYPE(0) == block.man) )\n"
11383 " result = vec4(1, 1, 1, 1);\n"
11386 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
11389 static const GLchar* fs = "#version 430 core\n"
11390 "#extension GL_ARB_enhanced_layouts : require\n"
11393 "out vec4 fs_out;\n"
11397 " fs_out = gs_fs;\n"
11400 static const GLchar* fs_tested = "#version 430 core\n"
11401 "#extension GL_ARB_enhanced_layouts : require\n"
11403 "layout (std140) buffer Block {\n"
11404 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11405 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11409 "out vec4 fs_out;\n"
11413 " if ((BOY_TYPE(1) == block.boy) ||\n"
11414 " (MAN_TYPE(0) == block.man) )\n"
11416 " fs_out = vec4(1, 1, 1, 1);\n"
11419 " fs_out += gs_fs;\n"
11422 static const GLchar* gs = "#version 430 core\n"
11423 "#extension GL_ARB_enhanced_layouts : require\n"
11425 "layout(points) in;\n"
11426 "layout(triangle_strip, max_vertices = 4) out;\n"
11428 "in vec4 tes_gs[];\n"
11429 "out vec4 gs_fs;\n"
11433 " gs_fs = tes_gs[0];\n"
11434 " gl_Position = vec4(-1, -1, 0, 1);\n"
11436 " gs_fs = tes_gs[0];\n"
11437 " gl_Position = vec4(-1, 1, 0, 1);\n"
11439 " gs_fs = tes_gs[0];\n"
11440 " gl_Position = vec4(1, -1, 0, 1);\n"
11442 " gs_fs = tes_gs[0];\n"
11443 " gl_Position = vec4(1, 1, 0, 1);\n"
11447 static const GLchar* gs_tested = "#version 430 core\n"
11448 "#extension GL_ARB_enhanced_layouts : require\n"
11450 "layout(points) in;\n"
11451 "layout(triangle_strip, max_vertices = 4) out;\n"
11453 "layout (std140) buffer Block {\n"
11454 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11455 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11458 "in vec4 tes_gs[];\n"
11459 "out vec4 gs_fs;\n"
11463 " if ((BOY_TYPE(1) == block.boy) ||\n"
11464 " (MAN_TYPE(0) == block.man) )\n"
11466 " gs_fs = vec4(1, 1, 1, 1);\n"
11469 " gs_fs += tes_gs[0];\n"
11470 " gl_Position = vec4(-1, -1, 0, 1);\n"
11472 " gs_fs += tes_gs[0];\n"
11473 " gl_Position = vec4(-1, 1, 0, 1);\n"
11475 " gs_fs += tes_gs[0];\n"
11476 " gl_Position = vec4(1, -1, 0, 1);\n"
11478 " gs_fs += tes_gs[0];\n"
11479 " gl_Position = vec4(1, 1, 0, 1);\n"
11483 static const GLchar* tcs = "#version 430 core\n"
11484 "#extension GL_ARB_enhanced_layouts : require\n"
11486 "layout(vertices = 1) out;\n"
11488 "in vec4 vs_tcs[];\n"
11489 "out vec4 tcs_tes[];\n"
11494 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
11496 " gl_TessLevelOuter[0] = 1.0;\n"
11497 " gl_TessLevelOuter[1] = 1.0;\n"
11498 " gl_TessLevelOuter[2] = 1.0;\n"
11499 " gl_TessLevelOuter[3] = 1.0;\n"
11500 " gl_TessLevelInner[0] = 1.0;\n"
11501 " gl_TessLevelInner[1] = 1.0;\n"
11504 static const GLchar* tcs_tested = "#version 430 core\n"
11505 "#extension GL_ARB_enhanced_layouts : require\n"
11507 "layout(vertices = 1) out;\n"
11509 "layout (std140) buffer Block {\n"
11510 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11511 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11514 "in vec4 vs_tcs[];\n"
11515 "out vec4 tcs_tes[];\n"
11519 " if ((BOY_TYPE(1) == block.boy) ||\n"
11520 " (MAN_TYPE(0) == block.man) )\n"
11522 " tcs_tes[gl_InvocationID] = vec4(1, 1, 1, 1);\n"
11526 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
11528 " gl_TessLevelOuter[0] = 1.0;\n"
11529 " gl_TessLevelOuter[1] = 1.0;\n"
11530 " gl_TessLevelOuter[2] = 1.0;\n"
11531 " gl_TessLevelOuter[3] = 1.0;\n"
11532 " gl_TessLevelInner[0] = 1.0;\n"
11533 " gl_TessLevelInner[1] = 1.0;\n"
11536 static const GLchar* tes = "#version 430 core\n"
11537 "#extension GL_ARB_enhanced_layouts : require\n"
11539 "layout(isolines, point_mode) in;\n"
11541 "in vec4 tcs_tes[];\n"
11542 "out vec4 tes_gs;\n"
11546 " tes_gs = tcs_tes[0];\n"
11549 static const GLchar* tes_tested = "#version 430 core\n"
11550 "#extension GL_ARB_enhanced_layouts : require\n"
11552 "layout(isolines, point_mode) in;\n"
11554 "layout (std140) buffer Block {\n"
11555 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11556 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11559 "in vec4 tcs_tes[];\n"
11560 "out vec4 tes_gs;\n"
11564 " if ((BOY_TYPE(1) == block.boy) ||\n"
11565 " (MAN_TYPE(0) == block.man) )\n"
11567 " tes_gs = vec4(1, 1, 1, 1);\n"
11570 " tes_gs += tcs_tes[0];\n"
11573 static const GLchar* vs = "#version 430 core\n"
11574 "#extension GL_ARB_enhanced_layouts : require\n"
11577 "out vec4 vs_tcs;\n"
11581 " vs_tcs = in_vs;\n"
11584 static const GLchar* vs_tested = "#version 430 core\n"
11585 "#extension GL_ARB_enhanced_layouts : require\n"
11587 "layout (std140) buffer Block {\n"
11588 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11589 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11593 "out vec4 vs_tcs;\n"
11597 " if ((BOY_TYPE(1) == block.boy) ||\n"
11598 " (MAN_TYPE(0) == block.man) )\n"
11600 " vs_tcs = vec4(1, 1, 1, 1);\n"
11603 " vs_tcs += in_vs;\n"
11607 std::string source;
11608 testCase& test_case = m_test_cases[test_case_index];
11610 if (test_case.m_stage == stage)
11613 const GLuint boy_offset = test_case.m_boy_offset;
11614 const Utils::Type& boy_type = test_case.m_boy_type;
11615 const GLchar* boy_type_name = boy_type.GetGLSLTypeName();
11616 const GLuint man_offset = test_case.m_man_offset;
11617 const Utils::Type& man_type = test_case.m_man_type;
11618 const GLchar* man_type_name = man_type.GetGLSLTypeName();
11619 size_t position = 0;
11623 case Utils::Shader::COMPUTE:
11626 case Utils::Shader::FRAGMENT:
11627 source = fs_tested;
11629 case Utils::Shader::GEOMETRY:
11630 source = gs_tested;
11632 case Utils::Shader::TESS_CTRL:
11633 source = tcs_tested;
11635 case Utils::Shader::TESS_EVAL:
11636 source = tes_tested;
11638 case Utils::Shader::VERTEX:
11639 source = vs_tested;
11642 TCU_FAIL("Invalid enum");
11645 sprintf(buffer, "%d", boy_offset);
11646 Utils::replaceToken("BOY_OFFSET", position, buffer, source);
11647 Utils::replaceToken("BOY_TYPE", position, boy_type_name, source);
11648 sprintf(buffer, "%d", man_offset);
11649 Utils::replaceToken("MAN_OFFSET", position, buffer, source);
11650 Utils::replaceToken("MAN_TYPE", position, man_type_name, source);
11651 Utils::replaceToken("BOY_TYPE", position, boy_type_name, source);
11652 Utils::replaceToken("MAN_TYPE", position, man_type_name, source);
11658 case Utils::Shader::FRAGMENT:
11661 case Utils::Shader::GEOMETRY:
11664 case Utils::Shader::TESS_CTRL:
11667 case Utils::Shader::TESS_EVAL:
11670 case Utils::Shader::VERTEX:
11674 TCU_FAIL("Invalid enum");
11681 /** Checks if stage is supported
11683 * @param stage Shader stage
11685 * @return true if supported, false otherwise
11687 bool SSBMemberOverlappingOffsetsTest::isStageSupported(Utils::Shader::STAGES stage)
11689 const Functions& gl = m_context.getRenderContext().getFunctions();
11690 GLint max_supported_buffers = 0;
11695 case Utils::Shader::COMPUTE:
11696 pname = GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS;
11698 case Utils::Shader::FRAGMENT:
11699 pname = GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS;
11701 case Utils::Shader::GEOMETRY:
11702 pname = GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS;
11704 case Utils::Shader::TESS_CTRL:
11705 pname = GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS;
11707 case Utils::Shader::TESS_EVAL:
11708 pname = GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS;
11710 case Utils::Shader::VERTEX:
11711 pname = GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS;
11714 TCU_FAIL("Invalid enum");
11717 gl.getIntegerv(pname, &max_supported_buffers);
11718 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
11720 return 1 <= max_supported_buffers;
11725 * @param context Test framework context
11727 SSBMemberAlignNonPowerOf2Test::SSBMemberAlignNonPowerOf2Test(deqp::Context& context)
11728 : UniformBlockMemberAlignNonPowerOf2Test(context, "ssb_member_align_non_power_of_2",
11729 "Test verifies that align qualifier requires value that is a power of 2")
11731 /* Nothing to be done here */
11734 /** Source for given test case and stage
11736 * @param test_case_index Index of test case
11737 * @param stage Shader stage
11739 * @return Shader source
11741 std::string SSBMemberAlignNonPowerOf2Test::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
11743 static const GLchar* cs = "#version 430 core\n"
11744 "#extension GL_ARB_enhanced_layouts : require\n"
11746 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
11748 "layout (std140) buffer Block {\n"
11750 " layout (align = ALIGN) TYPE man;\n"
11753 "writeonly uniform image2D uni_image;\n"
11757 " vec4 result = vec4(1, 0, 0.5, 1);\n"
11759 " if (TYPE(0) == block.man)\n"
11761 " result = vec4(1, 1, 1, 1) - block.boy;\n"
11764 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
11767 static const GLchar* fs = "#version 430 core\n"
11768 "#extension GL_ARB_enhanced_layouts : require\n"
11771 "out vec4 fs_out;\n"
11775 " fs_out = gs_fs;\n"
11778 static const GLchar* fs_tested = "#version 430 core\n"
11779 "#extension GL_ARB_enhanced_layouts : require\n"
11781 "layout (std140) buffer Block {\n"
11783 " layout (align = ALIGN) TYPE man;\n"
11787 "out vec4 fs_out;\n"
11791 " if (TYPE(0) == block.man)\n"
11793 " fs_out = block.boy;\n"
11796 " fs_out += gs_fs;\n"
11799 static const GLchar* gs = "#version 430 core\n"
11800 "#extension GL_ARB_enhanced_layouts : require\n"
11802 "layout(points) in;\n"
11803 "layout(triangle_strip, max_vertices = 4) out;\n"
11805 "in vec4 tes_gs[];\n"
11806 "out vec4 gs_fs;\n"
11810 " gs_fs = tes_gs[0];\n"
11811 " gl_Position = vec4(-1, -1, 0, 1);\n"
11813 " gs_fs = tes_gs[0];\n"
11814 " gl_Position = vec4(-1, 1, 0, 1);\n"
11816 " gs_fs = tes_gs[0];\n"
11817 " gl_Position = vec4(1, -1, 0, 1);\n"
11819 " gs_fs = tes_gs[0];\n"
11820 " gl_Position = vec4(1, 1, 0, 1);\n"
11824 static const GLchar* gs_tested = "#version 430 core\n"
11825 "#extension GL_ARB_enhanced_layouts : require\n"
11827 "layout(points) in;\n"
11828 "layout(triangle_strip, max_vertices = 4) out;\n"
11830 "layout (std140) buffer Block {\n"
11832 " layout (align = ALIGN) TYPE man;\n"
11835 "in vec4 tes_gs[];\n"
11836 "out vec4 gs_fs;\n"
11840 " if (TYPE(0) == block.man)\n"
11842 " gs_fs = block.boy;\n"
11845 " gs_fs += tes_gs[0];\n"
11846 " gl_Position = vec4(-1, -1, 0, 1);\n"
11848 " gs_fs += tes_gs[0];\n"
11849 " gl_Position = vec4(-1, 1, 0, 1);\n"
11851 " gs_fs += tes_gs[0];\n"
11852 " gl_Position = vec4(1, -1, 0, 1);\n"
11854 " gs_fs += tes_gs[0];\n"
11855 " gl_Position = vec4(1, 1, 0, 1);\n"
11859 static const GLchar* tcs = "#version 430 core\n"
11860 "#extension GL_ARB_enhanced_layouts : require\n"
11862 "layout(vertices = 1) out;\n"
11864 "in vec4 vs_tcs[];\n"
11865 "out vec4 tcs_tes[];\n"
11870 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
11872 " gl_TessLevelOuter[0] = 1.0;\n"
11873 " gl_TessLevelOuter[1] = 1.0;\n"
11874 " gl_TessLevelOuter[2] = 1.0;\n"
11875 " gl_TessLevelOuter[3] = 1.0;\n"
11876 " gl_TessLevelInner[0] = 1.0;\n"
11877 " gl_TessLevelInner[1] = 1.0;\n"
11880 static const GLchar* tcs_tested = "#version 430 core\n"
11881 "#extension GL_ARB_enhanced_layouts : require\n"
11883 "layout(vertices = 1) out;\n"
11885 "layout (std140) buffer Block {\n"
11887 " layout (align = ALIGN) TYPE man;\n"
11890 "in vec4 vs_tcs[];\n"
11891 "out vec4 tcs_tes[];\n"
11895 " if (TYPE(0) == block.man)\n"
11897 " tcs_tes[gl_InvocationID] = block.boy;\n"
11901 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
11903 " gl_TessLevelOuter[0] = 1.0;\n"
11904 " gl_TessLevelOuter[1] = 1.0;\n"
11905 " gl_TessLevelOuter[2] = 1.0;\n"
11906 " gl_TessLevelOuter[3] = 1.0;\n"
11907 " gl_TessLevelInner[0] = 1.0;\n"
11908 " gl_TessLevelInner[1] = 1.0;\n"
11911 static const GLchar* tes = "#version 430 core\n"
11912 "#extension GL_ARB_enhanced_layouts : require\n"
11914 "layout(isolines, point_mode) in;\n"
11916 "in vec4 tcs_tes[];\n"
11917 "out vec4 tes_gs;\n"
11921 " tes_gs = tcs_tes[0];\n"
11924 static const GLchar* tes_tested = "#version 430 core\n"
11925 "#extension GL_ARB_enhanced_layouts : require\n"
11927 "layout(isolines, point_mode) in;\n"
11929 "layout (std140) buffer Block {\n"
11931 " layout (align = ALIGN) TYPE man;\n"
11934 "in vec4 tcs_tes[];\n"
11935 "out vec4 tes_gs;\n"
11939 " if (TYPE(0) == block.man)\n"
11941 " tes_gs = block.boy;\n"
11944 " tes_gs += tcs_tes[0];\n"
11947 static const GLchar* vs = "#version 430 core\n"
11948 "#extension GL_ARB_enhanced_layouts : require\n"
11951 "out vec4 vs_tcs;\n"
11955 " vs_tcs = in_vs;\n"
11958 static const GLchar* vs_tested = "#version 430 core\n"
11959 "#extension GL_ARB_enhanced_layouts : require\n"
11961 "layout (std140) buffer Block {\n"
11963 " layout (align = ALIGN) TYPE man;\n"
11967 "out vec4 vs_tcs;\n"
11971 " if (TYPE(0) == block.man)\n"
11973 " vs_tcs = block.boy;\n"
11976 " vs_tcs += in_vs;\n"
11980 std::string source;
11981 testCase& test_case = m_test_cases[test_case_index];
11983 if (test_case.m_stage == stage)
11986 const GLuint alignment = test_case.m_alignment;
11987 const Utils::Type& type = test_case.m_type;
11988 const GLchar* type_name = type.GetGLSLTypeName();
11989 size_t position = 0;
11993 case Utils::Shader::COMPUTE:
11996 case Utils::Shader::FRAGMENT:
11997 source = fs_tested;
11999 case Utils::Shader::GEOMETRY:
12000 source = gs_tested;
12002 case Utils::Shader::TESS_CTRL:
12003 source = tcs_tested;
12005 case Utils::Shader::TESS_EVAL:
12006 source = tes_tested;
12008 case Utils::Shader::VERTEX:
12009 source = vs_tested;
12012 TCU_FAIL("Invalid enum");
12015 sprintf(buffer, "%d", alignment);
12016 Utils::replaceToken("ALIGN", position, buffer, source);
12017 Utils::replaceToken("TYPE", position, type_name, source);
12018 Utils::replaceToken("TYPE", position, type_name, source);
12024 case Utils::Shader::FRAGMENT:
12027 case Utils::Shader::GEOMETRY:
12030 case Utils::Shader::TESS_CTRL:
12033 case Utils::Shader::TESS_EVAL:
12036 case Utils::Shader::VERTEX:
12040 TCU_FAIL("Invalid enum");
12047 /** Checks if stage is supported
12049 * @param stage Shader stage
12051 * @return true if supported, false otherwise
12053 bool SSBMemberAlignNonPowerOf2Test::isStageSupported(Utils::Shader::STAGES stage)
12055 const Functions& gl = m_context.getRenderContext().getFunctions();
12056 GLint max_supported_buffers = 0;
12061 case Utils::Shader::COMPUTE:
12062 pname = GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS;
12064 case Utils::Shader::FRAGMENT:
12065 pname = GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS;
12067 case Utils::Shader::GEOMETRY:
12068 pname = GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS;
12070 case Utils::Shader::TESS_CTRL:
12071 pname = GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS;
12073 case Utils::Shader::TESS_EVAL:
12074 pname = GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS;
12076 case Utils::Shader::VERTEX:
12077 pname = GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS;
12080 TCU_FAIL("Invalid enum");
12083 gl.getIntegerv(pname, &max_supported_buffers);
12084 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
12086 return 1 <= max_supported_buffers;
12091 * @param context Test framework context
12093 SSBAlignmentTest::SSBAlignmentTest(deqp::Context& context)
12094 : TextureTestBase(context, "ssb_alignment", "Test verifies offset and alignment of ssb buffer")
12098 /** Get interface of program
12101 * @param program_interface Interface of program
12102 * @param varying_passthrough Collection of connections between in and out variables
12104 void SSBAlignmentTest::getProgramInterface(GLuint /* test_case_index */, Utils::ProgramInterface& program_interface,
12105 Utils::VaryingPassthrough& varying_passthrough)
12107 static const Utils::Type vec4 = Utils::Type::vec4;
12109 #if WRKARD_UNIFORMBLOCKALIGNMENT
12111 static const GLuint block_align = 16;
12113 #else /* WRKARD_UNIFORMBLOCKALIGNMENT */
12115 static const GLuint block_align = 64;
12117 #endif /* WRKARD_UNIFORMBLOCKALIGNMENT */
12119 static const GLuint fifth_align = 16;
12120 static const GLuint vec4_stride = 16;
12121 static const GLuint data_stride = vec4_stride * 2; /* one vec4 + one scalar aligned to 16 */
12123 const GLuint first_offset = 0; /* vec4 at 0 */
12124 const GLuint second_offset = Utils::Type::GetActualOffset(first_offset + vec4_stride, block_align); /* Data at 32 */
12125 const GLuint third_offset =
12126 Utils::Type::GetActualOffset(second_offset + data_stride, block_align); /* Data[2] at 64 */
12127 const GLuint fourth_offset =
12128 Utils::Type::GetActualOffset(third_offset + data_stride * 2, block_align); /* vec4[3] at 96 */
12129 const GLuint fifth_offset =
12130 Utils::Type::GetActualOffset(fourth_offset + vec4_stride * 3, fifth_align); /* vec4[2] at 160 */
12131 const GLuint sixth_offset =
12132 Utils::Type::GetActualOffset(fifth_offset + vec4_stride * 2, block_align); /* Data at 192 */
12134 Utils::Interface* structure = program_interface.Structure("Data");
12136 structure->Member("vector", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::vec4,
12137 false /* normalized */, 0 /* n_array_elements */, Utils::Type::vec4.GetSize(), 0 /* offset */);
12139 structure->Member("scalar", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::_float,
12140 false /* normalized */, 0 /* n_array_elements */, Utils::Type::_float.GetSize(),
12141 Utils::Type::vec4.GetSize() /* offset */);
12143 /* Prepare Block */
12144 Utils::Interface* vs_buf_Block = program_interface.Block("vs_buf_Block");
12146 vs_buf_Block->Member("first", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::vec4,
12147 false /* normalized */, 0 /* n_array_elements */, vec4_stride, first_offset /* offset */);
12149 vs_buf_Block->Member("second", "", 0 /* expected_component */, 0 /* expected_location */, structure,
12150 0 /* n_array_elements */, data_stride, second_offset);
12152 vs_buf_Block->Member("third", "", 0 /* expected_component */, 0 /* expected_location */, structure,
12153 2 /* n_array_elements */, data_stride, third_offset);
12155 vs_buf_Block->Member("fourth", "", 0 /* expected_component */, 0 /* expected_location */, vec4,
12156 false /* normalized */, 3 /* n_array_elements */, vec4_stride, fourth_offset);
12158 vs_buf_Block->Member("fifth", "layout(align = 16)", 0 /* expected_component */, 0 /* expected_location */, vec4,
12159 false /* normalized */, 2 /* n_array_elements */, vec4_stride, fifth_offset);
12161 vs_buf_Block->Member("sixth", "", 0 /* expected_component */, 0 /* expected_location */, structure,
12162 0 /* n_array_elements */, data_stride, sixth_offset);
12164 const GLuint stride = calculateStride(*vs_buf_Block);
12165 m_data.resize(stride);
12166 generateData(*vs_buf_Block, 0, m_data);
12168 Utils::ShaderInterface& vs_si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
12170 /* Add uniform BLOCK */
12171 #if WRKARD_UNIFORMBLOCKALIGNMENT
12172 vs_si.SSB("vs_buf_block", "layout (std140, binding = BINDING)", 0, 0, vs_buf_Block, 0,
12173 static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
12174 #else /* WRKARD_UNIFORMBLOCKALIGNMENT */
12175 vs_si.SSB("vs_buf_block", "layout (std140, binding = BINDING, align = 64)", 0, 0, vs_buf_Block, 0,
12176 static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
12177 #endif /* WRKARD_UNIFORMBLOCKALIGNMENT */
12179 program_interface.CloneVertexInterface(varying_passthrough);
12182 /** Selects if "draw" stages are relevant for test
12186 * @return true if all stages support shader storage buffers, false otherwise
12188 bool SSBAlignmentTest::isDrawRelevant(GLuint /* test_case_index */)
12190 const Functions& gl = m_context.getRenderContext().getFunctions();
12191 GLint gs_supported_buffers = 0;
12192 GLint tcs_supported_buffers = 0;
12193 GLint tes_supported_buffers = 0;
12194 GLint vs_supported_buffers = 0;
12196 gl.getIntegerv(GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS, &gs_supported_buffers);
12197 gl.getIntegerv(GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS, &tcs_supported_buffers);
12198 gl.getIntegerv(GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS, &tes_supported_buffers);
12199 gl.getIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &vs_supported_buffers);
12201 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
12203 return ((1 <= gs_supported_buffers) && (1 <= tcs_supported_buffers) && (1 <= tes_supported_buffers) &&
12204 (1 <= vs_supported_buffers));
12209 * @param context Test framework context
12211 VaryingLocationsTest::VaryingLocationsTest(deqp::Context& context)
12212 : TextureTestBase(context, "varying_locations", "Test verifies that input and output locations are respected")
12218 * @param context Test context
12219 * @param test_name Name of test
12220 * @param test_description Description of test
12222 VaryingLocationsTest::VaryingLocationsTest(deqp::Context& context, const glw::GLchar* test_name,
12223 const glw::GLchar* test_description)
12224 : TextureTestBase(context, test_name, test_description)
12228 /** Get interface of program
12230 * @param test_case_index Test case
12231 * @param program_interface Interface of program
12232 * @param varying_passthrough Collection of connections between in and out variables
12234 void VaryingLocationsTest::getProgramInterface(GLuint test_case_index, Utils::ProgramInterface& program_interface,
12235 Utils::VaryingPassthrough& varying_passthrough)
12237 const Utils::Type type = getType(test_case_index);
12239 m_first_data = type.GenerateDataPacked();
12240 m_last_data = type.GenerateDataPacked();
12242 prepareShaderStage(Utils::Shader::FRAGMENT, type, program_interface, varying_passthrough);
12243 prepareShaderStage(Utils::Shader::GEOMETRY, type, program_interface, varying_passthrough);
12244 prepareShaderStage(Utils::Shader::TESS_CTRL, type, program_interface, varying_passthrough);
12245 prepareShaderStage(Utils::Shader::TESS_EVAL, type, program_interface, varying_passthrough);
12246 prepareShaderStage(Utils::Shader::VERTEX, type, program_interface, varying_passthrough);
12251 * @param test_case_index Index of test case
12253 * @return Name of type test in test_case_index
12255 std::string VaryingLocationsTest::getTestCaseName(glw::GLuint test_case_index)
12257 return getTypeName(test_case_index);
12260 /** Returns number of types to test
12262 * @return Number of types, 34
12264 glw::GLuint VaryingLocationsTest::getTestCaseNumber()
12266 return getTypesNumber();
12269 /** Selects if "compute" stage is relevant for test
12275 bool VaryingLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
12284 std::string VaryingLocationsTest::prepareGlobals(GLint last_in_loc, GLint last_out_loc)
12287 std::string globals = "const uint first_input_location = 0u;\n"
12288 "const uint first_output_location = 0u;\n"
12289 "const uint last_input_location = LAST_INPUTu;\n"
12290 "const uint last_output_location = LAST_OUTPUTu;\n";
12291 size_t position = 100; /* Skip first part */
12293 sprintf(buffer, "%d", last_in_loc);
12294 Utils::replaceToken("LAST_INPUT", position, buffer, globals);
12296 sprintf(buffer, "%d", last_out_loc);
12297 Utils::replaceToken("LAST_OUTPUT", position, buffer, globals);
12305 void VaryingLocationsTest::prepareShaderStage(Utils::Shader::STAGES stage, const Utils::Type& type,
12306 Utils::ProgramInterface& program_interface,
12307 Utils::VaryingPassthrough& varying_passthrough)
12309 const GLuint array_length = 1;
12310 const GLuint first_in_loc = 0;
12311 const GLuint first_out_loc = 0;
12312 const GLuint last_in_loc = getLastInputLocation(stage, type, array_length);
12313 size_t position = 0;
12315 const GLchar* prefix_in = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::VARYING_INPUT);
12317 const GLchar* prefix_out = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::VARYING_OUTPUT);
12319 const GLchar* qual_first_in = "layout (location = first_input_location)";
12320 const GLchar* qual_first_out = "layout (location = first_output_location)";
12321 const GLchar* qual_last_in = "layout (location = last_input_location)";
12322 const GLchar* qual_last_out = "layout (location = last_output_location)";
12324 Utils::ShaderInterface& si = program_interface.GetShaderInterface(stage);
12325 const GLuint type_size = type.GetSize();
12327 std::string first_in_name = "PREFIXfirst";
12328 std::string first_out_name = "PREFIXfirst";
12329 std::string last_in_name = "PREFIXlast";
12330 std::string last_out_name = "PREFIXlast";
12332 Utils::replaceToken("PREFIX", position, prefix_in, first_in_name);
12334 Utils::replaceToken("PREFIX", position, prefix_out, first_out_name);
12336 Utils::replaceToken("PREFIX", position, prefix_in, last_in_name);
12338 Utils::replaceToken("PREFIX", position, prefix_out, last_out_name);
12340 if (Utils::Shader::FRAGMENT == stage)
12342 qual_first_in = "layout (location = first_input_location) flat";
12343 qual_last_in = "layout (location = last_input_location) flat";
12345 if (Utils::Shader::GEOMETRY == stage)
12347 qual_first_out = "layout (location = first_output_location) flat";
12348 qual_last_out = "layout (location = last_output_location) flat";
12351 Utils::Variable* first_in = si.Input(
12352 first_in_name.c_str(), qual_first_in /* qualifiers */, 0 /* expected_componenet */,
12353 first_in_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */, 0u /* n_array_elements */,
12354 0u /* stride */, 0u /* offset */, (GLvoid*)&m_first_data[0] /* data */, m_first_data.size() /* data_size */);
12356 Utils::Variable* last_in =
12357 si.Input(last_in_name.c_str(), qual_last_in /* qualifiers */, 0 /* expected_componenet */,
12358 last_in_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12359 0u /* n_array_elements */, 0u /* stride */, type_size /* offset */,
12360 (GLvoid*)&m_last_data[0] /* data */, m_last_data.size() /* data_size */);
12362 if (Utils::Shader::FRAGMENT != stage)
12364 const GLuint last_out_loc = getLastOutputLocation(stage, type, array_length);
12366 Utils::Variable* first_out =
12367 si.Output(first_out_name.c_str(), qual_first_out /* qualifiers */, 0 /* expected_componenet */,
12368 first_out_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12369 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)&m_first_data[0] /* data */,
12370 m_first_data.size() /* data_size */);
12372 Utils::Variable* last_out = si.Output(
12373 last_out_name.c_str(), qual_last_out /* qualifiers */, 0 /* expected_componenet */,
12374 last_out_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */, 0u /* n_array_elements */,
12375 0u /* stride */, 0u /* offset */, (GLvoid*)&m_last_data[0] /* data */, m_last_data.size() /* data_size */);
12377 si.m_globals = prepareGlobals(last_in_loc, last_out_loc);
12379 varying_passthrough.Add(stage, first_in, first_out);
12380 varying_passthrough.Add(stage, last_in, last_out);
12384 /* No outputs for fragment shader, so last_output_location can be 0 */
12385 si.m_globals = prepareGlobals(last_in_loc, 0);
12389 /** This test should be run with separable programs
12395 bool VaryingLocationsTest::useMonolithicProgram(GLuint /* test_case_index */)
12400 /* Constants used by VertexAttribLocationsTest */
12401 const GLuint VertexAttribLocationsTest::m_base_vertex = 4;
12402 const GLuint VertexAttribLocationsTest::m_base_instance = 2;
12403 const GLuint VertexAttribLocationsTest::m_loc_vertex = 2;
12404 const GLuint VertexAttribLocationsTest::m_loc_instance = 5;
12405 const GLuint VertexAttribLocationsTest::m_n_instances = 4;
12409 * @param context Test framework context
12411 VertexAttribLocationsTest::VertexAttribLocationsTest(deqp::Context& context)
12412 : TextureTestBase(context, "vertex_attrib_locations",
12413 "Test verifies that attribute locations are respected by drawing operations")
12417 /** Execute proper draw command for test case
12419 * @param test_case_index Index of test case
12421 void VertexAttribLocationsTest::executeDrawCall(GLuint test_case_index)
12423 const Functions& gl = m_context.getRenderContext().getFunctions();
12425 switch (test_case_index)
12428 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
12429 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
12431 case DRAWARRAYSINSTANCED:
12432 gl.drawArraysInstanced(GL_PATCHES, 0 /* first */, 1 /* count */, m_n_instances);
12433 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArraysInstanced");
12436 gl.drawElements(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL);
12437 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElements");
12439 case DRAWELEMENTSBASEVERTEX:
12440 gl.drawElementsBaseVertex(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL, m_base_vertex);
12441 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsBaseVertex");
12443 case DRAWELEMENTSINSTANCED:
12444 gl.drawElementsInstanced(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL, m_n_instances);
12445 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsInstanced");
12447 case DRAWELEMENTSINSTANCEDBASEINSTANCE:
12448 gl.drawElementsInstancedBaseInstance(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL, m_n_instances,
12450 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsInstancedBaseInstance");
12452 case DRAWELEMENTSINSTANCEDBASEVERTEX:
12453 gl.drawElementsInstancedBaseVertex(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL, m_n_instances,
12455 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsInstancedBaseVertex");
12457 case DRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCE:
12458 gl.drawElementsInstancedBaseVertexBaseInstance(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL,
12459 m_n_instances, m_base_vertex, m_base_instance);
12460 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsInstancedBaseVertexBaseInstance");
12463 TCU_FAIL("Invalid enum");
12467 /** Get interface of program
12470 * @param program_interface Interface of program
12473 void VertexAttribLocationsTest::getProgramInterface(GLuint /* test_case_index */,
12474 Utils::ProgramInterface& program_interface,
12475 Utils::VaryingPassthrough& /* varying_passthrough */)
12477 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
12480 si.m_globals = "const uint vertex_index_location = 2;\n"
12481 "const uint instance_index_location = 5;\n";
12484 si.Input("vertex_index" /* name */, "layout (location = vertex_index_location)" /* qualifiers */,
12485 0 /* expected_componenet */, m_loc_vertex /* expected_location */, Utils::Type::uint /* type */,
12486 GL_FALSE /* normalized */, 0u /* n_array_elements */, 16 /* stride */, 0u /* offset */,
12487 (GLvoid*)0 /* data */, 0 /* data_size */);
12488 si.Input("instance_index" /* name */, "layout (location = instance_index_location)" /* qualifiers */,
12489 0 /* expected_componenet */, m_loc_instance /* expected_location */, Utils::Type::uint /* type */,
12490 GL_FALSE /* normalized */, 0u /* n_array_elements */, 16 /* stride */, 16u /* offset */,
12491 (GLvoid*)0 /* data */, 0 /* data_size */);
12494 /** Get name of test case
12496 * @param test_case_index Index of test case
12498 * @return Name of test case
12500 std::string VertexAttribLocationsTest::getTestCaseName(glw::GLuint test_case_index)
12502 std::string result;
12504 switch (test_case_index)
12507 result = "DrawArrays";
12509 case DRAWARRAYSINSTANCED:
12510 result = "DrawArraysInstanced";
12513 result = "DrawElements";
12515 case DRAWELEMENTSBASEVERTEX:
12516 result = "DrawElementsBaseVertex";
12518 case DRAWELEMENTSINSTANCED:
12519 result = "DrawElementsInstanced";
12521 case DRAWELEMENTSINSTANCEDBASEINSTANCE:
12522 result = "DrawElementsInstancedBaseInstance";
12524 case DRAWELEMENTSINSTANCEDBASEVERTEX:
12525 result = "DrawElementsInstancedBaseVertex";
12527 case DRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCE:
12528 result = "DrawElementsInstancedBaseVertexBaseInstance";
12531 TCU_FAIL("Invalid enum");
12537 /** Get number of test cases
12539 * @return Number of test cases
12541 GLuint VertexAttribLocationsTest::getTestCaseNumber()
12543 return TESTCASES_MAX;
12546 /** Prepare code snippet that will verify in and uniform variables
12550 * @param stage Shader stage
12552 * @return Code that verify variables
12554 std::string VertexAttribLocationsTest::getVerificationSnippet(GLuint /* test_case_index */,
12555 Utils::ProgramInterface& /* program_interface */,
12556 Utils::Shader::STAGES stage)
12558 std::string verification;
12560 if (Utils::Shader::VERTEX == stage)
12563 #if DEBUG_VERTEX_ATTRIB_LOCATIONS_TEST_VARIABLE
12565 verification = "if (gl_InstanceID != instance_index)\n"
12569 " else if (gl_VertexID != vertex_index)\n"
12576 verification = "if ((gl_VertexID != vertex_index) ||\n"
12577 " (gl_InstanceID != instance_index) )\n"
12589 return verification;
12592 /** Selects if "compute" stage is relevant for test
12598 bool VertexAttribLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
12603 /** Prepare attributes, vertex array object and array buffer
12606 * @param ignored Interface of program
12607 * @param buffer Array buffer
12608 * @param vao Vertex array object
12610 void VertexAttribLocationsTest::prepareAttributes(GLuint test_case_index /* test_case_index */,
12611 Utils::ProgramInterface& /* program_interface */,
12612 Utils::Buffer& buffer, Utils::VertexArray& vao)
12614 static const GLuint vertex_index_data[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
12615 static const GLuint instance_index_data[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
12617 std::vector<GLuint> buffer_data;
12618 buffer_data.resize(8 + 8); /* vertex_index_data + instance_index_data */
12620 GLubyte* ptr = (GLubyte*)&buffer_data[0];
12623 When case index >=2, the test calls glDrawElement*(), such as glDrawElementsBaseVertex(), glDrawElementsInstanced(), glDrawElementsInstancedBaseInstance() and so on,
12624 So we need to change the buffer type as GL_ELEMENT_ARRAY_BUFFER
12626 if (test_case_index >= 2)
12628 buffer.m_buffer = Utils::Buffer::Element;
12633 vao.Attribute(m_loc_vertex /* vertex_index */, Utils::Type::uint, 0 /* array_elements */, false /* normalized */,
12634 0 /* stride */, 0 /* offset */);
12636 vao.Attribute(m_loc_instance /* instance_index */, Utils::Type::uint, 0 /* array_elements */,
12637 false /* normalized */, 0 /* stride */, (GLvoid*)sizeof(vertex_index_data) /* offset */);
12638 // when test_case_index is 5 or 7, the draw call is glDrawElementsInstancedBaseInstance, glDrawElementsInstancedBaseVertexBaseInstance
12639 // the instancecount is 4, the baseinstance is 2, the divisor should be set 2
12640 bool isBaseInstanced = (test_case_index == DRAWELEMENTSINSTANCEDBASEINSTANCE ||
12641 test_case_index == DRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCE);
12642 vao.Divisor(m_context.getRenderContext().getFunctions() /* gl */, m_loc_instance /* instance_index */,
12643 isBaseInstanced ? 2 : 1 /* divisor. 1 - advance once per instance */);
12645 memcpy(ptr + 0, vertex_index_data, sizeof(vertex_index_data));
12646 memcpy(ptr + sizeof(vertex_index_data), instance_index_data, sizeof(instance_index_data));
12648 buffer.Data(Utils::Buffer::StaticDraw, buffer_data.size() * sizeof(GLuint), ptr);
12651 /** This test should be run with separable programs
12657 bool VertexAttribLocationsTest::useMonolithicProgram(GLuint /* test_case_index */)
12664 * @param context Test framework context
12666 VaryingArrayLocationsTest::VaryingArrayLocationsTest(deqp::Context& context)
12667 : VaryingLocationsTest(context, "varying_array_locations",
12668 "Test verifies that input and output locations are respected for arrays")
12675 void VaryingArrayLocationsTest::prepareShaderStage(Utils::Shader::STAGES stage, const Utils::Type& type,
12676 Utils::ProgramInterface& program_interface,
12677 Utils::VaryingPassthrough& varying_passthrough)
12679 const GLuint array_length = 1u;
12680 const GLuint first_in_loc = 0;
12681 const GLuint first_out_loc = 0;
12682 const GLuint last_in_loc = getLastInputLocation(stage, type, array_length);
12683 size_t position = 0;
12685 const GLchar* prefix_in = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::VARYING_INPUT);
12687 const GLchar* prefix_out = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::VARYING_OUTPUT);
12689 const GLchar* qual_first_in = "layout (location = first_input_location)";
12690 const GLchar* qual_first_out = "layout (location = first_output_location)";
12691 const GLchar* qual_last_in = "layout (location = last_input_location)";
12692 const GLchar* qual_last_out = "layout (location = last_output_location)";
12694 Utils::ShaderInterface& si = program_interface.GetShaderInterface(stage);
12695 const GLuint type_size = type.GetSize();
12697 std::string first_in_name = "PREFIXfirst";
12698 std::string first_out_name = "PREFIXfirst";
12699 std::string last_in_name = "PREFIXlast";
12700 std::string last_out_name = "PREFIXlast";
12702 Utils::replaceToken("PREFIX", position, prefix_in, first_in_name);
12704 Utils::replaceToken("PREFIX", position, prefix_out, first_out_name);
12706 Utils::replaceToken("PREFIX", position, prefix_in, last_in_name);
12708 Utils::replaceToken("PREFIX", position, prefix_out, last_out_name);
12710 if (Utils::Shader::FRAGMENT == stage)
12712 qual_first_in = "layout (location = first_input_location) flat";
12713 qual_last_in = "layout (location = last_input_location) flat";
12715 if (Utils::Shader::GEOMETRY == stage)
12717 qual_first_out = "layout (location = first_output_location) flat";
12718 qual_last_out = "layout (location = last_output_location) flat";
12721 Utils::Variable* first_in =
12722 si.Input(first_in_name.c_str(), qual_first_in /* qualifiers */, 0 /* expected_componenet */,
12723 first_in_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12724 array_length /* n_array_elements */, 0u /* stride */, 0u /* offset */,
12725 (GLvoid*)&m_first_data[0] /* data */, m_first_data.size() /* data_size */);
12727 Utils::Variable* last_in =
12728 si.Input(last_in_name.c_str(), qual_last_in /* qualifiers */, 0 /* expected_componenet */,
12729 last_in_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12730 array_length /* n_array_elements */, 0u /* stride */, type_size /* offset */,
12731 (GLvoid*)&m_last_data[0] /* data */, m_last_data.size() /* data_size */);
12733 if (Utils::Shader::FRAGMENT != stage)
12735 const GLuint last_out_loc = getLastOutputLocation(stage, type, array_length);
12737 Utils::Variable* first_out =
12738 si.Output(first_out_name.c_str(), qual_first_out /* qualifiers */, 0 /* expected_componenet */,
12739 first_out_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12740 array_length /* n_array_elements */, 0u /* stride */, 0u /* offset */,
12741 (GLvoid*)&m_first_data[0] /* data */, m_first_data.size() /* data_size */);
12743 Utils::Variable* last_out =
12744 si.Output(last_out_name.c_str(), qual_last_out /* qualifiers */, 0 /* expected_componenet */,
12745 last_out_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12746 array_length /* n_array_elements */, 0u /* stride */, 0u /* offset */,
12747 (GLvoid*)&m_last_data[0] /* data */, m_last_data.size() /* data_size */);
12749 si.m_globals = prepareGlobals(last_in_loc, last_out_loc);
12751 varying_passthrough.Add(stage, first_in, first_out);
12752 varying_passthrough.Add(stage, last_in, last_out);
12756 /* No outputs for fragment shader, so last_output_location can be 0 */
12757 si.m_globals = prepareGlobals(last_in_loc, 0);
12763 * @param context Test framework context
12765 VaryingStructureLocationsTest::VaryingStructureLocationsTest(deqp::Context& context)
12766 : TextureTestBase(context, "varying_structure_locations",
12767 "Test verifies that locations are respected when structures are used as in and out ")
12771 /** Prepare code snippet that will pass in variables to out variables
12774 * @param varying_passthrough Collection of connections between in and out variables
12775 * @param stage Shader stage
12777 * @return Code that pass in variables to next stage
12779 std::string VaryingStructureLocationsTest::getPassSnippet(GLuint /* test_case_index */,
12780 Utils::VaryingPassthrough& varying_passthrough,
12781 Utils::Shader::STAGES stage)
12783 std::string result;
12785 if (Utils::Shader::VERTEX != stage)
12787 result = TextureTestBase::getPassSnippet(0, varying_passthrough, stage);
12791 result = " vs_tcs_output[0].single = vs_in_single[0];\n"
12792 " vs_tcs_output[0].array[0] = vs_in_array[0];\n";
12798 /** Get interface of program
12800 * @param test_case_index Test case
12801 * @param program_interface Interface of program
12802 * @param varying_passthrough Collection of connections between in and out variables
12804 void VaryingStructureLocationsTest::getProgramInterface(GLuint test_case_index,
12805 Utils::ProgramInterface& program_interface,
12806 Utils::VaryingPassthrough& varying_passthrough)
12808 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
12809 const Utils::Type type = getType(test_case_index);
12812 // We should call GenerateDataPacked() to generate data, which can make sure the data in shader is correct
12813 m_single_data = type.GenerateDataPacked();
12814 m_array_data = type.GenerateDataPacked();
12816 m_data.resize(m_single_data.size() + m_array_data.size());
12817 GLubyte* ptr = (GLubyte*)&m_data[0];
12818 memcpy(ptr, &m_single_data[0], m_single_data.size());
12819 memcpy(ptr + m_single_data.size(), &m_array_data[0], m_array_data.size());
12821 Utils::Interface* structure = program_interface.Structure("Data");
12823 structure->Member("single", "" /* qualifiers */, 0 /* component */, 0 /* location */, type, false /* normalized */,
12824 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */);
12826 // the second struct member 's location should not be 0, it is based on by how many the locations the first struct member consumed.
12827 structure->Member("array", "" /* qualifiers */, 0 /* component */, type.GetLocations() /* location */, type,
12828 false /* normalized */, 1u /* n_array_elements */, 0u /* stride */, type.GetSize() /* offset */);
12830 si.Input("vs_in_single", "layout (location = 0)", 0 /* component */, 0 /* location */, type, false /* normalized */,
12831 1u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)&m_single_data[0] /* data */,
12832 m_single_data.size() /* data_size */);
12834 si.Input("vs_in_array", "layout (location = 8)", 0 /* component */, 8 /* location */, type, false /* normalized */,
12835 1u /* n_array_elements */, 0u /* stride */, type.GetSize() /* offset */,
12836 (GLvoid*)&m_array_data[0] /* data */, m_array_data.size() /* data_size */);
12838 si.Output("vs_tcs_output", "layout (location = 0)", 0 /* component */, 0 /* location */, structure,
12839 1u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)&m_data[0] /* data */,
12840 m_data.size() /* data_size */);
12842 program_interface.CloneVertexInterface(varying_passthrough);
12847 * @param test_case_index Index of test case
12849 * @return Name of type test in test_case_index
12851 std::string VaryingStructureLocationsTest::getTestCaseName(glw::GLuint test_case_index)
12853 return getTypeName(test_case_index);
12856 /** Returns number of types to test
12858 * @return Number of types, 34
12860 glw::GLuint VaryingStructureLocationsTest::getTestCaseNumber()
12862 return getTypesNumber();
12865 /** Selects if "compute" stage is relevant for test
12871 bool VaryingStructureLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
12876 /** This test should be run with separable programs
12882 bool VaryingStructureLocationsTest::useMonolithicProgram(GLuint /* test_case_index */)
12889 * @param context Test context
12890 * @param test_name Name of test
12891 * @param test_description Description of test
12893 VaryingStructureMemberLocationTest::VaryingStructureMemberLocationTest(deqp::Context& context)
12894 : NegativeTestBase(context, "varying_structure_member_location",
12895 "Test verifies that compiler does not allow location qualifier on member of strucure")
12899 /** Source for given test case and stage
12901 * @param test_case_index Index of test case
12902 * @param stage Shader stage
12904 * @return Shader source
12906 std::string VaryingStructureMemberLocationTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
12908 static const GLchar* struct_definition = "struct Data {\n"
12910 " layout (location = 4) vec4 goten;\n"
12912 static const GLchar* input_var = "in Data data;\n";
12913 static const GLchar* output_var = "out Data data;\n";
12914 static const GLchar* input_use = " result += data.gohan + data.goten;\n";
12915 static const GLchar* output_use = " data.gohan = result / 2;\n"
12916 " data.goten = result / 4 - data.gohan;\n";
12917 static const GLchar* fs = "#version 430 core\n"
12918 "#extension GL_ARB_enhanced_layouts : require\n"
12921 "out vec4 fs_out;\n"
12925 " fs_out = gs_fs;\n"
12928 static const GLchar* fs_tested = "#version 430 core\n"
12929 "#extension GL_ARB_enhanced_layouts : require\n"
12931 "STRUCT_DEFINITION"
12933 "VARIABLE_DEFINITION"
12936 "out vec4 fs_out;\n"
12940 " vec4 result = gs_fs;\n"
12944 " fs_out += result;\n"
12947 static const GLchar* gs = "#version 430 core\n"
12948 "#extension GL_ARB_enhanced_layouts : require\n"
12950 "layout(points) in;\n"
12951 "layout(triangle_strip, max_vertices = 4) out;\n"
12953 "in vec4 tes_gs[];\n"
12954 "out vec4 gs_fs;\n"
12958 " gs_fs = tes_gs[0];\n"
12959 " gl_Position = vec4(-1, -1, 0, 1);\n"
12961 " gs_fs = tes_gs[0];\n"
12962 " gl_Position = vec4(-1, 1, 0, 1);\n"
12964 " gs_fs = tes_gs[0];\n"
12965 " gl_Position = vec4(1, -1, 0, 1);\n"
12967 " gs_fs = tes_gs[0];\n"
12968 " gl_Position = vec4(1, 1, 0, 1);\n"
12972 static const GLchar* gs_tested = "#version 430 core\n"
12973 "#extension GL_ARB_enhanced_layouts : require\n"
12975 "layout(points) in;\n"
12976 "layout(triangle_strip, max_vertices = 4) out;\n"
12978 "STRUCT_DEFINITION"
12980 "VARIABLE_DEFINITION"
12982 "in vec4 tes_gs[];\n"
12983 "out vec4 gs_fs;\n"
12987 " vec4 result = tes_gs[0];\n"
12991 " gs_fs = result;\n"
12992 " gl_Position = vec4(-1, -1, 0, 1);\n"
12994 " gs_fs = result;\n"
12995 " gl_Position = vec4(-1, 1, 0, 1);\n"
12997 " gs_fs = result;\n"
12998 " gl_Position = vec4(1, -1, 0, 1);\n"
13000 " gs_fs = result;\n"
13001 " gl_Position = vec4(1, 1, 0, 1);\n"
13005 static const GLchar* tcs = "#version 430 core\n"
13006 "#extension GL_ARB_enhanced_layouts : require\n"
13008 "layout(vertices = 1) out;\n"
13010 "in vec4 vs_tcs[];\n"
13011 "out vec4 tcs_tes[];\n"
13016 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
13018 " gl_TessLevelOuter[0] = 1.0;\n"
13019 " gl_TessLevelOuter[1] = 1.0;\n"
13020 " gl_TessLevelOuter[2] = 1.0;\n"
13021 " gl_TessLevelOuter[3] = 1.0;\n"
13022 " gl_TessLevelInner[0] = 1.0;\n"
13023 " gl_TessLevelInner[1] = 1.0;\n"
13026 static const GLchar* tcs_tested = "#version 430 core\n"
13027 "#extension GL_ARB_enhanced_layouts : require\n"
13029 "layout(vertices = 1) out;\n"
13031 "STRUCT_DEFINITION"
13033 "VARIABLE_DEFINITION"
13035 "in vec4 vs_tcs[];\n"
13036 "out vec4 tcs_tes[];\n"
13040 " vec4 result = vs_tcs[gl_InvocationID];\n"
13044 " tcs_tes[gl_InvocationID] = result;\n"
13046 " gl_TessLevelOuter[0] = 1.0;\n"
13047 " gl_TessLevelOuter[1] = 1.0;\n"
13048 " gl_TessLevelOuter[2] = 1.0;\n"
13049 " gl_TessLevelOuter[3] = 1.0;\n"
13050 " gl_TessLevelInner[0] = 1.0;\n"
13051 " gl_TessLevelInner[1] = 1.0;\n"
13054 static const GLchar* tes = "#version 430 core\n"
13055 "#extension GL_ARB_enhanced_layouts : require\n"
13057 "layout(isolines, point_mode) in;\n"
13059 "in vec4 tcs_tes[];\n"
13060 "out vec4 tes_gs;\n"
13064 " tes_gs = tcs_tes[0];\n"
13067 static const GLchar* tes_tested = "#version 430 core\n"
13068 "#extension GL_ARB_enhanced_layouts : require\n"
13070 "layout(isolines, point_mode) in;\n"
13072 "STRUCT_DEFINITION"
13074 "VARIABLE_DEFINITION"
13076 "in vec4 tcs_tes[];\n"
13077 "out vec4 tes_gs;\n"
13081 " vec4 result = tcs_tes[0];\n"
13085 " tes_gs += result;\n"
13088 static const GLchar* vs = "#version 430 core\n"
13089 "#extension GL_ARB_enhanced_layouts : require\n"
13092 "out vec4 vs_tcs;\n"
13096 " vs_tcs = in_vs;\n"
13099 static const GLchar* vs_tested = "#version 430 core\n"
13100 "#extension GL_ARB_enhanced_layouts : require\n"
13102 "STRUCT_DEFINITION"
13104 "VARIABLE_DEFINITION"
13107 "out vec4 vs_tcs;\n"
13111 " vec4 result = in_vs;\n"
13115 " vs_tcs += result;\n"
13119 std::string source;
13120 testCase& test_case = m_test_cases[test_case_index];
13121 const GLchar* var_definition = 0;
13122 const GLchar* var_use = 0;
13124 if (true == test_case.m_is_input)
13126 var_definition = input_var;
13127 var_use = input_use;
13131 var_definition = output_var;
13132 var_use = output_use;
13135 if (test_case.m_stage == stage)
13137 size_t position = 0;
13141 case Utils::Shader::FRAGMENT:
13142 source = fs_tested;
13144 case Utils::Shader::GEOMETRY:
13145 source = gs_tested;
13147 case Utils::Shader::TESS_CTRL:
13148 source = tcs_tested;
13150 case Utils::Shader::TESS_EVAL:
13151 source = tes_tested;
13153 case Utils::Shader::VERTEX:
13154 source = vs_tested;
13157 TCU_FAIL("Invalid enum");
13160 Utils::replaceToken("STRUCT_DEFINITION", position, struct_definition, source);
13161 Utils::replaceToken("VARIABLE_DEFINITION", position, var_definition, source);
13162 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
13168 case Utils::Shader::FRAGMENT:
13171 case Utils::Shader::GEOMETRY:
13174 case Utils::Shader::TESS_CTRL:
13177 case Utils::Shader::TESS_EVAL:
13180 case Utils::Shader::VERTEX:
13184 TCU_FAIL("Invalid enum");
13191 /** Get description of test case
13193 * @param test_case_index Index of test case
13195 * @return Test case description
13197 std::string VaryingStructureMemberLocationTest::getTestCaseName(GLuint test_case_index)
13199 std::stringstream stream;
13200 testCase& test_case = m_test_cases[test_case_index];
13202 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", direction: ";
13204 if (true == test_case.m_is_input)
13210 stream << "output";
13213 return stream.str();
13216 /** Get number of test cases
13218 * @return Number of test cases
13220 GLuint VaryingStructureMemberLocationTest::getTestCaseNumber()
13222 return static_cast<GLuint>(m_test_cases.size());
13225 /** Selects if "compute" stage is relevant for test
13231 bool VaryingStructureMemberLocationTest::isComputeRelevant(GLuint /* test_case_index */)
13236 /** Prepare all test cases
13239 void VaryingStructureMemberLocationTest::testInit()
13241 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
13243 if (Utils::Shader::COMPUTE == stage)
13248 testCase test_case_in = { true, (Utils::Shader::STAGES)stage };
13249 testCase test_case_out = { false, (Utils::Shader::STAGES)stage };
13251 m_test_cases.push_back(test_case_in);
13253 if (Utils::Shader::FRAGMENT != stage)
13255 m_test_cases.push_back(test_case_out);
13262 * @param context Test framework context
13264 VaryingBlockLocationsTest::VaryingBlockLocationsTest(deqp::Context& context)
13265 : TextureTestBase(context, "varying_block_locations",
13266 "Test verifies that locations are respected when blocks are used as in and out ")
13270 /** Prepare code snippet that will pass in variables to out variables
13273 * @param varying_passthrough Collection of connections between in and out variables
13274 * @param stage Shader stage
13276 * @return Code that pass in variables to next stage
13278 std::string VaryingBlockLocationsTest::getPassSnippet(GLuint /* test_case_index */,
13279 Utils::VaryingPassthrough& varying_passthrough,
13280 Utils::Shader::STAGES stage)
13282 std::string result;
13284 if (Utils::Shader::VERTEX != stage)
13286 result = TextureTestBase::getPassSnippet(0, varying_passthrough, stage);
13290 result = "vs_tcs_block.third = vs_in_third;\n"
13291 " vs_tcs_block.fourth = vs_in_fourth;\n"
13292 " vs_tcs_block.fifth = vs_in_fifth;\n";
13298 /** Get interface of program
13301 * @param program_interface Interface of program
13302 * @param varying_passthrough Collection of connections between in and out variables
13304 void VaryingBlockLocationsTest::getProgramInterface(GLuint /* test_case_index */,
13305 Utils::ProgramInterface& program_interface,
13306 Utils::VaryingPassthrough& varying_passthrough)
13308 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
13309 const Utils::Type vec4 = Utils::Type::vec4;
13312 m_third_data = vec4.GenerateData();
13313 m_fourth_data = vec4.GenerateData();
13314 m_fifth_data = vec4.GenerateData();
13316 /* Memory layout is different from location layout */
13317 const GLuint fifth_offset = 0u;
13318 const GLuint third_offset = static_cast<GLuint>(fifth_offset + m_fifth_data.size());
13319 const GLuint fourth_offset = static_cast<GLuint>(third_offset + m_fourth_data.size());
13321 m_data.resize(fourth_offset + m_fourth_data.size());
13322 GLubyte* ptr = (GLubyte*)&m_data[0];
13323 memcpy(ptr + third_offset, &m_third_data[0], m_third_data.size());
13324 memcpy(ptr + fourth_offset, &m_fourth_data[0], m_fourth_data.size());
13325 memcpy(ptr + fifth_offset, &m_fifth_data[0], m_fifth_data.size());
13327 Utils::Interface* block = program_interface.Block("vs_tcs_Block");
13329 block->Member("fifth", "" /* qualifiers */, 0 /* component */, 4 /* location */, vec4, false /* normalized */,
13330 0u /* n_array_elements */, 0u /* stride */, fifth_offset /* offset */);
13332 block->Member("third", "layout (location = 2)" /* qualifiers */, 0 /* component */, 2 /* location */, vec4,
13333 false /* normalized */, 0u /* n_array_elements */, 0u /* stride */, third_offset /* offset */);
13335 block->Member("fourth", "" /* qualifiers */, 0 /* component */, 3 /* location */, vec4, false /* normalized */,
13336 0u /* n_array_elements */, 0u /* stride */, fourth_offset /* offset */);
13338 si.Output("vs_tcs_block", "layout (location = 4)", 0 /* component */, 4 /* location */, block,
13339 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)&m_data[0] /* data */,
13340 m_data.size() /* data_size */);
13342 si.Input("vs_in_third", "layout (location = 0)", 0 /* component */, 0 /* location */, vec4, false /* normalized */,
13343 0u /* n_array_elements */, 0u /* stride */, third_offset /* offset */,
13344 (GLvoid*)&m_third_data[0] /* data */, m_third_data.size() /* data_size */);
13346 si.Input("vs_in_fourth", "layout (location = 1)", 0 /* component */, 1 /* location */, vec4, false /* normalized */,
13347 0u /* n_array_elements */, 0u /* stride */, fourth_offset /* offset */,
13348 (GLvoid*)&m_fourth_data[0] /* data */, m_fourth_data.size() /* data_size */);
13350 si.Input("vs_in_fifth", "layout (location = 2)", 0 /* component */, 2 /* location */, vec4, false /* normalized */,
13351 0u /* n_array_elements */, 0u /* stride */, fifth_offset /* offset */,
13352 (GLvoid*)&m_fifth_data[0] /* data */, m_fifth_data.size() /* data_size */);
13354 program_interface.CloneVertexInterface(varying_passthrough);
13357 /** Selects if "compute" stage is relevant for test
13363 bool VaryingBlockLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
13368 /** This test should be run with separable programs
13374 bool VaryingBlockLocationsTest::useMonolithicProgram(GLuint /* test_case_index */)
13381 * @param context Test framework context
13383 VaryingBlockMemberLocationsTest::VaryingBlockMemberLocationsTest(deqp::Context& context)
13384 : NegativeTestBase(
13385 context, "varying_block_member_locations",
13386 "Test verifies that compilation error is reported when not all members of block are qualified with location")
13390 /** Source for given test case and stage
13392 * @param test_case_index Index of test case
13393 * @param stage Shader stage
13395 * @return Shader source
13397 std::string VaryingBlockMemberLocationsTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
13399 static const GLchar* block_definition_all = "Goku {\n"
13400 " layout (location = 2) vec4 gohan;\n"
13401 " layout (location = 4) vec4 goten;\n"
13402 " layout (location = 6) vec4 chichi;\n"
13404 static const GLchar* block_definition_default = "Goku {\n"
13409 static const GLchar* block_definition_one = "Goku {\n"
13411 " layout (location = 4) vec4 goten;\n"
13414 static const GLchar* input_use = " result += gokuINDEX.gohan + gokuINDEX.goten + gokuINDEX.chichi;\n";
13415 static const GLchar* output_use = " gokuINDEX.gohan = result / 2;\n"
13416 " gokuINDEX.goten = result / 4 - gokuINDEX.gohan;\n"
13417 " gokuINDEX.chichi = result / 8 - gokuINDEX.goten;\n";
13418 static const GLchar* fs = "#version 430 core\n"
13419 "#extension GL_ARB_enhanced_layouts : require\n"
13422 "out vec4 fs_out;\n"
13426 " fs_out = gs_fs;\n"
13429 static const GLchar* fs_tested = "#version 430 core\n"
13430 "#extension GL_ARB_enhanced_layouts : require\n"
13432 "DIRECTION BLOCK_DEFINITION"
13435 "out vec4 fs_out;\n"
13439 " vec4 result = gs_fs;\n"
13443 " fs_out = result;\n"
13446 static const GLchar* gs = "#version 430 core\n"
13447 "#extension GL_ARB_enhanced_layouts : require\n"
13449 "layout(points) in;\n"
13450 "layout(triangle_strip, max_vertices = 4) out;\n"
13452 "in vec4 tes_gs[];\n"
13453 "out vec4 gs_fs;\n"
13457 " gs_fs = tes_gs[0];\n"
13458 " gl_Position = vec4(-1, -1, 0, 1);\n"
13460 " gs_fs = tes_gs[0];\n"
13461 " gl_Position = vec4(-1, 1, 0, 1);\n"
13463 " gs_fs = tes_gs[0];\n"
13464 " gl_Position = vec4(1, -1, 0, 1);\n"
13466 " gs_fs = tes_gs[0];\n"
13467 " gl_Position = vec4(1, 1, 0, 1);\n"
13471 static const GLchar* gs_tested = "#version 430 core\n"
13472 "#extension GL_ARB_enhanced_layouts : require\n"
13474 "layout(points) in;\n"
13475 "layout(triangle_strip, max_vertices = 4) out;\n"
13477 "DIRECTION BLOCK_DEFINITION"
13479 "in vec4 tes_gs[];\n"
13480 "out vec4 gs_fs;\n"
13484 " vec4 result = tes_gs[0];\n"
13488 " gs_fs = result;\n"
13489 " gl_Position = vec4(-1, -1, 0, 1);\n"
13491 " gs_fs = result;\n"
13492 " gl_Position = vec4(-1, 1, 0, 1);\n"
13494 " gs_fs = result;\n"
13495 " gl_Position = vec4(1, -1, 0, 1);\n"
13497 " gs_fs = result;\n"
13498 " gl_Position = vec4(1, 1, 0, 1);\n"
13502 static const GLchar* tcs = "#version 430 core\n"
13503 "#extension GL_ARB_enhanced_layouts : require\n"
13505 "layout(vertices = 1) out;\n"
13507 "in vec4 vs_tcs[];\n"
13508 "out vec4 tcs_tes[];\n"
13513 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
13515 " gl_TessLevelOuter[0] = 1.0;\n"
13516 " gl_TessLevelOuter[1] = 1.0;\n"
13517 " gl_TessLevelOuter[2] = 1.0;\n"
13518 " gl_TessLevelOuter[3] = 1.0;\n"
13519 " gl_TessLevelInner[0] = 1.0;\n"
13520 " gl_TessLevelInner[1] = 1.0;\n"
13523 static const GLchar* tcs_tested = "#version 430 core\n"
13524 "#extension GL_ARB_enhanced_layouts : require\n"
13526 "layout(vertices = 1) out;\n"
13528 "DIRECTION BLOCK_DEFINITION"
13530 "in vec4 vs_tcs[];\n"
13531 "out vec4 tcs_tes[];\n"
13535 " vec4 result = vs_tcs[gl_InvocationID];\n"
13539 " tcs_tes[gl_InvocationID] = result;\n"
13541 " gl_TessLevelOuter[0] = 1.0;\n"
13542 " gl_TessLevelOuter[1] = 1.0;\n"
13543 " gl_TessLevelOuter[2] = 1.0;\n"
13544 " gl_TessLevelOuter[3] = 1.0;\n"
13545 " gl_TessLevelInner[0] = 1.0;\n"
13546 " gl_TessLevelInner[1] = 1.0;\n"
13549 static const GLchar* tes = "#version 430 core\n"
13550 "#extension GL_ARB_enhanced_layouts : require\n"
13552 "layout(isolines, point_mode) in;\n"
13554 "in vec4 tcs_tes[];\n"
13555 "out vec4 tes_gs;\n"
13559 " tes_gs = tcs_tes[0];\n"
13562 static const GLchar* tes_tested = "#version 430 core\n"
13563 "#extension GL_ARB_enhanced_layouts : require\n"
13565 "layout(isolines, point_mode) in;\n"
13567 "DIRECTION BLOCK_DEFINITION"
13569 "in vec4 tcs_tes[];\n"
13570 "out vec4 tes_gs;\n"
13574 " vec4 result = tcs_tes[0];\n"
13578 " tes_gs = result;\n"
13581 static const GLchar* vs = "#version 430 core\n"
13582 "#extension GL_ARB_enhanced_layouts : require\n"
13585 "out vec4 vs_tcs;\n"
13589 " vs_tcs = in_vs;\n"
13592 static const GLchar* vs_tested = "#version 430 core\n"
13593 "#extension GL_ARB_enhanced_layouts : require\n"
13595 "DIRECTION BLOCK_DEFINITION"
13598 "out vec4 vs_tcs;\n"
13602 " vec4 result = in_vs;\n"
13606 " vs_tcs = result;\n"
13610 static const GLchar* shaders_in[6][6] = { /* cs */ { 0, 0, 0, 0, 0, 0 },
13611 /* vs */ { 0, vs_tested, tcs, tes, gs, fs },
13612 /* tcs */ { 0, vs_tested, tcs_tested, tes, gs, fs },
13613 /* tes */ { 0, vs, tcs_tested, tes_tested, gs, fs },
13614 /* gs */ { 0, vs, tcs, tes_tested, gs_tested, fs },
13615 /* fs */ { 0, vs, tcs, tes, gs_tested, fs_tested } };
13617 static const GLchar* shaders_out[6][6] = { /* cs */ { 0, 0, 0, 0, 0, 0 },
13618 /* vs */ { 0, vs_tested, tcs_tested, tes, gs, fs },
13619 /* tcs */ { 0, vs, tcs_tested, tes_tested, gs, fs },
13620 /* tes */ { 0, vs, tcs, tes_tested, gs_tested, fs },
13621 /* gs */ { 0, vs, tcs, tes, gs_tested, fs_tested },
13622 /* fs */ { 0, 0, 0, 0, 0, 0 } };
13624 static const bool require_modifications_in[6][6] = {
13625 /* cs */ { false, false, false, false, false, false },
13626 /* vs */ { false, true, false, false, false, false },
13627 /* tcs */ { false, true, true, false, false, false },
13628 /* tes */ { false, false, true, true, false, false },
13629 /* gs */ { false, false, false, true, true, false },
13630 /* fs */ { false, false, false, false, true, true }
13633 static const bool require_modifications_out[6][6] = {
13634 /* cs */ { false, false, false, false, false, false },
13635 /* vs */ { false, true, true, false, false, false },
13636 /* tcs */ { false, false, true, true, false, false },
13637 /* tes */ { false, false, false, true, true, false },
13638 /* gs */ { false, false, false, false, true, true },
13639 /* fs */ { false, false, false, false, false, false }
13642 const GLchar* array = "";
13643 const GLchar* definition = block_definition_default;
13644 const GLchar* direction = "out";
13645 const GLchar* index = "";
13646 bool require_modifications = false;
13647 std::string source;
13648 testCase& test_case = m_test_cases[test_case_index];
13649 const GLchar* var_use = output_use;
13651 if (true == test_case.m_is_input)
13653 require_modifications = require_modifications_in[test_case.m_stage][stage];
13654 source = shaders_in[test_case.m_stage][stage];
13656 if (test_case.m_stage == stage)
13659 var_use = input_use;
13664 require_modifications = require_modifications_out[test_case.m_stage][stage];
13665 source = shaders_out[test_case.m_stage][stage];
13667 if (test_case.m_stage != stage)
13670 var_use = input_use;
13674 if (test_case.m_stage == stage)
13676 if (true == test_case.m_qualify_all)
13678 definition = block_definition_all;
13682 definition = block_definition_one;
13688 case Utils::Shader::FRAGMENT:
13690 case Utils::Shader::GEOMETRY:
13694 case Utils::Shader::TESS_CTRL:
13696 index = "[gl_InvocationID]";
13698 // geometry shader's input must have one more dimension than tessellation evaluation shader's output,
13699 // the GS input block is an array, so the DS output can't be declared as an array
13700 case Utils::Shader::TESS_EVAL:
13702 if (std::string(direction) == std::string("in")) // match HS output and DS input
13707 else // match DS output and GS input
13714 case Utils::Shader::VERTEX:
13717 TCU_FAIL("Invalid enum");
13720 if (true == require_modifications)
13722 size_t position = 0;
13725 Utils::replaceToken("DIRECTION", position, direction, source);
13727 Utils::replaceToken("BLOCK_DEFINITION", position, definition, source);
13729 Utils::replaceToken("ARRAY", position, array, source);
13730 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
13732 Utils::replaceAllTokens("INDEX", index, source);
13738 case Utils::Shader::FRAGMENT:
13741 case Utils::Shader::GEOMETRY:
13744 case Utils::Shader::TESS_CTRL:
13747 case Utils::Shader::TESS_EVAL:
13750 case Utils::Shader::VERTEX:
13754 TCU_FAIL("Invalid enum");
13761 /** Get description of test case
13763 * @param test_case_index Index of test case
13765 * @return Test case description
13767 std::string VaryingBlockMemberLocationsTest::getTestCaseName(GLuint test_case_index)
13769 std::stringstream stream;
13770 testCase& test_case = m_test_cases[test_case_index];
13772 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", direction: ";
13774 if (true == test_case.m_is_input)
13780 stream << "output";
13783 if (true == test_case.m_qualify_all)
13785 stream << ", all members qualified";
13789 stream << ", not all members qualified";
13792 return stream.str();
13795 /** Get number of test cases
13797 * @return Number of test cases
13799 GLuint VaryingBlockMemberLocationsTest::getTestCaseNumber()
13801 return static_cast<GLuint>(m_test_cases.size());
13804 /** Selects if "compute" stage is relevant for test
13810 bool VaryingBlockMemberLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
13815 /** Selects if compilation failure is expected result
13817 * @param test_case_index Index of test case
13819 * @return false when all members are qualified, true otherwise
13821 bool VaryingBlockMemberLocationsTest::isFailureExpected(GLuint test_case_index)
13823 return (true != m_test_cases[test_case_index].m_qualify_all);
13826 /** Prepare all test cases
13829 void VaryingBlockMemberLocationsTest::testInit()
13831 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
13833 if (Utils::Shader::COMPUTE == stage)
13838 testCase test_case_in_all = { true, true, (Utils::Shader::STAGES)stage };
13839 testCase test_case_in_one = { true, false, (Utils::Shader::STAGES)stage };
13840 testCase test_case_out_all = { false, true, (Utils::Shader::STAGES)stage };
13841 testCase test_case_out_one = { false, false, (Utils::Shader::STAGES)stage };
13843 if (Utils::Shader::VERTEX != stage)
13845 m_test_cases.push_back(test_case_in_all);
13846 m_test_cases.push_back(test_case_in_one);
13849 if (Utils::Shader::FRAGMENT != stage)
13851 m_test_cases.push_back(test_case_out_all);
13852 m_test_cases.push_back(test_case_out_one);
13859 * @param context Test framework context
13861 VaryingBlockAutomaticMemberLocationsTest::VaryingBlockAutomaticMemberLocationsTest(deqp::Context& context)
13862 : NegativeTestBase(
13863 context, "varying_block_automatic_member_locations",
13864 "Test verifies that compiler assigns subsequent locations to block members, even if this causes errors")
13868 /** Source for given test case and stage
13870 * @param test_case_index Index of test case
13871 * @param stage Shader stage
13873 * @return Shader source
13875 std::string VaryingBlockAutomaticMemberLocationsTest::getShaderSource(GLuint test_case_index,
13876 Utils::Shader::STAGES stage)
13878 static const GLchar* block_definition = "layout (location = 2) DIRECTION DBZ {\n"
13880 " vec4 gohan[4];\n"
13882 " layout (location = 1) vec4 chichi;\n"
13885 static const GLchar* input_use = " result += dbzINDEX.goku + dbzINDEX.gohan[0] + dbzINDEX.gohan[1] + "
13886 "dbzINDEX.gohan[3] + dbzINDEX.gohan[2] + dbzINDEX.goten + dbzINDEX.chichi + "
13888 static const GLchar* output_use = " dbzINDEX.goku = result;\n"
13889 " dbzINDEX.gohan[0] = result / 2;\n"
13890 " dbzINDEX.gohan[1] = result / 2.25;\n"
13891 " dbzINDEX.gohan[2] = result / 2.5;\n"
13892 " dbzINDEX.gohan[3] = result / 2.75;\n"
13893 " dbzINDEX.goten = result / 4 - dbzINDEX.gohan[0] - dbzINDEX.gohan[1] - "
13894 "dbzINDEX.gohan[2] - dbzINDEX.gohan[3];\n"
13895 " dbzINDEX.chichi = result / 8 - dbzINDEX.goten;\n"
13896 " dbzINDEX.pan = result / 16 - dbzINDEX.chichi;\n";
13897 static const GLchar* fs = "#version 430 core\n"
13898 "#extension GL_ARB_enhanced_layouts : require\n"
13901 "out vec4 fs_out;\n"
13905 " fs_out = gs_fs;\n"
13908 static const GLchar* fs_tested = "#version 430 core\n"
13909 "#extension GL_ARB_enhanced_layouts : require\n"
13914 "out vec4 fs_out;\n"
13918 " vec4 result = gs_fs;\n"
13922 " fs_out += result;\n"
13925 static const GLchar* gs = "#version 430 core\n"
13926 "#extension GL_ARB_enhanced_layouts : require\n"
13928 "layout(points) in;\n"
13929 "layout(triangle_strip, max_vertices = 4) out;\n"
13931 "in vec4 tes_gs[];\n"
13932 "out vec4 gs_fs;\n"
13936 " gs_fs = tes_gs[0];\n"
13937 " gl_Position = vec4(-1, -1, 0, 1);\n"
13939 " gs_fs = tes_gs[0];\n"
13940 " gl_Position = vec4(-1, 1, 0, 1);\n"
13942 " gs_fs = tes_gs[0];\n"
13943 " gl_Position = vec4(1, -1, 0, 1);\n"
13945 " gs_fs = tes_gs[0];\n"
13946 " gl_Position = vec4(1, 1, 0, 1);\n"
13950 static const GLchar* gs_tested = "#version 430 core\n"
13951 "#extension GL_ARB_enhanced_layouts : require\n"
13953 "layout(points) in;\n"
13954 "layout(triangle_strip, max_vertices = 4) out;\n"
13958 "in vec4 tes_gs[];\n"
13959 "out vec4 gs_fs;\n"
13963 " vec4 result = tes_gs[0];\n"
13967 " gs_fs = result;\n"
13968 " gl_Position = vec4(-1, -1, 0, 1);\n"
13970 " gs_fs = result;\n"
13971 " gl_Position = vec4(-1, 1, 0, 1);\n"
13973 " gs_fs = result;\n"
13974 " gl_Position = vec4(1, -1, 0, 1);\n"
13976 " gs_fs = result;\n"
13977 " gl_Position = vec4(1, 1, 0, 1);\n"
13981 static const GLchar* tcs = "#version 430 core\n"
13982 "#extension GL_ARB_enhanced_layouts : require\n"
13984 "layout(vertices = 1) out;\n"
13986 "in vec4 vs_tcs[];\n"
13987 "out vec4 tcs_tes[];\n"
13992 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
13994 " gl_TessLevelOuter[0] = 1.0;\n"
13995 " gl_TessLevelOuter[1] = 1.0;\n"
13996 " gl_TessLevelOuter[2] = 1.0;\n"
13997 " gl_TessLevelOuter[3] = 1.0;\n"
13998 " gl_TessLevelInner[0] = 1.0;\n"
13999 " gl_TessLevelInner[1] = 1.0;\n"
14002 static const GLchar* tcs_tested = "#version 430 core\n"
14003 "#extension GL_ARB_enhanced_layouts : require\n"
14005 "layout(vertices = 1) out;\n"
14009 "in vec4 vs_tcs[];\n"
14010 "out vec4 tcs_tes[];\n"
14014 " vec4 result = vs_tcs[gl_InvocationID];\n"
14018 " tcs_tes[gl_InvocationID] = result;\n"
14020 " gl_TessLevelOuter[0] = 1.0;\n"
14021 " gl_TessLevelOuter[1] = 1.0;\n"
14022 " gl_TessLevelOuter[2] = 1.0;\n"
14023 " gl_TessLevelOuter[3] = 1.0;\n"
14024 " gl_TessLevelInner[0] = 1.0;\n"
14025 " gl_TessLevelInner[1] = 1.0;\n"
14028 static const GLchar* tes = "#version 430 core\n"
14029 "#extension GL_ARB_enhanced_layouts : require\n"
14031 "layout(isolines, point_mode) in;\n"
14033 "in vec4 tcs_tes[];\n"
14034 "out vec4 tes_gs;\n"
14038 " tes_gs = tcs_tes[0];\n"
14041 static const GLchar* tes_tested = "#version 430 core\n"
14042 "#extension GL_ARB_enhanced_layouts : require\n"
14044 "layout(isolines, point_mode) in;\n"
14048 "in vec4 tcs_tes[];\n"
14049 "out vec4 tes_gs;\n"
14053 " vec4 result = tcs_tes[0];\n"
14057 " tes_gs += result;\n"
14060 static const GLchar* vs = "#version 430 core\n"
14061 "#extension GL_ARB_enhanced_layouts : require\n"
14064 "out vec4 vs_tcs;\n"
14068 " vs_tcs = in_vs;\n"
14071 static const GLchar* vs_tested = "#version 430 core\n"
14072 "#extension GL_ARB_enhanced_layouts : require\n"
14077 "out vec4 vs_tcs;\n"
14081 " vec4 result = in_vs;\n"
14085 " vs_tcs += result;\n"
14089 const GLchar* array = "";
14090 const GLchar* direction = "out";
14091 const GLchar* index = "";
14092 std::string source;
14093 testCase& test_case = m_test_cases[test_case_index];
14094 const GLchar* var_use = output_use;
14096 if (true == test_case.m_is_input)
14099 var_use = input_use;
14102 if (test_case.m_stage == stage)
14104 size_t position = 0;
14109 case Utils::Shader::FRAGMENT:
14110 source = fs_tested;
14112 case Utils::Shader::GEOMETRY:
14113 source = gs_tested;
14117 case Utils::Shader::TESS_CTRL:
14118 source = tcs_tested;
14120 index = "[gl_InvocationID]";
14122 case Utils::Shader::TESS_EVAL:
14123 source = tes_tested;
14127 case Utils::Shader::VERTEX:
14128 source = vs_tested;
14131 TCU_FAIL("Invalid enum");
14135 Utils::replaceToken("BLOCK_DEFINITION", position, block_definition, source);
14137 Utils::replaceToken("DIRECTION", position, direction, source);
14138 Utils::replaceToken("ARRAY", position, array, source);
14139 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
14141 Utils::replaceAllTokens("INDEX", index, source);
14147 case Utils::Shader::FRAGMENT:
14150 case Utils::Shader::GEOMETRY:
14153 case Utils::Shader::TESS_CTRL:
14156 case Utils::Shader::TESS_EVAL:
14159 case Utils::Shader::VERTEX:
14163 TCU_FAIL("Invalid enum");
14170 /** Get description of test case
14172 * @param test_case_index Index of test case
14174 * @return Test case description
14176 std::string VaryingBlockAutomaticMemberLocationsTest::getTestCaseName(GLuint test_case_index)
14178 std::stringstream stream;
14179 testCase& test_case = m_test_cases[test_case_index];
14181 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", direction: ";
14183 if (true == test_case.m_is_input)
14189 stream << "output";
14192 return stream.str();
14195 /** Get number of test cases
14197 * @return Number of test cases
14199 GLuint VaryingBlockAutomaticMemberLocationsTest::getTestCaseNumber()
14201 return static_cast<GLuint>(m_test_cases.size());
14204 /** Selects if "compute" stage is relevant for test
14210 bool VaryingBlockAutomaticMemberLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
14215 /** Prepare all test cases
14218 void VaryingBlockAutomaticMemberLocationsTest::testInit()
14220 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
14222 if (Utils::Shader::COMPUTE == stage)
14227 testCase test_case_in = { true, (Utils::Shader::STAGES)stage };
14228 testCase test_case_out = { false, (Utils::Shader::STAGES)stage };
14230 if (Utils::Shader::VERTEX != stage)
14232 m_test_cases.push_back(test_case_in);
14235 if (Utils::Shader::FRAGMENT != stage)
14237 m_test_cases.push_back(test_case_out);
14244 * @param context Test framework context
14246 VaryingLocationLimitTest::VaryingLocationLimitTest(deqp::Context& context)
14247 : NegativeTestBase(context, "varying_location_limit",
14248 "Test verifies that compiler reports error when location qualifier exceed limits")
14252 /** Source for given test case and stage
14254 * @param test_case_index Index of test case
14255 * @param stage Shader stage
14257 * @return Shader source
14259 std::string VaryingLocationLimitTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
14261 static const GLchar* var_definition = "layout (location = LAST + 1) FLAT DIRECTION TYPE gokuARRAY;\n";
14262 static const GLchar* input_use = " if (TYPE(0) == gokuINDEX)\n"
14264 " result += vec4(1, 0.5, 0.25, 0.125);\n"
14266 static const GLchar* output_use = " gokuINDEX = TYPE(0);\n"
14267 " if (vec4(0) == result)\n"
14269 " gokuINDEX = TYPE(1);\n"
14271 static const GLchar* fs = "#version 430 core\n"
14272 "#extension GL_ARB_enhanced_layouts : require\n"
14275 "out vec4 fs_out;\n"
14279 " fs_out = gs_fs;\n"
14282 static const GLchar* fs_tested = "#version 430 core\n"
14283 "#extension GL_ARB_enhanced_layouts : require\n"
14288 "out vec4 fs_out;\n"
14292 " vec4 result = gs_fs;\n"
14296 " fs_out += result;\n"
14299 static const GLchar* gs = "#version 430 core\n"
14300 "#extension GL_ARB_enhanced_layouts : require\n"
14302 "layout(points) in;\n"
14303 "layout(triangle_strip, max_vertices = 4) out;\n"
14305 "in vec4 tes_gs[];\n"
14306 "out vec4 gs_fs;\n"
14310 " gs_fs = tes_gs[0];\n"
14311 " gl_Position = vec4(-1, -1, 0, 1);\n"
14313 " gs_fs = tes_gs[0];\n"
14314 " gl_Position = vec4(-1, 1, 0, 1);\n"
14316 " gs_fs = tes_gs[0];\n"
14317 " gl_Position = vec4(1, -1, 0, 1);\n"
14319 " gs_fs = tes_gs[0];\n"
14320 " gl_Position = vec4(1, 1, 0, 1);\n"
14324 static const GLchar* gs_tested = "#version 430 core\n"
14325 "#extension GL_ARB_enhanced_layouts : require\n"
14327 "layout(points) in;\n"
14328 "layout(triangle_strip, max_vertices = 4) out;\n"
14332 "in vec4 tes_gs[];\n"
14333 "out vec4 gs_fs;\n"
14337 " vec4 result = tes_gs[0];\n"
14341 " gs_fs = result;\n"
14342 " gl_Position = vec4(-1, -1, 0, 1);\n"
14344 " gs_fs = result;\n"
14345 " gl_Position = vec4(-1, 1, 0, 1);\n"
14347 " gs_fs = result;\n"
14348 " gl_Position = vec4(1, -1, 0, 1);\n"
14350 " gs_fs = result;\n"
14351 " gl_Position = vec4(1, 1, 0, 1);\n"
14355 static const GLchar* tcs = "#version 430 core\n"
14356 "#extension GL_ARB_enhanced_layouts : require\n"
14358 "layout(vertices = 1) out;\n"
14360 "in vec4 vs_tcs[];\n"
14361 "out vec4 tcs_tes[];\n"
14366 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
14368 " gl_TessLevelOuter[0] = 1.0;\n"
14369 " gl_TessLevelOuter[1] = 1.0;\n"
14370 " gl_TessLevelOuter[2] = 1.0;\n"
14371 " gl_TessLevelOuter[3] = 1.0;\n"
14372 " gl_TessLevelInner[0] = 1.0;\n"
14373 " gl_TessLevelInner[1] = 1.0;\n"
14376 static const GLchar* tcs_tested = "#version 430 core\n"
14377 "#extension GL_ARB_enhanced_layouts : require\n"
14379 "layout(vertices = 1) out;\n"
14383 "in vec4 vs_tcs[];\n"
14384 "out vec4 tcs_tes[];\n"
14388 " vec4 result = vs_tcs[gl_InvocationID];\n"
14392 " tcs_tes[gl_InvocationID] = result;\n"
14394 " gl_TessLevelOuter[0] = 1.0;\n"
14395 " gl_TessLevelOuter[1] = 1.0;\n"
14396 " gl_TessLevelOuter[2] = 1.0;\n"
14397 " gl_TessLevelOuter[3] = 1.0;\n"
14398 " gl_TessLevelInner[0] = 1.0;\n"
14399 " gl_TessLevelInner[1] = 1.0;\n"
14402 static const GLchar* tes = "#version 430 core\n"
14403 "#extension GL_ARB_enhanced_layouts : require\n"
14405 "layout(isolines, point_mode) in;\n"
14407 "in vec4 tcs_tes[];\n"
14408 "out vec4 tes_gs;\n"
14412 " tes_gs = tcs_tes[0];\n"
14415 static const GLchar* tes_tested = "#version 430 core\n"
14416 "#extension GL_ARB_enhanced_layouts : require\n"
14418 "layout(isolines, point_mode) in;\n"
14422 "in vec4 tcs_tes[];\n"
14423 "out vec4 tes_gs;\n"
14427 " vec4 result = tcs_tes[0];\n"
14431 " tes_gs += result;\n"
14434 static const GLchar* vs = "#version 430 core\n"
14435 "#extension GL_ARB_enhanced_layouts : require\n"
14438 "out vec4 vs_tcs;\n"
14442 " vs_tcs = in_vs;\n"
14445 static const GLchar* vs_tested = "#version 430 core\n"
14446 "#extension GL_ARB_enhanced_layouts : require\n"
14451 "out vec4 vs_tcs;\n"
14455 " vec4 result = in_vs;\n"
14459 " vs_tcs += result;\n"
14463 std::string source;
14464 testCase& test_case = m_test_cases[test_case_index];
14466 if (test_case.m_stage == stage)
14468 const GLchar* array = "";
14470 const GLchar* direction = "in ";
14471 const GLchar* flat = "";
14472 const GLchar* index = "";
14473 GLuint last = getLastInputLocation(stage, test_case.m_type, 0);
14474 size_t position = 0;
14476 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
14477 Utils::Variable::STORAGE storage = Utils::Variable::VARYING_INPUT;
14478 const GLchar* var_use = input_use;
14480 if (false == test_case.m_is_input)
14483 last = getLastOutputLocation(stage, test_case.m_type, 0);
14484 storage = Utils::Variable::VARYING_OUTPUT;
14485 var_use = output_use;
14488 if (true == isFlatRequired(stage, test_case.m_type, storage))
14493 sprintf(buffer, "%d", last);
14497 case Utils::Shader::FRAGMENT:
14498 source = fs_tested;
14500 case Utils::Shader::GEOMETRY:
14501 source = gs_tested;
14505 case Utils::Shader::TESS_CTRL:
14506 source = tcs_tested;
14508 index = "[gl_InvocationID]";
14510 case Utils::Shader::TESS_EVAL:
14511 source = tes_tested;
14515 case Utils::Shader::VERTEX:
14516 source = vs_tested;
14519 TCU_FAIL("Invalid enum");
14523 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
14525 Utils::replaceToken("LAST", position, buffer, source);
14526 Utils::replaceToken("FLAT", position, flat, source);
14527 Utils::replaceToken("DIRECTION", position, direction, source);
14528 Utils::replaceToken("ARRAY", position, array, source);
14529 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
14531 Utils::replaceAllTokens("TYPE", type_name, source);
14532 Utils::replaceAllTokens("INDEX", index, source);
14538 case Utils::Shader::FRAGMENT:
14541 case Utils::Shader::GEOMETRY:
14544 case Utils::Shader::TESS_CTRL:
14547 case Utils::Shader::TESS_EVAL:
14550 case Utils::Shader::VERTEX:
14554 TCU_FAIL("Invalid enum");
14561 /** Get description of test case
14563 * @param test_case_index Index of test case
14565 * @return Test case description
14567 std::string VaryingLocationLimitTest::getTestCaseName(GLuint test_case_index)
14569 std::stringstream stream;
14570 testCase& test_case = m_test_cases[test_case_index];
14572 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
14573 << " type: " << test_case.m_type.GetGLSLTypeName() << ", direction: ";
14575 if (true == test_case.m_is_input)
14581 stream << "output";
14584 return stream.str();
14587 /** Get number of test cases
14589 * @return Number of test cases
14591 GLuint VaryingLocationLimitTest::getTestCaseNumber()
14593 return static_cast<GLuint>(m_test_cases.size());
14596 /** Selects if "compute" stage is relevant for test
14602 bool VaryingLocationLimitTest::isComputeRelevant(GLuint /* test_case_index */)
14607 /** Prepare all test cases
14610 void VaryingLocationLimitTest::testInit()
14612 const GLuint n_types = getTypesNumber();
14614 for (GLuint i = 0; i < n_types; ++i)
14616 const Utils::Type& type = getType(i);
14618 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
14620 if (Utils::Shader::COMPUTE == stage)
14625 testCase test_case_in = { true, type, (Utils::Shader::STAGES)stage };
14626 testCase test_case_out = { false, type, (Utils::Shader::STAGES)stage };
14628 m_test_cases.push_back(test_case_in);
14630 if (Utils::Shader::FRAGMENT != stage)
14632 m_test_cases.push_back(test_case_out);
14640 * @param context Test framework context
14642 VaryingComponentsTest::VaryingComponentsTest(deqp::Context& context)
14643 : VaryingLocationsTest(context, "varying_components",
14644 "Test verifies that input and output components are respected")
14650 * @param context Test framework context
14651 * @param test_name Name of test
14652 * @param test_description Description of test
14654 VaryingComponentsTest::VaryingComponentsTest(deqp::Context& context, const glw::GLchar* test_name,
14655 const glw::GLchar* test_description)
14656 : VaryingLocationsTest(context, test_name, test_description)
14660 /** Get interface of program
14662 * @param test_case_index Test case
14663 * @param program_interface Interface of program
14664 * @param varying_passthrough Collection of connections between in and out variables
14666 void VaryingComponentsTest::getProgramInterface(GLuint test_case_index, Utils::ProgramInterface& program_interface,
14667 Utils::VaryingPassthrough& varying_passthrough)
14669 GLuint array_length = getArrayLength();
14670 const testCase& test_case = m_test_cases[test_case_index];
14671 const Utils::Type vector_type = Utils::Type::GetType(test_case.m_type, 1, 4);
14672 Utils::ShaderInterface si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
14674 /* Zero means no array, however we still need at least 1 slot of data */
14675 if (0 == array_length)
14680 /* Generate data */
14681 const std::vector<GLubyte>& data = vector_type.GenerateDataPacked();
14682 const size_t data_size = data.size();
14684 /* Prepare data for variables */
14685 m_data.resize(array_length * data_size);
14687 GLubyte* dst = &m_data[0];
14688 const GLubyte* src = &data[0];
14690 for (GLuint i = 0; i < array_length; ++i)
14692 memcpy(dst + data_size * i, src, data_size);
14695 /* Prepare interface for each stage */
14696 prepareShaderStage(Utils::Shader::FRAGMENT, vector_type, program_interface, test_case, varying_passthrough);
14697 prepareShaderStage(Utils::Shader::GEOMETRY, vector_type, program_interface, test_case, varying_passthrough);
14698 prepareShaderStage(Utils::Shader::TESS_CTRL, vector_type, program_interface, test_case, varying_passthrough);
14699 prepareShaderStage(Utils::Shader::TESS_EVAL, vector_type, program_interface, test_case, varying_passthrough);
14700 prepareShaderStage(Utils::Shader::VERTEX, vector_type, program_interface, test_case, varying_passthrough);
14705 * @param test_case_index Index of test case
14707 * @return Name of type test in test_case_index
14709 std::string VaryingComponentsTest::getTestCaseName(glw::GLuint test_case_index)
14713 const testCase& test_case = m_test_cases[test_case_index];
14717 switch (test_case.m_type)
14719 case Utils::Type::Double:
14720 name.append(Utils::Type::_double.GetGLSLTypeName());
14722 case Utils::Type::Float:
14723 name.append(Utils::Type::_float.GetGLSLTypeName());
14725 case Utils::Type::Int:
14726 name.append(Utils::Type::_int.GetGLSLTypeName());
14728 case Utils::Type::Uint:
14729 name.append(Utils::Type::uint.GetGLSLTypeName());
14733 name.append(", layout: ");
14735 switch (test_case.m_layout)
14738 name.append("GVEC4");
14741 name.append("SCALAR_GVEC3");
14744 name.append("GVEC3_SCALAR");
14747 name.append("GVEC2_GVEC2");
14749 case GVEC2_SCALAR_SCALAR:
14750 name.append("GVEC2_SCALAR_SCALAR");
14752 case SCALAR_GVEC2_SCALAR:
14753 name.append("SCALAR_GVEC2_SCALAR");
14755 case SCALAR_SCALAR_GVEC2:
14756 name.append("SCALAR_SCALAR_GVEC2");
14758 case SCALAR_SCALAR_SCALAR_SCALAR:
14759 name.append("SCALAR_SCALAR_SCALAR_SCALAR");
14766 /** Returns number of types to test
14768 * @return Number of types, 34
14770 glw::GLuint VaryingComponentsTest::getTestCaseNumber()
14772 return static_cast<GLuint>(m_test_cases.size());
14775 /* Prepare test cases */
14776 void VaryingComponentsTest::testInit()
14778 m_test_cases.push_back(testCase(GVEC4, Utils::Type::Double));
14779 m_test_cases.push_back(testCase(SCALAR_GVEC3, Utils::Type::Double));
14780 m_test_cases.push_back(testCase(GVEC3_SCALAR, Utils::Type::Double));
14781 m_test_cases.push_back(testCase(GVEC2_GVEC2, Utils::Type::Double));
14782 m_test_cases.push_back(testCase(GVEC2_SCALAR_SCALAR, Utils::Type::Double));
14783 m_test_cases.push_back(testCase(SCALAR_GVEC2_SCALAR, Utils::Type::Double));
14784 m_test_cases.push_back(testCase(SCALAR_SCALAR_GVEC2, Utils::Type::Double));
14785 m_test_cases.push_back(testCase(SCALAR_SCALAR_SCALAR_SCALAR, Utils::Type::Double));
14787 m_test_cases.push_back(testCase(GVEC4, Utils::Type::Float));
14788 m_test_cases.push_back(testCase(SCALAR_GVEC3, Utils::Type::Float));
14789 m_test_cases.push_back(testCase(GVEC3_SCALAR, Utils::Type::Float));
14790 m_test_cases.push_back(testCase(GVEC2_GVEC2, Utils::Type::Float));
14791 m_test_cases.push_back(testCase(GVEC2_SCALAR_SCALAR, Utils::Type::Float));
14792 m_test_cases.push_back(testCase(SCALAR_GVEC2_SCALAR, Utils::Type::Float));
14793 m_test_cases.push_back(testCase(SCALAR_SCALAR_GVEC2, Utils::Type::Float));
14794 m_test_cases.push_back(testCase(SCALAR_SCALAR_SCALAR_SCALAR, Utils::Type::Float));
14796 m_test_cases.push_back(testCase(GVEC4, Utils::Type::Int));
14797 m_test_cases.push_back(testCase(SCALAR_GVEC3, Utils::Type::Int));
14798 m_test_cases.push_back(testCase(GVEC3_SCALAR, Utils::Type::Int));
14799 m_test_cases.push_back(testCase(GVEC2_GVEC2, Utils::Type::Int));
14800 m_test_cases.push_back(testCase(GVEC2_SCALAR_SCALAR, Utils::Type::Int));
14801 m_test_cases.push_back(testCase(SCALAR_GVEC2_SCALAR, Utils::Type::Int));
14802 m_test_cases.push_back(testCase(SCALAR_SCALAR_GVEC2, Utils::Type::Int));
14803 m_test_cases.push_back(testCase(SCALAR_SCALAR_SCALAR_SCALAR, Utils::Type::Int));
14805 m_test_cases.push_back(testCase(GVEC4, Utils::Type::Uint));
14806 m_test_cases.push_back(testCase(SCALAR_GVEC3, Utils::Type::Uint));
14807 m_test_cases.push_back(testCase(GVEC3_SCALAR, Utils::Type::Uint));
14808 m_test_cases.push_back(testCase(GVEC2_GVEC2, Utils::Type::Uint));
14809 m_test_cases.push_back(testCase(GVEC2_SCALAR_SCALAR, Utils::Type::Uint));
14810 m_test_cases.push_back(testCase(SCALAR_GVEC2_SCALAR, Utils::Type::Uint));
14811 m_test_cases.push_back(testCase(SCALAR_SCALAR_GVEC2, Utils::Type::Uint));
14812 m_test_cases.push_back(testCase(SCALAR_SCALAR_SCALAR_SCALAR, Utils::Type::Uint));
14815 /** Inform that test use components
14821 bool VaryingComponentsTest::useComponentQualifier(glw::GLuint /* test_case_index */)
14826 /** Get length of arrays that should be used during test
14828 * @return 0u - no array at all
14830 GLuint VaryingComponentsTest::getArrayLength()
14835 std::string VaryingComponentsTest::prepareGlobals(GLuint last_in_location, GLuint last_out_location)
14837 std::string globals = VaryingLocationsTest::prepareGlobals(last_in_location, last_out_location);
14839 globals.append("const uint comp_x = 0u;\n"
14840 "const uint comp_y = 1u;\n"
14841 "const uint comp_z = 2u;\n"
14842 "const uint comp_w = 3u;\n");
14850 std::string VaryingComponentsTest::prepareName(const glw::GLchar* name, glw::GLint location, glw::GLint component,
14851 Utils::Shader::STAGES stage, Utils::Variable::STORAGE storage)
14854 std::string result = "PREFIXNAME_lLOCATION_cCOMPONENT";
14855 size_t position = 0;
14856 const GLchar* prefix = Utils::ProgramInterface::GetStagePrefix(stage, storage);
14858 Utils::replaceToken("PREFIX", position, prefix, result);
14859 Utils::replaceToken("NAME", position, name, result);
14861 sprintf(buffer, "%d", location);
14862 Utils::replaceToken("LOCATION", position, buffer, result);
14864 sprintf(buffer, "%d", component);
14865 Utils::replaceToken("COMPONENT", position, buffer, result);
14870 std::string VaryingComponentsTest::prepareQualifiers(const glw::GLchar* location, const glw::GLchar* component,
14871 const glw::GLchar* interpolation)
14873 size_t position = 0;
14874 std::string qualifiers = "layout (location = LOCATION, component = COMPONENT) INTERPOLATION";
14876 Utils::replaceToken("LOCATION", position, location, qualifiers);
14877 Utils::replaceToken("COMPONENT", position, component, qualifiers);
14878 Utils::replaceToken("INTERPOLATION", position, interpolation, qualifiers);
14886 void VaryingComponentsTest::prepareShaderStage(Utils::Shader::STAGES stage, const Utils::Type& vector_type,
14887 Utils::ProgramInterface& program_interface, const testCase& test_case,
14888 Utils::VaryingPassthrough& varying_passthrough)
14890 const GLuint array_length = getArrayLength();
14891 const Utils::Type& basic_type = Utils::Type::GetType(vector_type.m_basic_type, 1 /* n_cols */, 1 /* n_rows */);
14892 descriptor desc_in[8];
14893 descriptor desc_out[8];
14894 const GLuint first_in_loc = 0;
14895 const GLuint first_out_loc = 0;
14896 const GLchar* interpolation = "";
14897 const GLuint last_in_loc = getLastInputLocation(stage, vector_type, array_length);
14898 GLuint last_out_loc = 0;
14900 Utils::ShaderInterface& si = program_interface.GetShaderInterface(stage);
14902 /* Select interpolation */
14903 if ((Utils::Shader::FRAGMENT == stage) || (Utils::Shader::GEOMETRY == stage))
14905 interpolation = " flat";
14908 if (Utils::Shader::FRAGMENT != stage)
14910 last_out_loc = getLastOutputLocation(stage, vector_type, array_length);
14913 switch (test_case.m_layout)
14917 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 4, "gvec4");
14918 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 4, "gvec4");
14920 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 4, "gvec4");
14921 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 4, "gvec4");
14925 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "scalar");
14926 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "scalar");
14927 desc_in[2].assign(1, "comp_y", first_in_loc, "first_input_location", 3, "gvec3");
14928 desc_in[3].assign(1, "comp_y", last_in_loc, "last_input_location", 3, "gvec3");
14930 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "scalar");
14931 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "scalar");
14932 desc_out[2].assign(1, "comp_y", first_out_loc, "first_output_location", 3, "gvec3");
14933 desc_out[3].assign(1, "comp_y", last_out_loc, "last_output_location", 3, "gvec3");
14937 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 3, "gvec3");
14938 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 3, "gvec3");
14939 desc_in[2].assign(3, "comp_w", first_in_loc, "first_input_location", 1, "scalar");
14940 desc_in[3].assign(3, "comp_w", last_in_loc, "last_input_location", 1, "scalar");
14942 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 3, "gvec3");
14943 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 3, "gvec3");
14944 desc_out[2].assign(3, "comp_w", first_out_loc, "first_output_location", 1, "scalar");
14945 desc_out[3].assign(3, "comp_w", last_out_loc, "last_output_location", 1, "scalar");
14949 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 2, "gvec2");
14950 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 2, "gvec2");
14951 desc_in[2].assign(2, "comp_z", first_in_loc, "first_input_location", 2, "gvec2");
14952 desc_in[3].assign(2, "comp_z", last_in_loc, "last_input_location", 2, "gvec2");
14954 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 2, "gvec2");
14955 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 2, "gvec2");
14956 desc_out[2].assign(2, "comp_z", first_out_loc, "first_output_location", 2, "gvec2");
14957 desc_out[3].assign(2, "comp_z", last_out_loc, "last_output_location", 2, "gvec2");
14959 case GVEC2_SCALAR_SCALAR:
14961 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 2, "gvec2");
14962 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 2, "gvec2");
14963 desc_in[2].assign(2, "comp_z", first_in_loc, "first_input_location", 1, "scalar");
14964 desc_in[3].assign(2, "comp_z", last_in_loc, "last_input_location", 1, "scalar");
14965 desc_in[4].assign(3, "comp_w", first_in_loc, "first_input_location", 1, "scalar");
14966 desc_in[5].assign(3, "comp_w", last_in_loc, "last_input_location", 1, "scalar");
14968 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 2, "gvec2");
14969 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 2, "gvec2");
14970 desc_out[2].assign(2, "comp_z", first_out_loc, "first_output_location", 1, "scalar");
14971 desc_out[3].assign(2, "comp_z", last_out_loc, "last_output_location", 1, "scalar");
14972 desc_out[4].assign(3, "comp_w", first_out_loc, "first_output_location", 1, "scalar");
14973 desc_out[5].assign(3, "comp_w", last_out_loc, "last_output_location", 1, "scalar");
14975 case SCALAR_GVEC2_SCALAR:
14977 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "scalar");
14978 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "scalar");
14979 desc_in[2].assign(1, "comp_y", first_in_loc, "first_input_location", 2, "gvec2");
14980 desc_in[3].assign(1, "comp_y", last_in_loc, "last_input_location", 2, "gvec2");
14981 desc_in[4].assign(3, "comp_w", first_in_loc, "first_input_location", 1, "scalar");
14982 desc_in[5].assign(3, "comp_w", last_in_loc, "last_input_location", 1, "scalar");
14984 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "scalar");
14985 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "scalar");
14986 desc_out[2].assign(1, "comp_y", first_out_loc, "first_output_location", 2, "gvec2");
14987 desc_out[3].assign(1, "comp_y", last_out_loc, "last_output_location", 2, "gvec2");
14988 desc_out[4].assign(3, "comp_w", first_out_loc, "first_output_location", 1, "scalar");
14989 desc_out[5].assign(3, "comp_w", last_out_loc, "last_output_location", 1, "scalar");
14991 case SCALAR_SCALAR_GVEC2:
14993 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "scalar");
14994 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "scalar");
14995 desc_in[2].assign(1, "comp_y", first_in_loc, "first_input_location", 1, "scalar");
14996 desc_in[3].assign(1, "comp_y", last_in_loc, "last_input_location", 1, "scalar");
14997 desc_in[4].assign(2, "comp_z", first_in_loc, "first_input_location", 2, "gvec2");
14998 desc_in[5].assign(2, "comp_z", last_in_loc, "last_input_location", 2, "gvec2");
15000 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "scalar");
15001 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "scalar");
15002 desc_out[2].assign(1, "comp_y", first_out_loc, "first_output_location", 1, "scalar");
15003 desc_out[3].assign(1, "comp_y", last_out_loc, "last_output_location", 1, "scalar");
15004 desc_out[4].assign(2, "comp_z", first_out_loc, "first_output_location", 2, "gvec2");
15005 desc_out[5].assign(2, "comp_z", last_out_loc, "last_output_location", 2, "gvec2");
15007 case SCALAR_SCALAR_SCALAR_SCALAR:
15009 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "scalar");
15010 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "scalar");
15011 desc_in[2].assign(1, "comp_y", first_in_loc, "first_input_location", 1, "scalar");
15012 desc_in[3].assign(1, "comp_y", last_in_loc, "last_input_location", 1, "scalar");
15013 desc_in[4].assign(2, "comp_z", first_in_loc, "first_input_location", 1, "scalar");
15014 desc_in[5].assign(2, "comp_z", last_in_loc, "last_input_location", 1, "scalar");
15015 desc_in[6].assign(3, "comp_w", first_in_loc, "first_input_location", 1, "scalar");
15016 desc_in[7].assign(3, "comp_w", last_in_loc, "last_input_location", 1, "scalar");
15018 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "scalar");
15019 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "scalar");
15020 desc_out[2].assign(1, "comp_y", first_out_loc, "first_output_location", 1, "scalar");
15021 desc_out[3].assign(1, "comp_y", last_out_loc, "last_output_location", 1, "scalar");
15022 desc_out[4].assign(2, "comp_z", first_out_loc, "first_output_location", 1, "scalar");
15023 desc_out[5].assign(2, "comp_z", last_out_loc, "last_output_location", 1, "scalar");
15024 desc_out[6].assign(3, "comp_w", first_out_loc, "first_output_location", 1, "scalar");
15025 desc_out[7].assign(3, "comp_w", last_out_loc, "last_output_location", 1, "scalar");
15029 for (GLuint i = 0; i < n_desc; ++i)
15031 const descriptor& in_desc = desc_in[i];
15033 Utils::Variable* in =
15034 prepareVarying(basic_type, in_desc, interpolation, si, stage, Utils::Variable::VARYING_INPUT);
15036 if (Utils::Shader::FRAGMENT != stage)
15038 const descriptor& out_desc = desc_out[i];
15040 Utils::Variable* out =
15041 prepareVarying(basic_type, out_desc, interpolation, si, stage, Utils::Variable::VARYING_OUTPUT);
15043 varying_passthrough.Add(stage, in, out);
15047 si.m_globals = prepareGlobals(last_in_loc, last_out_loc);
15053 Utils::Variable* VaryingComponentsTest::prepareVarying(const Utils::Type& basic_type, const descriptor& desc,
15054 const GLchar* interpolation, Utils::ShaderInterface& si,
15055 Utils::Shader::STAGES stage, Utils::Variable::STORAGE storage)
15057 const GLuint array_length = getArrayLength();
15058 const GLuint component_size = basic_type.GetSize();
15059 const std::string& name = prepareName(desc.m_name, desc.m_location, desc.m_component, stage, storage);
15060 const GLuint offset = desc.m_component * component_size;
15061 const std::string& qual = prepareQualifiers(desc.m_location_str, desc.m_component_str, interpolation);
15062 const GLuint size = desc.m_n_rows * component_size;
15063 const Utils::Type& type = Utils::Type::GetType(basic_type.m_basic_type, 1 /* n_columns */, desc.m_n_rows);
15064 Utils::Variable* var = 0;
15066 if (Utils::Variable::VARYING_INPUT == storage)
15068 var = si.Input(name.c_str(), qual.c_str() /* qualifiers */, desc.m_component /* expected_componenet */,
15069 desc.m_location /* expected_location */, type, /* built_in_type */
15070 GL_FALSE /* normalized */, array_length /* n_array_elements */, 0u /* stride */,
15071 offset /* offset */, (GLvoid*)&m_data[offset] /* data */, size /* data_size */);
15075 var = si.Output(name.c_str(), qual.c_str() /* qualifiers */, desc.m_component /* expected_componenet */,
15076 desc.m_location /* expected_location */, type, /* built_in_type */
15077 GL_FALSE /* normalized */, array_length /* n_array_elements */, 0u /* stride */,
15078 offset /* offset */, (GLvoid*)&m_data[offset] /* data */, size /* data_size */);
15084 void VaryingComponentsTest::descriptor::assign(glw::GLint component, const glw::GLchar* component_str,
15085 glw::GLint location, const glw::GLchar* location_str, glw::GLuint n_rows,
15086 const glw::GLchar* name)
15088 m_component = component;
15089 m_component_str = component_str;
15090 m_location = location;
15091 m_location_str = location_str;
15096 VaryingComponentsTest::testCase::testCase(COMPONENTS_LAYOUT layout, Utils::Type::TYPES type)
15097 : m_layout(layout), m_type(type)
15103 * @param context Test framework context
15105 VaryingArrayComponentsTest::VaryingArrayComponentsTest(deqp::Context& context)
15106 : VaryingComponentsTest(context, "varying_array_components",
15107 "Test verifies that input and output components are respected for arrays")
15111 /** Get length of arrays that should be used during test
15115 GLuint VaryingArrayComponentsTest::getArrayLength()
15122 * @param context Test framework context
15124 VaryingExceedingComponentsTest::VaryingExceedingComponentsTest(deqp::Context& context)
15125 : NegativeTestBase(context, "varying_exceeding_components",
15126 "Test verifies that compiler reports error when component qualifier exceed limits")
15130 /** Source for given test case and stage
15132 * @param test_case_index Index of test case
15133 * @param stage Shader stage
15135 * @return Shader source
15137 std::string VaryingExceedingComponentsTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
15139 static const GLchar* var_definition_arr =
15140 "layout (location = 1, component = COMPONENT) flat DIRECTION TYPE gokuARRAY[1];\n";
15141 static const GLchar* var_definition_one =
15142 "layout (location = 1, component = COMPONENT) flat DIRECTION TYPE gokuARRAY;\n";
15143 static const GLchar* input_use_arr = " if (TYPE(0) == gokuINDEX[0])\n"
15145 " result += vec4(1, 0.5, 0.25, 0.125);\n"
15147 static const GLchar* input_use_one = " if (TYPE(0) == gokuINDEX)\n"
15149 " result += vec4(1, 0.5, 0.25, 0.125);\n"
15151 static const GLchar* output_use_arr = " gokuINDEX[0] = TYPE(0);\n"
15152 " if (vec4(0) == result)\n"
15154 " gokuINDEX[0] = TYPE(1);\n"
15156 static const GLchar* output_use_one = " gokuINDEX = TYPE(0);\n"
15157 " if (vec4(0) == result)\n"
15159 " gokuINDEX = TYPE(1);\n"
15161 static const GLchar* fs = "#version 430 core\n"
15162 "#extension GL_ARB_enhanced_layouts : require\n"
15165 "out vec4 fs_out;\n"
15169 " fs_out = gs_fs;\n"
15172 static const GLchar* fs_tested = "#version 430 core\n"
15173 "#extension GL_ARB_enhanced_layouts : require\n"
15178 "out vec4 fs_out;\n"
15182 " vec4 result = gs_fs;\n"
15186 " fs_out += result;\n"
15189 static const GLchar* gs = "#version 430 core\n"
15190 "#extension GL_ARB_enhanced_layouts : require\n"
15192 "layout(points) in;\n"
15193 "layout(triangle_strip, max_vertices = 4) out;\n"
15195 "in vec4 tes_gs[];\n"
15196 "out vec4 gs_fs;\n"
15200 " gs_fs = tes_gs[0];\n"
15201 " gl_Position = vec4(-1, -1, 0, 1);\n"
15203 " gs_fs = tes_gs[0];\n"
15204 " gl_Position = vec4(-1, 1, 0, 1);\n"
15206 " gs_fs = tes_gs[0];\n"
15207 " gl_Position = vec4(1, -1, 0, 1);\n"
15209 " gs_fs = tes_gs[0];\n"
15210 " gl_Position = vec4(1, 1, 0, 1);\n"
15214 static const GLchar* gs_tested = "#version 430 core\n"
15215 "#extension GL_ARB_enhanced_layouts : require\n"
15217 "layout(points) in;\n"
15218 "layout(triangle_strip, max_vertices = 4) out;\n"
15222 "in vec4 tes_gs[];\n"
15223 "out vec4 gs_fs;\n"
15227 " vec4 result = tes_gs[0];\n"
15231 " gs_fs = result;\n"
15232 " gl_Position = vec4(-1, -1, 0, 1);\n"
15234 " gs_fs = result;\n"
15235 " gl_Position = vec4(-1, 1, 0, 1);\n"
15237 " gs_fs = result;\n"
15238 " gl_Position = vec4(1, -1, 0, 1);\n"
15240 " gs_fs = result;\n"
15241 " gl_Position = vec4(1, 1, 0, 1);\n"
15245 static const GLchar* tcs = "#version 430 core\n"
15246 "#extension GL_ARB_enhanced_layouts : require\n"
15248 "layout(vertices = 1) out;\n"
15250 "in vec4 vs_tcs[];\n"
15251 "out vec4 tcs_tes[];\n"
15256 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
15258 " gl_TessLevelOuter[0] = 1.0;\n"
15259 " gl_TessLevelOuter[1] = 1.0;\n"
15260 " gl_TessLevelOuter[2] = 1.0;\n"
15261 " gl_TessLevelOuter[3] = 1.0;\n"
15262 " gl_TessLevelInner[0] = 1.0;\n"
15263 " gl_TessLevelInner[1] = 1.0;\n"
15266 static const GLchar* tcs_tested = "#version 430 core\n"
15267 "#extension GL_ARB_enhanced_layouts : require\n"
15269 "layout(vertices = 1) out;\n"
15273 "in vec4 vs_tcs[];\n"
15274 "out vec4 tcs_tes[];\n"
15278 " vec4 result = vs_tcs[gl_InvocationID];\n"
15282 " tcs_tes[gl_InvocationID] = result;\n"
15284 " gl_TessLevelOuter[0] = 1.0;\n"
15285 " gl_TessLevelOuter[1] = 1.0;\n"
15286 " gl_TessLevelOuter[2] = 1.0;\n"
15287 " gl_TessLevelOuter[3] = 1.0;\n"
15288 " gl_TessLevelInner[0] = 1.0;\n"
15289 " gl_TessLevelInner[1] = 1.0;\n"
15292 static const GLchar* tes = "#version 430 core\n"
15293 "#extension GL_ARB_enhanced_layouts : require\n"
15295 "layout(isolines, point_mode) in;\n"
15297 "in vec4 tcs_tes[];\n"
15298 "out vec4 tes_gs;\n"
15302 " tes_gs = tcs_tes[0];\n"
15305 static const GLchar* tes_tested = "#version 430 core\n"
15306 "#extension GL_ARB_enhanced_layouts : require\n"
15308 "layout(isolines, point_mode) in;\n"
15312 "in vec4 tcs_tes[];\n"
15313 "out vec4 tes_gs;\n"
15317 " vec4 result = tcs_tes[0];\n"
15321 " tes_gs += result;\n"
15324 static const GLchar* vs = "#version 430 core\n"
15325 "#extension GL_ARB_enhanced_layouts : require\n"
15328 "out vec4 vs_tcs;\n"
15332 " vs_tcs = in_vs;\n"
15335 static const GLchar* vs_tested = "#version 430 core\n"
15336 "#extension GL_ARB_enhanced_layouts : require\n"
15341 "out vec4 vs_tcs;\n"
15345 " vec4 result = in_vs;\n"
15349 " vs_tcs += result;\n"
15353 std::string source;
15354 testCase& test_case = m_test_cases[test_case_index];
15356 if (test_case.m_stage == stage)
15358 const GLchar* array = "";
15360 const GLchar* var_definition = 0;
15361 const GLchar* direction = "in ";
15362 const GLchar* index = "";
15363 size_t position = 0;
15365 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
15366 const GLchar* var_use = 0;
15368 if (false == test_case.m_is_input)
15372 if (false == test_case.m_is_array)
15374 var_definition = var_definition_one;
15375 var_use = output_use_one;
15379 var_definition = var_definition_arr;
15380 var_use = output_use_arr;
15385 if (false == test_case.m_is_array)
15387 var_definition = var_definition_one;
15388 var_use = input_use_one;
15392 var_definition = var_definition_arr;
15393 var_use = input_use_arr;
15397 sprintf(buffer, "%d", test_case.m_component);
15401 case Utils::Shader::FRAGMENT:
15402 source = fs_tested;
15404 case Utils::Shader::GEOMETRY:
15405 source = gs_tested;
15409 case Utils::Shader::TESS_CTRL:
15410 source = tcs_tested;
15412 index = "[gl_InvocationID]";
15414 case Utils::Shader::TESS_EVAL:
15415 source = tes_tested;
15419 case Utils::Shader::VERTEX:
15420 source = vs_tested;
15423 TCU_FAIL("Invalid enum");
15427 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
15429 Utils::replaceToken("COMPONENT", position, buffer, source);
15430 Utils::replaceToken("DIRECTION", position, direction, source);
15431 Utils::replaceToken("ARRAY", position, array, source);
15432 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
15434 Utils::replaceAllTokens("TYPE", type_name, source);
15435 Utils::replaceAllTokens("INDEX", index, source);
15441 case Utils::Shader::FRAGMENT:
15444 case Utils::Shader::GEOMETRY:
15447 case Utils::Shader::TESS_CTRL:
15450 case Utils::Shader::TESS_EVAL:
15453 case Utils::Shader::VERTEX:
15457 TCU_FAIL("Invalid enum");
15464 /** Get description of test case
15466 * @param test_case_index Index of test case
15468 * @return Test case description
15470 std::string VaryingExceedingComponentsTest::getTestCaseName(GLuint test_case_index)
15472 std::stringstream stream;
15473 testCase& test_case = m_test_cases[test_case_index];
15475 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
15476 << " type: " << test_case.m_type.GetGLSLTypeName();
15478 if (true == test_case.m_is_array)
15483 stream << ", direction: ";
15485 if (true == test_case.m_is_input)
15491 stream << "output";
15494 stream << ", component: " << test_case.m_component;
15496 return stream.str();
15499 /** Get number of test cases
15501 * @return Number of test cases
15503 GLuint VaryingExceedingComponentsTest::getTestCaseNumber()
15505 return static_cast<GLuint>(m_test_cases.size());
15508 /** Selects if "compute" stage is relevant for test
15514 bool VaryingExceedingComponentsTest::isComputeRelevant(GLuint /* test_case_index */)
15519 /** Prepare all test cases
15522 void VaryingExceedingComponentsTest::testInit()
15524 static const GLuint n_components_per_location = 4;
15525 const GLuint n_types = getTypesNumber();
15527 for (GLuint i = 0; i < n_types; ++i)
15529 const Utils::Type& type = getType(i);
15530 const GLuint n_req_components = type.m_n_rows;
15531 const GLuint valid_component = n_components_per_location - n_req_components;
15532 const GLuint invalid_component = valid_component + 1;
15534 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
15536 if (Utils::Shader::COMPUTE == stage)
15541 /* Component cannot be used for matrices */
15542 if (1 != type.m_n_columns)
15547 testCase test_case_in_arr = { invalid_component, true, true, (Utils::Shader::STAGES)stage, type };
15548 testCase test_case_in_one = { invalid_component, true, false, (Utils::Shader::STAGES)stage, type };
15549 testCase test_case_out_arr = { invalid_component, false, true, (Utils::Shader::STAGES)stage, type };
15550 testCase test_case_out_one = { invalid_component, false, false, (Utils::Shader::STAGES)stage, type };
15552 m_test_cases.push_back(test_case_in_arr);
15553 m_test_cases.push_back(test_case_in_one);
15555 if (Utils::Shader::FRAGMENT != stage)
15557 m_test_cases.push_back(test_case_out_arr);
15558 m_test_cases.push_back(test_case_out_one);
15566 * @param context Test framework context
15568 VaryingComponentWithoutLocationTest::VaryingComponentWithoutLocationTest(deqp::Context& context)
15569 : NegativeTestBase(context, "varying_component_without_location",
15570 "Test verifies that compiler reports error when component qualifier is used without location")
15574 /** Source for given test case and stage
15576 * @param test_case_index Index of test case
15577 * @param stage Shader stage
15579 * @return Shader source
15581 std::string VaryingComponentWithoutLocationTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
15583 static const GLchar* var_definition = "layout (component = COMPONENT) FLAT DIRECTION TYPE gokuARRAY;\n";
15584 static const GLchar* input_use = " if (TYPE(0) == gokuINDEX)\n"
15586 " result += vec4(1, 0.5, 0.25, 0.125);\n"
15588 static const GLchar* output_use = " gokuINDEX = TYPE(0);\n"
15589 " if (vec4(0) == result)\n"
15591 " gokuINDEX = TYPE(1);\n"
15593 static const GLchar* fs = "#version 430 core\n"
15594 "#extension GL_ARB_enhanced_layouts : require\n"
15597 "out vec4 fs_out;\n"
15601 " fs_out = gs_fs;\n"
15604 static const GLchar* fs_tested = "#version 430 core\n"
15605 "#extension GL_ARB_enhanced_layouts : require\n"
15610 "out vec4 fs_out;\n"
15614 " vec4 result = gs_fs;\n"
15618 " fs_out = result;\n"
15621 static const GLchar* gs = "#version 430 core\n"
15622 "#extension GL_ARB_enhanced_layouts : require\n"
15624 "layout(points) in;\n"
15625 "layout(triangle_strip, max_vertices = 4) out;\n"
15627 "in vec4 tes_gs[];\n"
15628 "out vec4 gs_fs;\n"
15632 " gs_fs = tes_gs[0];\n"
15633 " gl_Position = vec4(-1, -1, 0, 1);\n"
15635 " gs_fs = tes_gs[0];\n"
15636 " gl_Position = vec4(-1, 1, 0, 1);\n"
15638 " gs_fs = tes_gs[0];\n"
15639 " gl_Position = vec4(1, -1, 0, 1);\n"
15641 " gs_fs = tes_gs[0];\n"
15642 " gl_Position = vec4(1, 1, 0, 1);\n"
15646 static const GLchar* gs_tested = "#version 430 core\n"
15647 "#extension GL_ARB_enhanced_layouts : require\n"
15649 "layout(points) in;\n"
15650 "layout(triangle_strip, max_vertices = 4) out;\n"
15654 "in vec4 tes_gs[];\n"
15655 "out vec4 gs_fs;\n"
15659 " vec4 result = tes_gs[0];\n"
15663 " gs_fs = result;\n"
15664 " gl_Position = vec4(-1, -1, 0, 1);\n"
15666 " gs_fs = result;\n"
15667 " gl_Position = vec4(-1, 1, 0, 1);\n"
15669 " gs_fs = result;\n"
15670 " gl_Position = vec4(1, -1, 0, 1);\n"
15672 " gs_fs = result;\n"
15673 " gl_Position = vec4(1, 1, 0, 1);\n"
15677 static const GLchar* tcs = "#version 430 core\n"
15678 "#extension GL_ARB_enhanced_layouts : require\n"
15680 "layout(vertices = 1) out;\n"
15682 "in vec4 vs_tcs[];\n"
15683 "out vec4 tcs_tes[];\n"
15688 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
15690 " gl_TessLevelOuter[0] = 1.0;\n"
15691 " gl_TessLevelOuter[1] = 1.0;\n"
15692 " gl_TessLevelOuter[2] = 1.0;\n"
15693 " gl_TessLevelOuter[3] = 1.0;\n"
15694 " gl_TessLevelInner[0] = 1.0;\n"
15695 " gl_TessLevelInner[1] = 1.0;\n"
15698 static const GLchar* tcs_tested = "#version 430 core\n"
15699 "#extension GL_ARB_enhanced_layouts : require\n"
15701 "layout(vertices = 1) out;\n"
15705 "in vec4 vs_tcs[];\n"
15706 "out vec4 tcs_tes[];\n"
15710 " vec4 result = vs_tcs[gl_InvocationID];\n"
15714 " tcs_tes[gl_InvocationID] = result;\n"
15716 " gl_TessLevelOuter[0] = 1.0;\n"
15717 " gl_TessLevelOuter[1] = 1.0;\n"
15718 " gl_TessLevelOuter[2] = 1.0;\n"
15719 " gl_TessLevelOuter[3] = 1.0;\n"
15720 " gl_TessLevelInner[0] = 1.0;\n"
15721 " gl_TessLevelInner[1] = 1.0;\n"
15724 static const GLchar* tes = "#version 430 core\n"
15725 "#extension GL_ARB_enhanced_layouts : require\n"
15727 "layout(isolines, point_mode) in;\n"
15729 "in vec4 tcs_tes[];\n"
15730 "out vec4 tes_gs;\n"
15734 " tes_gs = tcs_tes[0];\n"
15737 static const GLchar* tes_tested = "#version 430 core\n"
15738 "#extension GL_ARB_enhanced_layouts : require\n"
15740 "layout(isolines, point_mode) in;\n"
15744 "in vec4 tcs_tes[];\n"
15745 "out vec4 tes_gs;\n"
15749 " vec4 result = tcs_tes[0];\n"
15753 " tes_gs = result;\n"
15756 static const GLchar* vs = "#version 430 core\n"
15757 "#extension GL_ARB_enhanced_layouts : require\n"
15760 "out vec4 vs_tcs;\n"
15764 " vs_tcs = in_vs;\n"
15767 static const GLchar* vs_tested = "#version 430 core\n"
15768 "#extension GL_ARB_enhanced_layouts : require\n"
15773 "out vec4 vs_tcs;\n"
15777 " vec4 result = in_vs;\n"
15781 " vs_tcs = result;\n"
15785 std::string source;
15786 testCase& test_case = m_test_cases[test_case_index];
15788 if (test_case.m_stage == stage)
15790 const GLchar* array = "";
15792 const GLchar* direction = "in ";
15793 const GLchar* index = "";
15794 size_t position = 0;
15796 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
15797 const GLchar* var_use = input_use;
15798 const GLchar* flat = "flat";
15800 if (false == test_case.m_is_input)
15803 var_use = output_use;
15806 sprintf(buffer, "%d", test_case.m_component);
15810 case Utils::Shader::FRAGMENT:
15811 source = fs_tested;
15813 case Utils::Shader::GEOMETRY:
15814 source = gs_tested;
15818 case Utils::Shader::TESS_CTRL:
15819 source = tcs_tested;
15821 index = "[gl_InvocationID]";
15823 case Utils::Shader::TESS_EVAL:
15824 source = tes_tested;
15828 case Utils::Shader::VERTEX:
15829 source = vs_tested;
15833 TCU_FAIL("Invalid enum");
15837 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
15839 Utils::replaceToken("COMPONENT", position, buffer, source);
15840 Utils::replaceToken("FLAT", position, flat, source);
15841 Utils::replaceToken("DIRECTION", position, direction, source);
15842 Utils::replaceToken("ARRAY", position, array, source);
15843 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
15845 Utils::replaceAllTokens("TYPE", type_name, source);
15846 Utils::replaceAllTokens("INDEX", index, source);
15852 case Utils::Shader::FRAGMENT:
15855 case Utils::Shader::GEOMETRY:
15858 case Utils::Shader::TESS_CTRL:
15861 case Utils::Shader::TESS_EVAL:
15864 case Utils::Shader::VERTEX:
15868 TCU_FAIL("Invalid enum");
15875 /** Get description of test case
15877 * @param test_case_index Index of test case
15879 * @return Test case description
15881 std::string VaryingComponentWithoutLocationTest::getTestCaseName(GLuint test_case_index)
15883 std::stringstream stream;
15884 testCase& test_case = m_test_cases[test_case_index];
15886 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
15887 << " type: " << test_case.m_type.GetGLSLTypeName() << ", direction: ";
15889 if (true == test_case.m_is_input)
15895 stream << "output";
15898 stream << ", component: " << test_case.m_component;
15900 return stream.str();
15903 /** Get number of test cases
15905 * @return Number of test cases
15907 GLuint VaryingComponentWithoutLocationTest::getTestCaseNumber()
15909 return static_cast<GLuint>(m_test_cases.size());
15912 /** Selects if "compute" stage is relevant for test
15918 bool VaryingComponentWithoutLocationTest::isComputeRelevant(GLuint /* test_case_index */)
15923 /** Prepare all test cases
15926 void VaryingComponentWithoutLocationTest::testInit()
15928 static const GLuint n_components_per_location = 4;
15929 const GLuint n_types = getTypesNumber();
15931 for (GLuint i = 0; i < n_types; ++i)
15933 const Utils::Type& type = getType(i);
15934 const GLuint n_req_components = type.m_n_rows;
15935 const GLuint valid_component = n_components_per_location - n_req_components;
15937 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
15939 if (Utils::Shader::COMPUTE == stage)
15944 /* Component cannot be used for matrices */
15945 if (1 != type.m_n_columns)
15950 testCase test_case_in = { valid_component, true, (Utils::Shader::STAGES)stage, type };
15951 testCase test_case_out = { valid_component, false, (Utils::Shader::STAGES)stage, type };
15953 m_test_cases.push_back(test_case_in);
15955 if (Utils::Shader::FRAGMENT != stage)
15957 m_test_cases.push_back(test_case_out);
15965 * @param context Test framework context
15967 VaryingComponentOfInvalidTypeTest::VaryingComponentOfInvalidTypeTest(deqp::Context& context)
15968 : NegativeTestBase(context, "varying_component_of_invalid_type",
15969 "Test verifies that compiler reports error when component qualifier is used for invalid type")
15973 /** Source for given test case and stage
15975 * @param test_case_index Index of test case
15976 * @param stage Shader stage
15978 * @return Shader source
15980 std::string VaryingComponentOfInvalidTypeTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
15982 static const GLchar* block_definition_arr = "layout (location = 1, component = COMPONENT) flat DIRECTION Goku {\n"
15984 "} gokuARRAY[1];\n";
15985 static const GLchar* block_definition_one = "layout (location = 1, component = COMPONENT) flat DIRECTION Goku {\n"
15988 static const GLchar* matrix_definition_arr =
15989 "layout (location = 1, component = COMPONENT) flat DIRECTION TYPE gokuARRAY[1];\n";
15990 static const GLchar* matrix_definition_one =
15991 "layout (location = 1, component = COMPONENT) flat DIRECTION TYPE gokuARRAY;\n";
15992 static const GLchar* struct_definition_arr =
15997 "layout (location = 1, component = COMPONENT) flat DIRECTION Goku gokuARRAY[1];\n";
15998 static const GLchar* struct_definition_one =
16003 "layout (location = 1, component = COMPONENT) flat DIRECTION Goku gokuARRAY;\n";
16004 static const GLchar* matrix_input_use_arr = " if (TYPE(0) == gokuINDEX[0])\n"
16006 " result += vec4(1, 0.5, 0.25, 0.125);\n"
16008 static const GLchar* matrix_input_use_one = " if (TYPE(0) == gokuINDEX)\n"
16010 " result += vec4(1, 0.5, 0.25, 0.125);\n"
16012 static const GLchar* matrix_output_use_arr = " gokuINDEX[0] = TYPE(0);\n"
16013 " if (vec4(0) == result)\n"
16015 " gokuINDEX[0] = TYPE(1);\n"
16017 static const GLchar* matrix_output_use_one = " gokuINDEX = TYPE(0);\n"
16018 " if (vec4(0) == result)\n"
16020 " gokuINDEX = TYPE(1);\n"
16022 static const GLchar* member_input_use_arr = " if (TYPE(0) == gokuINDEX[0].member)\n"
16024 " result += vec4(1, 0.5, 0.25, 0.125);\n"
16026 static const GLchar* member_input_use_one = " if (TYPE(0) == gokuINDEX.member)\n"
16028 " result += vec4(1, 0.5, 0.25, 0.125);\n"
16030 static const GLchar* member_output_use_arr = " gokuINDEX[0].member = TYPE(0);\n"
16031 " if (vec4(0) == result)\n"
16033 " gokuINDEX[0].member = TYPE(1);\n"
16035 static const GLchar* member_output_use_one = " gokuINDEX.member = TYPE(0);\n"
16036 " if (vec4(0) == result)\n"
16038 " gokuINDEX.member = TYPE(1);\n"
16040 static const GLchar* fs = "#version 430 core\n"
16041 "#extension GL_ARB_enhanced_layouts : require\n"
16044 "out vec4 fs_out;\n"
16048 " fs_out = gs_fs;\n"
16051 static const GLchar* fs_tested = "#version 430 core\n"
16052 "#extension GL_ARB_enhanced_layouts : require\n"
16057 "out vec4 fs_out;\n"
16061 " vec4 result = gs_fs;\n"
16065 " fs_out += result;\n"
16068 static const GLchar* gs = "#version 430 core\n"
16069 "#extension GL_ARB_enhanced_layouts : require\n"
16071 "layout(points) in;\n"
16072 "layout(triangle_strip, max_vertices = 4) out;\n"
16074 "in vec4 tes_gs[];\n"
16075 "out vec4 gs_fs;\n"
16079 " gs_fs = tes_gs[0];\n"
16080 " gl_Position = vec4(-1, -1, 0, 1);\n"
16082 " gs_fs = tes_gs[0];\n"
16083 " gl_Position = vec4(-1, 1, 0, 1);\n"
16085 " gs_fs = tes_gs[0];\n"
16086 " gl_Position = vec4(1, -1, 0, 1);\n"
16088 " gs_fs = tes_gs[0];\n"
16089 " gl_Position = vec4(1, 1, 0, 1);\n"
16093 static const GLchar* gs_tested = "#version 430 core\n"
16094 "#extension GL_ARB_enhanced_layouts : require\n"
16096 "layout(points) in;\n"
16097 "layout(triangle_strip, max_vertices = 4) out;\n"
16101 "in vec4 tes_gs[];\n"
16102 "out vec4 gs_fs;\n"
16106 " vec4 result = tes_gs[0];\n"
16110 " gs_fs = result;\n"
16111 " gl_Position = vec4(-1, -1, 0, 1);\n"
16113 " gs_fs = result;\n"
16114 " gl_Position = vec4(-1, 1, 0, 1);\n"
16116 " gs_fs = result;\n"
16117 " gl_Position = vec4(1, -1, 0, 1);\n"
16119 " gs_fs = result;\n"
16120 " gl_Position = vec4(1, 1, 0, 1);\n"
16124 static const GLchar* tcs = "#version 430 core\n"
16125 "#extension GL_ARB_enhanced_layouts : require\n"
16127 "layout(vertices = 1) out;\n"
16129 "in vec4 vs_tcs[];\n"
16130 "out vec4 tcs_tes[];\n"
16135 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
16137 " gl_TessLevelOuter[0] = 1.0;\n"
16138 " gl_TessLevelOuter[1] = 1.0;\n"
16139 " gl_TessLevelOuter[2] = 1.0;\n"
16140 " gl_TessLevelOuter[3] = 1.0;\n"
16141 " gl_TessLevelInner[0] = 1.0;\n"
16142 " gl_TessLevelInner[1] = 1.0;\n"
16145 static const GLchar* tcs_tested = "#version 430 core\n"
16146 "#extension GL_ARB_enhanced_layouts : require\n"
16148 "layout(vertices = 1) out;\n"
16152 "in vec4 vs_tcs[];\n"
16153 "out vec4 tcs_tes[];\n"
16157 " vec4 result = vs_tcs[gl_InvocationID];\n"
16161 " tcs_tes[gl_InvocationID] = result;\n"
16163 " gl_TessLevelOuter[0] = 1.0;\n"
16164 " gl_TessLevelOuter[1] = 1.0;\n"
16165 " gl_TessLevelOuter[2] = 1.0;\n"
16166 " gl_TessLevelOuter[3] = 1.0;\n"
16167 " gl_TessLevelInner[0] = 1.0;\n"
16168 " gl_TessLevelInner[1] = 1.0;\n"
16171 static const GLchar* tes = "#version 430 core\n"
16172 "#extension GL_ARB_enhanced_layouts : require\n"
16174 "layout(isolines, point_mode) in;\n"
16176 "in vec4 tcs_tes[];\n"
16177 "out vec4 tes_gs;\n"
16181 " tes_gs = tcs_tes[0];\n"
16184 static const GLchar* tes_tested = "#version 430 core\n"
16185 "#extension GL_ARB_enhanced_layouts : require\n"
16187 "layout(isolines, point_mode) in;\n"
16191 "in vec4 tcs_tes[];\n"
16192 "out vec4 tes_gs;\n"
16196 " vec4 result = tcs_tes[0];\n"
16200 " tes_gs += result;\n"
16203 static const GLchar* vs = "#version 430 core\n"
16204 "#extension GL_ARB_enhanced_layouts : require\n"
16207 "out vec4 vs_tcs;\n"
16211 " vs_tcs = in_vs;\n"
16214 static const GLchar* vs_tested = "#version 430 core\n"
16215 "#extension GL_ARB_enhanced_layouts : require\n"
16220 "out vec4 vs_tcs;\n"
16224 " vec4 result = in_vs;\n"
16228 " vs_tcs += result;\n"
16232 std::string source;
16233 testCase& test_case = m_test_cases[test_case_index];
16235 if (test_case.m_stage == stage)
16237 const GLchar* array = "";
16239 const GLchar* var_definition = 0;
16240 const GLchar* direction = "in ";
16241 const GLchar* index = "";
16242 size_t position = 0;
16244 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
16245 const GLchar* var_use = 0;
16247 if (false == test_case.m_is_input)
16251 if (false == test_case.m_is_array)
16253 switch (test_case.m_case)
16256 var_definition = block_definition_one;
16257 var_use = member_output_use_one;
16260 var_definition = matrix_definition_one;
16261 var_use = matrix_output_use_one;
16264 var_definition = struct_definition_one;
16265 var_use = member_output_use_one;
16268 TCU_FAIL("Invalid enum");
16273 switch (test_case.m_case)
16276 var_definition = block_definition_arr;
16277 var_use = member_output_use_arr;
16280 var_definition = matrix_definition_arr;
16281 var_use = matrix_output_use_arr;
16284 var_definition = struct_definition_arr;
16285 var_use = member_output_use_arr;
16288 TCU_FAIL("Invalid enum");
16294 if (false == test_case.m_is_array)
16296 switch (test_case.m_case)
16299 var_definition = block_definition_one;
16300 var_use = member_input_use_one;
16303 var_definition = matrix_definition_one;
16304 var_use = matrix_input_use_one;
16307 var_definition = struct_definition_one;
16308 var_use = member_input_use_one;
16311 TCU_FAIL("Invalid enum");
16316 switch (test_case.m_case)
16319 var_definition = block_definition_arr;
16320 var_use = member_input_use_arr;
16323 var_definition = matrix_definition_arr;
16324 var_use = matrix_input_use_arr;
16327 var_definition = struct_definition_arr;
16328 var_use = member_input_use_arr;
16331 TCU_FAIL("Invalid enum");
16336 sprintf(buffer, "%d", test_case.m_component);
16340 case Utils::Shader::FRAGMENT:
16341 source = fs_tested;
16343 case Utils::Shader::GEOMETRY:
16344 source = gs_tested;
16348 case Utils::Shader::TESS_CTRL:
16349 source = tcs_tested;
16351 index = "[gl_InvocationID]";
16353 case Utils::Shader::TESS_EVAL:
16354 source = tes_tested;
16358 case Utils::Shader::VERTEX:
16359 source = vs_tested;
16362 TCU_FAIL("Invalid enum");
16366 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
16368 Utils::replaceToken("COMPONENT", position, buffer, source);
16369 Utils::replaceToken("DIRECTION", position, direction, source);
16370 Utils::replaceToken("ARRAY", position, array, source);
16371 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
16373 Utils::replaceAllTokens("TYPE", type_name, source);
16374 Utils::replaceAllTokens("INDEX", index, source);
16380 case Utils::Shader::FRAGMENT:
16383 case Utils::Shader::GEOMETRY:
16386 case Utils::Shader::TESS_CTRL:
16389 case Utils::Shader::TESS_EVAL:
16392 case Utils::Shader::VERTEX:
16396 TCU_FAIL("Invalid enum");
16403 /** Get description of test case
16405 * @param test_case_index Index of test case
16407 * @return Test case description
16409 std::string VaryingComponentOfInvalidTypeTest::getTestCaseName(GLuint test_case_index)
16411 std::stringstream stream;
16412 testCase& test_case = m_test_cases[test_case_index];
16414 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
16415 << " type: " << test_case.m_type.GetGLSLTypeName();
16417 if (true == test_case.m_is_array)
16422 stream << ", direction: ";
16424 if (true == test_case.m_is_input)
16430 stream << "output";
16433 stream << ", component: " << test_case.m_component;
16435 return stream.str();
16438 /** Get number of test cases
16440 * @return Number of test cases
16442 GLuint VaryingComponentOfInvalidTypeTest::getTestCaseNumber()
16444 return static_cast<GLuint>(m_test_cases.size());
16447 /** Selects if "compute" stage is relevant for test
16453 bool VaryingComponentOfInvalidTypeTest::isComputeRelevant(GLuint /* test_case_index */)
16458 /** Prepare all test cases
16461 void VaryingComponentOfInvalidTypeTest::testInit()
16463 static const GLuint n_components_per_location = 4;
16464 const GLuint n_types = getTypesNumber();
16466 for (GLuint i = 0; i < n_types; ++i)
16468 const Utils::Type& type = getType(i);
16469 const GLuint n_req_components = type.m_n_rows;
16470 const GLuint valid_component = n_components_per_location - n_req_components;
16472 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
16474 if (Utils::Shader::COMPUTE == stage)
16479 /* Use different CASE for matrices */
16480 if (1 != type.m_n_columns)
16482 testCase test_case_in_arr = { MATRIX, valid_component, true, true, (Utils::Shader::STAGES)stage, type };
16483 testCase test_case_in_one = {
16484 MATRIX, valid_component, false, true, (Utils::Shader::STAGES)stage, type
16486 testCase test_case_out_arr = {
16487 MATRIX, valid_component, true, false, (Utils::Shader::STAGES)stage, type
16489 testCase test_case_out_one = {
16490 MATRIX, valid_component, false, false, (Utils::Shader::STAGES)stage, type
16493 m_test_cases.push_back(test_case_in_arr);
16494 m_test_cases.push_back(test_case_in_one);
16496 if (Utils::Shader::FRAGMENT != stage)
16498 m_test_cases.push_back(test_case_out_arr);
16499 m_test_cases.push_back(test_case_out_one);
16504 for (GLuint c = BLOCK; c < MAX_CASES; ++c)
16506 testCase test_case_in_arr = { (CASES)c, valid_component, true, true, (Utils::Shader::STAGES)stage,
16508 testCase test_case_in_one = { (CASES)c, valid_component, false, true, (Utils::Shader::STAGES)stage,
16510 testCase test_case_out_arr = { (CASES)c, valid_component, true, false, (Utils::Shader::STAGES)stage,
16512 testCase test_case_out_one = {
16513 (CASES)c, valid_component, false, false, (Utils::Shader::STAGES)stage, type
16516 if (Utils::Shader::VERTEX != stage)
16518 m_test_cases.push_back(test_case_in_arr);
16519 m_test_cases.push_back(test_case_in_one);
16522 if (Utils::Shader::FRAGMENT != stage)
16524 m_test_cases.push_back(test_case_out_arr);
16525 m_test_cases.push_back(test_case_out_one);
16535 * @param context Test framework context
16537 InputComponentAliasingTest::InputComponentAliasingTest(deqp::Context& context)
16538 : NegativeTestBase(context, "input_component_aliasing",
16539 "Test verifies that compiler reports component aliasing as error")
16543 /** Source for given test case and stage
16545 * @param test_case_index Index of test case
16546 * @param stage Shader stage
16548 * @return Shader source
16550 std::string InputComponentAliasingTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
16552 static const GLchar* var_definition = "layout (location = 1, component = COMPONENT) FLAT in TYPE gohanARRAY;\n"
16553 "layout (location = 1, component = COMPONENT) FLAT in TYPE gotenARRAY;\n";
16554 static const GLchar* test_one = " if (TYPE(0) == gohanINDEX)\n"
16556 " result += vec4(1, 0.5, 0.25, 0.125);\n"
16558 static const GLchar* test_both = " if (TYPE(0) == gohanINDEX)\n"
16560 " result = vec4(goten.xxxx);\n"
16562 static const GLchar* fs = "#version 430 core\n"
16563 "#extension GL_ARB_enhanced_layouts : require\n"
16566 "out vec4 fs_out;\n"
16570 " fs_out = gs_fs;\n"
16573 static const GLchar* fs_tested = "#version 430 core\n"
16574 "#extension GL_ARB_enhanced_layouts : require\n"
16579 "out vec4 fs_out;\n"
16583 " vec4 result = gs_fs;\n"
16587 " fs_out += result;\n"
16590 static const GLchar* gs = "#version 430 core\n"
16591 "#extension GL_ARB_enhanced_layouts : require\n"
16593 "layout(points) in;\n"
16594 "layout(triangle_strip, max_vertices = 4) out;\n"
16596 "in vec4 tes_gs[];\n"
16597 "out vec4 gs_fs;\n"
16601 " gs_fs = tes_gs[0];\n"
16602 " gl_Position = vec4(-1, -1, 0, 1);\n"
16604 " gs_fs = tes_gs[0];\n"
16605 " gl_Position = vec4(-1, 1, 0, 1);\n"
16607 " gs_fs = tes_gs[0];\n"
16608 " gl_Position = vec4(1, -1, 0, 1);\n"
16610 " gs_fs = tes_gs[0];\n"
16611 " gl_Position = vec4(1, 1, 0, 1);\n"
16615 static const GLchar* gs_tested = "#version 430 core\n"
16616 "#extension GL_ARB_enhanced_layouts : require\n"
16618 "layout(points) in;\n"
16619 "layout(triangle_strip, max_vertices = 4) out;\n"
16623 "in vec4 tes_gs[];\n"
16624 "out vec4 gs_fs;\n"
16628 " vec4 result = tes_gs[0];\n"
16632 " gs_fs = result;\n"
16633 " gl_Position = vec4(-1, -1, 0, 1);\n"
16635 " gs_fs = result;\n"
16636 " gl_Position = vec4(-1, 1, 0, 1);\n"
16638 " gs_fs = result;\n"
16639 " gl_Position = vec4(1, -1, 0, 1);\n"
16641 " gs_fs = result;\n"
16642 " gl_Position = vec4(1, 1, 0, 1);\n"
16646 static const GLchar* tcs = "#version 430 core\n"
16647 "#extension GL_ARB_enhanced_layouts : require\n"
16649 "layout(vertices = 1) out;\n"
16651 "in vec4 vs_tcs[];\n"
16652 "out vec4 tcs_tes[];\n"
16657 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
16659 " gl_TessLevelOuter[0] = 1.0;\n"
16660 " gl_TessLevelOuter[1] = 1.0;\n"
16661 " gl_TessLevelOuter[2] = 1.0;\n"
16662 " gl_TessLevelOuter[3] = 1.0;\n"
16663 " gl_TessLevelInner[0] = 1.0;\n"
16664 " gl_TessLevelInner[1] = 1.0;\n"
16667 static const GLchar* tcs_tested = "#version 430 core\n"
16668 "#extension GL_ARB_enhanced_layouts : require\n"
16670 "layout(vertices = 1) out;\n"
16674 "in vec4 vs_tcs[];\n"
16675 "out vec4 tcs_tes[];\n"
16679 " vec4 result = vs_tcs[gl_InvocationID];\n"
16683 " tcs_tes[gl_InvocationID] = result;\n"
16685 " gl_TessLevelOuter[0] = 1.0;\n"
16686 " gl_TessLevelOuter[1] = 1.0;\n"
16687 " gl_TessLevelOuter[2] = 1.0;\n"
16688 " gl_TessLevelOuter[3] = 1.0;\n"
16689 " gl_TessLevelInner[0] = 1.0;\n"
16690 " gl_TessLevelInner[1] = 1.0;\n"
16693 static const GLchar* tes = "#version 430 core\n"
16694 "#extension GL_ARB_enhanced_layouts : require\n"
16696 "layout(isolines, point_mode) in;\n"
16698 "in vec4 tcs_tes[];\n"
16699 "out vec4 tes_gs;\n"
16703 " tes_gs = tcs_tes[0];\n"
16706 static const GLchar* tes_tested = "#version 430 core\n"
16707 "#extension GL_ARB_enhanced_layouts : require\n"
16709 "layout(isolines, point_mode) in;\n"
16713 "in vec4 tcs_tes[];\n"
16714 "out vec4 tes_gs;\n"
16718 " vec4 result = tcs_tes[0];\n"
16722 " tes_gs += result;\n"
16725 static const GLchar* vs = "#version 430 core\n"
16726 "#extension GL_ARB_enhanced_layouts : require\n"
16729 "out vec4 vs_tcs;\n"
16733 " vs_tcs = in_vs;\n"
16736 static const GLchar* vs_tested = "#version 430 core\n"
16737 "#extension GL_ARB_enhanced_layouts : require\n"
16742 "out vec4 vs_tcs;\n"
16746 " vec4 result = in_vs;\n"
16750 " vs_tcs += result;\n"
16754 std::string source;
16755 testCase& test_case = m_test_cases[test_case_index];
16757 if (test_case.m_stage == stage)
16759 const GLchar* array = "";
16760 GLchar buffer_gohan[16];
16761 GLchar buffer_goten[16];
16762 const GLchar* flat = "";
16763 const GLchar* index = "";
16764 const bool is_flat_req = isFlatRequired(stage, test_case.m_type, Utils::Variable::VARYING_INPUT);
16765 size_t position = 0;
16767 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
16768 const GLchar* var_use = test_one;
16770 if (true == test_case.m_use_both)
16772 var_use = test_both;
16775 if (true == is_flat_req)
16780 sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
16781 sprintf(buffer_goten, "%d", test_case.m_component_goten);
16785 case Utils::Shader::FRAGMENT:
16786 source = fs_tested;
16788 case Utils::Shader::GEOMETRY:
16789 source = gs_tested;
16793 case Utils::Shader::TESS_CTRL:
16794 source = tcs_tested;
16796 index = "[gl_InvocationID]";
16798 case Utils::Shader::TESS_EVAL:
16799 source = tes_tested;
16803 case Utils::Shader::VERTEX:
16804 source = vs_tested;
16807 TCU_FAIL("Invalid enum");
16811 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
16813 Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
16814 Utils::replaceToken("ARRAY", position, array, source);
16815 Utils::replaceToken("COMPONENT", position, buffer_goten, source);
16816 Utils::replaceToken("ARRAY", position, array, source);
16817 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
16819 Utils::replaceAllTokens("FLAT", flat, source);
16820 Utils::replaceAllTokens("TYPE", type_name, source);
16821 Utils::replaceAllTokens("INDEX", index, source);
16827 case Utils::Shader::FRAGMENT:
16830 case Utils::Shader::GEOMETRY:
16833 case Utils::Shader::TESS_CTRL:
16836 case Utils::Shader::TESS_EVAL:
16839 case Utils::Shader::VERTEX:
16843 TCU_FAIL("Invalid enum");
16850 /** Get description of test case
16852 * @param test_case_index Index of test case
16854 * @return Test case description
16856 std::string InputComponentAliasingTest::getTestCaseName(GLuint test_case_index)
16858 std::stringstream stream;
16859 testCase& test_case = m_test_cases[test_case_index];
16861 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
16862 << " type: " << test_case.m_type.GetGLSLTypeName() << ", components: " << test_case.m_component_gohan
16863 << " & " << test_case.m_component_goten;
16865 return stream.str();
16868 /** Get number of test cases
16870 * @return Number of test cases
16872 GLuint InputComponentAliasingTest::getTestCaseNumber()
16874 return static_cast<GLuint>(m_test_cases.size());
16877 /** Selects if "compute" stage is relevant for test
16883 bool InputComponentAliasingTest::isComputeRelevant(GLuint /* test_case_index */)
16888 /** Selects if compilation failure is expected result
16890 * @param test_case_index Index of test case
16892 * @return false for VS that use only single variable, true otherwise
16894 bool InputComponentAliasingTest::isFailureExpected(GLuint test_case_index)
16896 testCase& test_case = m_test_cases[test_case_index];
16898 return !((Utils::Shader::VERTEX == test_case.m_stage) && (false == test_case.m_use_both));
16901 /** Prepare all test cases
16904 void InputComponentAliasingTest::testInit()
16906 static const GLuint n_components_per_location = 4;
16907 const GLuint n_types = getTypesNumber();
16909 for (GLuint i = 0; i < n_types; ++i)
16911 const Utils::Type& type = getType(i);
16912 const GLuint n_req_components = type.m_n_rows;
16913 const GLuint valid_component = n_components_per_location - n_req_components;
16915 /* Skip matrices */
16916 if (1 != type.m_n_columns)
16921 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
16923 if (Utils::Shader::COMPUTE == stage)
16928 for (GLuint gohan = 0; gohan <= valid_component; ++gohan)
16930 const GLint first_aliasing = gohan - n_req_components + 1;
16931 const GLint last_aliasing = gohan + n_req_components - 1;
16933 const GLuint goten_start = std::max(0, first_aliasing);
16934 const GLuint goten_stop = std::min((GLint)valid_component, last_aliasing);
16936 for (GLuint goten = goten_start; goten <= goten_stop; ++goten)
16938 testCase test_case = { gohan, goten, (Utils::Shader::STAGES)stage, type, false };
16940 m_test_cases.push_back(test_case);
16942 if (Utils::Shader::VERTEX == test_case.m_stage)
16944 test_case.m_use_both = true;
16946 m_test_cases.push_back(test_case);
16956 * @param context Test framework context
16958 OutputComponentAliasingTest::OutputComponentAliasingTest(deqp::Context& context)
16959 : NegativeTestBase(context, "output_component_aliasing",
16960 "Test verifies that compiler reports component aliasing as error")
16964 /** Source for given test case and stage
16966 * @param test_case_index Index of test case
16967 * @param stage Shader stage
16969 * @return Shader source
16971 std::string OutputComponentAliasingTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
16973 static const GLchar* var_definition = "layout (location = 1, component = COMPONENT) flat out TYPE gohanARRAY;\n"
16974 "layout (location = 1, component = COMPONENT) flat out TYPE gotenARRAY;\n";
16975 static const GLchar* l_test = " gohanINDEX = TYPE(1);\n"
16976 " gotenINDEX = TYPE(0);\n";
16977 static const GLchar* fs = "#version 430 core\n"
16978 "#extension GL_ARB_enhanced_layouts : require\n"
16981 "out vec4 fs_out;\n"
16985 " fs_out = gs_fs;\n"
16988 static const GLchar* fs_tested = "#version 430 core\n"
16989 "#extension GL_ARB_enhanced_layouts : require\n"
16994 "out vec4 fs_out;\n"
16998 " vec4 result = gs_fs;\n"
17002 " fs_out += result;\n"
17005 static const GLchar* gs = "#version 430 core\n"
17006 "#extension GL_ARB_enhanced_layouts : require\n"
17008 "layout(points) in;\n"
17009 "layout(triangle_strip, max_vertices = 4) out;\n"
17011 "in vec4 tes_gs[];\n"
17012 "out vec4 gs_fs;\n"
17016 " gs_fs = tes_gs[0];\n"
17017 " gl_Position = vec4(-1, -1, 0, 1);\n"
17019 " gs_fs = tes_gs[0];\n"
17020 " gl_Position = vec4(-1, 1, 0, 1);\n"
17022 " gs_fs = tes_gs[0];\n"
17023 " gl_Position = vec4(1, -1, 0, 1);\n"
17025 " gs_fs = tes_gs[0];\n"
17026 " gl_Position = vec4(1, 1, 0, 1);\n"
17030 static const GLchar* gs_tested = "#version 430 core\n"
17031 "#extension GL_ARB_enhanced_layouts : require\n"
17033 "layout(points) in;\n"
17034 "layout(triangle_strip, max_vertices = 4) out;\n"
17038 "in vec4 tes_gs[];\n"
17039 "out vec4 gs_fs;\n"
17043 " vec4 result = tes_gs[0];\n"
17047 " gs_fs = result;\n"
17048 " gl_Position = vec4(-1, -1, 0, 1);\n"
17050 " gs_fs = result;\n"
17051 " gl_Position = vec4(-1, 1, 0, 1);\n"
17053 " gs_fs = result;\n"
17054 " gl_Position = vec4(1, -1, 0, 1);\n"
17056 " gs_fs = result;\n"
17057 " gl_Position = vec4(1, 1, 0, 1);\n"
17061 static const GLchar* tcs = "#version 430 core\n"
17062 "#extension GL_ARB_enhanced_layouts : require\n"
17064 "layout(vertices = 1) out;\n"
17066 "in vec4 vs_tcs[];\n"
17067 "out vec4 tcs_tes[];\n"
17072 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
17074 " gl_TessLevelOuter[0] = 1.0;\n"
17075 " gl_TessLevelOuter[1] = 1.0;\n"
17076 " gl_TessLevelOuter[2] = 1.0;\n"
17077 " gl_TessLevelOuter[3] = 1.0;\n"
17078 " gl_TessLevelInner[0] = 1.0;\n"
17079 " gl_TessLevelInner[1] = 1.0;\n"
17082 static const GLchar* tcs_tested = "#version 430 core\n"
17083 "#extension GL_ARB_enhanced_layouts : require\n"
17085 "layout(vertices = 1) out;\n"
17089 "in vec4 vs_tcs[];\n"
17090 "out vec4 tcs_tes[];\n"
17094 " vec4 result = vs_tcs[gl_InvocationID];\n"
17098 " tcs_tes[gl_InvocationID] = result;\n"
17100 " gl_TessLevelOuter[0] = 1.0;\n"
17101 " gl_TessLevelOuter[1] = 1.0;\n"
17102 " gl_TessLevelOuter[2] = 1.0;\n"
17103 " gl_TessLevelOuter[3] = 1.0;\n"
17104 " gl_TessLevelInner[0] = 1.0;\n"
17105 " gl_TessLevelInner[1] = 1.0;\n"
17108 static const GLchar* tes = "#version 430 core\n"
17109 "#extension GL_ARB_enhanced_layouts : require\n"
17111 "layout(isolines, point_mode) in;\n"
17113 "in vec4 tcs_tes[];\n"
17114 "out vec4 tes_gs;\n"
17118 " tes_gs = tcs_tes[0];\n"
17121 static const GLchar* tes_tested = "#version 430 core\n"
17122 "#extension GL_ARB_enhanced_layouts : require\n"
17124 "layout(isolines, point_mode) in;\n"
17128 "in vec4 tcs_tes[];\n"
17129 "out vec4 tes_gs;\n"
17133 " vec4 result = tcs_tes[0];\n"
17137 " tes_gs += result;\n"
17140 static const GLchar* vs = "#version 430 core\n"
17141 "#extension GL_ARB_enhanced_layouts : require\n"
17144 "out vec4 vs_tcs;\n"
17148 " vs_tcs = in_vs;\n"
17151 static const GLchar* vs_tested = "#version 430 core\n"
17152 "#extension GL_ARB_enhanced_layouts : require\n"
17157 "out vec4 vs_tcs;\n"
17161 " vec4 result = in_vs;\n"
17165 " vs_tcs += result;\n"
17169 std::string source;
17170 testCase& test_case = m_test_cases[test_case_index];
17172 if (test_case.m_stage == stage)
17174 const GLchar* array = "";
17175 GLchar buffer_gohan[16];
17176 GLchar buffer_goten[16];
17177 const GLchar* index = "";
17178 size_t position = 0;
17180 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
17182 sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
17183 sprintf(buffer_goten, "%d", test_case.m_component_goten);
17187 case Utils::Shader::FRAGMENT:
17188 source = fs_tested;
17190 case Utils::Shader::GEOMETRY:
17191 source = gs_tested;
17195 case Utils::Shader::TESS_CTRL:
17196 source = tcs_tested;
17198 index = "[gl_InvocationID]";
17200 case Utils::Shader::TESS_EVAL:
17201 source = tes_tested;
17205 case Utils::Shader::VERTEX:
17206 source = vs_tested;
17209 TCU_FAIL("Invalid enum");
17213 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
17215 Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
17216 Utils::replaceToken("ARRAY", position, array, source);
17217 Utils::replaceToken("COMPONENT", position, buffer_goten, source);
17218 Utils::replaceToken("ARRAY", position, array, source);
17219 Utils::replaceToken("VARIABLE_USE", position, l_test, source);
17221 Utils::replaceAllTokens("TYPE", type_name, source);
17222 Utils::replaceAllTokens("INDEX", index, source);
17228 case Utils::Shader::FRAGMENT:
17231 case Utils::Shader::GEOMETRY:
17234 case Utils::Shader::TESS_CTRL:
17237 case Utils::Shader::TESS_EVAL:
17240 case Utils::Shader::VERTEX:
17244 TCU_FAIL("Invalid enum");
17251 /** Get description of test case
17253 * @param test_case_index Index of test case
17255 * @return Test case description
17257 std::string OutputComponentAliasingTest::getTestCaseName(GLuint test_case_index)
17259 std::stringstream stream;
17260 testCase& test_case = m_test_cases[test_case_index];
17262 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
17263 << " type: " << test_case.m_type.GetGLSLTypeName() << ", components: " << test_case.m_component_gohan
17264 << " & " << test_case.m_component_goten;
17266 return stream.str();
17269 /** Get number of test cases
17271 * @return Number of test cases
17273 GLuint OutputComponentAliasingTest::getTestCaseNumber()
17275 return static_cast<GLuint>(m_test_cases.size());
17278 /** Selects if "compute" stage is relevant for test
17284 bool OutputComponentAliasingTest::isComputeRelevant(GLuint /* test_case_index */)
17289 /** Prepare all test cases
17292 void OutputComponentAliasingTest::testInit()
17294 static const GLuint n_components_per_location = 4;
17295 const GLuint n_types = getTypesNumber();
17297 for (GLuint i = 0; i < n_types; ++i)
17299 const Utils::Type& type = getType(i);
17300 const GLuint n_req_components = type.m_n_rows;
17301 const GLuint valid_component = n_components_per_location - n_req_components;
17303 /* Skip matrices */
17304 if (1 != type.m_n_columns)
17309 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
17311 if (Utils::Shader::COMPUTE == stage)
17316 if ((Utils::Shader::FRAGMENT == stage) && (Utils::Type::Double == type.m_basic_type))
17321 for (GLuint gohan = 0; gohan <= valid_component; ++gohan)
17323 const GLint first_aliasing = gohan - n_req_components + 1;
17324 const GLint last_aliasing = gohan + n_req_components - 1;
17326 const GLuint goten_start = std::max(0, first_aliasing);
17327 const GLuint goten_stop = std::min((GLint)valid_component, last_aliasing);
17329 for (GLuint goten = goten_start; goten <= goten_stop; ++goten)
17331 testCase test_case = { gohan, goten, (Utils::Shader::STAGES)stage, type };
17333 m_test_cases.push_back(test_case);
17342 * @param context Test framework context
17344 VaryingLocationAliasingWithMixedTypesTest::VaryingLocationAliasingWithMixedTypesTest(deqp::Context& context)
17345 : NegativeTestBase(context, "varying_location_aliasing_with_mixed_types",
17346 "Test verifies that compiler reports error when float/int types are mixed at one location")
17350 /** Source for given test case and stage
17352 * @param test_case_index Index of test case
17353 * @param stage Shader stage
17355 * @return Shader source
17357 std::string VaryingLocationAliasingWithMixedTypesTest::getShaderSource(GLuint test_case_index,
17358 Utils::Shader::STAGES stage)
17360 static const GLchar* var_definition =
17361 "layout (location = 1, component = COMPONENT) FLAT DIRECTION TYPE gohanARRAY;\n"
17362 "layout (location = 1, component = COMPONENT) FLAT DIRECTION TYPE gotenARRAY;\n";
17363 static const GLchar* input_use = " if ((TYPE(0) == gohanINDEX) &&\n"
17364 " (TYPE(1) == gotenINDEX) )\n"
17366 " result += vec4(1, 0.5, 0.25, 0.125);\n"
17368 static const GLchar* output_use = " gohanINDEX = TYPE(0);\n"
17369 " gotenINDEX = TYPE(1);\n"
17370 " if (vec4(0) == result)\n"
17372 " gohanINDEX = TYPE(1);\n"
17373 " gotenINDEX = TYPE(0);\n"
17375 static const GLchar* fs = "#version 430 core\n"
17376 "#extension GL_ARB_enhanced_layouts : require\n"
17379 "out vec4 fs_out;\n"
17383 " fs_out = gs_fs;\n"
17386 static const GLchar* fs_tested = "#version 430 core\n"
17387 "#extension GL_ARB_enhanced_layouts : require\n"
17392 "out vec4 fs_out;\n"
17396 " vec4 result = gs_fs;\n"
17400 " fs_out += result;\n"
17403 static const GLchar* gs = "#version 430 core\n"
17404 "#extension GL_ARB_enhanced_layouts : require\n"
17406 "layout(points) in;\n"
17407 "layout(triangle_strip, max_vertices = 4) out;\n"
17409 "in vec4 tes_gs[];\n"
17410 "out vec4 gs_fs;\n"
17414 " gs_fs = tes_gs[0];\n"
17415 " gl_Position = vec4(-1, -1, 0, 1);\n"
17417 " gs_fs = tes_gs[0];\n"
17418 " gl_Position = vec4(-1, 1, 0, 1);\n"
17420 " gs_fs = tes_gs[0];\n"
17421 " gl_Position = vec4(1, -1, 0, 1);\n"
17423 " gs_fs = tes_gs[0];\n"
17424 " gl_Position = vec4(1, 1, 0, 1);\n"
17428 static const GLchar* gs_tested = "#version 430 core\n"
17429 "#extension GL_ARB_enhanced_layouts : require\n"
17431 "layout(points) in;\n"
17432 "layout(triangle_strip, max_vertices = 4) out;\n"
17436 "in vec4 tes_gs[];\n"
17437 "out vec4 gs_fs;\n"
17441 " vec4 result = tes_gs[0];\n"
17445 " gs_fs = result;\n"
17446 " gl_Position = vec4(-1, -1, 0, 1);\n"
17448 " gs_fs = result;\n"
17449 " gl_Position = vec4(-1, 1, 0, 1);\n"
17451 " gs_fs = result;\n"
17452 " gl_Position = vec4(1, -1, 0, 1);\n"
17454 " gs_fs = result;\n"
17455 " gl_Position = vec4(1, 1, 0, 1);\n"
17459 static const GLchar* tcs = "#version 430 core\n"
17460 "#extension GL_ARB_enhanced_layouts : require\n"
17462 "layout(vertices = 1) out;\n"
17464 "in vec4 vs_tcs[];\n"
17465 "out vec4 tcs_tes[];\n"
17470 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
17472 " gl_TessLevelOuter[0] = 1.0;\n"
17473 " gl_TessLevelOuter[1] = 1.0;\n"
17474 " gl_TessLevelOuter[2] = 1.0;\n"
17475 " gl_TessLevelOuter[3] = 1.0;\n"
17476 " gl_TessLevelInner[0] = 1.0;\n"
17477 " gl_TessLevelInner[1] = 1.0;\n"
17480 static const GLchar* tcs_tested = "#version 430 core\n"
17481 "#extension GL_ARB_enhanced_layouts : require\n"
17483 "layout(vertices = 1) out;\n"
17487 "in vec4 vs_tcs[];\n"
17488 "out vec4 tcs_tes[];\n"
17492 " vec4 result = vs_tcs[gl_InvocationID];\n"
17496 " tcs_tes[gl_InvocationID] = result;\n"
17498 " gl_TessLevelOuter[0] = 1.0;\n"
17499 " gl_TessLevelOuter[1] = 1.0;\n"
17500 " gl_TessLevelOuter[2] = 1.0;\n"
17501 " gl_TessLevelOuter[3] = 1.0;\n"
17502 " gl_TessLevelInner[0] = 1.0;\n"
17503 " gl_TessLevelInner[1] = 1.0;\n"
17506 static const GLchar* tes = "#version 430 core\n"
17507 "#extension GL_ARB_enhanced_layouts : require\n"
17509 "layout(isolines, point_mode) in;\n"
17511 "in vec4 tcs_tes[];\n"
17512 "out vec4 tes_gs;\n"
17516 " tes_gs = tcs_tes[0];\n"
17519 static const GLchar* tes_tested = "#version 430 core\n"
17520 "#extension GL_ARB_enhanced_layouts : require\n"
17522 "layout(isolines, point_mode) in;\n"
17526 "in vec4 tcs_tes[];\n"
17527 "out vec4 tes_gs;\n"
17531 " vec4 result = tcs_tes[0];\n"
17535 " tes_gs += result;\n"
17538 static const GLchar* vs = "#version 430 core\n"
17539 "#extension GL_ARB_enhanced_layouts : require\n"
17542 "out vec4 vs_tcs;\n"
17546 " vs_tcs = in_vs;\n"
17549 static const GLchar* vs_tested = "#version 430 core\n"
17550 "#extension GL_ARB_enhanced_layouts : require\n"
17555 "out vec4 vs_tcs;\n"
17559 " vec4 result = in_vs;\n"
17563 " vs_tcs += result;\n"
17567 std::string source;
17568 testCase& test_case = m_test_cases[test_case_index];
17570 if (test_case.m_stage == stage)
17572 const GLchar* array = "";
17573 GLchar buffer_gohan[16];
17574 GLchar buffer_goten[16];
17575 const GLchar* direction = "in ";
17576 const GLchar* flat_gohan = "";
17577 const GLchar* flat_goten = "";
17578 const GLchar* index = "";
17579 size_t position = 0;
17581 const GLchar* type_gohan_name = test_case.m_type_gohan.GetGLSLTypeName();
17582 const GLchar* type_goten_name = test_case.m_type_goten.GetGLSLTypeName();
17583 Utils::Variable::STORAGE storage = Utils::Variable::VARYING_INPUT;
17584 const GLchar* var_use = input_use;
17586 if (false == test_case.m_is_input)
17589 storage = Utils::Variable::VARYING_OUTPUT;
17590 var_use = output_use;
17593 if (true == isFlatRequired(stage, test_case.m_type_gohan, storage))
17595 flat_gohan = "flat";
17598 if (true == isFlatRequired(stage, test_case.m_type_goten, storage))
17600 flat_goten = "flat";
17603 sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
17604 sprintf(buffer_goten, "%d", test_case.m_component_goten);
17608 case Utils::Shader::FRAGMENT:
17609 source = fs_tested;
17611 case Utils::Shader::GEOMETRY:
17612 source = gs_tested;
17616 case Utils::Shader::TESS_CTRL:
17617 source = tcs_tested;
17619 index = "[gl_InvocationID]";
17621 case Utils::Shader::TESS_EVAL:
17622 source = tes_tested;
17626 case Utils::Shader::VERTEX:
17627 source = vs_tested;
17630 TCU_FAIL("Invalid enum");
17634 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
17636 Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
17637 Utils::replaceToken("FLAT", position, flat_gohan, source);
17638 Utils::replaceToken("DIRECTION", position, direction, source);
17639 Utils::replaceToken("TYPE", position, type_gohan_name, source);
17640 Utils::replaceToken("ARRAY", position, array, source);
17641 Utils::replaceToken("COMPONENT", position, buffer_goten, source);
17642 Utils::replaceToken("FLAT", position, flat_goten, source);
17643 Utils::replaceToken("DIRECTION", position, direction, source);
17644 Utils::replaceToken("TYPE", position, type_goten_name, source);
17645 Utils::replaceToken("ARRAY", position, array, source);
17648 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
17650 if (true == test_case.m_is_input)
17652 Utils::replaceToken("TYPE", position, type_gohan_name, source);
17653 Utils::replaceToken("TYPE", position, type_goten_name, source);
17657 Utils::replaceToken("TYPE", position, type_gohan_name, source);
17658 Utils::replaceToken("TYPE", position, type_goten_name, source);
17659 Utils::replaceToken("TYPE", position, type_gohan_name, source);
17660 Utils::replaceToken("TYPE", position, type_goten_name, source);
17663 Utils::replaceAllTokens("INDEX", index, source);
17669 case Utils::Shader::FRAGMENT:
17672 case Utils::Shader::GEOMETRY:
17675 case Utils::Shader::TESS_CTRL:
17678 case Utils::Shader::TESS_EVAL:
17681 case Utils::Shader::VERTEX:
17685 TCU_FAIL("Invalid enum");
17692 /** Get description of test case
17694 * @param test_case_index Index of test case
17696 * @return Test case description
17698 std::string VaryingLocationAliasingWithMixedTypesTest::getTestCaseName(GLuint test_case_index)
17700 std::stringstream stream;
17701 testCase& test_case = m_test_cases[test_case_index];
17703 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", "
17704 << test_case.m_type_gohan.GetGLSLTypeName() << " at " << test_case.m_component_gohan << ", "
17705 << test_case.m_type_goten.GetGLSLTypeName() << " at " << test_case.m_component_goten << ". Direction: ";
17707 if (true == test_case.m_is_input)
17713 stream << "output";
17716 return stream.str();
17719 /** Get number of test cases
17721 * @return Number of test cases
17723 GLuint VaryingLocationAliasingWithMixedTypesTest::getTestCaseNumber()
17725 return static_cast<GLuint>(m_test_cases.size());
17728 /** Selects if "compute" stage is relevant for test
17734 bool VaryingLocationAliasingWithMixedTypesTest::isComputeRelevant(GLuint /* test_case_index */)
17739 /** Prepare all test cases
17742 void VaryingLocationAliasingWithMixedTypesTest::testInit()
17744 static const GLuint n_components_per_location = 4;
17745 const GLuint n_types = getTypesNumber();
17747 for (GLuint i = 0; i < n_types; ++i)
17749 const Utils::Type& type_gohan = getType(i);
17750 const bool is_float_type_gohan = isFloatType(type_gohan);
17752 /* Skip matrices */
17753 if (1 != type_gohan.m_n_columns)
17758 for (GLuint j = 0; j < n_types; ++j)
17760 const Utils::Type& type_goten = getType(j);
17761 const bool is_float_type_goten = isFloatType(type_goten);
17763 /* Skip matrices */
17764 if (1 != type_goten.m_n_columns)
17769 /* Skip valid combinations */
17770 if (is_float_type_gohan == is_float_type_goten)
17775 const GLuint n_req_components_gohan = type_gohan.m_n_rows;
17776 const GLuint n_req_components_goten = type_goten.m_n_rows;
17777 const GLuint valid_component_gohan = n_components_per_location - n_req_components_gohan;
17778 const GLuint valid_component_goten = n_components_per_location - n_req_components_goten;
17780 /* Skip pairs that cannot fit into one location */
17781 if (n_components_per_location < (n_req_components_gohan + n_req_components_goten))
17786 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
17788 /* Skip compute shader */
17789 if (Utils::Shader::COMPUTE == stage)
17794 for (GLuint gohan = 0; gohan <= valid_component_gohan; ++gohan)
17796 const GLint first_aliasing = gohan - n_req_components_goten + 1;
17797 const GLint last_aliasing = gohan + n_req_components_gohan - 1;
17799 const GLuint goten_lower_limit = std::max(0, first_aliasing);
17800 const GLuint goten_upper_limit = last_aliasing + 1;
17802 /* Compoennets before gohan */
17803 for (GLuint goten = 0; goten < goten_lower_limit; ++goten)
17805 testCase test_case_in = { gohan, goten, true, (Utils::Shader::STAGES)stage,
17806 type_gohan, type_goten };
17807 testCase test_case_out = { gohan, goten, false, (Utils::Shader::STAGES)stage,
17808 type_gohan, type_goten };
17810 m_test_cases.push_back(test_case_in);
17812 /* Skip double outputs in fragment shader */
17813 if ((Utils::Shader::FRAGMENT != stage) || ((Utils::Type::Double != type_gohan.m_basic_type) &&
17814 (Utils::Type::Double != type_goten.m_basic_type)))
17816 m_test_cases.push_back(test_case_out);
17820 /* Components after gohan */
17821 for (GLuint goten = goten_upper_limit; goten <= valid_component_goten; ++goten)
17823 testCase test_case_in = { gohan, goten, true, (Utils::Shader::STAGES)stage,
17824 type_gohan, type_goten };
17825 testCase test_case_out = { gohan, goten, false, (Utils::Shader::STAGES)stage,
17826 type_gohan, type_goten };
17828 m_test_cases.push_back(test_case_in);
17830 /* Skip double outputs in fragment shader */
17831 if ((Utils::Shader::FRAGMENT != stage) || ((Utils::Type::Double != type_gohan.m_basic_type) &&
17832 (Utils::Type::Double != type_goten.m_basic_type)))
17834 m_test_cases.push_back(test_case_out);
17843 /** Check if given type is float
17845 * @param type Type in question
17847 * @return true if tpye is float, false otherwise
17849 bool VaryingLocationAliasingWithMixedTypesTest::isFloatType(const Utils::Type& type)
17851 bool is_float = false;
17853 if ((Utils::Type::Double == type.m_basic_type) || (Utils::Type::Float == type.m_basic_type))
17863 * @param context Test framework context
17865 VaryingLocationAliasingWithMixedInterpolationTest::VaryingLocationAliasingWithMixedInterpolationTest(
17866 deqp::Context& context)
17867 : NegativeTestBase(
17868 context, "varying_location_aliasing_with_mixed_interpolation",
17869 "Test verifies that compiler reports error when interpolation qualifiers are mixed at one location")
17873 /** Source for given test case and stage
17875 * @param test_case_index Index of test case
17876 * @param stage Shader stage
17878 * @return Shader source
17880 std::string VaryingLocationAliasingWithMixedInterpolationTest::getShaderSource(GLuint test_case_index,
17881 Utils::Shader::STAGES stage)
17883 static const GLchar* var_definition =
17884 "layout (location = 1, component = COMPONENT) INTERPOLATION DIRECTION TYPE gohanARRAY;\n"
17885 "layout (location = 1, component = COMPONENT) INTERPOLATION DIRECTION TYPE gotenARRAY;\n";
17886 static const GLchar* input_use = " if ((TYPE(0) == gohanINDEX) &&\n"
17887 " (TYPE(1) == gotenINDEX) )\n"
17889 " result += vec4(1, 0.5, 0.25, 0.125);\n"
17891 static const GLchar* output_use = " gohanINDEX = TYPE(0);\n"
17892 " gotenINDEX = TYPE(1);\n"
17893 " if (vec4(0) == result)\n"
17895 " gohanINDEX = TYPE(1);\n"
17896 " gotenINDEX = TYPE(0);\n"
17898 static const GLchar* fs = "#version 430 core\n"
17899 "#extension GL_ARB_enhanced_layouts : require\n"
17902 "out vec4 fs_out;\n"
17906 " fs_out = gs_fs;\n"
17909 static const GLchar* fs_tested = "#version 430 core\n"
17910 "#extension GL_ARB_enhanced_layouts : require\n"
17915 "out vec4 fs_out;\n"
17919 " vec4 result = gs_fs;\n"
17923 " fs_out = result;\n"
17926 static const GLchar* gs = "#version 430 core\n"
17927 "#extension GL_ARB_enhanced_layouts : require\n"
17929 "layout(points) in;\n"
17930 "layout(triangle_strip, max_vertices = 4) out;\n"
17932 "in vec4 tes_gs[];\n"
17933 "out vec4 gs_fs;\n"
17937 " gs_fs = tes_gs[0];\n"
17938 " gl_Position = vec4(-1, -1, 0, 1);\n"
17940 " gs_fs = tes_gs[0];\n"
17941 " gl_Position = vec4(-1, 1, 0, 1);\n"
17943 " gs_fs = tes_gs[0];\n"
17944 " gl_Position = vec4(1, -1, 0, 1);\n"
17946 " gs_fs = tes_gs[0];\n"
17947 " gl_Position = vec4(1, 1, 0, 1);\n"
17951 static const GLchar* gs_tested = "#version 430 core\n"
17952 "#extension GL_ARB_enhanced_layouts : require\n"
17954 "layout(points) in;\n"
17955 "layout(triangle_strip, max_vertices = 4) out;\n"
17959 "in vec4 tes_gs[];\n"
17960 "out vec4 gs_fs;\n"
17964 " vec4 result = tes_gs[0];\n"
17968 " gs_fs = result;\n"
17969 " gl_Position = vec4(-1, -1, 0, 1);\n"
17971 " gs_fs = result;\n"
17972 " gl_Position = vec4(-1, 1, 0, 1);\n"
17974 " gs_fs = result;\n"
17975 " gl_Position = vec4(1, -1, 0, 1);\n"
17977 " gs_fs = result;\n"
17978 " gl_Position = vec4(1, 1, 0, 1);\n"
17982 static const GLchar* tcs = "#version 430 core\n"
17983 "#extension GL_ARB_enhanced_layouts : require\n"
17985 "layout(vertices = 1) out;\n"
17987 "in vec4 vs_tcs[];\n"
17988 "out vec4 tcs_tes[];\n"
17993 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
17995 " gl_TessLevelOuter[0] = 1.0;\n"
17996 " gl_TessLevelOuter[1] = 1.0;\n"
17997 " gl_TessLevelOuter[2] = 1.0;\n"
17998 " gl_TessLevelOuter[3] = 1.0;\n"
17999 " gl_TessLevelInner[0] = 1.0;\n"
18000 " gl_TessLevelInner[1] = 1.0;\n"
18003 static const GLchar* tcs_tested = "#version 430 core\n"
18004 "#extension GL_ARB_enhanced_layouts : require\n"
18006 "layout(vertices = 1) out;\n"
18010 "in vec4 vs_tcs[];\n"
18011 "out vec4 tcs_tes[];\n"
18015 " vec4 result = vs_tcs[gl_InvocationID];\n"
18019 " tcs_tes[gl_InvocationID] = result;\n"
18021 " gl_TessLevelOuter[0] = 1.0;\n"
18022 " gl_TessLevelOuter[1] = 1.0;\n"
18023 " gl_TessLevelOuter[2] = 1.0;\n"
18024 " gl_TessLevelOuter[3] = 1.0;\n"
18025 " gl_TessLevelInner[0] = 1.0;\n"
18026 " gl_TessLevelInner[1] = 1.0;\n"
18029 static const GLchar* tes = "#version 430 core\n"
18030 "#extension GL_ARB_enhanced_layouts : require\n"
18032 "layout(isolines, point_mode) in;\n"
18034 "in vec4 tcs_tes[];\n"
18035 "out vec4 tes_gs;\n"
18039 " tes_gs = tcs_tes[0];\n"
18042 static const GLchar* tes_tested = "#version 430 core\n"
18043 "#extension GL_ARB_enhanced_layouts : require\n"
18045 "layout(isolines, point_mode) in;\n"
18049 "in vec4 tcs_tes[];\n"
18050 "out vec4 tes_gs;\n"
18054 " vec4 result = tcs_tes[0];\n"
18058 " tes_gs += result;\n"
18061 static const GLchar* vs = "#version 430 core\n"
18062 "#extension GL_ARB_enhanced_layouts : require\n"
18065 "out vec4 vs_tcs;\n"
18069 " vs_tcs = in_vs;\n"
18072 static const GLchar* vs_tested = "#version 430 core\n"
18073 "#extension GL_ARB_enhanced_layouts : require\n"
18078 "out vec4 vs_tcs;\n"
18082 " vec4 result = in_vs;\n"
18086 " vs_tcs += result;\n"
18090 std::string source;
18091 testCase& test_case = m_test_cases[test_case_index];
18093 if (test_case.m_stage == stage)
18095 const GLchar* array = "";
18096 GLchar buffer_gohan[16];
18097 GLchar buffer_goten[16];
18098 const GLchar* direction = "in ";
18099 const GLchar* index = "";
18100 const GLchar* int_gohan = getInterpolationQualifier(test_case.m_interpolation_gohan);
18101 const GLchar* int_goten = getInterpolationQualifier(test_case.m_interpolation_goten);
18102 size_t position = 0;
18104 const GLchar* type_gohan_name = test_case.m_type_gohan.GetGLSLTypeName();
18105 const GLchar* type_goten_name = test_case.m_type_goten.GetGLSLTypeName();
18106 const GLchar* var_use = input_use;
18108 if (false == test_case.m_is_input)
18112 var_use = output_use;
18115 sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
18116 sprintf(buffer_goten, "%d", test_case.m_component_goten);
18120 case Utils::Shader::FRAGMENT:
18121 source = fs_tested;
18123 case Utils::Shader::GEOMETRY:
18124 source = gs_tested;
18128 case Utils::Shader::TESS_CTRL:
18129 source = tcs_tested;
18131 index = "[gl_InvocationID]";
18133 case Utils::Shader::TESS_EVAL:
18134 source = tes_tested;
18138 case Utils::Shader::VERTEX:
18139 source = vs_tested;
18142 TCU_FAIL("Invalid enum");
18146 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
18148 Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
18149 Utils::replaceToken("INTERPOLATION", position, int_gohan, source);
18150 Utils::replaceToken("DIRECTION", position, direction, source);
18151 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18152 Utils::replaceToken("ARRAY", position, array, source);
18153 Utils::replaceToken("COMPONENT", position, buffer_goten, source);
18154 Utils::replaceToken("INTERPOLATION", position, int_goten, source);
18155 Utils::replaceToken("DIRECTION", position, direction, source);
18156 Utils::replaceToken("TYPE", position, type_goten_name, source);
18157 Utils::replaceToken("ARRAY", position, array, source);
18160 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
18162 if (true == test_case.m_is_input)
18164 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18165 Utils::replaceToken("TYPE", position, type_goten_name, source);
18169 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18170 Utils::replaceToken("TYPE", position, type_goten_name, source);
18171 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18172 Utils::replaceToken("TYPE", position, type_goten_name, source);
18175 Utils::replaceAllTokens("INDEX", index, source);
18181 case Utils::Shader::FRAGMENT:
18184 case Utils::Shader::GEOMETRY:
18187 case Utils::Shader::TESS_CTRL:
18190 case Utils::Shader::TESS_EVAL:
18193 case Utils::Shader::VERTEX:
18197 TCU_FAIL("Invalid enum");
18204 /** Get description of test case
18206 * @param test_case_index Index of test case
18208 * @return Test case description
18210 std::string VaryingLocationAliasingWithMixedInterpolationTest::getTestCaseName(GLuint test_case_index)
18212 std::stringstream stream;
18213 testCase& test_case = m_test_cases[test_case_index];
18215 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", "
18216 << getInterpolationQualifier(test_case.m_interpolation_gohan) << " "
18217 << test_case.m_type_gohan.GetGLSLTypeName() << " at " << test_case.m_component_gohan << ", "
18218 << getInterpolationQualifier(test_case.m_interpolation_goten) << " "
18219 << test_case.m_type_goten.GetGLSLTypeName() << " at " << test_case.m_component_goten << ". Direction: ";
18221 if (true == test_case.m_is_input)
18227 stream << "output";
18230 return stream.str();
18233 /** Get number of test cases
18235 * @return Number of test cases
18237 GLuint VaryingLocationAliasingWithMixedInterpolationTest::getTestCaseNumber()
18239 return static_cast<GLuint>(m_test_cases.size());
18242 /** Selects if "compute" stage is relevant for test
18248 bool VaryingLocationAliasingWithMixedInterpolationTest::isComputeRelevant(GLuint /* test_case_index */)
18253 /** Prepare all test cases
18256 void VaryingLocationAliasingWithMixedInterpolationTest::testInit()
18258 static const GLuint n_components_per_location = 4;
18259 const GLuint n_types = getTypesNumber();
18261 for (GLuint i = 0; i < n_types; ++i)
18263 const Utils::Type& type_gohan = getType(i);
18264 const bool is_float_type_gohan = isFloatType(type_gohan);
18266 /* Skip matrices */
18267 if (1 != type_gohan.m_n_columns)
18272 for (GLuint j = 0; j < n_types; ++j)
18274 const Utils::Type& type_goten = getType(j);
18275 const bool is_float_type_goten = isFloatType(type_goten);
18277 /* Skip matrices */
18278 if (1 != type_goten.m_n_columns)
18283 /* Skip invalid combinations */
18284 if (is_float_type_gohan != is_float_type_goten)
18289 const GLuint n_req_components_gohan = type_gohan.m_n_rows;
18290 const GLuint n_req_components_goten = type_goten.m_n_rows;
18292 /* Skip pairs that cannot fit into one location */
18293 if (n_components_per_location < (n_req_components_gohan + n_req_components_goten))
18298 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
18300 /* Skip compute shader */
18301 if (Utils::Shader::COMPUTE == stage)
18306 const GLuint gohan = 0;
18307 const GLuint goten = gohan + n_req_components_gohan;
18309 for (GLuint int_gohan = 0; int_gohan < INTERPOLATION_MAX; ++int_gohan)
18311 for (GLuint int_goten = 0; int_goten < INTERPOLATION_MAX; ++int_goten)
18313 const bool is_gohan_double = (Utils::Type::Double == type_gohan.m_basic_type) ? true : false;
18314 const bool is_goten_double = (Utils::Type::Double == type_goten.m_basic_type) ? true : false;
18315 const bool is_gohan_flat = (FLAT == int_gohan) ? true : false;
18316 const bool is_goten_flat = (FLAT == int_goten) ? true : false;
18317 const bool is_gohan_accepted_as_fs_in =
18318 (is_gohan_double && is_gohan_flat) || (!is_gohan_double);
18319 const bool is_goten_accepted_as_fs_in =
18320 (is_goten_double && is_goten_flat) || (!is_goten_double);
18321 const bool is_comb_accepted_as_fs_in = is_gohan_accepted_as_fs_in && is_goten_accepted_as_fs_in;
18323 /* Skip when both are the same */
18324 if (int_gohan == int_goten)
18329 testCase test_case_in = { gohan,
18331 (INTERPOLATIONS)int_gohan,
18332 (INTERPOLATIONS)int_goten,
18334 (Utils::Shader::STAGES)stage,
18338 testCase test_case_out = { gohan,
18340 (INTERPOLATIONS)int_gohan,
18341 (INTERPOLATIONS)int_goten,
18343 (Utils::Shader::STAGES)stage,
18349 * fragment shader when not flat double is used
18351 if ((Utils::Shader::VERTEX != stage) &&
18352 ((Utils::Shader::FRAGMENT != stage) || (true == is_comb_accepted_as_fs_in)))
18354 m_test_cases.push_back(test_case_in);
18357 /* Skip outputs in fragment shader */
18358 if (Utils::Shader::FRAGMENT != stage)
18360 m_test_cases.push_back(test_case_out);
18369 /** Get interpolation qualifier
18371 * @param interpolation Enumeration
18373 * @return GLSL qualifier
18375 const GLchar* VaryingLocationAliasingWithMixedInterpolationTest::getInterpolationQualifier(INTERPOLATIONS interpolation)
18377 const GLchar* result = 0;
18379 switch (interpolation)
18387 case NO_PERSPECTIVE:
18388 result = "noperspective";
18391 TCU_FAIL("Invalid enum");
18397 /** Check if given type is float
18399 * @param type Type in question
18401 * @return true if tpye is float, false otherwise
18403 bool VaryingLocationAliasingWithMixedInterpolationTest::isFloatType(const Utils::Type& type)
18405 bool is_float = false;
18407 if ((Utils::Type::Double == type.m_basic_type) || (Utils::Type::Float == type.m_basic_type))
18417 * @param context Test framework context
18419 VaryingLocationAliasingWithMixedAuxiliaryStorageTest::VaryingLocationAliasingWithMixedAuxiliaryStorageTest(
18420 deqp::Context& context)
18421 : NegativeTestBase(
18422 context, "varying_location_aliasing_with_mixed_auxiliary_storage",
18423 "Test verifies that compiler reports error when auxiliary storage qualifiers are mixed at one location")
18427 /** Source for given test case and stage
18429 * @param test_case_index Index of test case
18430 * @param stage Shader stage
18432 * @return Shader source
18434 std::string VaryingLocationAliasingWithMixedAuxiliaryStorageTest::getShaderSource(GLuint test_case_index,
18435 Utils::Shader::STAGES stage)
18437 static const GLchar* var_definition =
18438 "layout (location = 1, component = COMPONENT) AUX INTERPOLATION DIRECTION TYPE gohanARRAY;\n"
18439 "layout (location = 1, component = COMPONENT) AUX INTERPOLATION DIRECTION TYPE gotenARRAY;\n";
18440 static const GLchar* input_use = " if ((TYPE(0) == gohanINDEX_GOHAN) &&\n"
18441 " (TYPE(1) == gotenINDEX_GOTEN) )\n"
18443 " result += vec4(1, 0.5, 0.25, 0.125);\n"
18445 static const GLchar* output_use = " gohanINDEX_GOHAN = TYPE(0);\n"
18446 " gotenINDEX_GOTEN = TYPE(1);\n"
18447 " if (vec4(0) == result)\n"
18449 " gohanINDEX_GOHAN = TYPE(1);\n"
18450 " gotenINDEX_GOTEN = TYPE(0);\n"
18452 static const GLchar* fs = "#version 430 core\n"
18453 "#extension GL_ARB_enhanced_layouts : require\n"
18456 "out vec4 fs_out;\n"
18460 " fs_out = gs_fs;\n"
18463 static const GLchar* fs_tested = "#version 430 core\n"
18464 "#extension GL_ARB_enhanced_layouts : require\n"
18469 "out vec4 fs_out;\n"
18473 " vec4 result = gs_fs;\n"
18477 " fs_out = result;\n"
18480 static const GLchar* gs = "#version 430 core\n"
18481 "#extension GL_ARB_enhanced_layouts : require\n"
18483 "layout(points) in;\n"
18484 "layout(triangle_strip, max_vertices = 4) out;\n"
18486 "in vec4 tes_gs[];\n"
18487 "out vec4 gs_fs;\n"
18491 " gs_fs = tes_gs[0];\n"
18492 " gl_Position = vec4(-1, -1, 0, 1);\n"
18494 " gs_fs = tes_gs[0];\n"
18495 " gl_Position = vec4(-1, 1, 0, 1);\n"
18497 " gs_fs = tes_gs[0];\n"
18498 " gl_Position = vec4(1, -1, 0, 1);\n"
18500 " gs_fs = tes_gs[0];\n"
18501 " gl_Position = vec4(1, 1, 0, 1);\n"
18505 static const GLchar* gs_tested = "#version 430 core\n"
18506 "#extension GL_ARB_enhanced_layouts : require\n"
18508 "layout(points) in;\n"
18509 "layout(triangle_strip, max_vertices = 4) out;\n"
18513 "in vec4 tes_gs[];\n"
18514 "out vec4 gs_fs;\n"
18518 " vec4 result = tes_gs[0];\n"
18522 " gs_fs = result;\n"
18523 " gl_Position = vec4(-1, -1, 0, 1);\n"
18525 " gs_fs = result;\n"
18526 " gl_Position = vec4(-1, 1, 0, 1);\n"
18528 " gs_fs = result;\n"
18529 " gl_Position = vec4(1, -1, 0, 1);\n"
18531 " gs_fs = result;\n"
18532 " gl_Position = vec4(1, 1, 0, 1);\n"
18536 static const GLchar* tcs = "#version 430 core\n"
18537 "#extension GL_ARB_enhanced_layouts : require\n"
18539 "layout(vertices = 1) out;\n"
18541 "in vec4 vs_tcs[];\n"
18542 "out vec4 tcs_tes[];\n"
18547 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
18549 " gl_TessLevelOuter[0] = 1.0;\n"
18550 " gl_TessLevelOuter[1] = 1.0;\n"
18551 " gl_TessLevelOuter[2] = 1.0;\n"
18552 " gl_TessLevelOuter[3] = 1.0;\n"
18553 " gl_TessLevelInner[0] = 1.0;\n"
18554 " gl_TessLevelInner[1] = 1.0;\n"
18557 static const GLchar* tcs_tested = "#version 430 core\n"
18558 "#extension GL_ARB_enhanced_layouts : require\n"
18560 "layout(vertices = 1) out;\n"
18564 "in vec4 vs_tcs[];\n"
18565 "out vec4 tcs_tes[];\n"
18569 " vec4 result = vs_tcs[gl_InvocationID];\n"
18573 " tcs_tes[gl_InvocationID] = result;\n"
18575 " gl_TessLevelOuter[0] = 1.0;\n"
18576 " gl_TessLevelOuter[1] = 1.0;\n"
18577 " gl_TessLevelOuter[2] = 1.0;\n"
18578 " gl_TessLevelOuter[3] = 1.0;\n"
18579 " gl_TessLevelInner[0] = 1.0;\n"
18580 " gl_TessLevelInner[1] = 1.0;\n"
18583 static const GLchar* tes = "#version 430 core\n"
18584 "#extension GL_ARB_enhanced_layouts : require\n"
18586 "layout(isolines, point_mode) in;\n"
18588 "in vec4 tcs_tes[];\n"
18589 "out vec4 tes_gs;\n"
18593 " tes_gs = tcs_tes[0];\n"
18596 static const GLchar* tes_tested = "#version 430 core\n"
18597 "#extension GL_ARB_enhanced_layouts : require\n"
18599 "layout(isolines, point_mode) in;\n"
18603 "in vec4 tcs_tes[];\n"
18604 "out vec4 tes_gs;\n"
18608 " vec4 result = tcs_tes[0];\n"
18612 " tes_gs += result;\n"
18615 static const GLchar* vs = "#version 430 core\n"
18616 "#extension GL_ARB_enhanced_layouts : require\n"
18619 "out vec4 vs_tcs;\n"
18623 " vs_tcs = in_vs;\n"
18626 static const GLchar* vs_tested = "#version 430 core\n"
18627 "#extension GL_ARB_enhanced_layouts : require\n"
18632 "out vec4 vs_tcs;\n"
18636 " vec4 result = in_vs;\n"
18640 " vs_tcs += result;\n"
18644 std::string source;
18645 testCase& test_case = m_test_cases[test_case_index];
18647 if (test_case.m_stage == stage)
18649 const GLchar* array_gohan = "";
18650 const GLchar* array_goten = "";
18651 const GLchar* aux_gohan = getAuxiliaryQualifier(test_case.m_aux_gohan);
18652 const GLchar* aux_goten = getAuxiliaryQualifier(test_case.m_aux_goten);
18653 GLchar buffer_gohan[16];
18654 GLchar buffer_goten[16];
18655 const GLchar* direction = "in ";
18656 const GLchar* index_gohan = "";
18657 const GLchar* index_goten = "";
18658 const GLchar* int_gohan = test_case.m_int_gohan;
18659 const GLchar* int_goten = test_case.m_int_goten;
18660 size_t position = 0;
18662 const GLchar* type_gohan_name = test_case.m_type_gohan.GetGLSLTypeName();
18663 const GLchar* type_goten_name = test_case.m_type_goten.GetGLSLTypeName();
18664 const GLchar* var_use = input_use;
18666 if (false == test_case.m_is_input)
18670 var_use = output_use;
18673 sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
18674 sprintf(buffer_goten, "%d", test_case.m_component_goten);
18678 case Utils::Shader::FRAGMENT:
18679 source = fs_tested;
18681 case Utils::Shader::GEOMETRY:
18682 source = gs_tested;
18683 array_gohan = "[]";
18684 index_gohan = "[0]";
18685 array_goten = "[]";
18686 index_goten = "[0]";
18688 case Utils::Shader::TESS_CTRL:
18689 source = tcs_tested;
18690 if (PATCH != test_case.m_aux_gohan)
18692 array_gohan = "[]";
18693 index_gohan = "[gl_InvocationID]";
18695 if (PATCH != test_case.m_aux_goten)
18697 array_goten = "[]";
18698 index_goten = "[gl_InvocationID]";
18701 case Utils::Shader::TESS_EVAL:
18702 source = tes_tested;
18703 array_gohan = "[]";
18704 index_gohan = "[0]";
18705 array_goten = "[]";
18706 index_goten = "[0]";
18708 case Utils::Shader::VERTEX:
18709 source = vs_tested;
18712 TCU_FAIL("Invalid enum");
18716 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
18718 Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
18719 Utils::replaceToken("AUX", position, aux_gohan, source);
18720 Utils::replaceToken("INTERPOLATION", position, int_gohan, source);
18721 Utils::replaceToken("DIRECTION", position, direction, source);
18722 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18723 Utils::replaceToken("ARRAY", position, array_gohan, source);
18724 Utils::replaceToken("COMPONENT", position, buffer_goten, source);
18725 Utils::replaceToken("AUX", position, aux_goten, source);
18726 Utils::replaceToken("INTERPOLATION", position, int_goten, source);
18727 Utils::replaceToken("DIRECTION", position, direction, source);
18728 Utils::replaceToken("TYPE", position, type_goten_name, source);
18729 Utils::replaceToken("ARRAY", position, array_goten, source);
18732 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
18734 if (true == test_case.m_is_input)
18736 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18737 Utils::replaceToken("TYPE", position, type_goten_name, source);
18741 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18742 Utils::replaceToken("TYPE", position, type_goten_name, source);
18743 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18744 Utils::replaceToken("TYPE", position, type_goten_name, source);
18747 Utils::replaceAllTokens("INDEX_GOHAN", index_gohan, source);
18748 Utils::replaceAllTokens("INDEX_GOTEN", index_goten, source);
18754 case Utils::Shader::FRAGMENT:
18757 case Utils::Shader::GEOMETRY:
18760 case Utils::Shader::TESS_CTRL:
18763 case Utils::Shader::TESS_EVAL:
18766 case Utils::Shader::VERTEX:
18770 TCU_FAIL("Invalid enum");
18777 /** Get description of test case
18779 * @param test_case_index Index of test case
18781 * @return Test case description
18783 std::string VaryingLocationAliasingWithMixedAuxiliaryStorageTest::getTestCaseName(GLuint test_case_index)
18785 std::stringstream stream;
18786 testCase& test_case = m_test_cases[test_case_index];
18788 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", "
18789 << getAuxiliaryQualifier(test_case.m_aux_gohan) << " " << test_case.m_type_gohan.GetGLSLTypeName() << " at "
18790 << test_case.m_component_gohan << ", " << getAuxiliaryQualifier(test_case.m_aux_goten) << " "
18791 << test_case.m_type_goten.GetGLSLTypeName() << " at " << test_case.m_component_goten << ". Direction: ";
18793 if (true == test_case.m_is_input)
18799 stream << "output";
18802 return stream.str();
18805 /** Get number of test cases
18807 * @return Number of test cases
18809 GLuint VaryingLocationAliasingWithMixedAuxiliaryStorageTest::getTestCaseNumber()
18811 return static_cast<GLuint>(m_test_cases.size());
18814 /** Selects if "compute" stage is relevant for test
18820 bool VaryingLocationAliasingWithMixedAuxiliaryStorageTest::isComputeRelevant(GLuint /* test_case_index */)
18825 /** Prepare all test cases
18828 void VaryingLocationAliasingWithMixedAuxiliaryStorageTest::testInit()
18830 static const GLuint n_components_per_location = 4;
18831 const GLuint n_types = getTypesNumber();
18833 for (GLuint i = 0; i < n_types; ++i)
18835 const Utils::Type& type_gohan = getType(i);
18836 const bool is_float_type_gohan = isFloatType(type_gohan);
18838 /* Skip matrices */
18839 if (1 != type_gohan.m_n_columns)
18844 for (GLuint j = 0; j < n_types; ++j)
18846 const Utils::Type& type_goten = getType(j);
18847 const bool is_flat_req_gohan = (Utils::Type::Float == type_gohan.m_basic_type) ? false : true;
18848 const bool is_flat_req_goten = (Utils::Type::Float == type_goten.m_basic_type) ? false : true;
18849 const bool is_float_type_goten = isFloatType(type_goten);
18851 /* Skip matrices */
18852 if (1 != type_goten.m_n_columns)
18857 /* Skip invalid combinations */
18858 if (is_float_type_gohan != is_float_type_goten)
18863 const GLuint n_req_components_gohan = type_gohan.m_n_rows;
18864 const GLuint n_req_components_goten = type_goten.m_n_rows;
18866 /* Skip pairs that cannot fit into one location */
18867 if (n_components_per_location < (n_req_components_gohan + n_req_components_goten))
18872 const GLuint gohan = 0;
18873 const GLuint goten = gohan + n_req_components_gohan;
18875 const GLchar* fs_int_gohan = is_flat_req_gohan ? "flat" : "";
18876 const GLchar* fs_int_goten = is_flat_req_goten ? "flat" : "";
18878 testCase test_case_tcs_np = { gohan, goten, NONE, PATCH, "", "", false, Utils::Shader::TESS_CTRL,
18879 type_gohan, type_goten };
18881 testCase test_case_tcs_pn = { gohan, goten, PATCH, NONE, "", "", false, Utils::Shader::TESS_CTRL,
18882 type_gohan, type_goten };
18884 testCase test_case_tes_np = { gohan, goten, NONE, PATCH, "", "", true, Utils::Shader::TESS_EVAL,
18885 type_gohan, type_goten };
18887 testCase test_case_tes_pn = { gohan, goten, PATCH, NONE, "", "", true, Utils::Shader::TESS_EVAL,
18888 type_gohan, type_goten };
18890 testCase test_case_fs_nc = { gohan, goten, NONE, CENTROID,
18891 fs_int_gohan, fs_int_goten, true, Utils::Shader::FRAGMENT,
18892 type_gohan, type_goten };
18894 testCase test_case_fs_cn = { gohan, goten, CENTROID, NONE,
18895 fs_int_gohan, fs_int_goten, true, Utils::Shader::FRAGMENT,
18896 type_gohan, type_goten };
18898 testCase test_case_fs_ns = { gohan, goten, NONE, SAMPLE,
18899 fs_int_gohan, fs_int_goten, true, Utils::Shader::FRAGMENT,
18900 type_gohan, type_goten };
18902 testCase test_case_fs_sn = { gohan, goten, SAMPLE, NONE,
18903 fs_int_gohan, fs_int_goten, true, Utils::Shader::FRAGMENT,
18904 type_gohan, type_goten };
18906 testCase test_case_fs_cs = { gohan, goten, CENTROID, SAMPLE,
18907 fs_int_gohan, fs_int_goten, true, Utils::Shader::FRAGMENT,
18908 type_gohan, type_goten };
18910 testCase test_case_fs_sc = { gohan, goten, SAMPLE, CENTROID,
18911 fs_int_gohan, fs_int_goten, true, Utils::Shader::FRAGMENT,
18912 type_gohan, type_goten };
18914 m_test_cases.push_back(test_case_tcs_np);
18915 m_test_cases.push_back(test_case_tcs_pn);
18916 m_test_cases.push_back(test_case_tes_np);
18917 m_test_cases.push_back(test_case_tes_pn);
18918 m_test_cases.push_back(test_case_fs_nc);
18919 m_test_cases.push_back(test_case_fs_cn);
18920 m_test_cases.push_back(test_case_fs_ns);
18921 m_test_cases.push_back(test_case_fs_sn);
18922 m_test_cases.push_back(test_case_fs_cs);
18923 m_test_cases.push_back(test_case_fs_sc);
18928 /** Get auxiliary storage qualifier
18930 * @param aux Enumeration
18932 * @return GLSL qualifier
18934 const GLchar* VaryingLocationAliasingWithMixedAuxiliaryStorageTest::getAuxiliaryQualifier(AUXILIARIES aux)
18936 const GLchar* result = 0;
18947 result = "centroid";
18953 TCU_FAIL("Invalid enum");
18959 /** Check if given type is float
18961 * @param type Type in question
18963 * @return true if tpye is float, false otherwise
18965 bool VaryingLocationAliasingWithMixedAuxiliaryStorageTest::isFloatType(const Utils::Type& type)
18967 bool is_float = false;
18969 if ((Utils::Type::Double == type.m_basic_type) || (Utils::Type::Float == type.m_basic_type))
18977 /* Constants used by VertexAttribLocationAPITest */
18978 const GLuint VertexAttribLocationAPITest::m_goten_location = 6;
18982 * @param context Test framework context
18984 VertexAttribLocationAPITest::VertexAttribLocationAPITest(deqp::Context& context)
18985 : TextureTestBase(context, "vertex_attrib_location_api",
18986 "Test verifies that attribute locations API works as expected")
18990 /** Does BindAttribLocation for "goten" and relink program
18992 * @param program Program object
18993 * @param program_interface Interface of program
18995 void VertexAttribLocationAPITest::prepareAttribLocation(Utils::Program& program,
18996 Utils::ProgramInterface& program_interface)
18998 const Functions& gl = m_context.getRenderContext().getFunctions();
19000 gl.bindAttribLocation(program.m_id, m_goten_location, "goten");
19001 GLU_EXPECT_NO_ERROR(gl.getError(), "BindAttribLocation");
19003 program.Link(gl, program.m_id);
19005 /* We still need to get locations for gohan and chichi */
19006 TextureTestBase::prepareAttribLocation(program, program_interface);
19009 /** Get interface of program
19012 * @param program_interface Interface of program
19015 void VertexAttribLocationAPITest::getProgramInterface(GLuint /* test_case_index */,
19016 Utils::ProgramInterface& program_interface,
19017 Utils::VaryingPassthrough& /* varying_passthrough */)
19019 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
19020 const Utils::Type& type = Utils::Type::vec4;
19021 const GLuint type_size = type.GetSize();
19024 const GLuint chichi_offset = 0;
19025 const GLuint goten_offset = chichi_offset + type_size;
19026 const GLuint gohan_offset = goten_offset + type_size;
19027 const GLuint goku_offset = gohan_offset + type_size;
19030 const GLuint goku_location = 2;
19031 const GLuint goten_location = m_goten_location;
19033 /* Generate data */
19034 m_goku_data = type.GenerateDataPacked();
19035 m_gohan_data = type.GenerateDataPacked();
19036 m_goten_data = type.GenerateDataPacked();
19037 m_chichi_data = type.GenerateDataPacked();
19040 si.m_globals = "const uint GOKU_LOCATION = 2;\n";
19043 si.Input("goku" /* name */, "layout (location = GOKU_LOCATION)" /* qualifiers */, 0 /* expected_componenet */,
19044 goku_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19045 0u /* n_array_elements */, 0u /* stride */, goku_offset /* offset */, (GLvoid*)&m_goku_data[0] /* data */,
19046 m_goku_data.size() /* data_size */);
19048 si.Input("gohan" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19049 Utils::Variable::m_automatic_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19050 0u /* n_array_elements */, 0u /* stride */, gohan_offset /* offset */,
19051 (GLvoid*)&m_gohan_data[0] /* data */, m_gohan_data.size() /* data_size */);
19053 si.Input("goten" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19054 goten_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19055 0u /* n_array_elements */, 0u /* stride */, goten_offset /* offset */,
19056 (GLvoid*)&m_goten_data[0] /* data */, m_goten_data.size() /* data_size */);
19058 si.Input("chichi" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19059 Utils::Variable::m_automatic_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19060 0u /* n_array_elements */, 0u /* stride */, chichi_offset /* offset */,
19061 (GLvoid*)&m_chichi_data[0] /* data */, m_chichi_data.size() /* data_size */);
19064 /** Selects if "compute" stage is relevant for test
19070 bool VertexAttribLocationAPITest::isComputeRelevant(GLuint /* test_case_index */)
19075 /* Constants used by FragmentDataLocationAPITest */
19076 const GLuint FragmentDataLocationAPITest::m_goten_location = 6;
19080 * @param context Test framework context
19082 FragmentDataLocationAPITest::FragmentDataLocationAPITest(deqp::Context& context)
19083 : TextureTestBase(context, "fragment_data_location_api",
19084 "Test verifies that fragment data locations API works as expected")
19088 , m_chichi(context)
19092 /** Verifies contents of drawn images
19097 * @return true if images are filled with expected values, false otherwise
19099 bool FragmentDataLocationAPITest::checkResults(glw::GLuint /* test_case_index */, Utils::Texture& /* color_0 */)
19101 static const GLuint size = m_width * m_height;
19102 static const GLuint expected_goku = 0xff000000;
19103 static const GLuint expected_gohan = 0xff0000ff;
19104 static const GLuint expected_goten = 0xff00ff00;
19105 static const GLuint expected_chichi = 0xffff0000;
19107 std::vector<GLuint> data;
19110 m_goku.Get(GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
19112 for (GLuint i = 0; i < size; ++i)
19114 const GLuint color = data[i];
19116 if (expected_goku != color)
19118 m_context.getTestContext().getLog() << tcu::TestLog::Message << "RGBA8[" << i << "]:" << color
19119 << tcu::TestLog::EndMessage;
19124 m_gohan.Get(GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
19126 for (GLuint i = 0; i < size; ++i)
19128 const GLuint color = data[i];
19130 if (expected_gohan != color)
19132 m_context.getTestContext().getLog() << tcu::TestLog::Message << "RGBA8[" << i << "]:" << color
19133 << tcu::TestLog::EndMessage;
19138 m_goten.Get(GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
19140 for (GLuint i = 0; i < size; ++i)
19142 const GLuint color = data[i];
19144 if (expected_goten != color)
19146 m_context.getTestContext().getLog() << tcu::TestLog::Message << "RGBA8[" << i << "]:" << color
19147 << tcu::TestLog::EndMessage;
19152 m_chichi.Get(GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
19154 for (GLuint i = 0; i < size; ++i)
19156 const GLuint color = data[i];
19158 if (expected_chichi != color)
19160 m_context.getTestContext().getLog() << tcu::TestLog::Message << "RGBA8[" << i << "]:" << color
19161 << tcu::TestLog::EndMessage;
19169 /** Prepare code snippet that will set out variables
19173 * @param stage Shader stage
19175 * @return Code that pass in variables to next stage
19177 std::string FragmentDataLocationAPITest::getPassSnippet(GLuint /* test_case_index */,
19178 Utils::VaryingPassthrough& /* varying_passthrough */,
19179 Utils::Shader::STAGES stage)
19181 std::string result;
19183 /* Skip for compute shader */
19184 if (Utils::Shader::FRAGMENT != stage)
19190 result = "chichi = vec4(0, 0, 1, 1);\n"
19191 " goku = vec4(0, 0, 0, 1);\n"
19192 " goten = vec4(0, 1, 0, 1);\n"
19193 " gohan = vec4(1, 0, 0, 1);\n";
19199 /** Get interface of program
19202 * @param program_interface Interface of program
19205 void FragmentDataLocationAPITest::getProgramInterface(GLuint /* test_case_index */,
19206 Utils::ProgramInterface& program_interface,
19207 Utils::VaryingPassthrough& /* varying_passthrough */)
19209 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
19210 const Utils::Type& type = Utils::Type::vec4;
19213 m_goku_location = 2;
19216 si.m_globals = "const uint GOKU_LOCATION = 2;\n";
19219 si.Output("goku" /* name */, "layout (location = GOKU_LOCATION)" /* qualifiers */, 0 /* expected_componenet */,
19220 m_goku_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19221 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)0 /* data */, 0u /* data_size */);
19223 si.Output("gohan" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19224 Utils::Variable::m_automatic_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19225 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)0 /* data */, 0u /* data_size */);
19227 si.Output("goten" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19228 m_goten_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19229 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)0 /* data */, 0u /* data_size */);
19231 si.Output("chichi" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19232 Utils::Variable::m_automatic_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19233 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)0 /* data */, 0u /* data_size */);
19236 /** Selects if "compute" stage is relevant for test
19242 bool FragmentDataLocationAPITest::isComputeRelevant(GLuint /* test_case_index */)
19247 /** Get locations for all outputs with automatic_location
19249 * @param program Program object
19250 * @param program_interface Interface of program
19252 void FragmentDataLocationAPITest::prepareFragmentDataLoc(Utils::Program& program,
19253 Utils::ProgramInterface& program_interface)
19255 /* Bind location of goten */
19256 const Functions& gl = m_context.getRenderContext().getFunctions();
19258 gl.bindFragDataLocation(program.m_id, m_goten_location, "goten");
19259 GLU_EXPECT_NO_ERROR(gl.getError(), "BindFragDataLocation");
19261 program.Link(gl, program.m_id);
19263 /* Prepare locations for gohan and chichi */
19264 TextureTestBase::prepareFragmentDataLoc(program, program_interface);
19266 /* Get all locations */
19267 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
19269 Utils::Variable::PtrVector& outputs = si.m_outputs;
19271 for (Utils::Variable::PtrVector::iterator it = outputs.begin(); outputs.end() != it; ++it)
19273 const Utils::Variable::Descriptor& desc = (*it)->m_descriptor;
19275 if (0 == desc.m_name.compare("gohan"))
19277 m_gohan_location = desc.m_expected_location;
19279 else if (0 == desc.m_name.compare("chichi"))
19281 m_chichi_location = desc.m_expected_location;
19284 /* Locations of goku and goten are fixed */
19288 /** Prepare framebuffer with single texture as color attachment
19290 * @param framebuffer Framebuffer
19291 * @param color_0_texture Texture that will used as color attachment
19293 void FragmentDataLocationAPITest::prepareFramebuffer(Utils::Framebuffer& framebuffer, Utils::Texture& color_0_texture)
19295 /* Let parent prepare its stuff */
19296 TextureTestBase::prepareFramebuffer(framebuffer, color_0_texture);
19299 std::vector<GLuint> texture_data;
19300 texture_data.resize(m_width * m_height);
19302 for (GLuint i = 0; i < texture_data.size(); ++i)
19304 texture_data[i] = 0x20406080;
19307 /* Prepare textures */
19308 m_goku.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]);
19310 m_gohan.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]);
19312 m_goten.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]);
19314 m_chichi.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]);
19316 /* Attach textures to framebuffer */
19317 framebuffer.Bind();
19318 framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0 + m_goku_location, m_goku.m_id, m_width, m_height);
19319 framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0 + m_gohan_location, m_gohan.m_id, m_width, m_height);
19320 framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0 + m_goten_location, m_goten.m_id, m_width, m_height);
19321 framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0 + m_chichi_location, m_chichi.m_id, m_width, m_height);
19323 /* Set up drawbuffers */
19324 const Functions& gl = m_context.getRenderContext().getFunctions();
19325 // 1. There are only 4 outputs in fragment shader, so only need to do buffer mapping for 4 attachments,
19326 // 2. another issue is each output variable has a location, it is the fragment color index, so the index of
19327 // GL_COLOR_ATTACHMENT in glDrawBuffers() should keep the same with the location, to make test correct,
19328 // we needt to change the above code of glDrawBuffers() as :
19329 GLint buffers_size = 4;
19330 GLenum buffers[] = { GLenum(GL_COLOR_ATTACHMENT0 + m_chichi_location),
19331 GLenum(GL_COLOR_ATTACHMENT0 + m_goku_location),
19332 GLenum(GL_COLOR_ATTACHMENT0 + m_goten_location),
19333 GLenum(GL_COLOR_ATTACHMENT0 + m_gohan_location) };
19334 gl.drawBuffers(buffers_size, buffers);
19335 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawBuffers");
19340 * @param context Test framework context
19342 XFBInputTest::XFBInputTest(deqp::Context& context)
19343 : NegativeTestBase(context, "xfb_input",
19344 "Test verifies that compiler reports error when xfb qualifiers are used with input")
19348 /** Source for given test case and stage
19350 * @param test_case_index Index of test case
19351 * @param stage Shader stage
19353 * @return Shader source
19355 std::string XFBInputTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
19357 static const GLchar* buffer_var_definition = "layout (xfb_buffer = 2) in vec4 gohanARRAY;\n";
19358 static const GLchar* offset_var_definition = "layout (xfb_offset = 16) in vec4 gohanARRAY;\n";
19359 static const GLchar* stride_var_definition = "layout (xfb_stride = 32) in vec4 gohanARRAY;\n";
19360 static const GLchar* input_use = " result += gohanINDEX;\n";
19361 static const GLchar* fs = "#version 430 core\n"
19362 "#extension GL_ARB_enhanced_layouts : require\n"
19365 "out vec4 fs_out;\n"
19369 " fs_out = gs_fs;\n"
19372 static const GLchar* fs_tested = "#version 430 core\n"
19373 "#extension GL_ARB_enhanced_layouts : require\n"
19378 "out vec4 fs_out;\n"
19382 " vec4 result = gs_fs;\n"
19386 " fs_out = result;\n"
19389 static const GLchar* gs = "#version 430 core\n"
19390 "#extension GL_ARB_enhanced_layouts : require\n"
19392 "layout(points) in;\n"
19393 "layout(triangle_strip, max_vertices = 4) out;\n"
19395 "in vec4 tes_gs[];\n"
19396 "out vec4 gs_fs;\n"
19400 " gs_fs = tes_gs[0];\n"
19401 " gl_Position = vec4(-1, -1, 0, 1);\n"
19403 " gs_fs = tes_gs[0];\n"
19404 " gl_Position = vec4(-1, 1, 0, 1);\n"
19406 " gs_fs = tes_gs[0];\n"
19407 " gl_Position = vec4(1, -1, 0, 1);\n"
19409 " gs_fs = tes_gs[0];\n"
19410 " gl_Position = vec4(1, 1, 0, 1);\n"
19414 static const GLchar* gs_tested = "#version 430 core\n"
19415 "#extension GL_ARB_enhanced_layouts : require\n"
19417 "layout(points) in;\n"
19418 "layout(triangle_strip, max_vertices = 4) out;\n"
19422 "in vec4 tes_gs[];\n"
19423 "out vec4 gs_fs;\n"
19427 " vec4 result = tes_gs[0];\n"
19431 " gs_fs = result;\n"
19432 " gl_Position = vec4(-1, -1, 0, 1);\n"
19434 " gs_fs = result;\n"
19435 " gl_Position = vec4(-1, 1, 0, 1);\n"
19437 " gs_fs = result;\n"
19438 " gl_Position = vec4(1, -1, 0, 1);\n"
19440 " gs_fs = result;\n"
19441 " gl_Position = vec4(1, 1, 0, 1);\n"
19445 static const GLchar* tcs = "#version 430 core\n"
19446 "#extension GL_ARB_enhanced_layouts : require\n"
19448 "layout(vertices = 1) out;\n"
19450 "in vec4 vs_tcs[];\n"
19451 "out vec4 tcs_tes[];\n"
19456 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
19458 " gl_TessLevelOuter[0] = 1.0;\n"
19459 " gl_TessLevelOuter[1] = 1.0;\n"
19460 " gl_TessLevelOuter[2] = 1.0;\n"
19461 " gl_TessLevelOuter[3] = 1.0;\n"
19462 " gl_TessLevelInner[0] = 1.0;\n"
19463 " gl_TessLevelInner[1] = 1.0;\n"
19466 static const GLchar* tcs_tested = "#version 430 core\n"
19467 "#extension GL_ARB_enhanced_layouts : require\n"
19469 "layout(vertices = 1) out;\n"
19473 "in vec4 vs_tcs[];\n"
19474 "out vec4 tcs_tes[];\n"
19478 " vec4 result = vs_tcs[gl_InvocationID];\n"
19482 " tcs_tes[gl_InvocationID] = result;\n"
19484 " gl_TessLevelOuter[0] = 1.0;\n"
19485 " gl_TessLevelOuter[1] = 1.0;\n"
19486 " gl_TessLevelOuter[2] = 1.0;\n"
19487 " gl_TessLevelOuter[3] = 1.0;\n"
19488 " gl_TessLevelInner[0] = 1.0;\n"
19489 " gl_TessLevelInner[1] = 1.0;\n"
19492 static const GLchar* tes = "#version 430 core\n"
19493 "#extension GL_ARB_enhanced_layouts : require\n"
19495 "layout(isolines, point_mode) in;\n"
19497 "in vec4 tcs_tes[];\n"
19498 "out vec4 tes_gs;\n"
19502 " tes_gs = tcs_tes[0];\n"
19505 static const GLchar* tes_tested = "#version 430 core\n"
19506 "#extension GL_ARB_enhanced_layouts : require\n"
19508 "layout(isolines, point_mode) in;\n"
19512 "in vec4 tcs_tes[];\n"
19513 "out vec4 tes_gs;\n"
19517 " vec4 result = tcs_tes[0];\n"
19521 " tes_gs += result;\n"
19524 static const GLchar* vs = "#version 430 core\n"
19525 "#extension GL_ARB_enhanced_layouts : require\n"
19528 "out vec4 vs_tcs;\n"
19532 " vs_tcs = in_vs;\n"
19535 static const GLchar* vs_tested = "#version 430 core\n"
19536 "#extension GL_ARB_enhanced_layouts : require\n"
19541 "out vec4 vs_tcs;\n"
19545 " vec4 result = in_vs;\n"
19549 " vs_tcs += result;\n"
19553 std::string source;
19554 testCase& test_case = m_test_cases[test_case_index];
19556 if (test_case.m_stage == stage)
19558 const GLchar* array = "";
19559 const GLchar* index = "";
19560 size_t position = 0;
19562 const GLchar* var_definition = 0;
19563 const GLchar* var_use = input_use;
19565 switch (test_case.m_qualifier)
19568 var_definition = buffer_var_definition;
19571 var_definition = offset_var_definition;
19574 var_definition = stride_var_definition;
19577 TCU_FAIL("Invalid enum");
19582 case Utils::Shader::FRAGMENT:
19583 source = fs_tested;
19585 case Utils::Shader::GEOMETRY:
19586 source = gs_tested;
19590 case Utils::Shader::TESS_CTRL:
19591 source = tcs_tested;
19593 index = "[gl_InvocationID]";
19595 case Utils::Shader::TESS_EVAL:
19596 source = tes_tested;
19600 case Utils::Shader::VERTEX:
19601 source = vs_tested;
19604 TCU_FAIL("Invalid enum");
19608 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
19610 Utils::replaceToken("ARRAY", position, array, source);
19611 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
19613 Utils::replaceAllTokens("INDEX", index, source);
19619 case Utils::Shader::FRAGMENT:
19622 case Utils::Shader::GEOMETRY:
19625 case Utils::Shader::TESS_CTRL:
19628 case Utils::Shader::TESS_EVAL:
19631 case Utils::Shader::VERTEX:
19635 TCU_FAIL("Invalid enum");
19642 /** Get description of test case
19644 * @param test_case_index Index of test case
19646 * @return Test case description
19648 std::string XFBInputTest::getTestCaseName(GLuint test_case_index)
19650 std::stringstream stream;
19651 testCase& test_case = m_test_cases[test_case_index];
19653 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", qualifier: ";
19655 switch (test_case.m_qualifier)
19658 stream << "xfb_buffer";
19661 stream << "xfb_offset";
19664 stream << "xfb_stride";
19667 TCU_FAIL("Invalid enum");
19670 return stream.str();
19673 /** Get number of test cases
19675 * @return Number of test cases
19677 GLuint XFBInputTest::getTestCaseNumber()
19679 return static_cast<GLuint>(m_test_cases.size());
19682 /** Selects if "compute" stage is relevant for test
19688 bool XFBInputTest::isComputeRelevant(GLuint /* test_case_index */)
19693 /** Prepare all test cases
19696 void XFBInputTest::testInit()
19698 for (GLuint qualifier = 0; qualifier < QUALIFIERS_MAX; ++qualifier)
19700 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
19702 if (Utils::Shader::COMPUTE == stage)
19707 testCase test_case = { (QUALIFIERS)qualifier, (Utils::Shader::STAGES)stage };
19709 m_test_cases.push_back(test_case);
19714 /* Constants used by XFBAllStagesTest */
19715 const GLuint XFBAllStagesTest::m_gs_index = 3;
19719 * @param context Test context
19721 XFBAllStagesTest::XFBAllStagesTest(deqp::Context& context)
19722 : BufferTestBase(context, "xfb_all_stages",
19723 "Test verifies that only last stage in vertex processing can output to transform feedback")
19725 /* Nothing to be done here */
19728 /** Get descriptors of buffers necessary for test
19731 * @param out_descriptors Descriptors of buffers used by test
19733 void XFBAllStagesTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
19734 bufferDescriptor::Vector& out_descriptors)
19736 static const GLuint n_stages = 4;
19737 const Utils::Type& vec4 = Utils::Type::vec4;
19742 /* Test uses single uniform and xfb per stage + uniform for fragment shader */
19743 out_descriptors.resize(n_stages * 2 + 1);
19746 for (GLuint i = 0; i < n_stages; ++i)
19748 /* Get references */
19749 bufferDescriptor& uniform = out_descriptors[i + 0];
19750 bufferDescriptor& xfb = out_descriptors[i + n_stages];
19753 uniform.m_index = i;
19757 uniform.m_target = Utils::Buffer::Uniform;
19758 xfb.m_target = Utils::Buffer::Transform_feedback;
19761 const tcu::Vec4 var(Utils::GetRandFloat(), Utils::GetRandFloat(), Utils::GetRandFloat(), Utils::GetRandFloat());
19765 uniform.m_initial_data.resize(vec4.GetSize());
19766 memcpy(&uniform.m_initial_data[0], var.getPtr(), vec4.GetSize());
19768 xfb.m_initial_data = vec4.GenerateDataPacked();
19770 if (m_gs_index != i)
19772 xfb.m_expected_data = xfb.m_initial_data;
19776 xfb.m_expected_data.resize(vec4.GetSize());
19777 memcpy(&xfb.m_expected_data[0], sum.getPtr(), vec4.GetSize());
19783 /* Get reference */
19784 bufferDescriptor& uniform = out_descriptors[n_stages * 2];
19787 uniform.m_index = n_stages;
19790 uniform.m_target = Utils::Buffer::Uniform;
19793 const tcu::Vec4 var(Utils::GetRandFloat(), Utils::GetRandFloat(), Utils::GetRandFloat(), Utils::GetRandFloat());
19795 uniform.m_initial_data.resize(vec4.GetSize());
19796 memcpy(&uniform.m_initial_data[0], var.getPtr(), vec4.GetSize());
19800 /** Get body of main function for given shader stage
19803 * @param stage Shader stage
19804 * @param out_assignments Set to empty
19805 * @param out_calculations Set to empty
19807 void XFBAllStagesTest::getShaderBody(glw::GLuint /* test_case_index */, Utils::Shader::STAGES stage,
19808 std::string& out_assignments, std::string& out_calculations)
19810 out_calculations = "";
19812 static const GLchar* vs = " vs_tcs = uni_vs;\n";
19813 static const GLchar* tcs = " tcs_tes[gl_InvocationID] = uni_tcs + vs_tcs[gl_InvocationID];\n";
19814 static const GLchar* tes = " tes_gs = uni_tes + tcs_tes[0];\n";
19815 static const GLchar* gs = " gs_fs = uni_gs + tes_gs[0];\n";
19816 static const GLchar* fs = " fs_out = uni_fs + gs_fs;\n";
19818 const GLchar* assignments = 0;
19821 case Utils::Shader::FRAGMENT:
19824 case Utils::Shader::GEOMETRY:
19827 case Utils::Shader::TESS_CTRL:
19830 case Utils::Shader::TESS_EVAL:
19833 case Utils::Shader::VERTEX:
19837 TCU_FAIL("Invalid enum");
19840 out_assignments = assignments;
19843 /** Get interface of shader
19846 * @param stage Shader stage
19847 * @param out_interface Set to ""
19849 void XFBAllStagesTest::getShaderInterface(glw::GLuint /* test_case_index */, Utils::Shader::STAGES stage,
19850 std::string& out_interface)
19852 static const GLchar* vs = "layout(xfb_buffer = 0, xfb_offset = 0) out vec4 vs_tcs;\n"
19853 "layout(binding = 0) uniform vs_block {\n"
19856 static const GLchar* tcs = " in vec4 vs_tcs[];\n"
19857 "layout(xfb_buffer = 1, xfb_offset = 0) out vec4 tcs_tes[1];\n"
19858 "layout(binding = 1) uniform tcs_block {\n"
19861 static const GLchar* tes = " in vec4 tcs_tes[];\n"
19862 "layout(xfb_buffer = 2, xfb_offset = 0) out vec4 tes_gs;\n"
19863 "layout(binding = 2) uniform tes_block {\n"
19866 static const GLchar* gs = " in vec4 tes_gs[];\n"
19867 "layout(xfb_buffer = 3, xfb_offset = 0) out vec4 gs_fs;\n"
19868 "layout(binding = 3) uniform gs_block {\n"
19871 static const GLchar* fs = " in vec4 gs_fs;\n"
19872 " out vec4 fs_out;\n"
19873 "layout(binding = 4) uniform fs_block {\n"
19877 const GLchar* interface = 0;
19880 case Utils::Shader::FRAGMENT:
19883 case Utils::Shader::GEOMETRY:
19886 case Utils::Shader::TESS_CTRL:
19889 case Utils::Shader::TESS_EVAL:
19892 case Utils::Shader::VERTEX:
19896 TCU_FAIL("Invalid enum");
19899 out_interface = interface;
19902 /* Constants used by XFBStrideOfEmptyListTest */
19903 const GLuint XFBStrideOfEmptyListTest::m_stride = 64;
19907 * @param context Test context
19909 XFBStrideOfEmptyListTest::XFBStrideOfEmptyListTest(deqp::Context& context)
19910 : BufferTestBase(context, "xfb_stride_of_empty_list",
19911 "Test verifies that xfb_stride qualifier is respected when no xfb_offset is specified")
19913 /* Nothing to be done here */
19916 /** Execute drawArrays for single vertex
19918 * @param test_case_index Index of test case
19920 * @return true if proper error is reported
19922 bool XFBStrideOfEmptyListTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
19924 const Functions& gl = m_context.getRenderContext().getFunctions();
19925 bool result = true;
19928 gl.disable(GL_RASTERIZER_DISCARD);
19929 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
19931 gl.beginTransformFeedback(GL_POINTS);
19932 GLenum error = gl.getError();
19933 switch (test_case_index)
19936 if (GL_NO_ERROR != error)
19938 gl.endTransformFeedback();
19939 GLU_EXPECT_NO_ERROR(error, "BeginTransformFeedback");
19942 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
19943 error = gl.getError();
19945 gl.endTransformFeedback();
19946 GLU_EXPECT_NO_ERROR(error, "DrawArrays");
19947 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
19951 case FIRST_MISSING:
19952 if (GL_NO_ERROR == error)
19954 gl.endTransformFeedback();
19957 if (GL_INVALID_OPERATION != error)
19959 m_context.getTestContext().getLog()
19960 << tcu::TestLog::Message << "XFB at index 0, that is written by GS, is missing. It was expected that "
19961 "INVALID_OPERATION will generated by BeginTransformFeedback. Got: "
19962 << glu::getErrorStr(error) << tcu::TestLog::EndMessage;
19969 case SECOND_MISSING:
19970 if (GL_NO_ERROR == error)
19972 gl.endTransformFeedback();
19975 if (GL_INVALID_OPERATION != error)
19977 m_context.getTestContext().getLog()
19978 << tcu::TestLog::Message << "XFB at index 1, that is declared as empty, is missing. It was expected "
19979 "that INVALID_OPERATION will generated by BeginTransformFeedback. Got: "
19980 << glu::getErrorStr(error) << tcu::TestLog::EndMessage;
19992 /** Get descriptors of buffers necessary for test
19994 * @param test_case_index Index of test case
19995 * @param out_descriptors Descriptors of buffers used by test
19997 void XFBStrideOfEmptyListTest::getBufferDescriptors(glw::GLuint test_case_index,
19998 bufferDescriptor::Vector& out_descriptors)
20000 switch (test_case_index)
20004 /* Test needs single uniform and two xfbs */
20005 out_descriptors.resize(3);
20007 /* Get references */
20008 bufferDescriptor& uniform = out_descriptors[0];
20009 bufferDescriptor& xfb_0 = out_descriptors[1];
20010 bufferDescriptor& xfb_1 = out_descriptors[2];
20013 uniform.m_index = 0;
20018 uniform.m_target = Utils::Buffer::Uniform;
20019 xfb_0.m_target = Utils::Buffer::Transform_feedback;
20020 xfb_1.m_target = Utils::Buffer::Transform_feedback;
20023 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20025 xfb_0.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20026 xfb_0.m_expected_data = uniform.m_initial_data;
20028 /* Data, contents are the same as no modification is expected */
20029 xfb_1.m_initial_data.resize(m_stride);
20030 xfb_1.m_expected_data.resize(m_stride);
20032 for (GLuint i = 0; i < m_stride; ++i)
20034 xfb_1.m_initial_data[0] = (glw::GLubyte)i;
20035 xfb_1.m_expected_data[0] = (glw::GLubyte)i;
20041 case FIRST_MISSING:
20043 /* Test needs single uniform and two xfbs */
20044 out_descriptors.resize(2);
20046 /* Get references */
20047 bufferDescriptor& uniform = out_descriptors[0];
20048 bufferDescriptor& xfb_1 = out_descriptors[1];
20051 uniform.m_index = 0;
20055 uniform.m_target = Utils::Buffer::Uniform;
20056 xfb_1.m_target = Utils::Buffer::Transform_feedback;
20059 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20061 /* Draw call will not be executed, contents does not matter */
20062 xfb_1.m_initial_data.resize(m_stride);
20067 case SECOND_MISSING:
20069 /* Test needs single uniform and two xfbs */
20070 out_descriptors.resize(2);
20072 /* Get references */
20073 bufferDescriptor& uniform = out_descriptors[0];
20074 bufferDescriptor& xfb_0 = out_descriptors[1];
20077 uniform.m_index = 0;
20081 uniform.m_target = Utils::Buffer::Uniform;
20082 xfb_0.m_target = Utils::Buffer::Transform_feedback;
20085 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20087 /* Draw call will not be executed, contents does not matter */
20088 xfb_0.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20095 /** Get body of main function for given shader stage
20098 * @param stage Shader stage
20099 * @param out_assignments Set to empty
20100 * @param out_calculations Set to empty
20102 void XFBStrideOfEmptyListTest::getShaderBody(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
20103 std::string& out_assignments, std::string& out_calculations)
20105 out_calculations = "";
20107 static const GLchar* gs = " gs_fs = uni_gs;\n";
20108 static const GLchar* fs = " fs_out = vec4(gs_fs);\n";
20110 const GLchar* assignments = "";
20113 case Utils::Shader::FRAGMENT:
20116 case Utils::Shader::GEOMETRY:
20123 out_assignments = assignments;
20126 /** Get interface of shader
20129 * @param stage Shader stage
20130 * @param out_interface Set to ""
20132 void XFBStrideOfEmptyListTest::getShaderInterface(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
20133 std::string& out_interface)
20135 static const GLchar* gs = "layout (xfb_buffer = 0, xfb_offset = 0) out vec4 gs_fs;\n"
20136 "layout (xfb_buffer = 1, xfb_stride = 64) out;\n"
20138 "layout (binding = 0) uniform gs_block {\n"
20141 static const GLchar* fs = "in vec4 gs_fs;\n"
20142 "out vec4 fs_out;\n";
20146 case Utils::Shader::FRAGMENT:
20147 out_interface = fs;
20149 case Utils::Shader::GEOMETRY:
20150 out_interface = gs;
20153 out_interface = "";
20158 /** Returns buffer details in human readable form.
20160 * @param test_case_index Index of test case
20162 * @return Case description
20164 std::string XFBStrideOfEmptyListTest::getTestCaseName(GLuint test_case_index)
20166 std::string result;
20168 switch (test_case_index)
20171 result = "Valid case";
20173 case FIRST_MISSING:
20174 result = "Missing xfb at index 0";
20176 case SECOND_MISSING:
20177 result = "Missing xfb at index 1";
20180 TCU_FAIL("Invalid enum");
20186 /** Get number of test cases
20190 GLuint XFBStrideOfEmptyListTest::getTestCaseNumber()
20195 /* Constants used by XFBStrideOfEmptyListTest */
20196 const GLuint XFBStrideOfEmptyListAndAPITest::m_stride = 64;
20200 * @param context Test context
20202 XFBStrideOfEmptyListAndAPITest::XFBStrideOfEmptyListAndAPITest(deqp::Context& context)
20203 : BufferTestBase(context, "xfb_stride_of_empty_list_and_api",
20204 "Test verifies that xfb_stride qualifier is not overriden by API")
20206 /* Nothing to be done here */
20209 /** Execute drawArrays for single vertex
20211 * @param test_case_index Index of test case
20213 * @return true if proper error is reported
20215 bool XFBStrideOfEmptyListAndAPITest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
20217 const Functions& gl = m_context.getRenderContext().getFunctions();
20218 bool result = true;
20221 gl.disable(GL_RASTERIZER_DISCARD);
20222 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
20224 gl.beginTransformFeedback(GL_POINTS);
20225 GLenum error = gl.getError();
20226 switch (test_case_index)
20229 if (GL_NO_ERROR != error)
20231 gl.endTransformFeedback();
20232 GLU_EXPECT_NO_ERROR(error, "BeginTransformFeedback");
20235 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
20236 error = gl.getError();
20238 gl.endTransformFeedback();
20239 GLU_EXPECT_NO_ERROR(error, "DrawArrays");
20240 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
20244 case FIRST_MISSING:
20245 if (GL_NO_ERROR == error)
20247 gl.endTransformFeedback();
20250 if (GL_INVALID_OPERATION != error)
20252 m_context.getTestContext().getLog()
20253 << tcu::TestLog::Message << "XFB at index 0, that is declared as empty, is missing. It was expected "
20254 "that INVALID_OPERATION will generated by BeginTransformFeedback. Got: "
20255 << glu::getErrorStr(error) << tcu::TestLog::EndMessage;
20262 case SECOND_MISSING:
20263 if (GL_NO_ERROR == error)
20265 gl.endTransformFeedback();
20268 if (GL_INVALID_OPERATION != error)
20270 m_context.getTestContext().getLog()
20271 << tcu::TestLog::Message << "XFB at index 1, that is written by GS, is missing. It was expected that "
20272 "INVALID_OPERATION will generated by BeginTransformFeedback. Got: "
20273 << glu::getErrorStr(error) << tcu::TestLog::EndMessage;
20285 /** Get descriptors of buffers necessary for test
20287 * @param test_case_index Index of test case
20288 * @param out_descriptors Descriptors of buffers used by test
20290 void XFBStrideOfEmptyListAndAPITest::getBufferDescriptors(glw::GLuint test_case_index,
20291 bufferDescriptor::Vector& out_descriptors)
20293 switch (test_case_index)
20297 /* Test needs single uniform and two xfbs */
20298 out_descriptors.resize(3);
20300 /* Get references */
20301 bufferDescriptor& uniform = out_descriptors[0];
20302 bufferDescriptor& xfb_0 = out_descriptors[1];
20303 bufferDescriptor& xfb_1 = out_descriptors[2];
20306 uniform.m_index = 0;
20311 uniform.m_target = Utils::Buffer::Uniform;
20312 xfb_0.m_target = Utils::Buffer::Transform_feedback;
20313 xfb_1.m_target = Utils::Buffer::Transform_feedback;
20316 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20318 /* Data, contents are the same as no modification is expected */
20319 xfb_0.m_initial_data.resize(m_stride);
20320 xfb_0.m_expected_data.resize(m_stride);
20322 for (GLuint i = 0; i < m_stride; ++i)
20324 xfb_0.m_initial_data[0] = (glw::GLubyte)i;
20325 xfb_0.m_expected_data[0] = (glw::GLubyte)i;
20328 xfb_1.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20329 xfb_1.m_expected_data = uniform.m_initial_data;
20334 case FIRST_MISSING:
20336 /* Test needs single uniform and two xfbs */
20337 out_descriptors.resize(2);
20339 /* Get references */
20340 bufferDescriptor& uniform = out_descriptors[0];
20341 bufferDescriptor& xfb_1 = out_descriptors[1];
20344 uniform.m_index = 0;
20348 uniform.m_target = Utils::Buffer::Uniform;
20349 xfb_1.m_target = Utils::Buffer::Transform_feedback;
20352 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20354 /* Draw call will not be executed, contents does not matter */
20355 xfb_1.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20360 case SECOND_MISSING:
20362 /* Test needs single uniform and two xfbs */
20363 out_descriptors.resize(2);
20365 /* Get references */
20366 bufferDescriptor& uniform = out_descriptors[0];
20367 bufferDescriptor& xfb_0 = out_descriptors[1];
20370 uniform.m_index = 0;
20374 uniform.m_target = Utils::Buffer::Uniform;
20375 xfb_0.m_target = Utils::Buffer::Transform_feedback;
20378 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20380 /* Draw call will not be executed, contents does not matter */
20381 xfb_0.m_initial_data.resize(m_stride);
20388 /** Get list of names of varyings that will be registered with TransformFeedbackVaryings
20391 * @param captured_varyings Vector of varying names to be captured
20393 void XFBStrideOfEmptyListAndAPITest::getCapturedVaryings(glw::GLuint /* test_case_index */,
20394 Utils::Program::NameVector& captured_varyings)
20396 captured_varyings.push_back("gs_fs");
20399 /** Get body of main function for given shader stage
20402 * @param stage Shader stage
20403 * @param out_assignments Set to empty
20404 * @param out_calculations Set to empty
20406 void XFBStrideOfEmptyListAndAPITest::getShaderBody(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
20407 std::string& out_assignments, std::string& out_calculations)
20409 out_calculations = "";
20411 static const GLchar* gs = " gs_fs = uni_gs;\n";
20412 static const GLchar* fs = " fs_out = vec4(gs_fs);\n";
20414 const GLchar* assignments = "";
20417 case Utils::Shader::FRAGMENT:
20420 case Utils::Shader::GEOMETRY:
20427 out_assignments = assignments;
20430 /** Get interface of shader
20433 * @param stage Shader stage
20434 * @param out_interface Set to ""
20436 void XFBStrideOfEmptyListAndAPITest::getShaderInterface(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
20437 std::string& out_interface)
20439 static const GLchar* gs = "layout (xfb_buffer = 0, xfb_stride = 64) out;\n"
20440 "layout (xfb_buffer = 1, xfb_offset = 0) out vec4 gs_fs;\n"
20442 "layout(binding = 0) uniform gs_block {\n"
20445 static const GLchar* fs = "in vec4 gs_fs;\n"
20446 "out vec4 fs_out;\n";
20450 case Utils::Shader::FRAGMENT:
20451 out_interface = fs;
20453 case Utils::Shader::GEOMETRY:
20454 out_interface = gs;
20457 out_interface = "";
20462 /** Returns buffer details in human readable form.
20464 * @param test_case_index Index of test case
20466 * @return Case description
20468 std::string XFBStrideOfEmptyListAndAPITest::getTestCaseName(GLuint test_case_index)
20470 std::string result;
20472 switch (test_case_index)
20475 result = "Valid case";
20477 case FIRST_MISSING:
20478 result = "Missing xfb at index 0";
20480 case SECOND_MISSING:
20481 result = "Missing xfb at index 1";
20484 TCU_FAIL("Invalid enum");
20490 /** Get number of test cases
20494 GLuint XFBStrideOfEmptyListAndAPITest::getTestCaseNumber()
20501 * @param context Test framework context
20503 XFBTooSmallStrideTest::XFBTooSmallStrideTest(deqp::Context& context)
20504 : NegativeTestBase(context, "xfb_too_small_stride",
20505 "Test verifies that compiler reports error when xfb_stride sets not enough space")
20509 /** Source for given test case and stage
20511 * @param test_case_index Index of test case
20512 * @param stage Shader stage
20514 * @return Shader source
20516 std::string XFBTooSmallStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
20518 static const GLchar* array_var_definition = "layout (xfb_buffer = 0, xfb_stride = 32) out;\n"
20520 "layout (xfb_offset = 16) out vec4 gohanARRAY[4];\n";
20521 static const GLchar* block_var_definition = "layout (xfb_buffer = 0, xfb_stride = 32) out;\n"
20523 "layout (xfb_offset = 0) out Goku {\n"
20528 static const GLchar* offset_var_definition = "layout (xfb_buffer = 0, xfb_stride = 40) out;\n"
20530 "layout (xfb_offset = 32) out vec4 gohanARRAY;\n";
20531 // 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;"
20532 // To make the shader failed to compile, change xfb_stride to a value that is smaller than 32
20533 static const GLchar* stride_var_definition = "layout (xfb_buffer = 0, xfb_stride = 28) out;\n"
20535 "layout (xfb_offset = 16, xfb_stride = 28) out vec4 gohanARRAY;\n";
20536 static const GLchar* array_use = " gohanINDEX[0] = result / 2;\n"
20537 " gohanINDEX[1] = result / 4;\n"
20538 " gohanINDEX[2] = result / 6;\n"
20539 " gohanINDEX[3] = result / 8;\n";
20540 static const GLchar* block_use = " gokuINDEX.gohan = result / 2;\n"
20541 " gokuINDEX.goten = result / 4;\n"
20542 " gokuINDEX.chichi = result / 6;\n";
20543 static const GLchar* output_use = "gohanINDEX = result / 4;\n";
20544 static const GLchar* fs = "#version 430 core\n"
20545 "#extension GL_ARB_enhanced_layouts : require\n"
20548 "out vec4 fs_out;\n"
20552 " fs_out = gs_fs;\n"
20555 static const GLchar* gs_tested = "#version 430 core\n"
20556 "#extension GL_ARB_enhanced_layouts : require\n"
20558 "layout(points) in;\n"
20559 "layout(triangle_strip, max_vertices = 4) out;\n"
20563 "in vec4 tes_gs[];\n"
20564 "out vec4 gs_fs;\n"
20568 " vec4 result = tes_gs[0];\n"
20572 " gs_fs = result;\n"
20573 " gl_Position = vec4(-1, -1, 0, 1);\n"
20575 " gs_fs = result;\n"
20576 " gl_Position = vec4(-1, 1, 0, 1);\n"
20578 " gs_fs = result;\n"
20579 " gl_Position = vec4(1, -1, 0, 1);\n"
20581 " gs_fs = result;\n"
20582 " gl_Position = vec4(1, 1, 0, 1);\n"
20586 static const GLchar* tcs = "#version 430 core\n"
20587 "#extension GL_ARB_enhanced_layouts : require\n"
20589 "layout(vertices = 1) out;\n"
20591 "in vec4 vs_tcs[];\n"
20592 "out vec4 tcs_tes[];\n"
20597 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
20599 " gl_TessLevelOuter[0] = 1.0;\n"
20600 " gl_TessLevelOuter[1] = 1.0;\n"
20601 " gl_TessLevelOuter[2] = 1.0;\n"
20602 " gl_TessLevelOuter[3] = 1.0;\n"
20603 " gl_TessLevelInner[0] = 1.0;\n"
20604 " gl_TessLevelInner[1] = 1.0;\n"
20607 static const GLchar* tcs_tested = "#version 430 core\n"
20608 "#extension GL_ARB_enhanced_layouts : require\n"
20610 "layout(vertices = 1) out;\n"
20614 "in vec4 vs_tcs[];\n"
20615 "out vec4 tcs_tes[];\n"
20619 " vec4 result = vs_tcs[gl_InvocationID];\n"
20623 " tcs_tes[gl_InvocationID] = result;\n"
20625 " gl_TessLevelOuter[0] = 1.0;\n"
20626 " gl_TessLevelOuter[1] = 1.0;\n"
20627 " gl_TessLevelOuter[2] = 1.0;\n"
20628 " gl_TessLevelOuter[3] = 1.0;\n"
20629 " gl_TessLevelInner[0] = 1.0;\n"
20630 " gl_TessLevelInner[1] = 1.0;\n"
20633 static const GLchar* tes_tested = "#version 430 core\n"
20634 "#extension GL_ARB_enhanced_layouts : require\n"
20636 "layout(isolines, point_mode) in;\n"
20640 "in vec4 tcs_tes[];\n"
20641 "out vec4 tes_gs;\n"
20645 " vec4 result = tcs_tes[0];\n"
20649 " tes_gs += result;\n"
20652 static const GLchar* vs = "#version 430 core\n"
20653 "#extension GL_ARB_enhanced_layouts : require\n"
20656 "out vec4 vs_tcs;\n"
20660 " vs_tcs = in_vs;\n"
20663 static const GLchar* vs_tested = "#version 430 core\n"
20664 "#extension GL_ARB_enhanced_layouts : require\n"
20669 "out vec4 vs_tcs;\n"
20673 " vec4 result = in_vs;\n"
20677 " vs_tcs += result;\n"
20681 std::string source;
20682 testCase& test_case = m_test_cases[test_case_index];
20684 if (test_case.m_stage == stage)
20686 const GLchar* array = "";
20687 const GLchar* index = "";
20688 size_t position = 0;
20690 const GLchar* var_definition = 0;
20691 const GLchar* var_use = 0;
20693 switch (test_case.m_case)
20696 var_definition = offset_var_definition;
20697 var_use = output_use;
20700 var_definition = stride_var_definition;
20701 var_use = output_use;
20704 var_definition = block_var_definition;
20705 var_use = block_use;
20708 var_definition = array_var_definition;
20709 var_use = array_use;
20712 TCU_FAIL("Invalid enum");
20717 case Utils::Shader::GEOMETRY:
20718 source = gs_tested;
20722 case Utils::Shader::TESS_CTRL:
20723 source = tcs_tested;
20725 index = "[gl_InvocationID]";
20727 case Utils::Shader::TESS_EVAL:
20728 source = tes_tested;
20732 case Utils::Shader::VERTEX:
20733 source = vs_tested;
20736 TCU_FAIL("Invalid enum");
20740 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
20742 Utils::replaceToken("ARRAY", position, array, source);
20743 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
20745 Utils::replaceAllTokens("INDEX", index, source);
20749 switch (test_case.m_stage)
20751 case Utils::Shader::GEOMETRY:
20754 case Utils::Shader::FRAGMENT:
20757 case Utils::Shader::VERTEX:
20764 case Utils::Shader::TESS_CTRL:
20767 case Utils::Shader::FRAGMENT:
20770 case Utils::Shader::VERTEX:
20777 case Utils::Shader::TESS_EVAL:
20780 case Utils::Shader::FRAGMENT:
20783 case Utils::Shader::TESS_CTRL:
20786 case Utils::Shader::VERTEX:
20793 case Utils::Shader::VERTEX:
20796 case Utils::Shader::FRAGMENT:
20804 TCU_FAIL("Invalid enum");
20812 /** Get description of test case
20814 * @param test_case_index Index of test case
20816 * @return Test case description
20818 std::string XFBTooSmallStrideTest::getTestCaseName(GLuint test_case_index)
20820 std::stringstream stream;
20821 testCase& test_case = m_test_cases[test_case_index];
20823 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", case: ";
20825 switch (test_case.m_case)
20828 stream << "buffer stride: 40, vec4 offset: 32";
20831 stream << "buffer stride: 32, vec4 off 16 stride: 32";
20834 stream << "buffer stride: 32, block 3xvec4 offset 0";
20837 stream << "buffer stride: 32, vec4[4] offset 16";
20840 TCU_FAIL("Invalid enum");
20843 return stream.str();
20846 /** Get number of test cases
20848 * @return Number of test cases
20850 GLuint XFBTooSmallStrideTest::getTestCaseNumber()
20852 return static_cast<GLuint>(m_test_cases.size());
20855 /** Selects if "compute" stage is relevant for test
20861 bool XFBTooSmallStrideTest::isComputeRelevant(GLuint /* test_case_index */)
20866 /** Prepare all test cases
20869 void XFBTooSmallStrideTest::testInit()
20871 for (GLuint c = 0; c < CASE_MAX; ++c)
20873 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
20876 It is invalid to define transform feedback output in TCS, according to spec:
20877 The data captured in transform feedback mode depends on the active programs on each of the shader stages.
20878 If a program is active for the geometry shader stage, transform feedback captures the vertices of each
20879 primitive emitted by the geometry shader. Otherwise, if a program is active for the tessellation evaluation
20880 shader stage, transform feedback captures each primitive produced by the tessellation primitive generator,
20881 whose vertices are processed by the tessellation evaluation shader. Otherwise, transform feedback captures
20882 each primitive processed by the vertex shader.
20884 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
20885 (Utils::Shader::FRAGMENT == stage))
20890 testCase test_case = { (CASES)c, (Utils::Shader::STAGES)stage };
20892 m_test_cases.push_back(test_case);
20899 * @param context Test framework context
20901 XFBVariableStrideTest::XFBVariableStrideTest(deqp::Context& context)
20902 : NegativeTestBase(context, "xfb_variable_stride", "Test verifies that stride qualifier is respected")
20906 /** Source for given test case and stage
20908 * @param test_case_index Index of test case
20909 * @param stage Shader stage
20911 * @return Shader source
20913 std::string XFBVariableStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
20915 static const GLchar* invalid_var_definition =
20916 "const uint type_size = SIZE;\n"
20918 "layout (xfb_offset = 0, xfb_stride = 2 * type_size) out TYPE gokuARRAY;\n"
20919 "layout (xfb_offset = type_size) out TYPE vegetaARRAY;\n";
20920 static const GLchar* valid_var_definition =
20921 "const uint type_size = SIZE;\n"
20923 "layout (xfb_offset = 0, xfb_stride = 2 * type_size) out TYPE gokuARRAY;\n";
20924 static const GLchar* invalid_use = " gokuINDEX = TYPE(1);\n"
20925 " vegetaINDEX = TYPE(0);\n"
20926 " if (vec4(0) == result)\n"
20928 " gokuINDEX = TYPE(0);\n"
20929 " vegetaINDEX = TYPE(1);\n"
20931 static const GLchar* valid_use = " gokuINDEX = TYPE(1);\n"
20932 " if (vec4(0) == result)\n"
20934 " gokuINDEX = TYPE(0);\n"
20936 static const GLchar* fs = "#version 430 core\n"
20937 "#extension GL_ARB_enhanced_layouts : require\n"
20939 "in vec4 any_fs;\n"
20940 "out vec4 fs_out;\n"
20944 " fs_out = any_fs;\n"
20947 static const GLchar* gs_tested = "#version 430 core\n"
20948 "#extension GL_ARB_enhanced_layouts : require\n"
20950 "layout(points) in;\n"
20951 "layout(triangle_strip, max_vertices = 4) out;\n"
20955 "in vec4 vs_any[];\n"
20956 "out vec4 any_fs;\n"
20960 " vec4 result = vs_any[0];\n"
20964 " any_fs = result;\n"
20965 " gl_Position = vec4(-1, -1, 0, 1);\n"
20967 " any_fs = result;\n"
20968 " gl_Position = vec4(-1, 1, 0, 1);\n"
20970 " any_fs = result;\n"
20971 " gl_Position = vec4(1, -1, 0, 1);\n"
20973 " any_fs = result;\n"
20974 " gl_Position = vec4(1, 1, 0, 1);\n"
20978 static const GLchar* tcs = "#version 430 core\n"
20979 "#extension GL_ARB_enhanced_layouts : require\n"
20981 "layout(vertices = 1) out;\n"
20983 "in vec4 vs_any[];\n"
20984 "out vec4 tcs_tes[];\n"
20989 " tcs_tes[gl_InvocationID] = vs_any[gl_InvocationID];\n"
20991 " gl_TessLevelOuter[0] = 1.0;\n"
20992 " gl_TessLevelOuter[1] = 1.0;\n"
20993 " gl_TessLevelOuter[2] = 1.0;\n"
20994 " gl_TessLevelOuter[3] = 1.0;\n"
20995 " gl_TessLevelInner[0] = 1.0;\n"
20996 " gl_TessLevelInner[1] = 1.0;\n"
20999 static const GLchar* tcs_tested = "#version 430 core\n"
21000 "#extension GL_ARB_enhanced_layouts : require\n"
21002 "layout(vertices = 1) out;\n"
21006 "in vec4 vs_any[];\n"
21007 "out vec4 any_fs[];\n"
21011 " vec4 result = vs_any[gl_InvocationID];\n"
21015 " any_fs[gl_InvocationID] = result;\n"
21017 " gl_TessLevelOuter[0] = 1.0;\n"
21018 " gl_TessLevelOuter[1] = 1.0;\n"
21019 " gl_TessLevelOuter[2] = 1.0;\n"
21020 " gl_TessLevelOuter[3] = 1.0;\n"
21021 " gl_TessLevelInner[0] = 1.0;\n"
21022 " gl_TessLevelInner[1] = 1.0;\n"
21025 static const GLchar* tes_tested = "#version 430 core\n"
21026 "#extension GL_ARB_enhanced_layouts : require\n"
21028 "layout(isolines, point_mode) in;\n"
21032 "in vec4 tcs_tes[];\n"
21033 "out vec4 any_fs;\n"
21037 " vec4 result = tcs_tes[0];\n"
21041 " any_fs = result;\n"
21044 static const GLchar* vs = "#version 430 core\n"
21045 "#extension GL_ARB_enhanced_layouts : require\n"
21048 "out vec4 vs_any;\n"
21052 " vs_any = in_vs;\n"
21055 static const GLchar* vs_tested = "#version 430 core\n"
21056 "#extension GL_ARB_enhanced_layouts : require\n"
21061 "out vec4 any_fs;\n"
21065 " vec4 result = in_vs;\n"
21069 " any_fs = result;\n"
21073 std::string source;
21074 testCase& test_case = m_test_cases[test_case_index];
21076 if (test_case.m_stage == stage)
21078 const GLchar* array = "";
21080 const GLchar* index = "";
21081 size_t position = 0;
21083 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
21084 const GLchar* var_definition = 0;
21085 const GLchar* var_use = 0;
21087 sprintf(buffer, "%d", test_case.m_type.GetSize());
21089 switch (test_case.m_case)
21092 var_definition = valid_var_definition;
21093 var_use = valid_use;
21096 var_definition = invalid_var_definition;
21097 var_use = invalid_use;
21100 TCU_FAIL("Invalid enum");
21105 case Utils::Shader::GEOMETRY:
21106 source = gs_tested;
21110 case Utils::Shader::TESS_CTRL:
21111 source = tcs_tested;
21113 index = "[gl_InvocationID]";
21115 case Utils::Shader::TESS_EVAL:
21116 source = tes_tested;
21120 case Utils::Shader::VERTEX:
21121 source = vs_tested;
21124 TCU_FAIL("Invalid enum");
21128 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
21130 Utils::replaceToken("SIZE", position, buffer, source);
21131 Utils::replaceToken("ARRAY", position, array, source);
21132 if (INVALID == test_case.m_case)
21134 Utils::replaceToken("ARRAY", position, array, source);
21136 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
21138 Utils::replaceAllTokens("TYPE", type_name, source);
21139 Utils::replaceAllTokens("INDEX", index, source);
21143 switch (test_case.m_stage)
21145 case Utils::Shader::GEOMETRY:
21148 case Utils::Shader::FRAGMENT:
21151 case Utils::Shader::VERTEX:
21158 case Utils::Shader::TESS_CTRL:
21161 case Utils::Shader::FRAGMENT:
21164 case Utils::Shader::VERTEX:
21171 case Utils::Shader::TESS_EVAL:
21174 case Utils::Shader::FRAGMENT:
21177 case Utils::Shader::TESS_CTRL:
21180 case Utils::Shader::VERTEX:
21187 case Utils::Shader::VERTEX:
21190 case Utils::Shader::FRAGMENT:
21198 TCU_FAIL("Invalid enum");
21206 /** Get description of test case
21208 * @param test_case_index Index of test case
21210 * @return Test case description
21212 std::string XFBVariableStrideTest::getTestCaseName(GLuint test_case_index)
21214 std::stringstream stream;
21215 testCase& test_case = m_test_cases[test_case_index];
21217 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
21218 << ", type: " << test_case.m_type.GetGLSLTypeName() << ", case: ";
21220 switch (test_case.m_case)
21226 stream << "invalid";
21229 TCU_FAIL("Invalid enum");
21232 return stream.str();
21235 /** Get number of test cases
21237 * @return Number of test cases
21239 GLuint XFBVariableStrideTest::getTestCaseNumber()
21241 return static_cast<GLuint>(m_test_cases.size());
21244 /** Selects if "compute" stage is relevant for test
21250 bool XFBVariableStrideTest::isComputeRelevant(GLuint /* test_case_index */)
21255 /** Selects if compilation failure is expected result
21257 * @param test_case_index Index of test case
21261 bool XFBVariableStrideTest::isFailureExpected(GLuint test_case_index)
21263 testCase& test_case = m_test_cases[test_case_index];
21265 return (INVALID == test_case.m_case);
21268 /** Prepare all test cases
21271 void XFBVariableStrideTest::testInit()
21273 const GLuint n_types = getTypesNumber();
21275 for (GLuint i = 0; i < n_types; ++i)
21277 const Utils::Type& type = getType(i);
21280 Some of the cases are declared as following are considered as invalid,
21281 but accoring to spec, the following declaration is valid: shaders in the
21282 transform feedback capturing mode have an initial global default of layout(xfb_buffer=0) out,
21283 so for the first variable's declaration, the xfb_stride = 16 is applied on buffer 0, for the
21284 second variable, its buffer is also inherited from global buffer 0, and its offset does not overflows
21287 The xfb_stride is the memory width of given buffer, not for variable even though xfb_stride
21288 is declared on the variable. It seems that the writter of this case misunderstand the concept of
21289 xfb_stride, because spec describes that xfb_stride can be declared multiple times for the same buffer,
21290 it is a compile or link-time error to have different values specified for the stride for the same buffer.
21293 layout (xfb_offset = 0, xfb_stride = 2 * type_size) out double goku;
21294 layout (xfb_offset = type_size) out double vegeta;
21296 // all the shaders are valid, so remove the following loop(it contains CASE_MAX is enum of valid and invalid)
21297 // for (GLuint c = 0; c < CASE_MAX; ++c)
21299 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
21301 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
21302 (Utils::Shader::FRAGMENT == stage))
21307 testCase test_case = { (CASES)VALID, (Utils::Shader::STAGES)stage, type };
21309 m_test_cases.push_back(test_case);
21317 * @param context Test framework context
21319 XFBBlockStrideTest::XFBBlockStrideTest(deqp::Context& context)
21320 : TestBase(context, "xfb_block_stride", "Test verifies that stride qualifier is respected for blocks")
21324 /** Source for given test case and stage
21326 * @param test_case_index Index of test case
21327 * @param stage Shader stage
21329 * @return Shader source
21331 std::string XFBBlockStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
21333 static const GLchar* var_definition = "layout (xfb_offset = 0, xfb_stride = 128) out Goku {\n"
21338 static const GLchar* var_use = " gokuINDEX.gohan = vec4(1, 0, 0, 0);\n"
21339 " gokuINDEX.goten = vec4(0, 0, 1, 0);\n"
21340 " gokuINDEX.chichi = vec4(0, 1, 0, 0);\n"
21341 " if (vec4(0) == result)\n"
21343 " gokuINDEX.gohan = vec4(0, 1, 1, 1);\n"
21344 " gokuINDEX.goten = vec4(1, 1, 0, 1);\n"
21345 " gokuINDEX.chichi = vec4(1, 0, 1, 1);\n"
21347 static const GLchar* gs_tested =
21348 "#version 430 core\n"
21349 "#extension GL_ARB_enhanced_layouts : require\n"
21351 "layout(points) in;\n"
21352 "layout(triangle_strip, max_vertices = 4) out;\n"
21356 "out gl_PerVertex \n"
21358 " vec4 gl_Position; \n" // gl_Position must be redeclared in separable program mode
21360 "in vec4 tes_gs[];\n"
21361 "out vec4 gs_fs;\n"
21365 " vec4 result = tes_gs[0];\n"
21369 " gs_fs = result;\n"
21370 " gl_Position = vec4(-1, -1, 0, 1);\n"
21372 " gs_fs = result;\n"
21373 " gl_Position = vec4(-1, 1, 0, 1);\n"
21375 " gs_fs = result;\n"
21376 " gl_Position = vec4(1, -1, 0, 1);\n"
21378 " gs_fs = result;\n"
21379 " gl_Position = vec4(1, 1, 0, 1);\n"
21383 static const GLchar* tcs = "#version 430 core\n"
21384 "#extension GL_ARB_enhanced_layouts : require\n"
21386 "layout(vertices = 1) out;\n"
21388 "in vec4 vs_tcs[];\n"
21389 "out vec4 tcs_tes[];\n"
21394 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
21396 " gl_TessLevelOuter[0] = 1.0;\n"
21397 " gl_TessLevelOuter[1] = 1.0;\n"
21398 " gl_TessLevelOuter[2] = 1.0;\n"
21399 " gl_TessLevelOuter[3] = 1.0;\n"
21400 " gl_TessLevelInner[0] = 1.0;\n"
21401 " gl_TessLevelInner[1] = 1.0;\n"
21405 static const GLchar* tcs_tested =
21406 "#version 430 core\n"
21407 "#extension GL_ARB_enhanced_layouts : require\n"
21409 "layout(vertices = 1) out;\n"
21413 "in vec4 vs_tcs[];\n"
21414 "out vec4 tcs_tes[];\n"
21418 " vec4 result = vs_tcs[gl_InvocationID];\n"
21422 " tcs_tes[gl_InvocationID] = result;\n"
21424 " gl_TessLevelOuter[0] = 1.0;\n"
21425 " gl_TessLevelOuter[1] = 1.0;\n"
21426 " gl_TessLevelOuter[2] = 1.0;\n"
21427 " gl_TessLevelOuter[3] = 1.0;\n"
21428 " gl_TessLevelInner[0] = 1.0;\n"
21429 " gl_TessLevelInner[1] = 1.0;\n"
21433 static const GLchar* tes_tested = "#version 430 core\n"
21434 "#extension GL_ARB_enhanced_layouts : require\n"
21436 "layout(isolines, point_mode) in;\n"
21440 "in vec4 tcs_tes[];\n"
21441 "out vec4 tes_gs;\n"
21445 " vec4 result = tcs_tes[0];\n"
21449 " tes_gs += result;\n"
21452 static const GLchar* vs = "#version 430 core\n"
21453 "#extension GL_ARB_enhanced_layouts : require\n"
21456 "out vec4 vs_tcs;\n"
21460 " vs_tcs = in_vs;\n"
21463 static const GLchar* vs_tested = "#version 430 core\n"
21464 "#extension GL_ARB_enhanced_layouts : require\n"
21469 "out vec4 vs_tcs;\n"
21473 " vec4 result = in_vs;\n"
21477 " vs_tcs += result;\n"
21481 std::string source;
21482 Utils::Shader::STAGES test_case = m_test_cases[test_case_index];
21484 if (test_case == stage)
21486 const GLchar* array = "";
21487 const GLchar* index = "";
21488 size_t position = 0;
21490 // It is a compile time error to apply xfb_offset to the declaration of an unsized array(GLSL4.5 spec: Page73)
21491 // change array = "[]" to "[1]"
21494 case Utils::Shader::GEOMETRY:
21495 source = gs_tested;
21500 It is invalid to define transform feedback output in HS
21503 case Utils::Shader::TESS_CTRL:
21504 source = tcs_tested;
21506 index = "[gl_InvocationID]";
21509 case Utils::Shader::TESS_EVAL:
21510 source = tes_tested;
21514 case Utils::Shader::VERTEX:
21515 source = vs_tested;
21518 TCU_FAIL("Invalid enum");
21522 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
21524 Utils::replaceToken("ARRAY", position, array, source);
21525 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
21527 Utils::replaceAllTokens("INDEX", index, source);
21533 case Utils::Shader::GEOMETRY:
21536 case Utils::Shader::VERTEX:
21543 case Utils::Shader::TESS_CTRL:
21546 case Utils::Shader::VERTEX:
21553 case Utils::Shader::TESS_EVAL:
21556 case Utils::Shader::TESS_CTRL:
21559 case Utils::Shader::VERTEX:
21566 case Utils::Shader::VERTEX:
21570 TCU_FAIL("Invalid enum");
21578 /** Get description of test case
21580 * @param test_case_index Index of test case
21582 * @return Test case description
21584 std::string XFBBlockStrideTest::getTestCaseName(GLuint test_case_index)
21586 std::stringstream stream;
21588 stream << "Stage: " << Utils::Shader::GetStageName(m_test_cases[test_case_index]);
21590 return stream.str();
21593 /** Get number of test cases
21595 * @return Number of test cases
21597 GLuint XFBBlockStrideTest::getTestCaseNumber()
21599 return static_cast<GLuint>(m_test_cases.size());
21602 /** Inspects program for xfb stride
21604 * @param program Program to query
21606 * @return true if query results match expected values, false otherwise
21608 bool XFBBlockStrideTest::inspectProgram(Utils::Program& program)
21612 program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE,
21613 1 /* buf_size */, &stride);
21615 return (128 == stride);
21620 * @param test_case_index Id of test case
21622 * @return true if test case pass, false otherwise
21624 bool XFBBlockStrideTest::testCase(GLuint test_case_index)
21626 const std::string& gs_source = getShaderSource(test_case_index, Utils::Shader::GEOMETRY);
21627 Utils::Program program(m_context);
21628 const std::string& tcs_source = getShaderSource(test_case_index, Utils::Shader::TESS_CTRL);
21629 const std::string& tes_source = getShaderSource(test_case_index, Utils::Shader::TESS_EVAL);
21630 bool test_case_result = true;
21631 const std::string& vs_source = getShaderSource(test_case_index, Utils::Shader::VERTEX);
21633 program.Init("" /* cs */, "", gs_source, tcs_source, tes_source, vs_source, true /* separable */);
21635 test_case_result = inspectProgram(program);
21637 return test_case_result;
21640 /** Prepare all test cases
21643 void XFBBlockStrideTest::testInit()
21645 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
21647 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
21648 (Utils::Shader::FRAGMENT == stage))
21653 m_test_cases.push_back((Utils::Shader::STAGES)stage);
21659 * @param context Test context
21661 XFBBlockMemberStrideTest::XFBBlockMemberStrideTest(deqp::Context& context)
21662 : BufferTestBase(context, "xfb_block_member_stride",
21663 "Test verifies that xfb_stride qualifier is respected for block member")
21665 /* Nothing to be done here */
21668 /** Get descriptors of buffers necessary for test
21671 * @param out_descriptors Descriptors of buffers used by test
21673 void XFBBlockMemberStrideTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
21674 bufferDescriptor::Vector& out_descriptors)
21676 const Utils::Type& vec4 = Utils::Type::vec4;
21678 /* Test needs single uniform and xfb */
21679 out_descriptors.resize(2);
21681 /* Get references */
21682 bufferDescriptor& uniform = out_descriptors[0];
21683 bufferDescriptor& xfb = out_descriptors[1];
21686 uniform.m_index = 0;
21690 uniform.m_target = Utils::Buffer::Uniform;
21691 xfb.m_target = Utils::Buffer::Transform_feedback;
21694 static const GLuint vec4_size = 16;
21695 const std::vector<GLubyte>& gohan_data = vec4.GenerateDataPacked();
21696 const std::vector<GLubyte>& goten_data = vec4.GenerateDataPacked();
21697 const std::vector<GLubyte>& chichi_data = vec4.GenerateDataPacked();
21700 uniform.m_initial_data.resize(3 * vec4_size);
21701 memcpy(&uniform.m_initial_data[0] + 0, &gohan_data[0], vec4_size);
21702 memcpy(&uniform.m_initial_data[0] + vec4_size, &goten_data[0], vec4_size);
21703 memcpy(&uniform.m_initial_data[0] + 2 * vec4_size, &chichi_data[0], vec4_size);
21706 xfb.m_initial_data.resize(4 * vec4_size);
21707 xfb.m_expected_data.resize(4 * vec4_size);
21709 for (GLuint i = 0; i < 4 * vec4_size; ++i)
21711 xfb.m_initial_data[i] = (glw::GLubyte)i;
21712 xfb.m_expected_data[i] = (glw::GLubyte)i;
21715 // the xfb_offset of "chichi" should be 32
21716 memcpy(&xfb.m_expected_data[0] + 0, &gohan_data[0], vec4_size);
21717 memcpy(&xfb.m_expected_data[0] + vec4_size, &goten_data[0], vec4_size);
21718 memcpy(&xfb.m_expected_data[0] + 2 * vec4_size, &chichi_data[0], vec4_size);
21721 /** Get body of main function for given shader stage
21724 * @param stage Shader stage
21725 * @param out_assignments Set to empty
21726 * @param out_calculations Set to empty
21728 void XFBBlockMemberStrideTest::getShaderBody(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
21729 std::string& out_assignments, std::string& out_calculations)
21731 out_calculations = "";
21733 static const GLchar* gs = " gohan = uni_gohan;\n"
21734 " goten = uni_goten;\n"
21735 " chichi = uni_chichi;\n";
21736 static const GLchar* fs = " fs_out = gohan + goten + chichi;\n";
21738 const GLchar* assignments = "";
21741 case Utils::Shader::FRAGMENT:
21744 case Utils::Shader::GEOMETRY:
21751 out_assignments = assignments;
21754 /** Get interface of shader
21757 * @param stage Shader stage
21758 * @param out_interface Set to ""
21760 void XFBBlockMemberStrideTest::getShaderInterface(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
21761 std::string& out_interface)
21763 static const GLchar* gs = "layout (xfb_buffer = 0, xfb_offset = 0) out Goku {\n"
21765 " layout (xfb_stride = 32) vec4 goten;\n"
21768 "layout(binding = 0) uniform gs_block {\n"
21769 " vec4 uni_gohan;\n"
21770 " vec4 uni_goten;\n"
21771 " vec4 uni_chichi;\n"
21773 static const GLchar* fs = "in Goku {\n"
21778 "out vec4 fs_out;\n";
21782 case Utils::Shader::FRAGMENT:
21783 out_interface = fs;
21785 case Utils::Shader::GEOMETRY:
21786 out_interface = gs;
21789 out_interface = "";
21794 /** Inspects program to check if all resources are as expected
21797 * @param program Program instance
21798 * @param out_stream Error message
21800 * @return true if everything is ok, false otherwise
21802 bool XFBBlockMemberStrideTest::inspectProgram(GLuint /* test_case_index*/, Utils::Program& program,
21803 std::stringstream& out_stream)
21805 const GLuint gohan_id = program.GetResourceIndex("gohan", GL_TRANSFORM_FEEDBACK_VARYING);
21806 const GLuint goten_id = program.GetResourceIndex("goten", GL_TRANSFORM_FEEDBACK_VARYING);
21807 const GLuint chichi_id = program.GetResourceIndex("chichi", GL_TRANSFORM_FEEDBACK_VARYING);
21809 GLint gohan_offset = 0;
21810 GLint goten_offset = 0;
21811 GLint chichi_offset = 0;
21813 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, gohan_id, GL_OFFSET, 1, &gohan_offset);
21814 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, goten_id, GL_OFFSET, 1, &goten_offset);
21815 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, chichi_id, GL_OFFSET, 1, &chichi_offset);
21817 // the xfb_offset of "chichi" should be 32
21818 if ((0 != gohan_offset) || (16 != goten_offset) || (32 != chichi_offset))
21820 out_stream << "Got wrong offset: [" << gohan_offset << ", " << goten_offset << ", " << chichi_offset
21821 << "] expected: [0, 16, 48]";
21830 * @param context Test framework context
21832 XFBDuplicatedStrideTest::XFBDuplicatedStrideTest(deqp::Context& context)
21833 : NegativeTestBase(context, "xfb_duplicated_stride",
21834 "Test verifies that compiler reports error when conflicting stride qualifiers are used")
21838 /** Source for given test case and stage
21840 * @param test_case_index Index of test case
21841 * @param stage Shader stage
21843 * @return Shader source
21845 std::string XFBDuplicatedStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
21847 static const GLchar* invalid_var_definition = "const uint valid_stride = 64;\n"
21848 "const uint conflicting_stride = 128;\n"
21850 "layout (xfb_buffer = 0, xfb_stride = valid_stride) out;\n"
21851 "layout (xfb_buffer = 0, xfb_stride = conflicting_stride) out;\n";
21852 static const GLchar* valid_var_definition = "const uint valid_stride = 64;\n"
21854 "layout (xfb_buffer = 0, xfb_stride = valid_stride) out;\n"
21855 "layout (xfb_buffer = 0, xfb_stride = valid_stride) out;\n";
21856 static const GLchar* fs = "#version 430 core\n"
21857 "#extension GL_ARB_enhanced_layouts : require\n"
21859 "in vec4 any_fs;\n"
21860 "out vec4 fs_out;\n"
21864 " fs_out = any_fs;\n"
21867 static const GLchar* gs_tested = "#version 430 core\n"
21868 "#extension GL_ARB_enhanced_layouts : require\n"
21870 "layout(points) in;\n"
21871 "layout(triangle_strip, max_vertices = 4) out;\n"
21875 "in vec4 vs_any[];\n"
21876 "out vec4 any_fs;\n"
21880 " vec4 result = vs_any[0];\n"
21884 " any_fs = result;\n"
21885 " gl_Position = vec4(-1, -1, 0, 1);\n"
21887 " any_fs = result;\n"
21888 " gl_Position = vec4(-1, 1, 0, 1);\n"
21890 " any_fs = result;\n"
21891 " gl_Position = vec4(1, -1, 0, 1);\n"
21893 " any_fs = result;\n"
21894 " gl_Position = vec4(1, 1, 0, 1);\n"
21898 static const GLchar* tcs = "#version 430 core\n"
21899 "#extension GL_ARB_enhanced_layouts : require\n"
21901 "layout(vertices = 1) out;\n"
21903 "in vec4 vs_any[];\n"
21904 "out vec4 tcs_tes[];\n"
21909 " tcs_tes[gl_InvocationID] = vs_any[gl_InvocationID];\n"
21911 " gl_TessLevelOuter[0] = 1.0;\n"
21912 " gl_TessLevelOuter[1] = 1.0;\n"
21913 " gl_TessLevelOuter[2] = 1.0;\n"
21914 " gl_TessLevelOuter[3] = 1.0;\n"
21915 " gl_TessLevelInner[0] = 1.0;\n"
21916 " gl_TessLevelInner[1] = 1.0;\n"
21919 static const GLchar* tcs_tested = "#version 430 core\n"
21920 "#extension GL_ARB_enhanced_layouts : require\n"
21922 "layout(vertices = 1) out;\n"
21926 "in vec4 vs_any[];\n"
21927 "out vec4 any_fs[];\n"
21931 " vec4 result = vs_any[gl_InvocationID];\n"
21935 " any_fs[gl_InvocationID] = result;\n"
21937 " gl_TessLevelOuter[0] = 1.0;\n"
21938 " gl_TessLevelOuter[1] = 1.0;\n"
21939 " gl_TessLevelOuter[2] = 1.0;\n"
21940 " gl_TessLevelOuter[3] = 1.0;\n"
21941 " gl_TessLevelInner[0] = 1.0;\n"
21942 " gl_TessLevelInner[1] = 1.0;\n"
21945 static const GLchar* tes_tested = "#version 430 core\n"
21946 "#extension GL_ARB_enhanced_layouts : require\n"
21948 "layout(isolines, point_mode) in;\n"
21952 "in vec4 tcs_tes[];\n"
21953 "out vec4 any_fs;\n"
21957 " vec4 result = tcs_tes[0];\n"
21961 " any_fs = result;\n"
21964 static const GLchar* vs = "#version 430 core\n"
21965 "#extension GL_ARB_enhanced_layouts : require\n"
21968 "out vec4 vs_any;\n"
21972 " vs_any = in_vs;\n"
21975 static const GLchar* vs_tested = "#version 430 core\n"
21976 "#extension GL_ARB_enhanced_layouts : require\n"
21981 "out vec4 any_fs;\n"
21985 " vec4 result = in_vs;\n"
21989 " any_fs += result;\n"
21993 std::string source;
21994 testCase& test_case = m_test_cases[test_case_index];
21996 if (test_case.m_stage == stage)
21998 size_t position = 0;
21999 const GLchar* var_definition = 0;
22000 const GLchar* var_use = "";
22002 switch (test_case.m_case)
22005 var_definition = valid_var_definition;
22008 var_definition = invalid_var_definition;
22011 TCU_FAIL("Invalid enum");
22016 case Utils::Shader::GEOMETRY:
22017 source = gs_tested;
22019 case Utils::Shader::TESS_CTRL:
22020 source = tcs_tested;
22022 case Utils::Shader::TESS_EVAL:
22023 source = tes_tested;
22025 case Utils::Shader::VERTEX:
22026 source = vs_tested;
22029 TCU_FAIL("Invalid enum");
22032 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
22033 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
22037 switch (test_case.m_stage)
22039 case Utils::Shader::GEOMETRY:
22042 case Utils::Shader::FRAGMENT:
22045 case Utils::Shader::VERTEX:
22052 case Utils::Shader::TESS_CTRL:
22055 case Utils::Shader::FRAGMENT:
22058 case Utils::Shader::VERTEX:
22065 case Utils::Shader::TESS_EVAL:
22068 case Utils::Shader::FRAGMENT:
22071 case Utils::Shader::TESS_CTRL:
22074 case Utils::Shader::VERTEX:
22081 case Utils::Shader::VERTEX:
22084 case Utils::Shader::FRAGMENT:
22092 TCU_FAIL("Invalid enum");
22100 /** Get description of test case
22102 * @param test_case_index Index of test case
22104 * @return Test case description
22106 std::string XFBDuplicatedStrideTest::getTestCaseName(GLuint test_case_index)
22108 std::stringstream stream;
22109 testCase& test_case = m_test_cases[test_case_index];
22111 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", case: ";
22113 switch (test_case.m_case)
22119 stream << "invalid";
22122 TCU_FAIL("Invalid enum");
22125 return stream.str();
22128 /** Get number of test cases
22130 * @return Number of test cases
22132 GLuint XFBDuplicatedStrideTest::getTestCaseNumber()
22134 return static_cast<GLuint>(m_test_cases.size());
22137 /** Selects if "compute" stage is relevant for test
22143 bool XFBDuplicatedStrideTest::isComputeRelevant(GLuint /* test_case_index */)
22148 /** Selects if compilation failure is expected result
22150 * @param test_case_index Index of test case
22154 bool XFBDuplicatedStrideTest::isFailureExpected(GLuint test_case_index)
22156 testCase& test_case = m_test_cases[test_case_index];
22158 return (INVALID == test_case.m_case);
22161 /** Prepare all test cases
22164 void XFBDuplicatedStrideTest::testInit()
22166 for (GLuint c = 0; c < CASE_MAX; ++c)
22168 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
22170 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
22171 (Utils::Shader::FRAGMENT == stage))
22176 testCase test_case = { (CASES)c, (Utils::Shader::STAGES)stage };
22178 m_test_cases.push_back(test_case);
22185 * @param context Test framework context
22187 XFBGetProgramResourceAPITest::XFBGetProgramResourceAPITest(deqp::Context& context)
22188 : TestBase(context, "xfb_get_program_resource_api",
22189 "Test verifies that get program resource reports correct results for XFB")
22193 /** Source for given test case and stage
22195 * @param test_case_index Index of test case
22196 * @param stage Shader stage
22198 * @return Shader source
22200 std::string XFBGetProgramResourceAPITest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
22202 static const GLchar* api_var_definition = "out TYPE b0_v1ARRAY;\n"
22203 "out TYPE b1_v1ARRAY;\n"
22204 "out TYPE b0_v3ARRAY;\n"
22205 "out TYPE b0_v0ARRAY;\n";
22206 static const GLchar* xfb_var_definition =
22207 "const uint type_size = SIZE;\n"
22209 "layout (xfb_buffer = 1, xfb_stride = 4 * type_size) out;\n"
22211 "layout (xfb_buffer = 0, xfb_offset = 1 * type_size) out TYPE b0_v1ARRAY;\n"
22212 "layout (xfb_buffer = 1, xfb_offset = 1 * type_size) out TYPE b1_v1ARRAY;\n"
22213 "layout (xfb_buffer = 0, xfb_offset = 3 * type_size) out TYPE b0_v3ARRAY;\n"
22214 "layout (xfb_buffer = 0, xfb_offset = 0 * type_size) out TYPE b0_v0ARRAY;\n";
22215 static const GLchar* var_use = " b0_v1INDEX = TYPE(0);\n"
22216 " b1_v1INDEX = TYPE(1);\n"
22217 " b0_v3INDEX = TYPE(0);\n"
22218 " b0_v0INDEX = TYPE(1);\n"
22219 " if (vec4(0) == result)\n"
22221 " b0_v1INDEX = TYPE(1);\n"
22222 " b1_v1INDEX = TYPE(0);\n"
22223 " b0_v3INDEX = TYPE(1);\n"
22224 " b0_v0INDEX = TYPE(0);\n"
22226 static const GLchar* gs_tested =
22227 "#version 430 core\n"
22228 "#extension GL_ARB_enhanced_layouts : require\n"
22230 "layout(points) in;\n"
22231 "layout(triangle_strip, max_vertices = 4) out;\n"
22235 "out gl_PerVertex \n"
22237 " vec4 gl_Position; \n" // gl_Position must be redeclared in separable program mode
22239 "in vec4 tes_gs[];\n"
22240 "out vec4 gs_fs;\n"
22244 " vec4 result = tes_gs[0];\n"
22248 " gs_fs = result;\n"
22249 " gl_Position = vec4(-1, -1, 0, 1);\n"
22251 " gs_fs = result;\n"
22252 " gl_Position = vec4(-1, 1, 0, 1);\n"
22254 " gs_fs = result;\n"
22255 " gl_Position = vec4(1, -1, 0, 1);\n"
22257 " gs_fs = result;\n"
22258 " gl_Position = vec4(1, 1, 0, 1);\n"
22263 static const GLchar* tcs_tested =
22264 "#version 430 core\n"
22265 "#extension GL_ARB_enhanced_layouts : require\n"
22267 "layout(vertices = 1) out;\n"
22271 "in vec4 vs_tcs[];\n"
22272 "out vec4 tcs_tes[];\n"
22276 " vec4 result = vs_tcs[gl_InvocationID];\n"
22280 " tcs_tes[gl_InvocationID] = result;\n"
22282 " gl_TessLevelOuter[0] = 1.0;\n"
22283 " gl_TessLevelOuter[1] = 1.0;\n"
22284 " gl_TessLevelOuter[2] = 1.0;\n"
22285 " gl_TessLevelOuter[3] = 1.0;\n"
22286 " gl_TessLevelInner[0] = 1.0;\n"
22287 " gl_TessLevelInner[1] = 1.0;\n"
22291 static const GLchar* tes_tested = "#version 430 core\n"
22292 "#extension GL_ARB_enhanced_layouts : require\n"
22294 "layout(isolines, point_mode) in;\n"
22298 "in vec4 tcs_tes[];\n"
22299 "out vec4 tes_gs;\n"
22303 " vec4 result = tcs_tes[0];\n"
22307 " tes_gs = result;\n"
22310 static const GLchar* vs_tested = "#version 430 core\n"
22311 "#extension GL_ARB_enhanced_layouts : require\n"
22316 "out vec4 vs_tcs;\n"
22320 " vec4 result = in_vs;\n"
22324 " vs_tcs = result;\n"
22328 std::string source;
22329 const test_Case& test_case = m_test_cases[test_case_index];
22331 if (test_case.m_stage == stage)
22333 const GLchar* array = "";
22335 const GLchar* index = "";
22336 size_t position = 0;
22338 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
22339 const GLchar* var_definition = 0;
22341 sprintf(buffer, "%d", test_case.m_type.GetSize());
22343 if (XFB == test_case.m_case)
22345 var_definition = xfb_var_definition;
22349 var_definition = api_var_definition;
22352 // It is a compile time error to apply xfb_offset to the declaration of an unsized array(GLSL4.5 spec: Page73)
22353 // change array = "[]" to "[1]"
22356 case Utils::Shader::GEOMETRY:
22357 source = gs_tested;
22361 // It is invalid to output transform feedback varyings in tessellation control shader
22363 case Utils::Shader::TESS_CTRL:
22364 source = tcs_tested;
22366 index = "[gl_InvocationID]";
22369 case Utils::Shader::TESS_EVAL:
22370 source = tes_tested;
22374 case Utils::Shader::VERTEX:
22375 source = vs_tested;
22378 TCU_FAIL("Invalid enum");
22382 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
22383 if (XFB == test_case.m_case)
22386 Utils::replaceToken("SIZE", position, buffer, source);
22388 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
22390 Utils::replaceAllTokens("ARRAY", array, source);
22391 Utils::replaceAllTokens("INDEX", index, source);
22392 Utils::replaceAllTokens("TYPE", type_name, source);
22402 /** Get description of test case
22404 * @param test_case_index Index of test case
22406 * @return Test case description
22408 std::string XFBGetProgramResourceAPITest::getTestCaseName(GLuint test_case_index)
22410 std::stringstream stream;
22411 const test_Case& test_case = m_test_cases[test_case_index];
22413 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
22414 << ", type: " << test_case.m_type.GetGLSLTypeName() << ", case: ";
22416 switch (test_case.m_case)
22419 stream << "interleaved";
22422 stream << "separated";
22428 TCU_FAIL("Invalid enum");
22431 return stream.str();
22434 /** Get number of test cases
22436 * @return Number of test cases
22438 GLuint XFBGetProgramResourceAPITest::getTestCaseNumber()
22440 return static_cast<GLuint>(m_test_cases.size());
22443 /** Inspects program for offset, buffer index, buffer stride and type
22445 * @param test_case_index Index of test case
22446 * @param program Program to query
22448 * @return true if query results match expected values, false otherwise
22450 bool XFBGetProgramResourceAPITest::inspectProgram(glw::GLuint test_case_index, Utils::Program& program)
22452 GLint b0_stride = 0;
22453 GLint b1_stride = 0;
22454 GLint b0_v0_buf = 0;
22455 GLint b0_v0_offset = 0;
22456 GLint b0_v0_type = 0;
22457 GLint b0_v1_buf = 0;
22458 GLint b0_v1_offset = 0;
22459 GLint b0_v1_type = 0;
22460 GLint b0_v3_buf = 0;
22461 GLint b0_v3_offset = 0;
22462 GLint b0_v3_type = 0;
22463 GLint b1_v1_buf = 0;
22464 GLint b1_v1_offset = 0;
22465 GLint b1_v1_type = 0;
22466 const test_Case& test_case = m_test_cases[test_case_index];
22467 const GLenum type_enum = test_case.m_type.GetTypeGLenum();
22468 const GLint type_size = test_case.m_type.GetSize();
22470 GLuint b0_v0_index = program.GetResourceIndex("b0_v0", GL_TRANSFORM_FEEDBACK_VARYING);
22471 GLuint b0_v1_index = program.GetResourceIndex("b0_v1", GL_TRANSFORM_FEEDBACK_VARYING);
22472 GLuint b0_v3_index = program.GetResourceIndex("b0_v3", GL_TRANSFORM_FEEDBACK_VARYING);
22473 GLuint b1_v1_index = program.GetResourceIndex("b1_v1", GL_TRANSFORM_FEEDBACK_VARYING);
22475 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v0_index, GL_OFFSET, 1 /* buf_size */, &b0_v0_offset);
22476 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v1_index, GL_OFFSET, 1 /* buf_size */, &b0_v1_offset);
22477 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v3_index, GL_OFFSET, 1 /* buf_size */, &b0_v3_offset);
22478 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b1_v1_index, GL_OFFSET, 1 /* buf_size */, &b1_v1_offset);
22480 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v0_index, GL_TYPE, 1 /* buf_size */, &b0_v0_type);
22481 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v1_index, GL_TYPE, 1 /* buf_size */, &b0_v1_type);
22482 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v3_index, GL_TYPE, 1 /* buf_size */, &b0_v3_type);
22483 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b1_v1_index, GL_TYPE, 1 /* buf_size */, &b1_v1_type);
22485 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v0_index, GL_TRANSFORM_FEEDBACK_BUFFER_INDEX,
22486 1 /* buf_size */, &b0_v0_buf);
22487 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v1_index, GL_TRANSFORM_FEEDBACK_BUFFER_INDEX,
22488 1 /* buf_size */, &b0_v1_buf);
22489 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v3_index, GL_TRANSFORM_FEEDBACK_BUFFER_INDEX,
22490 1 /* buf_size */, &b0_v3_buf);
22491 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b1_v1_index, GL_TRANSFORM_FEEDBACK_BUFFER_INDEX,
22492 1 /* buf_size */, &b1_v1_buf);
22494 program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, b0_v0_buf, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE, 1 /* buf_size */,
22496 program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, b1_v1_buf, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE, 1 /* buf_size */,
22499 if (SEPARATED != test_case.m_case)
22501 return (((GLint)(4 * type_size) == b0_stride) && ((GLint)(4 * type_size) == b1_stride) &&
22502 ((GLint)(0) == b0_v0_buf) && ((GLint)(0 * type_size) == b0_v0_offset) &&
22503 ((GLint)(type_enum) == b0_v0_type) && ((GLint)(0) == b0_v1_buf) &&
22504 ((GLint)(1 * type_size) == b0_v1_offset) && ((GLint)(type_enum) == b0_v1_type) &&
22505 ((GLint)(0) == b0_v3_buf) && ((GLint)(3 * type_size) == b0_v3_offset) &&
22506 ((GLint)(type_enum) == b0_v3_type) && ((GLint)(1) == b1_v1_buf) &&
22507 ((GLint)(1 * type_size) == b1_v1_offset) && ((GLint)(type_enum) == b1_v1_type));
22511 return (((GLint)(1 * type_size) == b0_stride) && ((GLint)(1 * type_size) == b1_stride) &&
22512 ((GLint)(0) == b0_v0_buf) && ((GLint)(0) == b0_v0_offset) && ((GLint)(type_enum) == b0_v0_type) &&
22513 ((GLint)(1) == b0_v1_buf) && ((GLint)(0) == b0_v1_offset) && ((GLint)(type_enum) == b0_v1_type) &&
22514 ((GLint)(2) == b0_v3_buf) && ((GLint)(0) == b0_v3_offset) && ((GLint)(type_enum) == b0_v3_type) &&
22515 ((GLint)(3) == b1_v1_buf) && ((GLint)(0) == b1_v1_offset) && ((GLint)(type_enum) == b1_v1_type));
22519 /** Insert gl_SkipComponents
22521 * @param num_components How many gl_SkipComponents1 need to be inserted
22522 * @param varyings The transform feedback varyings string vector
22525 void XFBGetProgramResourceAPITest::insertSkipComponents(int num_components, Utils::Program::NameVector& varyings)
22527 int num_component_4 = num_components / 4;
22528 int num_component_1 = num_components % 4;
22529 for (int i = 0; i < num_component_4; i++)
22531 varyings.push_back("gl_SkipComponents4");
22533 switch (num_component_1)
22536 varyings.push_back("gl_SkipComponents1");
22539 varyings.push_back("gl_SkipComponents2");
22542 varyings.push_back("gl_SkipComponents3");
22551 * @param test_case_index Id of test case
22553 * @return true if test case pass, false otherwise
22555 bool XFBGetProgramResourceAPITest::testCase(GLuint test_case_index)
22557 const std::string& gs_source = getShaderSource(test_case_index, Utils::Shader::GEOMETRY);
22558 Utils::Program program(m_context);
22559 const std::string& tcs_source = getShaderSource(test_case_index, Utils::Shader::TESS_CTRL);
22560 const std::string& tes_source = getShaderSource(test_case_index, Utils::Shader::TESS_EVAL);
22561 const test_Case& test_case = m_test_cases[test_case_index];
22562 bool test_case_result = true;
22563 const std::string& vs_source = getShaderSource(test_case_index, Utils::Shader::VERTEX);
22565 // According to spec: gl_SkipComponents1 ~ gl_SkipComponents4 is treated as specifying a one- to four-component floating point output variables with undefined values.
22566 // 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.
22568 if (INTERLEAVED == test_case.m_case)
22571 layout (xfb_buffer = 0, xfb_offset = 1 * type_size) out type b0_v1;
22572 layout (xfb_buffer = 1, xfb_offset = 1 * type_size) out type b1_v1;
22573 layout (xfb_buffer = 0, xfb_offset = 3 * type_size) out type b0_v3;
22574 layout (xfb_buffer = 0, xfb_offset = 0 * type_size) out type b0_v0;
22576 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,
22577 we need to calculate how many "gl_SkipComponents" need to be inserted.
22579 Utils::Program::NameVector captured_varyings;
22580 captured_varyings.push_back("b0_v0");
22581 captured_varyings.push_back("b0_v1");
22582 // Compute how many gl_SkipComponents to be inserted
22583 int numComponents = test_case.m_type.GetSize() / 4;
22584 insertSkipComponents(numComponents, captured_varyings);
22585 captured_varyings.push_back("b0_v3");
22586 captured_varyings.push_back("gl_NextBuffer");
22587 insertSkipComponents(numComponents, captured_varyings);
22588 captured_varyings.push_back("b1_v1");
22589 insertSkipComponents(numComponents * 2, captured_varyings);
22591 program.Init("" /* cs */, "", gs_source, tcs_source, tes_source, vs_source, captured_varyings, true,
22592 true /* separable */);
22594 else if (SEPARATED == test_case.m_case)
22596 Utils::Program::NameVector captured_varyings;
22598 captured_varyings.push_back("b0_v0");
22599 captured_varyings.push_back("b0_v1");
22600 captured_varyings.push_back("b0_v3");
22601 captured_varyings.push_back("b1_v1");
22603 program.Init("" /* cs */, "", gs_source, tcs_source, tes_source, vs_source, captured_varyings, false,
22604 true /* separable */);
22609 program.Init("" /* cs */, "", gs_source, tcs_source, tes_source, vs_source, true /* separable */);
22612 test_case_result = inspectProgram(test_case_index, program);
22614 return test_case_result;
22617 /** Prepare all test cases
22620 void XFBGetProgramResourceAPITest::testInit()
22622 const Functions& gl = m_context.getRenderContext().getFunctions();
22623 const GLuint n_types = getTypesNumber();
22627 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_xfb_int);
22628 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
22630 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, &max_xfb_sep);
22631 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
22633 GLint max_varyings;
22634 gl.getIntegerv(GL_MAX_VARYING_COMPONENTS, &max_varyings);
22636 for (GLuint i = 0; i < n_types; ++i)
22638 // 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,
22639 // 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
22640 // shader valid, we can either skip the dmat4, dmat4x3 or query the implementation-dependent value MAX_VARYING_COMPONENTS before generating the shader
22641 // to guarantee the number of varying not exceeded.
22643 layout (xfb_buffer = 1, xfb_stride = 4 * type_size) out;
22644 layout (xfb_buffer = 0, xfb_offset = 1 * type_size) out type b0_v1;
22645 layout (xfb_buffer = 1, xfb_offset = 1 * type_size) out type b1_v1;
22646 layout (xfb_buffer = 0, xfb_offset = 3 * type_size) out type b0_v3;
22647 layout (xfb_buffer = 0, xfb_offset = 0 * type_size) out type b0_v0;
22651 if (i == 7 || i == 9)
22653 const Utils::Type& type = getType(i);
22654 if (4 * type.GetNumComponents() + 4 > (GLuint)max_varyings)
22658 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
22661 It is invalid to define transform feedback output in HS
22663 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
22664 (Utils::Shader::FRAGMENT == stage))
22669 test_Case test_case_int = { INTERLEAVED, (Utils::Shader::STAGES)stage, type };
22670 test_Case test_case_sep = { SEPARATED, (Utils::Shader::STAGES)stage, type };
22671 test_Case test_case_xfb = { XFB, (Utils::Shader::STAGES)stage, type };
22673 if ((int)type.GetSize() <= max_xfb_int)
22675 m_test_cases.push_back(test_case_xfb);
22676 m_test_cases.push_back(test_case_int);
22679 if ((int)type.GetSize() <= max_xfb_sep)
22681 m_test_cases.push_back(test_case_sep);
22689 * @param context Test context
22691 XFBOverrideQualifiersWithAPITest::XFBOverrideQualifiersWithAPITest(deqp::Context& context)
22692 : BufferTestBase(context, "xfb_override_qualifiers_with_api",
22693 "Test verifies that xfb_offset qualifier is not overriden with API")
22695 /* Nothing to be done here */
22698 /** Get descriptors of buffers necessary for test
22700 * @param test_case_index Index of test case
22701 * @param out_descriptors Descriptors of buffers used by test
22703 void XFBOverrideQualifiersWithAPITest::getBufferDescriptors(glw::GLuint test_case_index,
22704 bufferDescriptor::Vector& out_descriptors)
22706 const Utils::Type& type = getType(test_case_index);
22708 /* Test needs single uniform and xfb */
22709 out_descriptors.resize(2);
22711 /* Get references */
22712 bufferDescriptor& uniform = out_descriptors[0];
22713 bufferDescriptor& xfb = out_descriptors[1];
22716 uniform.m_index = 0;
22720 uniform.m_target = Utils::Buffer::Uniform;
22721 xfb.m_target = Utils::Buffer::Transform_feedback;
22724 const GLuint gen_start = Utils::s_rand;
22725 const std::vector<GLubyte>& vegeta_data = type.GenerateData();
22726 const std::vector<GLubyte>& trunks_data = type.GenerateData();
22727 const std::vector<GLubyte>& goku_data = type.GenerateData();
22728 const std::vector<GLubyte>& gohan_data = type.GenerateData();
22730 Utils::s_rand = gen_start;
22731 const std::vector<GLubyte>& vegeta_data_pck = type.GenerateDataPacked();
22733 The xfb varying goku is -0.375, it is expected to equal to xfb.m_expected_data[0], xfb.m_expected_data[0] is assigned from goku_data_pck(-0.5)
22734 how can make them equal ? is it as designed? Add the following statement, which can make sure goku_data_pck equals to goku_data
22736 const std::vector<GLubyte>& goku_data_pck = type.GenerateDataPacked();
22738 const GLuint type_size = static_cast<GLuint>(vegeta_data.size());
22739 const GLuint type_size_pck = static_cast<GLuint>(vegeta_data_pck.size());
22742 uniform.m_initial_data.resize(4 * type_size);
22743 memcpy(&uniform.m_initial_data[0] + 0, &vegeta_data[0], type_size);
22744 memcpy(&uniform.m_initial_data[0] + type_size, &trunks_data[0], type_size);
22745 memcpy(&uniform.m_initial_data[0] + 2 * type_size, &goku_data[0], type_size);
22746 memcpy(&uniform.m_initial_data[0] + 3 * type_size, &gohan_data[0], type_size);
22749 xfb.m_initial_data.resize(4 * type_size_pck);
22750 xfb.m_expected_data.resize(4 * type_size_pck);
22752 for (GLuint i = 0; i < 4 * type_size_pck; ++i)
22754 xfb.m_initial_data[i] = (glw::GLubyte)i;
22755 xfb.m_expected_data[i] = (glw::GLubyte)i;
22758 memcpy(&xfb.m_expected_data[0] + 0, &goku_data_pck[0], type_size_pck);
22759 memcpy(&xfb.m_expected_data[0] + 2 * type_size_pck, &vegeta_data_pck[0], type_size_pck);
22762 /** Get list of names of varyings that will be registered with TransformFeedbackVaryings
22765 * @param captured_varyings List of names
22767 void XFBOverrideQualifiersWithAPITest::getCapturedVaryings(glw::GLuint /* test_case_index */,
22768 Utils::Program::NameVector& captured_varyings)
22770 captured_varyings.resize(2);
22772 captured_varyings[0] = "trunks";
22773 captured_varyings[1] = "gohan";
22776 /** Get body of main function for given shader stage
22778 * @param test_case_index Index of test case
22779 * @param stage Shader stage
22780 * @param out_assignments Set to empty
22781 * @param out_calculations Set to empty
22783 void XFBOverrideQualifiersWithAPITest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
22784 std::string& out_assignments, std::string& out_calculations)
22786 out_calculations = "";
22788 static const GLchar* gs = " vegeta = uni_vegeta;\n"
22789 " trunks = uni_trunks;\n"
22790 " goku = uni_goku;\n"
22791 " gohan = uni_gohan;\n";
22792 static const GLchar* fs = " fs_out = vec4(0);\n"
22793 " if (TYPE(1) == gohan + goku + trunks + vegeta)\n"
22795 " fs_out = vec4(1);\n"
22798 const GLchar* assignments = "";
22801 case Utils::Shader::FRAGMENT:
22804 case Utils::Shader::GEOMETRY:
22811 out_assignments = assignments;
22813 if (Utils::Shader::FRAGMENT == stage)
22815 const Utils::Type& type = getType(test_case_index);
22817 Utils::replaceAllTokens("TYPE", type.GetGLSLTypeName(), out_assignments);
22821 /** Get interface of shader
22823 * @param test_case_index Index of test case
22824 * @param stage Shader stage
22825 * @param out_interface Set to ""
22827 void XFBOverrideQualifiersWithAPITest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
22828 std::string& out_interface)
22830 static const GLchar* gs = "const uint sizeof_type = SIZE;\n"
22832 "layout (xfb_offset = 2 * sizeof_type) flat out TYPE vegeta;\n"
22833 " flat out TYPE trunks;\n"
22834 "layout (xfb_offset = 0) flat out TYPE goku;\n"
22835 " flat out TYPE gohan;\n"
22838 There is no packing qualifier for uniform block gs_block, according to spec, it should be "shared" by default,
22839 the definition equals to "layout(binding=0, shared)", if the block is declared as shared, each block member will
22840 not be packed, and each block member's layout in memory is implementation dependent, so we can't use the API
22841 glBufferData() to update the UBO directly, we need to query each block member's offset first, then upload the
22842 data to the corresponding offset, otherwise we can't get the correct data from UBO; to make the test passed,
22843 we need to add the qualifier std140, and change the declaration as layout(binding=0, std140), which can make
22844 sure all the block members are packed and the application can upload the data by glBufferData() directly.
22846 "layout(binding = 0, std140) uniform gs_block {\n"
22847 " TYPE uni_vegeta;\n"
22848 " TYPE uni_trunks;\n"
22849 " TYPE uni_goku;\n"
22850 " TYPE uni_gohan;\n"
22852 static const GLchar* fs = "flat in TYPE vegeta;\n"
22853 "flat in TYPE trunks;\n"
22854 "flat in TYPE goku;\n"
22855 "flat in TYPE gohan;\n"
22857 "out vec4 fs_out;\n";
22859 const Utils::Type& type = getType(test_case_index);
22863 case Utils::Shader::FRAGMENT:
22864 out_interface = fs;
22866 case Utils::Shader::GEOMETRY:
22867 out_interface = gs;
22870 out_interface = "";
22874 if (Utils::Shader::GEOMETRY == stage)
22877 size_t position = 0;
22878 const GLuint type_size = type.GetSize();
22880 sprintf(buffer, "%d", type_size);
22882 Utils::replaceToken("SIZE", position, buffer, out_interface);
22885 Utils::replaceAllTokens("TYPE", type.GetGLSLTypeName(), out_interface);
22890 * @param test_case_index Index of test case
22892 * @return Name of type test in test_case_index
22894 std::string XFBOverrideQualifiersWithAPITest::getTestCaseName(glw::GLuint test_case_index)
22896 return getTypeName(test_case_index);
22899 /** Returns number of types to test
22901 * @return Number of types, 34
22903 glw::GLuint XFBOverrideQualifiersWithAPITest::getTestCaseNumber()
22905 return getTypesNumber();
22908 /** Inspects program to check if all resources are as expected
22910 * @param test_case_index Index of test case
22911 * @param program Program instance
22912 * @param out_stream Error message
22914 * @return true if everything is ok, false otherwise
22916 bool XFBOverrideQualifiersWithAPITest::inspectProgram(GLuint test_case_index, Utils::Program& program,
22917 std::stringstream& out_stream)
22920 const Utils::Type& type = getType(test_case_index);
22921 const GLuint type_size = type.GetSize();
22923 program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE,
22924 1 /* buf_size */, &stride);
22926 if ((GLint)(3 * type_size) != stride)
22928 out_stream << "Stride is: " << stride << " expected: " << (3 * type_size);
22938 * @param context Test context
22940 XFBVertexStreamsTest::XFBVertexStreamsTest(deqp::Context& context)
22941 : BufferTestBase(context, "xfb_vertex_streams",
22942 "Test verifies that xfb qualifier works with multiple output streams")
22944 /* Nothing to be done here */
22947 /** Get descriptors of buffers necessary for test
22950 * @param out_descriptors Descriptors of buffers used by test
22952 void XFBVertexStreamsTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
22953 bufferDescriptor::Vector& out_descriptors)
22955 const Utils::Type& type = Utils::Type::vec4;
22957 /* Test needs single uniform and three xfbs */
22958 out_descriptors.resize(4);
22960 /* Get references */
22961 bufferDescriptor& uniform = out_descriptors[0];
22962 bufferDescriptor& xfb_1 = out_descriptors[1];
22963 bufferDescriptor& xfb_2 = out_descriptors[2];
22964 bufferDescriptor& xfb_3 = out_descriptors[3];
22967 uniform.m_index = 0;
22973 uniform.m_target = Utils::Buffer::Uniform;
22974 xfb_1.m_target = Utils::Buffer::Transform_feedback;
22975 xfb_2.m_target = Utils::Buffer::Transform_feedback;
22976 xfb_3.m_target = Utils::Buffer::Transform_feedback;
22979 const std::vector<GLubyte>& goku_data = type.GenerateData();
22980 const std::vector<GLubyte>& gohan_data = type.GenerateData();
22981 const std::vector<GLubyte>& goten_data = type.GenerateData();
22982 const std::vector<GLubyte>& picolo_data = type.GenerateData();
22983 const std::vector<GLubyte>& vegeta_data = type.GenerateData();
22984 const std::vector<GLubyte>& bulma_data = type.GenerateData();
22986 const GLuint type_size = static_cast<GLuint>(vegeta_data.size());
22989 uniform.m_initial_data.resize(6 * type_size);
22990 memcpy(&uniform.m_initial_data[0] + 0, &goku_data[0], type_size);
22991 memcpy(&uniform.m_initial_data[0] + type_size, &gohan_data[0], type_size);
22992 memcpy(&uniform.m_initial_data[0] + 2 * type_size, &goten_data[0], type_size);
22993 memcpy(&uniform.m_initial_data[0] + 3 * type_size, &picolo_data[0], type_size);
22994 memcpy(&uniform.m_initial_data[0] + 4 * type_size, &vegeta_data[0], type_size);
22995 memcpy(&uniform.m_initial_data[0] + 5 * type_size, &bulma_data[0], type_size);
22998 static const GLuint xfb_stride = 64;
22999 xfb_1.m_initial_data.resize(xfb_stride);
23000 xfb_1.m_expected_data.resize(xfb_stride);
23001 xfb_2.m_initial_data.resize(xfb_stride);
23002 xfb_2.m_expected_data.resize(xfb_stride);
23003 xfb_3.m_initial_data.resize(xfb_stride);
23004 xfb_3.m_expected_data.resize(xfb_stride);
23006 for (GLuint i = 0; i < xfb_stride; ++i)
23008 xfb_1.m_initial_data[i] = (glw::GLubyte)i;
23009 xfb_1.m_expected_data[i] = (glw::GLubyte)i;
23010 xfb_2.m_initial_data[i] = (glw::GLubyte)i;
23011 xfb_2.m_expected_data[i] = (glw::GLubyte)i;
23012 xfb_3.m_initial_data[i] = (glw::GLubyte)i;
23013 xfb_3.m_expected_data[i] = (glw::GLubyte)i;
23016 memcpy(&xfb_1.m_expected_data[0] + 48, &goku_data[0], type_size);
23017 memcpy(&xfb_1.m_expected_data[0] + 32, &gohan_data[0], type_size);
23018 memcpy(&xfb_1.m_expected_data[0] + 16, &goten_data[0], type_size);
23019 memcpy(&xfb_3.m_expected_data[0] + 48, &picolo_data[0], type_size);
23020 memcpy(&xfb_3.m_expected_data[0] + 32, &vegeta_data[0], type_size);
23021 memcpy(&xfb_2.m_expected_data[0] + 32, &bulma_data[0], type_size);
23024 /** Get body of main function for given shader stage
23027 * @param stage Shader stage
23028 * @param out_assignments Set to empty
23029 * @param out_calculations Set to empty
23031 void XFBVertexStreamsTest::getShaderBody(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
23032 std::string& out_assignments, std::string& out_calculations)
23034 out_calculations = "";
23036 // the shader declares the output variables with different "stream" qualifier, to make the data can export to
23037 // each stream, we must call the function EmitStreamVertex() and EndStreamPrimitive() to make each vertex emitted
23038 // by the GS is assigned to specific stream.
23039 static const GLchar* gs = " goku = uni_goku;\n"
23040 " gohan = uni_gohan;\n"
23041 " goten = uni_goten;\n"
23042 " EmitStreamVertex(0);\n"
23043 " EndStreamPrimitive(0);\n"
23044 " picolo = uni_picolo;\n"
23045 " vegeta = uni_vegeta;\n"
23046 " EmitStreamVertex(1);\n"
23047 " EndStreamPrimitive(1);\n"
23048 " bulma = uni_bulma;\n"
23049 " EmitStreamVertex(2);\n"
23050 " EndStreamPrimitive(2);\n";
23052 static const GLchar* fs = " fs_out = gohan + goku + goten + picolo + vegeta + bulma;\n";
23054 const GLchar* assignments = "";
23057 case Utils::Shader::FRAGMENT:
23060 case Utils::Shader::GEOMETRY:
23067 out_assignments = assignments;
23070 /** Get interface of shader
23073 * @param stage Shader stage
23074 * @param out_interface Set to ""
23076 void XFBVertexStreamsTest::getShaderInterface(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
23077 std::string& out_interface)
23079 static const GLchar* gs = "layout (xfb_buffer = 1, xfb_stride = 64) out;\n"
23080 "layout (xfb_buffer = 2, xfb_stride = 64) out;\n"
23081 "layout (xfb_buffer = 3, xfb_stride = 64) out;\n"
23083 "layout (stream = 0, xfb_buffer = 1, xfb_offset = 48) out vec4 goku;\n"
23084 "layout (stream = 0, xfb_buffer = 1, xfb_offset = 32) out vec4 gohan;\n"
23085 "layout (stream = 0, xfb_buffer = 1, xfb_offset = 16) out vec4 goten;\n"
23086 "layout (stream = 1, xfb_buffer = 3, xfb_offset = 48) out vec4 picolo;\n"
23087 "layout (stream = 1, xfb_buffer = 3, xfb_offset = 32) out vec4 vegeta;\n"
23088 "layout (stream = 2, xfb_buffer = 2, xfb_offset = 32) out vec4 bulma;\n"
23090 "layout(binding = 0) uniform gs_block {\n"
23091 " vec4 uni_goku;\n"
23092 " vec4 uni_gohan;\n"
23093 " vec4 uni_goten;\n"
23094 " vec4 uni_picolo;\n"
23095 " vec4 uni_vegeta;\n"
23096 " vec4 uni_bulma;\n"
23099 Fixed incorrect usage of in/out qualifier, the following variable should be input symbols for fragment shader
23101 static const GLchar* fs = "in vec4 goku;\n"
23104 "in vec4 picolo;\n"
23105 "in vec4 vegeta;\n"
23108 "out vec4 fs_out;\n";
23112 case Utils::Shader::FRAGMENT:
23113 out_interface = fs;
23115 case Utils::Shader::GEOMETRY:
23116 out_interface = gs;
23119 out_interface = "";
23126 * @param context Test framework context
23128 XFBMultipleVertexStreamsTest::XFBMultipleVertexStreamsTest(deqp::Context& context)
23129 : NegativeTestBase(
23130 context, "xfb_multiple_vertex_streams",
23131 "Test verifies that compiler reports error when multiple streams are captured with same xfb_buffer")
23135 /** Source for given test case and stage
23138 * @param stage Shader stage
23140 * @return Shader source
23142 std::string XFBMultipleVertexStreamsTest::getShaderSource(GLuint /* test_case_index */, Utils::Shader::STAGES stage)
23144 static const GLchar* var_definition = "const uint valid_stride = 64;\n"
23146 "layout (xfb_buffer = 1, xfb_stride = valid_stride) out;\n"
23147 "layout (xfb_buffer = 3, xfb_stride = valid_stride) out;\n"
23150 "layout (stream = 0, xfb_buffer = 1, xfb_offset = 48) out vec4 goku;\n"
23151 "layout (stream = 1, xfb_buffer = 1, xfb_offset = 32) out vec4 gohan;\n"
23152 "layout (stream = 2, xfb_buffer = 1, xfb_offset = 16) out vec4 goten;\n";
23153 static const GLchar* var_use = " goku = result / 2;\n"
23154 " gohan = result / 4;\n"
23155 " goten = result / 6;\n";
23156 static const GLchar* fs = "#version 430 core\n"
23157 "#extension GL_ARB_enhanced_layouts : require\n"
23161 "out vec4 fs_out;\n"
23165 " fs_out = gs_fs + goku;\n"
23168 static const GLchar* gs = "#version 430 core\n"
23169 "#extension GL_ARB_enhanced_layouts : require\n"
23171 "layout(points) in;\n"
23172 "layout(triangle_strip, max_vertices = 4) out;\n"
23176 "in vec4 tes_gs[];\n"
23177 "out vec4 gs_fs;\n"
23181 " vec4 result = tes_gs[0];\n"
23185 " gs_fs = result;\n"
23186 " gl_Position = vec4(-1, -1, 0, 1);\n"
23188 " gs_fs = result;\n"
23189 " gl_Position = vec4(-1, 1, 0, 1);\n"
23191 " gs_fs = result;\n"
23192 " gl_Position = vec4(1, -1, 0, 1);\n"
23194 " gs_fs = result;\n"
23195 " gl_Position = vec4(1, 1, 0, 1);\n"
23199 static const GLchar* vs = "#version 430 core\n"
23200 "#extension GL_ARB_enhanced_layouts : require\n"
23203 "out vec4 vs_tcs;\n"
23207 " vs_tcs = in_vs;\n"
23211 std::string source;
23213 if (Utils::Shader::GEOMETRY == stage)
23215 size_t position = 0;
23219 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
23220 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
23226 case Utils::Shader::FRAGMENT:
23229 case Utils::Shader::VERTEX:
23240 /** Selects if "compute" stage is relevant for test
23246 bool XFBMultipleVertexStreamsTest::isComputeRelevant(GLuint /* test_case_index */)
23253 * @param context Test framework context
23255 XFBExceedBufferLimitTest::XFBExceedBufferLimitTest(deqp::Context& context)
23256 : NegativeTestBase(context, "xfb_exceed_buffer_limit",
23257 "Test verifies that compiler reports error when xfb_buffer qualifier exceeds limit")
23261 /** Source for given test case and stage
23263 * @param test_case_index Index of test case
23264 * @param stage Shader stage
23266 * @return Shader source
23268 std::string XFBExceedBufferLimitTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
23270 static const GLchar* block_var_definition = "const uint buffer_index = BUFFER;\n"
23272 "layout (xfb_buffer = buffer_index, xfb_offset = 0) out Goku {\n"
23275 static const GLchar* global_var_definition = "const uint buffer_index = BUFFER;\n"
23277 "layout (xfb_buffer = buffer_index) out;\n";
23278 static const GLchar* vector_var_definition = "const uint buffer_index = BUFFER;\n"
23280 "layout (xfb_buffer = buffer_index) out vec4 gokuARRAY;\n";
23281 static const GLchar* block_use = " gokuINDEX.member = result / 2;\n";
23282 static const GLchar* global_use = "";
23283 static const GLchar* vector_use = " gokuINDEX = result / 2;\n";
23284 static const GLchar* fs = "#version 430 core\n"
23285 "#extension GL_ARB_enhanced_layouts : require\n"
23288 "out vec4 fs_out;\n"
23292 " fs_out = gs_fs;\n"
23295 static const GLchar* gs_tested = "#version 430 core\n"
23296 "#extension GL_ARB_enhanced_layouts : require\n"
23298 "layout(points) in;\n"
23299 "layout(triangle_strip, max_vertices = 4) out;\n"
23303 "in vec4 tes_gs[];\n"
23304 "out vec4 gs_fs;\n"
23308 " vec4 result = tes_gs[0];\n"
23312 " gs_fs = result;\n"
23313 " gl_Position = vec4(-1, -1, 0, 1);\n"
23315 " gs_fs = result;\n"
23316 " gl_Position = vec4(-1, 1, 0, 1);\n"
23318 " gs_fs = result;\n"
23319 " gl_Position = vec4(1, -1, 0, 1);\n"
23321 " gs_fs = result;\n"
23322 " gl_Position = vec4(1, 1, 0, 1);\n"
23326 static const GLchar* tcs = "#version 430 core\n"
23327 "#extension GL_ARB_enhanced_layouts : require\n"
23329 "layout(vertices = 1) out;\n"
23331 "in vec4 vs_tcs[];\n"
23332 "out vec4 tcs_tes[];\n"
23337 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
23339 " gl_TessLevelOuter[0] = 1.0;\n"
23340 " gl_TessLevelOuter[1] = 1.0;\n"
23341 " gl_TessLevelOuter[2] = 1.0;\n"
23342 " gl_TessLevelOuter[3] = 1.0;\n"
23343 " gl_TessLevelInner[0] = 1.0;\n"
23344 " gl_TessLevelInner[1] = 1.0;\n"
23347 static const GLchar* tcs_tested = "#version 430 core\n"
23348 "#extension GL_ARB_enhanced_layouts : require\n"
23350 "layout(vertices = 1) out;\n"
23354 "in vec4 vs_tcs[];\n"
23355 "out vec4 tcs_tes[];\n"
23359 " vec4 result = vs_tcs[gl_InvocationID];\n"
23363 " tcs_tes[gl_InvocationID] = result;\n"
23365 " gl_TessLevelOuter[0] = 1.0;\n"
23366 " gl_TessLevelOuter[1] = 1.0;\n"
23367 " gl_TessLevelOuter[2] = 1.0;\n"
23368 " gl_TessLevelOuter[3] = 1.0;\n"
23369 " gl_TessLevelInner[0] = 1.0;\n"
23370 " gl_TessLevelInner[1] = 1.0;\n"
23373 static const GLchar* tes_tested = "#version 430 core\n"
23374 "#extension GL_ARB_enhanced_layouts : require\n"
23376 "layout(isolines, point_mode) in;\n"
23380 "in vec4 tcs_tes[];\n"
23381 "out vec4 tes_gs;\n"
23385 " vec4 result = tcs_tes[0];\n"
23389 " tes_gs += result;\n"
23392 static const GLchar* vs = "#version 430 core\n"
23393 "#extension GL_ARB_enhanced_layouts : require\n"
23396 "out vec4 vs_tcs;\n"
23400 " vs_tcs = in_vs;\n"
23403 static const GLchar* vs_tested = "#version 430 core\n"
23404 "#extension GL_ARB_enhanced_layouts : require\n"
23409 "out vec4 vs_tcs;\n"
23413 " vec4 result = in_vs;\n"
23417 " vs_tcs = result;\n"
23421 std::string source;
23422 testCase& test_case = m_test_cases[test_case_index];
23424 if (test_case.m_stage == stage)
23426 const GLchar* array = "";
23428 const Functions& gl = m_context.getRenderContext().getFunctions();
23429 const GLchar* index = "";
23430 GLint max_n_xfb = 0;
23431 size_t position = 0;
23433 const GLchar* var_definition = 0;
23434 const GLchar* var_use = 0;
23436 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_n_xfb);
23437 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
23439 sprintf(buffer, "%d", max_n_xfb);
23441 switch (test_case.m_case)
23444 var_definition = block_var_definition;
23445 var_use = block_use;
23448 var_definition = global_var_definition;
23449 var_use = global_use;
23452 var_definition = vector_var_definition;
23453 var_use = vector_use;
23456 TCU_FAIL("Invalid enum");
23461 case Utils::Shader::GEOMETRY:
23462 source = gs_tested;
23466 case Utils::Shader::TESS_CTRL:
23467 source = tcs_tested;
23469 index = "[gl_InvocationID]";
23471 case Utils::Shader::TESS_EVAL:
23472 source = tes_tested;
23476 case Utils::Shader::VERTEX:
23477 source = vs_tested;
23480 TCU_FAIL("Invalid enum");
23484 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
23486 Utils::replaceToken("BUFFER", position, buffer, source);
23487 if (GLOBAL != test_case.m_case)
23489 Utils::replaceToken("ARRAY", position, array, source);
23491 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
23493 Utils::replaceAllTokens("INDEX", index, source);
23497 switch (test_case.m_stage)
23499 case Utils::Shader::GEOMETRY:
23502 case Utils::Shader::FRAGMENT:
23505 case Utils::Shader::VERTEX:
23512 case Utils::Shader::TESS_CTRL:
23515 case Utils::Shader::FRAGMENT:
23518 case Utils::Shader::VERTEX:
23525 case Utils::Shader::TESS_EVAL:
23528 case Utils::Shader::FRAGMENT:
23531 case Utils::Shader::TESS_CTRL:
23534 case Utils::Shader::VERTEX:
23541 case Utils::Shader::VERTEX:
23544 case Utils::Shader::FRAGMENT:
23552 TCU_FAIL("Invalid enum");
23560 /** Get description of test case
23562 * @param test_case_index Index of test case
23564 * @return Test case description
23566 std::string XFBExceedBufferLimitTest::getTestCaseName(GLuint test_case_index)
23568 std::stringstream stream;
23569 testCase& test_case = m_test_cases[test_case_index];
23571 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", case: ";
23573 switch (test_case.m_case)
23579 stream << "GLOBAL";
23582 stream << "VECTOR";
23585 TCU_FAIL("Invalid enum");
23588 return stream.str();
23591 /** Get number of test cases
23593 * @return Number of test cases
23595 GLuint XFBExceedBufferLimitTest::getTestCaseNumber()
23597 return static_cast<GLuint>(m_test_cases.size());
23600 /** Selects if "compute" stage is relevant for test
23606 bool XFBExceedBufferLimitTest::isComputeRelevant(GLuint /* test_case_index */)
23611 /** Prepare all test cases
23614 void XFBExceedBufferLimitTest::testInit()
23616 for (GLuint c = 0; c < CASE_MAX; ++c)
23618 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
23620 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
23621 (Utils::Shader::FRAGMENT == stage))
23626 testCase test_case = { (CASES)c, (Utils::Shader::STAGES)stage };
23628 m_test_cases.push_back(test_case);
23635 * @param context Test framework context
23637 XFBExceedOffsetLimitTest::XFBExceedOffsetLimitTest(deqp::Context& context)
23638 : NegativeTestBase(context, "xfb_exceed_offset_limit",
23639 "Test verifies that compiler reports error when xfb_offset qualifier exceeds limit")
23643 /** Source for given test case and stage
23645 * @param test_case_index Index of test case
23646 * @param stage Shader stage
23648 * @return Shader source
23650 std::string XFBExceedOffsetLimitTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
23652 static const GLchar* block_var_definition = "const uint max_size = SIZE;\n"
23654 "layout (xfb_buffer = 0, xfb_offset = max_size + 16) out Goku {\n"
23657 static const GLchar* global_var_definition = "const uint max_size = SIZE;\n"
23659 "layout (xfb_buffer = 0, xfb_stride = max_size + 16) out;\n";
23660 static const GLchar* vector_var_definition =
23661 "const uint max_size = SIZE;\n"
23663 "layout (xfb_buffer = 0, xfb_offset = max_size + 16) out vec4 gokuARRAY;\n";
23664 static const GLchar* block_use = " gokuINDEX.member = result / 2;\n";
23665 static const GLchar* global_use = "";
23666 static const GLchar* vector_use = " gokuINDEX = result / 2;\n";
23667 static const GLchar* fs = "#version 430 core\n"
23668 "#extension GL_ARB_enhanced_layouts : require\n"
23671 "out vec4 fs_out;\n"
23675 " fs_out = gs_fs;\n"
23678 static const GLchar* gs_tested = "#version 430 core\n"
23679 "#extension GL_ARB_enhanced_layouts : require\n"
23681 "layout(points) in;\n"
23682 "layout(triangle_strip, max_vertices = 4) out;\n"
23686 "in vec4 tes_gs[];\n"
23687 "out vec4 gs_fs;\n"
23691 " vec4 result = tes_gs[0];\n"
23695 " gs_fs = result;\n"
23696 " gl_Position = vec4(-1, -1, 0, 1);\n"
23698 " gs_fs = result;\n"
23699 " gl_Position = vec4(-1, 1, 0, 1);\n"
23701 " gs_fs = result;\n"
23702 " gl_Position = vec4(1, -1, 0, 1);\n"
23704 " gs_fs = result;\n"
23705 " gl_Position = vec4(1, 1, 0, 1);\n"
23709 static const GLchar* tcs = "#version 430 core\n"
23710 "#extension GL_ARB_enhanced_layouts : require\n"
23712 "layout(vertices = 1) out;\n"
23714 "in vec4 vs_tcs[];\n"
23715 "out vec4 tcs_tes[];\n"
23720 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
23722 " gl_TessLevelOuter[0] = 1.0;\n"
23723 " gl_TessLevelOuter[1] = 1.0;\n"
23724 " gl_TessLevelOuter[2] = 1.0;\n"
23725 " gl_TessLevelOuter[3] = 1.0;\n"
23726 " gl_TessLevelInner[0] = 1.0;\n"
23727 " gl_TessLevelInner[1] = 1.0;\n"
23730 static const GLchar* tcs_tested = "#version 430 core\n"
23731 "#extension GL_ARB_enhanced_layouts : require\n"
23733 "layout(vertices = 1) out;\n"
23737 "in vec4 vs_tcs[];\n"
23738 "out vec4 tcs_tes[];\n"
23742 " vec4 result = vs_tcs[gl_InvocationID];\n"
23746 " tcs_tes[gl_InvocationID] = result;\n"
23748 " gl_TessLevelOuter[0] = 1.0;\n"
23749 " gl_TessLevelOuter[1] = 1.0;\n"
23750 " gl_TessLevelOuter[2] = 1.0;\n"
23751 " gl_TessLevelOuter[3] = 1.0;\n"
23752 " gl_TessLevelInner[0] = 1.0;\n"
23753 " gl_TessLevelInner[1] = 1.0;\n"
23756 static const GLchar* tes_tested = "#version 430 core\n"
23757 "#extension GL_ARB_enhanced_layouts : require\n"
23759 "layout(isolines, point_mode) in;\n"
23763 "in vec4 tcs_tes[];\n"
23764 "out vec4 tes_gs;\n"
23768 " vec4 result = tcs_tes[0];\n"
23772 " tes_gs += result;\n"
23775 static const GLchar* vs = "#version 430 core\n"
23776 "#extension GL_ARB_enhanced_layouts : require\n"
23779 "out vec4 vs_tcs;\n"
23783 " vs_tcs = in_vs;\n"
23786 static const GLchar* vs_tested = "#version 430 core\n"
23787 "#extension GL_ARB_enhanced_layouts : require\n"
23792 "out vec4 vs_tcs;\n"
23796 " vec4 result = in_vs;\n"
23800 " vs_tcs = result;\n"
23804 std::string source;
23805 testCase& test_case = m_test_cases[test_case_index];
23807 if (test_case.m_stage == stage)
23809 const GLchar* array = "";
23811 const Functions& gl = m_context.getRenderContext().getFunctions();
23812 const GLchar* index = "";
23813 GLint max_n_xfb_comp = 0;
23814 GLint max_n_xfb_bytes = 0;
23815 size_t position = 0;
23817 const GLchar* var_definition = 0;
23818 const GLchar* var_use = 0;
23820 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_n_xfb_comp);
23821 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
23823 max_n_xfb_bytes = max_n_xfb_comp * 4;
23825 sprintf(buffer, "%d", max_n_xfb_bytes);
23827 switch (test_case.m_case)
23830 var_definition = block_var_definition;
23831 var_use = block_use;
23834 var_definition = global_var_definition;
23835 var_use = global_use;
23838 var_definition = vector_var_definition;
23839 var_use = vector_use;
23842 TCU_FAIL("Invalid enum");
23844 // It is a compile time error to apply xfb_offset to the declaration of an unsized array(GLSL4.5 spec: Page73)
23845 // change array = "[]" to "[1]"
23848 case Utils::Shader::GEOMETRY:
23849 source = gs_tested;
23853 case Utils::Shader::TESS_CTRL:
23854 source = tcs_tested;
23856 index = "[gl_InvocationID]";
23858 case Utils::Shader::TESS_EVAL:
23859 source = tes_tested;
23863 case Utils::Shader::VERTEX:
23864 source = vs_tested;
23867 TCU_FAIL("Invalid enum");
23871 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
23873 Utils::replaceToken("SIZE", position, buffer, source);
23874 if (GLOBAL != test_case.m_case)
23876 Utils::replaceToken("ARRAY", position, array, source);
23878 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
23880 Utils::replaceAllTokens("INDEX", index, source);
23884 switch (test_case.m_stage)
23886 case Utils::Shader::GEOMETRY:
23889 case Utils::Shader::FRAGMENT:
23892 case Utils::Shader::VERTEX:
23899 case Utils::Shader::TESS_CTRL:
23902 case Utils::Shader::FRAGMENT:
23905 case Utils::Shader::VERTEX:
23912 case Utils::Shader::TESS_EVAL:
23915 case Utils::Shader::FRAGMENT:
23918 case Utils::Shader::TESS_CTRL:
23921 case Utils::Shader::VERTEX:
23928 case Utils::Shader::VERTEX:
23931 case Utils::Shader::FRAGMENT:
23939 TCU_FAIL("Invalid enum");
23947 /** Get description of test case
23949 * @param test_case_index Index of test case
23951 * @return Test case description
23953 std::string XFBExceedOffsetLimitTest::getTestCaseName(GLuint test_case_index)
23955 std::stringstream stream;
23956 testCase& test_case = m_test_cases[test_case_index];
23958 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", case: ";
23960 switch (test_case.m_case)
23966 stream << "GLOBAL";
23969 stream << "VECTOR";
23972 TCU_FAIL("Invalid enum");
23975 return stream.str();
23978 /** Get number of test cases
23980 * @return Number of test cases
23982 GLuint XFBExceedOffsetLimitTest::getTestCaseNumber()
23984 return static_cast<GLuint>(m_test_cases.size());
23987 /** Selects if "compute" stage is relevant for test
23993 bool XFBExceedOffsetLimitTest::isComputeRelevant(GLuint /* test_case_index */)
23998 /** Prepare all test cases
24001 void XFBExceedOffsetLimitTest::testInit()
24003 for (GLuint c = 0; c < CASE_MAX; ++c)
24005 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
24007 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
24008 (Utils::Shader::FRAGMENT == stage))
24013 testCase test_case = { (CASES)c, (Utils::Shader::STAGES)stage };
24015 m_test_cases.push_back(test_case);
24022 * @param context Test context
24024 XFBGlobalBufferTest::XFBGlobalBufferTest(deqp::Context& context)
24025 : BufferTestBase(context, "xfb_global_buffer", "Test verifies that global xfb_buffer qualifier is respected")
24027 /* Nothing to be done here */
24030 /** Get descriptors of buffers necessary for test
24032 * @param test_case_index Index of test case
24033 * @param out_descriptors Descriptors of buffers used by test
24035 void XFBGlobalBufferTest::getBufferDescriptors(glw::GLuint test_case_index, bufferDescriptor::Vector& out_descriptors)
24037 // the function "getType(test_case_index)" can't return correct data type, so change code as following:
24038 const Utils::Type& type = m_test_cases[test_case_index].m_type;
24040 /* Test needs single uniform and two xfbs */
24041 out_descriptors.resize(3);
24043 /* Get references */
24044 bufferDescriptor& uniform = out_descriptors[0];
24045 bufferDescriptor& xfb_1 = out_descriptors[1];
24046 bufferDescriptor& xfb_3 = out_descriptors[2];
24049 uniform.m_index = 0;
24054 uniform.m_target = Utils::Buffer::Uniform;
24055 xfb_1.m_target = Utils::Buffer::Transform_feedback;
24056 xfb_3.m_target = Utils::Buffer::Transform_feedback;
24059 const GLuint gen_start = Utils::s_rand;
24060 const std::vector<GLubyte>& chichi_data = type.GenerateData();
24061 const std::vector<GLubyte>& bulma_data = type.GenerateData();
24062 const std::vector<GLubyte>& trunks_data = type.GenerateData();
24063 const std::vector<GLubyte>& bra_data = type.GenerateData();
24064 const std::vector<GLubyte>& gohan_data = type.GenerateData();
24065 const std::vector<GLubyte>& goten_data = type.GenerateData();
24067 Utils::s_rand = gen_start;
24068 const std::vector<GLubyte>& chichi_data_pck = type.GenerateDataPacked();
24069 const std::vector<GLubyte>& bulma_data_pck = type.GenerateDataPacked();
24070 const std::vector<GLubyte>& trunks_data_pck = type.GenerateDataPacked();
24071 const std::vector<GLubyte>& bra_data_pck = type.GenerateDataPacked();
24072 const std::vector<GLubyte>& gohan_data_pck = type.GenerateDataPacked();
24073 const std::vector<GLubyte>& goten_data_pck = type.GenerateDataPacked();
24075 const GLuint type_size = static_cast<GLuint>(chichi_data.size());
24076 const GLuint type_size_pck = static_cast<GLuint>(chichi_data_pck.size());
24079 uniform.m_initial_data.resize(6 * type_size);
24080 memcpy(&uniform.m_initial_data[0] + 0, &chichi_data[0], type_size);
24081 memcpy(&uniform.m_initial_data[0] + type_size, &bulma_data[0], type_size);
24082 memcpy(&uniform.m_initial_data[0] + 2 * type_size, &trunks_data[0], type_size);
24083 memcpy(&uniform.m_initial_data[0] + 3 * type_size, &bra_data[0], type_size);
24084 memcpy(&uniform.m_initial_data[0] + 4 * type_size, &gohan_data[0], type_size);
24085 memcpy(&uniform.m_initial_data[0] + 5 * type_size, &goten_data[0], type_size);
24088 xfb_1.m_initial_data.resize(3 * type_size_pck);
24089 xfb_1.m_expected_data.resize(3 * type_size_pck);
24090 xfb_3.m_initial_data.resize(3 * type_size_pck);
24091 xfb_3.m_expected_data.resize(3 * type_size_pck);
24093 for (GLuint i = 0; i < 3 * type_size_pck; ++i)
24095 xfb_1.m_initial_data[i] = (glw::GLubyte)i;
24096 xfb_1.m_expected_data[i] = (glw::GLubyte)i;
24097 xfb_3.m_initial_data[i] = (glw::GLubyte)i;
24098 xfb_3.m_expected_data[i] = (glw::GLubyte)i;
24101 memcpy(&xfb_3.m_expected_data[0] + 2 * type_size_pck, &chichi_data_pck[0], type_size_pck);
24102 memcpy(&xfb_1.m_expected_data[0] + 0 * type_size_pck, &bulma_data_pck[0], type_size_pck);
24103 memcpy(&xfb_1.m_expected_data[0] + 1 * type_size_pck, &trunks_data_pck[0], type_size_pck);
24104 memcpy(&xfb_1.m_expected_data[0] + 2 * type_size_pck, &bra_data_pck[0], type_size_pck);
24105 memcpy(&xfb_3.m_expected_data[0] + 0 * type_size_pck, &gohan_data_pck[0], type_size_pck);
24106 memcpy(&xfb_3.m_expected_data[0] + 1 * type_size_pck, &goten_data_pck[0], type_size_pck);
24109 /** Source for given test case and stage
24111 * @param test_case_index Index of test case
24112 * @param stage Shader stage
24114 * @return Shader source
24116 std::string XFBGlobalBufferTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
24118 static const GLchar* fs =
24119 "#version 430 core\n"
24120 "#extension GL_ARB_enhanced_layouts : require\n"
24122 "flat in TYPE chichi;\n"
24123 "flat in TYPE bulma;\n"
24133 "out vec4 fs_out;\n"
24137 " fs_out = vec4(1);\n"
24138 " if (TYPE(1) != chichi + bulma + vegeta.trunk + vegeta.bra + goku.gohan + goku.goten)\n"
24140 " fs_out = vec4(0);\n"
24145 static const GLchar* gs = "#version 430 core\n"
24146 "#extension GL_ARB_enhanced_layouts : require\n"
24148 "layout(points) in;\n"
24149 "layout(points, max_vertices = 1) out;\n"
24160 static const GLchar* tcs = "#version 430 core\n"
24161 "#extension GL_ARB_enhanced_layouts : require\n"
24163 "layout(vertices = 1) out;\n"
24168 " gl_TessLevelOuter[0] = 1.0;\n"
24169 " gl_TessLevelOuter[1] = 1.0;\n"
24170 " gl_TessLevelOuter[2] = 1.0;\n"
24171 " gl_TessLevelOuter[3] = 1.0;\n"
24172 " gl_TessLevelInner[0] = 1.0;\n"
24173 " gl_TessLevelInner[1] = 1.0;\n"
24177 static const GLchar* tes = "#version 430 core\n"
24178 "#extension GL_ARB_enhanced_layouts : require\n"
24180 "layout(isolines, point_mode) in;\n"
24190 static const GLchar* vs = "#version 430 core\n"
24191 "#extension GL_ARB_enhanced_layouts : require\n"
24198 static const GLchar* vs_tested = "#version 430 core\n"
24199 "#extension GL_ARB_enhanced_layouts : require\n"
24209 std::string source;
24210 const _testCase& test_case = m_test_cases[test_case_index];
24211 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
24213 if (test_case.m_stage == stage)
24215 std::string assignments = " chichi = uni_chichi;\n"
24216 " bulma = uni_bulma;\n"
24217 " vegeta.trunk = uni_trunk;\n"
24218 " vegeta.bra = uni_bra;\n"
24219 " goku.gohan = uni_gohan;\n"
24220 " goku.goten = uni_goten;\n";
24222 std::string interface = "layout (xfb_buffer = 3) out;\n"
24224 "const uint type_size = SIZE;\n"
24226 "layout ( xfb_offset = 2 * type_size) flat out TYPE chichi;\n"
24227 "layout (xfb_buffer = 1, xfb_offset = 0) flat out TYPE bulma;\n"
24228 "layout (xfb_buffer = 1, xfb_offset = 1 * type_size) out Vegeta {\n"
24232 "layout ( xfb_offset = 0) out Goku {\n"
24237 // Uniform block must be declared with std140, otherwise each block member is not packed
24238 "layout(binding = 0, std140) uniform block {\n"
24239 " TYPE uni_chichi;\n"
24240 " TYPE uni_bulma;\n"
24241 " TYPE uni_trunk;\n"
24243 " TYPE uni_gohan;\n"
24244 " TYPE uni_goten;\n"
24247 /* Prepare interface string */
24250 size_t position = 0;
24251 const GLuint type_size = test_case.m_type.GetSize();
24253 sprintf(buffer, "%d", type_size);
24255 Utils::replaceToken("SIZE", position, buffer, interface);
24256 Utils::replaceAllTokens("TYPE", type_name, interface);
24261 case Utils::Shader::GEOMETRY:
24264 case Utils::Shader::TESS_EVAL:
24267 case Utils::Shader::VERTEX:
24268 source = vs_tested;
24271 TCU_FAIL("Invalid enum");
24274 /* Replace tokens */
24276 size_t position = 0;
24278 Utils::replaceToken("INTERFACE", position, interface.c_str(), source);
24279 Utils::replaceToken("ASSIGNMENTS", position, assignments.c_str(), source);
24284 switch (test_case.m_stage)
24286 case Utils::Shader::GEOMETRY:
24289 case Utils::Shader::FRAGMENT:
24291 Utils::replaceAllTokens("TYPE", type_name, source);
24293 case Utils::Shader::VERTEX:
24300 case Utils::Shader::TESS_EVAL:
24303 case Utils::Shader::FRAGMENT:
24305 Utils::replaceAllTokens("TYPE", type_name, source);
24307 case Utils::Shader::TESS_CTRL:
24310 case Utils::Shader::VERTEX:
24317 case Utils::Shader::VERTEX:
24320 case Utils::Shader::FRAGMENT:
24322 Utils::replaceAllTokens("TYPE", type_name, source);
24329 TCU_FAIL("Invalid enum");
24337 /** Get name of test case
24339 * @param test_case_index Index of test case
24341 * @return Name of case
24343 std::string XFBGlobalBufferTest::getTestCaseName(GLuint test_case_index)
24346 const _testCase& test_case = m_test_cases[test_case_index];
24348 name = "Tested stage: ";
24349 name.append(Utils::Shader::GetStageName(test_case.m_stage));
24350 name.append(". Tested type: ");
24351 name.append(test_case.m_type.GetGLSLTypeName());
24356 /** Get number of cases
24358 * @return Number of test cases
24360 GLuint XFBGlobalBufferTest::getTestCaseNumber()
24362 return static_cast<GLuint>(m_test_cases.size());
24365 /** Prepare set of test cases
24368 void XFBGlobalBufferTest::testInit()
24370 GLuint n_types = getTypesNumber();
24372 for (GLuint i = 0; i < n_types; ++i)
24374 const Utils::Type& type = getType(i);
24376 When the tfx varying is the following type, the number of output exceeds the gl_MaxVaryingComponents, which will
24377 cause a link time error.
24379 if (strcmp(type.GetGLSLTypeName(), "dmat3") == 0 || strcmp(type.GetGLSLTypeName(), "dmat4") == 0 ||
24380 strcmp(type.GetGLSLTypeName(), "dmat3x4") == 0 || strcmp(type.GetGLSLTypeName(), "dmat4x3") == 0)
24384 const _testCase test_cases[] = { { Utils::Shader::VERTEX, type },
24385 { Utils::Shader::GEOMETRY, type },
24386 { Utils::Shader::TESS_EVAL, type } };
24388 m_test_cases.push_back(test_cases[0]);
24389 m_test_cases.push_back(test_cases[1]);
24390 m_test_cases.push_back(test_cases[2]);
24396 * @param context Test context
24398 XFBStrideTest::XFBStrideTest(deqp::Context& context)
24399 : BufferTestBase(context, "xfb_stride", "Test verifies that correct stride is used for all types")
24401 /* Nothing to be done here */
24404 /** Execute drawArrays for single vertex
24406 * @param test_case_index
24410 bool XFBStrideTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
24412 const Functions& gl = m_context.getRenderContext().getFunctions();
24413 GLenum primitive_type = GL_PATCHES;
24414 const testCase& test_case = m_test_cases[test_case_index];
24416 if (Utils::Shader::VERTEX == test_case.m_stage)
24418 primitive_type = GL_POINTS;
24421 gl.disable(GL_RASTERIZER_DISCARD);
24422 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
24424 gl.beginTransformFeedback(GL_POINTS);
24425 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
24427 gl.drawArrays(primitive_type, 0 /* first */, 2 /* count */);
24428 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
24430 gl.endTransformFeedback();
24431 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
24436 /** Get descriptors of buffers necessary for test
24438 * @param test_case_index Index of test case
24439 * @param out_descriptors Descriptors of buffers used by test
24441 void XFBStrideTest::getBufferDescriptors(GLuint test_case_index, bufferDescriptor::Vector& out_descriptors)
24443 const testCase& test_case = m_test_cases[test_case_index];
24444 const Utils::Type& type = test_case.m_type;
24446 /* Test needs single uniform and xfb */
24447 out_descriptors.resize(2);
24449 /* Get references */
24450 bufferDescriptor& uniform = out_descriptors[0];
24451 bufferDescriptor& xfb = out_descriptors[1];
24454 uniform.m_index = 0;
24458 uniform.m_target = Utils::Buffer::Uniform;
24459 xfb.m_target = Utils::Buffer::Transform_feedback;
24462 const GLuint rand_start = Utils::s_rand;
24463 const std::vector<GLubyte>& uniform_data = type.GenerateData();
24465 Utils::s_rand = rand_start;
24466 const std::vector<GLubyte>& xfb_data = type.GenerateDataPacked();
24468 const GLuint uni_type_size = static_cast<GLuint>(uniform_data.size());
24469 const GLuint xfb_type_size = static_cast<GLuint>(xfb_data.size());
24471 Note: If xfb varying output from vertex shader, the variable "goku" will only output once to transform feedback buffer,
24472 if xfb varying output from TES or GS, because the input primitive type in TES is defined as "layout(isolines, point_mode) in;",
24473 the primitive type is line which make the variable "goku" will output twice to transform feedback buffer, so for vertex shader
24474 only one valid data should be initialized in xfb.m_expected_data
24476 const GLuint xfb_data_size = (test_case.m_stage == Utils::Shader::VERTEX) ? xfb_type_size : xfb_type_size * 2;
24478 uniform.m_initial_data.resize(uni_type_size);
24479 memcpy(&uniform.m_initial_data[0] + 0 * uni_type_size, &uniform_data[0], uni_type_size);
24482 xfb.m_initial_data.resize(xfb_data_size);
24483 xfb.m_expected_data.resize(xfb_data_size);
24485 for (GLuint i = 0; i < xfb_data_size; ++i)
24487 xfb.m_initial_data[i] = (glw::GLubyte)i;
24488 xfb.m_expected_data[i] = (glw::GLubyte)i;
24491 if (test_case.m_stage == Utils::Shader::VERTEX)
24493 memcpy(&xfb.m_expected_data[0] + 0 * xfb_type_size, &xfb_data[0], xfb_type_size);
24497 memcpy(&xfb.m_expected_data[0] + 0 * xfb_type_size, &xfb_data[0], xfb_type_size);
24498 memcpy(&xfb.m_expected_data[0] + 1 * xfb_type_size, &xfb_data[0], xfb_type_size);
24502 /** Get body of main function for given shader stage
24504 * @param test_case_index Index of test case
24505 * @param stage Shader stage
24506 * @param out_assignments Set to empty
24507 * @param out_calculations Set to empty
24509 void XFBStrideTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage, std::string& out_assignments,
24510 std::string& out_calculations)
24512 const testCase& test_case = m_test_cases[test_case_index];
24514 out_calculations = "";
24516 static const GLchar* vs_tes_gs = " goku = uni_goku;\n";
24517 static const GLchar* fs = " fs_out = vec4(1, 0.25, 0.5, 0.75);\n"
24518 " if (TYPE(0) == goku)\n"
24520 " fs_out = vec4(1, 0.75, 0.5, 0.5);\n"
24523 const GLchar* assignments = "";
24525 if (test_case.m_stage == stage)
24529 case Utils::Shader::GEOMETRY:
24530 assignments = vs_tes_gs;
24532 case Utils::Shader::TESS_EVAL:
24533 assignments = vs_tes_gs;
24535 case Utils::Shader::VERTEX:
24536 assignments = vs_tes_gs;
24539 TCU_FAIL("Invalid enum");
24546 case Utils::Shader::FRAGMENT:
24549 case Utils::Shader::GEOMETRY:
24550 case Utils::Shader::TESS_CTRL:
24551 case Utils::Shader::TESS_EVAL:
24552 case Utils::Shader::VERTEX:
24555 TCU_FAIL("Invalid enum");
24559 out_assignments = assignments;
24561 if (Utils::Shader::FRAGMENT == stage)
24563 Utils::replaceAllTokens("TYPE", test_case.m_type.GetGLSLTypeName(), out_assignments);
24567 /** Get interface of shader
24569 * @param test_case_index Index of test case
24570 * @param stage Shader stage
24571 * @param out_interface Set to ""
24573 void XFBStrideTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage, std::string& out_interface)
24575 static const GLchar* vs_tes_gs = "layout (xfb_offset = 0) FLAT out TYPE goku;\n"
24577 "layout(std140, binding = 0) uniform Goku {\n"
24578 " TYPE uni_goku;\n"
24580 static const GLchar* fs = "FLAT in TYPE goku;\n"
24582 "out vec4 fs_out;\n";
24584 const testCase& test_case = m_test_cases[test_case_index];
24585 const GLchar* interface = "";
24586 const GLchar* flat = "";
24588 if (test_case.m_stage == stage)
24592 case Utils::Shader::GEOMETRY:
24593 interface = vs_tes_gs;
24595 case Utils::Shader::TESS_EVAL:
24596 interface = vs_tes_gs;
24598 case Utils::Shader::VERTEX:
24599 interface = vs_tes_gs;
24602 TCU_FAIL("Invalid enum");
24609 case Utils::Shader::FRAGMENT:
24612 case Utils::Shader::GEOMETRY:
24613 case Utils::Shader::TESS_CTRL:
24614 case Utils::Shader::TESS_EVAL:
24615 case Utils::Shader::VERTEX:
24618 TCU_FAIL("Invalid enum");
24622 out_interface = interface;
24624 if (Utils::Type::Float != test_case.m_type.m_basic_type)
24629 Utils::replaceAllTokens("FLAT", flat, out_interface);
24630 Utils::replaceAllTokens("TYPE", test_case.m_type.GetGLSLTypeName(), out_interface);
24633 /** Get source code of shader
24635 * @param test_case_index Index of test case
24636 * @param stage Shader stage
24640 std::string XFBStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
24642 std::string source;
24643 const testCase& test_case = m_test_cases[test_case_index];
24645 switch (test_case.m_stage)
24647 case Utils::Shader::VERTEX:
24650 case Utils::Shader::FRAGMENT:
24651 case Utils::Shader::VERTEX:
24652 source = BufferTestBase::getShaderSource(test_case_index, stage);
24659 case Utils::Shader::TESS_EVAL:
24662 case Utils::Shader::FRAGMENT:
24663 case Utils::Shader::TESS_CTRL:
24664 case Utils::Shader::TESS_EVAL:
24665 case Utils::Shader::VERTEX:
24666 source = BufferTestBase::getShaderSource(test_case_index, stage);
24673 case Utils::Shader::GEOMETRY:
24674 source = BufferTestBase::getShaderSource(test_case_index, stage);
24678 TCU_FAIL("Invalid enum");
24686 /** Get name of test case
24688 * @param test_case_index Index of test case
24690 * @return Name of tested stage
24692 std::string XFBStrideTest::getTestCaseName(glw::GLuint test_case_index)
24694 std::stringstream stream;
24695 const testCase& test_case = m_test_cases[test_case_index];
24697 stream << "Type: " << test_case.m_type.GetGLSLTypeName()
24698 << ", stage: " << Utils::Shader::GetStageName(test_case.m_stage);
24700 return stream.str();
24703 /** Returns number of test cases
24707 glw::GLuint XFBStrideTest::getTestCaseNumber()
24709 return static_cast<GLuint>(m_test_cases.size());
24712 /** Prepare all test cases
24715 void XFBStrideTest::testInit()
24717 const GLuint n_types = getTypesNumber();
24719 for (GLuint i = 0; i < n_types; ++i)
24721 const Utils::Type& type = getType(i);
24723 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
24725 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::FRAGMENT == stage) ||
24726 (Utils::Shader::TESS_CTRL == stage))
24731 testCase test_case = { (Utils::Shader::STAGES)stage, type };
24733 m_test_cases.push_back(test_case);
24740 * @param context Test framework context
24742 XFBBlockMemberBufferTest::XFBBlockMemberBufferTest(deqp::Context& context)
24743 : NegativeTestBase(
24744 context, "xfb_block_member_buffer",
24745 "Test verifies that compiler reports error when block member has different xfb_buffer qualifier than buffer")
24749 /** Source for given test case and stage
24751 * @param test_case_index Index of test case
24752 * @param stage Shader stage
24754 * @return Shader source
24756 std::string XFBBlockMemberBufferTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
24758 static const GLchar* var_definition = "layout (xfb_offset = 0) out Goku {\n"
24760 " layout (xfb_buffer = 1) vec4 goten;\n"
24762 static const GLchar* var_use = " gokuINDEX.gohan = result / 2;\n"
24763 " gokuINDEX.goten = result / 4;\n";
24764 static const GLchar* fs = "#version 430 core\n"
24765 "#extension GL_ARB_enhanced_layouts : require\n"
24768 "out vec4 fs_out;\n"
24772 " fs_out = gs_fs;\n"
24775 static const GLchar* gs_tested = "#version 430 core\n"
24776 "#extension GL_ARB_enhanced_layouts : require\n"
24778 "layout(points) in;\n"
24779 "layout(triangle_strip, max_vertices = 4) out;\n"
24783 "in vec4 tes_gs[];\n"
24784 "out vec4 gs_fs;\n"
24788 " vec4 result = tes_gs[0];\n"
24792 " gs_fs = result;\n"
24793 " gl_Position = vec4(-1, -1, 0, 1);\n"
24795 " gs_fs = result;\n"
24796 " gl_Position = vec4(-1, 1, 0, 1);\n"
24798 " gs_fs = result;\n"
24799 " gl_Position = vec4(1, -1, 0, 1);\n"
24801 " gs_fs = result;\n"
24802 " gl_Position = vec4(1, 1, 0, 1);\n"
24806 static const GLchar* tcs = "#version 430 core\n"
24807 "#extension GL_ARB_enhanced_layouts : require\n"
24809 "layout(vertices = 1) out;\n"
24811 "in vec4 vs_tcs[];\n"
24812 "out vec4 tcs_tes[];\n"
24817 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
24819 " gl_TessLevelOuter[0] = 1.0;\n"
24820 " gl_TessLevelOuter[1] = 1.0;\n"
24821 " gl_TessLevelOuter[2] = 1.0;\n"
24822 " gl_TessLevelOuter[3] = 1.0;\n"
24823 " gl_TessLevelInner[0] = 1.0;\n"
24824 " gl_TessLevelInner[1] = 1.0;\n"
24827 static const GLchar* tcs_tested = "#version 430 core\n"
24828 "#extension GL_ARB_enhanced_layouts : require\n"
24830 "layout(vertices = 1) out;\n"
24834 "in vec4 vs_tcs[];\n"
24835 "out vec4 tcs_tes[];\n"
24839 " vec4 result = vs_tcs[gl_InvocationID];\n"
24843 " tcs_tes[gl_InvocationID] = result;\n"
24845 " gl_TessLevelOuter[0] = 1.0;\n"
24846 " gl_TessLevelOuter[1] = 1.0;\n"
24847 " gl_TessLevelOuter[2] = 1.0;\n"
24848 " gl_TessLevelOuter[3] = 1.0;\n"
24849 " gl_TessLevelInner[0] = 1.0;\n"
24850 " gl_TessLevelInner[1] = 1.0;\n"
24853 static const GLchar* tes_tested = "#version 430 core\n"
24854 "#extension GL_ARB_enhanced_layouts : require\n"
24856 "layout(isolines, point_mode) in;\n"
24860 "in vec4 tcs_tes[];\n"
24861 "out vec4 tes_gs;\n"
24865 " vec4 result = tcs_tes[0];\n"
24869 " tes_gs += result;\n"
24872 static const GLchar* vs = "#version 430 core\n"
24873 "#extension GL_ARB_enhanced_layouts : require\n"
24876 "out vec4 vs_tcs;\n"
24880 " vs_tcs = in_vs;\n"
24883 static const GLchar* vs_tested = "#version 430 core\n"
24884 "#extension GL_ARB_enhanced_layouts : require\n"
24889 "out vec4 vs_tcs;\n"
24893 " vec4 result = in_vs;\n"
24897 " vs_tcs = result;\n"
24901 std::string source;
24902 testCase& test_case = m_test_cases[test_case_index];
24904 if (test_case.m_stage == stage)
24906 const GLchar* array = "";
24907 const GLchar* index = "";
24908 size_t position = 0;
24912 case Utils::Shader::GEOMETRY:
24913 source = gs_tested;
24917 case Utils::Shader::TESS_CTRL:
24918 source = tcs_tested;
24920 index = "[gl_InvocationID]";
24922 case Utils::Shader::TESS_EVAL:
24923 source = tes_tested;
24927 case Utils::Shader::VERTEX:
24928 source = vs_tested;
24931 TCU_FAIL("Invalid enum");
24934 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
24936 Utils::replaceToken("ARRAY", position, array, source);
24937 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
24939 Utils::replaceAllTokens("INDEX", index, source);
24943 switch (test_case.m_stage)
24945 case Utils::Shader::GEOMETRY:
24948 case Utils::Shader::FRAGMENT:
24951 case Utils::Shader::VERTEX:
24958 case Utils::Shader::TESS_CTRL:
24961 case Utils::Shader::FRAGMENT:
24964 case Utils::Shader::VERTEX:
24971 case Utils::Shader::TESS_EVAL:
24974 case Utils::Shader::FRAGMENT:
24977 case Utils::Shader::TESS_CTRL:
24980 case Utils::Shader::VERTEX:
24987 case Utils::Shader::VERTEX:
24990 case Utils::Shader::FRAGMENT:
24998 TCU_FAIL("Invalid enum");
25006 /** Get description of test case
25008 * @param test_case_index Index of test case
25010 * @return Test case description
25012 std::string XFBBlockMemberBufferTest::getTestCaseName(GLuint test_case_index)
25014 std::stringstream stream;
25015 testCase& test_case = m_test_cases[test_case_index];
25017 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage);
25019 return stream.str();
25022 /** Get number of test cases
25024 * @return Number of test cases
25026 GLuint XFBBlockMemberBufferTest::getTestCaseNumber()
25028 return static_cast<GLuint>(m_test_cases.size());
25031 /** Selects if "compute" stage is relevant for test
25037 bool XFBBlockMemberBufferTest::isComputeRelevant(GLuint /* test_case_index */)
25042 /** Prepare all test cases
25045 void XFBBlockMemberBufferTest::testInit()
25047 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
25049 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
25050 (Utils::Shader::FRAGMENT == stage))
25055 testCase test_case = { (Utils::Shader::STAGES)stage };
25057 m_test_cases.push_back(test_case);
25063 * @param context Test framework context
25065 XFBOutputOverlappingTest::XFBOutputOverlappingTest(deqp::Context& context)
25066 : NegativeTestBase(context, "xfb_output_overlapping",
25067 "Test verifies that compiler reports error when two xfb qualified outputs overlap")
25071 /** Source for given test case and stage
25073 * @param test_case_index Index of test case
25074 * @param stage Shader stage
25076 * @return Shader source
25078 std::string XFBOutputOverlappingTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
25080 static const GLchar* var_definition = "layout (xfb_offset = OFFSET) out TYPE gohanARRAY;\n"
25081 "layout (xfb_offset = OFFSET) out TYPE gotenARRAY;\n";
25082 static const GLchar* var_use = " gohanINDEX = TYPE(0);\n"
25083 " gotenINDEX = TYPE(1);\n"
25084 " if (vec4(0) == result)\n"
25086 " gohanINDEX = TYPE(1);\n"
25087 " gotenINDEX = TYPE(0);\n"
25089 static const GLchar* fs = "#version 430 core\n"
25090 "#extension GL_ARB_enhanced_layouts : require\n"
25093 "out vec4 fs_out;\n"
25097 " fs_out = gs_fs;\n"
25100 static const GLchar* gs_tested = "#version 430 core\n"
25101 "#extension GL_ARB_enhanced_layouts : require\n"
25103 "layout(points) in;\n"
25104 "layout(triangle_strip, max_vertices = 4) out;\n"
25108 "in vec4 tes_gs[];\n"
25109 "out vec4 gs_fs;\n"
25113 " vec4 result = tes_gs[0];\n"
25117 " gs_fs = result;\n"
25118 " gl_Position = vec4(-1, -1, 0, 1);\n"
25120 " gs_fs = result;\n"
25121 " gl_Position = vec4(-1, 1, 0, 1);\n"
25123 " gs_fs = result;\n"
25124 " gl_Position = vec4(1, -1, 0, 1);\n"
25126 " gs_fs = result;\n"
25127 " gl_Position = vec4(1, 1, 0, 1);\n"
25131 static const GLchar* tcs = "#version 430 core\n"
25132 "#extension GL_ARB_enhanced_layouts : require\n"
25134 "layout(vertices = 1) out;\n"
25136 "in vec4 vs_tcs[];\n"
25137 "out vec4 tcs_tes[];\n"
25142 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
25144 " gl_TessLevelOuter[0] = 1.0;\n"
25145 " gl_TessLevelOuter[1] = 1.0;\n"
25146 " gl_TessLevelOuter[2] = 1.0;\n"
25147 " gl_TessLevelOuter[3] = 1.0;\n"
25148 " gl_TessLevelInner[0] = 1.0;\n"
25149 " gl_TessLevelInner[1] = 1.0;\n"
25152 static const GLchar* tcs_tested = "#version 430 core\n"
25153 "#extension GL_ARB_enhanced_layouts : require\n"
25155 "layout(vertices = 1) out;\n"
25159 "in vec4 vs_tcs[];\n"
25160 "out vec4 tcs_tes[];\n"
25164 " vec4 result = vs_tcs[gl_InvocationID];\n"
25168 " tcs_tes[gl_InvocationID] = result;\n"
25170 " gl_TessLevelOuter[0] = 1.0;\n"
25171 " gl_TessLevelOuter[1] = 1.0;\n"
25172 " gl_TessLevelOuter[2] = 1.0;\n"
25173 " gl_TessLevelOuter[3] = 1.0;\n"
25174 " gl_TessLevelInner[0] = 1.0;\n"
25175 " gl_TessLevelInner[1] = 1.0;\n"
25178 static const GLchar* tes_tested = "#version 430 core\n"
25179 "#extension GL_ARB_enhanced_layouts : require\n"
25181 "layout(isolines, point_mode) in;\n"
25185 "in vec4 tcs_tes[];\n"
25186 "out vec4 tes_gs;\n"
25190 " vec4 result = tcs_tes[0];\n"
25194 " tes_gs += result;\n"
25197 static const GLchar* vs = "#version 430 core\n"
25198 "#extension GL_ARB_enhanced_layouts : require\n"
25201 "out vec4 vs_tcs;\n"
25205 " vs_tcs = in_vs;\n"
25208 static const GLchar* vs_tested = "#version 430 core\n"
25209 "#extension GL_ARB_enhanced_layouts : require\n"
25214 "out vec4 vs_tcs;\n"
25218 " vec4 result = in_vs;\n"
25222 " vs_tcs = result;\n"
25226 std::string source;
25227 testCase& test_case = m_test_cases[test_case_index];
25229 if (test_case.m_stage == stage)
25231 const GLchar* array = "";
25232 GLchar buffer_gohan[16];
25233 GLchar buffer_goten[16];
25234 const GLchar* index = "";
25235 size_t position = 0;
25236 size_t position_start = 0;
25237 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
25239 sprintf(buffer_gohan, "%d", test_case.m_offset_gohan);
25240 sprintf(buffer_goten, "%d", test_case.m_offset_goten);
25244 case Utils::Shader::GEOMETRY:
25245 source = gs_tested;
25249 case Utils::Shader::TESS_CTRL:
25250 source = tcs_tested;
25252 index = "[gl_InvocationID]";
25254 case Utils::Shader::TESS_EVAL:
25255 source = tes_tested;
25259 case Utils::Shader::VERTEX:
25260 source = vs_tested;
25263 TCU_FAIL("Invalid enum");
25266 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
25268 Utils::replaceToken("OFFSET", position, buffer_gohan, source);
25269 Utils::replaceToken("TYPE", position, type_name, source);
25270 Utils::replaceToken("ARRAY", position, array, source);
25271 Utils::replaceToken("OFFSET", position, buffer_goten, source);
25272 Utils::replaceToken("TYPE", position, type_name, source);
25273 Utils::replaceToken("ARRAY", position, array, source);
25274 position_start = position;
25275 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
25276 position = position_start;
25277 Utils::replaceToken("INDEX", position, index, source);
25278 Utils::replaceToken("TYPE", position, type_name, source);
25279 Utils::replaceToken("INDEX", position, index, source);
25280 Utils::replaceToken("TYPE", position, type_name, source);
25281 Utils::replaceToken("INDEX", position, index, source);
25282 Utils::replaceToken("TYPE", position, type_name, source);
25283 Utils::replaceToken("INDEX", position, index, source);
25284 Utils::replaceToken("TYPE", position, type_name, source);
25288 switch (test_case.m_stage)
25290 case Utils::Shader::GEOMETRY:
25293 case Utils::Shader::FRAGMENT:
25296 case Utils::Shader::VERTEX:
25303 case Utils::Shader::TESS_CTRL:
25306 case Utils::Shader::FRAGMENT:
25309 case Utils::Shader::VERTEX:
25316 case Utils::Shader::TESS_EVAL:
25319 case Utils::Shader::FRAGMENT:
25322 case Utils::Shader::TESS_CTRL:
25325 case Utils::Shader::VERTEX:
25332 case Utils::Shader::VERTEX:
25335 case Utils::Shader::FRAGMENT:
25343 TCU_FAIL("Invalid enum");
25351 /** Get description of test case
25353 * @param test_case_index Index of test case
25355 * @return Test case description
25357 std::string XFBOutputOverlappingTest::getTestCaseName(GLuint test_case_index)
25359 std::stringstream stream;
25360 testCase& test_case = m_test_cases[test_case_index];
25362 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
25363 << ", type: " << test_case.m_type.GetGLSLTypeName() << ", offsets: " << test_case.m_offset_gohan << " & "
25364 << test_case.m_offset_goten;
25366 return stream.str();
25369 /** Get number of test cases
25371 * @return Number of test cases
25373 GLuint XFBOutputOverlappingTest::getTestCaseNumber()
25375 return static_cast<GLuint>(m_test_cases.size());
25378 /** Selects if "compute" stage is relevant for test
25384 bool XFBOutputOverlappingTest::isComputeRelevant(GLuint /* test_case_index */)
25389 /** Prepare all test cases
25392 void XFBOutputOverlappingTest::testInit()
25394 const GLuint n_types = getTypesNumber();
25396 for (GLuint i = 0; i < n_types; ++i)
25398 const Utils::Type& type = getType(i);
25399 const GLuint base_alingment = Utils::Type::GetTypeSize(type.m_basic_type);
25401 /* Skip scalars, not applicable as:
25403 * The offset must be a multiple of the size of the first component of the first
25404 * qualified variable or block member, or a compile-time error results.
25406 if ((1 == type.m_n_columns) && (1 == type.m_n_rows))
25411 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
25413 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
25414 (Utils::Shader::FRAGMENT == stage))
25419 testCase test_case = { 0 /* gohan offset */, base_alingment /* goten_offset */,
25420 (Utils::Shader::STAGES)stage, type };
25422 m_test_cases.push_back(test_case);
25429 * @param context Test framework context
25431 XFBInvalidOffsetAlignmentTest::XFBInvalidOffsetAlignmentTest(deqp::Context& context)
25432 : NegativeTestBase(context, "xfb_invalid_offset_alignment",
25433 "Test verifies that compiler reports error when xfb_offset has invalid alignment")
25437 /** Source for given test case and stage
25439 * @param test_case_index Index of test case
25440 * @param stage Shader stage
25442 * @return Shader source
25444 std::string XFBInvalidOffsetAlignmentTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
25446 static const GLchar* var_definition = "layout (xfb_offset = OFFSET) out TYPE gohanARRAY;\n";
25447 static const GLchar* var_use = " gohanINDEX = TYPE(0);\n"
25448 " if (vec4(0) == result)\n"
25450 " gohanINDEX = TYPE(1);\n"
25452 static const GLchar* fs = "#version 430 core\n"
25453 "#extension GL_ARB_enhanced_layouts : require\n"
25456 "out vec4 fs_out;\n"
25460 " fs_out = gs_fs;\n"
25463 static const GLchar* gs_tested = "#version 430 core\n"
25464 "#extension GL_ARB_enhanced_layouts : require\n"
25466 "layout(points) in;\n"
25467 "layout(triangle_strip, max_vertices = 4) out;\n"
25471 "in vec4 tes_gs[];\n"
25472 "out vec4 gs_fs;\n"
25476 " vec4 result = tes_gs[0];\n"
25480 " gs_fs = result;\n"
25481 " gl_Position = vec4(-1, -1, 0, 1);\n"
25483 " gs_fs = result;\n"
25484 " gl_Position = vec4(-1, 1, 0, 1);\n"
25486 " gs_fs = result;\n"
25487 " gl_Position = vec4(1, -1, 0, 1);\n"
25489 " gs_fs = result;\n"
25490 " gl_Position = vec4(1, 1, 0, 1);\n"
25494 static const GLchar* tcs = "#version 430 core\n"
25495 "#extension GL_ARB_enhanced_layouts : require\n"
25497 "layout(vertices = 1) out;\n"
25499 "in vec4 vs_tcs[];\n"
25500 "out vec4 tcs_tes[];\n"
25505 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
25507 " gl_TessLevelOuter[0] = 1.0;\n"
25508 " gl_TessLevelOuter[1] = 1.0;\n"
25509 " gl_TessLevelOuter[2] = 1.0;\n"
25510 " gl_TessLevelOuter[3] = 1.0;\n"
25511 " gl_TessLevelInner[0] = 1.0;\n"
25512 " gl_TessLevelInner[1] = 1.0;\n"
25515 static const GLchar* tcs_tested = "#version 430 core\n"
25516 "#extension GL_ARB_enhanced_layouts : require\n"
25518 "layout(vertices = 1) out;\n"
25522 "in vec4 vs_tcs[];\n"
25523 "out vec4 tcs_tes[];\n"
25527 " vec4 result = vs_tcs[gl_InvocationID];\n"
25531 " tcs_tes[gl_InvocationID] = result;\n"
25533 " gl_TessLevelOuter[0] = 1.0;\n"
25534 " gl_TessLevelOuter[1] = 1.0;\n"
25535 " gl_TessLevelOuter[2] = 1.0;\n"
25536 " gl_TessLevelOuter[3] = 1.0;\n"
25537 " gl_TessLevelInner[0] = 1.0;\n"
25538 " gl_TessLevelInner[1] = 1.0;\n"
25541 static const GLchar* tes_tested = "#version 430 core\n"
25542 "#extension GL_ARB_enhanced_layouts : require\n"
25544 "layout(isolines, point_mode) in;\n"
25548 "in vec4 tcs_tes[];\n"
25549 "out vec4 tes_gs;\n"
25553 " vec4 result = tcs_tes[0];\n"
25557 " tes_gs += result;\n"
25560 static const GLchar* vs = "#version 430 core\n"
25561 "#extension GL_ARB_enhanced_layouts : require\n"
25564 "out vec4 vs_tcs;\n"
25568 " vs_tcs = in_vs;\n"
25571 static const GLchar* vs_tested = "#version 430 core\n"
25572 "#extension GL_ARB_enhanced_layouts : require\n"
25577 "out vec4 vs_tcs;\n"
25581 " vec4 result = in_vs;\n"
25585 " vs_tcs = result;\n"
25589 std::string source;
25590 testCase& test_case = m_test_cases[test_case_index];
25592 if (test_case.m_stage == stage)
25594 const GLchar* array = "";
25596 const GLchar* index = "";
25597 size_t position = 0;
25598 size_t position_start = 0;
25599 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
25601 sprintf(buffer, "%d", test_case.m_offset);
25605 case Utils::Shader::GEOMETRY:
25606 source = gs_tested;
25610 case Utils::Shader::TESS_CTRL:
25611 source = tcs_tested;
25613 index = "[gl_InvocationID]";
25615 case Utils::Shader::TESS_EVAL:
25616 source = tes_tested;
25620 case Utils::Shader::VERTEX:
25621 source = vs_tested;
25624 TCU_FAIL("Invalid enum");
25627 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
25629 Utils::replaceToken("OFFSET", position, buffer, source);
25630 Utils::replaceToken("TYPE", position, type_name, source);
25631 Utils::replaceToken("ARRAY", position, array, source);
25632 position_start = position;
25633 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
25634 position = position_start;
25635 Utils::replaceToken("INDEX", position, index, source);
25636 Utils::replaceToken("TYPE", position, type_name, source);
25637 Utils::replaceToken("INDEX", position, index, source);
25638 Utils::replaceToken("TYPE", position, type_name, source);
25642 switch (test_case.m_stage)
25644 case Utils::Shader::GEOMETRY:
25647 case Utils::Shader::FRAGMENT:
25650 case Utils::Shader::VERTEX:
25657 case Utils::Shader::TESS_CTRL:
25660 case Utils::Shader::FRAGMENT:
25663 case Utils::Shader::VERTEX:
25670 case Utils::Shader::TESS_EVAL:
25673 case Utils::Shader::FRAGMENT:
25676 case Utils::Shader::TESS_CTRL:
25679 case Utils::Shader::VERTEX:
25686 case Utils::Shader::VERTEX:
25689 case Utils::Shader::FRAGMENT:
25697 TCU_FAIL("Invalid enum");
25705 /** Get description of test case
25707 * @param test_case_index Index of test case
25709 * @return Test case description
25711 std::string XFBInvalidOffsetAlignmentTest::getTestCaseName(GLuint test_case_index)
25713 std::stringstream stream;
25714 testCase& test_case = m_test_cases[test_case_index];
25716 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
25717 << ", type: " << test_case.m_type.GetGLSLTypeName() << ", offset: " << test_case.m_offset;
25719 return stream.str();
25722 /** Get number of test cases
25724 * @return Number of test cases
25726 GLuint XFBInvalidOffsetAlignmentTest::getTestCaseNumber()
25728 return static_cast<GLuint>(m_test_cases.size());
25731 /** Selects if "compute" stage is relevant for test
25737 bool XFBInvalidOffsetAlignmentTest::isComputeRelevant(GLuint /* test_case_index */)
25742 /** Prepare all test cases
25745 void XFBInvalidOffsetAlignmentTest::testInit()
25747 const GLuint n_types = getTypesNumber();
25749 for (GLuint i = 0; i < n_types; ++i)
25751 const Utils::Type& type = getType(i);
25752 const GLuint base_alingment = Utils::Type::GetTypeSize(type.m_basic_type);
25754 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
25756 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
25757 (Utils::Shader::FRAGMENT == stage))
25762 for (GLuint offset = base_alingment + 1; offset < 2 * base_alingment; ++offset)
25764 testCase test_case = { offset, (Utils::Shader::STAGES)stage, type };
25766 m_test_cases.push_back(test_case);
25774 * @param context Test context
25776 XFBCaptureInactiveOutputVariableTest::XFBCaptureInactiveOutputVariableTest(deqp::Context& context)
25777 : BufferTestBase(context, "xfb_capture_inactive_output_variable",
25778 "Test verifies that inactive variables are captured")
25780 /* Nothing to be done here */
25783 /** Execute drawArrays for single vertex
25785 * @param test_case_index
25789 bool XFBCaptureInactiveOutputVariableTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
25791 const Functions& gl = m_context.getRenderContext().getFunctions();
25792 GLenum primitive_type = GL_PATCHES;
25794 if (TEST_VS == test_case_index)
25796 primitive_type = GL_POINTS;
25799 gl.disable(GL_RASTERIZER_DISCARD);
25800 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
25802 gl.beginTransformFeedback(GL_POINTS);
25803 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
25805 gl.drawArrays(primitive_type, 0 /* first */, 1 /* count */);
25806 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
25808 gl.endTransformFeedback();
25809 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
25814 /** Get descriptors of buffers necessary for test
25817 * @param out_descriptors Descriptors of buffers used by test
25819 void XFBCaptureInactiveOutputVariableTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
25820 bufferDescriptor::Vector& out_descriptors)
25822 const Utils::Type& type = Utils::Type::vec4;
25824 /* Test needs single uniform and xfb */
25825 out_descriptors.resize(2);
25827 /* Get references */
25828 bufferDescriptor& uniform = out_descriptors[0];
25829 bufferDescriptor& xfb = out_descriptors[1];
25832 uniform.m_index = 0;
25836 uniform.m_target = Utils::Buffer::Uniform;
25837 xfb.m_target = Utils::Buffer::Transform_feedback;
25840 const std::vector<GLubyte>& gohan_data = type.GenerateData();
25841 const std::vector<GLubyte>& goten_data = type.GenerateData();
25843 const GLuint type_size = static_cast<GLuint>(gohan_data.size());
25846 uniform.m_initial_data.resize(2 * type_size);
25847 memcpy(&uniform.m_initial_data[0] + 0, &gohan_data[0], type_size);
25848 memcpy(&uniform.m_initial_data[0] + type_size, &goten_data[0], type_size);
25851 xfb.m_initial_data.resize(3 * type_size);
25852 xfb.m_expected_data.resize(3 * type_size);
25854 for (GLuint i = 0; i < 3 * type_size; ++i)
25856 xfb.m_initial_data[i] = (glw::GLubyte)i;
25857 xfb.m_expected_data[i] = (glw::GLubyte)i;
25860 memcpy(&xfb.m_expected_data[0] + 2 * type_size, &gohan_data[0], type_size);
25861 memcpy(&xfb.m_expected_data[0] + 0 * type_size, &goten_data[0], type_size);
25864 /** Get body of main function for given shader stage
25866 * @param test_case_index Index of test case
25867 * @param stage Shader stage
25868 * @param out_assignments Set to empty
25869 * @param out_calculations Set to empty
25871 void XFBCaptureInactiveOutputVariableTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
25872 std::string& out_assignments, std::string& out_calculations)
25874 out_calculations = "";
25876 static const GLchar* vs_tes_gs = " goten = uni_goten;\n"
25877 " gohan = uni_gohan;\n";
25878 static const GLchar* fs = " fs_out = goku + gohan + goten;\n";
25880 const GLchar* assignments = "";
25884 case Utils::Shader::FRAGMENT:
25888 case Utils::Shader::GEOMETRY:
25889 if (TEST_GS == test_case_index)
25891 assignments = vs_tes_gs;
25895 case Utils::Shader::TESS_CTRL:
25898 case Utils::Shader::TESS_EVAL:
25899 if (TEST_TES == test_case_index)
25901 assignments = vs_tes_gs;
25905 case Utils::Shader::VERTEX:
25906 if (TEST_VS == test_case_index)
25908 assignments = vs_tes_gs;
25913 TCU_FAIL("Invalid enum");
25916 out_assignments = assignments;
25919 /** Get interface of shader
25921 * @param test_case_index Index of test case
25922 * @param stage Shader stage
25923 * @param out_interface Set to ""
25925 void XFBCaptureInactiveOutputVariableTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
25926 std::string& out_interface)
25928 static const GLchar* vs_tes_gs = "const uint sizeof_type = 16;\n"
25930 "layout (xfb_offset = 1 * sizeof_type) out vec4 goku;\n"
25931 "layout (xfb_offset = 2 * sizeof_type) out vec4 gohan;\n"
25932 "layout (xfb_offset = 0 * sizeof_type) out vec4 goten;\n"
25934 "layout(binding = 0) uniform block {\n"
25935 " vec4 uni_gohan;\n"
25936 " vec4 uni_goten;\n"
25938 static const GLchar* fs = "in vec4 goku;\n"
25941 "out vec4 fs_out;\n";
25943 const GLchar* interface = "";
25947 case Utils::Shader::FRAGMENT:
25951 case Utils::Shader::GEOMETRY:
25952 if (TEST_GS == test_case_index)
25954 interface = vs_tes_gs;
25958 case Utils::Shader::TESS_CTRL:
25961 case Utils::Shader::TESS_EVAL:
25962 if (TEST_TES == test_case_index)
25964 interface = vs_tes_gs;
25968 case Utils::Shader::VERTEX:
25969 if (TEST_VS == test_case_index)
25971 interface = vs_tes_gs;
25976 TCU_FAIL("Invalid enum");
25979 out_interface = interface;
25982 /** Get source code of shader
25984 * @param test_case_index Index of test case
25985 * @param stage Shader stage
25989 std::string XFBCaptureInactiveOutputVariableTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
25991 std::string source;
25993 switch (test_case_index)
25998 case Utils::Shader::FRAGMENT:
25999 case Utils::Shader::VERTEX:
26000 source = BufferTestBase::getShaderSource(test_case_index, stage);
26010 case Utils::Shader::FRAGMENT:
26011 case Utils::Shader::TESS_CTRL:
26012 case Utils::Shader::TESS_EVAL:
26013 case Utils::Shader::VERTEX:
26014 source = BufferTestBase::getShaderSource(test_case_index, stage);
26022 source = BufferTestBase::getShaderSource(test_case_index, stage);
26026 TCU_FAIL("Invalid enum");
26034 /** Get name of test case
26036 * @param test_case_index Index of test case
26038 * @return Name of tested stage
26040 std::string XFBCaptureInactiveOutputVariableTest::getTestCaseName(glw::GLuint test_case_index)
26042 const GLchar* name = 0;
26044 switch (test_case_index)
26050 name = "tessellation evaluation";
26056 TCU_FAIL("Invalid enum");
26062 /** Returns number of test cases
26066 glw::GLuint XFBCaptureInactiveOutputVariableTest::getTestCaseNumber()
26071 /** Inspects program to check if all resources are as expected
26074 * @param program Program instance
26075 * @param out_stream Error message
26077 * @return true if everything is ok, false otherwise
26079 bool XFBCaptureInactiveOutputVariableTest::inspectProgram(GLuint /* test_case_index */, Utils::Program& program,
26080 std::stringstream& out_stream)
26083 const Utils::Type& type = Utils::Type::vec4;
26084 const GLuint type_size = type.GetSize();
26086 program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE,
26087 1 /* buf_size */, &stride);
26089 if ((GLint)(3 * type_size) != stride)
26091 out_stream << "Stride is: " << stride << " expected: " << (3 * type_size);
26099 /** Verify contents of buffers
26101 * @param buffers Collection of buffers to be verified
26103 * @return true if everything is as expected, false otherwise
26105 bool XFBCaptureInactiveOutputVariableTest::verifyBuffers(bufferCollection& buffers)
26107 bool result = true;
26109 bufferCollection::pair& pair = buffers.m_vector[1] /* xfb */;
26110 Utils::Buffer* buffer = pair.m_buffer;
26111 bufferDescriptor* descriptor = pair.m_descriptor;
26113 /* Get pointer to contents of buffer */
26115 GLubyte* buffer_data = (GLubyte*)buffer->Map(Utils::Buffer::ReadOnly);
26117 /* Get pointer to expected data */
26118 GLubyte* expected_data = (GLubyte*)&descriptor->m_expected_data[0];
26121 static const GLuint vec4_size = 16;
26123 int res_gohan = memcmp(buffer_data + 2 * vec4_size, expected_data + 2 * vec4_size, vec4_size);
26124 int res_goten = memcmp(buffer_data + 0 * vec4_size, expected_data + 0 * vec4_size, vec4_size);
26126 if ((0 != res_gohan) || (0 != res_goten))
26128 m_context.getTestContext().getLog()
26129 << tcu::TestLog::Message << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
26130 << ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
26135 /* Release buffer mapping */
26143 * @param context Test context
26145 XFBCaptureInactiveOutputComponentTest::XFBCaptureInactiveOutputComponentTest(deqp::Context& context)
26146 : BufferTestBase(context, "xfb_capture_inactive_output_component",
26147 "Test verifies that inactive components are not modified")
26149 /* Nothing to be done here */
26152 /** Execute drawArrays for single vertex
26154 * @param test_case_index
26158 bool XFBCaptureInactiveOutputComponentTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
26160 const Functions& gl = m_context.getRenderContext().getFunctions();
26161 GLenum primitive_type = GL_PATCHES;
26163 if (TEST_VS == test_case_index)
26165 primitive_type = GL_POINTS;
26168 gl.disable(GL_RASTERIZER_DISCARD);
26169 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
26171 gl.beginTransformFeedback(GL_POINTS);
26172 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
26174 gl.drawArrays(primitive_type, 0 /* first */, 1 /* count */);
26175 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
26177 gl.endTransformFeedback();
26178 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
26183 /** Get descriptors of buffers necessary for test
26186 * @param out_descriptors Descriptors of buffers used by test
26188 void XFBCaptureInactiveOutputComponentTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
26189 bufferDescriptor::Vector& out_descriptors)
26191 const Utils::Type& type = Utils::Type::vec4;
26193 /* Test needs single uniform and xfb */
26194 out_descriptors.resize(2);
26196 /* Get references */
26197 bufferDescriptor& uniform = out_descriptors[0];
26198 bufferDescriptor& xfb = out_descriptors[1];
26201 uniform.m_index = 0;
26205 uniform.m_target = Utils::Buffer::Uniform;
26206 xfb.m_target = Utils::Buffer::Transform_feedback;
26209 const std::vector<GLubyte>& goku_data = type.GenerateData();
26210 const std::vector<GLubyte>& gohan_data = type.GenerateData();
26211 const std::vector<GLubyte>& goten_data = type.GenerateData();
26212 const std::vector<GLubyte>& chichi_data = type.GenerateData();
26213 const std::vector<GLubyte>& vegeta_data = type.GenerateData();
26214 const std::vector<GLubyte>& trunks_data = type.GenerateData();
26215 const std::vector<GLubyte>& bra_data = type.GenerateData();
26216 const std::vector<GLubyte>& bulma_data = type.GenerateData();
26218 const GLuint comp_size = Utils::Type::GetTypeSize(type.m_basic_type);
26219 const GLuint type_size = static_cast<GLuint>(gohan_data.size());
26222 uniform.m_initial_data.resize(8 * type_size);
26223 memcpy(&uniform.m_initial_data[0] + 0 * type_size, &goku_data[0], type_size);
26224 memcpy(&uniform.m_initial_data[0] + 1 * type_size, &gohan_data[0], type_size);
26225 memcpy(&uniform.m_initial_data[0] + 2 * type_size, &goten_data[0], type_size);
26226 memcpy(&uniform.m_initial_data[0] + 3 * type_size, &chichi_data[0], type_size);
26227 memcpy(&uniform.m_initial_data[0] + 4 * type_size, &vegeta_data[0], type_size);
26228 memcpy(&uniform.m_initial_data[0] + 5 * type_size, &trunks_data[0], type_size);
26229 memcpy(&uniform.m_initial_data[0] + 6 * type_size, &bra_data[0], type_size);
26230 memcpy(&uniform.m_initial_data[0] + 7 * type_size, &bulma_data[0], type_size);
26233 xfb.m_initial_data.resize(8 * type_size);
26234 xfb.m_expected_data.resize(8 * type_size);
26236 for (GLuint i = 0; i < 8 * type_size; ++i)
26238 xfb.m_initial_data[i] = (glw::GLubyte)i;
26239 xfb.m_expected_data[i] = (glw::GLubyte)i;
26242 /* goku - x, z - 32 */
26243 memcpy(&xfb.m_expected_data[0] + 2 * type_size + 0 * comp_size, &goku_data[0] + 0 * comp_size, comp_size);
26244 memcpy(&xfb.m_expected_data[0] + 2 * type_size + 2 * comp_size, &goku_data[0] + 2 * comp_size, comp_size);
26246 /* gohan - y, w - 0 */
26247 memcpy(&xfb.m_expected_data[0] + 0 * type_size + 1 * comp_size, &gohan_data[0] + 1 * comp_size, comp_size);
26248 memcpy(&xfb.m_expected_data[0] + 0 * type_size + 3 * comp_size, &gohan_data[0] + 3 * comp_size, comp_size);
26250 /* goten - x, y - 16 */
26251 memcpy(&xfb.m_expected_data[0] + 1 * type_size + 0 * comp_size, &goten_data[0] + 0 * comp_size, comp_size);
26252 memcpy(&xfb.m_expected_data[0] + 1 * type_size + 1 * comp_size, &goten_data[0] + 1 * comp_size, comp_size);
26254 /* chichi - z, w - 48 */
26255 memcpy(&xfb.m_expected_data[0] + 3 * type_size + 2 * comp_size, &chichi_data[0] + 2 * comp_size, comp_size);
26256 memcpy(&xfb.m_expected_data[0] + 3 * type_size + 3 * comp_size, &chichi_data[0] + 3 * comp_size, comp_size);
26258 /* vegeta - x - 112 */
26259 memcpy(&xfb.m_expected_data[0] + 7 * type_size + 0 * comp_size, &vegeta_data[0] + 0 * comp_size, comp_size);
26261 /* trunks - y - 96 */
26262 memcpy(&xfb.m_expected_data[0] + 6 * type_size + 1 * comp_size, &trunks_data[0] + 1 * comp_size, comp_size);
26265 memcpy(&xfb.m_expected_data[0] + 5 * type_size + 2 * comp_size, &bra_data[0] + 2 * comp_size, comp_size);
26267 /* bulma - w - 64 */
26268 memcpy(&xfb.m_expected_data[0] + 4 * type_size + 3 * comp_size, &bulma_data[0] + 3 * comp_size, comp_size);
26271 /** Get body of main function for given shader stage
26273 * @param test_case_index Index of test case
26274 * @param stage Shader stage
26275 * @param out_assignments Set to empty
26276 * @param out_calculations Set to empty
26278 void XFBCaptureInactiveOutputComponentTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
26279 std::string& out_assignments, std::string& out_calculations)
26281 out_calculations = "";
26283 static const GLchar* vs_tes_gs = " goku.x = uni_goku.x ;\n"
26284 " goku.z = uni_goku.z ;\n"
26285 " gohan.y = uni_gohan.y ;\n"
26286 " gohan.w = uni_gohan.w ;\n"
26287 " goten.x = uni_goten.x ;\n"
26288 " goten.y = uni_goten.y ;\n"
26289 " chichi.z = uni_chichi.z ;\n"
26290 " chichi.w = uni_chichi.w ;\n"
26291 " vegeta.x = uni_vegeta.x ;\n"
26292 " trunks.y = uni_trunks.y ;\n"
26293 " bra.z = uni_bra.z ;\n"
26294 " bulma.w = uni_bulma.w ;\n";
26295 static const GLchar* fs = " fs_out = goku + gohan + goten + chichi + vegeta + trunks + bra + bulma;\n";
26297 const GLchar* assignments = "";
26301 case Utils::Shader::FRAGMENT:
26305 case Utils::Shader::GEOMETRY:
26306 if (TEST_GS == test_case_index)
26308 assignments = vs_tes_gs;
26312 case Utils::Shader::TESS_CTRL:
26315 case Utils::Shader::TESS_EVAL:
26316 if (TEST_TES == test_case_index)
26318 assignments = vs_tes_gs;
26322 case Utils::Shader::VERTEX:
26323 if (TEST_VS == test_case_index)
26325 assignments = vs_tes_gs;
26330 TCU_FAIL("Invalid enum");
26333 out_assignments = assignments;
26336 /** Get interface of shader
26338 * @param test_case_index Index of test case
26339 * @param stage Shader stage
26340 * @param out_interface Set to ""
26342 void XFBCaptureInactiveOutputComponentTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
26343 std::string& out_interface)
26345 static const GLchar* vs_tes_gs = "const uint sizeof_type = 16;\n"
26347 "layout (xfb_offset = 2 * sizeof_type) out vec4 goku;\n"
26348 "layout (xfb_offset = 0 * sizeof_type) out vec4 gohan;\n"
26349 "layout (xfb_offset = 1 * sizeof_type) out vec4 goten;\n"
26350 "layout (xfb_offset = 3 * sizeof_type) out vec4 chichi;\n"
26351 "layout (xfb_offset = 7 * sizeof_type) out vec4 vegeta;\n"
26352 "layout (xfb_offset = 6 * sizeof_type) out vec4 trunks;\n"
26353 "layout (xfb_offset = 5 * sizeof_type) out vec4 bra;\n"
26354 "layout (xfb_offset = 4 * sizeof_type) out vec4 bulma;\n"
26356 "layout(binding = 0) uniform block {\n"
26357 " vec4 uni_goku;\n"
26358 " vec4 uni_gohan;\n"
26359 " vec4 uni_goten;\n"
26360 " vec4 uni_chichi;\n"
26361 " vec4 uni_vegeta;\n"
26362 " vec4 uni_trunks;\n"
26364 " vec4 uni_bulma;\n"
26366 static const GLchar* fs = "in vec4 vegeta;\n"
26367 "in vec4 trunks;\n"
26373 "in vec4 chichi;\n"
26375 "out vec4 fs_out;\n";
26377 const GLchar* interface = "";
26381 case Utils::Shader::FRAGMENT:
26385 case Utils::Shader::GEOMETRY:
26386 if (TEST_GS == test_case_index)
26388 interface = vs_tes_gs;
26392 case Utils::Shader::TESS_CTRL:
26395 case Utils::Shader::TESS_EVAL:
26396 if (TEST_TES == test_case_index)
26398 interface = vs_tes_gs;
26402 case Utils::Shader::VERTEX:
26403 if (TEST_VS == test_case_index)
26405 interface = vs_tes_gs;
26410 TCU_FAIL("Invalid enum");
26413 out_interface = interface;
26416 /** Get source code of shader
26418 * @param test_case_index Index of test case
26419 * @param stage Shader stage
26423 std::string XFBCaptureInactiveOutputComponentTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
26425 std::string source;
26427 switch (test_case_index)
26432 case Utils::Shader::FRAGMENT:
26433 case Utils::Shader::VERTEX:
26434 source = BufferTestBase::getShaderSource(test_case_index, stage);
26444 case Utils::Shader::FRAGMENT:
26445 case Utils::Shader::TESS_CTRL:
26446 case Utils::Shader::TESS_EVAL:
26447 case Utils::Shader::VERTEX:
26448 source = BufferTestBase::getShaderSource(test_case_index, stage);
26456 source = BufferTestBase::getShaderSource(test_case_index, stage);
26460 TCU_FAIL("Invalid enum");
26468 /** Get name of test case
26470 * @param test_case_index Index of test case
26472 * @return Name of tested stage
26474 std::string XFBCaptureInactiveOutputComponentTest::getTestCaseName(glw::GLuint test_case_index)
26476 const GLchar* name = 0;
26478 switch (test_case_index)
26484 name = "tessellation evaluation";
26490 TCU_FAIL("Invalid enum");
26496 /** Returns number of test cases
26500 glw::GLuint XFBCaptureInactiveOutputComponentTest::getTestCaseNumber()
26505 /** Verify contents of buffers
26507 * @param buffers Collection of buffers to be verified
26509 * @return true if everything is as expected, false otherwise
26511 bool XFBCaptureInactiveOutputComponentTest::verifyBuffers(bufferCollection& buffers)
26513 bool result = true;
26515 bufferCollection::pair& pair = buffers.m_vector[1] /* xfb */;
26516 Utils::Buffer* buffer = pair.m_buffer;
26517 bufferDescriptor* descriptor = pair.m_descriptor;
26519 /* Get pointer to contents of buffer */
26521 GLubyte* buffer_data = (GLubyte*)buffer->Map(Utils::Buffer::ReadOnly);
26523 /* Get pointer to expected data */
26524 GLubyte* expected_data = (GLubyte*)&descriptor->m_expected_data[0];
26527 static const GLuint comp_size = 4;
26528 static const GLuint vec4_size = 16;
26531 memcmp(buffer_data + 2 * vec4_size + 0 * comp_size, expected_data + 2 * vec4_size + 0 * comp_size, comp_size);
26533 memcmp(buffer_data + 2 * vec4_size + 2 * comp_size, expected_data + 2 * vec4_size + 2 * comp_size, comp_size);
26536 memcmp(buffer_data + 0 * vec4_size + 1 * comp_size, expected_data + 0 * vec4_size + 1 * comp_size, comp_size);
26538 memcmp(buffer_data + 0 * vec4_size + 3 * comp_size, expected_data + 0 * vec4_size + 3 * comp_size, comp_size);
26541 memcmp(buffer_data + 1 * vec4_size + 0 * comp_size, expected_data + 1 * vec4_size + 0 * comp_size, comp_size);
26543 memcmp(buffer_data + 1 * vec4_size + 1 * comp_size, expected_data + 1 * vec4_size + 1 * comp_size, comp_size);
26546 memcmp(buffer_data + 3 * vec4_size + 2 * comp_size, expected_data + 3 * vec4_size + 2 * comp_size, comp_size);
26548 memcmp(buffer_data + 3 * vec4_size + 3 * comp_size, expected_data + 3 * vec4_size + 3 * comp_size, comp_size);
26551 memcmp(buffer_data + 7 * vec4_size + 0 * comp_size, expected_data + 7 * vec4_size + 0 * comp_size, comp_size);
26554 memcmp(buffer_data + 6 * vec4_size + 1 * comp_size, expected_data + 6 * vec4_size + 1 * comp_size, comp_size);
26557 memcmp(buffer_data + 5 * vec4_size + 2 * comp_size, expected_data + 5 * vec4_size + 2 * comp_size, comp_size);
26560 memcmp(buffer_data + 4 * vec4_size + 3 * comp_size, expected_data + 4 * vec4_size + 3 * comp_size, comp_size);
26562 if ((0 != res_goku_x) || (0 != res_goku_z) || (0 != res_gohan_y) || (0 != res_gohan_w) || (0 != res_goten_x) ||
26563 (0 != res_goten_y) || (0 != res_chichi_z) || (0 != res_chichi_w) || (0 != res_vegeta_x) ||
26564 (0 != res_trunks_y) || (0 != res_bra_z) || (0 != res_bulma_w))
26566 m_context.getTestContext().getLog()
26567 << tcu::TestLog::Message << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
26568 << ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
26573 /* Release buffer mapping */
26581 * @param context Test context
26583 XFBCaptureInactiveOutputBlockMemberTest::XFBCaptureInactiveOutputBlockMemberTest(deqp::Context& context)
26584 : BufferTestBase(context, "xfb_capture_inactive_output_block_member",
26585 "Test verifies that inactive block members are captured")
26587 /* Nothing to be done here */
26590 /** Execute drawArrays for single vertex
26592 * @param test_case_index
26596 bool XFBCaptureInactiveOutputBlockMemberTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
26598 const Functions& gl = m_context.getRenderContext().getFunctions();
26599 GLenum primitive_type = GL_PATCHES;
26601 if (TEST_VS == test_case_index)
26603 primitive_type = GL_POINTS;
26606 gl.disable(GL_RASTERIZER_DISCARD);
26607 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
26609 gl.beginTransformFeedback(GL_POINTS);
26610 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
26612 gl.drawArrays(primitive_type, 0 /* first */, 1 /* count */);
26613 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
26615 gl.endTransformFeedback();
26616 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
26621 /** Get descriptors of buffers necessary for test
26624 * @param out_descriptors Descriptors of buffers used by test
26626 void XFBCaptureInactiveOutputBlockMemberTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
26627 bufferDescriptor::Vector& out_descriptors)
26629 const Utils::Type& type = Utils::Type::vec4;
26631 /* Test needs single uniform and xfb */
26632 out_descriptors.resize(2);
26634 /* Get references */
26635 bufferDescriptor& uniform = out_descriptors[0];
26636 bufferDescriptor& xfb = out_descriptors[1];
26639 uniform.m_index = 0;
26643 uniform.m_target = Utils::Buffer::Uniform;
26644 xfb.m_target = Utils::Buffer::Transform_feedback;
26647 const std::vector<GLubyte>& gohan_data = type.GenerateData();
26648 const std::vector<GLubyte>& chichi_data = type.GenerateData();
26650 const GLuint type_size = static_cast<GLuint>(gohan_data.size());
26653 uniform.m_initial_data.resize(2 * type_size);
26654 memcpy(&uniform.m_initial_data[0] + 0, &gohan_data[0], type_size);
26655 memcpy(&uniform.m_initial_data[0] + type_size, &chichi_data[0], type_size);
26658 xfb.m_initial_data.resize(4 * type_size);
26659 xfb.m_expected_data.resize(4 * type_size);
26661 for (GLuint i = 0; i < 4 * type_size; ++i)
26663 xfb.m_initial_data[i] = (glw::GLubyte)i;
26664 xfb.m_expected_data[i] = (glw::GLubyte)i;
26667 memcpy(&xfb.m_expected_data[0] + 1 * type_size, &gohan_data[0], type_size);
26668 memcpy(&xfb.m_expected_data[0] + 3 * type_size, &chichi_data[0], type_size);
26671 /** Get body of main function for given shader stage
26673 * @param test_case_index Index of test case
26674 * @param stage Shader stage
26675 * @param out_assignments Set to empty
26676 * @param out_calculations Set to empty
26678 void XFBCaptureInactiveOutputBlockMemberTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
26679 std::string& out_assignments, std::string& out_calculations)
26681 out_calculations = "";
26683 static const GLchar* vs_tes_gs = " chichi = uni_chichi;\n"
26684 " gohan = uni_gohan;\n";
26685 static const GLchar* fs = " fs_out = goten + gohan + chichi;\n";
26687 const GLchar* assignments = "";
26691 case Utils::Shader::FRAGMENT:
26695 case Utils::Shader::GEOMETRY:
26696 if (TEST_GS == test_case_index)
26698 assignments = vs_tes_gs;
26702 case Utils::Shader::TESS_CTRL:
26705 case Utils::Shader::TESS_EVAL:
26706 if (TEST_TES == test_case_index)
26708 assignments = vs_tes_gs;
26712 case Utils::Shader::VERTEX:
26713 if (TEST_VS == test_case_index)
26715 assignments = vs_tes_gs;
26720 TCU_FAIL("Invalid enum");
26723 out_assignments = assignments;
26726 /** Get interface of shader
26728 * @param test_case_index Index of test case
26729 * @param stage Shader stage
26730 * @param out_interface Set to ""
26732 void XFBCaptureInactiveOutputBlockMemberTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
26733 std::string& out_interface)
26735 static const GLchar* vs_tes_gs = "const uint sizeof_type = 16;\n"
26737 "layout (xfb_offset = 1 * sizeof_type) out Goku {\n"
26743 "layout(binding = 0) uniform block {\n"
26744 " vec4 uni_gohan;\n"
26745 " vec4 uni_chichi;\n"
26747 static const GLchar* fs = "in Goku {\n"
26752 "out vec4 fs_out;\n";
26754 const GLchar* interface = "";
26758 case Utils::Shader::FRAGMENT:
26762 case Utils::Shader::GEOMETRY:
26763 if (TEST_GS == test_case_index)
26765 interface = vs_tes_gs;
26769 case Utils::Shader::TESS_CTRL:
26772 case Utils::Shader::TESS_EVAL:
26773 if (TEST_TES == test_case_index)
26775 interface = vs_tes_gs;
26779 case Utils::Shader::VERTEX:
26780 if (TEST_VS == test_case_index)
26782 interface = vs_tes_gs;
26787 TCU_FAIL("Invalid enum");
26790 out_interface = interface;
26793 /** Get source code of shader
26795 * @param test_case_index Index of test case
26796 * @param stage Shader stage
26800 std::string XFBCaptureInactiveOutputBlockMemberTest::getShaderSource(GLuint test_case_index,
26801 Utils::Shader::STAGES stage)
26803 std::string source;
26805 switch (test_case_index)
26810 case Utils::Shader::FRAGMENT:
26811 case Utils::Shader::VERTEX:
26812 source = BufferTestBase::getShaderSource(test_case_index, stage);
26822 case Utils::Shader::FRAGMENT:
26823 case Utils::Shader::TESS_CTRL:
26824 case Utils::Shader::TESS_EVAL:
26825 case Utils::Shader::VERTEX:
26826 source = BufferTestBase::getShaderSource(test_case_index, stage);
26834 source = BufferTestBase::getShaderSource(test_case_index, stage);
26838 TCU_FAIL("Invalid enum");
26846 /** Get name of test case
26848 * @param test_case_index Index of test case
26850 * @return Name of tested stage
26852 std::string XFBCaptureInactiveOutputBlockMemberTest::getTestCaseName(glw::GLuint test_case_index)
26854 const GLchar* name = 0;
26856 switch (test_case_index)
26862 name = "tessellation evaluation";
26868 TCU_FAIL("Invalid enum");
26874 /** Returns number of test cases
26878 glw::GLuint XFBCaptureInactiveOutputBlockMemberTest::getTestCaseNumber()
26883 /** Verify contents of buffers
26885 * @param buffers Collection of buffers to be verified
26887 * @return true if everything is as expected, false otherwise
26889 bool XFBCaptureInactiveOutputBlockMemberTest::verifyBuffers(bufferCollection& buffers)
26891 bool result = true;
26893 bufferCollection::pair& pair = buffers.m_vector[1] /* xfb */;
26894 Utils::Buffer* buffer = pair.m_buffer;
26895 bufferDescriptor* descriptor = pair.m_descriptor;
26897 /* Get pointer to contents of buffer */
26899 GLubyte* buffer_data = (GLubyte*)buffer->Map(Utils::Buffer::ReadOnly);
26901 /* Get pointer to expected data */
26902 GLubyte* expected_data = (GLubyte*)&descriptor->m_expected_data[0];
26905 static const GLuint vec4_size = 16;
26907 int res_before = memcmp(buffer_data, expected_data, vec4_size);
26908 int res_gohan = memcmp(buffer_data + 1 * vec4_size, expected_data + 1 * vec4_size, vec4_size);
26909 int res_chichi = memcmp(buffer_data + 3 * vec4_size, expected_data + 3 * vec4_size, vec4_size);
26911 if ((0 != res_before) || (0 != res_gohan) || (0 != res_chichi))
26913 m_context.getTestContext().getLog()
26914 << tcu::TestLog::Message << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
26915 << ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
26920 /* Release buffer mapping */
26928 * @param context Test context
26930 XFBCaptureStructTest::XFBCaptureStructTest(deqp::Context& context)
26931 : BufferTestBase(context, "xfb_capture_struct", "Test verifies that inactive structure members are captured")
26933 /* Nothing to be done here */
26936 /** Execute drawArrays for single vertex
26938 * @param test_case_index
26942 bool XFBCaptureStructTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
26944 const Functions& gl = m_context.getRenderContext().getFunctions();
26945 GLenum primitive_type = GL_PATCHES;
26947 if (TEST_VS == test_case_index)
26949 primitive_type = GL_POINTS;
26952 gl.disable(GL_RASTERIZER_DISCARD);
26953 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
26955 gl.beginTransformFeedback(GL_POINTS);
26956 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
26958 gl.drawArrays(primitive_type, 0 /* first */, 1 /* count */);
26959 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
26961 gl.endTransformFeedback();
26962 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
26967 /** Get descriptors of buffers necessary for test
26970 * @param out_descriptors Descriptors of buffers used by test
26972 void XFBCaptureStructTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
26973 bufferDescriptor::Vector& out_descriptors)
26975 const Utils::Type& type = Utils::Type::vec4;
26977 /* Test needs single uniform and xfb */
26978 out_descriptors.resize(2);
26980 /* Get references */
26981 bufferDescriptor& uniform = out_descriptors[0];
26982 bufferDescriptor& xfb = out_descriptors[1];
26985 uniform.m_index = 0;
26989 uniform.m_target = Utils::Buffer::Uniform;
26990 xfb.m_target = Utils::Buffer::Transform_feedback;
26993 const std::vector<GLubyte>& gohan_data = type.GenerateData();
26994 const std::vector<GLubyte>& chichi_data = type.GenerateData();
26996 const GLuint type_size = static_cast<GLuint>(gohan_data.size());
26999 uniform.m_initial_data.resize(2 * type_size);
27000 memcpy(&uniform.m_initial_data[0] + 0, &gohan_data[0], type_size);
27001 memcpy(&uniform.m_initial_data[0] + type_size, &chichi_data[0], type_size);
27004 xfb.m_initial_data.resize(4 * type_size);
27005 xfb.m_expected_data.resize(4 * type_size);
27007 for (GLuint i = 0; i < 4 * type_size; ++i)
27009 xfb.m_initial_data[i] = (glw::GLubyte)i;
27010 xfb.m_expected_data[i] = (glw::GLubyte)i;
27013 memcpy(&xfb.m_expected_data[0] + 1 * type_size, &gohan_data[0], type_size);
27014 memcpy(&xfb.m_expected_data[0] + 3 * type_size, &chichi_data[0], type_size);
27017 /** Get body of main function for given shader stage
27019 * @param test_case_index Index of test case
27020 * @param stage Shader stage
27021 * @param out_assignments Set to empty
27022 * @param out_calculations Set to empty
27024 void XFBCaptureStructTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
27025 std::string& out_assignments, std::string& out_calculations)
27027 out_calculations = "";
27029 static const GLchar* vs_tes_gs = " goku.chichi = uni_chichi;\n"
27030 " goku.gohan = uni_gohan;\n";
27031 static const GLchar* fs = " fs_out = goku.goten + goku.gohan + goku.chichi;\n";
27033 const GLchar* assignments = "";
27037 case Utils::Shader::FRAGMENT:
27041 case Utils::Shader::GEOMETRY:
27042 if (TEST_GS == test_case_index)
27044 assignments = vs_tes_gs;
27048 case Utils::Shader::TESS_CTRL:
27051 case Utils::Shader::TESS_EVAL:
27052 if (TEST_TES == test_case_index)
27054 assignments = vs_tes_gs;
27058 case Utils::Shader::VERTEX:
27059 if (TEST_VS == test_case_index)
27061 assignments = vs_tes_gs;
27066 TCU_FAIL("Invalid enum");
27069 out_assignments = assignments;
27072 /** Get interface of shader
27074 * @param test_case_index Index of test case
27075 * @param stage Shader stage
27076 * @param out_interface Set to ""
27078 void XFBCaptureStructTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
27079 std::string& out_interface)
27081 static const GLchar* vs_tes_gs = "const uint sizeof_type = 16;\n"
27089 "layout (xfb_offset = sizeof_type) out Goku goku;\n"
27091 "layout(binding = 0, std140) uniform block {\n"
27092 " vec4 uni_gohan;\n"
27093 " vec4 uni_chichi;\n"
27095 static const GLchar* fs = "struct Goku {\n"
27103 "out vec4 fs_out;\n";
27105 const GLchar* interface = "";
27109 case Utils::Shader::FRAGMENT:
27113 case Utils::Shader::GEOMETRY:
27114 if (TEST_GS == test_case_index)
27116 interface = vs_tes_gs;
27120 case Utils::Shader::TESS_CTRL:
27123 case Utils::Shader::TESS_EVAL:
27124 if (TEST_TES == test_case_index)
27126 interface = vs_tes_gs;
27130 case Utils::Shader::VERTEX:
27131 if (TEST_VS == test_case_index)
27133 interface = vs_tes_gs;
27138 TCU_FAIL("Invalid enum");
27141 out_interface = interface;
27144 /** Get source code of shader
27146 * @param test_case_index Index of test case
27147 * @param stage Shader stage
27151 std::string XFBCaptureStructTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
27153 std::string source;
27155 switch (test_case_index)
27160 case Utils::Shader::FRAGMENT:
27161 case Utils::Shader::VERTEX:
27162 source = BufferTestBase::getShaderSource(test_case_index, stage);
27172 case Utils::Shader::FRAGMENT:
27173 case Utils::Shader::TESS_CTRL:
27174 case Utils::Shader::TESS_EVAL:
27175 case Utils::Shader::VERTEX:
27176 source = BufferTestBase::getShaderSource(test_case_index, stage);
27184 source = BufferTestBase::getShaderSource(test_case_index, stage);
27188 TCU_FAIL("Invalid enum");
27196 /** Get name of test case
27198 * @param test_case_index Index of test case
27200 * @return Name of tested stage
27202 std::string XFBCaptureStructTest::getTestCaseName(glw::GLuint test_case_index)
27204 const GLchar* name = 0;
27206 switch (test_case_index)
27212 name = "tessellation evaluation";
27218 TCU_FAIL("Invalid enum");
27224 /** Returns number of test cases
27228 glw::GLuint XFBCaptureStructTest::getTestCaseNumber()
27233 /** Verify contents of buffers
27235 * @param buffers Collection of buffers to be verified
27237 * @return true if everything is as expected, false otherwise
27239 bool XFBCaptureStructTest::verifyBuffers(bufferCollection& buffers)
27241 bool result = true;
27243 bufferCollection::pair& pair = buffers.m_vector[1] /* xfb */;
27244 Utils::Buffer* buffer = pair.m_buffer;
27245 bufferDescriptor* descriptor = pair.m_descriptor;
27247 /* Get pointer to contents of buffer */
27249 GLubyte* buffer_data = (GLubyte*)buffer->Map(Utils::Buffer::ReadOnly);
27251 /* Get pointer to expected data */
27252 GLubyte* expected_data = (GLubyte*)&descriptor->m_expected_data[0];
27255 static const GLuint vec4_size = 16;
27257 int res_before = memcmp(buffer_data, expected_data, vec4_size);
27258 int res_gohan = memcmp(buffer_data + 1 * vec4_size, expected_data + 1 * vec4_size, vec4_size);
27259 int res_chichi = memcmp(buffer_data + 3 * vec4_size, expected_data + 3 * vec4_size, vec4_size);
27261 if ((0 != res_before) || (0 != res_gohan) || (0 != res_chichi))
27263 m_context.getTestContext().getLog()
27264 << tcu::TestLog::Message << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
27265 << ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
27270 /* Release buffer mapping */
27278 * @param context Test framework context
27280 XFBCaptureUnsizedArrayTest::XFBCaptureUnsizedArrayTest(deqp::Context& context)
27281 : NegativeTestBase(context, "xfb_capture_unsized_array",
27282 "Test verifies that compiler reports error when unsized array is qualified with xfb_offset")
27286 /** Source for given test case and stage
27288 * @param test_case_index Index of test case
27289 * @param stage Shader stage
27291 * @return Shader source
27293 std::string XFBCaptureUnsizedArrayTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
27295 static const GLchar* var_definition = "layout (xfb_offset = 0) out vec4 gokuARRAY[];\n";
27296 static const GLchar* var_use = " gokuINDEX[0] = result / 2;\n";
27297 static const GLchar* fs = "#version 430 core\n"
27298 "#extension GL_ARB_enhanced_layouts : require\n"
27301 "out vec4 fs_out;\n"
27305 " fs_out = gs_fs;\n"
27308 static const GLchar* gs_tested = "#version 430 core\n"
27309 "#extension GL_ARB_enhanced_layouts : require\n"
27311 "layout(points) in;\n"
27312 "layout(triangle_strip, max_vertices = 4) out;\n"
27316 "in vec4 tes_gs[];\n"
27317 "out vec4 gs_fs;\n"
27321 " vec4 result = tes_gs[0];\n"
27325 " gs_fs = result;\n"
27326 " gl_Position = vec4(-1, -1, 0, 1);\n"
27328 " gs_fs = result;\n"
27329 " gl_Position = vec4(-1, 1, 0, 1);\n"
27331 " gs_fs = result;\n"
27332 " gl_Position = vec4(1, -1, 0, 1);\n"
27334 " gs_fs = result;\n"
27335 " gl_Position = vec4(1, 1, 0, 1);\n"
27339 static const GLchar* tcs = "#version 430 core\n"
27340 "#extension GL_ARB_enhanced_layouts : require\n"
27342 "layout(vertices = 1) out;\n"
27344 "in vec4 vs_tcs[];\n"
27345 "out vec4 tcs_tes[];\n"
27350 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
27352 " gl_TessLevelOuter[0] = 1.0;\n"
27353 " gl_TessLevelOuter[1] = 1.0;\n"
27354 " gl_TessLevelOuter[2] = 1.0;\n"
27355 " gl_TessLevelOuter[3] = 1.0;\n"
27356 " gl_TessLevelInner[0] = 1.0;\n"
27357 " gl_TessLevelInner[1] = 1.0;\n"
27360 static const GLchar* tcs_tested = "#version 430 core\n"
27361 "#extension GL_ARB_enhanced_layouts : require\n"
27363 "layout(vertices = 1) out;\n"
27367 "in vec4 vs_tcs[];\n"
27368 "out vec4 tcs_tes[];\n"
27372 " vec4 result = vs_tcs[gl_InvocationID];\n"
27376 " tcs_tes[gl_InvocationID] = result;\n"
27378 " gl_TessLevelOuter[0] = 1.0;\n"
27379 " gl_TessLevelOuter[1] = 1.0;\n"
27380 " gl_TessLevelOuter[2] = 1.0;\n"
27381 " gl_TessLevelOuter[3] = 1.0;\n"
27382 " gl_TessLevelInner[0] = 1.0;\n"
27383 " gl_TessLevelInner[1] = 1.0;\n"
27386 static const GLchar* tes_tested = "#version 430 core\n"
27387 "#extension GL_ARB_enhanced_layouts : require\n"
27389 "layout(isolines, point_mode) in;\n"
27393 "in vec4 tcs_tes[];\n"
27394 "out vec4 tes_gs;\n"
27398 " vec4 result = tcs_tes[0];\n"
27402 " tes_gs += result;\n"
27405 static const GLchar* vs = "#version 430 core\n"
27406 "#extension GL_ARB_enhanced_layouts : require\n"
27409 "out vec4 vs_tcs;\n"
27413 " vs_tcs = in_vs;\n"
27416 static const GLchar* vs_tested = "#version 430 core\n"
27417 "#extension GL_ARB_enhanced_layouts : require\n"
27422 "out vec4 vs_tcs;\n"
27426 " vec4 result = in_vs;\n"
27430 " vs_tcs = result;\n"
27434 std::string source;
27435 testCase& test_case = m_test_cases[test_case_index];
27437 if (test_case.m_stage == stage)
27439 const GLchar* array = "";
27440 const GLchar* index = "";
27441 size_t position = 0;
27445 case Utils::Shader::GEOMETRY:
27446 source = gs_tested;
27450 case Utils::Shader::TESS_CTRL:
27451 source = tcs_tested;
27453 index = "[gl_InvocationID]";
27455 case Utils::Shader::TESS_EVAL:
27456 source = tes_tested;
27460 case Utils::Shader::VERTEX:
27461 source = vs_tested;
27464 TCU_FAIL("Invalid enum");
27467 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
27469 Utils::replaceToken("ARRAY", position, array, source);
27470 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
27472 Utils::replaceAllTokens("INDEX", index, source);
27476 switch (test_case.m_stage)
27478 case Utils::Shader::GEOMETRY:
27481 case Utils::Shader::FRAGMENT:
27484 case Utils::Shader::VERTEX:
27491 case Utils::Shader::TESS_CTRL:
27494 case Utils::Shader::FRAGMENT:
27497 case Utils::Shader::VERTEX:
27504 case Utils::Shader::TESS_EVAL:
27507 case Utils::Shader::FRAGMENT:
27510 case Utils::Shader::TESS_CTRL:
27513 case Utils::Shader::VERTEX:
27520 case Utils::Shader::VERTEX:
27523 case Utils::Shader::FRAGMENT:
27531 TCU_FAIL("Invalid enum");
27539 /** Get description of test case
27541 * @param test_case_index Index of test case
27543 * @return Test case description
27545 std::string XFBCaptureUnsizedArrayTest::getTestCaseName(GLuint test_case_index)
27547 std::stringstream stream;
27548 testCase& test_case = m_test_cases[test_case_index];
27550 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage);
27552 return stream.str();
27555 /** Get number of test cases
27557 * @return Number of test cases
27559 GLuint XFBCaptureUnsizedArrayTest::getTestCaseNumber()
27561 return static_cast<GLuint>(m_test_cases.size());
27564 /** Selects if "compute" stage is relevant for test
27570 bool XFBCaptureUnsizedArrayTest::isComputeRelevant(GLuint /* test_case_index */)
27575 /** Prepare all test cases
27578 void XFBCaptureUnsizedArrayTest::testInit()
27580 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
27582 /* Not aplicable for */
27583 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::FRAGMENT == stage) ||
27584 (Utils::Shader::GEOMETRY == stage) || (Utils::Shader::TESS_EVAL == stage))
27589 testCase test_case = { (Utils::Shader::STAGES)stage };
27591 m_test_cases.push_back(test_case);
27594 } /* EnhancedLayouts namespace */
27598 * @param context Rendering context.
27600 EnhancedLayoutsTests::EnhancedLayoutsTests(deqp::Context& context)
27601 : TestCaseGroup(context, "enhanced_layouts", "Verifies \"enhanced layouts\" functionality")
27603 /* Left blank on purpose */
27606 /** Initializes a texture_storage_multisample test group.
27609 void EnhancedLayoutsTests::init(void)
27611 addChild(new EnhancedLayouts::APIConstantValuesTest(m_context));
27612 addChild(new EnhancedLayouts::APIErrorsTest(m_context));
27613 addChild(new EnhancedLayouts::GLSLContantValuesTest(m_context));
27614 addChild(new EnhancedLayouts::GLSLContantImmutablityTest(m_context));
27615 addChild(new EnhancedLayouts::GLSLConstantIntegralExpressionTest(m_context));
27616 addChild(new EnhancedLayouts::UniformBlockLayoutQualifierConflictTest(m_context));
27617 addChild(new EnhancedLayouts::SSBMemberInvalidOffsetAlignmentTest(m_context));
27618 addChild(new EnhancedLayouts::SSBMemberOverlappingOffsetsTest(m_context));
27619 addChild(new EnhancedLayouts::VaryingExceedingComponentsTest(m_context));
27620 addChild(new EnhancedLayouts::VaryingComponentOfInvalidTypeTest(m_context));
27621 addChild(new EnhancedLayouts::OutputComponentAliasingTest(m_context));
27622 addChild(new EnhancedLayouts::VertexAttribLocationAPITest(m_context));
27623 addChild(new EnhancedLayouts::XFBInputTest(m_context));
27624 addChild(new EnhancedLayouts::XFBAllStagesTest(m_context));
27625 addChild(new EnhancedLayouts::XFBCaptureInactiveOutputVariableTest(m_context));
27626 addChild(new EnhancedLayouts::XFBCaptureInactiveOutputComponentTest(m_context));
27627 addChild(new EnhancedLayouts::XFBCaptureInactiveOutputBlockMemberTest(m_context));
27628 addChild(new EnhancedLayouts::XFBStrideTest(m_context));
27630 addChild(new EnhancedLayouts::UniformBlockMemberOffsetAndAlignTest(m_context));
27631 addChild(new EnhancedLayouts::UniformBlockMemberInvalidOffsetAlignmentTest(m_context));
27632 addChild(new EnhancedLayouts::UniformBlockMemberOverlappingOffsetsTest(m_context));
27633 addChild(new EnhancedLayouts::UniformBlockMemberAlignNonPowerOf2Test(m_context));
27634 addChild(new EnhancedLayouts::SSBLayoutQualifierConflictTest(m_context));
27635 addChild(new EnhancedLayouts::SSBMemberAlignNonPowerOf2Test(m_context));
27636 addChild(new EnhancedLayouts::SSBAlignmentTest(m_context));
27637 addChild(new EnhancedLayouts::VaryingStructureMemberLocationTest(m_context));
27638 addChild(new EnhancedLayouts::VaryingBlockAutomaticMemberLocationsTest(m_context));
27639 addChild(new EnhancedLayouts::VaryingComponentWithoutLocationTest(m_context));
27640 addChild(new EnhancedLayouts::InputComponentAliasingTest(m_context));
27641 addChild(new EnhancedLayouts::VaryingLocationAliasingWithMixedTypesTest(m_context));
27642 addChild(new EnhancedLayouts::VaryingLocationAliasingWithMixedInterpolationTest(m_context));
27643 addChild(new EnhancedLayouts::VaryingLocationAliasingWithMixedAuxiliaryStorageTest(m_context));
27644 addChild(new EnhancedLayouts::XFBStrideOfEmptyListTest(m_context));
27645 addChild(new EnhancedLayouts::XFBStrideOfEmptyListAndAPITest(m_context));
27646 addChild(new EnhancedLayouts::XFBTooSmallStrideTest(m_context));
27647 addChild(new EnhancedLayouts::XFBBlockMemberStrideTest(m_context));
27648 addChild(new EnhancedLayouts::XFBDuplicatedStrideTest(m_context));
27649 addChild(new EnhancedLayouts::XFBGetProgramResourceAPITest(m_context));
27650 addChild(new EnhancedLayouts::XFBMultipleVertexStreamsTest(m_context));
27651 addChild(new EnhancedLayouts::XFBExceedBufferLimitTest(m_context));
27652 addChild(new EnhancedLayouts::XFBExceedOffsetLimitTest(m_context));
27653 addChild(new EnhancedLayouts::XFBBlockMemberBufferTest(m_context));
27654 addChild(new EnhancedLayouts::XFBOutputOverlappingTest(m_context));
27655 addChild(new EnhancedLayouts::XFBInvalidOffsetAlignmentTest(m_context));
27656 addChild(new EnhancedLayouts::XFBCaptureStructTest(m_context));
27657 addChild(new EnhancedLayouts::XFBCaptureUnsizedArrayTest(m_context));
27658 addChild(new EnhancedLayouts::UniformBlockAlignmentTest(m_context));
27659 addChild(new EnhancedLayouts::SSBMemberOffsetAndAlignTest(m_context));
27660 addChild(new EnhancedLayouts::VertexAttribLocationsTest(m_context));
27661 addChild(new EnhancedLayouts::VaryingLocationsTest(m_context));
27662 addChild(new EnhancedLayouts::VaryingArrayLocationsTest(m_context));
27663 addChild(new EnhancedLayouts::VaryingStructureLocationsTest(m_context));
27664 addChild(new EnhancedLayouts::VaryingBlockLocationsTest(m_context));
27665 addChild(new EnhancedLayouts::VaryingBlockMemberLocationsTest(m_context));
27666 addChild(new EnhancedLayouts::XFBVariableStrideTest(m_context));
27667 addChild(new EnhancedLayouts::XFBBlockStrideTest(m_context));
27668 addChild(new EnhancedLayouts::XFBOverrideQualifiersWithAPITest(m_context));
27669 addChild(new EnhancedLayouts::XFBVertexStreamsTest(m_context));
27670 addChild(new EnhancedLayouts::XFBGlobalBufferTest(m_context));
27671 addChild(new EnhancedLayouts::FragmentDataLocationAPITest(m_context));
27672 addChild(new EnhancedLayouts::VaryingLocationLimitTest(m_context));
27673 addChild(new EnhancedLayouts::VaryingComponentsTest(m_context));
27674 addChild(new EnhancedLayouts::VaryingArrayComponentsTest(m_context));
27677 } /* gl4cts namespace */