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 = "tesselation control";
2414 result = "tesselation evaluation";
2417 result = "geomtery";
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 tesselation_control_shader Tesselation control shader source code
2625 * @param tesselation_evaluation_shader Tesselation 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& tesselation_control_shader,
2633 const std::string& tesselation_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, tesselation_control_shader);
2647 m_tess_eval.Init(Shader::TESS_EVAL, tesselation_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, tesselation_control_shader,
2675 tesselation_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 tesselation_control_shader Tesselation control shader source code
2685 * @param tesselation_evaluation_shader Tesselation 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& tesselation_control_shader,
2691 const std::string& tesselation_evaluation_shader, const std::string& vertex_shader,
2694 NameVector captured_varying;
2696 Init(compute_shader, fragment_shader, geometry_shader, tesselation_control_shader, tesselation_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 tesselation control stage
3096 * @param tess_eval_shader Source code for tesselation 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 /* Tesselation 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 test_case_result = false;
6148 const std::string& fs_source = getShaderSource(test_case_index, Utils::Shader::FRAGMENT);
6149 const std::string& gs_source = getShaderSource(test_case_index, Utils::Shader::GEOMETRY);
6150 bool is_build_error = false;
6151 const bool is_failure_expected = isFailureExpected(test_case_index);
6152 Utils::Program program(m_context);
6153 const std::string& tcs_source = getShaderSource(test_case_index, Utils::Shader::TESS_CTRL);
6154 const std::string& tes_source = getShaderSource(test_case_index, Utils::Shader::TESS_EVAL);
6155 const std::string& vs_source = getShaderSource(test_case_index, Utils::Shader::VERTEX);
6159 program.Init("" /* cs */, fs_source, gs_source, tcs_source, tes_source, vs_source, false /* separable */);
6161 catch (Utils::Shader::InvalidSourceException& exc)
6163 if (false == is_failure_expected)
6165 m_context.getTestContext().getLog()
6166 << tcu::TestLog::Message << "Unexpected error in shader compilation: " << tcu::TestLog::EndMessage;
6170 #if DEBUG_NEG_LOG_ERROR
6174 m_context.getTestContext().getLog()
6175 << tcu::TestLog::Message << "Error in shader compilation was expected, logged for verification: "
6176 << tcu::TestLog::EndMessage;
6180 #endif /* DEBUG_NEG_LOG_ERROR */
6182 is_build_error = true;
6184 catch (Utils::Program::BuildException& exc)
6186 if (false == is_failure_expected)
6188 m_context.getTestContext().getLog()
6189 << tcu::TestLog::Message << "Unexpected error in program linking: " << tcu::TestLog::EndMessage;
6193 #if DEBUG_NEG_LOG_ERROR
6197 m_context.getTestContext().getLog()
6198 << tcu::TestLog::Message
6199 << "Error in program linking was expected, logged for verification: " << tcu::TestLog::EndMessage;
6203 #endif /* DEBUG_NEG_LOG_ERROR */
6205 is_build_error = true;
6208 if (is_build_error != is_failure_expected)
6210 test_case_result = false;
6214 return test_case_result;
6217 /* Constants used by TextureTestBase */
6218 const glw::GLuint TextureTestBase::m_width = 16;
6219 const glw::GLuint TextureTestBase::m_height = 16;
6223 * @param context Test context
6224 * @param test_name Name of test
6225 * @param test_description Description of test
6227 TextureTestBase::TextureTestBase(deqp::Context& context, const GLchar* test_name, const GLchar* test_description)
6228 : TestBase(context, test_name, test_description)
6232 /** Get locations for all inputs with automatic_location
6234 * @param program Program object
6235 * @param program_interface Interface of program
6237 void TextureTestBase::prepareAttribLocation(Utils::Program& program, Utils::ProgramInterface& program_interface)
6239 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
6241 Utils::Variable::PtrVector& inputs = si.m_inputs;
6243 for (Utils::Variable::PtrVector::iterator it = inputs.begin(); inputs.end() != it; ++it)
6245 /* Test does not specify location, query value and set */
6246 if (Utils::Variable::m_automatic_location == (*it)->m_descriptor.m_expected_location)
6248 GLuint index = program.GetResourceIndex((*it)->m_descriptor.m_name, GL_PROGRAM_INPUT);
6251 program.GetResource(GL_PROGRAM_INPUT, index, GL_LOCATION, 1 /* size */, &location);
6253 (*it)->m_descriptor.m_expected_location = location;
6258 /** Verifies contents of drawn image
6261 * @param color_0 Verified image
6263 * @return true if image is filled with 1, false otherwise
6265 bool TextureTestBase::checkResults(glw::GLuint /* test_case_index */, Utils::Texture& color_0)
6267 static const GLuint size = m_width * m_height;
6268 static const GLuint expected_color = 1;
6270 std::vector<GLuint> data;
6273 color_0.Get(GL_RED_INTEGER, GL_UNSIGNED_INT, &data[0]);
6275 for (GLuint i = 0; i < size; ++i)
6277 const GLuint color = data[i];
6279 if (expected_color != color)
6281 m_context.getTestContext().getLog() << tcu::TestLog::Message << "R32UI[" << i << "]:" << color
6282 << tcu::TestLog::EndMessage;
6290 /** Execute dispatch compute for 16x16x1
6294 void TextureTestBase::executeDispatchCall(GLuint /* test_case_index */)
6296 const Functions& gl = m_context.getRenderContext().getFunctions();
6298 gl.dispatchCompute(16 /* x */, 16 /* y */, 1 /* z */);
6299 GLU_EXPECT_NO_ERROR(gl.getError(), "DispatchCompute");
6302 /** Execute drawArrays for single vertex
6306 void TextureTestBase::executeDrawCall(GLuint /* test_case_index */)
6308 const Functions& gl = m_context.getRenderContext().getFunctions();
6310 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
6311 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
6314 /** Prepare code snippet that will pass in variables to out variables
6317 * @param varying_passthrough Collection of connections between in and out variables
6318 * @param stage Shader stage
6320 * @return Code that pass in variables to next stage
6322 std::string TextureTestBase::getPassSnippet(GLuint /* test_case_index */,
6323 Utils::VaryingPassthrough& varying_passthrough, Utils::Shader::STAGES stage)
6325 static const GLchar* separator = "\n ";
6327 /* Skip for compute shader */
6328 if (Utils::Shader::COMPUTE == stage)
6333 Utils::VaryingConnection::Vector& vector = varying_passthrough.Get(stage);
6335 std::string result = Utils::g_list;
6336 size_t position = 0;
6338 for (GLuint i = 0; i < vector.size(); ++i)
6341 Utils::VaryingConnection& connection = vector[i];
6343 Utils::Variable* in = connection.m_in;
6344 Utils::Variable* out = connection.m_out;
6346 Utils::Variable::FLAVOUR in_flavour = Utils::Variable::GetFlavour(stage, Utils::Variable::INPUT);
6347 Utils::Variable::FLAVOUR out_flavour = Utils::Variable::GetFlavour(stage, Utils::Variable::OUTPUT);
6349 const std::string passthrough =
6350 getVariablePassthrough("", in->m_descriptor, in_flavour, "", out->m_descriptor, out_flavour);
6352 Utils::insertElementOfList(passthrough.c_str(), separator, position, result);
6355 Utils::endList("", position, result);
6360 /** Basic implementation of method getProgramInterface
6366 void TextureTestBase::getProgramInterface(GLuint /* test_case_index */,
6367 Utils::ProgramInterface& /* program_interface */,
6368 Utils::VaryingPassthrough& /* varying_passthrough */)
6372 /** Prepare code snippet that will verify in and uniform variables
6375 * @param program_interface Interface of program
6376 * @param stage Shader stage
6378 * @return Code that verify variables
6380 std::string TextureTestBase::getVerificationSnippet(GLuint /* test_case_index */,
6381 Utils::ProgramInterface& program_interface,
6382 Utils::Shader::STAGES stage)
6384 static const GLchar* separator = " ||\n ";
6386 std::string verification = "if (LIST)\n"
6391 /* Get flavour of in and out variables */
6392 Utils::Variable::FLAVOUR in_flavour = Utils::Variable::GetFlavour(stage, Utils::Variable::INPUT);
6394 /* Get interface for shader stage */
6395 Utils::ShaderInterface& si = program_interface.GetShaderInterface(stage);
6397 /* There are no varialbes to verify */
6398 if ((0 == si.m_inputs.size()) && (0 == si.m_uniforms.size()) && (0 == si.m_ssb_blocks.size()))
6403 /* For each in variable insert verification code */
6404 size_t position = 0;
6406 for (GLuint i = 0; i < si.m_inputs.size(); ++i)
6408 const Utils::Variable& var = *si.m_inputs[i];
6409 const std::string& var_verification = getVariableVerifcation("", var.m_data, var.m_descriptor, in_flavour);
6411 Utils::insertElementOfList(var_verification.c_str(), separator, position, verification);
6414 /* For each unifrom variable insert verification code */
6415 for (GLuint i = 0; i < si.m_uniforms.size(); ++i)
6417 const Utils::Variable& var = *si.m_uniforms[i];
6418 const std::string& var_verification =
6419 getVariableVerifcation("", var.m_data, var.m_descriptor, Utils::Variable::BASIC);
6421 Utils::insertElementOfList(var_verification.c_str(), separator, position, verification);
6424 /* For each ssb variable insert verification code */
6425 for (GLuint i = 0; i < si.m_ssb_blocks.size(); ++i)
6427 const Utils::Variable& var = *si.m_ssb_blocks[i];
6428 const std::string& var_verification =
6429 getVariableVerifcation("", var.m_data, var.m_descriptor, Utils::Variable::BASIC);
6431 Utils::insertElementOfList(var_verification.c_str(), separator, position, verification);
6434 Utils::endList("", position, verification);
6436 #if DEBUG_TTB_VERIFICATION_SNIPPET_STAGE
6440 sprintf(buffer, "%d", stage + 10);
6441 Utils::replaceToken("0u", position, buffer, verification);
6444 #elif DEBUG_TTB_VERIFICATION_SNIPPET_VARIABLE
6446 if (Utils::Shader::VERTEX == stage)
6448 Utils::replaceToken("0u", position, "in_vs_first.x", verification);
6452 Utils::replaceToken("0u", position, "31u", verification);
6458 return verification;
6461 /** Selects if "compute" stage is relevant for test
6467 bool TextureTestBase::isComputeRelevant(GLuint /* test_case_index */)
6472 /** Selects if "draw" stages are relevant for test
6478 bool TextureTestBase::isDrawRelevant(GLuint /* test_case_index */)
6483 /** Prepare code that will do assignment of single in to single out
6485 * @param in_parent_name Name of parent in variable
6486 * @param in_variable Descriptor of in variable
6487 * @param in_flavour Flavoud of in variable
6488 * @param out_parent_name Name of parent out variable
6489 * @param out_variable Descriptor of out variable
6490 * @param out_flavour Flavoud of out variable
6492 * @return Code that does OUT = IN
6494 std::string TextureTestBase::getVariablePassthrough(const std::string& in_parent_name,
6495 const Utils::Variable::Descriptor& in_variable,
6496 Utils::Variable::FLAVOUR in_flavour,
6497 const std::string& out_parent_name,
6498 const Utils::Variable::Descriptor& out_variable,
6499 Utils::Variable::FLAVOUR out_flavour)
6503 GLuint member_index = 0;
6504 size_t position = 0;
6505 std::string result = Utils::g_list;
6506 static const GLchar* separator = ";\n ";
6508 /* For each member of each array element */
6511 const std::string in_name = Utils::Variable::GetReference(in_parent_name, in_variable, in_flavour, index);
6512 const std::string out_name = Utils::Variable::GetReference(out_parent_name, out_variable, out_flavour, index);
6513 std::string passthrough;
6515 /* Prepare verification */
6516 if (Utils::Variable::BUILTIN == in_variable.m_type)
6518 size_t pass_position = 0;
6520 passthrough = "OUT = IN;";
6522 Utils::replaceToken("OUT", pass_position, out_name.c_str(), passthrough);
6523 Utils::replaceToken("IN", pass_position, in_name.c_str(), passthrough);
6525 /* Increment index */
6530 const Utils::Interface* in_interface = in_variable.m_interface;
6531 const Utils::Interface* out_interface = out_variable.m_interface;
6533 if ((0 == in_interface) || (0 == out_interface))
6535 TCU_FAIL("Nullptr");
6538 const Utils::Variable::Descriptor& in_member = in_interface->m_members[member_index];
6539 const Utils::Variable::Descriptor& out_member = out_interface->m_members[member_index];
6541 passthrough = getVariablePassthrough(in_name, in_member, Utils::Variable::BASIC, out_name, out_member,
6542 Utils::Variable::BASIC);
6544 /* Increment member_index */
6547 /* Increment index and reset member_index if all members were processed */
6548 if (in_interface->m_members.size() == member_index)
6555 /* Check if loop should end */
6556 if ((index >= in_variable.m_n_array_elements) && (0 == member_index))
6561 Utils::insertElementOfList(passthrough.c_str(), separator, position, result);
6563 } while (true != done);
6565 Utils::endList("", position, result);
6571 /** Get verification of single variable
6573 * @param parent_name Name of parent variable
6574 * @param data Data that should be used as EXPECTED
6575 * @param variable Descriptor of variable
6576 * @param flavour Flavour of variable
6578 * @return Code that does (EXPECTED != VALUE) ||
6580 std::string TextureTestBase::getVariableVerifcation(const std::string& parent_name, const GLvoid* data,
6581 const Utils::Variable::Descriptor& variable,
6582 Utils::Variable::FLAVOUR flavour)
6584 static const GLchar* logic_op = " ||\n ";
6585 const GLuint n_elements = (0 == variable.m_n_array_elements) ? 1 : variable.m_n_array_elements;
6586 size_t position = 0;
6587 std::string result = Utils::g_list;
6588 GLint stride = variable.m_expected_stride_of_element;
6590 /* For each each array element */
6591 for (GLuint element = 0; element < n_elements; ++element)
6593 const std::string name = Utils::Variable::GetReference(parent_name, variable, flavour, element);
6595 /* Calculate data pointer */
6596 GLvoid* data_ptr = (GLvoid*)((GLubyte*)data + element * stride);
6598 /* Prepare verification */
6599 if (Utils::Variable::BUILTIN == variable.m_type)
6601 const std::string& expected = variable.m_builtin.GetGLSLConstructor(data_ptr);
6602 std::string verification;
6603 size_t verification_position = 0;
6605 verification = "(EXPECTED != NAME)";
6607 Utils::replaceToken("EXPECTED", verification_position, expected.c_str(), verification);
6608 Utils::replaceToken("NAME", verification_position, name.c_str(), verification);
6610 Utils::insertElementOfList(verification.c_str(), logic_op, position, result);
6614 const Utils::Interface* interface = variable.m_interface;
6618 TCU_FAIL("Nullptr");
6621 const GLuint n_members = static_cast<GLuint>(interface->m_members.size());
6623 /* for each member */
6624 for (GLuint member_index = 0; member_index < n_members; ++member_index)
6626 const Utils::Variable::Descriptor& member = interface->m_members[member_index];
6628 /* Get verification of member */
6629 const std::string& verification =
6630 getVariableVerifcation(name, (GLubyte*)data_ptr + member.m_offset, member, Utils::Variable::BASIC);
6632 Utils::insertElementOfList(verification.c_str(), logic_op, position, result);
6637 Utils::endList("", position, result);
6642 /** Prepare attributes, vertex array object and array buffer
6644 * @param test_case_index Index of test case
6645 * @param program_interface Interface of program
6646 * @param buffer Array buffer
6647 * @param vao Vertex array object
6649 void TextureTestBase::prepareAttributes(GLuint test_case_index, Utils::ProgramInterface& program_interface,
6650 Utils::Buffer& buffer, Utils::VertexArray& vao)
6652 bool use_component_qualifier = useComponentQualifier(test_case_index);
6654 /* Get shader interface */
6655 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
6657 /* Bind vao and buffer */
6661 /* Skip if there are no input variables in vertex shader */
6662 if (0 == si.m_inputs.size())
6667 /* Calculate vertex stride and check */
6668 GLint vertex_stride = 0;
6670 for (GLuint i = 0; i < si.m_inputs.size(); ++i)
6672 Utils::Variable& variable = *si.m_inputs[i];
6674 GLint variable_size = static_cast<GLuint>(variable.m_data_size);
6676 GLint ends_at = variable_size + variable.m_descriptor.m_offset;
6678 vertex_stride = std::max(vertex_stride, ends_at);
6681 /* Prepare buffer data and set up vao */
6682 std::vector<GLubyte> buffer_data;
6683 buffer_data.resize(vertex_stride);
6685 GLubyte* ptr = &buffer_data[0];
6687 for (GLuint i = 0; i < si.m_inputs.size(); ++i)
6689 Utils::Variable& variable = *si.m_inputs[i];
6691 memcpy(ptr + variable.m_descriptor.m_offset, variable.m_data, variable.m_data_size);
6693 if (false == use_component_qualifier)
6695 vao.Attribute(variable.m_descriptor.m_expected_location, variable.m_descriptor.m_builtin,
6696 variable.m_descriptor.m_n_array_elements, variable.m_descriptor.m_normalized,
6697 variable.GetStride(), (GLvoid*)(intptr_t)variable.m_descriptor.m_offset);
6699 else if (0 == variable.m_descriptor.m_expected_component)
6701 /* Components can only be applied to vectors.
6702 Assumption that test use all 4 components */
6703 const Utils::Type& type =
6704 Utils::Type::GetType(variable.m_descriptor.m_builtin.m_basic_type, 1 /* n_columns */, 4 /* n_rows */);
6706 vao.Attribute(variable.m_descriptor.m_expected_location, type, variable.m_descriptor.m_n_array_elements,
6707 variable.m_descriptor.m_normalized, variable.GetStride(),
6708 (GLvoid*)(intptr_t)variable.m_descriptor.m_offset);
6713 buffer.Data(Utils::Buffer::StaticDraw, vertex_stride, ptr);
6716 /** Get locations for all outputs with automatic_location
6718 * @param program Program object
6719 * @param program_interface Interface of program
6721 void TextureTestBase::prepareFragmentDataLoc(Utils::Program& program, Utils::ProgramInterface& program_interface)
6723 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
6724 Utils::Variable::PtrVector& outputs = si.m_outputs;
6726 for (Utils::Variable::PtrVector::iterator it = outputs.begin(); outputs.end() != it; ++it)
6728 /* Test does not specify location, query value and set */
6729 if (Utils::Variable::m_automatic_location == (*it)->m_descriptor.m_expected_location)
6731 GLuint index = program.GetResourceIndex((*it)->m_descriptor.m_name, GL_PROGRAM_OUTPUT);
6734 program.GetResource(GL_PROGRAM_OUTPUT, index, GL_LOCATION, 1 /* size */, &location);
6736 (*it)->m_descriptor.m_expected_location = location;
6741 /** Prepare framebuffer with single texture as color attachment
6743 * @param framebuffer Framebuffer
6744 * @param color_0_texture Texture that will used as color attachment
6746 void TextureTestBase::prepareFramebuffer(Utils::Framebuffer& framebuffer, Utils::Texture& color_0_texture)
6749 std::vector<GLuint> texture_data;
6750 texture_data.resize(m_width * m_height);
6752 for (GLuint i = 0; i < texture_data.size(); ++i)
6754 texture_data[i] = 0x20406080;
6757 /* Prepare texture */
6758 color_0_texture.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT,
6761 /* Prepare framebuffer */
6764 framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0, color_0_texture.m_id, m_width, m_height);
6766 framebuffer.ClearColor(0.0f, 0.0f, 0.0f, 0.0f);
6767 framebuffer.Clear(GL_COLOR_BUFFER_BIT);
6770 /** Prepare iamge unit for compute shader
6772 * @param location Uniform location
6773 * @param image_texture Texture that will used as color attachment
6775 void TextureTestBase::prepareImage(GLint location, Utils::Texture& image_texture) const
6777 static const GLuint image_unit = 0;
6779 std::vector<GLuint> texture_data;
6780 texture_data.resize(m_width * m_height);
6782 for (GLuint i = 0; i < texture_data.size(); ++i)
6784 texture_data[i] = 0x20406080;
6787 image_texture.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT,
6790 const Functions& gl = m_context.getRenderContext().getFunctions();
6792 gl.bindImageTexture(image_unit, image_texture.m_id, 0 /* level */, GL_FALSE /* layered */, 0 /* Layer */,
6793 GL_WRITE_ONLY, GL_R32UI);
6794 GLU_EXPECT_NO_ERROR(gl.getError(), "BindImageTexture");
6796 Utils::Program::Uniform(gl, Utils::Type::_int, 1 /* count */, location, &image_unit);
6799 /** Basic implementation
6802 * @param si Shader interface
6803 * @param program Program
6804 * @param cs_buffer Buffer for ssb blocks
6806 void TextureTestBase::prepareSSBs(GLuint /* test_case_index */, Utils::ShaderInterface& si, Utils::Program& program,
6807 Utils::Buffer& buffer)
6809 /* Skip if there are no input variables in vertex shader */
6810 if (0 == si.m_ssb_blocks.size())
6815 /* Calculate vertex stride */
6816 GLint ssbs_stride = 0;
6818 for (GLuint i = 0; i < si.m_ssb_blocks.size(); ++i)
6820 Utils::Variable& variable = *si.m_ssb_blocks[i];
6822 if (false == variable.IsBlock())
6827 GLint variable_stride = variable.GetStride();
6829 GLint ends_at = variable_stride + variable.m_descriptor.m_offset;
6831 ssbs_stride = std::max(ssbs_stride, ends_at);
6834 /* Set active program */
6839 buffer.Data(Utils::Buffer::StaticDraw, ssbs_stride, 0);
6841 /* Set up uniforms */
6842 for (GLuint i = 0; i < si.m_ssb_blocks.size(); ++i)
6844 Utils::Variable& variable = *si.m_ssb_blocks[i];
6846 /* prepareUnifor should work fine for ssb blocks */
6847 prepareUniform(program, variable, buffer);
6851 /** Basic implementation
6853 * @param test_case_index Test case index
6854 * @param program_interface Program interface
6855 * @param program Program
6856 * @param cs_buffer Buffer for compute shader stage
6858 void TextureTestBase::prepareSSBs(GLuint test_case_index, Utils::ProgramInterface& program_interface,
6859 Utils::Program& program, Utils::Buffer& cs_buffer)
6861 cs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
6863 Utils::ShaderInterface& cs = program_interface.GetShaderInterface(Utils::Shader::COMPUTE);
6865 prepareSSBs(test_case_index, cs, program, cs_buffer);
6867 cs_buffer.BindBase(Utils::Shader::COMPUTE);
6870 /** Basic implementation
6872 * @param test_case_index Test case index
6873 * @param program_interface Program interface
6874 * @param program Program
6875 * @param fs_buffer Buffer for fragment shader stage
6876 * @param gs_buffer Buffer for geometry shader stage
6877 * @param tcs_buffer Buffer for tesselation control shader stage
6878 * @param tes_buffer Buffer for tesselation evaluation shader stage
6879 * @param vs_buffer Buffer for vertex shader stage
6881 void TextureTestBase::prepareSSBs(GLuint test_case_index, Utils::ProgramInterface& program_interface,
6882 Utils::Program& program, Utils::Buffer& fs_buffer, Utils::Buffer& gs_buffer,
6883 Utils::Buffer& tcs_buffer, Utils::Buffer& tes_buffer, Utils::Buffer& vs_buffer)
6885 fs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
6886 gs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
6887 tcs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
6888 tes_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
6889 vs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
6891 Utils::ShaderInterface& fs = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
6892 Utils::ShaderInterface& gs = program_interface.GetShaderInterface(Utils::Shader::GEOMETRY);
6893 Utils::ShaderInterface& tcs = program_interface.GetShaderInterface(Utils::Shader::TESS_CTRL);
6894 Utils::ShaderInterface& tes = program_interface.GetShaderInterface(Utils::Shader::TESS_EVAL);
6895 Utils::ShaderInterface& vs = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
6897 prepareSSBs(test_case_index, fs, program, fs_buffer);
6898 prepareSSBs(test_case_index, gs, program, gs_buffer);
6899 prepareSSBs(test_case_index, tcs, program, tcs_buffer);
6900 prepareSSBs(test_case_index, tes, program, tes_buffer);
6901 prepareSSBs(test_case_index, vs, program, vs_buffer);
6903 fs_buffer.BindBase(Utils::Shader::FRAGMENT);
6904 gs_buffer.BindBase(Utils::Shader::GEOMETRY);
6905 tcs_buffer.BindBase(Utils::Shader::TESS_CTRL);
6906 tes_buffer.BindBase(Utils::Shader::TESS_EVAL);
6907 vs_buffer.BindBase(Utils::Shader::VERTEX);
6910 /** Updates buffer data with variable
6912 * @param program Program object
6913 * @param variable Variable
6914 * @param buffer Buffer
6916 void TextureTestBase::prepareUniform(Utils::Program& program, Utils::Variable& variable, Utils::Buffer& buffer)
6918 const Functions& gl = m_context.getRenderContext().getFunctions();
6920 GLsizei count = variable.m_descriptor.m_n_array_elements;
6926 if (Utils::Variable::BUILTIN == variable.m_descriptor.m_type)
6928 program.Uniform(gl, variable.m_descriptor.m_builtin, count, variable.m_descriptor.m_expected_location,
6933 const bool is_block = variable.IsBlock();
6935 if (false == is_block)
6937 TCU_FAIL("Not implemented");
6941 buffer.SubData(variable.m_descriptor.m_offset, variable.m_descriptor.m_expected_stride_of_element * count,
6947 /** Basic implementation
6950 * @param si Shader interface
6951 * @param program Program
6952 * @param cs_buffer Buffer for uniform blocks
6954 void TextureTestBase::prepareUniforms(GLuint /* test_case_index */, Utils::ShaderInterface& si, Utils::Program& program,
6955 Utils::Buffer& buffer)
6957 /* Skip if there are no input variables in vertex shader */
6958 if (0 == si.m_uniforms.size())
6963 /* Calculate vertex stride */
6964 GLint uniforms_stride = 0;
6966 for (GLuint i = 0; i < si.m_uniforms.size(); ++i)
6968 Utils::Variable& variable = *si.m_uniforms[i];
6970 if (false == variable.IsBlock())
6975 GLint variable_stride = variable.GetStride();
6977 GLint ends_at = variable_stride + variable.m_descriptor.m_offset;
6979 uniforms_stride = std::max(uniforms_stride, ends_at);
6982 /* Set active program */
6987 buffer.Data(Utils::Buffer::StaticDraw, uniforms_stride, 0);
6989 /* Set up uniforms */
6990 for (GLuint i = 0; i < si.m_uniforms.size(); ++i)
6992 Utils::Variable& variable = *si.m_uniforms[i];
6994 prepareUniform(program, variable, buffer);
6998 /** Basic implementation
7000 * @param test_case_index Test case index
7001 * @param program_interface Program interface
7002 * @param program Program
7003 * @param cs_buffer Buffer for compute shader stage
7005 void TextureTestBase::prepareUniforms(GLuint test_case_index, Utils::ProgramInterface& program_interface,
7006 Utils::Program& program, Utils::Buffer& cs_buffer)
7008 cs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7010 Utils::ShaderInterface& cs = program_interface.GetShaderInterface(Utils::Shader::COMPUTE);
7012 prepareUniforms(test_case_index, cs, program, cs_buffer);
7014 cs_buffer.BindBase(Utils::Shader::COMPUTE);
7017 /** Basic implementation
7019 * @param test_case_index Test case index
7020 * @param program_interface Program interface
7021 * @param program Program
7022 * @param fs_buffer Buffer for fragment shader stage
7023 * @param gs_buffer Buffer for geometry shader stage
7024 * @param tcs_buffer Buffer for tesselation control shader stage
7025 * @param tes_buffer Buffer for tesselation evaluation shader stage
7026 * @param vs_buffer Buffer for vertex shader stage
7028 void TextureTestBase::prepareUniforms(GLuint test_case_index, Utils::ProgramInterface& program_interface,
7029 Utils::Program& program, Utils::Buffer& fs_buffer, Utils::Buffer& gs_buffer,
7030 Utils::Buffer& tcs_buffer, Utils::Buffer& tes_buffer, Utils::Buffer& vs_buffer)
7032 fs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7033 gs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7034 tcs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7035 tes_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7036 vs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7038 Utils::ShaderInterface& fs = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
7039 Utils::ShaderInterface& gs = program_interface.GetShaderInterface(Utils::Shader::GEOMETRY);
7040 Utils::ShaderInterface& tcs = program_interface.GetShaderInterface(Utils::Shader::TESS_CTRL);
7041 Utils::ShaderInterface& tes = program_interface.GetShaderInterface(Utils::Shader::TESS_EVAL);
7042 Utils::ShaderInterface& vs = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
7044 prepareUniforms(test_case_index, fs, program, fs_buffer);
7045 prepareUniforms(test_case_index, gs, program, gs_buffer);
7046 prepareUniforms(test_case_index, tcs, program, tcs_buffer);
7047 prepareUniforms(test_case_index, tes, program, tes_buffer);
7048 prepareUniforms(test_case_index, vs, program, vs_buffer);
7050 fs_buffer.BindBase(Utils::Shader::FRAGMENT);
7051 gs_buffer.BindBase(Utils::Shader::GEOMETRY);
7052 tcs_buffer.BindBase(Utils::Shader::TESS_CTRL);
7053 tes_buffer.BindBase(Utils::Shader::TESS_EVAL);
7054 vs_buffer.BindBase(Utils::Shader::VERTEX);
7057 /** Basic implementation
7059 * @param test_case_index Test case index
7060 * @param program_interface Program interface
7061 * @param program Program
7062 * @param fs_buffer Buffer for fragment shader stage
7063 * @param gs_buffer Buffer for geometry shader stage
7064 * @param tcs_buffer Buffer for tesselation control shader stage
7065 * @param tes_buffer Buffer for tesselation evaluation shader stage
7066 * @param vs_buffer Buffer for vertex shader stage
7068 void TextureTestBase::prepareUniforms(GLuint test_case_index, Utils::ProgramInterface& program_interface,
7069 Utils::Program& fs_program, Utils::Program& gs_program,
7070 Utils::Program& tcs_program, Utils::Program& tes_program,
7071 Utils::Program& vs_program, Utils::Buffer& fs_buffer, Utils::Buffer& gs_buffer,
7072 Utils::Buffer& tcs_buffer, Utils::Buffer& tes_buffer, Utils::Buffer& vs_buffer)
7074 fs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7075 gs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7076 tcs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7077 tes_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7078 vs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7080 Utils::ShaderInterface& fs = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
7081 Utils::ShaderInterface& gs = program_interface.GetShaderInterface(Utils::Shader::GEOMETRY);
7082 Utils::ShaderInterface& tcs = program_interface.GetShaderInterface(Utils::Shader::TESS_CTRL);
7083 Utils::ShaderInterface& tes = program_interface.GetShaderInterface(Utils::Shader::TESS_EVAL);
7084 Utils::ShaderInterface& vs = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
7086 prepareUniforms(test_case_index, fs, fs_program, fs_buffer);
7087 fs_buffer.BindBase(Utils::Shader::FRAGMENT);
7089 prepareUniforms(test_case_index, gs, gs_program, gs_buffer);
7090 gs_buffer.BindBase(Utils::Shader::GEOMETRY);
7092 prepareUniforms(test_case_index, tcs, tcs_program, tcs_buffer);
7093 tcs_buffer.BindBase(Utils::Shader::TESS_CTRL);
7095 prepareUniforms(test_case_index, tes, tes_program, tes_buffer);
7096 tes_buffer.BindBase(Utils::Shader::TESS_EVAL);
7098 prepareUniforms(test_case_index, vs, vs_program, vs_buffer);
7099 vs_buffer.BindBase(Utils::Shader::VERTEX);
7102 /** Prepare source for shader
7104 * @param test_case_index Index of test case
7105 * @param program_interface Interface of program
7106 * @param varying_passthrough Collection of connection between in and out variables
7107 * @param stage Shader stage
7109 * @return Source of shader
7111 std::string TextureTestBase::getShaderSource(GLuint test_case_index, Utils::ProgramInterface& program_interface,
7112 Utils::VaryingPassthrough& varying_passthrough,
7113 Utils::Shader::STAGES stage)
7116 const GLchar* shader_template = getShaderTemplate(stage);
7117 const std::string& shader_interface = program_interface.GetInterfaceForStage(stage);
7119 const std::string& verification = getVerificationSnippet(test_case_index, program_interface, stage);
7121 const std::string& passthrough = getPassSnippet(test_case_index, varying_passthrough, stage);
7123 const GLchar* per_vertex = "";
7125 std::string source = shader_template;
7126 size_t position = 0;
7128 /* Replace tokens in template */
7129 if (Utils::Shader::GEOMETRY == stage)
7131 if (false == useMonolithicProgram(test_case_index))
7133 per_vertex = "out gl_PerVertex {\n"
7134 "vec4 gl_Position;\n"
7139 Utils::replaceToken("PERVERTEX", position, per_vertex, source);
7142 Utils::replaceToken("INTERFACE", position, shader_interface.c_str(), source);
7143 Utils::replaceToken("VERIFICATION", position, verification.c_str(), source);
7145 if (false == verification.empty())
7147 Utils::replaceAllTokens("ELSE", " else ", source);
7151 Utils::replaceAllTokens("ELSE", "", source);
7154 Utils::replaceAllTokens("PASSTHROUGH", passthrough.c_str(), source);
7160 /** Returns template of shader for given stage
7162 * @param stage Shade stage
7164 * @return Proper template
7166 const GLchar* TextureTestBase::getShaderTemplate(Utils::Shader::STAGES stage)
7169 static const GLchar* compute_shader_template =
7170 "#version 430 core\n"
7171 "#extension GL_ARB_enhanced_layouts : require\n"
7173 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
7175 "writeonly uniform uimage2D uni_image;\n"
7181 " uint result = 1u;\n"
7185 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), uvec4(result, 0, 0, 0));\n"
7189 static const GLchar* fragment_shader_template = "#version 430 core\n"
7190 "#extension GL_ARB_enhanced_layouts : require\n"
7192 "flat in uint gs_fs_result;\n"
7193 " out uint fs_out_result;\n"
7199 " uint result = 1u;\n"
7201 " if (1u != gs_fs_result)\n"
7203 " result = gs_fs_result;\n"
7207 " fs_out_result = result;\n"
7212 static const GLchar* geometry_shader_template =
7213 "#version 430 core\n"
7214 "#extension GL_ARB_enhanced_layouts : require\n"
7216 "layout(points) in;\n"
7217 "layout(triangle_strip, max_vertices = 4) out;\n"
7219 " in uint tes_gs_result[];\n"
7220 "flat out uint gs_fs_result;\n"
7222 "PERVERTEX" /* Separable programs require explicit declaration of gl_PerVertex */
7227 " uint result = 1u;\n"
7229 " if (1u != tes_gs_result[0])\n"
7231 " result = tes_gs_result[0];\n"
7235 " gs_fs_result = result;\n"
7237 " gl_Position = vec4(-1, -1, 0, 1);\n"
7239 " gs_fs_result = result;\n"
7241 " gl_Position = vec4(-1, 1, 0, 1);\n"
7243 " gs_fs_result = result;\n"
7245 " gl_Position = vec4(1, -1, 0, 1);\n"
7247 " gs_fs_result = result;\n"
7249 " gl_Position = vec4(1, 1, 0, 1);\n"
7254 static const GLchar* tess_ctrl_shader_template = "#version 430 core\n"
7255 "#extension GL_ARB_enhanced_layouts : require\n"
7257 "layout(vertices = 1) out;\n"
7259 "in uint vs_tcs_result[];\n"
7260 "out uint tcs_tes_result[];\n"
7266 " uint result = 1u;\n"
7268 " if (1u != vs_tcs_result[gl_InvocationID])\n"
7270 " result = vs_tcs_result[gl_InvocationID];\n"
7274 " tcs_tes_result[gl_InvocationID] = result;\n"
7278 " gl_TessLevelOuter[0] = 1.0;\n"
7279 " gl_TessLevelOuter[1] = 1.0;\n"
7280 " gl_TessLevelOuter[2] = 1.0;\n"
7281 " gl_TessLevelOuter[3] = 1.0;\n"
7282 " gl_TessLevelInner[0] = 1.0;\n"
7283 " gl_TessLevelInner[1] = 1.0;\n"
7287 static const GLchar* tess_eval_shader_template = "#version 430 core\n"
7288 "#extension GL_ARB_enhanced_layouts : require\n"
7290 "layout(isolines, point_mode) in;\n"
7292 "in uint tcs_tes_result[];\n"
7293 "out uint tes_gs_result;\n"
7299 " uint result = 1u;\n"
7301 " if (1 != tcs_tes_result[0])\n"
7303 " result = tcs_tes_result[0];\n"
7307 " tes_gs_result = result;\n"
7313 static const GLchar* vertex_shader_template = "#version 430 core\n"
7314 "#extension GL_ARB_enhanced_layouts : require\n"
7316 "out uint vs_tcs_result;\n"
7322 " uint result = 1u;\n"
7326 " vs_tcs_result = result;\n"
7332 const GLchar* result = 0;
7336 case Utils::Shader::COMPUTE:
7337 result = compute_shader_template;
7339 case Utils::Shader::FRAGMENT:
7340 result = fragment_shader_template;
7342 case Utils::Shader::GEOMETRY:
7343 result = geometry_shader_template;
7345 case Utils::Shader::TESS_CTRL:
7346 result = tess_ctrl_shader_template;
7348 case Utils::Shader::TESS_EVAL:
7349 result = tess_eval_shader_template;
7351 case Utils::Shader::VERTEX:
7352 result = vertex_shader_template;
7355 TCU_FAIL("Invalid enum");
7363 * @param test_case_index Id of test case
7365 * @return true if test case pass, false otherwise
7367 bool TextureTestBase::testCase(GLuint test_case_index)
7371 if (true == useMonolithicProgram(test_case_index))
7373 return testMonolithic(test_case_index);
7377 return testSeparable(test_case_index);
7380 catch (Utils::Shader::InvalidSourceException& exc)
7383 TCU_FAIL(exc.what());
7385 catch (Utils::Program::BuildException& exc)
7387 TCU_FAIL(exc.what());
7391 /** Runs "draw" test with monolithic program
7393 * @param test_case_index Id of test case
7395 bool TextureTestBase::testMonolithic(GLuint test_case_index)
7397 Utils::ProgramInterface program_interface;
7398 Utils::VaryingPassthrough varying_passthrough;
7401 const std::string& test_name = getTestCaseName(test_case_index);
7404 getProgramInterface(test_case_index, program_interface, varying_passthrough);
7408 if (true == isDrawRelevant(test_case_index))
7410 Utils::Buffer buffer_attr(m_context);
7411 Utils::Buffer buffer_ssb_fs(m_context);
7412 Utils::Buffer buffer_ssb_gs(m_context);
7413 Utils::Buffer buffer_ssb_tcs(m_context);
7414 Utils::Buffer buffer_ssb_tes(m_context);
7415 Utils::Buffer buffer_ssb_vs(m_context);
7416 Utils::Buffer buffer_u_fs(m_context);
7417 Utils::Buffer buffer_u_gs(m_context);
7418 Utils::Buffer buffer_u_tcs(m_context);
7419 Utils::Buffer buffer_u_tes(m_context);
7420 Utils::Buffer buffer_u_vs(m_context);
7421 Utils::Framebuffer framebuffer(m_context);
7422 Utils::Program program(m_context);
7423 Utils::Texture texture_fb(m_context);
7424 Utils::VertexArray vao(m_context);
7427 const std::string& fragment_shader =
7428 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::FRAGMENT);
7429 const std::string& geometry_shader =
7430 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::GEOMETRY);
7431 const std::string& tess_ctrl_shader =
7432 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::TESS_CTRL);
7433 const std::string& tess_eval_shader =
7434 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::TESS_EVAL);
7435 const std::string& vertex_shader =
7436 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::VERTEX);
7438 program.Init("" /* compute_shader */, fragment_shader, geometry_shader, tess_ctrl_shader, tess_eval_shader,
7439 vertex_shader, false /* is_separable */);
7442 prepareAttribLocation(program, program_interface);
7443 prepareFragmentDataLoc(program, program_interface);
7446 std::stringstream stream;
7447 if (false == Utils::checkMonolithicDrawProgramInterface(program, program_interface, stream))
7449 m_context.getTestContext().getLog()
7450 << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7451 << ". Inspection of draw program interface failed:\n"
7452 << stream.str() << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(vertex_shader)
7453 << tcu::TestLog::KernelSource(tess_ctrl_shader) << tcu::TestLog::KernelSource(tess_eval_shader)
7454 << tcu::TestLog::KernelSource(geometry_shader) << tcu::TestLog::KernelSource(fragment_shader);
7463 buffer_attr.Init(Utils::Buffer::Array, Utils::Buffer::StaticDraw, 0, 0);
7465 prepareAttributes(test_case_index, program_interface, buffer_attr, vao);
7468 prepareUniforms(test_case_index, program_interface, program, buffer_u_fs, buffer_u_gs, buffer_u_tcs,
7469 buffer_u_tes, buffer_u_vs);
7471 prepareSSBs(test_case_index, program_interface, program, buffer_ssb_fs, buffer_ssb_gs, buffer_ssb_tcs,
7472 buffer_ssb_tes, buffer_ssb_vs);
7475 prepareFramebuffer(framebuffer, texture_fb);
7478 executeDrawCall(test_case_index);
7481 m_context.getRenderContext().postIterate();
7485 if (false == checkResults(test_case_index, texture_fb))
7487 m_context.getTestContext().getLog()
7488 << tcu::TestLog::Message << "FAILURE. Test case: " << test_name << ". Draw - invalid results."
7489 << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(vertex_shader)
7490 << tcu::TestLog::KernelSource(tess_ctrl_shader) << tcu::TestLog::KernelSource(tess_eval_shader)
7491 << tcu::TestLog::KernelSource(geometry_shader) << tcu::TestLog::KernelSource(fragment_shader);
7498 if (true == isComputeRelevant(test_case_index))
7500 Utils::Buffer buffer_ssb_cs(m_context);
7501 Utils::Buffer buffer_u_cs(m_context);
7502 Utils::Program program(m_context);
7503 Utils::Texture texture_im(m_context);
7504 Utils::VertexArray vao(m_context);
7507 const std::string& compute_shader =
7508 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::COMPUTE);
7510 program.Init(compute_shader, "" /* fragment_shader */, "" /* geometry_shader */, "" /* tess_ctrl_shader */,
7511 "" /* tess_eval_shader */, "" /* vertex_shader */, false /* is_separable */);
7515 std::stringstream stream;
7517 if (false == Utils::checkMonolithicComputeProgramInterface(program, program_interface, stream))
7519 m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7520 << ". Inspection of compute program interface failed:\n"
7521 << stream.str() << tcu::TestLog::EndMessage;
7535 prepareUniforms(test_case_index, program_interface, program, buffer_u_cs);
7537 prepareSSBs(test_case_index, program_interface, program, buffer_ssb_cs);
7540 GLint image_location = program.GetUniformLocation("uni_image");
7541 prepareImage(image_location, texture_im);
7544 executeDispatchCall(test_case_index);
7547 m_context.getRenderContext().postIterate();
7551 if (false == checkResults(test_case_index, texture_im))
7553 m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7554 << ". Compute - invalid results." << tcu::TestLog::EndMessage
7555 << tcu::TestLog::KernelSource(compute_shader);
7564 /** Runs "draw" test with separable program
7566 * @param test_case_index Id of test case
7568 bool TextureTestBase::testSeparable(GLuint test_case_index)
7570 Utils::ProgramInterface program_interface;
7571 Utils::VaryingPassthrough varying_passthrough;
7574 const std::string& test_name = getTestCaseName(test_case_index);
7577 getProgramInterface(test_case_index, program_interface, varying_passthrough);
7581 if (true == isDrawRelevant(test_case_index))
7583 Utils::Buffer buffer_attr(m_context);
7584 Utils::Buffer buffer_u_fs(m_context);
7585 Utils::Buffer buffer_u_gs(m_context);
7586 Utils::Buffer buffer_u_tcs(m_context);
7587 Utils::Buffer buffer_u_tes(m_context);
7588 Utils::Buffer buffer_u_vs(m_context);
7589 Utils::Framebuffer framebuffer(m_context);
7590 Utils::Pipeline pipeline(m_context);
7591 Utils::Program program_fs(m_context);
7592 Utils::Program program_gs(m_context);
7593 Utils::Program program_tcs(m_context);
7594 Utils::Program program_tes(m_context);
7595 Utils::Program program_vs(m_context);
7596 Utils::Texture texture_fb(m_context);
7597 Utils::VertexArray vao(m_context);
7600 const std::string& fs =
7601 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::FRAGMENT);
7602 const std::string& gs =
7603 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::GEOMETRY);
7604 const std::string& tcs =
7605 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::TESS_CTRL);
7606 const std::string& tes =
7607 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::TESS_EVAL);
7608 const std::string& vs =
7609 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::VERTEX);
7611 program_fs.Init("" /*cs*/, fs, "" /*gs*/, "" /*tcs*/, "" /*tes*/, "" /*vs*/, true /* is_separable */);
7612 program_gs.Init("" /*cs*/, "" /*fs*/, gs, "" /*tcs*/, "" /*tes*/, "" /*vs*/, true /* is_separable */);
7613 program_tcs.Init("" /*cs*/, "" /*fs*/, "" /*gs*/, tcs, "" /*tes*/, "" /*vs*/, true /* is_separable */);
7614 program_tes.Init("" /*cs*/, "" /*fs*/, "" /*gs*/, "" /*tcs*/, tes, "" /*vs*/, true /* is_separable */);
7615 program_vs.Init("" /*cs*/, "" /*fs*/, "" /*gs*/, "" /*tcs*/, "" /*tes*/, vs, true /* is_separable */);
7618 prepareAttribLocation(program_vs, program_interface);
7619 prepareFragmentDataLoc(program_vs, program_interface);
7622 std::stringstream stream;
7624 Utils::checkSeparableDrawProgramInterface(program_vs, program_interface, Utils::Shader::VERTEX, stream)) ||
7625 (false == Utils::checkSeparableDrawProgramInterface(program_fs, program_interface, Utils::Shader::FRAGMENT,
7627 (false == Utils::checkSeparableDrawProgramInterface(program_gs, program_interface, Utils::Shader::GEOMETRY,
7629 (false == Utils::checkSeparableDrawProgramInterface(program_tcs, program_interface,
7630 Utils::Shader::TESS_CTRL, stream)) ||
7631 (false == Utils::checkSeparableDrawProgramInterface(program_tes, program_interface,
7632 Utils::Shader::TESS_EVAL, stream)))
7634 m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7635 << ". Inspection of separable draw program interface failed:\n"
7636 << stream.str() << tcu::TestLog::EndMessage
7637 << tcu::TestLog::KernelSource(vs) << tcu::TestLog::KernelSource(tcs)
7638 << tcu::TestLog::KernelSource(tes) << tcu::TestLog::KernelSource(gs)
7639 << tcu::TestLog::KernelSource(fs);
7646 pipeline.UseProgramStages(program_fs.m_id, GL_FRAGMENT_SHADER_BIT);
7647 pipeline.UseProgramStages(program_gs.m_id, GL_GEOMETRY_SHADER_BIT);
7648 pipeline.UseProgramStages(program_tcs.m_id, GL_TESS_CONTROL_SHADER_BIT);
7649 pipeline.UseProgramStages(program_tes.m_id, GL_TESS_EVALUATION_SHADER_BIT);
7650 pipeline.UseProgramStages(program_vs.m_id, GL_VERTEX_SHADER_BIT);
7655 buffer_attr.Init(Utils::Buffer::Array, Utils::Buffer::StaticDraw, 0, 0);
7657 prepareAttributes(test_case_index, program_interface, buffer_attr, vao);
7660 prepareUniforms(test_case_index, program_interface, program_fs, program_gs, program_tcs, program_tes,
7661 program_vs, buffer_u_fs, buffer_u_gs, buffer_u_tcs, buffer_u_tes, buffer_u_vs);
7663 Utils::Program::Use(m_context.getRenderContext().getFunctions(), Utils::Program::m_invalid_id);
7666 prepareFramebuffer(framebuffer, texture_fb);
7669 executeDrawCall(test_case_index);
7672 m_context.getRenderContext().postIterate();
7676 if (false == checkResults(test_case_index, texture_fb))
7678 m_context.getTestContext().getLog()
7679 << tcu::TestLog::Message << "FAILURE. Test case: " << test_name << ". Draw - invalid results."
7680 << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(vs) << tcu::TestLog::KernelSource(tcs)
7681 << tcu::TestLog::KernelSource(tes) << tcu::TestLog::KernelSource(gs) << tcu::TestLog::KernelSource(fs);
7688 if (true == isComputeRelevant(test_case_index))
7690 Utils::Buffer buffer_u_cs(m_context);
7691 Utils::Program program(m_context);
7692 Utils::Texture texture_im(m_context);
7693 Utils::VertexArray vao(m_context);
7696 const std::string& compute_shader =
7697 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::COMPUTE);
7699 program.Init(compute_shader, "" /* fragment_shader */, "" /* geometry_shader */, "" /* tess_ctrl_shader */,
7700 "" /* tess_eval_shader */, "" /* vertex_shader */, false /* is_separable */);
7704 std::stringstream stream;
7706 if (false == Utils::checkMonolithicComputeProgramInterface(program, program_interface, stream))
7708 m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7709 << ". Inspection of compute program interface failed:\n"
7710 << stream.str() << tcu::TestLog::EndMessage;
7724 prepareUniforms(test_case_index, program_interface, program, buffer_u_cs);
7727 GLint image_location = program.GetUniformLocation("uni_image");
7728 prepareImage(image_location, texture_im);
7731 executeDispatchCall(test_case_index);
7734 m_context.getRenderContext().postIterate();
7738 if (false == checkResults(test_case_index, texture_im))
7740 m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7741 << ". Compute - invalid results." << tcu::TestLog::EndMessage
7742 << tcu::TestLog::KernelSource(compute_shader);
7751 /** Basic implementation
7757 bool TextureTestBase::useComponentQualifier(glw::GLuint /* test_case_index */)
7762 /** Basic implementation
7768 bool TextureTestBase::useMonolithicProgram(GLuint /* test_case_index */)
7775 * @param context Test framework context
7777 APIConstantValuesTest::APIConstantValuesTest(deqp::Context& context)
7778 : TestCase(context, "api_constant_values", "Test verifies values of api constants")
7780 /* Nothing to be done here */
7785 * @return tcu::TestNode::STOP otherwise
7787 tcu::TestNode::IterateResult APIConstantValuesTest::iterate()
7789 static const GLuint expected_comp = 64;
7790 static const GLuint expected_xfb = 4;
7791 static const GLuint expected_sep = 4;
7795 bool test_result = true;
7797 const Functions& gl = m_context.getRenderContext().getFunctions();
7799 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_xfb);
7800 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
7801 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_comp);
7802 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
7803 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, &max_sep);
7804 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
7806 if (expected_xfb > (GLuint)max_xfb)
7808 m_context.getTestContext().getLog() << tcu::TestLog::Message
7809 << "Invalid GL_MAX_TRANSFORM_FEEDBACK_BUFFERS. Got " << max_xfb
7810 << " Expected at least " << expected_xfb << tcu::TestLog::EndMessage;
7812 test_result = false;
7815 if (expected_comp > (GLuint)max_comp)
7817 m_context.getTestContext().getLog()
7818 << tcu::TestLog::Message << "Invalid GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS. Got " << max_comp
7819 << " Expected at least " << expected_comp << tcu::TestLog::EndMessage;
7821 test_result = false;
7824 if (expected_sep > (GLuint)max_sep)
7826 m_context.getTestContext().getLog() << tcu::TestLog::Message
7827 << "Invalid GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS. Got " << max_comp
7828 << " Expected at least " << expected_comp << tcu::TestLog::EndMessage;
7830 test_result = false;
7834 if (true == test_result)
7836 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
7840 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
7844 return tcu::TestNode::STOP;
7849 * @param context Test framework context
7851 APIErrorsTest::APIErrorsTest(deqp::Context& context)
7852 : TestCase(context, "api_errors", "Test verifies errors reeturned by api")
7854 /* Nothing to be done here */
7859 * @return tcu::TestNode::STOP otherwise
7861 tcu::TestNode::IterateResult APIErrorsTest::iterate()
7866 Utils::Program program(m_context);
7867 bool test_result = true;
7869 const Functions& gl = m_context.getRenderContext().getFunctions();
7873 program.Init("" /* cs */, "#version 430 core\n"
7874 "#extension GL_ARB_enhanced_layouts : require\n"
7877 "out vec4 fs_out;\n"
7881 " fs_out = vs_fs;\n"
7884 "" /* gs */, "" /* tcs */, "" /* tes */, "#version 430 core\n"
7885 "#extension GL_ARB_enhanced_layouts : require\n"
7888 "layout (xfb_offset = 16) out vec4 vs_fs;\n"
7895 false /* separable */);
7897 catch (Utils::Shader::InvalidSourceException& exc)
7900 TCU_FAIL(exc.what());
7902 catch (Utils::Program::BuildException& exc)
7904 TCU_FAIL(exc.what());
7908 * - GetProgramInterfaceiv should generate INVALID_OPERATION when
7909 * <programInterface> is TRANSFORM_FEEDBACK_BUFFER and <pname> is one of the
7911 * * MAX_NAME_LENGTH,
7912 * * MAX_NUM_ACTIVE_VARIABLES;
7914 gl.getProgramInterfaceiv(program.m_id, GL_TRANSFORM_FEEDBACK_BUFFER, GL_MAX_NAME_LENGTH, ¶m);
7915 checkError(GL_INVALID_OPERATION, "GetProgramInterfaceiv(GL_TRANSFORM_FEEDBACK_BUFFER, GL_MAX_NAME_LENGTH)",
7919 * - GetProgramResourceIndex should generate INVALID_ENUM when
7920 * <programInterface> is TRANSFORM_FEEDBACK_BUFFER;
7922 gl.getProgramResourceIndex(program.m_id, GL_TRANSFORM_FEEDBACK_BUFFER, "0");
7923 checkError(GL_INVALID_ENUM, "GetProgramResourceIndex(GL_TRANSFORM_FEEDBACK_BUFFER)", test_result);
7925 * - GetProgramResourceName should generate INVALID_ENUM when
7926 * <programInterface> is TRANSFORM_FEEDBACK_BUFFER;
7928 gl.getProgramResourceName(program.m_id, GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, 64 /* bufSize */, &length,
7930 checkError(GL_INVALID_ENUM, "GetProgramResourceName(GL_TRANSFORM_FEEDBACK_BUFFER)", test_result);
7933 if (true == test_result)
7935 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
7939 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
7943 return tcu::TestNode::STOP;
7946 /** Check if error is the expected one.
7948 * @param expected_error Expected error
7949 * @param message Message to log in case of error
7950 * @param test_result Test result, set to false in case of invalid error
7952 void APIErrorsTest::checkError(GLenum expected_error, const GLchar* message, bool& test_result)
7954 const Functions& gl = m_context.getRenderContext().getFunctions();
7956 GLenum error = gl.getError();
7958 if (error != expected_error)
7960 m_context.getTestContext().getLog()
7961 << tcu::TestLog::Message << "Failure. Invalid error. Got " << glu::getErrorStr(error) << " expected "
7962 << glu::getErrorStr(expected_error) << " Msg: " << message << tcu::TestLog::EndMessage;
7964 test_result = false;
7970 * @param context Test framework context
7972 GLSLContantImmutablityTest::GLSLContantImmutablityTest(deqp::Context& context)
7973 : NegativeTestBase(context, "glsl_contant_immutablity", "Test verifies that glsl constants cannot be modified")
7975 /* Nothing to be done here */
7978 /** Source for given test case and stage
7980 * @param test_case_index Index of test case
7981 * @param stage Shader stage
7983 * @return Shader source
7985 std::string GLSLContantImmutablityTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
7987 static const GLchar* cs = "#version 430 core\n"
7988 "#extension GL_ARB_enhanced_layouts : require\n"
7990 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
7992 "writeonly uniform uimage2D uni_image;\n"
7996 " uint result = 1u;\n"
7999 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), uvec4(result, 0, 0, 0));\n"
8002 static const GLchar* fs = "#version 430 core\n"
8003 "#extension GL_ARB_enhanced_layouts : require\n"
8006 "out vec4 fs_out;\n"
8011 " fs_out = gs_fs;\n"
8014 static const GLchar* gs = "#version 430 core\n"
8015 "#extension GL_ARB_enhanced_layouts : require\n"
8017 "layout(points) in;\n"
8018 "layout(triangle_strip, max_vertices = 4) out;\n"
8020 "in vec4 tes_gs[];\n"
8026 " gs_fs = tes_gs[0];\n"
8027 " gl_Position = vec4(-1, -1, 0, 1);\n"
8029 " gs_fs = tes_gs[0];\n"
8030 " gl_Position = vec4(-1, 1, 0, 1);\n"
8032 " gs_fs = tes_gs[0];\n"
8033 " gl_Position = vec4(1, -1, 0, 1);\n"
8035 " gs_fs = tes_gs[0];\n"
8036 " gl_Position = vec4(1, 1, 0, 1);\n"
8040 static const GLchar* tcs = "#version 430 core\n"
8041 "#extension GL_ARB_enhanced_layouts : require\n"
8043 "layout(vertices = 1) out;\n"
8045 "in vec4 vs_tcs[];\n"
8046 "out vec4 tcs_tes[];\n"
8052 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
8054 " gl_TessLevelOuter[0] = 1.0;\n"
8055 " gl_TessLevelOuter[1] = 1.0;\n"
8056 " gl_TessLevelOuter[2] = 1.0;\n"
8057 " gl_TessLevelOuter[3] = 1.0;\n"
8058 " gl_TessLevelInner[0] = 1.0;\n"
8059 " gl_TessLevelInner[1] = 1.0;\n"
8062 static const GLchar* tes = "#version 430 core\n"
8063 "#extension GL_ARB_enhanced_layouts : require\n"
8065 "layout(isolines, point_mode) in;\n"
8067 "in vec4 tcs_tes[];\n"
8068 "out vec4 tes_gs;\n"
8073 " tes_gs = tcs_tes[0];\n"
8076 static const GLchar* vs = "#version 430 core\n"
8077 "#extension GL_ARB_enhanced_layouts : require\n"
8080 "out vec4 vs_tcs;\n"
8085 " vs_tcs = in_vs;\n"
8090 testCase& test_case = m_test_cases[test_case_index];
8092 if (Utils::Shader::COMPUTE == test_case.m_stage)
8094 size_t position = 0;
8098 Utils::replaceToken("CONSTANT", position, getConstantName(test_case.m_constant), source);
8102 std::string assignment = " CONSTANT = 3;\n";
8103 size_t position = 0;
8107 case Utils::Shader::FRAGMENT:
8110 case Utils::Shader::GEOMETRY:
8113 case Utils::Shader::TESS_CTRL:
8116 case Utils::Shader::TESS_EVAL:
8119 case Utils::Shader::VERTEX:
8123 TCU_FAIL("Invalid enum");
8126 if (test_case.m_stage == stage)
8128 Utils::replaceToken("CONSTANT", position, getConstantName(test_case.m_constant), assignment);
8136 Utils::replaceToken("ASSIGNMENT", position, assignment.c_str(), source);
8142 /** Get description of test case
8144 * @param test_case_index Index of test case
8146 * @return Constant name
8148 std::string GLSLContantImmutablityTest::getTestCaseName(GLuint test_case_index)
8150 std::string result = getConstantName(m_test_cases[test_case_index].m_constant);
8155 /** Get number of test cases
8157 * @return Number of test cases
8159 GLuint GLSLContantImmutablityTest::getTestCaseNumber()
8161 return static_cast<GLuint>(m_test_cases.size());
8164 /** Selects if "compute" stage is relevant for test
8166 * @param test_case_index Index of test case
8168 * @return true when tested stage is compute
8170 bool GLSLContantImmutablityTest::isComputeRelevant(GLuint test_case_index)
8172 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
8175 /** Prepare all test cases
8178 void GLSLContantImmutablityTest::testInit()
8180 for (GLuint constant = 0; constant < CONSTANTS_MAX; ++constant)
8182 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
8184 testCase test_case = { (CONSTANTS)constant, (Utils::Shader::STAGES)stage };
8186 m_test_cases.push_back(test_case);
8191 /** Get name of glsl constant
8193 * @param Constant id
8195 * @return Name of constant used in GLSL
8197 const GLchar* GLSLContantImmutablityTest::getConstantName(CONSTANTS constant)
8199 const GLchar* name = "";
8203 case GL_ARB_ENHANCED_LAYOUTS:
8204 name = "GL_ARB_enhanced_layouts";
8207 name = "gl_MaxTransformFeedbackBuffers";
8209 case GL_MAX_XFB_INT_COMP:
8210 name = "gl_MaxTransformFeedbackInterleavedComponents";
8213 TCU_FAIL("Invalid enum");
8221 * @param context Test framework context
8223 GLSLContantValuesTest::GLSLContantValuesTest(deqp::Context& context)
8224 : TextureTestBase(context, "glsl_contant_values", "Test verifies values of constant symbols")
8228 /** Selects if "compute" stage is relevant for test
8234 bool GLSLContantValuesTest::isComputeRelevant(GLuint /* test_case_index */)
8239 /** Prepare code snippet that will verify in and uniform variables
8243 * @param stage Shader stage
8245 * @return Code that verify variables
8247 std::string GLSLContantValuesTest::getVerificationSnippet(GLuint /* test_case_index */,
8248 Utils::ProgramInterface& /* program_interface */,
8249 Utils::Shader::STAGES stage)
8252 const Functions& gl = m_context.getRenderContext().getFunctions();
8254 GLint max_transform_feedback_buffers = 0;
8255 GLint max_transform_feedback_interleaved_components = 0;
8257 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_transform_feedback_buffers);
8258 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8259 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_transform_feedback_interleaved_components);
8260 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8262 std::string verification;
8264 if (Utils::Shader::VERTEX == stage)
8266 verification = "if (1 != GL_ARB_enhanced_layouts)\n"
8270 " else if (MAX_TRANSFORM_FEEDBACK_BUFFERS\n"
8271 " != gl_MaxTransformFeedbackBuffers)\n"
8275 " else if (MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS \n"
8276 " != gl_MaxTransformFeedbackInterleavedComponents)\n"
8281 size_t position = 0;
8284 sprintf(buffer, "%d", max_transform_feedback_buffers);
8285 Utils::replaceToken("MAX_TRANSFORM_FEEDBACK_BUFFERS", position, buffer, verification);
8287 sprintf(buffer, "%d", max_transform_feedback_interleaved_components);
8288 Utils::replaceToken("MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS", position, buffer, verification);
8295 return verification;
8300 * @param context Test framework context
8302 GLSLConstantIntegralExpressionTest::GLSLConstantIntegralExpressionTest(deqp::Context& context)
8303 : TextureTestBase(context, "glsl_constant_integral_expression",
8304 "Test verifies that symbols can be used as constant integral expressions")
8308 /** Get interface of program
8311 * @param program_interface Interface of program
8314 void GLSLConstantIntegralExpressionTest::getProgramInterface(GLuint /* test_case_index */,
8315 Utils::ProgramInterface& program_interface,
8316 Utils::VaryingPassthrough& /* varying_passthrough */)
8319 const Functions& gl = m_context.getRenderContext().getFunctions();
8321 GLint max_transform_feedback_buffers = 0;
8322 GLint max_transform_feedback_interleaved_components = 0;
8324 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_transform_feedback_buffers);
8325 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8326 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_transform_feedback_interleaved_components);
8327 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8329 GLuint gohan_div = std::max(1, max_transform_feedback_buffers / 16);
8330 GLuint goten_div = std::max(1, max_transform_feedback_interleaved_components / 16);
8332 m_gohan_length = max_transform_feedback_buffers / gohan_div;
8333 m_goten_length = max_transform_feedback_interleaved_components / goten_div;
8336 std::string globals = "uniform uint goku [GL_ARB_enhanced_layouts / 1];\n"
8337 "uniform uint gohan[gl_MaxTransformFeedbackBuffers / GOHAN_DIV];\n"
8338 "uniform uint goten[gl_MaxTransformFeedbackInterleavedComponents / GOTEN_DIV];\n";
8340 size_t position = 0;
8343 sprintf(buffer, "%d", gohan_div);
8344 Utils::replaceToken("GOHAN_DIV", position, buffer, globals);
8346 sprintf(buffer, "%d", goten_div);
8347 Utils::replaceToken("GOTEN_DIV", position, buffer, globals);
8349 program_interface.m_vertex.m_globals = globals;
8350 program_interface.m_tess_ctrl.m_globals = globals;
8351 program_interface.m_tess_eval.m_globals = globals;
8352 program_interface.m_geometry.m_globals = globals;
8353 program_interface.m_fragment.m_globals = globals;
8354 program_interface.m_compute.m_globals = globals;
8357 /** Prepare code snippet that will verify in and uniform variables
8363 * @return Code that verify variables
8365 std::string GLSLConstantIntegralExpressionTest::getVerificationSnippet(GLuint /* test_case_index */,
8366 Utils::ProgramInterface& /* program_interface */,
8367 Utils::Shader::STAGES /* stage */)
8369 std::string verification = "{\n"
8370 " uint goku_sum = 0;\n"
8371 " uint gohan_sum = 0;\n"
8372 " uint goten_sum = 0;\n"
8374 " for (uint i = 0u; i < goku.length(); ++i)\n"
8376 " goku_sum += goku[i];\n"
8379 " for (uint i = 0u; i < gohan.length(); ++i)\n"
8381 " gohan_sum += gohan[i];\n"
8384 " for (uint i = 0u; i < goten.length(); ++i)\n"
8386 " goten_sum += goten[i];\n"
8389 " if ( (1u != goku_sum) &&\n"
8390 " (EXPECTED_GOHAN_SUMu != gohan_sum) ||\n"
8391 " (EXPECTED_GOTEN_SUMu != goten_sum) )\n"
8397 size_t position = 0;
8400 sprintf(buffer, "%d", m_gohan_length);
8401 Utils::replaceToken("EXPECTED_GOHAN_SUM", position, buffer, verification);
8403 sprintf(buffer, "%d", m_goten_length);
8404 Utils::replaceToken("EXPECTED_GOTEN_SUM", position, buffer, verification);
8406 return verification;
8409 /** Prepare unifroms
8413 * @param program Program object
8416 void GLSLConstantIntegralExpressionTest::prepareUniforms(GLuint /* test_case_index */,
8417 Utils::ProgramInterface& /* program_interface */,
8418 Utils::Program& program, Utils::Buffer& /* cs_buffer */)
8420 static const GLuint uniform_data[16] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
8422 const Functions& gl = m_context.getRenderContext().getFunctions();
8424 GLint goku_location = program.GetUniformLocation("goku");
8425 GLint gohan_location = program.GetUniformLocation("gohan");
8426 GLint goten_location = program.GetUniformLocation("goten");
8428 program.Uniform(gl, Utils::Type::uint, 1 /* count */, goku_location, uniform_data);
8429 program.Uniform(gl, Utils::Type::uint, m_gohan_length, gohan_location, uniform_data);
8430 program.Uniform(gl, Utils::Type::uint, m_goten_length, goten_location, uniform_data);
8433 /** Prepare unifroms
8435 * @param test_case_index Pass as param to first implemetnation
8436 * @param program_interface Pass as param to first implemetnation
8437 * @param program Pass as param to first implemetnation
8442 * @param vs_buffer Pass as param to first implemetnation
8444 void GLSLConstantIntegralExpressionTest::prepareUniforms(GLuint test_case_index,
8445 Utils::ProgramInterface& program_interface,
8446 Utils::Program& program, Utils::Buffer& /* fs_buffer */,
8447 Utils::Buffer& /* gs_buffer */,
8448 Utils::Buffer& /* tcs_buffer */,
8449 Utils::Buffer& /* tes_buffer */, Utils::Buffer& vs_buffer)
8451 /* Call first implementation */
8452 prepareUniforms(test_case_index, program_interface, program, vs_buffer);
8457 * @param context Test framework context
8459 UniformBlockMemberOffsetAndAlignTest::UniformBlockMemberOffsetAndAlignTest(deqp::Context& context)
8460 : TextureTestBase(context, "uniform_block_member_offset_and_align",
8461 "Test verifies offsets and alignment of uniform buffer members")
8465 /** Get interface of program
8467 * @param test_case_index Test case index
8468 * @param program_interface Interface of program
8469 * @param varying_passthrough Collection of connections between in and out variables
8471 void UniformBlockMemberOffsetAndAlignTest::getProgramInterface(GLuint test_case_index,
8472 Utils::ProgramInterface& program_interface,
8473 Utils::VaryingPassthrough& varying_passthrough)
8475 std::string globals = "const int basic_size = BASIC_SIZE;\n"
8476 "const int type_align = TYPE_ALIGN;\n"
8477 "const int type_size = TYPE_SIZE;\n";
8479 Utils::Type type = getType(test_case_index);
8480 GLuint basic_size = Utils::Type::GetTypeSize(type.m_basic_type);
8481 const GLuint base_align = type.GetBaseAlignment(false);
8482 const GLuint array_align = type.GetBaseAlignment(true);
8483 const GLuint base_stride = Utils::Type::CalculateStd140Stride(base_align, type.m_n_columns, 0);
8484 const GLuint type_align = Utils::roundUpToPowerOf2(base_stride);
8486 /* Calculate offsets */
8487 const GLuint first_offset = 0;
8488 const GLuint second_offset = type.GetActualOffset(base_stride, basic_size / 2);
8490 #if WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST
8492 const GLuint third_offset = type.GetActualOffset(second_offset + base_stride, base_align);
8493 const GLuint fourth_offset = type.GetActualOffset(third_offset + base_stride, base_align);
8494 const GLuint fifth_offset = type.GetActualOffset(fourth_offset + base_stride, base_align);
8495 const GLuint sixth_offset = type.GetActualOffset(fifth_offset + base_stride, array_align);
8496 const GLuint seventh_offset = type.GetActualOffset(sixth_offset + base_stride, array_align);
8497 const GLuint eigth_offset = type.GetActualOffset(seventh_offset + base_stride, array_align);
8499 #else /* WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST */
8501 const GLuint third_offset = type.GetActualOffset(second_offset + base_stride, 2 * type_align);
8502 const GLuint fourth_offset = type.GetActualOffset(3 * type_align + base_stride, base_align);
8503 const GLuint fifth_offset = type.GetActualOffset(fourth_offset + base_stride, base_align);
8504 const GLuint sixth_offset = type.GetActualOffset(fifth_offset + base_stride, array_align);
8505 const GLuint seventh_offset = type.GetActualOffset(sixth_offset + base_stride, array_align);
8506 const GLuint eigth_offset = type.GetActualOffset(seventh_offset + base_stride, 8 * basic_size);
8508 #endif /* WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST */
8511 const std::vector<GLubyte>& first = type.GenerateData();
8512 const std::vector<GLubyte>& second = type.GenerateData();
8513 const std::vector<GLubyte>& third = type.GenerateData();
8514 const std::vector<GLubyte>& fourth = type.GenerateData();
8516 m_data.resize(eigth_offset + base_stride);
8517 GLubyte* ptr = &m_data[0];
8518 memcpy(ptr + first_offset, &first[0], first.size());
8519 memcpy(ptr + second_offset, &second[0], second.size());
8520 memcpy(ptr + third_offset, &third[0], third.size());
8521 memcpy(ptr + fourth_offset, &fourth[0], fourth.size());
8522 memcpy(ptr + fifth_offset, &fourth[0], fourth.size());
8523 memcpy(ptr + sixth_offset, &third[0], third.size());
8524 memcpy(ptr + seventh_offset, &second[0], second.size());
8525 memcpy(ptr + eigth_offset, &first[0], first.size());
8527 /* Prepare globals */
8528 size_t position = 0;
8531 sprintf(buffer, "%d", basic_size);
8532 Utils::replaceToken("BASIC_SIZE", position, buffer, globals);
8534 sprintf(buffer, "%d", type_align);
8535 Utils::replaceToken("TYPE_ALIGN", position, buffer, globals);
8537 sprintf(buffer, "%d", base_stride);
8538 Utils::replaceToken("TYPE_SIZE", position, buffer, globals);
8541 Utils::Interface* vs_uni_block = program_interface.Block("vs_uni_Block");
8543 vs_uni_block->Member("at_first_offset", "layout(offset = 0, align = 8 * basic_size)", 0 /* expected_component */,
8544 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
8547 vs_uni_block->Member("at_second_offset", "layout(offset = type_size, align = basic_size / 2)",
8548 0 /* expected_component */, 0 /* expected_location */, type, false /* normalized */,
8549 0 /* n_array_elements */, base_stride, second_offset);
8551 vs_uni_block->Member("at_third_offset", "layout(align = 2 * type_align)", 0 /* expected_component */,
8552 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
8555 vs_uni_block->Member("at_fourth_offset", "layout(offset = 3 * type_align + type_size)", 0 /* expected_component */,
8556 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
8559 vs_uni_block->Member("at_fifth_offset", "", 0 /* expected_component */, 0 /* expected_location */, type,
8560 false /* normalized */, 0 /* n_array_elements */, base_stride, fifth_offset);
8562 vs_uni_block->Member("at_sixth_offset", "", 0 /* expected_component */, 0 /* expected_location */, type,
8563 false /* normalized */, 2 /* n_array_elements */, array_align * 2, sixth_offset);
8565 vs_uni_block->Member("at_eigth_offset", "layout(align = 8 * basic_size)", 0 /* expected_component */,
8566 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
8569 Utils::ShaderInterface& vs_si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
8572 vs_si.m_globals = globals;
8574 /* Add uniform BLOCK */
8575 vs_si.Uniform("vs_uni_block", "layout (std140, binding = BINDING)", 0, 0, vs_uni_block, 0,
8576 static_cast<glw::GLint>(m_data.size()), 0, &m_data[0], m_data.size());
8579 program_interface.CloneVertexInterface(varying_passthrough);
8584 * @param test_case_index Index of test case
8586 * @return Name of type test in test_case_index
8588 std::string UniformBlockMemberOffsetAndAlignTest::getTestCaseName(glw::GLuint test_case_index)
8590 return getTypeName(test_case_index);
8593 /** Returns number of types to test
8595 * @return Number of types, 34
8597 glw::GLuint UniformBlockMemberOffsetAndAlignTest::getTestCaseNumber()
8599 return getTypesNumber();
8602 /** Prepare code snippet that will verify in and uniform variables
8606 * @param stage Shader stage
8608 * @return Code that verify variables
8610 std::string UniformBlockMemberOffsetAndAlignTest::getVerificationSnippet(
8611 GLuint /* test_case_index */, Utils::ProgramInterface& /* program_interface */, Utils::Shader::STAGES stage)
8613 std::string verification = "if ( (PREFIXblock.at_first_offset != PREFIXblock.at_eigth_offset ) ||\n"
8614 " (PREFIXblock.at_second_offset != PREFIXblock.at_sixth_offset[1]) ||\n"
8615 " (PREFIXblock.at_third_offset != PREFIXblock.at_sixth_offset[0]) ||\n"
8616 " (PREFIXblock.at_fourth_offset != PREFIXblock.at_fifth_offset ) )\n"
8621 const GLchar* prefix = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::UNIFORM);
8623 Utils::replaceAllTokens("PREFIX", prefix, verification);
8625 return verification;
8630 * @param context Test framework context
8632 UniformBlockLayoutQualifierConflictTest::UniformBlockLayoutQualifierConflictTest(deqp::Context& context)
8634 context, "uniform_block_layout_qualifier_conflict",
8635 "Test verifies that std140 is required when offset and/or align qualifiers are used with uniform block")
8637 /* Nothing to be done here */
8640 /** Source for given test case and stage
8642 * @param test_case_index Index of test case
8643 * @param stage Shader stage
8645 * @return Shader source
8647 std::string UniformBlockLayoutQualifierConflictTest::getShaderSource(GLuint test_case_index,
8648 Utils::Shader::STAGES stage)
8650 static const GLchar* cs = "#version 430 core\n"
8651 "#extension GL_ARB_enhanced_layouts : require\n"
8653 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
8655 "LAYOUTuniform Block {\n"
8656 " layout(offset = 16) vec4 boy;\n"
8657 " layout(align = 64) vec4 man;\n"
8660 "writeonly uniform image2D uni_image;\n"
8664 " vec4 result = uni_block.boy + uni_block.man;\n"
8666 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
8669 static const GLchar* fs = "#version 430 core\n"
8670 "#extension GL_ARB_enhanced_layouts : require\n"
8672 "LAYOUTuniform Block {\n"
8673 " layout(offset = 16) vec4 boy;\n"
8674 " layout(align = 64) vec4 man;\n"
8678 "out vec4 fs_out;\n"
8682 " fs_out = gs_fs + uni_block.boy + uni_block.man;\n"
8685 static const GLchar* gs = "#version 430 core\n"
8686 "#extension GL_ARB_enhanced_layouts : require\n"
8688 "layout(points) in;\n"
8689 "layout(triangle_strip, max_vertices = 4) out;\n"
8691 "LAYOUTuniform Block {\n"
8692 " layout(offset = 16) vec4 boy;\n"
8693 " layout(align = 64) vec4 man;\n"
8696 "in vec4 tes_gs[];\n"
8701 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
8702 " gl_Position = vec4(-1, -1, 0, 1);\n"
8704 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
8705 " gl_Position = vec4(-1, 1, 0, 1);\n"
8707 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
8708 " gl_Position = vec4(1, -1, 0, 1);\n"
8710 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
8711 " gl_Position = vec4(1, 1, 0, 1);\n"
8715 static const GLchar* tcs =
8716 "#version 430 core\n"
8717 "#extension GL_ARB_enhanced_layouts : require\n"
8719 "layout(vertices = 1) out;\n"
8721 "LAYOUTuniform Block {\n"
8722 " layout(offset = 16) vec4 boy;\n"
8723 " layout(align = 64) vec4 man;\n"
8726 "in vec4 vs_tcs[];\n"
8727 "out vec4 tcs_tes[];\n"
8732 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID] + uni_block.boy + uni_block.man;\n"
8734 " gl_TessLevelOuter[0] = 1.0;\n"
8735 " gl_TessLevelOuter[1] = 1.0;\n"
8736 " gl_TessLevelOuter[2] = 1.0;\n"
8737 " gl_TessLevelOuter[3] = 1.0;\n"
8738 " gl_TessLevelInner[0] = 1.0;\n"
8739 " gl_TessLevelInner[1] = 1.0;\n"
8742 static const GLchar* tes = "#version 430 core\n"
8743 "#extension GL_ARB_enhanced_layouts : require\n"
8745 "layout(isolines, point_mode) in;\n"
8747 "LAYOUTuniform Block {\n"
8748 " layout(offset = 16) vec4 boy;\n"
8749 " layout(align = 64) vec4 man;\n"
8752 "in vec4 tcs_tes[];\n"
8753 "out vec4 tes_gs;\n"
8757 " tes_gs = tcs_tes[0] + uni_block.boy + uni_block.man;\n"
8760 static const GLchar* vs = "#version 430 core\n"
8761 "#extension GL_ARB_enhanced_layouts : require\n"
8763 "LAYOUTuniform Block {\n"
8764 " layout(offset = 16) vec4 boy;\n"
8765 " layout(align = 64) vec4 man;\n"
8769 "out vec4 vs_tcs;\n"
8773 " vs_tcs = in_vs + uni_block.boy + uni_block.man;\n"
8777 std::string layout = "";
8778 size_t position = 0;
8779 testCase& test_case = m_test_cases[test_case_index];
8780 const GLchar* qualifier = getQualifierName(test_case.m_qualifier);
8783 if (0 != qualifier[0])
8785 size_t layout_position = 0;
8787 layout = "layout (QUALIFIER) ";
8789 Utils::replaceToken("QUALIFIER", layout_position, qualifier, layout);
8794 case Utils::Shader::COMPUTE:
8797 case Utils::Shader::FRAGMENT:
8800 case Utils::Shader::GEOMETRY:
8803 case Utils::Shader::TESS_CTRL:
8806 case Utils::Shader::TESS_EVAL:
8809 case Utils::Shader::VERTEX:
8813 TCU_FAIL("Invalid enum");
8816 if (test_case.m_stage == stage)
8818 Utils::replaceToken("LAYOUT", position, layout.c_str(), source);
8822 Utils::replaceToken("LAYOUT", position, "layout (std140) ", source);
8828 /** Get description of test case
8830 * @param test_case_index Index of test case
8832 * @return Qualifier name
8834 std::string UniformBlockLayoutQualifierConflictTest::getTestCaseName(GLuint test_case_index)
8836 std::string result = getQualifierName(m_test_cases[test_case_index].m_qualifier);
8841 /** Get number of test cases
8843 * @return Number of test cases
8845 GLuint UniformBlockLayoutQualifierConflictTest::getTestCaseNumber()
8847 return static_cast<GLuint>(m_test_cases.size());
8850 /** Selects if "compute" stage is relevant for test
8852 * @param test_case_index Index of test case
8854 * @return true when tested stage is compute
8856 bool UniformBlockLayoutQualifierConflictTest::isComputeRelevant(GLuint test_case_index)
8858 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
8861 /** Selects if compilation failure is expected result
8863 * @param test_case_index Index of test case
8865 * @return false for STD140 cases, true otherwise
8867 bool UniformBlockLayoutQualifierConflictTest::isFailureExpected(GLuint test_case_index)
8869 return (STD140 != m_test_cases[test_case_index].m_qualifier);
8872 /** Prepare all test cases
8875 void UniformBlockLayoutQualifierConflictTest::testInit()
8877 for (GLuint qualifier = 0; qualifier < QUALIFIERS_MAX; ++qualifier)
8879 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
8881 testCase test_case = { (QUALIFIERS)qualifier, (Utils::Shader::STAGES)stage };
8883 m_test_cases.push_back(test_case);
8888 /** Get name of glsl constant
8890 * @param Constant id
8892 * @return Name of constant used in GLSL
8894 const GLchar* UniformBlockLayoutQualifierConflictTest::getQualifierName(QUALIFIERS qualifier)
8896 const GLchar* name = "";
8913 TCU_FAIL("Invalid enum");
8921 * @param context Test framework context
8923 UniformBlockMemberInvalidOffsetAlignmentTest::UniformBlockMemberInvalidOffsetAlignmentTest(deqp::Context& context)
8924 : NegativeTestBase(context, "uniform_block_member_invalid_offset_alignment",
8925 "Test verifies that invalid alignment of offset qualifiers cause compilation failure")
8927 /* Nothing to be done here */
8932 * @param context Test framework context
8933 * @param name Test name
8934 * @param description Test description
8936 UniformBlockMemberInvalidOffsetAlignmentTest::UniformBlockMemberInvalidOffsetAlignmentTest(
8937 deqp::Context& context, const glw::GLchar* name, const glw::GLchar* description)
8938 : NegativeTestBase(context, name, description)
8940 /* Nothing to be done here */
8943 /** Source for given test case and stage
8945 * @param test_case_index Index of test case
8946 * @param stage Shader stage
8948 * @return Shader source
8950 std::string UniformBlockMemberInvalidOffsetAlignmentTest::getShaderSource(GLuint test_case_index,
8951 Utils::Shader::STAGES stage)
8953 static const GLchar* cs = "#version 430 core\n"
8954 "#extension GL_ARB_enhanced_layouts : require\n"
8956 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
8958 "layout (std140) uniform Block {\n"
8959 " layout (offset = OFFSET) TYPE member;\n"
8962 "writeonly uniform image2D uni_image;\n"
8966 " vec4 result = vec4(1, 0, 0.5, 1);\n"
8968 " if (TYPE(1) == block.member)\n"
8970 " result = vec4(1, 1, 1, 1);\n"
8973 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
8976 static const GLchar* fs = "#version 430 core\n"
8977 "#extension GL_ARB_enhanced_layouts : require\n"
8980 "out vec4 fs_out;\n"
8984 " fs_out = gs_fs;\n"
8987 static const GLchar* fs_tested = "#version 430 core\n"
8988 "#extension GL_ARB_enhanced_layouts : require\n"
8990 "layout (std140) uniform Block {\n"
8991 " layout (offset = OFFSET) TYPE member;\n"
8995 "out vec4 fs_out;\n"
8999 " if (TYPE(1) == block.member)\n"
9001 " fs_out = vec4(1, 1, 1, 1);\n"
9004 " fs_out += gs_fs;\n"
9007 static const GLchar* gs = "#version 430 core\n"
9008 "#extension GL_ARB_enhanced_layouts : require\n"
9010 "layout(points) in;\n"
9011 "layout(triangle_strip, max_vertices = 4) out;\n"
9013 "in vec4 tes_gs[];\n"
9018 " gs_fs = tes_gs[0];\n"
9019 " gl_Position = vec4(-1, -1, 0, 1);\n"
9021 " gs_fs = tes_gs[0];\n"
9022 " gl_Position = vec4(-1, 1, 0, 1);\n"
9024 " gs_fs = tes_gs[0];\n"
9025 " gl_Position = vec4(1, -1, 0, 1);\n"
9027 " gs_fs = tes_gs[0];\n"
9028 " gl_Position = vec4(1, 1, 0, 1);\n"
9032 static const GLchar* gs_tested = "#version 430 core\n"
9033 "#extension GL_ARB_enhanced_layouts : require\n"
9035 "layout(points) in;\n"
9036 "layout(triangle_strip, max_vertices = 4) out;\n"
9038 "layout (std140) uniform Block {\n"
9039 " layout (offset = OFFSET) TYPE member;\n"
9042 "in vec4 tes_gs[];\n"
9047 " if (TYPE(1) == block.member)\n"
9049 " gs_fs = vec4(1, 1, 1, 1);\n"
9052 " gs_fs += tes_gs[0];\n"
9053 " gl_Position = vec4(-1, -1, 0, 1);\n"
9055 " gs_fs += tes_gs[0];\n"
9056 " gl_Position = vec4(-1, 1, 0, 1);\n"
9058 " gs_fs += tes_gs[0];\n"
9059 " gl_Position = vec4(1, -1, 0, 1);\n"
9061 " gs_fs += tes_gs[0];\n"
9062 " gl_Position = vec4(1, 1, 0, 1);\n"
9066 static const GLchar* tcs = "#version 430 core\n"
9067 "#extension GL_ARB_enhanced_layouts : require\n"
9069 "layout(vertices = 1) out;\n"
9071 "in vec4 vs_tcs[];\n"
9072 "out vec4 tcs_tes[];\n"
9077 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
9079 " gl_TessLevelOuter[0] = 1.0;\n"
9080 " gl_TessLevelOuter[1] = 1.0;\n"
9081 " gl_TessLevelOuter[2] = 1.0;\n"
9082 " gl_TessLevelOuter[3] = 1.0;\n"
9083 " gl_TessLevelInner[0] = 1.0;\n"
9084 " gl_TessLevelInner[1] = 1.0;\n"
9087 static const GLchar* tcs_tested = "#version 430 core\n"
9088 "#extension GL_ARB_enhanced_layouts : require\n"
9090 "layout(vertices = 1) out;\n"
9092 "layout (std140) uniform Block {\n"
9093 " layout (offset = OFFSET) TYPE member;\n"
9096 "in vec4 vs_tcs[];\n"
9097 "out vec4 tcs_tes[];\n"
9101 " if (TYPE(1) == block.member)\n"
9103 " tcs_tes[gl_InvocationID] = vec4(1, 1, 1, 1);\n"
9107 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
9109 " gl_TessLevelOuter[0] = 1.0;\n"
9110 " gl_TessLevelOuter[1] = 1.0;\n"
9111 " gl_TessLevelOuter[2] = 1.0;\n"
9112 " gl_TessLevelOuter[3] = 1.0;\n"
9113 " gl_TessLevelInner[0] = 1.0;\n"
9114 " gl_TessLevelInner[1] = 1.0;\n"
9117 static const GLchar* tes = "#version 430 core\n"
9118 "#extension GL_ARB_enhanced_layouts : require\n"
9120 "layout(isolines, point_mode) in;\n"
9122 "in vec4 tcs_tes[];\n"
9123 "out vec4 tes_gs;\n"
9127 " tes_gs = tcs_tes[0];\n"
9130 static const GLchar* tes_tested = "#version 430 core\n"
9131 "#extension GL_ARB_enhanced_layouts : require\n"
9133 "layout(isolines, point_mode) in;\n"
9135 "layout (std140) uniform Block {\n"
9136 " layout (offset = OFFSET) TYPE member;\n"
9139 "in vec4 tcs_tes[];\n"
9140 "out vec4 tes_gs;\n"
9144 " if (TYPE(1) == block.member)\n"
9146 " tes_gs = vec4(1, 1, 1, 1);\n"
9149 " tes_gs += tcs_tes[0];\n"
9152 static const GLchar* vs = "#version 430 core\n"
9153 "#extension GL_ARB_enhanced_layouts : require\n"
9156 "out vec4 vs_tcs;\n"
9160 " vs_tcs = in_vs;\n"
9163 static const GLchar* vs_tested = "#version 430 core\n"
9164 "#extension GL_ARB_enhanced_layouts : require\n"
9166 "layout (std140) uniform Block {\n"
9167 " layout (offset = OFFSET) TYPE member;\n"
9171 "out vec4 vs_tcs;\n"
9175 " if (TYPE(1) == block.member)\n"
9177 " vs_tcs = vec4(1, 1, 1, 1);\n"
9180 " vs_tcs += in_vs;\n"
9185 testCase& test_case = m_test_cases[test_case_index];
9187 if (test_case.m_stage == stage)
9190 const GLuint offset = test_case.m_offset;
9191 size_t position = 0;
9192 const Utils::Type& type = test_case.m_type;
9193 const GLchar* type_name = type.GetGLSLTypeName();
9195 sprintf(buffer, "%d", offset);
9199 case Utils::Shader::COMPUTE:
9202 case Utils::Shader::FRAGMENT:
9205 case Utils::Shader::GEOMETRY:
9208 case Utils::Shader::TESS_CTRL:
9209 source = tcs_tested;
9211 case Utils::Shader::TESS_EVAL:
9212 source = tes_tested;
9214 case Utils::Shader::VERTEX:
9218 TCU_FAIL("Invalid enum");
9221 Utils::replaceToken("OFFSET", position, buffer, source);
9222 Utils::replaceToken("TYPE", position, type_name, source);
9223 Utils::replaceToken("TYPE", position, type_name, source);
9229 case Utils::Shader::FRAGMENT:
9232 case Utils::Shader::GEOMETRY:
9235 case Utils::Shader::TESS_CTRL:
9238 case Utils::Shader::TESS_EVAL:
9241 case Utils::Shader::VERTEX:
9245 TCU_FAIL("Invalid enum");
9252 /** Get description of test case
9254 * @param test_case_index Index of test case
9256 * @return Type name and offset
9258 std::string UniformBlockMemberInvalidOffsetAlignmentTest::getTestCaseName(GLuint test_case_index)
9260 std::stringstream stream;
9261 testCase& test_case = m_test_cases[test_case_index];
9263 stream << "Type: " << test_case.m_type.GetGLSLTypeName() << ", offset: " << test_case.m_offset;
9265 return stream.str();
9268 /** Get number of test cases
9270 * @return Number of test cases
9272 GLuint UniformBlockMemberInvalidOffsetAlignmentTest::getTestCaseNumber()
9274 return static_cast<GLuint>(m_test_cases.size());
9277 /** Selects if "compute" stage is relevant for test
9279 * @param test_case_index Index of test case
9281 * @return true when tested stage is compute
9283 bool UniformBlockMemberInvalidOffsetAlignmentTest::isComputeRelevant(GLuint test_case_index)
9285 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
9288 /** Selects if compilation failure is expected result
9290 * @param test_case_index Index of test case
9292 * @return should_fail field from testCase
9294 bool UniformBlockMemberInvalidOffsetAlignmentTest::isFailureExpected(GLuint test_case_index)
9296 return m_test_cases[test_case_index].m_should_fail;
9299 /** Checks if stage is supported
9301 * @param stage ignored
9305 bool UniformBlockMemberInvalidOffsetAlignmentTest::isStageSupported(Utils::Shader::STAGES /* stage */)
9310 /** Prepare all test cases
9313 void UniformBlockMemberInvalidOffsetAlignmentTest::testInit()
9315 const Functions& gl = m_context.getRenderContext().getFunctions();
9317 const GLuint n_types = getTypesNumber();
9318 bool stage_support[Utils::Shader::STAGE_MAX];
9320 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
9322 stage_support[stage] = isStageSupported((Utils::Shader::STAGES)stage);
9325 gl.getIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &max_size);
9326 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
9328 for (GLuint i = 0; i < n_types; ++i)
9330 const Utils::Type& type = getType(i);
9331 const GLuint alignment = type.GetBaseAlignment(false);
9332 const GLuint type_size = type.GetSize();
9333 const GLuint sec_to_end = max_size - 2 * type_size;
9335 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
9337 if (false == stage_support[stage])
9342 for (GLuint offset = 0; offset <= type_size; ++offset)
9344 const GLuint modulo = offset % alignment;
9345 const bool is_aligned = (0 == modulo) ? true : false;
9346 const bool should_fail = !is_aligned;
9348 testCase test_case = { offset, should_fail, (Utils::Shader::STAGES)stage, type };
9350 m_test_cases.push_back(test_case);
9353 for (GLuint offset = sec_to_end; offset <= sec_to_end + type_size; ++offset)
9355 const GLuint modulo = offset % alignment;
9356 const bool is_aligned = (0 == modulo) ? true : false;
9357 const bool should_fail = !is_aligned;
9359 testCase test_case = { offset, should_fail, (Utils::Shader::STAGES)stage, type };
9361 m_test_cases.push_back(test_case);
9369 * @param context Test framework context
9371 UniformBlockMemberOverlappingOffsetsTest::UniformBlockMemberOverlappingOffsetsTest(deqp::Context& context)
9372 : NegativeTestBase(context, "uniform_block_member_overlapping_offsets",
9373 "Test verifies that overlapping offsets qualifiers cause compilation failure")
9375 /* Nothing to be done here */
9380 * @param context Test framework context
9381 * @param name Test name
9382 * @param description Test description
9384 UniformBlockMemberOverlappingOffsetsTest::UniformBlockMemberOverlappingOffsetsTest(deqp::Context& context,
9385 const glw::GLchar* name,
9386 const glw::GLchar* description)
9387 : NegativeTestBase(context, name, description)
9389 /* Nothing to be done here */
9392 /** Source for given test case and stage
9394 * @param test_case_index Index of test case
9395 * @param stage Shader stage
9397 * @return Shader source
9399 std::string UniformBlockMemberOverlappingOffsetsTest::getShaderSource(GLuint test_case_index,
9400 Utils::Shader::STAGES stage)
9402 static const GLchar* cs = "#version 430 core\n"
9403 "#extension GL_ARB_enhanced_layouts : require\n"
9405 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
9407 "layout (std140) uniform Block {\n"
9408 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9409 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9412 "writeonly uniform image2D uni_image;\n"
9416 " vec4 result = vec4(1, 0, 0.5, 1);\n"
9418 " if ((BOY_TYPE(1) == block.boy) ||\n"
9419 " (MAN_TYPE(0) == block.man) )\n"
9421 " result = vec4(1, 1, 1, 1);\n"
9424 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
9427 static const GLchar* fs = "#version 430 core\n"
9428 "#extension GL_ARB_enhanced_layouts : require\n"
9431 "out vec4 fs_out;\n"
9435 " fs_out = gs_fs;\n"
9438 static const GLchar* fs_tested = "#version 430 core\n"
9439 "#extension GL_ARB_enhanced_layouts : require\n"
9441 "layout (std140) uniform Block {\n"
9442 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9443 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9447 "out vec4 fs_out;\n"
9451 " if ((BOY_TYPE(1) == block.boy) ||\n"
9452 " (MAN_TYPE(0) == block.man) )\n"
9454 " fs_out = vec4(1, 1, 1, 1);\n"
9457 " fs_out += gs_fs;\n"
9460 static const GLchar* gs = "#version 430 core\n"
9461 "#extension GL_ARB_enhanced_layouts : require\n"
9463 "layout(points) in;\n"
9464 "layout(triangle_strip, max_vertices = 4) out;\n"
9466 "in vec4 tes_gs[];\n"
9471 " gs_fs = tes_gs[0];\n"
9472 " gl_Position = vec4(-1, -1, 0, 1);\n"
9474 " gs_fs = tes_gs[0];\n"
9475 " gl_Position = vec4(-1, 1, 0, 1);\n"
9477 " gs_fs = tes_gs[0];\n"
9478 " gl_Position = vec4(1, -1, 0, 1);\n"
9480 " gs_fs = tes_gs[0];\n"
9481 " gl_Position = vec4(1, 1, 0, 1);\n"
9485 static const GLchar* gs_tested = "#version 430 core\n"
9486 "#extension GL_ARB_enhanced_layouts : require\n"
9488 "layout(points) in;\n"
9489 "layout(triangle_strip, max_vertices = 4) out;\n"
9491 "layout (std140) uniform Block {\n"
9492 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9493 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9496 "in vec4 tes_gs[];\n"
9501 " if ((BOY_TYPE(1) == block.boy) ||\n"
9502 " (MAN_TYPE(0) == block.man) )\n"
9504 " gs_fs = vec4(1, 1, 1, 1);\n"
9507 " gs_fs += tes_gs[0];\n"
9508 " gl_Position = vec4(-1, -1, 0, 1);\n"
9510 " gs_fs += tes_gs[0];\n"
9511 " gl_Position = vec4(-1, 1, 0, 1);\n"
9513 " gs_fs += tes_gs[0];\n"
9514 " gl_Position = vec4(1, -1, 0, 1);\n"
9516 " gs_fs += tes_gs[0];\n"
9517 " gl_Position = vec4(1, 1, 0, 1);\n"
9521 static const GLchar* tcs = "#version 430 core\n"
9522 "#extension GL_ARB_enhanced_layouts : require\n"
9524 "layout(vertices = 1) out;\n"
9526 "in vec4 vs_tcs[];\n"
9527 "out vec4 tcs_tes[];\n"
9532 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
9534 " gl_TessLevelOuter[0] = 1.0;\n"
9535 " gl_TessLevelOuter[1] = 1.0;\n"
9536 " gl_TessLevelOuter[2] = 1.0;\n"
9537 " gl_TessLevelOuter[3] = 1.0;\n"
9538 " gl_TessLevelInner[0] = 1.0;\n"
9539 " gl_TessLevelInner[1] = 1.0;\n"
9542 static const GLchar* tcs_tested = "#version 430 core\n"
9543 "#extension GL_ARB_enhanced_layouts : require\n"
9545 "layout(vertices = 1) out;\n"
9547 "layout (std140) uniform Block {\n"
9548 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9549 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9552 "in vec4 vs_tcs[];\n"
9553 "out vec4 tcs_tes[];\n"
9557 " if ((BOY_TYPE(1) == block.boy) ||\n"
9558 " (MAN_TYPE(0) == block.man) )\n"
9560 " tcs_tes[gl_InvocationID] = vec4(1, 1, 1, 1);\n"
9564 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
9566 " gl_TessLevelOuter[0] = 1.0;\n"
9567 " gl_TessLevelOuter[1] = 1.0;\n"
9568 " gl_TessLevelOuter[2] = 1.0;\n"
9569 " gl_TessLevelOuter[3] = 1.0;\n"
9570 " gl_TessLevelInner[0] = 1.0;\n"
9571 " gl_TessLevelInner[1] = 1.0;\n"
9574 static const GLchar* tes = "#version 430 core\n"
9575 "#extension GL_ARB_enhanced_layouts : require\n"
9577 "layout(isolines, point_mode) in;\n"
9579 "in vec4 tcs_tes[];\n"
9580 "out vec4 tes_gs;\n"
9584 " tes_gs = tcs_tes[0];\n"
9587 static const GLchar* tes_tested = "#version 430 core\n"
9588 "#extension GL_ARB_enhanced_layouts : require\n"
9590 "layout(isolines, point_mode) in;\n"
9592 "layout (std140) uniform Block {\n"
9593 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9594 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9597 "in vec4 tcs_tes[];\n"
9598 "out vec4 tes_gs;\n"
9602 " if ((BOY_TYPE(1) == block.boy) ||\n"
9603 " (MAN_TYPE(0) == block.man) )\n"
9605 " tes_gs = vec4(1, 1, 1, 1);\n"
9608 " tes_gs += tcs_tes[0];\n"
9611 static const GLchar* vs = "#version 430 core\n"
9612 "#extension GL_ARB_enhanced_layouts : require\n"
9615 "out vec4 vs_tcs;\n"
9619 " vs_tcs = in_vs;\n"
9622 static const GLchar* vs_tested = "#version 430 core\n"
9623 "#extension GL_ARB_enhanced_layouts : require\n"
9625 "layout (std140) uniform Block {\n"
9626 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9627 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9631 "out vec4 vs_tcs;\n"
9635 " if ((BOY_TYPE(1) == block.boy) ||\n"
9636 " (MAN_TYPE(0) == block.man) )\n"
9638 " vs_tcs = vec4(1, 1, 1, 1);\n"
9641 " vs_tcs += in_vs;\n"
9646 testCase& test_case = m_test_cases[test_case_index];
9648 if (test_case.m_stage == stage)
9651 const GLuint boy_offset = test_case.m_boy_offset;
9652 const Utils::Type& boy_type = test_case.m_boy_type;
9653 const GLchar* boy_type_name = boy_type.GetGLSLTypeName();
9654 const GLuint man_offset = test_case.m_man_offset;
9655 const Utils::Type& man_type = test_case.m_man_type;
9656 const GLchar* man_type_name = man_type.GetGLSLTypeName();
9657 size_t position = 0;
9661 case Utils::Shader::COMPUTE:
9664 case Utils::Shader::FRAGMENT:
9667 case Utils::Shader::GEOMETRY:
9670 case Utils::Shader::TESS_CTRL:
9671 source = tcs_tested;
9673 case Utils::Shader::TESS_EVAL:
9674 source = tes_tested;
9676 case Utils::Shader::VERTEX:
9680 TCU_FAIL("Invalid enum");
9683 sprintf(buffer, "%d", boy_offset);
9684 Utils::replaceToken("BOY_OFFSET", position, buffer, source);
9685 Utils::replaceToken("BOY_TYPE", position, boy_type_name, source);
9686 sprintf(buffer, "%d", man_offset);
9687 Utils::replaceToken("MAN_OFFSET", position, buffer, source);
9688 Utils::replaceToken("MAN_TYPE", position, man_type_name, source);
9689 Utils::replaceToken("BOY_TYPE", position, boy_type_name, source);
9690 Utils::replaceToken("MAN_TYPE", position, man_type_name, source);
9696 case Utils::Shader::FRAGMENT:
9699 case Utils::Shader::GEOMETRY:
9702 case Utils::Shader::TESS_CTRL:
9705 case Utils::Shader::TESS_EVAL:
9708 case Utils::Shader::VERTEX:
9712 TCU_FAIL("Invalid enum");
9719 /** Get description of test case
9721 * @param test_case_index Index of test case
9723 * @return Type name and offset
9725 std::string UniformBlockMemberOverlappingOffsetsTest::getTestCaseName(GLuint test_case_index)
9727 std::stringstream stream;
9728 testCase& test_case = m_test_cases[test_case_index];
9730 stream << "Type: " << test_case.m_boy_type.GetGLSLTypeName() << ", offset: " << test_case.m_boy_offset
9731 << ". Type: " << test_case.m_man_type.GetGLSLTypeName() << ", offset: " << test_case.m_man_offset;
9733 return stream.str();
9736 /** Get number of test cases
9738 * @return Number of test cases
9740 GLuint UniformBlockMemberOverlappingOffsetsTest::getTestCaseNumber()
9742 return static_cast<GLuint>(m_test_cases.size());
9745 /** Selects if "compute" stage is relevant for test
9747 * @param test_case_index Index of test case
9749 * @return true when tested stage is compute
9751 bool UniformBlockMemberOverlappingOffsetsTest::isComputeRelevant(GLuint test_case_index)
9753 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
9756 /** Checks if stage is supported
9758 * @param stage ignored
9762 bool UniformBlockMemberOverlappingOffsetsTest::isStageSupported(Utils::Shader::STAGES /* stage */)
9767 /** Prepare all test cases
9770 void UniformBlockMemberOverlappingOffsetsTest::testInit()
9772 const GLuint n_types = getTypesNumber();
9773 bool stage_support[Utils::Shader::STAGE_MAX];
9775 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
9777 stage_support[stage] = isStageSupported((Utils::Shader::STAGES)stage);
9780 for (GLuint i = 0; i < n_types; ++i)
9782 const Utils::Type& boy_type = getType(i);
9783 const GLuint boy_size = boy_type.GetActualAlignment(1 /* align */, false /* is_array*/);
9785 for (GLuint j = 0; j < n_types; ++j)
9787 const Utils::Type& man_type = getType(j);
9788 const GLuint man_align = man_type.GetBaseAlignment(false);
9789 const GLuint man_size = man_type.GetActualAlignment(1 /* align */, false /* is_array*/);
9791 const GLuint boy_offset = lcm(boy_size, man_size);
9792 const GLuint man_after_start = boy_offset + 1;
9793 const GLuint man_after_off = man_type.GetActualOffset(man_after_start, man_size);
9794 const GLuint man_before_start = boy_offset - man_align;
9795 const GLuint man_before_off = man_type.GetActualOffset(man_before_start, man_size);
9797 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
9799 if (false == stage_support[stage])
9804 if ((boy_offset > man_before_off) && (boy_offset < man_before_off + man_size))
9806 testCase test_case = { boy_offset, boy_type, man_before_off, man_type,
9807 (Utils::Shader::STAGES)stage };
9809 m_test_cases.push_back(test_case);
9812 if ((boy_offset < man_after_off) && (boy_offset + boy_size > man_after_off))
9814 testCase test_case = { boy_offset, boy_type, man_after_off, man_type,
9815 (Utils::Shader::STAGES)stage };
9817 m_test_cases.push_back(test_case);
9820 /* Boy offset, should be fine for both types */
9821 testCase test_case = { boy_offset, boy_type, boy_offset, man_type, (Utils::Shader::STAGES)stage };
9823 m_test_cases.push_back(test_case);
9829 /** Find greatest common divisor for a and b
9831 * @param a A argument
9832 * @param b B argument
9834 * @return Found gcd value
9836 GLuint UniformBlockMemberOverlappingOffsetsTest::gcd(GLuint a, GLuint b)
9838 if ((0 != a) && (0 == b))
9844 GLuint greater = std::max(a, b);
9845 GLuint lesser = std::min(a, b);
9847 return gcd(lesser, greater % lesser);
9851 /** Find lowest common multiple for a and b
9853 * @param a A argument
9854 * @param b B argument
9856 * @return Found gcd value
9858 GLuint UniformBlockMemberOverlappingOffsetsTest::lcm(GLuint a, GLuint b)
9860 return (a * b) / gcd(a, b);
9865 * @param context Test framework context
9867 UniformBlockMemberAlignNonPowerOf2Test::UniformBlockMemberAlignNonPowerOf2Test(deqp::Context& context)
9868 : NegativeTestBase(context, "uniform_block_member_align_non_power_of_2",
9869 "Test verifies that align qualifier requires value that is a power of 2")
9871 /* Nothing to be done here */
9876 * @param context Test framework context
9877 * @param name Test name
9878 * @param description Test description
9880 UniformBlockMemberAlignNonPowerOf2Test::UniformBlockMemberAlignNonPowerOf2Test(deqp::Context& context,
9881 const glw::GLchar* name,
9882 const glw::GLchar* description)
9883 : NegativeTestBase(context, name, description)
9885 /* Nothing to be done here */
9888 /** Source for given test case and stage
9890 * @param test_case_index Index of test case
9891 * @param stage Shader stage
9893 * @return Shader source
9895 std::string UniformBlockMemberAlignNonPowerOf2Test::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
9897 static const GLchar* cs = "#version 430 core\n"
9898 "#extension GL_ARB_enhanced_layouts : require\n"
9900 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
9902 "layout (std140) uniform Block {\n"
9904 " layout (align = ALIGN) TYPE man;\n"
9907 "writeonly uniform image2D uni_image;\n"
9911 " vec4 result = vec4(1, 0, 0.5, 1);\n"
9913 " if (TYPE(0) == block.man)\n"
9915 " result = vec4(1, 1, 1, 1) - block.boy;\n"
9918 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
9921 static const GLchar* fs = "#version 430 core\n"
9922 "#extension GL_ARB_enhanced_layouts : require\n"
9925 "out vec4 fs_out;\n"
9929 " fs_out = gs_fs;\n"
9932 static const GLchar* fs_tested = "#version 430 core\n"
9933 "#extension GL_ARB_enhanced_layouts : require\n"
9935 "layout (std140) uniform Block {\n"
9937 " layout (align = ALIGN) TYPE man;\n"
9941 "out vec4 fs_out;\n"
9945 " if (TYPE(0) == block.man)\n"
9947 " fs_out = block.boy;\n"
9950 " fs_out += gs_fs;\n"
9953 static const GLchar* gs = "#version 430 core\n"
9954 "#extension GL_ARB_enhanced_layouts : require\n"
9956 "layout(points) in;\n"
9957 "layout(triangle_strip, max_vertices = 4) out;\n"
9959 "in vec4 tes_gs[];\n"
9964 " gs_fs = tes_gs[0];\n"
9965 " gl_Position = vec4(-1, -1, 0, 1);\n"
9967 " gs_fs = tes_gs[0];\n"
9968 " gl_Position = vec4(-1, 1, 0, 1);\n"
9970 " gs_fs = tes_gs[0];\n"
9971 " gl_Position = vec4(1, -1, 0, 1);\n"
9973 " gs_fs = tes_gs[0];\n"
9974 " gl_Position = vec4(1, 1, 0, 1);\n"
9978 static const GLchar* gs_tested = "#version 430 core\n"
9979 "#extension GL_ARB_enhanced_layouts : require\n"
9981 "layout(points) in;\n"
9982 "layout(triangle_strip, max_vertices = 4) out;\n"
9984 "layout (std140) uniform Block {\n"
9986 " layout (align = ALIGN) TYPE man;\n"
9989 "in vec4 tes_gs[];\n"
9994 " if (TYPE(0) == block.man)\n"
9996 " gs_fs = block.boy;\n"
9999 " gs_fs += tes_gs[0];\n"
10000 " gl_Position = vec4(-1, -1, 0, 1);\n"
10002 " gs_fs += tes_gs[0];\n"
10003 " gl_Position = vec4(-1, 1, 0, 1);\n"
10005 " gs_fs += tes_gs[0];\n"
10006 " gl_Position = vec4(1, -1, 0, 1);\n"
10008 " gs_fs += tes_gs[0];\n"
10009 " gl_Position = vec4(1, 1, 0, 1);\n"
10013 static const GLchar* tcs = "#version 430 core\n"
10014 "#extension GL_ARB_enhanced_layouts : require\n"
10016 "layout(vertices = 1) out;\n"
10018 "in vec4 vs_tcs[];\n"
10019 "out vec4 tcs_tes[];\n"
10024 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
10026 " gl_TessLevelOuter[0] = 1.0;\n"
10027 " gl_TessLevelOuter[1] = 1.0;\n"
10028 " gl_TessLevelOuter[2] = 1.0;\n"
10029 " gl_TessLevelOuter[3] = 1.0;\n"
10030 " gl_TessLevelInner[0] = 1.0;\n"
10031 " gl_TessLevelInner[1] = 1.0;\n"
10034 static const GLchar* tcs_tested = "#version 430 core\n"
10035 "#extension GL_ARB_enhanced_layouts : require\n"
10037 "layout(vertices = 1) out;\n"
10039 "layout (std140) uniform Block {\n"
10041 " layout (align = ALIGN) TYPE man;\n"
10044 "in vec4 vs_tcs[];\n"
10045 "out vec4 tcs_tes[];\n"
10049 " if (TYPE(0) == block.man)\n"
10051 " tcs_tes[gl_InvocationID] = block.boy;\n"
10055 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
10057 " gl_TessLevelOuter[0] = 1.0;\n"
10058 " gl_TessLevelOuter[1] = 1.0;\n"
10059 " gl_TessLevelOuter[2] = 1.0;\n"
10060 " gl_TessLevelOuter[3] = 1.0;\n"
10061 " gl_TessLevelInner[0] = 1.0;\n"
10062 " gl_TessLevelInner[1] = 1.0;\n"
10065 static const GLchar* tes = "#version 430 core\n"
10066 "#extension GL_ARB_enhanced_layouts : require\n"
10068 "layout(isolines, point_mode) in;\n"
10070 "in vec4 tcs_tes[];\n"
10071 "out vec4 tes_gs;\n"
10075 " tes_gs = tcs_tes[0];\n"
10078 static const GLchar* tes_tested = "#version 430 core\n"
10079 "#extension GL_ARB_enhanced_layouts : require\n"
10081 "layout(isolines, point_mode) in;\n"
10083 "layout (std140) uniform Block {\n"
10085 " layout (align = ALIGN) TYPE man;\n"
10088 "in vec4 tcs_tes[];\n"
10089 "out vec4 tes_gs;\n"
10093 " if (TYPE(0) == block.man)\n"
10095 " tes_gs = block.boy;\n"
10098 " tes_gs += tcs_tes[0];\n"
10101 static const GLchar* vs = "#version 430 core\n"
10102 "#extension GL_ARB_enhanced_layouts : require\n"
10105 "out vec4 vs_tcs;\n"
10109 " vs_tcs = in_vs;\n"
10112 static const GLchar* vs_tested = "#version 430 core\n"
10113 "#extension GL_ARB_enhanced_layouts : require\n"
10115 "layout (std140) uniform Block {\n"
10117 " layout (align = ALIGN) TYPE man;\n"
10121 "out vec4 vs_tcs;\n"
10125 " if (TYPE(0) == block.man)\n"
10127 " vs_tcs = block.boy;\n"
10130 " vs_tcs += in_vs;\n"
10134 std::string source;
10135 testCase& test_case = m_test_cases[test_case_index];
10137 if (test_case.m_stage == stage)
10140 const GLuint alignment = test_case.m_alignment;
10141 const Utils::Type& type = test_case.m_type;
10142 const GLchar* type_name = type.GetGLSLTypeName();
10143 size_t position = 0;
10147 case Utils::Shader::COMPUTE:
10150 case Utils::Shader::FRAGMENT:
10151 source = fs_tested;
10153 case Utils::Shader::GEOMETRY:
10154 source = gs_tested;
10156 case Utils::Shader::TESS_CTRL:
10157 source = tcs_tested;
10159 case Utils::Shader::TESS_EVAL:
10160 source = tes_tested;
10162 case Utils::Shader::VERTEX:
10163 source = vs_tested;
10166 TCU_FAIL("Invalid enum");
10169 sprintf(buffer, "%d", alignment);
10170 Utils::replaceToken("ALIGN", position, buffer, source);
10171 Utils::replaceToken("TYPE", position, type_name, source);
10172 Utils::replaceToken("TYPE", position, type_name, source);
10178 case Utils::Shader::FRAGMENT:
10181 case Utils::Shader::GEOMETRY:
10184 case Utils::Shader::TESS_CTRL:
10187 case Utils::Shader::TESS_EVAL:
10190 case Utils::Shader::VERTEX:
10194 TCU_FAIL("Invalid enum");
10201 /** Get description of test case
10203 * @param test_case_index Index of test case
10205 * @return Type name and offset
10207 std::string UniformBlockMemberAlignNonPowerOf2Test::getTestCaseName(GLuint test_case_index)
10209 std::stringstream stream;
10210 testCase& test_case = m_test_cases[test_case_index];
10212 stream << "Type: " << test_case.m_type.GetGLSLTypeName() << ", align: " << test_case.m_alignment;
10214 return stream.str();
10217 /** Get number of test cases
10219 * @return Number of test cases
10221 GLuint UniformBlockMemberAlignNonPowerOf2Test::getTestCaseNumber()
10223 return static_cast<GLuint>(m_test_cases.size());
10226 /** Selects if "compute" stage is relevant for test
10228 * @param test_case_index Index of test case
10230 * @return true when tested stage is compute
10232 bool UniformBlockMemberAlignNonPowerOf2Test::isComputeRelevant(GLuint test_case_index)
10234 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
10237 /** Checks if stage is supported
10243 bool UniformBlockMemberAlignNonPowerOf2Test::isStageSupported(Utils::Shader::STAGES /* stage */)
10248 /** Selects if compilation failure is expected result
10250 * @param test_case_index Index of test case
10252 * @return should_fail field from testCase
10254 bool UniformBlockMemberAlignNonPowerOf2Test::isFailureExpected(GLuint test_case_index)
10256 return m_test_cases[test_case_index].m_should_fail;
10259 /** Prepare all test cases
10262 void UniformBlockMemberAlignNonPowerOf2Test::testInit()
10264 static const GLuint dmat4_size = 128;
10265 const GLuint n_types = getTypesNumber();
10266 bool stage_support[Utils::Shader::STAGE_MAX];
10268 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
10270 stage_support[stage] = isStageSupported((Utils::Shader::STAGES)stage);
10273 for (GLuint j = 0; j < n_types; ++j)
10275 const Utils::Type& type = getType(j);
10277 for (GLuint align = 0; align <= dmat4_size; ++align)
10280 #if WRKARD_UNIFORMBLOCKMEMBERALIGNNONPOWEROF2TEST
10282 const bool should_fail = (0 == align) ? false : !isPowerOf2(align);
10284 #else /* WRKARD_UNIFORMBLOCKMEMBERALIGNNONPOWEROF2TEST */
10286 const bool should_fail = !isPowerOf2(align);
10288 #endif /* WRKARD_UNIFORMBLOCKMEMBERALIGNNONPOWEROF2TEST */
10290 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
10292 if (false == stage_support[stage])
10297 testCase test_case = { align, type, should_fail, (Utils::Shader::STAGES)stage };
10299 m_test_cases.push_back(test_case);
10305 /** Check if value is power of 2
10307 * @param val Tested value
10309 * @return true if val is power of 2, false otherwise
10311 bool UniformBlockMemberAlignNonPowerOf2Test::isPowerOf2(GLuint val)
10318 return (0 == (val & (val - 1)));
10323 * @param context Test framework context
10325 UniformBlockAlignmentTest::UniformBlockAlignmentTest(deqp::Context& context)
10326 : TextureTestBase(context, "uniform_block_alignment", "Test verifies offset and alignment of uniform buffer")
10330 /** Get interface of program
10333 * @param program_interface Interface of program
10334 * @param varying_passthrough Collection of connections between in and out variables
10336 void UniformBlockAlignmentTest::getProgramInterface(GLuint /* test_case_index */,
10337 Utils::ProgramInterface& program_interface,
10338 Utils::VaryingPassthrough& varying_passthrough)
10340 static const Utils::Type vec4 = Utils::Type::vec4;
10342 #if WRKARD_UNIFORMBLOCKALIGNMENT
10344 static const GLuint block_align = 16;
10346 #else /* WRKARD_UNIFORMBLOCKALIGNMENT */
10348 static const GLuint block_align = 64;
10350 #endif /* WRKARD_UNIFORMBLOCKALIGNMENT */
10352 static const GLuint vec4_stride = 16;
10353 static const GLuint data_stride = vec4_stride * 2; /* one vec4 + one scalar aligned to 16 */
10355 /*Fixed a test issue, the fifth_offset should be calculated by block_align, instead of fifth_align, according to spec, the actual
10356 alignment of a member will be the greater of the specified alignment and the base aligment for the member type
10358 const GLuint first_offset = 0; /* vec4 at 0 */
10359 const GLuint second_offset = Utils::Type::GetActualOffset(first_offset + vec4_stride, block_align); /* Data at 32 */
10360 const GLuint third_offset =
10361 Utils::Type::GetActualOffset(second_offset + data_stride, block_align); /* Data[2] at 64 */
10362 const GLuint fourth_offset =
10363 Utils::Type::GetActualOffset(third_offset + data_stride * 2, block_align); /* vec4[3] at 96 */
10364 const GLuint fifth_offset =
10365 Utils::Type::GetActualOffset(fourth_offset + vec4_stride * 3, block_align); /* vec4[2] at 160 */
10366 const GLuint sixth_offset =
10367 Utils::Type::GetActualOffset(fifth_offset + vec4_stride * 2, block_align); /* Data at 192 */
10369 Utils::Interface* structure = program_interface.Structure("Data");
10371 structure->Member("vector", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::vec4,
10372 false /* normalized */, 0 /* n_array_elements */, Utils::Type::vec4.GetSize(), 0 /* offset */);
10374 structure->Member("scalar", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::_float,
10375 false /* normalized */, 0 /* n_array_elements */, Utils::Type::_float.GetSize(),
10376 Utils::Type::vec4.GetSize() /* offset */);
10378 /* Prepare Block */
10379 Utils::Interface* vs_uni_block = program_interface.Block("vs_uni_Block");
10381 vs_uni_block->Member("first", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::vec4,
10382 false /* normalized */, 0 /* n_array_elements */, vec4_stride, first_offset /* offset */);
10384 vs_uni_block->Member("second", "", 0 /* expected_component */, 0 /* expected_location */, structure,
10385 0 /* n_array_elements */, data_stride, second_offset);
10387 vs_uni_block->Member("third", "", 0 /* expected_component */, 0 /* expected_location */, structure,
10388 2 /* n_array_elements */, data_stride, third_offset);
10390 vs_uni_block->Member("fourth", "", 0 /* expected_component */, 0 /* expected_location */, vec4,
10391 false /* normalized */, 3 /* n_array_elements */, vec4_stride, fourth_offset);
10393 vs_uni_block->Member("fifth", "layout(align = 64)", 0 /* expected_component */, 0 /* expected_location */, vec4,
10394 false /* normalized */, 2 /* n_array_elements */, vec4_stride, fifth_offset);
10396 vs_uni_block->Member("sixth", "", 0 /* expected_component */, 0 /* expected_location */, structure,
10397 0 /* n_array_elements */, data_stride, sixth_offset);
10399 const GLuint stride = calculateStride(*vs_uni_block);
10400 m_data.resize(stride);
10401 generateData(*vs_uni_block, 0, m_data);
10403 Utils::ShaderInterface& vs_si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
10405 /* Add uniform BLOCK */
10406 #if WRKARD_UNIFORMBLOCKALIGNMENT
10407 vs_si.Uniform("vs_uni_block", "layout (std140, binding = BINDING)", 0, 0, vs_uni_block, 0,
10408 static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
10409 #else /* WRKARD_UNIFORMBLOCKALIGNMENT */
10410 vs_si.Uniform("vs_uni_block", "layout (std140, binding = BINDING, align = 64)", 0, 0, vs_uni_block, 0,
10411 static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
10412 #endif /* WRKARD_UNIFORMBLOCKALIGNMENT */
10414 program_interface.CloneVertexInterface(varying_passthrough);
10419 * @param context Test framework context
10421 SSBMemberOffsetAndAlignTest::SSBMemberOffsetAndAlignTest(deqp::Context& context)
10422 : TextureTestBase(context, "ssb_member_offset_and_align",
10423 "Test verifies offsets and alignment of storage buffer members")
10427 /** Get interface of program
10429 * @param test_case_index Test case index
10430 * @param program_interface Interface of program
10431 * @param varying_passthrough Collection of connections between in and out variables
10433 void SSBMemberOffsetAndAlignTest::getProgramInterface(GLuint test_case_index,
10434 Utils::ProgramInterface& program_interface,
10435 Utils::VaryingPassthrough& varying_passthrough)
10437 std::string globals = "const int basic_size = BASIC_SIZE;\n"
10438 "const int type_align = TYPE_ALIGN;\n"
10439 "const int type_size = TYPE_SIZE;\n";
10441 Utils::Type type = getType(test_case_index);
10442 GLuint basic_size = Utils::Type::GetTypeSize(type.m_basic_type);
10443 const GLuint base_align = type.GetBaseAlignment(false);
10444 const GLuint array_align = type.GetBaseAlignment(true);
10445 const GLuint base_stride = Utils::Type::CalculateStd140Stride(base_align, type.m_n_columns, 0);
10446 const GLuint type_align = Utils::roundUpToPowerOf2(base_stride);
10448 /* Calculate offsets */
10449 const GLuint first_offset = 0;
10450 const GLuint second_offset = type.GetActualOffset(base_stride, basic_size / 2);
10452 #if WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST
10454 const GLuint third_offset = type.GetActualOffset(second_offset + base_stride, base_align);
10455 const GLuint fourth_offset = type.GetActualOffset(third_offset + base_stride, base_align);
10456 const GLuint fifth_offset = type.GetActualOffset(fourth_offset + base_stride, base_align);
10457 const GLuint sixth_offset = type.GetActualOffset(fifth_offset + base_stride, array_align);
10458 const GLuint seventh_offset = type.GetActualOffset(sixth_offset + base_stride, array_align);
10459 const GLuint eigth_offset = type.GetActualOffset(seventh_offset + base_stride, array_align);
10461 #else /* WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST */
10463 const GLuint third_offset = type.GetActualOffset(second_offset + base_stride, 2 * type_align);
10464 const GLuint fourth_offset = type.GetActualOffset(3 * type_align + base_stride, base_align);
10465 const GLuint fifth_offset = type.GetActualOffset(fourth_offset + base_stride, base_align);
10466 const GLuint sixth_offset = type.GetActualOffset(fifth_offset + base_stride, array_align);
10467 const GLuint seventh_offset = type.GetActualOffset(sixth_offset + base_stride, array_align);
10468 const GLuint eigth_offset = type.GetActualOffset(seventh_offset + base_stride, 8 * basic_size);
10470 #endif /* WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST */
10473 const std::vector<GLubyte>& first = type.GenerateData();
10474 const std::vector<GLubyte>& second = type.GenerateData();
10475 const std::vector<GLubyte>& third = type.GenerateData();
10476 const std::vector<GLubyte>& fourth = type.GenerateData();
10478 m_data.resize(eigth_offset + base_stride);
10479 GLubyte* ptr = &m_data[0];
10480 memcpy(ptr + first_offset, &first[0], first.size());
10481 memcpy(ptr + second_offset, &second[0], second.size());
10482 memcpy(ptr + third_offset, &third[0], third.size());
10483 memcpy(ptr + fourth_offset, &fourth[0], fourth.size());
10484 memcpy(ptr + fifth_offset, &fourth[0], fourth.size());
10485 memcpy(ptr + sixth_offset, &third[0], third.size());
10486 memcpy(ptr + seventh_offset, &second[0], second.size());
10487 memcpy(ptr + eigth_offset, &first[0], first.size());
10489 /* Prepare globals */
10490 size_t position = 0;
10493 sprintf(buffer, "%d", basic_size);
10494 Utils::replaceToken("BASIC_SIZE", position, buffer, globals);
10496 sprintf(buffer, "%d", type_align);
10497 Utils::replaceToken("TYPE_ALIGN", position, buffer, globals);
10499 sprintf(buffer, "%d", base_stride);
10500 Utils::replaceToken("TYPE_SIZE", position, buffer, globals);
10502 /* Prepare Block */
10503 Utils::Interface* vs_buf_block = program_interface.Block("vs_buf_Block");
10505 vs_buf_block->Member("at_first_offset", "layout(offset = 0, align = 8 * basic_size)", 0 /* expected_component */,
10506 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
10509 vs_buf_block->Member("at_second_offset", "layout(offset = type_size, align = basic_size / 2)",
10510 0 /* expected_component */, 0 /* expected_location */, type, false /* normalized */,
10511 0 /* n_array_elements */, base_stride, second_offset);
10513 vs_buf_block->Member("at_third_offset", "layout(align = 2 * type_align)", 0 /* expected_component */,
10514 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
10517 vs_buf_block->Member("at_fourth_offset", "layout(offset = 3 * type_align + type_size)", 0 /* expected_component */,
10518 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
10521 vs_buf_block->Member("at_fifth_offset", "", 0 /* expected_component */, 0 /* expected_location */, type,
10522 false /* normalized */, 0 /* n_array_elements */, base_stride, fifth_offset);
10524 vs_buf_block->Member("at_sixth_offset", "", 0 /* expected_component */, 0 /* expected_location */, type,
10525 false /* normalized */, 2 /* n_array_elements */, array_align * 2, sixth_offset);
10527 vs_buf_block->Member("at_eigth_offset", "layout(align = 8 * basic_size)", 0 /* expected_component */,
10528 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
10531 Utils::ShaderInterface& vs_si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
10534 vs_si.m_globals = globals;
10536 /* Add uniform BLOCK */
10537 vs_si.SSB("vs_buf_block", "layout (std140, binding = BINDING)", 0, 0, vs_buf_block, 0,
10538 static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
10541 program_interface.CloneVertexInterface(varying_passthrough);
10546 * @param test_case_index Index of test case
10548 * @return Name of type test in test_case_index
10550 std::string SSBMemberOffsetAndAlignTest::getTestCaseName(glw::GLuint test_case_index)
10552 return getTypeName(test_case_index);
10555 /** Returns number of types to test
10557 * @return Number of types, 34
10559 glw::GLuint SSBMemberOffsetAndAlignTest::getTestCaseNumber()
10561 return getTypesNumber();
10564 /** Prepare code snippet that will verify in and uniform variables
10568 * @param stage Shader stage
10570 * @return Code that verify variables
10572 std::string SSBMemberOffsetAndAlignTest::getVerificationSnippet(GLuint /* test_case_index */,
10573 Utils::ProgramInterface& /* program_interface */,
10574 Utils::Shader::STAGES stage)
10576 std::string verification = "if ( (PREFIXblock.at_first_offset != PREFIXblock.at_eigth_offset ) ||\n"
10577 " (PREFIXblock.at_second_offset != PREFIXblock.at_sixth_offset[1]) ||\n"
10578 " (PREFIXblock.at_third_offset != PREFIXblock.at_sixth_offset[0]) ||\n"
10579 " (PREFIXblock.at_fourth_offset != PREFIXblock.at_fifth_offset ) )\n"
10584 const GLchar* prefix = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::SSB);
10586 Utils::replaceAllTokens("PREFIX", prefix, verification);
10588 return verification;
10591 /** Selects if "draw" stages are relevant for test
10595 * @return true if all stages support shader storage buffers, false otherwise
10597 bool SSBMemberOffsetAndAlignTest::isDrawRelevant(GLuint /* test_case_index */)
10599 const Functions& gl = m_context.getRenderContext().getFunctions();
10600 GLint gs_supported_buffers = 0;
10601 GLint tcs_supported_buffers = 0;
10602 GLint tes_supported_buffers = 0;
10603 GLint vs_supported_buffers = 0;
10605 gl.getIntegerv(GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS, &gs_supported_buffers);
10606 gl.getIntegerv(GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS, &tcs_supported_buffers);
10607 gl.getIntegerv(GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS, &tes_supported_buffers);
10608 gl.getIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &vs_supported_buffers);
10610 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
10612 return ((1 <= gs_supported_buffers) && (1 <= tcs_supported_buffers) && (1 <= tes_supported_buffers) &&
10613 (1 <= vs_supported_buffers));
10618 * @param context Test framework context
10620 SSBLayoutQualifierConflictTest::SSBLayoutQualifierConflictTest(deqp::Context& context)
10621 : NegativeTestBase(context, "ssb_layout_qualifier_conflict", "Test verifies that std140 or std430 is required when "
10622 "offset and/or align qualifiers are used with storage "
10625 /* Nothing to be done here */
10628 /** Source for given test case and stage
10630 * @param test_case_index Index of test case
10631 * @param stage Shader stage
10633 * @return Shader source
10635 std::string SSBLayoutQualifierConflictTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
10637 static const GLchar* cs = "#version 430 core\n"
10638 "#extension GL_ARB_enhanced_layouts : require\n"
10640 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
10642 "layout (QUALIFIERbinding = BINDING) buffer cs_Block {\n"
10643 " layout(offset = 16) vec4 boy;\n"
10644 " layout(align = 64) vec4 man;\n"
10647 "writeonly uniform image2D uni_image;\n"
10651 " vec4 result = uni_block.boy + uni_block.man;\n"
10653 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
10656 static const GLchar* fs = "#version 430 core\n"
10657 "#extension GL_ARB_enhanced_layouts : require\n"
10659 "layout (QUALIFIERbinding = BINDING) buffer Block {\n"
10660 " layout(offset = 16) vec4 boy;\n"
10661 " layout(align = 64) vec4 man;\n"
10665 "out vec4 fs_out;\n"
10669 " fs_out = gs_fs + uni_block.boy + uni_block.man;\n"
10672 static const GLchar* gs = "#version 430 core\n"
10673 "#extension GL_ARB_enhanced_layouts : require\n"
10675 "layout(points) in;\n"
10676 "layout(triangle_strip, max_vertices = 4) out;\n"
10678 "layout (QUALIFIERbinding = BINDING) buffer gs_Block {\n"
10679 " layout(offset = 16) vec4 boy;\n"
10680 " layout(align = 64) vec4 man;\n"
10683 "in vec4 tes_gs[];\n"
10684 "out vec4 gs_fs;\n"
10688 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
10689 " gl_Position = vec4(-1, -1, 0, 1);\n"
10691 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
10692 " gl_Position = vec4(-1, 1, 0, 1);\n"
10694 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
10695 " gl_Position = vec4(1, -1, 0, 1);\n"
10697 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
10698 " gl_Position = vec4(1, 1, 0, 1);\n"
10702 static const GLchar* tcs =
10703 "#version 430 core\n"
10704 "#extension GL_ARB_enhanced_layouts : require\n"
10706 "layout(vertices = 1) out;\n"
10708 "layout (QUALIFIERbinding = BINDING) buffer tcs_Block {\n"
10709 " layout(offset = 16) vec4 boy;\n"
10710 " layout(align = 64) vec4 man;\n"
10713 "in vec4 vs_tcs[];\n"
10714 "out vec4 tcs_tes[];\n"
10719 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID] + uni_block.boy + uni_block.man;\n"
10721 " gl_TessLevelOuter[0] = 1.0;\n"
10722 " gl_TessLevelOuter[1] = 1.0;\n"
10723 " gl_TessLevelOuter[2] = 1.0;\n"
10724 " gl_TessLevelOuter[3] = 1.0;\n"
10725 " gl_TessLevelInner[0] = 1.0;\n"
10726 " gl_TessLevelInner[1] = 1.0;\n"
10729 static const GLchar* tes = "#version 430 core\n"
10730 "#extension GL_ARB_enhanced_layouts : require\n"
10732 "layout(isolines, point_mode) in;\n"
10734 "layout (QUALIFIERbinding = BINDING) buffer tes_Block {\n"
10735 " layout(offset = 16) vec4 boy;\n"
10736 " layout(align = 64) vec4 man;\n"
10739 "in vec4 tcs_tes[];\n"
10740 "out vec4 tes_gs;\n"
10744 " tes_gs = tcs_tes[0] + uni_block.boy + uni_block.man;\n"
10747 static const GLchar* vs = "#version 430 core\n"
10748 "#extension GL_ARB_enhanced_layouts : require\n"
10750 "layout (QUALIFIERbinding = BINDING) buffer vs_Block {\n"
10751 " layout(offset = 16) vec4 boy;\n"
10752 " layout(align = 64) vec4 man;\n"
10756 "out vec4 vs_tcs;\n"
10760 " vs_tcs = in_vs + uni_block.boy + uni_block.man;\n"
10765 size_t position = 0;
10766 std::string source;
10767 testCase& test_case = m_test_cases[test_case_index];
10768 std::string qualifier = getQualifierName(test_case.m_qualifier);
10770 if (false == qualifier.empty())
10772 qualifier.append(", ");
10775 sprintf(buffer, "%d", stage);
10779 case Utils::Shader::COMPUTE:
10782 case Utils::Shader::FRAGMENT:
10785 case Utils::Shader::GEOMETRY:
10788 case Utils::Shader::TESS_CTRL:
10791 case Utils::Shader::TESS_EVAL:
10794 case Utils::Shader::VERTEX:
10798 TCU_FAIL("Invalid enum");
10801 if (test_case.m_stage == stage)
10803 Utils::replaceToken("QUALIFIER", position, qualifier.c_str(), source);
10807 Utils::replaceToken("QUALIFIER", position, "std140, ", source);
10810 Utils::replaceToken("BINDING", position, buffer, source);
10815 /** Get description of test case
10817 * @param test_case_index Index of test case
10819 * @return Qualifier name
10821 std::string SSBLayoutQualifierConflictTest::getTestCaseName(GLuint test_case_index)
10823 std::string result = getQualifierName(m_test_cases[test_case_index].m_qualifier);
10828 /** Get number of test cases
10830 * @return Number of test cases
10832 GLuint SSBLayoutQualifierConflictTest::getTestCaseNumber()
10834 return static_cast<GLuint>(m_test_cases.size());
10837 /** Selects if "compute" stage is relevant for test
10839 * @param test_case_index Index of test case
10841 * @return true when tested stage is compute
10843 bool SSBLayoutQualifierConflictTest::isComputeRelevant(GLuint test_case_index)
10845 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
10848 /** Selects if compilation failure is expected result
10850 * @param test_case_index Index of test case
10852 * @return false for STD140 and STD430 cases, true otherwise
10854 bool SSBLayoutQualifierConflictTest::isFailureExpected(GLuint test_case_index)
10856 const QUALIFIERS qualifier = m_test_cases[test_case_index].m_qualifier;
10858 return !((STD140 == qualifier) || (STD430 == qualifier));
10861 /** Checks if stage is supported
10863 * @param stage Shader stage
10865 * @return true if supported, false otherwise
10867 bool SSBLayoutQualifierConflictTest::isStageSupported(Utils::Shader::STAGES stage)
10869 const Functions& gl = m_context.getRenderContext().getFunctions();
10870 GLint max_supported_buffers = 0;
10875 case Utils::Shader::COMPUTE:
10876 pname = GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS;
10878 case Utils::Shader::FRAGMENT:
10879 pname = GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS;
10881 case Utils::Shader::GEOMETRY:
10882 pname = GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS;
10884 case Utils::Shader::TESS_CTRL:
10885 pname = GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS;
10887 case Utils::Shader::TESS_EVAL:
10888 pname = GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS;
10890 case Utils::Shader::VERTEX:
10891 pname = GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS;
10894 TCU_FAIL("Invalid enum");
10897 gl.getIntegerv(pname, &max_supported_buffers);
10898 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
10900 return 1 <= max_supported_buffers;
10903 /** Prepare all test cases
10906 void SSBLayoutQualifierConflictTest::testInit()
10908 bool stage_support[Utils::Shader::STAGE_MAX];
10910 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
10912 stage_support[stage] = isStageSupported((Utils::Shader::STAGES)stage);
10915 for (GLuint qualifier = 0; qualifier < QUALIFIERS_MAX; ++qualifier)
10917 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
10919 if (false == stage_support[stage])
10924 testCase test_case = { (QUALIFIERS)qualifier, (Utils::Shader::STAGES)stage };
10926 m_test_cases.push_back(test_case);
10931 /** Get name of glsl constant
10933 * @param Constant id
10935 * @return Name of constant used in GLSL
10937 const GLchar* SSBLayoutQualifierConflictTest::getQualifierName(QUALIFIERS qualifier)
10939 const GLchar* name = "";
10959 TCU_FAIL("Invalid enum");
10967 * @param context Test framework context
10969 SSBMemberInvalidOffsetAlignmentTest::SSBMemberInvalidOffsetAlignmentTest(deqp::Context& context)
10970 : UniformBlockMemberInvalidOffsetAlignmentTest(
10971 context, "ssb_member_invalid_offset_alignment",
10972 "Test verifies that invalid alignment of offset qualifiers cause compilation failure")
10974 /* Nothing to be done here */
10977 /** Source for given test case and stage
10979 * @param test_case_index Index of test case
10980 * @param stage Shader stage
10982 * @return Shader source
10984 std::string SSBMemberInvalidOffsetAlignmentTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
10986 static const GLchar* cs = "#version 430 core\n"
10987 "#extension GL_ARB_enhanced_layouts : require\n"
10989 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
10991 "layout (std140) buffer Block {\n"
10992 " layout (offset = OFFSET) TYPE member;\n"
10995 "writeonly uniform image2D uni_image;\n"
10999 " vec4 result = vec4(1, 0, 0.5, 1);\n"
11001 " if (TYPE(1) == block.member)\n"
11003 " result = vec4(1, 1, 1, 1);\n"
11006 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
11009 static const GLchar* fs = "#version 430 core\n"
11010 "#extension GL_ARB_enhanced_layouts : require\n"
11013 "out vec4 fs_out;\n"
11017 " fs_out = gs_fs;\n"
11020 static const GLchar* fs_tested = "#version 430 core\n"
11021 "#extension GL_ARB_enhanced_layouts : require\n"
11023 "layout (std140) buffer Block {\n"
11024 " layout (offset = OFFSET) TYPE member;\n"
11028 "out vec4 fs_out;\n"
11032 " if (TYPE(1) == block.member)\n"
11034 " fs_out = vec4(1, 1, 1, 1);\n"
11037 " fs_out += gs_fs;\n"
11040 static const GLchar* gs = "#version 430 core\n"
11041 "#extension GL_ARB_enhanced_layouts : require\n"
11043 "layout(points) in;\n"
11044 "layout(triangle_strip, max_vertices = 4) out;\n"
11046 "in vec4 tes_gs[];\n"
11047 "out vec4 gs_fs;\n"
11051 " gs_fs = tes_gs[0];\n"
11052 " gl_Position = vec4(-1, -1, 0, 1);\n"
11054 " gs_fs = tes_gs[0];\n"
11055 " gl_Position = vec4(-1, 1, 0, 1);\n"
11057 " gs_fs = tes_gs[0];\n"
11058 " gl_Position = vec4(1, -1, 0, 1);\n"
11060 " gs_fs = tes_gs[0];\n"
11061 " gl_Position = vec4(1, 1, 0, 1);\n"
11065 static const GLchar* gs_tested = "#version 430 core\n"
11066 "#extension GL_ARB_enhanced_layouts : require\n"
11068 "layout(points) in;\n"
11069 "layout(triangle_strip, max_vertices = 4) out;\n"
11071 "layout (std140) buffer Block {\n"
11072 " layout (offset = OFFSET) TYPE member;\n"
11075 "in vec4 tes_gs[];\n"
11076 "out vec4 gs_fs;\n"
11080 " if (TYPE(1) == block.member)\n"
11082 " gs_fs = vec4(1, 1, 1, 1);\n"
11085 " gs_fs += tes_gs[0];\n"
11086 " gl_Position = vec4(-1, -1, 0, 1);\n"
11088 " gs_fs += tes_gs[0];\n"
11089 " gl_Position = vec4(-1, 1, 0, 1);\n"
11091 " gs_fs += tes_gs[0];\n"
11092 " gl_Position = vec4(1, -1, 0, 1);\n"
11094 " gs_fs += tes_gs[0];\n"
11095 " gl_Position = vec4(1, 1, 0, 1);\n"
11099 static const GLchar* tcs = "#version 430 core\n"
11100 "#extension GL_ARB_enhanced_layouts : require\n"
11102 "layout(vertices = 1) out;\n"
11104 "in vec4 vs_tcs[];\n"
11105 "out vec4 tcs_tes[];\n"
11110 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
11112 " gl_TessLevelOuter[0] = 1.0;\n"
11113 " gl_TessLevelOuter[1] = 1.0;\n"
11114 " gl_TessLevelOuter[2] = 1.0;\n"
11115 " gl_TessLevelOuter[3] = 1.0;\n"
11116 " gl_TessLevelInner[0] = 1.0;\n"
11117 " gl_TessLevelInner[1] = 1.0;\n"
11120 static const GLchar* tcs_tested = "#version 430 core\n"
11121 "#extension GL_ARB_enhanced_layouts : require\n"
11123 "layout(vertices = 1) out;\n"
11125 "layout (std140) buffer Block {\n"
11126 " layout (offset = OFFSET) TYPE member;\n"
11129 "in vec4 vs_tcs[];\n"
11130 "out vec4 tcs_tes[];\n"
11134 " if (TYPE(1) == block.member)\n"
11136 " tcs_tes[gl_InvocationID] = vec4(1, 1, 1, 1);\n"
11140 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
11142 " gl_TessLevelOuter[0] = 1.0;\n"
11143 " gl_TessLevelOuter[1] = 1.0;\n"
11144 " gl_TessLevelOuter[2] = 1.0;\n"
11145 " gl_TessLevelOuter[3] = 1.0;\n"
11146 " gl_TessLevelInner[0] = 1.0;\n"
11147 " gl_TessLevelInner[1] = 1.0;\n"
11150 static const GLchar* tes = "#version 430 core\n"
11151 "#extension GL_ARB_enhanced_layouts : require\n"
11153 "layout(isolines, point_mode) in;\n"
11155 "in vec4 tcs_tes[];\n"
11156 "out vec4 tes_gs;\n"
11160 " tes_gs = tcs_tes[0];\n"
11163 static const GLchar* tes_tested = "#version 430 core\n"
11164 "#extension GL_ARB_enhanced_layouts : require\n"
11166 "layout(isolines, point_mode) in;\n"
11168 "layout (std140) buffer Block {\n"
11169 " layout (offset = OFFSET) TYPE member;\n"
11172 "in vec4 tcs_tes[];\n"
11173 "out vec4 tes_gs;\n"
11177 " if (TYPE(1) == block.member)\n"
11179 " tes_gs = vec4(1, 1, 1, 1);\n"
11182 " tes_gs += tcs_tes[0];\n"
11185 static const GLchar* vs = "#version 430 core\n"
11186 "#extension GL_ARB_enhanced_layouts : require\n"
11189 "out vec4 vs_tcs;\n"
11193 " vs_tcs = in_vs;\n"
11196 static const GLchar* vs_tested = "#version 430 core\n"
11197 "#extension GL_ARB_enhanced_layouts : require\n"
11199 "layout (std140) buffer Block {\n"
11200 " layout (offset = OFFSET) TYPE member;\n"
11204 "out vec4 vs_tcs;\n"
11208 " if (TYPE(1) == block.member)\n"
11210 " vs_tcs = vec4(1, 1, 1, 1);\n"
11213 " vs_tcs += in_vs;\n"
11217 std::string source;
11218 testCase& test_case = m_test_cases[test_case_index];
11220 if (test_case.m_stage == stage)
11223 const GLuint offset = test_case.m_offset;
11224 size_t position = 0;
11225 const Utils::Type& type = test_case.m_type;
11226 const GLchar* type_name = type.GetGLSLTypeName();
11228 sprintf(buffer, "%d", offset);
11232 case Utils::Shader::COMPUTE:
11235 case Utils::Shader::FRAGMENT:
11236 source = fs_tested;
11238 case Utils::Shader::GEOMETRY:
11239 source = gs_tested;
11241 case Utils::Shader::TESS_CTRL:
11242 source = tcs_tested;
11244 case Utils::Shader::TESS_EVAL:
11245 source = tes_tested;
11247 case Utils::Shader::VERTEX:
11248 source = vs_tested;
11251 TCU_FAIL("Invalid enum");
11254 Utils::replaceToken("OFFSET", position, buffer, source);
11255 Utils::replaceToken("TYPE", position, type_name, source);
11256 Utils::replaceToken("TYPE", position, type_name, source);
11262 case Utils::Shader::FRAGMENT:
11265 case Utils::Shader::GEOMETRY:
11268 case Utils::Shader::TESS_CTRL:
11271 case Utils::Shader::TESS_EVAL:
11274 case Utils::Shader::VERTEX:
11278 TCU_FAIL("Invalid enum");
11285 /** Checks if stage is supported
11287 * @param stage Shader stage
11289 * @return true if supported, false otherwise
11291 bool SSBMemberInvalidOffsetAlignmentTest::isStageSupported(Utils::Shader::STAGES stage)
11293 const Functions& gl = m_context.getRenderContext().getFunctions();
11294 GLint max_supported_buffers = 0;
11299 case Utils::Shader::COMPUTE:
11300 pname = GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS;
11302 case Utils::Shader::FRAGMENT:
11303 pname = GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS;
11305 case Utils::Shader::GEOMETRY:
11306 pname = GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS;
11308 case Utils::Shader::TESS_CTRL:
11309 pname = GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS;
11311 case Utils::Shader::TESS_EVAL:
11312 pname = GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS;
11314 case Utils::Shader::VERTEX:
11315 pname = GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS;
11318 TCU_FAIL("Invalid enum");
11321 gl.getIntegerv(pname, &max_supported_buffers);
11322 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
11324 return 1 <= max_supported_buffers;
11329 * @param context Test framework context
11331 SSBMemberOverlappingOffsetsTest::SSBMemberOverlappingOffsetsTest(deqp::Context& context)
11332 : UniformBlockMemberOverlappingOffsetsTest(
11333 context, "ssb_member_overlapping_offsets",
11334 "Test verifies that overlapping offsets qualifiers cause compilation failure")
11336 /* Nothing to be done here */
11339 /** Source for given test case and stage
11341 * @param test_case_index Index of test case
11342 * @param stage Shader stage
11344 * @return Shader source
11346 std::string SSBMemberOverlappingOffsetsTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
11348 static const GLchar* cs = "#version 430 core\n"
11349 "#extension GL_ARB_enhanced_layouts : require\n"
11351 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
11353 "layout (std140) buffer Block {\n"
11354 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11355 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11358 "writeonly uniform image2D uni_image;\n"
11362 " vec4 result = vec4(1, 0, 0.5, 1);\n"
11364 " if ((BOY_TYPE(1) == block.boy) ||\n"
11365 " (MAN_TYPE(0) == block.man) )\n"
11367 " result = vec4(1, 1, 1, 1);\n"
11370 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
11373 static const GLchar* fs = "#version 430 core\n"
11374 "#extension GL_ARB_enhanced_layouts : require\n"
11377 "out vec4 fs_out;\n"
11381 " fs_out = gs_fs;\n"
11384 static const GLchar* fs_tested = "#version 430 core\n"
11385 "#extension GL_ARB_enhanced_layouts : require\n"
11387 "layout (std140) buffer Block {\n"
11388 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11389 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11393 "out vec4 fs_out;\n"
11397 " if ((BOY_TYPE(1) == block.boy) ||\n"
11398 " (MAN_TYPE(0) == block.man) )\n"
11400 " fs_out = vec4(1, 1, 1, 1);\n"
11403 " fs_out += gs_fs;\n"
11406 static const GLchar* gs = "#version 430 core\n"
11407 "#extension GL_ARB_enhanced_layouts : require\n"
11409 "layout(points) in;\n"
11410 "layout(triangle_strip, max_vertices = 4) out;\n"
11412 "in vec4 tes_gs[];\n"
11413 "out vec4 gs_fs;\n"
11417 " gs_fs = tes_gs[0];\n"
11418 " gl_Position = vec4(-1, -1, 0, 1);\n"
11420 " gs_fs = tes_gs[0];\n"
11421 " gl_Position = vec4(-1, 1, 0, 1);\n"
11423 " gs_fs = tes_gs[0];\n"
11424 " gl_Position = vec4(1, -1, 0, 1);\n"
11426 " gs_fs = tes_gs[0];\n"
11427 " gl_Position = vec4(1, 1, 0, 1);\n"
11431 static const GLchar* gs_tested = "#version 430 core\n"
11432 "#extension GL_ARB_enhanced_layouts : require\n"
11434 "layout(points) in;\n"
11435 "layout(triangle_strip, max_vertices = 4) out;\n"
11437 "layout (std140) buffer Block {\n"
11438 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11439 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11442 "in vec4 tes_gs[];\n"
11443 "out vec4 gs_fs;\n"
11447 " if ((BOY_TYPE(1) == block.boy) ||\n"
11448 " (MAN_TYPE(0) == block.man) )\n"
11450 " gs_fs = vec4(1, 1, 1, 1);\n"
11453 " gs_fs += tes_gs[0];\n"
11454 " gl_Position = vec4(-1, -1, 0, 1);\n"
11456 " gs_fs += tes_gs[0];\n"
11457 " gl_Position = vec4(-1, 1, 0, 1);\n"
11459 " gs_fs += tes_gs[0];\n"
11460 " gl_Position = vec4(1, -1, 0, 1);\n"
11462 " gs_fs += tes_gs[0];\n"
11463 " gl_Position = vec4(1, 1, 0, 1);\n"
11467 static const GLchar* tcs = "#version 430 core\n"
11468 "#extension GL_ARB_enhanced_layouts : require\n"
11470 "layout(vertices = 1) out;\n"
11472 "in vec4 vs_tcs[];\n"
11473 "out vec4 tcs_tes[];\n"
11478 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
11480 " gl_TessLevelOuter[0] = 1.0;\n"
11481 " gl_TessLevelOuter[1] = 1.0;\n"
11482 " gl_TessLevelOuter[2] = 1.0;\n"
11483 " gl_TessLevelOuter[3] = 1.0;\n"
11484 " gl_TessLevelInner[0] = 1.0;\n"
11485 " gl_TessLevelInner[1] = 1.0;\n"
11488 static const GLchar* tcs_tested = "#version 430 core\n"
11489 "#extension GL_ARB_enhanced_layouts : require\n"
11491 "layout(vertices = 1) out;\n"
11493 "layout (std140) buffer Block {\n"
11494 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11495 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11498 "in vec4 vs_tcs[];\n"
11499 "out vec4 tcs_tes[];\n"
11503 " if ((BOY_TYPE(1) == block.boy) ||\n"
11504 " (MAN_TYPE(0) == block.man) )\n"
11506 " tcs_tes[gl_InvocationID] = vec4(1, 1, 1, 1);\n"
11510 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
11512 " gl_TessLevelOuter[0] = 1.0;\n"
11513 " gl_TessLevelOuter[1] = 1.0;\n"
11514 " gl_TessLevelOuter[2] = 1.0;\n"
11515 " gl_TessLevelOuter[3] = 1.0;\n"
11516 " gl_TessLevelInner[0] = 1.0;\n"
11517 " gl_TessLevelInner[1] = 1.0;\n"
11520 static const GLchar* tes = "#version 430 core\n"
11521 "#extension GL_ARB_enhanced_layouts : require\n"
11523 "layout(isolines, point_mode) in;\n"
11525 "in vec4 tcs_tes[];\n"
11526 "out vec4 tes_gs;\n"
11530 " tes_gs = tcs_tes[0];\n"
11533 static const GLchar* tes_tested = "#version 430 core\n"
11534 "#extension GL_ARB_enhanced_layouts : require\n"
11536 "layout(isolines, point_mode) in;\n"
11538 "layout (std140) buffer Block {\n"
11539 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11540 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11543 "in vec4 tcs_tes[];\n"
11544 "out vec4 tes_gs;\n"
11548 " if ((BOY_TYPE(1) == block.boy) ||\n"
11549 " (MAN_TYPE(0) == block.man) )\n"
11551 " tes_gs = vec4(1, 1, 1, 1);\n"
11554 " tes_gs += tcs_tes[0];\n"
11557 static const GLchar* vs = "#version 430 core\n"
11558 "#extension GL_ARB_enhanced_layouts : require\n"
11561 "out vec4 vs_tcs;\n"
11565 " vs_tcs = in_vs;\n"
11568 static const GLchar* vs_tested = "#version 430 core\n"
11569 "#extension GL_ARB_enhanced_layouts : require\n"
11571 "layout (std140) buffer Block {\n"
11572 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11573 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11577 "out vec4 vs_tcs;\n"
11581 " if ((BOY_TYPE(1) == block.boy) ||\n"
11582 " (MAN_TYPE(0) == block.man) )\n"
11584 " vs_tcs = vec4(1, 1, 1, 1);\n"
11587 " vs_tcs += in_vs;\n"
11591 std::string source;
11592 testCase& test_case = m_test_cases[test_case_index];
11594 if (test_case.m_stage == stage)
11597 const GLuint boy_offset = test_case.m_boy_offset;
11598 const Utils::Type& boy_type = test_case.m_boy_type;
11599 const GLchar* boy_type_name = boy_type.GetGLSLTypeName();
11600 const GLuint man_offset = test_case.m_man_offset;
11601 const Utils::Type& man_type = test_case.m_man_type;
11602 const GLchar* man_type_name = man_type.GetGLSLTypeName();
11603 size_t position = 0;
11607 case Utils::Shader::COMPUTE:
11610 case Utils::Shader::FRAGMENT:
11611 source = fs_tested;
11613 case Utils::Shader::GEOMETRY:
11614 source = gs_tested;
11616 case Utils::Shader::TESS_CTRL:
11617 source = tcs_tested;
11619 case Utils::Shader::TESS_EVAL:
11620 source = tes_tested;
11622 case Utils::Shader::VERTEX:
11623 source = vs_tested;
11626 TCU_FAIL("Invalid enum");
11629 sprintf(buffer, "%d", boy_offset);
11630 Utils::replaceToken("BOY_OFFSET", position, buffer, source);
11631 Utils::replaceToken("BOY_TYPE", position, boy_type_name, source);
11632 sprintf(buffer, "%d", man_offset);
11633 Utils::replaceToken("MAN_OFFSET", position, buffer, source);
11634 Utils::replaceToken("MAN_TYPE", position, man_type_name, source);
11635 Utils::replaceToken("BOY_TYPE", position, boy_type_name, source);
11636 Utils::replaceToken("MAN_TYPE", position, man_type_name, source);
11642 case Utils::Shader::FRAGMENT:
11645 case Utils::Shader::GEOMETRY:
11648 case Utils::Shader::TESS_CTRL:
11651 case Utils::Shader::TESS_EVAL:
11654 case Utils::Shader::VERTEX:
11658 TCU_FAIL("Invalid enum");
11665 /** Checks if stage is supported
11667 * @param stage Shader stage
11669 * @return true if supported, false otherwise
11671 bool SSBMemberOverlappingOffsetsTest::isStageSupported(Utils::Shader::STAGES stage)
11673 const Functions& gl = m_context.getRenderContext().getFunctions();
11674 GLint max_supported_buffers = 0;
11679 case Utils::Shader::COMPUTE:
11680 pname = GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS;
11682 case Utils::Shader::FRAGMENT:
11683 pname = GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS;
11685 case Utils::Shader::GEOMETRY:
11686 pname = GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS;
11688 case Utils::Shader::TESS_CTRL:
11689 pname = GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS;
11691 case Utils::Shader::TESS_EVAL:
11692 pname = GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS;
11694 case Utils::Shader::VERTEX:
11695 pname = GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS;
11698 TCU_FAIL("Invalid enum");
11701 gl.getIntegerv(pname, &max_supported_buffers);
11702 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
11704 return 1 <= max_supported_buffers;
11709 * @param context Test framework context
11711 SSBMemberAlignNonPowerOf2Test::SSBMemberAlignNonPowerOf2Test(deqp::Context& context)
11712 : UniformBlockMemberAlignNonPowerOf2Test(context, "ssb_member_align_non_power_of_2",
11713 "Test verifies that align qualifier requires value that is a power of 2")
11715 /* Nothing to be done here */
11718 /** Source for given test case and stage
11720 * @param test_case_index Index of test case
11721 * @param stage Shader stage
11723 * @return Shader source
11725 std::string SSBMemberAlignNonPowerOf2Test::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
11727 static const GLchar* cs = "#version 430 core\n"
11728 "#extension GL_ARB_enhanced_layouts : require\n"
11730 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
11732 "layout (std140) buffer Block {\n"
11734 " layout (align = ALIGN) TYPE man;\n"
11737 "writeonly uniform image2D uni_image;\n"
11741 " vec4 result = vec4(1, 0, 0.5, 1);\n"
11743 " if (TYPE(0) == block.man)\n"
11745 " result = vec4(1, 1, 1, 1) - block.boy;\n"
11748 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
11751 static const GLchar* fs = "#version 430 core\n"
11752 "#extension GL_ARB_enhanced_layouts : require\n"
11755 "out vec4 fs_out;\n"
11759 " fs_out = gs_fs;\n"
11762 static const GLchar* fs_tested = "#version 430 core\n"
11763 "#extension GL_ARB_enhanced_layouts : require\n"
11765 "layout (std140) buffer Block {\n"
11767 " layout (align = ALIGN) TYPE man;\n"
11771 "out vec4 fs_out;\n"
11775 " if (TYPE(0) == block.man)\n"
11777 " fs_out = block.boy;\n"
11780 " fs_out += gs_fs;\n"
11783 static const GLchar* gs = "#version 430 core\n"
11784 "#extension GL_ARB_enhanced_layouts : require\n"
11786 "layout(points) in;\n"
11787 "layout(triangle_strip, max_vertices = 4) out;\n"
11789 "in vec4 tes_gs[];\n"
11790 "out vec4 gs_fs;\n"
11794 " gs_fs = tes_gs[0];\n"
11795 " gl_Position = vec4(-1, -1, 0, 1);\n"
11797 " gs_fs = tes_gs[0];\n"
11798 " gl_Position = vec4(-1, 1, 0, 1);\n"
11800 " gs_fs = tes_gs[0];\n"
11801 " gl_Position = vec4(1, -1, 0, 1);\n"
11803 " gs_fs = tes_gs[0];\n"
11804 " gl_Position = vec4(1, 1, 0, 1);\n"
11808 static const GLchar* gs_tested = "#version 430 core\n"
11809 "#extension GL_ARB_enhanced_layouts : require\n"
11811 "layout(points) in;\n"
11812 "layout(triangle_strip, max_vertices = 4) out;\n"
11814 "layout (std140) buffer Block {\n"
11816 " layout (align = ALIGN) TYPE man;\n"
11819 "in vec4 tes_gs[];\n"
11820 "out vec4 gs_fs;\n"
11824 " if (TYPE(0) == block.man)\n"
11826 " gs_fs = block.boy;\n"
11829 " gs_fs += tes_gs[0];\n"
11830 " gl_Position = vec4(-1, -1, 0, 1);\n"
11832 " gs_fs += tes_gs[0];\n"
11833 " gl_Position = vec4(-1, 1, 0, 1);\n"
11835 " gs_fs += tes_gs[0];\n"
11836 " gl_Position = vec4(1, -1, 0, 1);\n"
11838 " gs_fs += tes_gs[0];\n"
11839 " gl_Position = vec4(1, 1, 0, 1);\n"
11843 static const GLchar* tcs = "#version 430 core\n"
11844 "#extension GL_ARB_enhanced_layouts : require\n"
11846 "layout(vertices = 1) out;\n"
11848 "in vec4 vs_tcs[];\n"
11849 "out vec4 tcs_tes[];\n"
11854 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
11856 " gl_TessLevelOuter[0] = 1.0;\n"
11857 " gl_TessLevelOuter[1] = 1.0;\n"
11858 " gl_TessLevelOuter[2] = 1.0;\n"
11859 " gl_TessLevelOuter[3] = 1.0;\n"
11860 " gl_TessLevelInner[0] = 1.0;\n"
11861 " gl_TessLevelInner[1] = 1.0;\n"
11864 static const GLchar* tcs_tested = "#version 430 core\n"
11865 "#extension GL_ARB_enhanced_layouts : require\n"
11867 "layout(vertices = 1) out;\n"
11869 "layout (std140) buffer Block {\n"
11871 " layout (align = ALIGN) TYPE man;\n"
11874 "in vec4 vs_tcs[];\n"
11875 "out vec4 tcs_tes[];\n"
11879 " if (TYPE(0) == block.man)\n"
11881 " tcs_tes[gl_InvocationID] = block.boy;\n"
11885 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
11887 " gl_TessLevelOuter[0] = 1.0;\n"
11888 " gl_TessLevelOuter[1] = 1.0;\n"
11889 " gl_TessLevelOuter[2] = 1.0;\n"
11890 " gl_TessLevelOuter[3] = 1.0;\n"
11891 " gl_TessLevelInner[0] = 1.0;\n"
11892 " gl_TessLevelInner[1] = 1.0;\n"
11895 static const GLchar* tes = "#version 430 core\n"
11896 "#extension GL_ARB_enhanced_layouts : require\n"
11898 "layout(isolines, point_mode) in;\n"
11900 "in vec4 tcs_tes[];\n"
11901 "out vec4 tes_gs;\n"
11905 " tes_gs = tcs_tes[0];\n"
11908 static const GLchar* tes_tested = "#version 430 core\n"
11909 "#extension GL_ARB_enhanced_layouts : require\n"
11911 "layout(isolines, point_mode) in;\n"
11913 "layout (std140) buffer Block {\n"
11915 " layout (align = ALIGN) TYPE man;\n"
11918 "in vec4 tcs_tes[];\n"
11919 "out vec4 tes_gs;\n"
11923 " if (TYPE(0) == block.man)\n"
11925 " tes_gs = block.boy;\n"
11928 " tes_gs += tcs_tes[0];\n"
11931 static const GLchar* vs = "#version 430 core\n"
11932 "#extension GL_ARB_enhanced_layouts : require\n"
11935 "out vec4 vs_tcs;\n"
11939 " vs_tcs = in_vs;\n"
11942 static const GLchar* vs_tested = "#version 430 core\n"
11943 "#extension GL_ARB_enhanced_layouts : require\n"
11945 "layout (std140) buffer Block {\n"
11947 " layout (align = ALIGN) TYPE man;\n"
11951 "out vec4 vs_tcs;\n"
11955 " if (TYPE(0) == block.man)\n"
11957 " vs_tcs = block.boy;\n"
11960 " vs_tcs += in_vs;\n"
11964 std::string source;
11965 testCase& test_case = m_test_cases[test_case_index];
11967 if (test_case.m_stage == stage)
11970 const GLuint alignment = test_case.m_alignment;
11971 const Utils::Type& type = test_case.m_type;
11972 const GLchar* type_name = type.GetGLSLTypeName();
11973 size_t position = 0;
11977 case Utils::Shader::COMPUTE:
11980 case Utils::Shader::FRAGMENT:
11981 source = fs_tested;
11983 case Utils::Shader::GEOMETRY:
11984 source = gs_tested;
11986 case Utils::Shader::TESS_CTRL:
11987 source = tcs_tested;
11989 case Utils::Shader::TESS_EVAL:
11990 source = tes_tested;
11992 case Utils::Shader::VERTEX:
11993 source = vs_tested;
11996 TCU_FAIL("Invalid enum");
11999 sprintf(buffer, "%d", alignment);
12000 Utils::replaceToken("ALIGN", position, buffer, source);
12001 Utils::replaceToken("TYPE", position, type_name, source);
12002 Utils::replaceToken("TYPE", position, type_name, source);
12008 case Utils::Shader::FRAGMENT:
12011 case Utils::Shader::GEOMETRY:
12014 case Utils::Shader::TESS_CTRL:
12017 case Utils::Shader::TESS_EVAL:
12020 case Utils::Shader::VERTEX:
12024 TCU_FAIL("Invalid enum");
12031 /** Checks if stage is supported
12033 * @param stage Shader stage
12035 * @return true if supported, false otherwise
12037 bool SSBMemberAlignNonPowerOf2Test::isStageSupported(Utils::Shader::STAGES stage)
12039 const Functions& gl = m_context.getRenderContext().getFunctions();
12040 GLint max_supported_buffers = 0;
12045 case Utils::Shader::COMPUTE:
12046 pname = GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS;
12048 case Utils::Shader::FRAGMENT:
12049 pname = GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS;
12051 case Utils::Shader::GEOMETRY:
12052 pname = GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS;
12054 case Utils::Shader::TESS_CTRL:
12055 pname = GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS;
12057 case Utils::Shader::TESS_EVAL:
12058 pname = GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS;
12060 case Utils::Shader::VERTEX:
12061 pname = GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS;
12064 TCU_FAIL("Invalid enum");
12067 gl.getIntegerv(pname, &max_supported_buffers);
12068 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
12070 return 1 <= max_supported_buffers;
12075 * @param context Test framework context
12077 SSBAlignmentTest::SSBAlignmentTest(deqp::Context& context)
12078 : TextureTestBase(context, "ssb_alignment", "Test verifies offset and alignment of ssb buffer")
12082 /** Get interface of program
12085 * @param program_interface Interface of program
12086 * @param varying_passthrough Collection of connections between in and out variables
12088 void SSBAlignmentTest::getProgramInterface(GLuint /* test_case_index */, Utils::ProgramInterface& program_interface,
12089 Utils::VaryingPassthrough& varying_passthrough)
12091 static const Utils::Type vec4 = Utils::Type::vec4;
12093 #if WRKARD_UNIFORMBLOCKALIGNMENT
12095 static const GLuint block_align = 16;
12097 #else /* WRKARD_UNIFORMBLOCKALIGNMENT */
12099 static const GLuint block_align = 64;
12101 #endif /* WRKARD_UNIFORMBLOCKALIGNMENT */
12103 static const GLuint fifth_align = 16;
12104 static const GLuint vec4_stride = 16;
12105 static const GLuint data_stride = vec4_stride * 2; /* one vec4 + one scalar aligned to 16 */
12107 const GLuint first_offset = 0; /* vec4 at 0 */
12108 const GLuint second_offset = Utils::Type::GetActualOffset(first_offset + vec4_stride, block_align); /* Data at 32 */
12109 const GLuint third_offset =
12110 Utils::Type::GetActualOffset(second_offset + data_stride, block_align); /* Data[2] at 64 */
12111 const GLuint fourth_offset =
12112 Utils::Type::GetActualOffset(third_offset + data_stride * 2, block_align); /* vec4[3] at 96 */
12113 const GLuint fifth_offset =
12114 Utils::Type::GetActualOffset(fourth_offset + vec4_stride * 3, fifth_align); /* vec4[2] at 160 */
12115 const GLuint sixth_offset =
12116 Utils::Type::GetActualOffset(fifth_offset + vec4_stride * 2, block_align); /* Data at 192 */
12118 Utils::Interface* structure = program_interface.Structure("Data");
12120 structure->Member("vector", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::vec4,
12121 false /* normalized */, 0 /* n_array_elements */, Utils::Type::vec4.GetSize(), 0 /* offset */);
12123 structure->Member("scalar", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::_float,
12124 false /* normalized */, 0 /* n_array_elements */, Utils::Type::_float.GetSize(),
12125 Utils::Type::vec4.GetSize() /* offset */);
12127 /* Prepare Block */
12128 Utils::Interface* vs_buf_Block = program_interface.Block("vs_buf_Block");
12130 vs_buf_Block->Member("first", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::vec4,
12131 false /* normalized */, 0 /* n_array_elements */, vec4_stride, first_offset /* offset */);
12133 vs_buf_Block->Member("second", "", 0 /* expected_component */, 0 /* expected_location */, structure,
12134 0 /* n_array_elements */, data_stride, second_offset);
12136 vs_buf_Block->Member("third", "", 0 /* expected_component */, 0 /* expected_location */, structure,
12137 2 /* n_array_elements */, data_stride, third_offset);
12139 vs_buf_Block->Member("fourth", "", 0 /* expected_component */, 0 /* expected_location */, vec4,
12140 false /* normalized */, 3 /* n_array_elements */, vec4_stride, fourth_offset);
12142 vs_buf_Block->Member("fifth", "layout(align = 16)", 0 /* expected_component */, 0 /* expected_location */, vec4,
12143 false /* normalized */, 2 /* n_array_elements */, vec4_stride, fifth_offset);
12145 vs_buf_Block->Member("sixth", "", 0 /* expected_component */, 0 /* expected_location */, structure,
12146 0 /* n_array_elements */, data_stride, sixth_offset);
12148 const GLuint stride = calculateStride(*vs_buf_Block);
12149 m_data.resize(stride);
12150 generateData(*vs_buf_Block, 0, m_data);
12152 Utils::ShaderInterface& vs_si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
12154 /* Add uniform BLOCK */
12155 #if WRKARD_UNIFORMBLOCKALIGNMENT
12156 vs_si.SSB("vs_buf_block", "layout (std140, binding = BINDING)", 0, 0, vs_buf_Block, 0,
12157 static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
12158 #else /* WRKARD_UNIFORMBLOCKALIGNMENT */
12159 vs_si.SSB("vs_buf_block", "layout (std140, binding = BINDING, align = 64)", 0, 0, vs_buf_Block, 0,
12160 static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
12161 #endif /* WRKARD_UNIFORMBLOCKALIGNMENT */
12163 program_interface.CloneVertexInterface(varying_passthrough);
12166 /** Selects if "draw" stages are relevant for test
12170 * @return true if all stages support shader storage buffers, false otherwise
12172 bool SSBAlignmentTest::isDrawRelevant(GLuint /* test_case_index */)
12174 const Functions& gl = m_context.getRenderContext().getFunctions();
12175 GLint gs_supported_buffers = 0;
12176 GLint tcs_supported_buffers = 0;
12177 GLint tes_supported_buffers = 0;
12178 GLint vs_supported_buffers = 0;
12180 gl.getIntegerv(GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS, &gs_supported_buffers);
12181 gl.getIntegerv(GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS, &tcs_supported_buffers);
12182 gl.getIntegerv(GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS, &tes_supported_buffers);
12183 gl.getIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &vs_supported_buffers);
12185 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
12187 return ((1 <= gs_supported_buffers) && (1 <= tcs_supported_buffers) && (1 <= tes_supported_buffers) &&
12188 (1 <= vs_supported_buffers));
12193 * @param context Test framework context
12195 VaryingLocationsTest::VaryingLocationsTest(deqp::Context& context)
12196 : TextureTestBase(context, "varying_locations", "Test verifies that input and output locations are respected")
12202 * @param context Test context
12203 * @param test_name Name of test
12204 * @param test_description Description of test
12206 VaryingLocationsTest::VaryingLocationsTest(deqp::Context& context, const glw::GLchar* test_name,
12207 const glw::GLchar* test_description)
12208 : TextureTestBase(context, test_name, test_description)
12212 /** Get interface of program
12214 * @param test_case_index Test case
12215 * @param program_interface Interface of program
12216 * @param varying_passthrough Collection of connections between in and out variables
12218 void VaryingLocationsTest::getProgramInterface(GLuint test_case_index, Utils::ProgramInterface& program_interface,
12219 Utils::VaryingPassthrough& varying_passthrough)
12221 const Utils::Type type = getType(test_case_index);
12223 m_first_data = type.GenerateDataPacked();
12224 m_last_data = type.GenerateDataPacked();
12226 prepareShaderStage(Utils::Shader::FRAGMENT, type, program_interface, varying_passthrough);
12227 prepareShaderStage(Utils::Shader::GEOMETRY, type, program_interface, varying_passthrough);
12228 prepareShaderStage(Utils::Shader::TESS_CTRL, type, program_interface, varying_passthrough);
12229 prepareShaderStage(Utils::Shader::TESS_EVAL, type, program_interface, varying_passthrough);
12230 prepareShaderStage(Utils::Shader::VERTEX, type, program_interface, varying_passthrough);
12235 * @param test_case_index Index of test case
12237 * @return Name of type test in test_case_index
12239 std::string VaryingLocationsTest::getTestCaseName(glw::GLuint test_case_index)
12241 return getTypeName(test_case_index);
12244 /** Returns number of types to test
12246 * @return Number of types, 34
12248 glw::GLuint VaryingLocationsTest::getTestCaseNumber()
12250 return getTypesNumber();
12253 /** Selects if "compute" stage is relevant for test
12259 bool VaryingLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
12268 std::string VaryingLocationsTest::prepareGlobals(GLint last_in_loc, GLint last_out_loc)
12271 std::string globals = "const uint first_input_location = 0u;\n"
12272 "const uint first_output_location = 0u;\n"
12273 "const uint last_input_location = LAST_INPUTu;\n"
12274 "const uint last_output_location = LAST_OUTPUTu;\n";
12275 size_t position = 100; /* Skip first part */
12277 sprintf(buffer, "%d", last_in_loc);
12278 Utils::replaceToken("LAST_INPUT", position, buffer, globals);
12280 sprintf(buffer, "%d", last_out_loc);
12281 Utils::replaceToken("LAST_OUTPUT", position, buffer, globals);
12289 void VaryingLocationsTest::prepareShaderStage(Utils::Shader::STAGES stage, const Utils::Type& type,
12290 Utils::ProgramInterface& program_interface,
12291 Utils::VaryingPassthrough& varying_passthrough)
12293 const GLuint array_length = 1;
12294 const GLuint first_in_loc = 0;
12295 const GLuint first_out_loc = 0;
12296 const GLuint last_in_loc = getLastInputLocation(stage, type, array_length);
12297 size_t position = 0;
12299 const GLchar* prefix_in = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::VARYING_INPUT);
12301 const GLchar* prefix_out = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::VARYING_OUTPUT);
12303 const GLchar* qual_first_in = "layout (location = first_input_location)";
12304 const GLchar* qual_first_out = "layout (location = first_output_location)";
12305 const GLchar* qual_last_in = "layout (location = last_input_location)";
12306 const GLchar* qual_last_out = "layout (location = last_output_location)";
12308 Utils::ShaderInterface& si = program_interface.GetShaderInterface(stage);
12309 const GLuint type_size = type.GetSize();
12311 std::string first_in_name = "PREFIXfirst";
12312 std::string first_out_name = "PREFIXfirst";
12313 std::string last_in_name = "PREFIXlast";
12314 std::string last_out_name = "PREFIXlast";
12316 Utils::replaceToken("PREFIX", position, prefix_in, first_in_name);
12318 Utils::replaceToken("PREFIX", position, prefix_out, first_out_name);
12320 Utils::replaceToken("PREFIX", position, prefix_in, last_in_name);
12322 Utils::replaceToken("PREFIX", position, prefix_out, last_out_name);
12324 if (Utils::Shader::FRAGMENT == stage)
12326 qual_first_in = "layout (location = first_input_location) flat";
12327 qual_last_in = "layout (location = last_input_location) flat";
12329 if (Utils::Shader::GEOMETRY == stage)
12331 qual_first_out = "layout (location = first_output_location) flat";
12332 qual_last_out = "layout (location = last_output_location) flat";
12335 Utils::Variable* first_in = si.Input(
12336 first_in_name.c_str(), qual_first_in /* qualifiers */, 0 /* expected_componenet */,
12337 first_in_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */, 0u /* n_array_elements */,
12338 0u /* stride */, 0u /* offset */, (GLvoid*)&m_first_data[0] /* data */, m_first_data.size() /* data_size */);
12340 Utils::Variable* last_in =
12341 si.Input(last_in_name.c_str(), qual_last_in /* qualifiers */, 0 /* expected_componenet */,
12342 last_in_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12343 0u /* n_array_elements */, 0u /* stride */, type_size /* offset */,
12344 (GLvoid*)&m_last_data[0] /* data */, m_last_data.size() /* data_size */);
12346 if (Utils::Shader::FRAGMENT != stage)
12348 const GLuint last_out_loc = getLastOutputLocation(stage, type, array_length);
12350 Utils::Variable* first_out =
12351 si.Output(first_out_name.c_str(), qual_first_out /* qualifiers */, 0 /* expected_componenet */,
12352 first_out_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12353 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)&m_first_data[0] /* data */,
12354 m_first_data.size() /* data_size */);
12356 Utils::Variable* last_out = si.Output(
12357 last_out_name.c_str(), qual_last_out /* qualifiers */, 0 /* expected_componenet */,
12358 last_out_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */, 0u /* n_array_elements */,
12359 0u /* stride */, 0u /* offset */, (GLvoid*)&m_last_data[0] /* data */, m_last_data.size() /* data_size */);
12361 si.m_globals = prepareGlobals(last_in_loc, last_out_loc);
12363 varying_passthrough.Add(stage, first_in, first_out);
12364 varying_passthrough.Add(stage, last_in, last_out);
12368 /* No outputs for fragment shader, so last_output_location can be 0 */
12369 si.m_globals = prepareGlobals(last_in_loc, 0);
12373 /** This test should be run with separable programs
12379 bool VaryingLocationsTest::useMonolithicProgram(GLuint /* test_case_index */)
12384 /* Constants used by VertexAttribLocationsTest */
12385 const GLuint VertexAttribLocationsTest::m_base_vertex = 4;
12386 const GLuint VertexAttribLocationsTest::m_base_instance = 2;
12387 const GLuint VertexAttribLocationsTest::m_loc_vertex = 2;
12388 const GLuint VertexAttribLocationsTest::m_loc_instance = 5;
12389 const GLuint VertexAttribLocationsTest::m_n_instances = 4;
12393 * @param context Test framework context
12395 VertexAttribLocationsTest::VertexAttribLocationsTest(deqp::Context& context)
12396 : TextureTestBase(context, "vertex_attrib_locations",
12397 "Test verifies that attribute locations are respected by drawing operations")
12401 /** Execute proper draw command for test case
12403 * @param test_case_index Index of test case
12405 void VertexAttribLocationsTest::executeDrawCall(GLuint test_case_index)
12407 static const GLubyte indices[8] = { 0 };
12409 const Functions& gl = m_context.getRenderContext().getFunctions();
12411 switch (test_case_index)
12414 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
12415 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
12417 case DRAWARRAYSINSTANCED:
12418 gl.drawArraysInstanced(GL_PATCHES, 0 /* first */, 1 /* count */, m_n_instances);
12419 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArraysInstanced");
12422 gl.drawElements(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, indices);
12423 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElements");
12425 case DRAWELEMENTSBASEVERTEX:
12426 gl.drawElementsBaseVertex(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, indices, m_base_vertex);
12427 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsBaseVertex");
12429 case DRAWELEMENTSINSTANCED:
12430 gl.drawElementsInstanced(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, indices, m_n_instances);
12431 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsInstanced");
12433 case DRAWELEMENTSINSTANCEDBASEINSTANCE:
12434 gl.drawElementsInstancedBaseInstance(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, indices, m_n_instances,
12436 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsInstancedBaseInstance");
12438 case DRAWELEMENTSINSTANCEDBASEVERTEX:
12439 gl.drawElementsInstancedBaseVertex(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, indices, m_n_instances,
12441 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsInstancedBaseVertex");
12443 case DRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCE:
12444 gl.drawElementsInstancedBaseVertexBaseInstance(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, indices,
12445 m_n_instances, m_base_vertex, m_base_instance);
12446 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsInstancedBaseVertexBaseInstance");
12449 TCU_FAIL("Invalid enum");
12453 /** Get interface of program
12456 * @param program_interface Interface of program
12459 void VertexAttribLocationsTest::getProgramInterface(GLuint /* test_case_index */,
12460 Utils::ProgramInterface& program_interface,
12461 Utils::VaryingPassthrough& /* varying_passthrough */)
12463 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
12466 si.m_globals = "const uint vertex_index_location = 2;\n"
12467 "const uint instance_index_location = 5;\n";
12470 si.Input("vertex_index" /* name */, "layout (location = vertex_index_location)" /* qualifiers */,
12471 0 /* expected_componenet */, m_loc_vertex /* expected_location */, Utils::Type::uint /* type */,
12472 GL_FALSE /* normalized */, 0u /* n_array_elements */, 16 /* stride */, 0u /* offset */,
12473 (GLvoid*)0 /* data */, 0 /* data_size */);
12474 si.Input("instance_index" /* name */, "layout (location = instance_index_location)" /* qualifiers */,
12475 0 /* expected_componenet */, m_loc_instance /* expected_location */, Utils::Type::uint /* type */,
12476 GL_FALSE /* normalized */, 0u /* n_array_elements */, 16 /* stride */, 16u /* offset */,
12477 (GLvoid*)0 /* data */, 0 /* data_size */);
12480 /** Get name of test case
12482 * @param test_case_index Index of test case
12484 * @return Name of test case
12486 std::string VertexAttribLocationsTest::getTestCaseName(glw::GLuint test_case_index)
12488 std::string result;
12490 switch (test_case_index)
12493 result = "DrawArrays";
12495 case DRAWARRAYSINSTANCED:
12496 result = "DrawArraysInstanced";
12499 result = "DrawElements";
12501 case DRAWELEMENTSBASEVERTEX:
12502 result = "DrawElementsBaseVertex";
12504 case DRAWELEMENTSINSTANCED:
12505 result = "DrawElementsInstanced";
12507 case DRAWELEMENTSINSTANCEDBASEINSTANCE:
12508 result = "DrawElementsInstancedBaseInstance";
12510 case DRAWELEMENTSINSTANCEDBASEVERTEX:
12511 result = "DrawElementsInstancedBaseVertex";
12513 case DRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCE:
12514 result = "DrawElementsInstancedBaseVertexBaseInstance";
12517 TCU_FAIL("Invalid enum");
12523 /** Get number of test cases
12525 * @return Number of test cases
12527 GLuint VertexAttribLocationsTest::getTestCaseNumber()
12529 return TESTCASES_MAX;
12532 /** Prepare code snippet that will verify in and uniform variables
12536 * @param stage Shader stage
12538 * @return Code that verify variables
12540 std::string VertexAttribLocationsTest::getVerificationSnippet(GLuint /* test_case_index */,
12541 Utils::ProgramInterface& /* program_interface */,
12542 Utils::Shader::STAGES stage)
12544 std::string verification;
12546 if (Utils::Shader::VERTEX == stage)
12549 #if DEBUG_VERTEX_ATTRIB_LOCATIONS_TEST_VARIABLE
12551 verification = "if (gl_InstanceID != instance_index)\n"
12555 " else if (gl_VertexID != vertex_index)\n"
12562 verification = "if ((gl_VertexID != vertex_index) ||\n"
12563 " (gl_InstanceID != instance_index) )\n"
12575 return verification;
12578 /** Selects if "compute" stage is relevant for test
12584 bool VertexAttribLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
12589 /** Prepare attributes, vertex array object and array buffer
12592 * @param ignored Interface of program
12593 * @param buffer Array buffer
12594 * @param vao Vertex array object
12596 void VertexAttribLocationsTest::prepareAttributes(GLuint test_case_index /* test_case_index */,
12597 Utils::ProgramInterface& /* program_interface */,
12598 Utils::Buffer& buffer, Utils::VertexArray& vao)
12600 static const GLuint vertex_index_data[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
12601 static const GLuint instance_index_data[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
12603 std::vector<GLuint> buffer_data;
12604 buffer_data.resize(8 + 8); /* vertex_index_data + instance_index_data */
12606 GLubyte* ptr = (GLubyte*)&buffer_data[0];
12609 When case index >=2, the test calls glDrawElement*(), such as glDrawElementsBaseVertex(), glDrawElementsInstanced(), glDrawElementsInstancedBaseInstance() and so on,
12610 So we need to change the buffer type as GL_ELEMENT_ARRAY_BUFFER
12612 if (test_case_index >= 2)
12614 buffer.m_buffer = Utils::Buffer::Element;
12619 vao.Attribute(m_loc_vertex /* vertex_index */, Utils::Type::uint, 0 /* array_elements */, false /* normalized */,
12620 0 /* stride */, 0 /* offset */);
12622 vao.Attribute(m_loc_instance /* instance_index */, Utils::Type::uint, 0 /* array_elements */,
12623 false /* normalized */, 0 /* stride */, (GLvoid*)sizeof(vertex_index_data) /* offset */);
12624 // when test_case_index is 5 or 7, the draw call is glDrawElementsInstancedBaseInstance, glDrawElementsInstancedBaseVertexBaseInstance
12625 // the instancecount is 4, the baseinstance is 2, the divisor should be set 2
12626 bool isBaseInstanced = (test_case_index == DRAWELEMENTSINSTANCEDBASEINSTANCE ||
12627 test_case_index == DRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCE);
12628 vao.Divisor(m_context.getRenderContext().getFunctions() /* gl */, m_loc_instance /* instance_index */,
12629 isBaseInstanced ? 2 : 1 /* divisor. 1 - advance once per instance */);
12631 memcpy(ptr + 0, vertex_index_data, sizeof(vertex_index_data));
12632 memcpy(ptr + sizeof(vertex_index_data), instance_index_data, sizeof(instance_index_data));
12634 buffer.Data(Utils::Buffer::StaticDraw, buffer_data.size() * sizeof(GLuint), ptr);
12637 /** This test should be run with separable programs
12643 bool VertexAttribLocationsTest::useMonolithicProgram(GLuint /* test_case_index */)
12650 * @param context Test framework context
12652 VaryingArrayLocationsTest::VaryingArrayLocationsTest(deqp::Context& context)
12653 : VaryingLocationsTest(context, "varying_array_locations",
12654 "Test verifies that input and output locations are respected for arrays")
12661 void VaryingArrayLocationsTest::prepareShaderStage(Utils::Shader::STAGES stage, const Utils::Type& type,
12662 Utils::ProgramInterface& program_interface,
12663 Utils::VaryingPassthrough& varying_passthrough)
12665 const GLuint array_length = 1u;
12666 const GLuint first_in_loc = 0;
12667 const GLuint first_out_loc = 0;
12668 const GLuint last_in_loc = getLastInputLocation(stage, type, array_length);
12669 size_t position = 0;
12671 const GLchar* prefix_in = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::VARYING_INPUT);
12673 const GLchar* prefix_out = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::VARYING_OUTPUT);
12675 const GLchar* qual_first_in = "layout (location = first_input_location)";
12676 const GLchar* qual_first_out = "layout (location = first_output_location)";
12677 const GLchar* qual_last_in = "layout (location = last_input_location)";
12678 const GLchar* qual_last_out = "layout (location = last_output_location)";
12680 Utils::ShaderInterface& si = program_interface.GetShaderInterface(stage);
12681 const GLuint type_size = type.GetSize();
12683 std::string first_in_name = "PREFIXfirst";
12684 std::string first_out_name = "PREFIXfirst";
12685 std::string last_in_name = "PREFIXlast";
12686 std::string last_out_name = "PREFIXlast";
12688 Utils::replaceToken("PREFIX", position, prefix_in, first_in_name);
12690 Utils::replaceToken("PREFIX", position, prefix_out, first_out_name);
12692 Utils::replaceToken("PREFIX", position, prefix_in, last_in_name);
12694 Utils::replaceToken("PREFIX", position, prefix_out, last_out_name);
12696 if (Utils::Shader::FRAGMENT == stage)
12698 qual_first_in = "layout (location = first_input_location) flat";
12699 qual_last_in = "layout (location = last_input_location) flat";
12701 if (Utils::Shader::GEOMETRY == stage)
12703 qual_first_out = "layout (location = first_output_location) flat";
12704 qual_last_out = "layout (location = last_output_location) flat";
12707 Utils::Variable* first_in =
12708 si.Input(first_in_name.c_str(), qual_first_in /* qualifiers */, 0 /* expected_componenet */,
12709 first_in_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12710 array_length /* n_array_elements */, 0u /* stride */, 0u /* offset */,
12711 (GLvoid*)&m_first_data[0] /* data */, m_first_data.size() /* data_size */);
12713 Utils::Variable* last_in =
12714 si.Input(last_in_name.c_str(), qual_last_in /* qualifiers */, 0 /* expected_componenet */,
12715 last_in_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12716 array_length /* n_array_elements */, 0u /* stride */, type_size /* offset */,
12717 (GLvoid*)&m_last_data[0] /* data */, m_last_data.size() /* data_size */);
12719 if (Utils::Shader::FRAGMENT != stage)
12721 const GLuint last_out_loc = getLastOutputLocation(stage, type, array_length);
12723 Utils::Variable* first_out =
12724 si.Output(first_out_name.c_str(), qual_first_out /* qualifiers */, 0 /* expected_componenet */,
12725 first_out_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12726 array_length /* n_array_elements */, 0u /* stride */, 0u /* offset */,
12727 (GLvoid*)&m_first_data[0] /* data */, m_first_data.size() /* data_size */);
12729 Utils::Variable* last_out =
12730 si.Output(last_out_name.c_str(), qual_last_out /* qualifiers */, 0 /* expected_componenet */,
12731 last_out_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12732 array_length /* n_array_elements */, 0u /* stride */, 0u /* offset */,
12733 (GLvoid*)&m_last_data[0] /* data */, m_last_data.size() /* data_size */);
12735 si.m_globals = prepareGlobals(last_in_loc, last_out_loc);
12737 varying_passthrough.Add(stage, first_in, first_out);
12738 varying_passthrough.Add(stage, last_in, last_out);
12742 /* No outputs for fragment shader, so last_output_location can be 0 */
12743 si.m_globals = prepareGlobals(last_in_loc, 0);
12749 * @param context Test framework context
12751 VaryingStructureLocationsTest::VaryingStructureLocationsTest(deqp::Context& context)
12752 : TextureTestBase(context, "varying_structure_locations",
12753 "Test verifies that locations are respected when structures are used as in and out ")
12757 /** Prepare code snippet that will pass in variables to out variables
12760 * @param varying_passthrough Collection of connections between in and out variables
12761 * @param stage Shader stage
12763 * @return Code that pass in variables to next stage
12765 std::string VaryingStructureLocationsTest::getPassSnippet(GLuint /* test_case_index */,
12766 Utils::VaryingPassthrough& varying_passthrough,
12767 Utils::Shader::STAGES stage)
12769 std::string result;
12771 if (Utils::Shader::VERTEX != stage)
12773 result = TextureTestBase::getPassSnippet(0, varying_passthrough, stage);
12777 result = " vs_tcs_output[0].single = vs_in_single[0];\n"
12778 " vs_tcs_output[0].array[0] = vs_in_array[0];\n";
12784 /** Get interface of program
12786 * @param test_case_index Test case
12787 * @param program_interface Interface of program
12788 * @param varying_passthrough Collection of connections between in and out variables
12790 void VaryingStructureLocationsTest::getProgramInterface(GLuint test_case_index,
12791 Utils::ProgramInterface& program_interface,
12792 Utils::VaryingPassthrough& varying_passthrough)
12794 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
12795 const Utils::Type type = getType(test_case_index);
12798 // We should call GenerateDataPacked() to generate data, which can make sure the data in shader is correct
12799 m_single_data = type.GenerateDataPacked();
12800 m_array_data = type.GenerateDataPacked();
12802 m_data.resize(m_single_data.size() + m_array_data.size());
12803 GLubyte* ptr = (GLubyte*)&m_data[0];
12804 memcpy(ptr, &m_single_data[0], m_single_data.size());
12805 memcpy(ptr + m_single_data.size(), &m_array_data[0], m_array_data.size());
12807 Utils::Interface* structure = program_interface.Structure("Data");
12809 structure->Member("single", "" /* qualifiers */, 0 /* component */, 0 /* location */, type, false /* normalized */,
12810 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */);
12812 // the second struct member 's location should not be 0, it is based on by how many the locations the first struct member consumed.
12813 structure->Member("array", "" /* qualifiers */, 0 /* component */, type.GetLocations() /* location */, type,
12814 false /* normalized */, 1u /* n_array_elements */, 0u /* stride */, type.GetSize() /* offset */);
12816 si.Input("vs_in_single", "layout (location = 0)", 0 /* component */, 0 /* location */, type, false /* normalized */,
12817 1u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)&m_single_data[0] /* data */,
12818 m_single_data.size() /* data_size */);
12820 si.Input("vs_in_array", "layout (location = 8)", 0 /* component */, 8 /* location */, type, false /* normalized */,
12821 1u /* n_array_elements */, 0u /* stride */, type.GetSize() /* offset */,
12822 (GLvoid*)&m_array_data[0] /* data */, m_array_data.size() /* data_size */);
12824 si.Output("vs_tcs_output", "layout (location = 0)", 0 /* component */, 0 /* location */, structure,
12825 1u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)&m_data[0] /* data */,
12826 m_data.size() /* data_size */);
12828 program_interface.CloneVertexInterface(varying_passthrough);
12833 * @param test_case_index Index of test case
12835 * @return Name of type test in test_case_index
12837 std::string VaryingStructureLocationsTest::getTestCaseName(glw::GLuint test_case_index)
12839 return getTypeName(test_case_index);
12842 /** Returns number of types to test
12844 * @return Number of types, 34
12846 glw::GLuint VaryingStructureLocationsTest::getTestCaseNumber()
12848 return getTypesNumber();
12851 /** Selects if "compute" stage is relevant for test
12857 bool VaryingStructureLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
12862 /** This test should be run with separable programs
12868 bool VaryingStructureLocationsTest::useMonolithicProgram(GLuint /* test_case_index */)
12875 * @param context Test context
12876 * @param test_name Name of test
12877 * @param test_description Description of test
12879 VaryingStructureMemberLocationTest::VaryingStructureMemberLocationTest(deqp::Context& context)
12880 : NegativeTestBase(context, "varying_structure_member_location",
12881 "Test verifies that compiler does not allow location qualifier on member of strucure")
12885 /** Source for given test case and stage
12887 * @param test_case_index Index of test case
12888 * @param stage Shader stage
12890 * @return Shader source
12892 std::string VaryingStructureMemberLocationTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
12894 static const GLchar* struct_definition = "struct Data {\n"
12896 " layout (location = 4) vec4 goten;\n"
12898 static const GLchar* input_var = "in Data data;\n";
12899 static const GLchar* output_var = "out Data data;\n";
12900 static const GLchar* input_use = " result += data.gohan + data.goten;\n";
12901 static const GLchar* output_use = " data.gohan = result / 2;\n"
12902 " data.goten = result / 4 - data.gohan;\n";
12903 static const GLchar* fs = "#version 430 core\n"
12904 "#extension GL_ARB_enhanced_layouts : require\n"
12907 "out vec4 fs_out;\n"
12911 " fs_out = gs_fs;\n"
12914 static const GLchar* fs_tested = "#version 430 core\n"
12915 "#extension GL_ARB_enhanced_layouts : require\n"
12917 "STRUCT_DEFINITION"
12919 "VARIABLE_DEFINITION"
12922 "out vec4 fs_out;\n"
12926 " vec4 result = gs_fs;\n"
12930 " fs_out += result;\n"
12933 static const GLchar* gs = "#version 430 core\n"
12934 "#extension GL_ARB_enhanced_layouts : require\n"
12936 "layout(points) in;\n"
12937 "layout(triangle_strip, max_vertices = 4) out;\n"
12939 "in vec4 tes_gs[];\n"
12940 "out vec4 gs_fs;\n"
12944 " gs_fs = tes_gs[0];\n"
12945 " gl_Position = vec4(-1, -1, 0, 1);\n"
12947 " gs_fs = tes_gs[0];\n"
12948 " gl_Position = vec4(-1, 1, 0, 1);\n"
12950 " gs_fs = tes_gs[0];\n"
12951 " gl_Position = vec4(1, -1, 0, 1);\n"
12953 " gs_fs = tes_gs[0];\n"
12954 " gl_Position = vec4(1, 1, 0, 1);\n"
12958 static const GLchar* gs_tested = "#version 430 core\n"
12959 "#extension GL_ARB_enhanced_layouts : require\n"
12961 "layout(points) in;\n"
12962 "layout(triangle_strip, max_vertices = 4) out;\n"
12964 "STRUCT_DEFINITION"
12966 "VARIABLE_DEFINITION"
12968 "in vec4 tes_gs[];\n"
12969 "out vec4 gs_fs;\n"
12973 " vec4 result = tes_gs[0];\n"
12977 " gs_fs = result;\n"
12978 " gl_Position = vec4(-1, -1, 0, 1);\n"
12980 " gs_fs = result;\n"
12981 " gl_Position = vec4(-1, 1, 0, 1);\n"
12983 " gs_fs = result;\n"
12984 " gl_Position = vec4(1, -1, 0, 1);\n"
12986 " gs_fs = result;\n"
12987 " gl_Position = vec4(1, 1, 0, 1);\n"
12991 static const GLchar* tcs = "#version 430 core\n"
12992 "#extension GL_ARB_enhanced_layouts : require\n"
12994 "layout(vertices = 1) out;\n"
12996 "in vec4 vs_tcs[];\n"
12997 "out vec4 tcs_tes[];\n"
13002 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
13004 " gl_TessLevelOuter[0] = 1.0;\n"
13005 " gl_TessLevelOuter[1] = 1.0;\n"
13006 " gl_TessLevelOuter[2] = 1.0;\n"
13007 " gl_TessLevelOuter[3] = 1.0;\n"
13008 " gl_TessLevelInner[0] = 1.0;\n"
13009 " gl_TessLevelInner[1] = 1.0;\n"
13012 static const GLchar* tcs_tested = "#version 430 core\n"
13013 "#extension GL_ARB_enhanced_layouts : require\n"
13015 "layout(vertices = 1) out;\n"
13017 "STRUCT_DEFINITION"
13019 "VARIABLE_DEFINITION"
13021 "in vec4 vs_tcs[];\n"
13022 "out vec4 tcs_tes[];\n"
13026 " vec4 result = vs_tcs[gl_InvocationID];\n"
13030 " tcs_tes[gl_InvocationID] = result;\n"
13032 " gl_TessLevelOuter[0] = 1.0;\n"
13033 " gl_TessLevelOuter[1] = 1.0;\n"
13034 " gl_TessLevelOuter[2] = 1.0;\n"
13035 " gl_TessLevelOuter[3] = 1.0;\n"
13036 " gl_TessLevelInner[0] = 1.0;\n"
13037 " gl_TessLevelInner[1] = 1.0;\n"
13040 static const GLchar* tes = "#version 430 core\n"
13041 "#extension GL_ARB_enhanced_layouts : require\n"
13043 "layout(isolines, point_mode) in;\n"
13045 "in vec4 tcs_tes[];\n"
13046 "out vec4 tes_gs;\n"
13050 " tes_gs = tcs_tes[0];\n"
13053 static const GLchar* tes_tested = "#version 430 core\n"
13054 "#extension GL_ARB_enhanced_layouts : require\n"
13056 "layout(isolines, point_mode) in;\n"
13058 "STRUCT_DEFINITION"
13060 "VARIABLE_DEFINITION"
13062 "in vec4 tcs_tes[];\n"
13063 "out vec4 tes_gs;\n"
13067 " vec4 result = tcs_tes[0];\n"
13071 " tes_gs += result;\n"
13074 static const GLchar* vs = "#version 430 core\n"
13075 "#extension GL_ARB_enhanced_layouts : require\n"
13078 "out vec4 vs_tcs;\n"
13082 " vs_tcs = in_vs;\n"
13085 static const GLchar* vs_tested = "#version 430 core\n"
13086 "#extension GL_ARB_enhanced_layouts : require\n"
13088 "STRUCT_DEFINITION"
13090 "VARIABLE_DEFINITION"
13093 "out vec4 vs_tcs;\n"
13097 " vec4 result = in_vs;\n"
13101 " vs_tcs += result;\n"
13105 std::string source;
13106 testCase& test_case = m_test_cases[test_case_index];
13107 const GLchar* var_definition = 0;
13108 const GLchar* var_use = 0;
13110 if (true == test_case.m_is_input)
13112 var_definition = input_var;
13113 var_use = input_use;
13117 var_definition = output_var;
13118 var_use = output_use;
13121 if (test_case.m_stage == stage)
13123 size_t position = 0;
13127 case Utils::Shader::FRAGMENT:
13128 source = fs_tested;
13130 case Utils::Shader::GEOMETRY:
13131 source = gs_tested;
13133 case Utils::Shader::TESS_CTRL:
13134 source = tcs_tested;
13136 case Utils::Shader::TESS_EVAL:
13137 source = tes_tested;
13139 case Utils::Shader::VERTEX:
13140 source = vs_tested;
13143 TCU_FAIL("Invalid enum");
13146 Utils::replaceToken("STRUCT_DEFINITION", position, struct_definition, source);
13147 Utils::replaceToken("VARIABLE_DEFINITION", position, var_definition, source);
13148 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
13154 case Utils::Shader::FRAGMENT:
13157 case Utils::Shader::GEOMETRY:
13160 case Utils::Shader::TESS_CTRL:
13163 case Utils::Shader::TESS_EVAL:
13166 case Utils::Shader::VERTEX:
13170 TCU_FAIL("Invalid enum");
13177 /** Get description of test case
13179 * @param test_case_index Index of test case
13181 * @return Test case description
13183 std::string VaryingStructureMemberLocationTest::getTestCaseName(GLuint test_case_index)
13185 std::stringstream stream;
13186 testCase& test_case = m_test_cases[test_case_index];
13188 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", direction: ";
13190 if (true == test_case.m_is_input)
13196 stream << "output";
13199 return stream.str();
13202 /** Get number of test cases
13204 * @return Number of test cases
13206 GLuint VaryingStructureMemberLocationTest::getTestCaseNumber()
13208 return static_cast<GLuint>(m_test_cases.size());
13211 /** Selects if "compute" stage is relevant for test
13217 bool VaryingStructureMemberLocationTest::isComputeRelevant(GLuint /* test_case_index */)
13222 /** Prepare all test cases
13225 void VaryingStructureMemberLocationTest::testInit()
13227 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
13229 if (Utils::Shader::COMPUTE == stage)
13234 testCase test_case_in = { true, (Utils::Shader::STAGES)stage };
13235 testCase test_case_out = { false, (Utils::Shader::STAGES)stage };
13237 m_test_cases.push_back(test_case_in);
13239 if (Utils::Shader::FRAGMENT != stage)
13241 m_test_cases.push_back(test_case_out);
13248 * @param context Test framework context
13250 VaryingBlockLocationsTest::VaryingBlockLocationsTest(deqp::Context& context)
13251 : TextureTestBase(context, "varying_block_locations",
13252 "Test verifies that locations are respected when blocks are used as in and out ")
13256 /** Prepare code snippet that will pass in variables to out variables
13259 * @param varying_passthrough Collection of connections between in and out variables
13260 * @param stage Shader stage
13262 * @return Code that pass in variables to next stage
13264 std::string VaryingBlockLocationsTest::getPassSnippet(GLuint /* test_case_index */,
13265 Utils::VaryingPassthrough& varying_passthrough,
13266 Utils::Shader::STAGES stage)
13268 std::string result;
13270 if (Utils::Shader::VERTEX != stage)
13272 result = TextureTestBase::getPassSnippet(0, varying_passthrough, stage);
13276 result = "vs_tcs_block.third = vs_in_third;\n"
13277 " vs_tcs_block.fourth = vs_in_fourth;\n"
13278 " vs_tcs_block.fifth = vs_in_fifth;\n";
13284 /** Get interface of program
13287 * @param program_interface Interface of program
13288 * @param varying_passthrough Collection of connections between in and out variables
13290 void VaryingBlockLocationsTest::getProgramInterface(GLuint /* test_case_index */,
13291 Utils::ProgramInterface& program_interface,
13292 Utils::VaryingPassthrough& varying_passthrough)
13294 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
13295 const Utils::Type vec4 = Utils::Type::vec4;
13298 m_third_data = vec4.GenerateData();
13299 m_fourth_data = vec4.GenerateData();
13300 m_fifth_data = vec4.GenerateData();
13302 /* Memory layout is different from location layout */
13303 const GLuint fifth_offset = 0u;
13304 const GLuint third_offset = static_cast<GLuint>(fifth_offset + m_fifth_data.size());
13305 const GLuint fourth_offset = static_cast<GLuint>(third_offset + m_fourth_data.size());
13307 m_data.resize(fourth_offset + m_fourth_data.size());
13308 GLubyte* ptr = (GLubyte*)&m_data[0];
13309 memcpy(ptr + third_offset, &m_third_data[0], m_third_data.size());
13310 memcpy(ptr + fourth_offset, &m_fourth_data[0], m_fourth_data.size());
13311 memcpy(ptr + fifth_offset, &m_fifth_data[0], m_fifth_data.size());
13313 Utils::Interface* block = program_interface.Block("vs_tcs_Block");
13315 block->Member("fifth", "" /* qualifiers */, 0 /* component */, 4 /* location */, vec4, false /* normalized */,
13316 0u /* n_array_elements */, 0u /* stride */, fifth_offset /* offset */);
13318 block->Member("third", "layout (location = 2)" /* qualifiers */, 0 /* component */, 2 /* location */, vec4,
13319 false /* normalized */, 0u /* n_array_elements */, 0u /* stride */, third_offset /* offset */);
13321 block->Member("fourth", "" /* qualifiers */, 0 /* component */, 3 /* location */, vec4, false /* normalized */,
13322 0u /* n_array_elements */, 0u /* stride */, fourth_offset /* offset */);
13324 si.Output("vs_tcs_block", "layout (location = 4)", 0 /* component */, 4 /* location */, block,
13325 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)&m_data[0] /* data */,
13326 m_data.size() /* data_size */);
13328 si.Input("vs_in_third", "layout (location = 0)", 0 /* component */, 0 /* location */, vec4, false /* normalized */,
13329 0u /* n_array_elements */, 0u /* stride */, third_offset /* offset */,
13330 (GLvoid*)&m_third_data[0] /* data */, m_third_data.size() /* data_size */);
13332 si.Input("vs_in_fourth", "layout (location = 1)", 0 /* component */, 1 /* location */, vec4, false /* normalized */,
13333 0u /* n_array_elements */, 0u /* stride */, fourth_offset /* offset */,
13334 (GLvoid*)&m_fourth_data[0] /* data */, m_fourth_data.size() /* data_size */);
13336 si.Input("vs_in_fifth", "layout (location = 2)", 0 /* component */, 2 /* location */, vec4, false /* normalized */,
13337 0u /* n_array_elements */, 0u /* stride */, fifth_offset /* offset */,
13338 (GLvoid*)&m_fifth_data[0] /* data */, m_fifth_data.size() /* data_size */);
13340 program_interface.CloneVertexInterface(varying_passthrough);
13343 /** Selects if "compute" stage is relevant for test
13349 bool VaryingBlockLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
13354 /** This test should be run with separable programs
13360 bool VaryingBlockLocationsTest::useMonolithicProgram(GLuint /* test_case_index */)
13367 * @param context Test framework context
13369 VaryingBlockMemberLocationsTest::VaryingBlockMemberLocationsTest(deqp::Context& context)
13370 : NegativeTestBase(
13371 context, "varying_block_member_locations",
13372 "Test verifies that compilation error is reported when not all members of block are qualified with location")
13376 /** Source for given test case and stage
13378 * @param test_case_index Index of test case
13379 * @param stage Shader stage
13381 * @return Shader source
13383 std::string VaryingBlockMemberLocationsTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
13385 static const GLchar* block_definition_all = "Goku {\n"
13386 " layout (location = 2) vec4 gohan;\n"
13387 " layout (location = 4) vec4 goten;\n"
13388 " layout (location = 6) vec4 chichi;\n"
13390 static const GLchar* block_definition_default = "Goku {\n"
13395 static const GLchar* block_definition_one = "Goku {\n"
13397 " layout (location = 4) vec4 goten;\n"
13400 static const GLchar* input_use = " result += gokuINDEX.gohan + gokuINDEX.goten + gokuINDEX.chichi;\n";
13401 static const GLchar* output_use = " gokuINDEX.gohan = result / 2;\n"
13402 " gokuINDEX.goten = result / 4 - gokuINDEX.gohan;\n"
13403 " gokuINDEX.chichi = result / 8 - gokuINDEX.goten;\n";
13404 static const GLchar* fs = "#version 430 core\n"
13405 "#extension GL_ARB_enhanced_layouts : require\n"
13408 "out vec4 fs_out;\n"
13412 " fs_out = gs_fs;\n"
13415 static const GLchar* fs_tested = "#version 430 core\n"
13416 "#extension GL_ARB_enhanced_layouts : require\n"
13418 "DIRECTION BLOCK_DEFINITION"
13421 "out vec4 fs_out;\n"
13425 " vec4 result = gs_fs;\n"
13429 " fs_out = result;\n"
13432 static const GLchar* gs = "#version 430 core\n"
13433 "#extension GL_ARB_enhanced_layouts : require\n"
13435 "layout(points) in;\n"
13436 "layout(triangle_strip, max_vertices = 4) out;\n"
13438 "in vec4 tes_gs[];\n"
13439 "out vec4 gs_fs;\n"
13443 " gs_fs = tes_gs[0];\n"
13444 " gl_Position = vec4(-1, -1, 0, 1);\n"
13446 " gs_fs = tes_gs[0];\n"
13447 " gl_Position = vec4(-1, 1, 0, 1);\n"
13449 " gs_fs = tes_gs[0];\n"
13450 " gl_Position = vec4(1, -1, 0, 1);\n"
13452 " gs_fs = tes_gs[0];\n"
13453 " gl_Position = vec4(1, 1, 0, 1);\n"
13457 static const GLchar* gs_tested = "#version 430 core\n"
13458 "#extension GL_ARB_enhanced_layouts : require\n"
13460 "layout(points) in;\n"
13461 "layout(triangle_strip, max_vertices = 4) out;\n"
13463 "DIRECTION BLOCK_DEFINITION"
13465 "in vec4 tes_gs[];\n"
13466 "out vec4 gs_fs;\n"
13470 " vec4 result = tes_gs[0];\n"
13474 " gs_fs = result;\n"
13475 " gl_Position = vec4(-1, -1, 0, 1);\n"
13477 " gs_fs = result;\n"
13478 " gl_Position = vec4(-1, 1, 0, 1);\n"
13480 " gs_fs = result;\n"
13481 " gl_Position = vec4(1, -1, 0, 1);\n"
13483 " gs_fs = result;\n"
13484 " gl_Position = vec4(1, 1, 0, 1);\n"
13488 static const GLchar* tcs = "#version 430 core\n"
13489 "#extension GL_ARB_enhanced_layouts : require\n"
13491 "layout(vertices = 1) out;\n"
13493 "in vec4 vs_tcs[];\n"
13494 "out vec4 tcs_tes[];\n"
13499 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
13501 " gl_TessLevelOuter[0] = 1.0;\n"
13502 " gl_TessLevelOuter[1] = 1.0;\n"
13503 " gl_TessLevelOuter[2] = 1.0;\n"
13504 " gl_TessLevelOuter[3] = 1.0;\n"
13505 " gl_TessLevelInner[0] = 1.0;\n"
13506 " gl_TessLevelInner[1] = 1.0;\n"
13509 static const GLchar* tcs_tested = "#version 430 core\n"
13510 "#extension GL_ARB_enhanced_layouts : require\n"
13512 "layout(vertices = 1) out;\n"
13514 "DIRECTION BLOCK_DEFINITION"
13516 "in vec4 vs_tcs[];\n"
13517 "out vec4 tcs_tes[];\n"
13521 " vec4 result = vs_tcs[gl_InvocationID];\n"
13525 " tcs_tes[gl_InvocationID] = result;\n"
13527 " gl_TessLevelOuter[0] = 1.0;\n"
13528 " gl_TessLevelOuter[1] = 1.0;\n"
13529 " gl_TessLevelOuter[2] = 1.0;\n"
13530 " gl_TessLevelOuter[3] = 1.0;\n"
13531 " gl_TessLevelInner[0] = 1.0;\n"
13532 " gl_TessLevelInner[1] = 1.0;\n"
13535 static const GLchar* tes = "#version 430 core\n"
13536 "#extension GL_ARB_enhanced_layouts : require\n"
13538 "layout(isolines, point_mode) in;\n"
13540 "in vec4 tcs_tes[];\n"
13541 "out vec4 tes_gs;\n"
13545 " tes_gs = tcs_tes[0];\n"
13548 static const GLchar* tes_tested = "#version 430 core\n"
13549 "#extension GL_ARB_enhanced_layouts : require\n"
13551 "layout(isolines, point_mode) in;\n"
13553 "DIRECTION BLOCK_DEFINITION"
13555 "in vec4 tcs_tes[];\n"
13556 "out vec4 tes_gs;\n"
13560 " vec4 result = tcs_tes[0];\n"
13564 " tes_gs = result;\n"
13567 static const GLchar* vs = "#version 430 core\n"
13568 "#extension GL_ARB_enhanced_layouts : require\n"
13571 "out vec4 vs_tcs;\n"
13575 " vs_tcs = in_vs;\n"
13578 static const GLchar* vs_tested = "#version 430 core\n"
13579 "#extension GL_ARB_enhanced_layouts : require\n"
13581 "DIRECTION BLOCK_DEFINITION"
13584 "out vec4 vs_tcs;\n"
13588 " vec4 result = in_vs;\n"
13592 " vs_tcs = result;\n"
13596 static const GLchar* shaders_in[6][6] = { /* cs */ { 0, 0, 0, 0, 0, 0 },
13597 /* vs */ { 0, vs_tested, tcs, tes, gs, fs },
13598 /* tcs */ { 0, vs_tested, tcs_tested, tes, gs, fs },
13599 /* tes */ { 0, vs, tcs_tested, tes_tested, gs, fs },
13600 /* gs */ { 0, vs, tcs, tes_tested, gs_tested, fs },
13601 /* fs */ { 0, vs, tcs, tes, gs_tested, fs_tested } };
13603 static const GLchar* shaders_out[6][6] = { /* cs */ { 0, 0, 0, 0, 0, 0 },
13604 /* vs */ { 0, vs_tested, tcs_tested, tes, gs, fs },
13605 /* tcs */ { 0, vs, tcs_tested, tes_tested, gs, fs },
13606 /* tes */ { 0, vs, tcs, tes_tested, gs_tested, fs },
13607 /* gs */ { 0, vs, tcs, tes, gs_tested, fs_tested },
13608 /* fs */ { 0, 0, 0, 0, 0, 0 } };
13610 static const bool require_modifications_in[6][6] = {
13611 /* cs */ { false, false, false, false, false, false },
13612 /* vs */ { false, true, false, false, false, false },
13613 /* tcs */ { false, true, true, false, false, false },
13614 /* tes */ { false, false, true, true, false, false },
13615 /* gs */ { false, false, false, true, true, false },
13616 /* fs */ { false, false, false, false, true, true }
13619 static const bool require_modifications_out[6][6] = {
13620 /* cs */ { false, false, false, false, false, false },
13621 /* vs */ { false, true, true, false, false, false },
13622 /* tcs */ { false, false, true, true, false, false },
13623 /* tes */ { false, false, false, true, true, false },
13624 /* gs */ { false, false, false, false, true, true },
13625 /* fs */ { false, false, false, false, false, false }
13628 const GLchar* array = "";
13629 const GLchar* definition = block_definition_default;
13630 const GLchar* direction = "out";
13631 const GLchar* index = "";
13632 bool require_modifications = false;
13633 std::string source;
13634 testCase& test_case = m_test_cases[test_case_index];
13635 const GLchar* var_use = output_use;
13637 if (true == test_case.m_is_input)
13639 require_modifications = require_modifications_in[test_case.m_stage][stage];
13640 source = shaders_in[test_case.m_stage][stage];
13642 if (test_case.m_stage == stage)
13645 var_use = input_use;
13650 require_modifications = require_modifications_out[test_case.m_stage][stage];
13651 source = shaders_out[test_case.m_stage][stage];
13653 if (test_case.m_stage != stage)
13656 var_use = input_use;
13660 if (test_case.m_stage == stage)
13662 if (true == test_case.m_qualify_all)
13664 definition = block_definition_all;
13668 definition = block_definition_one;
13674 case Utils::Shader::FRAGMENT:
13676 case Utils::Shader::GEOMETRY:
13680 case Utils::Shader::TESS_CTRL:
13682 index = "[gl_InvocationID]";
13684 // geometry shader's input must have one more dimension than tessellation evaluation shader's output,
13685 // the GS input block is an array, so the DS output can't be declared as an array
13686 case Utils::Shader::TESS_EVAL:
13688 if (std::string(direction) == std::string("in")) // match HS output and DS input
13693 else // match DS output and GS input
13700 case Utils::Shader::VERTEX:
13703 TCU_FAIL("Invalid enum");
13706 if (true == require_modifications)
13708 size_t position = 0;
13711 Utils::replaceToken("DIRECTION", position, direction, source);
13713 Utils::replaceToken("BLOCK_DEFINITION", position, definition, source);
13715 Utils::replaceToken("ARRAY", position, array, source);
13716 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
13718 Utils::replaceAllTokens("INDEX", index, source);
13724 case Utils::Shader::FRAGMENT:
13727 case Utils::Shader::GEOMETRY:
13730 case Utils::Shader::TESS_CTRL:
13733 case Utils::Shader::TESS_EVAL:
13736 case Utils::Shader::VERTEX:
13740 TCU_FAIL("Invalid enum");
13747 /** Get description of test case
13749 * @param test_case_index Index of test case
13751 * @return Test case description
13753 std::string VaryingBlockMemberLocationsTest::getTestCaseName(GLuint test_case_index)
13755 std::stringstream stream;
13756 testCase& test_case = m_test_cases[test_case_index];
13758 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", direction: ";
13760 if (true == test_case.m_is_input)
13766 stream << "output";
13769 if (true == test_case.m_qualify_all)
13771 stream << ", all members qualified";
13775 stream << ", not all members qualified";
13778 return stream.str();
13781 /** Get number of test cases
13783 * @return Number of test cases
13785 GLuint VaryingBlockMemberLocationsTest::getTestCaseNumber()
13787 return static_cast<GLuint>(m_test_cases.size());
13790 /** Selects if "compute" stage is relevant for test
13796 bool VaryingBlockMemberLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
13801 /** Selects if compilation failure is expected result
13803 * @param test_case_index Index of test case
13805 * @return false when all members are qualified, true otherwise
13807 bool VaryingBlockMemberLocationsTest::isFailureExpected(GLuint test_case_index)
13809 return (true != m_test_cases[test_case_index].m_qualify_all);
13812 /** Prepare all test cases
13815 void VaryingBlockMemberLocationsTest::testInit()
13817 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
13819 if (Utils::Shader::COMPUTE == stage)
13824 testCase test_case_in_all = { true, true, (Utils::Shader::STAGES)stage };
13825 testCase test_case_in_one = { true, false, (Utils::Shader::STAGES)stage };
13826 testCase test_case_out_all = { false, true, (Utils::Shader::STAGES)stage };
13827 testCase test_case_out_one = { false, false, (Utils::Shader::STAGES)stage };
13829 if (Utils::Shader::VERTEX != stage)
13831 m_test_cases.push_back(test_case_in_all);
13832 m_test_cases.push_back(test_case_in_one);
13835 if (Utils::Shader::FRAGMENT != stage)
13837 m_test_cases.push_back(test_case_out_all);
13838 m_test_cases.push_back(test_case_out_one);
13845 * @param context Test framework context
13847 VaryingBlockAutomaticMemberLocationsTest::VaryingBlockAutomaticMemberLocationsTest(deqp::Context& context)
13848 : NegativeTestBase(
13849 context, "varying_block_automatic_member_locations",
13850 "Test verifies that compiler assigns subsequent locations to block members, even if this casue error")
13854 /** Source for given test case and stage
13856 * @param test_case_index Index of test case
13857 * @param stage Shader stage
13859 * @return Shader source
13861 std::string VaryingBlockAutomaticMemberLocationsTest::getShaderSource(GLuint test_case_index,
13862 Utils::Shader::STAGES stage)
13864 static const GLchar* block_definition = "layout (location = 2) DIRECTION DBZ {\n"
13866 " vec4 gohan[4];\n"
13868 " layout (location = 1) vec4 chichi;\n"
13871 static const GLchar* input_use = " result += dbzINDEX.goku + dbzINDEX.gohan[0] + dbzINDEX.gohan[1] + "
13872 "dbzINDEX.gohan[3] + dbzINDEX.gohan[2] + dbzINDEX.goten + dbzINDEX.chichi + "
13874 static const GLchar* output_use = " dbzINDEX.goku = result;\n"
13875 " dbzINDEX.gohan[0] = result / 2;\n"
13876 " dbzINDEX.gohan[1] = result / 2.25;\n"
13877 " dbzINDEX.gohan[2] = result / 2.5;\n"
13878 " dbzINDEX.gohan[3] = result / 2.75;\n"
13879 " dbzINDEX.goten = result / 4 - dbzINDEX.gohan[0] - dbzINDEX.gohan[1] - "
13880 "dbzINDEX.gohan[2] - dbzINDEX.gohan[3];\n"
13881 " dbzINDEX.chichi = result / 8 - dbzINDEX.goten;\n"
13882 " dbzINDEX.pan = result / 16 - dbzINDEX.chichi;\n";
13883 static const GLchar* fs = "#version 430 core\n"
13884 "#extension GL_ARB_enhanced_layouts : require\n"
13887 "out vec4 fs_out;\n"
13891 " fs_out = gs_fs;\n"
13894 static const GLchar* fs_tested = "#version 430 core\n"
13895 "#extension GL_ARB_enhanced_layouts : require\n"
13900 "out vec4 fs_out;\n"
13904 " vec4 result = gs_fs;\n"
13908 " fs_out += result;\n"
13911 static const GLchar* gs = "#version 430 core\n"
13912 "#extension GL_ARB_enhanced_layouts : require\n"
13914 "layout(points) in;\n"
13915 "layout(triangle_strip, max_vertices = 4) out;\n"
13917 "in vec4 tes_gs[];\n"
13918 "out vec4 gs_fs;\n"
13922 " gs_fs = tes_gs[0];\n"
13923 " gl_Position = vec4(-1, -1, 0, 1);\n"
13925 " gs_fs = tes_gs[0];\n"
13926 " gl_Position = vec4(-1, 1, 0, 1);\n"
13928 " gs_fs = tes_gs[0];\n"
13929 " gl_Position = vec4(1, -1, 0, 1);\n"
13931 " gs_fs = tes_gs[0];\n"
13932 " gl_Position = vec4(1, 1, 0, 1);\n"
13936 static const GLchar* gs_tested = "#version 430 core\n"
13937 "#extension GL_ARB_enhanced_layouts : require\n"
13939 "layout(points) in;\n"
13940 "layout(triangle_strip, max_vertices = 4) out;\n"
13944 "in vec4 tes_gs[];\n"
13945 "out vec4 gs_fs;\n"
13949 " vec4 result = tes_gs[0];\n"
13953 " gs_fs = result;\n"
13954 " gl_Position = vec4(-1, -1, 0, 1);\n"
13956 " gs_fs = result;\n"
13957 " gl_Position = vec4(-1, 1, 0, 1);\n"
13959 " gs_fs = result;\n"
13960 " gl_Position = vec4(1, -1, 0, 1);\n"
13962 " gs_fs = result;\n"
13963 " gl_Position = vec4(1, 1, 0, 1);\n"
13967 static const GLchar* tcs = "#version 430 core\n"
13968 "#extension GL_ARB_enhanced_layouts : require\n"
13970 "layout(vertices = 1) out;\n"
13972 "in vec4 vs_tcs[];\n"
13973 "out vec4 tcs_tes[];\n"
13978 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
13980 " gl_TessLevelOuter[0] = 1.0;\n"
13981 " gl_TessLevelOuter[1] = 1.0;\n"
13982 " gl_TessLevelOuter[2] = 1.0;\n"
13983 " gl_TessLevelOuter[3] = 1.0;\n"
13984 " gl_TessLevelInner[0] = 1.0;\n"
13985 " gl_TessLevelInner[1] = 1.0;\n"
13988 static const GLchar* tcs_tested = "#version 430 core\n"
13989 "#extension GL_ARB_enhanced_layouts : require\n"
13991 "layout(vertices = 1) out;\n"
13995 "in vec4 vs_tcs[];\n"
13996 "out vec4 tcs_tes[];\n"
14000 " vec4 result = vs_tcs[gl_InvocationID];\n"
14004 " tcs_tes[gl_InvocationID] = result;\n"
14006 " gl_TessLevelOuter[0] = 1.0;\n"
14007 " gl_TessLevelOuter[1] = 1.0;\n"
14008 " gl_TessLevelOuter[2] = 1.0;\n"
14009 " gl_TessLevelOuter[3] = 1.0;\n"
14010 " gl_TessLevelInner[0] = 1.0;\n"
14011 " gl_TessLevelInner[1] = 1.0;\n"
14014 static const GLchar* tes = "#version 430 core\n"
14015 "#extension GL_ARB_enhanced_layouts : require\n"
14017 "layout(isolines, point_mode) in;\n"
14019 "in vec4 tcs_tes[];\n"
14020 "out vec4 tes_gs;\n"
14024 " tes_gs = tcs_tes[0];\n"
14027 static const GLchar* tes_tested = "#version 430 core\n"
14028 "#extension GL_ARB_enhanced_layouts : require\n"
14030 "layout(isolines, point_mode) in;\n"
14034 "in vec4 tcs_tes[];\n"
14035 "out vec4 tes_gs;\n"
14039 " vec4 result = tcs_tes[0];\n"
14043 " tes_gs += result;\n"
14046 static const GLchar* vs = "#version 430 core\n"
14047 "#extension GL_ARB_enhanced_layouts : require\n"
14050 "out vec4 vs_tcs;\n"
14054 " vs_tcs = in_vs;\n"
14057 static const GLchar* vs_tested = "#version 430 core\n"
14058 "#extension GL_ARB_enhanced_layouts : require\n"
14063 "out vec4 vs_tcs;\n"
14067 " vec4 result = in_vs;\n"
14071 " vs_tcs += result;\n"
14075 const GLchar* array = "";
14076 const GLchar* direction = "out";
14077 const GLchar* index = "";
14078 std::string source;
14079 testCase& test_case = m_test_cases[test_case_index];
14080 const GLchar* var_use = output_use;
14082 if (true == test_case.m_is_input)
14085 var_use = input_use;
14088 if (test_case.m_stage == stage)
14090 size_t position = 0;
14095 case Utils::Shader::FRAGMENT:
14096 source = fs_tested;
14098 case Utils::Shader::GEOMETRY:
14099 source = gs_tested;
14103 case Utils::Shader::TESS_CTRL:
14104 source = tcs_tested;
14106 index = "[gl_InvocationID]";
14108 case Utils::Shader::TESS_EVAL:
14109 source = tes_tested;
14113 case Utils::Shader::VERTEX:
14114 source = vs_tested;
14117 TCU_FAIL("Invalid enum");
14121 Utils::replaceToken("BLOCK_DEFINITION", position, block_definition, source);
14123 Utils::replaceToken("DIRECTION", position, direction, source);
14124 Utils::replaceToken("ARRAY", position, array, source);
14125 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
14127 Utils::replaceAllTokens("INDEX", index, source);
14133 case Utils::Shader::FRAGMENT:
14136 case Utils::Shader::GEOMETRY:
14139 case Utils::Shader::TESS_CTRL:
14142 case Utils::Shader::TESS_EVAL:
14145 case Utils::Shader::VERTEX:
14149 TCU_FAIL("Invalid enum");
14156 /** Get description of test case
14158 * @param test_case_index Index of test case
14160 * @return Test case description
14162 std::string VaryingBlockAutomaticMemberLocationsTest::getTestCaseName(GLuint test_case_index)
14164 std::stringstream stream;
14165 testCase& test_case = m_test_cases[test_case_index];
14167 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", direction: ";
14169 if (true == test_case.m_is_input)
14175 stream << "output";
14178 return stream.str();
14181 /** Get number of test cases
14183 * @return Number of test cases
14185 GLuint VaryingBlockAutomaticMemberLocationsTest::getTestCaseNumber()
14187 return static_cast<GLuint>(m_test_cases.size());
14190 /** Selects if "compute" stage is relevant for test
14196 bool VaryingBlockAutomaticMemberLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
14201 /** Prepare all test cases
14204 void VaryingBlockAutomaticMemberLocationsTest::testInit()
14206 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
14208 if (Utils::Shader::COMPUTE == stage)
14213 testCase test_case_in = { true, (Utils::Shader::STAGES)stage };
14214 testCase test_case_out = { false, (Utils::Shader::STAGES)stage };
14216 if (Utils::Shader::VERTEX != stage)
14218 m_test_cases.push_back(test_case_in);
14221 if (Utils::Shader::FRAGMENT != stage)
14223 m_test_cases.push_back(test_case_out);
14230 * @param context Test framework context
14232 VaryingLocationLimitTest::VaryingLocationLimitTest(deqp::Context& context)
14233 : NegativeTestBase(context, "varying_location_limit",
14234 "Test verifies that compiler reports error when location qualifier exceed limits")
14238 /** Source for given test case and stage
14240 * @param test_case_index Index of test case
14241 * @param stage Shader stage
14243 * @return Shader source
14245 std::string VaryingLocationLimitTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
14247 static const GLchar* var_definition = "layout (location = LAST + 1) FLAT DIRECTION TYPE gokuARRAY;\n";
14248 static const GLchar* input_use = " if (TYPE(0) == gokuINDEX)\n"
14250 " result += vec4(1, 0.5, 0.25, 0.125);\n"
14252 static const GLchar* output_use = " gokuINDEX = TYPE(0);\n"
14253 " if (vec4(0) == result)\n"
14255 " gokuINDEX = TYPE(1);\n"
14257 static const GLchar* fs = "#version 430 core\n"
14258 "#extension GL_ARB_enhanced_layouts : require\n"
14261 "out vec4 fs_out;\n"
14265 " fs_out = gs_fs;\n"
14268 static const GLchar* fs_tested = "#version 430 core\n"
14269 "#extension GL_ARB_enhanced_layouts : require\n"
14274 "out vec4 fs_out;\n"
14278 " vec4 result = gs_fs;\n"
14282 " fs_out += result;\n"
14285 static const GLchar* gs = "#version 430 core\n"
14286 "#extension GL_ARB_enhanced_layouts : require\n"
14288 "layout(points) in;\n"
14289 "layout(triangle_strip, max_vertices = 4) out;\n"
14291 "in vec4 tes_gs[];\n"
14292 "out vec4 gs_fs;\n"
14296 " gs_fs = tes_gs[0];\n"
14297 " gl_Position = vec4(-1, -1, 0, 1);\n"
14299 " gs_fs = tes_gs[0];\n"
14300 " gl_Position = vec4(-1, 1, 0, 1);\n"
14302 " gs_fs = tes_gs[0];\n"
14303 " gl_Position = vec4(1, -1, 0, 1);\n"
14305 " gs_fs = tes_gs[0];\n"
14306 " gl_Position = vec4(1, 1, 0, 1);\n"
14310 static const GLchar* gs_tested = "#version 430 core\n"
14311 "#extension GL_ARB_enhanced_layouts : require\n"
14313 "layout(points) in;\n"
14314 "layout(triangle_strip, max_vertices = 4) out;\n"
14318 "in vec4 tes_gs[];\n"
14319 "out vec4 gs_fs;\n"
14323 " vec4 result = tes_gs[0];\n"
14327 " gs_fs = result;\n"
14328 " gl_Position = vec4(-1, -1, 0, 1);\n"
14330 " gs_fs = result;\n"
14331 " gl_Position = vec4(-1, 1, 0, 1);\n"
14333 " gs_fs = result;\n"
14334 " gl_Position = vec4(1, -1, 0, 1);\n"
14336 " gs_fs = result;\n"
14337 " gl_Position = vec4(1, 1, 0, 1);\n"
14341 static const GLchar* tcs = "#version 430 core\n"
14342 "#extension GL_ARB_enhanced_layouts : require\n"
14344 "layout(vertices = 1) out;\n"
14346 "in vec4 vs_tcs[];\n"
14347 "out vec4 tcs_tes[];\n"
14352 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
14354 " gl_TessLevelOuter[0] = 1.0;\n"
14355 " gl_TessLevelOuter[1] = 1.0;\n"
14356 " gl_TessLevelOuter[2] = 1.0;\n"
14357 " gl_TessLevelOuter[3] = 1.0;\n"
14358 " gl_TessLevelInner[0] = 1.0;\n"
14359 " gl_TessLevelInner[1] = 1.0;\n"
14362 static const GLchar* tcs_tested = "#version 430 core\n"
14363 "#extension GL_ARB_enhanced_layouts : require\n"
14365 "layout(vertices = 1) out;\n"
14369 "in vec4 vs_tcs[];\n"
14370 "out vec4 tcs_tes[];\n"
14374 " vec4 result = vs_tcs[gl_InvocationID];\n"
14378 " tcs_tes[gl_InvocationID] = result;\n"
14380 " gl_TessLevelOuter[0] = 1.0;\n"
14381 " gl_TessLevelOuter[1] = 1.0;\n"
14382 " gl_TessLevelOuter[2] = 1.0;\n"
14383 " gl_TessLevelOuter[3] = 1.0;\n"
14384 " gl_TessLevelInner[0] = 1.0;\n"
14385 " gl_TessLevelInner[1] = 1.0;\n"
14388 static const GLchar* tes = "#version 430 core\n"
14389 "#extension GL_ARB_enhanced_layouts : require\n"
14391 "layout(isolines, point_mode) in;\n"
14393 "in vec4 tcs_tes[];\n"
14394 "out vec4 tes_gs;\n"
14398 " tes_gs = tcs_tes[0];\n"
14401 static const GLchar* tes_tested = "#version 430 core\n"
14402 "#extension GL_ARB_enhanced_layouts : require\n"
14404 "layout(isolines, point_mode) in;\n"
14408 "in vec4 tcs_tes[];\n"
14409 "out vec4 tes_gs;\n"
14413 " vec4 result = tcs_tes[0];\n"
14417 " tes_gs += result;\n"
14420 static const GLchar* vs = "#version 430 core\n"
14421 "#extension GL_ARB_enhanced_layouts : require\n"
14424 "out vec4 vs_tcs;\n"
14428 " vs_tcs = in_vs;\n"
14431 static const GLchar* vs_tested = "#version 430 core\n"
14432 "#extension GL_ARB_enhanced_layouts : require\n"
14437 "out vec4 vs_tcs;\n"
14441 " vec4 result = in_vs;\n"
14445 " vs_tcs += result;\n"
14449 std::string source;
14450 testCase& test_case = m_test_cases[test_case_index];
14452 if (test_case.m_stage == stage)
14454 const GLchar* array = "";
14456 const GLchar* direction = "in ";
14457 const GLchar* flat = "";
14458 const GLchar* index = "";
14459 GLuint last = getLastInputLocation(stage, test_case.m_type, 0);
14460 size_t position = 0;
14462 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
14463 Utils::Variable::STORAGE storage = Utils::Variable::VARYING_INPUT;
14464 const GLchar* var_use = input_use;
14466 if (false == test_case.m_is_input)
14469 last = getLastOutputLocation(stage, test_case.m_type, 0);
14470 storage = Utils::Variable::VARYING_OUTPUT;
14471 var_use = output_use;
14474 if (true == isFlatRequired(stage, test_case.m_type, storage))
14479 sprintf(buffer, "%d", last);
14483 case Utils::Shader::FRAGMENT:
14484 source = fs_tested;
14486 case Utils::Shader::GEOMETRY:
14487 source = gs_tested;
14491 case Utils::Shader::TESS_CTRL:
14492 source = tcs_tested;
14494 index = "[gl_InvocationID]";
14496 case Utils::Shader::TESS_EVAL:
14497 source = tes_tested;
14501 case Utils::Shader::VERTEX:
14502 source = vs_tested;
14505 TCU_FAIL("Invalid enum");
14509 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
14511 Utils::replaceToken("LAST", position, buffer, source);
14512 Utils::replaceToken("FLAT", position, flat, source);
14513 Utils::replaceToken("DIRECTION", position, direction, source);
14514 Utils::replaceToken("ARRAY", position, array, source);
14515 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
14517 Utils::replaceAllTokens("TYPE", type_name, source);
14518 Utils::replaceAllTokens("INDEX", index, source);
14524 case Utils::Shader::FRAGMENT:
14527 case Utils::Shader::GEOMETRY:
14530 case Utils::Shader::TESS_CTRL:
14533 case Utils::Shader::TESS_EVAL:
14536 case Utils::Shader::VERTEX:
14540 TCU_FAIL("Invalid enum");
14547 /** Get description of test case
14549 * @param test_case_index Index of test case
14551 * @return Test case description
14553 std::string VaryingLocationLimitTest::getTestCaseName(GLuint test_case_index)
14555 std::stringstream stream;
14556 testCase& test_case = m_test_cases[test_case_index];
14558 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
14559 << " type: " << test_case.m_type.GetGLSLTypeName() << ", direction: ";
14561 if (true == test_case.m_is_input)
14567 stream << "output";
14570 return stream.str();
14573 /** Get number of test cases
14575 * @return Number of test cases
14577 GLuint VaryingLocationLimitTest::getTestCaseNumber()
14579 return static_cast<GLuint>(m_test_cases.size());
14582 /** Selects if "compute" stage is relevant for test
14588 bool VaryingLocationLimitTest::isComputeRelevant(GLuint /* test_case_index */)
14593 /** Prepare all test cases
14596 void VaryingLocationLimitTest::testInit()
14598 const GLuint n_types = getTypesNumber();
14600 for (GLuint i = 0; i < n_types; ++i)
14602 const Utils::Type& type = getType(i);
14604 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
14606 if (Utils::Shader::COMPUTE == stage)
14611 testCase test_case_in = { true, type, (Utils::Shader::STAGES)stage };
14612 testCase test_case_out = { false, type, (Utils::Shader::STAGES)stage };
14614 m_test_cases.push_back(test_case_in);
14616 if (Utils::Shader::FRAGMENT != stage)
14618 m_test_cases.push_back(test_case_out);
14626 * @param context Test framework context
14628 VaryingComponentsTest::VaryingComponentsTest(deqp::Context& context)
14629 : VaryingLocationsTest(context, "varying_components",
14630 "Test verifies that input and output components are respected")
14636 * @param context Test framework context
14637 * @param test_name Name of test
14638 * @param test_description Description of test
14640 VaryingComponentsTest::VaryingComponentsTest(deqp::Context& context, const glw::GLchar* test_name,
14641 const glw::GLchar* test_description)
14642 : VaryingLocationsTest(context, test_name, test_description)
14646 /** Get interface of program
14648 * @param test_case_index Test case
14649 * @param program_interface Interface of program
14650 * @param varying_passthrough Collection of connections between in and out variables
14652 void VaryingComponentsTest::getProgramInterface(GLuint test_case_index, Utils::ProgramInterface& program_interface,
14653 Utils::VaryingPassthrough& varying_passthrough)
14655 GLuint array_length = getArrayLength();
14656 const testCase& test_case = m_test_cases[test_case_index];
14657 const Utils::Type vector_type = Utils::Type::GetType(test_case.m_type, 1, 4);
14658 Utils::ShaderInterface si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
14660 /* Zero means no array, however we still need at least 1 slot of data */
14661 if (0 == array_length)
14666 /* Generate data */
14667 const std::vector<GLubyte>& data = vector_type.GenerateDataPacked();
14668 const size_t data_size = data.size();
14670 /* Prepare data for variables */
14671 m_data.resize(array_length * data_size);
14673 GLubyte* dst = &m_data[0];
14674 const GLubyte* src = &data[0];
14676 for (GLuint i = 0; i < array_length; ++i)
14678 memcpy(dst + data_size * i, src, data_size);
14681 /* Prepare interface for each stage */
14682 prepareShaderStage(Utils::Shader::FRAGMENT, vector_type, program_interface, test_case, varying_passthrough);
14683 prepareShaderStage(Utils::Shader::GEOMETRY, vector_type, program_interface, test_case, varying_passthrough);
14684 prepareShaderStage(Utils::Shader::TESS_CTRL, vector_type, program_interface, test_case, varying_passthrough);
14685 prepareShaderStage(Utils::Shader::TESS_EVAL, vector_type, program_interface, test_case, varying_passthrough);
14686 prepareShaderStage(Utils::Shader::VERTEX, vector_type, program_interface, test_case, varying_passthrough);
14691 * @param test_case_index Index of test case
14693 * @return Name of type test in test_case_index
14695 std::string VaryingComponentsTest::getTestCaseName(glw::GLuint test_case_index)
14699 const testCase& test_case = m_test_cases[test_case_index];
14703 switch (test_case.m_type)
14705 case Utils::Type::Double:
14706 name.append(Utils::Type::_double.GetGLSLTypeName());
14708 case Utils::Type::Float:
14709 name.append(Utils::Type::_float.GetGLSLTypeName());
14711 case Utils::Type::Int:
14712 name.append(Utils::Type::_int.GetGLSLTypeName());
14714 case Utils::Type::Uint:
14715 name.append(Utils::Type::uint.GetGLSLTypeName());
14719 name.append(", layout: ");
14721 switch (test_case.m_layout)
14724 name.append("GVEC4");
14727 name.append("SCALAR_GVEC3");
14730 name.append("GVEC3_SCALAR");
14733 name.append("GVEC2_GVEC2");
14735 case GVEC2_SCALAR_SCALAR:
14736 name.append("GVEC2_SCALAR_SCALAR");
14738 case SCALAR_GVEC2_SCALAR:
14739 name.append("SCALAR_GVEC2_SCALAR");
14741 case SCALAR_SCALAR_GVEC2:
14742 name.append("SCALAR_SCALAR_GVEC2");
14744 case SCALAR_SCALAR_SCALAR_SCALAR:
14745 name.append("SCALAR_SCALAR_SCALAR_SCALAR");
14752 /** Returns number of types to test
14754 * @return Number of types, 34
14756 glw::GLuint VaryingComponentsTest::getTestCaseNumber()
14758 return static_cast<GLuint>(m_test_cases.size());
14761 /* Prepare test cases */
14762 void VaryingComponentsTest::testInit()
14764 m_test_cases.push_back(testCase(GVEC4, Utils::Type::Double));
14765 m_test_cases.push_back(testCase(SCALAR_GVEC3, Utils::Type::Double));
14766 m_test_cases.push_back(testCase(GVEC3_SCALAR, Utils::Type::Double));
14767 m_test_cases.push_back(testCase(GVEC2_GVEC2, Utils::Type::Double));
14768 m_test_cases.push_back(testCase(GVEC2_SCALAR_SCALAR, Utils::Type::Double));
14769 m_test_cases.push_back(testCase(SCALAR_GVEC2_SCALAR, Utils::Type::Double));
14770 m_test_cases.push_back(testCase(SCALAR_SCALAR_GVEC2, Utils::Type::Double));
14771 m_test_cases.push_back(testCase(SCALAR_SCALAR_SCALAR_SCALAR, Utils::Type::Double));
14773 m_test_cases.push_back(testCase(GVEC4, Utils::Type::Float));
14774 m_test_cases.push_back(testCase(SCALAR_GVEC3, Utils::Type::Float));
14775 m_test_cases.push_back(testCase(GVEC3_SCALAR, Utils::Type::Float));
14776 m_test_cases.push_back(testCase(GVEC2_GVEC2, Utils::Type::Float));
14777 m_test_cases.push_back(testCase(GVEC2_SCALAR_SCALAR, Utils::Type::Float));
14778 m_test_cases.push_back(testCase(SCALAR_GVEC2_SCALAR, Utils::Type::Float));
14779 m_test_cases.push_back(testCase(SCALAR_SCALAR_GVEC2, Utils::Type::Float));
14780 m_test_cases.push_back(testCase(SCALAR_SCALAR_SCALAR_SCALAR, Utils::Type::Float));
14782 m_test_cases.push_back(testCase(GVEC4, Utils::Type::Int));
14783 m_test_cases.push_back(testCase(SCALAR_GVEC3, Utils::Type::Int));
14784 m_test_cases.push_back(testCase(GVEC3_SCALAR, Utils::Type::Int));
14785 m_test_cases.push_back(testCase(GVEC2_GVEC2, Utils::Type::Int));
14786 m_test_cases.push_back(testCase(GVEC2_SCALAR_SCALAR, Utils::Type::Int));
14787 m_test_cases.push_back(testCase(SCALAR_GVEC2_SCALAR, Utils::Type::Int));
14788 m_test_cases.push_back(testCase(SCALAR_SCALAR_GVEC2, Utils::Type::Int));
14789 m_test_cases.push_back(testCase(SCALAR_SCALAR_SCALAR_SCALAR, Utils::Type::Int));
14791 m_test_cases.push_back(testCase(GVEC4, Utils::Type::Uint));
14792 m_test_cases.push_back(testCase(SCALAR_GVEC3, Utils::Type::Uint));
14793 m_test_cases.push_back(testCase(GVEC3_SCALAR, Utils::Type::Uint));
14794 m_test_cases.push_back(testCase(GVEC2_GVEC2, Utils::Type::Uint));
14795 m_test_cases.push_back(testCase(GVEC2_SCALAR_SCALAR, Utils::Type::Uint));
14796 m_test_cases.push_back(testCase(SCALAR_GVEC2_SCALAR, Utils::Type::Uint));
14797 m_test_cases.push_back(testCase(SCALAR_SCALAR_GVEC2, Utils::Type::Uint));
14798 m_test_cases.push_back(testCase(SCALAR_SCALAR_SCALAR_SCALAR, Utils::Type::Uint));
14801 /** Inform that test use components
14807 bool VaryingComponentsTest::useComponentQualifier(glw::GLuint /* test_case_index */)
14812 /** Get length of arrays that should be used during test
14814 * @return 0u - no array at all
14816 GLuint VaryingComponentsTest::getArrayLength()
14821 std::string VaryingComponentsTest::prepareGlobals(GLuint last_in_location, GLuint last_out_location)
14823 std::string globals = VaryingLocationsTest::prepareGlobals(last_in_location, last_out_location);
14825 globals.append("const uint comp_x = 0u;\n"
14826 "const uint comp_y = 1u;\n"
14827 "const uint comp_z = 2u;\n"
14828 "const uint comp_w = 3u;\n");
14836 std::string VaryingComponentsTest::prepareName(const glw::GLchar* name, glw::GLint location, glw::GLint component,
14837 Utils::Shader::STAGES stage, Utils::Variable::STORAGE storage)
14840 std::string result = "PREFIXNAME_lLOCATION_cCOMPONENT";
14841 size_t position = 0;
14842 const GLchar* prefix = Utils::ProgramInterface::GetStagePrefix(stage, storage);
14844 Utils::replaceToken("PREFIX", position, prefix, result);
14845 Utils::replaceToken("NAME", position, name, result);
14847 sprintf(buffer, "%d", location);
14848 Utils::replaceToken("LOCATION", position, buffer, result);
14850 sprintf(buffer, "%d", component);
14851 Utils::replaceToken("COMPONENT", position, buffer, result);
14856 std::string VaryingComponentsTest::prepareQualifiers(const glw::GLchar* location, const glw::GLchar* component,
14857 const glw::GLchar* interpolation)
14859 size_t position = 0;
14860 std::string qualifiers = "layout (location = LOCATION, component = COMPONENT) INTERPOLATION";
14862 Utils::replaceToken("LOCATION", position, location, qualifiers);
14863 Utils::replaceToken("COMPONENT", position, component, qualifiers);
14864 Utils::replaceToken("INTERPOLATION", position, interpolation, qualifiers);
14872 void VaryingComponentsTest::prepareShaderStage(Utils::Shader::STAGES stage, const Utils::Type& vector_type,
14873 Utils::ProgramInterface& program_interface, const testCase& test_case,
14874 Utils::VaryingPassthrough& varying_passthrough)
14876 const GLuint array_length = getArrayLength();
14877 const Utils::Type& basic_type = Utils::Type::GetType(vector_type.m_basic_type, 1 /* n_cols */, 1 /* n_rows */);
14878 descriptor desc_in[8];
14879 descriptor desc_out[8];
14880 const GLuint first_in_loc = 0;
14881 const GLuint first_out_loc = 0;
14882 const GLchar* interpolation = "";
14883 const GLuint last_in_loc = getLastInputLocation(stage, vector_type, array_length);
14884 GLuint last_out_loc = 0;
14886 Utils::ShaderInterface& si = program_interface.GetShaderInterface(stage);
14888 /* Select interpolation */
14889 if ((Utils::Shader::FRAGMENT == stage) || (Utils::Shader::GEOMETRY == stage))
14891 interpolation = " flat";
14894 if (Utils::Shader::FRAGMENT != stage)
14896 last_out_loc = getLastOutputLocation(stage, vector_type, array_length);
14899 switch (test_case.m_layout)
14903 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 4, "gvec4");
14904 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 4, "gvec4");
14906 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 4, "gvec4");
14907 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 4, "gvec4");
14911 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "scalar");
14912 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "scalar");
14913 desc_in[2].assign(1, "comp_y", first_in_loc, "first_input_location", 3, "gvec3");
14914 desc_in[3].assign(1, "comp_y", last_in_loc, "last_input_location", 3, "gvec3");
14916 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "scalar");
14917 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "scalar");
14918 desc_out[2].assign(1, "comp_y", first_out_loc, "first_output_location", 3, "gvec3");
14919 desc_out[3].assign(1, "comp_y", last_out_loc, "last_output_location", 3, "gvec3");
14923 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 3, "gvec3");
14924 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 3, "gvec3");
14925 desc_in[2].assign(3, "comp_w", first_in_loc, "first_input_location", 1, "scalar");
14926 desc_in[3].assign(3, "comp_w", last_in_loc, "last_input_location", 1, "scalar");
14928 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 3, "gvec3");
14929 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 3, "gvec3");
14930 desc_out[2].assign(3, "comp_w", first_out_loc, "first_output_location", 1, "scalar");
14931 desc_out[3].assign(3, "comp_w", last_out_loc, "last_output_location", 1, "scalar");
14935 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 2, "gvec2");
14936 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 2, "gvec2");
14937 desc_in[2].assign(2, "comp_z", first_in_loc, "first_input_location", 2, "gvec2");
14938 desc_in[3].assign(2, "comp_z", last_in_loc, "last_input_location", 2, "gvec2");
14940 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 2, "gvec2");
14941 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 2, "gvec2");
14942 desc_out[2].assign(2, "comp_z", first_out_loc, "first_output_location", 2, "gvec2");
14943 desc_out[3].assign(2, "comp_z", last_out_loc, "last_output_location", 2, "gvec2");
14945 case GVEC2_SCALAR_SCALAR:
14947 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 2, "gvec2");
14948 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 2, "gvec2");
14949 desc_in[2].assign(2, "comp_z", first_in_loc, "first_input_location", 1, "scalar");
14950 desc_in[3].assign(2, "comp_z", last_in_loc, "last_input_location", 1, "scalar");
14951 desc_in[4].assign(3, "comp_w", first_in_loc, "first_input_location", 1, "scalar");
14952 desc_in[5].assign(3, "comp_w", last_in_loc, "last_input_location", 1, "scalar");
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", 1, "scalar");
14957 desc_out[3].assign(2, "comp_z", last_out_loc, "last_output_location", 1, "scalar");
14958 desc_out[4].assign(3, "comp_w", first_out_loc, "first_output_location", 1, "scalar");
14959 desc_out[5].assign(3, "comp_w", last_out_loc, "last_output_location", 1, "scalar");
14961 case SCALAR_GVEC2_SCALAR:
14963 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "scalar");
14964 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "scalar");
14965 desc_in[2].assign(1, "comp_y", first_in_loc, "first_input_location", 2, "gvec2");
14966 desc_in[3].assign(1, "comp_y", last_in_loc, "last_input_location", 2, "gvec2");
14967 desc_in[4].assign(3, "comp_w", first_in_loc, "first_input_location", 1, "scalar");
14968 desc_in[5].assign(3, "comp_w", last_in_loc, "last_input_location", 1, "scalar");
14970 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "scalar");
14971 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "scalar");
14972 desc_out[2].assign(1, "comp_y", first_out_loc, "first_output_location", 2, "gvec2");
14973 desc_out[3].assign(1, "comp_y", last_out_loc, "last_output_location", 2, "gvec2");
14974 desc_out[4].assign(3, "comp_w", first_out_loc, "first_output_location", 1, "scalar");
14975 desc_out[5].assign(3, "comp_w", last_out_loc, "last_output_location", 1, "scalar");
14977 case SCALAR_SCALAR_GVEC2:
14979 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "scalar");
14980 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "scalar");
14981 desc_in[2].assign(1, "comp_y", first_in_loc, "first_input_location", 1, "scalar");
14982 desc_in[3].assign(1, "comp_y", last_in_loc, "last_input_location", 1, "scalar");
14983 desc_in[4].assign(2, "comp_z", first_in_loc, "first_input_location", 2, "gvec2");
14984 desc_in[5].assign(2, "comp_z", last_in_loc, "last_input_location", 2, "gvec2");
14986 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "scalar");
14987 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "scalar");
14988 desc_out[2].assign(1, "comp_y", first_out_loc, "first_output_location", 1, "scalar");
14989 desc_out[3].assign(1, "comp_y", last_out_loc, "last_output_location", 1, "scalar");
14990 desc_out[4].assign(2, "comp_z", first_out_loc, "first_output_location", 2, "gvec2");
14991 desc_out[5].assign(2, "comp_z", last_out_loc, "last_output_location", 2, "gvec2");
14993 case SCALAR_SCALAR_SCALAR_SCALAR:
14995 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "scalar");
14996 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "scalar");
14997 desc_in[2].assign(1, "comp_y", first_in_loc, "first_input_location", 1, "scalar");
14998 desc_in[3].assign(1, "comp_y", last_in_loc, "last_input_location", 1, "scalar");
14999 desc_in[4].assign(2, "comp_z", first_in_loc, "first_input_location", 1, "scalar");
15000 desc_in[5].assign(2, "comp_z", last_in_loc, "last_input_location", 1, "scalar");
15001 desc_in[6].assign(3, "comp_w", first_in_loc, "first_input_location", 1, "scalar");
15002 desc_in[7].assign(3, "comp_w", last_in_loc, "last_input_location", 1, "scalar");
15004 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "scalar");
15005 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "scalar");
15006 desc_out[2].assign(1, "comp_y", first_out_loc, "first_output_location", 1, "scalar");
15007 desc_out[3].assign(1, "comp_y", last_out_loc, "last_output_location", 1, "scalar");
15008 desc_out[4].assign(2, "comp_z", first_out_loc, "first_output_location", 1, "scalar");
15009 desc_out[5].assign(2, "comp_z", last_out_loc, "last_output_location", 1, "scalar");
15010 desc_out[6].assign(3, "comp_w", first_out_loc, "first_output_location", 1, "scalar");
15011 desc_out[7].assign(3, "comp_w", last_out_loc, "last_output_location", 1, "scalar");
15015 for (GLuint i = 0; i < n_desc; ++i)
15017 const descriptor& in_desc = desc_in[i];
15019 Utils::Variable* in =
15020 prepareVarying(basic_type, in_desc, interpolation, si, stage, Utils::Variable::VARYING_INPUT);
15022 if (Utils::Shader::FRAGMENT != stage)
15024 const descriptor& out_desc = desc_out[i];
15026 Utils::Variable* out =
15027 prepareVarying(basic_type, out_desc, interpolation, si, stage, Utils::Variable::VARYING_OUTPUT);
15029 varying_passthrough.Add(stage, in, out);
15033 si.m_globals = prepareGlobals(last_in_loc, last_out_loc);
15039 Utils::Variable* VaryingComponentsTest::prepareVarying(const Utils::Type& basic_type, const descriptor& desc,
15040 const GLchar* interpolation, Utils::ShaderInterface& si,
15041 Utils::Shader::STAGES stage, Utils::Variable::STORAGE storage)
15043 const GLuint array_length = getArrayLength();
15044 const GLuint component_size = basic_type.GetSize();
15045 const std::string& name = prepareName(desc.m_name, desc.m_location, desc.m_component, stage, storage);
15046 const GLuint offset = desc.m_component * component_size;
15047 const std::string& qual = prepareQualifiers(desc.m_location_str, desc.m_component_str, interpolation);
15048 const GLuint size = desc.m_n_rows * component_size;
15049 const Utils::Type& type = Utils::Type::GetType(basic_type.m_basic_type, 1 /* n_columns */, desc.m_n_rows);
15050 Utils::Variable* var = 0;
15052 if (Utils::Variable::VARYING_INPUT == storage)
15054 var = si.Input(name.c_str(), qual.c_str() /* qualifiers */, desc.m_component /* expected_componenet */,
15055 desc.m_location /* expected_location */, type, /* built_in_type */
15056 GL_FALSE /* normalized */, array_length /* n_array_elements */, 0u /* stride */,
15057 offset /* offset */, (GLvoid*)&m_data[offset] /* data */, size /* data_size */);
15061 var = si.Output(name.c_str(), qual.c_str() /* qualifiers */, desc.m_component /* expected_componenet */,
15062 desc.m_location /* expected_location */, type, /* built_in_type */
15063 GL_FALSE /* normalized */, array_length /* n_array_elements */, 0u /* stride */,
15064 offset /* offset */, (GLvoid*)&m_data[offset] /* data */, size /* data_size */);
15070 void VaryingComponentsTest::descriptor::assign(glw::GLint component, const glw::GLchar* component_str,
15071 glw::GLint location, const glw::GLchar* location_str, glw::GLuint n_rows,
15072 const glw::GLchar* name)
15074 m_component = component;
15075 m_component_str = component_str;
15076 m_location = location;
15077 m_location_str = location_str;
15082 VaryingComponentsTest::testCase::testCase(COMPONENTS_LAYOUT layout, Utils::Type::TYPES type)
15083 : m_layout(layout), m_type(type)
15089 * @param context Test framework context
15091 VaryingArrayComponentsTest::VaryingArrayComponentsTest(deqp::Context& context)
15092 : VaryingComponentsTest(context, "varying_array_components",
15093 "Test verifies that input and output components are respected for arrays")
15097 /** Get length of arrays that should be used during test
15101 GLuint VaryingArrayComponentsTest::getArrayLength()
15108 * @param context Test framework context
15110 VaryingExceedingComponentsTest::VaryingExceedingComponentsTest(deqp::Context& context)
15111 : NegativeTestBase(context, "varying_exceeding_components",
15112 "Test verifies that compiler reports error when component qualifier exceed limits")
15116 /** Source for given test case and stage
15118 * @param test_case_index Index of test case
15119 * @param stage Shader stage
15121 * @return Shader source
15123 std::string VaryingExceedingComponentsTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
15125 static const GLchar* var_definition_arr =
15126 "layout (location = 1, component = COMPONENT) flat DIRECTION TYPE gokuARRAY[1];\n";
15127 static const GLchar* var_definition_one =
15128 "layout (location = 1, component = COMPONENT) flat DIRECTION TYPE gokuARRAY;\n";
15129 static const GLchar* input_use_arr = " if (TYPE(0) == gokuINDEX[0])\n"
15131 " result += vec4(1, 0.5, 0.25, 0.125);\n"
15133 static const GLchar* input_use_one = " if (TYPE(0) == gokuINDEX)\n"
15135 " result += vec4(1, 0.5, 0.25, 0.125);\n"
15137 static const GLchar* output_use_arr = " gokuINDEX[0] = TYPE(0);\n"
15138 " if (vec4(0) == result)\n"
15140 " gokuINDEX[0] = TYPE(1);\n"
15142 static const GLchar* output_use_one = " gokuINDEX = TYPE(0);\n"
15143 " if (vec4(0) == result)\n"
15145 " gokuINDEX = TYPE(1);\n"
15147 static const GLchar* fs = "#version 430 core\n"
15148 "#extension GL_ARB_enhanced_layouts : require\n"
15151 "out vec4 fs_out;\n"
15155 " fs_out = gs_fs;\n"
15158 static const GLchar* fs_tested = "#version 430 core\n"
15159 "#extension GL_ARB_enhanced_layouts : require\n"
15164 "out vec4 fs_out;\n"
15168 " vec4 result = gs_fs;\n"
15172 " fs_out += result;\n"
15175 static const GLchar* gs = "#version 430 core\n"
15176 "#extension GL_ARB_enhanced_layouts : require\n"
15178 "layout(points) in;\n"
15179 "layout(triangle_strip, max_vertices = 4) out;\n"
15181 "in vec4 tes_gs[];\n"
15182 "out vec4 gs_fs;\n"
15186 " gs_fs = tes_gs[0];\n"
15187 " gl_Position = vec4(-1, -1, 0, 1);\n"
15189 " gs_fs = tes_gs[0];\n"
15190 " gl_Position = vec4(-1, 1, 0, 1);\n"
15192 " gs_fs = tes_gs[0];\n"
15193 " gl_Position = vec4(1, -1, 0, 1);\n"
15195 " gs_fs = tes_gs[0];\n"
15196 " gl_Position = vec4(1, 1, 0, 1);\n"
15200 static const GLchar* gs_tested = "#version 430 core\n"
15201 "#extension GL_ARB_enhanced_layouts : require\n"
15203 "layout(points) in;\n"
15204 "layout(triangle_strip, max_vertices = 4) out;\n"
15208 "in vec4 tes_gs[];\n"
15209 "out vec4 gs_fs;\n"
15213 " vec4 result = tes_gs[0];\n"
15217 " gs_fs = result;\n"
15218 " gl_Position = vec4(-1, -1, 0, 1);\n"
15220 " gs_fs = result;\n"
15221 " gl_Position = vec4(-1, 1, 0, 1);\n"
15223 " gs_fs = result;\n"
15224 " gl_Position = vec4(1, -1, 0, 1);\n"
15226 " gs_fs = result;\n"
15227 " gl_Position = vec4(1, 1, 0, 1);\n"
15231 static const GLchar* tcs = "#version 430 core\n"
15232 "#extension GL_ARB_enhanced_layouts : require\n"
15234 "layout(vertices = 1) out;\n"
15236 "in vec4 vs_tcs[];\n"
15237 "out vec4 tcs_tes[];\n"
15242 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
15244 " gl_TessLevelOuter[0] = 1.0;\n"
15245 " gl_TessLevelOuter[1] = 1.0;\n"
15246 " gl_TessLevelOuter[2] = 1.0;\n"
15247 " gl_TessLevelOuter[3] = 1.0;\n"
15248 " gl_TessLevelInner[0] = 1.0;\n"
15249 " gl_TessLevelInner[1] = 1.0;\n"
15252 static const GLchar* tcs_tested = "#version 430 core\n"
15253 "#extension GL_ARB_enhanced_layouts : require\n"
15255 "layout(vertices = 1) out;\n"
15259 "in vec4 vs_tcs[];\n"
15260 "out vec4 tcs_tes[];\n"
15264 " vec4 result = vs_tcs[gl_InvocationID];\n"
15268 " tcs_tes[gl_InvocationID] = result;\n"
15270 " gl_TessLevelOuter[0] = 1.0;\n"
15271 " gl_TessLevelOuter[1] = 1.0;\n"
15272 " gl_TessLevelOuter[2] = 1.0;\n"
15273 " gl_TessLevelOuter[3] = 1.0;\n"
15274 " gl_TessLevelInner[0] = 1.0;\n"
15275 " gl_TessLevelInner[1] = 1.0;\n"
15278 static const GLchar* tes = "#version 430 core\n"
15279 "#extension GL_ARB_enhanced_layouts : require\n"
15281 "layout(isolines, point_mode) in;\n"
15283 "in vec4 tcs_tes[];\n"
15284 "out vec4 tes_gs;\n"
15288 " tes_gs = tcs_tes[0];\n"
15291 static const GLchar* tes_tested = "#version 430 core\n"
15292 "#extension GL_ARB_enhanced_layouts : require\n"
15294 "layout(isolines, point_mode) in;\n"
15298 "in vec4 tcs_tes[];\n"
15299 "out vec4 tes_gs;\n"
15303 " vec4 result = tcs_tes[0];\n"
15307 " tes_gs += result;\n"
15310 static const GLchar* vs = "#version 430 core\n"
15311 "#extension GL_ARB_enhanced_layouts : require\n"
15314 "out vec4 vs_tcs;\n"
15318 " vs_tcs = in_vs;\n"
15321 static const GLchar* vs_tested = "#version 430 core\n"
15322 "#extension GL_ARB_enhanced_layouts : require\n"
15327 "out vec4 vs_tcs;\n"
15331 " vec4 result = in_vs;\n"
15335 " vs_tcs += result;\n"
15339 std::string source;
15340 testCase& test_case = m_test_cases[test_case_index];
15342 if (test_case.m_stage == stage)
15344 const GLchar* array = "";
15346 const GLchar* var_definition = 0;
15347 const GLchar* direction = "in ";
15348 const GLchar* index = "";
15349 size_t position = 0;
15351 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
15352 const GLchar* var_use = 0;
15354 if (false == test_case.m_is_input)
15358 if (false == test_case.m_is_array)
15360 var_definition = var_definition_one;
15361 var_use = output_use_one;
15365 var_definition = var_definition_arr;
15366 var_use = output_use_arr;
15371 if (false == test_case.m_is_array)
15373 var_definition = var_definition_one;
15374 var_use = input_use_one;
15378 var_definition = var_definition_arr;
15379 var_use = input_use_arr;
15383 sprintf(buffer, "%d", test_case.m_component);
15387 case Utils::Shader::FRAGMENT:
15388 source = fs_tested;
15390 case Utils::Shader::GEOMETRY:
15391 source = gs_tested;
15395 case Utils::Shader::TESS_CTRL:
15396 source = tcs_tested;
15398 index = "[gl_InvocationID]";
15400 case Utils::Shader::TESS_EVAL:
15401 source = tes_tested;
15405 case Utils::Shader::VERTEX:
15406 source = vs_tested;
15409 TCU_FAIL("Invalid enum");
15413 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
15415 Utils::replaceToken("COMPONENT", position, buffer, source);
15416 Utils::replaceToken("DIRECTION", position, direction, source);
15417 Utils::replaceToken("ARRAY", position, array, source);
15418 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
15420 Utils::replaceAllTokens("TYPE", type_name, source);
15421 Utils::replaceAllTokens("INDEX", index, source);
15427 case Utils::Shader::FRAGMENT:
15430 case Utils::Shader::GEOMETRY:
15433 case Utils::Shader::TESS_CTRL:
15436 case Utils::Shader::TESS_EVAL:
15439 case Utils::Shader::VERTEX:
15443 TCU_FAIL("Invalid enum");
15450 /** Get description of test case
15452 * @param test_case_index Index of test case
15454 * @return Test case description
15456 std::string VaryingExceedingComponentsTest::getTestCaseName(GLuint test_case_index)
15458 std::stringstream stream;
15459 testCase& test_case = m_test_cases[test_case_index];
15461 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
15462 << " type: " << test_case.m_type.GetGLSLTypeName();
15464 if (true == test_case.m_is_array)
15469 stream << ", direction: ";
15471 if (true == test_case.m_is_input)
15477 stream << "output";
15480 stream << ", component: " << test_case.m_component;
15482 return stream.str();
15485 /** Get number of test cases
15487 * @return Number of test cases
15489 GLuint VaryingExceedingComponentsTest::getTestCaseNumber()
15491 return static_cast<GLuint>(m_test_cases.size());
15494 /** Selects if "compute" stage is relevant for test
15500 bool VaryingExceedingComponentsTest::isComputeRelevant(GLuint /* test_case_index */)
15505 /** Prepare all test cases
15508 void VaryingExceedingComponentsTest::testInit()
15510 static const GLuint n_components_per_location = 4;
15511 const GLuint n_types = getTypesNumber();
15513 for (GLuint i = 0; i < n_types; ++i)
15515 const Utils::Type& type = getType(i);
15516 const GLuint n_req_components = type.m_n_rows;
15517 const GLuint valid_component = n_components_per_location - n_req_components;
15518 const GLuint invalid_component = valid_component + 1;
15520 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
15522 if (Utils::Shader::COMPUTE == stage)
15527 /* Component cannot be used for matrices */
15528 if (1 != type.m_n_columns)
15533 testCase test_case_in_arr = { invalid_component, true, true, (Utils::Shader::STAGES)stage, type };
15534 testCase test_case_in_one = { invalid_component, true, false, (Utils::Shader::STAGES)stage, type };
15535 testCase test_case_out_arr = { invalid_component, false, true, (Utils::Shader::STAGES)stage, type };
15536 testCase test_case_out_one = { invalid_component, false, false, (Utils::Shader::STAGES)stage, type };
15538 m_test_cases.push_back(test_case_in_arr);
15539 m_test_cases.push_back(test_case_in_one);
15541 if (Utils::Shader::FRAGMENT != stage)
15543 m_test_cases.push_back(test_case_out_arr);
15544 m_test_cases.push_back(test_case_out_one);
15552 * @param context Test framework context
15554 VaryingComponentWithoutLocationTest::VaryingComponentWithoutLocationTest(deqp::Context& context)
15555 : NegativeTestBase(context, "varying_component_without_location",
15556 "Test verifies that compiler reports error when component qualifier is used without location")
15560 /** Source for given test case and stage
15562 * @param test_case_index Index of test case
15563 * @param stage Shader stage
15565 * @return Shader source
15567 std::string VaryingComponentWithoutLocationTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
15569 static const GLchar* var_definition = "layout (component = COMPONENT) flat DIRECTION TYPE gokuARRAY;\n";
15570 static const GLchar* input_use = " if (TYPE(0) == gokuINDEX)\n"
15572 " result += vec4(1, 0.5, 0.25, 0.125);\n"
15574 static const GLchar* output_use = " gokuINDEX = TYPE(0);\n"
15575 " if (vec4(0) == result)\n"
15577 " gokuINDEX = TYPE(1);\n"
15579 static const GLchar* fs = "#version 430 core\n"
15580 "#extension GL_ARB_enhanced_layouts : require\n"
15583 "out vec4 fs_out;\n"
15587 " fs_out = gs_fs;\n"
15590 static const GLchar* fs_tested = "#version 430 core\n"
15591 "#extension GL_ARB_enhanced_layouts : require\n"
15596 "out vec4 fs_out;\n"
15600 " vec4 result = gs_fs;\n"
15604 " fs_out += result;\n"
15607 static const GLchar* gs = "#version 430 core\n"
15608 "#extension GL_ARB_enhanced_layouts : require\n"
15610 "layout(points) in;\n"
15611 "layout(triangle_strip, max_vertices = 4) out;\n"
15613 "in vec4 tes_gs[];\n"
15614 "out vec4 gs_fs;\n"
15618 " gs_fs = tes_gs[0];\n"
15619 " gl_Position = vec4(-1, -1, 0, 1);\n"
15621 " gs_fs = tes_gs[0];\n"
15622 " gl_Position = vec4(-1, 1, 0, 1);\n"
15624 " gs_fs = tes_gs[0];\n"
15625 " gl_Position = vec4(1, -1, 0, 1);\n"
15627 " gs_fs = tes_gs[0];\n"
15628 " gl_Position = vec4(1, 1, 0, 1);\n"
15632 static const GLchar* gs_tested = "#version 430 core\n"
15633 "#extension GL_ARB_enhanced_layouts : require\n"
15635 "layout(points) in;\n"
15636 "layout(triangle_strip, max_vertices = 4) out;\n"
15640 "in vec4 tes_gs[];\n"
15641 "out vec4 gs_fs;\n"
15645 " vec4 result = tes_gs[0];\n"
15649 " gs_fs = result;\n"
15650 " gl_Position = vec4(-1, -1, 0, 1);\n"
15652 " gs_fs = result;\n"
15653 " gl_Position = vec4(-1, 1, 0, 1);\n"
15655 " gs_fs = result;\n"
15656 " gl_Position = vec4(1, -1, 0, 1);\n"
15658 " gs_fs = result;\n"
15659 " gl_Position = vec4(1, 1, 0, 1);\n"
15663 static const GLchar* tcs = "#version 430 core\n"
15664 "#extension GL_ARB_enhanced_layouts : require\n"
15666 "layout(vertices = 1) out;\n"
15668 "in vec4 vs_tcs[];\n"
15669 "out vec4 tcs_tes[];\n"
15674 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
15676 " gl_TessLevelOuter[0] = 1.0;\n"
15677 " gl_TessLevelOuter[1] = 1.0;\n"
15678 " gl_TessLevelOuter[2] = 1.0;\n"
15679 " gl_TessLevelOuter[3] = 1.0;\n"
15680 " gl_TessLevelInner[0] = 1.0;\n"
15681 " gl_TessLevelInner[1] = 1.0;\n"
15684 static const GLchar* tcs_tested = "#version 430 core\n"
15685 "#extension GL_ARB_enhanced_layouts : require\n"
15687 "layout(vertices = 1) out;\n"
15691 "in vec4 vs_tcs[];\n"
15692 "out vec4 tcs_tes[];\n"
15696 " vec4 result = vs_tcs[gl_InvocationID];\n"
15700 " tcs_tes[gl_InvocationID] = result;\n"
15702 " gl_TessLevelOuter[0] = 1.0;\n"
15703 " gl_TessLevelOuter[1] = 1.0;\n"
15704 " gl_TessLevelOuter[2] = 1.0;\n"
15705 " gl_TessLevelOuter[3] = 1.0;\n"
15706 " gl_TessLevelInner[0] = 1.0;\n"
15707 " gl_TessLevelInner[1] = 1.0;\n"
15710 static const GLchar* tes = "#version 430 core\n"
15711 "#extension GL_ARB_enhanced_layouts : require\n"
15713 "layout(isolines, point_mode) in;\n"
15715 "in vec4 tcs_tes[];\n"
15716 "out vec4 tes_gs;\n"
15720 " tes_gs = tcs_tes[0];\n"
15723 static const GLchar* tes_tested = "#version 430 core\n"
15724 "#extension GL_ARB_enhanced_layouts : require\n"
15726 "layout(isolines, point_mode) in;\n"
15730 "in vec4 tcs_tes[];\n"
15731 "out vec4 tes_gs;\n"
15735 " vec4 result = tcs_tes[0];\n"
15739 " tes_gs += result;\n"
15742 static const GLchar* vs = "#version 430 core\n"
15743 "#extension GL_ARB_enhanced_layouts : require\n"
15746 "out vec4 vs_tcs;\n"
15750 " vs_tcs = in_vs;\n"
15753 static const GLchar* vs_tested = "#version 430 core\n"
15754 "#extension GL_ARB_enhanced_layouts : require\n"
15759 "out vec4 vs_tcs;\n"
15763 " vec4 result = in_vs;\n"
15767 " vs_tcs += result;\n"
15771 std::string source;
15772 testCase& test_case = m_test_cases[test_case_index];
15774 if (test_case.m_stage == stage)
15776 const GLchar* array = "";
15778 const GLchar* direction = "in ";
15779 const GLchar* index = "";
15780 size_t position = 0;
15782 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
15783 const GLchar* var_use = input_use;
15785 if (false == test_case.m_is_input)
15788 var_use = output_use;
15791 sprintf(buffer, "%d", test_case.m_component);
15795 case Utils::Shader::FRAGMENT:
15796 source = fs_tested;
15798 case Utils::Shader::GEOMETRY:
15799 source = gs_tested;
15803 case Utils::Shader::TESS_CTRL:
15804 source = tcs_tested;
15806 index = "[gl_InvocationID]";
15808 case Utils::Shader::TESS_EVAL:
15809 source = tes_tested;
15813 case Utils::Shader::VERTEX:
15814 source = vs_tested;
15817 TCU_FAIL("Invalid enum");
15821 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
15823 Utils::replaceToken("COMPONENT", position, buffer, source);
15824 Utils::replaceToken("DIRECTION", position, direction, source);
15825 Utils::replaceToken("ARRAY", position, array, source);
15826 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
15828 Utils::replaceAllTokens("TYPE", type_name, source);
15829 Utils::replaceAllTokens("INDEX", index, source);
15835 case Utils::Shader::FRAGMENT:
15838 case Utils::Shader::GEOMETRY:
15841 case Utils::Shader::TESS_CTRL:
15844 case Utils::Shader::TESS_EVAL:
15847 case Utils::Shader::VERTEX:
15851 TCU_FAIL("Invalid enum");
15858 /** Get description of test case
15860 * @param test_case_index Index of test case
15862 * @return Test case description
15864 std::string VaryingComponentWithoutLocationTest::getTestCaseName(GLuint test_case_index)
15866 std::stringstream stream;
15867 testCase& test_case = m_test_cases[test_case_index];
15869 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
15870 << " type: " << test_case.m_type.GetGLSLTypeName() << ", direction: ";
15872 if (true == test_case.m_is_input)
15878 stream << "output";
15881 stream << ", component: " << test_case.m_component;
15883 return stream.str();
15886 /** Get number of test cases
15888 * @return Number of test cases
15890 GLuint VaryingComponentWithoutLocationTest::getTestCaseNumber()
15892 return static_cast<GLuint>(m_test_cases.size());
15895 /** Selects if "compute" stage is relevant for test
15901 bool VaryingComponentWithoutLocationTest::isComputeRelevant(GLuint /* test_case_index */)
15906 /** Prepare all test cases
15909 void VaryingComponentWithoutLocationTest::testInit()
15911 static const GLuint n_components_per_location = 4;
15912 const GLuint n_types = getTypesNumber();
15914 for (GLuint i = 0; i < n_types; ++i)
15916 const Utils::Type& type = getType(i);
15917 const GLuint n_req_components = type.m_n_rows;
15918 const GLuint valid_component = n_components_per_location - n_req_components;
15920 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
15922 if (Utils::Shader::COMPUTE == stage)
15927 /* Component cannot be used for matrices */
15928 if (1 != type.m_n_columns)
15933 testCase test_case_in = { valid_component, true, (Utils::Shader::STAGES)stage, type };
15934 testCase test_case_out = { valid_component, false, (Utils::Shader::STAGES)stage, type };
15936 m_test_cases.push_back(test_case_in);
15938 if (Utils::Shader::FRAGMENT != stage)
15940 m_test_cases.push_back(test_case_out);
15948 * @param context Test framework context
15950 VaryingComponentOfInvalidTypeTest::VaryingComponentOfInvalidTypeTest(deqp::Context& context)
15951 : NegativeTestBase(context, "varying_component_of_invalid_type",
15952 "Test verifies that compiler reports error when component qualifier is used for invalid type")
15956 /** Source for given test case and stage
15958 * @param test_case_index Index of test case
15959 * @param stage Shader stage
15961 * @return Shader source
15963 std::string VaryingComponentOfInvalidTypeTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
15965 static const GLchar* block_definition_arr = "layout (location = 1, component = COMPONENT) flat DIRECTION Goku {\n"
15967 "} gokuARRAY[1];\n";
15968 static const GLchar* block_definition_one = "layout (location = 1, component = COMPONENT) flat DIRECTION Goku {\n"
15971 static const GLchar* matrix_definition_arr =
15972 "layout (location = 1, component = COMPONENT) flat DIRECTION TYPE gokuARRAY[1];\n";
15973 static const GLchar* matrix_definition_one =
15974 "layout (location = 1, component = COMPONENT) flat DIRECTION TYPE gokuARRAY;\n";
15975 static const GLchar* struct_definition_arr =
15980 "layout (location = 1, component = COMPONENT) flat DIRECTION Goku gokuARRAY[1];\n";
15981 static const GLchar* struct_definition_one =
15986 "layout (location = 1, component = COMPONENT) flat DIRECTION Goku gokuARRAY;\n";
15987 static const GLchar* matrix_input_use_arr = " if (TYPE(0) == gokuINDEX[0])\n"
15989 " result += vec4(1, 0.5, 0.25, 0.125);\n"
15991 static const GLchar* matrix_input_use_one = " if (TYPE(0) == gokuINDEX)\n"
15993 " result += vec4(1, 0.5, 0.25, 0.125);\n"
15995 static const GLchar* matrix_output_use_arr = " gokuINDEX[0] = TYPE(0);\n"
15996 " if (vec4(0) == result)\n"
15998 " gokuINDEX[0] = TYPE(1);\n"
16000 static const GLchar* matrix_output_use_one = " gokuINDEX = TYPE(0);\n"
16001 " if (vec4(0) == result)\n"
16003 " gokuINDEX = TYPE(1);\n"
16005 static const GLchar* member_input_use_arr = " if (TYPE(0) == gokuINDEX[0].member)\n"
16007 " result += vec4(1, 0.5, 0.25, 0.125);\n"
16009 static const GLchar* member_input_use_one = " if (TYPE(0) == gokuINDEX.member)\n"
16011 " result += vec4(1, 0.5, 0.25, 0.125);\n"
16013 static const GLchar* member_output_use_arr = " gokuINDEX[0].member = TYPE(0);\n"
16014 " if (vec4(0) == result)\n"
16016 " gokuINDEX[0].member = TYPE(1);\n"
16018 static const GLchar* member_output_use_one = " gokuINDEX.member = TYPE(0);\n"
16019 " if (vec4(0) == result)\n"
16021 " gokuINDEX.member = TYPE(1);\n"
16023 static const GLchar* fs = "#version 430 core\n"
16024 "#extension GL_ARB_enhanced_layouts : require\n"
16027 "out vec4 fs_out;\n"
16031 " fs_out = gs_fs;\n"
16034 static const GLchar* fs_tested = "#version 430 core\n"
16035 "#extension GL_ARB_enhanced_layouts : require\n"
16040 "out vec4 fs_out;\n"
16044 " vec4 result = gs_fs;\n"
16048 " fs_out += result;\n"
16051 static const GLchar* gs = "#version 430 core\n"
16052 "#extension GL_ARB_enhanced_layouts : require\n"
16054 "layout(points) in;\n"
16055 "layout(triangle_strip, max_vertices = 4) out;\n"
16057 "in vec4 tes_gs[];\n"
16058 "out vec4 gs_fs;\n"
16062 " gs_fs = tes_gs[0];\n"
16063 " gl_Position = vec4(-1, -1, 0, 1);\n"
16065 " gs_fs = tes_gs[0];\n"
16066 " gl_Position = vec4(-1, 1, 0, 1);\n"
16068 " gs_fs = tes_gs[0];\n"
16069 " gl_Position = vec4(1, -1, 0, 1);\n"
16071 " gs_fs = tes_gs[0];\n"
16072 " gl_Position = vec4(1, 1, 0, 1);\n"
16076 static const GLchar* gs_tested = "#version 430 core\n"
16077 "#extension GL_ARB_enhanced_layouts : require\n"
16079 "layout(points) in;\n"
16080 "layout(triangle_strip, max_vertices = 4) out;\n"
16084 "in vec4 tes_gs[];\n"
16085 "out vec4 gs_fs;\n"
16089 " vec4 result = tes_gs[0];\n"
16093 " gs_fs = result;\n"
16094 " gl_Position = vec4(-1, -1, 0, 1);\n"
16096 " gs_fs = result;\n"
16097 " gl_Position = vec4(-1, 1, 0, 1);\n"
16099 " gs_fs = result;\n"
16100 " gl_Position = vec4(1, -1, 0, 1);\n"
16102 " gs_fs = result;\n"
16103 " gl_Position = vec4(1, 1, 0, 1);\n"
16107 static const GLchar* tcs = "#version 430 core\n"
16108 "#extension GL_ARB_enhanced_layouts : require\n"
16110 "layout(vertices = 1) out;\n"
16112 "in vec4 vs_tcs[];\n"
16113 "out vec4 tcs_tes[];\n"
16118 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
16120 " gl_TessLevelOuter[0] = 1.0;\n"
16121 " gl_TessLevelOuter[1] = 1.0;\n"
16122 " gl_TessLevelOuter[2] = 1.0;\n"
16123 " gl_TessLevelOuter[3] = 1.0;\n"
16124 " gl_TessLevelInner[0] = 1.0;\n"
16125 " gl_TessLevelInner[1] = 1.0;\n"
16128 static const GLchar* tcs_tested = "#version 430 core\n"
16129 "#extension GL_ARB_enhanced_layouts : require\n"
16131 "layout(vertices = 1) out;\n"
16135 "in vec4 vs_tcs[];\n"
16136 "out vec4 tcs_tes[];\n"
16140 " vec4 result = vs_tcs[gl_InvocationID];\n"
16144 " tcs_tes[gl_InvocationID] = result;\n"
16146 " gl_TessLevelOuter[0] = 1.0;\n"
16147 " gl_TessLevelOuter[1] = 1.0;\n"
16148 " gl_TessLevelOuter[2] = 1.0;\n"
16149 " gl_TessLevelOuter[3] = 1.0;\n"
16150 " gl_TessLevelInner[0] = 1.0;\n"
16151 " gl_TessLevelInner[1] = 1.0;\n"
16154 static const GLchar* tes = "#version 430 core\n"
16155 "#extension GL_ARB_enhanced_layouts : require\n"
16157 "layout(isolines, point_mode) in;\n"
16159 "in vec4 tcs_tes[];\n"
16160 "out vec4 tes_gs;\n"
16164 " tes_gs = tcs_tes[0];\n"
16167 static const GLchar* tes_tested = "#version 430 core\n"
16168 "#extension GL_ARB_enhanced_layouts : require\n"
16170 "layout(isolines, point_mode) in;\n"
16174 "in vec4 tcs_tes[];\n"
16175 "out vec4 tes_gs;\n"
16179 " vec4 result = tcs_tes[0];\n"
16183 " tes_gs += result;\n"
16186 static const GLchar* vs = "#version 430 core\n"
16187 "#extension GL_ARB_enhanced_layouts : require\n"
16190 "out vec4 vs_tcs;\n"
16194 " vs_tcs = in_vs;\n"
16197 static const GLchar* vs_tested = "#version 430 core\n"
16198 "#extension GL_ARB_enhanced_layouts : require\n"
16203 "out vec4 vs_tcs;\n"
16207 " vec4 result = in_vs;\n"
16211 " vs_tcs += result;\n"
16215 std::string source;
16216 testCase& test_case = m_test_cases[test_case_index];
16218 if (test_case.m_stage == stage)
16220 const GLchar* array = "";
16222 const GLchar* var_definition = 0;
16223 const GLchar* direction = "in ";
16224 const GLchar* index = "";
16225 size_t position = 0;
16227 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
16228 const GLchar* var_use = 0;
16230 if (false == test_case.m_is_input)
16234 if (false == test_case.m_is_array)
16236 switch (test_case.m_case)
16239 var_definition = block_definition_one;
16240 var_use = member_output_use_one;
16243 var_definition = matrix_definition_one;
16244 var_use = matrix_output_use_one;
16247 var_definition = struct_definition_one;
16248 var_use = member_output_use_one;
16251 TCU_FAIL("Invalid enum");
16256 switch (test_case.m_case)
16259 var_definition = block_definition_arr;
16260 var_use = member_output_use_arr;
16263 var_definition = matrix_definition_arr;
16264 var_use = matrix_output_use_arr;
16267 var_definition = struct_definition_arr;
16268 var_use = member_output_use_arr;
16271 TCU_FAIL("Invalid enum");
16277 if (false == test_case.m_is_array)
16279 switch (test_case.m_case)
16282 var_definition = block_definition_one;
16283 var_use = member_input_use_one;
16286 var_definition = matrix_definition_one;
16287 var_use = matrix_input_use_one;
16290 var_definition = struct_definition_one;
16291 var_use = member_input_use_one;
16294 TCU_FAIL("Invalid enum");
16299 switch (test_case.m_case)
16302 var_definition = block_definition_arr;
16303 var_use = member_input_use_arr;
16306 var_definition = matrix_definition_arr;
16307 var_use = matrix_input_use_arr;
16310 var_definition = struct_definition_arr;
16311 var_use = member_input_use_arr;
16314 TCU_FAIL("Invalid enum");
16319 sprintf(buffer, "%d", test_case.m_component);
16323 case Utils::Shader::FRAGMENT:
16324 source = fs_tested;
16326 case Utils::Shader::GEOMETRY:
16327 source = gs_tested;
16331 case Utils::Shader::TESS_CTRL:
16332 source = tcs_tested;
16334 index = "[gl_InvocationID]";
16336 case Utils::Shader::TESS_EVAL:
16337 source = tes_tested;
16341 case Utils::Shader::VERTEX:
16342 source = vs_tested;
16345 TCU_FAIL("Invalid enum");
16349 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
16351 Utils::replaceToken("COMPONENT", position, buffer, source);
16352 Utils::replaceToken("DIRECTION", position, direction, source);
16353 Utils::replaceToken("ARRAY", position, array, source);
16354 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
16356 Utils::replaceAllTokens("TYPE", type_name, source);
16357 Utils::replaceAllTokens("INDEX", index, source);
16363 case Utils::Shader::FRAGMENT:
16366 case Utils::Shader::GEOMETRY:
16369 case Utils::Shader::TESS_CTRL:
16372 case Utils::Shader::TESS_EVAL:
16375 case Utils::Shader::VERTEX:
16379 TCU_FAIL("Invalid enum");
16386 /** Get description of test case
16388 * @param test_case_index Index of test case
16390 * @return Test case description
16392 std::string VaryingComponentOfInvalidTypeTest::getTestCaseName(GLuint test_case_index)
16394 std::stringstream stream;
16395 testCase& test_case = m_test_cases[test_case_index];
16397 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
16398 << " type: " << test_case.m_type.GetGLSLTypeName();
16400 if (true == test_case.m_is_array)
16405 stream << ", direction: ";
16407 if (true == test_case.m_is_input)
16413 stream << "output";
16416 stream << ", component: " << test_case.m_component;
16418 return stream.str();
16421 /** Get number of test cases
16423 * @return Number of test cases
16425 GLuint VaryingComponentOfInvalidTypeTest::getTestCaseNumber()
16427 return static_cast<GLuint>(m_test_cases.size());
16430 /** Selects if "compute" stage is relevant for test
16436 bool VaryingComponentOfInvalidTypeTest::isComputeRelevant(GLuint /* test_case_index */)
16441 /** Prepare all test cases
16444 void VaryingComponentOfInvalidTypeTest::testInit()
16446 static const GLuint n_components_per_location = 4;
16447 const GLuint n_types = getTypesNumber();
16449 for (GLuint i = 0; i < n_types; ++i)
16451 const Utils::Type& type = getType(i);
16452 const GLuint n_req_components = type.m_n_rows;
16453 const GLuint valid_component = n_components_per_location - n_req_components;
16455 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
16457 if (Utils::Shader::COMPUTE == stage)
16462 /* Use different CASE for matrices */
16463 if (1 != type.m_n_columns)
16465 testCase test_case_in_arr = { MATRIX, valid_component, true, true, (Utils::Shader::STAGES)stage, type };
16466 testCase test_case_in_one = {
16467 MATRIX, valid_component, false, true, (Utils::Shader::STAGES)stage, type
16469 testCase test_case_out_arr = {
16470 MATRIX, valid_component, true, false, (Utils::Shader::STAGES)stage, type
16472 testCase test_case_out_one = {
16473 MATRIX, valid_component, false, false, (Utils::Shader::STAGES)stage, type
16476 m_test_cases.push_back(test_case_in_arr);
16477 m_test_cases.push_back(test_case_in_one);
16479 if (Utils::Shader::FRAGMENT != stage)
16481 m_test_cases.push_back(test_case_out_arr);
16482 m_test_cases.push_back(test_case_out_one);
16487 for (GLuint c = BLOCK; c < MAX_CASES; ++c)
16489 testCase test_case_in_arr = { (CASES)c, valid_component, true, true, (Utils::Shader::STAGES)stage,
16491 testCase test_case_in_one = { (CASES)c, valid_component, false, true, (Utils::Shader::STAGES)stage,
16493 testCase test_case_out_arr = { (CASES)c, valid_component, true, false, (Utils::Shader::STAGES)stage,
16495 testCase test_case_out_one = {
16496 (CASES)c, valid_component, false, false, (Utils::Shader::STAGES)stage, type
16499 if (Utils::Shader::VERTEX != stage)
16501 m_test_cases.push_back(test_case_in_arr);
16502 m_test_cases.push_back(test_case_in_one);
16505 if (Utils::Shader::FRAGMENT != stage)
16507 m_test_cases.push_back(test_case_out_arr);
16508 m_test_cases.push_back(test_case_out_one);
16518 * @param context Test framework context
16520 InputComponentAliasingTest::InputComponentAliasingTest(deqp::Context& context)
16521 : NegativeTestBase(context, "input_component_aliasing",
16522 "Test verifies that compiler reports component aliasing as error")
16526 /** Source for given test case and stage
16528 * @param test_case_index Index of test case
16529 * @param stage Shader stage
16531 * @return Shader source
16533 std::string InputComponentAliasingTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
16535 static const GLchar* var_definition = "layout (location = 1, component = COMPONENT) FLAT in TYPE gohanARRAY;\n"
16536 "layout (location = 1, component = COMPONENT) FLAT in TYPE gotenARRAY;\n";
16537 static const GLchar* test_one = " if (TYPE(0) == gohanINDEX)\n"
16539 " result += vec4(1, 0.5, 0.25, 0.125);\n"
16541 static const GLchar* test_both = " if (TYPE(0) == gohanINDEX)\n"
16543 " result = vec4(goten.xxxx);\n"
16545 static const GLchar* fs = "#version 430 core\n"
16546 "#extension GL_ARB_enhanced_layouts : require\n"
16549 "out vec4 fs_out;\n"
16553 " fs_out = gs_fs;\n"
16556 static const GLchar* fs_tested = "#version 430 core\n"
16557 "#extension GL_ARB_enhanced_layouts : require\n"
16562 "out vec4 fs_out;\n"
16566 " vec4 result = gs_fs;\n"
16570 " fs_out += result;\n"
16573 static const GLchar* gs = "#version 430 core\n"
16574 "#extension GL_ARB_enhanced_layouts : require\n"
16576 "layout(points) in;\n"
16577 "layout(triangle_strip, max_vertices = 4) out;\n"
16579 "in vec4 tes_gs[];\n"
16580 "out vec4 gs_fs;\n"
16584 " gs_fs = tes_gs[0];\n"
16585 " gl_Position = vec4(-1, -1, 0, 1);\n"
16587 " gs_fs = tes_gs[0];\n"
16588 " gl_Position = vec4(-1, 1, 0, 1);\n"
16590 " gs_fs = tes_gs[0];\n"
16591 " gl_Position = vec4(1, -1, 0, 1);\n"
16593 " gs_fs = tes_gs[0];\n"
16594 " gl_Position = vec4(1, 1, 0, 1);\n"
16598 static const GLchar* gs_tested = "#version 430 core\n"
16599 "#extension GL_ARB_enhanced_layouts : require\n"
16601 "layout(points) in;\n"
16602 "layout(triangle_strip, max_vertices = 4) out;\n"
16606 "in vec4 tes_gs[];\n"
16607 "out vec4 gs_fs;\n"
16611 " vec4 result = tes_gs[0];\n"
16615 " gs_fs = result;\n"
16616 " gl_Position = vec4(-1, -1, 0, 1);\n"
16618 " gs_fs = result;\n"
16619 " gl_Position = vec4(-1, 1, 0, 1);\n"
16621 " gs_fs = result;\n"
16622 " gl_Position = vec4(1, -1, 0, 1);\n"
16624 " gs_fs = result;\n"
16625 " gl_Position = vec4(1, 1, 0, 1);\n"
16629 static const GLchar* tcs = "#version 430 core\n"
16630 "#extension GL_ARB_enhanced_layouts : require\n"
16632 "layout(vertices = 1) out;\n"
16634 "in vec4 vs_tcs[];\n"
16635 "out vec4 tcs_tes[];\n"
16640 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
16642 " gl_TessLevelOuter[0] = 1.0;\n"
16643 " gl_TessLevelOuter[1] = 1.0;\n"
16644 " gl_TessLevelOuter[2] = 1.0;\n"
16645 " gl_TessLevelOuter[3] = 1.0;\n"
16646 " gl_TessLevelInner[0] = 1.0;\n"
16647 " gl_TessLevelInner[1] = 1.0;\n"
16650 static const GLchar* tcs_tested = "#version 430 core\n"
16651 "#extension GL_ARB_enhanced_layouts : require\n"
16653 "layout(vertices = 1) out;\n"
16657 "in vec4 vs_tcs[];\n"
16658 "out vec4 tcs_tes[];\n"
16662 " vec4 result = vs_tcs[gl_InvocationID];\n"
16666 " tcs_tes[gl_InvocationID] = result;\n"
16668 " gl_TessLevelOuter[0] = 1.0;\n"
16669 " gl_TessLevelOuter[1] = 1.0;\n"
16670 " gl_TessLevelOuter[2] = 1.0;\n"
16671 " gl_TessLevelOuter[3] = 1.0;\n"
16672 " gl_TessLevelInner[0] = 1.0;\n"
16673 " gl_TessLevelInner[1] = 1.0;\n"
16676 static const GLchar* tes = "#version 430 core\n"
16677 "#extension GL_ARB_enhanced_layouts : require\n"
16679 "layout(isolines, point_mode) in;\n"
16681 "in vec4 tcs_tes[];\n"
16682 "out vec4 tes_gs;\n"
16686 " tes_gs = tcs_tes[0];\n"
16689 static const GLchar* tes_tested = "#version 430 core\n"
16690 "#extension GL_ARB_enhanced_layouts : require\n"
16692 "layout(isolines, point_mode) in;\n"
16696 "in vec4 tcs_tes[];\n"
16697 "out vec4 tes_gs;\n"
16701 " vec4 result = tcs_tes[0];\n"
16705 " tes_gs += result;\n"
16708 static const GLchar* vs = "#version 430 core\n"
16709 "#extension GL_ARB_enhanced_layouts : require\n"
16712 "out vec4 vs_tcs;\n"
16716 " vs_tcs = in_vs;\n"
16719 static const GLchar* vs_tested = "#version 430 core\n"
16720 "#extension GL_ARB_enhanced_layouts : require\n"
16725 "out vec4 vs_tcs;\n"
16729 " vec4 result = in_vs;\n"
16733 " vs_tcs += result;\n"
16737 std::string source;
16738 testCase& test_case = m_test_cases[test_case_index];
16740 if (test_case.m_stage == stage)
16742 const GLchar* array = "";
16743 GLchar buffer_gohan[16];
16744 GLchar buffer_goten[16];
16745 const GLchar* flat = "";
16746 const GLchar* index = "";
16747 const bool is_flat_req = isFlatRequired(stage, test_case.m_type, Utils::Variable::VARYING_INPUT);
16748 size_t position = 0;
16750 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
16751 const GLchar* var_use = test_one;
16753 if (true == test_case.m_use_both)
16755 var_use = test_both;
16758 if (true == is_flat_req)
16763 sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
16764 sprintf(buffer_goten, "%d", test_case.m_component_goten);
16768 case Utils::Shader::FRAGMENT:
16769 source = fs_tested;
16771 case Utils::Shader::GEOMETRY:
16772 source = gs_tested;
16776 case Utils::Shader::TESS_CTRL:
16777 source = tcs_tested;
16779 index = "[gl_InvocationID]";
16781 case Utils::Shader::TESS_EVAL:
16782 source = tes_tested;
16786 case Utils::Shader::VERTEX:
16787 source = vs_tested;
16790 TCU_FAIL("Invalid enum");
16794 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
16796 Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
16797 Utils::replaceToken("ARRAY", position, array, source);
16798 Utils::replaceToken("COMPONENT", position, buffer_goten, source);
16799 Utils::replaceToken("ARRAY", position, array, source);
16800 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
16802 Utils::replaceAllTokens("FLAT", flat, source);
16803 Utils::replaceAllTokens("TYPE", type_name, source);
16804 Utils::replaceAllTokens("INDEX", index, source);
16810 case Utils::Shader::FRAGMENT:
16813 case Utils::Shader::GEOMETRY:
16816 case Utils::Shader::TESS_CTRL:
16819 case Utils::Shader::TESS_EVAL:
16822 case Utils::Shader::VERTEX:
16826 TCU_FAIL("Invalid enum");
16833 /** Get description of test case
16835 * @param test_case_index Index of test case
16837 * @return Test case description
16839 std::string InputComponentAliasingTest::getTestCaseName(GLuint test_case_index)
16841 std::stringstream stream;
16842 testCase& test_case = m_test_cases[test_case_index];
16844 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
16845 << " type: " << test_case.m_type.GetGLSLTypeName() << ", components: " << test_case.m_component_gohan
16846 << " & " << test_case.m_component_goten;
16848 return stream.str();
16851 /** Get number of test cases
16853 * @return Number of test cases
16855 GLuint InputComponentAliasingTest::getTestCaseNumber()
16857 return static_cast<GLuint>(m_test_cases.size());
16860 /** Selects if "compute" stage is relevant for test
16866 bool InputComponentAliasingTest::isComputeRelevant(GLuint /* test_case_index */)
16871 /** Selects if compilation failure is expected result
16873 * @param test_case_index Index of test case
16875 * @return false for VS that use only single variable, true otherwise
16877 bool InputComponentAliasingTest::isFailureExpected(GLuint test_case_index)
16879 testCase& test_case = m_test_cases[test_case_index];
16881 return !((Utils::Shader::VERTEX == test_case.m_stage) && (false == test_case.m_use_both));
16884 /** Prepare all test cases
16887 void InputComponentAliasingTest::testInit()
16889 static const GLuint n_components_per_location = 4;
16890 const GLuint n_types = getTypesNumber();
16892 for (GLuint i = 0; i < n_types; ++i)
16894 const Utils::Type& type = getType(i);
16895 const GLuint n_req_components = type.m_n_rows;
16896 const GLuint valid_component = n_components_per_location - n_req_components;
16898 /* Skip matrices */
16899 if (1 != type.m_n_columns)
16904 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
16906 if (Utils::Shader::COMPUTE == stage)
16911 for (GLuint gohan = 0; gohan <= valid_component; ++gohan)
16913 const GLint first_aliasing = gohan - n_req_components + 1;
16914 const GLint last_aliasing = gohan + n_req_components - 1;
16916 const GLuint goten_start = std::max(0, first_aliasing);
16917 const GLuint goten_stop = std::min((GLint)valid_component, last_aliasing);
16919 for (GLuint goten = goten_start; goten <= goten_stop; ++goten)
16921 testCase test_case = { gohan, goten, (Utils::Shader::STAGES)stage, type, false };
16923 m_test_cases.push_back(test_case);
16925 if (Utils::Shader::VERTEX == test_case.m_stage)
16927 test_case.m_use_both = true;
16929 m_test_cases.push_back(test_case);
16939 * @param context Test framework context
16941 OutputComponentAliasingTest::OutputComponentAliasingTest(deqp::Context& context)
16942 : NegativeTestBase(context, "output_component_aliasing",
16943 "Test verifies that compiler reports component aliasing as error")
16947 /** Source for given test case and stage
16949 * @param test_case_index Index of test case
16950 * @param stage Shader stage
16952 * @return Shader source
16954 std::string OutputComponentAliasingTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
16956 static const GLchar* var_definition = "layout (location = 1, component = COMPONENT) flat out TYPE gohanARRAY;\n"
16957 "layout (location = 1, component = COMPONENT) flat out TYPE gotenARRAY;\n";
16958 static const GLchar* l_test = " gohanINDEX = TYPE(1);\n"
16959 " gotenINDEX = TYPE(0);\n";
16960 static const GLchar* fs = "#version 430 core\n"
16961 "#extension GL_ARB_enhanced_layouts : require\n"
16964 "out vec4 fs_out;\n"
16968 " fs_out = gs_fs;\n"
16971 static const GLchar* fs_tested = "#version 430 core\n"
16972 "#extension GL_ARB_enhanced_layouts : require\n"
16977 "out vec4 fs_out;\n"
16981 " vec4 result = gs_fs;\n"
16985 " fs_out += result;\n"
16988 static const GLchar* gs = "#version 430 core\n"
16989 "#extension GL_ARB_enhanced_layouts : require\n"
16991 "layout(points) in;\n"
16992 "layout(triangle_strip, max_vertices = 4) out;\n"
16994 "in vec4 tes_gs[];\n"
16995 "out vec4 gs_fs;\n"
16999 " gs_fs = tes_gs[0];\n"
17000 " gl_Position = vec4(-1, -1, 0, 1);\n"
17002 " gs_fs = tes_gs[0];\n"
17003 " gl_Position = vec4(-1, 1, 0, 1);\n"
17005 " gs_fs = tes_gs[0];\n"
17006 " gl_Position = vec4(1, -1, 0, 1);\n"
17008 " gs_fs = tes_gs[0];\n"
17009 " gl_Position = vec4(1, 1, 0, 1);\n"
17013 static const GLchar* gs_tested = "#version 430 core\n"
17014 "#extension GL_ARB_enhanced_layouts : require\n"
17016 "layout(points) in;\n"
17017 "layout(triangle_strip, max_vertices = 4) out;\n"
17021 "in vec4 tes_gs[];\n"
17022 "out vec4 gs_fs;\n"
17026 " vec4 result = tes_gs[0];\n"
17030 " gs_fs = result;\n"
17031 " gl_Position = vec4(-1, -1, 0, 1);\n"
17033 " gs_fs = result;\n"
17034 " gl_Position = vec4(-1, 1, 0, 1);\n"
17036 " gs_fs = result;\n"
17037 " gl_Position = vec4(1, -1, 0, 1);\n"
17039 " gs_fs = result;\n"
17040 " gl_Position = vec4(1, 1, 0, 1);\n"
17044 static const GLchar* tcs = "#version 430 core\n"
17045 "#extension GL_ARB_enhanced_layouts : require\n"
17047 "layout(vertices = 1) out;\n"
17049 "in vec4 vs_tcs[];\n"
17050 "out vec4 tcs_tes[];\n"
17055 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
17057 " gl_TessLevelOuter[0] = 1.0;\n"
17058 " gl_TessLevelOuter[1] = 1.0;\n"
17059 " gl_TessLevelOuter[2] = 1.0;\n"
17060 " gl_TessLevelOuter[3] = 1.0;\n"
17061 " gl_TessLevelInner[0] = 1.0;\n"
17062 " gl_TessLevelInner[1] = 1.0;\n"
17065 static const GLchar* tcs_tested = "#version 430 core\n"
17066 "#extension GL_ARB_enhanced_layouts : require\n"
17068 "layout(vertices = 1) out;\n"
17072 "in vec4 vs_tcs[];\n"
17073 "out vec4 tcs_tes[];\n"
17077 " vec4 result = vs_tcs[gl_InvocationID];\n"
17081 " tcs_tes[gl_InvocationID] = result;\n"
17083 " gl_TessLevelOuter[0] = 1.0;\n"
17084 " gl_TessLevelOuter[1] = 1.0;\n"
17085 " gl_TessLevelOuter[2] = 1.0;\n"
17086 " gl_TessLevelOuter[3] = 1.0;\n"
17087 " gl_TessLevelInner[0] = 1.0;\n"
17088 " gl_TessLevelInner[1] = 1.0;\n"
17091 static const GLchar* tes = "#version 430 core\n"
17092 "#extension GL_ARB_enhanced_layouts : require\n"
17094 "layout(isolines, point_mode) in;\n"
17096 "in vec4 tcs_tes[];\n"
17097 "out vec4 tes_gs;\n"
17101 " tes_gs = tcs_tes[0];\n"
17104 static const GLchar* tes_tested = "#version 430 core\n"
17105 "#extension GL_ARB_enhanced_layouts : require\n"
17107 "layout(isolines, point_mode) in;\n"
17111 "in vec4 tcs_tes[];\n"
17112 "out vec4 tes_gs;\n"
17116 " vec4 result = tcs_tes[0];\n"
17120 " tes_gs += result;\n"
17123 static const GLchar* vs = "#version 430 core\n"
17124 "#extension GL_ARB_enhanced_layouts : require\n"
17127 "out vec4 vs_tcs;\n"
17131 " vs_tcs = in_vs;\n"
17134 static const GLchar* vs_tested = "#version 430 core\n"
17135 "#extension GL_ARB_enhanced_layouts : require\n"
17140 "out vec4 vs_tcs;\n"
17144 " vec4 result = in_vs;\n"
17148 " vs_tcs += result;\n"
17152 std::string source;
17153 testCase& test_case = m_test_cases[test_case_index];
17155 if (test_case.m_stage == stage)
17157 const GLchar* array = "";
17158 GLchar buffer_gohan[16];
17159 GLchar buffer_goten[16];
17160 const GLchar* index = "";
17161 size_t position = 0;
17163 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
17165 sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
17166 sprintf(buffer_goten, "%d", test_case.m_component_goten);
17170 case Utils::Shader::FRAGMENT:
17171 source = fs_tested;
17173 case Utils::Shader::GEOMETRY:
17174 source = gs_tested;
17178 case Utils::Shader::TESS_CTRL:
17179 source = tcs_tested;
17181 index = "[gl_InvocationID]";
17183 case Utils::Shader::TESS_EVAL:
17184 source = tes_tested;
17188 case Utils::Shader::VERTEX:
17189 source = vs_tested;
17192 TCU_FAIL("Invalid enum");
17196 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
17198 Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
17199 Utils::replaceToken("ARRAY", position, array, source);
17200 Utils::replaceToken("COMPONENT", position, buffer_goten, source);
17201 Utils::replaceToken("ARRAY", position, array, source);
17202 Utils::replaceToken("VARIABLE_USE", position, l_test, source);
17204 Utils::replaceAllTokens("TYPE", type_name, source);
17205 Utils::replaceAllTokens("INDEX", index, source);
17211 case Utils::Shader::FRAGMENT:
17214 case Utils::Shader::GEOMETRY:
17217 case Utils::Shader::TESS_CTRL:
17220 case Utils::Shader::TESS_EVAL:
17223 case Utils::Shader::VERTEX:
17227 TCU_FAIL("Invalid enum");
17234 /** Get description of test case
17236 * @param test_case_index Index of test case
17238 * @return Test case description
17240 std::string OutputComponentAliasingTest::getTestCaseName(GLuint test_case_index)
17242 std::stringstream stream;
17243 testCase& test_case = m_test_cases[test_case_index];
17245 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
17246 << " type: " << test_case.m_type.GetGLSLTypeName() << ", components: " << test_case.m_component_gohan
17247 << " & " << test_case.m_component_goten;
17249 return stream.str();
17252 /** Get number of test cases
17254 * @return Number of test cases
17256 GLuint OutputComponentAliasingTest::getTestCaseNumber()
17258 return static_cast<GLuint>(m_test_cases.size());
17261 /** Selects if "compute" stage is relevant for test
17267 bool OutputComponentAliasingTest::isComputeRelevant(GLuint /* test_case_index */)
17272 /** Prepare all test cases
17275 void OutputComponentAliasingTest::testInit()
17277 static const GLuint n_components_per_location = 4;
17278 const GLuint n_types = getTypesNumber();
17280 for (GLuint i = 0; i < n_types; ++i)
17282 const Utils::Type& type = getType(i);
17283 const GLuint n_req_components = type.m_n_rows;
17284 const GLuint valid_component = n_components_per_location - n_req_components;
17286 /* Skip matrices */
17287 if (1 != type.m_n_columns)
17292 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
17294 if (Utils::Shader::COMPUTE == stage)
17299 if ((Utils::Shader::FRAGMENT == stage) && (Utils::Type::Double == type.m_basic_type))
17304 for (GLuint gohan = 0; gohan <= valid_component; ++gohan)
17306 const GLint first_aliasing = gohan - n_req_components + 1;
17307 const GLint last_aliasing = gohan + n_req_components - 1;
17309 const GLuint goten_start = std::max(0, first_aliasing);
17310 const GLuint goten_stop = std::min((GLint)valid_component, last_aliasing);
17312 for (GLuint goten = goten_start; goten <= goten_stop; ++goten)
17314 testCase test_case = { gohan, goten, (Utils::Shader::STAGES)stage, type };
17316 m_test_cases.push_back(test_case);
17325 * @param context Test framework context
17327 VaryingLocationAliasingWithMixedTypesTest::VaryingLocationAliasingWithMixedTypesTest(deqp::Context& context)
17328 : NegativeTestBase(context, "varying_location_aliasing_with_mixed_types",
17329 "Test verifies that compiler reports error when float/int types are mixed at one location")
17333 /** Source for given test case and stage
17335 * @param test_case_index Index of test case
17336 * @param stage Shader stage
17338 * @return Shader source
17340 std::string VaryingLocationAliasingWithMixedTypesTest::getShaderSource(GLuint test_case_index,
17341 Utils::Shader::STAGES stage)
17343 static const GLchar* var_definition =
17344 "layout (location = 1, component = COMPONENT) FLAT DIRECTION TYPE gohanARRAY;\n"
17345 "layout (location = 1, component = COMPONENT) FLAT DIRECTION TYPE gotenARRAY;\n";
17346 static const GLchar* input_use = " if ((TYPE(0) == gohanINDEX) &&\n"
17347 " (TYPE(1) == gotenINDEX) )\n"
17349 " result += vec4(1, 0.5, 0.25, 0.125);\n"
17351 static const GLchar* output_use = " gohanINDEX = TYPE(0);\n"
17352 " gotenINDEX = TYPE(1);\n"
17353 " if (vec4(0) == result)\n"
17355 " gohanINDEX = TYPE(1);\n"
17356 " gotenINDEX = TYPE(0);\n"
17358 static const GLchar* fs = "#version 430 core\n"
17359 "#extension GL_ARB_enhanced_layouts : require\n"
17362 "out vec4 fs_out;\n"
17366 " fs_out = gs_fs;\n"
17369 static const GLchar* fs_tested = "#version 430 core\n"
17370 "#extension GL_ARB_enhanced_layouts : require\n"
17375 "out vec4 fs_out;\n"
17379 " vec4 result = gs_fs;\n"
17383 " fs_out += result;\n"
17386 static const GLchar* gs = "#version 430 core\n"
17387 "#extension GL_ARB_enhanced_layouts : require\n"
17389 "layout(points) in;\n"
17390 "layout(triangle_strip, max_vertices = 4) out;\n"
17392 "in vec4 tes_gs[];\n"
17393 "out vec4 gs_fs;\n"
17397 " gs_fs = tes_gs[0];\n"
17398 " gl_Position = vec4(-1, -1, 0, 1);\n"
17400 " gs_fs = tes_gs[0];\n"
17401 " gl_Position = vec4(-1, 1, 0, 1);\n"
17403 " gs_fs = tes_gs[0];\n"
17404 " gl_Position = vec4(1, -1, 0, 1);\n"
17406 " gs_fs = tes_gs[0];\n"
17407 " gl_Position = vec4(1, 1, 0, 1);\n"
17411 static const GLchar* gs_tested = "#version 430 core\n"
17412 "#extension GL_ARB_enhanced_layouts : require\n"
17414 "layout(points) in;\n"
17415 "layout(triangle_strip, max_vertices = 4) out;\n"
17419 "in vec4 tes_gs[];\n"
17420 "out vec4 gs_fs;\n"
17424 " vec4 result = tes_gs[0];\n"
17428 " gs_fs = result;\n"
17429 " gl_Position = vec4(-1, -1, 0, 1);\n"
17431 " gs_fs = result;\n"
17432 " gl_Position = vec4(-1, 1, 0, 1);\n"
17434 " gs_fs = result;\n"
17435 " gl_Position = vec4(1, -1, 0, 1);\n"
17437 " gs_fs = result;\n"
17438 " gl_Position = vec4(1, 1, 0, 1);\n"
17442 static const GLchar* tcs = "#version 430 core\n"
17443 "#extension GL_ARB_enhanced_layouts : require\n"
17445 "layout(vertices = 1) out;\n"
17447 "in vec4 vs_tcs[];\n"
17448 "out vec4 tcs_tes[];\n"
17453 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
17455 " gl_TessLevelOuter[0] = 1.0;\n"
17456 " gl_TessLevelOuter[1] = 1.0;\n"
17457 " gl_TessLevelOuter[2] = 1.0;\n"
17458 " gl_TessLevelOuter[3] = 1.0;\n"
17459 " gl_TessLevelInner[0] = 1.0;\n"
17460 " gl_TessLevelInner[1] = 1.0;\n"
17463 static const GLchar* tcs_tested = "#version 430 core\n"
17464 "#extension GL_ARB_enhanced_layouts : require\n"
17466 "layout(vertices = 1) out;\n"
17470 "in vec4 vs_tcs[];\n"
17471 "out vec4 tcs_tes[];\n"
17475 " vec4 result = vs_tcs[gl_InvocationID];\n"
17479 " tcs_tes[gl_InvocationID] = result;\n"
17481 " gl_TessLevelOuter[0] = 1.0;\n"
17482 " gl_TessLevelOuter[1] = 1.0;\n"
17483 " gl_TessLevelOuter[2] = 1.0;\n"
17484 " gl_TessLevelOuter[3] = 1.0;\n"
17485 " gl_TessLevelInner[0] = 1.0;\n"
17486 " gl_TessLevelInner[1] = 1.0;\n"
17489 static const GLchar* tes = "#version 430 core\n"
17490 "#extension GL_ARB_enhanced_layouts : require\n"
17492 "layout(isolines, point_mode) in;\n"
17494 "in vec4 tcs_tes[];\n"
17495 "out vec4 tes_gs;\n"
17499 " tes_gs = tcs_tes[0];\n"
17502 static const GLchar* tes_tested = "#version 430 core\n"
17503 "#extension GL_ARB_enhanced_layouts : require\n"
17505 "layout(isolines, point_mode) in;\n"
17509 "in vec4 tcs_tes[];\n"
17510 "out vec4 tes_gs;\n"
17514 " vec4 result = tcs_tes[0];\n"
17518 " tes_gs += result;\n"
17521 static const GLchar* vs = "#version 430 core\n"
17522 "#extension GL_ARB_enhanced_layouts : require\n"
17525 "out vec4 vs_tcs;\n"
17529 " vs_tcs = in_vs;\n"
17532 static const GLchar* vs_tested = "#version 430 core\n"
17533 "#extension GL_ARB_enhanced_layouts : require\n"
17538 "out vec4 vs_tcs;\n"
17542 " vec4 result = in_vs;\n"
17546 " vs_tcs += result;\n"
17550 std::string source;
17551 testCase& test_case = m_test_cases[test_case_index];
17553 if (test_case.m_stage == stage)
17555 const GLchar* array = "";
17556 GLchar buffer_gohan[16];
17557 GLchar buffer_goten[16];
17558 const GLchar* direction = "in ";
17559 const GLchar* flat_gohan = "";
17560 const GLchar* flat_goten = "";
17561 const GLchar* index = "";
17562 size_t position = 0;
17564 const GLchar* type_gohan_name = test_case.m_type_gohan.GetGLSLTypeName();
17565 const GLchar* type_goten_name = test_case.m_type_goten.GetGLSLTypeName();
17566 Utils::Variable::STORAGE storage = Utils::Variable::VARYING_INPUT;
17567 const GLchar* var_use = input_use;
17569 if (false == test_case.m_is_input)
17572 storage = Utils::Variable::VARYING_OUTPUT;
17573 var_use = output_use;
17576 if (true == isFlatRequired(stage, test_case.m_type_gohan, storage))
17578 flat_gohan = "flat";
17581 if (true == isFlatRequired(stage, test_case.m_type_goten, storage))
17583 flat_goten = "flat";
17586 sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
17587 sprintf(buffer_goten, "%d", test_case.m_component_goten);
17591 case Utils::Shader::FRAGMENT:
17592 source = fs_tested;
17594 case Utils::Shader::GEOMETRY:
17595 source = gs_tested;
17599 case Utils::Shader::TESS_CTRL:
17600 source = tcs_tested;
17602 index = "[gl_InvocationID]";
17604 case Utils::Shader::TESS_EVAL:
17605 source = tes_tested;
17609 case Utils::Shader::VERTEX:
17610 source = vs_tested;
17613 TCU_FAIL("Invalid enum");
17617 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
17619 Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
17620 Utils::replaceToken("FLAT", position, flat_gohan, source);
17621 Utils::replaceToken("DIRECTION", position, direction, source);
17622 Utils::replaceToken("TYPE", position, type_gohan_name, source);
17623 Utils::replaceToken("ARRAY", position, array, source);
17624 Utils::replaceToken("COMPONENT", position, buffer_goten, source);
17625 Utils::replaceToken("FLAT", position, flat_goten, source);
17626 Utils::replaceToken("DIRECTION", position, direction, source);
17627 Utils::replaceToken("TYPE", position, type_goten_name, source);
17628 Utils::replaceToken("ARRAY", position, array, source);
17631 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
17633 if (true == test_case.m_is_input)
17635 Utils::replaceToken("TYPE", position, type_gohan_name, source);
17636 Utils::replaceToken("TYPE", position, type_goten_name, source);
17640 Utils::replaceToken("TYPE", position, type_gohan_name, source);
17641 Utils::replaceToken("TYPE", position, type_goten_name, source);
17642 Utils::replaceToken("TYPE", position, type_gohan_name, source);
17643 Utils::replaceToken("TYPE", position, type_goten_name, source);
17646 Utils::replaceAllTokens("INDEX", index, source);
17652 case Utils::Shader::FRAGMENT:
17655 case Utils::Shader::GEOMETRY:
17658 case Utils::Shader::TESS_CTRL:
17661 case Utils::Shader::TESS_EVAL:
17664 case Utils::Shader::VERTEX:
17668 TCU_FAIL("Invalid enum");
17675 /** Get description of test case
17677 * @param test_case_index Index of test case
17679 * @return Test case description
17681 std::string VaryingLocationAliasingWithMixedTypesTest::getTestCaseName(GLuint test_case_index)
17683 std::stringstream stream;
17684 testCase& test_case = m_test_cases[test_case_index];
17686 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", "
17687 << test_case.m_type_gohan.GetGLSLTypeName() << " at " << test_case.m_component_gohan << ", "
17688 << test_case.m_type_goten.GetGLSLTypeName() << " at " << test_case.m_component_goten << ". Direction: ";
17690 if (true == test_case.m_is_input)
17696 stream << "output";
17699 return stream.str();
17702 /** Get number of test cases
17704 * @return Number of test cases
17706 GLuint VaryingLocationAliasingWithMixedTypesTest::getTestCaseNumber()
17708 return static_cast<GLuint>(m_test_cases.size());
17711 /** Selects if "compute" stage is relevant for test
17717 bool VaryingLocationAliasingWithMixedTypesTest::isComputeRelevant(GLuint /* test_case_index */)
17722 /** Prepare all test cases
17725 void VaryingLocationAliasingWithMixedTypesTest::testInit()
17727 static const GLuint n_components_per_location = 4;
17728 const GLuint n_types = getTypesNumber();
17730 for (GLuint i = 0; i < n_types; ++i)
17732 const Utils::Type& type_gohan = getType(i);
17733 const bool is_float_type_gohan = isFloatType(type_gohan);
17735 /* Skip matrices */
17736 if (1 != type_gohan.m_n_columns)
17741 for (GLuint j = 0; j < n_types; ++j)
17743 const Utils::Type& type_goten = getType(j);
17744 const bool is_float_type_goten = isFloatType(type_goten);
17746 /* Skip matrices */
17747 if (1 != type_goten.m_n_columns)
17752 /* Skip valid combinations */
17753 if (is_float_type_gohan == is_float_type_goten)
17758 const GLuint n_req_components_gohan = type_gohan.m_n_rows;
17759 const GLuint n_req_components_goten = type_goten.m_n_rows;
17760 const GLuint valid_component_gohan = n_components_per_location - n_req_components_gohan;
17761 const GLuint valid_component_goten = n_components_per_location - n_req_components_goten;
17763 /* Skip pairs that cannot fit into one location */
17764 if (n_components_per_location < (n_req_components_gohan + n_req_components_goten))
17769 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
17771 /* Skip compute shader */
17772 if (Utils::Shader::COMPUTE == stage)
17777 for (GLuint gohan = 0; gohan <= valid_component_gohan; ++gohan)
17779 const GLint first_aliasing = gohan - n_req_components_goten + 1;
17780 const GLint last_aliasing = gohan + n_req_components_gohan - 1;
17782 const GLuint goten_lower_limit = std::max(0, first_aliasing);
17783 const GLuint goten_upper_limit = last_aliasing + 1;
17785 /* Compoennets before gohan */
17786 for (GLuint goten = 0; goten < goten_lower_limit; ++goten)
17788 testCase test_case_in = { gohan, goten, true, (Utils::Shader::STAGES)stage,
17789 type_gohan, type_goten };
17790 testCase test_case_out = { gohan, goten, false, (Utils::Shader::STAGES)stage,
17791 type_gohan, type_goten };
17793 m_test_cases.push_back(test_case_in);
17795 /* Skip double outputs in fragment shader */
17796 if ((Utils::Shader::FRAGMENT != stage) || ((Utils::Type::Double != type_gohan.m_basic_type) &&
17797 (Utils::Type::Double != type_goten.m_basic_type)))
17799 m_test_cases.push_back(test_case_out);
17803 /* Components after gohan */
17804 for (GLuint goten = goten_upper_limit; goten <= valid_component_goten; ++goten)
17806 testCase test_case_in = { gohan, goten, true, (Utils::Shader::STAGES)stage,
17807 type_gohan, type_goten };
17808 testCase test_case_out = { gohan, goten, false, (Utils::Shader::STAGES)stage,
17809 type_gohan, type_goten };
17811 m_test_cases.push_back(test_case_in);
17813 /* Skip double outputs in fragment shader */
17814 if ((Utils::Shader::FRAGMENT != stage) || ((Utils::Type::Double != type_gohan.m_basic_type) &&
17815 (Utils::Type::Double != type_goten.m_basic_type)))
17817 m_test_cases.push_back(test_case_out);
17826 /** Check if given type is float
17828 * @param type Type in question
17830 * @return true if tpye is float, false otherwise
17832 bool VaryingLocationAliasingWithMixedTypesTest::isFloatType(const Utils::Type& type)
17834 bool is_float = false;
17836 if ((Utils::Type::Double == type.m_basic_type) || (Utils::Type::Float == type.m_basic_type))
17846 * @param context Test framework context
17848 VaryingLocationAliasingWithMixedInterpolationTest::VaryingLocationAliasingWithMixedInterpolationTest(
17849 deqp::Context& context)
17850 : NegativeTestBase(
17851 context, "varying_location_aliasing_with_mixed_interpolation",
17852 "Test verifies that compiler reports error when interpolation qualifiers are mixed at one location")
17856 /** Source for given test case and stage
17858 * @param test_case_index Index of test case
17859 * @param stage Shader stage
17861 * @return Shader source
17863 std::string VaryingLocationAliasingWithMixedInterpolationTest::getShaderSource(GLuint test_case_index,
17864 Utils::Shader::STAGES stage)
17866 static const GLchar* var_definition =
17867 "layout (location = 1, component = COMPONENT) INTERPOLATION DIRECTION TYPE gohanARRAY;\n"
17868 "layout (location = 1, component = COMPONENT) INTERPOLATION DIRECTION TYPE gotenARRAY;\n";
17869 static const GLchar* input_use = " if ((TYPE(0) == gohanINDEX) &&\n"
17870 " (TYPE(1) == gotenINDEX) )\n"
17872 " result += vec4(1, 0.5, 0.25, 0.125);\n"
17874 static const GLchar* output_use = " gohanINDEX = TYPE(0);\n"
17875 " gotenINDEX = TYPE(1);\n"
17876 " if (vec4(0) == result)\n"
17878 " gohanINDEX = TYPE(1);\n"
17879 " gotenINDEX = TYPE(0);\n"
17881 static const GLchar* fs = "#version 430 core\n"
17882 "#extension GL_ARB_enhanced_layouts : require\n"
17885 "out vec4 fs_out;\n"
17889 " fs_out = gs_fs;\n"
17892 static const GLchar* fs_tested = "#version 430 core\n"
17893 "#extension GL_ARB_enhanced_layouts : require\n"
17898 "out vec4 fs_out;\n"
17902 " vec4 result = gs_fs;\n"
17906 " fs_out = result;\n"
17909 static const GLchar* gs = "#version 430 core\n"
17910 "#extension GL_ARB_enhanced_layouts : require\n"
17912 "layout(points) in;\n"
17913 "layout(triangle_strip, max_vertices = 4) out;\n"
17915 "in vec4 tes_gs[];\n"
17916 "out vec4 gs_fs;\n"
17920 " gs_fs = tes_gs[0];\n"
17921 " gl_Position = vec4(-1, -1, 0, 1);\n"
17923 " gs_fs = tes_gs[0];\n"
17924 " gl_Position = vec4(-1, 1, 0, 1);\n"
17926 " gs_fs = tes_gs[0];\n"
17927 " gl_Position = vec4(1, -1, 0, 1);\n"
17929 " gs_fs = tes_gs[0];\n"
17930 " gl_Position = vec4(1, 1, 0, 1);\n"
17934 static const GLchar* gs_tested = "#version 430 core\n"
17935 "#extension GL_ARB_enhanced_layouts : require\n"
17937 "layout(points) in;\n"
17938 "layout(triangle_strip, max_vertices = 4) out;\n"
17942 "in vec4 tes_gs[];\n"
17943 "out vec4 gs_fs;\n"
17947 " vec4 result = tes_gs[0];\n"
17951 " gs_fs = result;\n"
17952 " gl_Position = vec4(-1, -1, 0, 1);\n"
17954 " gs_fs = result;\n"
17955 " gl_Position = vec4(-1, 1, 0, 1);\n"
17957 " gs_fs = result;\n"
17958 " gl_Position = vec4(1, -1, 0, 1);\n"
17960 " gs_fs = result;\n"
17961 " gl_Position = vec4(1, 1, 0, 1);\n"
17965 static const GLchar* tcs = "#version 430 core\n"
17966 "#extension GL_ARB_enhanced_layouts : require\n"
17968 "layout(vertices = 1) out;\n"
17970 "in vec4 vs_tcs[];\n"
17971 "out vec4 tcs_tes[];\n"
17976 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
17978 " gl_TessLevelOuter[0] = 1.0;\n"
17979 " gl_TessLevelOuter[1] = 1.0;\n"
17980 " gl_TessLevelOuter[2] = 1.0;\n"
17981 " gl_TessLevelOuter[3] = 1.0;\n"
17982 " gl_TessLevelInner[0] = 1.0;\n"
17983 " gl_TessLevelInner[1] = 1.0;\n"
17986 static const GLchar* tcs_tested = "#version 430 core\n"
17987 "#extension GL_ARB_enhanced_layouts : require\n"
17989 "layout(vertices = 1) out;\n"
17993 "in vec4 vs_tcs[];\n"
17994 "out vec4 tcs_tes[];\n"
17998 " vec4 result = vs_tcs[gl_InvocationID];\n"
18002 " tcs_tes[gl_InvocationID] = result;\n"
18004 " gl_TessLevelOuter[0] = 1.0;\n"
18005 " gl_TessLevelOuter[1] = 1.0;\n"
18006 " gl_TessLevelOuter[2] = 1.0;\n"
18007 " gl_TessLevelOuter[3] = 1.0;\n"
18008 " gl_TessLevelInner[0] = 1.0;\n"
18009 " gl_TessLevelInner[1] = 1.0;\n"
18012 static const GLchar* tes = "#version 430 core\n"
18013 "#extension GL_ARB_enhanced_layouts : require\n"
18015 "layout(isolines, point_mode) in;\n"
18017 "in vec4 tcs_tes[];\n"
18018 "out vec4 tes_gs;\n"
18022 " tes_gs = tcs_tes[0];\n"
18025 static const GLchar* tes_tested = "#version 430 core\n"
18026 "#extension GL_ARB_enhanced_layouts : require\n"
18028 "layout(isolines, point_mode) in;\n"
18032 "in vec4 tcs_tes[];\n"
18033 "out vec4 tes_gs;\n"
18037 " vec4 result = tcs_tes[0];\n"
18041 " tes_gs += result;\n"
18044 static const GLchar* vs = "#version 430 core\n"
18045 "#extension GL_ARB_enhanced_layouts : require\n"
18048 "out vec4 vs_tcs;\n"
18052 " vs_tcs = in_vs;\n"
18055 static const GLchar* vs_tested = "#version 430 core\n"
18056 "#extension GL_ARB_enhanced_layouts : require\n"
18061 "out vec4 vs_tcs;\n"
18065 " vec4 result = in_vs;\n"
18069 " vs_tcs += result;\n"
18073 std::string source;
18074 testCase& test_case = m_test_cases[test_case_index];
18076 if (test_case.m_stage == stage)
18078 const GLchar* array = "";
18079 GLchar buffer_gohan[16];
18080 GLchar buffer_goten[16];
18081 const GLchar* direction = "in ";
18082 const GLchar* index = "";
18083 const GLchar* int_gohan = getInterpolationQualifier(test_case.m_interpolation_gohan);
18084 const GLchar* int_goten = getInterpolationQualifier(test_case.m_interpolation_goten);
18085 size_t position = 0;
18087 const GLchar* type_gohan_name = test_case.m_type_gohan.GetGLSLTypeName();
18088 const GLchar* type_goten_name = test_case.m_type_goten.GetGLSLTypeName();
18089 const GLchar* var_use = input_use;
18091 if (false == test_case.m_is_input)
18095 var_use = output_use;
18098 sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
18099 sprintf(buffer_goten, "%d", test_case.m_component_goten);
18103 case Utils::Shader::FRAGMENT:
18104 source = fs_tested;
18106 case Utils::Shader::GEOMETRY:
18107 source = gs_tested;
18111 case Utils::Shader::TESS_CTRL:
18112 source = tcs_tested;
18114 index = "[gl_InvocationID]";
18116 case Utils::Shader::TESS_EVAL:
18117 source = tes_tested;
18121 case Utils::Shader::VERTEX:
18122 source = vs_tested;
18125 TCU_FAIL("Invalid enum");
18129 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
18131 Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
18132 Utils::replaceToken("INTERPOLATION", position, int_gohan, source);
18133 Utils::replaceToken("DIRECTION", position, direction, source);
18134 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18135 Utils::replaceToken("ARRAY", position, array, source);
18136 Utils::replaceToken("COMPONENT", position, buffer_goten, source);
18137 Utils::replaceToken("INTERPOLATION", position, int_goten, source);
18138 Utils::replaceToken("DIRECTION", position, direction, source);
18139 Utils::replaceToken("TYPE", position, type_goten_name, source);
18140 Utils::replaceToken("ARRAY", position, array, source);
18143 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
18145 if (true == test_case.m_is_input)
18147 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18148 Utils::replaceToken("TYPE", position, type_goten_name, source);
18152 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18153 Utils::replaceToken("TYPE", position, type_goten_name, source);
18154 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18155 Utils::replaceToken("TYPE", position, type_goten_name, source);
18158 Utils::replaceAllTokens("INDEX", index, source);
18164 case Utils::Shader::FRAGMENT:
18167 case Utils::Shader::GEOMETRY:
18170 case Utils::Shader::TESS_CTRL:
18173 case Utils::Shader::TESS_EVAL:
18176 case Utils::Shader::VERTEX:
18180 TCU_FAIL("Invalid enum");
18187 /** Get description of test case
18189 * @param test_case_index Index of test case
18191 * @return Test case description
18193 std::string VaryingLocationAliasingWithMixedInterpolationTest::getTestCaseName(GLuint test_case_index)
18195 std::stringstream stream;
18196 testCase& test_case = m_test_cases[test_case_index];
18198 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", "
18199 << getInterpolationQualifier(test_case.m_interpolation_gohan) << " "
18200 << test_case.m_type_gohan.GetGLSLTypeName() << " at " << test_case.m_component_gohan << ", "
18201 << getInterpolationQualifier(test_case.m_interpolation_goten) << " "
18202 << test_case.m_type_goten.GetGLSLTypeName() << " at " << test_case.m_component_goten << ". Direction: ";
18204 if (true == test_case.m_is_input)
18210 stream << "output";
18213 return stream.str();
18216 /** Get number of test cases
18218 * @return Number of test cases
18220 GLuint VaryingLocationAliasingWithMixedInterpolationTest::getTestCaseNumber()
18222 return static_cast<GLuint>(m_test_cases.size());
18225 /** Selects if "compute" stage is relevant for test
18231 bool VaryingLocationAliasingWithMixedInterpolationTest::isComputeRelevant(GLuint /* test_case_index */)
18236 /** Prepare all test cases
18239 void VaryingLocationAliasingWithMixedInterpolationTest::testInit()
18241 static const GLuint n_components_per_location = 4;
18242 const GLuint n_types = getTypesNumber();
18244 for (GLuint i = 0; i < n_types; ++i)
18246 const Utils::Type& type_gohan = getType(i);
18247 const bool is_float_type_gohan = isFloatType(type_gohan);
18249 /* Skip matrices */
18250 if (1 != type_gohan.m_n_columns)
18255 for (GLuint j = 0; j < n_types; ++j)
18257 const Utils::Type& type_goten = getType(j);
18258 const bool is_float_type_goten = isFloatType(type_goten);
18260 /* Skip matrices */
18261 if (1 != type_goten.m_n_columns)
18266 /* Skip invalid combinations */
18267 if (is_float_type_gohan != is_float_type_goten)
18272 const GLuint n_req_components_gohan = type_gohan.m_n_rows;
18273 const GLuint n_req_components_goten = type_goten.m_n_rows;
18275 /* Skip pairs that cannot fit into one location */
18276 if (n_components_per_location < (n_req_components_gohan + n_req_components_goten))
18281 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
18283 /* Skip compute shader */
18284 if (Utils::Shader::COMPUTE == stage)
18289 const GLuint gohan = 0;
18290 const GLuint goten = gohan + n_req_components_gohan;
18292 for (GLuint int_gohan = 0; int_gohan < INTERPOLATION_MAX; ++int_gohan)
18294 for (GLuint int_goten = 0; int_goten < INTERPOLATION_MAX; ++int_goten)
18296 const bool is_gohan_double = (Utils::Type::Double == type_gohan.m_basic_type) ? true : false;
18297 const bool is_goten_double = (Utils::Type::Double == type_goten.m_basic_type) ? true : false;
18298 const bool is_gohan_flat = (FLAT == int_gohan) ? true : false;
18299 const bool is_goten_flat = (FLAT == int_goten) ? true : false;
18300 const bool is_gohan_accepted_as_fs_in =
18301 (is_gohan_double && is_gohan_flat) || (!is_gohan_double);
18302 const bool is_goten_accepted_as_fs_in =
18303 (is_goten_double && is_goten_flat) || (!is_goten_double);
18304 const bool is_comb_accepted_as_fs_in = is_gohan_accepted_as_fs_in && is_goten_accepted_as_fs_in;
18306 /* Skip when both are the same */
18307 if (int_gohan == int_goten)
18312 testCase test_case_in = { gohan,
18314 (INTERPOLATIONS)int_gohan,
18315 (INTERPOLATIONS)int_goten,
18317 (Utils::Shader::STAGES)stage,
18321 testCase test_case_out = { gohan,
18323 (INTERPOLATIONS)int_gohan,
18324 (INTERPOLATIONS)int_goten,
18326 (Utils::Shader::STAGES)stage,
18332 * fragment shader when not flat double is used
18334 if ((Utils::Shader::VERTEX != stage) &&
18335 ((Utils::Shader::FRAGMENT != stage) || (true == is_comb_accepted_as_fs_in)))
18337 m_test_cases.push_back(test_case_in);
18340 /* Skip outputs in fragment shader */
18341 if (Utils::Shader::FRAGMENT != stage)
18343 m_test_cases.push_back(test_case_out);
18352 /** Get interpolation qualifier
18354 * @param interpolation Enumeration
18356 * @return GLSL qualifier
18358 const GLchar* VaryingLocationAliasingWithMixedInterpolationTest::getInterpolationQualifier(INTERPOLATIONS interpolation)
18360 const GLchar* result = 0;
18362 switch (interpolation)
18370 case NO_PERSPECTIVE:
18371 result = "noperspective";
18374 TCU_FAIL("Invalid enum");
18380 /** Check if given type is float
18382 * @param type Type in question
18384 * @return true if tpye is float, false otherwise
18386 bool VaryingLocationAliasingWithMixedInterpolationTest::isFloatType(const Utils::Type& type)
18388 bool is_float = false;
18390 if ((Utils::Type::Double == type.m_basic_type) || (Utils::Type::Float == type.m_basic_type))
18400 * @param context Test framework context
18402 VaryingLocationAliasingWithMixedAuxiliaryStorageTest::VaryingLocationAliasingWithMixedAuxiliaryStorageTest(
18403 deqp::Context& context)
18404 : NegativeTestBase(
18405 context, "varying_location_aliasing_with_mixed_auxiliary_storage",
18406 "Test verifies that compiler reports error when auxiliary storage qualifiers are mixed at one location")
18410 /** Source for given test case and stage
18412 * @param test_case_index Index of test case
18413 * @param stage Shader stage
18415 * @return Shader source
18417 std::string VaryingLocationAliasingWithMixedAuxiliaryStorageTest::getShaderSource(GLuint test_case_index,
18418 Utils::Shader::STAGES stage)
18420 static const GLchar* var_definition =
18421 "layout (location = 1, component = COMPONENT) AUX INTERPOLATION DIRECTION TYPE gohanARRAY;\n"
18422 "layout (location = 1, component = COMPONENT) AUX INTERPOLATION DIRECTION TYPE gotenARRAY;\n";
18423 static const GLchar* input_use = " if ((TYPE(0) == gohanINDEX_GOHAN) &&\n"
18424 " (TYPE(1) == gotenINDEX_GOTEN) )\n"
18426 " result += vec4(1, 0.5, 0.25, 0.125);\n"
18428 static const GLchar* output_use = " gohanINDEX_GOHAN = TYPE(0);\n"
18429 " gotenINDEX_GOTEN = TYPE(1);\n"
18430 " if (vec4(0) == result)\n"
18432 " gohanINDEX_GOHAN = TYPE(1);\n"
18433 " gotenINDEX_GOTEN = TYPE(0);\n"
18435 static const GLchar* fs = "#version 430 core\n"
18436 "#extension GL_ARB_enhanced_layouts : require\n"
18439 "out vec4 fs_out;\n"
18443 " fs_out = gs_fs;\n"
18446 static const GLchar* fs_tested = "#version 430 core\n"
18447 "#extension GL_ARB_enhanced_layouts : require\n"
18452 "out vec4 fs_out;\n"
18456 " vec4 result = gs_fs;\n"
18460 " fs_out = result;\n"
18463 static const GLchar* gs = "#version 430 core\n"
18464 "#extension GL_ARB_enhanced_layouts : require\n"
18466 "layout(points) in;\n"
18467 "layout(triangle_strip, max_vertices = 4) out;\n"
18469 "in vec4 tes_gs[];\n"
18470 "out vec4 gs_fs;\n"
18474 " gs_fs = tes_gs[0];\n"
18475 " gl_Position = vec4(-1, -1, 0, 1);\n"
18477 " gs_fs = tes_gs[0];\n"
18478 " gl_Position = vec4(-1, 1, 0, 1);\n"
18480 " gs_fs = tes_gs[0];\n"
18481 " gl_Position = vec4(1, -1, 0, 1);\n"
18483 " gs_fs = tes_gs[0];\n"
18484 " gl_Position = vec4(1, 1, 0, 1);\n"
18488 static const GLchar* gs_tested = "#version 430 core\n"
18489 "#extension GL_ARB_enhanced_layouts : require\n"
18491 "layout(points) in;\n"
18492 "layout(triangle_strip, max_vertices = 4) out;\n"
18496 "in vec4 tes_gs[];\n"
18497 "out vec4 gs_fs;\n"
18501 " vec4 result = tes_gs[0];\n"
18505 " gs_fs = result;\n"
18506 " gl_Position = vec4(-1, -1, 0, 1);\n"
18508 " gs_fs = result;\n"
18509 " gl_Position = vec4(-1, 1, 0, 1);\n"
18511 " gs_fs = result;\n"
18512 " gl_Position = vec4(1, -1, 0, 1);\n"
18514 " gs_fs = result;\n"
18515 " gl_Position = vec4(1, 1, 0, 1);\n"
18519 static const GLchar* tcs = "#version 430 core\n"
18520 "#extension GL_ARB_enhanced_layouts : require\n"
18522 "layout(vertices = 1) out;\n"
18524 "in vec4 vs_tcs[];\n"
18525 "out vec4 tcs_tes[];\n"
18530 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
18532 " gl_TessLevelOuter[0] = 1.0;\n"
18533 " gl_TessLevelOuter[1] = 1.0;\n"
18534 " gl_TessLevelOuter[2] = 1.0;\n"
18535 " gl_TessLevelOuter[3] = 1.0;\n"
18536 " gl_TessLevelInner[0] = 1.0;\n"
18537 " gl_TessLevelInner[1] = 1.0;\n"
18540 static const GLchar* tcs_tested = "#version 430 core\n"
18541 "#extension GL_ARB_enhanced_layouts : require\n"
18543 "layout(vertices = 1) out;\n"
18547 "in vec4 vs_tcs[];\n"
18548 "out vec4 tcs_tes[];\n"
18552 " vec4 result = vs_tcs[gl_InvocationID];\n"
18556 " tcs_tes[gl_InvocationID] = result;\n"
18558 " gl_TessLevelOuter[0] = 1.0;\n"
18559 " gl_TessLevelOuter[1] = 1.0;\n"
18560 " gl_TessLevelOuter[2] = 1.0;\n"
18561 " gl_TessLevelOuter[3] = 1.0;\n"
18562 " gl_TessLevelInner[0] = 1.0;\n"
18563 " gl_TessLevelInner[1] = 1.0;\n"
18566 static const GLchar* tes = "#version 430 core\n"
18567 "#extension GL_ARB_enhanced_layouts : require\n"
18569 "layout(isolines, point_mode) in;\n"
18571 "in vec4 tcs_tes[];\n"
18572 "out vec4 tes_gs;\n"
18576 " tes_gs = tcs_tes[0];\n"
18579 static const GLchar* tes_tested = "#version 430 core\n"
18580 "#extension GL_ARB_enhanced_layouts : require\n"
18582 "layout(isolines, point_mode) in;\n"
18586 "in vec4 tcs_tes[];\n"
18587 "out vec4 tes_gs;\n"
18591 " vec4 result = tcs_tes[0];\n"
18595 " tes_gs += result;\n"
18598 static const GLchar* vs = "#version 430 core\n"
18599 "#extension GL_ARB_enhanced_layouts : require\n"
18602 "out vec4 vs_tcs;\n"
18606 " vs_tcs = in_vs;\n"
18609 static const GLchar* vs_tested = "#version 430 core\n"
18610 "#extension GL_ARB_enhanced_layouts : require\n"
18615 "out vec4 vs_tcs;\n"
18619 " vec4 result = in_vs;\n"
18623 " vs_tcs += result;\n"
18627 std::string source;
18628 testCase& test_case = m_test_cases[test_case_index];
18630 if (test_case.m_stage == stage)
18632 const GLchar* array_gohan = "";
18633 const GLchar* array_goten = "";
18634 const GLchar* aux_gohan = getAuxiliaryQualifier(test_case.m_aux_gohan);
18635 const GLchar* aux_goten = getAuxiliaryQualifier(test_case.m_aux_goten);
18636 GLchar buffer_gohan[16];
18637 GLchar buffer_goten[16];
18638 const GLchar* direction = "in ";
18639 const GLchar* index_gohan = "";
18640 const GLchar* index_goten = "";
18641 const GLchar* int_gohan = test_case.m_int_gohan;
18642 const GLchar* int_goten = test_case.m_int_goten;
18643 size_t position = 0;
18645 const GLchar* type_gohan_name = test_case.m_type_gohan.GetGLSLTypeName();
18646 const GLchar* type_goten_name = test_case.m_type_goten.GetGLSLTypeName();
18647 const GLchar* var_use = input_use;
18649 if (false == test_case.m_is_input)
18653 var_use = output_use;
18656 sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
18657 sprintf(buffer_goten, "%d", test_case.m_component_goten);
18661 case Utils::Shader::FRAGMENT:
18662 source = fs_tested;
18664 case Utils::Shader::GEOMETRY:
18665 source = gs_tested;
18666 array_gohan = "[]";
18667 index_gohan = "[0]";
18668 array_goten = "[]";
18669 index_goten = "[0]";
18671 case Utils::Shader::TESS_CTRL:
18672 source = tcs_tested;
18673 if (PATCH != test_case.m_aux_gohan)
18675 array_gohan = "[]";
18676 index_gohan = "[gl_InvocationID]";
18678 if (PATCH != test_case.m_aux_goten)
18680 array_goten = "[]";
18681 index_goten = "[gl_InvocationID]";
18684 case Utils::Shader::TESS_EVAL:
18685 source = tes_tested;
18686 array_gohan = "[]";
18687 index_gohan = "[0]";
18688 array_goten = "[]";
18689 index_goten = "[0]";
18691 case Utils::Shader::VERTEX:
18692 source = vs_tested;
18695 TCU_FAIL("Invalid enum");
18699 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
18701 Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
18702 Utils::replaceToken("AUX", position, aux_gohan, source);
18703 Utils::replaceToken("INTERPOLATION", position, int_gohan, source);
18704 Utils::replaceToken("DIRECTION", position, direction, source);
18705 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18706 Utils::replaceToken("ARRAY", position, array_gohan, source);
18707 Utils::replaceToken("COMPONENT", position, buffer_goten, source);
18708 Utils::replaceToken("AUX", position, aux_goten, source);
18709 Utils::replaceToken("INTERPOLATION", position, int_goten, source);
18710 Utils::replaceToken("DIRECTION", position, direction, source);
18711 Utils::replaceToken("TYPE", position, type_goten_name, source);
18712 Utils::replaceToken("ARRAY", position, array_goten, source);
18715 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
18717 if (true == test_case.m_is_input)
18719 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18720 Utils::replaceToken("TYPE", position, type_goten_name, source);
18724 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18725 Utils::replaceToken("TYPE", position, type_goten_name, source);
18726 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18727 Utils::replaceToken("TYPE", position, type_goten_name, source);
18730 Utils::replaceAllTokens("INDEX_GOHAN", index_gohan, source);
18731 Utils::replaceAllTokens("INDEX_GOTEN", index_goten, source);
18737 case Utils::Shader::FRAGMENT:
18740 case Utils::Shader::GEOMETRY:
18743 case Utils::Shader::TESS_CTRL:
18746 case Utils::Shader::TESS_EVAL:
18749 case Utils::Shader::VERTEX:
18753 TCU_FAIL("Invalid enum");
18760 /** Get description of test case
18762 * @param test_case_index Index of test case
18764 * @return Test case description
18766 std::string VaryingLocationAliasingWithMixedAuxiliaryStorageTest::getTestCaseName(GLuint test_case_index)
18768 std::stringstream stream;
18769 testCase& test_case = m_test_cases[test_case_index];
18771 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", "
18772 << getAuxiliaryQualifier(test_case.m_aux_gohan) << " " << test_case.m_type_gohan.GetGLSLTypeName() << " at "
18773 << test_case.m_component_gohan << ", " << getAuxiliaryQualifier(test_case.m_aux_goten) << " "
18774 << test_case.m_type_goten.GetGLSLTypeName() << " at " << test_case.m_component_goten << ". Direction: ";
18776 if (true == test_case.m_is_input)
18782 stream << "output";
18785 return stream.str();
18788 /** Get number of test cases
18790 * @return Number of test cases
18792 GLuint VaryingLocationAliasingWithMixedAuxiliaryStorageTest::getTestCaseNumber()
18794 return static_cast<GLuint>(m_test_cases.size());
18797 /** Selects if "compute" stage is relevant for test
18803 bool VaryingLocationAliasingWithMixedAuxiliaryStorageTest::isComputeRelevant(GLuint /* test_case_index */)
18808 /** Prepare all test cases
18811 void VaryingLocationAliasingWithMixedAuxiliaryStorageTest::testInit()
18813 static const GLuint n_components_per_location = 4;
18814 const GLuint n_types = getTypesNumber();
18816 for (GLuint i = 0; i < n_types; ++i)
18818 const Utils::Type& type_gohan = getType(i);
18819 const bool is_float_type_gohan = isFloatType(type_gohan);
18821 /* Skip matrices */
18822 if (1 != type_gohan.m_n_columns)
18827 for (GLuint j = 0; j < n_types; ++j)
18829 const Utils::Type& type_goten = getType(j);
18830 const bool is_flat_req_gohan = (Utils::Type::Float == type_gohan.m_basic_type) ? false : true;
18831 const bool is_flat_req_goten = (Utils::Type::Float == type_goten.m_basic_type) ? false : true;
18832 const bool is_float_type_goten = isFloatType(type_goten);
18834 /* Skip matrices */
18835 if (1 != type_goten.m_n_columns)
18840 /* Skip invalid combinations */
18841 if (is_float_type_gohan != is_float_type_goten)
18846 const GLuint n_req_components_gohan = type_gohan.m_n_rows;
18847 const GLuint n_req_components_goten = type_goten.m_n_rows;
18849 /* Skip pairs that cannot fit into one location */
18850 if (n_components_per_location < (n_req_components_gohan + n_req_components_goten))
18855 const GLuint gohan = 0;
18856 const GLuint goten = gohan + n_req_components_gohan;
18858 const GLchar* fs_int_gohan = is_flat_req_gohan ? "flat" : "";
18859 const GLchar* fs_int_goten = is_flat_req_goten ? "flat" : "";
18861 testCase test_case_tcs_np = { gohan, goten, NONE, PATCH, "", "", false, Utils::Shader::TESS_CTRL,
18862 type_gohan, type_goten };
18864 testCase test_case_tcs_pn = { gohan, goten, PATCH, NONE, "", "", false, Utils::Shader::TESS_CTRL,
18865 type_gohan, type_goten };
18867 testCase test_case_tes_np = { gohan, goten, NONE, PATCH, "", "", true, Utils::Shader::TESS_EVAL,
18868 type_gohan, type_goten };
18870 testCase test_case_tes_pn = { gohan, goten, PATCH, NONE, "", "", true, Utils::Shader::TESS_EVAL,
18871 type_gohan, type_goten };
18873 testCase test_case_fs_nc = { gohan, goten, NONE, CENTROID,
18874 fs_int_gohan, fs_int_goten, true, Utils::Shader::FRAGMENT,
18875 type_gohan, type_goten };
18877 testCase test_case_fs_cn = { gohan, goten, CENTROID, NONE,
18878 fs_int_gohan, fs_int_goten, true, Utils::Shader::FRAGMENT,
18879 type_gohan, type_goten };
18881 testCase test_case_fs_ns = { gohan, goten, NONE, SAMPLE,
18882 fs_int_gohan, fs_int_goten, true, Utils::Shader::FRAGMENT,
18883 type_gohan, type_goten };
18885 testCase test_case_fs_sn = { gohan, goten, SAMPLE, NONE,
18886 fs_int_gohan, fs_int_goten, true, Utils::Shader::FRAGMENT,
18887 type_gohan, type_goten };
18889 testCase test_case_fs_cs = { gohan, goten, CENTROID, SAMPLE,
18890 fs_int_gohan, fs_int_goten, true, Utils::Shader::FRAGMENT,
18891 type_gohan, type_goten };
18893 testCase test_case_fs_sc = { gohan, goten, SAMPLE, CENTROID,
18894 fs_int_gohan, fs_int_goten, true, Utils::Shader::FRAGMENT,
18895 type_gohan, type_goten };
18897 m_test_cases.push_back(test_case_tcs_np);
18898 m_test_cases.push_back(test_case_tcs_pn);
18899 m_test_cases.push_back(test_case_tes_np);
18900 m_test_cases.push_back(test_case_tes_pn);
18901 m_test_cases.push_back(test_case_fs_nc);
18902 m_test_cases.push_back(test_case_fs_cn);
18903 m_test_cases.push_back(test_case_fs_ns);
18904 m_test_cases.push_back(test_case_fs_sn);
18905 m_test_cases.push_back(test_case_fs_cs);
18906 m_test_cases.push_back(test_case_fs_sc);
18911 /** Get auxiliary storage qualifier
18913 * @param aux Enumeration
18915 * @return GLSL qualifier
18917 const GLchar* VaryingLocationAliasingWithMixedAuxiliaryStorageTest::getAuxiliaryQualifier(AUXILIARIES aux)
18919 const GLchar* result = 0;
18930 result = "centroid";
18936 TCU_FAIL("Invalid enum");
18942 /** Check if given type is float
18944 * @param type Type in question
18946 * @return true if tpye is float, false otherwise
18948 bool VaryingLocationAliasingWithMixedAuxiliaryStorageTest::isFloatType(const Utils::Type& type)
18950 bool is_float = false;
18952 if ((Utils::Type::Double == type.m_basic_type) || (Utils::Type::Float == type.m_basic_type))
18960 /* Constants used by VertexAttribLocationAPITest */
18961 const GLuint VertexAttribLocationAPITest::m_goten_location = 6;
18965 * @param context Test framework context
18967 VertexAttribLocationAPITest::VertexAttribLocationAPITest(deqp::Context& context)
18968 : TextureTestBase(context, "vertex_attrib_location_api",
18969 "Test verifies that attribute locations API works as expected")
18973 /** Does BindAttribLocation for "goten" and relink program
18975 * @param program Program object
18976 * @param program_interface Interface of program
18978 void VertexAttribLocationAPITest::prepareAttribLocation(Utils::Program& program,
18979 Utils::ProgramInterface& program_interface)
18981 const Functions& gl = m_context.getRenderContext().getFunctions();
18983 gl.bindAttribLocation(program.m_id, m_goten_location, "goten");
18984 GLU_EXPECT_NO_ERROR(gl.getError(), "BindAttribLocation");
18986 program.Link(gl, program.m_id);
18988 /* We still need to get locations for gohan and chichi */
18989 TextureTestBase::prepareAttribLocation(program, program_interface);
18992 /** Get interface of program
18995 * @param program_interface Interface of program
18998 void VertexAttribLocationAPITest::getProgramInterface(GLuint /* test_case_index */,
18999 Utils::ProgramInterface& program_interface,
19000 Utils::VaryingPassthrough& /* varying_passthrough */)
19002 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
19003 const Utils::Type& type = Utils::Type::vec4;
19004 const GLuint type_size = type.GetSize();
19007 const GLuint chichi_offset = 0;
19008 const GLuint goten_offset = chichi_offset + type_size;
19009 const GLuint gohan_offset = goten_offset + type_size;
19010 const GLuint goku_offset = gohan_offset + type_size;
19013 const GLuint goku_location = 2;
19014 const GLuint goten_location = m_goten_location;
19016 /* Generate data */
19017 m_goku_data = type.GenerateDataPacked();
19018 m_gohan_data = type.GenerateDataPacked();
19019 m_goten_data = type.GenerateDataPacked();
19020 m_chichi_data = type.GenerateDataPacked();
19023 si.m_globals = "const uint GOKU_LOCATION = 2;\n";
19026 si.Input("goku" /* name */, "layout (location = GOKU_LOCATION)" /* qualifiers */, 0 /* expected_componenet */,
19027 goku_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19028 0u /* n_array_elements */, 0u /* stride */, goku_offset /* offset */, (GLvoid*)&m_goku_data[0] /* data */,
19029 m_goku_data.size() /* data_size */);
19031 si.Input("gohan" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19032 Utils::Variable::m_automatic_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19033 0u /* n_array_elements */, 0u /* stride */, gohan_offset /* offset */,
19034 (GLvoid*)&m_gohan_data[0] /* data */, m_gohan_data.size() /* data_size */);
19036 si.Input("goten" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19037 goten_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19038 0u /* n_array_elements */, 0u /* stride */, goten_offset /* offset */,
19039 (GLvoid*)&m_goten_data[0] /* data */, m_goten_data.size() /* data_size */);
19041 si.Input("chichi" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19042 Utils::Variable::m_automatic_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19043 0u /* n_array_elements */, 0u /* stride */, chichi_offset /* offset */,
19044 (GLvoid*)&m_chichi_data[0] /* data */, m_chichi_data.size() /* data_size */);
19047 /** Selects if "compute" stage is relevant for test
19053 bool VertexAttribLocationAPITest::isComputeRelevant(GLuint /* test_case_index */)
19058 /* Constants used by FragmentDataLocationAPITest */
19059 const GLuint FragmentDataLocationAPITest::m_goten_location = 6;
19063 * @param context Test framework context
19065 FragmentDataLocationAPITest::FragmentDataLocationAPITest(deqp::Context& context)
19066 : TextureTestBase(context, "fragment_data_location_api",
19067 "Test verifies that fragment data locations API works as expected")
19071 , m_chichi(context)
19075 /** Verifies contents of drawn images
19080 * @return true if images are filled with expected values, false otherwise
19082 bool FragmentDataLocationAPITest::checkResults(glw::GLuint /* test_case_index */, Utils::Texture& /* color_0 */)
19084 static const GLuint size = m_width * m_height;
19085 static const GLuint expected_goku = 0xff000000;
19086 static const GLuint expected_gohan = 0xff0000ff;
19087 static const GLuint expected_goten = 0xff00ff00;
19088 static const GLuint expected_chichi = 0xffff0000;
19090 std::vector<GLuint> data;
19093 m_goku.Get(GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
19095 for (GLuint i = 0; i < size; ++i)
19097 const GLuint color = data[i];
19099 if (expected_goku != color)
19101 m_context.getTestContext().getLog() << tcu::TestLog::Message << "RGBA8[" << i << "]:" << color
19102 << tcu::TestLog::EndMessage;
19107 m_gohan.Get(GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
19109 for (GLuint i = 0; i < size; ++i)
19111 const GLuint color = data[i];
19113 if (expected_gohan != color)
19115 m_context.getTestContext().getLog() << tcu::TestLog::Message << "RGBA8[" << i << "]:" << color
19116 << tcu::TestLog::EndMessage;
19121 m_goten.Get(GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
19123 for (GLuint i = 0; i < size; ++i)
19125 const GLuint color = data[i];
19127 if (expected_goten != color)
19129 m_context.getTestContext().getLog() << tcu::TestLog::Message << "RGBA8[" << i << "]:" << color
19130 << tcu::TestLog::EndMessage;
19135 m_chichi.Get(GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
19137 for (GLuint i = 0; i < size; ++i)
19139 const GLuint color = data[i];
19141 if (expected_chichi != color)
19143 m_context.getTestContext().getLog() << tcu::TestLog::Message << "RGBA8[" << i << "]:" << color
19144 << tcu::TestLog::EndMessage;
19152 /** Prepare code snippet that will set out variables
19156 * @param stage Shader stage
19158 * @return Code that pass in variables to next stage
19160 std::string FragmentDataLocationAPITest::getPassSnippet(GLuint /* test_case_index */,
19161 Utils::VaryingPassthrough& /* varying_passthrough */,
19162 Utils::Shader::STAGES stage)
19164 std::string result;
19166 /* Skip for compute shader */
19167 if (Utils::Shader::FRAGMENT != stage)
19173 result = "chichi = vec4(0, 0, 1, 1);\n"
19174 " goku = vec4(0, 0, 0, 1);\n"
19175 " goten = vec4(0, 1, 0, 1);\n"
19176 " gohan = vec4(1, 0, 0, 1);\n";
19182 /** Get interface of program
19185 * @param program_interface Interface of program
19188 void FragmentDataLocationAPITest::getProgramInterface(GLuint /* test_case_index */,
19189 Utils::ProgramInterface& program_interface,
19190 Utils::VaryingPassthrough& /* varying_passthrough */)
19192 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
19193 const Utils::Type& type = Utils::Type::vec4;
19196 m_goku_location = 2;
19199 si.m_globals = "const uint GOKU_LOCATION = 2;\n";
19202 si.Output("goku" /* name */, "layout (location = GOKU_LOCATION)" /* qualifiers */, 0 /* expected_componenet */,
19203 m_goku_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19204 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)0 /* data */, 0u /* data_size */);
19206 si.Output("gohan" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19207 Utils::Variable::m_automatic_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19208 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)0 /* data */, 0u /* data_size */);
19210 si.Output("goten" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19211 m_goten_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19212 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)0 /* data */, 0u /* data_size */);
19214 si.Output("chichi" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19215 Utils::Variable::m_automatic_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19216 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)0 /* data */, 0u /* data_size */);
19219 /** Selects if "compute" stage is relevant for test
19225 bool FragmentDataLocationAPITest::isComputeRelevant(GLuint /* test_case_index */)
19230 /** Get locations for all outputs with automatic_location
19232 * @param program Program object
19233 * @param program_interface Interface of program
19235 void FragmentDataLocationAPITest::prepareFragmentDataLoc(Utils::Program& program,
19236 Utils::ProgramInterface& program_interface)
19238 /* Bind location of goten */
19239 const Functions& gl = m_context.getRenderContext().getFunctions();
19241 gl.bindFragDataLocation(program.m_id, m_goten_location, "goten");
19242 GLU_EXPECT_NO_ERROR(gl.getError(), "BindFragDataLocation");
19244 program.Link(gl, program.m_id);
19246 /* Prepare locations for gohan and chichi */
19247 TextureTestBase::prepareFragmentDataLoc(program, program_interface);
19249 /* Get all locations */
19250 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
19252 Utils::Variable::PtrVector& outputs = si.m_outputs;
19254 for (Utils::Variable::PtrVector::iterator it = outputs.begin(); outputs.end() != it; ++it)
19256 const Utils::Variable::Descriptor& desc = (*it)->m_descriptor;
19258 if (0 == desc.m_name.compare("gohan"))
19260 m_gohan_location = desc.m_expected_location;
19262 else if (0 == desc.m_name.compare("chichi"))
19264 m_chichi_location = desc.m_expected_location;
19267 /* Locations of goku and goten are fixed */
19271 /** Prepare framebuffer with single texture as color attachment
19273 * @param framebuffer Framebuffer
19274 * @param color_0_texture Texture that will used as color attachment
19276 void FragmentDataLocationAPITest::prepareFramebuffer(Utils::Framebuffer& framebuffer, Utils::Texture& color_0_texture)
19278 /* Let parent prepare its stuff */
19279 TextureTestBase::prepareFramebuffer(framebuffer, color_0_texture);
19282 std::vector<GLuint> texture_data;
19283 texture_data.resize(m_width * m_height);
19285 for (GLuint i = 0; i < texture_data.size(); ++i)
19287 texture_data[i] = 0x20406080;
19290 /* Prepare textures */
19291 m_goku.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]);
19293 m_gohan.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]);
19295 m_goten.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]);
19297 m_chichi.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]);
19299 /* Attach textures to framebuffer */
19300 framebuffer.Bind();
19301 framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0 + m_goku_location, m_goku.m_id, m_width, m_height);
19302 framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0 + m_gohan_location, m_gohan.m_id, m_width, m_height);
19303 framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0 + m_goten_location, m_goten.m_id, m_width, m_height);
19304 framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0 + m_chichi_location, m_chichi.m_id, m_width, m_height);
19306 /* Set up drawbuffers */
19307 const Functions& gl = m_context.getRenderContext().getFunctions();
19308 // 1. There are only 4 outputs in fragment shader, so only need to do buffer mapping for 4 attachments,
19309 // 2. another issue is each output variable has a location, it is the fragment color index, so the index of
19310 // GL_COLOR_ATTACHMENT in glDrawBuffers() should keep the same with the location, to make test correct,
19311 // we needt to change the above code of glDrawBuffers() as :
19312 GLint buffers_size = 4;
19313 GLenum buffers[] = { GLenum(GL_COLOR_ATTACHMENT0 + m_chichi_location),
19314 GLenum(GL_COLOR_ATTACHMENT0 + m_goku_location),
19315 GLenum(GL_COLOR_ATTACHMENT0 + m_goten_location),
19316 GLenum(GL_COLOR_ATTACHMENT0 + m_gohan_location) };
19317 gl.drawBuffers(buffers_size, buffers);
19318 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawBuffers");
19323 * @param context Test framework context
19325 XFBInputTest::XFBInputTest(deqp::Context& context)
19326 : NegativeTestBase(context, "xfb_input",
19327 "Test verifies that compiler reports error when xfb qualifiers are used with input")
19331 /** Source for given test case and stage
19333 * @param test_case_index Index of test case
19334 * @param stage Shader stage
19336 * @return Shader source
19338 std::string XFBInputTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
19340 static const GLchar* buffer_var_definition = "layout (xfb_buffer = 2) in vec4 gohanARRAY;\n";
19341 static const GLchar* offset_var_definition = "layout (xfb_offset = 16) in vec4 gohanARRAY;\n";
19342 static const GLchar* stride_var_definition = "layout (xfb_stride = 32) in vec4 gohanARRAY;\n";
19343 static const GLchar* input_use = " result += gohanINDEX;\n";
19344 static const GLchar* fs = "#version 430 core\n"
19345 "#extension GL_ARB_enhanced_layouts : require\n"
19348 "out vec4 fs_out;\n"
19352 " fs_out = gs_fs;\n"
19355 static const GLchar* fs_tested = "#version 430 core\n"
19356 "#extension GL_ARB_enhanced_layouts : require\n"
19361 "out vec4 fs_out;\n"
19365 " vec4 result = gs_fs;\n"
19369 " fs_out = result;\n"
19372 static const GLchar* gs = "#version 430 core\n"
19373 "#extension GL_ARB_enhanced_layouts : require\n"
19375 "layout(points) in;\n"
19376 "layout(triangle_strip, max_vertices = 4) out;\n"
19378 "in vec4 tes_gs[];\n"
19379 "out vec4 gs_fs;\n"
19383 " gs_fs = tes_gs[0];\n"
19384 " gl_Position = vec4(-1, -1, 0, 1);\n"
19386 " gs_fs = tes_gs[0];\n"
19387 " gl_Position = vec4(-1, 1, 0, 1);\n"
19389 " gs_fs = tes_gs[0];\n"
19390 " gl_Position = vec4(1, -1, 0, 1);\n"
19392 " gs_fs = tes_gs[0];\n"
19393 " gl_Position = vec4(1, 1, 0, 1);\n"
19397 static const GLchar* gs_tested = "#version 430 core\n"
19398 "#extension GL_ARB_enhanced_layouts : require\n"
19400 "layout(points) in;\n"
19401 "layout(triangle_strip, max_vertices = 4) out;\n"
19405 "in vec4 tes_gs[];\n"
19406 "out vec4 gs_fs;\n"
19410 " vec4 result = tes_gs[0];\n"
19414 " gs_fs = result;\n"
19415 " gl_Position = vec4(-1, -1, 0, 1);\n"
19417 " gs_fs = result;\n"
19418 " gl_Position = vec4(-1, 1, 0, 1);\n"
19420 " gs_fs = result;\n"
19421 " gl_Position = vec4(1, -1, 0, 1);\n"
19423 " gs_fs = result;\n"
19424 " gl_Position = vec4(1, 1, 0, 1);\n"
19428 static const GLchar* tcs = "#version 430 core\n"
19429 "#extension GL_ARB_enhanced_layouts : require\n"
19431 "layout(vertices = 1) out;\n"
19433 "in vec4 vs_tcs[];\n"
19434 "out vec4 tcs_tes[];\n"
19439 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
19441 " gl_TessLevelOuter[0] = 1.0;\n"
19442 " gl_TessLevelOuter[1] = 1.0;\n"
19443 " gl_TessLevelOuter[2] = 1.0;\n"
19444 " gl_TessLevelOuter[3] = 1.0;\n"
19445 " gl_TessLevelInner[0] = 1.0;\n"
19446 " gl_TessLevelInner[1] = 1.0;\n"
19449 static const GLchar* tcs_tested = "#version 430 core\n"
19450 "#extension GL_ARB_enhanced_layouts : require\n"
19452 "layout(vertices = 1) out;\n"
19456 "in vec4 vs_tcs[];\n"
19457 "out vec4 tcs_tes[];\n"
19461 " vec4 result = vs_tcs[gl_InvocationID];\n"
19465 " tcs_tes[gl_InvocationID] = result;\n"
19467 " gl_TessLevelOuter[0] = 1.0;\n"
19468 " gl_TessLevelOuter[1] = 1.0;\n"
19469 " gl_TessLevelOuter[2] = 1.0;\n"
19470 " gl_TessLevelOuter[3] = 1.0;\n"
19471 " gl_TessLevelInner[0] = 1.0;\n"
19472 " gl_TessLevelInner[1] = 1.0;\n"
19475 static const GLchar* tes = "#version 430 core\n"
19476 "#extension GL_ARB_enhanced_layouts : require\n"
19478 "layout(isolines, point_mode) in;\n"
19480 "in vec4 tcs_tes[];\n"
19481 "out vec4 tes_gs;\n"
19485 " tes_gs = tcs_tes[0];\n"
19488 static const GLchar* tes_tested = "#version 430 core\n"
19489 "#extension GL_ARB_enhanced_layouts : require\n"
19491 "layout(isolines, point_mode) in;\n"
19495 "in vec4 tcs_tes[];\n"
19496 "out vec4 tes_gs;\n"
19500 " vec4 result = tcs_tes[0];\n"
19504 " tes_gs += result;\n"
19507 static const GLchar* vs = "#version 430 core\n"
19508 "#extension GL_ARB_enhanced_layouts : require\n"
19511 "out vec4 vs_tcs;\n"
19515 " vs_tcs = in_vs;\n"
19518 static const GLchar* vs_tested = "#version 430 core\n"
19519 "#extension GL_ARB_enhanced_layouts : require\n"
19524 "out vec4 vs_tcs;\n"
19528 " vec4 result = in_vs;\n"
19532 " vs_tcs += result;\n"
19536 std::string source;
19537 testCase& test_case = m_test_cases[test_case_index];
19539 if (test_case.m_stage == stage)
19541 const GLchar* array = "";
19542 const GLchar* index = "";
19543 size_t position = 0;
19545 const GLchar* var_definition = 0;
19546 const GLchar* var_use = input_use;
19548 switch (test_case.m_qualifier)
19551 var_definition = buffer_var_definition;
19554 var_definition = offset_var_definition;
19557 var_definition = stride_var_definition;
19560 TCU_FAIL("Invalid enum");
19565 case Utils::Shader::FRAGMENT:
19566 source = fs_tested;
19568 case Utils::Shader::GEOMETRY:
19569 source = gs_tested;
19573 case Utils::Shader::TESS_CTRL:
19574 source = tcs_tested;
19576 index = "[gl_InvocationID]";
19578 case Utils::Shader::TESS_EVAL:
19579 source = tes_tested;
19583 case Utils::Shader::VERTEX:
19584 source = vs_tested;
19587 TCU_FAIL("Invalid enum");
19591 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
19593 Utils::replaceToken("ARRAY", position, array, source);
19594 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
19596 Utils::replaceAllTokens("INDEX", index, source);
19602 case Utils::Shader::FRAGMENT:
19605 case Utils::Shader::GEOMETRY:
19608 case Utils::Shader::TESS_CTRL:
19611 case Utils::Shader::TESS_EVAL:
19614 case Utils::Shader::VERTEX:
19618 TCU_FAIL("Invalid enum");
19625 /** Get description of test case
19627 * @param test_case_index Index of test case
19629 * @return Test case description
19631 std::string XFBInputTest::getTestCaseName(GLuint test_case_index)
19633 std::stringstream stream;
19634 testCase& test_case = m_test_cases[test_case_index];
19636 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", qualifier: ";
19638 switch (test_case.m_qualifier)
19641 stream << "xfb_buffer";
19644 stream << "xfb_offset";
19647 stream << "xfb_stride";
19650 TCU_FAIL("Invalid enum");
19653 return stream.str();
19656 /** Get number of test cases
19658 * @return Number of test cases
19660 GLuint XFBInputTest::getTestCaseNumber()
19662 return static_cast<GLuint>(m_test_cases.size());
19665 /** Selects if "compute" stage is relevant for test
19671 bool XFBInputTest::isComputeRelevant(GLuint /* test_case_index */)
19676 /** Prepare all test cases
19679 void XFBInputTest::testInit()
19681 for (GLuint qualifier = 0; qualifier < QUALIFIERS_MAX; ++qualifier)
19683 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
19685 if (Utils::Shader::COMPUTE == stage)
19690 testCase test_case = { (QUALIFIERS)qualifier, (Utils::Shader::STAGES)stage };
19692 m_test_cases.push_back(test_case);
19697 /* Constants used by XFBAllStagesTest */
19698 const GLuint XFBAllStagesTest::m_gs_index = 3;
19702 * @param context Test context
19704 XFBAllStagesTest::XFBAllStagesTest(deqp::Context& context)
19705 : BufferTestBase(context, "xfb_all_stages",
19706 "Test verifies that only last stage in vertex processing can output to transform feedback")
19708 /* Nothing to be done here */
19711 /** Get descriptors of buffers necessary for test
19714 * @param out_descriptors Descriptors of buffers used by test
19716 void XFBAllStagesTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
19717 bufferDescriptor::Vector& out_descriptors)
19719 static const GLuint n_stages = 4;
19720 const Utils::Type& vec4 = Utils::Type::vec4;
19725 /* Test uses single uniform and xfb per stage + uniform for fragment shader */
19726 out_descriptors.resize(n_stages * 2 + 1);
19729 for (GLuint i = 0; i < n_stages; ++i)
19731 /* Get references */
19732 bufferDescriptor& uniform = out_descriptors[i + 0];
19733 bufferDescriptor& xfb = out_descriptors[i + n_stages];
19736 uniform.m_index = i;
19740 uniform.m_target = Utils::Buffer::Uniform;
19741 xfb.m_target = Utils::Buffer::Transform_feedback;
19744 const tcu::Vec4 var(Utils::GetRandFloat(), Utils::GetRandFloat(), Utils::GetRandFloat(), Utils::GetRandFloat());
19748 uniform.m_initial_data.resize(vec4.GetSize());
19749 memcpy(&uniform.m_initial_data[0], var.getPtr(), vec4.GetSize());
19751 xfb.m_initial_data = vec4.GenerateDataPacked();
19753 if (m_gs_index != i)
19755 xfb.m_expected_data = xfb.m_initial_data;
19759 xfb.m_expected_data.resize(vec4.GetSize());
19760 memcpy(&xfb.m_expected_data[0], sum.getPtr(), vec4.GetSize());
19766 /* Get reference */
19767 bufferDescriptor& uniform = out_descriptors[n_stages * 2];
19770 uniform.m_index = n_stages;
19773 uniform.m_target = Utils::Buffer::Uniform;
19776 const tcu::Vec4 var(Utils::GetRandFloat(), Utils::GetRandFloat(), Utils::GetRandFloat(), Utils::GetRandFloat());
19778 uniform.m_initial_data.resize(vec4.GetSize());
19779 memcpy(&uniform.m_initial_data[0], var.getPtr(), vec4.GetSize());
19783 /** Get body of main function for given shader stage
19786 * @param stage Shader stage
19787 * @param out_assignments Set to empty
19788 * @param out_calculations Set to empty
19790 void XFBAllStagesTest::getShaderBody(glw::GLuint /* test_case_index */, Utils::Shader::STAGES stage,
19791 std::string& out_assignments, std::string& out_calculations)
19793 out_calculations = "";
19795 static const GLchar* vs = " vs_tcs = uni_vs;\n";
19796 static const GLchar* tcs = " tcs_tes[gl_InvocationID] = uni_tcs + vs_tcs[gl_InvocationID];\n";
19797 static const GLchar* tes = " tes_gs = uni_tes + tcs_tes[0];\n";
19798 static const GLchar* gs = " gs_fs = uni_gs + tes_gs[0];\n";
19799 static const GLchar* fs = " fs_out = uni_fs + gs_fs;\n";
19801 const GLchar* assignments = 0;
19804 case Utils::Shader::FRAGMENT:
19807 case Utils::Shader::GEOMETRY:
19810 case Utils::Shader::TESS_CTRL:
19813 case Utils::Shader::TESS_EVAL:
19816 case Utils::Shader::VERTEX:
19820 TCU_FAIL("Invalid enum");
19823 out_assignments = assignments;
19826 /** Get interface of shader
19829 * @param stage Shader stage
19830 * @param out_interface Set to ""
19832 void XFBAllStagesTest::getShaderInterface(glw::GLuint /* test_case_index */, Utils::Shader::STAGES stage,
19833 std::string& out_interface)
19835 static const GLchar* vs = "layout(xfb_buffer = 0, xfb_offset = 0) out vec4 vs_tcs;\n"
19836 "layout(binding = 0) uniform vs_block {\n"
19839 static const GLchar* tcs = " in vec4 vs_tcs[];\n"
19840 "layout(xfb_buffer = 1, xfb_offset = 0) out vec4 tcs_tes[1];\n"
19841 "layout(binding = 1) uniform tcs_block {\n"
19844 static const GLchar* tes = " in vec4 tcs_tes[];\n"
19845 "layout(xfb_buffer = 2, xfb_offset = 0) out vec4 tes_gs;\n"
19846 "layout(binding = 2) uniform tes_block {\n"
19849 static const GLchar* gs = " in vec4 tes_gs[];\n"
19850 "layout(xfb_buffer = 3, xfb_offset = 0) out vec4 gs_fs;\n"
19851 "layout(binding = 3) uniform gs_block {\n"
19854 static const GLchar* fs = " in vec4 gs_fs;\n"
19855 " out vec4 fs_out;\n"
19856 "layout(binding = 4) uniform fs_block {\n"
19860 const GLchar* interface = 0;
19863 case Utils::Shader::FRAGMENT:
19866 case Utils::Shader::GEOMETRY:
19869 case Utils::Shader::TESS_CTRL:
19872 case Utils::Shader::TESS_EVAL:
19875 case Utils::Shader::VERTEX:
19879 TCU_FAIL("Invalid enum");
19882 out_interface = interface;
19885 /* Constants used by XFBStrideOfEmptyListTest */
19886 const GLuint XFBStrideOfEmptyListTest::m_stride = 64;
19890 * @param context Test context
19892 XFBStrideOfEmptyListTest::XFBStrideOfEmptyListTest(deqp::Context& context)
19893 : BufferTestBase(context, "xfb_stride_of_empty_list",
19894 "Test verifies that xfb_stride qualifier is respected when no xfb_offset is specified")
19896 /* Nothing to be done here */
19899 /** Execute drawArrays for single vertex
19901 * @param test_case_index Index of test case
19903 * @return true if proper error is reported
19905 bool XFBStrideOfEmptyListTest::executeDrawCall(GLuint test_case_index)
19907 const Functions& gl = m_context.getRenderContext().getFunctions();
19908 bool result = true;
19911 gl.disable(GL_RASTERIZER_DISCARD);
19912 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
19914 gl.beginTransformFeedback(GL_POINTS);
19915 GLenum error = gl.getError();
19916 switch (test_case_index)
19919 if (GL_NO_ERROR != error)
19921 gl.endTransformFeedback();
19922 GLU_EXPECT_NO_ERROR(error, "BeginTransformFeedback");
19925 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
19926 error = gl.getError();
19928 gl.endTransformFeedback();
19929 GLU_EXPECT_NO_ERROR(error, "DrawArrays");
19930 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
19934 case FIRST_MISSING:
19935 if (GL_NO_ERROR == error)
19937 gl.endTransformFeedback();
19940 if (GL_INVALID_OPERATION != error)
19942 m_context.getTestContext().getLog()
19943 << tcu::TestLog::Message << "XFB at index 0, that is written by GS, is missing. It was expected that "
19944 "INVALID_OPERATION will generated by BeginTransformFeedback. Got: "
19945 << glu::getErrorStr(error) << tcu::TestLog::EndMessage;
19952 case SECOND_MISSING:
19953 if (GL_NO_ERROR == error)
19955 gl.endTransformFeedback();
19958 if (GL_INVALID_OPERATION != error)
19960 m_context.getTestContext().getLog()
19961 << tcu::TestLog::Message << "XFB at index 1, that is declared as empty, is missing. It was expected "
19962 "that INVALID_OPERATION will generated by BeginTransformFeedback. Got: "
19963 << glu::getErrorStr(error) << tcu::TestLog::EndMessage;
19975 /** Get descriptors of buffers necessary for test
19977 * @param test_case_index Index of test case
19978 * @param out_descriptors Descriptors of buffers used by test
19980 void XFBStrideOfEmptyListTest::getBufferDescriptors(glw::GLuint test_case_index,
19981 bufferDescriptor::Vector& out_descriptors)
19983 switch (test_case_index)
19987 /* Test needs single uniform and two xfbs */
19988 out_descriptors.resize(3);
19990 /* Get references */
19991 bufferDescriptor& uniform = out_descriptors[0];
19992 bufferDescriptor& xfb_0 = out_descriptors[1];
19993 bufferDescriptor& xfb_1 = out_descriptors[2];
19996 uniform.m_index = 0;
20001 uniform.m_target = Utils::Buffer::Uniform;
20002 xfb_0.m_target = Utils::Buffer::Transform_feedback;
20003 xfb_1.m_target = Utils::Buffer::Transform_feedback;
20006 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20008 xfb_0.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20009 xfb_0.m_expected_data = uniform.m_initial_data;
20011 /* Data, contents are the same as no modification is expected */
20012 xfb_1.m_initial_data.resize(m_stride);
20013 xfb_1.m_expected_data.resize(m_stride);
20015 for (GLuint i = 0; i < m_stride; ++i)
20017 xfb_1.m_initial_data[0] = (glw::GLubyte)i;
20018 xfb_1.m_expected_data[0] = (glw::GLubyte)i;
20024 case FIRST_MISSING:
20026 /* Test needs single uniform and two xfbs */
20027 out_descriptors.resize(2);
20029 /* Get references */
20030 bufferDescriptor& uniform = out_descriptors[0];
20031 bufferDescriptor& xfb_1 = out_descriptors[1];
20034 uniform.m_index = 0;
20038 uniform.m_target = Utils::Buffer::Uniform;
20039 xfb_1.m_target = Utils::Buffer::Transform_feedback;
20042 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20044 /* Draw call will not be executed, contents does not matter */
20045 xfb_1.m_initial_data.resize(m_stride);
20050 case SECOND_MISSING:
20052 /* Test needs single uniform and two xfbs */
20053 out_descriptors.resize(2);
20055 /* Get references */
20056 bufferDescriptor& uniform = out_descriptors[0];
20057 bufferDescriptor& xfb_0 = out_descriptors[1];
20060 uniform.m_index = 0;
20064 uniform.m_target = Utils::Buffer::Uniform;
20065 xfb_0.m_target = Utils::Buffer::Transform_feedback;
20068 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20070 /* Draw call will not be executed, contents does not matter */
20071 xfb_0.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20078 /** Get body of main function for given shader stage
20081 * @param stage Shader stage
20082 * @param out_assignments Set to empty
20083 * @param out_calculations Set to empty
20085 void XFBStrideOfEmptyListTest::getShaderBody(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
20086 std::string& out_assignments, std::string& out_calculations)
20088 out_calculations = "";
20090 static const GLchar* gs = " gs_fs = uni_gs;\n";
20091 static const GLchar* fs = " fs_out = vec4(gs_fs);\n";
20093 const GLchar* assignments = "";
20096 case Utils::Shader::FRAGMENT:
20099 case Utils::Shader::GEOMETRY:
20106 out_assignments = assignments;
20109 /** Get interface of shader
20112 * @param stage Shader stage
20113 * @param out_interface Set to ""
20115 void XFBStrideOfEmptyListTest::getShaderInterface(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
20116 std::string& out_interface)
20118 static const GLchar* gs = "layout (xfb_buffer = 0, xfb_offset = 0) out vec4 gs_fs;\n"
20119 "layout (xfb_buffer = 1, xfb_stride = 64) out;\n"
20121 "layout (binding = 0) uniform gs_block {\n"
20124 static const GLchar* fs = "in vec4 gs_fs;\n"
20125 "out vec4 fs_out;\n";
20129 case Utils::Shader::FRAGMENT:
20130 out_interface = fs;
20132 case Utils::Shader::GEOMETRY:
20133 out_interface = gs;
20136 out_interface = "";
20141 /** Returns buffer details in human readable form.
20143 * @param test_case_index Index of test case
20145 * @return Case description
20147 std::string XFBStrideOfEmptyListTest::getTestCaseName(GLuint test_case_index)
20149 std::string result;
20151 switch (test_case_index)
20154 result = "Valid case";
20156 case FIRST_MISSING:
20157 result = "Missing xfb at index 0";
20159 case SECOND_MISSING:
20160 result = "Missing xfb at index 1";
20163 TCU_FAIL("Invalid enum");
20169 /** Get number of test cases
20173 GLuint XFBStrideOfEmptyListTest::getTestCaseNumber()
20178 /* Constants used by XFBStrideOfEmptyListTest */
20179 const GLuint XFBStrideOfEmptyListAndAPITest::m_stride = 64;
20183 * @param context Test context
20185 XFBStrideOfEmptyListAndAPITest::XFBStrideOfEmptyListAndAPITest(deqp::Context& context)
20186 : BufferTestBase(context, "xfb_stride_of_empty_list_and_api",
20187 "Test verifies that xfb_stride qualifier is not overriden by API")
20189 /* Nothing to be done here */
20192 /** Execute drawArrays for single vertex
20194 * @param test_case_index Index of test case
20196 * @return true if proper error is reported
20198 bool XFBStrideOfEmptyListAndAPITest::executeDrawCall(GLuint test_case_index)
20200 const Functions& gl = m_context.getRenderContext().getFunctions();
20201 bool result = true;
20204 gl.disable(GL_RASTERIZER_DISCARD);
20205 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
20207 gl.beginTransformFeedback(GL_POINTS);
20208 GLenum error = gl.getError();
20209 switch (test_case_index)
20212 if (GL_NO_ERROR != error)
20214 gl.endTransformFeedback();
20215 GLU_EXPECT_NO_ERROR(error, "BeginTransformFeedback");
20218 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
20219 error = gl.getError();
20221 gl.endTransformFeedback();
20222 GLU_EXPECT_NO_ERROR(error, "DrawArrays");
20223 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
20227 case FIRST_MISSING:
20228 if (GL_NO_ERROR == error)
20230 gl.endTransformFeedback();
20233 if (GL_INVALID_OPERATION != error)
20235 m_context.getTestContext().getLog()
20236 << tcu::TestLog::Message << "XFB at index 0, that is declared as empty, is missing. It was expected "
20237 "that INVALID_OPERATION will generated by BeginTransformFeedback. Got: "
20238 << glu::getErrorStr(error) << tcu::TestLog::EndMessage;
20245 case SECOND_MISSING:
20246 if (GL_NO_ERROR == error)
20248 gl.endTransformFeedback();
20251 if (GL_INVALID_OPERATION != error)
20253 m_context.getTestContext().getLog()
20254 << tcu::TestLog::Message << "XFB at index 1, that is written by GS, is missing. It was expected that "
20255 "INVALID_OPERATION will generated by BeginTransformFeedback. Got: "
20256 << glu::getErrorStr(error) << tcu::TestLog::EndMessage;
20268 /** Get descriptors of buffers necessary for test
20270 * @param test_case_index Index of test case
20271 * @param out_descriptors Descriptors of buffers used by test
20273 void XFBStrideOfEmptyListAndAPITest::getBufferDescriptors(glw::GLuint test_case_index,
20274 bufferDescriptor::Vector& out_descriptors)
20276 switch (test_case_index)
20280 /* Test needs single uniform and two xfbs */
20281 out_descriptors.resize(3);
20283 /* Get references */
20284 bufferDescriptor& uniform = out_descriptors[0];
20285 bufferDescriptor& xfb_0 = out_descriptors[1];
20286 bufferDescriptor& xfb_1 = out_descriptors[2];
20289 uniform.m_index = 0;
20294 uniform.m_target = Utils::Buffer::Uniform;
20295 xfb_0.m_target = Utils::Buffer::Transform_feedback;
20296 xfb_1.m_target = Utils::Buffer::Transform_feedback;
20299 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20301 /* Data, contents are the same as no modification is expected */
20302 xfb_0.m_initial_data.resize(m_stride);
20303 xfb_0.m_expected_data.resize(m_stride);
20305 for (GLuint i = 0; i < m_stride; ++i)
20307 xfb_0.m_initial_data[0] = (glw::GLubyte)i;
20308 xfb_0.m_expected_data[0] = (glw::GLubyte)i;
20311 xfb_1.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20312 xfb_1.m_expected_data = uniform.m_initial_data;
20317 case FIRST_MISSING:
20319 /* Test needs single uniform and two xfbs */
20320 out_descriptors.resize(2);
20322 /* Get references */
20323 bufferDescriptor& uniform = out_descriptors[0];
20324 bufferDescriptor& xfb_1 = out_descriptors[1];
20327 uniform.m_index = 0;
20331 uniform.m_target = Utils::Buffer::Uniform;
20332 xfb_1.m_target = Utils::Buffer::Transform_feedback;
20335 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20337 /* Draw call will not be executed, contents does not matter */
20338 xfb_1.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20343 case SECOND_MISSING:
20345 /* Test needs single uniform and two xfbs */
20346 out_descriptors.resize(2);
20348 /* Get references */
20349 bufferDescriptor& uniform = out_descriptors[0];
20350 bufferDescriptor& xfb_0 = out_descriptors[1];
20353 uniform.m_index = 0;
20357 uniform.m_target = Utils::Buffer::Uniform;
20358 xfb_0.m_target = Utils::Buffer::Transform_feedback;
20361 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20363 /* Draw call will not be executed, contents does not matter */
20364 xfb_0.m_initial_data.resize(m_stride);
20371 /** Get list of names of varyings that will be registered with TransformFeedbackVaryings
20374 * @param captured_varyings Vector of varying names to be captured
20376 void XFBStrideOfEmptyListAndAPITest::getCapturedVaryings(glw::GLuint /* test_case_index */,
20377 Utils::Program::NameVector& captured_varyings)
20379 captured_varyings.push_back("gs_fs");
20382 /** Get body of main function for given shader stage
20385 * @param stage Shader stage
20386 * @param out_assignments Set to empty
20387 * @param out_calculations Set to empty
20389 void XFBStrideOfEmptyListAndAPITest::getShaderBody(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
20390 std::string& out_assignments, std::string& out_calculations)
20392 out_calculations = "";
20394 static const GLchar* gs = " gs_fs = uni_gs;\n";
20395 static const GLchar* fs = " fs_out = vec4(gs_fs);\n";
20397 const GLchar* assignments = "";
20400 case Utils::Shader::FRAGMENT:
20403 case Utils::Shader::GEOMETRY:
20410 out_assignments = assignments;
20413 /** Get interface of shader
20416 * @param stage Shader stage
20417 * @param out_interface Set to ""
20419 void XFBStrideOfEmptyListAndAPITest::getShaderInterface(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
20420 std::string& out_interface)
20422 static const GLchar* gs = "layout (xfb_buffer = 0, xfb_stride = 64) out;\n"
20423 "layout (xfb_buffer = 1, xfb_offset = 0) out vec4 gs_fs;\n"
20425 "layout(binding = 0) uniform gs_block {\n"
20428 static const GLchar* fs = "in vec4 gs_fs;\n"
20429 "out vec4 fs_out;\n";
20433 case Utils::Shader::FRAGMENT:
20434 out_interface = fs;
20436 case Utils::Shader::GEOMETRY:
20437 out_interface = gs;
20440 out_interface = "";
20445 /** Returns buffer details in human readable form.
20447 * @param test_case_index Index of test case
20449 * @return Case description
20451 std::string XFBStrideOfEmptyListAndAPITest::getTestCaseName(GLuint test_case_index)
20453 std::string result;
20455 switch (test_case_index)
20458 result = "Valid case";
20460 case FIRST_MISSING:
20461 result = "Missing xfb at index 0";
20463 case SECOND_MISSING:
20464 result = "Missing xfb at index 1";
20467 TCU_FAIL("Invalid enum");
20473 /** Get number of test cases
20477 GLuint XFBStrideOfEmptyListAndAPITest::getTestCaseNumber()
20484 * @param context Test framework context
20486 XFBTooSmallStrideTest::XFBTooSmallStrideTest(deqp::Context& context)
20487 : NegativeTestBase(context, "xfb_too_small_stride",
20488 "Test verifies that compiler reports error when xfb_stride sets not enough space")
20492 /** Source for given test case and stage
20494 * @param test_case_index Index of test case
20495 * @param stage Shader stage
20497 * @return Shader source
20499 std::string XFBTooSmallStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
20501 static const GLchar* array_var_definition = "layout (xfb_buffer = 0, xfb_stride = 32) out;\n"
20503 "layout (xfb_offset = 16) out vec4 gohanARRAY[4];\n";
20504 static const GLchar* block_var_definition = "layout (xfb_buffer = 0, xfb_stride = 32) out;\n"
20506 "layout (xfb_offset = 0) out Goku {\n"
20511 static const GLchar* offset_var_definition = "layout (xfb_buffer = 0, xfb_stride = 40) out;\n"
20513 "layout (xfb_offset = 32) out vec4 gohanARRAY;\n";
20514 // 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;"
20515 // To make the shader failed to compile, change xfb_stride to a value that is smaller than 32
20516 static const GLchar* stride_var_definition = "layout (xfb_buffer = 0, xfb_stride = 28) out;\n"
20518 "layout (xfb_offset = 16, xfb_stride = 28) out vec4 gohanARRAY;\n";
20519 static const GLchar* array_use = " gohanINDEX[0] = result / 2;\n"
20520 " gohanINDEX[1] = result / 4;\n"
20521 " gohanINDEX[2] = result / 6;\n"
20522 " gohanINDEX[3] = result / 8;\n";
20523 static const GLchar* block_use = " gokuINDEX.gohan = result / 2;\n"
20524 " gokuINDEX.goten = result / 4;\n"
20525 " gokuINDEX.chichi = result / 6;\n";
20526 static const GLchar* output_use = "gohanINDEX = result / 4;\n";
20527 static const GLchar* fs = "#version 430 core\n"
20528 "#extension GL_ARB_enhanced_layouts : require\n"
20531 "out vec4 fs_out;\n"
20535 " fs_out = gs_fs;\n"
20538 static const GLchar* gs_tested = "#version 430 core\n"
20539 "#extension GL_ARB_enhanced_layouts : require\n"
20541 "layout(points) in;\n"
20542 "layout(triangle_strip, max_vertices = 4) out;\n"
20546 "in vec4 tes_gs[];\n"
20547 "out vec4 gs_fs;\n"
20551 " vec4 result = tes_gs[0];\n"
20555 " gs_fs = result;\n"
20556 " gl_Position = vec4(-1, -1, 0, 1);\n"
20558 " gs_fs = result;\n"
20559 " gl_Position = vec4(-1, 1, 0, 1);\n"
20561 " gs_fs = result;\n"
20562 " gl_Position = vec4(1, -1, 0, 1);\n"
20564 " gs_fs = result;\n"
20565 " gl_Position = vec4(1, 1, 0, 1);\n"
20569 static const GLchar* tcs = "#version 430 core\n"
20570 "#extension GL_ARB_enhanced_layouts : require\n"
20572 "layout(vertices = 1) out;\n"
20574 "in vec4 vs_tcs[];\n"
20575 "out vec4 tcs_tes[];\n"
20580 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
20582 " gl_TessLevelOuter[0] = 1.0;\n"
20583 " gl_TessLevelOuter[1] = 1.0;\n"
20584 " gl_TessLevelOuter[2] = 1.0;\n"
20585 " gl_TessLevelOuter[3] = 1.0;\n"
20586 " gl_TessLevelInner[0] = 1.0;\n"
20587 " gl_TessLevelInner[1] = 1.0;\n"
20590 static const GLchar* tcs_tested = "#version 430 core\n"
20591 "#extension GL_ARB_enhanced_layouts : require\n"
20593 "layout(vertices = 1) out;\n"
20597 "in vec4 vs_tcs[];\n"
20598 "out vec4 tcs_tes[];\n"
20602 " vec4 result = vs_tcs[gl_InvocationID];\n"
20606 " tcs_tes[gl_InvocationID] = result;\n"
20608 " gl_TessLevelOuter[0] = 1.0;\n"
20609 " gl_TessLevelOuter[1] = 1.0;\n"
20610 " gl_TessLevelOuter[2] = 1.0;\n"
20611 " gl_TessLevelOuter[3] = 1.0;\n"
20612 " gl_TessLevelInner[0] = 1.0;\n"
20613 " gl_TessLevelInner[1] = 1.0;\n"
20616 static const GLchar* tes_tested = "#version 430 core\n"
20617 "#extension GL_ARB_enhanced_layouts : require\n"
20619 "layout(isolines, point_mode) in;\n"
20623 "in vec4 tcs_tes[];\n"
20624 "out vec4 tes_gs;\n"
20628 " vec4 result = tcs_tes[0];\n"
20632 " tes_gs += result;\n"
20635 static const GLchar* vs = "#version 430 core\n"
20636 "#extension GL_ARB_enhanced_layouts : require\n"
20639 "out vec4 vs_tcs;\n"
20643 " vs_tcs = in_vs;\n"
20646 static const GLchar* vs_tested = "#version 430 core\n"
20647 "#extension GL_ARB_enhanced_layouts : require\n"
20652 "out vec4 vs_tcs;\n"
20656 " vec4 result = in_vs;\n"
20660 " vs_tcs += result;\n"
20664 std::string source;
20665 testCase& test_case = m_test_cases[test_case_index];
20667 if (test_case.m_stage == stage)
20669 const GLchar* array = "";
20670 const GLchar* index = "";
20671 size_t position = 0;
20673 const GLchar* var_definition = 0;
20674 const GLchar* var_use = 0;
20676 switch (test_case.m_case)
20679 var_definition = offset_var_definition;
20680 var_use = output_use;
20683 var_definition = stride_var_definition;
20684 var_use = output_use;
20687 var_definition = block_var_definition;
20688 var_use = block_use;
20691 var_definition = array_var_definition;
20692 var_use = array_use;
20695 TCU_FAIL("Invalid enum");
20700 case Utils::Shader::GEOMETRY:
20701 source = gs_tested;
20705 case Utils::Shader::TESS_CTRL:
20706 source = tcs_tested;
20708 index = "[gl_InvocationID]";
20710 case Utils::Shader::TESS_EVAL:
20711 source = tes_tested;
20715 case Utils::Shader::VERTEX:
20716 source = vs_tested;
20719 TCU_FAIL("Invalid enum");
20723 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
20725 Utils::replaceToken("ARRAY", position, array, source);
20726 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
20728 Utils::replaceAllTokens("INDEX", index, source);
20732 switch (test_case.m_stage)
20734 case Utils::Shader::GEOMETRY:
20737 case Utils::Shader::FRAGMENT:
20740 case Utils::Shader::VERTEX:
20747 case Utils::Shader::TESS_CTRL:
20750 case Utils::Shader::FRAGMENT:
20753 case Utils::Shader::VERTEX:
20760 case Utils::Shader::TESS_EVAL:
20763 case Utils::Shader::FRAGMENT:
20766 case Utils::Shader::TESS_CTRL:
20769 case Utils::Shader::VERTEX:
20776 case Utils::Shader::VERTEX:
20779 case Utils::Shader::FRAGMENT:
20787 TCU_FAIL("Invalid enum");
20795 /** Get description of test case
20797 * @param test_case_index Index of test case
20799 * @return Test case description
20801 std::string XFBTooSmallStrideTest::getTestCaseName(GLuint test_case_index)
20803 std::stringstream stream;
20804 testCase& test_case = m_test_cases[test_case_index];
20806 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", case: ";
20808 switch (test_case.m_case)
20811 stream << "buffer stride: 40, vec4 offset: 32";
20814 stream << "buffer stride: 32, vec4 off 16 stride: 32";
20817 stream << "buffer stride: 32, block 3xvec4 offset 0";
20820 stream << "buffer stride: 32, vec4[4] offset 16";
20823 TCU_FAIL("Invalid enum");
20826 return stream.str();
20829 /** Get number of test cases
20831 * @return Number of test cases
20833 GLuint XFBTooSmallStrideTest::getTestCaseNumber()
20835 return static_cast<GLuint>(m_test_cases.size());
20838 /** Selects if "compute" stage is relevant for test
20844 bool XFBTooSmallStrideTest::isComputeRelevant(GLuint /* test_case_index */)
20849 /** Prepare all test cases
20852 void XFBTooSmallStrideTest::testInit()
20854 for (GLuint c = 0; c < CASE_MAX; ++c)
20856 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
20859 It is invalid to define transform feedback output in TCS, according to spec:
20860 The data captured in transform feedback mode depends on the active programs on each of the shader stages.
20861 If a program is active for the geometry shader stage, transform feedback captures the vertices of each
20862 primitive emitted by the geometry shader. Otherwise, if a program is active for the tessellation evaluation
20863 shader stage, transform feedback captures each primitive produced by the tessellation primitive generator,
20864 whose vertices are processed by the tessellation evaluation shader. Otherwise, transform feedback captures
20865 each primitive processed by the vertex shader.
20867 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
20868 (Utils::Shader::FRAGMENT == stage))
20873 testCase test_case = { (CASES)c, (Utils::Shader::STAGES)stage };
20875 m_test_cases.push_back(test_case);
20882 * @param context Test framework context
20884 XFBVariableStrideTest::XFBVariableStrideTest(deqp::Context& context)
20885 : NegativeTestBase(context, "xfb_variable_stride", "Test verifies that stride qualifier is respected")
20889 /** Source for given test case and stage
20891 * @param test_case_index Index of test case
20892 * @param stage Shader stage
20894 * @return Shader source
20896 std::string XFBVariableStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
20898 static const GLchar* invalid_var_definition =
20899 "const uint type_size = SIZE;\n"
20901 "layout (xfb_offset = 0, xfb_stride = 2 * type_size) out TYPE gokuARRAY;\n"
20902 "layout (xfb_offset = type_size) out TYPE vegetaARRAY;\n";
20903 static const GLchar* valid_var_definition =
20904 "const uint type_size = SIZE;\n"
20906 "layout (xfb_offset = 0, xfb_stride = 2 * type_size) out TYPE gokuARRAY;\n";
20907 static const GLchar* invalid_use = " gokuINDEX = TYPE(1);\n"
20908 " vegetaINDEX = TYPE(0);\n"
20909 " if (vec4(0) == result)\n"
20911 " gokuINDEX = TYPE(0);\n"
20912 " vegetaINDEX = TYPE(1);\n"
20914 static const GLchar* valid_use = " gokuINDEX = TYPE(1);\n"
20915 " if (vec4(0) == result)\n"
20917 " gokuINDEX = TYPE(0);\n"
20919 static const GLchar* fs = "#version 430 core\n"
20920 "#extension GL_ARB_enhanced_layouts : require\n"
20922 "in vec4 any_fs;\n"
20923 "out vec4 fs_out;\n"
20927 " fs_out = any_fs;\n"
20930 static const GLchar* gs_tested = "#version 430 core\n"
20931 "#extension GL_ARB_enhanced_layouts : require\n"
20933 "layout(points) in;\n"
20934 "layout(triangle_strip, max_vertices = 4) out;\n"
20938 "in vec4 vs_any[];\n"
20939 "out vec4 any_fs;\n"
20943 " vec4 result = vs_any[0];\n"
20947 " any_fs = result;\n"
20948 " gl_Position = vec4(-1, -1, 0, 1);\n"
20950 " any_fs = result;\n"
20951 " gl_Position = vec4(-1, 1, 0, 1);\n"
20953 " any_fs = result;\n"
20954 " gl_Position = vec4(1, -1, 0, 1);\n"
20956 " any_fs = result;\n"
20957 " gl_Position = vec4(1, 1, 0, 1);\n"
20961 static const GLchar* tcs = "#version 430 core\n"
20962 "#extension GL_ARB_enhanced_layouts : require\n"
20964 "layout(vertices = 1) out;\n"
20966 "in vec4 vs_any[];\n"
20967 "out vec4 tcs_tes[];\n"
20972 " tcs_tes[gl_InvocationID] = vs_any[gl_InvocationID];\n"
20974 " gl_TessLevelOuter[0] = 1.0;\n"
20975 " gl_TessLevelOuter[1] = 1.0;\n"
20976 " gl_TessLevelOuter[2] = 1.0;\n"
20977 " gl_TessLevelOuter[3] = 1.0;\n"
20978 " gl_TessLevelInner[0] = 1.0;\n"
20979 " gl_TessLevelInner[1] = 1.0;\n"
20982 static const GLchar* tcs_tested = "#version 430 core\n"
20983 "#extension GL_ARB_enhanced_layouts : require\n"
20985 "layout(vertices = 1) out;\n"
20989 "in vec4 vs_any[];\n"
20990 "out vec4 any_fs[];\n"
20994 " vec4 result = vs_any[gl_InvocationID];\n"
20998 " any_fs[gl_InvocationID] = result;\n"
21000 " gl_TessLevelOuter[0] = 1.0;\n"
21001 " gl_TessLevelOuter[1] = 1.0;\n"
21002 " gl_TessLevelOuter[2] = 1.0;\n"
21003 " gl_TessLevelOuter[3] = 1.0;\n"
21004 " gl_TessLevelInner[0] = 1.0;\n"
21005 " gl_TessLevelInner[1] = 1.0;\n"
21008 static const GLchar* tes_tested = "#version 430 core\n"
21009 "#extension GL_ARB_enhanced_layouts : require\n"
21011 "layout(isolines, point_mode) in;\n"
21015 "in vec4 tcs_tes[];\n"
21016 "out vec4 any_fs;\n"
21020 " vec4 result = tcs_tes[0];\n"
21024 " any_fs = result;\n"
21027 static const GLchar* vs = "#version 430 core\n"
21028 "#extension GL_ARB_enhanced_layouts : require\n"
21031 "out vec4 vs_any;\n"
21035 " vs_any = in_vs;\n"
21038 static const GLchar* vs_tested = "#version 430 core\n"
21039 "#extension GL_ARB_enhanced_layouts : require\n"
21044 "out vec4 any_fs;\n"
21048 " vec4 result = in_vs;\n"
21052 " any_fs = result;\n"
21056 std::string source;
21057 testCase& test_case = m_test_cases[test_case_index];
21059 if (test_case.m_stage == stage)
21061 const GLchar* array = "";
21063 const GLchar* index = "";
21064 size_t position = 0;
21066 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
21067 const GLchar* var_definition = 0;
21068 const GLchar* var_use = 0;
21070 sprintf(buffer, "%d", test_case.m_type.GetSize());
21072 switch (test_case.m_case)
21075 var_definition = valid_var_definition;
21076 var_use = valid_use;
21079 var_definition = invalid_var_definition;
21080 var_use = invalid_use;
21083 TCU_FAIL("Invalid enum");
21088 case Utils::Shader::GEOMETRY:
21089 source = gs_tested;
21093 case Utils::Shader::TESS_CTRL:
21094 source = tcs_tested;
21096 index = "[gl_InvocationID]";
21098 case Utils::Shader::TESS_EVAL:
21099 source = tes_tested;
21103 case Utils::Shader::VERTEX:
21104 source = vs_tested;
21107 TCU_FAIL("Invalid enum");
21111 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
21113 Utils::replaceToken("SIZE", position, buffer, source);
21114 Utils::replaceToken("ARRAY", position, array, source);
21115 if (INVALID == test_case.m_case)
21117 Utils::replaceToken("ARRAY", position, array, source);
21119 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
21121 Utils::replaceAllTokens("TYPE", type_name, source);
21122 Utils::replaceAllTokens("INDEX", index, source);
21126 switch (test_case.m_stage)
21128 case Utils::Shader::GEOMETRY:
21131 case Utils::Shader::FRAGMENT:
21134 case Utils::Shader::VERTEX:
21141 case Utils::Shader::TESS_CTRL:
21144 case Utils::Shader::FRAGMENT:
21147 case Utils::Shader::VERTEX:
21154 case Utils::Shader::TESS_EVAL:
21157 case Utils::Shader::FRAGMENT:
21160 case Utils::Shader::TESS_CTRL:
21163 case Utils::Shader::VERTEX:
21170 case Utils::Shader::VERTEX:
21173 case Utils::Shader::FRAGMENT:
21181 TCU_FAIL("Invalid enum");
21189 /** Get description of test case
21191 * @param test_case_index Index of test case
21193 * @return Test case description
21195 std::string XFBVariableStrideTest::getTestCaseName(GLuint test_case_index)
21197 std::stringstream stream;
21198 testCase& test_case = m_test_cases[test_case_index];
21200 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
21201 << ", type: " << test_case.m_type.GetGLSLTypeName() << ", case: ";
21203 switch (test_case.m_case)
21209 stream << "invalid";
21212 TCU_FAIL("Invalid enum");
21215 return stream.str();
21218 /** Get number of test cases
21220 * @return Number of test cases
21222 GLuint XFBVariableStrideTest::getTestCaseNumber()
21224 return static_cast<GLuint>(m_test_cases.size());
21227 /** Selects if "compute" stage is relevant for test
21233 bool XFBVariableStrideTest::isComputeRelevant(GLuint /* test_case_index */)
21238 /** Selects if compilation failure is expected result
21240 * @param test_case_index Index of test case
21244 bool XFBVariableStrideTest::isFailureExpected(GLuint test_case_index)
21246 testCase& test_case = m_test_cases[test_case_index];
21248 return (INVALID == test_case.m_case);
21251 /** Prepare all test cases
21254 void XFBVariableStrideTest::testInit()
21256 const GLuint n_types = getTypesNumber();
21258 for (GLuint i = 0; i < n_types; ++i)
21260 const Utils::Type& type = getType(i);
21263 Some of the cases are declared as following are considered as invalid,
21264 but accoring to spec, the following declaration is valid: shaders in the
21265 transform feedback capturing mode have an initial global default of layout(xfb_buffer=0) out,
21266 so for the first variable's declaration, the xfb_stride = 16 is applied on buffer 0, for the
21267 second variable, its buffer is also inherited from global buffer 0, and its offset does not overflows
21270 The xfb_stride is the memory width of given buffer, not for variable even though xfb_stride
21271 is declared on the variable. It seems that the writter of this case misunderstand the concept of
21272 xfb_stride, because spec describes that xfb_stride can be declared multiple times for the same buffer,
21273 it is a compile or link-time error to have different values specified for the stride for the same buffer.
21276 layout (xfb_offset = 0, xfb_stride = 2 * type_size) out double goku;
21277 layout (xfb_offset = type_size) out double vegeta;
21279 // all the shaders are valid, so remove the following loop(it contains CASE_MAX is enum of valid and invalid)
21280 // for (GLuint c = 0; c < CASE_MAX; ++c)
21282 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
21284 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
21285 (Utils::Shader::FRAGMENT == stage))
21290 testCase test_case = { (CASES)VALID, (Utils::Shader::STAGES)stage, type };
21292 m_test_cases.push_back(test_case);
21300 * @param context Test framework context
21302 XFBBlockStrideTest::XFBBlockStrideTest(deqp::Context& context)
21303 : TestBase(context, "xfb_block_stride", "Test verifies that stride qualifier is respected for blocks")
21307 /** Source for given test case and stage
21309 * @param test_case_index Index of test case
21310 * @param stage Shader stage
21312 * @return Shader source
21314 std::string XFBBlockStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
21316 static const GLchar* var_definition = "layout (xfb_offset = 0, xfb_stride = 128) out Goku {\n"
21321 static const GLchar* var_use = " gokuINDEX.gohan = vec4(1, 0, 0, 0);\n"
21322 " gokuINDEX.goten = vec4(0, 0, 1, 0);\n"
21323 " gokuINDEX.chichi = vec4(0, 1, 0, 0);\n"
21324 " if (vec4(0) == result)\n"
21326 " gokuINDEX.gohan = vec4(0, 1, 1, 1);\n"
21327 " gokuINDEX.goten = vec4(1, 1, 0, 1);\n"
21328 " gokuINDEX.chichi = vec4(1, 0, 1, 1);\n"
21330 static const GLchar* gs_tested =
21331 "#version 430 core\n"
21332 "#extension GL_ARB_enhanced_layouts : require\n"
21334 "layout(points) in;\n"
21335 "layout(triangle_strip, max_vertices = 4) out;\n"
21339 "out gl_PerVertex \n"
21341 " vec4 gl_Position; \n" // gl_Position must be redeclared in separable program mode
21343 "in vec4 tes_gs[];\n"
21344 "out vec4 gs_fs;\n"
21348 " vec4 result = tes_gs[0];\n"
21352 " gs_fs = result;\n"
21353 " gl_Position = vec4(-1, -1, 0, 1);\n"
21355 " gs_fs = result;\n"
21356 " gl_Position = vec4(-1, 1, 0, 1);\n"
21358 " gs_fs = result;\n"
21359 " gl_Position = vec4(1, -1, 0, 1);\n"
21361 " gs_fs = result;\n"
21362 " gl_Position = vec4(1, 1, 0, 1);\n"
21366 static const GLchar* tcs = "#version 430 core\n"
21367 "#extension GL_ARB_enhanced_layouts : require\n"
21369 "layout(vertices = 1) out;\n"
21371 "in vec4 vs_tcs[];\n"
21372 "out vec4 tcs_tes[];\n"
21377 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
21379 " gl_TessLevelOuter[0] = 1.0;\n"
21380 " gl_TessLevelOuter[1] = 1.0;\n"
21381 " gl_TessLevelOuter[2] = 1.0;\n"
21382 " gl_TessLevelOuter[3] = 1.0;\n"
21383 " gl_TessLevelInner[0] = 1.0;\n"
21384 " gl_TessLevelInner[1] = 1.0;\n"
21388 static const GLchar* tcs_tested =
21389 "#version 430 core\n"
21390 "#extension GL_ARB_enhanced_layouts : require\n"
21392 "layout(vertices = 1) out;\n"
21396 "in vec4 vs_tcs[];\n"
21397 "out vec4 tcs_tes[];\n"
21401 " vec4 result = vs_tcs[gl_InvocationID];\n"
21405 " tcs_tes[gl_InvocationID] = result;\n"
21407 " gl_TessLevelOuter[0] = 1.0;\n"
21408 " gl_TessLevelOuter[1] = 1.0;\n"
21409 " gl_TessLevelOuter[2] = 1.0;\n"
21410 " gl_TessLevelOuter[3] = 1.0;\n"
21411 " gl_TessLevelInner[0] = 1.0;\n"
21412 " gl_TessLevelInner[1] = 1.0;\n"
21416 static const GLchar* tes_tested = "#version 430 core\n"
21417 "#extension GL_ARB_enhanced_layouts : require\n"
21419 "layout(isolines, point_mode) in;\n"
21423 "in vec4 tcs_tes[];\n"
21424 "out vec4 tes_gs;\n"
21428 " vec4 result = tcs_tes[0];\n"
21432 " tes_gs += result;\n"
21435 static const GLchar* vs = "#version 430 core\n"
21436 "#extension GL_ARB_enhanced_layouts : require\n"
21439 "out vec4 vs_tcs;\n"
21443 " vs_tcs = in_vs;\n"
21446 static const GLchar* vs_tested = "#version 430 core\n"
21447 "#extension GL_ARB_enhanced_layouts : require\n"
21452 "out vec4 vs_tcs;\n"
21456 " vec4 result = in_vs;\n"
21460 " vs_tcs += result;\n"
21464 std::string source;
21465 Utils::Shader::STAGES test_case = m_test_cases[test_case_index];
21467 if (test_case == stage)
21469 const GLchar* array = "";
21470 const GLchar* index = "";
21471 size_t position = 0;
21473 // It is a compile time error to apply xfb_offset to the declaration of an unsized array(GLSL4.5 spec: Page73)
21474 // change array = "[]" to "[1]"
21477 case Utils::Shader::GEOMETRY:
21478 source = gs_tested;
21483 It is invalid to define transform feedback output in HS
21486 case Utils::Shader::TESS_CTRL:
21487 source = tcs_tested;
21489 index = "[gl_InvocationID]";
21492 case Utils::Shader::TESS_EVAL:
21493 source = tes_tested;
21497 case Utils::Shader::VERTEX:
21498 source = vs_tested;
21501 TCU_FAIL("Invalid enum");
21505 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
21507 Utils::replaceToken("ARRAY", position, array, source);
21508 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
21510 Utils::replaceAllTokens("INDEX", index, source);
21516 case Utils::Shader::GEOMETRY:
21519 case Utils::Shader::VERTEX:
21526 case Utils::Shader::TESS_CTRL:
21529 case Utils::Shader::VERTEX:
21536 case Utils::Shader::TESS_EVAL:
21539 case Utils::Shader::TESS_CTRL:
21542 case Utils::Shader::VERTEX:
21549 case Utils::Shader::VERTEX:
21553 TCU_FAIL("Invalid enum");
21561 /** Get description of test case
21563 * @param test_case_index Index of test case
21565 * @return Test case description
21567 std::string XFBBlockStrideTest::getTestCaseName(GLuint test_case_index)
21569 std::stringstream stream;
21571 stream << "Stage: " << Utils::Shader::GetStageName(m_test_cases[test_case_index]);
21573 return stream.str();
21576 /** Get number of test cases
21578 * @return Number of test cases
21580 GLuint XFBBlockStrideTest::getTestCaseNumber()
21582 return static_cast<GLuint>(m_test_cases.size());
21585 /** Inspects program for xfb stride
21587 * @param program Program to query
21589 * @return true if query results match expected values, false otherwise
21591 bool XFBBlockStrideTest::inspectProgram(Utils::Program& program)
21595 program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE,
21596 1 /* buf_size */, &stride);
21598 return (128 == stride);
21603 * @param test_case_index Id of test case
21605 * @return true if test case pass, false otherwise
21607 bool XFBBlockStrideTest::testCase(GLuint test_case_index)
21609 const std::string& gs_source = getShaderSource(test_case_index, Utils::Shader::GEOMETRY);
21610 Utils::Program program(m_context);
21611 const std::string& tcs_source = getShaderSource(test_case_index, Utils::Shader::TESS_CTRL);
21612 const std::string& tes_source = getShaderSource(test_case_index, Utils::Shader::TESS_EVAL);
21613 bool test_case_result = true;
21614 const std::string& vs_source = getShaderSource(test_case_index, Utils::Shader::VERTEX);
21616 program.Init("" /* cs */, "", gs_source, tcs_source, tes_source, vs_source, true /* separable */);
21618 test_case_result = inspectProgram(program);
21620 return test_case_result;
21623 /** Prepare all test cases
21626 void XFBBlockStrideTest::testInit()
21628 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
21630 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
21631 (Utils::Shader::FRAGMENT == stage))
21636 m_test_cases.push_back((Utils::Shader::STAGES)stage);
21642 * @param context Test context
21644 XFBBlockMemberStrideTest::XFBBlockMemberStrideTest(deqp::Context& context)
21645 : BufferTestBase(context, "xfb_block_member_stride",
21646 "Test verifies that xfb_stride qualifier is respected for block member")
21648 /* Nothing to be done here */
21651 /** Get descriptors of buffers necessary for test
21654 * @param out_descriptors Descriptors of buffers used by test
21656 void XFBBlockMemberStrideTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
21657 bufferDescriptor::Vector& out_descriptors)
21659 const Utils::Type& vec4 = Utils::Type::vec4;
21661 /* Test needs single uniform and xfb */
21662 out_descriptors.resize(2);
21664 /* Get references */
21665 bufferDescriptor& uniform = out_descriptors[0];
21666 bufferDescriptor& xfb = out_descriptors[1];
21669 uniform.m_index = 0;
21673 uniform.m_target = Utils::Buffer::Uniform;
21674 xfb.m_target = Utils::Buffer::Transform_feedback;
21677 static const GLuint vec4_size = 16;
21678 const std::vector<GLubyte>& gohan_data = vec4.GenerateDataPacked();
21679 const std::vector<GLubyte>& goten_data = vec4.GenerateDataPacked();
21680 const std::vector<GLubyte>& chichi_data = vec4.GenerateDataPacked();
21683 uniform.m_initial_data.resize(3 * vec4_size);
21684 memcpy(&uniform.m_initial_data[0] + 0, &gohan_data[0], vec4_size);
21685 memcpy(&uniform.m_initial_data[0] + vec4_size, &goten_data[0], vec4_size);
21686 memcpy(&uniform.m_initial_data[0] + 2 * vec4_size, &chichi_data[0], vec4_size);
21689 xfb.m_initial_data.resize(4 * vec4_size);
21690 xfb.m_expected_data.resize(4 * vec4_size);
21692 for (GLuint i = 0; i < 4 * vec4_size; ++i)
21694 xfb.m_initial_data[i] = (glw::GLubyte)i;
21695 xfb.m_expected_data[i] = (glw::GLubyte)i;
21698 // the xfb_offset of "chichi" should be 32
21699 memcpy(&xfb.m_expected_data[0] + 0, &gohan_data[0], vec4_size);
21700 memcpy(&xfb.m_expected_data[0] + vec4_size, &goten_data[0], vec4_size);
21701 memcpy(&xfb.m_expected_data[0] + 2 * vec4_size, &chichi_data[0], vec4_size);
21704 /** Get body of main function for given shader stage
21707 * @param stage Shader stage
21708 * @param out_assignments Set to empty
21709 * @param out_calculations Set to empty
21711 void XFBBlockMemberStrideTest::getShaderBody(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
21712 std::string& out_assignments, std::string& out_calculations)
21714 out_calculations = "";
21716 static const GLchar* gs = " gohan = uni_gohan;\n"
21717 " goten = uni_goten;\n"
21718 " chichi = uni_chichi;\n";
21719 static const GLchar* fs = " fs_out = gohan + goten + chichi;\n";
21721 const GLchar* assignments = "";
21724 case Utils::Shader::FRAGMENT:
21727 case Utils::Shader::GEOMETRY:
21734 out_assignments = assignments;
21737 /** Get interface of shader
21740 * @param stage Shader stage
21741 * @param out_interface Set to ""
21743 void XFBBlockMemberStrideTest::getShaderInterface(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
21744 std::string& out_interface)
21746 static const GLchar* gs = "layout (xfb_buffer = 0, xfb_offset = 0) out Goku {\n"
21748 " layout (xfb_stride = 32) vec4 goten;\n"
21751 "layout(binding = 0) uniform gs_block {\n"
21752 " vec4 uni_gohan;\n"
21753 " vec4 uni_goten;\n"
21754 " vec4 uni_chichi;\n"
21756 static const GLchar* fs = "in Goku {\n"
21761 "out vec4 fs_out;\n";
21765 case Utils::Shader::FRAGMENT:
21766 out_interface = fs;
21768 case Utils::Shader::GEOMETRY:
21769 out_interface = gs;
21772 out_interface = "";
21777 /** Inspects program to check if all resources are as expected
21780 * @param program Program instance
21781 * @param out_stream Error message
21783 * @return true if everything is ok, false otherwise
21785 bool XFBBlockMemberStrideTest::inspectProgram(GLuint /* test_case_index*/, Utils::Program& program,
21786 std::stringstream& out_stream)
21788 const GLuint gohan_id = program.GetResourceIndex("gohan", GL_TRANSFORM_FEEDBACK_VARYING);
21789 const GLuint goten_id = program.GetResourceIndex("goten", GL_TRANSFORM_FEEDBACK_VARYING);
21790 const GLuint chichi_id = program.GetResourceIndex("chichi", GL_TRANSFORM_FEEDBACK_VARYING);
21792 GLint gohan_offset = 0;
21793 GLint goten_offset = 0;
21794 GLint chichi_offset = 0;
21796 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, gohan_id, GL_OFFSET, 1, &gohan_offset);
21797 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, goten_id, GL_OFFSET, 1, &goten_offset);
21798 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, chichi_id, GL_OFFSET, 1, &chichi_offset);
21800 // the xfb_offset of "chichi" should be 32
21801 if ((0 != gohan_offset) || (16 != goten_offset) || (32 != chichi_offset))
21803 out_stream << "Got wrong offset: [" << gohan_offset << ", " << goten_offset << ", " << chichi_offset
21804 << "] expected: [0, 16, 48]";
21813 * @param context Test framework context
21815 XFBDuplicatedStrideTest::XFBDuplicatedStrideTest(deqp::Context& context)
21816 : NegativeTestBase(context, "xfb_duplicated_stride",
21817 "Test verifies that compiler reports error when conflicting stride qualifiers are used")
21821 /** Source for given test case and stage
21823 * @param test_case_index Index of test case
21824 * @param stage Shader stage
21826 * @return Shader source
21828 std::string XFBDuplicatedStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
21830 static const GLchar* invalid_var_definition = "const uint valid_stride = 64;\n"
21831 "const uint conflicting_stride = 128;\n"
21833 "layout (xfb_buffer = 0, xfb_stride = valid_stride) out;\n"
21834 "layout (xfb_buffer = 0, xfb_stride = conflicting_stride) out;\n";
21835 static const GLchar* valid_var_definition = "const uint valid_stride = 64;\n"
21837 "layout (xfb_buffer = 0, xfb_stride = valid_stride) out;\n"
21838 "layout (xfb_buffer = 0, xfb_stride = valid_stride) out;\n";
21839 static const GLchar* fs = "#version 430 core\n"
21840 "#extension GL_ARB_enhanced_layouts : require\n"
21842 "in vec4 any_fs;\n"
21843 "out vec4 fs_out;\n"
21847 " fs_out = any_fs;\n"
21850 static const GLchar* gs_tested = "#version 430 core\n"
21851 "#extension GL_ARB_enhanced_layouts : require\n"
21853 "layout(points) in;\n"
21854 "layout(triangle_strip, max_vertices = 4) out;\n"
21858 "in vec4 vs_any[];\n"
21859 "out vec4 any_fs;\n"
21863 " vec4 result = vs_any[0];\n"
21867 " any_fs = result;\n"
21868 " gl_Position = vec4(-1, -1, 0, 1);\n"
21870 " any_fs = result;\n"
21871 " gl_Position = vec4(-1, 1, 0, 1);\n"
21873 " any_fs = result;\n"
21874 " gl_Position = vec4(1, -1, 0, 1);\n"
21876 " any_fs = result;\n"
21877 " gl_Position = vec4(1, 1, 0, 1);\n"
21881 static const GLchar* tcs = "#version 430 core\n"
21882 "#extension GL_ARB_enhanced_layouts : require\n"
21884 "layout(vertices = 1) out;\n"
21886 "in vec4 vs_any[];\n"
21887 "out vec4 tcs_tes[];\n"
21892 " tcs_tes[gl_InvocationID] = vs_any[gl_InvocationID];\n"
21894 " gl_TessLevelOuter[0] = 1.0;\n"
21895 " gl_TessLevelOuter[1] = 1.0;\n"
21896 " gl_TessLevelOuter[2] = 1.0;\n"
21897 " gl_TessLevelOuter[3] = 1.0;\n"
21898 " gl_TessLevelInner[0] = 1.0;\n"
21899 " gl_TessLevelInner[1] = 1.0;\n"
21902 static const GLchar* tcs_tested = "#version 430 core\n"
21903 "#extension GL_ARB_enhanced_layouts : require\n"
21905 "layout(vertices = 1) out;\n"
21909 "in vec4 vs_any[];\n"
21910 "out vec4 any_fs[];\n"
21914 " vec4 result = vs_any[gl_InvocationID];\n"
21918 " any_fs[gl_InvocationID] = result;\n"
21920 " gl_TessLevelOuter[0] = 1.0;\n"
21921 " gl_TessLevelOuter[1] = 1.0;\n"
21922 " gl_TessLevelOuter[2] = 1.0;\n"
21923 " gl_TessLevelOuter[3] = 1.0;\n"
21924 " gl_TessLevelInner[0] = 1.0;\n"
21925 " gl_TessLevelInner[1] = 1.0;\n"
21928 static const GLchar* tes_tested = "#version 430 core\n"
21929 "#extension GL_ARB_enhanced_layouts : require\n"
21931 "layout(isolines, point_mode) in;\n"
21935 "in vec4 tcs_tes[];\n"
21936 "out vec4 any_fs;\n"
21940 " vec4 result = tcs_tes[0];\n"
21944 " any_fs = result;\n"
21947 static const GLchar* vs = "#version 430 core\n"
21948 "#extension GL_ARB_enhanced_layouts : require\n"
21951 "out vec4 vs_any;\n"
21955 " vs_any = in_vs;\n"
21958 static const GLchar* vs_tested = "#version 430 core\n"
21959 "#extension GL_ARB_enhanced_layouts : require\n"
21964 "out vec4 any_fs;\n"
21968 " vec4 result = in_vs;\n"
21972 " any_fs += result;\n"
21976 std::string source;
21977 testCase& test_case = m_test_cases[test_case_index];
21979 if (test_case.m_stage == stage)
21981 size_t position = 0;
21982 const GLchar* var_definition = 0;
21983 const GLchar* var_use = "";
21985 switch (test_case.m_case)
21988 var_definition = valid_var_definition;
21991 var_definition = invalid_var_definition;
21994 TCU_FAIL("Invalid enum");
21999 case Utils::Shader::GEOMETRY:
22000 source = gs_tested;
22002 case Utils::Shader::TESS_CTRL:
22003 source = tcs_tested;
22005 case Utils::Shader::TESS_EVAL:
22006 source = tes_tested;
22008 case Utils::Shader::VERTEX:
22009 source = vs_tested;
22012 TCU_FAIL("Invalid enum");
22015 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
22016 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
22020 switch (test_case.m_stage)
22022 case Utils::Shader::GEOMETRY:
22025 case Utils::Shader::FRAGMENT:
22028 case Utils::Shader::VERTEX:
22035 case Utils::Shader::TESS_CTRL:
22038 case Utils::Shader::FRAGMENT:
22041 case Utils::Shader::VERTEX:
22048 case Utils::Shader::TESS_EVAL:
22051 case Utils::Shader::FRAGMENT:
22054 case Utils::Shader::TESS_CTRL:
22057 case Utils::Shader::VERTEX:
22064 case Utils::Shader::VERTEX:
22067 case Utils::Shader::FRAGMENT:
22075 TCU_FAIL("Invalid enum");
22083 /** Get description of test case
22085 * @param test_case_index Index of test case
22087 * @return Test case description
22089 std::string XFBDuplicatedStrideTest::getTestCaseName(GLuint test_case_index)
22091 std::stringstream stream;
22092 testCase& test_case = m_test_cases[test_case_index];
22094 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", case: ";
22096 switch (test_case.m_case)
22102 stream << "invalid";
22105 TCU_FAIL("Invalid enum");
22108 return stream.str();
22111 /** Get number of test cases
22113 * @return Number of test cases
22115 GLuint XFBDuplicatedStrideTest::getTestCaseNumber()
22117 return static_cast<GLuint>(m_test_cases.size());
22120 /** Selects if "compute" stage is relevant for test
22126 bool XFBDuplicatedStrideTest::isComputeRelevant(GLuint /* test_case_index */)
22131 /** Selects if compilation failure is expected result
22133 * @param test_case_index Index of test case
22137 bool XFBDuplicatedStrideTest::isFailureExpected(GLuint test_case_index)
22139 testCase& test_case = m_test_cases[test_case_index];
22141 return (INVALID == test_case.m_case);
22144 /** Prepare all test cases
22147 void XFBDuplicatedStrideTest::testInit()
22149 for (GLuint c = 0; c < CASE_MAX; ++c)
22151 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
22153 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
22154 (Utils::Shader::FRAGMENT == stage))
22159 testCase test_case = { (CASES)c, (Utils::Shader::STAGES)stage };
22161 m_test_cases.push_back(test_case);
22168 * @param context Test framework context
22170 XFBGetProgramResourceAPITest::XFBGetProgramResourceAPITest(deqp::Context& context)
22171 : TestBase(context, "xfb_get_program_resource_api",
22172 "Test verifies that get program resource reports correct results for XFB")
22176 /** Source for given test case and stage
22178 * @param test_case_index Index of test case
22179 * @param stage Shader stage
22181 * @return Shader source
22183 std::string XFBGetProgramResourceAPITest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
22185 static const GLchar* api_var_definition = "out TYPE b0_v1ARRAY;\n"
22186 "out TYPE b1_v1ARRAY;\n"
22187 "out TYPE b0_v3ARRAY;\n"
22188 "out TYPE b0_v0ARRAY;\n";
22189 static const GLchar* xfb_var_definition =
22190 "const uint type_size = SIZE;\n"
22192 "layout (xfb_buffer = 1, xfb_stride = 4 * type_size) out;\n"
22194 "layout (xfb_buffer = 0, xfb_offset = 1 * type_size) out TYPE b0_v1ARRAY;\n"
22195 "layout (xfb_buffer = 1, xfb_offset = 1 * type_size) out TYPE b1_v1ARRAY;\n"
22196 "layout (xfb_buffer = 0, xfb_offset = 3 * type_size) out TYPE b0_v3ARRAY;\n"
22197 "layout (xfb_buffer = 0, xfb_offset = 0 * type_size) out TYPE b0_v0ARRAY;\n";
22198 static const GLchar* var_use = " b0_v1INDEX = TYPE(0);\n"
22199 " b1_v1INDEX = TYPE(1);\n"
22200 " b0_v3INDEX = TYPE(0);\n"
22201 " b0_v0INDEX = TYPE(1);\n"
22202 " if (vec4(0) == result)\n"
22204 " b0_v1INDEX = TYPE(1);\n"
22205 " b1_v1INDEX = TYPE(0);\n"
22206 " b0_v3INDEX = TYPE(1);\n"
22207 " b0_v0INDEX = TYPE(0);\n"
22209 static const GLchar* gs_tested =
22210 "#version 430 core\n"
22211 "#extension GL_ARB_enhanced_layouts : require\n"
22213 "layout(points) in;\n"
22214 "layout(triangle_strip, max_vertices = 4) out;\n"
22218 "out gl_PerVertex \n"
22220 " vec4 gl_Position; \n" // gl_Position must be redeclared in separable program mode
22222 "in vec4 tes_gs[];\n"
22223 "out vec4 gs_fs;\n"
22227 " vec4 result = tes_gs[0];\n"
22231 " gs_fs = result;\n"
22232 " gl_Position = vec4(-1, -1, 0, 1);\n"
22234 " gs_fs = result;\n"
22235 " gl_Position = vec4(-1, 1, 0, 1);\n"
22237 " gs_fs = result;\n"
22238 " gl_Position = vec4(1, -1, 0, 1);\n"
22240 " gs_fs = result;\n"
22241 " gl_Position = vec4(1, 1, 0, 1);\n"
22246 static const GLchar* tcs_tested =
22247 "#version 430 core\n"
22248 "#extension GL_ARB_enhanced_layouts : require\n"
22250 "layout(vertices = 1) out;\n"
22254 "in vec4 vs_tcs[];\n"
22255 "out vec4 tcs_tes[];\n"
22259 " vec4 result = vs_tcs[gl_InvocationID];\n"
22263 " tcs_tes[gl_InvocationID] = result;\n"
22265 " gl_TessLevelOuter[0] = 1.0;\n"
22266 " gl_TessLevelOuter[1] = 1.0;\n"
22267 " gl_TessLevelOuter[2] = 1.0;\n"
22268 " gl_TessLevelOuter[3] = 1.0;\n"
22269 " gl_TessLevelInner[0] = 1.0;\n"
22270 " gl_TessLevelInner[1] = 1.0;\n"
22274 static const GLchar* tes_tested = "#version 430 core\n"
22275 "#extension GL_ARB_enhanced_layouts : require\n"
22277 "layout(isolines, point_mode) in;\n"
22281 "in vec4 tcs_tes[];\n"
22282 "out vec4 tes_gs;\n"
22286 " vec4 result = tcs_tes[0];\n"
22290 " tes_gs = result;\n"
22293 static const GLchar* vs_tested = "#version 430 core\n"
22294 "#extension GL_ARB_enhanced_layouts : require\n"
22299 "out vec4 vs_tcs;\n"
22303 " vec4 result = in_vs;\n"
22307 " vs_tcs = result;\n"
22311 std::string source;
22312 const test_Case& test_case = m_test_cases[test_case_index];
22314 if (test_case.m_stage == stage)
22316 const GLchar* array = "";
22318 const GLchar* index = "";
22319 size_t position = 0;
22321 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
22322 const GLchar* var_definition = 0;
22324 sprintf(buffer, "%d", test_case.m_type.GetSize());
22326 if (XFB == test_case.m_case)
22328 var_definition = xfb_var_definition;
22332 var_definition = api_var_definition;
22335 // It is a compile time error to apply xfb_offset to the declaration of an unsized array(GLSL4.5 spec: Page73)
22336 // change array = "[]" to "[1]"
22339 case Utils::Shader::GEOMETRY:
22340 source = gs_tested;
22344 // It is invalid to output transform feedback varyings in tessellation control shader
22346 case Utils::Shader::TESS_CTRL:
22347 source = tcs_tested;
22349 index = "[gl_InvocationID]";
22352 case Utils::Shader::TESS_EVAL:
22353 source = tes_tested;
22357 case Utils::Shader::VERTEX:
22358 source = vs_tested;
22361 TCU_FAIL("Invalid enum");
22365 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
22366 if (XFB == test_case.m_case)
22369 Utils::replaceToken("SIZE", position, buffer, source);
22371 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
22373 Utils::replaceAllTokens("ARRAY", array, source);
22374 Utils::replaceAllTokens("INDEX", index, source);
22375 Utils::replaceAllTokens("TYPE", type_name, source);
22385 /** Get description of test case
22387 * @param test_case_index Index of test case
22389 * @return Test case description
22391 std::string XFBGetProgramResourceAPITest::getTestCaseName(GLuint test_case_index)
22393 std::stringstream stream;
22394 const test_Case& test_case = m_test_cases[test_case_index];
22396 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
22397 << ", type: " << test_case.m_type.GetGLSLTypeName() << ", case: ";
22399 switch (test_case.m_case)
22402 stream << "interleaved";
22405 stream << "separated";
22411 TCU_FAIL("Invalid enum");
22414 return stream.str();
22417 /** Get number of test cases
22419 * @return Number of test cases
22421 GLuint XFBGetProgramResourceAPITest::getTestCaseNumber()
22423 return static_cast<GLuint>(m_test_cases.size());
22426 /** Inspects program for offset, buffer index, buffer stride and type
22428 * @param test_case_index Index of test case
22429 * @param program Program to query
22431 * @return true if query results match expected values, false otherwise
22433 bool XFBGetProgramResourceAPITest::inspectProgram(glw::GLuint test_case_index, Utils::Program& program)
22435 GLint b0_stride = 0;
22436 GLint b1_stride = 0;
22437 GLint b0_v0_buf = 0;
22438 GLint b0_v0_offset = 0;
22439 GLint b0_v0_type = 0;
22440 GLint b0_v1_buf = 0;
22441 GLint b0_v1_offset = 0;
22442 GLint b0_v1_type = 0;
22443 GLint b0_v3_buf = 0;
22444 GLint b0_v3_offset = 0;
22445 GLint b0_v3_type = 0;
22446 GLint b1_v1_buf = 0;
22447 GLint b1_v1_offset = 0;
22448 GLint b1_v1_type = 0;
22449 const test_Case& test_case = m_test_cases[test_case_index];
22450 const GLenum type_enum = test_case.m_type.GetTypeGLenum();
22451 const GLint type_size = test_case.m_type.GetSize();
22453 GLuint b0_v0_index = program.GetResourceIndex("b0_v0", GL_TRANSFORM_FEEDBACK_VARYING);
22454 GLuint b0_v1_index = program.GetResourceIndex("b0_v1", GL_TRANSFORM_FEEDBACK_VARYING);
22455 GLuint b0_v3_index = program.GetResourceIndex("b0_v3", GL_TRANSFORM_FEEDBACK_VARYING);
22456 GLuint b1_v1_index = program.GetResourceIndex("b1_v1", GL_TRANSFORM_FEEDBACK_VARYING);
22458 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v0_index, GL_OFFSET, 1 /* buf_size */, &b0_v0_offset);
22459 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v1_index, GL_OFFSET, 1 /* buf_size */, &b0_v1_offset);
22460 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v3_index, GL_OFFSET, 1 /* buf_size */, &b0_v3_offset);
22461 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b1_v1_index, GL_OFFSET, 1 /* buf_size */, &b1_v1_offset);
22463 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v0_index, GL_TYPE, 1 /* buf_size */, &b0_v0_type);
22464 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v1_index, GL_TYPE, 1 /* buf_size */, &b0_v1_type);
22465 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v3_index, GL_TYPE, 1 /* buf_size */, &b0_v3_type);
22466 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b1_v1_index, GL_TYPE, 1 /* buf_size */, &b1_v1_type);
22468 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v0_index, GL_TRANSFORM_FEEDBACK_BUFFER_INDEX,
22469 1 /* buf_size */, &b0_v0_buf);
22470 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v1_index, GL_TRANSFORM_FEEDBACK_BUFFER_INDEX,
22471 1 /* buf_size */, &b0_v1_buf);
22472 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v3_index, GL_TRANSFORM_FEEDBACK_BUFFER_INDEX,
22473 1 /* buf_size */, &b0_v3_buf);
22474 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b1_v1_index, GL_TRANSFORM_FEEDBACK_BUFFER_INDEX,
22475 1 /* buf_size */, &b1_v1_buf);
22477 program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, b0_v0_buf, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE, 1 /* buf_size */,
22479 program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, b1_v1_buf, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE, 1 /* buf_size */,
22482 if (SEPARATED != test_case.m_case)
22484 return (((GLint)(4 * type_size) == b0_stride) && ((GLint)(4 * type_size) == b1_stride) &&
22485 ((GLint)(0) == b0_v0_buf) && ((GLint)(0 * type_size) == b0_v0_offset) &&
22486 ((GLint)(type_enum) == b0_v0_type) && ((GLint)(0) == b0_v1_buf) &&
22487 ((GLint)(1 * type_size) == b0_v1_offset) && ((GLint)(type_enum) == b0_v1_type) &&
22488 ((GLint)(0) == b0_v3_buf) && ((GLint)(3 * type_size) == b0_v3_offset) &&
22489 ((GLint)(type_enum) == b0_v3_type) && ((GLint)(1) == b1_v1_buf) &&
22490 ((GLint)(1 * type_size) == b1_v1_offset) && ((GLint)(type_enum) == b1_v1_type));
22494 return (((GLint)(1 * type_size) == b0_stride) && ((GLint)(1 * type_size) == b1_stride) &&
22495 ((GLint)(0) == b0_v0_buf) && ((GLint)(0) == b0_v0_offset) && ((GLint)(type_enum) == b0_v0_type) &&
22496 ((GLint)(1) == b0_v1_buf) && ((GLint)(0) == b0_v1_offset) && ((GLint)(type_enum) == b0_v1_type) &&
22497 ((GLint)(2) == b0_v3_buf) && ((GLint)(0) == b0_v3_offset) && ((GLint)(type_enum) == b0_v3_type) &&
22498 ((GLint)(3) == b1_v1_buf) && ((GLint)(0) == b1_v1_offset) && ((GLint)(type_enum) == b1_v1_type));
22502 /** Insert gl_SkipComponents
22504 * @param num_components How many gl_SkipComponents1 need to be inserted
22505 * @param varyings The transform feedback varyings string vector
22508 void XFBGetProgramResourceAPITest::insertSkipComponents(int num_components, Utils::Program::NameVector& varyings)
22510 int num_component_4 = num_components / 4;
22511 int num_component_1 = num_components % 4;
22512 for (int i = 0; i < num_component_4; i++)
22514 varyings.push_back("gl_SkipComponents4");
22516 switch (num_component_1)
22519 varyings.push_back("gl_SkipComponents1");
22522 varyings.push_back("gl_SkipComponents2");
22525 varyings.push_back("gl_SkipComponents3");
22534 * @param test_case_index Id of test case
22536 * @return true if test case pass, false otherwise
22538 bool XFBGetProgramResourceAPITest::testCase(GLuint test_case_index)
22540 const std::string& gs_source = getShaderSource(test_case_index, Utils::Shader::GEOMETRY);
22541 Utils::Program program(m_context);
22542 const std::string& tcs_source = getShaderSource(test_case_index, Utils::Shader::TESS_CTRL);
22543 const std::string& tes_source = getShaderSource(test_case_index, Utils::Shader::TESS_EVAL);
22544 const test_Case& test_case = m_test_cases[test_case_index];
22545 bool test_case_result = true;
22546 const std::string& vs_source = getShaderSource(test_case_index, Utils::Shader::VERTEX);
22548 // According to spec: gl_SkipComponents1 ~ gl_SkipComponents4 is treated as specifying a one- to four-component floating point output variables with undefined values.
22549 // 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.
22551 if (INTERLEAVED == test_case.m_case)
22554 layout (xfb_buffer = 0, xfb_offset = 1 * type_size) out type b0_v1;
22555 layout (xfb_buffer = 1, xfb_offset = 1 * type_size) out type b1_v1;
22556 layout (xfb_buffer = 0, xfb_offset = 3 * type_size) out type b0_v3;
22557 layout (xfb_buffer = 0, xfb_offset = 0 * type_size) out type b0_v0;
22559 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,
22560 we need to calculate how many "gl_SkipComponents" need to be inserted.
22562 Utils::Program::NameVector captured_varyings;
22563 captured_varyings.push_back("b0_v0");
22564 captured_varyings.push_back("b0_v1");
22565 // Compute how many gl_SkipComponents to be inserted
22566 int numComponents = test_case.m_type.GetSize() / 4;
22567 insertSkipComponents(numComponents, captured_varyings);
22568 captured_varyings.push_back("b0_v3");
22569 captured_varyings.push_back("gl_NextBuffer");
22570 insertSkipComponents(numComponents, captured_varyings);
22571 captured_varyings.push_back("b1_v1");
22572 insertSkipComponents(numComponents * 2, captured_varyings);
22574 program.Init("" /* cs */, "", gs_source, tcs_source, tes_source, vs_source, captured_varyings, true,
22575 true /* separable */);
22577 else if (SEPARATED == test_case.m_case)
22579 Utils::Program::NameVector captured_varyings;
22581 captured_varyings.push_back("b0_v0");
22582 captured_varyings.push_back("b0_v1");
22583 captured_varyings.push_back("b0_v3");
22584 captured_varyings.push_back("b1_v1");
22586 program.Init("" /* cs */, "", gs_source, tcs_source, tes_source, vs_source, captured_varyings, false,
22587 true /* separable */);
22592 program.Init("" /* cs */, "", gs_source, tcs_source, tes_source, vs_source, true /* separable */);
22595 test_case_result = inspectProgram(test_case_index, program);
22597 return test_case_result;
22600 /** Prepare all test cases
22603 void XFBGetProgramResourceAPITest::testInit()
22605 const Functions& gl = m_context.getRenderContext().getFunctions();
22606 const GLuint n_types = getTypesNumber();
22610 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_xfb_int);
22611 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
22613 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, &max_xfb_sep);
22614 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
22616 GLint max_varyings;
22617 gl.getIntegerv(GL_MAX_VARYING_COMPONENTS, &max_varyings);
22619 for (GLuint i = 0; i < n_types; ++i)
22621 // 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,
22622 // 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
22623 // shader valid, we can either skip the dmat4, dmat4x3 or query the implementation-dependent value MAX_VARYING_COMPONENTS before generating the shader
22624 // to guarantee the number of varying not exceeded.
22626 layout (xfb_buffer = 1, xfb_stride = 4 * type_size) out;
22627 layout (xfb_buffer = 0, xfb_offset = 1 * type_size) out type b0_v1;
22628 layout (xfb_buffer = 1, xfb_offset = 1 * type_size) out type b1_v1;
22629 layout (xfb_buffer = 0, xfb_offset = 3 * type_size) out type b0_v3;
22630 layout (xfb_buffer = 0, xfb_offset = 0 * type_size) out type b0_v0;
22634 if (i == 7 || i == 9)
22636 const Utils::Type& type = getType(i);
22637 if (4 * type.GetNumComponents() + 4 > (GLuint)max_varyings)
22641 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
22644 It is invalid to define transform feedback output in HS
22646 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
22647 (Utils::Shader::FRAGMENT == stage))
22652 test_Case test_case_int = { INTERLEAVED, (Utils::Shader::STAGES)stage, type };
22653 test_Case test_case_sep = { SEPARATED, (Utils::Shader::STAGES)stage, type };
22654 test_Case test_case_xfb = { XFB, (Utils::Shader::STAGES)stage, type };
22656 if ((int)type.GetSize() <= max_xfb_int)
22658 m_test_cases.push_back(test_case_xfb);
22659 m_test_cases.push_back(test_case_int);
22662 if ((int)type.GetSize() <= max_xfb_sep)
22664 m_test_cases.push_back(test_case_sep);
22672 * @param context Test context
22674 XFBOverrideQualifiersWithAPITest::XFBOverrideQualifiersWithAPITest(deqp::Context& context)
22675 : BufferTestBase(context, "xfb_override_qualifiers_with_api",
22676 "Test verifies that xfb_offset qualifier is not overriden with API")
22678 /* Nothing to be done here */
22681 /** Get descriptors of buffers necessary for test
22683 * @param test_case_index Index of test case
22684 * @param out_descriptors Descriptors of buffers used by test
22686 void XFBOverrideQualifiersWithAPITest::getBufferDescriptors(glw::GLuint test_case_index,
22687 bufferDescriptor::Vector& out_descriptors)
22689 const Utils::Type& type = getType(test_case_index);
22691 /* Test needs single uniform and xfb */
22692 out_descriptors.resize(2);
22694 /* Get references */
22695 bufferDescriptor& uniform = out_descriptors[0];
22696 bufferDescriptor& xfb = out_descriptors[1];
22699 uniform.m_index = 0;
22703 uniform.m_target = Utils::Buffer::Uniform;
22704 xfb.m_target = Utils::Buffer::Transform_feedback;
22707 const GLuint gen_start = Utils::s_rand;
22708 const std::vector<GLubyte>& vegeta_data = type.GenerateData();
22709 const std::vector<GLubyte>& trunks_data = type.GenerateData();
22710 const std::vector<GLubyte>& goku_data = type.GenerateData();
22711 const std::vector<GLubyte>& gohan_data = type.GenerateData();
22713 Utils::s_rand = gen_start;
22714 const std::vector<GLubyte>& vegeta_data_pck = type.GenerateDataPacked();
22716 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)
22717 how can make them equal ? is it as designed? Add the following statement, which can make sure goku_data_pck equals to goku_data
22719 const std::vector<GLubyte>& goku_data_pck = type.GenerateDataPacked();
22721 const GLuint type_size = static_cast<GLuint>(vegeta_data.size());
22722 const GLuint type_size_pck = static_cast<GLuint>(vegeta_data_pck.size());
22725 uniform.m_initial_data.resize(4 * type_size);
22726 memcpy(&uniform.m_initial_data[0] + 0, &vegeta_data[0], type_size);
22727 memcpy(&uniform.m_initial_data[0] + type_size, &trunks_data[0], type_size);
22728 memcpy(&uniform.m_initial_data[0] + 2 * type_size, &goku_data[0], type_size);
22729 memcpy(&uniform.m_initial_data[0] + 3 * type_size, &gohan_data[0], type_size);
22732 xfb.m_initial_data.resize(4 * type_size_pck);
22733 xfb.m_expected_data.resize(4 * type_size_pck);
22735 for (GLuint i = 0; i < 4 * type_size_pck; ++i)
22737 xfb.m_initial_data[i] = (glw::GLubyte)i;
22738 xfb.m_expected_data[i] = (glw::GLubyte)i;
22741 memcpy(&xfb.m_expected_data[0] + 0, &goku_data_pck[0], type_size_pck);
22742 memcpy(&xfb.m_expected_data[0] + 2 * type_size_pck, &vegeta_data_pck[0], type_size_pck);
22745 /** Get list of names of varyings that will be registered with TransformFeedbackVaryings
22748 * @param captured_varyings List of names
22750 void XFBOverrideQualifiersWithAPITest::getCapturedVaryings(glw::GLuint /* test_case_index */,
22751 Utils::Program::NameVector& captured_varyings)
22753 captured_varyings.resize(2);
22755 captured_varyings[0] = "trunks";
22756 captured_varyings[1] = "gohan";
22759 /** Get body of main function for given shader stage
22761 * @param test_case_index Index of test case
22762 * @param stage Shader stage
22763 * @param out_assignments Set to empty
22764 * @param out_calculations Set to empty
22766 void XFBOverrideQualifiersWithAPITest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
22767 std::string& out_assignments, std::string& out_calculations)
22769 out_calculations = "";
22771 static const GLchar* gs = " vegeta = uni_vegeta;\n"
22772 " trunks = uni_trunks;\n"
22773 " goku = uni_goku;\n"
22774 " gohan = uni_gohan;\n";
22775 static const GLchar* fs = " fs_out = vec4(0);\n"
22776 " if (TYPE(1) == gohan + goku + trunks + vegeta)\n"
22778 " fs_out = vec4(1);\n"
22781 const GLchar* assignments = "";
22784 case Utils::Shader::FRAGMENT:
22787 case Utils::Shader::GEOMETRY:
22794 out_assignments = assignments;
22796 if (Utils::Shader::FRAGMENT == stage)
22798 const Utils::Type& type = getType(test_case_index);
22800 Utils::replaceAllTokens("TYPE", type.GetGLSLTypeName(), out_assignments);
22804 /** Get interface of shader
22806 * @param test_case_index Index of test case
22807 * @param stage Shader stage
22808 * @param out_interface Set to ""
22810 void XFBOverrideQualifiersWithAPITest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
22811 std::string& out_interface)
22813 static const GLchar* gs = "const uint sizeof_type = SIZE;\n"
22815 "layout (xfb_offset = 2 * sizeof_type) flat out TYPE vegeta;\n"
22816 " flat out TYPE trunks;\n"
22817 "layout (xfb_offset = 0) flat out TYPE goku;\n"
22818 " flat out TYPE gohan;\n"
22821 There is no packing qualifier for uniform block gs_block, according to spec, it should be "shared" by default,
22822 the definition equals to "layout(binding=0, shared)", if the block is declared as shared, each block member will
22823 not be packed, and each block member's layout in memory is implementation dependent, so we can't use the API
22824 glBufferData() to update the UBO directly, we need to query each block member's offset first, then upload the
22825 data to the corresponding offset, otherwise we can't get the correct data from UBO; to make the test passed,
22826 we need to add the qualifier std140, and change the declaration as layout(binding=0, std140), which can make
22827 sure all the block members are packed and the application can upload the data by glBufferData() directly.
22829 "layout(binding = 0, std140) uniform gs_block {\n"
22830 " TYPE uni_vegeta;\n"
22831 " TYPE uni_trunks;\n"
22832 " TYPE uni_goku;\n"
22833 " TYPE uni_gohan;\n"
22835 static const GLchar* fs = "flat in TYPE vegeta;\n"
22836 "flat in TYPE trunks;\n"
22837 "flat in TYPE goku;\n"
22838 "flat in TYPE gohan;\n"
22840 "out vec4 fs_out;\n";
22842 const Utils::Type& type = getType(test_case_index);
22846 case Utils::Shader::FRAGMENT:
22847 out_interface = fs;
22849 case Utils::Shader::GEOMETRY:
22850 out_interface = gs;
22853 out_interface = "";
22857 if (Utils::Shader::GEOMETRY == stage)
22860 size_t position = 0;
22861 const GLuint type_size = type.GetSize();
22863 sprintf(buffer, "%d", type_size);
22865 Utils::replaceToken("SIZE", position, buffer, out_interface);
22868 Utils::replaceAllTokens("TYPE", type.GetGLSLTypeName(), out_interface);
22873 * @param test_case_index Index of test case
22875 * @return Name of type test in test_case_index
22877 std::string XFBOverrideQualifiersWithAPITest::getTestCaseName(glw::GLuint test_case_index)
22879 return getTypeName(test_case_index);
22882 /** Returns number of types to test
22884 * @return Number of types, 34
22886 glw::GLuint XFBOverrideQualifiersWithAPITest::getTestCaseNumber()
22888 return getTypesNumber();
22891 /** Inspects program to check if all resources are as expected
22893 * @param test_case_index Index of test case
22894 * @param program Program instance
22895 * @param out_stream Error message
22897 * @return true if everything is ok, false otherwise
22899 bool XFBOverrideQualifiersWithAPITest::inspectProgram(GLuint test_case_index, Utils::Program& program,
22900 std::stringstream& out_stream)
22903 const Utils::Type& type = getType(test_case_index);
22904 const GLuint type_size = type.GetSize();
22906 program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE,
22907 1 /* buf_size */, &stride);
22909 if ((GLint)(3 * type_size) != stride)
22911 out_stream << "Stride is: " << stride << " expected: " << (3 * type_size);
22921 * @param context Test context
22923 XFBVertexStreamsTest::XFBVertexStreamsTest(deqp::Context& context)
22924 : BufferTestBase(context, "xfb_vertex_streams",
22925 "Test verifies that xfb qualifier works with multiple output streams")
22927 /* Nothing to be done here */
22930 /** Get descriptors of buffers necessary for test
22933 * @param out_descriptors Descriptors of buffers used by test
22935 void XFBVertexStreamsTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
22936 bufferDescriptor::Vector& out_descriptors)
22938 const Utils::Type& type = Utils::Type::vec4;
22940 /* Test needs single uniform and three xfbs */
22941 out_descriptors.resize(4);
22943 /* Get references */
22944 bufferDescriptor& uniform = out_descriptors[0];
22945 bufferDescriptor& xfb_1 = out_descriptors[1];
22946 bufferDescriptor& xfb_2 = out_descriptors[2];
22947 bufferDescriptor& xfb_3 = out_descriptors[3];
22950 uniform.m_index = 0;
22956 uniform.m_target = Utils::Buffer::Uniform;
22957 xfb_1.m_target = Utils::Buffer::Transform_feedback;
22958 xfb_2.m_target = Utils::Buffer::Transform_feedback;
22959 xfb_3.m_target = Utils::Buffer::Transform_feedback;
22962 const std::vector<GLubyte>& goku_data = type.GenerateData();
22963 const std::vector<GLubyte>& gohan_data = type.GenerateData();
22964 const std::vector<GLubyte>& goten_data = type.GenerateData();
22965 const std::vector<GLubyte>& picolo_data = type.GenerateData();
22966 const std::vector<GLubyte>& vegeta_data = type.GenerateData();
22967 const std::vector<GLubyte>& bulma_data = type.GenerateData();
22969 const GLuint type_size = static_cast<GLuint>(vegeta_data.size());
22972 uniform.m_initial_data.resize(6 * type_size);
22973 memcpy(&uniform.m_initial_data[0] + 0, &goku_data[0], type_size);
22974 memcpy(&uniform.m_initial_data[0] + type_size, &gohan_data[0], type_size);
22975 memcpy(&uniform.m_initial_data[0] + 2 * type_size, &goten_data[0], type_size);
22976 memcpy(&uniform.m_initial_data[0] + 3 * type_size, &picolo_data[0], type_size);
22977 memcpy(&uniform.m_initial_data[0] + 4 * type_size, &vegeta_data[0], type_size);
22978 memcpy(&uniform.m_initial_data[0] + 5 * type_size, &bulma_data[0], type_size);
22981 static const GLuint xfb_stride = 64;
22982 xfb_1.m_initial_data.resize(xfb_stride);
22983 xfb_1.m_expected_data.resize(xfb_stride);
22984 xfb_2.m_initial_data.resize(xfb_stride);
22985 xfb_2.m_expected_data.resize(xfb_stride);
22986 xfb_3.m_initial_data.resize(xfb_stride);
22987 xfb_3.m_expected_data.resize(xfb_stride);
22989 for (GLuint i = 0; i < xfb_stride; ++i)
22991 xfb_1.m_initial_data[i] = (glw::GLubyte)i;
22992 xfb_1.m_expected_data[i] = (glw::GLubyte)i;
22993 xfb_2.m_initial_data[i] = (glw::GLubyte)i;
22994 xfb_2.m_expected_data[i] = (glw::GLubyte)i;
22995 xfb_3.m_initial_data[i] = (glw::GLubyte)i;
22996 xfb_3.m_expected_data[i] = (glw::GLubyte)i;
22999 memcpy(&xfb_1.m_expected_data[0] + 48, &goku_data[0], type_size);
23000 memcpy(&xfb_1.m_expected_data[0] + 32, &gohan_data[0], type_size);
23001 memcpy(&xfb_1.m_expected_data[0] + 16, &goten_data[0], type_size);
23002 memcpy(&xfb_3.m_expected_data[0] + 48, &picolo_data[0], type_size);
23003 memcpy(&xfb_3.m_expected_data[0] + 32, &vegeta_data[0], type_size);
23004 memcpy(&xfb_2.m_expected_data[0] + 32, &bulma_data[0], type_size);
23007 /** Get body of main function for given shader stage
23010 * @param stage Shader stage
23011 * @param out_assignments Set to empty
23012 * @param out_calculations Set to empty
23014 void XFBVertexStreamsTest::getShaderBody(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
23015 std::string& out_assignments, std::string& out_calculations)
23017 out_calculations = "";
23019 // the shader declares the output variables with different "stream" qualifier, to make the data can export to
23020 // each stream, we must call the function EmitStreamVertex() and EndStreamPrimitive() to make each vertex emitted
23021 // by the GS is assigned to specific stream.
23022 static const GLchar* gs = " goku = uni_goku;\n"
23023 " gohan = uni_gohan;\n"
23024 " goten = uni_goten;\n"
23025 " EmitStreamVertex(0);\n"
23026 " EndStreamPrimitive(0);\n"
23027 " picolo = uni_picolo;\n"
23028 " vegeta = uni_vegeta;\n"
23029 " EmitStreamVertex(1);\n"
23030 " EndStreamPrimitive(1);\n"
23031 " bulma = uni_bulma;\n"
23032 " EmitStreamVertex(2);\n"
23033 " EndStreamPrimitive(2);\n";
23035 static const GLchar* fs = " fs_out = gohan + goku + goten + picolo + vegeta + bulma;\n";
23037 const GLchar* assignments = "";
23040 case Utils::Shader::FRAGMENT:
23043 case Utils::Shader::GEOMETRY:
23050 out_assignments = assignments;
23053 /** Get interface of shader
23056 * @param stage Shader stage
23057 * @param out_interface Set to ""
23059 void XFBVertexStreamsTest::getShaderInterface(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
23060 std::string& out_interface)
23062 static const GLchar* gs = "layout (xfb_buffer = 1, xfb_stride = 64) out;\n"
23063 "layout (xfb_buffer = 2, xfb_stride = 64) out;\n"
23064 "layout (xfb_buffer = 3, xfb_stride = 64) out;\n"
23066 "layout (stream = 0, xfb_buffer = 1, xfb_offset = 48) out vec4 goku;\n"
23067 "layout (stream = 0, xfb_buffer = 1, xfb_offset = 32) out vec4 gohan;\n"
23068 "layout (stream = 0, xfb_buffer = 1, xfb_offset = 16) out vec4 goten;\n"
23069 "layout (stream = 1, xfb_buffer = 3, xfb_offset = 48) out vec4 picolo;\n"
23070 "layout (stream = 1, xfb_buffer = 3, xfb_offset = 32) out vec4 vegeta;\n"
23071 "layout (stream = 2, xfb_buffer = 2, xfb_offset = 32) out vec4 bulma;\n"
23073 "layout(binding = 0) uniform gs_block {\n"
23074 " vec4 uni_goku;\n"
23075 " vec4 uni_gohan;\n"
23076 " vec4 uni_goten;\n"
23077 " vec4 uni_picolo;\n"
23078 " vec4 uni_vegeta;\n"
23079 " vec4 uni_bulma;\n"
23082 Fixed incorrect usage of in/out qualifier, the following variable should be input symbols for fragment shader
23084 static const GLchar* fs = "in vec4 goku;\n"
23087 "in vec4 picolo;\n"
23088 "in vec4 vegeta;\n"
23091 "out vec4 fs_out;\n";
23095 case Utils::Shader::FRAGMENT:
23096 out_interface = fs;
23098 case Utils::Shader::GEOMETRY:
23099 out_interface = gs;
23102 out_interface = "";
23109 * @param context Test framework context
23111 XFBMultipleVertexStreamsTest::XFBMultipleVertexStreamsTest(deqp::Context& context)
23112 : NegativeTestBase(
23113 context, "xfb_multiple_vertex_streams",
23114 "Test verifies that compiler reports error when multiple streams are captured with same xfb_buffer")
23118 /** Source for given test case and stage
23121 * @param stage Shader stage
23123 * @return Shader source
23125 std::string XFBMultipleVertexStreamsTest::getShaderSource(GLuint /* test_case_index */, Utils::Shader::STAGES stage)
23127 static const GLchar* var_definition = "const uint valid_stride = 64;\n"
23129 "layout (xfb_buffer = 1, xfb_stride = valid_stride) out;\n"
23130 "layout (xfb_buffer = 3, xfb_stride = valid_stride) out;\n"
23133 "layout (stream = 0, xfb_buffer = 1, xfb_offset = 48) out vec4 goku;\n"
23134 "layout (stream = 1, xfb_buffer = 1, xfb_offset = 32) out vec4 gohan;\n"
23135 "layout (stream = 2, xfb_buffer = 1, xfb_offset = 16) out vec4 goten;\n";
23136 static const GLchar* var_use = " goku = result / 2;\n"
23137 " gohan = result / 4;\n"
23138 " goten = result / 6;\n";
23139 static const GLchar* fs = "#version 430 core\n"
23140 "#extension GL_ARB_enhanced_layouts : require\n"
23144 "out vec4 fs_out;\n"
23148 " fs_out = gs_fs + goku;\n"
23151 static const GLchar* gs = "#version 430 core\n"
23152 "#extension GL_ARB_enhanced_layouts : require\n"
23154 "layout(points) in;\n"
23155 "layout(triangle_strip, max_vertices = 4) out;\n"
23159 "in vec4 tes_gs[];\n"
23160 "out vec4 gs_fs;\n"
23164 " vec4 result = tes_gs[0];\n"
23168 " gs_fs = result;\n"
23169 " gl_Position = vec4(-1, -1, 0, 1);\n"
23171 " gs_fs = result;\n"
23172 " gl_Position = vec4(-1, 1, 0, 1);\n"
23174 " gs_fs = result;\n"
23175 " gl_Position = vec4(1, -1, 0, 1);\n"
23177 " gs_fs = result;\n"
23178 " gl_Position = vec4(1, 1, 0, 1);\n"
23182 static const GLchar* vs = "#version 430 core\n"
23183 "#extension GL_ARB_enhanced_layouts : require\n"
23186 "out vec4 vs_tcs;\n"
23190 " vs_tcs = in_vs;\n"
23194 std::string source;
23196 if (Utils::Shader::GEOMETRY == stage)
23198 size_t position = 0;
23202 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
23203 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
23209 case Utils::Shader::FRAGMENT:
23212 case Utils::Shader::VERTEX:
23223 /** Selects if "compute" stage is relevant for test
23229 bool XFBMultipleVertexStreamsTest::isComputeRelevant(GLuint /* test_case_index */)
23236 * @param context Test framework context
23238 XFBExceedBufferLimitTest::XFBExceedBufferLimitTest(deqp::Context& context)
23239 : NegativeTestBase(context, "xfb_exceed_buffer_limit",
23240 "Test verifies that compiler reports error when xfb_buffer qualifier exceeds limit")
23244 /** Source for given test case and stage
23246 * @param test_case_index Index of test case
23247 * @param stage Shader stage
23249 * @return Shader source
23251 std::string XFBExceedBufferLimitTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
23253 static const GLchar* block_var_definition = "const uint buffer_index = BUFFER;\n"
23255 "layout (xfb_buffer = buffer_index, xfb_offset = 0) out Goku {\n"
23258 static const GLchar* global_var_definition = "const uint buffer_index = BUFFER;\n"
23260 "layout (xfb_buffer = buffer_index) out;\n";
23261 static const GLchar* vector_var_definition = "const uint buffer_index = BUFFER;\n"
23263 "layout (xfb_buffer = buffer_index) out vec4 gokuARRAY;\n";
23264 static const GLchar* block_use = " gokuINDEX.member = result / 2;\n";
23265 static const GLchar* global_use = "";
23266 static const GLchar* vector_use = " gokuINDEX = result / 2;\n";
23267 static const GLchar* fs = "#version 430 core\n"
23268 "#extension GL_ARB_enhanced_layouts : require\n"
23271 "out vec4 fs_out;\n"
23275 " fs_out = gs_fs;\n"
23278 static const GLchar* gs_tested = "#version 430 core\n"
23279 "#extension GL_ARB_enhanced_layouts : require\n"
23281 "layout(points) in;\n"
23282 "layout(triangle_strip, max_vertices = 4) out;\n"
23286 "in vec4 tes_gs[];\n"
23287 "out vec4 gs_fs;\n"
23291 " vec4 result = tes_gs[0];\n"
23295 " gs_fs = result;\n"
23296 " gl_Position = vec4(-1, -1, 0, 1);\n"
23298 " gs_fs = result;\n"
23299 " gl_Position = vec4(-1, 1, 0, 1);\n"
23301 " gs_fs = result;\n"
23302 " gl_Position = vec4(1, -1, 0, 1);\n"
23304 " gs_fs = result;\n"
23305 " gl_Position = vec4(1, 1, 0, 1);\n"
23309 static const GLchar* tcs = "#version 430 core\n"
23310 "#extension GL_ARB_enhanced_layouts : require\n"
23312 "layout(vertices = 1) out;\n"
23314 "in vec4 vs_tcs[];\n"
23315 "out vec4 tcs_tes[];\n"
23320 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
23322 " gl_TessLevelOuter[0] = 1.0;\n"
23323 " gl_TessLevelOuter[1] = 1.0;\n"
23324 " gl_TessLevelOuter[2] = 1.0;\n"
23325 " gl_TessLevelOuter[3] = 1.0;\n"
23326 " gl_TessLevelInner[0] = 1.0;\n"
23327 " gl_TessLevelInner[1] = 1.0;\n"
23330 static const GLchar* tcs_tested = "#version 430 core\n"
23331 "#extension GL_ARB_enhanced_layouts : require\n"
23333 "layout(vertices = 1) out;\n"
23337 "in vec4 vs_tcs[];\n"
23338 "out vec4 tcs_tes[];\n"
23342 " vec4 result = vs_tcs[gl_InvocationID];\n"
23346 " tcs_tes[gl_InvocationID] = result;\n"
23348 " gl_TessLevelOuter[0] = 1.0;\n"
23349 " gl_TessLevelOuter[1] = 1.0;\n"
23350 " gl_TessLevelOuter[2] = 1.0;\n"
23351 " gl_TessLevelOuter[3] = 1.0;\n"
23352 " gl_TessLevelInner[0] = 1.0;\n"
23353 " gl_TessLevelInner[1] = 1.0;\n"
23356 static const GLchar* tes_tested = "#version 430 core\n"
23357 "#extension GL_ARB_enhanced_layouts : require\n"
23359 "layout(isolines, point_mode) in;\n"
23363 "in vec4 tcs_tes[];\n"
23364 "out vec4 tes_gs;\n"
23368 " vec4 result = tcs_tes[0];\n"
23372 " tes_gs += result;\n"
23375 static const GLchar* vs = "#version 430 core\n"
23376 "#extension GL_ARB_enhanced_layouts : require\n"
23379 "out vec4 vs_tcs;\n"
23383 " vs_tcs = in_vs;\n"
23386 static const GLchar* vs_tested = "#version 430 core\n"
23387 "#extension GL_ARB_enhanced_layouts : require\n"
23392 "out vec4 vs_tcs;\n"
23396 " vec4 result = in_vs;\n"
23400 " vs_tcs = result;\n"
23404 std::string source;
23405 testCase& test_case = m_test_cases[test_case_index];
23407 if (test_case.m_stage == stage)
23409 const GLchar* array = "";
23411 const Functions& gl = m_context.getRenderContext().getFunctions();
23412 const GLchar* index = "";
23413 GLint max_n_xfb = 0;
23414 size_t position = 0;
23416 const GLchar* var_definition = 0;
23417 const GLchar* var_use = 0;
23419 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_n_xfb);
23420 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
23422 sprintf(buffer, "%d", max_n_xfb);
23424 switch (test_case.m_case)
23427 var_definition = block_var_definition;
23428 var_use = block_use;
23431 var_definition = global_var_definition;
23432 var_use = global_use;
23435 var_definition = vector_var_definition;
23436 var_use = vector_use;
23439 TCU_FAIL("Invalid enum");
23444 case Utils::Shader::GEOMETRY:
23445 source = gs_tested;
23449 case Utils::Shader::TESS_CTRL:
23450 source = tcs_tested;
23452 index = "[gl_InvocationID]";
23454 case Utils::Shader::TESS_EVAL:
23455 source = tes_tested;
23459 case Utils::Shader::VERTEX:
23460 source = vs_tested;
23463 TCU_FAIL("Invalid enum");
23467 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
23469 Utils::replaceToken("BUFFER", position, buffer, source);
23470 if (GLOBAL != test_case.m_case)
23472 Utils::replaceToken("ARRAY", position, array, source);
23474 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
23476 Utils::replaceAllTokens("INDEX", index, source);
23480 switch (test_case.m_stage)
23482 case Utils::Shader::GEOMETRY:
23485 case Utils::Shader::FRAGMENT:
23488 case Utils::Shader::VERTEX:
23495 case Utils::Shader::TESS_CTRL:
23498 case Utils::Shader::FRAGMENT:
23501 case Utils::Shader::VERTEX:
23508 case Utils::Shader::TESS_EVAL:
23511 case Utils::Shader::FRAGMENT:
23514 case Utils::Shader::TESS_CTRL:
23517 case Utils::Shader::VERTEX:
23524 case Utils::Shader::VERTEX:
23527 case Utils::Shader::FRAGMENT:
23535 TCU_FAIL("Invalid enum");
23543 /** Get description of test case
23545 * @param test_case_index Index of test case
23547 * @return Test case description
23549 std::string XFBExceedBufferLimitTest::getTestCaseName(GLuint test_case_index)
23551 std::stringstream stream;
23552 testCase& test_case = m_test_cases[test_case_index];
23554 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", case: ";
23556 switch (test_case.m_case)
23562 stream << "GLOBAL";
23565 stream << "VECTOR";
23568 TCU_FAIL("Invalid enum");
23571 return stream.str();
23574 /** Get number of test cases
23576 * @return Number of test cases
23578 GLuint XFBExceedBufferLimitTest::getTestCaseNumber()
23580 return static_cast<GLuint>(m_test_cases.size());
23583 /** Selects if "compute" stage is relevant for test
23589 bool XFBExceedBufferLimitTest::isComputeRelevant(GLuint /* test_case_index */)
23594 /** Prepare all test cases
23597 void XFBExceedBufferLimitTest::testInit()
23599 for (GLuint c = 0; c < CASE_MAX; ++c)
23601 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
23603 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
23604 (Utils::Shader::FRAGMENT == stage))
23609 testCase test_case = { (CASES)c, (Utils::Shader::STAGES)stage };
23611 m_test_cases.push_back(test_case);
23618 * @param context Test framework context
23620 XFBExceedOffsetLimitTest::XFBExceedOffsetLimitTest(deqp::Context& context)
23621 : NegativeTestBase(context, "xfb_exceed_offset_limit",
23622 "Test verifies that compiler reports error when xfb_offset qualifier exceeds limit")
23626 /** Source for given test case and stage
23628 * @param test_case_index Index of test case
23629 * @param stage Shader stage
23631 * @return Shader source
23633 std::string XFBExceedOffsetLimitTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
23635 static const GLchar* block_var_definition = "const uint max_size = SIZE;\n"
23637 "layout (xfb_buffer = 0, xfb_offset = max_size + 16) out Goku {\n"
23640 static const GLchar* global_var_definition = "const uint max_size = SIZE;\n"
23642 "layout (xfb_buffer = 0, xfb_stride = max_size + 16) out;\n";
23643 static const GLchar* vector_var_definition =
23644 "const uint max_size = SIZE;\n"
23646 "layout (xfb_buffer = 0, xfb_offset = max_size + 16) out vec4 gokuARRAY;\n";
23647 static const GLchar* block_use = " gokuINDEX.member = result / 2;\n";
23648 static const GLchar* global_use = "";
23649 static const GLchar* vector_use = " gokuINDEX = result / 2;\n";
23650 static const GLchar* fs = "#version 430 core\n"
23651 "#extension GL_ARB_enhanced_layouts : require\n"
23654 "out vec4 fs_out;\n"
23658 " fs_out = gs_fs;\n"
23661 static const GLchar* gs_tested = "#version 430 core\n"
23662 "#extension GL_ARB_enhanced_layouts : require\n"
23664 "layout(points) in;\n"
23665 "layout(triangle_strip, max_vertices = 4) out;\n"
23669 "in vec4 tes_gs[];\n"
23670 "out vec4 gs_fs;\n"
23674 " vec4 result = tes_gs[0];\n"
23678 " gs_fs = result;\n"
23679 " gl_Position = vec4(-1, -1, 0, 1);\n"
23681 " gs_fs = result;\n"
23682 " gl_Position = vec4(-1, 1, 0, 1);\n"
23684 " gs_fs = result;\n"
23685 " gl_Position = vec4(1, -1, 0, 1);\n"
23687 " gs_fs = result;\n"
23688 " gl_Position = vec4(1, 1, 0, 1);\n"
23692 static const GLchar* tcs = "#version 430 core\n"
23693 "#extension GL_ARB_enhanced_layouts : require\n"
23695 "layout(vertices = 1) out;\n"
23697 "in vec4 vs_tcs[];\n"
23698 "out vec4 tcs_tes[];\n"
23703 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
23705 " gl_TessLevelOuter[0] = 1.0;\n"
23706 " gl_TessLevelOuter[1] = 1.0;\n"
23707 " gl_TessLevelOuter[2] = 1.0;\n"
23708 " gl_TessLevelOuter[3] = 1.0;\n"
23709 " gl_TessLevelInner[0] = 1.0;\n"
23710 " gl_TessLevelInner[1] = 1.0;\n"
23713 static const GLchar* tcs_tested = "#version 430 core\n"
23714 "#extension GL_ARB_enhanced_layouts : require\n"
23716 "layout(vertices = 1) out;\n"
23720 "in vec4 vs_tcs[];\n"
23721 "out vec4 tcs_tes[];\n"
23725 " vec4 result = vs_tcs[gl_InvocationID];\n"
23729 " tcs_tes[gl_InvocationID] = result;\n"
23731 " gl_TessLevelOuter[0] = 1.0;\n"
23732 " gl_TessLevelOuter[1] = 1.0;\n"
23733 " gl_TessLevelOuter[2] = 1.0;\n"
23734 " gl_TessLevelOuter[3] = 1.0;\n"
23735 " gl_TessLevelInner[0] = 1.0;\n"
23736 " gl_TessLevelInner[1] = 1.0;\n"
23739 static const GLchar* tes_tested = "#version 430 core\n"
23740 "#extension GL_ARB_enhanced_layouts : require\n"
23742 "layout(isolines, point_mode) in;\n"
23746 "in vec4 tcs_tes[];\n"
23747 "out vec4 tes_gs;\n"
23751 " vec4 result = tcs_tes[0];\n"
23755 " tes_gs += result;\n"
23758 static const GLchar* vs = "#version 430 core\n"
23759 "#extension GL_ARB_enhanced_layouts : require\n"
23762 "out vec4 vs_tcs;\n"
23766 " vs_tcs = in_vs;\n"
23769 static const GLchar* vs_tested = "#version 430 core\n"
23770 "#extension GL_ARB_enhanced_layouts : require\n"
23775 "out vec4 vs_tcs;\n"
23779 " vec4 result = in_vs;\n"
23783 " vs_tcs = result;\n"
23787 std::string source;
23788 testCase& test_case = m_test_cases[test_case_index];
23790 if (test_case.m_stage == stage)
23792 const GLchar* array = "";
23794 const Functions& gl = m_context.getRenderContext().getFunctions();
23795 const GLchar* index = "";
23796 GLint max_n_xfb_comp = 0;
23797 GLint max_n_xfb_bytes = 0;
23798 size_t position = 0;
23800 const GLchar* var_definition = 0;
23801 const GLchar* var_use = 0;
23803 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_n_xfb_comp);
23804 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
23806 max_n_xfb_bytes = max_n_xfb_comp * 4;
23808 sprintf(buffer, "%d", max_n_xfb_bytes);
23810 switch (test_case.m_case)
23813 var_definition = block_var_definition;
23814 var_use = block_use;
23817 var_definition = global_var_definition;
23818 var_use = global_use;
23821 var_definition = vector_var_definition;
23822 var_use = vector_use;
23825 TCU_FAIL("Invalid enum");
23827 // It is a compile time error to apply xfb_offset to the declaration of an unsized array(GLSL4.5 spec: Page73)
23828 // change array = "[]" to "[1]"
23831 case Utils::Shader::GEOMETRY:
23832 source = gs_tested;
23836 case Utils::Shader::TESS_CTRL:
23837 source = tcs_tested;
23839 index = "[gl_InvocationID]";
23841 case Utils::Shader::TESS_EVAL:
23842 source = tes_tested;
23846 case Utils::Shader::VERTEX:
23847 source = vs_tested;
23850 TCU_FAIL("Invalid enum");
23854 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
23856 Utils::replaceToken("SIZE", position, buffer, source);
23857 if (GLOBAL != test_case.m_case)
23859 Utils::replaceToken("ARRAY", position, array, source);
23861 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
23863 Utils::replaceAllTokens("INDEX", index, source);
23867 switch (test_case.m_stage)
23869 case Utils::Shader::GEOMETRY:
23872 case Utils::Shader::FRAGMENT:
23875 case Utils::Shader::VERTEX:
23882 case Utils::Shader::TESS_CTRL:
23885 case Utils::Shader::FRAGMENT:
23888 case Utils::Shader::VERTEX:
23895 case Utils::Shader::TESS_EVAL:
23898 case Utils::Shader::FRAGMENT:
23901 case Utils::Shader::TESS_CTRL:
23904 case Utils::Shader::VERTEX:
23911 case Utils::Shader::VERTEX:
23914 case Utils::Shader::FRAGMENT:
23922 TCU_FAIL("Invalid enum");
23930 /** Get description of test case
23932 * @param test_case_index Index of test case
23934 * @return Test case description
23936 std::string XFBExceedOffsetLimitTest::getTestCaseName(GLuint test_case_index)
23938 std::stringstream stream;
23939 testCase& test_case = m_test_cases[test_case_index];
23941 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", case: ";
23943 switch (test_case.m_case)
23949 stream << "GLOBAL";
23952 stream << "VECTOR";
23955 TCU_FAIL("Invalid enum");
23958 return stream.str();
23961 /** Get number of test cases
23963 * @return Number of test cases
23965 GLuint XFBExceedOffsetLimitTest::getTestCaseNumber()
23967 return static_cast<GLuint>(m_test_cases.size());
23970 /** Selects if "compute" stage is relevant for test
23976 bool XFBExceedOffsetLimitTest::isComputeRelevant(GLuint /* test_case_index */)
23981 /** Prepare all test cases
23984 void XFBExceedOffsetLimitTest::testInit()
23986 for (GLuint c = 0; c < CASE_MAX; ++c)
23988 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
23990 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
23991 (Utils::Shader::FRAGMENT == stage))
23996 testCase test_case = { (CASES)c, (Utils::Shader::STAGES)stage };
23998 m_test_cases.push_back(test_case);
24005 * @param context Test context
24007 XFBGlobalBufferTest::XFBGlobalBufferTest(deqp::Context& context)
24008 : BufferTestBase(context, "xfb_global_buffer", "Test verifies that global xfb_buffer qualifier is respected")
24010 /* Nothing to be done here */
24013 /** Get descriptors of buffers necessary for test
24015 * @param test_case_index Index of test case
24016 * @param out_descriptors Descriptors of buffers used by test
24018 void XFBGlobalBufferTest::getBufferDescriptors(glw::GLuint test_case_index, bufferDescriptor::Vector& out_descriptors)
24020 // the function "getType(test_case_index)" can't return correct data type, so change code as following:
24021 const Utils::Type& type = m_test_cases[test_case_index].m_type;
24023 /* Test needs single uniform and two xfbs */
24024 out_descriptors.resize(3);
24026 /* Get references */
24027 bufferDescriptor& uniform = out_descriptors[0];
24028 bufferDescriptor& xfb_1 = out_descriptors[1];
24029 bufferDescriptor& xfb_3 = out_descriptors[2];
24032 uniform.m_index = 0;
24037 uniform.m_target = Utils::Buffer::Uniform;
24038 xfb_1.m_target = Utils::Buffer::Transform_feedback;
24039 xfb_3.m_target = Utils::Buffer::Transform_feedback;
24042 const GLuint gen_start = Utils::s_rand;
24043 const std::vector<GLubyte>& chichi_data = type.GenerateData();
24044 const std::vector<GLubyte>& bulma_data = type.GenerateData();
24045 const std::vector<GLubyte>& trunks_data = type.GenerateData();
24046 const std::vector<GLubyte>& bra_data = type.GenerateData();
24047 const std::vector<GLubyte>& gohan_data = type.GenerateData();
24048 const std::vector<GLubyte>& goten_data = type.GenerateData();
24050 Utils::s_rand = gen_start;
24051 const std::vector<GLubyte>& chichi_data_pck = type.GenerateDataPacked();
24052 const std::vector<GLubyte>& bulma_data_pck = type.GenerateDataPacked();
24053 const std::vector<GLubyte>& trunks_data_pck = type.GenerateDataPacked();
24054 const std::vector<GLubyte>& bra_data_pck = type.GenerateDataPacked();
24055 const std::vector<GLubyte>& gohan_data_pck = type.GenerateDataPacked();
24056 const std::vector<GLubyte>& goten_data_pck = type.GenerateDataPacked();
24058 const GLuint type_size = static_cast<GLuint>(chichi_data.size());
24059 const GLuint type_size_pck = static_cast<GLuint>(chichi_data_pck.size());
24062 uniform.m_initial_data.resize(6 * type_size);
24063 memcpy(&uniform.m_initial_data[0] + 0, &chichi_data[0], type_size);
24064 memcpy(&uniform.m_initial_data[0] + type_size, &bulma_data[0], type_size);
24065 memcpy(&uniform.m_initial_data[0] + 2 * type_size, &trunks_data[0], type_size);
24066 memcpy(&uniform.m_initial_data[0] + 3 * type_size, &bra_data[0], type_size);
24067 memcpy(&uniform.m_initial_data[0] + 4 * type_size, &gohan_data[0], type_size);
24068 memcpy(&uniform.m_initial_data[0] + 5 * type_size, &goten_data[0], type_size);
24071 xfb_1.m_initial_data.resize(3 * type_size_pck);
24072 xfb_1.m_expected_data.resize(3 * type_size_pck);
24073 xfb_3.m_initial_data.resize(3 * type_size_pck);
24074 xfb_3.m_expected_data.resize(3 * type_size_pck);
24076 for (GLuint i = 0; i < 3 * type_size_pck; ++i)
24078 xfb_1.m_initial_data[i] = (glw::GLubyte)i;
24079 xfb_1.m_expected_data[i] = (glw::GLubyte)i;
24080 xfb_3.m_initial_data[i] = (glw::GLubyte)i;
24081 xfb_3.m_expected_data[i] = (glw::GLubyte)i;
24084 memcpy(&xfb_3.m_expected_data[0] + 2 * type_size_pck, &chichi_data_pck[0], type_size_pck);
24085 memcpy(&xfb_1.m_expected_data[0] + 0 * type_size_pck, &bulma_data_pck[0], type_size_pck);
24086 memcpy(&xfb_1.m_expected_data[0] + 1 * type_size_pck, &trunks_data_pck[0], type_size_pck);
24087 memcpy(&xfb_1.m_expected_data[0] + 2 * type_size_pck, &bra_data_pck[0], type_size_pck);
24088 memcpy(&xfb_3.m_expected_data[0] + 0 * type_size_pck, &gohan_data_pck[0], type_size_pck);
24089 memcpy(&xfb_3.m_expected_data[0] + 1 * type_size_pck, &goten_data_pck[0], type_size_pck);
24092 /** Source for given test case and stage
24094 * @param test_case_index Index of test case
24095 * @param stage Shader stage
24097 * @return Shader source
24099 std::string XFBGlobalBufferTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
24101 static const GLchar* fs =
24102 "#version 430 core\n"
24103 "#extension GL_ARB_enhanced_layouts : require\n"
24105 "flat in TYPE chichi;\n"
24106 "flat in TYPE bulma;\n"
24116 "out vec4 fs_out;\n"
24120 " fs_out = vec4(1);\n"
24121 " if (TYPE(1) != chichi + bulma + vegeta.trunk + vegeta.bra + goku.gohan + goku.goten)\n"
24123 " fs_out = vec4(0);\n"
24128 static const GLchar* gs = "#version 430 core\n"
24129 "#extension GL_ARB_enhanced_layouts : require\n"
24131 "layout(points) in;\n"
24132 "layout(points, max_vertices = 1) out;\n"
24143 static const GLchar* tcs = "#version 430 core\n"
24144 "#extension GL_ARB_enhanced_layouts : require\n"
24146 "layout(vertices = 1) out;\n"
24151 " gl_TessLevelOuter[0] = 1.0;\n"
24152 " gl_TessLevelOuter[1] = 1.0;\n"
24153 " gl_TessLevelOuter[2] = 1.0;\n"
24154 " gl_TessLevelOuter[3] = 1.0;\n"
24155 " gl_TessLevelInner[0] = 1.0;\n"
24156 " gl_TessLevelInner[1] = 1.0;\n"
24160 static const GLchar* tes = "#version 430 core\n"
24161 "#extension GL_ARB_enhanced_layouts : require\n"
24163 "layout(isolines, point_mode) in;\n"
24173 static const GLchar* vs = "#version 430 core\n"
24174 "#extension GL_ARB_enhanced_layouts : require\n"
24181 static const GLchar* vs_tested = "#version 430 core\n"
24182 "#extension GL_ARB_enhanced_layouts : require\n"
24192 std::string source;
24193 const _testCase& test_case = m_test_cases[test_case_index];
24194 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
24196 if (test_case.m_stage == stage)
24198 std::string assignments = " chichi = uni_chichi;\n"
24199 " bulma = uni_bulma;\n"
24200 " vegeta.trunk = uni_trunk;\n"
24201 " vegeta.bra = uni_bra;\n"
24202 " goku.gohan = uni_gohan;\n"
24203 " goku.goten = uni_goten;\n";
24205 std::string interface = "layout (xfb_buffer = 3) out;\n"
24207 "const uint type_size = SIZE;\n"
24209 "layout ( xfb_offset = 2 * type_size) flat out TYPE chichi;\n"
24210 "layout (xfb_buffer = 1, xfb_offset = 0) flat out TYPE bulma;\n"
24211 "layout (xfb_buffer = 1, xfb_offset = 1 * type_size) out Vegeta {\n"
24215 "layout ( xfb_offset = 0) out Goku {\n"
24220 // Uniform block must be declared with std140, otherwise each block member is not packed
24221 "layout(binding = 0, std140) uniform block {\n"
24222 " TYPE uni_chichi;\n"
24223 " TYPE uni_bulma;\n"
24224 " TYPE uni_trunk;\n"
24226 " TYPE uni_gohan;\n"
24227 " TYPE uni_goten;\n"
24230 /* Prepare interface string */
24233 size_t position = 0;
24234 const GLuint type_size = test_case.m_type.GetSize();
24236 sprintf(buffer, "%d", type_size);
24238 Utils::replaceToken("SIZE", position, buffer, interface);
24239 Utils::replaceAllTokens("TYPE", type_name, interface);
24244 case Utils::Shader::GEOMETRY:
24247 case Utils::Shader::TESS_EVAL:
24250 case Utils::Shader::VERTEX:
24251 source = vs_tested;
24254 TCU_FAIL("Invalid enum");
24257 /* Replace tokens */
24259 size_t position = 0;
24261 Utils::replaceToken("INTERFACE", position, interface.c_str(), source);
24262 Utils::replaceToken("ASSIGNMENTS", position, assignments.c_str(), source);
24267 switch (test_case.m_stage)
24269 case Utils::Shader::GEOMETRY:
24272 case Utils::Shader::FRAGMENT:
24274 Utils::replaceAllTokens("TYPE", type_name, source);
24276 case Utils::Shader::VERTEX:
24283 case Utils::Shader::TESS_EVAL:
24286 case Utils::Shader::FRAGMENT:
24288 Utils::replaceAllTokens("TYPE", type_name, source);
24290 case Utils::Shader::TESS_CTRL:
24293 case Utils::Shader::VERTEX:
24300 case Utils::Shader::VERTEX:
24303 case Utils::Shader::FRAGMENT:
24305 Utils::replaceAllTokens("TYPE", type_name, source);
24312 TCU_FAIL("Invalid enum");
24320 /** Get name of test case
24322 * @param test_case_index Index of test case
24324 * @return Name of case
24326 std::string XFBGlobalBufferTest::getTestCaseName(GLuint test_case_index)
24329 const _testCase& test_case = m_test_cases[test_case_index];
24331 name = "Tested stage: ";
24332 name.append(Utils::Shader::GetStageName(test_case.m_stage));
24333 name.append(". Tested type: ");
24334 name.append(test_case.m_type.GetGLSLTypeName());
24339 /** Get number of cases
24341 * @return Number of test cases
24343 GLuint XFBGlobalBufferTest::getTestCaseNumber()
24345 return static_cast<GLuint>(m_test_cases.size());
24348 /** Prepare set of test cases
24351 void XFBGlobalBufferTest::testInit()
24353 GLuint n_types = getTypesNumber();
24355 for (GLuint i = 0; i < n_types; ++i)
24357 const Utils::Type& type = getType(i);
24359 When the tfx varying is the following type, the number of output exceeds the gl_MaxVaryingComponents, which will
24360 cause a link time error.
24362 if (strcmp(type.GetGLSLTypeName(), "dmat3") == 0 || strcmp(type.GetGLSLTypeName(), "dmat4") == 0 ||
24363 strcmp(type.GetGLSLTypeName(), "dmat3x4") == 0 || strcmp(type.GetGLSLTypeName(), "dmat4x3") == 0)
24367 const _testCase test_cases[] = { { Utils::Shader::VERTEX, type },
24368 { Utils::Shader::GEOMETRY, type },
24369 { Utils::Shader::TESS_EVAL, type } };
24371 m_test_cases.push_back(test_cases[0]);
24372 m_test_cases.push_back(test_cases[1]);
24373 m_test_cases.push_back(test_cases[2]);
24379 * @param context Test context
24381 XFBStrideTest::XFBStrideTest(deqp::Context& context)
24382 : BufferTestBase(context, "xfb_stride", "Test verifies that correct stride is used for all types")
24384 /* Nothing to be done here */
24387 /** Execute drawArrays for single vertex
24389 * @param test_case_index
24393 bool XFBStrideTest::executeDrawCall(GLuint test_case_index)
24395 const Functions& gl = m_context.getRenderContext().getFunctions();
24396 GLenum primitive_type = GL_PATCHES;
24397 const testCase& test_case = m_test_cases[test_case_index];
24399 if (Utils::Shader::VERTEX == test_case.m_stage)
24401 primitive_type = GL_POINTS;
24404 gl.disable(GL_RASTERIZER_DISCARD);
24405 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
24407 gl.beginTransformFeedback(GL_POINTS);
24408 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
24410 gl.drawArrays(primitive_type, 0 /* first */, 2 /* count */);
24411 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
24413 gl.endTransformFeedback();
24414 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
24419 /** Get descriptors of buffers necessary for test
24421 * @param test_case_index Index of test case
24422 * @param out_descriptors Descriptors of buffers used by test
24424 void XFBStrideTest::getBufferDescriptors(GLuint test_case_index, bufferDescriptor::Vector& out_descriptors)
24426 const testCase& test_case = m_test_cases[test_case_index];
24427 const Utils::Type& type = test_case.m_type;
24429 /* Test needs single uniform and xfb */
24430 out_descriptors.resize(2);
24432 /* Get references */
24433 bufferDescriptor& uniform = out_descriptors[0];
24434 bufferDescriptor& xfb = out_descriptors[1];
24437 uniform.m_index = 0;
24441 uniform.m_target = Utils::Buffer::Uniform;
24442 xfb.m_target = Utils::Buffer::Transform_feedback;
24445 const GLuint rand_start = Utils::s_rand;
24446 const std::vector<GLubyte>& uniform_data = type.GenerateData();
24448 Utils::s_rand = rand_start;
24449 const std::vector<GLubyte>& xfb_data = type.GenerateDataPacked();
24451 const GLuint uni_type_size = static_cast<GLuint>(uniform_data.size());
24452 const GLuint xfb_type_size = static_cast<GLuint>(xfb_data.size());
24454 Note: If xfb varying output from vertex shader, the variable "goku" will only output once to transform feedback buffer,
24455 if xfb varying output from TES or GS, because the input primitive type in TES is defined as "layout(isolines, point_mode) in;",
24456 the primitive type is line which make the variable "goku" will output twice to transform feedback buffer, so for vertex shader
24457 only one valid data should be initialized in xfb.m_expected_data
24459 const GLuint xfb_data_size = (test_case.m_stage == Utils::Shader::VERTEX) ? xfb_type_size : xfb_type_size * 2;
24461 uniform.m_initial_data.resize(uni_type_size);
24462 memcpy(&uniform.m_initial_data[0] + 0 * uni_type_size, &uniform_data[0], uni_type_size);
24465 xfb.m_initial_data.resize(xfb_data_size);
24466 xfb.m_expected_data.resize(xfb_data_size);
24468 for (GLuint i = 0; i < xfb_data_size; ++i)
24470 xfb.m_initial_data[i] = (glw::GLubyte)i;
24471 xfb.m_expected_data[i] = (glw::GLubyte)i;
24474 if (test_case.m_stage == Utils::Shader::VERTEX)
24476 memcpy(&xfb.m_expected_data[0] + 0 * xfb_type_size, &xfb_data[0], xfb_type_size);
24480 memcpy(&xfb.m_expected_data[0] + 0 * xfb_type_size, &xfb_data[0], xfb_type_size);
24481 memcpy(&xfb.m_expected_data[0] + 1 * xfb_type_size, &xfb_data[0], xfb_type_size);
24485 /** Get body of main function for given shader stage
24487 * @param test_case_index Index of test case
24488 * @param stage Shader stage
24489 * @param out_assignments Set to empty
24490 * @param out_calculations Set to empty
24492 void XFBStrideTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage, std::string& out_assignments,
24493 std::string& out_calculations)
24495 const testCase& test_case = m_test_cases[test_case_index];
24497 out_calculations = "";
24499 static const GLchar* vs_tes_gs = " goku = uni_goku;\n";
24500 static const GLchar* fs = " fs_out = vec4(1, 0.25, 0.5, 0.75);\n"
24501 " if (TYPE(0) == goku)\n"
24503 " fs_out = vec4(1, 0.75, 0.5, 0.5);\n"
24506 const GLchar* assignments = "";
24508 if (test_case.m_stage == stage)
24512 case Utils::Shader::GEOMETRY:
24513 assignments = vs_tes_gs;
24515 case Utils::Shader::TESS_EVAL:
24516 assignments = vs_tes_gs;
24518 case Utils::Shader::VERTEX:
24519 assignments = vs_tes_gs;
24522 TCU_FAIL("Invalid enum");
24529 case Utils::Shader::FRAGMENT:
24532 case Utils::Shader::GEOMETRY:
24533 case Utils::Shader::TESS_CTRL:
24534 case Utils::Shader::TESS_EVAL:
24535 case Utils::Shader::VERTEX:
24538 TCU_FAIL("Invalid enum");
24542 out_assignments = assignments;
24544 if (Utils::Shader::FRAGMENT == stage)
24546 Utils::replaceAllTokens("TYPE", test_case.m_type.GetGLSLTypeName(), out_assignments);
24550 /** Get interface of shader
24552 * @param test_case_index Index of test case
24553 * @param stage Shader stage
24554 * @param out_interface Set to ""
24556 void XFBStrideTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage, std::string& out_interface)
24558 static const GLchar* vs_tes_gs = "layout (xfb_offset = 0) FLAT out TYPE goku;\n"
24560 "layout(std140, binding = 0) uniform Goku {\n"
24561 " TYPE uni_goku;\n"
24563 static const GLchar* fs = "FLAT in TYPE goku;\n"
24565 "out vec4 fs_out;\n";
24567 const testCase& test_case = m_test_cases[test_case_index];
24568 const GLchar* interface = "";
24569 const GLchar* flat = "";
24571 if (test_case.m_stage == stage)
24575 case Utils::Shader::GEOMETRY:
24576 interface = vs_tes_gs;
24578 case Utils::Shader::TESS_EVAL:
24579 interface = vs_tes_gs;
24581 case Utils::Shader::VERTEX:
24582 interface = vs_tes_gs;
24585 TCU_FAIL("Invalid enum");
24592 case Utils::Shader::FRAGMENT:
24595 case Utils::Shader::GEOMETRY:
24596 case Utils::Shader::TESS_CTRL:
24597 case Utils::Shader::TESS_EVAL:
24598 case Utils::Shader::VERTEX:
24601 TCU_FAIL("Invalid enum");
24605 out_interface = interface;
24607 if (Utils::Type::Float != test_case.m_type.m_basic_type)
24612 Utils::replaceAllTokens("FLAT", flat, out_interface);
24613 Utils::replaceAllTokens("TYPE", test_case.m_type.GetGLSLTypeName(), out_interface);
24616 /** Get source code of shader
24618 * @param test_case_index Index of test case
24619 * @param stage Shader stage
24623 std::string XFBStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
24625 std::string source;
24626 const testCase& test_case = m_test_cases[test_case_index];
24628 switch (test_case.m_stage)
24630 case Utils::Shader::VERTEX:
24633 case Utils::Shader::FRAGMENT:
24634 case Utils::Shader::VERTEX:
24635 source = BufferTestBase::getShaderSource(test_case_index, stage);
24642 case Utils::Shader::TESS_EVAL:
24645 case Utils::Shader::FRAGMENT:
24646 case Utils::Shader::TESS_CTRL:
24647 case Utils::Shader::TESS_EVAL:
24648 case Utils::Shader::VERTEX:
24649 source = BufferTestBase::getShaderSource(test_case_index, stage);
24656 case Utils::Shader::GEOMETRY:
24657 source = BufferTestBase::getShaderSource(test_case_index, stage);
24661 TCU_FAIL("Invalid enum");
24669 /** Get name of test case
24671 * @param test_case_index Index of test case
24673 * @return Name of tested stage
24675 std::string XFBStrideTest::getTestCaseName(glw::GLuint test_case_index)
24677 std::stringstream stream;
24678 const testCase& test_case = m_test_cases[test_case_index];
24680 stream << "Type: " << test_case.m_type.GetGLSLTypeName()
24681 << ", stage: " << Utils::Shader::GetStageName(test_case.m_stage);
24683 return stream.str();
24686 /** Returns number of test cases
24690 glw::GLuint XFBStrideTest::getTestCaseNumber()
24692 return static_cast<GLuint>(m_test_cases.size());
24695 /** Prepare all test cases
24698 void XFBStrideTest::testInit()
24700 const GLuint n_types = getTypesNumber();
24702 for (GLuint i = 0; i < n_types; ++i)
24704 const Utils::Type& type = getType(i);
24706 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
24708 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::FRAGMENT == stage) ||
24709 (Utils::Shader::TESS_CTRL == stage))
24714 testCase test_case = { (Utils::Shader::STAGES)stage, type };
24716 m_test_cases.push_back(test_case);
24723 * @param context Test framework context
24725 XFBBlockMemberBufferTest::XFBBlockMemberBufferTest(deqp::Context& context)
24726 : NegativeTestBase(
24727 context, "xfb_block_member_buffer",
24728 "Test verifies that compiler reports error when block member has different xfb_buffer qualifier than buffer")
24732 /** Source for given test case and stage
24734 * @param test_case_index Index of test case
24735 * @param stage Shader stage
24737 * @return Shader source
24739 std::string XFBBlockMemberBufferTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
24741 static const GLchar* var_definition = "layout (xfb_offset = 0) out Goku {\n"
24743 " layout (xfb_buffer = 1) vec4 goten;\n"
24745 static const GLchar* var_use = " gokuINDEX.gohan = result / 2;\n"
24746 " gokuINDEX.goten = result / 4;\n";
24747 static const GLchar* fs = "#version 430 core\n"
24748 "#extension GL_ARB_enhanced_layouts : require\n"
24751 "out vec4 fs_out;\n"
24755 " fs_out = gs_fs;\n"
24758 static const GLchar* gs_tested = "#version 430 core\n"
24759 "#extension GL_ARB_enhanced_layouts : require\n"
24761 "layout(points) in;\n"
24762 "layout(triangle_strip, max_vertices = 4) out;\n"
24766 "in vec4 tes_gs[];\n"
24767 "out vec4 gs_fs;\n"
24771 " vec4 result = tes_gs[0];\n"
24775 " gs_fs = result;\n"
24776 " gl_Position = vec4(-1, -1, 0, 1);\n"
24778 " gs_fs = result;\n"
24779 " gl_Position = vec4(-1, 1, 0, 1);\n"
24781 " gs_fs = result;\n"
24782 " gl_Position = vec4(1, -1, 0, 1);\n"
24784 " gs_fs = result;\n"
24785 " gl_Position = vec4(1, 1, 0, 1);\n"
24789 static const GLchar* tcs = "#version 430 core\n"
24790 "#extension GL_ARB_enhanced_layouts : require\n"
24792 "layout(vertices = 1) out;\n"
24794 "in vec4 vs_tcs[];\n"
24795 "out vec4 tcs_tes[];\n"
24800 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
24802 " gl_TessLevelOuter[0] = 1.0;\n"
24803 " gl_TessLevelOuter[1] = 1.0;\n"
24804 " gl_TessLevelOuter[2] = 1.0;\n"
24805 " gl_TessLevelOuter[3] = 1.0;\n"
24806 " gl_TessLevelInner[0] = 1.0;\n"
24807 " gl_TessLevelInner[1] = 1.0;\n"
24810 static const GLchar* tcs_tested = "#version 430 core\n"
24811 "#extension GL_ARB_enhanced_layouts : require\n"
24813 "layout(vertices = 1) out;\n"
24817 "in vec4 vs_tcs[];\n"
24818 "out vec4 tcs_tes[];\n"
24822 " vec4 result = vs_tcs[gl_InvocationID];\n"
24826 " tcs_tes[gl_InvocationID] = result;\n"
24828 " gl_TessLevelOuter[0] = 1.0;\n"
24829 " gl_TessLevelOuter[1] = 1.0;\n"
24830 " gl_TessLevelOuter[2] = 1.0;\n"
24831 " gl_TessLevelOuter[3] = 1.0;\n"
24832 " gl_TessLevelInner[0] = 1.0;\n"
24833 " gl_TessLevelInner[1] = 1.0;\n"
24836 static const GLchar* tes_tested = "#version 430 core\n"
24837 "#extension GL_ARB_enhanced_layouts : require\n"
24839 "layout(isolines, point_mode) in;\n"
24843 "in vec4 tcs_tes[];\n"
24844 "out vec4 tes_gs;\n"
24848 " vec4 result = tcs_tes[0];\n"
24852 " tes_gs += result;\n"
24855 static const GLchar* vs = "#version 430 core\n"
24856 "#extension GL_ARB_enhanced_layouts : require\n"
24859 "out vec4 vs_tcs;\n"
24863 " vs_tcs = in_vs;\n"
24866 static const GLchar* vs_tested = "#version 430 core\n"
24867 "#extension GL_ARB_enhanced_layouts : require\n"
24872 "out vec4 vs_tcs;\n"
24876 " vec4 result = in_vs;\n"
24880 " vs_tcs = result;\n"
24884 std::string source;
24885 testCase& test_case = m_test_cases[test_case_index];
24887 if (test_case.m_stage == stage)
24889 const GLchar* array = "";
24890 const GLchar* index = "";
24891 size_t position = 0;
24895 case Utils::Shader::GEOMETRY:
24896 source = gs_tested;
24900 case Utils::Shader::TESS_CTRL:
24901 source = tcs_tested;
24903 index = "[gl_InvocationID]";
24905 case Utils::Shader::TESS_EVAL:
24906 source = tes_tested;
24910 case Utils::Shader::VERTEX:
24911 source = vs_tested;
24914 TCU_FAIL("Invalid enum");
24917 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
24919 Utils::replaceToken("ARRAY", position, array, source);
24920 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
24922 Utils::replaceAllTokens("INDEX", index, source);
24926 switch (test_case.m_stage)
24928 case Utils::Shader::GEOMETRY:
24931 case Utils::Shader::FRAGMENT:
24934 case Utils::Shader::VERTEX:
24941 case Utils::Shader::TESS_CTRL:
24944 case Utils::Shader::FRAGMENT:
24947 case Utils::Shader::VERTEX:
24954 case Utils::Shader::TESS_EVAL:
24957 case Utils::Shader::FRAGMENT:
24960 case Utils::Shader::TESS_CTRL:
24963 case Utils::Shader::VERTEX:
24970 case Utils::Shader::VERTEX:
24973 case Utils::Shader::FRAGMENT:
24981 TCU_FAIL("Invalid enum");
24989 /** Get description of test case
24991 * @param test_case_index Index of test case
24993 * @return Test case description
24995 std::string XFBBlockMemberBufferTest::getTestCaseName(GLuint test_case_index)
24997 std::stringstream stream;
24998 testCase& test_case = m_test_cases[test_case_index];
25000 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage);
25002 return stream.str();
25005 /** Get number of test cases
25007 * @return Number of test cases
25009 GLuint XFBBlockMemberBufferTest::getTestCaseNumber()
25011 return static_cast<GLuint>(m_test_cases.size());
25014 /** Selects if "compute" stage is relevant for test
25020 bool XFBBlockMemberBufferTest::isComputeRelevant(GLuint /* test_case_index */)
25025 /** Prepare all test cases
25028 void XFBBlockMemberBufferTest::testInit()
25030 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
25032 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
25033 (Utils::Shader::FRAGMENT == stage))
25038 testCase test_case = { (Utils::Shader::STAGES)stage };
25040 m_test_cases.push_back(test_case);
25046 * @param context Test framework context
25048 XFBOutputOverlappingTest::XFBOutputOverlappingTest(deqp::Context& context)
25049 : NegativeTestBase(context, "xfb_output_overlapping",
25050 "Test verifies that compiler reports error when two xfb qualified outputs overlap")
25054 /** Source for given test case and stage
25056 * @param test_case_index Index of test case
25057 * @param stage Shader stage
25059 * @return Shader source
25061 std::string XFBOutputOverlappingTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
25063 static const GLchar* var_definition = "layout (xfb_offset = OFFSET) out TYPE gohanARRAY;\n"
25064 "layout (xfb_offset = OFFSET) out TYPE gotenARRAY;\n";
25065 static const GLchar* var_use = " gohanINDEX = TYPE(0);\n"
25066 " gotenINDEX = TYPE(1);\n"
25067 " if (vec4(0) == result)\n"
25069 " gohanINDEX = TYPE(1);\n"
25070 " gotenINDEX = TYPE(0);\n"
25072 static const GLchar* fs = "#version 430 core\n"
25073 "#extension GL_ARB_enhanced_layouts : require\n"
25076 "out vec4 fs_out;\n"
25080 " fs_out = gs_fs;\n"
25083 static const GLchar* gs_tested = "#version 430 core\n"
25084 "#extension GL_ARB_enhanced_layouts : require\n"
25086 "layout(points) in;\n"
25087 "layout(triangle_strip, max_vertices = 4) out;\n"
25091 "in vec4 tes_gs[];\n"
25092 "out vec4 gs_fs;\n"
25096 " vec4 result = tes_gs[0];\n"
25100 " gs_fs = result;\n"
25101 " gl_Position = vec4(-1, -1, 0, 1);\n"
25103 " gs_fs = result;\n"
25104 " gl_Position = vec4(-1, 1, 0, 1);\n"
25106 " gs_fs = result;\n"
25107 " gl_Position = vec4(1, -1, 0, 1);\n"
25109 " gs_fs = result;\n"
25110 " gl_Position = vec4(1, 1, 0, 1);\n"
25114 static const GLchar* tcs = "#version 430 core\n"
25115 "#extension GL_ARB_enhanced_layouts : require\n"
25117 "layout(vertices = 1) out;\n"
25119 "in vec4 vs_tcs[];\n"
25120 "out vec4 tcs_tes[];\n"
25125 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
25127 " gl_TessLevelOuter[0] = 1.0;\n"
25128 " gl_TessLevelOuter[1] = 1.0;\n"
25129 " gl_TessLevelOuter[2] = 1.0;\n"
25130 " gl_TessLevelOuter[3] = 1.0;\n"
25131 " gl_TessLevelInner[0] = 1.0;\n"
25132 " gl_TessLevelInner[1] = 1.0;\n"
25135 static const GLchar* tcs_tested = "#version 430 core\n"
25136 "#extension GL_ARB_enhanced_layouts : require\n"
25138 "layout(vertices = 1) out;\n"
25142 "in vec4 vs_tcs[];\n"
25143 "out vec4 tcs_tes[];\n"
25147 " vec4 result = vs_tcs[gl_InvocationID];\n"
25151 " tcs_tes[gl_InvocationID] = result;\n"
25153 " gl_TessLevelOuter[0] = 1.0;\n"
25154 " gl_TessLevelOuter[1] = 1.0;\n"
25155 " gl_TessLevelOuter[2] = 1.0;\n"
25156 " gl_TessLevelOuter[3] = 1.0;\n"
25157 " gl_TessLevelInner[0] = 1.0;\n"
25158 " gl_TessLevelInner[1] = 1.0;\n"
25161 static const GLchar* tes_tested = "#version 430 core\n"
25162 "#extension GL_ARB_enhanced_layouts : require\n"
25164 "layout(isolines, point_mode) in;\n"
25168 "in vec4 tcs_tes[];\n"
25169 "out vec4 tes_gs;\n"
25173 " vec4 result = tcs_tes[0];\n"
25177 " tes_gs += result;\n"
25180 static const GLchar* vs = "#version 430 core\n"
25181 "#extension GL_ARB_enhanced_layouts : require\n"
25184 "out vec4 vs_tcs;\n"
25188 " vs_tcs = in_vs;\n"
25191 static const GLchar* vs_tested = "#version 430 core\n"
25192 "#extension GL_ARB_enhanced_layouts : require\n"
25197 "out vec4 vs_tcs;\n"
25201 " vec4 result = in_vs;\n"
25205 " vs_tcs = result;\n"
25209 std::string source;
25210 testCase& test_case = m_test_cases[test_case_index];
25212 if (test_case.m_stage == stage)
25214 const GLchar* array = "";
25215 GLchar buffer_gohan[16];
25216 GLchar buffer_goten[16];
25217 const GLchar* index = "";
25218 size_t position = 0;
25219 size_t position_start = 0;
25220 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
25222 sprintf(buffer_gohan, "%d", test_case.m_offset_gohan);
25223 sprintf(buffer_goten, "%d", test_case.m_offset_goten);
25227 case Utils::Shader::GEOMETRY:
25228 source = gs_tested;
25232 case Utils::Shader::TESS_CTRL:
25233 source = tcs_tested;
25235 index = "[gl_InvocationID]";
25237 case Utils::Shader::TESS_EVAL:
25238 source = tes_tested;
25242 case Utils::Shader::VERTEX:
25243 source = vs_tested;
25246 TCU_FAIL("Invalid enum");
25249 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
25251 Utils::replaceToken("OFFSET", position, buffer_gohan, source);
25252 Utils::replaceToken("TYPE", position, type_name, source);
25253 Utils::replaceToken("ARRAY", position, array, source);
25254 Utils::replaceToken("OFFSET", position, buffer_goten, source);
25255 Utils::replaceToken("TYPE", position, type_name, source);
25256 Utils::replaceToken("ARRAY", position, array, source);
25257 position_start = position;
25258 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
25259 position = position_start;
25260 Utils::replaceToken("INDEX", position, index, source);
25261 Utils::replaceToken("TYPE", position, type_name, source);
25262 Utils::replaceToken("INDEX", position, index, source);
25263 Utils::replaceToken("TYPE", position, type_name, source);
25264 Utils::replaceToken("INDEX", position, index, source);
25265 Utils::replaceToken("TYPE", position, type_name, source);
25266 Utils::replaceToken("INDEX", position, index, source);
25267 Utils::replaceToken("TYPE", position, type_name, source);
25271 switch (test_case.m_stage)
25273 case Utils::Shader::GEOMETRY:
25276 case Utils::Shader::FRAGMENT:
25279 case Utils::Shader::VERTEX:
25286 case Utils::Shader::TESS_CTRL:
25289 case Utils::Shader::FRAGMENT:
25292 case Utils::Shader::VERTEX:
25299 case Utils::Shader::TESS_EVAL:
25302 case Utils::Shader::FRAGMENT:
25305 case Utils::Shader::TESS_CTRL:
25308 case Utils::Shader::VERTEX:
25315 case Utils::Shader::VERTEX:
25318 case Utils::Shader::FRAGMENT:
25326 TCU_FAIL("Invalid enum");
25334 /** Get description of test case
25336 * @param test_case_index Index of test case
25338 * @return Test case description
25340 std::string XFBOutputOverlappingTest::getTestCaseName(GLuint test_case_index)
25342 std::stringstream stream;
25343 testCase& test_case = m_test_cases[test_case_index];
25345 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
25346 << ", type: " << test_case.m_type.GetGLSLTypeName() << ", offsets: " << test_case.m_offset_gohan << " & "
25347 << test_case.m_offset_goten;
25349 return stream.str();
25352 /** Get number of test cases
25354 * @return Number of test cases
25356 GLuint XFBOutputOverlappingTest::getTestCaseNumber()
25358 return static_cast<GLuint>(m_test_cases.size());
25361 /** Selects if "compute" stage is relevant for test
25367 bool XFBOutputOverlappingTest::isComputeRelevant(GLuint /* test_case_index */)
25372 /** Prepare all test cases
25375 void XFBOutputOverlappingTest::testInit()
25377 const GLuint n_types = getTypesNumber();
25379 for (GLuint i = 0; i < n_types; ++i)
25381 const Utils::Type& type = getType(i);
25382 const GLuint base_alingment = Utils::Type::GetTypeSize(type.m_basic_type);
25384 /* Skip scalars, not applicable as:
25386 * The offset must be a multiple of the size of the first component of the first
25387 * qualified variable or block member, or a compile-time error results.
25389 if ((1 == type.m_n_columns) && (1 == type.m_n_rows))
25394 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
25396 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
25397 (Utils::Shader::FRAGMENT == stage))
25402 testCase test_case = { 0 /* gohan offset */, base_alingment /* goten_offset */,
25403 (Utils::Shader::STAGES)stage, type };
25405 m_test_cases.push_back(test_case);
25412 * @param context Test framework context
25414 XFBInvalidOffsetAlignmentTest::XFBInvalidOffsetAlignmentTest(deqp::Context& context)
25415 : NegativeTestBase(context, "xfb_invalid_offset_alignment",
25416 "Test verifies that compiler reports error when xfb_offset has invalid alignment")
25420 /** Source for given test case and stage
25422 * @param test_case_index Index of test case
25423 * @param stage Shader stage
25425 * @return Shader source
25427 std::string XFBInvalidOffsetAlignmentTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
25429 static const GLchar* var_definition = "layout (xfb_offset = OFFSET) out TYPE gohanARRAY;\n";
25430 static const GLchar* var_use = " gohanINDEX = TYPE(0);\n"
25431 " if (vec4(0) == result)\n"
25433 " gohanINDEX = TYPE(1);\n"
25435 static const GLchar* fs = "#version 430 core\n"
25436 "#extension GL_ARB_enhanced_layouts : require\n"
25439 "out vec4 fs_out;\n"
25443 " fs_out = gs_fs;\n"
25446 static const GLchar* gs_tested = "#version 430 core\n"
25447 "#extension GL_ARB_enhanced_layouts : require\n"
25449 "layout(points) in;\n"
25450 "layout(triangle_strip, max_vertices = 4) out;\n"
25454 "in vec4 tes_gs[];\n"
25455 "out vec4 gs_fs;\n"
25459 " vec4 result = tes_gs[0];\n"
25463 " gs_fs = result;\n"
25464 " gl_Position = vec4(-1, -1, 0, 1);\n"
25466 " gs_fs = result;\n"
25467 " gl_Position = vec4(-1, 1, 0, 1);\n"
25469 " gs_fs = result;\n"
25470 " gl_Position = vec4(1, -1, 0, 1);\n"
25472 " gs_fs = result;\n"
25473 " gl_Position = vec4(1, 1, 0, 1);\n"
25477 static const GLchar* tcs = "#version 430 core\n"
25478 "#extension GL_ARB_enhanced_layouts : require\n"
25480 "layout(vertices = 1) out;\n"
25482 "in vec4 vs_tcs[];\n"
25483 "out vec4 tcs_tes[];\n"
25488 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
25490 " gl_TessLevelOuter[0] = 1.0;\n"
25491 " gl_TessLevelOuter[1] = 1.0;\n"
25492 " gl_TessLevelOuter[2] = 1.0;\n"
25493 " gl_TessLevelOuter[3] = 1.0;\n"
25494 " gl_TessLevelInner[0] = 1.0;\n"
25495 " gl_TessLevelInner[1] = 1.0;\n"
25498 static const GLchar* tcs_tested = "#version 430 core\n"
25499 "#extension GL_ARB_enhanced_layouts : require\n"
25501 "layout(vertices = 1) out;\n"
25505 "in vec4 vs_tcs[];\n"
25506 "out vec4 tcs_tes[];\n"
25510 " vec4 result = vs_tcs[gl_InvocationID];\n"
25514 " tcs_tes[gl_InvocationID] = result;\n"
25516 " gl_TessLevelOuter[0] = 1.0;\n"
25517 " gl_TessLevelOuter[1] = 1.0;\n"
25518 " gl_TessLevelOuter[2] = 1.0;\n"
25519 " gl_TessLevelOuter[3] = 1.0;\n"
25520 " gl_TessLevelInner[0] = 1.0;\n"
25521 " gl_TessLevelInner[1] = 1.0;\n"
25524 static const GLchar* tes_tested = "#version 430 core\n"
25525 "#extension GL_ARB_enhanced_layouts : require\n"
25527 "layout(isolines, point_mode) in;\n"
25531 "in vec4 tcs_tes[];\n"
25532 "out vec4 tes_gs;\n"
25536 " vec4 result = tcs_tes[0];\n"
25540 " tes_gs += result;\n"
25543 static const GLchar* vs = "#version 430 core\n"
25544 "#extension GL_ARB_enhanced_layouts : require\n"
25547 "out vec4 vs_tcs;\n"
25551 " vs_tcs = in_vs;\n"
25554 static const GLchar* vs_tested = "#version 430 core\n"
25555 "#extension GL_ARB_enhanced_layouts : require\n"
25560 "out vec4 vs_tcs;\n"
25564 " vec4 result = in_vs;\n"
25568 " vs_tcs = result;\n"
25572 std::string source;
25573 testCase& test_case = m_test_cases[test_case_index];
25575 if (test_case.m_stage == stage)
25577 const GLchar* array = "";
25579 const GLchar* index = "";
25580 size_t position = 0;
25581 size_t position_start = 0;
25582 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
25584 sprintf(buffer, "%d", test_case.m_offset);
25588 case Utils::Shader::GEOMETRY:
25589 source = gs_tested;
25593 case Utils::Shader::TESS_CTRL:
25594 source = tcs_tested;
25596 index = "[gl_InvocationID]";
25598 case Utils::Shader::TESS_EVAL:
25599 source = tes_tested;
25603 case Utils::Shader::VERTEX:
25604 source = vs_tested;
25607 TCU_FAIL("Invalid enum");
25610 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
25612 Utils::replaceToken("OFFSET", position, buffer, source);
25613 Utils::replaceToken("TYPE", position, type_name, source);
25614 Utils::replaceToken("ARRAY", position, array, source);
25615 position_start = position;
25616 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
25617 position = position_start;
25618 Utils::replaceToken("INDEX", position, index, source);
25619 Utils::replaceToken("TYPE", position, type_name, source);
25620 Utils::replaceToken("INDEX", position, index, source);
25621 Utils::replaceToken("TYPE", position, type_name, source);
25625 switch (test_case.m_stage)
25627 case Utils::Shader::GEOMETRY:
25630 case Utils::Shader::FRAGMENT:
25633 case Utils::Shader::VERTEX:
25640 case Utils::Shader::TESS_CTRL:
25643 case Utils::Shader::FRAGMENT:
25646 case Utils::Shader::VERTEX:
25653 case Utils::Shader::TESS_EVAL:
25656 case Utils::Shader::FRAGMENT:
25659 case Utils::Shader::TESS_CTRL:
25662 case Utils::Shader::VERTEX:
25669 case Utils::Shader::VERTEX:
25672 case Utils::Shader::FRAGMENT:
25680 TCU_FAIL("Invalid enum");
25688 /** Get description of test case
25690 * @param test_case_index Index of test case
25692 * @return Test case description
25694 std::string XFBInvalidOffsetAlignmentTest::getTestCaseName(GLuint test_case_index)
25696 std::stringstream stream;
25697 testCase& test_case = m_test_cases[test_case_index];
25699 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
25700 << ", type: " << test_case.m_type.GetGLSLTypeName() << ", offset: " << test_case.m_offset;
25702 return stream.str();
25705 /** Get number of test cases
25707 * @return Number of test cases
25709 GLuint XFBInvalidOffsetAlignmentTest::getTestCaseNumber()
25711 return static_cast<GLuint>(m_test_cases.size());
25714 /** Selects if "compute" stage is relevant for test
25720 bool XFBInvalidOffsetAlignmentTest::isComputeRelevant(GLuint /* test_case_index */)
25725 /** Prepare all test cases
25728 void XFBInvalidOffsetAlignmentTest::testInit()
25730 const GLuint n_types = getTypesNumber();
25732 for (GLuint i = 0; i < n_types; ++i)
25734 const Utils::Type& type = getType(i);
25735 const GLuint base_alingment = Utils::Type::GetTypeSize(type.m_basic_type);
25737 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
25739 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
25740 (Utils::Shader::FRAGMENT == stage))
25745 for (GLuint offset = base_alingment + 1; offset < 2 * base_alingment; ++offset)
25747 testCase test_case = { offset, (Utils::Shader::STAGES)stage, type };
25749 m_test_cases.push_back(test_case);
25757 * @param context Test context
25759 XFBCaptureInactiveOutputVariableTest::XFBCaptureInactiveOutputVariableTest(deqp::Context& context)
25760 : BufferTestBase(context, "xfb_capture_inactive_output_variable",
25761 "Test verifies that inactive variables are captured")
25763 /* Nothing to be done here */
25766 /** Execute drawArrays for single vertex
25768 * @param test_case_index
25772 bool XFBCaptureInactiveOutputVariableTest::executeDrawCall(GLuint test_case_index)
25774 const Functions& gl = m_context.getRenderContext().getFunctions();
25775 GLenum primitive_type = GL_PATCHES;
25777 if (TEST_VS == test_case_index)
25779 primitive_type = GL_POINTS;
25782 gl.disable(GL_RASTERIZER_DISCARD);
25783 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
25785 gl.beginTransformFeedback(GL_POINTS);
25786 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
25788 gl.drawArrays(primitive_type, 0 /* first */, 1 /* count */);
25789 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
25791 gl.endTransformFeedback();
25792 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
25797 /** Get descriptors of buffers necessary for test
25800 * @param out_descriptors Descriptors of buffers used by test
25802 void XFBCaptureInactiveOutputVariableTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
25803 bufferDescriptor::Vector& out_descriptors)
25805 const Utils::Type& type = Utils::Type::vec4;
25807 /* Test needs single uniform and xfb */
25808 out_descriptors.resize(2);
25810 /* Get references */
25811 bufferDescriptor& uniform = out_descriptors[0];
25812 bufferDescriptor& xfb = out_descriptors[1];
25815 uniform.m_index = 0;
25819 uniform.m_target = Utils::Buffer::Uniform;
25820 xfb.m_target = Utils::Buffer::Transform_feedback;
25823 const std::vector<GLubyte>& gohan_data = type.GenerateData();
25824 const std::vector<GLubyte>& goten_data = type.GenerateData();
25826 const GLuint type_size = static_cast<GLuint>(gohan_data.size());
25829 uniform.m_initial_data.resize(2 * type_size);
25830 memcpy(&uniform.m_initial_data[0] + 0, &gohan_data[0], type_size);
25831 memcpy(&uniform.m_initial_data[0] + type_size, &goten_data[0], type_size);
25834 xfb.m_initial_data.resize(3 * type_size);
25835 xfb.m_expected_data.resize(3 * type_size);
25837 for (GLuint i = 0; i < 3 * type_size; ++i)
25839 xfb.m_initial_data[i] = (glw::GLubyte)i;
25840 xfb.m_expected_data[i] = (glw::GLubyte)i;
25843 memcpy(&xfb.m_expected_data[0] + 2 * type_size, &gohan_data[0], type_size);
25844 memcpy(&xfb.m_expected_data[0] + 0 * type_size, &goten_data[0], type_size);
25847 /** Get body of main function for given shader stage
25849 * @param test_case_index Index of test case
25850 * @param stage Shader stage
25851 * @param out_assignments Set to empty
25852 * @param out_calculations Set to empty
25854 void XFBCaptureInactiveOutputVariableTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
25855 std::string& out_assignments, std::string& out_calculations)
25857 out_calculations = "";
25859 static const GLchar* vs_tes_gs = " goten = uni_goten;\n"
25860 " gohan = uni_gohan;\n";
25861 static const GLchar* fs = " fs_out = goku + gohan + goten;\n";
25863 const GLchar* assignments = "";
25867 case Utils::Shader::FRAGMENT:
25871 case Utils::Shader::GEOMETRY:
25872 if (TEST_GS == test_case_index)
25874 assignments = vs_tes_gs;
25878 case Utils::Shader::TESS_CTRL:
25881 case Utils::Shader::TESS_EVAL:
25882 if (TEST_TES == test_case_index)
25884 assignments = vs_tes_gs;
25888 case Utils::Shader::VERTEX:
25889 if (TEST_VS == test_case_index)
25891 assignments = vs_tes_gs;
25896 TCU_FAIL("Invalid enum");
25899 out_assignments = assignments;
25902 /** Get interface of shader
25904 * @param test_case_index Index of test case
25905 * @param stage Shader stage
25906 * @param out_interface Set to ""
25908 void XFBCaptureInactiveOutputVariableTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
25909 std::string& out_interface)
25911 static const GLchar* vs_tes_gs = "const uint sizeof_type = 16;\n"
25913 "layout (xfb_offset = 1 * sizeof_type) out vec4 goku;\n"
25914 "layout (xfb_offset = 2 * sizeof_type) out vec4 gohan;\n"
25915 "layout (xfb_offset = 0 * sizeof_type) out vec4 goten;\n"
25917 "layout(binding = 0) uniform block {\n"
25918 " vec4 uni_gohan;\n"
25919 " vec4 uni_goten;\n"
25921 static const GLchar* fs = "in vec4 goku;\n"
25924 "out vec4 fs_out;\n";
25926 const GLchar* interface = "";
25930 case Utils::Shader::FRAGMENT:
25934 case Utils::Shader::GEOMETRY:
25935 if (TEST_GS == test_case_index)
25937 interface = vs_tes_gs;
25941 case Utils::Shader::TESS_CTRL:
25944 case Utils::Shader::TESS_EVAL:
25945 if (TEST_TES == test_case_index)
25947 interface = vs_tes_gs;
25951 case Utils::Shader::VERTEX:
25952 if (TEST_VS == test_case_index)
25954 interface = vs_tes_gs;
25959 TCU_FAIL("Invalid enum");
25962 out_interface = interface;
25965 /** Get source code of shader
25967 * @param test_case_index Index of test case
25968 * @param stage Shader stage
25972 std::string XFBCaptureInactiveOutputVariableTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
25974 std::string source;
25976 switch (test_case_index)
25981 case Utils::Shader::FRAGMENT:
25982 case Utils::Shader::VERTEX:
25983 source = BufferTestBase::getShaderSource(test_case_index, stage);
25993 case Utils::Shader::FRAGMENT:
25994 case Utils::Shader::TESS_CTRL:
25995 case Utils::Shader::TESS_EVAL:
25996 case Utils::Shader::VERTEX:
25997 source = BufferTestBase::getShaderSource(test_case_index, stage);
26005 source = BufferTestBase::getShaderSource(test_case_index, stage);
26009 TCU_FAIL("Invalid enum");
26017 /** Get name of test case
26019 * @param test_case_index Index of test case
26021 * @return Name of tested stage
26023 std::string XFBCaptureInactiveOutputVariableTest::getTestCaseName(glw::GLuint test_case_index)
26025 const GLchar* name = 0;
26027 switch (test_case_index)
26033 name = "tesselation evaluation";
26039 TCU_FAIL("Invalid enum");
26045 /** Returns number of test cases
26049 glw::GLuint XFBCaptureInactiveOutputVariableTest::getTestCaseNumber()
26054 /** Inspects program to check if all resources are as expected
26057 * @param program Program instance
26058 * @param out_stream Error message
26060 * @return true if everything is ok, false otherwise
26062 bool XFBCaptureInactiveOutputVariableTest::inspectProgram(GLuint /* test_case_index */, Utils::Program& program,
26063 std::stringstream& out_stream)
26066 const Utils::Type& type = Utils::Type::vec4;
26067 const GLuint type_size = type.GetSize();
26069 program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE,
26070 1 /* buf_size */, &stride);
26072 if ((GLint)(3 * type_size) != stride)
26074 out_stream << "Stride is: " << stride << " expected: " << (3 * type_size);
26082 /** Verify contents of buffers
26084 * @param buffers Collection of buffers to be verified
26086 * @return true if everything is as expected, false otherwise
26088 bool XFBCaptureInactiveOutputVariableTest::verifyBuffers(bufferCollection& buffers)
26090 bool result = true;
26092 bufferCollection::pair& pair = buffers.m_vector[1] /* xfb */;
26093 Utils::Buffer* buffer = pair.m_buffer;
26094 bufferDescriptor* descriptor = pair.m_descriptor;
26096 /* Get pointer to contents of buffer */
26098 GLubyte* buffer_data = (GLubyte*)buffer->Map(Utils::Buffer::ReadOnly);
26100 /* Get pointer to expected data */
26101 GLubyte* expected_data = (GLubyte*)&descriptor->m_expected_data[0];
26104 static const GLuint vec4_size = 16;
26106 int res_gohan = memcmp(buffer_data + 2 * vec4_size, expected_data + 2 * vec4_size, vec4_size);
26107 int res_goten = memcmp(buffer_data + 0 * vec4_size, expected_data + 0 * vec4_size, vec4_size);
26109 if ((0 != res_gohan) || (0 != res_goten))
26111 m_context.getTestContext().getLog()
26112 << tcu::TestLog::Message << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
26113 << ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
26118 /* Release buffer mapping */
26126 * @param context Test context
26128 XFBCaptureInactiveOutputComponentTest::XFBCaptureInactiveOutputComponentTest(deqp::Context& context)
26129 : BufferTestBase(context, "xfb_capture_inactive_output_component",
26130 "Test verifies that inactive components are not modified")
26132 /* Nothing to be done here */
26135 /** Execute drawArrays for single vertex
26137 * @param test_case_index
26141 bool XFBCaptureInactiveOutputComponentTest::executeDrawCall(GLuint test_case_index)
26143 const Functions& gl = m_context.getRenderContext().getFunctions();
26144 GLenum primitive_type = GL_PATCHES;
26146 if (TEST_VS == test_case_index)
26148 primitive_type = GL_POINTS;
26151 gl.disable(GL_RASTERIZER_DISCARD);
26152 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
26154 gl.beginTransformFeedback(GL_POINTS);
26155 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
26157 gl.drawArrays(primitive_type, 0 /* first */, 1 /* count */);
26158 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
26160 gl.endTransformFeedback();
26161 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
26166 /** Get descriptors of buffers necessary for test
26169 * @param out_descriptors Descriptors of buffers used by test
26171 void XFBCaptureInactiveOutputComponentTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
26172 bufferDescriptor::Vector& out_descriptors)
26174 const Utils::Type& type = Utils::Type::vec4;
26176 /* Test needs single uniform and xfb */
26177 out_descriptors.resize(2);
26179 /* Get references */
26180 bufferDescriptor& uniform = out_descriptors[0];
26181 bufferDescriptor& xfb = out_descriptors[1];
26184 uniform.m_index = 0;
26188 uniform.m_target = Utils::Buffer::Uniform;
26189 xfb.m_target = Utils::Buffer::Transform_feedback;
26192 const std::vector<GLubyte>& goku_data = type.GenerateData();
26193 const std::vector<GLubyte>& gohan_data = type.GenerateData();
26194 const std::vector<GLubyte>& goten_data = type.GenerateData();
26195 const std::vector<GLubyte>& chichi_data = type.GenerateData();
26196 const std::vector<GLubyte>& vegeta_data = type.GenerateData();
26197 const std::vector<GLubyte>& trunks_data = type.GenerateData();
26198 const std::vector<GLubyte>& bra_data = type.GenerateData();
26199 const std::vector<GLubyte>& bulma_data = type.GenerateData();
26201 const GLuint comp_size = Utils::Type::GetTypeSize(type.m_basic_type);
26202 const GLuint type_size = static_cast<GLuint>(gohan_data.size());
26205 uniform.m_initial_data.resize(8 * type_size);
26206 memcpy(&uniform.m_initial_data[0] + 0 * type_size, &goku_data[0], type_size);
26207 memcpy(&uniform.m_initial_data[0] + 1 * type_size, &gohan_data[0], type_size);
26208 memcpy(&uniform.m_initial_data[0] + 2 * type_size, &goten_data[0], type_size);
26209 memcpy(&uniform.m_initial_data[0] + 3 * type_size, &chichi_data[0], type_size);
26210 memcpy(&uniform.m_initial_data[0] + 4 * type_size, &vegeta_data[0], type_size);
26211 memcpy(&uniform.m_initial_data[0] + 5 * type_size, &trunks_data[0], type_size);
26212 memcpy(&uniform.m_initial_data[0] + 6 * type_size, &bra_data[0], type_size);
26213 memcpy(&uniform.m_initial_data[0] + 7 * type_size, &bulma_data[0], type_size);
26216 xfb.m_initial_data.resize(8 * type_size);
26217 xfb.m_expected_data.resize(8 * type_size);
26219 for (GLuint i = 0; i < 8 * type_size; ++i)
26221 xfb.m_initial_data[i] = (glw::GLubyte)i;
26222 xfb.m_expected_data[i] = (glw::GLubyte)i;
26225 /* goku - x, z - 32 */
26226 memcpy(&xfb.m_expected_data[0] + 2 * type_size + 0 * comp_size, &goku_data[0] + 0 * comp_size, comp_size);
26227 memcpy(&xfb.m_expected_data[0] + 2 * type_size + 2 * comp_size, &goku_data[0] + 2 * comp_size, comp_size);
26229 /* gohan - y, w - 0 */
26230 memcpy(&xfb.m_expected_data[0] + 0 * type_size + 1 * comp_size, &gohan_data[0] + 1 * comp_size, comp_size);
26231 memcpy(&xfb.m_expected_data[0] + 0 * type_size + 3 * comp_size, &gohan_data[0] + 3 * comp_size, comp_size);
26233 /* goten - x, y - 16 */
26234 memcpy(&xfb.m_expected_data[0] + 1 * type_size + 0 * comp_size, &goten_data[0] + 0 * comp_size, comp_size);
26235 memcpy(&xfb.m_expected_data[0] + 1 * type_size + 1 * comp_size, &goten_data[0] + 1 * comp_size, comp_size);
26237 /* chichi - z, w - 48 */
26238 memcpy(&xfb.m_expected_data[0] + 3 * type_size + 2 * comp_size, &chichi_data[0] + 2 * comp_size, comp_size);
26239 memcpy(&xfb.m_expected_data[0] + 3 * type_size + 3 * comp_size, &chichi_data[0] + 3 * comp_size, comp_size);
26241 /* vegeta - x - 112 */
26242 memcpy(&xfb.m_expected_data[0] + 7 * type_size + 0 * comp_size, &vegeta_data[0] + 0 * comp_size, comp_size);
26244 /* trunks - y - 96 */
26245 memcpy(&xfb.m_expected_data[0] + 6 * type_size + 1 * comp_size, &trunks_data[0] + 1 * comp_size, comp_size);
26248 memcpy(&xfb.m_expected_data[0] + 5 * type_size + 2 * comp_size, &bra_data[0] + 2 * comp_size, comp_size);
26250 /* bulma - w - 64 */
26251 memcpy(&xfb.m_expected_data[0] + 4 * type_size + 3 * comp_size, &bulma_data[0] + 3 * comp_size, comp_size);
26254 /** Get body of main function for given shader stage
26256 * @param test_case_index Index of test case
26257 * @param stage Shader stage
26258 * @param out_assignments Set to empty
26259 * @param out_calculations Set to empty
26261 void XFBCaptureInactiveOutputComponentTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
26262 std::string& out_assignments, std::string& out_calculations)
26264 out_calculations = "";
26266 static const GLchar* vs_tes_gs = " goku.x = uni_goku.x ;\n"
26267 " goku.z = uni_goku.z ;\n"
26268 " gohan.y = uni_gohan.y ;\n"
26269 " gohan.w = uni_gohan.w ;\n"
26270 " goten.x = uni_goten.x ;\n"
26271 " goten.y = uni_goten.y ;\n"
26272 " chichi.z = uni_chichi.z ;\n"
26273 " chichi.w = uni_chichi.w ;\n"
26274 " vegeta.x = uni_vegeta.x ;\n"
26275 " trunks.y = uni_trunks.y ;\n"
26276 " bra.z = uni_bra.z ;\n"
26277 " bulma.w = uni_bulma.w ;\n";
26278 static const GLchar* fs = " fs_out = goku + gohan + goten + chichi + vegeta + trunks + bra + bulma;\n";
26280 const GLchar* assignments = "";
26284 case Utils::Shader::FRAGMENT:
26288 case Utils::Shader::GEOMETRY:
26289 if (TEST_GS == test_case_index)
26291 assignments = vs_tes_gs;
26295 case Utils::Shader::TESS_CTRL:
26298 case Utils::Shader::TESS_EVAL:
26299 if (TEST_TES == test_case_index)
26301 assignments = vs_tes_gs;
26305 case Utils::Shader::VERTEX:
26306 if (TEST_VS == test_case_index)
26308 assignments = vs_tes_gs;
26313 TCU_FAIL("Invalid enum");
26316 out_assignments = assignments;
26319 /** Get interface of shader
26321 * @param test_case_index Index of test case
26322 * @param stage Shader stage
26323 * @param out_interface Set to ""
26325 void XFBCaptureInactiveOutputComponentTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
26326 std::string& out_interface)
26328 static const GLchar* vs_tes_gs = "const uint sizeof_type = 16;\n"
26330 "layout (xfb_offset = 2 * sizeof_type) out vec4 goku;\n"
26331 "layout (xfb_offset = 0 * sizeof_type) out vec4 gohan;\n"
26332 "layout (xfb_offset = 1 * sizeof_type) out vec4 goten;\n"
26333 "layout (xfb_offset = 3 * sizeof_type) out vec4 chichi;\n"
26334 "layout (xfb_offset = 7 * sizeof_type) out vec4 vegeta;\n"
26335 "layout (xfb_offset = 6 * sizeof_type) out vec4 trunks;\n"
26336 "layout (xfb_offset = 5 * sizeof_type) out vec4 bra;\n"
26337 "layout (xfb_offset = 4 * sizeof_type) out vec4 bulma;\n"
26339 "layout(binding = 0) uniform block {\n"
26340 " vec4 uni_goku;\n"
26341 " vec4 uni_gohan;\n"
26342 " vec4 uni_goten;\n"
26343 " vec4 uni_chichi;\n"
26344 " vec4 uni_vegeta;\n"
26345 " vec4 uni_trunks;\n"
26347 " vec4 uni_bulma;\n"
26349 static const GLchar* fs = "in vec4 vegeta;\n"
26350 "in vec4 trunks;\n"
26356 "in vec4 chichi;\n"
26358 "out vec4 fs_out;\n";
26360 const GLchar* interface = "";
26364 case Utils::Shader::FRAGMENT:
26368 case Utils::Shader::GEOMETRY:
26369 if (TEST_GS == test_case_index)
26371 interface = vs_tes_gs;
26375 case Utils::Shader::TESS_CTRL:
26378 case Utils::Shader::TESS_EVAL:
26379 if (TEST_TES == test_case_index)
26381 interface = vs_tes_gs;
26385 case Utils::Shader::VERTEX:
26386 if (TEST_VS == test_case_index)
26388 interface = vs_tes_gs;
26393 TCU_FAIL("Invalid enum");
26396 out_interface = interface;
26399 /** Get source code of shader
26401 * @param test_case_index Index of test case
26402 * @param stage Shader stage
26406 std::string XFBCaptureInactiveOutputComponentTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
26408 std::string source;
26410 switch (test_case_index)
26415 case Utils::Shader::FRAGMENT:
26416 case Utils::Shader::VERTEX:
26417 source = BufferTestBase::getShaderSource(test_case_index, stage);
26427 case Utils::Shader::FRAGMENT:
26428 case Utils::Shader::TESS_CTRL:
26429 case Utils::Shader::TESS_EVAL:
26430 case Utils::Shader::VERTEX:
26431 source = BufferTestBase::getShaderSource(test_case_index, stage);
26439 source = BufferTestBase::getShaderSource(test_case_index, stage);
26443 TCU_FAIL("Invalid enum");
26451 /** Get name of test case
26453 * @param test_case_index Index of test case
26455 * @return Name of tested stage
26457 std::string XFBCaptureInactiveOutputComponentTest::getTestCaseName(glw::GLuint test_case_index)
26459 const GLchar* name = 0;
26461 switch (test_case_index)
26467 name = "tesselation evaluation";
26473 TCU_FAIL("Invalid enum");
26479 /** Returns number of test cases
26483 glw::GLuint XFBCaptureInactiveOutputComponentTest::getTestCaseNumber()
26488 /** Verify contents of buffers
26490 * @param buffers Collection of buffers to be verified
26492 * @return true if everything is as expected, false otherwise
26494 bool XFBCaptureInactiveOutputComponentTest::verifyBuffers(bufferCollection& buffers)
26496 bool result = true;
26498 bufferCollection::pair& pair = buffers.m_vector[1] /* xfb */;
26499 Utils::Buffer* buffer = pair.m_buffer;
26500 bufferDescriptor* descriptor = pair.m_descriptor;
26502 /* Get pointer to contents of buffer */
26504 GLubyte* buffer_data = (GLubyte*)buffer->Map(Utils::Buffer::ReadOnly);
26506 /* Get pointer to expected data */
26507 GLubyte* expected_data = (GLubyte*)&descriptor->m_expected_data[0];
26510 static const GLuint comp_size = 4;
26511 static const GLuint vec4_size = 16;
26514 memcmp(buffer_data + 2 * vec4_size + 0 * comp_size, expected_data + 2 * vec4_size + 0 * comp_size, comp_size);
26516 memcmp(buffer_data + 2 * vec4_size + 2 * comp_size, expected_data + 2 * vec4_size + 2 * comp_size, comp_size);
26519 memcmp(buffer_data + 0 * vec4_size + 1 * comp_size, expected_data + 0 * vec4_size + 1 * comp_size, comp_size);
26521 memcmp(buffer_data + 0 * vec4_size + 3 * comp_size, expected_data + 0 * vec4_size + 3 * comp_size, comp_size);
26524 memcmp(buffer_data + 1 * vec4_size + 0 * comp_size, expected_data + 1 * vec4_size + 0 * comp_size, comp_size);
26526 memcmp(buffer_data + 1 * vec4_size + 1 * comp_size, expected_data + 1 * vec4_size + 1 * comp_size, comp_size);
26529 memcmp(buffer_data + 3 * vec4_size + 2 * comp_size, expected_data + 3 * vec4_size + 2 * comp_size, comp_size);
26531 memcmp(buffer_data + 3 * vec4_size + 3 * comp_size, expected_data + 3 * vec4_size + 3 * comp_size, comp_size);
26534 memcmp(buffer_data + 7 * vec4_size + 0 * comp_size, expected_data + 7 * vec4_size + 0 * comp_size, comp_size);
26537 memcmp(buffer_data + 6 * vec4_size + 1 * comp_size, expected_data + 6 * vec4_size + 1 * comp_size, comp_size);
26540 memcmp(buffer_data + 5 * vec4_size + 2 * comp_size, expected_data + 5 * vec4_size + 2 * comp_size, comp_size);
26543 memcmp(buffer_data + 4 * vec4_size + 3 * comp_size, expected_data + 4 * vec4_size + 3 * comp_size, comp_size);
26545 if ((0 != res_goku_x) || (0 != res_goku_z) || (0 != res_gohan_y) || (0 != res_gohan_w) || (0 != res_goten_x) ||
26546 (0 != res_goten_y) || (0 != res_chichi_z) || (0 != res_chichi_w) || (0 != res_vegeta_x) ||
26547 (0 != res_trunks_y) || (0 != res_bra_z) || (0 != res_bulma_w))
26549 m_context.getTestContext().getLog()
26550 << tcu::TestLog::Message << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
26551 << ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
26556 /* Release buffer mapping */
26564 * @param context Test context
26566 XFBCaptureInactiveOutputBlockMemberTest::XFBCaptureInactiveOutputBlockMemberTest(deqp::Context& context)
26567 : BufferTestBase(context, "xfb_capture_inactive_output_block_member",
26568 "Test verifies that inactive block members are captured")
26570 /* Nothing to be done here */
26573 /** Execute drawArrays for single vertex
26575 * @param test_case_index
26579 bool XFBCaptureInactiveOutputBlockMemberTest::executeDrawCall(GLuint test_case_index)
26581 const Functions& gl = m_context.getRenderContext().getFunctions();
26582 GLenum primitive_type = GL_PATCHES;
26584 if (TEST_VS == test_case_index)
26586 primitive_type = GL_POINTS;
26589 gl.disable(GL_RASTERIZER_DISCARD);
26590 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
26592 gl.beginTransformFeedback(GL_POINTS);
26593 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
26595 gl.drawArrays(primitive_type, 0 /* first */, 1 /* count */);
26596 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
26598 gl.endTransformFeedback();
26599 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
26604 /** Get descriptors of buffers necessary for test
26607 * @param out_descriptors Descriptors of buffers used by test
26609 void XFBCaptureInactiveOutputBlockMemberTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
26610 bufferDescriptor::Vector& out_descriptors)
26612 const Utils::Type& type = Utils::Type::vec4;
26614 /* Test needs single uniform and xfb */
26615 out_descriptors.resize(2);
26617 /* Get references */
26618 bufferDescriptor& uniform = out_descriptors[0];
26619 bufferDescriptor& xfb = out_descriptors[1];
26622 uniform.m_index = 0;
26626 uniform.m_target = Utils::Buffer::Uniform;
26627 xfb.m_target = Utils::Buffer::Transform_feedback;
26630 const std::vector<GLubyte>& gohan_data = type.GenerateData();
26631 const std::vector<GLubyte>& chichi_data = type.GenerateData();
26633 const GLuint type_size = static_cast<GLuint>(gohan_data.size());
26636 uniform.m_initial_data.resize(2 * type_size);
26637 memcpy(&uniform.m_initial_data[0] + 0, &gohan_data[0], type_size);
26638 memcpy(&uniform.m_initial_data[0] + type_size, &chichi_data[0], type_size);
26641 xfb.m_initial_data.resize(4 * type_size);
26642 xfb.m_expected_data.resize(4 * type_size);
26644 for (GLuint i = 0; i < 4 * type_size; ++i)
26646 xfb.m_initial_data[i] = (glw::GLubyte)i;
26647 xfb.m_expected_data[i] = (glw::GLubyte)i;
26650 memcpy(&xfb.m_expected_data[0] + 1 * type_size, &gohan_data[0], type_size);
26651 memcpy(&xfb.m_expected_data[0] + 3 * type_size, &chichi_data[0], type_size);
26654 /** Get body of main function for given shader stage
26656 * @param test_case_index Index of test case
26657 * @param stage Shader stage
26658 * @param out_assignments Set to empty
26659 * @param out_calculations Set to empty
26661 void XFBCaptureInactiveOutputBlockMemberTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
26662 std::string& out_assignments, std::string& out_calculations)
26664 out_calculations = "";
26666 static const GLchar* vs_tes_gs = " chichi = uni_chichi;\n"
26667 " gohan = uni_gohan;\n";
26668 static const GLchar* fs = " fs_out = goten + gohan + chichi;\n";
26670 const GLchar* assignments = "";
26674 case Utils::Shader::FRAGMENT:
26678 case Utils::Shader::GEOMETRY:
26679 if (TEST_GS == test_case_index)
26681 assignments = vs_tes_gs;
26685 case Utils::Shader::TESS_CTRL:
26688 case Utils::Shader::TESS_EVAL:
26689 if (TEST_TES == test_case_index)
26691 assignments = vs_tes_gs;
26695 case Utils::Shader::VERTEX:
26696 if (TEST_VS == test_case_index)
26698 assignments = vs_tes_gs;
26703 TCU_FAIL("Invalid enum");
26706 out_assignments = assignments;
26709 /** Get interface of shader
26711 * @param test_case_index Index of test case
26712 * @param stage Shader stage
26713 * @param out_interface Set to ""
26715 void XFBCaptureInactiveOutputBlockMemberTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
26716 std::string& out_interface)
26718 static const GLchar* vs_tes_gs = "const uint sizeof_type = 16;\n"
26720 "layout (xfb_offset = 1 * sizeof_type) out Goku {\n"
26726 "layout(binding = 0) uniform block {\n"
26727 " vec4 uni_gohan;\n"
26728 " vec4 uni_chichi;\n"
26730 static const GLchar* fs = "in Goku {\n"
26735 "out vec4 fs_out;\n";
26737 const GLchar* interface = "";
26741 case Utils::Shader::FRAGMENT:
26745 case Utils::Shader::GEOMETRY:
26746 if (TEST_GS == test_case_index)
26748 interface = vs_tes_gs;
26752 case Utils::Shader::TESS_CTRL:
26755 case Utils::Shader::TESS_EVAL:
26756 if (TEST_TES == test_case_index)
26758 interface = vs_tes_gs;
26762 case Utils::Shader::VERTEX:
26763 if (TEST_VS == test_case_index)
26765 interface = vs_tes_gs;
26770 TCU_FAIL("Invalid enum");
26773 out_interface = interface;
26776 /** Get source code of shader
26778 * @param test_case_index Index of test case
26779 * @param stage Shader stage
26783 std::string XFBCaptureInactiveOutputBlockMemberTest::getShaderSource(GLuint test_case_index,
26784 Utils::Shader::STAGES stage)
26786 std::string source;
26788 switch (test_case_index)
26793 case Utils::Shader::FRAGMENT:
26794 case Utils::Shader::VERTEX:
26795 source = BufferTestBase::getShaderSource(test_case_index, stage);
26805 case Utils::Shader::FRAGMENT:
26806 case Utils::Shader::TESS_CTRL:
26807 case Utils::Shader::TESS_EVAL:
26808 case Utils::Shader::VERTEX:
26809 source = BufferTestBase::getShaderSource(test_case_index, stage);
26817 source = BufferTestBase::getShaderSource(test_case_index, stage);
26821 TCU_FAIL("Invalid enum");
26829 /** Get name of test case
26831 * @param test_case_index Index of test case
26833 * @return Name of tested stage
26835 std::string XFBCaptureInactiveOutputBlockMemberTest::getTestCaseName(glw::GLuint test_case_index)
26837 const GLchar* name = 0;
26839 switch (test_case_index)
26845 name = "tesselation evaluation";
26851 TCU_FAIL("Invalid enum");
26857 /** Returns number of test cases
26861 glw::GLuint XFBCaptureInactiveOutputBlockMemberTest::getTestCaseNumber()
26866 /** Verify contents of buffers
26868 * @param buffers Collection of buffers to be verified
26870 * @return true if everything is as expected, false otherwise
26872 bool XFBCaptureInactiveOutputBlockMemberTest::verifyBuffers(bufferCollection& buffers)
26874 bool result = true;
26876 bufferCollection::pair& pair = buffers.m_vector[1] /* xfb */;
26877 Utils::Buffer* buffer = pair.m_buffer;
26878 bufferDescriptor* descriptor = pair.m_descriptor;
26880 /* Get pointer to contents of buffer */
26882 GLubyte* buffer_data = (GLubyte*)buffer->Map(Utils::Buffer::ReadOnly);
26884 /* Get pointer to expected data */
26885 GLubyte* expected_data = (GLubyte*)&descriptor->m_expected_data[0];
26888 static const GLuint vec4_size = 16;
26890 int res_before = memcmp(buffer_data, expected_data, vec4_size);
26891 int res_gohan = memcmp(buffer_data + 1 * vec4_size, expected_data + 1 * vec4_size, vec4_size);
26892 int res_chichi = memcmp(buffer_data + 3 * vec4_size, expected_data + 3 * vec4_size, vec4_size);
26894 if ((0 != res_before) || (0 != res_gohan) || (0 != res_chichi))
26896 m_context.getTestContext().getLog()
26897 << tcu::TestLog::Message << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
26898 << ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
26903 /* Release buffer mapping */
26911 * @param context Test context
26913 XFBCaptureStructTest::XFBCaptureStructTest(deqp::Context& context)
26914 : BufferTestBase(context, "xfb_capture_struct", "Test verifies that inactive structure members are captured")
26916 /* Nothing to be done here */
26919 /** Execute drawArrays for single vertex
26921 * @param test_case_index
26925 bool XFBCaptureStructTest::executeDrawCall(GLuint test_case_index)
26927 const Functions& gl = m_context.getRenderContext().getFunctions();
26928 GLenum primitive_type = GL_PATCHES;
26930 if (TEST_VS == test_case_index)
26932 primitive_type = GL_POINTS;
26935 gl.disable(GL_RASTERIZER_DISCARD);
26936 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
26938 gl.beginTransformFeedback(GL_POINTS);
26939 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
26941 gl.drawArrays(primitive_type, 0 /* first */, 1 /* count */);
26942 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
26944 gl.endTransformFeedback();
26945 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
26950 /** Get descriptors of buffers necessary for test
26953 * @param out_descriptors Descriptors of buffers used by test
26955 void XFBCaptureStructTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
26956 bufferDescriptor::Vector& out_descriptors)
26958 const Utils::Type& type = Utils::Type::vec4;
26960 /* Test needs single uniform and xfb */
26961 out_descriptors.resize(2);
26963 /* Get references */
26964 bufferDescriptor& uniform = out_descriptors[0];
26965 bufferDescriptor& xfb = out_descriptors[1];
26968 uniform.m_index = 0;
26972 uniform.m_target = Utils::Buffer::Uniform;
26973 xfb.m_target = Utils::Buffer::Transform_feedback;
26976 const std::vector<GLubyte>& gohan_data = type.GenerateData();
26977 const std::vector<GLubyte>& chichi_data = type.GenerateData();
26979 const GLuint type_size = static_cast<GLuint>(gohan_data.size());
26982 uniform.m_initial_data.resize(2 * type_size);
26983 memcpy(&uniform.m_initial_data[0] + 0, &gohan_data[0], type_size);
26984 memcpy(&uniform.m_initial_data[0] + type_size, &chichi_data[0], type_size);
26987 xfb.m_initial_data.resize(4 * type_size);
26988 xfb.m_expected_data.resize(4 * type_size);
26990 for (GLuint i = 0; i < 4 * type_size; ++i)
26992 xfb.m_initial_data[i] = (glw::GLubyte)i;
26993 xfb.m_expected_data[i] = (glw::GLubyte)i;
26996 memcpy(&xfb.m_expected_data[0] + 1 * type_size, &gohan_data[0], type_size);
26997 memcpy(&xfb.m_expected_data[0] + 3 * type_size, &chichi_data[0], type_size);
27000 /** Get body of main function for given shader stage
27002 * @param test_case_index Index of test case
27003 * @param stage Shader stage
27004 * @param out_assignments Set to empty
27005 * @param out_calculations Set to empty
27007 void XFBCaptureStructTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
27008 std::string& out_assignments, std::string& out_calculations)
27010 out_calculations = "";
27012 static const GLchar* vs_tes_gs = " goku.chichi = uni_chichi;\n"
27013 " goku.gohan = uni_gohan;\n";
27014 static const GLchar* fs = " fs_out = goku.goten + goku.gohan + goku.chichi;\n";
27016 const GLchar* assignments = "";
27020 case Utils::Shader::FRAGMENT:
27024 case Utils::Shader::GEOMETRY:
27025 if (TEST_GS == test_case_index)
27027 assignments = vs_tes_gs;
27031 case Utils::Shader::TESS_CTRL:
27034 case Utils::Shader::TESS_EVAL:
27035 if (TEST_TES == test_case_index)
27037 assignments = vs_tes_gs;
27041 case Utils::Shader::VERTEX:
27042 if (TEST_VS == test_case_index)
27044 assignments = vs_tes_gs;
27049 TCU_FAIL("Invalid enum");
27052 out_assignments = assignments;
27055 /** Get interface of shader
27057 * @param test_case_index Index of test case
27058 * @param stage Shader stage
27059 * @param out_interface Set to ""
27061 void XFBCaptureStructTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
27062 std::string& out_interface)
27064 static const GLchar* vs_tes_gs = "const uint sizeof_type = 16;\n"
27072 "layout (xfb_offset = sizeof_type) out Goku goku;\n"
27074 "layout(binding = 0, std140) uniform block {\n"
27075 " vec4 uni_gohan;\n"
27076 " vec4 uni_chichi;\n"
27078 static const GLchar* fs = "struct Goku {\n"
27086 "out vec4 fs_out;\n";
27088 const GLchar* interface = "";
27092 case Utils::Shader::FRAGMENT:
27096 case Utils::Shader::GEOMETRY:
27097 if (TEST_GS == test_case_index)
27099 interface = vs_tes_gs;
27103 case Utils::Shader::TESS_CTRL:
27106 case Utils::Shader::TESS_EVAL:
27107 if (TEST_TES == test_case_index)
27109 interface = vs_tes_gs;
27113 case Utils::Shader::VERTEX:
27114 if (TEST_VS == test_case_index)
27116 interface = vs_tes_gs;
27121 TCU_FAIL("Invalid enum");
27124 out_interface = interface;
27127 /** Get source code of shader
27129 * @param test_case_index Index of test case
27130 * @param stage Shader stage
27134 std::string XFBCaptureStructTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
27136 std::string source;
27138 switch (test_case_index)
27143 case Utils::Shader::FRAGMENT:
27144 case Utils::Shader::VERTEX:
27145 source = BufferTestBase::getShaderSource(test_case_index, stage);
27155 case Utils::Shader::FRAGMENT:
27156 case Utils::Shader::TESS_CTRL:
27157 case Utils::Shader::TESS_EVAL:
27158 case Utils::Shader::VERTEX:
27159 source = BufferTestBase::getShaderSource(test_case_index, stage);
27167 source = BufferTestBase::getShaderSource(test_case_index, stage);
27171 TCU_FAIL("Invalid enum");
27179 /** Get name of test case
27181 * @param test_case_index Index of test case
27183 * @return Name of tested stage
27185 std::string XFBCaptureStructTest::getTestCaseName(glw::GLuint test_case_index)
27187 const GLchar* name = 0;
27189 switch (test_case_index)
27195 name = "tesselation evaluation";
27201 TCU_FAIL("Invalid enum");
27207 /** Returns number of test cases
27211 glw::GLuint XFBCaptureStructTest::getTestCaseNumber()
27216 /** Verify contents of buffers
27218 * @param buffers Collection of buffers to be verified
27220 * @return true if everything is as expected, false otherwise
27222 bool XFBCaptureStructTest::verifyBuffers(bufferCollection& buffers)
27224 bool result = true;
27226 bufferCollection::pair& pair = buffers.m_vector[1] /* xfb */;
27227 Utils::Buffer* buffer = pair.m_buffer;
27228 bufferDescriptor* descriptor = pair.m_descriptor;
27230 /* Get pointer to contents of buffer */
27232 GLubyte* buffer_data = (GLubyte*)buffer->Map(Utils::Buffer::ReadOnly);
27234 /* Get pointer to expected data */
27235 GLubyte* expected_data = (GLubyte*)&descriptor->m_expected_data[0];
27238 static const GLuint vec4_size = 16;
27240 int res_before = memcmp(buffer_data, expected_data, vec4_size);
27241 int res_gohan = memcmp(buffer_data + 1 * vec4_size, expected_data + 1 * vec4_size, vec4_size);
27242 int res_chichi = memcmp(buffer_data + 3 * vec4_size, expected_data + 3 * vec4_size, vec4_size);
27244 if ((0 != res_before) || (0 != res_gohan) || (0 != res_chichi))
27246 m_context.getTestContext().getLog()
27247 << tcu::TestLog::Message << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
27248 << ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
27253 /* Release buffer mapping */
27261 * @param context Test framework context
27263 XFBCaptureUnsizedArrayTest::XFBCaptureUnsizedArrayTest(deqp::Context& context)
27264 : NegativeTestBase(context, "xfb_capture_unsized_array",
27265 "Test verifies that compiler reports error when unsized array is qualified with xfb_offset")
27269 /** Source for given test case and stage
27271 * @param test_case_index Index of test case
27272 * @param stage Shader stage
27274 * @return Shader source
27276 std::string XFBCaptureUnsizedArrayTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
27278 static const GLchar* var_definition = "layout (xfb_offset = 0) out vec4 gokuARRAY[];\n";
27279 static const GLchar* var_use = " gokuINDEX[0] = result / 2;\n";
27280 static const GLchar* fs = "#version 430 core\n"
27281 "#extension GL_ARB_enhanced_layouts : require\n"
27284 "out vec4 fs_out;\n"
27288 " fs_out = gs_fs;\n"
27291 static const GLchar* gs_tested = "#version 430 core\n"
27292 "#extension GL_ARB_enhanced_layouts : require\n"
27294 "layout(points) in;\n"
27295 "layout(triangle_strip, max_vertices = 4) out;\n"
27299 "in vec4 tes_gs[];\n"
27300 "out vec4 gs_fs;\n"
27304 " vec4 result = tes_gs[0];\n"
27308 " gs_fs = result;\n"
27309 " gl_Position = vec4(-1, -1, 0, 1);\n"
27311 " gs_fs = result;\n"
27312 " gl_Position = vec4(-1, 1, 0, 1);\n"
27314 " gs_fs = result;\n"
27315 " gl_Position = vec4(1, -1, 0, 1);\n"
27317 " gs_fs = result;\n"
27318 " gl_Position = vec4(1, 1, 0, 1);\n"
27322 static const GLchar* tcs = "#version 430 core\n"
27323 "#extension GL_ARB_enhanced_layouts : require\n"
27325 "layout(vertices = 1) out;\n"
27327 "in vec4 vs_tcs[];\n"
27328 "out vec4 tcs_tes[];\n"
27333 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
27335 " gl_TessLevelOuter[0] = 1.0;\n"
27336 " gl_TessLevelOuter[1] = 1.0;\n"
27337 " gl_TessLevelOuter[2] = 1.0;\n"
27338 " gl_TessLevelOuter[3] = 1.0;\n"
27339 " gl_TessLevelInner[0] = 1.0;\n"
27340 " gl_TessLevelInner[1] = 1.0;\n"
27343 static const GLchar* tcs_tested = "#version 430 core\n"
27344 "#extension GL_ARB_enhanced_layouts : require\n"
27346 "layout(vertices = 1) out;\n"
27350 "in vec4 vs_tcs[];\n"
27351 "out vec4 tcs_tes[];\n"
27355 " vec4 result = vs_tcs[gl_InvocationID];\n"
27359 " tcs_tes[gl_InvocationID] = result;\n"
27361 " gl_TessLevelOuter[0] = 1.0;\n"
27362 " gl_TessLevelOuter[1] = 1.0;\n"
27363 " gl_TessLevelOuter[2] = 1.0;\n"
27364 " gl_TessLevelOuter[3] = 1.0;\n"
27365 " gl_TessLevelInner[0] = 1.0;\n"
27366 " gl_TessLevelInner[1] = 1.0;\n"
27369 static const GLchar* tes_tested = "#version 430 core\n"
27370 "#extension GL_ARB_enhanced_layouts : require\n"
27372 "layout(isolines, point_mode) in;\n"
27376 "in vec4 tcs_tes[];\n"
27377 "out vec4 tes_gs;\n"
27381 " vec4 result = tcs_tes[0];\n"
27385 " tes_gs += result;\n"
27388 static const GLchar* vs = "#version 430 core\n"
27389 "#extension GL_ARB_enhanced_layouts : require\n"
27392 "out vec4 vs_tcs;\n"
27396 " vs_tcs = in_vs;\n"
27399 static const GLchar* vs_tested = "#version 430 core\n"
27400 "#extension GL_ARB_enhanced_layouts : require\n"
27405 "out vec4 vs_tcs;\n"
27409 " vec4 result = in_vs;\n"
27413 " vs_tcs = result;\n"
27417 std::string source;
27418 testCase& test_case = m_test_cases[test_case_index];
27420 if (test_case.m_stage == stage)
27422 const GLchar* array = "";
27423 const GLchar* index = "";
27424 size_t position = 0;
27428 case Utils::Shader::GEOMETRY:
27429 source = gs_tested;
27433 case Utils::Shader::TESS_CTRL:
27434 source = tcs_tested;
27436 index = "[gl_InvocationID]";
27438 case Utils::Shader::TESS_EVAL:
27439 source = tes_tested;
27443 case Utils::Shader::VERTEX:
27444 source = vs_tested;
27447 TCU_FAIL("Invalid enum");
27450 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
27452 Utils::replaceToken("ARRAY", position, array, source);
27453 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
27455 Utils::replaceAllTokens("INDEX", index, source);
27459 switch (test_case.m_stage)
27461 case Utils::Shader::GEOMETRY:
27464 case Utils::Shader::FRAGMENT:
27467 case Utils::Shader::VERTEX:
27474 case Utils::Shader::TESS_CTRL:
27477 case Utils::Shader::FRAGMENT:
27480 case Utils::Shader::VERTEX:
27487 case Utils::Shader::TESS_EVAL:
27490 case Utils::Shader::FRAGMENT:
27493 case Utils::Shader::TESS_CTRL:
27496 case Utils::Shader::VERTEX:
27503 case Utils::Shader::VERTEX:
27506 case Utils::Shader::FRAGMENT:
27514 TCU_FAIL("Invalid enum");
27522 /** Get description of test case
27524 * @param test_case_index Index of test case
27526 * @return Test case description
27528 std::string XFBCaptureUnsizedArrayTest::getTestCaseName(GLuint test_case_index)
27530 std::stringstream stream;
27531 testCase& test_case = m_test_cases[test_case_index];
27533 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage);
27535 return stream.str();
27538 /** Get number of test cases
27540 * @return Number of test cases
27542 GLuint XFBCaptureUnsizedArrayTest::getTestCaseNumber()
27544 return static_cast<GLuint>(m_test_cases.size());
27547 /** Selects if "compute" stage is relevant for test
27553 bool XFBCaptureUnsizedArrayTest::isComputeRelevant(GLuint /* test_case_index */)
27558 /** Prepare all test cases
27561 void XFBCaptureUnsizedArrayTest::testInit()
27563 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
27565 /* Not aplicable for */
27566 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::FRAGMENT == stage) ||
27567 (Utils::Shader::GEOMETRY == stage) || (Utils::Shader::TESS_EVAL == stage))
27572 testCase test_case = { (Utils::Shader::STAGES)stage };
27574 m_test_cases.push_back(test_case);
27577 } /* EnhancedLayouts namespace */
27581 * @param context Rendering context.
27583 EnhancedLayoutsTests::EnhancedLayoutsTests(deqp::Context& context)
27584 : TestCaseGroup(context, "enhanced_layouts", "Verifies \"enhanced layouts\" functionality")
27586 /* Left blank on purpose */
27589 /** Initializes a texture_storage_multisample test group.
27592 void EnhancedLayoutsTests::init(void)
27594 addChild(new EnhancedLayouts::APIConstantValuesTest(m_context));
27595 addChild(new EnhancedLayouts::APIErrorsTest(m_context));
27596 addChild(new EnhancedLayouts::GLSLContantValuesTest(m_context));
27597 addChild(new EnhancedLayouts::GLSLContantImmutablityTest(m_context));
27598 addChild(new EnhancedLayouts::GLSLConstantIntegralExpressionTest(m_context));
27599 addChild(new EnhancedLayouts::UniformBlockLayoutQualifierConflictTest(m_context));
27600 addChild(new EnhancedLayouts::SSBMemberInvalidOffsetAlignmentTest(m_context));
27601 addChild(new EnhancedLayouts::SSBMemberOverlappingOffsetsTest(m_context));
27602 addChild(new EnhancedLayouts::VaryingExceedingComponentsTest(m_context));
27603 addChild(new EnhancedLayouts::VaryingComponentOfInvalidTypeTest(m_context));
27604 addChild(new EnhancedLayouts::OutputComponentAliasingTest(m_context));
27605 addChild(new EnhancedLayouts::VertexAttribLocationAPITest(m_context));
27606 addChild(new EnhancedLayouts::XFBInputTest(m_context));
27607 addChild(new EnhancedLayouts::XFBAllStagesTest(m_context));
27608 addChild(new EnhancedLayouts::XFBCaptureInactiveOutputVariableTest(m_context));
27609 addChild(new EnhancedLayouts::XFBCaptureInactiveOutputComponentTest(m_context));
27610 addChild(new EnhancedLayouts::XFBCaptureInactiveOutputBlockMemberTest(m_context));
27611 addChild(new EnhancedLayouts::XFBStrideTest(m_context));
27613 addChild(new EnhancedLayouts::UniformBlockMemberOffsetAndAlignTest(m_context));
27614 addChild(new EnhancedLayouts::UniformBlockMemberInvalidOffsetAlignmentTest(m_context));
27615 addChild(new EnhancedLayouts::UniformBlockMemberOverlappingOffsetsTest(m_context));
27616 addChild(new EnhancedLayouts::UniformBlockMemberAlignNonPowerOf2Test(m_context));
27617 addChild(new EnhancedLayouts::SSBLayoutQualifierConflictTest(m_context));
27618 addChild(new EnhancedLayouts::SSBMemberAlignNonPowerOf2Test(m_context));
27619 addChild(new EnhancedLayouts::SSBAlignmentTest(m_context));
27620 addChild(new EnhancedLayouts::VaryingStructureMemberLocationTest(m_context));
27621 addChild(new EnhancedLayouts::VaryingBlockAutomaticMemberLocationsTest(m_context));
27622 addChild(new EnhancedLayouts::VaryingComponentWithoutLocationTest(m_context));
27623 addChild(new EnhancedLayouts::InputComponentAliasingTest(m_context));
27624 addChild(new EnhancedLayouts::VaryingLocationAliasingWithMixedTypesTest(m_context));
27625 addChild(new EnhancedLayouts::VaryingLocationAliasingWithMixedInterpolationTest(m_context));
27626 addChild(new EnhancedLayouts::VaryingLocationAliasingWithMixedAuxiliaryStorageTest(m_context));
27627 addChild(new EnhancedLayouts::XFBStrideOfEmptyListTest(m_context));
27628 addChild(new EnhancedLayouts::XFBStrideOfEmptyListAndAPITest(m_context));
27629 addChild(new EnhancedLayouts::XFBTooSmallStrideTest(m_context));
27630 addChild(new EnhancedLayouts::XFBBlockMemberStrideTest(m_context));
27631 addChild(new EnhancedLayouts::XFBDuplicatedStrideTest(m_context));
27632 addChild(new EnhancedLayouts::XFBGetProgramResourceAPITest(m_context));
27633 addChild(new EnhancedLayouts::XFBMultipleVertexStreamsTest(m_context));
27634 addChild(new EnhancedLayouts::XFBExceedBufferLimitTest(m_context));
27635 addChild(new EnhancedLayouts::XFBExceedOffsetLimitTest(m_context));
27636 addChild(new EnhancedLayouts::XFBBlockMemberBufferTest(m_context));
27637 addChild(new EnhancedLayouts::XFBOutputOverlappingTest(m_context));
27638 addChild(new EnhancedLayouts::XFBInvalidOffsetAlignmentTest(m_context));
27639 addChild(new EnhancedLayouts::XFBCaptureStructTest(m_context));
27640 addChild(new EnhancedLayouts::XFBCaptureUnsizedArrayTest(m_context));
27641 addChild(new EnhancedLayouts::UniformBlockAlignmentTest(m_context));
27642 addChild(new EnhancedLayouts::SSBMemberOffsetAndAlignTest(m_context));
27643 addChild(new EnhancedLayouts::VertexAttribLocationsTest(m_context));
27644 addChild(new EnhancedLayouts::VaryingLocationsTest(m_context));
27645 addChild(new EnhancedLayouts::VaryingArrayLocationsTest(m_context));
27646 addChild(new EnhancedLayouts::VaryingStructureLocationsTest(m_context));
27647 addChild(new EnhancedLayouts::VaryingBlockLocationsTest(m_context));
27648 addChild(new EnhancedLayouts::VaryingBlockMemberLocationsTest(m_context));
27649 addChild(new EnhancedLayouts::XFBVariableStrideTest(m_context));
27650 addChild(new EnhancedLayouts::XFBBlockStrideTest(m_context));
27651 addChild(new EnhancedLayouts::XFBOverrideQualifiersWithAPITest(m_context));
27652 addChild(new EnhancedLayouts::XFBVertexStreamsTest(m_context));
27653 addChild(new EnhancedLayouts::XFBGlobalBufferTest(m_context));
27654 addChild(new EnhancedLayouts::FragmentDataLocationAPITest(m_context));
27655 addChild(new EnhancedLayouts::VaryingLocationLimitTest(m_context));
27656 addChild(new EnhancedLayouts::VaryingComponentsTest(m_context));
27657 addChild(new EnhancedLayouts::VaryingArrayComponentsTest(m_context));
27660 } /* gl4cts namespace */