1 /*-------------------------------------------------------------------------
2 * OpenGL Conformance Test Suite
3 * -----------------------------
5 * Copyright (c) 2015-2016 The Khronos Group Inc.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
22 */ /*-------------------------------------------------------------------*/
25 * \file gl4cEnhancedLayoutsTests.cpp
26 * \brief Implements conformance tests for "Enhanced Layouts" functionality.
27 */ /*-------------------------------------------------------------------*/
29 #include "gl4cEnhancedLayoutsTests.hpp"
31 #include "gluContextInfo.hpp"
32 #include "gluDefs.hpp"
33 #include "gluStrUtil.hpp"
34 #include "glwEnums.hpp"
35 #include "glwFunctions.hpp"
36 #include "tcuTestLog.hpp"
45 #define DEBUG_ENBALE_MESSAGE_CALLBACK 0
46 #define DEBUG_NEG_LOG_ERROR 0
47 #define DEBUG_REPLACE_TOKEN 0
48 #define DEBUG_REPEAT_TEST_CASE 0
49 #define DEBUG_REPEATED_TEST_CASE 0
51 /* Texture test base */
52 #define DEBUG_TTB_VERIFICATION_SNIPPET_STAGE 0
53 #define DEBUG_TTB_VERIFICATION_SNIPPET_VARIABLE 0
56 #define DEBUG_VERTEX_ATTRIB_LOCATIONS_TEST_VARIABLE 0
59 #define WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST 0
60 #define WRKARD_UNIFORMBLOCKMEMBERALIGNNONPOWEROF2TEST 0
61 #define WRKARD_UNIFORMBLOCKALIGNMENT 0
62 #define WRKARD_VARYINGLOCATIONSTEST 0
68 namespace EnhancedLayouts
72 /** Constants used by "random" generators **/
73 static const GLuint s_rand_start = 3;
74 static const GLuint s_rand_max = 16;
75 static const GLuint s_rand_max_half = s_rand_max / 2;
77 /** Seed used by "random" generators **/
78 static GLuint s_rand = s_rand_start;
80 /** Get "random" unsigned int value
84 static GLuint GetRandUint()
86 const GLuint rand = s_rand++;
88 if (s_rand_max <= s_rand)
90 s_rand = s_rand_start;
96 /** Get "random" int value
102 const GLint rand = GetRandUint() - s_rand_max_half;
107 /** Get "random" double value
111 GLdouble GetRandDouble()
113 const GLint rand = GetRandInt();
115 GLdouble result = (GLfloat)rand / (GLdouble)s_rand_max_half;
120 /** Get "random" float value
124 GLfloat GetRandFloat()
126 const GLint rand = GetRandInt();
128 GLfloat result = (GLfloat)rand / (GLfloat)s_rand_max_half;
133 /** String used by list routines **/
134 static const GLchar* const g_list = "LIST";
136 /** Type constants **/
137 const Type Type::_double = Type::GetType(Type::Double, 1, 1);
138 const Type Type::dmat2 = Type::GetType(Type::Double, 2, 2);
139 const Type Type::dmat2x3 = Type::GetType(Type::Double, 2, 3);
140 const Type Type::dmat2x4 = Type::GetType(Type::Double, 2, 4);
141 const Type Type::dmat3x2 = Type::GetType(Type::Double, 3, 2);
142 const Type Type::dmat3 = Type::GetType(Type::Double, 3, 3);
143 const Type Type::dmat3x4 = Type::GetType(Type::Double, 3, 4);
144 const Type Type::dmat4x2 = Type::GetType(Type::Double, 4, 2);
145 const Type Type::dmat4x3 = Type::GetType(Type::Double, 4, 3);
146 const Type Type::dmat4 = Type::GetType(Type::Double, 4, 4);
147 const Type Type::dvec2 = Type::GetType(Type::Double, 1, 2);
148 const Type Type::dvec3 = Type::GetType(Type::Double, 1, 3);
149 const Type Type::dvec4 = Type::GetType(Type::Double, 1, 4);
150 const Type Type::_int = Type::GetType(Type::Int, 1, 1);
151 const Type Type::ivec2 = Type::GetType(Type::Int, 1, 2);
152 const Type Type::ivec3 = Type::GetType(Type::Int, 1, 3);
153 const Type Type::ivec4 = Type::GetType(Type::Int, 1, 4);
154 const Type Type::_float = Type::GetType(Type::Float, 1, 1);
155 const Type Type::mat2 = Type::GetType(Type::Float, 2, 2);
156 const Type Type::mat2x3 = Type::GetType(Type::Float, 2, 3);
157 const Type Type::mat2x4 = Type::GetType(Type::Float, 2, 4);
158 const Type Type::mat3x2 = Type::GetType(Type::Float, 3, 2);
159 const Type Type::mat3 = Type::GetType(Type::Float, 3, 3);
160 const Type Type::mat3x4 = Type::GetType(Type::Float, 3, 4);
161 const Type Type::mat4x2 = Type::GetType(Type::Float, 4, 2);
162 const Type Type::mat4x3 = Type::GetType(Type::Float, 4, 3);
163 const Type Type::mat4 = Type::GetType(Type::Float, 4, 4);
164 const Type Type::vec2 = Type::GetType(Type::Float, 1, 2);
165 const Type Type::vec3 = Type::GetType(Type::Float, 1, 3);
166 const Type Type::vec4 = Type::GetType(Type::Float, 1, 4);
167 const Type Type::uint = Type::GetType(Type::Uint, 1, 1);
168 const Type Type::uvec2 = Type::GetType(Type::Uint, 1, 2);
169 const Type Type::uvec3 = Type::GetType(Type::Uint, 1, 3);
170 const Type Type::uvec4 = Type::GetType(Type::Uint, 1, 4);
172 /** Generate data for type. This routine follows STD140 rules
174 * @return Vector of bytes filled with data
176 std::vector<GLubyte> Type::GenerateData() const
178 const GLuint alignment = GetActualAlignment(0, false);
180 std::vector<GLubyte> data;
181 data.resize(alignment * m_n_columns);
183 for (GLuint column = 0; column < m_n_columns; ++column)
185 GLvoid* ptr = (GLvoid*)&data[column * alignment];
187 switch (m_basic_type)
191 GLdouble* d_ptr = (GLdouble*)ptr;
193 for (GLuint i = 0; i < m_n_rows; ++i)
195 d_ptr[i] = GetRandDouble();
201 GLfloat* f_ptr = (GLfloat*)ptr;
203 for (GLuint i = 0; i < m_n_rows; ++i)
205 f_ptr[i] = GetRandFloat();
211 GLint* i_ptr = (GLint*)ptr;
213 for (GLuint i = 0; i < m_n_rows; ++i)
215 i_ptr[i] = GetRandInt();
221 GLuint* ui_ptr = (GLuint*)ptr;
223 for (GLuint i = 0; i < m_n_rows; ++i)
225 ui_ptr[i] = GetRandUint();
235 /** Generate data for type. This routine packs data tightly.
237 * @return Vector of bytes filled with data
239 std::vector<GLubyte> Type::GenerateDataPacked() const
241 const GLuint basic_size = GetTypeSize(m_basic_type);
242 const GLuint n_elements = m_n_columns * m_n_rows;
243 const GLuint size = basic_size * n_elements;
245 std::vector<GLubyte> data;
248 GLvoid* ptr = (GLvoid*)&data[0];
250 switch (m_basic_type)
254 GLdouble* d_ptr = (GLdouble*)ptr;
256 for (GLuint i = 0; i < n_elements; ++i)
258 d_ptr[i] = GetRandDouble();
264 GLfloat* f_ptr = (GLfloat*)ptr;
266 for (GLuint i = 0; i < n_elements; ++i)
268 f_ptr[i] = GetRandFloat();
274 GLint* i_ptr = (GLint*)ptr;
276 for (GLuint i = 0; i < n_elements; ++i)
278 i_ptr[i] = GetRandInt();
284 GLuint* ui_ptr = (GLuint*)ptr;
286 for (GLuint i = 0; i < n_elements; ++i)
288 ui_ptr[i] = GetRandUint();
297 /** Calculate "actual alignment". It work under assumption that align value is valid
299 * @param align Requested alignment, eg with "align" qualifier
300 * @param is_array Selects if an array of type or single instance should be considered
302 * @return Calculated value
304 GLuint Type::GetActualAlignment(GLuint align, bool is_array) const
306 const GLuint base_alignment = GetBaseAlignment(is_array);
308 return std::max(align, base_alignment);
311 /** Align given ofset with specified alignment
313 * @param offset Offset
314 * @param alignment Alignment
316 * @return Calculated value
318 GLuint align(GLuint offset, GLuint alignment)
320 const GLuint rest = offset % alignment;
324 GLuint missing = alignment - rest;
331 /** Calculate "actual offset"
333 * @param start_offset Requested offset
334 * @param actual_alignment Actual alignemnt
336 * @return Calculated value
338 GLuint Type::GetActualOffset(GLuint start_offset, GLuint actual_alignment)
340 GLuint offset = align(start_offset, actual_alignment);
345 /** Calculate "base alignment" for given type
347 * @param is_array Select if array or single instance should be considered
349 * @return Calculated value
351 GLuint Type::GetBaseAlignment(bool is_array) const
368 GLuint N = GetTypeSize(m_basic_type);
369 GLuint alignment = N * elements;
371 if ((true == is_array) || (1 != m_n_columns))
373 alignment = align(alignment, 16 /* vec4 alignment */);
379 /** Returns string representing GLSL constructor of type with arguments provided in data
381 * @param data Array of values that will be used as construcotr arguments.
382 * It is interpreted as tightly packed array of type matching this type.
384 * @return String in form "Type(args)"
386 std::string Type::GetGLSLConstructor(const GLvoid* data) const
388 const GLchar* type = GetGLSLTypeName();
390 std::stringstream stream;
392 stream << type << "(";
394 /* Scalar or vector */
395 if (1 == m_n_columns)
397 for (GLuint row = 0; row < m_n_rows; ++row)
399 switch (m_basic_type)
402 stream << ((GLdouble*)data)[row];
405 stream << ((GLfloat*)data)[row];
408 stream << ((GLint*)data)[row];
411 stream << ((GLuint*)data)[row];
415 if (row + 1 != m_n_rows)
421 else /* Matrix: mat(vec(), vec() .. ) */
423 const GLuint basic_size = GetTypeSize(m_basic_type);
424 // Very indescoverable defect, the column stride should be calculated by rows, such as mat2x3, which is 2, columns 3 rows, its column stride should be 3 * sizeof(float)
425 const GLuint column_stride = m_n_rows * basic_size;
426 const Type column_type = GetType(m_basic_type, 1, m_n_rows);
428 for (GLuint column = 0; column < m_n_columns; ++column)
430 const GLuint column_offset = column * column_stride;
431 const GLvoid* column_data = (GLubyte*)data + column_offset;
433 stream << column_type.GetGLSLConstructor(column_data);
435 if (column + 1 != m_n_columns)
447 /** Get glsl name of the type
449 * @return Name of glsl type
451 const glw::GLchar* Type::GetGLSLTypeName() const
453 static const GLchar* float_lut[4][4] = {
454 { "float", "vec2", "vec3", "vec4" },
455 { 0, "mat2", "mat2x3", "mat2x4" },
456 { 0, "mat3x2", "mat3", "mat3x4" },
457 { 0, "mat4x2", "mat4x3", "mat4" },
460 static const GLchar* double_lut[4][4] = {
461 { "double", "dvec2", "dvec3", "dvec4" },
462 { 0, "dmat2", "dmat2x3", "dmat2x4" },
463 { 0, "dmat3x2", "dmat3", "dmat3x4" },
464 { 0, "dmat4x2", "dmat4x3", "dmat4" },
467 static const GLchar* int_lut[4] = { "int", "ivec2", "ivec3", "ivec4" };
469 static const GLchar* uint_lut[4] = { "uint", "uvec2", "uvec3", "uvec4" };
471 const GLchar* result = 0;
473 if ((1 > m_n_columns) || (1 > m_n_rows) || (4 < m_n_columns) || (4 < m_n_rows))
478 switch (m_basic_type)
481 result = float_lut[m_n_columns - 1][m_n_rows - 1];
484 result = double_lut[m_n_columns - 1][m_n_rows - 1];
487 result = int_lut[m_n_rows - 1];
490 result = uint_lut[m_n_rows - 1];
493 TCU_FAIL("Invliad enum");
499 /** Get number of locations required for the type
501 * @return Number of columns times:
502 * - 2 when type is double with 3 or 4 rows,
505 GLuint Type::GetLocations() const
507 GLuint n_loc_per_column;
509 /* 1 or 2 doubles any for rest */
510 if ((2 >= m_n_rows) || (Double != m_basic_type))
512 n_loc_per_column = 1;
516 /* 3 and 4 doubles */
517 n_loc_per_column = 2;
520 return n_loc_per_column * m_n_columns;
523 /** Get size of the type in bytes. Note that this routine assumes tightly packing
525 * @return Formula Number of columns * number of rows * sizeof(base_type)
527 GLuint Type::GetSize() const
529 const GLuint basic_type_size = GetTypeSize(m_basic_type);
530 const GLuint n_elements = m_n_columns * m_n_rows;
532 return basic_type_size * n_elements;
535 /** Get GLenum representing the type
539 GLenum Type::GetTypeGLenum() const
541 static const GLenum float_lut[4][4] = {
542 { GL_FLOAT, GL_FLOAT_VEC2, GL_FLOAT_VEC3, GL_FLOAT_VEC4 },
543 { 0, GL_FLOAT_MAT2, GL_FLOAT_MAT2x3, GL_FLOAT_MAT2x4 },
544 { 0, GL_FLOAT_MAT3x2, GL_FLOAT_MAT3, GL_FLOAT_MAT3x4 },
545 { 0, GL_FLOAT_MAT4x2, GL_FLOAT_MAT4x3, GL_FLOAT_MAT4 },
548 static const GLenum double_lut[4][4] = {
549 { GL_DOUBLE, GL_DOUBLE_VEC2, GL_DOUBLE_VEC3, GL_DOUBLE_VEC4 },
550 { 0, GL_DOUBLE_MAT2, GL_DOUBLE_MAT2x3, GL_DOUBLE_MAT2x4 },
551 { 0, GL_DOUBLE_MAT3x2, GL_DOUBLE_MAT3, GL_DOUBLE_MAT3x4 },
552 { 0, GL_DOUBLE_MAT4x2, GL_DOUBLE_MAT4x3, GL_DOUBLE_MAT4 },
555 static const GLenum int_lut[4] = { GL_INT, GL_INT_VEC2, GL_INT_VEC3, GL_INT_VEC4 };
557 static const GLenum uint_lut[4] = { GL_UNSIGNED_INT, GL_UNSIGNED_INT_VEC2, GL_UNSIGNED_INT_VEC3,
558 GL_UNSIGNED_INT_VEC4 };
562 if ((1 > m_n_columns) || (1 > m_n_rows) || (4 < m_n_columns) || (4 < m_n_rows))
567 switch (m_basic_type)
570 result = float_lut[m_n_columns - 1][m_n_rows - 1];
573 result = double_lut[m_n_columns - 1][m_n_rows - 1];
576 result = int_lut[m_n_rows - 1];
579 result = uint_lut[m_n_rows - 1];
582 TCU_FAIL("Invliad enum");
588 /** Calculate the numbe of components consumed by a type
589 * according to 11.1.2.1 Output Variables
591 * @return Calculated number of components for the type
593 GLuint Type::GetNumComponents() const
595 // Rule 3 of Section 7.6.2.2
596 // If the member is a three-component vector with components consuming N
597 // basic machine units, the base alignment is 4N.
598 GLuint num_components = (m_n_rows == 3 ? 4 : m_n_rows) * m_n_columns;
600 if (m_basic_type == Double)
605 return num_components;
608 /** Calculate stride for the type according to std140 rules
610 * @param alignment Alignment of type
611 * @param n_columns Number of columns
612 * @param n_array_elements Number of elements in array
614 * @return Calculated value
616 GLuint Type::CalculateStd140Stride(GLuint alignment, GLuint n_columns, GLuint n_array_elements)
618 GLuint stride = alignment * n_columns;
619 if (0 != n_array_elements)
621 stride *= n_array_elements;
627 /** Check if glsl support matrices for specific basic type
629 * @param type Basic type
631 * @return true if matrices of <type> are supported, false otherwise
633 bool Type::DoesTypeSupportMatrix(TYPES type)
648 TCU_FAIL("Invliad enum");
654 /** Creates instance of Type
656 * @param basic_type Select basic type of instance
657 * @param n_columns Number of columns
658 * @param n_rows Number of rows
660 * @return Type instance
662 Type Type::GetType(TYPES basic_type, glw::GLuint n_columns, glw::GLuint n_rows)
664 Type type = { basic_type, n_columns, n_rows };
669 /** Get Size of given type in bytes
673 * @return Size of type
675 GLuint Type::GetTypeSize(TYPES type)
682 result = sizeof(GLfloat);
685 result = sizeof(GLdouble);
688 result = sizeof(GLint);
691 result = sizeof(GLuint);
694 TCU_FAIL("Invalid enum");
700 /** Get GLenum representing given type
704 * @return GLenum value
706 GLenum Type::GetTypeGLenum(TYPES type)
722 result = GL_UNSIGNED_INT;
725 TCU_FAIL("Invalid enum");
731 /** Get proper glUniformNdv routine for vectors with specified number of rows
733 * @param gl GL functions
734 * @param n_rows Number of rows
736 * @return Function address
738 uniformNdv getUniformNdv(const glw::Functions& gl, glw::GLuint n_rows)
740 uniformNdv result = 0;
745 result = gl.uniform1dv;
748 result = gl.uniform2dv;
751 result = gl.uniform3dv;
754 result = gl.uniform4dv;
757 TCU_FAIL("Invalid number of rows");
763 /** Get proper glUniformNfv routine for vectors with specified number of rows
765 * @param gl GL functions
766 * @param n_rows Number of rows
768 * @return Function address
770 uniformNfv getUniformNfv(const glw::Functions& gl, glw::GLuint n_rows)
772 uniformNfv result = 0;
777 result = gl.uniform1fv;
780 result = gl.uniform2fv;
783 result = gl.uniform3fv;
786 result = gl.uniform4fv;
789 TCU_FAIL("Invalid number of rows");
795 /** Get proper glUniformNiv routine for vectors with specified number of rows
797 * @param gl GL functions
798 * @param n_rows Number of rows
800 * @return Function address
802 uniformNiv getUniformNiv(const glw::Functions& gl, glw::GLuint n_rows)
804 uniformNiv result = 0;
809 result = gl.uniform1iv;
812 result = gl.uniform2iv;
815 result = gl.uniform3iv;
818 result = gl.uniform4iv;
821 TCU_FAIL("Invalid number of rows");
827 /** Get proper glUniformNuiv routine for vectors with specified number of rows
829 * @param gl GL functions
830 * @param n_rows Number of rows
832 * @return Function address
834 uniformNuiv getUniformNuiv(const glw::Functions& gl, glw::GLuint n_rows)
836 uniformNuiv result = 0;
841 result = gl.uniform1uiv;
844 result = gl.uniform2uiv;
847 result = gl.uniform3uiv;
850 result = gl.uniform4uiv;
853 TCU_FAIL("Invalid number of rows");
859 /** Get proper glUniformMatrixNdv routine for matrix with specified number of columns and rows
861 * @param gl GL functions
862 * @param n_rows Number of rows
864 * @return Function address
866 uniformMatrixNdv getUniformMatrixNdv(const glw::Functions& gl, glw::GLuint n_columns, glw::GLuint n_rows)
868 uniformMatrixNdv result = 0;
876 result = gl.uniformMatrix2dv;
879 result = gl.uniformMatrix2x3dv;
882 result = gl.uniformMatrix2x4dv;
885 TCU_FAIL("Invalid number of rows");
892 result = gl.uniformMatrix3x2dv;
895 result = gl.uniformMatrix3dv;
898 result = gl.uniformMatrix3x4dv;
901 TCU_FAIL("Invalid number of rows");
908 result = gl.uniformMatrix4x2dv;
911 result = gl.uniformMatrix4x3dv;
914 result = gl.uniformMatrix4dv;
917 TCU_FAIL("Invalid number of rows");
921 TCU_FAIL("Invalid number of columns");
927 /** Get proper glUniformMatrixNfv routine for vectors with specified number of columns and rows
929 * @param gl GL functions
930 * @param n_rows Number of rows
932 * @return Function address
934 uniformMatrixNfv getUniformMatrixNfv(const glw::Functions& gl, glw::GLuint n_columns, glw::GLuint n_rows)
936 uniformMatrixNfv result = 0;
944 result = gl.uniformMatrix2fv;
947 result = gl.uniformMatrix2x3fv;
950 result = gl.uniformMatrix2x4fv;
953 TCU_FAIL("Invalid number of rows");
960 result = gl.uniformMatrix3x2fv;
963 result = gl.uniformMatrix3fv;
966 result = gl.uniformMatrix3x4fv;
969 TCU_FAIL("Invalid number of rows");
976 result = gl.uniformMatrix4x2fv;
979 result = gl.uniformMatrix4x3fv;
982 result = gl.uniformMatrix4fv;
985 TCU_FAIL("Invalid number of rows");
989 TCU_FAIL("Invalid number of columns");
995 bool verifyVarying(Program& program, const std::string& parent_name, const Variable::Descriptor& desc,
996 std::stringstream& stream, bool is_input)
1000 GLenum interface = GL_PROGRAM_INPUT;
1003 if (false == is_input)
1005 interface = GL_PROGRAM_OUTPUT;
1008 const std::string& name = Utils::Variable::GetReference(parent_name, desc, Utils::Variable::BASIC, 0);
1012 index = program.GetResourceIndex(name, interface);
1014 program.GetResource(interface, index, GL_LOCATION, 1 /* size */, &location);
1015 program.GetResource(interface, index, GL_LOCATION_COMPONENT, 1 /* size */, &component);
1017 catch (std::exception& exc)
1019 stream << "Failed to query program for varying: " << desc.m_name << ". Reason: " << exc.what() << "\n";
1026 if (location != desc.m_expected_location)
1028 stream << "Attribute: " << desc.m_name << " - invalid location: " << location
1029 << " expected: " << desc.m_expected_location << std::endl;
1032 if (component != desc.m_expected_component)
1034 stream << "Attribute: " << desc.m_name << " - invalid component: " << component
1035 << " expected: " << desc.m_expected_component << std::endl;
1042 /** Query program resource for given variable and verify that everything is as expected
1044 * @param program Program object
1045 * @param variable Variable object
1046 * @param stream Stream that will be used to log any error
1047 * @param is_input Selects if varying is input or output
1049 * @return true if verification is positive, false otherwise
1051 bool checkVarying(Program& program, const Variable& variable, std::stringstream& stream, bool is_input)
1055 if (variable.IsBlock())
1057 Utils::Interface* interface = variable.m_descriptor.m_interface;
1058 const size_t n_members = interface->m_members.size();
1060 for (size_t i = 0; i < n_members; ++i)
1062 const Variable::Descriptor& member = interface->m_members[i];
1063 bool member_result = verifyVarying(program, interface->m_name, member, stream, is_input);
1065 if (false == member_result)
1072 To query the the location of struct member by glGetProgramResource, we need pass the variable name "gs_fs_output[0].single",
1073 but in original implementation, the test pass the name "Data.single", which can't get any valid result.
1078 layout (location = 0) in Data gs_fs_output[1];
1080 else if (variable.IsStruct())
1082 Utils::Interface* interface = variable.m_descriptor.m_interface;
1083 const size_t n_members = interface->m_members.size();
1084 std::string structVariable = variable.m_descriptor.m_name;
1085 // If struct variable is an array
1086 if (0 != variable.m_descriptor.m_n_array_elements)
1088 for (GLuint i = 0; i < variable.m_descriptor.m_n_array_elements; i++)
1091 sprintf(buffer, "%d", i);
1092 structVariable.append("[");
1093 structVariable.append(buffer);
1094 structVariable.append("]");
1095 for (size_t j = 0; j < n_members; ++j)
1097 const Variable::Descriptor& member = interface->m_members[j];
1098 bool member_result = verifyVarying(program, structVariable, member, stream, is_input);
1100 if (false == member_result)
1109 for (GLuint i = 0; i < n_members; ++i)
1111 const Variable::Descriptor& member = interface->m_members[i];
1112 bool member_result = verifyVarying(program, structVariable, member, stream, is_input);
1114 if (false == member_result)
1123 result = verifyVarying(program, "", variable.m_descriptor, stream, is_input);
1128 /** Query program resource for given variable and verify that everything is as expected
1130 * @param program Program object
1131 * @param variable Variable object
1132 * @param stream Stream that will be used to log any error
1134 * @return true if verification is positive, false otherwise
1136 bool checkUniform(Program& program, const Utils::Variable& variable, std::stringstream& stream)
1140 if (false == variable.IsBlock())
1142 TCU_FAIL("Not implemented");
1146 Utils::Interface* interface = variable.m_descriptor.m_interface;
1148 size_t size = interface->m_members.size();
1150 std::vector<GLuint> indices;
1151 std::vector<const char*> names;
1152 std::vector<std::string> names_str;
1153 std::vector<GLint> offsets;
1155 indices.resize(size);
1157 names_str.resize(size);
1158 offsets.resize(size);
1160 for (size_t i = 0; i < size; ++i)
1165 const std::string& name =
1166 Utils::Variable::GetReference(interface->m_name, interface->m_members[i], Utils::Variable::BASIC, 0);
1168 if (Utils::Variable::INTERFACE == interface->m_members[i].m_type)
1170 const std::string& member_name = Utils::Variable::GetReference(
1171 name, interface->m_members[i].m_interface->m_members[0], Utils::Variable::BASIC, 0);
1173 names_str[i] = member_name;
1177 names_str[i] = name;
1180 names[i] = names_str[i].c_str();
1185 program.GetUniformIndices(static_cast<glw::GLsizei>(size), &names[0], &indices[0]);
1186 program.GetActiveUniformsiv(static_cast<glw::GLsizei>(size), &indices[0], GL_UNIFORM_OFFSET, &offsets[0]);
1188 catch (std::exception& exc)
1190 stream << "Failed to query program for uniforms in block: " << variable.m_descriptor.m_name
1191 << ". Reason: " << exc.what() << "\n";
1196 for (size_t i = 0; i < size; ++i)
1198 Utils::Variable::Descriptor& desc = interface->m_members[i];
1200 if (offsets[i] != (GLint)desc.m_offset)
1202 stream << "Uniform: " << desc.m_name << " - invalid offset: " << offsets[i]
1203 << " expected: " << desc.m_offset << std::endl;
1212 /** Query program resource for given variable and verify that everything is as expected
1214 * @param program Program object
1215 * @param variable Variable object
1216 * @param stream Stream that will be used to log any error
1218 * @return true if verification is positive, false otherwise
1220 bool checkSSB(Program& program, const Utils::Variable& variable, std::stringstream& stream)
1224 if (false == variable.IsBlock())
1226 TCU_FAIL("Not implemented");
1230 Utils::Interface* interface = variable.m_descriptor.m_interface;
1232 size_t size = interface->m_members.size();
1234 for (size_t i = 0; i < size; ++i)
1237 std::string name_str = "";
1240 const std::string& name =
1241 Utils::Variable::GetReference(interface->m_name, interface->m_members[i], Utils::Variable::BASIC, 0);
1243 if (Utils::Variable::INTERFACE == interface->m_members[i].m_type)
1245 const std::string& member_name = Utils::Variable::GetReference(
1246 name, interface->m_members[i].m_interface->m_members[0], Utils::Variable::BASIC, 0);
1248 name_str = member_name;
1257 index = program.GetResourceIndex(name_str, GL_BUFFER_VARIABLE);
1259 program.GetResource(GL_BUFFER_VARIABLE, index, GL_OFFSET, 1, &offset);
1261 catch (std::exception& exc)
1263 stream << "Failed to query program for buffer variable: " << variable.m_descriptor.m_name
1264 << ". Reason: " << exc.what() << "\n";
1269 Utils::Variable::Descriptor& desc = interface->m_members[i];
1271 if (offset != (GLint)desc.m_offset)
1273 stream << "Uniform: " << desc.m_name << " - invalid offset: " << offset
1274 << " expected: " << desc.m_offset << std::endl;
1283 /** Query program resources at given stage and verifies results
1285 * @param program Program object
1286 * @param program_interface Definition of program interface
1287 * @param stage Stage to be verified
1288 * @param check_inputs Select if inputs should be verified
1289 * @param check_outputs Select if output should be verified
1290 * @param check_uniforms Select if uniforms should be verified
1291 * @param check_ssbs Select if buffers should be verified
1292 * @param stream Stream that will be used to log any error
1294 * @return true if verification is positive, false otherwise
1296 bool checkProgramStage(Program& program, const ProgramInterface& program_interface, Utils::Shader::STAGES stage,
1297 bool check_inputs, bool check_outputs, bool check_uniforms, bool check_ssbs,
1298 std::stringstream& stream)
1300 typedef Variable::PtrVector::const_iterator const_iterator;
1302 const ShaderInterface& interface = program_interface.GetShaderInterface(stage);
1307 if (true == check_inputs)
1309 const Variable::PtrVector& inputs = interface.m_inputs;
1311 for (const_iterator it = inputs.begin(); it != inputs.end(); ++it)
1313 if (false == checkVarying(program, **it, stream, true))
1321 if (true == check_outputs)
1323 const Variable::PtrVector& outputs = interface.m_outputs;
1325 for (const_iterator it = outputs.begin(); it != outputs.end(); ++it)
1327 if (false == checkVarying(program, **it, stream, false))
1335 if (true == check_uniforms)
1337 const Variable::PtrVector& uniforms = interface.m_uniforms;
1339 for (const_iterator it = uniforms.begin(); it != uniforms.end(); ++it)
1341 if (false == checkUniform(program, **it, stream))
1349 if (true == check_ssbs)
1351 const Variable::PtrVector& ssbs = interface.m_ssb_blocks;
1353 for (const_iterator it = ssbs.begin(); it != ssbs.end(); ++it)
1355 if (false == checkSSB(program, **it, stream))
1365 /** Query resources of monolithic compute program and verifies results
1367 * @param program Program object
1368 * @param program_interface Definition of program interface
1369 * @param stream Stream that will be used to log any error
1371 * @return true if verification is positive, false otherwise
1373 bool checkMonolithicComputeProgramInterface(Program& program, const ProgramInterface& program_interface,
1374 std::stringstream& stream)
1378 if (false == checkProgramStage(program, program_interface, Shader::COMPUTE, false, false, true, true, stream))
1387 /** Query resources of monolithic draw program and verifies results
1389 * @param program Program object
1390 * @param program_interface Definition of program interface
1391 * @param stream Stream that will be used to log any error
1393 * @return true if verification is positive, false otherwise
1395 bool checkMonolithicDrawProgramInterface(Program& program, const ProgramInterface& program_interface,
1396 std::stringstream& stream)
1400 if (false == checkProgramStage(program, program_interface, Shader::VERTEX, true, false, true, true, stream))
1409 /** Query resources of separable draw program and verifies results
1411 * @param program Program object
1412 * @param program_interface Definition of program interface
1413 * @param stream Stream that will be used to log any error
1415 * @return true if verification is positive, false otherwise
1417 bool checkSeparableDrawProgramInterface(Program& program, const ProgramInterface& program_interface,
1418 Utils::Shader::STAGES stage, std::stringstream& stream)
1422 if (false == checkProgramStage(program, program_interface, stage, true, true, true, true, stream))
1431 /** Check if extension is supported
1433 * @param context Test context
1434 * @param extension_name Name of extension
1436 * @return true if extension is supported, false otherwise
1438 bool isExtensionSupported(deqp::Context& context, const GLchar* extension_name)
1440 const std::vector<std::string>& extensions = context.getContextInfo().getExtensions();
1442 if (std::find(extensions.begin(), extensions.end(), extension_name) == extensions.end())
1450 /** Check if GL context meets version requirements
1452 * @param gl Functions
1453 * @param required_major Minimum required MAJOR_VERSION
1454 * @param required_minor Minimum required MINOR_VERSION
1456 * @return true if GL context version is at least as requested, false otherwise
1458 bool isGLVersionAtLeast(const Functions& gl, GLint required_major, GLint required_minor)
1460 glw::GLint major = 0;
1461 glw::GLint minor = 0;
1463 gl.getIntegerv(GL_MAJOR_VERSION, &major);
1464 gl.getIntegerv(GL_MINOR_VERSION, &minor);
1466 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
1468 if (major > required_major)
1470 /* Major is higher than required one */
1473 else if (major == required_major)
1475 if (minor >= required_minor)
1477 /* Major is equal to required one */
1478 /* Minor is higher than or equal to required one */
1483 /* Major is equal to required one */
1484 /* Minor is lower than required one */
1490 /* Major is lower than required one */
1495 /** Replace first occurance of <token> with <text> in <string> starting at <search_posistion>
1497 * @param token Token string
1498 * @param search_position Position at which find will start, it is updated to position at which replaced text ends
1499 * @param text String that will be used as replacement for <token>
1500 * @param string String to work on
1502 void replaceToken(const GLchar* token, size_t& search_position, const GLchar* text, std::string& string)
1504 const size_t text_length = strlen(text);
1505 const size_t token_length = strlen(token);
1506 const size_t token_position = string.find(token, search_position);
1508 #if DEBUG_REPLACE_TOKEN
1509 if (std::string::npos == token_position)
1511 string.append("\n\nInvalid token: ");
1512 string.append(token);
1514 TCU_FAIL(string.c_str());
1516 #endif /* DEBUG_REPLACE_TOKEN */
1518 string.replace(token_position, token_length, text, text_length);
1520 search_position = token_position + text_length;
1523 /** Replace all occurances of <token> with <text> in <string>
1525 * @param token Token string
1526 * @param text String that will be used as replacement for <token>
1527 * @param string String to work on
1529 void replaceAllTokens(const GLchar* token, const GLchar* text, std::string& string)
1531 const size_t text_length = strlen(text);
1532 const size_t token_length = strlen(token);
1534 size_t search_position = 0;
1538 const size_t token_position = string.find(token, search_position);
1540 if (std::string::npos == token_position)
1545 search_position = token_position + text_length;
1547 string.replace(token_position, token_length, text, text_length);
1551 /** Rounds up the value to the next power of 2.
1552 * This routine does not work for 0, see the url for explanations.
1554 * @param value Starting point
1556 * @return Calculated value
1558 glw::GLuint roundUpToPowerOf2(glw::GLuint value)
1560 /* Taken from: graphics.stanford.edu/~seander/bithacks.html */
1563 value |= value >> 1;
1564 value |= value >> 2;
1565 value |= value >> 4;
1566 value |= value >> 8;
1567 value |= value >> 16;
1574 /** Insert elements of list into string.
1575 * List in string is represented either by token "LIST" or "SEPARATORLIST".
1576 * If SEPARATORLIST is available, than SEPARATOR is replaced with <separator>.
1577 * LIST is replaced with <element>SEPARATORLIST
1579 * @param element Element to be inserted
1580 * @param separator Separator inserted between elements
1581 * @param search_position Position in string, where search for list should start
1582 * @param string String
1584 void insertElementOfList(const GLchar* element, const GLchar* separator, size_t& search_position, std::string& string)
1586 static const char* list = g_list;
1587 static const char* sep_list = "SEPARATORLIST";
1589 /* Try to get "list" positions */
1590 const size_t list_position = string.find(list, search_position);
1591 const size_t sep_list_position = string.find(sep_list, search_position);
1593 /* There is no list in string */
1594 if (std::string::npos == list_position)
1599 if (9 /* strlen(SEPARATOR) */ == list_position - sep_list_position)
1601 replaceToken("SEPARATOR", search_position, separator, string);
1604 /* Save search_position */
1605 const size_t start_position = search_position;
1607 /* Prepare new element */
1608 replaceToken("LIST", search_position, "ELEMENTSEPARATORLIST", string);
1610 /* Restore search_position */
1611 search_position = start_position;
1613 /* Replace element and separator */
1614 replaceToken("ELEMENT", search_position, element, string);
1617 /** Close list in string.
1618 * If SEPARATORLIST is available, than SEPARATOR is replaced with <separator>
1619 * LIST is replaced with ""
1621 * @param separator Separator inserted between elements
1622 * @param search_position Position in string, where search for list should start
1623 * @param string String
1625 void endList(const glw::GLchar* separator, size_t& search_position, std::string& string)
1627 const size_t sep_position = string.find("SEPARATOR", search_position);
1628 if (std::string::npos != sep_position)
1630 replaceToken("SEPARATOR", search_position, separator, string);
1633 replaceToken("LIST", search_position, "", string);
1636 /* Buffer constants */
1637 const GLuint Buffer::m_invalid_id = -1;
1641 * @param context CTS context.
1643 Buffer::Buffer(deqp::Context& context) : m_id(m_invalid_id), m_buffer(Array), m_context(context)
1655 /** Initialize buffer instance
1657 * @param buffer Buffer type
1658 * @param usage Buffer usage enum
1659 * @param size <size> parameter
1660 * @param data <data> parameter
1662 void Buffer::Init(BUFFERS buffer, USAGE usage, GLsizeiptr size, GLvoid* data)
1664 /* Delete previous buffer instance */
1669 const Functions& gl = m_context.getRenderContext().getFunctions();
1672 Bind(gl, m_id, m_buffer);
1673 Data(gl, m_buffer, usage, size, data);
1676 /** Release buffer instance
1679 void Buffer::Release()
1681 if (m_invalid_id != m_id)
1683 const Functions& gl = m_context.getRenderContext().getFunctions();
1685 gl.deleteBuffers(1, &m_id);
1686 m_id = m_invalid_id;
1690 /** Binds buffer to its target
1693 void Buffer::Bind() const
1695 const Functions& gl = m_context.getRenderContext().getFunctions();
1697 Bind(gl, m_id, m_buffer);
1700 /** Binds indexed buffer
1702 * @param index <index> parameter
1704 void Buffer::BindBase(GLuint index) const
1706 const Functions& gl = m_context.getRenderContext().getFunctions();
1708 BindBase(gl, m_id, m_buffer, index);
1711 /** Binds range of buffer
1713 * @param index <index> parameter
1714 * @param offset <offset> parameter
1715 * @param size <size> parameter
1717 void Buffer::BindRange(GLuint index, GLintptr offset, GLsizeiptr size) const
1719 const Functions& gl = m_context.getRenderContext().getFunctions();
1721 BindRange(gl, m_id, m_buffer, index, offset, size);
1724 /** Allocate memory for buffer and sends initial content
1726 * @param usage Buffer usage enum
1727 * @param size <size> parameter
1728 * @param data <data> parameter
1730 void Buffer::Data(USAGE usage, glw::GLsizeiptr size, glw::GLvoid* data)
1732 const Functions& gl = m_context.getRenderContext().getFunctions();
1734 Data(gl, m_buffer, usage, size, data);
1737 /** Maps contents of buffer into CPU space
1739 * @param access Requested access
1741 * @return Pointer to memory region available for CPU
1743 GLvoid* Buffer::Map(ACCESS access)
1745 const Functions& gl = m_context.getRenderContext().getFunctions();
1747 return Map(gl, m_buffer, access);
1750 /** Allocate memory for buffer and sends initial content
1752 * @param offset Offset in buffer
1753 * @param size <size> parameter
1754 * @param data <data> parameter
1756 void Buffer::SubData(glw::GLintptr offset, glw::GLsizeiptr size, glw::GLvoid* data)
1758 const Functions& gl = m_context.getRenderContext().getFunctions();
1760 SubData(gl, m_buffer, offset, size, data);
1763 /** Maps contents of buffer into CPU space
1765 void Buffer::UnMap()
1767 const Functions& gl = m_context.getRenderContext().getFunctions();
1769 return UnMap(gl, m_buffer);
1772 /** Bind buffer to given target
1774 * @param gl GL functions
1775 * @param id Id of buffer
1776 * @param buffer Buffer enum
1778 void Buffer::Bind(const Functions& gl, GLuint id, BUFFERS buffer)
1780 GLenum target = GetBufferGLenum(buffer);
1782 gl.bindBuffer(target, id);
1783 GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffer");
1786 /** Binds indexed buffer
1788 * @param gl GL functions
1789 * @param id Id of buffer
1790 * @param buffer Buffer enum
1791 * @param index <index> parameter
1793 void Buffer::BindBase(const Functions& gl, GLuint id, BUFFERS buffer, GLuint index)
1795 GLenum target = GetBufferGLenum(buffer);
1797 gl.bindBufferBase(target, index, id);
1798 GLU_EXPECT_NO_ERROR(gl.getError(), "BindBufferBase");
1801 /** Binds buffer range
1803 * @param gl GL functions
1804 * @param id Id of buffer
1805 * @param buffer Buffer enum
1806 * @param index <index> parameter
1807 * @param offset <offset> parameter
1808 * @param size <size> parameter
1810 void Buffer::BindRange(const Functions& gl, GLuint id, BUFFERS buffer, GLuint index, GLintptr offset, GLsizeiptr size)
1812 GLenum target = GetBufferGLenum(buffer);
1814 gl.bindBufferRange(target, index, id, offset, size);
1815 GLU_EXPECT_NO_ERROR(gl.getError(), "BindBufferRange");
1818 /** Allocate memory for buffer and sends initial content
1820 * @param gl GL functions
1821 * @param buffer Buffer enum
1822 * @param usage Buffer usage enum
1823 * @param size <size> parameter
1824 * @param data <data> parameter
1826 void Buffer::Data(const glw::Functions& gl, BUFFERS buffer, USAGE usage, glw::GLsizeiptr size, glw::GLvoid* data)
1828 GLenum target = GetBufferGLenum(buffer);
1829 GLenum gl_usage = GetUsageGLenum(usage);
1831 gl.bufferData(target, size, data, gl_usage);
1832 GLU_EXPECT_NO_ERROR(gl.getError(), "BufferData");
1835 /** Allocate memory for buffer and sends initial content
1837 * @param gl GL functions
1838 * @param buffer Buffer enum
1839 * @param offset Offset in buffer
1840 * @param size <size> parameter
1841 * @param data <data> parameter
1843 void Buffer::SubData(const glw::Functions& gl, BUFFERS buffer, glw::GLintptr offset, glw::GLsizeiptr size,
1846 GLenum target = GetBufferGLenum(buffer);
1848 gl.bufferSubData(target, offset, size, data);
1849 GLU_EXPECT_NO_ERROR(gl.getError(), "BufferSubData");
1854 * @param gl GL functions
1855 * @param out_id Id of buffer
1857 void Buffer::Generate(const Functions& gl, GLuint& out_id)
1859 GLuint id = m_invalid_id;
1861 gl.genBuffers(1, &id);
1862 GLU_EXPECT_NO_ERROR(gl.getError(), "GenBuffers");
1864 if (m_invalid_id == id)
1866 TCU_FAIL("Got invalid id");
1872 /** Maps buffer content
1874 * @param gl GL functions
1875 * @param buffer Buffer enum
1876 * @param access Access rights for mapped region
1878 * @return Mapped memory
1880 void* Buffer::Map(const Functions& gl, BUFFERS buffer, ACCESS access)
1882 GLenum target = GetBufferGLenum(buffer);
1883 GLenum gl_access = GetAccessGLenum(access);
1885 void* result = gl.mapBuffer(target, gl_access);
1886 GLU_EXPECT_NO_ERROR(gl.getError(), "MapBuffer");
1894 void Buffer::UnMap(const Functions& gl, BUFFERS buffer)
1896 GLenum target = GetBufferGLenum(buffer);
1898 gl.unmapBuffer(target);
1899 GLU_EXPECT_NO_ERROR(gl.getError(), "UnmapBuffer");
1902 /** Return GLenum representation of requested access
1904 * @param access Requested access
1906 * @return GLenum value
1908 GLenum Buffer::GetAccessGLenum(ACCESS access)
1915 result = GL_READ_ONLY;
1918 result = GL_WRITE_ONLY;
1921 result = GL_READ_WRITE;
1924 TCU_FAIL("Invalid enum");
1930 /** Return GLenum representation of requested buffer type
1932 * @param buffer Requested buffer type
1934 * @return GLenum value
1936 GLenum Buffer::GetBufferGLenum(BUFFERS buffer)
1943 result = GL_ARRAY_BUFFER;
1946 result = GL_ELEMENT_ARRAY_BUFFER;
1948 case Shader_Storage:
1949 result = GL_SHADER_STORAGE_BUFFER;
1952 result = GL_TEXTURE_BUFFER;
1954 case Transform_feedback:
1955 result = GL_TRANSFORM_FEEDBACK_BUFFER;
1958 result = GL_UNIFORM_BUFFER;
1961 TCU_FAIL("Invalid enum");
1967 /** Return GLenum representation of requested usage
1969 * @param usage Requested usage
1971 * @return GLenum value
1973 GLenum Buffer::GetUsageGLenum(USAGE usage)
1980 result = GL_DYNAMIC_COPY;
1983 result = GL_DYNAMIC_DRAW;
1986 result = GL_DYNAMIC_READ;
1989 result = GL_STATIC_COPY;
1992 result = GL_STATIC_DRAW;
1995 result = GL_STATIC_READ;
1998 result = GL_STREAM_COPY;
2001 result = GL_STREAM_DRAW;
2004 result = GL_STREAM_READ;
2007 TCU_FAIL("Invalid enum");
2013 /** Returns name of buffer target
2015 * @param buffer Target enum
2017 * @return Name of target
2019 const GLchar* Buffer::GetBufferName(BUFFERS buffer)
2021 const GLchar* name = 0;
2031 case Shader_Storage:
2032 name = "Shader_Storage";
2037 case Transform_feedback:
2038 name = "Transform_feedback";
2044 TCU_FAIL("Invalid enum");
2050 /* Framebuffer constants */
2051 const GLuint Framebuffer::m_invalid_id = -1;
2055 * @param context CTS context
2057 Framebuffer::Framebuffer(deqp::Context& context) : m_id(m_invalid_id), m_context(context)
2059 /* Nothing to be done here */
2065 Framebuffer::~Framebuffer()
2070 /** Initialize framebuffer instance
2073 void Framebuffer::Init()
2075 /* Delete previous instance */
2078 const Functions& gl = m_context.getRenderContext().getFunctions();
2083 /** Release framebuffer instance
2086 void Framebuffer::Release()
2088 if (m_invalid_id != m_id)
2090 const Functions& gl = m_context.getRenderContext().getFunctions();
2092 gl.deleteFramebuffers(1, &m_id);
2093 m_id = m_invalid_id;
2097 /** Attach texture to specified attachment
2099 * @param attachment Attachment
2100 * @param texture_id Texture id
2101 * @param width Texture width
2102 * @param height Texture height
2104 void Framebuffer::AttachTexture(GLenum attachment, GLuint texture_id, GLuint width, GLuint height)
2106 const Functions& gl = m_context.getRenderContext().getFunctions();
2108 AttachTexture(gl, attachment, texture_id, width, height);
2111 /** Binds framebuffer to DRAW_FRAMEBUFFER
2114 void Framebuffer::Bind()
2116 const Functions& gl = m_context.getRenderContext().getFunctions();
2121 /** Clear framebuffer
2123 * @param mask <mask> parameter of glClear. Decides which shall be cleared
2125 void Framebuffer::Clear(GLenum mask)
2127 const Functions& gl = m_context.getRenderContext().getFunctions();
2132 /** Specifies clear color
2134 * @param red Red channel
2135 * @param green Green channel
2136 * @param blue Blue channel
2137 * @param alpha Alpha channel
2139 void Framebuffer::ClearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
2141 const Functions& gl = m_context.getRenderContext().getFunctions();
2143 ClearColor(gl, red, green, blue, alpha);
2146 /** Attach texture to specified attachment
2148 * @param gl GL functions
2149 * @param attachment Attachment
2150 * @param texture_id Texture id
2151 * @param width Texture width
2152 * @param height Texture height
2154 void Framebuffer::AttachTexture(const Functions& gl, GLenum attachment, GLuint texture_id, GLuint width, GLuint height)
2156 gl.framebufferTexture(GL_DRAW_FRAMEBUFFER, attachment, texture_id, 0 /* level */);
2157 GLU_EXPECT_NO_ERROR(gl.getError(), "FramebufferTexture");
2159 gl.viewport(0 /* x */, 0 /* y */, width, height);
2160 GLU_EXPECT_NO_ERROR(gl.getError(), "Viewport");
2163 /** Binds framebuffer to DRAW_FRAMEBUFFER
2165 * @param gl GL functions
2166 * @param id ID of framebuffer
2168 void Framebuffer::Bind(const Functions& gl, GLuint id)
2170 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, id);
2171 GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer");
2174 /** Clear framebuffer
2176 * @param gl GL functions
2177 * @param mask <mask> parameter of glClear. Decides which shall be cleared
2179 void Framebuffer::Clear(const Functions& gl, GLenum mask)
2182 GLU_EXPECT_NO_ERROR(gl.getError(), "Clear");
2185 /** Specifies clear color
2187 * @param gl GL functions
2188 * @param red Red channel
2189 * @param green Green channel
2190 * @param blue Blue channel
2191 * @param alpha Alpha channel
2193 void Framebuffer::ClearColor(const Functions& gl, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
2195 gl.clearColor(red, green, blue, alpha);
2196 GLU_EXPECT_NO_ERROR(gl.getError(), "ClearColor");
2199 /** Generate framebuffer
2202 void Framebuffer::Generate(const Functions& gl, GLuint& out_id)
2204 GLuint id = m_invalid_id;
2206 gl.genFramebuffers(1, &id);
2207 GLU_EXPECT_NO_ERROR(gl.getError(), "GenFramebuffers");
2209 if (m_invalid_id == id)
2211 TCU_FAIL("Invalid id");
2217 /* Shader's constants */
2218 const GLuint Shader::m_invalid_id = 0;
2222 * @param context CTS context.
2224 Shader::Shader(deqp::Context& context) : m_id(m_invalid_id), m_context(context)
2226 /* Nothing to be done here */
2237 /** Initialize shader instance
2239 * @param stage Shader stage
2240 * @param source Source code
2242 void Shader::Init(STAGES stage, const std::string& source)
2244 if (true == source.empty())
2246 /* No source == no shader */
2250 /* Delete any previous shader */
2253 /* Create, set source and compile */
2254 const Functions& gl = m_context.getRenderContext().getFunctions();
2256 Create(gl, stage, m_id);
2257 Source(gl, m_id, source);
2263 catch (const CompilationException& exc)
2265 throw InvalidSourceException(exc.what(), source, stage);
2269 /** Release shader instance
2272 void Shader::Release()
2274 if (m_invalid_id != m_id)
2276 const Functions& gl = m_context.getRenderContext().getFunctions();
2278 gl.deleteShader(m_id);
2279 m_id = m_invalid_id;
2285 * @param gl GL functions
2286 * @param id Shader id
2288 void Shader::Compile(const Functions& gl, GLuint id)
2290 GLint status = GL_FALSE;
2293 gl.compileShader(id);
2294 GLU_EXPECT_NO_ERROR(gl.getError(), "CompileShader");
2296 /* Get compilation status */
2297 gl.getShaderiv(id, GL_COMPILE_STATUS, &status);
2298 GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");
2300 /* Log compilation error */
2301 if (GL_TRUE != status)
2303 glw::GLint length = 0;
2304 std::string message;
2306 /* Error log length */
2307 gl.getShaderiv(id, GL_INFO_LOG_LENGTH, &length);
2308 GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");
2310 /* Prepare storage */
2311 message.resize(length, 0);
2314 gl.getShaderInfoLog(id, length, 0, &message[0]);
2315 GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderInfoLog");
2317 throw CompilationException(message.c_str());
2323 * @param gl GL functions
2324 * @param stage Shader stage
2325 * @param out_id Shader id
2327 void Shader::Create(const Functions& gl, STAGES stage, GLuint& out_id)
2329 const GLenum shaderType = GetShaderStageGLenum(stage);
2330 const GLuint id = gl.createShader(shaderType);
2331 GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
2333 if (m_invalid_id == id)
2335 TCU_FAIL("Failed to create shader");
2341 /** Set shader's source code
2343 * @param gl GL functions
2344 * @param id Shader id
2345 * @param source Shader source code
2347 void Shader::Source(const Functions& gl, GLuint id, const std::string& source)
2349 const GLchar* code = source.c_str();
2351 gl.shaderSource(id, 1 /* count */, &code, 0 /* lengths */);
2352 GLU_EXPECT_NO_ERROR(gl.getError(), "ShaderSource");
2355 /** Get GLenum repesenting shader stage
2357 * @param stage Shader stage
2361 GLenum Shader::GetShaderStageGLenum(STAGES stage)
2368 result = GL_COMPUTE_SHADER;
2371 result = GL_FRAGMENT_SHADER;
2374 result = GL_GEOMETRY_SHADER;
2377 result = GL_TESS_CONTROL_SHADER;
2380 result = GL_TESS_EVALUATION_SHADER;
2383 result = GL_VERTEX_SHADER;
2386 TCU_FAIL("Invalid enum");
2392 /** Get string representing name of shader stage
2394 * @param stage Shader stage
2396 * @return String with name of shader stage
2398 const glw::GLchar* Shader::GetStageName(STAGES stage)
2400 const GLchar* result = 0;
2411 result = "tessellation control";
2414 result = "tessellation evaluation";
2417 result = "geometry";
2420 result = "fragment";
2423 TCU_FAIL("Invalid enum");
2429 /** Logs shader source
2431 * @param context CTS context
2432 * @param source Source of shader
2433 * @param stage Shader stage
2435 void Shader::LogSource(deqp::Context& context, const std::string& source, STAGES stage)
2437 /* Skip empty shaders */
2438 if (true == source.empty())
2443 context.getTestContext().getLog() << tcu::TestLog::Message
2444 << "Shader source. Stage: " << Shader::GetStageName(stage)
2445 << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(source);
2450 * @param message Compilation error message
2452 Shader::CompilationException::CompilationException(const GLchar* message)
2454 m_message = message;
2457 /** Returns error messages
2459 * @return Compilation error message
2461 const char* Shader::CompilationException::what() const throw()
2463 return m_message.c_str();
2468 * @param message Compilation error message
2470 Shader::InvalidSourceException::InvalidSourceException(const GLchar* error_message, const std::string& source,
2472 : m_message(error_message), m_source(source), m_stage(stage)
2476 /** Returns error messages
2478 * @return Compilation error message
2480 const char* Shader::InvalidSourceException::what() const throw()
2482 return "Compilation error";
2485 /** Logs error message and shader sources **/
2486 void Shader::InvalidSourceException::log(deqp::Context& context) const
2488 context.getTestContext().getLog() << tcu::TestLog::Message << "Failed to compile shader: " << m_message.c_str()
2489 << tcu::TestLog::EndMessage;
2491 LogSource(context, m_source, m_stage);
2494 /* Program constants */
2495 const GLuint Pipeline::m_invalid_id = 0;
2499 * @param context CTS context.
2501 Pipeline::Pipeline(deqp::Context& context) : m_id(m_invalid_id), m_context(context)
2503 /* Nothing to be done here */
2509 Pipeline::~Pipeline()
2514 /** Initialize pipline object
2517 void Pipeline::Init()
2521 const Functions& gl = m_context.getRenderContext().getFunctions();
2524 gl.genProgramPipelines(1, &m_id);
2525 GLU_EXPECT_NO_ERROR(gl.getError(), "GenProgramPipelines");
2528 /** Release pipeline object
2531 void Pipeline::Release()
2533 if (m_invalid_id != m_id)
2535 const Functions& gl = m_context.getRenderContext().getFunctions();
2538 gl.deleteProgramPipelines(1, &m_id);
2539 GLU_EXPECT_NO_ERROR(gl.getError(), "DeleteProgramPipelines");
2541 m_id = m_invalid_id;
2548 void Pipeline::Bind()
2550 const Functions& gl = m_context.getRenderContext().getFunctions();
2555 /** Set which stages should be active
2557 * @param program_id Id of program
2558 * @param stages Logical combination of enums representing stages
2560 void Pipeline::UseProgramStages(GLuint program_id, GLenum stages)
2562 const Functions& gl = m_context.getRenderContext().getFunctions();
2564 UseProgramStages(gl, m_id, program_id, stages);
2569 * @param gl Functiions
2570 * @param id Pipeline id
2572 void Pipeline::Bind(const Functions& gl, GLuint id)
2574 gl.bindProgramPipeline(id);
2575 GLU_EXPECT_NO_ERROR(gl.getError(), "BindProgramPipeline");
2578 /** Set which stages should be active
2580 * @param gl Functiions
2581 * @param id Pipeline id
2582 * @param program_id Id of program
2583 * @param stages Logical combination of enums representing stages
2585 void Pipeline::UseProgramStages(const Functions& gl, GLuint id, GLuint program_id, GLenum stages)
2587 gl.useProgramStages(id, stages, program_id);
2588 GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgramStages");
2591 /* Program constants */
2592 const GLuint Program::m_invalid_id = 0;
2596 * @param context CTS context.
2598 Program::Program(deqp::Context& context)
2599 : m_id(m_invalid_id)
2600 , m_compute(context)
2601 , m_fragment(context)
2602 , m_geometry(context)
2603 , m_tess_ctrl(context)
2604 , m_tess_eval(context)
2606 , m_context(context)
2608 /* Nothing to be done here */
2619 /** Initialize program instance
2621 * @param compute_shader Compute shader source code
2622 * @param fragment_shader Fragment shader source code
2623 * @param geometry_shader Geometry shader source code
2624 * @param tessellation_control_shader Tessellation control shader source code
2625 * @param tessellation_evaluation_shader Tessellation evaluation shader source code
2626 * @param vertex_shader Vertex shader source code
2627 * @param captured_varyings Vector of variables to be captured with transfrom feedback
2628 * @param capture_interleaved Select mode of transform feedback (separate or interleaved)
2629 * @param is_separable Selects if monolithic or separable program should be built. Defaults to false
2631 void Program::Init(const std::string& compute_shader, const std::string& fragment_shader,
2632 const std::string& geometry_shader, const std::string& tessellation_control_shader,
2633 const std::string& tessellation_evaluation_shader, const std::string& vertex_shader,
2634 const NameVector& captured_varyings, bool capture_interleaved, bool is_separable)
2636 /* Delete previous program */
2639 /* GL entry points */
2640 const Functions& gl = m_context.getRenderContext().getFunctions();
2642 /* Initialize shaders */
2643 m_compute.Init(Shader::COMPUTE, compute_shader);
2644 m_fragment.Init(Shader::FRAGMENT, fragment_shader);
2645 m_geometry.Init(Shader::GEOMETRY, geometry_shader);
2646 m_tess_ctrl.Init(Shader::TESS_CTRL, tessellation_control_shader);
2647 m_tess_eval.Init(Shader::TESS_EVAL, tessellation_evaluation_shader);
2648 m_vertex.Init(Shader::VERTEX, vertex_shader);
2650 /* Create program, set up transform feedback and attach shaders */
2652 Capture(gl, m_id, captured_varyings, capture_interleaved);
2653 Attach(gl, m_id, m_compute.m_id);
2654 Attach(gl, m_id, m_fragment.m_id);
2655 Attach(gl, m_id, m_geometry.m_id);
2656 Attach(gl, m_id, m_tess_ctrl.m_id);
2657 Attach(gl, m_id, m_tess_eval.m_id);
2658 Attach(gl, m_id, m_vertex.m_id);
2660 /* Set separable parameter */
2661 if (true == is_separable)
2663 gl.programParameteri(m_id, GL_PROGRAM_SEPARABLE, GL_TRUE);
2664 GLU_EXPECT_NO_ERROR(gl.getError(), "ProgramParameteri");
2672 catch (const LinkageException& exc)
2674 throw BuildException(exc.what(), compute_shader, fragment_shader, geometry_shader, tessellation_control_shader,
2675 tessellation_evaluation_shader, vertex_shader);
2679 /** Initialize program instance
2681 * @param compute_shader Compute shader source code
2682 * @param fragment_shader Fragment shader source code
2683 * @param geometry_shader Geometry shader source code
2684 * @param tessellation_control_shader Tessellation control shader source code
2685 * @param tessellation_evaluation_shader Tessellation evaluation shader source code
2686 * @param vertex_shader Vertex shader source code
2687 * @param is_separable Selects if monolithic or separable program should be built. Defaults to false
2689 void Program::Init(const std::string& compute_shader, const std::string& fragment_shader,
2690 const std::string& geometry_shader, const std::string& tessellation_control_shader,
2691 const std::string& tessellation_evaluation_shader, const std::string& vertex_shader,
2694 NameVector captured_varying;
2696 Init(compute_shader, fragment_shader, geometry_shader, tessellation_control_shader, tessellation_evaluation_shader,
2697 vertex_shader, captured_varying, true, is_separable);
2700 /** Release program instance
2703 void Program::Release()
2705 const Functions& gl = m_context.getRenderContext().getFunctions();
2707 if (m_invalid_id != m_id)
2709 Use(gl, m_invalid_id);
2711 gl.deleteProgram(m_id);
2712 m_id = m_invalid_id;
2715 m_compute.Release();
2716 m_fragment.Release();
2717 m_geometry.Release();
2718 m_tess_ctrl.Release();
2719 m_tess_eval.Release();
2723 /** Get <pname> for a set of active uniforms
2725 * @param count Number of indices
2726 * @param indices Indices of uniforms
2727 * @param pname Queired pname
2728 * @param params Array that will be filled with values of parameters
2730 void Program::GetActiveUniformsiv(GLsizei count, const GLuint* indices, GLenum pname, GLint* params) const
2732 const Functions& gl = m_context.getRenderContext().getFunctions();
2734 GetActiveUniformsiv(gl, m_id, count, indices, pname, params);
2737 /** Get location of attribute
2739 * @param name Name of attribute
2741 * @return Result of query
2743 glw::GLint Program::GetAttribLocation(const std::string& name) const
2745 const Functions& gl = m_context.getRenderContext().getFunctions();
2747 return GetAttribLocation(gl, m_id, name);
2752 * @param interface Interface to be queried
2753 * @param index Index of resource
2754 * @param property Property to be queried
2755 * @param buf_size Size of <params> buffer
2756 * @param params Results of query
2758 void Program::GetResource(GLenum interface, GLuint index, GLenum property, GLsizei buf_size, GLint* params) const
2760 const Functions& gl = m_context.getRenderContext().getFunctions();
2762 GetResource(gl, m_id, interface, index, property, buf_size, params);
2765 /** Query for index of resource
2767 * @param name Name of resource
2768 * @param interface Interface to be queried
2770 * @return Result of query
2772 glw::GLuint Program::GetResourceIndex(const std::string& name, GLenum interface) const
2774 const Functions& gl = m_context.getRenderContext().getFunctions();
2776 return GetResourceIndex(gl, m_id, name, interface);
2779 /** Get indices for a set of uniforms
2781 * @param count Count number of uniforms
2782 * @param names Names of uniforms
2783 * @param indices Buffer that will be filled with indices
2785 void Program::GetUniformIndices(GLsizei count, const GLchar** names, GLuint* indices) const
2787 const Functions& gl = m_context.getRenderContext().getFunctions();
2789 GetUniformIndices(gl, m_id, count, names, indices);
2792 /** Get uniform location
2794 * @param name Name of uniform
2796 * @return Results of query
2798 glw::GLint Program::GetUniformLocation(const std::string& name) const
2800 const Functions& gl = m_context.getRenderContext().getFunctions();
2802 return GetUniformLocation(gl, m_id, name);
2805 /** Set program as active
2808 void Program::Use() const
2810 const Functions& gl = m_context.getRenderContext().getFunctions();
2815 /** Attach shader to program
2817 * @param gl GL functions
2818 * @param program_id Id of program
2819 * @param shader_id Id of shader
2821 void Program::Attach(const Functions& gl, GLuint program_id, GLuint shader_id)
2824 if ((m_invalid_id == program_id) || (Shader::m_invalid_id == shader_id))
2829 gl.attachShader(program_id, shader_id);
2830 GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
2833 /** Set up captured varyings
2835 * @param gl GL functions
2836 * @param id Id of program
2837 * @param captured_varyings Vector of varyings
2838 * @param capture_interleaved Selects if interleaved or separate mode should be used
2840 void Program::Capture(const Functions& gl, GLuint id, const NameVector& captured_varyings, bool capture_interleaved)
2842 const size_t n_varyings = captured_varyings.size();
2844 if (0 == n_varyings)
2846 /* empty list, skip */
2850 std::vector<const GLchar*> varying_names;
2851 varying_names.resize(n_varyings);
2853 for (size_t i = 0; i < n_varyings; ++i)
2855 varying_names[i] = captured_varyings[i].c_str();
2859 if (true == capture_interleaved)
2861 mode = GL_INTERLEAVED_ATTRIBS;
2865 mode = GL_SEPARATE_ATTRIBS;
2868 gl.transformFeedbackVaryings(id, static_cast<GLsizei>(n_varyings), &varying_names[0], mode);
2869 GLU_EXPECT_NO_ERROR(gl.getError(), "TransformFeedbackVaryings");
2872 /** Create program instance
2874 * @param gl GL functions
2875 * @param out_id Id of program
2877 void Program::Create(const Functions& gl, GLuint& out_id)
2879 const GLuint id = gl.createProgram();
2880 GLU_EXPECT_NO_ERROR(gl.getError(), "CreateProgram");
2882 if (m_invalid_id == id)
2884 TCU_FAIL("Failed to create program");
2890 /** Get <pname> for a set of active uniforms
2892 * @param gl Functions
2893 * @param program_id Id of program
2894 * @param count Number of indices
2895 * @param indices Indices of uniforms
2896 * @param pname Queired pname
2897 * @param params Array that will be filled with values of parameters
2899 void Program::GetActiveUniformsiv(const Functions& gl, GLuint program_id, GLsizei count, const GLuint* indices,
2900 GLenum pname, GLint* params)
2902 gl.getActiveUniformsiv(program_id, count, indices, pname, params);
2903 GLU_EXPECT_NO_ERROR(gl.getError(), "GetActiveUniformsiv");
2906 /** Get indices for a set of uniforms
2908 * @param gl Functions
2909 * @param program_id Id of program
2910 * @param count Count number of uniforms
2911 * @param names Names of uniforms
2912 * @param indices Buffer that will be filled with indices
2914 void Program::GetUniformIndices(const Functions& gl, GLuint program_id, GLsizei count, const GLchar** names,
2917 gl.getUniformIndices(program_id, count, names, indices);
2918 GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformIndices");
2923 * @param gl GL functions
2924 * @param id Id of program
2926 void Program::Link(const Functions& gl, GLuint id)
2928 GLint status = GL_FALSE;
2931 GLU_EXPECT_NO_ERROR(gl.getError(), "LinkProgram");
2933 /* Get link status */
2934 gl.getProgramiv(id, GL_LINK_STATUS, &status);
2935 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");
2937 /* Log link error */
2938 if (GL_TRUE != status)
2940 glw::GLint length = 0;
2941 std::string message;
2943 /* Get error log length */
2944 gl.getProgramiv(id, GL_INFO_LOG_LENGTH, &length);
2945 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");
2947 message.resize(length, 0);
2950 gl.getProgramInfoLog(id, length, 0, &message[0]);
2951 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramInfoLog");
2953 throw LinkageException(message.c_str());
2957 /** Set generic uniform
2959 * @param gl Functions
2960 * @param type Type of uniform
2961 * @param count Length of array
2962 * @param location Location of uniform
2963 * @param data Data that will be used
2965 void Program::Uniform(const Functions& gl, const Type& type, GLsizei count, GLint location, const GLvoid* data)
2969 TCU_FAIL("Uniform is inactive");
2972 switch (type.m_basic_type)
2975 if (1 == type.m_n_columns)
2977 getUniformNdv(gl, type.m_n_rows)(location, count, (const GLdouble*)data);
2978 GLU_EXPECT_NO_ERROR(gl.getError(), "UniformNdv");
2982 getUniformMatrixNdv(gl, type.m_n_columns, type.m_n_rows)(location, count, false, (const GLdouble*)data);
2983 GLU_EXPECT_NO_ERROR(gl.getError(), "UniformMatrixNdv");
2987 if (1 == type.m_n_columns)
2989 getUniformNfv(gl, type.m_n_rows)(location, count, (const GLfloat*)data);
2990 GLU_EXPECT_NO_ERROR(gl.getError(), "UniformNfv");
2994 getUniformMatrixNfv(gl, type.m_n_columns, type.m_n_rows)(location, count, false, (const GLfloat*)data);
2995 GLU_EXPECT_NO_ERROR(gl.getError(), "UniformMatrixNfv");
2999 getUniformNiv(gl, type.m_n_rows)(location, count, (const GLint*)data);
3000 GLU_EXPECT_NO_ERROR(gl.getError(), "UniformNiv");
3003 getUniformNuiv(gl, type.m_n_rows)(location, count, (const GLuint*)data);
3004 GLU_EXPECT_NO_ERROR(gl.getError(), "UniformNuiv");
3007 TCU_FAIL("Invalid enum");
3013 * @param gl GL functions
3014 * @param id Id of program
3016 void Program::Use(const Functions& gl, GLuint id)
3019 GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram");
3022 /** Get location of attribute
3024 * @param gl GL functions
3025 * @param id Id of program
3026 * @param name Name of attribute
3028 * @return Location of attribute
3030 GLint Program::GetAttribLocation(const Functions& gl, GLuint id, const std::string& name)
3032 GLint location = gl.getAttribLocation(id, name.c_str());
3033 GLU_EXPECT_NO_ERROR(gl.getError(), "GetAttribLocation");
3040 * @param gl GL functions
3041 * @param id Id of program
3042 * @param interface Interface to be queried
3043 * @param index Index of resource
3044 * @param property Property to be queried
3045 * @param buf_size Size of <params> buffer
3046 * @param params Results of query
3048 void Program::GetResource(const Functions& gl, GLuint id, GLenum interface, GLuint index, GLenum property,
3049 GLsizei buf_size, GLint* params)
3051 gl.getProgramResourceiv(id, interface, index, 1 /* propCount */, &property, buf_size /* bufSize */, 0 /* length */,
3053 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramResourceiv");
3056 /** Get index of resource
3058 * @param gl GL functions
3059 * @param id Id of program
3060 * @param name Name of resource
3061 * @param interface Program interface to queried
3063 * @return Location of attribute
3065 GLuint Program::GetResourceIndex(const Functions& gl, GLuint id, const std::string& name, GLenum interface)
3067 GLuint index = gl.getProgramResourceIndex(id, interface, name.c_str());
3068 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramResourceIndex");
3073 /** Get location of attribute
3075 * @param gl GL functions
3076 * @param id Id of program
3077 * @param name Name of attribute
3079 * @return Location of uniform
3081 GLint Program::GetUniformLocation(const Functions& gl, GLuint id, const std::string& name)
3083 GLint location = gl.getUniformLocation(id, name.c_str());
3084 GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformLocation");
3091 * @param error_message Error message
3092 * @param compute_shader Source code for compute stage
3093 * @param fragment_shader Source code for fragment stage
3094 * @param geometry_shader Source code for geometry stage
3095 * @param tess_ctrl_shader Source code for tessellation control stage
3096 * @param tess_eval_shader Source code for tessellation evaluation stage
3097 * @param vertex_shader Source code for vertex stage
3099 Program::BuildException::BuildException(const glw::GLchar* error_message, const std::string compute_shader,
3100 const std::string fragment_shader, const std::string geometry_shader,
3101 const std::string tess_ctrl_shader, const std::string tess_eval_shader,
3102 const std::string vertex_shader)
3103 : m_error_message(error_message)
3104 , m_compute_shader(compute_shader)
3105 , m_fragment_shader(fragment_shader)
3106 , m_geometry_shader(geometry_shader)
3107 , m_tess_ctrl_shader(tess_ctrl_shader)
3108 , m_tess_eval_shader(tess_eval_shader)
3109 , m_vertex_shader(vertex_shader)
3113 /** Overwrites std::exception::what method
3115 * @return Message compossed from error message and shader sources
3117 const char* Program::BuildException::what() const throw()
3119 return "Failed to link program";
3122 /** Logs error message and shader sources **/
3123 void Program::BuildException::log(deqp::Context& context) const
3125 context.getTestContext().getLog() << tcu::TestLog::Message << "Link failure: " << m_error_message
3126 << tcu::TestLog::EndMessage;
3128 Shader::LogSource(context, m_vertex_shader, Shader::VERTEX);
3129 Shader::LogSource(context, m_tess_ctrl_shader, Shader::TESS_CTRL);
3130 Shader::LogSource(context, m_tess_eval_shader, Shader::TESS_EVAL);
3131 Shader::LogSource(context, m_geometry_shader, Shader::GEOMETRY);
3132 Shader::LogSource(context, m_fragment_shader, Shader::FRAGMENT);
3133 Shader::LogSource(context, m_compute_shader, Shader::COMPUTE);
3138 * @param message Linking error message
3140 Program::LinkageException::LinkageException(const glw::GLchar* message) : m_error_message(message)
3142 /* Nothing to be done */
3145 /** Returns error messages
3147 * @return Linking error message
3149 const char* Program::LinkageException::what() const throw()
3151 return m_error_message.c_str();
3154 /* Texture constants */
3155 const GLuint Texture::m_invalid_id = -1;
3159 * @param context CTS context.
3161 Texture::Texture(deqp::Context& context) : m_id(m_invalid_id), m_context(context), m_type(TEX_2D)
3163 /* Nothing to done here */
3174 /** Initialize texture instance
3176 * @param tex_type Type of texture
3177 * @param width Width of texture
3178 * @param height Height of texture
3179 * @param depth Depth of texture
3180 * @param internal_format Internal format of texture
3181 * @param format Format of texture data
3182 * @param type Type of texture data
3183 * @param data Texture data
3185 void Texture::Init(TYPES tex_type, GLuint width, GLuint height, GLuint depth, GLenum internal_format, GLenum format,
3186 GLenum type, GLvoid* data)
3188 const Functions& gl = m_context.getRenderContext().getFunctions();
3190 /* Delete previous texture */
3195 /* Generate, bind, allocate storage and upload data */
3197 Bind(gl, m_id, tex_type);
3198 Storage(gl, tex_type, width, height, depth, internal_format);
3199 Update(gl, tex_type, width, height, depth, format, type, data);
3202 /** Initialize buffer texture
3204 * @param internal_format Internal format of texture
3205 * @param buffer_id Id of buffer that will be used as data source
3207 void Texture::Init(GLenum internal_format, GLuint buffer_id)
3209 const Functions& gl = m_context.getRenderContext().getFunctions();
3211 /* Delete previous texture */
3214 m_type = TEX_BUFFER;
3216 /* Generate, bind and attach buffer */
3218 Bind(gl, m_id, TEX_BUFFER);
3219 TexBuffer(gl, buffer_id, internal_format);
3222 /** Release texture instance
3225 void Texture::Release()
3227 if (m_invalid_id != m_id)
3229 const Functions& gl = m_context.getRenderContext().getFunctions();
3231 gl.deleteTextures(1, &m_id);
3232 m_id = m_invalid_id;
3236 /** Bind texture to its target
3239 void Texture::Bind() const
3241 const Functions& gl = m_context.getRenderContext().getFunctions();
3243 Bind(gl, m_id, m_type);
3246 /** Get texture data
3248 * @param format Format of data
3249 * @param type Type of data
3250 * @param out_data Buffer for data
3252 void Texture::Get(GLenum format, GLenum type, GLvoid* out_data) const
3254 const Functions& gl = m_context.getRenderContext().getFunctions();
3256 Bind(gl, m_id, m_type);
3257 Get(gl, m_type, format, type, out_data);
3260 /** Bind texture to target
3262 * @param gl GL functions
3263 * @param id Id of texture
3264 * @param tex_type Type of texture
3266 void Texture::Bind(const Functions& gl, GLuint id, TYPES tex_type)
3268 GLenum target = GetTargetGLenum(tex_type);
3270 gl.bindTexture(target, id);
3271 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
3274 /** Generate texture instance
3276 * @param gl GL functions
3277 * @param out_id Id of texture
3279 void Texture::Generate(const Functions& gl, GLuint& out_id)
3281 GLuint id = m_invalid_id;
3283 gl.genTextures(1, &id);
3284 GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures");
3286 if (m_invalid_id == id)
3288 TCU_FAIL("Invalid id");
3294 /** Get texture data
3296 * @param gl GL functions
3297 * @param format Format of data
3298 * @param type Type of data
3299 * @param out_data Buffer for data
3301 void Texture::Get(const Functions& gl, TYPES tex_type, GLenum format, GLenum type, GLvoid* out_data)
3303 GLenum target = GetTargetGLenum(tex_type);
3305 if (TEX_CUBE != tex_type)
3307 gl.getTexImage(target, 0 /* level */, format, type, out_data);
3308 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexImage");
3315 if ((GL_RGBA != format) && (GL_UNSIGNED_BYTE != type))
3317 TCU_FAIL("Not implemented");
3320 GLuint texel_size = 4;
3322 gl.getTexLevelParameteriv(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0 /* level */, GL_TEXTURE_WIDTH, &width);
3323 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv");
3325 gl.getTexLevelParameteriv(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0 /* level */, GL_TEXTURE_HEIGHT, &height);
3326 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv");
3328 const GLuint image_size = width * height * texel_size;
3330 gl.getTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0 /* level */, format, type,
3331 (GLvoid*)((GLchar*)out_data + (image_size * 0)));
3332 gl.getTexImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0 /* level */, format, type,
3333 (GLvoid*)((GLchar*)out_data + (image_size * 1)));
3334 gl.getTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0 /* level */, format, type,
3335 (GLvoid*)((GLchar*)out_data + (image_size * 2)));
3336 gl.getTexImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0 /* level */, format, type,
3337 (GLvoid*)((GLchar*)out_data + (image_size * 3)));
3338 gl.getTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0 /* level */, format, type,
3339 (GLvoid*)((GLchar*)out_data + (image_size * 4)));
3340 gl.getTexImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0 /* level */, format, type,
3341 (GLvoid*)((GLchar*)out_data + (image_size * 5)));
3342 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexImage");
3346 /** Allocate storage for texture
3348 * @param gl GL functions
3349 * @param tex_type Type of texture
3350 * @param width Width of texture
3351 * @param height Height of texture
3352 * @param depth Depth of texture
3353 * @param internal_format Internal format of texture
3355 void Texture::Storage(const Functions& gl, TYPES tex_type, GLuint width, GLuint height, GLuint depth,
3356 GLenum internal_format)
3358 static const GLuint levels = 1;
3360 GLenum target = GetTargetGLenum(tex_type);
3365 gl.texStorage1D(target, levels, internal_format, width);
3366 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage1D");
3372 gl.texStorage2D(target, levels, internal_format, width, height);
3373 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2D");
3377 gl.texStorage3D(target, levels, internal_format, width, height, depth);
3378 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage3D");
3381 TCU_FAIL("Invliad enum");
3386 /** Attach buffer as source of texture buffer data
3388 * @param gl GL functions
3389 * @param internal_format Internal format of texture
3390 * @param buffer_id Id of buffer that will be used as data source
3392 void Texture::TexBuffer(const Functions& gl, GLenum internal_format, GLuint& buffer_id)
3394 gl.texBuffer(GL_TEXTURE_BUFFER, internal_format, buffer_id);
3395 GLU_EXPECT_NO_ERROR(gl.getError(), "TexBuffer");
3398 /** Update contents of texture
3400 * @param gl GL functions
3401 * @param tex_type Type of texture
3402 * @param width Width of texture
3403 * @param height Height of texture
3404 * @param format Format of data
3405 * @param type Type of data
3406 * @param data Buffer with image data
3408 void Texture::Update(const Functions& gl, TYPES tex_type, GLuint width, GLuint height, GLuint depth, GLenum format,
3409 GLenum type, GLvoid* data)
3411 static const GLuint level = 0;
3413 GLenum target = GetTargetGLenum(tex_type);
3418 gl.texSubImage1D(target, level, 0 /* x */, width, format, type, data);
3419 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage1D");
3424 gl.texSubImage2D(target, level, 0 /* x */, 0 /* y */, width, height, format, type, data);
3425 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2D");
3428 gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, level, 0 /* x */, 0 /* y */, width, height, format, type,
3430 gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, level, 0 /* x */, 0 /* y */, width, height, format, type,
3432 gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, level, 0 /* x */, 0 /* y */, width, height, format, type,
3434 gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, level, 0 /* x */, 0 /* y */, width, height, format, type,
3436 gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, level, 0 /* x */, 0 /* y */, width, height, format, type,
3438 gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, level, 0 /* x */, 0 /* y */, width, height, format, type,
3440 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2D");
3444 gl.texSubImage3D(target, level, 0 /* x */, 0 /* y */, 0 /* z */, width, height, depth, format, type, data);
3445 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage3D");
3448 TCU_FAIL("Invliad enum");
3453 /** Get target for given texture type
3455 * @param type Type of texture
3459 GLenum Texture::GetTargetGLenum(TYPES type)
3466 result = GL_TEXTURE_BUFFER;
3469 result = GL_TEXTURE_2D;
3472 result = GL_TEXTURE_RECTANGLE;
3475 result = GL_TEXTURE_2D_ARRAY;
3478 result = GL_TEXTURE_3D;
3481 result = GL_TEXTURE_CUBE_MAP;
3484 result = GL_TEXTURE_1D;
3487 result = GL_TEXTURE_1D_ARRAY;
3494 /* VertexArray constants */
3495 const GLuint VertexArray::m_invalid_id = -1;
3499 * @param context CTS context.
3501 VertexArray::VertexArray(deqp::Context& context) : m_id(m_invalid_id), m_context(context)
3508 VertexArray::~VertexArray()
3513 /** Initialize vertex array instance
3516 void VertexArray::Init()
3518 /* Delete previous instance */
3521 const Functions& gl = m_context.getRenderContext().getFunctions();
3526 /** Release vertex array object instance
3529 void VertexArray::Release()
3531 if (m_invalid_id != m_id)
3533 const Functions& gl = m_context.getRenderContext().getFunctions();
3535 gl.deleteVertexArrays(1, &m_id);
3537 m_id = m_invalid_id;
3541 /** Set attribute in VAO
3543 * @param index Index of attribute
3544 * @param type Type of attribute
3545 * @param n_array_elements Arary length
3546 * @param normalized Selectis if values should be normalized
3547 * @param stride Stride
3548 * @param pointer Pointer to data, or offset in buffer
3550 void VertexArray::Attribute(GLuint index, const Type& type, GLuint n_array_elements, GLboolean normalized,
3551 GLsizei stride, const GLvoid* pointer)
3553 const Functions& gl = m_context.getRenderContext().getFunctions();
3555 AttribPointer(gl, index, type, n_array_elements, normalized, stride, pointer);
3556 Enable(gl, index, type, n_array_elements);
3559 /** Binds Vertex array object
3562 void VertexArray::Bind()
3564 const Functions& gl = m_context.getRenderContext().getFunctions();
3569 /** Set attribute in VAO
3571 * @param gl Functions
3572 * @param index Index of attribute
3573 * @param type Type of attribute
3574 * @param n_array_elements Arary length
3575 * @param normalized Selectis if values should be normalized
3576 * @param stride Stride
3577 * @param pointer Pointer to data, or offset in buffer
3579 void VertexArray::AttribPointer(const Functions& gl, GLuint index, const Type& type, GLuint n_array_elements,
3580 GLboolean normalized, GLsizei stride, const GLvoid* pointer)
3582 const GLuint basic_type_size = Type::GetTypeSize(type.m_basic_type);
3583 const GLint size = (GLint)type.m_n_rows;
3584 const GLuint column_size = (GLuint)size * basic_type_size;
3585 const GLenum gl_type = Type::GetTypeGLenum(type.m_basic_type);
3589 /* If attribute is not an array */
3590 if (0 == n_array_elements)
3592 n_array_elements = 1;
3595 /* For each element in array */
3596 for (GLuint element = 0; element < n_array_elements; ++element)
3598 /* For each column in matrix */
3599 for (GLuint column = 1; column <= type.m_n_columns; ++column)
3601 /* Calculate offset */
3602 const GLvoid* ptr = (GLubyte*)pointer + offset;
3604 /* Set up attribute */
3605 switch (type.m_basic_type)
3608 gl.vertexAttribPointer(index, size, gl_type, normalized, stride, ptr);
3609 GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttribPointer");
3613 gl.vertexAttribIPointer(index, size, gl_type, stride, ptr);
3614 GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttribIPointer");
3617 gl.vertexAttribLPointer(index, size, gl_type, stride, ptr);
3618 GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttribLPointer");
3621 TCU_FAIL("Invalid enum");
3625 offset += column_size;
3631 /** Binds Vertex array object
3633 * @param gl GL functions
3634 * @param id ID of vertex array object
3636 void VertexArray::Bind(const glw::Functions& gl, glw::GLuint id)
3638 gl.bindVertexArray(id);
3639 GLU_EXPECT_NO_ERROR(gl.getError(), "BindVertexArray");
3642 /** Disable attribute in VAO
3644 * @param gl Functions
3645 * @param index Index of attribute
3646 * @param type Type of attribute
3647 * @param n_array_elements Arary length
3649 void VertexArray::Disable(const Functions& gl, GLuint index, const Type& type, GLuint n_array_elements)
3651 /* If attribute is not an array */
3652 if (0 == n_array_elements)
3654 n_array_elements = 1;
3657 /* For each element in array */
3658 for (GLuint element = 0; element < n_array_elements; ++element)
3660 /* For each column in matrix */
3661 for (GLuint column = 1; column <= type.m_n_columns; ++column)
3663 /* Enable attribute array */
3664 gl.disableVertexAttribArray(index);
3665 GLU_EXPECT_NO_ERROR(gl.getError(), "DisableVertexAttribArray");
3673 /** Set divisor for attribute
3675 * @param gl Functions
3676 * @param index Index of attribute
3677 * @param divisor New divisor value
3679 void VertexArray::Divisor(const Functions& gl, GLuint index, GLuint divisor)
3681 gl.vertexAttribDivisor(index, divisor);
3682 GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttribDivisor");
3685 /** Enables attribute in VAO
3687 * @param gl Functions
3688 * @param index Index of attribute
3689 * @param type Type of attribute
3690 * @param n_array_elements Arary length
3692 void VertexArray::Enable(const Functions& gl, GLuint index, const Type& type, GLuint n_array_elements)
3694 /* If attribute is not an array */
3695 if (0 == n_array_elements)
3697 n_array_elements = 1;
3700 /* For each element in array */
3701 for (GLuint element = 0; element < n_array_elements; ++element)
3703 /* For each column in matrix */
3704 for (GLuint column = 1; column <= type.m_n_columns; ++column)
3706 /* Enable attribute array */
3707 gl.enableVertexAttribArray(index);
3708 GLU_EXPECT_NO_ERROR(gl.getError(), "EnableVertexAttribArray");
3716 /** Generates Vertex array object
3718 * @param gl GL functions
3719 * @param out_id ID of vertex array object
3721 void VertexArray::Generate(const glw::Functions& gl, glw::GLuint& out_id)
3723 GLuint id = m_invalid_id;
3725 gl.genVertexArrays(1, &id);
3726 GLU_EXPECT_NO_ERROR(gl.getError(), "GenVertexArrays");
3728 if (m_invalid_id == id)
3730 TCU_FAIL("Invalid id");
3736 /* Constatns used by Variable */
3737 const GLint Variable::m_automatic_location = -1;
3739 /** Copy constructor
3742 Variable::Variable(const Variable& var)
3743 : m_data(var.m_data)
3744 , m_data_size(var.m_data_size)
3745 , m_descriptor(var.m_descriptor.m_name.c_str(), var.m_descriptor.m_qualifiers.c_str(),
3746 var.m_descriptor.m_expected_component, var.m_descriptor.m_expected_location,
3747 var.m_descriptor.m_builtin, var.m_descriptor.m_normalized, var.m_descriptor.m_n_array_elements,
3748 var.m_descriptor.m_expected_stride_of_element, var.m_descriptor.m_offset)
3749 , m_storage(var.m_storage)
3751 m_descriptor.m_type = var.m_descriptor.m_type;
3753 if (BUILTIN != var.m_descriptor.m_type)
3755 m_descriptor.m_interface = var.m_descriptor.m_interface;
3759 /** Get code that defines variable
3761 * @param flavour Provides info if variable is array or not
3763 * @return String with code
3765 std::string Variable::GetDefinition(FLAVOUR flavour) const
3767 return m_descriptor.GetDefinition(flavour, m_storage);
3770 /** Calcualtes stride of variable
3772 * @return Calculated value
3774 GLuint Variable::GetStride() const
3776 GLint variable_stride = 0;
3778 if (0 == m_descriptor.m_n_array_elements)
3780 variable_stride = m_descriptor.m_expected_stride_of_element;
3784 variable_stride = m_descriptor.m_expected_stride_of_element * m_descriptor.m_n_array_elements;
3787 return variable_stride;
3790 /** Check if variable is block
3792 * @return true if variable type is block, false otherwise
3794 bool Variable::IsBlock() const
3796 if (BUILTIN == m_descriptor.m_type)
3801 const Interface* interface = m_descriptor.m_interface;
3804 TCU_FAIL("Nullptr");
3807 return (Interface::BLOCK == interface->m_type);
3810 /** Check if variable is struct
3812 * @return true if variable type is struct, false otherwise
3814 bool Variable::IsStruct() const
3816 if (BUILTIN == m_descriptor.m_type)
3821 const Interface* interface = m_descriptor.m_interface;
3824 TCU_FAIL("Nullptr");
3827 return (Interface::STRUCT == interface->m_type);
3829 /** Get code that reference variable
3831 * @param parent_name Name of parent
3832 * @param variable Descriptor of variable
3833 * @param flavour Provides info about how variable should be referenced
3834 * @param array_index Index of array, ignored when variable is not array
3836 * @return String with code
3838 std::string Variable::GetReference(const std::string& parent_name, const Descriptor& variable, FLAVOUR flavour,
3844 if (false == parent_name.empty())
3848 name.append(variable.m_name);
3852 name = variable.m_name;
3858 case Utils::Variable::BASIC:
3861 case Utils::Variable::ARRAY:
3865 case Utils::Variable::INDEXED_BY_INVOCATION_ID:
3866 name.append("[gl_InvocationID]");
3870 /* Assumption that both variables have same lengths */
3871 if (0 != variable.m_n_array_elements)
3874 sprintf(buffer, "%d", array_index);
3876 name.append(buffer);
3883 /** Get "flavour" of varying
3885 * @param stage Stage of shader
3886 * @param direction Selects if varying is in or out
3890 Variable::FLAVOUR Variable::GetFlavour(Shader::STAGES stage, VARYING_DIRECTION direction)
3892 FLAVOUR result = BASIC;
3896 case Shader::GEOMETRY:
3897 case Shader::TESS_EVAL:
3898 if (INPUT == direction)
3903 case Shader::TESS_CTRL:
3904 result = INDEXED_BY_INVOCATION_ID;
3913 /** Constructor, for built-in types
3916 * @param qualifiers Qualifiers
3917 * @param expected_component Expected component of variable
3918 * @param expected_location Expected location
3920 * @param normalized Selects if data should be normalized
3921 * @param n_array_elements Length of array
3922 * @param expected_stride_of_element Expected stride of element
3923 * @param offset Offset
3925 Variable::Descriptor::Descriptor(const GLchar* name, const GLchar* qualifiers, GLint expected_component,
3926 GLint expected_location, const Type& type, GLboolean normalized,
3927 GLuint n_array_elements, GLint expected_stride_of_element, GLuint offset)
3928 : m_expected_component(expected_component)
3929 , m_expected_location(expected_location)
3930 , m_expected_stride_of_element(expected_stride_of_element)
3931 , m_n_array_elements(n_array_elements)
3933 , m_normalized(normalized)
3935 , m_qualifiers(qualifiers)
3941 /** Constructor, for interface types
3944 * @param qualifiers Qualifiers
3945 * @param expected_component Expected component of variable
3946 * @param expected_location Expected location
3947 * @param interface Interface of variable
3948 * @param n_array_elements Length of array
3949 * @param expected_stride_of_element Expected stride of element
3950 * @param offset Offset
3952 Variable::Descriptor::Descriptor(const GLchar* name, const GLchar* qualifiers, GLint expected_componenet,
3953 GLint expected_location, Interface* interface, GLuint n_array_elements,
3954 GLint expected_stride_of_element, GLuint offset)
3955 : m_expected_component(expected_componenet)
3956 , m_expected_location(expected_location)
3957 , m_expected_stride_of_element(expected_stride_of_element)
3958 , m_n_array_elements(n_array_elements)
3960 , m_normalized(GL_FALSE)
3962 , m_qualifiers(qualifiers)
3964 , m_interface(interface)
3968 /** Get definition of variable
3970 * @param flavour Flavour of variable
3971 * @param storage Storage used for variable
3973 * @return code with defintion
3975 std::string Variable::Descriptor::GetDefinition(FLAVOUR flavour, STORAGE storage) const
3977 static const GLchar* basic_template = "QUALIFIERS STORAGETYPE NAMEARRAY;";
3978 static const GLchar* array_template = "QUALIFIERS STORAGETYPE NAME[]ARRAY;";
3979 const GLchar* storage_str = 0;
3981 std::string definition;
3982 size_t position = 0;
3984 /* Select definition template */
3988 definition = basic_template;
3991 case INDEXED_BY_INVOCATION_ID:
3992 definition = array_template;
3995 TCU_FAIL("Invliad enum");
3999 if (BUILTIN != m_type)
4001 if (0 == m_interface)
4003 TCU_FAIL("Nullptr");
4008 if (true == m_qualifiers.empty())
4010 replaceToken("QUALIFIERS ", position, "", definition);
4014 replaceToken("QUALIFIERS", position, m_qualifiers.c_str(), definition);
4017 // According to spec: integer or unsigned integer type must always be declared with flat qualifier
4018 bool flat_qualifier = false;
4019 if (m_type != BUILTIN && m_interface != NULL)
4021 if (m_interface->m_members[0].m_builtin.m_basic_type == Utils::Type::Int ||
4022 m_interface->m_members[0].m_builtin.m_basic_type == Utils::Type::Uint)
4024 flat_qualifier = true;
4031 storage_str = flat_qualifier ? "flat in " : "in ";
4033 case VARYING_OUTPUT:
4034 storage_str = "out ";
4037 storage_str = "uniform ";
4040 storage_str = "buffer ";
4046 TCU_FAIL("Invalid enum");
4050 replaceToken("STORAGE", position, storage_str, definition);
4053 if (BUILTIN == m_type)
4055 replaceToken("TYPE", position, m_builtin.GetGLSLTypeName(), definition);
4059 if (Interface::STRUCT == m_interface->m_type)
4061 replaceToken("TYPE", position, m_interface->m_name.c_str(), definition);
4065 const std::string& block_definition = m_interface->GetDefinition();
4067 replaceToken("TYPE", position, block_definition.c_str(), definition);
4072 replaceToken("NAME", position, m_name.c_str(), definition);
4075 if (0 == m_n_array_elements)
4077 replaceToken("ARRAY", position, "", definition);
4082 sprintf(buffer, "[%d]", m_n_array_elements);
4084 replaceToken("ARRAY", position, buffer, definition);
4091 /** Get definitions for variables collected in vector
4093 * @param vector Collection of variables
4094 * @param flavour Flavour of variables
4096 * @return Code with definitions
4098 std::string GetDefinitions(const Variable::PtrVector& vector, Variable::FLAVOUR flavour)
4100 std::string list = Utils::g_list;
4101 size_t position = 0;
4103 for (GLuint i = 0; i < vector.size(); ++i)
4105 Utils::insertElementOfList(vector[i]->GetDefinition(flavour).c_str(), "\n", position, list);
4108 Utils::endList("", position, list);
4113 /** Get definitions for interfaces collected in vector
4115 * @param vector Collection of interfaces
4117 * @return Code with definitions
4119 std::string GetDefinitions(const Interface::PtrVector& vector)
4121 std::string list = Utils::g_list;
4122 size_t position = 0;
4124 for (GLuint i = 0; i < vector.size(); ++i)
4126 Utils::insertElementOfList(vector[i]->GetDefinition().c_str(), "\n", position, list);
4129 Utils::endList("", position, list);
4137 * @param type Type of interface
4139 Interface::Interface(const GLchar* name, Interface::TYPE type) : m_name(name), m_type(type)
4143 /** Adds member to interface
4145 * @param member Descriptor of new member
4147 * @return Pointer to just created member
4149 Variable::Descriptor* Interface::AddMember(const Variable::Descriptor& member)
4151 m_members.push_back(member);
4153 return &m_members.back();
4156 /** Get definition of interface
4158 * @param Code with definition
4160 std::string Interface::GetDefinition() const
4162 std::string definition;
4163 size_t position = 0;
4165 const GLchar* member_list = " MEMBER_DEFINITION\nMEMBER_LIST";
4167 if (STRUCT == m_type)
4169 definition = "struct NAME {\nMEMBER_LIST};";
4173 definition = "NAME {\nMEMBER_LIST}";
4177 replaceToken("NAME", position, m_name.c_str(), definition);
4180 for (GLuint i = 0; i < m_members.size(); ++i)
4182 const size_t start_position = position;
4183 const std::string& member_definition = m_members[i].GetDefinition(Variable::BASIC, Variable::MEMBER);
4186 replaceToken("MEMBER_LIST", position, member_list, definition);
4188 /* Move back position */
4189 position = start_position;
4191 /* Member definition */
4192 replaceToken("MEMBER_DEFINITION", position, member_definition.c_str(), definition);
4195 /* Remove last member list */
4196 replaceToken("MEMBER_LIST", position, "", definition);
4202 /** Adds member of built-in type to interface
4205 * @param qualifiers Qualifiers
4206 * @param expected_component Expected component of variable
4207 * @param expected_location Expected location
4209 * @param normalized Selects if data should be normalized
4210 * @param n_array_elements Length of array
4211 * @param expected_stride_of_element Expected stride of element
4212 * @param offset Offset
4214 * @return Pointer to just created member
4216 Variable::Descriptor* Interface::Member(const GLchar* name, const GLchar* qualifiers, GLint expected_component,
4217 GLint expected_location, const Type& type, GLboolean normalized,
4218 GLuint n_array_elements, GLint expected_stride_of_element, GLuint offset)
4220 return AddMember(Variable::Descriptor(name, qualifiers, expected_component, expected_location, type, normalized,
4221 n_array_elements, expected_stride_of_element, offset));
4224 /** Adds member of interface type to interface
4227 * @param qualifiers Qualifiers
4228 * @param expected_component Expected component of variable
4229 * @param expected_location Expected location
4231 * @param normalized Selects if data should be normalized
4232 * @param n_array_elements Length of array
4233 * @param expected_stride_of_element Expected stride of element
4234 * @param offset Offset
4236 * @return Pointer to just created member
4238 Variable::Descriptor* Interface::Member(const GLchar* name, const GLchar* qualifiers, GLint expected_component,
4239 GLint expected_location, Interface* nterface, GLuint n_array_elements,
4240 GLint expected_stride_of_element, GLuint offset)
4242 return AddMember(Variable::Descriptor(name, qualifiers, expected_component, expected_location, nterface,
4243 n_array_elements, expected_stride_of_element, offset));
4246 /** Clears contents of vector of pointers
4248 * @tparam T Type of elements
4250 * @param vector Collection to be cleared
4252 template <typename T>
4253 void clearPtrVector(std::vector<T*>& vector)
4255 for (size_t i = 0; i < vector.size(); ++i)
4272 * @param stage Stage described by that interface
4274 ShaderInterface::ShaderInterface(Shader::STAGES stage) : m_stage(stage)
4276 /* Nothing to be done */
4279 /** Get definitions of globals
4281 * @return Code with definitions
4283 std::string ShaderInterface::GetDefinitionsGlobals() const
4288 /** Get definitions of inputs
4290 * @return Code with definitions
4292 std::string ShaderInterface::GetDefinitionsInputs() const
4294 Variable::FLAVOUR flavour = Variable::GetFlavour(m_stage, Variable::INPUT);
4296 return GetDefinitions(m_inputs, flavour);
4299 /** Get definitions of outputs
4301 * @return Code with definitions
4303 std::string ShaderInterface::GetDefinitionsOutputs() const
4305 Variable::FLAVOUR flavour = Variable::GetFlavour(m_stage, Variable::OUTPUT);
4307 return GetDefinitions(m_outputs, flavour);
4310 /** Get definitions of buffers
4312 * @return Code with definitions
4314 std::string ShaderInterface::GetDefinitionsSSBs() const
4316 return GetDefinitions(m_ssb_blocks, Variable::BASIC);
4319 /** Get definitions of uniforms
4321 * @return Code with definitions
4323 std::string ShaderInterface::GetDefinitionsUniforms() const
4325 return GetDefinitions(m_uniforms, Variable::BASIC);
4330 * @param in Input variable
4331 * @param out Output variable
4333 VaryingConnection::VaryingConnection(Variable* in, Variable* out) : m_in(in), m_out(out)
4335 /* NBothing to be done here */
4338 /** Adds new varying connection to given stage
4340 * @param stage Shader stage
4341 * @param in In varying
4342 * @param out Out varying
4344 void VaryingPassthrough::Add(Shader::STAGES stage, Variable* in, Variable* out)
4346 VaryingConnection::Vector& vector = Get(stage);
4348 vector.push_back(VaryingConnection(in, out));
4351 /** Get all passthrough connections for given stage
4353 * @param stage Shader stage
4355 * @return Vector of connections
4357 VaryingConnection::Vector& VaryingPassthrough::Get(Shader::STAGES stage)
4359 VaryingConnection::Vector* result = 0;
4363 case Shader::FRAGMENT:
4364 result = &m_fragment;
4366 case Shader::GEOMETRY:
4367 result = &m_geometry;
4369 case Shader::TESS_CTRL:
4370 result = &m_tess_ctrl;
4372 case Shader::TESS_EVAL:
4373 result = &m_tess_eval;
4375 case Shader::VERTEX:
4379 TCU_FAIL("Invalid enum");
4388 ProgramInterface::ProgramInterface()
4389 : m_compute(Shader::COMPUTE)
4390 , m_vertex(Shader::VERTEX)
4391 , m_tess_ctrl(Shader::TESS_CTRL)
4392 , m_tess_eval(Shader::TESS_EVAL)
4393 , m_geometry(Shader::GEOMETRY)
4394 , m_fragment(Shader::FRAGMENT)
4401 ProgramInterface::~ProgramInterface()
4403 clearPtrVector(m_blocks);
4404 clearPtrVector(m_structures);
4407 /** Adds new interface
4412 * @return Pointer to created interface
4414 Interface* ProgramInterface::AddInterface(const GLchar* name, Interface::TYPE type)
4416 Interface* interface = 0;
4418 if (Interface::STRUCT == type)
4420 interface = new Interface(name, type);
4422 m_structures.push_back(interface);
4426 interface = new Interface(name, type);
4428 m_blocks.push_back(interface);
4434 /** Adds new block interface
4438 * @return Pointer to created interface
4440 Interface* ProgramInterface::Block(const GLchar* name)
4442 return AddInterface(name, Interface::BLOCK);
4445 /** Get interface of given shader stage
4447 * @param stage Shader stage
4449 * @return Reference to stage interface
4451 ShaderInterface& ProgramInterface::GetShaderInterface(Shader::STAGES stage)
4453 ShaderInterface* interface = 0;
4457 case Shader::COMPUTE:
4458 interface = &m_compute;
4460 case Shader::FRAGMENT:
4461 interface = &m_fragment;
4463 case Shader::GEOMETRY:
4464 interface = &m_geometry;
4466 case Shader::TESS_CTRL:
4467 interface = &m_tess_ctrl;
4469 case Shader::TESS_EVAL:
4470 interface = &m_tess_eval;
4472 case Shader::VERTEX:
4473 interface = &m_vertex;
4476 TCU_FAIL("Invalid enum");
4482 /** Get interface of given shader stage
4484 * @param stage Shader stage
4486 * @return Reference to stage interface
4488 const ShaderInterface& ProgramInterface::GetShaderInterface(Shader::STAGES stage) const
4490 const ShaderInterface* interface = 0;
4494 case Shader::COMPUTE:
4495 interface = &m_compute;
4497 case Shader::FRAGMENT:
4498 interface = &m_fragment;
4500 case Shader::GEOMETRY:
4501 interface = &m_geometry;
4503 case Shader::TESS_CTRL:
4504 interface = &m_tess_ctrl;
4506 case Shader::TESS_EVAL:
4507 interface = &m_tess_eval;
4509 case Shader::VERTEX:
4510 interface = &m_vertex;
4513 TCU_FAIL("Invalid enum");
4519 /** Clone interface of Vertex shader stage to other stages
4520 * It creates matching inputs, outputs, uniforms and buffers in other stages.
4521 * There are no additional outputs for FRAGMENT shader generated.
4523 * @param varying_passthrough Collection of varyings connections
4525 void ProgramInterface::CloneVertexInterface(VaryingPassthrough& varying_passthrough)
4527 /* VS outputs >> TCS inputs >> TCS outputs >> .. >> FS inputs */
4528 for (size_t i = 0; i < m_vertex.m_outputs.size(); ++i)
4530 const Variable& vs_var = *m_vertex.m_outputs[i];
4531 const GLchar* prefix = GetStagePrefix(Shader::VERTEX, vs_var.m_storage);
4533 cloneVariableForStage(vs_var, Shader::TESS_CTRL, prefix, varying_passthrough);
4534 cloneVariableForStage(vs_var, Shader::TESS_EVAL, prefix, varying_passthrough);
4535 cloneVariableForStage(vs_var, Shader::GEOMETRY, prefix, varying_passthrough);
4536 cloneVariableForStage(vs_var, Shader::FRAGMENT, prefix, varying_passthrough);
4539 /* Copy uniforms from VS to other stages */
4540 for (size_t i = 0; i < m_vertex.m_uniforms.size(); ++i)
4542 Variable& vs_var = *m_vertex.m_uniforms[i];
4543 const GLchar* prefix = GetStagePrefix(Shader::VERTEX, vs_var.m_storage);
4545 cloneVariableForStage(vs_var, Shader::COMPUTE, prefix, varying_passthrough);
4546 cloneVariableForStage(vs_var, Shader::TESS_CTRL, prefix, varying_passthrough);
4547 cloneVariableForStage(vs_var, Shader::TESS_EVAL, prefix, varying_passthrough);
4548 cloneVariableForStage(vs_var, Shader::GEOMETRY, prefix, varying_passthrough);
4549 cloneVariableForStage(vs_var, Shader::FRAGMENT, prefix, varying_passthrough);
4551 /* Uniform blocks needs unique binding */
4552 if (true == vs_var.IsBlock())
4554 replaceBinding(vs_var, Shader::VERTEX);
4558 /* Copy SSBs from VS to other stages */
4559 for (size_t i = 0; i < m_vertex.m_ssb_blocks.size(); ++i)
4561 Variable& vs_var = *m_vertex.m_ssb_blocks[i];
4562 const GLchar* prefix = GetStagePrefix(Shader::VERTEX, vs_var.m_storage);
4564 cloneVariableForStage(vs_var, Shader::COMPUTE, prefix, varying_passthrough);
4565 cloneVariableForStage(vs_var, Shader::TESS_CTRL, prefix, varying_passthrough);
4566 cloneVariableForStage(vs_var, Shader::TESS_EVAL, prefix, varying_passthrough);
4567 cloneVariableForStage(vs_var, Shader::GEOMETRY, prefix, varying_passthrough);
4568 cloneVariableForStage(vs_var, Shader::FRAGMENT, prefix, varying_passthrough);
4570 /* SSBs blocks needs unique binding */
4571 if (true == vs_var.IsBlock())
4573 replaceBinding(vs_var, Shader::VERTEX);
4577 m_compute.m_globals = m_vertex.m_globals;
4578 m_fragment.m_globals = m_vertex.m_globals;
4579 m_geometry.m_globals = m_vertex.m_globals;
4580 m_tess_ctrl.m_globals = m_vertex.m_globals;
4581 m_tess_eval.m_globals = m_vertex.m_globals;
4584 /** Clone variable for specific stage
4586 * @param variable Variable
4587 * @param stage Requested stage
4588 * @param prefix Prefix used in variable name that is specific for original stage
4589 * @param varying_passthrough Collection of varyings connections
4591 void ProgramInterface::cloneVariableForStage(const Variable& variable, Shader::STAGES stage, const GLchar* prefix,
4592 VaryingPassthrough& varying_passthrough)
4594 switch (variable.m_storage)
4596 case Variable::VARYING_OUTPUT:
4598 Variable* in = cloneVariableForStage(variable, stage, Variable::VARYING_INPUT, prefix);
4600 if (Shader::FRAGMENT != stage)
4602 Variable* out = cloneVariableForStage(variable, stage, Variable::VARYING_OUTPUT, prefix);
4603 varying_passthrough.Add(stage, in, out);
4607 case Variable::UNIFORM:
4609 cloneVariableForStage(variable, stage, variable.m_storage, prefix);
4612 TCU_FAIL("Invalid enum");
4617 /** Clone variable for specific stage
4619 * @param variable Variable
4620 * @param stage Requested stage
4621 * @param storage Storage used by variable
4622 * @param prefix Prefix used in variable name that is specific for original stage
4624 * @return New variable
4626 Variable* ProgramInterface::cloneVariableForStage(const Variable& variable, Shader::STAGES stage,
4627 Variable::STORAGE storage, const GLchar* prefix)
4629 /* Initialize with original variable */
4630 Variable* var = new Variable(variable);
4633 TCU_FAIL("Memory allocation");
4636 /* Set up storage */
4637 var->m_storage = storage;
4640 std::string name = variable.m_descriptor.m_name;
4642 /* Prefix name with stage ID, empty means default block */
4643 if (false == name.empty())
4645 size_t position = 0;
4646 const GLchar* stage_prefix = GetStagePrefix(stage, storage);
4647 Utils::replaceToken(prefix, position, stage_prefix, name);
4649 var->m_descriptor.m_name = name;
4652 const bool is_block = variable.IsBlock();
4653 if (true == is_block)
4655 const Interface* interface = variable.m_descriptor.m_interface;
4657 Interface* block = CloneBlockForStage(*interface, stage, storage, prefix);
4659 var->m_descriptor.m_interface = block;
4662 /* Store variable */
4663 ShaderInterface& si = GetShaderInterface(stage);
4664 Variable* result = 0;
4668 case Variable::VARYING_INPUT:
4669 si.m_inputs.push_back(var);
4670 result = si.m_inputs.back();
4672 case Variable::VARYING_OUTPUT:
4673 si.m_outputs.push_back(var);
4674 result = si.m_outputs.back();
4676 case Variable::UNIFORM:
4677 /* Uniform blocks needs unique binding */
4678 if (true == is_block)
4680 replaceBinding(*var, stage);
4683 si.m_uniforms.push_back(var);
4684 result = si.m_uniforms.back();
4687 /* SSBs needs unique binding */
4688 if (true == is_block)
4690 replaceBinding(*var, stage);
4693 si.m_ssb_blocks.push_back(var);
4694 result = si.m_ssb_blocks.back();
4697 TCU_FAIL("Invalid enum");
4704 /** clone block to specific stage
4706 * @param block Block to be copied
4707 * @param stage Specific stage
4708 * @param storage Storage used by block
4709 * @param prefix Prefix used in block name
4711 * @return New interface
4713 Interface* ProgramInterface::CloneBlockForStage(const Interface& block, Shader::STAGES stage, Variable::STORAGE storage,
4714 const GLchar* prefix)
4717 std::string name = block.m_name;
4719 /* Prefix name with stage ID */
4720 size_t position = 0;
4721 const GLchar* stage_prefix = GetStagePrefix(stage, storage);
4722 Utils::replaceToken(prefix, position, stage_prefix, name);
4724 Interface* ptr = GetBlock(name.c_str());
4728 ptr = AddInterface(name.c_str(), Interface::BLOCK);
4731 ptr->m_members = block.m_members;
4736 /** Get stage specific prefix used in names
4738 * @param stage Stage
4739 * @param storage Storage class
4743 const GLchar* ProgramInterface::GetStagePrefix(Shader::STAGES stage, Variable::STORAGE storage)
4745 static const GLchar* lut[Shader::STAGE_MAX][Variable::STORAGE_MAX] = {
4746 /* IN OUT UNIFORM SSB MEMBER */
4747 /* CS */ { 0, 0, "cs_uni_", "cs_buf_", "" },
4748 /* VS */ { "in_vs_", "vs_tcs_", "vs_uni_", "vs_buf_", "" },
4749 /* TCS */ { "vs_tcs_", "tcs_tes_", "tcs_uni_", "tcs_buf_", "" },
4750 /* TES */ { "tcs_tes_", "tes_gs_", "tes_uni_", "tes_buf_", "" },
4751 /* GS */ { "tes_gs_", "gs_fs_", "gs_uni_", "gs_buf_", "" },
4752 /* FS */ { "gs_fs_", "fs_out_", "fs_uni_", "fs_buf_", "" },
4755 const GLchar* result = 0;
4757 result = lut[stage][storage];
4762 /** Get definitions of all structures used in program interface
4764 * @return String with code
4766 std::string ProgramInterface::GetDefinitionsStructures() const
4768 return GetDefinitions(m_structures);
4771 /** Get interface code for stage
4773 * @param stage Specific stage
4775 * @return String with code
4777 std::string ProgramInterface::GetInterfaceForStage(Shader::STAGES stage) const
4779 size_t position = 0;
4780 std::string interface = "/* Globals */\n"
4783 "/* Structures */\n"
4798 const ShaderInterface& si = GetShaderInterface(stage);
4800 const std::string& structures = GetDefinitionsStructures();
4802 const std::string& globals = si.GetDefinitionsGlobals();
4803 const std::string& inputs = si.GetDefinitionsInputs();
4804 const std::string& outputs = si.GetDefinitionsOutputs();
4805 const std::string& uniforms = si.GetDefinitionsUniforms();
4806 const std::string& ssbs = si.GetDefinitionsSSBs();
4808 replaceToken("GLOBALS", position, globals.c_str(), interface);
4809 replaceToken("STRUCTURES", position, structures.c_str(), interface);
4810 replaceToken("UNIFORMS", position, uniforms.c_str(), interface);
4811 replaceToken("INPUTS", position, inputs.c_str(), interface);
4812 replaceToken("OUTPUTS", position, outputs.c_str(), interface);
4813 replaceToken("STORAGE", position, ssbs.c_str(), interface);
4818 /** Functional object used in find_if algorithm, in search for interface of given name
4821 struct matchInterfaceName
4823 matchInterfaceName(const GLchar* name) : m_name(name)
4827 bool operator()(const Interface* interface)
4829 return 0 == interface->m_name.compare(m_name);
4832 const GLchar* m_name;
4835 /** Finds interface of given name in given vector of interfaces
4837 * @param vector Collection of interfaces
4838 * @param name Requested name
4840 * @return Pointer to interface if available, 0 otherwise
4842 static Interface* findInterfaceByName(Interface::PtrVector& vector, const GLchar* name)
4844 Interface::PtrVector::iterator it = std::find_if(vector.begin(), vector.end(), matchInterfaceName(name));
4846 if (vector.end() != it)
4856 /** Search for block of given name
4858 * @param name Name of block
4860 * @return Pointer to block or 0
4862 Interface* ProgramInterface::GetBlock(const GLchar* name)
4864 return findInterfaceByName(m_blocks, name);
4867 /** Search for structure of given name
4869 * @param name Name of structure
4871 * @return Pointer to structure or 0
4873 Interface* ProgramInterface::GetStructure(const GLchar* name)
4875 return findInterfaceByName(m_structures, name);
4878 /** Adds new sturcture to interface
4880 * @param name Name of structure
4882 * @return Created structure
4884 Interface* ProgramInterface::Structure(const GLchar* name)
4886 return AddInterface(name, Interface::STRUCT);
4889 /** Replace "BINDING" token in qualifiers string to value specific for given stage
4891 * @param variable Variable to modify
4892 * @param stage Requested stage
4894 void ProgramInterface::replaceBinding(Variable& variable, Shader::STAGES stage)
4897 sprintf(binding, "%d", stage);
4898 replaceAllTokens("BINDING", binding, variable.m_descriptor.m_qualifiers);
4900 } /* Utils namespace */
4902 /** Debuging procedure. Logs parameters.
4904 * @param source As specified in GL spec.
4905 * @param type As specified in GL spec.
4906 * @param id As specified in GL spec.
4907 * @param severity As specified in GL spec.
4909 * @param message As specified in GL spec.
4910 * @param info Pointer to instance of Context used by test.
4912 void GLW_APIENTRY debug_proc(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei /* length */,
4913 const GLchar* message, void* info)
4915 deqp::Context* ctx = (deqp::Context*)info;
4917 const GLchar* source_str = "Unknown";
4918 const GLchar* type_str = "Unknown";
4919 const GLchar* severity_str = "Unknown";
4923 case GL_DEBUG_SOURCE_API:
4926 case GL_DEBUG_SOURCE_APPLICATION:
4929 case GL_DEBUG_SOURCE_OTHER:
4932 case GL_DEBUG_SOURCE_SHADER_COMPILER:
4935 case GL_DEBUG_SOURCE_THIRD_PARTY:
4938 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
4947 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
4948 type_str = "DEPRECATED_BEHAVIOR";
4950 case GL_DEBUG_TYPE_ERROR:
4953 case GL_DEBUG_TYPE_MARKER:
4954 type_str = "MARKER";
4956 case GL_DEBUG_TYPE_OTHER:
4959 case GL_DEBUG_TYPE_PERFORMANCE:
4960 type_str = "PERFORMANCE";
4962 case GL_DEBUG_TYPE_POP_GROUP:
4963 type_str = "POP_GROUP";
4965 case GL_DEBUG_TYPE_PORTABILITY:
4966 type_str = "PORTABILITY";
4968 case GL_DEBUG_TYPE_PUSH_GROUP:
4969 type_str = "PUSH_GROUP";
4971 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
4972 type_str = "UNDEFINED_BEHAVIOR";
4980 case GL_DEBUG_SEVERITY_HIGH:
4983 case GL_DEBUG_SEVERITY_LOW:
4986 case GL_DEBUG_SEVERITY_MEDIUM:
4989 case GL_DEBUG_SEVERITY_NOTIFICATION:
4996 ctx->getTestContext().getLog() << tcu::TestLog::Message << "DEBUG_INFO: " << std::setw(3) << source_str << "|"
4997 << severity_str << "|" << std::setw(18) << type_str << "|" << std::setw(12) << id
4998 << ": " << message << tcu::TestLog::EndMessage;
5003 * @param context Test context
5004 * @param test_name Test name
5005 * @param test_description Test description
5007 TestBase::TestBase(deqp::Context& context, const GLchar* test_name, const GLchar* test_description)
5008 : TestCase(context, test_name, test_description)
5010 /* Nothing to be done here */
5015 * @return tcu::TestNode::STOP otherwise
5017 tcu::TestNode::IterateResult TestBase::iterate()
5021 #if DEBUG_ENBALE_MESSAGE_CALLBACK
5022 const Functions& gl = m_context.getRenderContext().getFunctions();
5024 gl.debugMessageCallback(debug_proc, &m_context);
5025 GLU_EXPECT_NO_ERROR(gl.getError(), "DebugMessageCallback");
5026 #endif /* DEBUG_ENBALE_MESSAGE_CALLBACK */
5031 test_result = test();
5033 catch (std::exception& exc)
5035 TCU_FAIL(exc.what());
5039 if (true == test_result)
5041 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
5045 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
5049 return tcu::TestNode::STOP;
5052 /** Get last input location available for given type at specific stage
5054 * @param stage Shader stage
5055 * @param type Input type
5056 * @param array_length Length of input array
5058 * @return Last location index
5060 GLint TestBase::getLastInputLocation(Utils::Shader::STAGES stage, const Utils::Type& type, GLuint array_length)
5062 GLint divide = 4; /* 4 components per location */
5069 case Utils::Shader::FRAGMENT:
5070 pname = GL_MAX_FRAGMENT_INPUT_COMPONENTS;
5072 case Utils::Shader::GEOMETRY:
5073 pname = GL_MAX_GEOMETRY_INPUT_COMPONENTS;
5075 case Utils::Shader::TESS_CTRL:
5076 pname = GL_MAX_TESS_CONTROL_INPUT_COMPONENTS;
5078 case Utils::Shader::TESS_EVAL:
5079 pname = GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS;
5081 case Utils::Shader::VERTEX:
5082 pname = GL_MAX_VERTEX_ATTRIBS;
5086 TCU_FAIL("Invalid enum");
5090 /* Zero means no array, but 1 slot is required */
5091 if (0 == array_length)
5097 const Functions& gl = m_context.getRenderContext().getFunctions();
5099 gl.getIntegerv(pname, ¶m);
5100 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
5103 #if WRKARD_VARYINGLOCATIONSTEST
5105 const GLint n_avl_locations = 16;
5109 const GLint n_avl_locations = param / divide;
5113 const GLuint n_req_location = type.GetLocations() * array_length;
5115 return n_avl_locations - n_req_location; /* last is max - 1 */
5118 /** Get last input location available for given type at specific stage
5120 * @param stage Shader stage
5121 * @param type Input type
5122 * @param array_length Length of input array
5124 * @return Last location index
5126 GLint TestBase::getLastOutputLocation(Utils::Shader::STAGES stage, const Utils::Type& type, GLuint array_length)
5134 case Utils::Shader::GEOMETRY:
5135 pname = GL_MAX_GEOMETRY_OUTPUT_COMPONENTS;
5137 case Utils::Shader::TESS_CTRL:
5138 pname = GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS;
5140 case Utils::Shader::TESS_EVAL:
5141 pname = GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS;
5143 case Utils::Shader::VERTEX:
5144 pname = GL_MAX_VERTEX_OUTPUT_COMPONENTS;
5147 TCU_FAIL("Invalid enum");
5151 /* Zero means no array, but 1 slot is required */
5152 if (0 == array_length)
5158 const Functions& gl = m_context.getRenderContext().getFunctions();
5160 gl.getIntegerv(pname, ¶m);
5161 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
5164 #if WRKARD_VARYINGLOCATIONSTEST
5166 const GLint n_avl_locations = 16;
5170 const GLint n_avl_locations = param / 4; /* 4 components per location */
5174 const GLuint n_req_location = type.GetLocations() * array_length;
5176 return n_avl_locations - n_req_location; /* last is max - 1 */
5179 /** Basic implementation
5183 * @return Empty string
5185 std::string TestBase::getTestCaseName(GLuint /* test_case_index */)
5192 /** Basic implementation
5196 GLuint TestBase::getTestCaseNumber()
5201 /** Check if flat qualifier is required for given type, stage and storage
5203 * @param stage Shader stage
5204 * @param type Input type
5205 * @param storage Storage of variable
5207 * @return Last location index
5209 bool TestBase::isFlatRequired(Utils::Shader::STAGES stage, const Utils::Type& type,
5210 Utils::Variable::STORAGE storage) const
5212 /* Float types do not need flat at all */
5213 if (Utils::Type::Float == type.m_basic_type)
5218 /* Inputs to fragment shader */
5219 if ((Utils::Shader::FRAGMENT == stage) && (Utils::Variable::VARYING_INPUT == storage))
5224 /* Outputs from geometry shader */
5225 if ((Utils::Shader::FRAGMENT == stage) && (Utils::Variable::VARYING_OUTPUT == storage))
5233 /** Basic implementation of testInit method
5236 void TestBase::testInit()
5240 /** Calculate stride for interface
5242 * @param interface Interface
5244 * @return Calculated value
5246 GLuint TestBase::calculateStride(const Utils::Interface& interface) const
5248 const size_t n_members = interface.m_members.size();
5252 for (size_t i = 0; i < n_members; ++i)
5254 const Utils::Variable::Descriptor& member = interface.m_members[i];
5255 const GLuint member_offset = member.m_offset;
5256 const GLuint member_stride = member.m_expected_stride_of_element;
5257 const GLuint member_ends_at = member_offset + member_stride;
5259 stride = std::max(stride, member_ends_at);
5265 /** Generate data for interface. This routine is recursive
5267 * @param interface Interface
5268 * @param offset Offset in out_data
5269 * @param out_data Buffer to be filled
5271 void TestBase::generateData(const Utils::Interface& interface, GLuint offset, std::vector<GLubyte>& out_data) const
5273 const size_t n_members = interface.m_members.size();
5274 GLubyte* ptr = &out_data[offset];
5276 for (size_t i = 0; i < n_members; ++i)
5278 const Utils::Variable::Descriptor& member = interface.m_members[i];
5279 const GLuint member_offset = member.m_offset;
5280 const GLuint n_elements = (0 == member.m_n_array_elements) ? 1 : member.m_n_array_elements;
5282 for (GLuint element = 0; element < n_elements; ++element)
5284 const GLuint element_offset = element * member.m_expected_stride_of_element;
5285 const GLuint data_offfset = member_offset + element_offset;
5287 if (Utils::Variable::BUILTIN == member.m_type)
5289 const std::vector<GLubyte>& data = member.m_builtin.GenerateData();
5291 memcpy(ptr + data_offfset, &data[0], data.size());
5295 generateData(*member.m_interface, offset + data_offfset, out_data);
5301 /** Get type at index
5303 * @param index Index of requested type
5307 Utils::Type TestBase::getType(GLuint index) const
5314 type = Utils::Type::_double;
5317 type = Utils::Type::dmat2;
5320 type = Utils::Type::dmat2x3;
5323 type = Utils::Type::dmat2x4;
5326 type = Utils::Type::dmat3;
5329 type = Utils::Type::dmat3x2;
5332 type = Utils::Type::dmat3x4;
5335 type = Utils::Type::dmat4;
5338 type = Utils::Type::dmat4x2;
5341 type = Utils::Type::dmat4x3;
5344 type = Utils::Type::dvec2;
5347 type = Utils::Type::dvec3;
5350 type = Utils::Type::dvec4;
5353 type = Utils::Type::_float;
5356 type = Utils::Type::mat2;
5359 type = Utils::Type::mat2x3;
5362 type = Utils::Type::mat2x4;
5365 type = Utils::Type::mat3;
5368 type = Utils::Type::mat3x2;
5371 type = Utils::Type::mat3x4;
5374 type = Utils::Type::mat4;
5377 type = Utils::Type::mat4x2;
5380 type = Utils::Type::mat4x3;
5383 type = Utils::Type::vec2;
5386 type = Utils::Type::vec3;
5389 type = Utils::Type::vec4;
5392 type = Utils::Type::_int;
5395 type = Utils::Type::ivec2;
5398 type = Utils::Type::ivec3;
5401 type = Utils::Type::ivec4;
5404 type = Utils::Type::uint;
5407 type = Utils::Type::uvec2;
5410 type = Utils::Type::uvec3;
5413 type = Utils::Type::uvec4;
5416 TCU_FAIL("invalid enum");
5422 /** Get name of type at index
5424 * @param index Index of type
5428 std::string TestBase::getTypeName(GLuint index) const
5430 std::string name = getType(index).GetGLSLTypeName();
5435 /** Get number of types
5439 glw::GLuint TestBase::getTypesNumber() const
5446 * @return true if test pass, false otherwise
5448 bool TestBase::test()
5451 GLuint n_test_cases = 0;
5456 /* GL entry points */
5457 const Functions& gl = m_context.getRenderContext().getFunctions();
5459 /* Tessellation patch set up */
5460 gl.patchParameteri(GL_PATCH_VERTICES, 1);
5461 GLU_EXPECT_NO_ERROR(gl.getError(), "PatchParameteri");
5463 /* Get number of test cases */
5464 n_test_cases = getTestCaseNumber();
5466 #if DEBUG_REPEAT_TEST_CASE
5470 GLuint test_case = DEBUG_REPEATED_TEST_CASE;
5472 #else /* DEBUG_REPEAT_TEST_CASE */
5474 for (GLuint test_case = 0; test_case < n_test_cases; ++test_case)
5477 #endif /* DEBUG_REPEAT_TEST_CASE */
5479 bool case_result = true;
5482 if (false == testCase(test_case))
5484 case_result = false;
5488 if (false == case_result)
5490 const std::string& test_case_name = getTestCaseName(test_case);
5492 if (false == test_case_name.empty())
5494 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Test case (" << test_case_name
5495 << ") failed." << tcu::TestLog::EndMessage;
5499 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Test case (" << test_case
5500 << ") failed." << tcu::TestLog::EndMessage;
5511 /* Constants used by BufferTestBase */
5512 const GLuint BufferTestBase::bufferDescriptor::m_non_indexed = -1;
5516 * @param context Test context
5517 * @param test_name Name of test
5518 * @param test_description Description of test
5520 BufferTestBase::BufferTestBase(deqp::Context& context, const GLchar* test_name, const GLchar* test_description)
5521 : TestBase(context, test_name, test_description)
5525 /** Execute drawArrays for single vertex
5531 bool BufferTestBase::executeDrawCall(bool tesEnabled, GLuint /* test_case_index */)
5533 const Functions& gl = m_context.getRenderContext().getFunctions();
5535 gl.disable(GL_RASTERIZER_DISCARD);
5536 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
5538 gl.beginTransformFeedback(GL_POINTS);
5539 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
5541 // Only TES is existed, glDrawArray can use the parameter GL_PATCHES
5542 if (tesEnabled == false)
5544 gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */);
5548 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
5551 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
5553 gl.endTransformFeedback();
5554 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
5559 /** Get descriptors of buffers necessary for test
5564 void BufferTestBase::getBufferDescriptors(glw::GLuint /* test_case_index */,
5565 bufferDescriptor::Vector& /* out_descriptors */)
5567 /* Nothhing to be done */
5570 /** Get list of names of varyings that will be registered with TransformFeedbackVaryings
5575 void BufferTestBase::getCapturedVaryings(glw::GLuint /* test_case_index */,
5576 Utils::Program::NameVector& /* captured_varyings */)
5578 /* Nothing to be done */
5581 /** Get body of main function for given shader stage
5585 * @param out_assignments Set to empty
5586 * @param out_calculations Set to empty
5588 void BufferTestBase::getShaderBody(glw::GLuint /* test_case_index */, Utils::Shader::STAGES /* stage */,
5589 std::string& out_assignments, std::string& out_calculations)
5591 out_assignments = "";
5592 out_calculations = "";
5595 /** Get interface of shader
5599 * @param out_interface Set to ""
5601 void BufferTestBase::getShaderInterface(glw::GLuint /* test_case_index */, Utils::Shader::STAGES /* stage */,
5602 std::string& out_interface)
5607 /** Get source code of shader
5609 * @param test_case_index Index of test case
5610 * @param stage Shader stage
5614 std::string BufferTestBase::getShaderSource(glw::GLuint test_case_index, Utils::Shader::STAGES stage)
5616 std::string assignments;
5617 std::string calculations;
5618 std::string interface;
5621 getShaderBody(test_case_index, stage, assignments, calculations);
5622 getShaderInterface(test_case_index, stage, interface);
5625 std::string source = getShaderTemplate(stage);
5628 size_t position = 0;
5629 Utils::replaceToken("INTERFACE", position, interface.c_str(), source);
5630 Utils::replaceToken("CALCULATIONS", position, calculations.c_str(), source);
5631 Utils::replaceToken("ASSIGNMENTS", position, assignments.c_str(), source);
5637 /** Inspects program to check if all resources are as expected
5645 bool BufferTestBase::inspectProgram(GLuint /* test_case_index */, Utils::Program& /* program */,
5646 std::stringstream& /* out_stream */)
5653 * @param test_case_index Id of test case
5655 * @return true if test case pass, false otherwise
5657 bool BufferTestBase::testCase(GLuint test_case_index)
5661 bufferCollection buffers;
5662 Utils::Program::NameVector captured_varyings;
5663 bufferDescriptor::Vector descriptors;
5664 Utils::Program program(m_context);
5665 Utils::VertexArray vao(m_context);
5667 /* Get captured varyings */
5668 getCapturedVaryings(test_case_index, captured_varyings);
5670 /* Get shader sources */
5671 const std::string& fragment_shader = getShaderSource(test_case_index, Utils::Shader::FRAGMENT);
5672 const std::string& geometry_shader = getShaderSource(test_case_index, Utils::Shader::GEOMETRY);
5673 const std::string& tess_ctrl_shader = getShaderSource(test_case_index, Utils::Shader::TESS_CTRL);
5674 const std::string& tess_eval_shader = getShaderSource(test_case_index, Utils::Shader::TESS_EVAL);
5675 const std::string& vertex_shader = getShaderSource(test_case_index, Utils::Shader::VERTEX);
5677 /* Set up program */
5678 program.Init("" /* compute_shader */, fragment_shader, geometry_shader, tess_ctrl_shader, tess_eval_shader,
5679 vertex_shader, captured_varyings, true, false /* is_separable */);
5683 std::stringstream stream;
5684 if (false == inspectProgram(test_case_index, program, stream))
5686 m_context.getTestContext().getLog()
5687 << tcu::TestLog::Message
5688 << "Program inspection failed. Test case: " << getTestCaseName(test_case_index)
5689 << ". Reason: " << stream.str() << tcu::TestLog::EndMessage
5690 << tcu::TestLog::KernelSource(vertex_shader) << tcu::TestLog::KernelSource(tess_ctrl_shader)
5691 << tcu::TestLog::KernelSource(tess_eval_shader) << tcu::TestLog::KernelSource(geometry_shader)
5692 << tcu::TestLog::KernelSource(fragment_shader);
5700 /* Set up buffers */
5701 getBufferDescriptors(test_case_index, descriptors);
5703 prepareBuffers(descriptors, buffers);
5710 bool result = executeDrawCall((program.m_tess_eval.m_id != 0), test_case_index);
5713 m_context.getRenderContext().postIterate();
5716 if (false == result)
5718 m_context.getTestContext().getLog()
5719 << tcu::TestLog::KernelSource(vertex_shader) << tcu::TestLog::KernelSource(tess_ctrl_shader)
5720 << tcu::TestLog::KernelSource(tess_eval_shader) << tcu::TestLog::KernelSource(geometry_shader)
5721 << tcu::TestLog::KernelSource(fragment_shader);
5727 if (false == verifyBuffers(buffers))
5729 m_context.getTestContext().getLog()
5730 << tcu::TestLog::KernelSource(vertex_shader) << tcu::TestLog::KernelSource(tess_ctrl_shader)
5731 << tcu::TestLog::KernelSource(tess_eval_shader) << tcu::TestLog::KernelSource(geometry_shader)
5732 << tcu::TestLog::KernelSource(fragment_shader);
5737 catch (Utils::Shader::InvalidSourceException& exc)
5740 TCU_FAIL(exc.what());
5742 catch (Utils::Program::BuildException& exc)
5745 TCU_FAIL(exc.what());
5752 /** Verify contents of buffers
5754 * @param buffers Collection of buffers to be verified
5756 * @return true if everything is as expected, false otherwise
5758 bool BufferTestBase::verifyBuffers(bufferCollection& buffers)
5762 for (bufferCollection::Vector::iterator it = buffers.m_vector.begin(), end = buffers.m_vector.end(); end != it;
5765 bufferCollection::pair& pair = *it;
5766 Utils::Buffer* buffer = pair.m_buffer;
5767 bufferDescriptor* descriptor = pair.m_descriptor;
5768 size_t size = descriptor->m_expected_data.size();
5770 /* Skip buffers that have no expected data */
5776 /* Get pointer to contents of buffer */
5778 GLvoid* buffer_data = buffer->Map(Utils::Buffer::ReadOnly);
5780 /* Get pointer to expected data */
5781 GLvoid* expected_data = &descriptor->m_expected_data[0];
5784 int res = memcmp(buffer_data, expected_data, size);
5788 m_context.getTestContext().getLog()
5789 << tcu::TestLog::Message
5790 << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
5791 << ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
5796 /* Release buffer mapping */
5803 /** Unbinds all uniforms and xfb
5806 void BufferTestBase::cleanBuffers()
5808 const Functions& gl = m_context.getRenderContext().getFunctions();
5813 gl.getIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &max_uni);
5814 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_xfb);
5815 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
5817 for (GLint i = 0; i < max_uni; ++i)
5819 Utils::Buffer::BindBase(gl, 0, Utils::Buffer::Uniform, i);
5822 for (GLint i = 0; i < max_xfb; ++i)
5824 Utils::Buffer::BindBase(gl, 0, Utils::Buffer::Transform_feedback, i);
5828 /** Get template of shader for given stage
5830 * @param stage Stage
5832 * @return Template of shader source
5834 std::string BufferTestBase::getShaderTemplate(Utils::Shader::STAGES stage)
5836 static const GLchar* compute_shader_template = "#version 430 core\n"
5837 "#extension GL_ARB_enhanced_layouts : require\n"
5839 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
5841 "writeonly uniform uimage2D uni_image;\n"
5853 static const GLchar* fragment_shader_template = "#version 430 core\n"
5854 "#extension GL_ARB_enhanced_layouts : require\n"
5866 // max_vertices is set to 3 for the test case "xfb_vertex_streams" declares 3 streams in geometry shader,
5867 // according to spec, max_vertices should be no less than 3 if there are 3 streams in GS.
5868 static const GLchar* geometry_shader_template = "#version 430 core\n"
5869 "#extension GL_ARB_enhanced_layouts : require\n"
5871 "layout(points) in;\n"
5872 "layout(points, max_vertices = 3) out;\n"
5882 " gl_Position = vec4(0, 0, 0, 1);\n"
5887 static const GLchar* tess_ctrl_shader_template = "#version 430 core\n"
5888 "#extension GL_ARB_enhanced_layouts : require\n"
5890 "layout(vertices = 1) out;\n"
5900 " gl_TessLevelOuter[0] = 1.0;\n"
5901 " gl_TessLevelOuter[1] = 1.0;\n"
5902 " gl_TessLevelOuter[2] = 1.0;\n"
5903 " gl_TessLevelOuter[3] = 1.0;\n"
5904 " gl_TessLevelInner[0] = 1.0;\n"
5905 " gl_TessLevelInner[1] = 1.0;\n"
5909 static const GLchar* tess_eval_shader_template = "#version 430 core\n"
5910 "#extension GL_ARB_enhanced_layouts : require\n"
5912 "layout(isolines, point_mode) in;\n"
5924 static const GLchar* vertex_shader_template = "#version 430 core\n"
5925 "#extension GL_ARB_enhanced_layouts : require\n"
5937 const GLchar* result = 0;
5941 case Utils::Shader::COMPUTE:
5942 result = compute_shader_template;
5944 case Utils::Shader::FRAGMENT:
5945 result = fragment_shader_template;
5947 case Utils::Shader::GEOMETRY:
5948 result = geometry_shader_template;
5950 case Utils::Shader::TESS_CTRL:
5951 result = tess_ctrl_shader_template;
5953 case Utils::Shader::TESS_EVAL:
5954 result = tess_eval_shader_template;
5956 case Utils::Shader::VERTEX:
5957 result = vertex_shader_template;
5960 TCU_FAIL("Invalid enum");
5966 /** Prepare buffer according to descriptor
5968 * @param buffer Buffer to prepare
5969 * @param desc Descriptor
5971 void BufferTestBase::prepareBuffer(Utils::Buffer& buffer, bufferDescriptor& desc)
5973 GLsizeiptr size = 0;
5976 if (false == desc.m_initial_data.empty())
5978 size = desc.m_initial_data.size();
5979 data = &desc.m_initial_data[0];
5981 else if (false == desc.m_expected_data.empty())
5983 size = desc.m_expected_data.size();
5986 buffer.Init(desc.m_target, Utils::Buffer::StaticDraw, size, data);
5988 if (bufferDescriptor::m_non_indexed != desc.m_index)
5990 buffer.BindBase(desc.m_index);
5998 /** Prepare collection of buffer
6000 * @param descriptors Collection of descriptors
6001 * @param out_buffers Collection of buffers
6003 void BufferTestBase::prepareBuffers(bufferDescriptor::Vector& descriptors, bufferCollection& out_buffers)
6005 for (bufferDescriptor::Vector::iterator it = descriptors.begin(), end = descriptors.end(); end != it; ++it)
6007 bufferCollection::pair pair;
6009 pair.m_buffer = new Utils::Buffer(m_context);
6010 if (0 == pair.m_buffer)
6012 TCU_FAIL("Memory allocation failed");
6015 pair.m_descriptor = &(*it);
6017 prepareBuffer(*pair.m_buffer, *pair.m_descriptor);
6019 out_buffers.m_vector.push_back(pair);
6026 BufferTestBase::bufferCollection::~bufferCollection()
6028 for (Vector::iterator it = m_vector.begin(), end = m_vector.end(); end != it; ++it)
6030 if (0 != it->m_buffer)
6032 delete it->m_buffer;
6040 * @param context Test context
6041 * @param test_name Name of test
6042 * @param test_description Description of test
6044 NegativeTestBase::NegativeTestBase(deqp::Context& context, const GLchar* test_name, const GLchar* test_description)
6045 : TestBase(context, test_name, test_description)
6049 /** Selects if "compute" stage is relevant for test
6055 bool NegativeTestBase::isComputeRelevant(GLuint /* test_case_index */)
6060 /** Selects if compilation failure is expected result
6066 bool NegativeTestBase::isFailureExpected(GLuint /* test_case_index */)
6073 * @param test_case_index Id of test case
6075 * @return true if test case pass, false otherwise
6077 bool NegativeTestBase::testCase(GLuint test_case_index)
6079 bool test_case_result = true;
6082 if (true == isComputeRelevant(test_case_index))
6084 const std::string& cs_source = getShaderSource(test_case_index, Utils::Shader::COMPUTE);
6085 bool is_build_error = false;
6086 const bool is_failure_expected = isFailureExpected(test_case_index);
6087 Utils::Program program(m_context);
6091 program.Init(cs_source, "" /* fs */, "" /* gs */, "" /* tcs */, "" /* tes */, "" /* vs */,
6092 false /* separable */);
6094 catch (Utils::Shader::InvalidSourceException& exc)
6096 if (false == is_failure_expected)
6098 m_context.getTestContext().getLog()
6099 << tcu::TestLog::Message << "Unexpected error in shader compilation: " << tcu::TestLog::EndMessage;
6103 #if DEBUG_NEG_LOG_ERROR
6107 m_context.getTestContext().getLog()
6108 << tcu::TestLog::Message << "Error in shader compilation was expected, logged for verification: "
6109 << tcu::TestLog::EndMessage;
6113 #endif /* DEBUG_NEG_LOG_ERROR */
6115 is_build_error = true;
6117 catch (Utils::Program::BuildException& exc)
6119 if (false == is_failure_expected)
6121 m_context.getTestContext().getLog()
6122 << tcu::TestLog::Message << "Unexpected error in program linking: " << tcu::TestLog::EndMessage;
6126 #if DEBUG_NEG_LOG_ERROR
6130 m_context.getTestContext().getLog()
6131 << tcu::TestLog::Message
6132 << "Error in program linking was expected, logged for verification: " << tcu::TestLog::EndMessage;
6136 #endif /* DEBUG_NEG_LOG_ERROR */
6138 is_build_error = true;
6141 if (is_build_error != is_failure_expected)
6143 if (!is_build_error)
6145 m_context.getTestContext().getLog()
6146 << tcu::TestLog::Message << "Unexpected success: " << tcu::TestLog::EndMessage;
6147 Utils::Shader::LogSource(m_context, cs_source, Utils::Shader::COMPUTE);
6149 test_case_result = false;
6154 const std::string& fs_source = getShaderSource(test_case_index, Utils::Shader::FRAGMENT);
6155 const std::string& gs_source = getShaderSource(test_case_index, Utils::Shader::GEOMETRY);
6156 bool is_build_error = false;
6157 const bool is_failure_expected = isFailureExpected(test_case_index);
6158 Utils::Program program(m_context);
6159 const std::string& tcs_source = getShaderSource(test_case_index, Utils::Shader::TESS_CTRL);
6160 const std::string& tes_source = getShaderSource(test_case_index, Utils::Shader::TESS_EVAL);
6161 const std::string& vs_source = getShaderSource(test_case_index, Utils::Shader::VERTEX);
6165 program.Init("" /* cs */, fs_source, gs_source, tcs_source, tes_source, vs_source, false /* separable */);
6167 catch (Utils::Shader::InvalidSourceException& exc)
6169 if (false == is_failure_expected)
6171 m_context.getTestContext().getLog()
6172 << tcu::TestLog::Message << "Unexpected error in shader compilation: " << tcu::TestLog::EndMessage;
6176 #if DEBUG_NEG_LOG_ERROR
6180 m_context.getTestContext().getLog()
6181 << tcu::TestLog::Message << "Error in shader compilation was expected, logged for verification: "
6182 << tcu::TestLog::EndMessage;
6186 #endif /* DEBUG_NEG_LOG_ERROR */
6188 is_build_error = true;
6190 catch (Utils::Program::BuildException& exc)
6192 if (false == is_failure_expected)
6194 m_context.getTestContext().getLog()
6195 << tcu::TestLog::Message << "Unexpected error in program linking: " << tcu::TestLog::EndMessage;
6199 #if DEBUG_NEG_LOG_ERROR
6203 m_context.getTestContext().getLog()
6204 << tcu::TestLog::Message
6205 << "Error in program linking was expected, logged for verification: " << tcu::TestLog::EndMessage;
6209 #endif /* DEBUG_NEG_LOG_ERROR */
6211 is_build_error = true;
6214 if (is_build_error != is_failure_expected)
6216 if (!is_build_error)
6218 m_context.getTestContext().getLog()
6219 << tcu::TestLog::Message << "Unexpected success: " << tcu::TestLog::EndMessage;
6220 Utils::Shader::LogSource(m_context, vs_source, Utils::Shader::VERTEX);
6221 Utils::Shader::LogSource(m_context, tcs_source, Utils::Shader::TESS_CTRL);
6222 Utils::Shader::LogSource(m_context, tes_source, Utils::Shader::TESS_EVAL);
6223 Utils::Shader::LogSource(m_context, gs_source, Utils::Shader::GEOMETRY);
6224 Utils::Shader::LogSource(m_context, fs_source, Utils::Shader::FRAGMENT);
6226 test_case_result = false;
6230 return test_case_result;
6233 /* Constants used by TextureTestBase */
6234 const glw::GLuint TextureTestBase::m_width = 16;
6235 const glw::GLuint TextureTestBase::m_height = 16;
6239 * @param context Test context
6240 * @param test_name Name of test
6241 * @param test_description Description of test
6243 TextureTestBase::TextureTestBase(deqp::Context& context, const GLchar* test_name, const GLchar* test_description)
6244 : TestBase(context, test_name, test_description)
6248 /** Get locations for all inputs with automatic_location
6250 * @param program Program object
6251 * @param program_interface Interface of program
6253 void TextureTestBase::prepareAttribLocation(Utils::Program& program, Utils::ProgramInterface& program_interface)
6255 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
6257 Utils::Variable::PtrVector& inputs = si.m_inputs;
6259 for (Utils::Variable::PtrVector::iterator it = inputs.begin(); inputs.end() != it; ++it)
6261 /* Test does not specify location, query value and set */
6262 if (Utils::Variable::m_automatic_location == (*it)->m_descriptor.m_expected_location)
6264 GLuint index = program.GetResourceIndex((*it)->m_descriptor.m_name, GL_PROGRAM_INPUT);
6267 program.GetResource(GL_PROGRAM_INPUT, index, GL_LOCATION, 1 /* size */, &location);
6269 (*it)->m_descriptor.m_expected_location = location;
6274 /** Verifies contents of drawn image
6277 * @param color_0 Verified image
6279 * @return true if image is filled with 1, false otherwise
6281 bool TextureTestBase::checkResults(glw::GLuint /* test_case_index */, Utils::Texture& color_0)
6283 static const GLuint size = m_width * m_height;
6284 static const GLuint expected_color = 1;
6286 std::vector<GLuint> data;
6289 color_0.Get(GL_RED_INTEGER, GL_UNSIGNED_INT, &data[0]);
6291 for (GLuint i = 0; i < size; ++i)
6293 const GLuint color = data[i];
6295 if (expected_color != color)
6297 m_context.getTestContext().getLog() << tcu::TestLog::Message << "R32UI[" << i << "]:" << color
6298 << tcu::TestLog::EndMessage;
6306 /** Execute dispatch compute for 16x16x1
6310 void TextureTestBase::executeDispatchCall(GLuint /* test_case_index */)
6312 const Functions& gl = m_context.getRenderContext().getFunctions();
6314 gl.dispatchCompute(16 /* x */, 16 /* y */, 1 /* z */);
6315 GLU_EXPECT_NO_ERROR(gl.getError(), "DispatchCompute");
6318 /** Execute drawArrays for single vertex
6322 void TextureTestBase::executeDrawCall(GLuint /* test_case_index */)
6324 const Functions& gl = m_context.getRenderContext().getFunctions();
6326 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
6327 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
6330 /** Prepare code snippet that will pass in variables to out variables
6333 * @param varying_passthrough Collection of connections between in and out variables
6334 * @param stage Shader stage
6336 * @return Code that pass in variables to next stage
6338 std::string TextureTestBase::getPassSnippet(GLuint /* test_case_index */,
6339 Utils::VaryingPassthrough& varying_passthrough, Utils::Shader::STAGES stage)
6341 static const GLchar* separator = "\n ";
6343 /* Skip for compute shader */
6344 if (Utils::Shader::COMPUTE == stage)
6349 Utils::VaryingConnection::Vector& vector = varying_passthrough.Get(stage);
6351 std::string result = Utils::g_list;
6352 size_t position = 0;
6354 for (GLuint i = 0; i < vector.size(); ++i)
6357 Utils::VaryingConnection& connection = vector[i];
6359 Utils::Variable* in = connection.m_in;
6360 Utils::Variable* out = connection.m_out;
6362 Utils::Variable::FLAVOUR in_flavour = Utils::Variable::GetFlavour(stage, Utils::Variable::INPUT);
6363 Utils::Variable::FLAVOUR out_flavour = Utils::Variable::GetFlavour(stage, Utils::Variable::OUTPUT);
6365 const std::string passthrough =
6366 getVariablePassthrough("", in->m_descriptor, in_flavour, "", out->m_descriptor, out_flavour);
6368 Utils::insertElementOfList(passthrough.c_str(), separator, position, result);
6371 Utils::endList("", position, result);
6376 /** Basic implementation of method getProgramInterface
6382 void TextureTestBase::getProgramInterface(GLuint /* test_case_index */,
6383 Utils::ProgramInterface& /* program_interface */,
6384 Utils::VaryingPassthrough& /* varying_passthrough */)
6388 /** Prepare code snippet that will verify in and uniform variables
6391 * @param program_interface Interface of program
6392 * @param stage Shader stage
6394 * @return Code that verify variables
6396 std::string TextureTestBase::getVerificationSnippet(GLuint /* test_case_index */,
6397 Utils::ProgramInterface& program_interface,
6398 Utils::Shader::STAGES stage)
6400 static const GLchar* separator = " ||\n ";
6402 std::string verification = "if (LIST)\n"
6407 /* Get flavour of in and out variables */
6408 Utils::Variable::FLAVOUR in_flavour = Utils::Variable::GetFlavour(stage, Utils::Variable::INPUT);
6410 /* Get interface for shader stage */
6411 Utils::ShaderInterface& si = program_interface.GetShaderInterface(stage);
6413 /* There are no varialbes to verify */
6414 if ((0 == si.m_inputs.size()) && (0 == si.m_uniforms.size()) && (0 == si.m_ssb_blocks.size()))
6419 /* For each in variable insert verification code */
6420 size_t position = 0;
6422 for (GLuint i = 0; i < si.m_inputs.size(); ++i)
6424 const Utils::Variable& var = *si.m_inputs[i];
6425 const std::string& var_verification = getVariableVerifcation("", var.m_data, var.m_descriptor, in_flavour);
6427 Utils::insertElementOfList(var_verification.c_str(), separator, position, verification);
6430 /* For each unifrom variable insert verification code */
6431 for (GLuint i = 0; i < si.m_uniforms.size(); ++i)
6433 const Utils::Variable& var = *si.m_uniforms[i];
6434 const std::string& var_verification =
6435 getVariableVerifcation("", var.m_data, var.m_descriptor, Utils::Variable::BASIC);
6437 Utils::insertElementOfList(var_verification.c_str(), separator, position, verification);
6440 /* For each ssb variable insert verification code */
6441 for (GLuint i = 0; i < si.m_ssb_blocks.size(); ++i)
6443 const Utils::Variable& var = *si.m_ssb_blocks[i];
6444 const std::string& var_verification =
6445 getVariableVerifcation("", var.m_data, var.m_descriptor, Utils::Variable::BASIC);
6447 Utils::insertElementOfList(var_verification.c_str(), separator, position, verification);
6450 Utils::endList("", position, verification);
6452 #if DEBUG_TTB_VERIFICATION_SNIPPET_STAGE
6456 sprintf(buffer, "%d", stage + 10);
6457 Utils::replaceToken("0u", position, buffer, verification);
6460 #elif DEBUG_TTB_VERIFICATION_SNIPPET_VARIABLE
6462 if (Utils::Shader::VERTEX == stage)
6464 Utils::replaceToken("0u", position, "in_vs_first.x", verification);
6468 Utils::replaceToken("0u", position, "31u", verification);
6474 return verification;
6477 /** Selects if "compute" stage is relevant for test
6483 bool TextureTestBase::isComputeRelevant(GLuint /* test_case_index */)
6488 /** Selects if "draw" stages are relevant for test
6494 bool TextureTestBase::isDrawRelevant(GLuint /* test_case_index */)
6499 /** Prepare code that will do assignment of single in to single out
6501 * @param in_parent_name Name of parent in variable
6502 * @param in_variable Descriptor of in variable
6503 * @param in_flavour Flavoud of in variable
6504 * @param out_parent_name Name of parent out variable
6505 * @param out_variable Descriptor of out variable
6506 * @param out_flavour Flavoud of out variable
6508 * @return Code that does OUT = IN
6510 std::string TextureTestBase::getVariablePassthrough(const std::string& in_parent_name,
6511 const Utils::Variable::Descriptor& in_variable,
6512 Utils::Variable::FLAVOUR in_flavour,
6513 const std::string& out_parent_name,
6514 const Utils::Variable::Descriptor& out_variable,
6515 Utils::Variable::FLAVOUR out_flavour)
6519 GLuint member_index = 0;
6520 size_t position = 0;
6521 std::string result = Utils::g_list;
6522 static const GLchar* separator = ";\n ";
6524 /* For each member of each array element */
6527 const std::string in_name = Utils::Variable::GetReference(in_parent_name, in_variable, in_flavour, index);
6528 const std::string out_name = Utils::Variable::GetReference(out_parent_name, out_variable, out_flavour, index);
6529 std::string passthrough;
6531 /* Prepare verification */
6532 if (Utils::Variable::BUILTIN == in_variable.m_type)
6534 size_t pass_position = 0;
6536 passthrough = "OUT = IN;";
6538 Utils::replaceToken("OUT", pass_position, out_name.c_str(), passthrough);
6539 Utils::replaceToken("IN", pass_position, in_name.c_str(), passthrough);
6541 /* Increment index */
6546 const Utils::Interface* in_interface = in_variable.m_interface;
6547 const Utils::Interface* out_interface = out_variable.m_interface;
6549 if ((0 == in_interface) || (0 == out_interface))
6551 TCU_FAIL("Nullptr");
6554 const Utils::Variable::Descriptor& in_member = in_interface->m_members[member_index];
6555 const Utils::Variable::Descriptor& out_member = out_interface->m_members[member_index];
6557 passthrough = getVariablePassthrough(in_name, in_member, Utils::Variable::BASIC, out_name, out_member,
6558 Utils::Variable::BASIC);
6560 /* Increment member_index */
6563 /* Increment index and reset member_index if all members were processed */
6564 if (in_interface->m_members.size() == member_index)
6571 /* Check if loop should end */
6572 if ((index >= in_variable.m_n_array_elements) && (0 == member_index))
6577 Utils::insertElementOfList(passthrough.c_str(), separator, position, result);
6579 } while (true != done);
6581 Utils::endList("", position, result);
6587 /** Get verification of single variable
6589 * @param parent_name Name of parent variable
6590 * @param data Data that should be used as EXPECTED
6591 * @param variable Descriptor of variable
6592 * @param flavour Flavour of variable
6594 * @return Code that does (EXPECTED != VALUE) ||
6596 std::string TextureTestBase::getVariableVerifcation(const std::string& parent_name, const GLvoid* data,
6597 const Utils::Variable::Descriptor& variable,
6598 Utils::Variable::FLAVOUR flavour)
6600 static const GLchar* logic_op = " ||\n ";
6601 const GLuint n_elements = (0 == variable.m_n_array_elements) ? 1 : variable.m_n_array_elements;
6602 size_t position = 0;
6603 std::string result = Utils::g_list;
6604 GLint stride = variable.m_expected_stride_of_element;
6606 /* For each each array element */
6607 for (GLuint element = 0; element < n_elements; ++element)
6609 const std::string name = Utils::Variable::GetReference(parent_name, variable, flavour, element);
6611 /* Calculate data pointer */
6612 GLvoid* data_ptr = (GLvoid*)((GLubyte*)data + element * stride);
6614 /* Prepare verification */
6615 if (Utils::Variable::BUILTIN == variable.m_type)
6617 const std::string& expected = variable.m_builtin.GetGLSLConstructor(data_ptr);
6618 std::string verification;
6619 size_t verification_position = 0;
6621 verification = "(EXPECTED != NAME)";
6623 Utils::replaceToken("EXPECTED", verification_position, expected.c_str(), verification);
6624 Utils::replaceToken("NAME", verification_position, name.c_str(), verification);
6626 Utils::insertElementOfList(verification.c_str(), logic_op, position, result);
6630 const Utils::Interface* interface = variable.m_interface;
6634 TCU_FAIL("Nullptr");
6637 const GLuint n_members = static_cast<GLuint>(interface->m_members.size());
6639 /* for each member */
6640 for (GLuint member_index = 0; member_index < n_members; ++member_index)
6642 const Utils::Variable::Descriptor& member = interface->m_members[member_index];
6644 /* Get verification of member */
6645 const std::string& verification =
6646 getVariableVerifcation(name, (GLubyte*)data_ptr + member.m_offset, member, Utils::Variable::BASIC);
6648 Utils::insertElementOfList(verification.c_str(), logic_op, position, result);
6653 Utils::endList("", position, result);
6658 /** Prepare attributes, vertex array object and array buffer
6660 * @param test_case_index Index of test case
6661 * @param program_interface Interface of program
6662 * @param buffer Array buffer
6663 * @param vao Vertex array object
6665 void TextureTestBase::prepareAttributes(GLuint test_case_index, Utils::ProgramInterface& program_interface,
6666 Utils::Buffer& buffer, Utils::VertexArray& vao)
6668 bool use_component_qualifier = useComponentQualifier(test_case_index);
6670 /* Get shader interface */
6671 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
6673 /* Bind vao and buffer */
6677 /* Skip if there are no input variables in vertex shader */
6678 if (0 == si.m_inputs.size())
6683 /* Calculate vertex stride and check */
6684 GLint vertex_stride = 0;
6686 for (GLuint i = 0; i < si.m_inputs.size(); ++i)
6688 Utils::Variable& variable = *si.m_inputs[i];
6690 GLint variable_size = static_cast<GLuint>(variable.m_data_size);
6692 GLint ends_at = variable_size + variable.m_descriptor.m_offset;
6694 vertex_stride = std::max(vertex_stride, ends_at);
6697 /* Prepare buffer data and set up vao */
6698 std::vector<GLubyte> buffer_data;
6699 buffer_data.resize(vertex_stride);
6701 GLubyte* ptr = &buffer_data[0];
6703 for (GLuint i = 0; i < si.m_inputs.size(); ++i)
6705 Utils::Variable& variable = *si.m_inputs[i];
6707 memcpy(ptr + variable.m_descriptor.m_offset, variable.m_data, variable.m_data_size);
6709 if (false == use_component_qualifier)
6711 vao.Attribute(variable.m_descriptor.m_expected_location, variable.m_descriptor.m_builtin,
6712 variable.m_descriptor.m_n_array_elements, variable.m_descriptor.m_normalized,
6713 variable.GetStride(), (GLvoid*)(intptr_t)variable.m_descriptor.m_offset);
6715 else if (0 == variable.m_descriptor.m_expected_component)
6717 /* Components can only be applied to vectors.
6718 Assumption that test use all 4 components */
6719 const Utils::Type& type =
6720 Utils::Type::GetType(variable.m_descriptor.m_builtin.m_basic_type, 1 /* n_columns */, 4 /* n_rows */);
6722 vao.Attribute(variable.m_descriptor.m_expected_location, type, variable.m_descriptor.m_n_array_elements,
6723 variable.m_descriptor.m_normalized, variable.GetStride(),
6724 (GLvoid*)(intptr_t)variable.m_descriptor.m_offset);
6729 buffer.Data(Utils::Buffer::StaticDraw, vertex_stride, ptr);
6732 /** Get locations for all outputs with automatic_location
6734 * @param program Program object
6735 * @param program_interface Interface of program
6737 void TextureTestBase::prepareFragmentDataLoc(Utils::Program& program, Utils::ProgramInterface& program_interface)
6739 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
6740 Utils::Variable::PtrVector& outputs = si.m_outputs;
6742 for (Utils::Variable::PtrVector::iterator it = outputs.begin(); outputs.end() != it; ++it)
6744 /* Test does not specify location, query value and set */
6745 if (Utils::Variable::m_automatic_location == (*it)->m_descriptor.m_expected_location)
6747 GLuint index = program.GetResourceIndex((*it)->m_descriptor.m_name, GL_PROGRAM_OUTPUT);
6750 program.GetResource(GL_PROGRAM_OUTPUT, index, GL_LOCATION, 1 /* size */, &location);
6752 (*it)->m_descriptor.m_expected_location = location;
6757 /** Prepare framebuffer with single texture as color attachment
6759 * @param framebuffer Framebuffer
6760 * @param color_0_texture Texture that will used as color attachment
6762 void TextureTestBase::prepareFramebuffer(Utils::Framebuffer& framebuffer, Utils::Texture& color_0_texture)
6765 std::vector<GLuint> texture_data;
6766 texture_data.resize(m_width * m_height);
6768 for (GLuint i = 0; i < texture_data.size(); ++i)
6770 texture_data[i] = 0x20406080;
6773 /* Prepare texture */
6774 color_0_texture.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT,
6777 /* Prepare framebuffer */
6780 framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0, color_0_texture.m_id, m_width, m_height);
6782 framebuffer.ClearColor(0.0f, 0.0f, 0.0f, 0.0f);
6783 framebuffer.Clear(GL_COLOR_BUFFER_BIT);
6786 /** Prepare iamge unit for compute shader
6788 * @param location Uniform location
6789 * @param image_texture Texture that will used as color attachment
6791 void TextureTestBase::prepareImage(GLint location, Utils::Texture& image_texture) const
6793 static const GLuint image_unit = 0;
6795 std::vector<GLuint> texture_data;
6796 texture_data.resize(m_width * m_height);
6798 for (GLuint i = 0; i < texture_data.size(); ++i)
6800 texture_data[i] = 0x20406080;
6803 image_texture.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT,
6806 const Functions& gl = m_context.getRenderContext().getFunctions();
6808 gl.bindImageTexture(image_unit, image_texture.m_id, 0 /* level */, GL_FALSE /* layered */, 0 /* Layer */,
6809 GL_WRITE_ONLY, GL_R32UI);
6810 GLU_EXPECT_NO_ERROR(gl.getError(), "BindImageTexture");
6812 Utils::Program::Uniform(gl, Utils::Type::_int, 1 /* count */, location, &image_unit);
6815 /** Basic implementation
6818 * @param si Shader interface
6819 * @param program Program
6820 * @param cs_buffer Buffer for ssb blocks
6822 void TextureTestBase::prepareSSBs(GLuint /* test_case_index */, Utils::ShaderInterface& si, Utils::Program& program,
6823 Utils::Buffer& buffer)
6825 /* Skip if there are no input variables in vertex shader */
6826 if (0 == si.m_ssb_blocks.size())
6831 /* Calculate vertex stride */
6832 GLint ssbs_stride = 0;
6834 for (GLuint i = 0; i < si.m_ssb_blocks.size(); ++i)
6836 Utils::Variable& variable = *si.m_ssb_blocks[i];
6838 if (false == variable.IsBlock())
6843 GLint variable_stride = variable.GetStride();
6845 GLint ends_at = variable_stride + variable.m_descriptor.m_offset;
6847 ssbs_stride = std::max(ssbs_stride, ends_at);
6850 /* Set active program */
6855 buffer.Data(Utils::Buffer::StaticDraw, ssbs_stride, 0);
6857 /* Set up uniforms */
6858 for (GLuint i = 0; i < si.m_ssb_blocks.size(); ++i)
6860 Utils::Variable& variable = *si.m_ssb_blocks[i];
6862 /* prepareUnifor should work fine for ssb blocks */
6863 prepareUniform(program, variable, buffer);
6867 /** Basic implementation
6869 * @param test_case_index Test case index
6870 * @param program_interface Program interface
6871 * @param program Program
6872 * @param cs_buffer Buffer for compute shader stage
6874 void TextureTestBase::prepareSSBs(GLuint test_case_index, Utils::ProgramInterface& program_interface,
6875 Utils::Program& program, Utils::Buffer& cs_buffer)
6877 cs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
6879 Utils::ShaderInterface& cs = program_interface.GetShaderInterface(Utils::Shader::COMPUTE);
6881 prepareSSBs(test_case_index, cs, program, cs_buffer);
6883 cs_buffer.BindBase(Utils::Shader::COMPUTE);
6886 /** Basic implementation
6888 * @param test_case_index Test case index
6889 * @param program_interface Program interface
6890 * @param program Program
6891 * @param fs_buffer Buffer for fragment shader stage
6892 * @param gs_buffer Buffer for geometry shader stage
6893 * @param tcs_buffer Buffer for tessellation control shader stage
6894 * @param tes_buffer Buffer for tessellation evaluation shader stage
6895 * @param vs_buffer Buffer for vertex shader stage
6897 void TextureTestBase::prepareSSBs(GLuint test_case_index, Utils::ProgramInterface& program_interface,
6898 Utils::Program& program, Utils::Buffer& fs_buffer, Utils::Buffer& gs_buffer,
6899 Utils::Buffer& tcs_buffer, Utils::Buffer& tes_buffer, Utils::Buffer& vs_buffer)
6901 fs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
6902 gs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
6903 tcs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
6904 tes_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
6905 vs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
6907 Utils::ShaderInterface& fs = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
6908 Utils::ShaderInterface& gs = program_interface.GetShaderInterface(Utils::Shader::GEOMETRY);
6909 Utils::ShaderInterface& tcs = program_interface.GetShaderInterface(Utils::Shader::TESS_CTRL);
6910 Utils::ShaderInterface& tes = program_interface.GetShaderInterface(Utils::Shader::TESS_EVAL);
6911 Utils::ShaderInterface& vs = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
6913 prepareSSBs(test_case_index, fs, program, fs_buffer);
6914 prepareSSBs(test_case_index, gs, program, gs_buffer);
6915 prepareSSBs(test_case_index, tcs, program, tcs_buffer);
6916 prepareSSBs(test_case_index, tes, program, tes_buffer);
6917 prepareSSBs(test_case_index, vs, program, vs_buffer);
6919 fs_buffer.BindBase(Utils::Shader::FRAGMENT);
6920 gs_buffer.BindBase(Utils::Shader::GEOMETRY);
6921 tcs_buffer.BindBase(Utils::Shader::TESS_CTRL);
6922 tes_buffer.BindBase(Utils::Shader::TESS_EVAL);
6923 vs_buffer.BindBase(Utils::Shader::VERTEX);
6926 /** Updates buffer data with variable
6928 * @param program Program object
6929 * @param variable Variable
6930 * @param buffer Buffer
6932 void TextureTestBase::prepareUniform(Utils::Program& program, Utils::Variable& variable, Utils::Buffer& buffer)
6934 const Functions& gl = m_context.getRenderContext().getFunctions();
6936 GLsizei count = variable.m_descriptor.m_n_array_elements;
6942 if (Utils::Variable::BUILTIN == variable.m_descriptor.m_type)
6944 program.Uniform(gl, variable.m_descriptor.m_builtin, count, variable.m_descriptor.m_expected_location,
6949 const bool is_block = variable.IsBlock();
6951 if (false == is_block)
6953 TCU_FAIL("Not implemented");
6957 buffer.SubData(variable.m_descriptor.m_offset, variable.m_descriptor.m_expected_stride_of_element * count,
6963 /** Basic implementation
6966 * @param si Shader interface
6967 * @param program Program
6968 * @param cs_buffer Buffer for uniform blocks
6970 void TextureTestBase::prepareUniforms(GLuint /* test_case_index */, Utils::ShaderInterface& si, Utils::Program& program,
6971 Utils::Buffer& buffer)
6973 /* Skip if there are no input variables in vertex shader */
6974 if (0 == si.m_uniforms.size())
6979 /* Calculate vertex stride */
6980 GLint uniforms_stride = 0;
6982 for (GLuint i = 0; i < si.m_uniforms.size(); ++i)
6984 Utils::Variable& variable = *si.m_uniforms[i];
6986 if (false == variable.IsBlock())
6991 GLint variable_stride = variable.GetStride();
6993 GLint ends_at = variable_stride + variable.m_descriptor.m_offset;
6995 uniforms_stride = std::max(uniforms_stride, ends_at);
6998 /* Set active program */
7003 buffer.Data(Utils::Buffer::StaticDraw, uniforms_stride, 0);
7005 /* Set up uniforms */
7006 for (GLuint i = 0; i < si.m_uniforms.size(); ++i)
7008 Utils::Variable& variable = *si.m_uniforms[i];
7010 prepareUniform(program, variable, buffer);
7014 /** Basic implementation
7016 * @param test_case_index Test case index
7017 * @param program_interface Program interface
7018 * @param program Program
7019 * @param cs_buffer Buffer for compute shader stage
7021 void TextureTestBase::prepareUniforms(GLuint test_case_index, Utils::ProgramInterface& program_interface,
7022 Utils::Program& program, Utils::Buffer& cs_buffer)
7024 cs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7026 Utils::ShaderInterface& cs = program_interface.GetShaderInterface(Utils::Shader::COMPUTE);
7028 prepareUniforms(test_case_index, cs, program, cs_buffer);
7030 cs_buffer.BindBase(Utils::Shader::COMPUTE);
7033 /** Basic implementation
7035 * @param test_case_index Test case index
7036 * @param program_interface Program interface
7037 * @param program Program
7038 * @param fs_buffer Buffer for fragment shader stage
7039 * @param gs_buffer Buffer for geometry shader stage
7040 * @param tcs_buffer Buffer for tessellation control shader stage
7041 * @param tes_buffer Buffer for tessellation evaluation shader stage
7042 * @param vs_buffer Buffer for vertex shader stage
7044 void TextureTestBase::prepareUniforms(GLuint test_case_index, Utils::ProgramInterface& program_interface,
7045 Utils::Program& program, Utils::Buffer& fs_buffer, Utils::Buffer& gs_buffer,
7046 Utils::Buffer& tcs_buffer, Utils::Buffer& tes_buffer, Utils::Buffer& vs_buffer)
7048 fs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7049 gs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7050 tcs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7051 tes_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7052 vs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7054 Utils::ShaderInterface& fs = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
7055 Utils::ShaderInterface& gs = program_interface.GetShaderInterface(Utils::Shader::GEOMETRY);
7056 Utils::ShaderInterface& tcs = program_interface.GetShaderInterface(Utils::Shader::TESS_CTRL);
7057 Utils::ShaderInterface& tes = program_interface.GetShaderInterface(Utils::Shader::TESS_EVAL);
7058 Utils::ShaderInterface& vs = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
7060 prepareUniforms(test_case_index, fs, program, fs_buffer);
7061 prepareUniforms(test_case_index, gs, program, gs_buffer);
7062 prepareUniforms(test_case_index, tcs, program, tcs_buffer);
7063 prepareUniforms(test_case_index, tes, program, tes_buffer);
7064 prepareUniforms(test_case_index, vs, program, vs_buffer);
7066 fs_buffer.BindBase(Utils::Shader::FRAGMENT);
7067 gs_buffer.BindBase(Utils::Shader::GEOMETRY);
7068 tcs_buffer.BindBase(Utils::Shader::TESS_CTRL);
7069 tes_buffer.BindBase(Utils::Shader::TESS_EVAL);
7070 vs_buffer.BindBase(Utils::Shader::VERTEX);
7073 /** Basic implementation
7075 * @param test_case_index Test case index
7076 * @param program_interface Program interface
7077 * @param program Program
7078 * @param fs_buffer Buffer for fragment shader stage
7079 * @param gs_buffer Buffer for geometry shader stage
7080 * @param tcs_buffer Buffer for tessellation control shader stage
7081 * @param tes_buffer Buffer for tessellation evaluation shader stage
7082 * @param vs_buffer Buffer for vertex shader stage
7084 void TextureTestBase::prepareUniforms(GLuint test_case_index, Utils::ProgramInterface& program_interface,
7085 Utils::Program& fs_program, Utils::Program& gs_program,
7086 Utils::Program& tcs_program, Utils::Program& tes_program,
7087 Utils::Program& vs_program, Utils::Buffer& fs_buffer, Utils::Buffer& gs_buffer,
7088 Utils::Buffer& tcs_buffer, Utils::Buffer& tes_buffer, Utils::Buffer& vs_buffer)
7090 fs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7091 gs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7092 tcs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7093 tes_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7094 vs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7096 Utils::ShaderInterface& fs = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
7097 Utils::ShaderInterface& gs = program_interface.GetShaderInterface(Utils::Shader::GEOMETRY);
7098 Utils::ShaderInterface& tcs = program_interface.GetShaderInterface(Utils::Shader::TESS_CTRL);
7099 Utils::ShaderInterface& tes = program_interface.GetShaderInterface(Utils::Shader::TESS_EVAL);
7100 Utils::ShaderInterface& vs = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
7102 prepareUniforms(test_case_index, fs, fs_program, fs_buffer);
7103 fs_buffer.BindBase(Utils::Shader::FRAGMENT);
7105 prepareUniforms(test_case_index, gs, gs_program, gs_buffer);
7106 gs_buffer.BindBase(Utils::Shader::GEOMETRY);
7108 prepareUniforms(test_case_index, tcs, tcs_program, tcs_buffer);
7109 tcs_buffer.BindBase(Utils::Shader::TESS_CTRL);
7111 prepareUniforms(test_case_index, tes, tes_program, tes_buffer);
7112 tes_buffer.BindBase(Utils::Shader::TESS_EVAL);
7114 prepareUniforms(test_case_index, vs, vs_program, vs_buffer);
7115 vs_buffer.BindBase(Utils::Shader::VERTEX);
7118 /** Prepare source for shader
7120 * @param test_case_index Index of test case
7121 * @param program_interface Interface of program
7122 * @param varying_passthrough Collection of connection between in and out variables
7123 * @param stage Shader stage
7125 * @return Source of shader
7127 std::string TextureTestBase::getShaderSource(GLuint test_case_index, Utils::ProgramInterface& program_interface,
7128 Utils::VaryingPassthrough& varying_passthrough,
7129 Utils::Shader::STAGES stage)
7132 const GLchar* shader_template = getShaderTemplate(stage);
7133 const std::string& shader_interface = program_interface.GetInterfaceForStage(stage);
7135 const std::string& verification = getVerificationSnippet(test_case_index, program_interface, stage);
7137 const std::string& passthrough = getPassSnippet(test_case_index, varying_passthrough, stage);
7139 const GLchar* per_vertex = "";
7141 std::string source = shader_template;
7142 size_t position = 0;
7144 /* Replace tokens in template */
7145 if (Utils::Shader::GEOMETRY == stage)
7147 if (false == useMonolithicProgram(test_case_index))
7149 per_vertex = "out gl_PerVertex {\n"
7150 "vec4 gl_Position;\n"
7155 Utils::replaceToken("PERVERTEX", position, per_vertex, source);
7158 Utils::replaceToken("INTERFACE", position, shader_interface.c_str(), source);
7159 Utils::replaceToken("VERIFICATION", position, verification.c_str(), source);
7161 if (false == verification.empty())
7163 Utils::replaceAllTokens("ELSE", " else ", source);
7167 Utils::replaceAllTokens("ELSE", "", source);
7170 Utils::replaceAllTokens("PASSTHROUGH", passthrough.c_str(), source);
7176 /** Returns template of shader for given stage
7178 * @param stage Shade stage
7180 * @return Proper template
7182 const GLchar* TextureTestBase::getShaderTemplate(Utils::Shader::STAGES stage)
7185 static const GLchar* compute_shader_template =
7186 "#version 430 core\n"
7187 "#extension GL_ARB_enhanced_layouts : require\n"
7189 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
7191 "writeonly uniform uimage2D uni_image;\n"
7197 " uint result = 1u;\n"
7201 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), uvec4(result, 0, 0, 0));\n"
7205 static const GLchar* fragment_shader_template = "#version 430 core\n"
7206 "#extension GL_ARB_enhanced_layouts : require\n"
7208 "flat in uint gs_fs_result;\n"
7209 " out uint fs_out_result;\n"
7215 " uint result = 1u;\n"
7217 " if (1u != gs_fs_result)\n"
7219 " result = gs_fs_result;\n"
7223 " fs_out_result = result;\n"
7228 static const GLchar* geometry_shader_template =
7229 "#version 430 core\n"
7230 "#extension GL_ARB_enhanced_layouts : require\n"
7232 "layout(points) in;\n"
7233 "layout(triangle_strip, max_vertices = 4) out;\n"
7235 " in uint tes_gs_result[];\n"
7236 "flat out uint gs_fs_result;\n"
7238 "PERVERTEX" /* Separable programs require explicit declaration of gl_PerVertex */
7243 " uint result = 1u;\n"
7245 " if (1u != tes_gs_result[0])\n"
7247 " result = tes_gs_result[0];\n"
7251 " gs_fs_result = result;\n"
7253 " gl_Position = vec4(-1, -1, 0, 1);\n"
7255 " gs_fs_result = result;\n"
7257 " gl_Position = vec4(-1, 1, 0, 1);\n"
7259 " gs_fs_result = result;\n"
7261 " gl_Position = vec4(1, -1, 0, 1);\n"
7263 " gs_fs_result = result;\n"
7265 " gl_Position = vec4(1, 1, 0, 1);\n"
7270 static const GLchar* tess_ctrl_shader_template = "#version 430 core\n"
7271 "#extension GL_ARB_enhanced_layouts : require\n"
7273 "layout(vertices = 1) out;\n"
7275 "in uint vs_tcs_result[];\n"
7276 "out uint tcs_tes_result[];\n"
7282 " uint result = 1u;\n"
7284 " if (1u != vs_tcs_result[gl_InvocationID])\n"
7286 " result = vs_tcs_result[gl_InvocationID];\n"
7290 " tcs_tes_result[gl_InvocationID] = result;\n"
7294 " gl_TessLevelOuter[0] = 1.0;\n"
7295 " gl_TessLevelOuter[1] = 1.0;\n"
7296 " gl_TessLevelOuter[2] = 1.0;\n"
7297 " gl_TessLevelOuter[3] = 1.0;\n"
7298 " gl_TessLevelInner[0] = 1.0;\n"
7299 " gl_TessLevelInner[1] = 1.0;\n"
7303 static const GLchar* tess_eval_shader_template = "#version 430 core\n"
7304 "#extension GL_ARB_enhanced_layouts : require\n"
7306 "layout(isolines, point_mode) in;\n"
7308 "in uint tcs_tes_result[];\n"
7309 "out uint tes_gs_result;\n"
7315 " uint result = 1u;\n"
7317 " if (1 != tcs_tes_result[0])\n"
7319 " result = tcs_tes_result[0];\n"
7323 " tes_gs_result = result;\n"
7329 static const GLchar* vertex_shader_template = "#version 430 core\n"
7330 "#extension GL_ARB_enhanced_layouts : require\n"
7332 "out uint vs_tcs_result;\n"
7338 " uint result = 1u;\n"
7342 " vs_tcs_result = result;\n"
7348 const GLchar* result = 0;
7352 case Utils::Shader::COMPUTE:
7353 result = compute_shader_template;
7355 case Utils::Shader::FRAGMENT:
7356 result = fragment_shader_template;
7358 case Utils::Shader::GEOMETRY:
7359 result = geometry_shader_template;
7361 case Utils::Shader::TESS_CTRL:
7362 result = tess_ctrl_shader_template;
7364 case Utils::Shader::TESS_EVAL:
7365 result = tess_eval_shader_template;
7367 case Utils::Shader::VERTEX:
7368 result = vertex_shader_template;
7371 TCU_FAIL("Invalid enum");
7379 * @param test_case_index Id of test case
7381 * @return true if test case pass, false otherwise
7383 bool TextureTestBase::testCase(GLuint test_case_index)
7387 if (true == useMonolithicProgram(test_case_index))
7389 return testMonolithic(test_case_index);
7393 return testSeparable(test_case_index);
7396 catch (Utils::Shader::InvalidSourceException& exc)
7399 TCU_FAIL(exc.what());
7401 catch (Utils::Program::BuildException& exc)
7403 TCU_FAIL(exc.what());
7407 /** Runs "draw" test with monolithic program
7409 * @param test_case_index Id of test case
7411 bool TextureTestBase::testMonolithic(GLuint test_case_index)
7413 Utils::ProgramInterface program_interface;
7414 Utils::VaryingPassthrough varying_passthrough;
7417 const std::string& test_name = getTestCaseName(test_case_index);
7420 getProgramInterface(test_case_index, program_interface, varying_passthrough);
7424 if (true == isDrawRelevant(test_case_index))
7426 Utils::Buffer buffer_attr(m_context);
7427 Utils::Buffer buffer_ssb_fs(m_context);
7428 Utils::Buffer buffer_ssb_gs(m_context);
7429 Utils::Buffer buffer_ssb_tcs(m_context);
7430 Utils::Buffer buffer_ssb_tes(m_context);
7431 Utils::Buffer buffer_ssb_vs(m_context);
7432 Utils::Buffer buffer_u_fs(m_context);
7433 Utils::Buffer buffer_u_gs(m_context);
7434 Utils::Buffer buffer_u_tcs(m_context);
7435 Utils::Buffer buffer_u_tes(m_context);
7436 Utils::Buffer buffer_u_vs(m_context);
7437 Utils::Framebuffer framebuffer(m_context);
7438 Utils::Program program(m_context);
7439 Utils::Texture texture_fb(m_context);
7440 Utils::VertexArray vao(m_context);
7443 const std::string& fragment_shader =
7444 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::FRAGMENT);
7445 const std::string& geometry_shader =
7446 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::GEOMETRY);
7447 const std::string& tess_ctrl_shader =
7448 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::TESS_CTRL);
7449 const std::string& tess_eval_shader =
7450 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::TESS_EVAL);
7451 const std::string& vertex_shader =
7452 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::VERTEX);
7454 program.Init("" /* compute_shader */, fragment_shader, geometry_shader, tess_ctrl_shader, tess_eval_shader,
7455 vertex_shader, false /* is_separable */);
7458 prepareAttribLocation(program, program_interface);
7459 prepareFragmentDataLoc(program, program_interface);
7462 std::stringstream stream;
7463 if (false == Utils::checkMonolithicDrawProgramInterface(program, program_interface, stream))
7465 m_context.getTestContext().getLog()
7466 << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7467 << ". Inspection of draw program interface failed:\n"
7468 << stream.str() << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(vertex_shader)
7469 << tcu::TestLog::KernelSource(tess_ctrl_shader) << tcu::TestLog::KernelSource(tess_eval_shader)
7470 << tcu::TestLog::KernelSource(geometry_shader) << tcu::TestLog::KernelSource(fragment_shader);
7479 buffer_attr.Init(Utils::Buffer::Array, Utils::Buffer::StaticDraw, 0, 0);
7481 prepareAttributes(test_case_index, program_interface, buffer_attr, vao);
7484 prepareUniforms(test_case_index, program_interface, program, buffer_u_fs, buffer_u_gs, buffer_u_tcs,
7485 buffer_u_tes, buffer_u_vs);
7487 prepareSSBs(test_case_index, program_interface, program, buffer_ssb_fs, buffer_ssb_gs, buffer_ssb_tcs,
7488 buffer_ssb_tes, buffer_ssb_vs);
7491 prepareFramebuffer(framebuffer, texture_fb);
7494 executeDrawCall(test_case_index);
7497 m_context.getRenderContext().postIterate();
7501 if (false == checkResults(test_case_index, texture_fb))
7503 m_context.getTestContext().getLog()
7504 << tcu::TestLog::Message << "FAILURE. Test case: " << test_name << ". Draw - invalid results."
7505 << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(vertex_shader)
7506 << tcu::TestLog::KernelSource(tess_ctrl_shader) << tcu::TestLog::KernelSource(tess_eval_shader)
7507 << tcu::TestLog::KernelSource(geometry_shader) << tcu::TestLog::KernelSource(fragment_shader);
7514 if (true == isComputeRelevant(test_case_index))
7516 Utils::Buffer buffer_ssb_cs(m_context);
7517 Utils::Buffer buffer_u_cs(m_context);
7518 Utils::Program program(m_context);
7519 Utils::Texture texture_im(m_context);
7520 Utils::VertexArray vao(m_context);
7523 const std::string& compute_shader =
7524 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::COMPUTE);
7526 program.Init(compute_shader, "" /* fragment_shader */, "" /* geometry_shader */, "" /* tess_ctrl_shader */,
7527 "" /* tess_eval_shader */, "" /* vertex_shader */, false /* is_separable */);
7531 std::stringstream stream;
7533 if (false == Utils::checkMonolithicComputeProgramInterface(program, program_interface, stream))
7535 m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7536 << ". Inspection of compute program interface failed:\n"
7537 << stream.str() << tcu::TestLog::EndMessage;
7551 prepareUniforms(test_case_index, program_interface, program, buffer_u_cs);
7553 prepareSSBs(test_case_index, program_interface, program, buffer_ssb_cs);
7556 GLint image_location = program.GetUniformLocation("uni_image");
7557 prepareImage(image_location, texture_im);
7560 executeDispatchCall(test_case_index);
7563 m_context.getRenderContext().postIterate();
7567 if (false == checkResults(test_case_index, texture_im))
7569 m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7570 << ". Compute - invalid results." << tcu::TestLog::EndMessage
7571 << tcu::TestLog::KernelSource(compute_shader);
7580 /** Runs "draw" test with separable program
7582 * @param test_case_index Id of test case
7584 bool TextureTestBase::testSeparable(GLuint test_case_index)
7586 Utils::ProgramInterface program_interface;
7587 Utils::VaryingPassthrough varying_passthrough;
7590 const std::string& test_name = getTestCaseName(test_case_index);
7593 getProgramInterface(test_case_index, program_interface, varying_passthrough);
7597 if (true == isDrawRelevant(test_case_index))
7599 Utils::Buffer buffer_attr(m_context);
7600 Utils::Buffer buffer_u_fs(m_context);
7601 Utils::Buffer buffer_u_gs(m_context);
7602 Utils::Buffer buffer_u_tcs(m_context);
7603 Utils::Buffer buffer_u_tes(m_context);
7604 Utils::Buffer buffer_u_vs(m_context);
7605 Utils::Framebuffer framebuffer(m_context);
7606 Utils::Pipeline pipeline(m_context);
7607 Utils::Program program_fs(m_context);
7608 Utils::Program program_gs(m_context);
7609 Utils::Program program_tcs(m_context);
7610 Utils::Program program_tes(m_context);
7611 Utils::Program program_vs(m_context);
7612 Utils::Texture texture_fb(m_context);
7613 Utils::VertexArray vao(m_context);
7616 const std::string& fs =
7617 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::FRAGMENT);
7618 const std::string& gs =
7619 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::GEOMETRY);
7620 const std::string& tcs =
7621 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::TESS_CTRL);
7622 const std::string& tes =
7623 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::TESS_EVAL);
7624 const std::string& vs =
7625 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::VERTEX);
7627 program_fs.Init("" /*cs*/, fs, "" /*gs*/, "" /*tcs*/, "" /*tes*/, "" /*vs*/, true /* is_separable */);
7628 program_gs.Init("" /*cs*/, "" /*fs*/, gs, "" /*tcs*/, "" /*tes*/, "" /*vs*/, true /* is_separable */);
7629 program_tcs.Init("" /*cs*/, "" /*fs*/, "" /*gs*/, tcs, "" /*tes*/, "" /*vs*/, true /* is_separable */);
7630 program_tes.Init("" /*cs*/, "" /*fs*/, "" /*gs*/, "" /*tcs*/, tes, "" /*vs*/, true /* is_separable */);
7631 program_vs.Init("" /*cs*/, "" /*fs*/, "" /*gs*/, "" /*tcs*/, "" /*tes*/, vs, true /* is_separable */);
7634 prepareAttribLocation(program_vs, program_interface);
7635 prepareFragmentDataLoc(program_vs, program_interface);
7638 std::stringstream stream;
7640 Utils::checkSeparableDrawProgramInterface(program_vs, program_interface, Utils::Shader::VERTEX, stream)) ||
7641 (false == Utils::checkSeparableDrawProgramInterface(program_fs, program_interface, Utils::Shader::FRAGMENT,
7643 (false == Utils::checkSeparableDrawProgramInterface(program_gs, program_interface, Utils::Shader::GEOMETRY,
7645 (false == Utils::checkSeparableDrawProgramInterface(program_tcs, program_interface,
7646 Utils::Shader::TESS_CTRL, stream)) ||
7647 (false == Utils::checkSeparableDrawProgramInterface(program_tes, program_interface,
7648 Utils::Shader::TESS_EVAL, stream)))
7650 m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7651 << ". Inspection of separable draw program interface failed:\n"
7652 << stream.str() << tcu::TestLog::EndMessage
7653 << tcu::TestLog::KernelSource(vs) << tcu::TestLog::KernelSource(tcs)
7654 << tcu::TestLog::KernelSource(tes) << tcu::TestLog::KernelSource(gs)
7655 << tcu::TestLog::KernelSource(fs);
7662 pipeline.UseProgramStages(program_fs.m_id, GL_FRAGMENT_SHADER_BIT);
7663 pipeline.UseProgramStages(program_gs.m_id, GL_GEOMETRY_SHADER_BIT);
7664 pipeline.UseProgramStages(program_tcs.m_id, GL_TESS_CONTROL_SHADER_BIT);
7665 pipeline.UseProgramStages(program_tes.m_id, GL_TESS_EVALUATION_SHADER_BIT);
7666 pipeline.UseProgramStages(program_vs.m_id, GL_VERTEX_SHADER_BIT);
7671 buffer_attr.Init(Utils::Buffer::Array, Utils::Buffer::StaticDraw, 0, 0);
7673 prepareAttributes(test_case_index, program_interface, buffer_attr, vao);
7676 prepareUniforms(test_case_index, program_interface, program_fs, program_gs, program_tcs, program_tes,
7677 program_vs, buffer_u_fs, buffer_u_gs, buffer_u_tcs, buffer_u_tes, buffer_u_vs);
7679 Utils::Program::Use(m_context.getRenderContext().getFunctions(), Utils::Program::m_invalid_id);
7682 prepareFramebuffer(framebuffer, texture_fb);
7685 executeDrawCall(test_case_index);
7688 m_context.getRenderContext().postIterate();
7692 if (false == checkResults(test_case_index, texture_fb))
7694 m_context.getTestContext().getLog()
7695 << tcu::TestLog::Message << "FAILURE. Test case: " << test_name << ". Draw - invalid results."
7696 << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(vs) << tcu::TestLog::KernelSource(tcs)
7697 << tcu::TestLog::KernelSource(tes) << tcu::TestLog::KernelSource(gs) << tcu::TestLog::KernelSource(fs);
7704 if (true == isComputeRelevant(test_case_index))
7706 Utils::Buffer buffer_u_cs(m_context);
7707 Utils::Program program(m_context);
7708 Utils::Texture texture_im(m_context);
7709 Utils::VertexArray vao(m_context);
7712 const std::string& compute_shader =
7713 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::COMPUTE);
7715 program.Init(compute_shader, "" /* fragment_shader */, "" /* geometry_shader */, "" /* tess_ctrl_shader */,
7716 "" /* tess_eval_shader */, "" /* vertex_shader */, false /* is_separable */);
7720 std::stringstream stream;
7722 if (false == Utils::checkMonolithicComputeProgramInterface(program, program_interface, stream))
7724 m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7725 << ". Inspection of compute program interface failed:\n"
7726 << stream.str() << tcu::TestLog::EndMessage;
7740 prepareUniforms(test_case_index, program_interface, program, buffer_u_cs);
7743 GLint image_location = program.GetUniformLocation("uni_image");
7744 prepareImage(image_location, texture_im);
7747 executeDispatchCall(test_case_index);
7750 m_context.getRenderContext().postIterate();
7754 if (false == checkResults(test_case_index, texture_im))
7756 m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7757 << ". Compute - invalid results." << tcu::TestLog::EndMessage
7758 << tcu::TestLog::KernelSource(compute_shader);
7767 /** Basic implementation
7773 bool TextureTestBase::useComponentQualifier(glw::GLuint /* test_case_index */)
7778 /** Basic implementation
7784 bool TextureTestBase::useMonolithicProgram(GLuint /* test_case_index */)
7791 * @param context Test framework context
7793 APIConstantValuesTest::APIConstantValuesTest(deqp::Context& context)
7794 : TestCase(context, "api_constant_values", "Test verifies values of api constants")
7796 /* Nothing to be done here */
7801 * @return tcu::TestNode::STOP otherwise
7803 tcu::TestNode::IterateResult APIConstantValuesTest::iterate()
7805 static const GLuint expected_comp = 64;
7806 static const GLuint expected_xfb = 4;
7807 static const GLuint expected_sep = 4;
7811 bool test_result = true;
7813 const Functions& gl = m_context.getRenderContext().getFunctions();
7815 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_xfb);
7816 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
7817 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_comp);
7818 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
7819 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, &max_sep);
7820 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
7822 if (expected_xfb > (GLuint)max_xfb)
7824 m_context.getTestContext().getLog() << tcu::TestLog::Message
7825 << "Invalid GL_MAX_TRANSFORM_FEEDBACK_BUFFERS. Got " << max_xfb
7826 << " Expected at least " << expected_xfb << tcu::TestLog::EndMessage;
7828 test_result = false;
7831 if (expected_comp > (GLuint)max_comp)
7833 m_context.getTestContext().getLog()
7834 << tcu::TestLog::Message << "Invalid GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS. Got " << max_comp
7835 << " Expected at least " << expected_comp << tcu::TestLog::EndMessage;
7837 test_result = false;
7840 if (expected_sep > (GLuint)max_sep)
7842 m_context.getTestContext().getLog() << tcu::TestLog::Message
7843 << "Invalid GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS. Got " << max_comp
7844 << " Expected at least " << expected_comp << tcu::TestLog::EndMessage;
7846 test_result = false;
7850 if (true == test_result)
7852 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
7856 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
7860 return tcu::TestNode::STOP;
7865 * @param context Test framework context
7867 APIErrorsTest::APIErrorsTest(deqp::Context& context)
7868 : TestCase(context, "api_errors", "Test verifies errors reeturned by api")
7870 /* Nothing to be done here */
7875 * @return tcu::TestNode::STOP otherwise
7877 tcu::TestNode::IterateResult APIErrorsTest::iterate()
7882 Utils::Program program(m_context);
7883 bool test_result = true;
7885 const Functions& gl = m_context.getRenderContext().getFunctions();
7889 program.Init("" /* cs */, "#version 430 core\n"
7890 "#extension GL_ARB_enhanced_layouts : require\n"
7893 "out vec4 fs_out;\n"
7897 " fs_out = vs_fs;\n"
7900 "" /* gs */, "" /* tcs */, "" /* tes */, "#version 430 core\n"
7901 "#extension GL_ARB_enhanced_layouts : require\n"
7904 "layout (xfb_offset = 16) out vec4 vs_fs;\n"
7911 false /* separable */);
7913 catch (Utils::Shader::InvalidSourceException& exc)
7916 TCU_FAIL(exc.what());
7918 catch (Utils::Program::BuildException& exc)
7920 TCU_FAIL(exc.what());
7924 * - GetProgramInterfaceiv should generate INVALID_OPERATION when
7925 * <programInterface> is TRANSFORM_FEEDBACK_BUFFER and <pname> is one of the
7927 * * MAX_NAME_LENGTH,
7928 * * MAX_NUM_ACTIVE_VARIABLES;
7930 gl.getProgramInterfaceiv(program.m_id, GL_TRANSFORM_FEEDBACK_BUFFER, GL_MAX_NAME_LENGTH, ¶m);
7931 checkError(GL_INVALID_OPERATION, "GetProgramInterfaceiv(GL_TRANSFORM_FEEDBACK_BUFFER, GL_MAX_NAME_LENGTH)",
7935 * - GetProgramResourceIndex should generate INVALID_ENUM when
7936 * <programInterface> is TRANSFORM_FEEDBACK_BUFFER;
7938 gl.getProgramResourceIndex(program.m_id, GL_TRANSFORM_FEEDBACK_BUFFER, "0");
7939 checkError(GL_INVALID_ENUM, "GetProgramResourceIndex(GL_TRANSFORM_FEEDBACK_BUFFER)", test_result);
7941 * - GetProgramResourceName should generate INVALID_ENUM when
7942 * <programInterface> is TRANSFORM_FEEDBACK_BUFFER;
7944 gl.getProgramResourceName(program.m_id, GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, 64 /* bufSize */, &length,
7946 checkError(GL_INVALID_ENUM, "GetProgramResourceName(GL_TRANSFORM_FEEDBACK_BUFFER)", test_result);
7949 if (true == test_result)
7951 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
7955 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
7959 return tcu::TestNode::STOP;
7962 /** Check if error is the expected one.
7964 * @param expected_error Expected error
7965 * @param message Message to log in case of error
7966 * @param test_result Test result, set to false in case of invalid error
7968 void APIErrorsTest::checkError(GLenum expected_error, const GLchar* message, bool& test_result)
7970 const Functions& gl = m_context.getRenderContext().getFunctions();
7972 GLenum error = gl.getError();
7974 if (error != expected_error)
7976 m_context.getTestContext().getLog()
7977 << tcu::TestLog::Message << "Failure. Invalid error. Got " << glu::getErrorStr(error) << " expected "
7978 << glu::getErrorStr(expected_error) << " Msg: " << message << tcu::TestLog::EndMessage;
7980 test_result = false;
7986 * @param context Test framework context
7988 GLSLContantImmutablityTest::GLSLContantImmutablityTest(deqp::Context& context)
7989 : NegativeTestBase(context, "glsl_contant_immutablity", "Test verifies that glsl constants cannot be modified")
7991 /* Nothing to be done here */
7994 /** Source for given test case and stage
7996 * @param test_case_index Index of test case
7997 * @param stage Shader stage
7999 * @return Shader source
8001 std::string GLSLContantImmutablityTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
8003 static const GLchar* cs = "#version 430 core\n"
8004 "#extension GL_ARB_enhanced_layouts : require\n"
8006 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
8008 "writeonly uniform uimage2D uni_image;\n"
8012 " uint result = 1u;\n"
8015 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), uvec4(result, 0, 0, 0));\n"
8018 static const GLchar* fs = "#version 430 core\n"
8019 "#extension GL_ARB_enhanced_layouts : require\n"
8022 "out vec4 fs_out;\n"
8027 " fs_out = gs_fs;\n"
8030 static const GLchar* gs = "#version 430 core\n"
8031 "#extension GL_ARB_enhanced_layouts : require\n"
8033 "layout(points) in;\n"
8034 "layout(triangle_strip, max_vertices = 4) out;\n"
8036 "in vec4 tes_gs[];\n"
8042 " gs_fs = tes_gs[0];\n"
8043 " gl_Position = vec4(-1, -1, 0, 1);\n"
8045 " gs_fs = tes_gs[0];\n"
8046 " gl_Position = vec4(-1, 1, 0, 1);\n"
8048 " gs_fs = tes_gs[0];\n"
8049 " gl_Position = vec4(1, -1, 0, 1);\n"
8051 " gs_fs = tes_gs[0];\n"
8052 " gl_Position = vec4(1, 1, 0, 1);\n"
8056 static const GLchar* tcs = "#version 430 core\n"
8057 "#extension GL_ARB_enhanced_layouts : require\n"
8059 "layout(vertices = 1) out;\n"
8061 "in vec4 vs_tcs[];\n"
8062 "out vec4 tcs_tes[];\n"
8068 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
8070 " gl_TessLevelOuter[0] = 1.0;\n"
8071 " gl_TessLevelOuter[1] = 1.0;\n"
8072 " gl_TessLevelOuter[2] = 1.0;\n"
8073 " gl_TessLevelOuter[3] = 1.0;\n"
8074 " gl_TessLevelInner[0] = 1.0;\n"
8075 " gl_TessLevelInner[1] = 1.0;\n"
8078 static const GLchar* tes = "#version 430 core\n"
8079 "#extension GL_ARB_enhanced_layouts : require\n"
8081 "layout(isolines, point_mode) in;\n"
8083 "in vec4 tcs_tes[];\n"
8084 "out vec4 tes_gs;\n"
8089 " tes_gs = tcs_tes[0];\n"
8092 static const GLchar* vs = "#version 430 core\n"
8093 "#extension GL_ARB_enhanced_layouts : require\n"
8096 "out vec4 vs_tcs;\n"
8101 " vs_tcs = in_vs;\n"
8106 testCase& test_case = m_test_cases[test_case_index];
8108 if (Utils::Shader::COMPUTE == test_case.m_stage)
8110 size_t position = 0;
8114 Utils::replaceToken("CONSTANT", position, getConstantName(test_case.m_constant), source);
8118 std::string assignment = " CONSTANT = 3;\n";
8119 size_t position = 0;
8123 case Utils::Shader::FRAGMENT:
8126 case Utils::Shader::GEOMETRY:
8129 case Utils::Shader::TESS_CTRL:
8132 case Utils::Shader::TESS_EVAL:
8135 case Utils::Shader::VERTEX:
8139 TCU_FAIL("Invalid enum");
8142 if (test_case.m_stage == stage)
8144 Utils::replaceToken("CONSTANT", position, getConstantName(test_case.m_constant), assignment);
8152 Utils::replaceToken("ASSIGNMENT", position, assignment.c_str(), source);
8158 /** Get description of test case
8160 * @param test_case_index Index of test case
8162 * @return Constant name
8164 std::string GLSLContantImmutablityTest::getTestCaseName(GLuint test_case_index)
8166 std::string result = getConstantName(m_test_cases[test_case_index].m_constant);
8171 /** Get number of test cases
8173 * @return Number of test cases
8175 GLuint GLSLContantImmutablityTest::getTestCaseNumber()
8177 return static_cast<GLuint>(m_test_cases.size());
8180 /** Selects if "compute" stage is relevant for test
8182 * @param test_case_index Index of test case
8184 * @return true when tested stage is compute
8186 bool GLSLContantImmutablityTest::isComputeRelevant(GLuint test_case_index)
8188 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
8191 /** Prepare all test cases
8194 void GLSLContantImmutablityTest::testInit()
8196 for (GLuint constant = 0; constant < CONSTANTS_MAX; ++constant)
8198 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
8200 testCase test_case = { (CONSTANTS)constant, (Utils::Shader::STAGES)stage };
8202 m_test_cases.push_back(test_case);
8207 /** Get name of glsl constant
8209 * @param Constant id
8211 * @return Name of constant used in GLSL
8213 const GLchar* GLSLContantImmutablityTest::getConstantName(CONSTANTS constant)
8215 const GLchar* name = "";
8219 case GL_ARB_ENHANCED_LAYOUTS:
8220 name = "GL_ARB_enhanced_layouts";
8223 name = "gl_MaxTransformFeedbackBuffers";
8225 case GL_MAX_XFB_INT_COMP:
8226 name = "gl_MaxTransformFeedbackInterleavedComponents";
8229 TCU_FAIL("Invalid enum");
8237 * @param context Test framework context
8239 GLSLContantValuesTest::GLSLContantValuesTest(deqp::Context& context)
8240 : TextureTestBase(context, "glsl_contant_values", "Test verifies values of constant symbols")
8244 /** Selects if "compute" stage is relevant for test
8250 bool GLSLContantValuesTest::isComputeRelevant(GLuint /* test_case_index */)
8255 /** Prepare code snippet that will verify in and uniform variables
8259 * @param stage Shader stage
8261 * @return Code that verify variables
8263 std::string GLSLContantValuesTest::getVerificationSnippet(GLuint /* test_case_index */,
8264 Utils::ProgramInterface& /* program_interface */,
8265 Utils::Shader::STAGES stage)
8268 const Functions& gl = m_context.getRenderContext().getFunctions();
8270 GLint max_transform_feedback_buffers = 0;
8271 GLint max_transform_feedback_interleaved_components = 0;
8273 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_transform_feedback_buffers);
8274 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8275 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_transform_feedback_interleaved_components);
8276 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8278 std::string verification;
8280 if (Utils::Shader::VERTEX == stage)
8282 verification = "if (1 != GL_ARB_enhanced_layouts)\n"
8286 " else if (MAX_TRANSFORM_FEEDBACK_BUFFERS\n"
8287 " != gl_MaxTransformFeedbackBuffers)\n"
8291 " else if (MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS \n"
8292 " != gl_MaxTransformFeedbackInterleavedComponents)\n"
8297 size_t position = 0;
8300 sprintf(buffer, "%d", max_transform_feedback_buffers);
8301 Utils::replaceToken("MAX_TRANSFORM_FEEDBACK_BUFFERS", position, buffer, verification);
8303 sprintf(buffer, "%d", max_transform_feedback_interleaved_components);
8304 Utils::replaceToken("MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS", position, buffer, verification);
8311 return verification;
8316 * @param context Test framework context
8318 GLSLConstantIntegralExpressionTest::GLSLConstantIntegralExpressionTest(deqp::Context& context)
8319 : TextureTestBase(context, "glsl_constant_integral_expression",
8320 "Test verifies that symbols can be used as constant integral expressions")
8324 /** Get interface of program
8327 * @param program_interface Interface of program
8330 void GLSLConstantIntegralExpressionTest::getProgramInterface(GLuint /* test_case_index */,
8331 Utils::ProgramInterface& program_interface,
8332 Utils::VaryingPassthrough& /* varying_passthrough */)
8335 const Functions& gl = m_context.getRenderContext().getFunctions();
8337 GLint max_transform_feedback_buffers = 0;
8338 GLint max_transform_feedback_interleaved_components = 0;
8340 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_transform_feedback_buffers);
8341 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8342 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_transform_feedback_interleaved_components);
8343 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8345 GLuint gohan_div = std::max(1, max_transform_feedback_buffers / 16);
8346 GLuint goten_div = std::max(1, max_transform_feedback_interleaved_components / 16);
8348 m_gohan_length = max_transform_feedback_buffers / gohan_div;
8349 m_goten_length = max_transform_feedback_interleaved_components / goten_div;
8352 std::string globals = "uniform uint goku [GL_ARB_enhanced_layouts / 1];\n"
8353 "uniform uint gohan[gl_MaxTransformFeedbackBuffers / GOHAN_DIV];\n"
8354 "uniform uint goten[gl_MaxTransformFeedbackInterleavedComponents / GOTEN_DIV];\n";
8356 size_t position = 0;
8359 sprintf(buffer, "%d", gohan_div);
8360 Utils::replaceToken("GOHAN_DIV", position, buffer, globals);
8362 sprintf(buffer, "%d", goten_div);
8363 Utils::replaceToken("GOTEN_DIV", position, buffer, globals);
8365 program_interface.m_vertex.m_globals = globals;
8366 program_interface.m_tess_ctrl.m_globals = globals;
8367 program_interface.m_tess_eval.m_globals = globals;
8368 program_interface.m_geometry.m_globals = globals;
8369 program_interface.m_fragment.m_globals = globals;
8370 program_interface.m_compute.m_globals = globals;
8373 /** Prepare code snippet that will verify in and uniform variables
8379 * @return Code that verify variables
8381 std::string GLSLConstantIntegralExpressionTest::getVerificationSnippet(GLuint /* test_case_index */,
8382 Utils::ProgramInterface& /* program_interface */,
8383 Utils::Shader::STAGES /* stage */)
8385 std::string verification = "{\n"
8386 " uint goku_sum = 0;\n"
8387 " uint gohan_sum = 0;\n"
8388 " uint goten_sum = 0;\n"
8390 " for (uint i = 0u; i < goku.length(); ++i)\n"
8392 " goku_sum += goku[i];\n"
8395 " for (uint i = 0u; i < gohan.length(); ++i)\n"
8397 " gohan_sum += gohan[i];\n"
8400 " for (uint i = 0u; i < goten.length(); ++i)\n"
8402 " goten_sum += goten[i];\n"
8405 " if ( (1u != goku_sum) &&\n"
8406 " (EXPECTED_GOHAN_SUMu != gohan_sum) ||\n"
8407 " (EXPECTED_GOTEN_SUMu != goten_sum) )\n"
8413 size_t position = 0;
8416 sprintf(buffer, "%d", m_gohan_length);
8417 Utils::replaceToken("EXPECTED_GOHAN_SUM", position, buffer, verification);
8419 sprintf(buffer, "%d", m_goten_length);
8420 Utils::replaceToken("EXPECTED_GOTEN_SUM", position, buffer, verification);
8422 return verification;
8425 /** Prepare unifroms
8429 * @param program Program object
8432 void GLSLConstantIntegralExpressionTest::prepareUniforms(GLuint /* test_case_index */,
8433 Utils::ProgramInterface& /* program_interface */,
8434 Utils::Program& program, Utils::Buffer& /* cs_buffer */)
8436 static const GLuint uniform_data[16] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
8438 const Functions& gl = m_context.getRenderContext().getFunctions();
8440 GLint goku_location = program.GetUniformLocation("goku");
8441 GLint gohan_location = program.GetUniformLocation("gohan");
8442 GLint goten_location = program.GetUniformLocation("goten");
8444 program.Uniform(gl, Utils::Type::uint, 1 /* count */, goku_location, uniform_data);
8445 program.Uniform(gl, Utils::Type::uint, m_gohan_length, gohan_location, uniform_data);
8446 program.Uniform(gl, Utils::Type::uint, m_goten_length, goten_location, uniform_data);
8449 /** Prepare unifroms
8451 * @param test_case_index Pass as param to first implemetnation
8452 * @param program_interface Pass as param to first implemetnation
8453 * @param program Pass as param to first implemetnation
8458 * @param vs_buffer Pass as param to first implemetnation
8460 void GLSLConstantIntegralExpressionTest::prepareUniforms(GLuint test_case_index,
8461 Utils::ProgramInterface& program_interface,
8462 Utils::Program& program, Utils::Buffer& /* fs_buffer */,
8463 Utils::Buffer& /* gs_buffer */,
8464 Utils::Buffer& /* tcs_buffer */,
8465 Utils::Buffer& /* tes_buffer */, Utils::Buffer& vs_buffer)
8467 /* Call first implementation */
8468 prepareUniforms(test_case_index, program_interface, program, vs_buffer);
8473 * @param context Test framework context
8475 UniformBlockMemberOffsetAndAlignTest::UniformBlockMemberOffsetAndAlignTest(deqp::Context& context)
8476 : TextureTestBase(context, "uniform_block_member_offset_and_align",
8477 "Test verifies offsets and alignment of uniform buffer members")
8481 /** Get interface of program
8483 * @param test_case_index Test case index
8484 * @param program_interface Interface of program
8485 * @param varying_passthrough Collection of connections between in and out variables
8487 void UniformBlockMemberOffsetAndAlignTest::getProgramInterface(GLuint test_case_index,
8488 Utils::ProgramInterface& program_interface,
8489 Utils::VaryingPassthrough& varying_passthrough)
8491 std::string globals = "const int basic_size = BASIC_SIZE;\n"
8492 "const int type_align = TYPE_ALIGN;\n"
8493 "const int type_size = TYPE_SIZE;\n";
8495 Utils::Type type = getType(test_case_index);
8496 GLuint basic_size = Utils::Type::GetTypeSize(type.m_basic_type);
8497 const GLuint base_align = type.GetBaseAlignment(false);
8498 const GLuint array_align = type.GetBaseAlignment(true);
8499 const GLuint base_stride = Utils::Type::CalculateStd140Stride(base_align, type.m_n_columns, 0);
8500 const GLuint type_align = Utils::roundUpToPowerOf2(base_stride);
8502 /* Calculate offsets */
8503 const GLuint first_offset = 0;
8504 const GLuint second_offset = type.GetActualOffset(base_stride, basic_size / 2);
8506 #if WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST
8508 const GLuint third_offset = type.GetActualOffset(second_offset + base_stride, base_align);
8509 const GLuint fourth_offset = type.GetActualOffset(third_offset + base_stride, base_align);
8510 const GLuint fifth_offset = type.GetActualOffset(fourth_offset + base_stride, base_align);
8511 const GLuint sixth_offset = type.GetActualOffset(fifth_offset + base_stride, array_align);
8512 const GLuint seventh_offset = type.GetActualOffset(sixth_offset + base_stride, array_align);
8513 const GLuint eigth_offset = type.GetActualOffset(seventh_offset + base_stride, array_align);
8515 #else /* WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST */
8517 const GLuint third_offset = type.GetActualOffset(second_offset + base_stride, 2 * type_align);
8518 const GLuint fourth_offset = type.GetActualOffset(3 * type_align + base_stride, base_align);
8519 const GLuint fifth_offset = type.GetActualOffset(fourth_offset + base_stride, base_align);
8520 const GLuint sixth_offset = type.GetActualOffset(fifth_offset + base_stride, array_align);
8521 const GLuint seventh_offset = type.GetActualOffset(sixth_offset + base_stride, array_align);
8522 const GLuint eigth_offset = type.GetActualOffset(seventh_offset + base_stride, 8 * basic_size);
8524 #endif /* WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST */
8527 const std::vector<GLubyte>& first = type.GenerateData();
8528 const std::vector<GLubyte>& second = type.GenerateData();
8529 const std::vector<GLubyte>& third = type.GenerateData();
8530 const std::vector<GLubyte>& fourth = type.GenerateData();
8532 m_data.resize(eigth_offset + base_stride);
8533 GLubyte* ptr = &m_data[0];
8534 memcpy(ptr + first_offset, &first[0], first.size());
8535 memcpy(ptr + second_offset, &second[0], second.size());
8536 memcpy(ptr + third_offset, &third[0], third.size());
8537 memcpy(ptr + fourth_offset, &fourth[0], fourth.size());
8538 memcpy(ptr + fifth_offset, &fourth[0], fourth.size());
8539 memcpy(ptr + sixth_offset, &third[0], third.size());
8540 memcpy(ptr + seventh_offset, &second[0], second.size());
8541 memcpy(ptr + eigth_offset, &first[0], first.size());
8543 /* Prepare globals */
8544 size_t position = 0;
8547 sprintf(buffer, "%d", basic_size);
8548 Utils::replaceToken("BASIC_SIZE", position, buffer, globals);
8550 sprintf(buffer, "%d", type_align);
8551 Utils::replaceToken("TYPE_ALIGN", position, buffer, globals);
8553 sprintf(buffer, "%d", base_stride);
8554 Utils::replaceToken("TYPE_SIZE", position, buffer, globals);
8557 Utils::Interface* vs_uni_block = program_interface.Block("vs_uni_Block");
8559 vs_uni_block->Member("at_first_offset", "layout(offset = 0, align = 8 * basic_size)", 0 /* expected_component */,
8560 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
8563 vs_uni_block->Member("at_second_offset", "layout(offset = type_size, align = basic_size / 2)",
8564 0 /* expected_component */, 0 /* expected_location */, type, false /* normalized */,
8565 0 /* n_array_elements */, base_stride, second_offset);
8567 vs_uni_block->Member("at_third_offset", "layout(align = 2 * type_align)", 0 /* expected_component */,
8568 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
8571 vs_uni_block->Member("at_fourth_offset", "layout(offset = 3 * type_align + type_size)", 0 /* expected_component */,
8572 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
8575 vs_uni_block->Member("at_fifth_offset", "", 0 /* expected_component */, 0 /* expected_location */, type,
8576 false /* normalized */, 0 /* n_array_elements */, base_stride, fifth_offset);
8578 vs_uni_block->Member("at_sixth_offset", "", 0 /* expected_component */, 0 /* expected_location */, type,
8579 false /* normalized */, 2 /* n_array_elements */, array_align * 2, sixth_offset);
8581 vs_uni_block->Member("at_eigth_offset", "layout(align = 8 * basic_size)", 0 /* expected_component */,
8582 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
8585 Utils::ShaderInterface& vs_si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
8588 vs_si.m_globals = globals;
8590 /* Add uniform BLOCK */
8591 vs_si.Uniform("vs_uni_block", "layout (std140, binding = BINDING)", 0, 0, vs_uni_block, 0,
8592 static_cast<glw::GLint>(m_data.size()), 0, &m_data[0], m_data.size());
8595 program_interface.CloneVertexInterface(varying_passthrough);
8600 * @param test_case_index Index of test case
8602 * @return Name of type test in test_case_index
8604 std::string UniformBlockMemberOffsetAndAlignTest::getTestCaseName(glw::GLuint test_case_index)
8606 return getTypeName(test_case_index);
8609 /** Returns number of types to test
8611 * @return Number of types, 34
8613 glw::GLuint UniformBlockMemberOffsetAndAlignTest::getTestCaseNumber()
8615 return getTypesNumber();
8618 /** Prepare code snippet that will verify in and uniform variables
8622 * @param stage Shader stage
8624 * @return Code that verify variables
8626 std::string UniformBlockMemberOffsetAndAlignTest::getVerificationSnippet(
8627 GLuint /* test_case_index */, Utils::ProgramInterface& /* program_interface */, Utils::Shader::STAGES stage)
8629 std::string verification = "if ( (PREFIXblock.at_first_offset != PREFIXblock.at_eigth_offset ) ||\n"
8630 " (PREFIXblock.at_second_offset != PREFIXblock.at_sixth_offset[1]) ||\n"
8631 " (PREFIXblock.at_third_offset != PREFIXblock.at_sixth_offset[0]) ||\n"
8632 " (PREFIXblock.at_fourth_offset != PREFIXblock.at_fifth_offset ) )\n"
8637 const GLchar* prefix = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::UNIFORM);
8639 Utils::replaceAllTokens("PREFIX", prefix, verification);
8641 return verification;
8646 * @param context Test framework context
8648 UniformBlockLayoutQualifierConflictTest::UniformBlockLayoutQualifierConflictTest(deqp::Context& context)
8650 context, "uniform_block_layout_qualifier_conflict",
8651 "Test verifies that std140 is required when offset and/or align qualifiers are used with uniform block")
8653 /* Nothing to be done here */
8656 /** Source for given test case and stage
8658 * @param test_case_index Index of test case
8659 * @param stage Shader stage
8661 * @return Shader source
8663 std::string UniformBlockLayoutQualifierConflictTest::getShaderSource(GLuint test_case_index,
8664 Utils::Shader::STAGES stage)
8666 static const GLchar* cs = "#version 430 core\n"
8667 "#extension GL_ARB_enhanced_layouts : require\n"
8669 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
8671 "LAYOUTuniform Block {\n"
8672 " layout(offset = 16) vec4 boy;\n"
8673 " layout(align = 64) vec4 man;\n"
8676 "writeonly uniform image2D uni_image;\n"
8680 " vec4 result = uni_block.boy + uni_block.man;\n"
8682 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
8685 static const GLchar* fs = "#version 430 core\n"
8686 "#extension GL_ARB_enhanced_layouts : require\n"
8688 "LAYOUTuniform Block {\n"
8689 " layout(offset = 16) vec4 boy;\n"
8690 " layout(align = 64) vec4 man;\n"
8694 "out vec4 fs_out;\n"
8698 " fs_out = gs_fs + uni_block.boy + uni_block.man;\n"
8701 static const GLchar* gs = "#version 430 core\n"
8702 "#extension GL_ARB_enhanced_layouts : require\n"
8704 "layout(points) in;\n"
8705 "layout(triangle_strip, max_vertices = 4) out;\n"
8707 "LAYOUTuniform Block {\n"
8708 " layout(offset = 16) vec4 boy;\n"
8709 " layout(align = 64) vec4 man;\n"
8712 "in vec4 tes_gs[];\n"
8717 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
8718 " gl_Position = vec4(-1, -1, 0, 1);\n"
8720 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
8721 " gl_Position = vec4(-1, 1, 0, 1);\n"
8723 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
8724 " gl_Position = vec4(1, -1, 0, 1);\n"
8726 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
8727 " gl_Position = vec4(1, 1, 0, 1);\n"
8731 static const GLchar* tcs =
8732 "#version 430 core\n"
8733 "#extension GL_ARB_enhanced_layouts : require\n"
8735 "layout(vertices = 1) out;\n"
8737 "LAYOUTuniform Block {\n"
8738 " layout(offset = 16) vec4 boy;\n"
8739 " layout(align = 64) vec4 man;\n"
8742 "in vec4 vs_tcs[];\n"
8743 "out vec4 tcs_tes[];\n"
8748 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID] + uni_block.boy + uni_block.man;\n"
8750 " gl_TessLevelOuter[0] = 1.0;\n"
8751 " gl_TessLevelOuter[1] = 1.0;\n"
8752 " gl_TessLevelOuter[2] = 1.0;\n"
8753 " gl_TessLevelOuter[3] = 1.0;\n"
8754 " gl_TessLevelInner[0] = 1.0;\n"
8755 " gl_TessLevelInner[1] = 1.0;\n"
8758 static const GLchar* tes = "#version 430 core\n"
8759 "#extension GL_ARB_enhanced_layouts : require\n"
8761 "layout(isolines, point_mode) in;\n"
8763 "LAYOUTuniform Block {\n"
8764 " layout(offset = 16) vec4 boy;\n"
8765 " layout(align = 64) vec4 man;\n"
8768 "in vec4 tcs_tes[];\n"
8769 "out vec4 tes_gs;\n"
8773 " tes_gs = tcs_tes[0] + uni_block.boy + uni_block.man;\n"
8776 static const GLchar* vs = "#version 430 core\n"
8777 "#extension GL_ARB_enhanced_layouts : require\n"
8779 "LAYOUTuniform Block {\n"
8780 " layout(offset = 16) vec4 boy;\n"
8781 " layout(align = 64) vec4 man;\n"
8785 "out vec4 vs_tcs;\n"
8789 " vs_tcs = in_vs + uni_block.boy + uni_block.man;\n"
8793 std::string layout = "";
8794 size_t position = 0;
8795 testCase& test_case = m_test_cases[test_case_index];
8796 const GLchar* qualifier = getQualifierName(test_case.m_qualifier);
8799 if (0 != qualifier[0])
8801 size_t layout_position = 0;
8803 layout = "layout (QUALIFIER) ";
8805 Utils::replaceToken("QUALIFIER", layout_position, qualifier, layout);
8810 case Utils::Shader::COMPUTE:
8813 case Utils::Shader::FRAGMENT:
8816 case Utils::Shader::GEOMETRY:
8819 case Utils::Shader::TESS_CTRL:
8822 case Utils::Shader::TESS_EVAL:
8825 case Utils::Shader::VERTEX:
8829 TCU_FAIL("Invalid enum");
8832 if (test_case.m_stage == stage)
8834 Utils::replaceToken("LAYOUT", position, layout.c_str(), source);
8838 Utils::replaceToken("LAYOUT", position, "layout (std140) ", source);
8844 /** Get description of test case
8846 * @param test_case_index Index of test case
8848 * @return Qualifier name
8850 std::string UniformBlockLayoutQualifierConflictTest::getTestCaseName(GLuint test_case_index)
8852 std::string result = getQualifierName(m_test_cases[test_case_index].m_qualifier);
8857 /** Get number of test cases
8859 * @return Number of test cases
8861 GLuint UniformBlockLayoutQualifierConflictTest::getTestCaseNumber()
8863 return static_cast<GLuint>(m_test_cases.size());
8866 /** Selects if "compute" stage is relevant for test
8868 * @param test_case_index Index of test case
8870 * @return true when tested stage is compute
8872 bool UniformBlockLayoutQualifierConflictTest::isComputeRelevant(GLuint test_case_index)
8874 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
8877 /** Selects if compilation failure is expected result
8879 * @param test_case_index Index of test case
8881 * @return false for STD140 cases, true otherwise
8883 bool UniformBlockLayoutQualifierConflictTest::isFailureExpected(GLuint test_case_index)
8885 return (STD140 != m_test_cases[test_case_index].m_qualifier);
8888 /** Prepare all test cases
8891 void UniformBlockLayoutQualifierConflictTest::testInit()
8893 for (GLuint qualifier = 0; qualifier < QUALIFIERS_MAX; ++qualifier)
8895 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
8897 testCase test_case = { (QUALIFIERS)qualifier, (Utils::Shader::STAGES)stage };
8899 m_test_cases.push_back(test_case);
8904 /** Get name of glsl constant
8906 * @param Constant id
8908 * @return Name of constant used in GLSL
8910 const GLchar* UniformBlockLayoutQualifierConflictTest::getQualifierName(QUALIFIERS qualifier)
8912 const GLchar* name = "";
8929 TCU_FAIL("Invalid enum");
8937 * @param context Test framework context
8939 UniformBlockMemberInvalidOffsetAlignmentTest::UniformBlockMemberInvalidOffsetAlignmentTest(deqp::Context& context)
8940 : NegativeTestBase(context, "uniform_block_member_invalid_offset_alignment",
8941 "Test verifies that invalid alignment of offset qualifiers cause compilation failure")
8943 /* Nothing to be done here */
8948 * @param context Test framework context
8949 * @param name Test name
8950 * @param description Test description
8952 UniformBlockMemberInvalidOffsetAlignmentTest::UniformBlockMemberInvalidOffsetAlignmentTest(
8953 deqp::Context& context, const glw::GLchar* name, const glw::GLchar* description)
8954 : NegativeTestBase(context, name, description)
8956 /* Nothing to be done here */
8959 /** Source for given test case and stage
8961 * @param test_case_index Index of test case
8962 * @param stage Shader stage
8964 * @return Shader source
8966 std::string UniformBlockMemberInvalidOffsetAlignmentTest::getShaderSource(GLuint test_case_index,
8967 Utils::Shader::STAGES stage)
8969 static const GLchar* cs = "#version 430 core\n"
8970 "#extension GL_ARB_enhanced_layouts : require\n"
8972 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
8974 "layout (std140) uniform Block {\n"
8975 " layout (offset = OFFSET) TYPE member;\n"
8978 "writeonly uniform image2D uni_image;\n"
8982 " vec4 result = vec4(1, 0, 0.5, 1);\n"
8984 " if (TYPE(1) == block.member)\n"
8986 " result = vec4(1, 1, 1, 1);\n"
8989 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
8992 static const GLchar* fs = "#version 430 core\n"
8993 "#extension GL_ARB_enhanced_layouts : require\n"
8996 "out vec4 fs_out;\n"
9000 " fs_out = gs_fs;\n"
9003 static const GLchar* fs_tested = "#version 430 core\n"
9004 "#extension GL_ARB_enhanced_layouts : require\n"
9006 "layout (std140) uniform Block {\n"
9007 " layout (offset = OFFSET) TYPE member;\n"
9011 "out vec4 fs_out;\n"
9015 " if (TYPE(1) == block.member)\n"
9017 " fs_out = vec4(1, 1, 1, 1);\n"
9020 " fs_out += gs_fs;\n"
9023 static const GLchar* gs = "#version 430 core\n"
9024 "#extension GL_ARB_enhanced_layouts : require\n"
9026 "layout(points) in;\n"
9027 "layout(triangle_strip, max_vertices = 4) out;\n"
9029 "in vec4 tes_gs[];\n"
9034 " gs_fs = tes_gs[0];\n"
9035 " gl_Position = vec4(-1, -1, 0, 1);\n"
9037 " gs_fs = tes_gs[0];\n"
9038 " gl_Position = vec4(-1, 1, 0, 1);\n"
9040 " gs_fs = tes_gs[0];\n"
9041 " gl_Position = vec4(1, -1, 0, 1);\n"
9043 " gs_fs = tes_gs[0];\n"
9044 " gl_Position = vec4(1, 1, 0, 1);\n"
9048 static const GLchar* gs_tested = "#version 430 core\n"
9049 "#extension GL_ARB_enhanced_layouts : require\n"
9051 "layout(points) in;\n"
9052 "layout(triangle_strip, max_vertices = 4) out;\n"
9054 "layout (std140) uniform Block {\n"
9055 " layout (offset = OFFSET) TYPE member;\n"
9058 "in vec4 tes_gs[];\n"
9063 " if (TYPE(1) == block.member)\n"
9065 " gs_fs = vec4(1, 1, 1, 1);\n"
9068 " gs_fs += tes_gs[0];\n"
9069 " gl_Position = vec4(-1, -1, 0, 1);\n"
9071 " gs_fs += tes_gs[0];\n"
9072 " gl_Position = vec4(-1, 1, 0, 1);\n"
9074 " gs_fs += tes_gs[0];\n"
9075 " gl_Position = vec4(1, -1, 0, 1);\n"
9077 " gs_fs += tes_gs[0];\n"
9078 " gl_Position = vec4(1, 1, 0, 1);\n"
9082 static const GLchar* tcs = "#version 430 core\n"
9083 "#extension GL_ARB_enhanced_layouts : require\n"
9085 "layout(vertices = 1) out;\n"
9087 "in vec4 vs_tcs[];\n"
9088 "out vec4 tcs_tes[];\n"
9093 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
9095 " gl_TessLevelOuter[0] = 1.0;\n"
9096 " gl_TessLevelOuter[1] = 1.0;\n"
9097 " gl_TessLevelOuter[2] = 1.0;\n"
9098 " gl_TessLevelOuter[3] = 1.0;\n"
9099 " gl_TessLevelInner[0] = 1.0;\n"
9100 " gl_TessLevelInner[1] = 1.0;\n"
9103 static const GLchar* tcs_tested = "#version 430 core\n"
9104 "#extension GL_ARB_enhanced_layouts : require\n"
9106 "layout(vertices = 1) out;\n"
9108 "layout (std140) uniform Block {\n"
9109 " layout (offset = OFFSET) TYPE member;\n"
9112 "in vec4 vs_tcs[];\n"
9113 "out vec4 tcs_tes[];\n"
9117 " if (TYPE(1) == block.member)\n"
9119 " tcs_tes[gl_InvocationID] = vec4(1, 1, 1, 1);\n"
9123 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
9125 " gl_TessLevelOuter[0] = 1.0;\n"
9126 " gl_TessLevelOuter[1] = 1.0;\n"
9127 " gl_TessLevelOuter[2] = 1.0;\n"
9128 " gl_TessLevelOuter[3] = 1.0;\n"
9129 " gl_TessLevelInner[0] = 1.0;\n"
9130 " gl_TessLevelInner[1] = 1.0;\n"
9133 static const GLchar* tes = "#version 430 core\n"
9134 "#extension GL_ARB_enhanced_layouts : require\n"
9136 "layout(isolines, point_mode) in;\n"
9138 "in vec4 tcs_tes[];\n"
9139 "out vec4 tes_gs;\n"
9143 " tes_gs = tcs_tes[0];\n"
9146 static const GLchar* tes_tested = "#version 430 core\n"
9147 "#extension GL_ARB_enhanced_layouts : require\n"
9149 "layout(isolines, point_mode) in;\n"
9151 "layout (std140) uniform Block {\n"
9152 " layout (offset = OFFSET) TYPE member;\n"
9155 "in vec4 tcs_tes[];\n"
9156 "out vec4 tes_gs;\n"
9160 " if (TYPE(1) == block.member)\n"
9162 " tes_gs = vec4(1, 1, 1, 1);\n"
9165 " tes_gs += tcs_tes[0];\n"
9168 static const GLchar* vs = "#version 430 core\n"
9169 "#extension GL_ARB_enhanced_layouts : require\n"
9172 "out vec4 vs_tcs;\n"
9176 " vs_tcs = in_vs;\n"
9179 static const GLchar* vs_tested = "#version 430 core\n"
9180 "#extension GL_ARB_enhanced_layouts : require\n"
9182 "layout (std140) uniform Block {\n"
9183 " layout (offset = OFFSET) TYPE member;\n"
9187 "out vec4 vs_tcs;\n"
9191 " if (TYPE(1) == block.member)\n"
9193 " vs_tcs = vec4(1, 1, 1, 1);\n"
9196 " vs_tcs += in_vs;\n"
9201 testCase& test_case = m_test_cases[test_case_index];
9203 if (test_case.m_stage == stage)
9206 const GLuint offset = test_case.m_offset;
9207 size_t position = 0;
9208 const Utils::Type& type = test_case.m_type;
9209 const GLchar* type_name = type.GetGLSLTypeName();
9211 sprintf(buffer, "%d", offset);
9215 case Utils::Shader::COMPUTE:
9218 case Utils::Shader::FRAGMENT:
9221 case Utils::Shader::GEOMETRY:
9224 case Utils::Shader::TESS_CTRL:
9225 source = tcs_tested;
9227 case Utils::Shader::TESS_EVAL:
9228 source = tes_tested;
9230 case Utils::Shader::VERTEX:
9234 TCU_FAIL("Invalid enum");
9237 Utils::replaceToken("OFFSET", position, buffer, source);
9238 Utils::replaceToken("TYPE", position, type_name, source);
9239 Utils::replaceToken("TYPE", position, type_name, source);
9245 case Utils::Shader::FRAGMENT:
9248 case Utils::Shader::GEOMETRY:
9251 case Utils::Shader::TESS_CTRL:
9254 case Utils::Shader::TESS_EVAL:
9257 case Utils::Shader::VERTEX:
9261 TCU_FAIL("Invalid enum");
9268 /** Get description of test case
9270 * @param test_case_index Index of test case
9272 * @return Type name and offset
9274 std::string UniformBlockMemberInvalidOffsetAlignmentTest::getTestCaseName(GLuint test_case_index)
9276 std::stringstream stream;
9277 testCase& test_case = m_test_cases[test_case_index];
9279 stream << "Type: " << test_case.m_type.GetGLSLTypeName() << ", offset: " << test_case.m_offset;
9281 return stream.str();
9284 /** Get number of test cases
9286 * @return Number of test cases
9288 GLuint UniformBlockMemberInvalidOffsetAlignmentTest::getTestCaseNumber()
9290 return static_cast<GLuint>(m_test_cases.size());
9293 /** Selects if "compute" stage is relevant for test
9295 * @param test_case_index Index of test case
9297 * @return true when tested stage is compute
9299 bool UniformBlockMemberInvalidOffsetAlignmentTest::isComputeRelevant(GLuint test_case_index)
9301 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
9304 /** Selects if compilation failure is expected result
9306 * @param test_case_index Index of test case
9308 * @return should_fail field from testCase
9310 bool UniformBlockMemberInvalidOffsetAlignmentTest::isFailureExpected(GLuint test_case_index)
9312 return m_test_cases[test_case_index].m_should_fail;
9315 /** Checks if stage is supported
9317 * @param stage ignored
9321 bool UniformBlockMemberInvalidOffsetAlignmentTest::isStageSupported(Utils::Shader::STAGES /* stage */)
9326 /** Prepare all test cases
9329 void UniformBlockMemberInvalidOffsetAlignmentTest::testInit()
9331 const Functions& gl = m_context.getRenderContext().getFunctions();
9333 const GLuint n_types = getTypesNumber();
9334 bool stage_support[Utils::Shader::STAGE_MAX];
9336 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
9338 stage_support[stage] = isStageSupported((Utils::Shader::STAGES)stage);
9341 gl.getIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &max_size);
9342 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
9344 for (GLuint i = 0; i < n_types; ++i)
9346 const Utils::Type& type = getType(i);
9347 const GLuint alignment = type.GetBaseAlignment(false);
9348 const GLuint type_size = type.GetSize();
9349 const GLuint sec_to_end = max_size - 2 * type_size;
9351 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
9353 if (false == stage_support[stage])
9358 for (GLuint offset = 0; offset <= type_size; ++offset)
9360 const GLuint modulo = offset % alignment;
9361 const bool is_aligned = (0 == modulo) ? true : false;
9362 const bool should_fail = !is_aligned;
9364 testCase test_case = { offset, should_fail, (Utils::Shader::STAGES)stage, type };
9366 m_test_cases.push_back(test_case);
9369 for (GLuint offset = sec_to_end; offset <= sec_to_end + type_size; ++offset)
9371 const GLuint modulo = offset % alignment;
9372 const bool is_aligned = (0 == modulo) ? true : false;
9373 const bool should_fail = !is_aligned;
9375 testCase test_case = { offset, should_fail, (Utils::Shader::STAGES)stage, type };
9377 m_test_cases.push_back(test_case);
9385 * @param context Test framework context
9387 UniformBlockMemberOverlappingOffsetsTest::UniformBlockMemberOverlappingOffsetsTest(deqp::Context& context)
9388 : NegativeTestBase(context, "uniform_block_member_overlapping_offsets",
9389 "Test verifies that overlapping offsets qualifiers cause compilation failure")
9391 /* Nothing to be done here */
9396 * @param context Test framework context
9397 * @param name Test name
9398 * @param description Test description
9400 UniformBlockMemberOverlappingOffsetsTest::UniformBlockMemberOverlappingOffsetsTest(deqp::Context& context,
9401 const glw::GLchar* name,
9402 const glw::GLchar* description)
9403 : NegativeTestBase(context, name, description)
9405 /* Nothing to be done here */
9408 /** Source for given test case and stage
9410 * @param test_case_index Index of test case
9411 * @param stage Shader stage
9413 * @return Shader source
9415 std::string UniformBlockMemberOverlappingOffsetsTest::getShaderSource(GLuint test_case_index,
9416 Utils::Shader::STAGES stage)
9418 static const GLchar* cs = "#version 430 core\n"
9419 "#extension GL_ARB_enhanced_layouts : require\n"
9421 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
9423 "layout (std140) uniform Block {\n"
9424 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9425 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9428 "writeonly uniform image2D uni_image;\n"
9432 " vec4 result = vec4(1, 0, 0.5, 1);\n"
9434 " if ((BOY_TYPE(1) == block.boy) ||\n"
9435 " (MAN_TYPE(0) == block.man) )\n"
9437 " result = vec4(1, 1, 1, 1);\n"
9440 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
9443 static const GLchar* fs = "#version 430 core\n"
9444 "#extension GL_ARB_enhanced_layouts : require\n"
9447 "out vec4 fs_out;\n"
9451 " fs_out = gs_fs;\n"
9454 static const GLchar* fs_tested = "#version 430 core\n"
9455 "#extension GL_ARB_enhanced_layouts : require\n"
9457 "layout (std140) uniform Block {\n"
9458 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9459 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9463 "out vec4 fs_out;\n"
9467 " if ((BOY_TYPE(1) == block.boy) ||\n"
9468 " (MAN_TYPE(0) == block.man) )\n"
9470 " fs_out = vec4(1, 1, 1, 1);\n"
9473 " fs_out += gs_fs;\n"
9476 static const GLchar* gs = "#version 430 core\n"
9477 "#extension GL_ARB_enhanced_layouts : require\n"
9479 "layout(points) in;\n"
9480 "layout(triangle_strip, max_vertices = 4) out;\n"
9482 "in vec4 tes_gs[];\n"
9487 " gs_fs = tes_gs[0];\n"
9488 " gl_Position = vec4(-1, -1, 0, 1);\n"
9490 " gs_fs = tes_gs[0];\n"
9491 " gl_Position = vec4(-1, 1, 0, 1);\n"
9493 " gs_fs = tes_gs[0];\n"
9494 " gl_Position = vec4(1, -1, 0, 1);\n"
9496 " gs_fs = tes_gs[0];\n"
9497 " gl_Position = vec4(1, 1, 0, 1);\n"
9501 static const GLchar* gs_tested = "#version 430 core\n"
9502 "#extension GL_ARB_enhanced_layouts : require\n"
9504 "layout(points) in;\n"
9505 "layout(triangle_strip, max_vertices = 4) out;\n"
9507 "layout (std140) uniform Block {\n"
9508 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9509 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9512 "in vec4 tes_gs[];\n"
9517 " if ((BOY_TYPE(1) == block.boy) ||\n"
9518 " (MAN_TYPE(0) == block.man) )\n"
9520 " gs_fs = vec4(1, 1, 1, 1);\n"
9523 " gs_fs += tes_gs[0];\n"
9524 " gl_Position = vec4(-1, -1, 0, 1);\n"
9526 " gs_fs += tes_gs[0];\n"
9527 " gl_Position = vec4(-1, 1, 0, 1);\n"
9529 " gs_fs += tes_gs[0];\n"
9530 " gl_Position = vec4(1, -1, 0, 1);\n"
9532 " gs_fs += tes_gs[0];\n"
9533 " gl_Position = vec4(1, 1, 0, 1);\n"
9537 static const GLchar* tcs = "#version 430 core\n"
9538 "#extension GL_ARB_enhanced_layouts : require\n"
9540 "layout(vertices = 1) out;\n"
9542 "in vec4 vs_tcs[];\n"
9543 "out vec4 tcs_tes[];\n"
9548 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
9550 " gl_TessLevelOuter[0] = 1.0;\n"
9551 " gl_TessLevelOuter[1] = 1.0;\n"
9552 " gl_TessLevelOuter[2] = 1.0;\n"
9553 " gl_TessLevelOuter[3] = 1.0;\n"
9554 " gl_TessLevelInner[0] = 1.0;\n"
9555 " gl_TessLevelInner[1] = 1.0;\n"
9558 static const GLchar* tcs_tested = "#version 430 core\n"
9559 "#extension GL_ARB_enhanced_layouts : require\n"
9561 "layout(vertices = 1) out;\n"
9563 "layout (std140) uniform Block {\n"
9564 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9565 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9568 "in vec4 vs_tcs[];\n"
9569 "out vec4 tcs_tes[];\n"
9573 " if ((BOY_TYPE(1) == block.boy) ||\n"
9574 " (MAN_TYPE(0) == block.man) )\n"
9576 " tcs_tes[gl_InvocationID] = vec4(1, 1, 1, 1);\n"
9580 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
9582 " gl_TessLevelOuter[0] = 1.0;\n"
9583 " gl_TessLevelOuter[1] = 1.0;\n"
9584 " gl_TessLevelOuter[2] = 1.0;\n"
9585 " gl_TessLevelOuter[3] = 1.0;\n"
9586 " gl_TessLevelInner[0] = 1.0;\n"
9587 " gl_TessLevelInner[1] = 1.0;\n"
9590 static const GLchar* tes = "#version 430 core\n"
9591 "#extension GL_ARB_enhanced_layouts : require\n"
9593 "layout(isolines, point_mode) in;\n"
9595 "in vec4 tcs_tes[];\n"
9596 "out vec4 tes_gs;\n"
9600 " tes_gs = tcs_tes[0];\n"
9603 static const GLchar* tes_tested = "#version 430 core\n"
9604 "#extension GL_ARB_enhanced_layouts : require\n"
9606 "layout(isolines, point_mode) in;\n"
9608 "layout (std140) uniform Block {\n"
9609 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9610 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9613 "in vec4 tcs_tes[];\n"
9614 "out vec4 tes_gs;\n"
9618 " if ((BOY_TYPE(1) == block.boy) ||\n"
9619 " (MAN_TYPE(0) == block.man) )\n"
9621 " tes_gs = vec4(1, 1, 1, 1);\n"
9624 " tes_gs += tcs_tes[0];\n"
9627 static const GLchar* vs = "#version 430 core\n"
9628 "#extension GL_ARB_enhanced_layouts : require\n"
9631 "out vec4 vs_tcs;\n"
9635 " vs_tcs = in_vs;\n"
9638 static const GLchar* vs_tested = "#version 430 core\n"
9639 "#extension GL_ARB_enhanced_layouts : require\n"
9641 "layout (std140) uniform Block {\n"
9642 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9643 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9647 "out vec4 vs_tcs;\n"
9651 " if ((BOY_TYPE(1) == block.boy) ||\n"
9652 " (MAN_TYPE(0) == block.man) )\n"
9654 " vs_tcs = vec4(1, 1, 1, 1);\n"
9657 " vs_tcs += in_vs;\n"
9662 testCase& test_case = m_test_cases[test_case_index];
9664 if (test_case.m_stage == stage)
9667 const GLuint boy_offset = test_case.m_boy_offset;
9668 const Utils::Type& boy_type = test_case.m_boy_type;
9669 const GLchar* boy_type_name = boy_type.GetGLSLTypeName();
9670 const GLuint man_offset = test_case.m_man_offset;
9671 const Utils::Type& man_type = test_case.m_man_type;
9672 const GLchar* man_type_name = man_type.GetGLSLTypeName();
9673 size_t position = 0;
9677 case Utils::Shader::COMPUTE:
9680 case Utils::Shader::FRAGMENT:
9683 case Utils::Shader::GEOMETRY:
9686 case Utils::Shader::TESS_CTRL:
9687 source = tcs_tested;
9689 case Utils::Shader::TESS_EVAL:
9690 source = tes_tested;
9692 case Utils::Shader::VERTEX:
9696 TCU_FAIL("Invalid enum");
9699 sprintf(buffer, "%d", boy_offset);
9700 Utils::replaceToken("BOY_OFFSET", position, buffer, source);
9701 Utils::replaceToken("BOY_TYPE", position, boy_type_name, source);
9702 sprintf(buffer, "%d", man_offset);
9703 Utils::replaceToken("MAN_OFFSET", position, buffer, source);
9704 Utils::replaceToken("MAN_TYPE", position, man_type_name, source);
9705 Utils::replaceToken("BOY_TYPE", position, boy_type_name, source);
9706 Utils::replaceToken("MAN_TYPE", position, man_type_name, source);
9712 case Utils::Shader::FRAGMENT:
9715 case Utils::Shader::GEOMETRY:
9718 case Utils::Shader::TESS_CTRL:
9721 case Utils::Shader::TESS_EVAL:
9724 case Utils::Shader::VERTEX:
9728 TCU_FAIL("Invalid enum");
9735 /** Get description of test case
9737 * @param test_case_index Index of test case
9739 * @return Type name and offset
9741 std::string UniformBlockMemberOverlappingOffsetsTest::getTestCaseName(GLuint test_case_index)
9743 std::stringstream stream;
9744 testCase& test_case = m_test_cases[test_case_index];
9746 stream << "Type: " << test_case.m_boy_type.GetGLSLTypeName() << ", offset: " << test_case.m_boy_offset
9747 << ". Type: " << test_case.m_man_type.GetGLSLTypeName() << ", offset: " << test_case.m_man_offset;
9749 return stream.str();
9752 /** Get number of test cases
9754 * @return Number of test cases
9756 GLuint UniformBlockMemberOverlappingOffsetsTest::getTestCaseNumber()
9758 return static_cast<GLuint>(m_test_cases.size());
9761 /** Selects if "compute" stage is relevant for test
9763 * @param test_case_index Index of test case
9765 * @return true when tested stage is compute
9767 bool UniformBlockMemberOverlappingOffsetsTest::isComputeRelevant(GLuint test_case_index)
9769 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
9772 /** Checks if stage is supported
9774 * @param stage ignored
9778 bool UniformBlockMemberOverlappingOffsetsTest::isStageSupported(Utils::Shader::STAGES /* stage */)
9783 /** Prepare all test cases
9786 void UniformBlockMemberOverlappingOffsetsTest::testInit()
9788 const GLuint n_types = getTypesNumber();
9789 bool stage_support[Utils::Shader::STAGE_MAX];
9791 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
9793 stage_support[stage] = isStageSupported((Utils::Shader::STAGES)stage);
9796 for (GLuint i = 0; i < n_types; ++i)
9798 const Utils::Type& boy_type = getType(i);
9799 const GLuint boy_size = boy_type.GetActualAlignment(1 /* align */, false /* is_array*/);
9801 for (GLuint j = 0; j < n_types; ++j)
9803 const Utils::Type& man_type = getType(j);
9804 const GLuint man_align = man_type.GetBaseAlignment(false);
9805 const GLuint man_size = man_type.GetActualAlignment(1 /* align */, false /* is_array*/);
9807 const GLuint boy_offset = lcm(boy_size, man_size);
9808 const GLuint man_after_start = boy_offset + 1;
9809 const GLuint man_after_off = man_type.GetActualOffset(man_after_start, man_size);
9810 const GLuint man_before_start = boy_offset - man_align;
9811 const GLuint man_before_off = man_type.GetActualOffset(man_before_start, man_size);
9813 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
9815 if (false == stage_support[stage])
9820 if ((boy_offset > man_before_off) && (boy_offset < man_before_off + man_size))
9822 testCase test_case = { boy_offset, boy_type, man_before_off, man_type,
9823 (Utils::Shader::STAGES)stage };
9825 m_test_cases.push_back(test_case);
9828 if ((boy_offset < man_after_off) && (boy_offset + boy_size > man_after_off))
9830 testCase test_case = { boy_offset, boy_type, man_after_off, man_type,
9831 (Utils::Shader::STAGES)stage };
9833 m_test_cases.push_back(test_case);
9836 /* Boy offset, should be fine for both types */
9837 testCase test_case = { boy_offset, boy_type, boy_offset, man_type, (Utils::Shader::STAGES)stage };
9839 m_test_cases.push_back(test_case);
9845 /** Find greatest common divisor for a and b
9847 * @param a A argument
9848 * @param b B argument
9850 * @return Found gcd value
9852 GLuint UniformBlockMemberOverlappingOffsetsTest::gcd(GLuint a, GLuint b)
9854 if ((0 != a) && (0 == b))
9860 GLuint greater = std::max(a, b);
9861 GLuint lesser = std::min(a, b);
9863 return gcd(lesser, greater % lesser);
9867 /** Find lowest common multiple for a and b
9869 * @param a A argument
9870 * @param b B argument
9872 * @return Found gcd value
9874 GLuint UniformBlockMemberOverlappingOffsetsTest::lcm(GLuint a, GLuint b)
9876 return (a * b) / gcd(a, b);
9881 * @param context Test framework context
9883 UniformBlockMemberAlignNonPowerOf2Test::UniformBlockMemberAlignNonPowerOf2Test(deqp::Context& context)
9884 : NegativeTestBase(context, "uniform_block_member_align_non_power_of_2",
9885 "Test verifies that align qualifier requires value that is a power of 2")
9887 /* Nothing to be done here */
9892 * @param context Test framework context
9893 * @param name Test name
9894 * @param description Test description
9896 UniformBlockMemberAlignNonPowerOf2Test::UniformBlockMemberAlignNonPowerOf2Test(deqp::Context& context,
9897 const glw::GLchar* name,
9898 const glw::GLchar* description)
9899 : NegativeTestBase(context, name, description)
9901 /* Nothing to be done here */
9904 /** Source for given test case and stage
9906 * @param test_case_index Index of test case
9907 * @param stage Shader stage
9909 * @return Shader source
9911 std::string UniformBlockMemberAlignNonPowerOf2Test::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
9913 static const GLchar* cs = "#version 430 core\n"
9914 "#extension GL_ARB_enhanced_layouts : require\n"
9916 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
9918 "layout (std140) uniform Block {\n"
9920 " layout (align = ALIGN) TYPE man;\n"
9923 "writeonly uniform image2D uni_image;\n"
9927 " vec4 result = vec4(1, 0, 0.5, 1);\n"
9929 " if (TYPE(0) == block.man)\n"
9931 " result = vec4(1, 1, 1, 1) - block.boy;\n"
9934 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
9937 static const GLchar* fs = "#version 430 core\n"
9938 "#extension GL_ARB_enhanced_layouts : require\n"
9941 "out vec4 fs_out;\n"
9945 " fs_out = gs_fs;\n"
9948 static const GLchar* fs_tested = "#version 430 core\n"
9949 "#extension GL_ARB_enhanced_layouts : require\n"
9951 "layout (std140) uniform Block {\n"
9953 " layout (align = ALIGN) TYPE man;\n"
9957 "out vec4 fs_out;\n"
9961 " if (TYPE(0) == block.man)\n"
9963 " fs_out = block.boy;\n"
9966 " fs_out += gs_fs;\n"
9969 static const GLchar* gs = "#version 430 core\n"
9970 "#extension GL_ARB_enhanced_layouts : require\n"
9972 "layout(points) in;\n"
9973 "layout(triangle_strip, max_vertices = 4) out;\n"
9975 "in vec4 tes_gs[];\n"
9980 " gs_fs = tes_gs[0];\n"
9981 " gl_Position = vec4(-1, -1, 0, 1);\n"
9983 " gs_fs = tes_gs[0];\n"
9984 " gl_Position = vec4(-1, 1, 0, 1);\n"
9986 " gs_fs = tes_gs[0];\n"
9987 " gl_Position = vec4(1, -1, 0, 1);\n"
9989 " gs_fs = tes_gs[0];\n"
9990 " gl_Position = vec4(1, 1, 0, 1);\n"
9994 static const GLchar* gs_tested = "#version 430 core\n"
9995 "#extension GL_ARB_enhanced_layouts : require\n"
9997 "layout(points) in;\n"
9998 "layout(triangle_strip, max_vertices = 4) out;\n"
10000 "layout (std140) uniform Block {\n"
10002 " layout (align = ALIGN) TYPE man;\n"
10005 "in vec4 tes_gs[];\n"
10006 "out vec4 gs_fs;\n"
10010 " if (TYPE(0) == block.man)\n"
10012 " gs_fs = block.boy;\n"
10015 " gs_fs += tes_gs[0];\n"
10016 " gl_Position = vec4(-1, -1, 0, 1);\n"
10018 " gs_fs += tes_gs[0];\n"
10019 " gl_Position = vec4(-1, 1, 0, 1);\n"
10021 " gs_fs += tes_gs[0];\n"
10022 " gl_Position = vec4(1, -1, 0, 1);\n"
10024 " gs_fs += tes_gs[0];\n"
10025 " gl_Position = vec4(1, 1, 0, 1);\n"
10029 static const GLchar* tcs = "#version 430 core\n"
10030 "#extension GL_ARB_enhanced_layouts : require\n"
10032 "layout(vertices = 1) out;\n"
10034 "in vec4 vs_tcs[];\n"
10035 "out vec4 tcs_tes[];\n"
10040 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
10042 " gl_TessLevelOuter[0] = 1.0;\n"
10043 " gl_TessLevelOuter[1] = 1.0;\n"
10044 " gl_TessLevelOuter[2] = 1.0;\n"
10045 " gl_TessLevelOuter[3] = 1.0;\n"
10046 " gl_TessLevelInner[0] = 1.0;\n"
10047 " gl_TessLevelInner[1] = 1.0;\n"
10050 static const GLchar* tcs_tested = "#version 430 core\n"
10051 "#extension GL_ARB_enhanced_layouts : require\n"
10053 "layout(vertices = 1) out;\n"
10055 "layout (std140) uniform Block {\n"
10057 " layout (align = ALIGN) TYPE man;\n"
10060 "in vec4 vs_tcs[];\n"
10061 "out vec4 tcs_tes[];\n"
10065 " if (TYPE(0) == block.man)\n"
10067 " tcs_tes[gl_InvocationID] = block.boy;\n"
10071 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
10073 " gl_TessLevelOuter[0] = 1.0;\n"
10074 " gl_TessLevelOuter[1] = 1.0;\n"
10075 " gl_TessLevelOuter[2] = 1.0;\n"
10076 " gl_TessLevelOuter[3] = 1.0;\n"
10077 " gl_TessLevelInner[0] = 1.0;\n"
10078 " gl_TessLevelInner[1] = 1.0;\n"
10081 static const GLchar* tes = "#version 430 core\n"
10082 "#extension GL_ARB_enhanced_layouts : require\n"
10084 "layout(isolines, point_mode) in;\n"
10086 "in vec4 tcs_tes[];\n"
10087 "out vec4 tes_gs;\n"
10091 " tes_gs = tcs_tes[0];\n"
10094 static const GLchar* tes_tested = "#version 430 core\n"
10095 "#extension GL_ARB_enhanced_layouts : require\n"
10097 "layout(isolines, point_mode) in;\n"
10099 "layout (std140) uniform Block {\n"
10101 " layout (align = ALIGN) TYPE man;\n"
10104 "in vec4 tcs_tes[];\n"
10105 "out vec4 tes_gs;\n"
10109 " if (TYPE(0) == block.man)\n"
10111 " tes_gs = block.boy;\n"
10114 " tes_gs += tcs_tes[0];\n"
10117 static const GLchar* vs = "#version 430 core\n"
10118 "#extension GL_ARB_enhanced_layouts : require\n"
10121 "out vec4 vs_tcs;\n"
10125 " vs_tcs = in_vs;\n"
10128 static const GLchar* vs_tested = "#version 430 core\n"
10129 "#extension GL_ARB_enhanced_layouts : require\n"
10131 "layout (std140) uniform Block {\n"
10133 " layout (align = ALIGN) TYPE man;\n"
10137 "out vec4 vs_tcs;\n"
10141 " if (TYPE(0) == block.man)\n"
10143 " vs_tcs = block.boy;\n"
10146 " vs_tcs += in_vs;\n"
10150 std::string source;
10151 testCase& test_case = m_test_cases[test_case_index];
10153 if (test_case.m_stage == stage)
10156 const GLuint alignment = test_case.m_alignment;
10157 const Utils::Type& type = test_case.m_type;
10158 const GLchar* type_name = type.GetGLSLTypeName();
10159 size_t position = 0;
10163 case Utils::Shader::COMPUTE:
10166 case Utils::Shader::FRAGMENT:
10167 source = fs_tested;
10169 case Utils::Shader::GEOMETRY:
10170 source = gs_tested;
10172 case Utils::Shader::TESS_CTRL:
10173 source = tcs_tested;
10175 case Utils::Shader::TESS_EVAL:
10176 source = tes_tested;
10178 case Utils::Shader::VERTEX:
10179 source = vs_tested;
10182 TCU_FAIL("Invalid enum");
10185 sprintf(buffer, "%d", alignment);
10186 Utils::replaceToken("ALIGN", position, buffer, source);
10187 Utils::replaceToken("TYPE", position, type_name, source);
10188 Utils::replaceToken("TYPE", position, type_name, source);
10194 case Utils::Shader::FRAGMENT:
10197 case Utils::Shader::GEOMETRY:
10200 case Utils::Shader::TESS_CTRL:
10203 case Utils::Shader::TESS_EVAL:
10206 case Utils::Shader::VERTEX:
10210 TCU_FAIL("Invalid enum");
10217 /** Get description of test case
10219 * @param test_case_index Index of test case
10221 * @return Type name and offset
10223 std::string UniformBlockMemberAlignNonPowerOf2Test::getTestCaseName(GLuint test_case_index)
10225 std::stringstream stream;
10226 testCase& test_case = m_test_cases[test_case_index];
10228 stream << "Type: " << test_case.m_type.GetGLSLTypeName() << ", align: " << test_case.m_alignment;
10230 return stream.str();
10233 /** Get number of test cases
10235 * @return Number of test cases
10237 GLuint UniformBlockMemberAlignNonPowerOf2Test::getTestCaseNumber()
10239 return static_cast<GLuint>(m_test_cases.size());
10242 /** Selects if "compute" stage is relevant for test
10244 * @param test_case_index Index of test case
10246 * @return true when tested stage is compute
10248 bool UniformBlockMemberAlignNonPowerOf2Test::isComputeRelevant(GLuint test_case_index)
10250 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
10253 /** Checks if stage is supported
10259 bool UniformBlockMemberAlignNonPowerOf2Test::isStageSupported(Utils::Shader::STAGES /* stage */)
10264 /** Selects if compilation failure is expected result
10266 * @param test_case_index Index of test case
10268 * @return should_fail field from testCase
10270 bool UniformBlockMemberAlignNonPowerOf2Test::isFailureExpected(GLuint test_case_index)
10272 return m_test_cases[test_case_index].m_should_fail;
10275 /** Prepare all test cases
10278 void UniformBlockMemberAlignNonPowerOf2Test::testInit()
10280 static const GLuint dmat4_size = 128;
10281 const GLuint n_types = getTypesNumber();
10282 bool stage_support[Utils::Shader::STAGE_MAX];
10284 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
10286 stage_support[stage] = isStageSupported((Utils::Shader::STAGES)stage);
10289 for (GLuint j = 0; j < n_types; ++j)
10291 const Utils::Type& type = getType(j);
10293 for (GLuint align = 0; align <= dmat4_size; ++align)
10296 #if WRKARD_UNIFORMBLOCKMEMBERALIGNNONPOWEROF2TEST
10298 const bool should_fail = (0 == align) ? false : !isPowerOf2(align);
10300 #else /* WRKARD_UNIFORMBLOCKMEMBERALIGNNONPOWEROF2TEST */
10302 const bool should_fail = !isPowerOf2(align);
10304 #endif /* WRKARD_UNIFORMBLOCKMEMBERALIGNNONPOWEROF2TEST */
10306 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
10308 if (false == stage_support[stage])
10313 testCase test_case = { align, type, should_fail, (Utils::Shader::STAGES)stage };
10315 m_test_cases.push_back(test_case);
10321 /** Check if value is power of 2
10323 * @param val Tested value
10325 * @return true if val is power of 2, false otherwise
10327 bool UniformBlockMemberAlignNonPowerOf2Test::isPowerOf2(GLuint val)
10334 return (0 == (val & (val - 1)));
10339 * @param context Test framework context
10341 UniformBlockAlignmentTest::UniformBlockAlignmentTest(deqp::Context& context)
10342 : TextureTestBase(context, "uniform_block_alignment", "Test verifies offset and alignment of uniform buffer")
10346 /** Get interface of program
10349 * @param program_interface Interface of program
10350 * @param varying_passthrough Collection of connections between in and out variables
10352 void UniformBlockAlignmentTest::getProgramInterface(GLuint /* test_case_index */,
10353 Utils::ProgramInterface& program_interface,
10354 Utils::VaryingPassthrough& varying_passthrough)
10356 static const Utils::Type vec4 = Utils::Type::vec4;
10358 #if WRKARD_UNIFORMBLOCKALIGNMENT
10360 static const GLuint block_align = 16;
10362 #else /* WRKARD_UNIFORMBLOCKALIGNMENT */
10364 static const GLuint block_align = 64;
10366 #endif /* WRKARD_UNIFORMBLOCKALIGNMENT */
10368 static const GLuint vec4_stride = 16;
10369 static const GLuint data_stride = vec4_stride * 2; /* one vec4 + one scalar aligned to 16 */
10371 /*Fixed a test issue, the fifth_offset should be calculated by block_align, instead of fifth_align, according to spec, the actual
10372 alignment of a member will be the greater of the specified alignment and the base aligment for the member type
10374 const GLuint first_offset = 0; /* vec4 at 0 */
10375 const GLuint second_offset = Utils::Type::GetActualOffset(first_offset + vec4_stride, block_align); /* Data at 32 */
10376 const GLuint third_offset =
10377 Utils::Type::GetActualOffset(second_offset + data_stride, block_align); /* Data[2] at 64 */
10378 const GLuint fourth_offset =
10379 Utils::Type::GetActualOffset(third_offset + data_stride * 2, block_align); /* vec4[3] at 96 */
10380 const GLuint fifth_offset =
10381 Utils::Type::GetActualOffset(fourth_offset + vec4_stride * 3, block_align); /* vec4[2] at 160 */
10382 const GLuint sixth_offset =
10383 Utils::Type::GetActualOffset(fifth_offset + vec4_stride * 2, block_align); /* Data at 192 */
10385 Utils::Interface* structure = program_interface.Structure("Data");
10387 structure->Member("vector", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::vec4,
10388 false /* normalized */, 0 /* n_array_elements */, Utils::Type::vec4.GetSize(), 0 /* offset */);
10390 structure->Member("scalar", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::_float,
10391 false /* normalized */, 0 /* n_array_elements */, Utils::Type::_float.GetSize(),
10392 Utils::Type::vec4.GetSize() /* offset */);
10394 /* Prepare Block */
10395 Utils::Interface* vs_uni_block = program_interface.Block("vs_uni_Block");
10397 vs_uni_block->Member("first", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::vec4,
10398 false /* normalized */, 0 /* n_array_elements */, vec4_stride, first_offset /* offset */);
10400 vs_uni_block->Member("second", "", 0 /* expected_component */, 0 /* expected_location */, structure,
10401 0 /* n_array_elements */, data_stride, second_offset);
10403 vs_uni_block->Member("third", "", 0 /* expected_component */, 0 /* expected_location */, structure,
10404 2 /* n_array_elements */, data_stride, third_offset);
10406 vs_uni_block->Member("fourth", "", 0 /* expected_component */, 0 /* expected_location */, vec4,
10407 false /* normalized */, 3 /* n_array_elements */, vec4_stride, fourth_offset);
10409 vs_uni_block->Member("fifth", "layout(align = 64)", 0 /* expected_component */, 0 /* expected_location */, vec4,
10410 false /* normalized */, 2 /* n_array_elements */, vec4_stride, fifth_offset);
10412 vs_uni_block->Member("sixth", "", 0 /* expected_component */, 0 /* expected_location */, structure,
10413 0 /* n_array_elements */, data_stride, sixth_offset);
10415 const GLuint stride = calculateStride(*vs_uni_block);
10416 m_data.resize(stride);
10417 generateData(*vs_uni_block, 0, m_data);
10419 Utils::ShaderInterface& vs_si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
10421 /* Add uniform BLOCK */
10422 #if WRKARD_UNIFORMBLOCKALIGNMENT
10423 vs_si.Uniform("vs_uni_block", "layout (std140, binding = BINDING)", 0, 0, vs_uni_block, 0,
10424 static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
10425 #else /* WRKARD_UNIFORMBLOCKALIGNMENT */
10426 vs_si.Uniform("vs_uni_block", "layout (std140, binding = BINDING, align = 64)", 0, 0, vs_uni_block, 0,
10427 static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
10428 #endif /* WRKARD_UNIFORMBLOCKALIGNMENT */
10430 program_interface.CloneVertexInterface(varying_passthrough);
10435 * @param context Test framework context
10437 SSBMemberOffsetAndAlignTest::SSBMemberOffsetAndAlignTest(deqp::Context& context)
10438 : TextureTestBase(context, "ssb_member_offset_and_align",
10439 "Test verifies offsets and alignment of storage buffer members")
10443 /** Get interface of program
10445 * @param test_case_index Test case index
10446 * @param program_interface Interface of program
10447 * @param varying_passthrough Collection of connections between in and out variables
10449 void SSBMemberOffsetAndAlignTest::getProgramInterface(GLuint test_case_index,
10450 Utils::ProgramInterface& program_interface,
10451 Utils::VaryingPassthrough& varying_passthrough)
10453 std::string globals = "const int basic_size = BASIC_SIZE;\n"
10454 "const int type_align = TYPE_ALIGN;\n"
10455 "const int type_size = TYPE_SIZE;\n";
10457 Utils::Type type = getType(test_case_index);
10458 GLuint basic_size = Utils::Type::GetTypeSize(type.m_basic_type);
10459 const GLuint base_align = type.GetBaseAlignment(false);
10460 const GLuint array_align = type.GetBaseAlignment(true);
10461 const GLuint base_stride = Utils::Type::CalculateStd140Stride(base_align, type.m_n_columns, 0);
10462 const GLuint type_align = Utils::roundUpToPowerOf2(base_stride);
10464 /* Calculate offsets */
10465 const GLuint first_offset = 0;
10466 const GLuint second_offset = type.GetActualOffset(base_stride, basic_size / 2);
10468 #if WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST
10470 const GLuint third_offset = type.GetActualOffset(second_offset + base_stride, base_align);
10471 const GLuint fourth_offset = type.GetActualOffset(third_offset + base_stride, base_align);
10472 const GLuint fifth_offset = type.GetActualOffset(fourth_offset + base_stride, base_align);
10473 const GLuint sixth_offset = type.GetActualOffset(fifth_offset + base_stride, array_align);
10474 const GLuint seventh_offset = type.GetActualOffset(sixth_offset + base_stride, array_align);
10475 const GLuint eigth_offset = type.GetActualOffset(seventh_offset + base_stride, array_align);
10477 #else /* WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST */
10479 const GLuint third_offset = type.GetActualOffset(second_offset + base_stride, 2 * type_align);
10480 const GLuint fourth_offset = type.GetActualOffset(3 * type_align + base_stride, base_align);
10481 const GLuint fifth_offset = type.GetActualOffset(fourth_offset + base_stride, base_align);
10482 const GLuint sixth_offset = type.GetActualOffset(fifth_offset + base_stride, array_align);
10483 const GLuint seventh_offset = type.GetActualOffset(sixth_offset + base_stride, array_align);
10484 const GLuint eigth_offset = type.GetActualOffset(seventh_offset + base_stride, 8 * basic_size);
10486 #endif /* WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST */
10489 const std::vector<GLubyte>& first = type.GenerateData();
10490 const std::vector<GLubyte>& second = type.GenerateData();
10491 const std::vector<GLubyte>& third = type.GenerateData();
10492 const std::vector<GLubyte>& fourth = type.GenerateData();
10494 m_data.resize(eigth_offset + base_stride);
10495 GLubyte* ptr = &m_data[0];
10496 memcpy(ptr + first_offset, &first[0], first.size());
10497 memcpy(ptr + second_offset, &second[0], second.size());
10498 memcpy(ptr + third_offset, &third[0], third.size());
10499 memcpy(ptr + fourth_offset, &fourth[0], fourth.size());
10500 memcpy(ptr + fifth_offset, &fourth[0], fourth.size());
10501 memcpy(ptr + sixth_offset, &third[0], third.size());
10502 memcpy(ptr + seventh_offset, &second[0], second.size());
10503 memcpy(ptr + eigth_offset, &first[0], first.size());
10505 /* Prepare globals */
10506 size_t position = 0;
10509 sprintf(buffer, "%d", basic_size);
10510 Utils::replaceToken("BASIC_SIZE", position, buffer, globals);
10512 sprintf(buffer, "%d", type_align);
10513 Utils::replaceToken("TYPE_ALIGN", position, buffer, globals);
10515 sprintf(buffer, "%d", base_stride);
10516 Utils::replaceToken("TYPE_SIZE", position, buffer, globals);
10518 /* Prepare Block */
10519 Utils::Interface* vs_buf_block = program_interface.Block("vs_buf_Block");
10521 vs_buf_block->Member("at_first_offset", "layout(offset = 0, align = 8 * basic_size)", 0 /* expected_component */,
10522 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
10525 vs_buf_block->Member("at_second_offset", "layout(offset = type_size, align = basic_size / 2)",
10526 0 /* expected_component */, 0 /* expected_location */, type, false /* normalized */,
10527 0 /* n_array_elements */, base_stride, second_offset);
10529 vs_buf_block->Member("at_third_offset", "layout(align = 2 * type_align)", 0 /* expected_component */,
10530 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
10533 vs_buf_block->Member("at_fourth_offset", "layout(offset = 3 * type_align + type_size)", 0 /* expected_component */,
10534 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
10537 vs_buf_block->Member("at_fifth_offset", "", 0 /* expected_component */, 0 /* expected_location */, type,
10538 false /* normalized */, 0 /* n_array_elements */, base_stride, fifth_offset);
10540 vs_buf_block->Member("at_sixth_offset", "", 0 /* expected_component */, 0 /* expected_location */, type,
10541 false /* normalized */, 2 /* n_array_elements */, array_align * 2, sixth_offset);
10543 vs_buf_block->Member("at_eigth_offset", "layout(align = 8 * basic_size)", 0 /* expected_component */,
10544 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
10547 Utils::ShaderInterface& vs_si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
10550 vs_si.m_globals = globals;
10552 /* Add uniform BLOCK */
10553 vs_si.SSB("vs_buf_block", "layout (std140, binding = BINDING)", 0, 0, vs_buf_block, 0,
10554 static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
10557 program_interface.CloneVertexInterface(varying_passthrough);
10562 * @param test_case_index Index of test case
10564 * @return Name of type test in test_case_index
10566 std::string SSBMemberOffsetAndAlignTest::getTestCaseName(glw::GLuint test_case_index)
10568 return getTypeName(test_case_index);
10571 /** Returns number of types to test
10573 * @return Number of types, 34
10575 glw::GLuint SSBMemberOffsetAndAlignTest::getTestCaseNumber()
10577 return getTypesNumber();
10580 /** Prepare code snippet that will verify in and uniform variables
10584 * @param stage Shader stage
10586 * @return Code that verify variables
10588 std::string SSBMemberOffsetAndAlignTest::getVerificationSnippet(GLuint /* test_case_index */,
10589 Utils::ProgramInterface& /* program_interface */,
10590 Utils::Shader::STAGES stage)
10592 std::string verification = "if ( (PREFIXblock.at_first_offset != PREFIXblock.at_eigth_offset ) ||\n"
10593 " (PREFIXblock.at_second_offset != PREFIXblock.at_sixth_offset[1]) ||\n"
10594 " (PREFIXblock.at_third_offset != PREFIXblock.at_sixth_offset[0]) ||\n"
10595 " (PREFIXblock.at_fourth_offset != PREFIXblock.at_fifth_offset ) )\n"
10600 const GLchar* prefix = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::SSB);
10602 Utils::replaceAllTokens("PREFIX", prefix, verification);
10604 return verification;
10607 /** Selects if "draw" stages are relevant for test
10611 * @return true if all stages support shader storage buffers, false otherwise
10613 bool SSBMemberOffsetAndAlignTest::isDrawRelevant(GLuint /* test_case_index */)
10615 const Functions& gl = m_context.getRenderContext().getFunctions();
10616 GLint gs_supported_buffers = 0;
10617 GLint tcs_supported_buffers = 0;
10618 GLint tes_supported_buffers = 0;
10619 GLint vs_supported_buffers = 0;
10621 gl.getIntegerv(GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS, &gs_supported_buffers);
10622 gl.getIntegerv(GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS, &tcs_supported_buffers);
10623 gl.getIntegerv(GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS, &tes_supported_buffers);
10624 gl.getIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &vs_supported_buffers);
10626 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
10628 return ((1 <= gs_supported_buffers) && (1 <= tcs_supported_buffers) && (1 <= tes_supported_buffers) &&
10629 (1 <= vs_supported_buffers));
10634 * @param context Test framework context
10636 SSBLayoutQualifierConflictTest::SSBLayoutQualifierConflictTest(deqp::Context& context)
10637 : NegativeTestBase(context, "ssb_layout_qualifier_conflict", "Test verifies that std140 or std430 is required when "
10638 "offset and/or align qualifiers are used with storage "
10641 /* Nothing to be done here */
10644 /** Source for given test case and stage
10646 * @param test_case_index Index of test case
10647 * @param stage Shader stage
10649 * @return Shader source
10651 std::string SSBLayoutQualifierConflictTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
10653 static const GLchar* cs = "#version 430 core\n"
10654 "#extension GL_ARB_enhanced_layouts : require\n"
10656 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
10658 "layout (QUALIFIERbinding = BINDING) buffer cs_Block {\n"
10659 " layout(offset = 16) vec4 boy;\n"
10660 " layout(align = 64) vec4 man;\n"
10663 "writeonly uniform image2D uni_image;\n"
10667 " vec4 result = uni_block.boy + uni_block.man;\n"
10669 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
10672 static const GLchar* fs = "#version 430 core\n"
10673 "#extension GL_ARB_enhanced_layouts : require\n"
10675 "layout (QUALIFIERbinding = BINDING) buffer Block {\n"
10676 " layout(offset = 16) vec4 boy;\n"
10677 " layout(align = 64) vec4 man;\n"
10681 "out vec4 fs_out;\n"
10685 " fs_out = gs_fs + uni_block.boy + uni_block.man;\n"
10688 static const GLchar* gs = "#version 430 core\n"
10689 "#extension GL_ARB_enhanced_layouts : require\n"
10691 "layout(points) in;\n"
10692 "layout(triangle_strip, max_vertices = 4) out;\n"
10694 "layout (QUALIFIERbinding = BINDING) buffer gs_Block {\n"
10695 " layout(offset = 16) vec4 boy;\n"
10696 " layout(align = 64) vec4 man;\n"
10699 "in vec4 tes_gs[];\n"
10700 "out vec4 gs_fs;\n"
10704 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
10705 " gl_Position = vec4(-1, -1, 0, 1);\n"
10707 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
10708 " gl_Position = vec4(-1, 1, 0, 1);\n"
10710 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
10711 " gl_Position = vec4(1, -1, 0, 1);\n"
10713 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
10714 " gl_Position = vec4(1, 1, 0, 1);\n"
10718 static const GLchar* tcs =
10719 "#version 430 core\n"
10720 "#extension GL_ARB_enhanced_layouts : require\n"
10722 "layout(vertices = 1) out;\n"
10724 "layout (QUALIFIERbinding = BINDING) buffer tcs_Block {\n"
10725 " layout(offset = 16) vec4 boy;\n"
10726 " layout(align = 64) vec4 man;\n"
10729 "in vec4 vs_tcs[];\n"
10730 "out vec4 tcs_tes[];\n"
10735 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID] + uni_block.boy + uni_block.man;\n"
10737 " gl_TessLevelOuter[0] = 1.0;\n"
10738 " gl_TessLevelOuter[1] = 1.0;\n"
10739 " gl_TessLevelOuter[2] = 1.0;\n"
10740 " gl_TessLevelOuter[3] = 1.0;\n"
10741 " gl_TessLevelInner[0] = 1.0;\n"
10742 " gl_TessLevelInner[1] = 1.0;\n"
10745 static const GLchar* tes = "#version 430 core\n"
10746 "#extension GL_ARB_enhanced_layouts : require\n"
10748 "layout(isolines, point_mode) in;\n"
10750 "layout (QUALIFIERbinding = BINDING) buffer tes_Block {\n"
10751 " layout(offset = 16) vec4 boy;\n"
10752 " layout(align = 64) vec4 man;\n"
10755 "in vec4 tcs_tes[];\n"
10756 "out vec4 tes_gs;\n"
10760 " tes_gs = tcs_tes[0] + uni_block.boy + uni_block.man;\n"
10763 static const GLchar* vs = "#version 430 core\n"
10764 "#extension GL_ARB_enhanced_layouts : require\n"
10766 "layout (QUALIFIERbinding = BINDING) buffer vs_Block {\n"
10767 " layout(offset = 16) vec4 boy;\n"
10768 " layout(align = 64) vec4 man;\n"
10772 "out vec4 vs_tcs;\n"
10776 " vs_tcs = in_vs + uni_block.boy + uni_block.man;\n"
10781 size_t position = 0;
10782 std::string source;
10783 testCase& test_case = m_test_cases[test_case_index];
10784 std::string qualifier = getQualifierName(test_case.m_qualifier);
10786 if (false == qualifier.empty())
10788 qualifier.append(", ");
10791 sprintf(buffer, "%d", stage);
10795 case Utils::Shader::COMPUTE:
10798 case Utils::Shader::FRAGMENT:
10801 case Utils::Shader::GEOMETRY:
10804 case Utils::Shader::TESS_CTRL:
10807 case Utils::Shader::TESS_EVAL:
10810 case Utils::Shader::VERTEX:
10814 TCU_FAIL("Invalid enum");
10817 if (test_case.m_stage == stage)
10819 Utils::replaceToken("QUALIFIER", position, qualifier.c_str(), source);
10823 Utils::replaceToken("QUALIFIER", position, "std140, ", source);
10826 Utils::replaceToken("BINDING", position, buffer, source);
10831 /** Get description of test case
10833 * @param test_case_index Index of test case
10835 * @return Qualifier name
10837 std::string SSBLayoutQualifierConflictTest::getTestCaseName(GLuint test_case_index)
10839 std::string result = getQualifierName(m_test_cases[test_case_index].m_qualifier);
10844 /** Get number of test cases
10846 * @return Number of test cases
10848 GLuint SSBLayoutQualifierConflictTest::getTestCaseNumber()
10850 return static_cast<GLuint>(m_test_cases.size());
10853 /** Selects if "compute" stage is relevant for test
10855 * @param test_case_index Index of test case
10857 * @return true when tested stage is compute
10859 bool SSBLayoutQualifierConflictTest::isComputeRelevant(GLuint test_case_index)
10861 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
10864 /** Selects if compilation failure is expected result
10866 * @param test_case_index Index of test case
10868 * @return false for STD140 and STD430 cases, true otherwise
10870 bool SSBLayoutQualifierConflictTest::isFailureExpected(GLuint test_case_index)
10872 const QUALIFIERS qualifier = m_test_cases[test_case_index].m_qualifier;
10874 return !((STD140 == qualifier) || (STD430 == qualifier));
10877 /** Checks if stage is supported
10879 * @param stage Shader stage
10881 * @return true if supported, false otherwise
10883 bool SSBLayoutQualifierConflictTest::isStageSupported(Utils::Shader::STAGES stage)
10885 const Functions& gl = m_context.getRenderContext().getFunctions();
10886 GLint max_supported_buffers = 0;
10891 case Utils::Shader::COMPUTE:
10892 pname = GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS;
10894 case Utils::Shader::FRAGMENT:
10895 pname = GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS;
10897 case Utils::Shader::GEOMETRY:
10898 pname = GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS;
10900 case Utils::Shader::TESS_CTRL:
10901 pname = GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS;
10903 case Utils::Shader::TESS_EVAL:
10904 pname = GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS;
10906 case Utils::Shader::VERTEX:
10907 pname = GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS;
10910 TCU_FAIL("Invalid enum");
10913 gl.getIntegerv(pname, &max_supported_buffers);
10914 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
10916 return 1 <= max_supported_buffers;
10919 /** Prepare all test cases
10922 void SSBLayoutQualifierConflictTest::testInit()
10924 bool stage_support[Utils::Shader::STAGE_MAX];
10926 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
10928 stage_support[stage] = isStageSupported((Utils::Shader::STAGES)stage);
10931 for (GLuint qualifier = 0; qualifier < QUALIFIERS_MAX; ++qualifier)
10933 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
10935 if (false == stage_support[stage])
10940 testCase test_case = { (QUALIFIERS)qualifier, (Utils::Shader::STAGES)stage };
10942 m_test_cases.push_back(test_case);
10947 /** Get name of glsl constant
10949 * @param Constant id
10951 * @return Name of constant used in GLSL
10953 const GLchar* SSBLayoutQualifierConflictTest::getQualifierName(QUALIFIERS qualifier)
10955 const GLchar* name = "";
10975 TCU_FAIL("Invalid enum");
10983 * @param context Test framework context
10985 SSBMemberInvalidOffsetAlignmentTest::SSBMemberInvalidOffsetAlignmentTest(deqp::Context& context)
10986 : UniformBlockMemberInvalidOffsetAlignmentTest(
10987 context, "ssb_member_invalid_offset_alignment",
10988 "Test verifies that invalid alignment of offset qualifiers cause compilation failure")
10990 /* Nothing to be done here */
10993 /** Source for given test case and stage
10995 * @param test_case_index Index of test case
10996 * @param stage Shader stage
10998 * @return Shader source
11000 std::string SSBMemberInvalidOffsetAlignmentTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
11002 static const GLchar* cs = "#version 430 core\n"
11003 "#extension GL_ARB_enhanced_layouts : require\n"
11005 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
11007 "layout (std140) buffer Block {\n"
11008 " layout (offset = OFFSET) TYPE member;\n"
11011 "writeonly uniform image2D uni_image;\n"
11015 " vec4 result = vec4(1, 0, 0.5, 1);\n"
11017 " if (TYPE(1) == block.member)\n"
11019 " result = vec4(1, 1, 1, 1);\n"
11022 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
11025 static const GLchar* fs = "#version 430 core\n"
11026 "#extension GL_ARB_enhanced_layouts : require\n"
11029 "out vec4 fs_out;\n"
11033 " fs_out = gs_fs;\n"
11036 static const GLchar* fs_tested = "#version 430 core\n"
11037 "#extension GL_ARB_enhanced_layouts : require\n"
11039 "layout (std140) buffer Block {\n"
11040 " layout (offset = OFFSET) TYPE member;\n"
11044 "out vec4 fs_out;\n"
11048 " if (TYPE(1) == block.member)\n"
11050 " fs_out = vec4(1, 1, 1, 1);\n"
11053 " fs_out += gs_fs;\n"
11056 static const GLchar* gs = "#version 430 core\n"
11057 "#extension GL_ARB_enhanced_layouts : require\n"
11059 "layout(points) in;\n"
11060 "layout(triangle_strip, max_vertices = 4) out;\n"
11062 "in vec4 tes_gs[];\n"
11063 "out vec4 gs_fs;\n"
11067 " gs_fs = tes_gs[0];\n"
11068 " gl_Position = vec4(-1, -1, 0, 1);\n"
11070 " gs_fs = tes_gs[0];\n"
11071 " gl_Position = vec4(-1, 1, 0, 1);\n"
11073 " gs_fs = tes_gs[0];\n"
11074 " gl_Position = vec4(1, -1, 0, 1);\n"
11076 " gs_fs = tes_gs[0];\n"
11077 " gl_Position = vec4(1, 1, 0, 1);\n"
11081 static const GLchar* gs_tested = "#version 430 core\n"
11082 "#extension GL_ARB_enhanced_layouts : require\n"
11084 "layout(points) in;\n"
11085 "layout(triangle_strip, max_vertices = 4) out;\n"
11087 "layout (std140) buffer Block {\n"
11088 " layout (offset = OFFSET) TYPE member;\n"
11091 "in vec4 tes_gs[];\n"
11092 "out vec4 gs_fs;\n"
11096 " if (TYPE(1) == block.member)\n"
11098 " gs_fs = vec4(1, 1, 1, 1);\n"
11101 " gs_fs += tes_gs[0];\n"
11102 " gl_Position = vec4(-1, -1, 0, 1);\n"
11104 " gs_fs += tes_gs[0];\n"
11105 " gl_Position = vec4(-1, 1, 0, 1);\n"
11107 " gs_fs += tes_gs[0];\n"
11108 " gl_Position = vec4(1, -1, 0, 1);\n"
11110 " gs_fs += tes_gs[0];\n"
11111 " gl_Position = vec4(1, 1, 0, 1);\n"
11115 static const GLchar* tcs = "#version 430 core\n"
11116 "#extension GL_ARB_enhanced_layouts : require\n"
11118 "layout(vertices = 1) out;\n"
11120 "in vec4 vs_tcs[];\n"
11121 "out vec4 tcs_tes[];\n"
11126 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
11128 " gl_TessLevelOuter[0] = 1.0;\n"
11129 " gl_TessLevelOuter[1] = 1.0;\n"
11130 " gl_TessLevelOuter[2] = 1.0;\n"
11131 " gl_TessLevelOuter[3] = 1.0;\n"
11132 " gl_TessLevelInner[0] = 1.0;\n"
11133 " gl_TessLevelInner[1] = 1.0;\n"
11136 static const GLchar* tcs_tested = "#version 430 core\n"
11137 "#extension GL_ARB_enhanced_layouts : require\n"
11139 "layout(vertices = 1) out;\n"
11141 "layout (std140) buffer Block {\n"
11142 " layout (offset = OFFSET) TYPE member;\n"
11145 "in vec4 vs_tcs[];\n"
11146 "out vec4 tcs_tes[];\n"
11150 " if (TYPE(1) == block.member)\n"
11152 " tcs_tes[gl_InvocationID] = vec4(1, 1, 1, 1);\n"
11156 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
11158 " gl_TessLevelOuter[0] = 1.0;\n"
11159 " gl_TessLevelOuter[1] = 1.0;\n"
11160 " gl_TessLevelOuter[2] = 1.0;\n"
11161 " gl_TessLevelOuter[3] = 1.0;\n"
11162 " gl_TessLevelInner[0] = 1.0;\n"
11163 " gl_TessLevelInner[1] = 1.0;\n"
11166 static const GLchar* tes = "#version 430 core\n"
11167 "#extension GL_ARB_enhanced_layouts : require\n"
11169 "layout(isolines, point_mode) in;\n"
11171 "in vec4 tcs_tes[];\n"
11172 "out vec4 tes_gs;\n"
11176 " tes_gs = tcs_tes[0];\n"
11179 static const GLchar* tes_tested = "#version 430 core\n"
11180 "#extension GL_ARB_enhanced_layouts : require\n"
11182 "layout(isolines, point_mode) in;\n"
11184 "layout (std140) buffer Block {\n"
11185 " layout (offset = OFFSET) TYPE member;\n"
11188 "in vec4 tcs_tes[];\n"
11189 "out vec4 tes_gs;\n"
11193 " if (TYPE(1) == block.member)\n"
11195 " tes_gs = vec4(1, 1, 1, 1);\n"
11198 " tes_gs += tcs_tes[0];\n"
11201 static const GLchar* vs = "#version 430 core\n"
11202 "#extension GL_ARB_enhanced_layouts : require\n"
11205 "out vec4 vs_tcs;\n"
11209 " vs_tcs = in_vs;\n"
11212 static const GLchar* vs_tested = "#version 430 core\n"
11213 "#extension GL_ARB_enhanced_layouts : require\n"
11215 "layout (std140) buffer Block {\n"
11216 " layout (offset = OFFSET) TYPE member;\n"
11220 "out vec4 vs_tcs;\n"
11224 " if (TYPE(1) == block.member)\n"
11226 " vs_tcs = vec4(1, 1, 1, 1);\n"
11229 " vs_tcs += in_vs;\n"
11233 std::string source;
11234 testCase& test_case = m_test_cases[test_case_index];
11236 if (test_case.m_stage == stage)
11239 const GLuint offset = test_case.m_offset;
11240 size_t position = 0;
11241 const Utils::Type& type = test_case.m_type;
11242 const GLchar* type_name = type.GetGLSLTypeName();
11244 sprintf(buffer, "%d", offset);
11248 case Utils::Shader::COMPUTE:
11251 case Utils::Shader::FRAGMENT:
11252 source = fs_tested;
11254 case Utils::Shader::GEOMETRY:
11255 source = gs_tested;
11257 case Utils::Shader::TESS_CTRL:
11258 source = tcs_tested;
11260 case Utils::Shader::TESS_EVAL:
11261 source = tes_tested;
11263 case Utils::Shader::VERTEX:
11264 source = vs_tested;
11267 TCU_FAIL("Invalid enum");
11270 Utils::replaceToken("OFFSET", position, buffer, source);
11271 Utils::replaceToken("TYPE", position, type_name, source);
11272 Utils::replaceToken("TYPE", position, type_name, source);
11278 case Utils::Shader::FRAGMENT:
11281 case Utils::Shader::GEOMETRY:
11284 case Utils::Shader::TESS_CTRL:
11287 case Utils::Shader::TESS_EVAL:
11290 case Utils::Shader::VERTEX:
11294 TCU_FAIL("Invalid enum");
11301 /** Checks if stage is supported
11303 * @param stage Shader stage
11305 * @return true if supported, false otherwise
11307 bool SSBMemberInvalidOffsetAlignmentTest::isStageSupported(Utils::Shader::STAGES stage)
11309 const Functions& gl = m_context.getRenderContext().getFunctions();
11310 GLint max_supported_buffers = 0;
11315 case Utils::Shader::COMPUTE:
11316 pname = GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS;
11318 case Utils::Shader::FRAGMENT:
11319 pname = GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS;
11321 case Utils::Shader::GEOMETRY:
11322 pname = GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS;
11324 case Utils::Shader::TESS_CTRL:
11325 pname = GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS;
11327 case Utils::Shader::TESS_EVAL:
11328 pname = GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS;
11330 case Utils::Shader::VERTEX:
11331 pname = GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS;
11334 TCU_FAIL("Invalid enum");
11337 gl.getIntegerv(pname, &max_supported_buffers);
11338 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
11340 return 1 <= max_supported_buffers;
11345 * @param context Test framework context
11347 SSBMemberOverlappingOffsetsTest::SSBMemberOverlappingOffsetsTest(deqp::Context& context)
11348 : UniformBlockMemberOverlappingOffsetsTest(
11349 context, "ssb_member_overlapping_offsets",
11350 "Test verifies that overlapping offsets qualifiers cause compilation failure")
11352 /* Nothing to be done here */
11355 /** Source for given test case and stage
11357 * @param test_case_index Index of test case
11358 * @param stage Shader stage
11360 * @return Shader source
11362 std::string SSBMemberOverlappingOffsetsTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
11364 static const GLchar* cs = "#version 430 core\n"
11365 "#extension GL_ARB_enhanced_layouts : require\n"
11367 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
11369 "layout (std140) buffer Block {\n"
11370 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11371 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11374 "writeonly uniform image2D uni_image;\n"
11378 " vec4 result = vec4(1, 0, 0.5, 1);\n"
11380 " if ((BOY_TYPE(1) == block.boy) ||\n"
11381 " (MAN_TYPE(0) == block.man) )\n"
11383 " result = vec4(1, 1, 1, 1);\n"
11386 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
11389 static const GLchar* fs = "#version 430 core\n"
11390 "#extension GL_ARB_enhanced_layouts : require\n"
11393 "out vec4 fs_out;\n"
11397 " fs_out = gs_fs;\n"
11400 static const GLchar* fs_tested = "#version 430 core\n"
11401 "#extension GL_ARB_enhanced_layouts : require\n"
11403 "layout (std140) buffer Block {\n"
11404 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11405 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11409 "out vec4 fs_out;\n"
11413 " if ((BOY_TYPE(1) == block.boy) ||\n"
11414 " (MAN_TYPE(0) == block.man) )\n"
11416 " fs_out = vec4(1, 1, 1, 1);\n"
11419 " fs_out += gs_fs;\n"
11422 static const GLchar* gs = "#version 430 core\n"
11423 "#extension GL_ARB_enhanced_layouts : require\n"
11425 "layout(points) in;\n"
11426 "layout(triangle_strip, max_vertices = 4) out;\n"
11428 "in vec4 tes_gs[];\n"
11429 "out vec4 gs_fs;\n"
11433 " gs_fs = tes_gs[0];\n"
11434 " gl_Position = vec4(-1, -1, 0, 1);\n"
11436 " gs_fs = tes_gs[0];\n"
11437 " gl_Position = vec4(-1, 1, 0, 1);\n"
11439 " gs_fs = tes_gs[0];\n"
11440 " gl_Position = vec4(1, -1, 0, 1);\n"
11442 " gs_fs = tes_gs[0];\n"
11443 " gl_Position = vec4(1, 1, 0, 1);\n"
11447 static const GLchar* gs_tested = "#version 430 core\n"
11448 "#extension GL_ARB_enhanced_layouts : require\n"
11450 "layout(points) in;\n"
11451 "layout(triangle_strip, max_vertices = 4) out;\n"
11453 "layout (std140) buffer Block {\n"
11454 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11455 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11458 "in vec4 tes_gs[];\n"
11459 "out vec4 gs_fs;\n"
11463 " if ((BOY_TYPE(1) == block.boy) ||\n"
11464 " (MAN_TYPE(0) == block.man) )\n"
11466 " gs_fs = vec4(1, 1, 1, 1);\n"
11469 " gs_fs += tes_gs[0];\n"
11470 " gl_Position = vec4(-1, -1, 0, 1);\n"
11472 " gs_fs += tes_gs[0];\n"
11473 " gl_Position = vec4(-1, 1, 0, 1);\n"
11475 " gs_fs += tes_gs[0];\n"
11476 " gl_Position = vec4(1, -1, 0, 1);\n"
11478 " gs_fs += tes_gs[0];\n"
11479 " gl_Position = vec4(1, 1, 0, 1);\n"
11483 static const GLchar* tcs = "#version 430 core\n"
11484 "#extension GL_ARB_enhanced_layouts : require\n"
11486 "layout(vertices = 1) out;\n"
11488 "in vec4 vs_tcs[];\n"
11489 "out vec4 tcs_tes[];\n"
11494 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
11496 " gl_TessLevelOuter[0] = 1.0;\n"
11497 " gl_TessLevelOuter[1] = 1.0;\n"
11498 " gl_TessLevelOuter[2] = 1.0;\n"
11499 " gl_TessLevelOuter[3] = 1.0;\n"
11500 " gl_TessLevelInner[0] = 1.0;\n"
11501 " gl_TessLevelInner[1] = 1.0;\n"
11504 static const GLchar* tcs_tested = "#version 430 core\n"
11505 "#extension GL_ARB_enhanced_layouts : require\n"
11507 "layout(vertices = 1) out;\n"
11509 "layout (std140) buffer Block {\n"
11510 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11511 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11514 "in vec4 vs_tcs[];\n"
11515 "out vec4 tcs_tes[];\n"
11519 " if ((BOY_TYPE(1) == block.boy) ||\n"
11520 " (MAN_TYPE(0) == block.man) )\n"
11522 " tcs_tes[gl_InvocationID] = vec4(1, 1, 1, 1);\n"
11526 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
11528 " gl_TessLevelOuter[0] = 1.0;\n"
11529 " gl_TessLevelOuter[1] = 1.0;\n"
11530 " gl_TessLevelOuter[2] = 1.0;\n"
11531 " gl_TessLevelOuter[3] = 1.0;\n"
11532 " gl_TessLevelInner[0] = 1.0;\n"
11533 " gl_TessLevelInner[1] = 1.0;\n"
11536 static const GLchar* tes = "#version 430 core\n"
11537 "#extension GL_ARB_enhanced_layouts : require\n"
11539 "layout(isolines, point_mode) in;\n"
11541 "in vec4 tcs_tes[];\n"
11542 "out vec4 tes_gs;\n"
11546 " tes_gs = tcs_tes[0];\n"
11549 static const GLchar* tes_tested = "#version 430 core\n"
11550 "#extension GL_ARB_enhanced_layouts : require\n"
11552 "layout(isolines, point_mode) in;\n"
11554 "layout (std140) buffer Block {\n"
11555 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11556 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11559 "in vec4 tcs_tes[];\n"
11560 "out vec4 tes_gs;\n"
11564 " if ((BOY_TYPE(1) == block.boy) ||\n"
11565 " (MAN_TYPE(0) == block.man) )\n"
11567 " tes_gs = vec4(1, 1, 1, 1);\n"
11570 " tes_gs += tcs_tes[0];\n"
11573 static const GLchar* vs = "#version 430 core\n"
11574 "#extension GL_ARB_enhanced_layouts : require\n"
11577 "out vec4 vs_tcs;\n"
11581 " vs_tcs = in_vs;\n"
11584 static const GLchar* vs_tested = "#version 430 core\n"
11585 "#extension GL_ARB_enhanced_layouts : require\n"
11587 "layout (std140) buffer Block {\n"
11588 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11589 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11593 "out vec4 vs_tcs;\n"
11597 " if ((BOY_TYPE(1) == block.boy) ||\n"
11598 " (MAN_TYPE(0) == block.man) )\n"
11600 " vs_tcs = vec4(1, 1, 1, 1);\n"
11603 " vs_tcs += in_vs;\n"
11607 std::string source;
11608 testCase& test_case = m_test_cases[test_case_index];
11610 if (test_case.m_stage == stage)
11613 const GLuint boy_offset = test_case.m_boy_offset;
11614 const Utils::Type& boy_type = test_case.m_boy_type;
11615 const GLchar* boy_type_name = boy_type.GetGLSLTypeName();
11616 const GLuint man_offset = test_case.m_man_offset;
11617 const Utils::Type& man_type = test_case.m_man_type;
11618 const GLchar* man_type_name = man_type.GetGLSLTypeName();
11619 size_t position = 0;
11623 case Utils::Shader::COMPUTE:
11626 case Utils::Shader::FRAGMENT:
11627 source = fs_tested;
11629 case Utils::Shader::GEOMETRY:
11630 source = gs_tested;
11632 case Utils::Shader::TESS_CTRL:
11633 source = tcs_tested;
11635 case Utils::Shader::TESS_EVAL:
11636 source = tes_tested;
11638 case Utils::Shader::VERTEX:
11639 source = vs_tested;
11642 TCU_FAIL("Invalid enum");
11645 sprintf(buffer, "%d", boy_offset);
11646 Utils::replaceToken("BOY_OFFSET", position, buffer, source);
11647 Utils::replaceToken("BOY_TYPE", position, boy_type_name, source);
11648 sprintf(buffer, "%d", man_offset);
11649 Utils::replaceToken("MAN_OFFSET", position, buffer, source);
11650 Utils::replaceToken("MAN_TYPE", position, man_type_name, source);
11651 Utils::replaceToken("BOY_TYPE", position, boy_type_name, source);
11652 Utils::replaceToken("MAN_TYPE", position, man_type_name, source);
11658 case Utils::Shader::FRAGMENT:
11661 case Utils::Shader::GEOMETRY:
11664 case Utils::Shader::TESS_CTRL:
11667 case Utils::Shader::TESS_EVAL:
11670 case Utils::Shader::VERTEX:
11674 TCU_FAIL("Invalid enum");
11681 /** Checks if stage is supported
11683 * @param stage Shader stage
11685 * @return true if supported, false otherwise
11687 bool SSBMemberOverlappingOffsetsTest::isStageSupported(Utils::Shader::STAGES stage)
11689 const Functions& gl = m_context.getRenderContext().getFunctions();
11690 GLint max_supported_buffers = 0;
11695 case Utils::Shader::COMPUTE:
11696 pname = GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS;
11698 case Utils::Shader::FRAGMENT:
11699 pname = GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS;
11701 case Utils::Shader::GEOMETRY:
11702 pname = GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS;
11704 case Utils::Shader::TESS_CTRL:
11705 pname = GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS;
11707 case Utils::Shader::TESS_EVAL:
11708 pname = GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS;
11710 case Utils::Shader::VERTEX:
11711 pname = GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS;
11714 TCU_FAIL("Invalid enum");
11717 gl.getIntegerv(pname, &max_supported_buffers);
11718 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
11720 return 1 <= max_supported_buffers;
11725 * @param context Test framework context
11727 SSBMemberAlignNonPowerOf2Test::SSBMemberAlignNonPowerOf2Test(deqp::Context& context)
11728 : UniformBlockMemberAlignNonPowerOf2Test(context, "ssb_member_align_non_power_of_2",
11729 "Test verifies that align qualifier requires value that is a power of 2")
11731 /* Nothing to be done here */
11734 /** Source for given test case and stage
11736 * @param test_case_index Index of test case
11737 * @param stage Shader stage
11739 * @return Shader source
11741 std::string SSBMemberAlignNonPowerOf2Test::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
11743 static const GLchar* cs = "#version 430 core\n"
11744 "#extension GL_ARB_enhanced_layouts : require\n"
11746 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
11748 "layout (std140) buffer Block {\n"
11750 " layout (align = ALIGN) TYPE man;\n"
11753 "writeonly uniform image2D uni_image;\n"
11757 " vec4 result = vec4(1, 0, 0.5, 1);\n"
11759 " if (TYPE(0) == block.man)\n"
11761 " result = vec4(1, 1, 1, 1) - block.boy;\n"
11764 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
11767 static const GLchar* fs = "#version 430 core\n"
11768 "#extension GL_ARB_enhanced_layouts : require\n"
11771 "out vec4 fs_out;\n"
11775 " fs_out = gs_fs;\n"
11778 static const GLchar* fs_tested = "#version 430 core\n"
11779 "#extension GL_ARB_enhanced_layouts : require\n"
11781 "layout (std140) buffer Block {\n"
11783 " layout (align = ALIGN) TYPE man;\n"
11787 "out vec4 fs_out;\n"
11791 " if (TYPE(0) == block.man)\n"
11793 " fs_out = block.boy;\n"
11796 " fs_out += gs_fs;\n"
11799 static const GLchar* gs = "#version 430 core\n"
11800 "#extension GL_ARB_enhanced_layouts : require\n"
11802 "layout(points) in;\n"
11803 "layout(triangle_strip, max_vertices = 4) out;\n"
11805 "in vec4 tes_gs[];\n"
11806 "out vec4 gs_fs;\n"
11810 " gs_fs = tes_gs[0];\n"
11811 " gl_Position = vec4(-1, -1, 0, 1);\n"
11813 " gs_fs = tes_gs[0];\n"
11814 " gl_Position = vec4(-1, 1, 0, 1);\n"
11816 " gs_fs = tes_gs[0];\n"
11817 " gl_Position = vec4(1, -1, 0, 1);\n"
11819 " gs_fs = tes_gs[0];\n"
11820 " gl_Position = vec4(1, 1, 0, 1);\n"
11824 static const GLchar* gs_tested = "#version 430 core\n"
11825 "#extension GL_ARB_enhanced_layouts : require\n"
11827 "layout(points) in;\n"
11828 "layout(triangle_strip, max_vertices = 4) out;\n"
11830 "layout (std140) buffer Block {\n"
11832 " layout (align = ALIGN) TYPE man;\n"
11835 "in vec4 tes_gs[];\n"
11836 "out vec4 gs_fs;\n"
11840 " if (TYPE(0) == block.man)\n"
11842 " gs_fs = block.boy;\n"
11845 " gs_fs += tes_gs[0];\n"
11846 " gl_Position = vec4(-1, -1, 0, 1);\n"
11848 " gs_fs += tes_gs[0];\n"
11849 " gl_Position = vec4(-1, 1, 0, 1);\n"
11851 " gs_fs += tes_gs[0];\n"
11852 " gl_Position = vec4(1, -1, 0, 1);\n"
11854 " gs_fs += tes_gs[0];\n"
11855 " gl_Position = vec4(1, 1, 0, 1);\n"
11859 static const GLchar* tcs = "#version 430 core\n"
11860 "#extension GL_ARB_enhanced_layouts : require\n"
11862 "layout(vertices = 1) out;\n"
11864 "in vec4 vs_tcs[];\n"
11865 "out vec4 tcs_tes[];\n"
11870 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
11872 " gl_TessLevelOuter[0] = 1.0;\n"
11873 " gl_TessLevelOuter[1] = 1.0;\n"
11874 " gl_TessLevelOuter[2] = 1.0;\n"
11875 " gl_TessLevelOuter[3] = 1.0;\n"
11876 " gl_TessLevelInner[0] = 1.0;\n"
11877 " gl_TessLevelInner[1] = 1.0;\n"
11880 static const GLchar* tcs_tested = "#version 430 core\n"
11881 "#extension GL_ARB_enhanced_layouts : require\n"
11883 "layout(vertices = 1) out;\n"
11885 "layout (std140) buffer Block {\n"
11887 " layout (align = ALIGN) TYPE man;\n"
11890 "in vec4 vs_tcs[];\n"
11891 "out vec4 tcs_tes[];\n"
11895 " if (TYPE(0) == block.man)\n"
11897 " tcs_tes[gl_InvocationID] = block.boy;\n"
11901 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
11903 " gl_TessLevelOuter[0] = 1.0;\n"
11904 " gl_TessLevelOuter[1] = 1.0;\n"
11905 " gl_TessLevelOuter[2] = 1.0;\n"
11906 " gl_TessLevelOuter[3] = 1.0;\n"
11907 " gl_TessLevelInner[0] = 1.0;\n"
11908 " gl_TessLevelInner[1] = 1.0;\n"
11911 static const GLchar* tes = "#version 430 core\n"
11912 "#extension GL_ARB_enhanced_layouts : require\n"
11914 "layout(isolines, point_mode) in;\n"
11916 "in vec4 tcs_tes[];\n"
11917 "out vec4 tes_gs;\n"
11921 " tes_gs = tcs_tes[0];\n"
11924 static const GLchar* tes_tested = "#version 430 core\n"
11925 "#extension GL_ARB_enhanced_layouts : require\n"
11927 "layout(isolines, point_mode) in;\n"
11929 "layout (std140) buffer Block {\n"
11931 " layout (align = ALIGN) TYPE man;\n"
11934 "in vec4 tcs_tes[];\n"
11935 "out vec4 tes_gs;\n"
11939 " if (TYPE(0) == block.man)\n"
11941 " tes_gs = block.boy;\n"
11944 " tes_gs += tcs_tes[0];\n"
11947 static const GLchar* vs = "#version 430 core\n"
11948 "#extension GL_ARB_enhanced_layouts : require\n"
11951 "out vec4 vs_tcs;\n"
11955 " vs_tcs = in_vs;\n"
11958 static const GLchar* vs_tested = "#version 430 core\n"
11959 "#extension GL_ARB_enhanced_layouts : require\n"
11961 "layout (std140) buffer Block {\n"
11963 " layout (align = ALIGN) TYPE man;\n"
11967 "out vec4 vs_tcs;\n"
11971 " if (TYPE(0) == block.man)\n"
11973 " vs_tcs = block.boy;\n"
11976 " vs_tcs += in_vs;\n"
11980 std::string source;
11981 testCase& test_case = m_test_cases[test_case_index];
11983 if (test_case.m_stage == stage)
11986 const GLuint alignment = test_case.m_alignment;
11987 const Utils::Type& type = test_case.m_type;
11988 const GLchar* type_name = type.GetGLSLTypeName();
11989 size_t position = 0;
11993 case Utils::Shader::COMPUTE:
11996 case Utils::Shader::FRAGMENT:
11997 source = fs_tested;
11999 case Utils::Shader::GEOMETRY:
12000 source = gs_tested;
12002 case Utils::Shader::TESS_CTRL:
12003 source = tcs_tested;
12005 case Utils::Shader::TESS_EVAL:
12006 source = tes_tested;
12008 case Utils::Shader::VERTEX:
12009 source = vs_tested;
12012 TCU_FAIL("Invalid enum");
12015 sprintf(buffer, "%d", alignment);
12016 Utils::replaceToken("ALIGN", position, buffer, source);
12017 Utils::replaceToken("TYPE", position, type_name, source);
12018 Utils::replaceToken("TYPE", position, type_name, source);
12024 case Utils::Shader::FRAGMENT:
12027 case Utils::Shader::GEOMETRY:
12030 case Utils::Shader::TESS_CTRL:
12033 case Utils::Shader::TESS_EVAL:
12036 case Utils::Shader::VERTEX:
12040 TCU_FAIL("Invalid enum");
12047 /** Checks if stage is supported
12049 * @param stage Shader stage
12051 * @return true if supported, false otherwise
12053 bool SSBMemberAlignNonPowerOf2Test::isStageSupported(Utils::Shader::STAGES stage)
12055 const Functions& gl = m_context.getRenderContext().getFunctions();
12056 GLint max_supported_buffers = 0;
12061 case Utils::Shader::COMPUTE:
12062 pname = GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS;
12064 case Utils::Shader::FRAGMENT:
12065 pname = GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS;
12067 case Utils::Shader::GEOMETRY:
12068 pname = GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS;
12070 case Utils::Shader::TESS_CTRL:
12071 pname = GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS;
12073 case Utils::Shader::TESS_EVAL:
12074 pname = GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS;
12076 case Utils::Shader::VERTEX:
12077 pname = GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS;
12080 TCU_FAIL("Invalid enum");
12083 gl.getIntegerv(pname, &max_supported_buffers);
12084 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
12086 return 1 <= max_supported_buffers;
12091 * @param context Test framework context
12093 SSBAlignmentTest::SSBAlignmentTest(deqp::Context& context)
12094 : TextureTestBase(context, "ssb_alignment", "Test verifies offset and alignment of ssb buffer")
12098 /** Get interface of program
12101 * @param program_interface Interface of program
12102 * @param varying_passthrough Collection of connections between in and out variables
12104 void SSBAlignmentTest::getProgramInterface(GLuint /* test_case_index */, Utils::ProgramInterface& program_interface,
12105 Utils::VaryingPassthrough& varying_passthrough)
12107 static const Utils::Type vec4 = Utils::Type::vec4;
12109 #if WRKARD_UNIFORMBLOCKALIGNMENT
12111 static const GLuint block_align = 16;
12113 #else /* WRKARD_UNIFORMBLOCKALIGNMENT */
12115 static const GLuint block_align = 64;
12117 #endif /* WRKARD_UNIFORMBLOCKALIGNMENT */
12119 static const GLuint fifth_align = 16;
12120 static const GLuint vec4_stride = 16;
12121 static const GLuint data_stride = vec4_stride * 2; /* one vec4 + one scalar aligned to 16 */
12123 const GLuint first_offset = 0; /* vec4 at 0 */
12124 const GLuint second_offset = Utils::Type::GetActualOffset(first_offset + vec4_stride, block_align); /* Data at 32 */
12125 const GLuint third_offset =
12126 Utils::Type::GetActualOffset(second_offset + data_stride, block_align); /* Data[2] at 64 */
12127 const GLuint fourth_offset =
12128 Utils::Type::GetActualOffset(third_offset + data_stride * 2, block_align); /* vec4[3] at 96 */
12129 const GLuint fifth_offset =
12130 Utils::Type::GetActualOffset(fourth_offset + vec4_stride * 3, fifth_align); /* vec4[2] at 160 */
12131 const GLuint sixth_offset =
12132 Utils::Type::GetActualOffset(fifth_offset + vec4_stride * 2, block_align); /* Data at 192 */
12134 Utils::Interface* structure = program_interface.Structure("Data");
12136 structure->Member("vector", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::vec4,
12137 false /* normalized */, 0 /* n_array_elements */, Utils::Type::vec4.GetSize(), 0 /* offset */);
12139 structure->Member("scalar", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::_float,
12140 false /* normalized */, 0 /* n_array_elements */, Utils::Type::_float.GetSize(),
12141 Utils::Type::vec4.GetSize() /* offset */);
12143 /* Prepare Block */
12144 Utils::Interface* vs_buf_Block = program_interface.Block("vs_buf_Block");
12146 vs_buf_Block->Member("first", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::vec4,
12147 false /* normalized */, 0 /* n_array_elements */, vec4_stride, first_offset /* offset */);
12149 vs_buf_Block->Member("second", "", 0 /* expected_component */, 0 /* expected_location */, structure,
12150 0 /* n_array_elements */, data_stride, second_offset);
12152 vs_buf_Block->Member("third", "", 0 /* expected_component */, 0 /* expected_location */, structure,
12153 2 /* n_array_elements */, data_stride, third_offset);
12155 vs_buf_Block->Member("fourth", "", 0 /* expected_component */, 0 /* expected_location */, vec4,
12156 false /* normalized */, 3 /* n_array_elements */, vec4_stride, fourth_offset);
12158 vs_buf_Block->Member("fifth", "layout(align = 16)", 0 /* expected_component */, 0 /* expected_location */, vec4,
12159 false /* normalized */, 2 /* n_array_elements */, vec4_stride, fifth_offset);
12161 vs_buf_Block->Member("sixth", "", 0 /* expected_component */, 0 /* expected_location */, structure,
12162 0 /* n_array_elements */, data_stride, sixth_offset);
12164 const GLuint stride = calculateStride(*vs_buf_Block);
12165 m_data.resize(stride);
12166 generateData(*vs_buf_Block, 0, m_data);
12168 Utils::ShaderInterface& vs_si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
12170 /* Add uniform BLOCK */
12171 #if WRKARD_UNIFORMBLOCKALIGNMENT
12172 vs_si.SSB("vs_buf_block", "layout (std140, binding = BINDING)", 0, 0, vs_buf_Block, 0,
12173 static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
12174 #else /* WRKARD_UNIFORMBLOCKALIGNMENT */
12175 vs_si.SSB("vs_buf_block", "layout (std140, binding = BINDING, align = 64)", 0, 0, vs_buf_Block, 0,
12176 static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
12177 #endif /* WRKARD_UNIFORMBLOCKALIGNMENT */
12179 program_interface.CloneVertexInterface(varying_passthrough);
12182 /** Selects if "draw" stages are relevant for test
12186 * @return true if all stages support shader storage buffers, false otherwise
12188 bool SSBAlignmentTest::isDrawRelevant(GLuint /* test_case_index */)
12190 const Functions& gl = m_context.getRenderContext().getFunctions();
12191 GLint gs_supported_buffers = 0;
12192 GLint tcs_supported_buffers = 0;
12193 GLint tes_supported_buffers = 0;
12194 GLint vs_supported_buffers = 0;
12196 gl.getIntegerv(GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS, &gs_supported_buffers);
12197 gl.getIntegerv(GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS, &tcs_supported_buffers);
12198 gl.getIntegerv(GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS, &tes_supported_buffers);
12199 gl.getIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &vs_supported_buffers);
12201 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
12203 return ((1 <= gs_supported_buffers) && (1 <= tcs_supported_buffers) && (1 <= tes_supported_buffers) &&
12204 (1 <= vs_supported_buffers));
12209 * @param context Test framework context
12211 VaryingLocationsTest::VaryingLocationsTest(deqp::Context& context)
12212 : TextureTestBase(context, "varying_locations", "Test verifies that input and output locations are respected")
12218 * @param context Test context
12219 * @param test_name Name of test
12220 * @param test_description Description of test
12222 VaryingLocationsTest::VaryingLocationsTest(deqp::Context& context, const glw::GLchar* test_name,
12223 const glw::GLchar* test_description)
12224 : TextureTestBase(context, test_name, test_description)
12228 /** Get interface of program
12230 * @param test_case_index Test case
12231 * @param program_interface Interface of program
12232 * @param varying_passthrough Collection of connections between in and out variables
12234 void VaryingLocationsTest::getProgramInterface(GLuint test_case_index, Utils::ProgramInterface& program_interface,
12235 Utils::VaryingPassthrough& varying_passthrough)
12237 const Utils::Type type = getType(test_case_index);
12239 m_first_data = type.GenerateDataPacked();
12240 m_last_data = type.GenerateDataPacked();
12242 prepareShaderStage(Utils::Shader::FRAGMENT, type, program_interface, varying_passthrough);
12243 prepareShaderStage(Utils::Shader::GEOMETRY, type, program_interface, varying_passthrough);
12244 prepareShaderStage(Utils::Shader::TESS_CTRL, type, program_interface, varying_passthrough);
12245 prepareShaderStage(Utils::Shader::TESS_EVAL, type, program_interface, varying_passthrough);
12246 prepareShaderStage(Utils::Shader::VERTEX, type, program_interface, varying_passthrough);
12251 * @param test_case_index Index of test case
12253 * @return Name of type test in test_case_index
12255 std::string VaryingLocationsTest::getTestCaseName(glw::GLuint test_case_index)
12257 return getTypeName(test_case_index);
12260 /** Returns number of types to test
12262 * @return Number of types, 34
12264 glw::GLuint VaryingLocationsTest::getTestCaseNumber()
12266 return getTypesNumber();
12269 /** Selects if "compute" stage is relevant for test
12275 bool VaryingLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
12284 std::string VaryingLocationsTest::prepareGlobals(GLint last_in_loc, GLint last_out_loc)
12287 std::string globals = "const uint first_input_location = 0u;\n"
12288 "const uint first_output_location = 0u;\n"
12289 "const uint last_input_location = LAST_INPUTu;\n"
12290 "const uint last_output_location = LAST_OUTPUTu;\n";
12291 size_t position = 100; /* Skip first part */
12293 sprintf(buffer, "%d", last_in_loc);
12294 Utils::replaceToken("LAST_INPUT", position, buffer, globals);
12296 sprintf(buffer, "%d", last_out_loc);
12297 Utils::replaceToken("LAST_OUTPUT", position, buffer, globals);
12305 void VaryingLocationsTest::prepareShaderStage(Utils::Shader::STAGES stage, const Utils::Type& type,
12306 Utils::ProgramInterface& program_interface,
12307 Utils::VaryingPassthrough& varying_passthrough)
12309 const GLuint array_length = 1;
12310 const GLuint first_in_loc = 0;
12311 const GLuint first_out_loc = 0;
12312 const GLuint last_in_loc = getLastInputLocation(stage, type, array_length);
12313 size_t position = 0;
12315 const GLchar* prefix_in = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::VARYING_INPUT);
12317 const GLchar* prefix_out = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::VARYING_OUTPUT);
12319 const GLchar* qual_first_in = "layout (location = first_input_location)";
12320 const GLchar* qual_first_out = "layout (location = first_output_location)";
12321 const GLchar* qual_last_in = "layout (location = last_input_location)";
12322 const GLchar* qual_last_out = "layout (location = last_output_location)";
12324 Utils::ShaderInterface& si = program_interface.GetShaderInterface(stage);
12325 const GLuint type_size = type.GetSize();
12327 std::string first_in_name = "PREFIXfirst";
12328 std::string first_out_name = "PREFIXfirst";
12329 std::string last_in_name = "PREFIXlast";
12330 std::string last_out_name = "PREFIXlast";
12332 Utils::replaceToken("PREFIX", position, prefix_in, first_in_name);
12334 Utils::replaceToken("PREFIX", position, prefix_out, first_out_name);
12336 Utils::replaceToken("PREFIX", position, prefix_in, last_in_name);
12338 Utils::replaceToken("PREFIX", position, prefix_out, last_out_name);
12340 if (Utils::Shader::FRAGMENT == stage)
12342 qual_first_in = "layout (location = first_input_location) flat";
12343 qual_last_in = "layout (location = last_input_location) flat";
12345 if (Utils::Shader::GEOMETRY == stage)
12347 qual_first_out = "layout (location = first_output_location) flat";
12348 qual_last_out = "layout (location = last_output_location) flat";
12351 Utils::Variable* first_in = si.Input(
12352 first_in_name.c_str(), qual_first_in /* qualifiers */, 0 /* expected_componenet */,
12353 first_in_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */, 0u /* n_array_elements */,
12354 0u /* stride */, 0u /* offset */, (GLvoid*)&m_first_data[0] /* data */, m_first_data.size() /* data_size */);
12356 Utils::Variable* last_in =
12357 si.Input(last_in_name.c_str(), qual_last_in /* qualifiers */, 0 /* expected_componenet */,
12358 last_in_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12359 0u /* n_array_elements */, 0u /* stride */, type_size /* offset */,
12360 (GLvoid*)&m_last_data[0] /* data */, m_last_data.size() /* data_size */);
12362 if (Utils::Shader::FRAGMENT != stage)
12364 const GLuint last_out_loc = getLastOutputLocation(stage, type, array_length);
12366 Utils::Variable* first_out =
12367 si.Output(first_out_name.c_str(), qual_first_out /* qualifiers */, 0 /* expected_componenet */,
12368 first_out_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12369 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)&m_first_data[0] /* data */,
12370 m_first_data.size() /* data_size */);
12372 Utils::Variable* last_out = si.Output(
12373 last_out_name.c_str(), qual_last_out /* qualifiers */, 0 /* expected_componenet */,
12374 last_out_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */, 0u /* n_array_elements */,
12375 0u /* stride */, 0u /* offset */, (GLvoid*)&m_last_data[0] /* data */, m_last_data.size() /* data_size */);
12377 si.m_globals = prepareGlobals(last_in_loc, last_out_loc);
12379 varying_passthrough.Add(stage, first_in, first_out);
12380 varying_passthrough.Add(stage, last_in, last_out);
12384 /* No outputs for fragment shader, so last_output_location can be 0 */
12385 si.m_globals = prepareGlobals(last_in_loc, 0);
12389 /** This test should be run with separable programs
12395 bool VaryingLocationsTest::useMonolithicProgram(GLuint /* test_case_index */)
12400 /* Constants used by VertexAttribLocationsTest */
12401 const GLuint VertexAttribLocationsTest::m_base_vertex = 4;
12402 const GLuint VertexAttribLocationsTest::m_base_instance = 2;
12403 const GLuint VertexAttribLocationsTest::m_loc_vertex = 2;
12404 const GLuint VertexAttribLocationsTest::m_loc_instance = 5;
12405 const GLuint VertexAttribLocationsTest::m_n_instances = 4;
12409 * @param context Test framework context
12411 VertexAttribLocationsTest::VertexAttribLocationsTest(deqp::Context& context)
12412 : TextureTestBase(context, "vertex_attrib_locations",
12413 "Test verifies that attribute locations are respected by drawing operations")
12417 /** Execute proper draw command for test case
12419 * @param test_case_index Index of test case
12421 void VertexAttribLocationsTest::executeDrawCall(GLuint test_case_index)
12423 const Functions& gl = m_context.getRenderContext().getFunctions();
12425 switch (test_case_index)
12428 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
12429 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
12431 case DRAWARRAYSINSTANCED:
12432 gl.drawArraysInstanced(GL_PATCHES, 0 /* first */, 1 /* count */, m_n_instances);
12433 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArraysInstanced");
12436 gl.drawElements(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL);
12437 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElements");
12439 case DRAWELEMENTSBASEVERTEX:
12440 gl.drawElementsBaseVertex(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL, m_base_vertex);
12441 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsBaseVertex");
12443 case DRAWELEMENTSINSTANCED:
12444 gl.drawElementsInstanced(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL, m_n_instances);
12445 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsInstanced");
12447 case DRAWELEMENTSINSTANCEDBASEINSTANCE:
12448 gl.drawElementsInstancedBaseInstance(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL, m_n_instances,
12450 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsInstancedBaseInstance");
12452 case DRAWELEMENTSINSTANCEDBASEVERTEX:
12453 gl.drawElementsInstancedBaseVertex(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL, m_n_instances,
12455 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsInstancedBaseVertex");
12457 case DRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCE:
12458 gl.drawElementsInstancedBaseVertexBaseInstance(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL,
12459 m_n_instances, m_base_vertex, m_base_instance);
12460 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsInstancedBaseVertexBaseInstance");
12463 TCU_FAIL("Invalid enum");
12467 /** Get interface of program
12470 * @param program_interface Interface of program
12473 void VertexAttribLocationsTest::getProgramInterface(GLuint /* test_case_index */,
12474 Utils::ProgramInterface& program_interface,
12475 Utils::VaryingPassthrough& /* varying_passthrough */)
12477 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
12480 si.m_globals = "const uint vertex_index_location = 2;\n"
12481 "const uint instance_index_location = 5;\n";
12484 si.Input("vertex_index" /* name */, "layout (location = vertex_index_location)" /* qualifiers */,
12485 0 /* expected_componenet */, m_loc_vertex /* expected_location */, Utils::Type::uint /* type */,
12486 GL_FALSE /* normalized */, 0u /* n_array_elements */, 16 /* stride */, 0u /* offset */,
12487 (GLvoid*)0 /* data */, 0 /* data_size */);
12488 si.Input("instance_index" /* name */, "layout (location = instance_index_location)" /* qualifiers */,
12489 0 /* expected_componenet */, m_loc_instance /* expected_location */, Utils::Type::uint /* type */,
12490 GL_FALSE /* normalized */, 0u /* n_array_elements */, 16 /* stride */, 16u /* offset */,
12491 (GLvoid*)0 /* data */, 0 /* data_size */);
12494 /** Get name of test case
12496 * @param test_case_index Index of test case
12498 * @return Name of test case
12500 std::string VertexAttribLocationsTest::getTestCaseName(glw::GLuint test_case_index)
12502 std::string result;
12504 switch (test_case_index)
12507 result = "DrawArrays";
12509 case DRAWARRAYSINSTANCED:
12510 result = "DrawArraysInstanced";
12513 result = "DrawElements";
12515 case DRAWELEMENTSBASEVERTEX:
12516 result = "DrawElementsBaseVertex";
12518 case DRAWELEMENTSINSTANCED:
12519 result = "DrawElementsInstanced";
12521 case DRAWELEMENTSINSTANCEDBASEINSTANCE:
12522 result = "DrawElementsInstancedBaseInstance";
12524 case DRAWELEMENTSINSTANCEDBASEVERTEX:
12525 result = "DrawElementsInstancedBaseVertex";
12527 case DRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCE:
12528 result = "DrawElementsInstancedBaseVertexBaseInstance";
12531 TCU_FAIL("Invalid enum");
12537 /** Get number of test cases
12539 * @return Number of test cases
12541 GLuint VertexAttribLocationsTest::getTestCaseNumber()
12543 return TESTCASES_MAX;
12546 /** Prepare code snippet that will verify in and uniform variables
12550 * @param stage Shader stage
12552 * @return Code that verify variables
12554 std::string VertexAttribLocationsTest::getVerificationSnippet(GLuint /* test_case_index */,
12555 Utils::ProgramInterface& /* program_interface */,
12556 Utils::Shader::STAGES stage)
12558 std::string verification;
12560 if (Utils::Shader::VERTEX == stage)
12563 #if DEBUG_VERTEX_ATTRIB_LOCATIONS_TEST_VARIABLE
12565 verification = "if (gl_InstanceID != instance_index)\n"
12569 " else if (gl_VertexID != vertex_index)\n"
12576 verification = "if ((gl_VertexID != vertex_index) ||\n"
12577 " (gl_InstanceID != instance_index) )\n"
12589 return verification;
12592 /** Selects if "compute" stage is relevant for test
12598 bool VertexAttribLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
12603 /** Prepare attributes, vertex array object and array buffer
12606 * @param ignored Interface of program
12607 * @param buffer Array buffer
12608 * @param vao Vertex array object
12610 void VertexAttribLocationsTest::prepareAttributes(GLuint test_case_index /* test_case_index */,
12611 Utils::ProgramInterface& /* program_interface */,
12612 Utils::Buffer& buffer, Utils::VertexArray& vao)
12614 static const GLuint vertex_index_data[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
12615 static const GLuint instance_index_data[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
12617 std::vector<GLuint> buffer_data;
12618 buffer_data.resize(8 + 8); /* vertex_index_data + instance_index_data */
12620 GLubyte* ptr = (GLubyte*)&buffer_data[0];
12623 When case index >=2, the test calls glDrawElement*(), such as glDrawElementsBaseVertex(), glDrawElementsInstanced(), glDrawElementsInstancedBaseInstance() and so on,
12624 So we need to change the buffer type as GL_ELEMENT_ARRAY_BUFFER
12626 if (test_case_index >= 2)
12628 buffer.m_buffer = Utils::Buffer::Element;
12633 vao.Attribute(m_loc_vertex /* vertex_index */, Utils::Type::uint, 0 /* array_elements */, false /* normalized */,
12634 0 /* stride */, 0 /* offset */);
12636 vao.Attribute(m_loc_instance /* instance_index */, Utils::Type::uint, 0 /* array_elements */,
12637 false /* normalized */, 0 /* stride */, (GLvoid*)sizeof(vertex_index_data) /* offset */);
12638 // when test_case_index is 5 or 7, the draw call is glDrawElementsInstancedBaseInstance, glDrawElementsInstancedBaseVertexBaseInstance
12639 // the instancecount is 4, the baseinstance is 2, the divisor should be set 2
12640 bool isBaseInstanced = (test_case_index == DRAWELEMENTSINSTANCEDBASEINSTANCE ||
12641 test_case_index == DRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCE);
12642 vao.Divisor(m_context.getRenderContext().getFunctions() /* gl */, m_loc_instance /* instance_index */,
12643 isBaseInstanced ? 2 : 1 /* divisor. 1 - advance once per instance */);
12645 memcpy(ptr + 0, vertex_index_data, sizeof(vertex_index_data));
12646 memcpy(ptr + sizeof(vertex_index_data), instance_index_data, sizeof(instance_index_data));
12648 buffer.Data(Utils::Buffer::StaticDraw, buffer_data.size() * sizeof(GLuint), ptr);
12651 /** This test should be run with separable programs
12657 bool VertexAttribLocationsTest::useMonolithicProgram(GLuint /* test_case_index */)
12664 * @param context Test framework context
12666 VaryingArrayLocationsTest::VaryingArrayLocationsTest(deqp::Context& context)
12667 : VaryingLocationsTest(context, "varying_array_locations",
12668 "Test verifies that input and output locations are respected for arrays")
12675 void VaryingArrayLocationsTest::prepareShaderStage(Utils::Shader::STAGES stage, const Utils::Type& type,
12676 Utils::ProgramInterface& program_interface,
12677 Utils::VaryingPassthrough& varying_passthrough)
12679 const GLuint array_length = 1u;
12680 const GLuint first_in_loc = 0;
12681 const GLuint first_out_loc = 0;
12682 const GLuint last_in_loc = getLastInputLocation(stage, type, array_length);
12683 size_t position = 0;
12685 const GLchar* prefix_in = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::VARYING_INPUT);
12687 const GLchar* prefix_out = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::VARYING_OUTPUT);
12689 const GLchar* qual_first_in = "layout (location = first_input_location)";
12690 const GLchar* qual_first_out = "layout (location = first_output_location)";
12691 const GLchar* qual_last_in = "layout (location = last_input_location)";
12692 const GLchar* qual_last_out = "layout (location = last_output_location)";
12694 Utils::ShaderInterface& si = program_interface.GetShaderInterface(stage);
12695 const GLuint type_size = type.GetSize();
12697 std::string first_in_name = "PREFIXfirst";
12698 std::string first_out_name = "PREFIXfirst";
12699 std::string last_in_name = "PREFIXlast";
12700 std::string last_out_name = "PREFIXlast";
12702 Utils::replaceToken("PREFIX", position, prefix_in, first_in_name);
12704 Utils::replaceToken("PREFIX", position, prefix_out, first_out_name);
12706 Utils::replaceToken("PREFIX", position, prefix_in, last_in_name);
12708 Utils::replaceToken("PREFIX", position, prefix_out, last_out_name);
12710 if (Utils::Shader::FRAGMENT == stage)
12712 qual_first_in = "layout (location = first_input_location) flat";
12713 qual_last_in = "layout (location = last_input_location) flat";
12715 if (Utils::Shader::GEOMETRY == stage)
12717 qual_first_out = "layout (location = first_output_location) flat";
12718 qual_last_out = "layout (location = last_output_location) flat";
12721 Utils::Variable* first_in =
12722 si.Input(first_in_name.c_str(), qual_first_in /* qualifiers */, 0 /* expected_componenet */,
12723 first_in_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12724 array_length /* n_array_elements */, 0u /* stride */, 0u /* offset */,
12725 (GLvoid*)&m_first_data[0] /* data */, m_first_data.size() /* data_size */);
12727 Utils::Variable* last_in =
12728 si.Input(last_in_name.c_str(), qual_last_in /* qualifiers */, 0 /* expected_componenet */,
12729 last_in_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12730 array_length /* n_array_elements */, 0u /* stride */, type_size /* offset */,
12731 (GLvoid*)&m_last_data[0] /* data */, m_last_data.size() /* data_size */);
12733 if (Utils::Shader::FRAGMENT != stage)
12735 const GLuint last_out_loc = getLastOutputLocation(stage, type, array_length);
12737 Utils::Variable* first_out =
12738 si.Output(first_out_name.c_str(), qual_first_out /* qualifiers */, 0 /* expected_componenet */,
12739 first_out_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12740 array_length /* n_array_elements */, 0u /* stride */, 0u /* offset */,
12741 (GLvoid*)&m_first_data[0] /* data */, m_first_data.size() /* data_size */);
12743 Utils::Variable* last_out =
12744 si.Output(last_out_name.c_str(), qual_last_out /* qualifiers */, 0 /* expected_componenet */,
12745 last_out_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12746 array_length /* n_array_elements */, 0u /* stride */, 0u /* offset */,
12747 (GLvoid*)&m_last_data[0] /* data */, m_last_data.size() /* data_size */);
12749 si.m_globals = prepareGlobals(last_in_loc, last_out_loc);
12751 varying_passthrough.Add(stage, first_in, first_out);
12752 varying_passthrough.Add(stage, last_in, last_out);
12756 /* No outputs for fragment shader, so last_output_location can be 0 */
12757 si.m_globals = prepareGlobals(last_in_loc, 0);
12763 * @param context Test framework context
12765 VaryingStructureLocationsTest::VaryingStructureLocationsTest(deqp::Context& context)
12766 : TextureTestBase(context, "varying_structure_locations",
12767 "Test verifies that locations are respected when structures are used as in and out ")
12771 /** Prepare code snippet that will pass in variables to out variables
12774 * @param varying_passthrough Collection of connections between in and out variables
12775 * @param stage Shader stage
12777 * @return Code that pass in variables to next stage
12779 std::string VaryingStructureLocationsTest::getPassSnippet(GLuint /* test_case_index */,
12780 Utils::VaryingPassthrough& varying_passthrough,
12781 Utils::Shader::STAGES stage)
12783 std::string result;
12785 if (Utils::Shader::VERTEX != stage)
12787 result = TextureTestBase::getPassSnippet(0, varying_passthrough, stage);
12791 result = " vs_tcs_output[0].single = vs_in_single[0];\n"
12792 " vs_tcs_output[0].array[0] = vs_in_array[0];\n";
12798 /** Get interface of program
12800 * @param test_case_index Test case
12801 * @param program_interface Interface of program
12802 * @param varying_passthrough Collection of connections between in and out variables
12804 void VaryingStructureLocationsTest::getProgramInterface(GLuint test_case_index,
12805 Utils::ProgramInterface& program_interface,
12806 Utils::VaryingPassthrough& varying_passthrough)
12808 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
12809 const Utils::Type type = getType(test_case_index);
12812 // We should call GenerateDataPacked() to generate data, which can make sure the data in shader is correct
12813 m_single_data = type.GenerateDataPacked();
12814 m_array_data = type.GenerateDataPacked();
12816 m_data.resize(m_single_data.size() + m_array_data.size());
12817 GLubyte* ptr = (GLubyte*)&m_data[0];
12818 memcpy(ptr, &m_single_data[0], m_single_data.size());
12819 memcpy(ptr + m_single_data.size(), &m_array_data[0], m_array_data.size());
12821 Utils::Interface* structure = program_interface.Structure("Data");
12823 structure->Member("single", "" /* qualifiers */, 0 /* component */, 0 /* location */, type, false /* normalized */,
12824 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */);
12826 // the second struct member 's location should not be 0, it is based on by how many the locations the first struct member consumed.
12827 structure->Member("array", "" /* qualifiers */, 0 /* component */, type.GetLocations() /* location */, type,
12828 false /* normalized */, 1u /* n_array_elements */, 0u /* stride */, type.GetSize() /* offset */);
12830 si.Input("vs_in_single", "layout (location = 0)", 0 /* component */, 0 /* location */, type, false /* normalized */,
12831 1u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)&m_single_data[0] /* data */,
12832 m_single_data.size() /* data_size */);
12834 si.Input("vs_in_array", "layout (location = 8)", 0 /* component */, 8 /* location */, type, false /* normalized */,
12835 1u /* n_array_elements */, 0u /* stride */, type.GetSize() /* offset */,
12836 (GLvoid*)&m_array_data[0] /* data */, m_array_data.size() /* data_size */);
12838 si.Output("vs_tcs_output", "layout (location = 0)", 0 /* component */, 0 /* location */, structure,
12839 1u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)&m_data[0] /* data */,
12840 m_data.size() /* data_size */);
12842 program_interface.CloneVertexInterface(varying_passthrough);
12847 * @param test_case_index Index of test case
12849 * @return Name of type test in test_case_index
12851 std::string VaryingStructureLocationsTest::getTestCaseName(glw::GLuint test_case_index)
12853 return getTypeName(test_case_index);
12856 /** Returns number of types to test
12858 * @return Number of types, 34
12860 glw::GLuint VaryingStructureLocationsTest::getTestCaseNumber()
12862 return getTypesNumber();
12865 /** Selects if "compute" stage is relevant for test
12871 bool VaryingStructureLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
12876 /** This test should be run with separable programs
12882 bool VaryingStructureLocationsTest::useMonolithicProgram(GLuint /* test_case_index */)
12889 * @param context Test context
12890 * @param test_name Name of test
12891 * @param test_description Description of test
12893 VaryingStructureMemberLocationTest::VaryingStructureMemberLocationTest(deqp::Context& context)
12894 : NegativeTestBase(context, "varying_structure_member_location",
12895 "Test verifies that compiler does not allow location qualifier on member of strucure")
12899 /** Source for given test case and stage
12901 * @param test_case_index Index of test case
12902 * @param stage Shader stage
12904 * @return Shader source
12906 std::string VaryingStructureMemberLocationTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
12908 static const GLchar* struct_definition = "struct Data {\n"
12910 " layout (location = 4) vec4 goten;\n"
12912 static const GLchar* input_var = "in Data data;\n";
12913 static const GLchar* output_var = "out Data data;\n";
12914 static const GLchar* input_use = " result += data.gohan + data.goten;\n";
12915 static const GLchar* output_use = " data.gohan = result / 2;\n"
12916 " data.goten = result / 4 - data.gohan;\n";
12917 static const GLchar* fs = "#version 430 core\n"
12918 "#extension GL_ARB_enhanced_layouts : require\n"
12921 "out vec4 fs_out;\n"
12925 " fs_out = gs_fs;\n"
12928 static const GLchar* fs_tested = "#version 430 core\n"
12929 "#extension GL_ARB_enhanced_layouts : require\n"
12931 "STRUCT_DEFINITION"
12933 "VARIABLE_DEFINITION"
12936 "out vec4 fs_out;\n"
12940 " vec4 result = gs_fs;\n"
12944 " fs_out += result;\n"
12947 static const GLchar* gs = "#version 430 core\n"
12948 "#extension GL_ARB_enhanced_layouts : require\n"
12950 "layout(points) in;\n"
12951 "layout(triangle_strip, max_vertices = 4) out;\n"
12953 "in vec4 tes_gs[];\n"
12954 "out vec4 gs_fs;\n"
12958 " gs_fs = tes_gs[0];\n"
12959 " gl_Position = vec4(-1, -1, 0, 1);\n"
12961 " gs_fs = tes_gs[0];\n"
12962 " gl_Position = vec4(-1, 1, 0, 1);\n"
12964 " gs_fs = tes_gs[0];\n"
12965 " gl_Position = vec4(1, -1, 0, 1);\n"
12967 " gs_fs = tes_gs[0];\n"
12968 " gl_Position = vec4(1, 1, 0, 1);\n"
12972 static const GLchar* gs_tested = "#version 430 core\n"
12973 "#extension GL_ARB_enhanced_layouts : require\n"
12975 "layout(points) in;\n"
12976 "layout(triangle_strip, max_vertices = 4) out;\n"
12978 "STRUCT_DEFINITION"
12980 "VARIABLE_DEFINITION"
12982 "in vec4 tes_gs[];\n"
12983 "out vec4 gs_fs;\n"
12987 " vec4 result = tes_gs[0];\n"
12991 " gs_fs = result;\n"
12992 " gl_Position = vec4(-1, -1, 0, 1);\n"
12994 " gs_fs = result;\n"
12995 " gl_Position = vec4(-1, 1, 0, 1);\n"
12997 " gs_fs = result;\n"
12998 " gl_Position = vec4(1, -1, 0, 1);\n"
13000 " gs_fs = result;\n"
13001 " gl_Position = vec4(1, 1, 0, 1);\n"
13005 static const GLchar* tcs = "#version 430 core\n"
13006 "#extension GL_ARB_enhanced_layouts : require\n"
13008 "layout(vertices = 1) out;\n"
13010 "in vec4 vs_tcs[];\n"
13011 "out vec4 tcs_tes[];\n"
13016 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
13018 " gl_TessLevelOuter[0] = 1.0;\n"
13019 " gl_TessLevelOuter[1] = 1.0;\n"
13020 " gl_TessLevelOuter[2] = 1.0;\n"
13021 " gl_TessLevelOuter[3] = 1.0;\n"
13022 " gl_TessLevelInner[0] = 1.0;\n"
13023 " gl_TessLevelInner[1] = 1.0;\n"
13026 static const GLchar* tcs_tested = "#version 430 core\n"
13027 "#extension GL_ARB_enhanced_layouts : require\n"
13029 "layout(vertices = 1) out;\n"
13031 "STRUCT_DEFINITION"
13033 "VARIABLE_DEFINITION"
13035 "in vec4 vs_tcs[];\n"
13036 "out vec4 tcs_tes[];\n"
13040 " vec4 result = vs_tcs[gl_InvocationID];\n"
13044 " tcs_tes[gl_InvocationID] = result;\n"
13046 " gl_TessLevelOuter[0] = 1.0;\n"
13047 " gl_TessLevelOuter[1] = 1.0;\n"
13048 " gl_TessLevelOuter[2] = 1.0;\n"
13049 " gl_TessLevelOuter[3] = 1.0;\n"
13050 " gl_TessLevelInner[0] = 1.0;\n"
13051 " gl_TessLevelInner[1] = 1.0;\n"
13054 static const GLchar* tes = "#version 430 core\n"
13055 "#extension GL_ARB_enhanced_layouts : require\n"
13057 "layout(isolines, point_mode) in;\n"
13059 "in vec4 tcs_tes[];\n"
13060 "out vec4 tes_gs;\n"
13064 " tes_gs = tcs_tes[0];\n"
13067 static const GLchar* tes_tested = "#version 430 core\n"
13068 "#extension GL_ARB_enhanced_layouts : require\n"
13070 "layout(isolines, point_mode) in;\n"
13072 "STRUCT_DEFINITION"
13074 "VARIABLE_DEFINITION"
13076 "in vec4 tcs_tes[];\n"
13077 "out vec4 tes_gs;\n"
13081 " vec4 result = tcs_tes[0];\n"
13085 " tes_gs += result;\n"
13088 static const GLchar* vs = "#version 430 core\n"
13089 "#extension GL_ARB_enhanced_layouts : require\n"
13092 "out vec4 vs_tcs;\n"
13096 " vs_tcs = in_vs;\n"
13099 static const GLchar* vs_tested = "#version 430 core\n"
13100 "#extension GL_ARB_enhanced_layouts : require\n"
13102 "STRUCT_DEFINITION"
13104 "VARIABLE_DEFINITION"
13107 "out vec4 vs_tcs;\n"
13111 " vec4 result = in_vs;\n"
13115 " vs_tcs += result;\n"
13119 std::string source;
13120 testCase& test_case = m_test_cases[test_case_index];
13121 const GLchar* var_definition = 0;
13122 const GLchar* var_use = 0;
13124 if (true == test_case.m_is_input)
13126 var_definition = input_var;
13127 var_use = input_use;
13131 var_definition = output_var;
13132 var_use = output_use;
13135 if (test_case.m_stage == stage)
13137 size_t position = 0;
13141 case Utils::Shader::FRAGMENT:
13142 source = fs_tested;
13144 case Utils::Shader::GEOMETRY:
13145 source = gs_tested;
13147 case Utils::Shader::TESS_CTRL:
13148 source = tcs_tested;
13150 case Utils::Shader::TESS_EVAL:
13151 source = tes_tested;
13153 case Utils::Shader::VERTEX:
13154 source = vs_tested;
13157 TCU_FAIL("Invalid enum");
13160 Utils::replaceToken("STRUCT_DEFINITION", position, struct_definition, source);
13161 Utils::replaceToken("VARIABLE_DEFINITION", position, var_definition, source);
13162 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
13168 case Utils::Shader::FRAGMENT:
13171 case Utils::Shader::GEOMETRY:
13174 case Utils::Shader::TESS_CTRL:
13177 case Utils::Shader::TESS_EVAL:
13180 case Utils::Shader::VERTEX:
13184 TCU_FAIL("Invalid enum");
13191 /** Get description of test case
13193 * @param test_case_index Index of test case
13195 * @return Test case description
13197 std::string VaryingStructureMemberLocationTest::getTestCaseName(GLuint test_case_index)
13199 std::stringstream stream;
13200 testCase& test_case = m_test_cases[test_case_index];
13202 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", direction: ";
13204 if (true == test_case.m_is_input)
13210 stream << "output";
13213 return stream.str();
13216 /** Get number of test cases
13218 * @return Number of test cases
13220 GLuint VaryingStructureMemberLocationTest::getTestCaseNumber()
13222 return static_cast<GLuint>(m_test_cases.size());
13225 /** Selects if "compute" stage is relevant for test
13231 bool VaryingStructureMemberLocationTest::isComputeRelevant(GLuint /* test_case_index */)
13236 /** Prepare all test cases
13239 void VaryingStructureMemberLocationTest::testInit()
13241 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
13243 if (Utils::Shader::COMPUTE == stage)
13248 testCase test_case_in = { true, (Utils::Shader::STAGES)stage };
13249 testCase test_case_out = { false, (Utils::Shader::STAGES)stage };
13251 m_test_cases.push_back(test_case_in);
13253 if (Utils::Shader::FRAGMENT != stage)
13255 m_test_cases.push_back(test_case_out);
13262 * @param context Test framework context
13264 VaryingBlockLocationsTest::VaryingBlockLocationsTest(deqp::Context& context)
13265 : TextureTestBase(context, "varying_block_locations",
13266 "Test verifies that locations are respected when blocks are used as in and out ")
13270 /** Prepare code snippet that will pass in variables to out variables
13273 * @param varying_passthrough Collection of connections between in and out variables
13274 * @param stage Shader stage
13276 * @return Code that pass in variables to next stage
13278 std::string VaryingBlockLocationsTest::getPassSnippet(GLuint /* test_case_index */,
13279 Utils::VaryingPassthrough& varying_passthrough,
13280 Utils::Shader::STAGES stage)
13282 std::string result;
13284 if (Utils::Shader::VERTEX != stage)
13286 result = TextureTestBase::getPassSnippet(0, varying_passthrough, stage);
13290 result = "vs_tcs_block.third = vs_in_third;\n"
13291 " vs_tcs_block.fourth = vs_in_fourth;\n"
13292 " vs_tcs_block.fifth = vs_in_fifth;\n";
13298 /** Get interface of program
13301 * @param program_interface Interface of program
13302 * @param varying_passthrough Collection of connections between in and out variables
13304 void VaryingBlockLocationsTest::getProgramInterface(GLuint /* test_case_index */,
13305 Utils::ProgramInterface& program_interface,
13306 Utils::VaryingPassthrough& varying_passthrough)
13308 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
13309 const Utils::Type vec4 = Utils::Type::vec4;
13312 m_third_data = vec4.GenerateData();
13313 m_fourth_data = vec4.GenerateData();
13314 m_fifth_data = vec4.GenerateData();
13316 /* Memory layout is different from location layout */
13317 const GLuint fifth_offset = 0u;
13318 const GLuint third_offset = static_cast<GLuint>(fifth_offset + m_fifth_data.size());
13319 const GLuint fourth_offset = static_cast<GLuint>(third_offset + m_fourth_data.size());
13321 m_data.resize(fourth_offset + m_fourth_data.size());
13322 GLubyte* ptr = (GLubyte*)&m_data[0];
13323 memcpy(ptr + third_offset, &m_third_data[0], m_third_data.size());
13324 memcpy(ptr + fourth_offset, &m_fourth_data[0], m_fourth_data.size());
13325 memcpy(ptr + fifth_offset, &m_fifth_data[0], m_fifth_data.size());
13327 Utils::Interface* block = program_interface.Block("vs_tcs_Block");
13329 block->Member("fifth", "" /* qualifiers */, 0 /* component */, 4 /* location */, vec4, false /* normalized */,
13330 0u /* n_array_elements */, 0u /* stride */, fifth_offset /* offset */);
13332 block->Member("third", "layout (location = 2)" /* qualifiers */, 0 /* component */, 2 /* location */, vec4,
13333 false /* normalized */, 0u /* n_array_elements */, 0u /* stride */, third_offset /* offset */);
13335 block->Member("fourth", "" /* qualifiers */, 0 /* component */, 3 /* location */, vec4, false /* normalized */,
13336 0u /* n_array_elements */, 0u /* stride */, fourth_offset /* offset */);
13338 si.Output("vs_tcs_block", "layout (location = 4)", 0 /* component */, 4 /* location */, block,
13339 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)&m_data[0] /* data */,
13340 m_data.size() /* data_size */);
13342 si.Input("vs_in_third", "layout (location = 0)", 0 /* component */, 0 /* location */, vec4, false /* normalized */,
13343 0u /* n_array_elements */, 0u /* stride */, third_offset /* offset */,
13344 (GLvoid*)&m_third_data[0] /* data */, m_third_data.size() /* data_size */);
13346 si.Input("vs_in_fourth", "layout (location = 1)", 0 /* component */, 1 /* location */, vec4, false /* normalized */,
13347 0u /* n_array_elements */, 0u /* stride */, fourth_offset /* offset */,
13348 (GLvoid*)&m_fourth_data[0] /* data */, m_fourth_data.size() /* data_size */);
13350 si.Input("vs_in_fifth", "layout (location = 2)", 0 /* component */, 2 /* location */, vec4, false /* normalized */,
13351 0u /* n_array_elements */, 0u /* stride */, fifth_offset /* offset */,
13352 (GLvoid*)&m_fifth_data[0] /* data */, m_fifth_data.size() /* data_size */);
13354 program_interface.CloneVertexInterface(varying_passthrough);
13357 /** Selects if "compute" stage is relevant for test
13363 bool VaryingBlockLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
13368 /** This test should be run with separable programs
13374 bool VaryingBlockLocationsTest::useMonolithicProgram(GLuint /* test_case_index */)
13381 * @param context Test framework context
13383 VaryingBlockMemberLocationsTest::VaryingBlockMemberLocationsTest(deqp::Context& context)
13384 : NegativeTestBase(
13385 context, "varying_block_member_locations",
13386 "Test verifies that compilation error is reported when not all members of block are qualified with location")
13390 /** Source for given test case and stage
13392 * @param test_case_index Index of test case
13393 * @param stage Shader stage
13395 * @return Shader source
13397 std::string VaryingBlockMemberLocationsTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
13399 static const GLchar* block_definition_all = "Goku {\n"
13400 " layout (location = 2) vec4 gohan;\n"
13401 " layout (location = 4) vec4 goten;\n"
13402 " layout (location = 6) vec4 chichi;\n"
13404 static const GLchar* block_definition_default = "Goku {\n"
13409 static const GLchar* block_definition_one = "Goku {\n"
13411 " layout (location = 4) vec4 goten;\n"
13414 static const GLchar* input_use = " result += gokuINDEX.gohan + gokuINDEX.goten + gokuINDEX.chichi;\n";
13415 static const GLchar* output_use = " gokuINDEX.gohan = result / 2;\n"
13416 " gokuINDEX.goten = result / 4 - gokuINDEX.gohan;\n"
13417 " gokuINDEX.chichi = result / 8 - gokuINDEX.goten;\n";
13418 static const GLchar* fs = "#version 430 core\n"
13419 "#extension GL_ARB_enhanced_layouts : require\n"
13422 "out vec4 fs_out;\n"
13426 " fs_out = gs_fs;\n"
13429 static const GLchar* fs_tested = "#version 430 core\n"
13430 "#extension GL_ARB_enhanced_layouts : require\n"
13432 "DIRECTION BLOCK_DEFINITION"
13435 "out vec4 fs_out;\n"
13439 " vec4 result = gs_fs;\n"
13443 " fs_out = result;\n"
13446 static const GLchar* gs = "#version 430 core\n"
13447 "#extension GL_ARB_enhanced_layouts : require\n"
13449 "layout(points) in;\n"
13450 "layout(triangle_strip, max_vertices = 4) out;\n"
13452 "in vec4 tes_gs[];\n"
13453 "out vec4 gs_fs;\n"
13457 " gs_fs = tes_gs[0];\n"
13458 " gl_Position = vec4(-1, -1, 0, 1);\n"
13460 " gs_fs = tes_gs[0];\n"
13461 " gl_Position = vec4(-1, 1, 0, 1);\n"
13463 " gs_fs = tes_gs[0];\n"
13464 " gl_Position = vec4(1, -1, 0, 1);\n"
13466 " gs_fs = tes_gs[0];\n"
13467 " gl_Position = vec4(1, 1, 0, 1);\n"
13471 static const GLchar* gs_tested = "#version 430 core\n"
13472 "#extension GL_ARB_enhanced_layouts : require\n"
13474 "layout(points) in;\n"
13475 "layout(triangle_strip, max_vertices = 4) out;\n"
13477 "DIRECTION BLOCK_DEFINITION"
13479 "in vec4 tes_gs[];\n"
13480 "out vec4 gs_fs;\n"
13484 " vec4 result = tes_gs[0];\n"
13488 " gs_fs = result;\n"
13489 " gl_Position = vec4(-1, -1, 0, 1);\n"
13491 " gs_fs = result;\n"
13492 " gl_Position = vec4(-1, 1, 0, 1);\n"
13494 " gs_fs = result;\n"
13495 " gl_Position = vec4(1, -1, 0, 1);\n"
13497 " gs_fs = result;\n"
13498 " gl_Position = vec4(1, 1, 0, 1);\n"
13502 static const GLchar* tcs = "#version 430 core\n"
13503 "#extension GL_ARB_enhanced_layouts : require\n"
13505 "layout(vertices = 1) out;\n"
13507 "in vec4 vs_tcs[];\n"
13508 "out vec4 tcs_tes[];\n"
13513 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
13515 " gl_TessLevelOuter[0] = 1.0;\n"
13516 " gl_TessLevelOuter[1] = 1.0;\n"
13517 " gl_TessLevelOuter[2] = 1.0;\n"
13518 " gl_TessLevelOuter[3] = 1.0;\n"
13519 " gl_TessLevelInner[0] = 1.0;\n"
13520 " gl_TessLevelInner[1] = 1.0;\n"
13523 static const GLchar* tcs_tested = "#version 430 core\n"
13524 "#extension GL_ARB_enhanced_layouts : require\n"
13526 "layout(vertices = 1) out;\n"
13528 "DIRECTION BLOCK_DEFINITION"
13530 "in vec4 vs_tcs[];\n"
13531 "out vec4 tcs_tes[];\n"
13535 " vec4 result = vs_tcs[gl_InvocationID];\n"
13539 " tcs_tes[gl_InvocationID] = result;\n"
13541 " gl_TessLevelOuter[0] = 1.0;\n"
13542 " gl_TessLevelOuter[1] = 1.0;\n"
13543 " gl_TessLevelOuter[2] = 1.0;\n"
13544 " gl_TessLevelOuter[3] = 1.0;\n"
13545 " gl_TessLevelInner[0] = 1.0;\n"
13546 " gl_TessLevelInner[1] = 1.0;\n"
13549 static const GLchar* tes = "#version 430 core\n"
13550 "#extension GL_ARB_enhanced_layouts : require\n"
13552 "layout(isolines, point_mode) in;\n"
13554 "in vec4 tcs_tes[];\n"
13555 "out vec4 tes_gs;\n"
13559 " tes_gs = tcs_tes[0];\n"
13562 static const GLchar* tes_tested = "#version 430 core\n"
13563 "#extension GL_ARB_enhanced_layouts : require\n"
13565 "layout(isolines, point_mode) in;\n"
13567 "DIRECTION BLOCK_DEFINITION"
13569 "in vec4 tcs_tes[];\n"
13570 "out vec4 tes_gs;\n"
13574 " vec4 result = tcs_tes[0];\n"
13578 " tes_gs = result;\n"
13581 static const GLchar* vs = "#version 430 core\n"
13582 "#extension GL_ARB_enhanced_layouts : require\n"
13585 "out vec4 vs_tcs;\n"
13589 " vs_tcs = in_vs;\n"
13592 static const GLchar* vs_tested = "#version 430 core\n"
13593 "#extension GL_ARB_enhanced_layouts : require\n"
13595 "DIRECTION BLOCK_DEFINITION"
13598 "out vec4 vs_tcs;\n"
13602 " vec4 result = in_vs;\n"
13606 " vs_tcs = result;\n"
13610 static const GLchar* shaders_in[6][6] = { /* cs */ { 0, 0, 0, 0, 0, 0 },
13611 /* vs */ { 0, vs_tested, tcs, tes, gs, fs },
13612 /* tcs */ { 0, vs_tested, tcs_tested, tes, gs, fs },
13613 /* tes */ { 0, vs, tcs_tested, tes_tested, gs, fs },
13614 /* gs */ { 0, vs, tcs, tes_tested, gs_tested, fs },
13615 /* fs */ { 0, vs, tcs, tes, gs_tested, fs_tested } };
13617 static const GLchar* shaders_out[6][6] = { /* cs */ { 0, 0, 0, 0, 0, 0 },
13618 /* vs */ { 0, vs_tested, tcs_tested, tes, gs, fs },
13619 /* tcs */ { 0, vs, tcs_tested, tes_tested, gs, fs },
13620 /* tes */ { 0, vs, tcs, tes_tested, gs_tested, fs },
13621 /* gs */ { 0, vs, tcs, tes, gs_tested, fs_tested },
13622 /* fs */ { 0, 0, 0, 0, 0, 0 } };
13624 static const bool require_modifications_in[6][6] = {
13625 /* cs */ { false, false, false, false, false, false },
13626 /* vs */ { false, true, false, false, false, false },
13627 /* tcs */ { false, true, true, false, false, false },
13628 /* tes */ { false, false, true, true, false, false },
13629 /* gs */ { false, false, false, true, true, false },
13630 /* fs */ { false, false, false, false, true, true }
13633 static const bool require_modifications_out[6][6] = {
13634 /* cs */ { false, false, false, false, false, false },
13635 /* vs */ { false, true, true, false, false, false },
13636 /* tcs */ { false, false, true, true, false, false },
13637 /* tes */ { false, false, false, true, true, false },
13638 /* gs */ { false, false, false, false, true, true },
13639 /* fs */ { false, false, false, false, false, false }
13642 const GLchar* array = "";
13643 const GLchar* definition = block_definition_default;
13644 const GLchar* direction = "out";
13645 const GLchar* index = "";
13646 bool require_modifications = false;
13647 std::string source;
13648 testCase& test_case = m_test_cases[test_case_index];
13649 const GLchar* var_use = output_use;
13651 if (true == test_case.m_is_input)
13653 require_modifications = require_modifications_in[test_case.m_stage][stage];
13654 source = shaders_in[test_case.m_stage][stage];
13656 if (test_case.m_stage == stage)
13659 var_use = input_use;
13664 require_modifications = require_modifications_out[test_case.m_stage][stage];
13665 source = shaders_out[test_case.m_stage][stage];
13667 if (test_case.m_stage != stage)
13670 var_use = input_use;
13674 if (test_case.m_stage == stage)
13676 if (true == test_case.m_qualify_all)
13678 definition = block_definition_all;
13682 definition = block_definition_one;
13688 case Utils::Shader::FRAGMENT:
13690 case Utils::Shader::GEOMETRY:
13694 case Utils::Shader::TESS_CTRL:
13696 index = "[gl_InvocationID]";
13698 // geometry shader's input must have one more dimension than tessellation evaluation shader's output,
13699 // the GS input block is an array, so the DS output can't be declared as an array
13700 case Utils::Shader::TESS_EVAL:
13702 if (std::string(direction) == std::string("in")) // match HS output and DS input
13707 else // match DS output and GS input
13714 case Utils::Shader::VERTEX:
13717 TCU_FAIL("Invalid enum");
13720 if (true == require_modifications)
13722 size_t position = 0;
13725 Utils::replaceToken("DIRECTION", position, direction, source);
13727 Utils::replaceToken("BLOCK_DEFINITION", position, definition, source);
13729 Utils::replaceToken("ARRAY", position, array, source);
13730 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
13732 Utils::replaceAllTokens("INDEX", index, source);
13738 case Utils::Shader::FRAGMENT:
13741 case Utils::Shader::GEOMETRY:
13744 case Utils::Shader::TESS_CTRL:
13747 case Utils::Shader::TESS_EVAL:
13750 case Utils::Shader::VERTEX:
13754 TCU_FAIL("Invalid enum");
13761 /** Get description of test case
13763 * @param test_case_index Index of test case
13765 * @return Test case description
13767 std::string VaryingBlockMemberLocationsTest::getTestCaseName(GLuint test_case_index)
13769 std::stringstream stream;
13770 testCase& test_case = m_test_cases[test_case_index];
13772 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", direction: ";
13774 if (true == test_case.m_is_input)
13780 stream << "output";
13783 if (true == test_case.m_qualify_all)
13785 stream << ", all members qualified";
13789 stream << ", not all members qualified";
13792 return stream.str();
13795 /** Get number of test cases
13797 * @return Number of test cases
13799 GLuint VaryingBlockMemberLocationsTest::getTestCaseNumber()
13801 return static_cast<GLuint>(m_test_cases.size());
13804 /** Selects if "compute" stage is relevant for test
13810 bool VaryingBlockMemberLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
13815 /** Selects if compilation failure is expected result
13817 * @param test_case_index Index of test case
13819 * @return false when all members are qualified, true otherwise
13821 bool VaryingBlockMemberLocationsTest::isFailureExpected(GLuint test_case_index)
13823 return (true != m_test_cases[test_case_index].m_qualify_all);
13826 /** Prepare all test cases
13829 void VaryingBlockMemberLocationsTest::testInit()
13831 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
13833 if (Utils::Shader::COMPUTE == stage)
13838 testCase test_case_in_all = { true, true, (Utils::Shader::STAGES)stage };
13839 testCase test_case_in_one = { true, false, (Utils::Shader::STAGES)stage };
13840 testCase test_case_out_all = { false, true, (Utils::Shader::STAGES)stage };
13841 testCase test_case_out_one = { false, false, (Utils::Shader::STAGES)stage };
13843 if (Utils::Shader::VERTEX != stage)
13845 m_test_cases.push_back(test_case_in_all);
13846 m_test_cases.push_back(test_case_in_one);
13849 if (Utils::Shader::FRAGMENT != stage)
13851 m_test_cases.push_back(test_case_out_all);
13852 m_test_cases.push_back(test_case_out_one);
13859 * @param context Test framework context
13861 VaryingBlockAutomaticMemberLocationsTest::VaryingBlockAutomaticMemberLocationsTest(deqp::Context& context)
13862 : NegativeTestBase(
13863 context, "varying_block_automatic_member_locations",
13864 "Test verifies that compiler assigns subsequent locations to block members, even if this causes errors")
13868 /** Source for given test case and stage
13870 * @param test_case_index Index of test case
13871 * @param stage Shader stage
13873 * @return Shader source
13875 std::string VaryingBlockAutomaticMemberLocationsTest::getShaderSource(GLuint test_case_index,
13876 Utils::Shader::STAGES stage)
13878 static const GLchar* block_definition = "layout (location = 2) DIRECTION DBZ {\n"
13880 " vec4 gohan[4];\n"
13882 " layout (location = 1) vec4 chichi;\n"
13885 static const GLchar* input_use = " result += dbzINDEX.goku + dbzINDEX.gohan[0] + dbzINDEX.gohan[1] + "
13886 "dbzINDEX.gohan[3] + dbzINDEX.gohan[2] + dbzINDEX.goten + dbzINDEX.chichi + "
13888 static const GLchar* output_use = " dbzINDEX.goku = result;\n"
13889 " dbzINDEX.gohan[0] = result / 2;\n"
13890 " dbzINDEX.gohan[1] = result / 2.25;\n"
13891 " dbzINDEX.gohan[2] = result / 2.5;\n"
13892 " dbzINDEX.gohan[3] = result / 2.75;\n"
13893 " dbzINDEX.goten = result / 4 - dbzINDEX.gohan[0] - dbzINDEX.gohan[1] - "
13894 "dbzINDEX.gohan[2] - dbzINDEX.gohan[3];\n"
13895 " dbzINDEX.chichi = result / 8 - dbzINDEX.goten;\n"
13896 " dbzINDEX.pan = result / 16 - dbzINDEX.chichi;\n";
13897 static const GLchar* fs = "#version 430 core\n"
13898 "#extension GL_ARB_enhanced_layouts : require\n"
13901 "out vec4 fs_out;\n"
13905 " fs_out = gs_fs;\n"
13908 static const GLchar* fs_tested = "#version 430 core\n"
13909 "#extension GL_ARB_enhanced_layouts : require\n"
13914 "out vec4 fs_out;\n"
13918 " vec4 result = gs_fs;\n"
13922 " fs_out += result;\n"
13925 static const GLchar* gs = "#version 430 core\n"
13926 "#extension GL_ARB_enhanced_layouts : require\n"
13928 "layout(points) in;\n"
13929 "layout(triangle_strip, max_vertices = 4) out;\n"
13931 "in vec4 tes_gs[];\n"
13932 "out vec4 gs_fs;\n"
13936 " gs_fs = tes_gs[0];\n"
13937 " gl_Position = vec4(-1, -1, 0, 1);\n"
13939 " gs_fs = tes_gs[0];\n"
13940 " gl_Position = vec4(-1, 1, 0, 1);\n"
13942 " gs_fs = tes_gs[0];\n"
13943 " gl_Position = vec4(1, -1, 0, 1);\n"
13945 " gs_fs = tes_gs[0];\n"
13946 " gl_Position = vec4(1, 1, 0, 1);\n"
13950 static const GLchar* gs_tested = "#version 430 core\n"
13951 "#extension GL_ARB_enhanced_layouts : require\n"
13953 "layout(points) in;\n"
13954 "layout(triangle_strip, max_vertices = 4) out;\n"
13958 "in vec4 tes_gs[];\n"
13959 "out vec4 gs_fs;\n"
13963 " vec4 result = tes_gs[0];\n"
13967 " gs_fs = result;\n"
13968 " gl_Position = vec4(-1, -1, 0, 1);\n"
13970 " gs_fs = result;\n"
13971 " gl_Position = vec4(-1, 1, 0, 1);\n"
13973 " gs_fs = result;\n"
13974 " gl_Position = vec4(1, -1, 0, 1);\n"
13976 " gs_fs = result;\n"
13977 " gl_Position = vec4(1, 1, 0, 1);\n"
13981 static const GLchar* tcs = "#version 430 core\n"
13982 "#extension GL_ARB_enhanced_layouts : require\n"
13984 "layout(vertices = 1) out;\n"
13986 "in vec4 vs_tcs[];\n"
13987 "out vec4 tcs_tes[];\n"
13992 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
13994 " gl_TessLevelOuter[0] = 1.0;\n"
13995 " gl_TessLevelOuter[1] = 1.0;\n"
13996 " gl_TessLevelOuter[2] = 1.0;\n"
13997 " gl_TessLevelOuter[3] = 1.0;\n"
13998 " gl_TessLevelInner[0] = 1.0;\n"
13999 " gl_TessLevelInner[1] = 1.0;\n"
14002 static const GLchar* tcs_tested = "#version 430 core\n"
14003 "#extension GL_ARB_enhanced_layouts : require\n"
14005 "layout(vertices = 1) out;\n"
14009 "in vec4 vs_tcs[];\n"
14010 "out vec4 tcs_tes[];\n"
14014 " vec4 result = vs_tcs[gl_InvocationID];\n"
14018 " tcs_tes[gl_InvocationID] = result;\n"
14020 " gl_TessLevelOuter[0] = 1.0;\n"
14021 " gl_TessLevelOuter[1] = 1.0;\n"
14022 " gl_TessLevelOuter[2] = 1.0;\n"
14023 " gl_TessLevelOuter[3] = 1.0;\n"
14024 " gl_TessLevelInner[0] = 1.0;\n"
14025 " gl_TessLevelInner[1] = 1.0;\n"
14028 static const GLchar* tes = "#version 430 core\n"
14029 "#extension GL_ARB_enhanced_layouts : require\n"
14031 "layout(isolines, point_mode) in;\n"
14033 "in vec4 tcs_tes[];\n"
14034 "out vec4 tes_gs;\n"
14038 " tes_gs = tcs_tes[0];\n"
14041 static const GLchar* tes_tested = "#version 430 core\n"
14042 "#extension GL_ARB_enhanced_layouts : require\n"
14044 "layout(isolines, point_mode) in;\n"
14048 "in vec4 tcs_tes[];\n"
14049 "out vec4 tes_gs;\n"
14053 " vec4 result = tcs_tes[0];\n"
14057 " tes_gs += result;\n"
14060 static const GLchar* vs = "#version 430 core\n"
14061 "#extension GL_ARB_enhanced_layouts : require\n"
14064 "out vec4 vs_tcs;\n"
14068 " vs_tcs = in_vs;\n"
14071 static const GLchar* vs_tested = "#version 430 core\n"
14072 "#extension GL_ARB_enhanced_layouts : require\n"
14077 "out vec4 vs_tcs;\n"
14081 " vec4 result = in_vs;\n"
14085 " vs_tcs += result;\n"
14089 const GLchar* array = "";
14090 const GLchar* direction = "out";
14091 const GLchar* index = "";
14092 std::string source;
14093 testCase& test_case = m_test_cases[test_case_index];
14094 const GLchar* var_use = output_use;
14096 if (true == test_case.m_is_input)
14099 var_use = input_use;
14102 if (test_case.m_stage == stage)
14104 size_t position = 0;
14109 case Utils::Shader::FRAGMENT:
14110 source = fs_tested;
14112 case Utils::Shader::GEOMETRY:
14113 source = gs_tested;
14117 case Utils::Shader::TESS_CTRL:
14118 source = tcs_tested;
14120 index = "[gl_InvocationID]";
14122 case Utils::Shader::TESS_EVAL:
14123 source = tes_tested;
14127 case Utils::Shader::VERTEX:
14128 source = vs_tested;
14131 TCU_FAIL("Invalid enum");
14135 Utils::replaceToken("BLOCK_DEFINITION", position, block_definition, source);
14137 Utils::replaceToken("DIRECTION", position, direction, source);
14138 Utils::replaceToken("ARRAY", position, array, source);
14139 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
14141 Utils::replaceAllTokens("INDEX", index, source);
14147 case Utils::Shader::FRAGMENT:
14150 case Utils::Shader::GEOMETRY:
14153 case Utils::Shader::TESS_CTRL:
14156 case Utils::Shader::TESS_EVAL:
14159 case Utils::Shader::VERTEX:
14163 TCU_FAIL("Invalid enum");
14170 /** Get description of test case
14172 * @param test_case_index Index of test case
14174 * @return Test case description
14176 std::string VaryingBlockAutomaticMemberLocationsTest::getTestCaseName(GLuint test_case_index)
14178 std::stringstream stream;
14179 testCase& test_case = m_test_cases[test_case_index];
14181 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", direction: ";
14183 if (true == test_case.m_is_input)
14189 stream << "output";
14192 return stream.str();
14195 /** Get number of test cases
14197 * @return Number of test cases
14199 GLuint VaryingBlockAutomaticMemberLocationsTest::getTestCaseNumber()
14201 return static_cast<GLuint>(m_test_cases.size());
14204 /** Selects if "compute" stage is relevant for test
14210 bool VaryingBlockAutomaticMemberLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
14215 /** Prepare all test cases
14218 void VaryingBlockAutomaticMemberLocationsTest::testInit()
14220 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
14222 if (Utils::Shader::COMPUTE == stage)
14227 testCase test_case_in = { true, (Utils::Shader::STAGES)stage };
14228 testCase test_case_out = { false, (Utils::Shader::STAGES)stage };
14230 if (Utils::Shader::VERTEX != stage)
14232 m_test_cases.push_back(test_case_in);
14235 if (Utils::Shader::FRAGMENT != stage)
14237 m_test_cases.push_back(test_case_out);
14244 * @param context Test framework context
14246 VaryingLocationLimitTest::VaryingLocationLimitTest(deqp::Context& context)
14247 : NegativeTestBase(context, "varying_location_limit",
14248 "Test verifies that compiler reports error when location qualifier exceed limits")
14252 /** Source for given test case and stage
14254 * @param test_case_index Index of test case
14255 * @param stage Shader stage
14257 * @return Shader source
14259 std::string VaryingLocationLimitTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
14261 static const GLchar* var_definition = "layout (location = LAST + 1) FLAT DIRECTION TYPE gokuARRAY;\n";
14262 static const GLchar* input_use = " if (TYPE(0) == gokuINDEX)\n"
14264 " result += vec4(1, 0.5, 0.25, 0.125);\n"
14266 static const GLchar* output_use = " gokuINDEX = TYPE(0);\n"
14267 " if (vec4(0) == result)\n"
14269 " gokuINDEX = TYPE(1);\n"
14271 static const GLchar* fs = "#version 430 core\n"
14272 "#extension GL_ARB_enhanced_layouts : require\n"
14275 "out vec4 fs_out;\n"
14279 " fs_out = gs_fs;\n"
14282 static const GLchar* fs_tested = "#version 430 core\n"
14283 "#extension GL_ARB_enhanced_layouts : require\n"
14288 "out vec4 fs_out;\n"
14292 " vec4 result = gs_fs;\n"
14296 " fs_out += result;\n"
14299 static const GLchar* gs = "#version 430 core\n"
14300 "#extension GL_ARB_enhanced_layouts : require\n"
14302 "layout(points) in;\n"
14303 "layout(triangle_strip, max_vertices = 4) out;\n"
14305 "in vec4 tes_gs[];\n"
14306 "out vec4 gs_fs;\n"
14310 " gs_fs = tes_gs[0];\n"
14311 " gl_Position = vec4(-1, -1, 0, 1);\n"
14313 " gs_fs = tes_gs[0];\n"
14314 " gl_Position = vec4(-1, 1, 0, 1);\n"
14316 " gs_fs = tes_gs[0];\n"
14317 " gl_Position = vec4(1, -1, 0, 1);\n"
14319 " gs_fs = tes_gs[0];\n"
14320 " gl_Position = vec4(1, 1, 0, 1);\n"
14324 static const GLchar* gs_tested = "#version 430 core\n"
14325 "#extension GL_ARB_enhanced_layouts : require\n"
14327 "layout(points) in;\n"
14328 "layout(triangle_strip, max_vertices = 4) out;\n"
14332 "in vec4 tes_gs[];\n"
14333 "out vec4 gs_fs;\n"
14337 " vec4 result = tes_gs[0];\n"
14341 " gs_fs = result;\n"
14342 " gl_Position = vec4(-1, -1, 0, 1);\n"
14344 " gs_fs = result;\n"
14345 " gl_Position = vec4(-1, 1, 0, 1);\n"
14347 " gs_fs = result;\n"
14348 " gl_Position = vec4(1, -1, 0, 1);\n"
14350 " gs_fs = result;\n"
14351 " gl_Position = vec4(1, 1, 0, 1);\n"
14355 static const GLchar* tcs = "#version 430 core\n"
14356 "#extension GL_ARB_enhanced_layouts : require\n"
14358 "layout(vertices = 1) out;\n"
14360 "in vec4 vs_tcs[];\n"
14361 "out vec4 tcs_tes[];\n"
14366 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
14368 " gl_TessLevelOuter[0] = 1.0;\n"
14369 " gl_TessLevelOuter[1] = 1.0;\n"
14370 " gl_TessLevelOuter[2] = 1.0;\n"
14371 " gl_TessLevelOuter[3] = 1.0;\n"
14372 " gl_TessLevelInner[0] = 1.0;\n"
14373 " gl_TessLevelInner[1] = 1.0;\n"
14376 static const GLchar* tcs_tested = "#version 430 core\n"
14377 "#extension GL_ARB_enhanced_layouts : require\n"
14379 "layout(vertices = 1) out;\n"
14383 "in vec4 vs_tcs[];\n"
14384 "out vec4 tcs_tes[];\n"
14388 " vec4 result = vs_tcs[gl_InvocationID];\n"
14392 " tcs_tes[gl_InvocationID] = result;\n"
14394 " gl_TessLevelOuter[0] = 1.0;\n"
14395 " gl_TessLevelOuter[1] = 1.0;\n"
14396 " gl_TessLevelOuter[2] = 1.0;\n"
14397 " gl_TessLevelOuter[3] = 1.0;\n"
14398 " gl_TessLevelInner[0] = 1.0;\n"
14399 " gl_TessLevelInner[1] = 1.0;\n"
14402 static const GLchar* tes = "#version 430 core\n"
14403 "#extension GL_ARB_enhanced_layouts : require\n"
14405 "layout(isolines, point_mode) in;\n"
14407 "in vec4 tcs_tes[];\n"
14408 "out vec4 tes_gs;\n"
14412 " tes_gs = tcs_tes[0];\n"
14415 static const GLchar* tes_tested = "#version 430 core\n"
14416 "#extension GL_ARB_enhanced_layouts : require\n"
14418 "layout(isolines, point_mode) in;\n"
14422 "in vec4 tcs_tes[];\n"
14423 "out vec4 tes_gs;\n"
14427 " vec4 result = tcs_tes[0];\n"
14431 " tes_gs += result;\n"
14434 static const GLchar* vs = "#version 430 core\n"
14435 "#extension GL_ARB_enhanced_layouts : require\n"
14438 "out vec4 vs_tcs;\n"
14442 " vs_tcs = in_vs;\n"
14445 static const GLchar* vs_tested = "#version 430 core\n"
14446 "#extension GL_ARB_enhanced_layouts : require\n"
14451 "out vec4 vs_tcs;\n"
14455 " vec4 result = in_vs;\n"
14459 " vs_tcs += result;\n"
14463 std::string source;
14464 testCase& test_case = m_test_cases[test_case_index];
14466 if (test_case.m_stage == stage)
14468 const GLchar* array = "";
14470 const GLchar* direction = "in ";
14471 const GLchar* flat = "";
14472 const GLchar* index = "";
14473 GLuint last = getLastInputLocation(stage, test_case.m_type, 0);
14474 size_t position = 0;
14476 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
14477 Utils::Variable::STORAGE storage = Utils::Variable::VARYING_INPUT;
14478 const GLchar* var_use = input_use;
14480 if (false == test_case.m_is_input)
14483 last = getLastOutputLocation(stage, test_case.m_type, 0);
14484 storage = Utils::Variable::VARYING_OUTPUT;
14485 var_use = output_use;
14488 if (true == isFlatRequired(stage, test_case.m_type, storage))
14493 sprintf(buffer, "%d", last);
14497 case Utils::Shader::FRAGMENT:
14498 source = fs_tested;
14500 case Utils::Shader::GEOMETRY:
14501 source = gs_tested;
14505 case Utils::Shader::TESS_CTRL:
14506 source = tcs_tested;
14508 index = "[gl_InvocationID]";
14510 case Utils::Shader::TESS_EVAL:
14511 source = tes_tested;
14515 case Utils::Shader::VERTEX:
14516 source = vs_tested;
14519 TCU_FAIL("Invalid enum");
14523 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
14525 Utils::replaceToken("LAST", position, buffer, source);
14526 Utils::replaceToken("FLAT", position, flat, source);
14527 Utils::replaceToken("DIRECTION", position, direction, source);
14528 Utils::replaceToken("ARRAY", position, array, source);
14529 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
14531 Utils::replaceAllTokens("TYPE", type_name, source);
14532 Utils::replaceAllTokens("INDEX", index, source);
14538 case Utils::Shader::FRAGMENT:
14541 case Utils::Shader::GEOMETRY:
14544 case Utils::Shader::TESS_CTRL:
14547 case Utils::Shader::TESS_EVAL:
14550 case Utils::Shader::VERTEX:
14554 TCU_FAIL("Invalid enum");
14561 /** Get description of test case
14563 * @param test_case_index Index of test case
14565 * @return Test case description
14567 std::string VaryingLocationLimitTest::getTestCaseName(GLuint test_case_index)
14569 std::stringstream stream;
14570 testCase& test_case = m_test_cases[test_case_index];
14572 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
14573 << " type: " << test_case.m_type.GetGLSLTypeName() << ", direction: ";
14575 if (true == test_case.m_is_input)
14581 stream << "output";
14584 return stream.str();
14587 /** Get number of test cases
14589 * @return Number of test cases
14591 GLuint VaryingLocationLimitTest::getTestCaseNumber()
14593 return static_cast<GLuint>(m_test_cases.size());
14596 /** Selects if "compute" stage is relevant for test
14602 bool VaryingLocationLimitTest::isComputeRelevant(GLuint /* test_case_index */)
14607 /** Prepare all test cases
14610 void VaryingLocationLimitTest::testInit()
14612 const GLuint n_types = getTypesNumber();
14614 for (GLuint i = 0; i < n_types; ++i)
14616 const Utils::Type& type = getType(i);
14618 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
14620 if (Utils::Shader::COMPUTE == stage)
14625 testCase test_case_in = { true, type, (Utils::Shader::STAGES)stage };
14626 testCase test_case_out = { false, type, (Utils::Shader::STAGES)stage };
14628 m_test_cases.push_back(test_case_in);
14630 if (Utils::Shader::FRAGMENT != stage)
14632 m_test_cases.push_back(test_case_out);
14640 * @param context Test framework context
14642 VaryingComponentsTest::VaryingComponentsTest(deqp::Context& context)
14643 : VaryingLocationsTest(context, "varying_components",
14644 "Test verifies that input and output components are respected")
14650 * @param context Test framework context
14651 * @param test_name Name of test
14652 * @param test_description Description of test
14654 VaryingComponentsTest::VaryingComponentsTest(deqp::Context& context, const glw::GLchar* test_name,
14655 const glw::GLchar* test_description)
14656 : VaryingLocationsTest(context, test_name, test_description)
14660 /** Get interface of program
14662 * @param test_case_index Test case
14663 * @param program_interface Interface of program
14664 * @param varying_passthrough Collection of connections between in and out variables
14666 void VaryingComponentsTest::getProgramInterface(GLuint test_case_index, Utils::ProgramInterface& program_interface,
14667 Utils::VaryingPassthrough& varying_passthrough)
14669 GLuint array_length = getArrayLength();
14670 const testCase& test_case = m_test_cases[test_case_index];
14671 const Utils::Type vector_type = Utils::Type::GetType(test_case.m_type, 1, 4);
14672 Utils::ShaderInterface si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
14674 /* Zero means no array, however we still need at least 1 slot of data */
14675 if (0 == array_length)
14680 /* Generate data */
14681 const std::vector<GLubyte>& data = vector_type.GenerateDataPacked();
14682 const size_t data_size = data.size();
14684 /* Prepare data for variables */
14685 m_data.resize(array_length * data_size);
14687 GLubyte* dst = &m_data[0];
14688 const GLubyte* src = &data[0];
14690 for (GLuint i = 0; i < array_length; ++i)
14692 memcpy(dst + data_size * i, src, data_size);
14695 /* Prepare interface for each stage */
14696 prepareShaderStage(Utils::Shader::FRAGMENT, vector_type, program_interface, test_case, varying_passthrough);
14697 prepareShaderStage(Utils::Shader::GEOMETRY, vector_type, program_interface, test_case, varying_passthrough);
14698 prepareShaderStage(Utils::Shader::TESS_CTRL, vector_type, program_interface, test_case, varying_passthrough);
14699 prepareShaderStage(Utils::Shader::TESS_EVAL, vector_type, program_interface, test_case, varying_passthrough);
14700 prepareShaderStage(Utils::Shader::VERTEX, vector_type, program_interface, test_case, varying_passthrough);
14705 * @param test_case_index Index of test case
14707 * @return Name of type test in test_case_index
14709 std::string VaryingComponentsTest::getTestCaseName(glw::GLuint test_case_index)
14713 const testCase& test_case = m_test_cases[test_case_index];
14717 switch (test_case.m_type)
14719 case Utils::Type::Double:
14720 name.append(Utils::Type::_double.GetGLSLTypeName());
14722 case Utils::Type::Float:
14723 name.append(Utils::Type::_float.GetGLSLTypeName());
14725 case Utils::Type::Int:
14726 name.append(Utils::Type::_int.GetGLSLTypeName());
14728 case Utils::Type::Uint:
14729 name.append(Utils::Type::uint.GetGLSLTypeName());
14733 name.append(", layout: ");
14735 switch (test_case.m_layout)
14738 name.append("GVEC4");
14741 name.append("SCALAR_GVEC3");
14744 name.append("GVEC3_SCALAR");
14747 name.append("GVEC2_GVEC2");
14749 case GVEC2_SCALAR_SCALAR:
14750 name.append("GVEC2_SCALAR_SCALAR");
14752 case SCALAR_GVEC2_SCALAR:
14753 name.append("SCALAR_GVEC2_SCALAR");
14755 case SCALAR_SCALAR_GVEC2:
14756 name.append("SCALAR_SCALAR_GVEC2");
14758 case SCALAR_SCALAR_SCALAR_SCALAR:
14759 name.append("SCALAR_SCALAR_SCALAR_SCALAR");
14766 /** Returns number of types to test
14768 * @return Number of types, 34
14770 glw::GLuint VaryingComponentsTest::getTestCaseNumber()
14772 return static_cast<GLuint>(m_test_cases.size());
14775 /* Prepare test cases */
14776 void VaryingComponentsTest::testInit()
14778 m_test_cases.push_back(testCase(GVEC4, Utils::Type::Double));
14779 m_test_cases.push_back(testCase(SCALAR_GVEC3, Utils::Type::Double));
14780 m_test_cases.push_back(testCase(GVEC3_SCALAR, Utils::Type::Double));
14781 m_test_cases.push_back(testCase(GVEC2_GVEC2, Utils::Type::Double));
14782 m_test_cases.push_back(testCase(GVEC2_SCALAR_SCALAR, Utils::Type::Double));
14783 m_test_cases.push_back(testCase(SCALAR_GVEC2_SCALAR, Utils::Type::Double));
14784 m_test_cases.push_back(testCase(SCALAR_SCALAR_GVEC2, Utils::Type::Double));
14785 m_test_cases.push_back(testCase(SCALAR_SCALAR_SCALAR_SCALAR, Utils::Type::Double));
14787 m_test_cases.push_back(testCase(GVEC4, Utils::Type::Float));
14788 m_test_cases.push_back(testCase(SCALAR_GVEC3, Utils::Type::Float));
14789 m_test_cases.push_back(testCase(GVEC3_SCALAR, Utils::Type::Float));
14790 m_test_cases.push_back(testCase(GVEC2_GVEC2, Utils::Type::Float));
14791 m_test_cases.push_back(testCase(GVEC2_SCALAR_SCALAR, Utils::Type::Float));
14792 m_test_cases.push_back(testCase(SCALAR_GVEC2_SCALAR, Utils::Type::Float));
14793 m_test_cases.push_back(testCase(SCALAR_SCALAR_GVEC2, Utils::Type::Float));
14794 m_test_cases.push_back(testCase(SCALAR_SCALAR_SCALAR_SCALAR, Utils::Type::Float));
14796 m_test_cases.push_back(testCase(GVEC4, Utils::Type::Int));
14797 m_test_cases.push_back(testCase(SCALAR_GVEC3, Utils::Type::Int));
14798 m_test_cases.push_back(testCase(GVEC3_SCALAR, Utils::Type::Int));
14799 m_test_cases.push_back(testCase(GVEC2_GVEC2, Utils::Type::Int));
14800 m_test_cases.push_back(testCase(GVEC2_SCALAR_SCALAR, Utils::Type::Int));
14801 m_test_cases.push_back(testCase(SCALAR_GVEC2_SCALAR, Utils::Type::Int));
14802 m_test_cases.push_back(testCase(SCALAR_SCALAR_GVEC2, Utils::Type::Int));
14803 m_test_cases.push_back(testCase(SCALAR_SCALAR_SCALAR_SCALAR, Utils::Type::Int));
14805 m_test_cases.push_back(testCase(GVEC4, Utils::Type::Uint));
14806 m_test_cases.push_back(testCase(SCALAR_GVEC3, Utils::Type::Uint));
14807 m_test_cases.push_back(testCase(GVEC3_SCALAR, Utils::Type::Uint));
14808 m_test_cases.push_back(testCase(GVEC2_GVEC2, Utils::Type::Uint));
14809 m_test_cases.push_back(testCase(GVEC2_SCALAR_SCALAR, Utils::Type::Uint));
14810 m_test_cases.push_back(testCase(SCALAR_GVEC2_SCALAR, Utils::Type::Uint));
14811 m_test_cases.push_back(testCase(SCALAR_SCALAR_GVEC2, Utils::Type::Uint));
14812 m_test_cases.push_back(testCase(SCALAR_SCALAR_SCALAR_SCALAR, Utils::Type::Uint));
14815 /** Inform that test use components
14821 bool VaryingComponentsTest::useComponentQualifier(glw::GLuint /* test_case_index */)
14826 /** Get length of arrays that should be used during test
14828 * @return 0u - no array at all
14830 GLuint VaryingComponentsTest::getArrayLength()
14835 std::string VaryingComponentsTest::prepareGlobals(GLuint last_in_location, GLuint last_out_location)
14837 std::string globals = VaryingLocationsTest::prepareGlobals(last_in_location, last_out_location);
14839 globals.append("const uint comp_x = 0u;\n"
14840 "const uint comp_y = 1u;\n"
14841 "const uint comp_z = 2u;\n"
14842 "const uint comp_w = 3u;\n");
14850 std::string VaryingComponentsTest::prepareName(const glw::GLchar* name, glw::GLint location, glw::GLint component,
14851 Utils::Shader::STAGES stage, Utils::Variable::STORAGE storage)
14854 std::string result = "PREFIXNAME_lLOCATION_cCOMPONENT";
14855 size_t position = 0;
14856 const GLchar* prefix = Utils::ProgramInterface::GetStagePrefix(stage, storage);
14858 Utils::replaceToken("PREFIX", position, prefix, result);
14859 Utils::replaceToken("NAME", position, name, result);
14861 sprintf(buffer, "%d", location);
14862 Utils::replaceToken("LOCATION", position, buffer, result);
14864 sprintf(buffer, "%d", component);
14865 Utils::replaceToken("COMPONENT", position, buffer, result);
14870 std::string VaryingComponentsTest::prepareQualifiers(const glw::GLchar* location, const glw::GLchar* component,
14871 const glw::GLchar* interpolation)
14873 size_t position = 0;
14874 std::string qualifiers = "layout (location = LOCATION, component = COMPONENT) INTERPOLATION";
14876 Utils::replaceToken("LOCATION", position, location, qualifiers);
14877 Utils::replaceToken("COMPONENT", position, component, qualifiers);
14878 Utils::replaceToken("INTERPOLATION", position, interpolation, qualifiers);
14886 void VaryingComponentsTest::prepareShaderStage(Utils::Shader::STAGES stage, const Utils::Type& vector_type,
14887 Utils::ProgramInterface& program_interface, const testCase& test_case,
14888 Utils::VaryingPassthrough& varying_passthrough)
14890 const GLuint array_length = getArrayLength();
14891 const Utils::Type& basic_type = Utils::Type::GetType(vector_type.m_basic_type, 1 /* n_cols */, 1 /* n_rows */);
14892 descriptor desc_in[8];
14893 descriptor desc_out[8];
14894 const GLuint first_in_loc = 0;
14895 const GLuint first_out_loc = 0;
14896 const GLchar* interpolation = "";
14897 const GLuint last_in_loc = getLastInputLocation(stage, vector_type, array_length);
14898 GLuint last_out_loc = 0;
14900 Utils::ShaderInterface& si = program_interface.GetShaderInterface(stage);
14902 /* Select interpolation */
14903 if ((Utils::Shader::FRAGMENT == stage) || (Utils::Shader::GEOMETRY == stage))
14905 interpolation = " flat";
14908 if (Utils::Shader::FRAGMENT != stage)
14910 last_out_loc = getLastOutputLocation(stage, vector_type, array_length);
14913 switch (test_case.m_layout)
14917 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 4, "gvec4");
14918 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 4, "gvec4");
14920 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 4, "gvec4");
14921 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 4, "gvec4");
14925 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "scalar");
14926 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "scalar");
14927 desc_in[2].assign(1, "comp_y", first_in_loc, "first_input_location", 3, "gvec3");
14928 desc_in[3].assign(1, "comp_y", last_in_loc, "last_input_location", 3, "gvec3");
14930 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "scalar");
14931 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "scalar");
14932 desc_out[2].assign(1, "comp_y", first_out_loc, "first_output_location", 3, "gvec3");
14933 desc_out[3].assign(1, "comp_y", last_out_loc, "last_output_location", 3, "gvec3");
14937 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 3, "gvec3");
14938 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 3, "gvec3");
14939 desc_in[2].assign(3, "comp_w", first_in_loc, "first_input_location", 1, "scalar");
14940 desc_in[3].assign(3, "comp_w", last_in_loc, "last_input_location", 1, "scalar");
14942 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 3, "gvec3");
14943 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 3, "gvec3");
14944 desc_out[2].assign(3, "comp_w", first_out_loc, "first_output_location", 1, "scalar");
14945 desc_out[3].assign(3, "comp_w", last_out_loc, "last_output_location", 1, "scalar");
14949 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 2, "gvec2");
14950 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 2, "gvec2");
14951 desc_in[2].assign(2, "comp_z", first_in_loc, "first_input_location", 2, "gvec2");
14952 desc_in[3].assign(2, "comp_z", last_in_loc, "last_input_location", 2, "gvec2");
14954 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 2, "gvec2");
14955 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 2, "gvec2");
14956 desc_out[2].assign(2, "comp_z", first_out_loc, "first_output_location", 2, "gvec2");
14957 desc_out[3].assign(2, "comp_z", last_out_loc, "last_output_location", 2, "gvec2");
14959 case GVEC2_SCALAR_SCALAR:
14961 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 2, "gvec2");
14962 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 2, "gvec2");
14963 desc_in[2].assign(2, "comp_z", first_in_loc, "first_input_location", 1, "scalar");
14964 desc_in[3].assign(2, "comp_z", last_in_loc, "last_input_location", 1, "scalar");
14965 desc_in[4].assign(3, "comp_w", first_in_loc, "first_input_location", 1, "scalar");
14966 desc_in[5].assign(3, "comp_w", last_in_loc, "last_input_location", 1, "scalar");
14968 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 2, "gvec2");
14969 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 2, "gvec2");
14970 desc_out[2].assign(2, "comp_z", first_out_loc, "first_output_location", 1, "scalar");
14971 desc_out[3].assign(2, "comp_z", last_out_loc, "last_output_location", 1, "scalar");
14972 desc_out[4].assign(3, "comp_w", first_out_loc, "first_output_location", 1, "scalar");
14973 desc_out[5].assign(3, "comp_w", last_out_loc, "last_output_location", 1, "scalar");
14975 case SCALAR_GVEC2_SCALAR:
14977 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "scalar");
14978 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "scalar");
14979 desc_in[2].assign(1, "comp_y", first_in_loc, "first_input_location", 2, "gvec2");
14980 desc_in[3].assign(1, "comp_y", last_in_loc, "last_input_location", 2, "gvec2");
14981 desc_in[4].assign(3, "comp_w", first_in_loc, "first_input_location", 1, "scalar");
14982 desc_in[5].assign(3, "comp_w", last_in_loc, "last_input_location", 1, "scalar");
14984 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "scalar");
14985 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "scalar");
14986 desc_out[2].assign(1, "comp_y", first_out_loc, "first_output_location", 2, "gvec2");
14987 desc_out[3].assign(1, "comp_y", last_out_loc, "last_output_location", 2, "gvec2");
14988 desc_out[4].assign(3, "comp_w", first_out_loc, "first_output_location", 1, "scalar");
14989 desc_out[5].assign(3, "comp_w", last_out_loc, "last_output_location", 1, "scalar");
14991 case SCALAR_SCALAR_GVEC2:
14993 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "scalar");
14994 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "scalar");
14995 desc_in[2].assign(1, "comp_y", first_in_loc, "first_input_location", 1, "scalar");
14996 desc_in[3].assign(1, "comp_y", last_in_loc, "last_input_location", 1, "scalar");
14997 desc_in[4].assign(2, "comp_z", first_in_loc, "first_input_location", 2, "gvec2");
14998 desc_in[5].assign(2, "comp_z", last_in_loc, "last_input_location", 2, "gvec2");
15000 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "scalar");
15001 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "scalar");
15002 desc_out[2].assign(1, "comp_y", first_out_loc, "first_output_location", 1, "scalar");
15003 desc_out[3].assign(1, "comp_y", last_out_loc, "last_output_location", 1, "scalar");
15004 desc_out[4].assign(2, "comp_z", first_out_loc, "first_output_location", 2, "gvec2");
15005 desc_out[5].assign(2, "comp_z", last_out_loc, "last_output_location", 2, "gvec2");
15007 case SCALAR_SCALAR_SCALAR_SCALAR:
15009 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "scalar");
15010 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "scalar");
15011 desc_in[2].assign(1, "comp_y", first_in_loc, "first_input_location", 1, "scalar");
15012 desc_in[3].assign(1, "comp_y", last_in_loc, "last_input_location", 1, "scalar");
15013 desc_in[4].assign(2, "comp_z", first_in_loc, "first_input_location", 1, "scalar");
15014 desc_in[5].assign(2, "comp_z", last_in_loc, "last_input_location", 1, "scalar");
15015 desc_in[6].assign(3, "comp_w", first_in_loc, "first_input_location", 1, "scalar");
15016 desc_in[7].assign(3, "comp_w", last_in_loc, "last_input_location", 1, "scalar");
15018 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "scalar");
15019 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "scalar");
15020 desc_out[2].assign(1, "comp_y", first_out_loc, "first_output_location", 1, "scalar");
15021 desc_out[3].assign(1, "comp_y", last_out_loc, "last_output_location", 1, "scalar");
15022 desc_out[4].assign(2, "comp_z", first_out_loc, "first_output_location", 1, "scalar");
15023 desc_out[5].assign(2, "comp_z", last_out_loc, "last_output_location", 1, "scalar");
15024 desc_out[6].assign(3, "comp_w", first_out_loc, "first_output_location", 1, "scalar");
15025 desc_out[7].assign(3, "comp_w", last_out_loc, "last_output_location", 1, "scalar");
15029 for (GLuint i = 0; i < n_desc; ++i)
15031 const descriptor& in_desc = desc_in[i];
15033 Utils::Variable* in =
15034 prepareVarying(basic_type, in_desc, interpolation, si, stage, Utils::Variable::VARYING_INPUT);
15036 if (Utils::Shader::FRAGMENT != stage)
15038 const descriptor& out_desc = desc_out[i];
15040 Utils::Variable* out =
15041 prepareVarying(basic_type, out_desc, interpolation, si, stage, Utils::Variable::VARYING_OUTPUT);
15043 varying_passthrough.Add(stage, in, out);
15047 si.m_globals = prepareGlobals(last_in_loc, last_out_loc);
15053 Utils::Variable* VaryingComponentsTest::prepareVarying(const Utils::Type& basic_type, const descriptor& desc,
15054 const GLchar* interpolation, Utils::ShaderInterface& si,
15055 Utils::Shader::STAGES stage, Utils::Variable::STORAGE storage)
15057 const GLuint array_length = getArrayLength();
15058 const GLuint component_size = basic_type.GetSize();
15059 const std::string& name = prepareName(desc.m_name, desc.m_location, desc.m_component, stage, storage);
15060 const GLuint offset = desc.m_component * component_size;
15061 const std::string& qual = prepareQualifiers(desc.m_location_str, desc.m_component_str, interpolation);
15062 const GLuint size = desc.m_n_rows * component_size;
15063 const Utils::Type& type = Utils::Type::GetType(basic_type.m_basic_type, 1 /* n_columns */, desc.m_n_rows);
15064 Utils::Variable* var = 0;
15066 if (Utils::Variable::VARYING_INPUT == storage)
15068 var = si.Input(name.c_str(), qual.c_str() /* qualifiers */, desc.m_component /* expected_componenet */,
15069 desc.m_location /* expected_location */, type, /* built_in_type */
15070 GL_FALSE /* normalized */, array_length /* n_array_elements */, 0u /* stride */,
15071 offset /* offset */, (GLvoid*)&m_data[offset] /* data */, size /* data_size */);
15075 var = si.Output(name.c_str(), qual.c_str() /* qualifiers */, desc.m_component /* expected_componenet */,
15076 desc.m_location /* expected_location */, type, /* built_in_type */
15077 GL_FALSE /* normalized */, array_length /* n_array_elements */, 0u /* stride */,
15078 offset /* offset */, (GLvoid*)&m_data[offset] /* data */, size /* data_size */);
15084 void VaryingComponentsTest::descriptor::assign(glw::GLint component, const glw::GLchar* component_str,
15085 glw::GLint location, const glw::GLchar* location_str, glw::GLuint n_rows,
15086 const glw::GLchar* name)
15088 m_component = component;
15089 m_component_str = component_str;
15090 m_location = location;
15091 m_location_str = location_str;
15096 VaryingComponentsTest::testCase::testCase(COMPONENTS_LAYOUT layout, Utils::Type::TYPES type)
15097 : m_layout(layout), m_type(type)
15103 * @param context Test framework context
15105 VaryingArrayComponentsTest::VaryingArrayComponentsTest(deqp::Context& context)
15106 : VaryingComponentsTest(context, "varying_array_components",
15107 "Test verifies that input and output components are respected for arrays")
15111 /** Get length of arrays that should be used during test
15115 GLuint VaryingArrayComponentsTest::getArrayLength()
15122 * @param context Test framework context
15124 VaryingExceedingComponentsTest::VaryingExceedingComponentsTest(deqp::Context& context)
15125 : NegativeTestBase(context, "varying_exceeding_components",
15126 "Test verifies that compiler reports error when component qualifier exceed limits")
15130 /** Source for given test case and stage
15132 * @param test_case_index Index of test case
15133 * @param stage Shader stage
15135 * @return Shader source
15137 std::string VaryingExceedingComponentsTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
15139 static const GLchar* var_definition_arr =
15140 "layout (location = 1, component = COMPONENT) flat DIRECTION TYPE gokuARRAY[1];\n";
15141 static const GLchar* var_definition_one =
15142 "layout (location = 1, component = COMPONENT) flat DIRECTION TYPE gokuARRAY;\n";
15143 static const GLchar* input_use_arr = " if (TYPE(0) == gokuINDEX[0])\n"
15145 " result += vec4(1, 0.5, 0.25, 0.125);\n"
15147 static const GLchar* input_use_one = " if (TYPE(0) == gokuINDEX)\n"
15149 " result += vec4(1, 0.5, 0.25, 0.125);\n"
15151 static const GLchar* output_use_arr = " gokuINDEX[0] = TYPE(0);\n"
15152 " if (vec4(0) == result)\n"
15154 " gokuINDEX[0] = TYPE(1);\n"
15156 static const GLchar* output_use_one = " gokuINDEX = TYPE(0);\n"
15157 " if (vec4(0) == result)\n"
15159 " gokuINDEX = TYPE(1);\n"
15161 static const GLchar* fs = "#version 430 core\n"
15162 "#extension GL_ARB_enhanced_layouts : require\n"
15165 "out vec4 fs_out;\n"
15169 " fs_out = gs_fs;\n"
15172 static const GLchar* fs_tested = "#version 430 core\n"
15173 "#extension GL_ARB_enhanced_layouts : require\n"
15178 "out vec4 fs_out;\n"
15182 " vec4 result = gs_fs;\n"
15186 " fs_out += result;\n"
15189 static const GLchar* gs = "#version 430 core\n"
15190 "#extension GL_ARB_enhanced_layouts : require\n"
15192 "layout(points) in;\n"
15193 "layout(triangle_strip, max_vertices = 4) out;\n"
15195 "in vec4 tes_gs[];\n"
15196 "out vec4 gs_fs;\n"
15200 " gs_fs = tes_gs[0];\n"
15201 " gl_Position = vec4(-1, -1, 0, 1);\n"
15203 " gs_fs = tes_gs[0];\n"
15204 " gl_Position = vec4(-1, 1, 0, 1);\n"
15206 " gs_fs = tes_gs[0];\n"
15207 " gl_Position = vec4(1, -1, 0, 1);\n"
15209 " gs_fs = tes_gs[0];\n"
15210 " gl_Position = vec4(1, 1, 0, 1);\n"
15214 static const GLchar* gs_tested = "#version 430 core\n"
15215 "#extension GL_ARB_enhanced_layouts : require\n"
15217 "layout(points) in;\n"
15218 "layout(triangle_strip, max_vertices = 4) out;\n"
15222 "in vec4 tes_gs[];\n"
15223 "out vec4 gs_fs;\n"
15227 " vec4 result = tes_gs[0];\n"
15231 " gs_fs = result;\n"
15232 " gl_Position = vec4(-1, -1, 0, 1);\n"
15234 " gs_fs = result;\n"
15235 " gl_Position = vec4(-1, 1, 0, 1);\n"
15237 " gs_fs = result;\n"
15238 " gl_Position = vec4(1, -1, 0, 1);\n"
15240 " gs_fs = result;\n"
15241 " gl_Position = vec4(1, 1, 0, 1);\n"
15245 static const GLchar* tcs = "#version 430 core\n"
15246 "#extension GL_ARB_enhanced_layouts : require\n"
15248 "layout(vertices = 1) out;\n"
15250 "in vec4 vs_tcs[];\n"
15251 "out vec4 tcs_tes[];\n"
15256 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
15258 " gl_TessLevelOuter[0] = 1.0;\n"
15259 " gl_TessLevelOuter[1] = 1.0;\n"
15260 " gl_TessLevelOuter[2] = 1.0;\n"
15261 " gl_TessLevelOuter[3] = 1.0;\n"
15262 " gl_TessLevelInner[0] = 1.0;\n"
15263 " gl_TessLevelInner[1] = 1.0;\n"
15266 static const GLchar* tcs_tested = "#version 430 core\n"
15267 "#extension GL_ARB_enhanced_layouts : require\n"
15269 "layout(vertices = 1) out;\n"
15273 "in vec4 vs_tcs[];\n"
15274 "out vec4 tcs_tes[];\n"
15278 " vec4 result = vs_tcs[gl_InvocationID];\n"
15282 " tcs_tes[gl_InvocationID] = result;\n"
15284 " gl_TessLevelOuter[0] = 1.0;\n"
15285 " gl_TessLevelOuter[1] = 1.0;\n"
15286 " gl_TessLevelOuter[2] = 1.0;\n"
15287 " gl_TessLevelOuter[3] = 1.0;\n"
15288 " gl_TessLevelInner[0] = 1.0;\n"
15289 " gl_TessLevelInner[1] = 1.0;\n"
15292 static const GLchar* tes = "#version 430 core\n"
15293 "#extension GL_ARB_enhanced_layouts : require\n"
15295 "layout(isolines, point_mode) in;\n"
15297 "in vec4 tcs_tes[];\n"
15298 "out vec4 tes_gs;\n"
15302 " tes_gs = tcs_tes[0];\n"
15305 static const GLchar* tes_tested = "#version 430 core\n"
15306 "#extension GL_ARB_enhanced_layouts : require\n"
15308 "layout(isolines, point_mode) in;\n"
15312 "in vec4 tcs_tes[];\n"
15313 "out vec4 tes_gs;\n"
15317 " vec4 result = tcs_tes[0];\n"
15321 " tes_gs += result;\n"
15324 static const GLchar* vs = "#version 430 core\n"
15325 "#extension GL_ARB_enhanced_layouts : require\n"
15328 "out vec4 vs_tcs;\n"
15332 " vs_tcs = in_vs;\n"
15335 static const GLchar* vs_tested = "#version 430 core\n"
15336 "#extension GL_ARB_enhanced_layouts : require\n"
15341 "out vec4 vs_tcs;\n"
15345 " vec4 result = in_vs;\n"
15349 " vs_tcs += result;\n"
15353 std::string source;
15354 testCase& test_case = m_test_cases[test_case_index];
15356 if (test_case.m_stage == stage)
15358 const GLchar* array = "";
15360 const GLchar* var_definition = 0;
15361 const GLchar* direction = "in ";
15362 const GLchar* index = "";
15363 size_t position = 0;
15365 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
15366 const GLchar* var_use = 0;
15368 if (false == test_case.m_is_input)
15372 if (false == test_case.m_is_array)
15374 var_definition = var_definition_one;
15375 var_use = output_use_one;
15379 var_definition = var_definition_arr;
15380 var_use = output_use_arr;
15385 if (false == test_case.m_is_array)
15387 var_definition = var_definition_one;
15388 var_use = input_use_one;
15392 var_definition = var_definition_arr;
15393 var_use = input_use_arr;
15397 sprintf(buffer, "%d", test_case.m_component);
15401 case Utils::Shader::FRAGMENT:
15402 source = fs_tested;
15404 case Utils::Shader::GEOMETRY:
15405 source = gs_tested;
15409 case Utils::Shader::TESS_CTRL:
15410 source = tcs_tested;
15412 index = "[gl_InvocationID]";
15414 case Utils::Shader::TESS_EVAL:
15415 source = tes_tested;
15419 case Utils::Shader::VERTEX:
15420 source = vs_tested;
15423 TCU_FAIL("Invalid enum");
15427 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
15429 Utils::replaceToken("COMPONENT", position, buffer, source);
15430 Utils::replaceToken("DIRECTION", position, direction, source);
15431 Utils::replaceToken("ARRAY", position, array, source);
15432 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
15434 Utils::replaceAllTokens("TYPE", type_name, source);
15435 Utils::replaceAllTokens("INDEX", index, source);
15441 case Utils::Shader::FRAGMENT:
15444 case Utils::Shader::GEOMETRY:
15447 case Utils::Shader::TESS_CTRL:
15450 case Utils::Shader::TESS_EVAL:
15453 case Utils::Shader::VERTEX:
15457 TCU_FAIL("Invalid enum");
15464 /** Get description of test case
15466 * @param test_case_index Index of test case
15468 * @return Test case description
15470 std::string VaryingExceedingComponentsTest::getTestCaseName(GLuint test_case_index)
15472 std::stringstream stream;
15473 testCase& test_case = m_test_cases[test_case_index];
15475 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
15476 << " type: " << test_case.m_type.GetGLSLTypeName();
15478 if (true == test_case.m_is_array)
15483 stream << ", direction: ";
15485 if (true == test_case.m_is_input)
15491 stream << "output";
15494 stream << ", component: " << test_case.m_component;
15496 return stream.str();
15499 /** Get number of test cases
15501 * @return Number of test cases
15503 GLuint VaryingExceedingComponentsTest::getTestCaseNumber()
15505 return static_cast<GLuint>(m_test_cases.size());
15508 /** Selects if "compute" stage is relevant for test
15514 bool VaryingExceedingComponentsTest::isComputeRelevant(GLuint /* test_case_index */)
15519 /** Prepare all test cases
15522 void VaryingExceedingComponentsTest::testInit()
15524 static const GLuint n_components_per_location = 4;
15525 const GLuint n_types = getTypesNumber();
15527 for (GLuint i = 0; i < n_types; ++i)
15529 const Utils::Type& type = getType(i);
15530 const GLuint n_req_components = type.m_n_rows;
15531 const GLuint valid_component = n_components_per_location - n_req_components;
15532 const GLuint invalid_component = valid_component + 1;
15534 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
15536 if (Utils::Shader::COMPUTE == stage)
15541 /* Component cannot be used for matrices */
15542 if (1 != type.m_n_columns)
15547 testCase test_case_in_arr = { invalid_component, true, true, (Utils::Shader::STAGES)stage, type };
15548 testCase test_case_in_one = { invalid_component, true, false, (Utils::Shader::STAGES)stage, type };
15549 testCase test_case_out_arr = { invalid_component, false, true, (Utils::Shader::STAGES)stage, type };
15550 testCase test_case_out_one = { invalid_component, false, false, (Utils::Shader::STAGES)stage, type };
15552 m_test_cases.push_back(test_case_in_arr);
15553 m_test_cases.push_back(test_case_in_one);
15555 if (Utils::Shader::FRAGMENT != stage)
15557 m_test_cases.push_back(test_case_out_arr);
15558 m_test_cases.push_back(test_case_out_one);
15566 * @param context Test framework context
15568 VaryingComponentWithoutLocationTest::VaryingComponentWithoutLocationTest(deqp::Context& context)
15569 : NegativeTestBase(context, "varying_component_without_location",
15570 "Test verifies that compiler reports error when component qualifier is used without location")
15574 /** Source for given test case and stage
15576 * @param test_case_index Index of test case
15577 * @param stage Shader stage
15579 * @return Shader source
15581 std::string VaryingComponentWithoutLocationTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
15583 static const GLchar* var_definition = "layout (component = COMPONENT) flat DIRECTION TYPE gokuARRAY;\n";
15584 static const GLchar* input_use = " if (TYPE(0) == gokuINDEX)\n"
15586 " result += vec4(1, 0.5, 0.25, 0.125);\n"
15588 static const GLchar* output_use = " gokuINDEX = TYPE(0);\n"
15589 " if (vec4(0) == result)\n"
15591 " gokuINDEX = TYPE(1);\n"
15593 static const GLchar* fs = "#version 430 core\n"
15594 "#extension GL_ARB_enhanced_layouts : require\n"
15597 "out vec4 fs_out;\n"
15601 " fs_out = gs_fs;\n"
15604 static const GLchar* fs_tested = "#version 430 core\n"
15605 "#extension GL_ARB_enhanced_layouts : require\n"
15610 "out vec4 fs_out;\n"
15614 " vec4 result = gs_fs;\n"
15618 " fs_out += result;\n"
15621 static const GLchar* gs = "#version 430 core\n"
15622 "#extension GL_ARB_enhanced_layouts : require\n"
15624 "layout(points) in;\n"
15625 "layout(triangle_strip, max_vertices = 4) out;\n"
15627 "in vec4 tes_gs[];\n"
15628 "out vec4 gs_fs;\n"
15632 " gs_fs = tes_gs[0];\n"
15633 " gl_Position = vec4(-1, -1, 0, 1);\n"
15635 " gs_fs = tes_gs[0];\n"
15636 " gl_Position = vec4(-1, 1, 0, 1);\n"
15638 " gs_fs = tes_gs[0];\n"
15639 " gl_Position = vec4(1, -1, 0, 1);\n"
15641 " gs_fs = tes_gs[0];\n"
15642 " gl_Position = vec4(1, 1, 0, 1);\n"
15646 static const GLchar* gs_tested = "#version 430 core\n"
15647 "#extension GL_ARB_enhanced_layouts : require\n"
15649 "layout(points) in;\n"
15650 "layout(triangle_strip, max_vertices = 4) out;\n"
15654 "in vec4 tes_gs[];\n"
15655 "out vec4 gs_fs;\n"
15659 " vec4 result = tes_gs[0];\n"
15663 " gs_fs = result;\n"
15664 " gl_Position = vec4(-1, -1, 0, 1);\n"
15666 " gs_fs = result;\n"
15667 " gl_Position = vec4(-1, 1, 0, 1);\n"
15669 " gs_fs = result;\n"
15670 " gl_Position = vec4(1, -1, 0, 1);\n"
15672 " gs_fs = result;\n"
15673 " gl_Position = vec4(1, 1, 0, 1);\n"
15677 static const GLchar* tcs = "#version 430 core\n"
15678 "#extension GL_ARB_enhanced_layouts : require\n"
15680 "layout(vertices = 1) out;\n"
15682 "in vec4 vs_tcs[];\n"
15683 "out vec4 tcs_tes[];\n"
15688 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
15690 " gl_TessLevelOuter[0] = 1.0;\n"
15691 " gl_TessLevelOuter[1] = 1.0;\n"
15692 " gl_TessLevelOuter[2] = 1.0;\n"
15693 " gl_TessLevelOuter[3] = 1.0;\n"
15694 " gl_TessLevelInner[0] = 1.0;\n"
15695 " gl_TessLevelInner[1] = 1.0;\n"
15698 static const GLchar* tcs_tested = "#version 430 core\n"
15699 "#extension GL_ARB_enhanced_layouts : require\n"
15701 "layout(vertices = 1) out;\n"
15705 "in vec4 vs_tcs[];\n"
15706 "out vec4 tcs_tes[];\n"
15710 " vec4 result = vs_tcs[gl_InvocationID];\n"
15714 " tcs_tes[gl_InvocationID] = result;\n"
15716 " gl_TessLevelOuter[0] = 1.0;\n"
15717 " gl_TessLevelOuter[1] = 1.0;\n"
15718 " gl_TessLevelOuter[2] = 1.0;\n"
15719 " gl_TessLevelOuter[3] = 1.0;\n"
15720 " gl_TessLevelInner[0] = 1.0;\n"
15721 " gl_TessLevelInner[1] = 1.0;\n"
15724 static const GLchar* tes = "#version 430 core\n"
15725 "#extension GL_ARB_enhanced_layouts : require\n"
15727 "layout(isolines, point_mode) in;\n"
15729 "in vec4 tcs_tes[];\n"
15730 "out vec4 tes_gs;\n"
15734 " tes_gs = tcs_tes[0];\n"
15737 static const GLchar* tes_tested = "#version 430 core\n"
15738 "#extension GL_ARB_enhanced_layouts : require\n"
15740 "layout(isolines, point_mode) in;\n"
15744 "in vec4 tcs_tes[];\n"
15745 "out vec4 tes_gs;\n"
15749 " vec4 result = tcs_tes[0];\n"
15753 " tes_gs += result;\n"
15756 static const GLchar* vs = "#version 430 core\n"
15757 "#extension GL_ARB_enhanced_layouts : require\n"
15760 "out vec4 vs_tcs;\n"
15764 " vs_tcs = in_vs;\n"
15767 static const GLchar* vs_tested = "#version 430 core\n"
15768 "#extension GL_ARB_enhanced_layouts : require\n"
15773 "out vec4 vs_tcs;\n"
15777 " vec4 result = in_vs;\n"
15781 " vs_tcs += result;\n"
15785 std::string source;
15786 testCase& test_case = m_test_cases[test_case_index];
15788 if (test_case.m_stage == stage)
15790 const GLchar* array = "";
15792 const GLchar* direction = "in ";
15793 const GLchar* index = "";
15794 size_t position = 0;
15796 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
15797 const GLchar* var_use = input_use;
15799 if (false == test_case.m_is_input)
15802 var_use = output_use;
15805 sprintf(buffer, "%d", test_case.m_component);
15809 case Utils::Shader::FRAGMENT:
15810 source = fs_tested;
15812 case Utils::Shader::GEOMETRY:
15813 source = gs_tested;
15817 case Utils::Shader::TESS_CTRL:
15818 source = tcs_tested;
15820 index = "[gl_InvocationID]";
15822 case Utils::Shader::TESS_EVAL:
15823 source = tes_tested;
15827 case Utils::Shader::VERTEX:
15828 source = vs_tested;
15831 TCU_FAIL("Invalid enum");
15835 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
15837 Utils::replaceToken("COMPONENT", position, buffer, source);
15838 Utils::replaceToken("DIRECTION", position, direction, source);
15839 Utils::replaceToken("ARRAY", position, array, source);
15840 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
15842 Utils::replaceAllTokens("TYPE", type_name, source);
15843 Utils::replaceAllTokens("INDEX", index, source);
15849 case Utils::Shader::FRAGMENT:
15852 case Utils::Shader::GEOMETRY:
15855 case Utils::Shader::TESS_CTRL:
15858 case Utils::Shader::TESS_EVAL:
15861 case Utils::Shader::VERTEX:
15865 TCU_FAIL("Invalid enum");
15872 /** Get description of test case
15874 * @param test_case_index Index of test case
15876 * @return Test case description
15878 std::string VaryingComponentWithoutLocationTest::getTestCaseName(GLuint test_case_index)
15880 std::stringstream stream;
15881 testCase& test_case = m_test_cases[test_case_index];
15883 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
15884 << " type: " << test_case.m_type.GetGLSLTypeName() << ", direction: ";
15886 if (true == test_case.m_is_input)
15892 stream << "output";
15895 stream << ", component: " << test_case.m_component;
15897 return stream.str();
15900 /** Get number of test cases
15902 * @return Number of test cases
15904 GLuint VaryingComponentWithoutLocationTest::getTestCaseNumber()
15906 return static_cast<GLuint>(m_test_cases.size());
15909 /** Selects if "compute" stage is relevant for test
15915 bool VaryingComponentWithoutLocationTest::isComputeRelevant(GLuint /* test_case_index */)
15920 /** Prepare all test cases
15923 void VaryingComponentWithoutLocationTest::testInit()
15925 static const GLuint n_components_per_location = 4;
15926 const GLuint n_types = getTypesNumber();
15928 for (GLuint i = 0; i < n_types; ++i)
15930 const Utils::Type& type = getType(i);
15931 const GLuint n_req_components = type.m_n_rows;
15932 const GLuint valid_component = n_components_per_location - n_req_components;
15934 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
15936 if (Utils::Shader::COMPUTE == stage)
15941 /* Component cannot be used for matrices */
15942 if (1 != type.m_n_columns)
15947 testCase test_case_in = { valid_component, true, (Utils::Shader::STAGES)stage, type };
15948 testCase test_case_out = { valid_component, false, (Utils::Shader::STAGES)stage, type };
15950 m_test_cases.push_back(test_case_in);
15952 if (Utils::Shader::FRAGMENT != stage)
15954 m_test_cases.push_back(test_case_out);
15962 * @param context Test framework context
15964 VaryingComponentOfInvalidTypeTest::VaryingComponentOfInvalidTypeTest(deqp::Context& context)
15965 : NegativeTestBase(context, "varying_component_of_invalid_type",
15966 "Test verifies that compiler reports error when component qualifier is used for invalid type")
15970 /** Source for given test case and stage
15972 * @param test_case_index Index of test case
15973 * @param stage Shader stage
15975 * @return Shader source
15977 std::string VaryingComponentOfInvalidTypeTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
15979 static const GLchar* block_definition_arr = "layout (location = 1, component = COMPONENT) flat DIRECTION Goku {\n"
15981 "} gokuARRAY[1];\n";
15982 static const GLchar* block_definition_one = "layout (location = 1, component = COMPONENT) flat DIRECTION Goku {\n"
15985 static const GLchar* matrix_definition_arr =
15986 "layout (location = 1, component = COMPONENT) flat DIRECTION TYPE gokuARRAY[1];\n";
15987 static const GLchar* matrix_definition_one =
15988 "layout (location = 1, component = COMPONENT) flat DIRECTION TYPE gokuARRAY;\n";
15989 static const GLchar* struct_definition_arr =
15994 "layout (location = 1, component = COMPONENT) flat DIRECTION Goku gokuARRAY[1];\n";
15995 static const GLchar* struct_definition_one =
16000 "layout (location = 1, component = COMPONENT) flat DIRECTION Goku gokuARRAY;\n";
16001 static const GLchar* matrix_input_use_arr = " if (TYPE(0) == gokuINDEX[0])\n"
16003 " result += vec4(1, 0.5, 0.25, 0.125);\n"
16005 static const GLchar* matrix_input_use_one = " if (TYPE(0) == gokuINDEX)\n"
16007 " result += vec4(1, 0.5, 0.25, 0.125);\n"
16009 static const GLchar* matrix_output_use_arr = " gokuINDEX[0] = TYPE(0);\n"
16010 " if (vec4(0) == result)\n"
16012 " gokuINDEX[0] = TYPE(1);\n"
16014 static const GLchar* matrix_output_use_one = " gokuINDEX = TYPE(0);\n"
16015 " if (vec4(0) == result)\n"
16017 " gokuINDEX = TYPE(1);\n"
16019 static const GLchar* member_input_use_arr = " if (TYPE(0) == gokuINDEX[0].member)\n"
16021 " result += vec4(1, 0.5, 0.25, 0.125);\n"
16023 static const GLchar* member_input_use_one = " if (TYPE(0) == gokuINDEX.member)\n"
16025 " result += vec4(1, 0.5, 0.25, 0.125);\n"
16027 static const GLchar* member_output_use_arr = " gokuINDEX[0].member = TYPE(0);\n"
16028 " if (vec4(0) == result)\n"
16030 " gokuINDEX[0].member = TYPE(1);\n"
16032 static const GLchar* member_output_use_one = " gokuINDEX.member = TYPE(0);\n"
16033 " if (vec4(0) == result)\n"
16035 " gokuINDEX.member = TYPE(1);\n"
16037 static const GLchar* fs = "#version 430 core\n"
16038 "#extension GL_ARB_enhanced_layouts : require\n"
16041 "out vec4 fs_out;\n"
16045 " fs_out = gs_fs;\n"
16048 static const GLchar* fs_tested = "#version 430 core\n"
16049 "#extension GL_ARB_enhanced_layouts : require\n"
16054 "out vec4 fs_out;\n"
16058 " vec4 result = gs_fs;\n"
16062 " fs_out += result;\n"
16065 static const GLchar* gs = "#version 430 core\n"
16066 "#extension GL_ARB_enhanced_layouts : require\n"
16068 "layout(points) in;\n"
16069 "layout(triangle_strip, max_vertices = 4) out;\n"
16071 "in vec4 tes_gs[];\n"
16072 "out vec4 gs_fs;\n"
16076 " gs_fs = tes_gs[0];\n"
16077 " gl_Position = vec4(-1, -1, 0, 1);\n"
16079 " gs_fs = tes_gs[0];\n"
16080 " gl_Position = vec4(-1, 1, 0, 1);\n"
16082 " gs_fs = tes_gs[0];\n"
16083 " gl_Position = vec4(1, -1, 0, 1);\n"
16085 " gs_fs = tes_gs[0];\n"
16086 " gl_Position = vec4(1, 1, 0, 1);\n"
16090 static const GLchar* gs_tested = "#version 430 core\n"
16091 "#extension GL_ARB_enhanced_layouts : require\n"
16093 "layout(points) in;\n"
16094 "layout(triangle_strip, max_vertices = 4) out;\n"
16098 "in vec4 tes_gs[];\n"
16099 "out vec4 gs_fs;\n"
16103 " vec4 result = tes_gs[0];\n"
16107 " gs_fs = result;\n"
16108 " gl_Position = vec4(-1, -1, 0, 1);\n"
16110 " gs_fs = result;\n"
16111 " gl_Position = vec4(-1, 1, 0, 1);\n"
16113 " gs_fs = result;\n"
16114 " gl_Position = vec4(1, -1, 0, 1);\n"
16116 " gs_fs = result;\n"
16117 " gl_Position = vec4(1, 1, 0, 1);\n"
16121 static const GLchar* tcs = "#version 430 core\n"
16122 "#extension GL_ARB_enhanced_layouts : require\n"
16124 "layout(vertices = 1) out;\n"
16126 "in vec4 vs_tcs[];\n"
16127 "out vec4 tcs_tes[];\n"
16132 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
16134 " gl_TessLevelOuter[0] = 1.0;\n"
16135 " gl_TessLevelOuter[1] = 1.0;\n"
16136 " gl_TessLevelOuter[2] = 1.0;\n"
16137 " gl_TessLevelOuter[3] = 1.0;\n"
16138 " gl_TessLevelInner[0] = 1.0;\n"
16139 " gl_TessLevelInner[1] = 1.0;\n"
16142 static const GLchar* tcs_tested = "#version 430 core\n"
16143 "#extension GL_ARB_enhanced_layouts : require\n"
16145 "layout(vertices = 1) out;\n"
16149 "in vec4 vs_tcs[];\n"
16150 "out vec4 tcs_tes[];\n"
16154 " vec4 result = vs_tcs[gl_InvocationID];\n"
16158 " tcs_tes[gl_InvocationID] = result;\n"
16160 " gl_TessLevelOuter[0] = 1.0;\n"
16161 " gl_TessLevelOuter[1] = 1.0;\n"
16162 " gl_TessLevelOuter[2] = 1.0;\n"
16163 " gl_TessLevelOuter[3] = 1.0;\n"
16164 " gl_TessLevelInner[0] = 1.0;\n"
16165 " gl_TessLevelInner[1] = 1.0;\n"
16168 static const GLchar* tes = "#version 430 core\n"
16169 "#extension GL_ARB_enhanced_layouts : require\n"
16171 "layout(isolines, point_mode) in;\n"
16173 "in vec4 tcs_tes[];\n"
16174 "out vec4 tes_gs;\n"
16178 " tes_gs = tcs_tes[0];\n"
16181 static const GLchar* tes_tested = "#version 430 core\n"
16182 "#extension GL_ARB_enhanced_layouts : require\n"
16184 "layout(isolines, point_mode) in;\n"
16188 "in vec4 tcs_tes[];\n"
16189 "out vec4 tes_gs;\n"
16193 " vec4 result = tcs_tes[0];\n"
16197 " tes_gs += result;\n"
16200 static const GLchar* vs = "#version 430 core\n"
16201 "#extension GL_ARB_enhanced_layouts : require\n"
16204 "out vec4 vs_tcs;\n"
16208 " vs_tcs = in_vs;\n"
16211 static const GLchar* vs_tested = "#version 430 core\n"
16212 "#extension GL_ARB_enhanced_layouts : require\n"
16217 "out vec4 vs_tcs;\n"
16221 " vec4 result = in_vs;\n"
16225 " vs_tcs += result;\n"
16229 std::string source;
16230 testCase& test_case = m_test_cases[test_case_index];
16232 if (test_case.m_stage == stage)
16234 const GLchar* array = "";
16236 const GLchar* var_definition = 0;
16237 const GLchar* direction = "in ";
16238 const GLchar* index = "";
16239 size_t position = 0;
16241 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
16242 const GLchar* var_use = 0;
16244 if (false == test_case.m_is_input)
16248 if (false == test_case.m_is_array)
16250 switch (test_case.m_case)
16253 var_definition = block_definition_one;
16254 var_use = member_output_use_one;
16257 var_definition = matrix_definition_one;
16258 var_use = matrix_output_use_one;
16261 var_definition = struct_definition_one;
16262 var_use = member_output_use_one;
16265 TCU_FAIL("Invalid enum");
16270 switch (test_case.m_case)
16273 var_definition = block_definition_arr;
16274 var_use = member_output_use_arr;
16277 var_definition = matrix_definition_arr;
16278 var_use = matrix_output_use_arr;
16281 var_definition = struct_definition_arr;
16282 var_use = member_output_use_arr;
16285 TCU_FAIL("Invalid enum");
16291 if (false == test_case.m_is_array)
16293 switch (test_case.m_case)
16296 var_definition = block_definition_one;
16297 var_use = member_input_use_one;
16300 var_definition = matrix_definition_one;
16301 var_use = matrix_input_use_one;
16304 var_definition = struct_definition_one;
16305 var_use = member_input_use_one;
16308 TCU_FAIL("Invalid enum");
16313 switch (test_case.m_case)
16316 var_definition = block_definition_arr;
16317 var_use = member_input_use_arr;
16320 var_definition = matrix_definition_arr;
16321 var_use = matrix_input_use_arr;
16324 var_definition = struct_definition_arr;
16325 var_use = member_input_use_arr;
16328 TCU_FAIL("Invalid enum");
16333 sprintf(buffer, "%d", test_case.m_component);
16337 case Utils::Shader::FRAGMENT:
16338 source = fs_tested;
16340 case Utils::Shader::GEOMETRY:
16341 source = gs_tested;
16345 case Utils::Shader::TESS_CTRL:
16346 source = tcs_tested;
16348 index = "[gl_InvocationID]";
16350 case Utils::Shader::TESS_EVAL:
16351 source = tes_tested;
16355 case Utils::Shader::VERTEX:
16356 source = vs_tested;
16359 TCU_FAIL("Invalid enum");
16363 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
16365 Utils::replaceToken("COMPONENT", position, buffer, source);
16366 Utils::replaceToken("DIRECTION", position, direction, source);
16367 Utils::replaceToken("ARRAY", position, array, source);
16368 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
16370 Utils::replaceAllTokens("TYPE", type_name, source);
16371 Utils::replaceAllTokens("INDEX", index, source);
16377 case Utils::Shader::FRAGMENT:
16380 case Utils::Shader::GEOMETRY:
16383 case Utils::Shader::TESS_CTRL:
16386 case Utils::Shader::TESS_EVAL:
16389 case Utils::Shader::VERTEX:
16393 TCU_FAIL("Invalid enum");
16400 /** Get description of test case
16402 * @param test_case_index Index of test case
16404 * @return Test case description
16406 std::string VaryingComponentOfInvalidTypeTest::getTestCaseName(GLuint test_case_index)
16408 std::stringstream stream;
16409 testCase& test_case = m_test_cases[test_case_index];
16411 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
16412 << " type: " << test_case.m_type.GetGLSLTypeName();
16414 if (true == test_case.m_is_array)
16419 stream << ", direction: ";
16421 if (true == test_case.m_is_input)
16427 stream << "output";
16430 stream << ", component: " << test_case.m_component;
16432 return stream.str();
16435 /** Get number of test cases
16437 * @return Number of test cases
16439 GLuint VaryingComponentOfInvalidTypeTest::getTestCaseNumber()
16441 return static_cast<GLuint>(m_test_cases.size());
16444 /** Selects if "compute" stage is relevant for test
16450 bool VaryingComponentOfInvalidTypeTest::isComputeRelevant(GLuint /* test_case_index */)
16455 /** Prepare all test cases
16458 void VaryingComponentOfInvalidTypeTest::testInit()
16460 static const GLuint n_components_per_location = 4;
16461 const GLuint n_types = getTypesNumber();
16463 for (GLuint i = 0; i < n_types; ++i)
16465 const Utils::Type& type = getType(i);
16466 const GLuint n_req_components = type.m_n_rows;
16467 const GLuint valid_component = n_components_per_location - n_req_components;
16469 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
16471 if (Utils::Shader::COMPUTE == stage)
16476 /* Use different CASE for matrices */
16477 if (1 != type.m_n_columns)
16479 testCase test_case_in_arr = { MATRIX, valid_component, true, true, (Utils::Shader::STAGES)stage, type };
16480 testCase test_case_in_one = {
16481 MATRIX, valid_component, false, true, (Utils::Shader::STAGES)stage, type
16483 testCase test_case_out_arr = {
16484 MATRIX, valid_component, true, false, (Utils::Shader::STAGES)stage, type
16486 testCase test_case_out_one = {
16487 MATRIX, valid_component, false, false, (Utils::Shader::STAGES)stage, type
16490 m_test_cases.push_back(test_case_in_arr);
16491 m_test_cases.push_back(test_case_in_one);
16493 if (Utils::Shader::FRAGMENT != stage)
16495 m_test_cases.push_back(test_case_out_arr);
16496 m_test_cases.push_back(test_case_out_one);
16501 for (GLuint c = BLOCK; c < MAX_CASES; ++c)
16503 testCase test_case_in_arr = { (CASES)c, valid_component, true, true, (Utils::Shader::STAGES)stage,
16505 testCase test_case_in_one = { (CASES)c, valid_component, false, true, (Utils::Shader::STAGES)stage,
16507 testCase test_case_out_arr = { (CASES)c, valid_component, true, false, (Utils::Shader::STAGES)stage,
16509 testCase test_case_out_one = {
16510 (CASES)c, valid_component, false, false, (Utils::Shader::STAGES)stage, type
16513 if (Utils::Shader::VERTEX != stage)
16515 m_test_cases.push_back(test_case_in_arr);
16516 m_test_cases.push_back(test_case_in_one);
16519 if (Utils::Shader::FRAGMENT != stage)
16521 m_test_cases.push_back(test_case_out_arr);
16522 m_test_cases.push_back(test_case_out_one);
16532 * @param context Test framework context
16534 InputComponentAliasingTest::InputComponentAliasingTest(deqp::Context& context)
16535 : NegativeTestBase(context, "input_component_aliasing",
16536 "Test verifies that compiler reports component aliasing as error")
16540 /** Source for given test case and stage
16542 * @param test_case_index Index of test case
16543 * @param stage Shader stage
16545 * @return Shader source
16547 std::string InputComponentAliasingTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
16549 static const GLchar* var_definition = "layout (location = 1, component = COMPONENT) FLAT in TYPE gohanARRAY;\n"
16550 "layout (location = 1, component = COMPONENT) FLAT in TYPE gotenARRAY;\n";
16551 static const GLchar* test_one = " if (TYPE(0) == gohanINDEX)\n"
16553 " result += vec4(1, 0.5, 0.25, 0.125);\n"
16555 static const GLchar* test_both = " if (TYPE(0) == gohanINDEX)\n"
16557 " result = vec4(goten.xxxx);\n"
16559 static const GLchar* fs = "#version 430 core\n"
16560 "#extension GL_ARB_enhanced_layouts : require\n"
16563 "out vec4 fs_out;\n"
16567 " fs_out = gs_fs;\n"
16570 static const GLchar* fs_tested = "#version 430 core\n"
16571 "#extension GL_ARB_enhanced_layouts : require\n"
16576 "out vec4 fs_out;\n"
16580 " vec4 result = gs_fs;\n"
16584 " fs_out += result;\n"
16587 static const GLchar* gs = "#version 430 core\n"
16588 "#extension GL_ARB_enhanced_layouts : require\n"
16590 "layout(points) in;\n"
16591 "layout(triangle_strip, max_vertices = 4) out;\n"
16593 "in vec4 tes_gs[];\n"
16594 "out vec4 gs_fs;\n"
16598 " gs_fs = tes_gs[0];\n"
16599 " gl_Position = vec4(-1, -1, 0, 1);\n"
16601 " gs_fs = tes_gs[0];\n"
16602 " gl_Position = vec4(-1, 1, 0, 1);\n"
16604 " gs_fs = tes_gs[0];\n"
16605 " gl_Position = vec4(1, -1, 0, 1);\n"
16607 " gs_fs = tes_gs[0];\n"
16608 " gl_Position = vec4(1, 1, 0, 1);\n"
16612 static const GLchar* gs_tested = "#version 430 core\n"
16613 "#extension GL_ARB_enhanced_layouts : require\n"
16615 "layout(points) in;\n"
16616 "layout(triangle_strip, max_vertices = 4) out;\n"
16620 "in vec4 tes_gs[];\n"
16621 "out vec4 gs_fs;\n"
16625 " vec4 result = tes_gs[0];\n"
16629 " gs_fs = result;\n"
16630 " gl_Position = vec4(-1, -1, 0, 1);\n"
16632 " gs_fs = result;\n"
16633 " gl_Position = vec4(-1, 1, 0, 1);\n"
16635 " gs_fs = result;\n"
16636 " gl_Position = vec4(1, -1, 0, 1);\n"
16638 " gs_fs = result;\n"
16639 " gl_Position = vec4(1, 1, 0, 1);\n"
16643 static const GLchar* tcs = "#version 430 core\n"
16644 "#extension GL_ARB_enhanced_layouts : require\n"
16646 "layout(vertices = 1) out;\n"
16648 "in vec4 vs_tcs[];\n"
16649 "out vec4 tcs_tes[];\n"
16654 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
16656 " gl_TessLevelOuter[0] = 1.0;\n"
16657 " gl_TessLevelOuter[1] = 1.0;\n"
16658 " gl_TessLevelOuter[2] = 1.0;\n"
16659 " gl_TessLevelOuter[3] = 1.0;\n"
16660 " gl_TessLevelInner[0] = 1.0;\n"
16661 " gl_TessLevelInner[1] = 1.0;\n"
16664 static const GLchar* tcs_tested = "#version 430 core\n"
16665 "#extension GL_ARB_enhanced_layouts : require\n"
16667 "layout(vertices = 1) out;\n"
16671 "in vec4 vs_tcs[];\n"
16672 "out vec4 tcs_tes[];\n"
16676 " vec4 result = vs_tcs[gl_InvocationID];\n"
16680 " tcs_tes[gl_InvocationID] = result;\n"
16682 " gl_TessLevelOuter[0] = 1.0;\n"
16683 " gl_TessLevelOuter[1] = 1.0;\n"
16684 " gl_TessLevelOuter[2] = 1.0;\n"
16685 " gl_TessLevelOuter[3] = 1.0;\n"
16686 " gl_TessLevelInner[0] = 1.0;\n"
16687 " gl_TessLevelInner[1] = 1.0;\n"
16690 static const GLchar* tes = "#version 430 core\n"
16691 "#extension GL_ARB_enhanced_layouts : require\n"
16693 "layout(isolines, point_mode) in;\n"
16695 "in vec4 tcs_tes[];\n"
16696 "out vec4 tes_gs;\n"
16700 " tes_gs = tcs_tes[0];\n"
16703 static const GLchar* tes_tested = "#version 430 core\n"
16704 "#extension GL_ARB_enhanced_layouts : require\n"
16706 "layout(isolines, point_mode) in;\n"
16710 "in vec4 tcs_tes[];\n"
16711 "out vec4 tes_gs;\n"
16715 " vec4 result = tcs_tes[0];\n"
16719 " tes_gs += result;\n"
16722 static const GLchar* vs = "#version 430 core\n"
16723 "#extension GL_ARB_enhanced_layouts : require\n"
16726 "out vec4 vs_tcs;\n"
16730 " vs_tcs = in_vs;\n"
16733 static const GLchar* vs_tested = "#version 430 core\n"
16734 "#extension GL_ARB_enhanced_layouts : require\n"
16739 "out vec4 vs_tcs;\n"
16743 " vec4 result = in_vs;\n"
16747 " vs_tcs += result;\n"
16751 std::string source;
16752 testCase& test_case = m_test_cases[test_case_index];
16754 if (test_case.m_stage == stage)
16756 const GLchar* array = "";
16757 GLchar buffer_gohan[16];
16758 GLchar buffer_goten[16];
16759 const GLchar* flat = "";
16760 const GLchar* index = "";
16761 const bool is_flat_req = isFlatRequired(stage, test_case.m_type, Utils::Variable::VARYING_INPUT);
16762 size_t position = 0;
16764 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
16765 const GLchar* var_use = test_one;
16767 if (true == test_case.m_use_both)
16769 var_use = test_both;
16772 if (true == is_flat_req)
16777 sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
16778 sprintf(buffer_goten, "%d", test_case.m_component_goten);
16782 case Utils::Shader::FRAGMENT:
16783 source = fs_tested;
16785 case Utils::Shader::GEOMETRY:
16786 source = gs_tested;
16790 case Utils::Shader::TESS_CTRL:
16791 source = tcs_tested;
16793 index = "[gl_InvocationID]";
16795 case Utils::Shader::TESS_EVAL:
16796 source = tes_tested;
16800 case Utils::Shader::VERTEX:
16801 source = vs_tested;
16804 TCU_FAIL("Invalid enum");
16808 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
16810 Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
16811 Utils::replaceToken("ARRAY", position, array, source);
16812 Utils::replaceToken("COMPONENT", position, buffer_goten, source);
16813 Utils::replaceToken("ARRAY", position, array, source);
16814 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
16816 Utils::replaceAllTokens("FLAT", flat, source);
16817 Utils::replaceAllTokens("TYPE", type_name, source);
16818 Utils::replaceAllTokens("INDEX", index, source);
16824 case Utils::Shader::FRAGMENT:
16827 case Utils::Shader::GEOMETRY:
16830 case Utils::Shader::TESS_CTRL:
16833 case Utils::Shader::TESS_EVAL:
16836 case Utils::Shader::VERTEX:
16840 TCU_FAIL("Invalid enum");
16847 /** Get description of test case
16849 * @param test_case_index Index of test case
16851 * @return Test case description
16853 std::string InputComponentAliasingTest::getTestCaseName(GLuint test_case_index)
16855 std::stringstream stream;
16856 testCase& test_case = m_test_cases[test_case_index];
16858 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
16859 << " type: " << test_case.m_type.GetGLSLTypeName() << ", components: " << test_case.m_component_gohan
16860 << " & " << test_case.m_component_goten;
16862 return stream.str();
16865 /** Get number of test cases
16867 * @return Number of test cases
16869 GLuint InputComponentAliasingTest::getTestCaseNumber()
16871 return static_cast<GLuint>(m_test_cases.size());
16874 /** Selects if "compute" stage is relevant for test
16880 bool InputComponentAliasingTest::isComputeRelevant(GLuint /* test_case_index */)
16885 /** Selects if compilation failure is expected result
16887 * @param test_case_index Index of test case
16889 * @return false for VS that use only single variable, true otherwise
16891 bool InputComponentAliasingTest::isFailureExpected(GLuint test_case_index)
16893 testCase& test_case = m_test_cases[test_case_index];
16895 return !((Utils::Shader::VERTEX == test_case.m_stage) && (false == test_case.m_use_both));
16898 /** Prepare all test cases
16901 void InputComponentAliasingTest::testInit()
16903 static const GLuint n_components_per_location = 4;
16904 const GLuint n_types = getTypesNumber();
16906 for (GLuint i = 0; i < n_types; ++i)
16908 const Utils::Type& type = getType(i);
16909 const GLuint n_req_components = type.m_n_rows;
16910 const GLuint valid_component = n_components_per_location - n_req_components;
16912 /* Skip matrices */
16913 if (1 != type.m_n_columns)
16918 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
16920 if (Utils::Shader::COMPUTE == stage)
16925 for (GLuint gohan = 0; gohan <= valid_component; ++gohan)
16927 const GLint first_aliasing = gohan - n_req_components + 1;
16928 const GLint last_aliasing = gohan + n_req_components - 1;
16930 const GLuint goten_start = std::max(0, first_aliasing);
16931 const GLuint goten_stop = std::min((GLint)valid_component, last_aliasing);
16933 for (GLuint goten = goten_start; goten <= goten_stop; ++goten)
16935 testCase test_case = { gohan, goten, (Utils::Shader::STAGES)stage, type, false };
16937 m_test_cases.push_back(test_case);
16939 if (Utils::Shader::VERTEX == test_case.m_stage)
16941 test_case.m_use_both = true;
16943 m_test_cases.push_back(test_case);
16953 * @param context Test framework context
16955 OutputComponentAliasingTest::OutputComponentAliasingTest(deqp::Context& context)
16956 : NegativeTestBase(context, "output_component_aliasing",
16957 "Test verifies that compiler reports component aliasing as error")
16961 /** Source for given test case and stage
16963 * @param test_case_index Index of test case
16964 * @param stage Shader stage
16966 * @return Shader source
16968 std::string OutputComponentAliasingTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
16970 static const GLchar* var_definition = "layout (location = 1, component = COMPONENT) flat out TYPE gohanARRAY;\n"
16971 "layout (location = 1, component = COMPONENT) flat out TYPE gotenARRAY;\n";
16972 static const GLchar* l_test = " gohanINDEX = TYPE(1);\n"
16973 " gotenINDEX = TYPE(0);\n";
16974 static const GLchar* fs = "#version 430 core\n"
16975 "#extension GL_ARB_enhanced_layouts : require\n"
16978 "out vec4 fs_out;\n"
16982 " fs_out = gs_fs;\n"
16985 static const GLchar* fs_tested = "#version 430 core\n"
16986 "#extension GL_ARB_enhanced_layouts : require\n"
16991 "out vec4 fs_out;\n"
16995 " vec4 result = gs_fs;\n"
16999 " fs_out += result;\n"
17002 static const GLchar* gs = "#version 430 core\n"
17003 "#extension GL_ARB_enhanced_layouts : require\n"
17005 "layout(points) in;\n"
17006 "layout(triangle_strip, max_vertices = 4) out;\n"
17008 "in vec4 tes_gs[];\n"
17009 "out vec4 gs_fs;\n"
17013 " gs_fs = tes_gs[0];\n"
17014 " gl_Position = vec4(-1, -1, 0, 1);\n"
17016 " gs_fs = tes_gs[0];\n"
17017 " gl_Position = vec4(-1, 1, 0, 1);\n"
17019 " gs_fs = tes_gs[0];\n"
17020 " gl_Position = vec4(1, -1, 0, 1);\n"
17022 " gs_fs = tes_gs[0];\n"
17023 " gl_Position = vec4(1, 1, 0, 1);\n"
17027 static const GLchar* gs_tested = "#version 430 core\n"
17028 "#extension GL_ARB_enhanced_layouts : require\n"
17030 "layout(points) in;\n"
17031 "layout(triangle_strip, max_vertices = 4) out;\n"
17035 "in vec4 tes_gs[];\n"
17036 "out vec4 gs_fs;\n"
17040 " vec4 result = tes_gs[0];\n"
17044 " gs_fs = result;\n"
17045 " gl_Position = vec4(-1, -1, 0, 1);\n"
17047 " gs_fs = result;\n"
17048 " gl_Position = vec4(-1, 1, 0, 1);\n"
17050 " gs_fs = result;\n"
17051 " gl_Position = vec4(1, -1, 0, 1);\n"
17053 " gs_fs = result;\n"
17054 " gl_Position = vec4(1, 1, 0, 1);\n"
17058 static const GLchar* tcs = "#version 430 core\n"
17059 "#extension GL_ARB_enhanced_layouts : require\n"
17061 "layout(vertices = 1) out;\n"
17063 "in vec4 vs_tcs[];\n"
17064 "out vec4 tcs_tes[];\n"
17069 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
17071 " gl_TessLevelOuter[0] = 1.0;\n"
17072 " gl_TessLevelOuter[1] = 1.0;\n"
17073 " gl_TessLevelOuter[2] = 1.0;\n"
17074 " gl_TessLevelOuter[3] = 1.0;\n"
17075 " gl_TessLevelInner[0] = 1.0;\n"
17076 " gl_TessLevelInner[1] = 1.0;\n"
17079 static const GLchar* tcs_tested = "#version 430 core\n"
17080 "#extension GL_ARB_enhanced_layouts : require\n"
17082 "layout(vertices = 1) out;\n"
17086 "in vec4 vs_tcs[];\n"
17087 "out vec4 tcs_tes[];\n"
17091 " vec4 result = vs_tcs[gl_InvocationID];\n"
17095 " tcs_tes[gl_InvocationID] = result;\n"
17097 " gl_TessLevelOuter[0] = 1.0;\n"
17098 " gl_TessLevelOuter[1] = 1.0;\n"
17099 " gl_TessLevelOuter[2] = 1.0;\n"
17100 " gl_TessLevelOuter[3] = 1.0;\n"
17101 " gl_TessLevelInner[0] = 1.0;\n"
17102 " gl_TessLevelInner[1] = 1.0;\n"
17105 static const GLchar* tes = "#version 430 core\n"
17106 "#extension GL_ARB_enhanced_layouts : require\n"
17108 "layout(isolines, point_mode) in;\n"
17110 "in vec4 tcs_tes[];\n"
17111 "out vec4 tes_gs;\n"
17115 " tes_gs = tcs_tes[0];\n"
17118 static const GLchar* tes_tested = "#version 430 core\n"
17119 "#extension GL_ARB_enhanced_layouts : require\n"
17121 "layout(isolines, point_mode) in;\n"
17125 "in vec4 tcs_tes[];\n"
17126 "out vec4 tes_gs;\n"
17130 " vec4 result = tcs_tes[0];\n"
17134 " tes_gs += result;\n"
17137 static const GLchar* vs = "#version 430 core\n"
17138 "#extension GL_ARB_enhanced_layouts : require\n"
17141 "out vec4 vs_tcs;\n"
17145 " vs_tcs = in_vs;\n"
17148 static const GLchar* vs_tested = "#version 430 core\n"
17149 "#extension GL_ARB_enhanced_layouts : require\n"
17154 "out vec4 vs_tcs;\n"
17158 " vec4 result = in_vs;\n"
17162 " vs_tcs += result;\n"
17166 std::string source;
17167 testCase& test_case = m_test_cases[test_case_index];
17169 if (test_case.m_stage == stage)
17171 const GLchar* array = "";
17172 GLchar buffer_gohan[16];
17173 GLchar buffer_goten[16];
17174 const GLchar* index = "";
17175 size_t position = 0;
17177 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
17179 sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
17180 sprintf(buffer_goten, "%d", test_case.m_component_goten);
17184 case Utils::Shader::FRAGMENT:
17185 source = fs_tested;
17187 case Utils::Shader::GEOMETRY:
17188 source = gs_tested;
17192 case Utils::Shader::TESS_CTRL:
17193 source = tcs_tested;
17195 index = "[gl_InvocationID]";
17197 case Utils::Shader::TESS_EVAL:
17198 source = tes_tested;
17202 case Utils::Shader::VERTEX:
17203 source = vs_tested;
17206 TCU_FAIL("Invalid enum");
17210 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
17212 Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
17213 Utils::replaceToken("ARRAY", position, array, source);
17214 Utils::replaceToken("COMPONENT", position, buffer_goten, source);
17215 Utils::replaceToken("ARRAY", position, array, source);
17216 Utils::replaceToken("VARIABLE_USE", position, l_test, source);
17218 Utils::replaceAllTokens("TYPE", type_name, source);
17219 Utils::replaceAllTokens("INDEX", index, source);
17225 case Utils::Shader::FRAGMENT:
17228 case Utils::Shader::GEOMETRY:
17231 case Utils::Shader::TESS_CTRL:
17234 case Utils::Shader::TESS_EVAL:
17237 case Utils::Shader::VERTEX:
17241 TCU_FAIL("Invalid enum");
17248 /** Get description of test case
17250 * @param test_case_index Index of test case
17252 * @return Test case description
17254 std::string OutputComponentAliasingTest::getTestCaseName(GLuint test_case_index)
17256 std::stringstream stream;
17257 testCase& test_case = m_test_cases[test_case_index];
17259 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
17260 << " type: " << test_case.m_type.GetGLSLTypeName() << ", components: " << test_case.m_component_gohan
17261 << " & " << test_case.m_component_goten;
17263 return stream.str();
17266 /** Get number of test cases
17268 * @return Number of test cases
17270 GLuint OutputComponentAliasingTest::getTestCaseNumber()
17272 return static_cast<GLuint>(m_test_cases.size());
17275 /** Selects if "compute" stage is relevant for test
17281 bool OutputComponentAliasingTest::isComputeRelevant(GLuint /* test_case_index */)
17286 /** Prepare all test cases
17289 void OutputComponentAliasingTest::testInit()
17291 static const GLuint n_components_per_location = 4;
17292 const GLuint n_types = getTypesNumber();
17294 for (GLuint i = 0; i < n_types; ++i)
17296 const Utils::Type& type = getType(i);
17297 const GLuint n_req_components = type.m_n_rows;
17298 const GLuint valid_component = n_components_per_location - n_req_components;
17300 /* Skip matrices */
17301 if (1 != type.m_n_columns)
17306 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
17308 if (Utils::Shader::COMPUTE == stage)
17313 if ((Utils::Shader::FRAGMENT == stage) && (Utils::Type::Double == type.m_basic_type))
17318 for (GLuint gohan = 0; gohan <= valid_component; ++gohan)
17320 const GLint first_aliasing = gohan - n_req_components + 1;
17321 const GLint last_aliasing = gohan + n_req_components - 1;
17323 const GLuint goten_start = std::max(0, first_aliasing);
17324 const GLuint goten_stop = std::min((GLint)valid_component, last_aliasing);
17326 for (GLuint goten = goten_start; goten <= goten_stop; ++goten)
17328 testCase test_case = { gohan, goten, (Utils::Shader::STAGES)stage, type };
17330 m_test_cases.push_back(test_case);
17339 * @param context Test framework context
17341 VaryingLocationAliasingWithMixedTypesTest::VaryingLocationAliasingWithMixedTypesTest(deqp::Context& context)
17342 : NegativeTestBase(context, "varying_location_aliasing_with_mixed_types",
17343 "Test verifies that compiler reports error when float/int types are mixed at one location")
17347 /** Source for given test case and stage
17349 * @param test_case_index Index of test case
17350 * @param stage Shader stage
17352 * @return Shader source
17354 std::string VaryingLocationAliasingWithMixedTypesTest::getShaderSource(GLuint test_case_index,
17355 Utils::Shader::STAGES stage)
17357 static const GLchar* var_definition =
17358 "layout (location = 1, component = COMPONENT) FLAT DIRECTION TYPE gohanARRAY;\n"
17359 "layout (location = 1, component = COMPONENT) FLAT DIRECTION TYPE gotenARRAY;\n";
17360 static const GLchar* input_use = " if ((TYPE(0) == gohanINDEX) &&\n"
17361 " (TYPE(1) == gotenINDEX) )\n"
17363 " result += vec4(1, 0.5, 0.25, 0.125);\n"
17365 static const GLchar* output_use = " gohanINDEX = TYPE(0);\n"
17366 " gotenINDEX = TYPE(1);\n"
17367 " if (vec4(0) == result)\n"
17369 " gohanINDEX = TYPE(1);\n"
17370 " gotenINDEX = TYPE(0);\n"
17372 static const GLchar* fs = "#version 430 core\n"
17373 "#extension GL_ARB_enhanced_layouts : require\n"
17376 "out vec4 fs_out;\n"
17380 " fs_out = gs_fs;\n"
17383 static const GLchar* fs_tested = "#version 430 core\n"
17384 "#extension GL_ARB_enhanced_layouts : require\n"
17389 "out vec4 fs_out;\n"
17393 " vec4 result = gs_fs;\n"
17397 " fs_out += result;\n"
17400 static const GLchar* gs = "#version 430 core\n"
17401 "#extension GL_ARB_enhanced_layouts : require\n"
17403 "layout(points) in;\n"
17404 "layout(triangle_strip, max_vertices = 4) out;\n"
17406 "in vec4 tes_gs[];\n"
17407 "out vec4 gs_fs;\n"
17411 " gs_fs = tes_gs[0];\n"
17412 " gl_Position = vec4(-1, -1, 0, 1);\n"
17414 " gs_fs = tes_gs[0];\n"
17415 " gl_Position = vec4(-1, 1, 0, 1);\n"
17417 " gs_fs = tes_gs[0];\n"
17418 " gl_Position = vec4(1, -1, 0, 1);\n"
17420 " gs_fs = tes_gs[0];\n"
17421 " gl_Position = vec4(1, 1, 0, 1);\n"
17425 static const GLchar* gs_tested = "#version 430 core\n"
17426 "#extension GL_ARB_enhanced_layouts : require\n"
17428 "layout(points) in;\n"
17429 "layout(triangle_strip, max_vertices = 4) out;\n"
17433 "in vec4 tes_gs[];\n"
17434 "out vec4 gs_fs;\n"
17438 " vec4 result = tes_gs[0];\n"
17442 " gs_fs = result;\n"
17443 " gl_Position = vec4(-1, -1, 0, 1);\n"
17445 " gs_fs = result;\n"
17446 " gl_Position = vec4(-1, 1, 0, 1);\n"
17448 " gs_fs = result;\n"
17449 " gl_Position = vec4(1, -1, 0, 1);\n"
17451 " gs_fs = result;\n"
17452 " gl_Position = vec4(1, 1, 0, 1);\n"
17456 static const GLchar* tcs = "#version 430 core\n"
17457 "#extension GL_ARB_enhanced_layouts : require\n"
17459 "layout(vertices = 1) out;\n"
17461 "in vec4 vs_tcs[];\n"
17462 "out vec4 tcs_tes[];\n"
17467 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
17469 " gl_TessLevelOuter[0] = 1.0;\n"
17470 " gl_TessLevelOuter[1] = 1.0;\n"
17471 " gl_TessLevelOuter[2] = 1.0;\n"
17472 " gl_TessLevelOuter[3] = 1.0;\n"
17473 " gl_TessLevelInner[0] = 1.0;\n"
17474 " gl_TessLevelInner[1] = 1.0;\n"
17477 static const GLchar* tcs_tested = "#version 430 core\n"
17478 "#extension GL_ARB_enhanced_layouts : require\n"
17480 "layout(vertices = 1) out;\n"
17484 "in vec4 vs_tcs[];\n"
17485 "out vec4 tcs_tes[];\n"
17489 " vec4 result = vs_tcs[gl_InvocationID];\n"
17493 " tcs_tes[gl_InvocationID] = result;\n"
17495 " gl_TessLevelOuter[0] = 1.0;\n"
17496 " gl_TessLevelOuter[1] = 1.0;\n"
17497 " gl_TessLevelOuter[2] = 1.0;\n"
17498 " gl_TessLevelOuter[3] = 1.0;\n"
17499 " gl_TessLevelInner[0] = 1.0;\n"
17500 " gl_TessLevelInner[1] = 1.0;\n"
17503 static const GLchar* tes = "#version 430 core\n"
17504 "#extension GL_ARB_enhanced_layouts : require\n"
17506 "layout(isolines, point_mode) in;\n"
17508 "in vec4 tcs_tes[];\n"
17509 "out vec4 tes_gs;\n"
17513 " tes_gs = tcs_tes[0];\n"
17516 static const GLchar* tes_tested = "#version 430 core\n"
17517 "#extension GL_ARB_enhanced_layouts : require\n"
17519 "layout(isolines, point_mode) in;\n"
17523 "in vec4 tcs_tes[];\n"
17524 "out vec4 tes_gs;\n"
17528 " vec4 result = tcs_tes[0];\n"
17532 " tes_gs += result;\n"
17535 static const GLchar* vs = "#version 430 core\n"
17536 "#extension GL_ARB_enhanced_layouts : require\n"
17539 "out vec4 vs_tcs;\n"
17543 " vs_tcs = in_vs;\n"
17546 static const GLchar* vs_tested = "#version 430 core\n"
17547 "#extension GL_ARB_enhanced_layouts : require\n"
17552 "out vec4 vs_tcs;\n"
17556 " vec4 result = in_vs;\n"
17560 " vs_tcs += result;\n"
17564 std::string source;
17565 testCase& test_case = m_test_cases[test_case_index];
17567 if (test_case.m_stage == stage)
17569 const GLchar* array = "";
17570 GLchar buffer_gohan[16];
17571 GLchar buffer_goten[16];
17572 const GLchar* direction = "in ";
17573 const GLchar* flat_gohan = "";
17574 const GLchar* flat_goten = "";
17575 const GLchar* index = "";
17576 size_t position = 0;
17578 const GLchar* type_gohan_name = test_case.m_type_gohan.GetGLSLTypeName();
17579 const GLchar* type_goten_name = test_case.m_type_goten.GetGLSLTypeName();
17580 Utils::Variable::STORAGE storage = Utils::Variable::VARYING_INPUT;
17581 const GLchar* var_use = input_use;
17583 if (false == test_case.m_is_input)
17586 storage = Utils::Variable::VARYING_OUTPUT;
17587 var_use = output_use;
17590 if (true == isFlatRequired(stage, test_case.m_type_gohan, storage))
17592 flat_gohan = "flat";
17595 if (true == isFlatRequired(stage, test_case.m_type_goten, storage))
17597 flat_goten = "flat";
17600 sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
17601 sprintf(buffer_goten, "%d", test_case.m_component_goten);
17605 case Utils::Shader::FRAGMENT:
17606 source = fs_tested;
17608 case Utils::Shader::GEOMETRY:
17609 source = gs_tested;
17613 case Utils::Shader::TESS_CTRL:
17614 source = tcs_tested;
17616 index = "[gl_InvocationID]";
17618 case Utils::Shader::TESS_EVAL:
17619 source = tes_tested;
17623 case Utils::Shader::VERTEX:
17624 source = vs_tested;
17627 TCU_FAIL("Invalid enum");
17631 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
17633 Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
17634 Utils::replaceToken("FLAT", position, flat_gohan, source);
17635 Utils::replaceToken("DIRECTION", position, direction, source);
17636 Utils::replaceToken("TYPE", position, type_gohan_name, source);
17637 Utils::replaceToken("ARRAY", position, array, source);
17638 Utils::replaceToken("COMPONENT", position, buffer_goten, source);
17639 Utils::replaceToken("FLAT", position, flat_goten, source);
17640 Utils::replaceToken("DIRECTION", position, direction, source);
17641 Utils::replaceToken("TYPE", position, type_goten_name, source);
17642 Utils::replaceToken("ARRAY", position, array, source);
17645 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
17647 if (true == test_case.m_is_input)
17649 Utils::replaceToken("TYPE", position, type_gohan_name, source);
17650 Utils::replaceToken("TYPE", position, type_goten_name, source);
17654 Utils::replaceToken("TYPE", position, type_gohan_name, source);
17655 Utils::replaceToken("TYPE", position, type_goten_name, source);
17656 Utils::replaceToken("TYPE", position, type_gohan_name, source);
17657 Utils::replaceToken("TYPE", position, type_goten_name, source);
17660 Utils::replaceAllTokens("INDEX", index, source);
17666 case Utils::Shader::FRAGMENT:
17669 case Utils::Shader::GEOMETRY:
17672 case Utils::Shader::TESS_CTRL:
17675 case Utils::Shader::TESS_EVAL:
17678 case Utils::Shader::VERTEX:
17682 TCU_FAIL("Invalid enum");
17689 /** Get description of test case
17691 * @param test_case_index Index of test case
17693 * @return Test case description
17695 std::string VaryingLocationAliasingWithMixedTypesTest::getTestCaseName(GLuint test_case_index)
17697 std::stringstream stream;
17698 testCase& test_case = m_test_cases[test_case_index];
17700 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", "
17701 << test_case.m_type_gohan.GetGLSLTypeName() << " at " << test_case.m_component_gohan << ", "
17702 << test_case.m_type_goten.GetGLSLTypeName() << " at " << test_case.m_component_goten << ". Direction: ";
17704 if (true == test_case.m_is_input)
17710 stream << "output";
17713 return stream.str();
17716 /** Get number of test cases
17718 * @return Number of test cases
17720 GLuint VaryingLocationAliasingWithMixedTypesTest::getTestCaseNumber()
17722 return static_cast<GLuint>(m_test_cases.size());
17725 /** Selects if "compute" stage is relevant for test
17731 bool VaryingLocationAliasingWithMixedTypesTest::isComputeRelevant(GLuint /* test_case_index */)
17736 /** Prepare all test cases
17739 void VaryingLocationAliasingWithMixedTypesTest::testInit()
17741 static const GLuint n_components_per_location = 4;
17742 const GLuint n_types = getTypesNumber();
17744 for (GLuint i = 0; i < n_types; ++i)
17746 const Utils::Type& type_gohan = getType(i);
17747 const bool is_float_type_gohan = isFloatType(type_gohan);
17749 /* Skip matrices */
17750 if (1 != type_gohan.m_n_columns)
17755 for (GLuint j = 0; j < n_types; ++j)
17757 const Utils::Type& type_goten = getType(j);
17758 const bool is_float_type_goten = isFloatType(type_goten);
17760 /* Skip matrices */
17761 if (1 != type_goten.m_n_columns)
17766 /* Skip valid combinations */
17767 if (is_float_type_gohan == is_float_type_goten)
17772 const GLuint n_req_components_gohan = type_gohan.m_n_rows;
17773 const GLuint n_req_components_goten = type_goten.m_n_rows;
17774 const GLuint valid_component_gohan = n_components_per_location - n_req_components_gohan;
17775 const GLuint valid_component_goten = n_components_per_location - n_req_components_goten;
17777 /* Skip pairs that cannot fit into one location */
17778 if (n_components_per_location < (n_req_components_gohan + n_req_components_goten))
17783 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
17785 /* Skip compute shader */
17786 if (Utils::Shader::COMPUTE == stage)
17791 for (GLuint gohan = 0; gohan <= valid_component_gohan; ++gohan)
17793 const GLint first_aliasing = gohan - n_req_components_goten + 1;
17794 const GLint last_aliasing = gohan + n_req_components_gohan - 1;
17796 const GLuint goten_lower_limit = std::max(0, first_aliasing);
17797 const GLuint goten_upper_limit = last_aliasing + 1;
17799 /* Compoennets before gohan */
17800 for (GLuint goten = 0; goten < goten_lower_limit; ++goten)
17802 testCase test_case_in = { gohan, goten, true, (Utils::Shader::STAGES)stage,
17803 type_gohan, type_goten };
17804 testCase test_case_out = { gohan, goten, false, (Utils::Shader::STAGES)stage,
17805 type_gohan, type_goten };
17807 m_test_cases.push_back(test_case_in);
17809 /* Skip double outputs in fragment shader */
17810 if ((Utils::Shader::FRAGMENT != stage) || ((Utils::Type::Double != type_gohan.m_basic_type) &&
17811 (Utils::Type::Double != type_goten.m_basic_type)))
17813 m_test_cases.push_back(test_case_out);
17817 /* Components after gohan */
17818 for (GLuint goten = goten_upper_limit; goten <= valid_component_goten; ++goten)
17820 testCase test_case_in = { gohan, goten, true, (Utils::Shader::STAGES)stage,
17821 type_gohan, type_goten };
17822 testCase test_case_out = { gohan, goten, false, (Utils::Shader::STAGES)stage,
17823 type_gohan, type_goten };
17825 m_test_cases.push_back(test_case_in);
17827 /* Skip double outputs in fragment shader */
17828 if ((Utils::Shader::FRAGMENT != stage) || ((Utils::Type::Double != type_gohan.m_basic_type) &&
17829 (Utils::Type::Double != type_goten.m_basic_type)))
17831 m_test_cases.push_back(test_case_out);
17840 /** Check if given type is float
17842 * @param type Type in question
17844 * @return true if tpye is float, false otherwise
17846 bool VaryingLocationAliasingWithMixedTypesTest::isFloatType(const Utils::Type& type)
17848 bool is_float = false;
17850 if ((Utils::Type::Double == type.m_basic_type) || (Utils::Type::Float == type.m_basic_type))
17860 * @param context Test framework context
17862 VaryingLocationAliasingWithMixedInterpolationTest::VaryingLocationAliasingWithMixedInterpolationTest(
17863 deqp::Context& context)
17864 : NegativeTestBase(
17865 context, "varying_location_aliasing_with_mixed_interpolation",
17866 "Test verifies that compiler reports error when interpolation qualifiers are mixed at one location")
17870 /** Source for given test case and stage
17872 * @param test_case_index Index of test case
17873 * @param stage Shader stage
17875 * @return Shader source
17877 std::string VaryingLocationAliasingWithMixedInterpolationTest::getShaderSource(GLuint test_case_index,
17878 Utils::Shader::STAGES stage)
17880 static const GLchar* var_definition =
17881 "layout (location = 1, component = COMPONENT) INTERPOLATION DIRECTION TYPE gohanARRAY;\n"
17882 "layout (location = 1, component = COMPONENT) INTERPOLATION DIRECTION TYPE gotenARRAY;\n";
17883 static const GLchar* input_use = " if ((TYPE(0) == gohanINDEX) &&\n"
17884 " (TYPE(1) == gotenINDEX) )\n"
17886 " result += vec4(1, 0.5, 0.25, 0.125);\n"
17888 static const GLchar* output_use = " gohanINDEX = TYPE(0);\n"
17889 " gotenINDEX = TYPE(1);\n"
17890 " if (vec4(0) == result)\n"
17892 " gohanINDEX = TYPE(1);\n"
17893 " gotenINDEX = TYPE(0);\n"
17895 static const GLchar* fs = "#version 430 core\n"
17896 "#extension GL_ARB_enhanced_layouts : require\n"
17899 "out vec4 fs_out;\n"
17903 " fs_out = gs_fs;\n"
17906 static const GLchar* fs_tested = "#version 430 core\n"
17907 "#extension GL_ARB_enhanced_layouts : require\n"
17912 "out vec4 fs_out;\n"
17916 " vec4 result = gs_fs;\n"
17920 " fs_out = result;\n"
17923 static const GLchar* gs = "#version 430 core\n"
17924 "#extension GL_ARB_enhanced_layouts : require\n"
17926 "layout(points) in;\n"
17927 "layout(triangle_strip, max_vertices = 4) out;\n"
17929 "in vec4 tes_gs[];\n"
17930 "out vec4 gs_fs;\n"
17934 " gs_fs = tes_gs[0];\n"
17935 " gl_Position = vec4(-1, -1, 0, 1);\n"
17937 " gs_fs = tes_gs[0];\n"
17938 " gl_Position = vec4(-1, 1, 0, 1);\n"
17940 " gs_fs = tes_gs[0];\n"
17941 " gl_Position = vec4(1, -1, 0, 1);\n"
17943 " gs_fs = tes_gs[0];\n"
17944 " gl_Position = vec4(1, 1, 0, 1);\n"
17948 static const GLchar* gs_tested = "#version 430 core\n"
17949 "#extension GL_ARB_enhanced_layouts : require\n"
17951 "layout(points) in;\n"
17952 "layout(triangle_strip, max_vertices = 4) out;\n"
17956 "in vec4 tes_gs[];\n"
17957 "out vec4 gs_fs;\n"
17961 " vec4 result = tes_gs[0];\n"
17965 " gs_fs = result;\n"
17966 " gl_Position = vec4(-1, -1, 0, 1);\n"
17968 " gs_fs = result;\n"
17969 " gl_Position = vec4(-1, 1, 0, 1);\n"
17971 " gs_fs = result;\n"
17972 " gl_Position = vec4(1, -1, 0, 1);\n"
17974 " gs_fs = result;\n"
17975 " gl_Position = vec4(1, 1, 0, 1);\n"
17979 static const GLchar* tcs = "#version 430 core\n"
17980 "#extension GL_ARB_enhanced_layouts : require\n"
17982 "layout(vertices = 1) out;\n"
17984 "in vec4 vs_tcs[];\n"
17985 "out vec4 tcs_tes[];\n"
17990 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
17992 " gl_TessLevelOuter[0] = 1.0;\n"
17993 " gl_TessLevelOuter[1] = 1.0;\n"
17994 " gl_TessLevelOuter[2] = 1.0;\n"
17995 " gl_TessLevelOuter[3] = 1.0;\n"
17996 " gl_TessLevelInner[0] = 1.0;\n"
17997 " gl_TessLevelInner[1] = 1.0;\n"
18000 static const GLchar* tcs_tested = "#version 430 core\n"
18001 "#extension GL_ARB_enhanced_layouts : require\n"
18003 "layout(vertices = 1) out;\n"
18007 "in vec4 vs_tcs[];\n"
18008 "out vec4 tcs_tes[];\n"
18012 " vec4 result = vs_tcs[gl_InvocationID];\n"
18016 " tcs_tes[gl_InvocationID] = result;\n"
18018 " gl_TessLevelOuter[0] = 1.0;\n"
18019 " gl_TessLevelOuter[1] = 1.0;\n"
18020 " gl_TessLevelOuter[2] = 1.0;\n"
18021 " gl_TessLevelOuter[3] = 1.0;\n"
18022 " gl_TessLevelInner[0] = 1.0;\n"
18023 " gl_TessLevelInner[1] = 1.0;\n"
18026 static const GLchar* tes = "#version 430 core\n"
18027 "#extension GL_ARB_enhanced_layouts : require\n"
18029 "layout(isolines, point_mode) in;\n"
18031 "in vec4 tcs_tes[];\n"
18032 "out vec4 tes_gs;\n"
18036 " tes_gs = tcs_tes[0];\n"
18039 static const GLchar* tes_tested = "#version 430 core\n"
18040 "#extension GL_ARB_enhanced_layouts : require\n"
18042 "layout(isolines, point_mode) in;\n"
18046 "in vec4 tcs_tes[];\n"
18047 "out vec4 tes_gs;\n"
18051 " vec4 result = tcs_tes[0];\n"
18055 " tes_gs += result;\n"
18058 static const GLchar* vs = "#version 430 core\n"
18059 "#extension GL_ARB_enhanced_layouts : require\n"
18062 "out vec4 vs_tcs;\n"
18066 " vs_tcs = in_vs;\n"
18069 static const GLchar* vs_tested = "#version 430 core\n"
18070 "#extension GL_ARB_enhanced_layouts : require\n"
18075 "out vec4 vs_tcs;\n"
18079 " vec4 result = in_vs;\n"
18083 " vs_tcs += result;\n"
18087 std::string source;
18088 testCase& test_case = m_test_cases[test_case_index];
18090 if (test_case.m_stage == stage)
18092 const GLchar* array = "";
18093 GLchar buffer_gohan[16];
18094 GLchar buffer_goten[16];
18095 const GLchar* direction = "in ";
18096 const GLchar* index = "";
18097 const GLchar* int_gohan = getInterpolationQualifier(test_case.m_interpolation_gohan);
18098 const GLchar* int_goten = getInterpolationQualifier(test_case.m_interpolation_goten);
18099 size_t position = 0;
18101 const GLchar* type_gohan_name = test_case.m_type_gohan.GetGLSLTypeName();
18102 const GLchar* type_goten_name = test_case.m_type_goten.GetGLSLTypeName();
18103 const GLchar* var_use = input_use;
18105 if (false == test_case.m_is_input)
18109 var_use = output_use;
18112 sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
18113 sprintf(buffer_goten, "%d", test_case.m_component_goten);
18117 case Utils::Shader::FRAGMENT:
18118 source = fs_tested;
18120 case Utils::Shader::GEOMETRY:
18121 source = gs_tested;
18125 case Utils::Shader::TESS_CTRL:
18126 source = tcs_tested;
18128 index = "[gl_InvocationID]";
18130 case Utils::Shader::TESS_EVAL:
18131 source = tes_tested;
18135 case Utils::Shader::VERTEX:
18136 source = vs_tested;
18139 TCU_FAIL("Invalid enum");
18143 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
18145 Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
18146 Utils::replaceToken("INTERPOLATION", position, int_gohan, source);
18147 Utils::replaceToken("DIRECTION", position, direction, source);
18148 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18149 Utils::replaceToken("ARRAY", position, array, source);
18150 Utils::replaceToken("COMPONENT", position, buffer_goten, source);
18151 Utils::replaceToken("INTERPOLATION", position, int_goten, source);
18152 Utils::replaceToken("DIRECTION", position, direction, source);
18153 Utils::replaceToken("TYPE", position, type_goten_name, source);
18154 Utils::replaceToken("ARRAY", position, array, source);
18157 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
18159 if (true == test_case.m_is_input)
18161 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18162 Utils::replaceToken("TYPE", position, type_goten_name, source);
18166 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18167 Utils::replaceToken("TYPE", position, type_goten_name, source);
18168 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18169 Utils::replaceToken("TYPE", position, type_goten_name, source);
18172 Utils::replaceAllTokens("INDEX", index, source);
18178 case Utils::Shader::FRAGMENT:
18181 case Utils::Shader::GEOMETRY:
18184 case Utils::Shader::TESS_CTRL:
18187 case Utils::Shader::TESS_EVAL:
18190 case Utils::Shader::VERTEX:
18194 TCU_FAIL("Invalid enum");
18201 /** Get description of test case
18203 * @param test_case_index Index of test case
18205 * @return Test case description
18207 std::string VaryingLocationAliasingWithMixedInterpolationTest::getTestCaseName(GLuint test_case_index)
18209 std::stringstream stream;
18210 testCase& test_case = m_test_cases[test_case_index];
18212 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", "
18213 << getInterpolationQualifier(test_case.m_interpolation_gohan) << " "
18214 << test_case.m_type_gohan.GetGLSLTypeName() << " at " << test_case.m_component_gohan << ", "
18215 << getInterpolationQualifier(test_case.m_interpolation_goten) << " "
18216 << test_case.m_type_goten.GetGLSLTypeName() << " at " << test_case.m_component_goten << ". Direction: ";
18218 if (true == test_case.m_is_input)
18224 stream << "output";
18227 return stream.str();
18230 /** Get number of test cases
18232 * @return Number of test cases
18234 GLuint VaryingLocationAliasingWithMixedInterpolationTest::getTestCaseNumber()
18236 return static_cast<GLuint>(m_test_cases.size());
18239 /** Selects if "compute" stage is relevant for test
18245 bool VaryingLocationAliasingWithMixedInterpolationTest::isComputeRelevant(GLuint /* test_case_index */)
18250 /** Prepare all test cases
18253 void VaryingLocationAliasingWithMixedInterpolationTest::testInit()
18255 static const GLuint n_components_per_location = 4;
18256 const GLuint n_types = getTypesNumber();
18258 for (GLuint i = 0; i < n_types; ++i)
18260 const Utils::Type& type_gohan = getType(i);
18261 const bool is_float_type_gohan = isFloatType(type_gohan);
18263 /* Skip matrices */
18264 if (1 != type_gohan.m_n_columns)
18269 for (GLuint j = 0; j < n_types; ++j)
18271 const Utils::Type& type_goten = getType(j);
18272 const bool is_float_type_goten = isFloatType(type_goten);
18274 /* Skip matrices */
18275 if (1 != type_goten.m_n_columns)
18280 /* Skip invalid combinations */
18281 if (is_float_type_gohan != is_float_type_goten)
18286 const GLuint n_req_components_gohan = type_gohan.m_n_rows;
18287 const GLuint n_req_components_goten = type_goten.m_n_rows;
18289 /* Skip pairs that cannot fit into one location */
18290 if (n_components_per_location < (n_req_components_gohan + n_req_components_goten))
18295 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
18297 /* Skip compute shader */
18298 if (Utils::Shader::COMPUTE == stage)
18303 const GLuint gohan = 0;
18304 const GLuint goten = gohan + n_req_components_gohan;
18306 for (GLuint int_gohan = 0; int_gohan < INTERPOLATION_MAX; ++int_gohan)
18308 for (GLuint int_goten = 0; int_goten < INTERPOLATION_MAX; ++int_goten)
18310 const bool is_gohan_double = (Utils::Type::Double == type_gohan.m_basic_type) ? true : false;
18311 const bool is_goten_double = (Utils::Type::Double == type_goten.m_basic_type) ? true : false;
18312 const bool is_gohan_flat = (FLAT == int_gohan) ? true : false;
18313 const bool is_goten_flat = (FLAT == int_goten) ? true : false;
18314 const bool is_gohan_accepted_as_fs_in =
18315 (is_gohan_double && is_gohan_flat) || (!is_gohan_double);
18316 const bool is_goten_accepted_as_fs_in =
18317 (is_goten_double && is_goten_flat) || (!is_goten_double);
18318 const bool is_comb_accepted_as_fs_in = is_gohan_accepted_as_fs_in && is_goten_accepted_as_fs_in;
18320 /* Skip when both are the same */
18321 if (int_gohan == int_goten)
18326 testCase test_case_in = { gohan,
18328 (INTERPOLATIONS)int_gohan,
18329 (INTERPOLATIONS)int_goten,
18331 (Utils::Shader::STAGES)stage,
18335 testCase test_case_out = { gohan,
18337 (INTERPOLATIONS)int_gohan,
18338 (INTERPOLATIONS)int_goten,
18340 (Utils::Shader::STAGES)stage,
18346 * fragment shader when not flat double is used
18348 if ((Utils::Shader::VERTEX != stage) &&
18349 ((Utils::Shader::FRAGMENT != stage) || (true == is_comb_accepted_as_fs_in)))
18351 m_test_cases.push_back(test_case_in);
18354 /* Skip outputs in fragment shader */
18355 if (Utils::Shader::FRAGMENT != stage)
18357 m_test_cases.push_back(test_case_out);
18366 /** Get interpolation qualifier
18368 * @param interpolation Enumeration
18370 * @return GLSL qualifier
18372 const GLchar* VaryingLocationAliasingWithMixedInterpolationTest::getInterpolationQualifier(INTERPOLATIONS interpolation)
18374 const GLchar* result = 0;
18376 switch (interpolation)
18384 case NO_PERSPECTIVE:
18385 result = "noperspective";
18388 TCU_FAIL("Invalid enum");
18394 /** Check if given type is float
18396 * @param type Type in question
18398 * @return true if tpye is float, false otherwise
18400 bool VaryingLocationAliasingWithMixedInterpolationTest::isFloatType(const Utils::Type& type)
18402 bool is_float = false;
18404 if ((Utils::Type::Double == type.m_basic_type) || (Utils::Type::Float == type.m_basic_type))
18414 * @param context Test framework context
18416 VaryingLocationAliasingWithMixedAuxiliaryStorageTest::VaryingLocationAliasingWithMixedAuxiliaryStorageTest(
18417 deqp::Context& context)
18418 : NegativeTestBase(
18419 context, "varying_location_aliasing_with_mixed_auxiliary_storage",
18420 "Test verifies that compiler reports error when auxiliary storage qualifiers are mixed at one location")
18424 /** Source for given test case and stage
18426 * @param test_case_index Index of test case
18427 * @param stage Shader stage
18429 * @return Shader source
18431 std::string VaryingLocationAliasingWithMixedAuxiliaryStorageTest::getShaderSource(GLuint test_case_index,
18432 Utils::Shader::STAGES stage)
18434 static const GLchar* var_definition =
18435 "layout (location = 1, component = COMPONENT) AUX INTERPOLATION DIRECTION TYPE gohanARRAY;\n"
18436 "layout (location = 1, component = COMPONENT) AUX INTERPOLATION DIRECTION TYPE gotenARRAY;\n";
18437 static const GLchar* input_use = " if ((TYPE(0) == gohanINDEX_GOHAN) &&\n"
18438 " (TYPE(1) == gotenINDEX_GOTEN) )\n"
18440 " result += vec4(1, 0.5, 0.25, 0.125);\n"
18442 static const GLchar* output_use = " gohanINDEX_GOHAN = TYPE(0);\n"
18443 " gotenINDEX_GOTEN = TYPE(1);\n"
18444 " if (vec4(0) == result)\n"
18446 " gohanINDEX_GOHAN = TYPE(1);\n"
18447 " gotenINDEX_GOTEN = TYPE(0);\n"
18449 static const GLchar* fs = "#version 430 core\n"
18450 "#extension GL_ARB_enhanced_layouts : require\n"
18453 "out vec4 fs_out;\n"
18457 " fs_out = gs_fs;\n"
18460 static const GLchar* fs_tested = "#version 430 core\n"
18461 "#extension GL_ARB_enhanced_layouts : require\n"
18466 "out vec4 fs_out;\n"
18470 " vec4 result = gs_fs;\n"
18474 " fs_out = result;\n"
18477 static const GLchar* gs = "#version 430 core\n"
18478 "#extension GL_ARB_enhanced_layouts : require\n"
18480 "layout(points) in;\n"
18481 "layout(triangle_strip, max_vertices = 4) out;\n"
18483 "in vec4 tes_gs[];\n"
18484 "out vec4 gs_fs;\n"
18488 " gs_fs = tes_gs[0];\n"
18489 " gl_Position = vec4(-1, -1, 0, 1);\n"
18491 " gs_fs = tes_gs[0];\n"
18492 " gl_Position = vec4(-1, 1, 0, 1);\n"
18494 " gs_fs = tes_gs[0];\n"
18495 " gl_Position = vec4(1, -1, 0, 1);\n"
18497 " gs_fs = tes_gs[0];\n"
18498 " gl_Position = vec4(1, 1, 0, 1);\n"
18502 static const GLchar* gs_tested = "#version 430 core\n"
18503 "#extension GL_ARB_enhanced_layouts : require\n"
18505 "layout(points) in;\n"
18506 "layout(triangle_strip, max_vertices = 4) out;\n"
18510 "in vec4 tes_gs[];\n"
18511 "out vec4 gs_fs;\n"
18515 " vec4 result = tes_gs[0];\n"
18519 " gs_fs = result;\n"
18520 " gl_Position = vec4(-1, -1, 0, 1);\n"
18522 " gs_fs = result;\n"
18523 " gl_Position = vec4(-1, 1, 0, 1);\n"
18525 " gs_fs = result;\n"
18526 " gl_Position = vec4(1, -1, 0, 1);\n"
18528 " gs_fs = result;\n"
18529 " gl_Position = vec4(1, 1, 0, 1);\n"
18533 static const GLchar* tcs = "#version 430 core\n"
18534 "#extension GL_ARB_enhanced_layouts : require\n"
18536 "layout(vertices = 1) out;\n"
18538 "in vec4 vs_tcs[];\n"
18539 "out vec4 tcs_tes[];\n"
18544 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
18546 " gl_TessLevelOuter[0] = 1.0;\n"
18547 " gl_TessLevelOuter[1] = 1.0;\n"
18548 " gl_TessLevelOuter[2] = 1.0;\n"
18549 " gl_TessLevelOuter[3] = 1.0;\n"
18550 " gl_TessLevelInner[0] = 1.0;\n"
18551 " gl_TessLevelInner[1] = 1.0;\n"
18554 static const GLchar* tcs_tested = "#version 430 core\n"
18555 "#extension GL_ARB_enhanced_layouts : require\n"
18557 "layout(vertices = 1) out;\n"
18561 "in vec4 vs_tcs[];\n"
18562 "out vec4 tcs_tes[];\n"
18566 " vec4 result = vs_tcs[gl_InvocationID];\n"
18570 " tcs_tes[gl_InvocationID] = result;\n"
18572 " gl_TessLevelOuter[0] = 1.0;\n"
18573 " gl_TessLevelOuter[1] = 1.0;\n"
18574 " gl_TessLevelOuter[2] = 1.0;\n"
18575 " gl_TessLevelOuter[3] = 1.0;\n"
18576 " gl_TessLevelInner[0] = 1.0;\n"
18577 " gl_TessLevelInner[1] = 1.0;\n"
18580 static const GLchar* tes = "#version 430 core\n"
18581 "#extension GL_ARB_enhanced_layouts : require\n"
18583 "layout(isolines, point_mode) in;\n"
18585 "in vec4 tcs_tes[];\n"
18586 "out vec4 tes_gs;\n"
18590 " tes_gs = tcs_tes[0];\n"
18593 static const GLchar* tes_tested = "#version 430 core\n"
18594 "#extension GL_ARB_enhanced_layouts : require\n"
18596 "layout(isolines, point_mode) in;\n"
18600 "in vec4 tcs_tes[];\n"
18601 "out vec4 tes_gs;\n"
18605 " vec4 result = tcs_tes[0];\n"
18609 " tes_gs += result;\n"
18612 static const GLchar* vs = "#version 430 core\n"
18613 "#extension GL_ARB_enhanced_layouts : require\n"
18616 "out vec4 vs_tcs;\n"
18620 " vs_tcs = in_vs;\n"
18623 static const GLchar* vs_tested = "#version 430 core\n"
18624 "#extension GL_ARB_enhanced_layouts : require\n"
18629 "out vec4 vs_tcs;\n"
18633 " vec4 result = in_vs;\n"
18637 " vs_tcs += result;\n"
18641 std::string source;
18642 testCase& test_case = m_test_cases[test_case_index];
18644 if (test_case.m_stage == stage)
18646 const GLchar* array_gohan = "";
18647 const GLchar* array_goten = "";
18648 const GLchar* aux_gohan = getAuxiliaryQualifier(test_case.m_aux_gohan);
18649 const GLchar* aux_goten = getAuxiliaryQualifier(test_case.m_aux_goten);
18650 GLchar buffer_gohan[16];
18651 GLchar buffer_goten[16];
18652 const GLchar* direction = "in ";
18653 const GLchar* index_gohan = "";
18654 const GLchar* index_goten = "";
18655 const GLchar* int_gohan = test_case.m_int_gohan;
18656 const GLchar* int_goten = test_case.m_int_goten;
18657 size_t position = 0;
18659 const GLchar* type_gohan_name = test_case.m_type_gohan.GetGLSLTypeName();
18660 const GLchar* type_goten_name = test_case.m_type_goten.GetGLSLTypeName();
18661 const GLchar* var_use = input_use;
18663 if (false == test_case.m_is_input)
18667 var_use = output_use;
18670 sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
18671 sprintf(buffer_goten, "%d", test_case.m_component_goten);
18675 case Utils::Shader::FRAGMENT:
18676 source = fs_tested;
18678 case Utils::Shader::GEOMETRY:
18679 source = gs_tested;
18680 array_gohan = "[]";
18681 index_gohan = "[0]";
18682 array_goten = "[]";
18683 index_goten = "[0]";
18685 case Utils::Shader::TESS_CTRL:
18686 source = tcs_tested;
18687 if (PATCH != test_case.m_aux_gohan)
18689 array_gohan = "[]";
18690 index_gohan = "[gl_InvocationID]";
18692 if (PATCH != test_case.m_aux_goten)
18694 array_goten = "[]";
18695 index_goten = "[gl_InvocationID]";
18698 case Utils::Shader::TESS_EVAL:
18699 source = tes_tested;
18700 array_gohan = "[]";
18701 index_gohan = "[0]";
18702 array_goten = "[]";
18703 index_goten = "[0]";
18705 case Utils::Shader::VERTEX:
18706 source = vs_tested;
18709 TCU_FAIL("Invalid enum");
18713 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
18715 Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
18716 Utils::replaceToken("AUX", position, aux_gohan, source);
18717 Utils::replaceToken("INTERPOLATION", position, int_gohan, source);
18718 Utils::replaceToken("DIRECTION", position, direction, source);
18719 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18720 Utils::replaceToken("ARRAY", position, array_gohan, source);
18721 Utils::replaceToken("COMPONENT", position, buffer_goten, source);
18722 Utils::replaceToken("AUX", position, aux_goten, source);
18723 Utils::replaceToken("INTERPOLATION", position, int_goten, source);
18724 Utils::replaceToken("DIRECTION", position, direction, source);
18725 Utils::replaceToken("TYPE", position, type_goten_name, source);
18726 Utils::replaceToken("ARRAY", position, array_goten, source);
18729 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
18731 if (true == test_case.m_is_input)
18733 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18734 Utils::replaceToken("TYPE", position, type_goten_name, source);
18738 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18739 Utils::replaceToken("TYPE", position, type_goten_name, source);
18740 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18741 Utils::replaceToken("TYPE", position, type_goten_name, source);
18744 Utils::replaceAllTokens("INDEX_GOHAN", index_gohan, source);
18745 Utils::replaceAllTokens("INDEX_GOTEN", index_goten, source);
18751 case Utils::Shader::FRAGMENT:
18754 case Utils::Shader::GEOMETRY:
18757 case Utils::Shader::TESS_CTRL:
18760 case Utils::Shader::TESS_EVAL:
18763 case Utils::Shader::VERTEX:
18767 TCU_FAIL("Invalid enum");
18774 /** Get description of test case
18776 * @param test_case_index Index of test case
18778 * @return Test case description
18780 std::string VaryingLocationAliasingWithMixedAuxiliaryStorageTest::getTestCaseName(GLuint test_case_index)
18782 std::stringstream stream;
18783 testCase& test_case = m_test_cases[test_case_index];
18785 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", "
18786 << getAuxiliaryQualifier(test_case.m_aux_gohan) << " " << test_case.m_type_gohan.GetGLSLTypeName() << " at "
18787 << test_case.m_component_gohan << ", " << getAuxiliaryQualifier(test_case.m_aux_goten) << " "
18788 << test_case.m_type_goten.GetGLSLTypeName() << " at " << test_case.m_component_goten << ". Direction: ";
18790 if (true == test_case.m_is_input)
18796 stream << "output";
18799 return stream.str();
18802 /** Get number of test cases
18804 * @return Number of test cases
18806 GLuint VaryingLocationAliasingWithMixedAuxiliaryStorageTest::getTestCaseNumber()
18808 return static_cast<GLuint>(m_test_cases.size());
18811 /** Selects if "compute" stage is relevant for test
18817 bool VaryingLocationAliasingWithMixedAuxiliaryStorageTest::isComputeRelevant(GLuint /* test_case_index */)
18822 /** Prepare all test cases
18825 void VaryingLocationAliasingWithMixedAuxiliaryStorageTest::testInit()
18827 static const GLuint n_components_per_location = 4;
18828 const GLuint n_types = getTypesNumber();
18830 for (GLuint i = 0; i < n_types; ++i)
18832 const Utils::Type& type_gohan = getType(i);
18833 const bool is_float_type_gohan = isFloatType(type_gohan);
18835 /* Skip matrices */
18836 if (1 != type_gohan.m_n_columns)
18841 for (GLuint j = 0; j < n_types; ++j)
18843 const Utils::Type& type_goten = getType(j);
18844 const bool is_flat_req_gohan = (Utils::Type::Float == type_gohan.m_basic_type) ? false : true;
18845 const bool is_flat_req_goten = (Utils::Type::Float == type_goten.m_basic_type) ? false : true;
18846 const bool is_float_type_goten = isFloatType(type_goten);
18848 /* Skip matrices */
18849 if (1 != type_goten.m_n_columns)
18854 /* Skip invalid combinations */
18855 if (is_float_type_gohan != is_float_type_goten)
18860 const GLuint n_req_components_gohan = type_gohan.m_n_rows;
18861 const GLuint n_req_components_goten = type_goten.m_n_rows;
18863 /* Skip pairs that cannot fit into one location */
18864 if (n_components_per_location < (n_req_components_gohan + n_req_components_goten))
18869 const GLuint gohan = 0;
18870 const GLuint goten = gohan + n_req_components_gohan;
18872 const GLchar* fs_int_gohan = is_flat_req_gohan ? "flat" : "";
18873 const GLchar* fs_int_goten = is_flat_req_goten ? "flat" : "";
18875 testCase test_case_tcs_np = { gohan, goten, NONE, PATCH, "", "", false, Utils::Shader::TESS_CTRL,
18876 type_gohan, type_goten };
18878 testCase test_case_tcs_pn = { gohan, goten, PATCH, NONE, "", "", false, Utils::Shader::TESS_CTRL,
18879 type_gohan, type_goten };
18881 testCase test_case_tes_np = { gohan, goten, NONE, PATCH, "", "", true, Utils::Shader::TESS_EVAL,
18882 type_gohan, type_goten };
18884 testCase test_case_tes_pn = { gohan, goten, PATCH, NONE, "", "", true, Utils::Shader::TESS_EVAL,
18885 type_gohan, type_goten };
18887 testCase test_case_fs_nc = { gohan, goten, NONE, CENTROID,
18888 fs_int_gohan, fs_int_goten, true, Utils::Shader::FRAGMENT,
18889 type_gohan, type_goten };
18891 testCase test_case_fs_cn = { gohan, goten, CENTROID, NONE,
18892 fs_int_gohan, fs_int_goten, true, Utils::Shader::FRAGMENT,
18893 type_gohan, type_goten };
18895 testCase test_case_fs_ns = { gohan, goten, NONE, SAMPLE,
18896 fs_int_gohan, fs_int_goten, true, Utils::Shader::FRAGMENT,
18897 type_gohan, type_goten };
18899 testCase test_case_fs_sn = { gohan, goten, SAMPLE, NONE,
18900 fs_int_gohan, fs_int_goten, true, Utils::Shader::FRAGMENT,
18901 type_gohan, type_goten };
18903 testCase test_case_fs_cs = { gohan, goten, CENTROID, SAMPLE,
18904 fs_int_gohan, fs_int_goten, true, Utils::Shader::FRAGMENT,
18905 type_gohan, type_goten };
18907 testCase test_case_fs_sc = { gohan, goten, SAMPLE, CENTROID,
18908 fs_int_gohan, fs_int_goten, true, Utils::Shader::FRAGMENT,
18909 type_gohan, type_goten };
18911 m_test_cases.push_back(test_case_tcs_np);
18912 m_test_cases.push_back(test_case_tcs_pn);
18913 m_test_cases.push_back(test_case_tes_np);
18914 m_test_cases.push_back(test_case_tes_pn);
18915 m_test_cases.push_back(test_case_fs_nc);
18916 m_test_cases.push_back(test_case_fs_cn);
18917 m_test_cases.push_back(test_case_fs_ns);
18918 m_test_cases.push_back(test_case_fs_sn);
18919 m_test_cases.push_back(test_case_fs_cs);
18920 m_test_cases.push_back(test_case_fs_sc);
18925 /** Get auxiliary storage qualifier
18927 * @param aux Enumeration
18929 * @return GLSL qualifier
18931 const GLchar* VaryingLocationAliasingWithMixedAuxiliaryStorageTest::getAuxiliaryQualifier(AUXILIARIES aux)
18933 const GLchar* result = 0;
18944 result = "centroid";
18950 TCU_FAIL("Invalid enum");
18956 /** Check if given type is float
18958 * @param type Type in question
18960 * @return true if tpye is float, false otherwise
18962 bool VaryingLocationAliasingWithMixedAuxiliaryStorageTest::isFloatType(const Utils::Type& type)
18964 bool is_float = false;
18966 if ((Utils::Type::Double == type.m_basic_type) || (Utils::Type::Float == type.m_basic_type))
18974 /* Constants used by VertexAttribLocationAPITest */
18975 const GLuint VertexAttribLocationAPITest::m_goten_location = 6;
18979 * @param context Test framework context
18981 VertexAttribLocationAPITest::VertexAttribLocationAPITest(deqp::Context& context)
18982 : TextureTestBase(context, "vertex_attrib_location_api",
18983 "Test verifies that attribute locations API works as expected")
18987 /** Does BindAttribLocation for "goten" and relink program
18989 * @param program Program object
18990 * @param program_interface Interface of program
18992 void VertexAttribLocationAPITest::prepareAttribLocation(Utils::Program& program,
18993 Utils::ProgramInterface& program_interface)
18995 const Functions& gl = m_context.getRenderContext().getFunctions();
18997 gl.bindAttribLocation(program.m_id, m_goten_location, "goten");
18998 GLU_EXPECT_NO_ERROR(gl.getError(), "BindAttribLocation");
19000 program.Link(gl, program.m_id);
19002 /* We still need to get locations for gohan and chichi */
19003 TextureTestBase::prepareAttribLocation(program, program_interface);
19006 /** Get interface of program
19009 * @param program_interface Interface of program
19012 void VertexAttribLocationAPITest::getProgramInterface(GLuint /* test_case_index */,
19013 Utils::ProgramInterface& program_interface,
19014 Utils::VaryingPassthrough& /* varying_passthrough */)
19016 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
19017 const Utils::Type& type = Utils::Type::vec4;
19018 const GLuint type_size = type.GetSize();
19021 const GLuint chichi_offset = 0;
19022 const GLuint goten_offset = chichi_offset + type_size;
19023 const GLuint gohan_offset = goten_offset + type_size;
19024 const GLuint goku_offset = gohan_offset + type_size;
19027 const GLuint goku_location = 2;
19028 const GLuint goten_location = m_goten_location;
19030 /* Generate data */
19031 m_goku_data = type.GenerateDataPacked();
19032 m_gohan_data = type.GenerateDataPacked();
19033 m_goten_data = type.GenerateDataPacked();
19034 m_chichi_data = type.GenerateDataPacked();
19037 si.m_globals = "const uint GOKU_LOCATION = 2;\n";
19040 si.Input("goku" /* name */, "layout (location = GOKU_LOCATION)" /* qualifiers */, 0 /* expected_componenet */,
19041 goku_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19042 0u /* n_array_elements */, 0u /* stride */, goku_offset /* offset */, (GLvoid*)&m_goku_data[0] /* data */,
19043 m_goku_data.size() /* data_size */);
19045 si.Input("gohan" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19046 Utils::Variable::m_automatic_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19047 0u /* n_array_elements */, 0u /* stride */, gohan_offset /* offset */,
19048 (GLvoid*)&m_gohan_data[0] /* data */, m_gohan_data.size() /* data_size */);
19050 si.Input("goten" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19051 goten_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19052 0u /* n_array_elements */, 0u /* stride */, goten_offset /* offset */,
19053 (GLvoid*)&m_goten_data[0] /* data */, m_goten_data.size() /* data_size */);
19055 si.Input("chichi" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19056 Utils::Variable::m_automatic_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19057 0u /* n_array_elements */, 0u /* stride */, chichi_offset /* offset */,
19058 (GLvoid*)&m_chichi_data[0] /* data */, m_chichi_data.size() /* data_size */);
19061 /** Selects if "compute" stage is relevant for test
19067 bool VertexAttribLocationAPITest::isComputeRelevant(GLuint /* test_case_index */)
19072 /* Constants used by FragmentDataLocationAPITest */
19073 const GLuint FragmentDataLocationAPITest::m_goten_location = 6;
19077 * @param context Test framework context
19079 FragmentDataLocationAPITest::FragmentDataLocationAPITest(deqp::Context& context)
19080 : TextureTestBase(context, "fragment_data_location_api",
19081 "Test verifies that fragment data locations API works as expected")
19085 , m_chichi(context)
19089 /** Verifies contents of drawn images
19094 * @return true if images are filled with expected values, false otherwise
19096 bool FragmentDataLocationAPITest::checkResults(glw::GLuint /* test_case_index */, Utils::Texture& /* color_0 */)
19098 static const GLuint size = m_width * m_height;
19099 static const GLuint expected_goku = 0xff000000;
19100 static const GLuint expected_gohan = 0xff0000ff;
19101 static const GLuint expected_goten = 0xff00ff00;
19102 static const GLuint expected_chichi = 0xffff0000;
19104 std::vector<GLuint> data;
19107 m_goku.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_goku != color)
19115 m_context.getTestContext().getLog() << tcu::TestLog::Message << "RGBA8[" << i << "]:" << color
19116 << tcu::TestLog::EndMessage;
19121 m_gohan.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_gohan != color)
19129 m_context.getTestContext().getLog() << tcu::TestLog::Message << "RGBA8[" << i << "]:" << color
19130 << tcu::TestLog::EndMessage;
19135 m_goten.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_goten != color)
19143 m_context.getTestContext().getLog() << tcu::TestLog::Message << "RGBA8[" << i << "]:" << color
19144 << tcu::TestLog::EndMessage;
19149 m_chichi.Get(GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
19151 for (GLuint i = 0; i < size; ++i)
19153 const GLuint color = data[i];
19155 if (expected_chichi != color)
19157 m_context.getTestContext().getLog() << tcu::TestLog::Message << "RGBA8[" << i << "]:" << color
19158 << tcu::TestLog::EndMessage;
19166 /** Prepare code snippet that will set out variables
19170 * @param stage Shader stage
19172 * @return Code that pass in variables to next stage
19174 std::string FragmentDataLocationAPITest::getPassSnippet(GLuint /* test_case_index */,
19175 Utils::VaryingPassthrough& /* varying_passthrough */,
19176 Utils::Shader::STAGES stage)
19178 std::string result;
19180 /* Skip for compute shader */
19181 if (Utils::Shader::FRAGMENT != stage)
19187 result = "chichi = vec4(0, 0, 1, 1);\n"
19188 " goku = vec4(0, 0, 0, 1);\n"
19189 " goten = vec4(0, 1, 0, 1);\n"
19190 " gohan = vec4(1, 0, 0, 1);\n";
19196 /** Get interface of program
19199 * @param program_interface Interface of program
19202 void FragmentDataLocationAPITest::getProgramInterface(GLuint /* test_case_index */,
19203 Utils::ProgramInterface& program_interface,
19204 Utils::VaryingPassthrough& /* varying_passthrough */)
19206 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
19207 const Utils::Type& type = Utils::Type::vec4;
19210 m_goku_location = 2;
19213 si.m_globals = "const uint GOKU_LOCATION = 2;\n";
19216 si.Output("goku" /* name */, "layout (location = GOKU_LOCATION)" /* qualifiers */, 0 /* expected_componenet */,
19217 m_goku_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19218 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)0 /* data */, 0u /* data_size */);
19220 si.Output("gohan" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19221 Utils::Variable::m_automatic_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19222 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)0 /* data */, 0u /* data_size */);
19224 si.Output("goten" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19225 m_goten_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19226 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)0 /* data */, 0u /* data_size */);
19228 si.Output("chichi" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19229 Utils::Variable::m_automatic_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19230 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)0 /* data */, 0u /* data_size */);
19233 /** Selects if "compute" stage is relevant for test
19239 bool FragmentDataLocationAPITest::isComputeRelevant(GLuint /* test_case_index */)
19244 /** Get locations for all outputs with automatic_location
19246 * @param program Program object
19247 * @param program_interface Interface of program
19249 void FragmentDataLocationAPITest::prepareFragmentDataLoc(Utils::Program& program,
19250 Utils::ProgramInterface& program_interface)
19252 /* Bind location of goten */
19253 const Functions& gl = m_context.getRenderContext().getFunctions();
19255 gl.bindFragDataLocation(program.m_id, m_goten_location, "goten");
19256 GLU_EXPECT_NO_ERROR(gl.getError(), "BindFragDataLocation");
19258 program.Link(gl, program.m_id);
19260 /* Prepare locations for gohan and chichi */
19261 TextureTestBase::prepareFragmentDataLoc(program, program_interface);
19263 /* Get all locations */
19264 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
19266 Utils::Variable::PtrVector& outputs = si.m_outputs;
19268 for (Utils::Variable::PtrVector::iterator it = outputs.begin(); outputs.end() != it; ++it)
19270 const Utils::Variable::Descriptor& desc = (*it)->m_descriptor;
19272 if (0 == desc.m_name.compare("gohan"))
19274 m_gohan_location = desc.m_expected_location;
19276 else if (0 == desc.m_name.compare("chichi"))
19278 m_chichi_location = desc.m_expected_location;
19281 /* Locations of goku and goten are fixed */
19285 /** Prepare framebuffer with single texture as color attachment
19287 * @param framebuffer Framebuffer
19288 * @param color_0_texture Texture that will used as color attachment
19290 void FragmentDataLocationAPITest::prepareFramebuffer(Utils::Framebuffer& framebuffer, Utils::Texture& color_0_texture)
19292 /* Let parent prepare its stuff */
19293 TextureTestBase::prepareFramebuffer(framebuffer, color_0_texture);
19296 std::vector<GLuint> texture_data;
19297 texture_data.resize(m_width * m_height);
19299 for (GLuint i = 0; i < texture_data.size(); ++i)
19301 texture_data[i] = 0x20406080;
19304 /* Prepare textures */
19305 m_goku.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]);
19307 m_gohan.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]);
19309 m_goten.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]);
19311 m_chichi.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]);
19313 /* Attach textures to framebuffer */
19314 framebuffer.Bind();
19315 framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0 + m_goku_location, m_goku.m_id, m_width, m_height);
19316 framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0 + m_gohan_location, m_gohan.m_id, m_width, m_height);
19317 framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0 + m_goten_location, m_goten.m_id, m_width, m_height);
19318 framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0 + m_chichi_location, m_chichi.m_id, m_width, m_height);
19320 /* Set up drawbuffers */
19321 const Functions& gl = m_context.getRenderContext().getFunctions();
19322 // 1. There are only 4 outputs in fragment shader, so only need to do buffer mapping for 4 attachments,
19323 // 2. another issue is each output variable has a location, it is the fragment color index, so the index of
19324 // GL_COLOR_ATTACHMENT in glDrawBuffers() should keep the same with the location, to make test correct,
19325 // we needt to change the above code of glDrawBuffers() as :
19326 GLint buffers_size = 4;
19327 GLenum buffers[] = { GLenum(GL_COLOR_ATTACHMENT0 + m_chichi_location),
19328 GLenum(GL_COLOR_ATTACHMENT0 + m_goku_location),
19329 GLenum(GL_COLOR_ATTACHMENT0 + m_goten_location),
19330 GLenum(GL_COLOR_ATTACHMENT0 + m_gohan_location) };
19331 gl.drawBuffers(buffers_size, buffers);
19332 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawBuffers");
19337 * @param context Test framework context
19339 XFBInputTest::XFBInputTest(deqp::Context& context)
19340 : NegativeTestBase(context, "xfb_input",
19341 "Test verifies that compiler reports error when xfb qualifiers are used with input")
19345 /** Source for given test case and stage
19347 * @param test_case_index Index of test case
19348 * @param stage Shader stage
19350 * @return Shader source
19352 std::string XFBInputTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
19354 static const GLchar* buffer_var_definition = "layout (xfb_buffer = 2) in vec4 gohanARRAY;\n";
19355 static const GLchar* offset_var_definition = "layout (xfb_offset = 16) in vec4 gohanARRAY;\n";
19356 static const GLchar* stride_var_definition = "layout (xfb_stride = 32) in vec4 gohanARRAY;\n";
19357 static const GLchar* input_use = " result += gohanINDEX;\n";
19358 static const GLchar* fs = "#version 430 core\n"
19359 "#extension GL_ARB_enhanced_layouts : require\n"
19362 "out vec4 fs_out;\n"
19366 " fs_out = gs_fs;\n"
19369 static const GLchar* fs_tested = "#version 430 core\n"
19370 "#extension GL_ARB_enhanced_layouts : require\n"
19375 "out vec4 fs_out;\n"
19379 " vec4 result = gs_fs;\n"
19383 " fs_out = result;\n"
19386 static const GLchar* gs = "#version 430 core\n"
19387 "#extension GL_ARB_enhanced_layouts : require\n"
19389 "layout(points) in;\n"
19390 "layout(triangle_strip, max_vertices = 4) out;\n"
19392 "in vec4 tes_gs[];\n"
19393 "out vec4 gs_fs;\n"
19397 " gs_fs = tes_gs[0];\n"
19398 " gl_Position = vec4(-1, -1, 0, 1);\n"
19400 " gs_fs = tes_gs[0];\n"
19401 " gl_Position = vec4(-1, 1, 0, 1);\n"
19403 " gs_fs = tes_gs[0];\n"
19404 " gl_Position = vec4(1, -1, 0, 1);\n"
19406 " gs_fs = tes_gs[0];\n"
19407 " gl_Position = vec4(1, 1, 0, 1);\n"
19411 static const GLchar* gs_tested = "#version 430 core\n"
19412 "#extension GL_ARB_enhanced_layouts : require\n"
19414 "layout(points) in;\n"
19415 "layout(triangle_strip, max_vertices = 4) out;\n"
19419 "in vec4 tes_gs[];\n"
19420 "out vec4 gs_fs;\n"
19424 " vec4 result = tes_gs[0];\n"
19428 " gs_fs = result;\n"
19429 " gl_Position = vec4(-1, -1, 0, 1);\n"
19431 " gs_fs = result;\n"
19432 " gl_Position = vec4(-1, 1, 0, 1);\n"
19434 " gs_fs = result;\n"
19435 " gl_Position = vec4(1, -1, 0, 1);\n"
19437 " gs_fs = result;\n"
19438 " gl_Position = vec4(1, 1, 0, 1);\n"
19442 static const GLchar* tcs = "#version 430 core\n"
19443 "#extension GL_ARB_enhanced_layouts : require\n"
19445 "layout(vertices = 1) out;\n"
19447 "in vec4 vs_tcs[];\n"
19448 "out vec4 tcs_tes[];\n"
19453 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
19455 " gl_TessLevelOuter[0] = 1.0;\n"
19456 " gl_TessLevelOuter[1] = 1.0;\n"
19457 " gl_TessLevelOuter[2] = 1.0;\n"
19458 " gl_TessLevelOuter[3] = 1.0;\n"
19459 " gl_TessLevelInner[0] = 1.0;\n"
19460 " gl_TessLevelInner[1] = 1.0;\n"
19463 static const GLchar* tcs_tested = "#version 430 core\n"
19464 "#extension GL_ARB_enhanced_layouts : require\n"
19466 "layout(vertices = 1) out;\n"
19470 "in vec4 vs_tcs[];\n"
19471 "out vec4 tcs_tes[];\n"
19475 " vec4 result = vs_tcs[gl_InvocationID];\n"
19479 " tcs_tes[gl_InvocationID] = result;\n"
19481 " gl_TessLevelOuter[0] = 1.0;\n"
19482 " gl_TessLevelOuter[1] = 1.0;\n"
19483 " gl_TessLevelOuter[2] = 1.0;\n"
19484 " gl_TessLevelOuter[3] = 1.0;\n"
19485 " gl_TessLevelInner[0] = 1.0;\n"
19486 " gl_TessLevelInner[1] = 1.0;\n"
19489 static const GLchar* tes = "#version 430 core\n"
19490 "#extension GL_ARB_enhanced_layouts : require\n"
19492 "layout(isolines, point_mode) in;\n"
19494 "in vec4 tcs_tes[];\n"
19495 "out vec4 tes_gs;\n"
19499 " tes_gs = tcs_tes[0];\n"
19502 static const GLchar* tes_tested = "#version 430 core\n"
19503 "#extension GL_ARB_enhanced_layouts : require\n"
19505 "layout(isolines, point_mode) in;\n"
19509 "in vec4 tcs_tes[];\n"
19510 "out vec4 tes_gs;\n"
19514 " vec4 result = tcs_tes[0];\n"
19518 " tes_gs += result;\n"
19521 static const GLchar* vs = "#version 430 core\n"
19522 "#extension GL_ARB_enhanced_layouts : require\n"
19525 "out vec4 vs_tcs;\n"
19529 " vs_tcs = in_vs;\n"
19532 static const GLchar* vs_tested = "#version 430 core\n"
19533 "#extension GL_ARB_enhanced_layouts : require\n"
19538 "out vec4 vs_tcs;\n"
19542 " vec4 result = in_vs;\n"
19546 " vs_tcs += result;\n"
19550 std::string source;
19551 testCase& test_case = m_test_cases[test_case_index];
19553 if (test_case.m_stage == stage)
19555 const GLchar* array = "";
19556 const GLchar* index = "";
19557 size_t position = 0;
19559 const GLchar* var_definition = 0;
19560 const GLchar* var_use = input_use;
19562 switch (test_case.m_qualifier)
19565 var_definition = buffer_var_definition;
19568 var_definition = offset_var_definition;
19571 var_definition = stride_var_definition;
19574 TCU_FAIL("Invalid enum");
19579 case Utils::Shader::FRAGMENT:
19580 source = fs_tested;
19582 case Utils::Shader::GEOMETRY:
19583 source = gs_tested;
19587 case Utils::Shader::TESS_CTRL:
19588 source = tcs_tested;
19590 index = "[gl_InvocationID]";
19592 case Utils::Shader::TESS_EVAL:
19593 source = tes_tested;
19597 case Utils::Shader::VERTEX:
19598 source = vs_tested;
19601 TCU_FAIL("Invalid enum");
19605 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
19607 Utils::replaceToken("ARRAY", position, array, source);
19608 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
19610 Utils::replaceAllTokens("INDEX", index, source);
19616 case Utils::Shader::FRAGMENT:
19619 case Utils::Shader::GEOMETRY:
19622 case Utils::Shader::TESS_CTRL:
19625 case Utils::Shader::TESS_EVAL:
19628 case Utils::Shader::VERTEX:
19632 TCU_FAIL("Invalid enum");
19639 /** Get description of test case
19641 * @param test_case_index Index of test case
19643 * @return Test case description
19645 std::string XFBInputTest::getTestCaseName(GLuint test_case_index)
19647 std::stringstream stream;
19648 testCase& test_case = m_test_cases[test_case_index];
19650 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", qualifier: ";
19652 switch (test_case.m_qualifier)
19655 stream << "xfb_buffer";
19658 stream << "xfb_offset";
19661 stream << "xfb_stride";
19664 TCU_FAIL("Invalid enum");
19667 return stream.str();
19670 /** Get number of test cases
19672 * @return Number of test cases
19674 GLuint XFBInputTest::getTestCaseNumber()
19676 return static_cast<GLuint>(m_test_cases.size());
19679 /** Selects if "compute" stage is relevant for test
19685 bool XFBInputTest::isComputeRelevant(GLuint /* test_case_index */)
19690 /** Prepare all test cases
19693 void XFBInputTest::testInit()
19695 for (GLuint qualifier = 0; qualifier < QUALIFIERS_MAX; ++qualifier)
19697 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
19699 if (Utils::Shader::COMPUTE == stage)
19704 testCase test_case = { (QUALIFIERS)qualifier, (Utils::Shader::STAGES)stage };
19706 m_test_cases.push_back(test_case);
19711 /* Constants used by XFBAllStagesTest */
19712 const GLuint XFBAllStagesTest::m_gs_index = 3;
19716 * @param context Test context
19718 XFBAllStagesTest::XFBAllStagesTest(deqp::Context& context)
19719 : BufferTestBase(context, "xfb_all_stages",
19720 "Test verifies that only last stage in vertex processing can output to transform feedback")
19722 /* Nothing to be done here */
19725 /** Get descriptors of buffers necessary for test
19728 * @param out_descriptors Descriptors of buffers used by test
19730 void XFBAllStagesTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
19731 bufferDescriptor::Vector& out_descriptors)
19733 static const GLuint n_stages = 4;
19734 const Utils::Type& vec4 = Utils::Type::vec4;
19739 /* Test uses single uniform and xfb per stage + uniform for fragment shader */
19740 out_descriptors.resize(n_stages * 2 + 1);
19743 for (GLuint i = 0; i < n_stages; ++i)
19745 /* Get references */
19746 bufferDescriptor& uniform = out_descriptors[i + 0];
19747 bufferDescriptor& xfb = out_descriptors[i + n_stages];
19750 uniform.m_index = i;
19754 uniform.m_target = Utils::Buffer::Uniform;
19755 xfb.m_target = Utils::Buffer::Transform_feedback;
19758 const tcu::Vec4 var(Utils::GetRandFloat(), Utils::GetRandFloat(), Utils::GetRandFloat(), Utils::GetRandFloat());
19762 uniform.m_initial_data.resize(vec4.GetSize());
19763 memcpy(&uniform.m_initial_data[0], var.getPtr(), vec4.GetSize());
19765 xfb.m_initial_data = vec4.GenerateDataPacked();
19767 if (m_gs_index != i)
19769 xfb.m_expected_data = xfb.m_initial_data;
19773 xfb.m_expected_data.resize(vec4.GetSize());
19774 memcpy(&xfb.m_expected_data[0], sum.getPtr(), vec4.GetSize());
19780 /* Get reference */
19781 bufferDescriptor& uniform = out_descriptors[n_stages * 2];
19784 uniform.m_index = n_stages;
19787 uniform.m_target = Utils::Buffer::Uniform;
19790 const tcu::Vec4 var(Utils::GetRandFloat(), Utils::GetRandFloat(), Utils::GetRandFloat(), Utils::GetRandFloat());
19792 uniform.m_initial_data.resize(vec4.GetSize());
19793 memcpy(&uniform.m_initial_data[0], var.getPtr(), vec4.GetSize());
19797 /** Get body of main function for given shader stage
19800 * @param stage Shader stage
19801 * @param out_assignments Set to empty
19802 * @param out_calculations Set to empty
19804 void XFBAllStagesTest::getShaderBody(glw::GLuint /* test_case_index */, Utils::Shader::STAGES stage,
19805 std::string& out_assignments, std::string& out_calculations)
19807 out_calculations = "";
19809 static const GLchar* vs = " vs_tcs = uni_vs;\n";
19810 static const GLchar* tcs = " tcs_tes[gl_InvocationID] = uni_tcs + vs_tcs[gl_InvocationID];\n";
19811 static const GLchar* tes = " tes_gs = uni_tes + tcs_tes[0];\n";
19812 static const GLchar* gs = " gs_fs = uni_gs + tes_gs[0];\n";
19813 static const GLchar* fs = " fs_out = uni_fs + gs_fs;\n";
19815 const GLchar* assignments = 0;
19818 case Utils::Shader::FRAGMENT:
19821 case Utils::Shader::GEOMETRY:
19824 case Utils::Shader::TESS_CTRL:
19827 case Utils::Shader::TESS_EVAL:
19830 case Utils::Shader::VERTEX:
19834 TCU_FAIL("Invalid enum");
19837 out_assignments = assignments;
19840 /** Get interface of shader
19843 * @param stage Shader stage
19844 * @param out_interface Set to ""
19846 void XFBAllStagesTest::getShaderInterface(glw::GLuint /* test_case_index */, Utils::Shader::STAGES stage,
19847 std::string& out_interface)
19849 static const GLchar* vs = "layout(xfb_buffer = 0, xfb_offset = 0) out vec4 vs_tcs;\n"
19850 "layout(binding = 0) uniform vs_block {\n"
19853 static const GLchar* tcs = " in vec4 vs_tcs[];\n"
19854 "layout(xfb_buffer = 1, xfb_offset = 0) out vec4 tcs_tes[1];\n"
19855 "layout(binding = 1) uniform tcs_block {\n"
19858 static const GLchar* tes = " in vec4 tcs_tes[];\n"
19859 "layout(xfb_buffer = 2, xfb_offset = 0) out vec4 tes_gs;\n"
19860 "layout(binding = 2) uniform tes_block {\n"
19863 static const GLchar* gs = " in vec4 tes_gs[];\n"
19864 "layout(xfb_buffer = 3, xfb_offset = 0) out vec4 gs_fs;\n"
19865 "layout(binding = 3) uniform gs_block {\n"
19868 static const GLchar* fs = " in vec4 gs_fs;\n"
19869 " out vec4 fs_out;\n"
19870 "layout(binding = 4) uniform fs_block {\n"
19874 const GLchar* interface = 0;
19877 case Utils::Shader::FRAGMENT:
19880 case Utils::Shader::GEOMETRY:
19883 case Utils::Shader::TESS_CTRL:
19886 case Utils::Shader::TESS_EVAL:
19889 case Utils::Shader::VERTEX:
19893 TCU_FAIL("Invalid enum");
19896 out_interface = interface;
19899 /* Constants used by XFBStrideOfEmptyListTest */
19900 const GLuint XFBStrideOfEmptyListTest::m_stride = 64;
19904 * @param context Test context
19906 XFBStrideOfEmptyListTest::XFBStrideOfEmptyListTest(deqp::Context& context)
19907 : BufferTestBase(context, "xfb_stride_of_empty_list",
19908 "Test verifies that xfb_stride qualifier is respected when no xfb_offset is specified")
19910 /* Nothing to be done here */
19913 /** Execute drawArrays for single vertex
19915 * @param test_case_index Index of test case
19917 * @return true if proper error is reported
19919 bool XFBStrideOfEmptyListTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
19921 const Functions& gl = m_context.getRenderContext().getFunctions();
19922 bool result = true;
19925 gl.disable(GL_RASTERIZER_DISCARD);
19926 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
19928 gl.beginTransformFeedback(GL_POINTS);
19929 GLenum error = gl.getError();
19930 switch (test_case_index)
19933 if (GL_NO_ERROR != error)
19935 gl.endTransformFeedback();
19936 GLU_EXPECT_NO_ERROR(error, "BeginTransformFeedback");
19939 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
19940 error = gl.getError();
19942 gl.endTransformFeedback();
19943 GLU_EXPECT_NO_ERROR(error, "DrawArrays");
19944 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
19948 case FIRST_MISSING:
19949 if (GL_NO_ERROR == error)
19951 gl.endTransformFeedback();
19954 if (GL_INVALID_OPERATION != error)
19956 m_context.getTestContext().getLog()
19957 << tcu::TestLog::Message << "XFB at index 0, that is written by GS, is missing. It was expected that "
19958 "INVALID_OPERATION will generated by BeginTransformFeedback. Got: "
19959 << glu::getErrorStr(error) << tcu::TestLog::EndMessage;
19966 case SECOND_MISSING:
19967 if (GL_NO_ERROR == error)
19969 gl.endTransformFeedback();
19972 if (GL_INVALID_OPERATION != error)
19974 m_context.getTestContext().getLog()
19975 << tcu::TestLog::Message << "XFB at index 1, that is declared as empty, is missing. It was expected "
19976 "that INVALID_OPERATION will generated by BeginTransformFeedback. Got: "
19977 << glu::getErrorStr(error) << tcu::TestLog::EndMessage;
19989 /** Get descriptors of buffers necessary for test
19991 * @param test_case_index Index of test case
19992 * @param out_descriptors Descriptors of buffers used by test
19994 void XFBStrideOfEmptyListTest::getBufferDescriptors(glw::GLuint test_case_index,
19995 bufferDescriptor::Vector& out_descriptors)
19997 switch (test_case_index)
20001 /* Test needs single uniform and two xfbs */
20002 out_descriptors.resize(3);
20004 /* Get references */
20005 bufferDescriptor& uniform = out_descriptors[0];
20006 bufferDescriptor& xfb_0 = out_descriptors[1];
20007 bufferDescriptor& xfb_1 = out_descriptors[2];
20010 uniform.m_index = 0;
20015 uniform.m_target = Utils::Buffer::Uniform;
20016 xfb_0.m_target = Utils::Buffer::Transform_feedback;
20017 xfb_1.m_target = Utils::Buffer::Transform_feedback;
20020 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20022 xfb_0.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20023 xfb_0.m_expected_data = uniform.m_initial_data;
20025 /* Data, contents are the same as no modification is expected */
20026 xfb_1.m_initial_data.resize(m_stride);
20027 xfb_1.m_expected_data.resize(m_stride);
20029 for (GLuint i = 0; i < m_stride; ++i)
20031 xfb_1.m_initial_data[0] = (glw::GLubyte)i;
20032 xfb_1.m_expected_data[0] = (glw::GLubyte)i;
20038 case FIRST_MISSING:
20040 /* Test needs single uniform and two xfbs */
20041 out_descriptors.resize(2);
20043 /* Get references */
20044 bufferDescriptor& uniform = out_descriptors[0];
20045 bufferDescriptor& xfb_1 = out_descriptors[1];
20048 uniform.m_index = 0;
20052 uniform.m_target = Utils::Buffer::Uniform;
20053 xfb_1.m_target = Utils::Buffer::Transform_feedback;
20056 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20058 /* Draw call will not be executed, contents does not matter */
20059 xfb_1.m_initial_data.resize(m_stride);
20064 case SECOND_MISSING:
20066 /* Test needs single uniform and two xfbs */
20067 out_descriptors.resize(2);
20069 /* Get references */
20070 bufferDescriptor& uniform = out_descriptors[0];
20071 bufferDescriptor& xfb_0 = out_descriptors[1];
20074 uniform.m_index = 0;
20078 uniform.m_target = Utils::Buffer::Uniform;
20079 xfb_0.m_target = Utils::Buffer::Transform_feedback;
20082 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20084 /* Draw call will not be executed, contents does not matter */
20085 xfb_0.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20092 /** Get body of main function for given shader stage
20095 * @param stage Shader stage
20096 * @param out_assignments Set to empty
20097 * @param out_calculations Set to empty
20099 void XFBStrideOfEmptyListTest::getShaderBody(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
20100 std::string& out_assignments, std::string& out_calculations)
20102 out_calculations = "";
20104 static const GLchar* gs = " gs_fs = uni_gs;\n";
20105 static const GLchar* fs = " fs_out = vec4(gs_fs);\n";
20107 const GLchar* assignments = "";
20110 case Utils::Shader::FRAGMENT:
20113 case Utils::Shader::GEOMETRY:
20120 out_assignments = assignments;
20123 /** Get interface of shader
20126 * @param stage Shader stage
20127 * @param out_interface Set to ""
20129 void XFBStrideOfEmptyListTest::getShaderInterface(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
20130 std::string& out_interface)
20132 static const GLchar* gs = "layout (xfb_buffer = 0, xfb_offset = 0) out vec4 gs_fs;\n"
20133 "layout (xfb_buffer = 1, xfb_stride = 64) out;\n"
20135 "layout (binding = 0) uniform gs_block {\n"
20138 static const GLchar* fs = "in vec4 gs_fs;\n"
20139 "out vec4 fs_out;\n";
20143 case Utils::Shader::FRAGMENT:
20144 out_interface = fs;
20146 case Utils::Shader::GEOMETRY:
20147 out_interface = gs;
20150 out_interface = "";
20155 /** Returns buffer details in human readable form.
20157 * @param test_case_index Index of test case
20159 * @return Case description
20161 std::string XFBStrideOfEmptyListTest::getTestCaseName(GLuint test_case_index)
20163 std::string result;
20165 switch (test_case_index)
20168 result = "Valid case";
20170 case FIRST_MISSING:
20171 result = "Missing xfb at index 0";
20173 case SECOND_MISSING:
20174 result = "Missing xfb at index 1";
20177 TCU_FAIL("Invalid enum");
20183 /** Get number of test cases
20187 GLuint XFBStrideOfEmptyListTest::getTestCaseNumber()
20192 /* Constants used by XFBStrideOfEmptyListTest */
20193 const GLuint XFBStrideOfEmptyListAndAPITest::m_stride = 64;
20197 * @param context Test context
20199 XFBStrideOfEmptyListAndAPITest::XFBStrideOfEmptyListAndAPITest(deqp::Context& context)
20200 : BufferTestBase(context, "xfb_stride_of_empty_list_and_api",
20201 "Test verifies that xfb_stride qualifier is not overriden by API")
20203 /* Nothing to be done here */
20206 /** Execute drawArrays for single vertex
20208 * @param test_case_index Index of test case
20210 * @return true if proper error is reported
20212 bool XFBStrideOfEmptyListAndAPITest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
20214 const Functions& gl = m_context.getRenderContext().getFunctions();
20215 bool result = true;
20218 gl.disable(GL_RASTERIZER_DISCARD);
20219 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
20221 gl.beginTransformFeedback(GL_POINTS);
20222 GLenum error = gl.getError();
20223 switch (test_case_index)
20226 if (GL_NO_ERROR != error)
20228 gl.endTransformFeedback();
20229 GLU_EXPECT_NO_ERROR(error, "BeginTransformFeedback");
20232 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
20233 error = gl.getError();
20235 gl.endTransformFeedback();
20236 GLU_EXPECT_NO_ERROR(error, "DrawArrays");
20237 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
20241 case FIRST_MISSING:
20242 if (GL_NO_ERROR == error)
20244 gl.endTransformFeedback();
20247 if (GL_INVALID_OPERATION != error)
20249 m_context.getTestContext().getLog()
20250 << tcu::TestLog::Message << "XFB at index 0, that is declared as empty, is missing. It was expected "
20251 "that INVALID_OPERATION will generated by BeginTransformFeedback. Got: "
20252 << glu::getErrorStr(error) << tcu::TestLog::EndMessage;
20259 case SECOND_MISSING:
20260 if (GL_NO_ERROR == error)
20262 gl.endTransformFeedback();
20265 if (GL_INVALID_OPERATION != error)
20267 m_context.getTestContext().getLog()
20268 << tcu::TestLog::Message << "XFB at index 1, that is written by GS, is missing. It was expected that "
20269 "INVALID_OPERATION will generated by BeginTransformFeedback. Got: "
20270 << glu::getErrorStr(error) << tcu::TestLog::EndMessage;
20282 /** Get descriptors of buffers necessary for test
20284 * @param test_case_index Index of test case
20285 * @param out_descriptors Descriptors of buffers used by test
20287 void XFBStrideOfEmptyListAndAPITest::getBufferDescriptors(glw::GLuint test_case_index,
20288 bufferDescriptor::Vector& out_descriptors)
20290 switch (test_case_index)
20294 /* Test needs single uniform and two xfbs */
20295 out_descriptors.resize(3);
20297 /* Get references */
20298 bufferDescriptor& uniform = out_descriptors[0];
20299 bufferDescriptor& xfb_0 = out_descriptors[1];
20300 bufferDescriptor& xfb_1 = out_descriptors[2];
20303 uniform.m_index = 0;
20308 uniform.m_target = Utils::Buffer::Uniform;
20309 xfb_0.m_target = Utils::Buffer::Transform_feedback;
20310 xfb_1.m_target = Utils::Buffer::Transform_feedback;
20313 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20315 /* Data, contents are the same as no modification is expected */
20316 xfb_0.m_initial_data.resize(m_stride);
20317 xfb_0.m_expected_data.resize(m_stride);
20319 for (GLuint i = 0; i < m_stride; ++i)
20321 xfb_0.m_initial_data[0] = (glw::GLubyte)i;
20322 xfb_0.m_expected_data[0] = (glw::GLubyte)i;
20325 xfb_1.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20326 xfb_1.m_expected_data = uniform.m_initial_data;
20331 case FIRST_MISSING:
20333 /* Test needs single uniform and two xfbs */
20334 out_descriptors.resize(2);
20336 /* Get references */
20337 bufferDescriptor& uniform = out_descriptors[0];
20338 bufferDescriptor& xfb_1 = out_descriptors[1];
20341 uniform.m_index = 0;
20345 uniform.m_target = Utils::Buffer::Uniform;
20346 xfb_1.m_target = Utils::Buffer::Transform_feedback;
20349 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20351 /* Draw call will not be executed, contents does not matter */
20352 xfb_1.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20357 case SECOND_MISSING:
20359 /* Test needs single uniform and two xfbs */
20360 out_descriptors.resize(2);
20362 /* Get references */
20363 bufferDescriptor& uniform = out_descriptors[0];
20364 bufferDescriptor& xfb_0 = out_descriptors[1];
20367 uniform.m_index = 0;
20371 uniform.m_target = Utils::Buffer::Uniform;
20372 xfb_0.m_target = Utils::Buffer::Transform_feedback;
20375 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20377 /* Draw call will not be executed, contents does not matter */
20378 xfb_0.m_initial_data.resize(m_stride);
20385 /** Get list of names of varyings that will be registered with TransformFeedbackVaryings
20388 * @param captured_varyings Vector of varying names to be captured
20390 void XFBStrideOfEmptyListAndAPITest::getCapturedVaryings(glw::GLuint /* test_case_index */,
20391 Utils::Program::NameVector& captured_varyings)
20393 captured_varyings.push_back("gs_fs");
20396 /** Get body of main function for given shader stage
20399 * @param stage Shader stage
20400 * @param out_assignments Set to empty
20401 * @param out_calculations Set to empty
20403 void XFBStrideOfEmptyListAndAPITest::getShaderBody(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
20404 std::string& out_assignments, std::string& out_calculations)
20406 out_calculations = "";
20408 static const GLchar* gs = " gs_fs = uni_gs;\n";
20409 static const GLchar* fs = " fs_out = vec4(gs_fs);\n";
20411 const GLchar* assignments = "";
20414 case Utils::Shader::FRAGMENT:
20417 case Utils::Shader::GEOMETRY:
20424 out_assignments = assignments;
20427 /** Get interface of shader
20430 * @param stage Shader stage
20431 * @param out_interface Set to ""
20433 void XFBStrideOfEmptyListAndAPITest::getShaderInterface(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
20434 std::string& out_interface)
20436 static const GLchar* gs = "layout (xfb_buffer = 0, xfb_stride = 64) out;\n"
20437 "layout (xfb_buffer = 1, xfb_offset = 0) out vec4 gs_fs;\n"
20439 "layout(binding = 0) uniform gs_block {\n"
20442 static const GLchar* fs = "in vec4 gs_fs;\n"
20443 "out vec4 fs_out;\n";
20447 case Utils::Shader::FRAGMENT:
20448 out_interface = fs;
20450 case Utils::Shader::GEOMETRY:
20451 out_interface = gs;
20454 out_interface = "";
20459 /** Returns buffer details in human readable form.
20461 * @param test_case_index Index of test case
20463 * @return Case description
20465 std::string XFBStrideOfEmptyListAndAPITest::getTestCaseName(GLuint test_case_index)
20467 std::string result;
20469 switch (test_case_index)
20472 result = "Valid case";
20474 case FIRST_MISSING:
20475 result = "Missing xfb at index 0";
20477 case SECOND_MISSING:
20478 result = "Missing xfb at index 1";
20481 TCU_FAIL("Invalid enum");
20487 /** Get number of test cases
20491 GLuint XFBStrideOfEmptyListAndAPITest::getTestCaseNumber()
20498 * @param context Test framework context
20500 XFBTooSmallStrideTest::XFBTooSmallStrideTest(deqp::Context& context)
20501 : NegativeTestBase(context, "xfb_too_small_stride",
20502 "Test verifies that compiler reports error when xfb_stride sets not enough space")
20506 /** Source for given test case and stage
20508 * @param test_case_index Index of test case
20509 * @param stage Shader stage
20511 * @return Shader source
20513 std::string XFBTooSmallStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
20515 static const GLchar* array_var_definition = "layout (xfb_buffer = 0, xfb_stride = 32) out;\n"
20517 "layout (xfb_offset = 16) out vec4 gohanARRAY[4];\n";
20518 static const GLchar* block_var_definition = "layout (xfb_buffer = 0, xfb_stride = 32) out;\n"
20520 "layout (xfb_offset = 0) out Goku {\n"
20525 static const GLchar* offset_var_definition = "layout (xfb_buffer = 0, xfb_stride = 40) out;\n"
20527 "layout (xfb_offset = 32) out vec4 gohanARRAY;\n";
20528 // 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;"
20529 // To make the shader failed to compile, change xfb_stride to a value that is smaller than 32
20530 static const GLchar* stride_var_definition = "layout (xfb_buffer = 0, xfb_stride = 28) out;\n"
20532 "layout (xfb_offset = 16, xfb_stride = 28) out vec4 gohanARRAY;\n";
20533 static const GLchar* array_use = " gohanINDEX[0] = result / 2;\n"
20534 " gohanINDEX[1] = result / 4;\n"
20535 " gohanINDEX[2] = result / 6;\n"
20536 " gohanINDEX[3] = result / 8;\n";
20537 static const GLchar* block_use = " gokuINDEX.gohan = result / 2;\n"
20538 " gokuINDEX.goten = result / 4;\n"
20539 " gokuINDEX.chichi = result / 6;\n";
20540 static const GLchar* output_use = "gohanINDEX = result / 4;\n";
20541 static const GLchar* fs = "#version 430 core\n"
20542 "#extension GL_ARB_enhanced_layouts : require\n"
20545 "out vec4 fs_out;\n"
20549 " fs_out = gs_fs;\n"
20552 static const GLchar* gs_tested = "#version 430 core\n"
20553 "#extension GL_ARB_enhanced_layouts : require\n"
20555 "layout(points) in;\n"
20556 "layout(triangle_strip, max_vertices = 4) out;\n"
20560 "in vec4 tes_gs[];\n"
20561 "out vec4 gs_fs;\n"
20565 " vec4 result = tes_gs[0];\n"
20569 " gs_fs = result;\n"
20570 " gl_Position = vec4(-1, -1, 0, 1);\n"
20572 " gs_fs = result;\n"
20573 " gl_Position = vec4(-1, 1, 0, 1);\n"
20575 " gs_fs = result;\n"
20576 " gl_Position = vec4(1, -1, 0, 1);\n"
20578 " gs_fs = result;\n"
20579 " gl_Position = vec4(1, 1, 0, 1);\n"
20583 static const GLchar* tcs = "#version 430 core\n"
20584 "#extension GL_ARB_enhanced_layouts : require\n"
20586 "layout(vertices = 1) out;\n"
20588 "in vec4 vs_tcs[];\n"
20589 "out vec4 tcs_tes[];\n"
20594 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
20596 " gl_TessLevelOuter[0] = 1.0;\n"
20597 " gl_TessLevelOuter[1] = 1.0;\n"
20598 " gl_TessLevelOuter[2] = 1.0;\n"
20599 " gl_TessLevelOuter[3] = 1.0;\n"
20600 " gl_TessLevelInner[0] = 1.0;\n"
20601 " gl_TessLevelInner[1] = 1.0;\n"
20604 static const GLchar* tcs_tested = "#version 430 core\n"
20605 "#extension GL_ARB_enhanced_layouts : require\n"
20607 "layout(vertices = 1) out;\n"
20611 "in vec4 vs_tcs[];\n"
20612 "out vec4 tcs_tes[];\n"
20616 " vec4 result = vs_tcs[gl_InvocationID];\n"
20620 " tcs_tes[gl_InvocationID] = result;\n"
20622 " gl_TessLevelOuter[0] = 1.0;\n"
20623 " gl_TessLevelOuter[1] = 1.0;\n"
20624 " gl_TessLevelOuter[2] = 1.0;\n"
20625 " gl_TessLevelOuter[3] = 1.0;\n"
20626 " gl_TessLevelInner[0] = 1.0;\n"
20627 " gl_TessLevelInner[1] = 1.0;\n"
20630 static const GLchar* tes_tested = "#version 430 core\n"
20631 "#extension GL_ARB_enhanced_layouts : require\n"
20633 "layout(isolines, point_mode) in;\n"
20637 "in vec4 tcs_tes[];\n"
20638 "out vec4 tes_gs;\n"
20642 " vec4 result = tcs_tes[0];\n"
20646 " tes_gs += result;\n"
20649 static const GLchar* vs = "#version 430 core\n"
20650 "#extension GL_ARB_enhanced_layouts : require\n"
20653 "out vec4 vs_tcs;\n"
20657 " vs_tcs = in_vs;\n"
20660 static const GLchar* vs_tested = "#version 430 core\n"
20661 "#extension GL_ARB_enhanced_layouts : require\n"
20666 "out vec4 vs_tcs;\n"
20670 " vec4 result = in_vs;\n"
20674 " vs_tcs += result;\n"
20678 std::string source;
20679 testCase& test_case = m_test_cases[test_case_index];
20681 if (test_case.m_stage == stage)
20683 const GLchar* array = "";
20684 const GLchar* index = "";
20685 size_t position = 0;
20687 const GLchar* var_definition = 0;
20688 const GLchar* var_use = 0;
20690 switch (test_case.m_case)
20693 var_definition = offset_var_definition;
20694 var_use = output_use;
20697 var_definition = stride_var_definition;
20698 var_use = output_use;
20701 var_definition = block_var_definition;
20702 var_use = block_use;
20705 var_definition = array_var_definition;
20706 var_use = array_use;
20709 TCU_FAIL("Invalid enum");
20714 case Utils::Shader::GEOMETRY:
20715 source = gs_tested;
20719 case Utils::Shader::TESS_CTRL:
20720 source = tcs_tested;
20722 index = "[gl_InvocationID]";
20724 case Utils::Shader::TESS_EVAL:
20725 source = tes_tested;
20729 case Utils::Shader::VERTEX:
20730 source = vs_tested;
20733 TCU_FAIL("Invalid enum");
20737 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
20739 Utils::replaceToken("ARRAY", position, array, source);
20740 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
20742 Utils::replaceAllTokens("INDEX", index, source);
20746 switch (test_case.m_stage)
20748 case Utils::Shader::GEOMETRY:
20751 case Utils::Shader::FRAGMENT:
20754 case Utils::Shader::VERTEX:
20761 case Utils::Shader::TESS_CTRL:
20764 case Utils::Shader::FRAGMENT:
20767 case Utils::Shader::VERTEX:
20774 case Utils::Shader::TESS_EVAL:
20777 case Utils::Shader::FRAGMENT:
20780 case Utils::Shader::TESS_CTRL:
20783 case Utils::Shader::VERTEX:
20790 case Utils::Shader::VERTEX:
20793 case Utils::Shader::FRAGMENT:
20801 TCU_FAIL("Invalid enum");
20809 /** Get description of test case
20811 * @param test_case_index Index of test case
20813 * @return Test case description
20815 std::string XFBTooSmallStrideTest::getTestCaseName(GLuint test_case_index)
20817 std::stringstream stream;
20818 testCase& test_case = m_test_cases[test_case_index];
20820 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", case: ";
20822 switch (test_case.m_case)
20825 stream << "buffer stride: 40, vec4 offset: 32";
20828 stream << "buffer stride: 32, vec4 off 16 stride: 32";
20831 stream << "buffer stride: 32, block 3xvec4 offset 0";
20834 stream << "buffer stride: 32, vec4[4] offset 16";
20837 TCU_FAIL("Invalid enum");
20840 return stream.str();
20843 /** Get number of test cases
20845 * @return Number of test cases
20847 GLuint XFBTooSmallStrideTest::getTestCaseNumber()
20849 return static_cast<GLuint>(m_test_cases.size());
20852 /** Selects if "compute" stage is relevant for test
20858 bool XFBTooSmallStrideTest::isComputeRelevant(GLuint /* test_case_index */)
20863 /** Prepare all test cases
20866 void XFBTooSmallStrideTest::testInit()
20868 for (GLuint c = 0; c < CASE_MAX; ++c)
20870 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
20873 It is invalid to define transform feedback output in TCS, according to spec:
20874 The data captured in transform feedback mode depends on the active programs on each of the shader stages.
20875 If a program is active for the geometry shader stage, transform feedback captures the vertices of each
20876 primitive emitted by the geometry shader. Otherwise, if a program is active for the tessellation evaluation
20877 shader stage, transform feedback captures each primitive produced by the tessellation primitive generator,
20878 whose vertices are processed by the tessellation evaluation shader. Otherwise, transform feedback captures
20879 each primitive processed by the vertex shader.
20881 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
20882 (Utils::Shader::FRAGMENT == stage))
20887 testCase test_case = { (CASES)c, (Utils::Shader::STAGES)stage };
20889 m_test_cases.push_back(test_case);
20896 * @param context Test framework context
20898 XFBVariableStrideTest::XFBVariableStrideTest(deqp::Context& context)
20899 : NegativeTestBase(context, "xfb_variable_stride", "Test verifies that stride qualifier is respected")
20903 /** Source for given test case and stage
20905 * @param test_case_index Index of test case
20906 * @param stage Shader stage
20908 * @return Shader source
20910 std::string XFBVariableStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
20912 static const GLchar* invalid_var_definition =
20913 "const uint type_size = SIZE;\n"
20915 "layout (xfb_offset = 0, xfb_stride = 2 * type_size) out TYPE gokuARRAY;\n"
20916 "layout (xfb_offset = type_size) out TYPE vegetaARRAY;\n";
20917 static const GLchar* valid_var_definition =
20918 "const uint type_size = SIZE;\n"
20920 "layout (xfb_offset = 0, xfb_stride = 2 * type_size) out TYPE gokuARRAY;\n";
20921 static const GLchar* invalid_use = " gokuINDEX = TYPE(1);\n"
20922 " vegetaINDEX = TYPE(0);\n"
20923 " if (vec4(0) == result)\n"
20925 " gokuINDEX = TYPE(0);\n"
20926 " vegetaINDEX = TYPE(1);\n"
20928 static const GLchar* valid_use = " gokuINDEX = TYPE(1);\n"
20929 " if (vec4(0) == result)\n"
20931 " gokuINDEX = TYPE(0);\n"
20933 static const GLchar* fs = "#version 430 core\n"
20934 "#extension GL_ARB_enhanced_layouts : require\n"
20936 "in vec4 any_fs;\n"
20937 "out vec4 fs_out;\n"
20941 " fs_out = any_fs;\n"
20944 static const GLchar* gs_tested = "#version 430 core\n"
20945 "#extension GL_ARB_enhanced_layouts : require\n"
20947 "layout(points) in;\n"
20948 "layout(triangle_strip, max_vertices = 4) out;\n"
20952 "in vec4 vs_any[];\n"
20953 "out vec4 any_fs;\n"
20957 " vec4 result = vs_any[0];\n"
20961 " any_fs = result;\n"
20962 " gl_Position = vec4(-1, -1, 0, 1);\n"
20964 " any_fs = result;\n"
20965 " gl_Position = vec4(-1, 1, 0, 1);\n"
20967 " any_fs = result;\n"
20968 " gl_Position = vec4(1, -1, 0, 1);\n"
20970 " any_fs = result;\n"
20971 " gl_Position = vec4(1, 1, 0, 1);\n"
20975 static const GLchar* tcs = "#version 430 core\n"
20976 "#extension GL_ARB_enhanced_layouts : require\n"
20978 "layout(vertices = 1) out;\n"
20980 "in vec4 vs_any[];\n"
20981 "out vec4 tcs_tes[];\n"
20986 " tcs_tes[gl_InvocationID] = vs_any[gl_InvocationID];\n"
20988 " gl_TessLevelOuter[0] = 1.0;\n"
20989 " gl_TessLevelOuter[1] = 1.0;\n"
20990 " gl_TessLevelOuter[2] = 1.0;\n"
20991 " gl_TessLevelOuter[3] = 1.0;\n"
20992 " gl_TessLevelInner[0] = 1.0;\n"
20993 " gl_TessLevelInner[1] = 1.0;\n"
20996 static const GLchar* tcs_tested = "#version 430 core\n"
20997 "#extension GL_ARB_enhanced_layouts : require\n"
20999 "layout(vertices = 1) out;\n"
21003 "in vec4 vs_any[];\n"
21004 "out vec4 any_fs[];\n"
21008 " vec4 result = vs_any[gl_InvocationID];\n"
21012 " any_fs[gl_InvocationID] = result;\n"
21014 " gl_TessLevelOuter[0] = 1.0;\n"
21015 " gl_TessLevelOuter[1] = 1.0;\n"
21016 " gl_TessLevelOuter[2] = 1.0;\n"
21017 " gl_TessLevelOuter[3] = 1.0;\n"
21018 " gl_TessLevelInner[0] = 1.0;\n"
21019 " gl_TessLevelInner[1] = 1.0;\n"
21022 static const GLchar* tes_tested = "#version 430 core\n"
21023 "#extension GL_ARB_enhanced_layouts : require\n"
21025 "layout(isolines, point_mode) in;\n"
21029 "in vec4 tcs_tes[];\n"
21030 "out vec4 any_fs;\n"
21034 " vec4 result = tcs_tes[0];\n"
21038 " any_fs = result;\n"
21041 static const GLchar* vs = "#version 430 core\n"
21042 "#extension GL_ARB_enhanced_layouts : require\n"
21045 "out vec4 vs_any;\n"
21049 " vs_any = in_vs;\n"
21052 static const GLchar* vs_tested = "#version 430 core\n"
21053 "#extension GL_ARB_enhanced_layouts : require\n"
21058 "out vec4 any_fs;\n"
21062 " vec4 result = in_vs;\n"
21066 " any_fs = result;\n"
21070 std::string source;
21071 testCase& test_case = m_test_cases[test_case_index];
21073 if (test_case.m_stage == stage)
21075 const GLchar* array = "";
21077 const GLchar* index = "";
21078 size_t position = 0;
21080 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
21081 const GLchar* var_definition = 0;
21082 const GLchar* var_use = 0;
21084 sprintf(buffer, "%d", test_case.m_type.GetSize());
21086 switch (test_case.m_case)
21089 var_definition = valid_var_definition;
21090 var_use = valid_use;
21093 var_definition = invalid_var_definition;
21094 var_use = invalid_use;
21097 TCU_FAIL("Invalid enum");
21102 case Utils::Shader::GEOMETRY:
21103 source = gs_tested;
21107 case Utils::Shader::TESS_CTRL:
21108 source = tcs_tested;
21110 index = "[gl_InvocationID]";
21112 case Utils::Shader::TESS_EVAL:
21113 source = tes_tested;
21117 case Utils::Shader::VERTEX:
21118 source = vs_tested;
21121 TCU_FAIL("Invalid enum");
21125 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
21127 Utils::replaceToken("SIZE", position, buffer, source);
21128 Utils::replaceToken("ARRAY", position, array, source);
21129 if (INVALID == test_case.m_case)
21131 Utils::replaceToken("ARRAY", position, array, source);
21133 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
21135 Utils::replaceAllTokens("TYPE", type_name, source);
21136 Utils::replaceAllTokens("INDEX", index, source);
21140 switch (test_case.m_stage)
21142 case Utils::Shader::GEOMETRY:
21145 case Utils::Shader::FRAGMENT:
21148 case Utils::Shader::VERTEX:
21155 case Utils::Shader::TESS_CTRL:
21158 case Utils::Shader::FRAGMENT:
21161 case Utils::Shader::VERTEX:
21168 case Utils::Shader::TESS_EVAL:
21171 case Utils::Shader::FRAGMENT:
21174 case Utils::Shader::TESS_CTRL:
21177 case Utils::Shader::VERTEX:
21184 case Utils::Shader::VERTEX:
21187 case Utils::Shader::FRAGMENT:
21195 TCU_FAIL("Invalid enum");
21203 /** Get description of test case
21205 * @param test_case_index Index of test case
21207 * @return Test case description
21209 std::string XFBVariableStrideTest::getTestCaseName(GLuint test_case_index)
21211 std::stringstream stream;
21212 testCase& test_case = m_test_cases[test_case_index];
21214 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
21215 << ", type: " << test_case.m_type.GetGLSLTypeName() << ", case: ";
21217 switch (test_case.m_case)
21223 stream << "invalid";
21226 TCU_FAIL("Invalid enum");
21229 return stream.str();
21232 /** Get number of test cases
21234 * @return Number of test cases
21236 GLuint XFBVariableStrideTest::getTestCaseNumber()
21238 return static_cast<GLuint>(m_test_cases.size());
21241 /** Selects if "compute" stage is relevant for test
21247 bool XFBVariableStrideTest::isComputeRelevant(GLuint /* test_case_index */)
21252 /** Selects if compilation failure is expected result
21254 * @param test_case_index Index of test case
21258 bool XFBVariableStrideTest::isFailureExpected(GLuint test_case_index)
21260 testCase& test_case = m_test_cases[test_case_index];
21262 return (INVALID == test_case.m_case);
21265 /** Prepare all test cases
21268 void XFBVariableStrideTest::testInit()
21270 const GLuint n_types = getTypesNumber();
21272 for (GLuint i = 0; i < n_types; ++i)
21274 const Utils::Type& type = getType(i);
21277 Some of the cases are declared as following are considered as invalid,
21278 but accoring to spec, the following declaration is valid: shaders in the
21279 transform feedback capturing mode have an initial global default of layout(xfb_buffer=0) out,
21280 so for the first variable's declaration, the xfb_stride = 16 is applied on buffer 0, for the
21281 second variable, its buffer is also inherited from global buffer 0, and its offset does not overflows
21284 The xfb_stride is the memory width of given buffer, not for variable even though xfb_stride
21285 is declared on the variable. It seems that the writter of this case misunderstand the concept of
21286 xfb_stride, because spec describes that xfb_stride can be declared multiple times for the same buffer,
21287 it is a compile or link-time error to have different values specified for the stride for the same buffer.
21290 layout (xfb_offset = 0, xfb_stride = 2 * type_size) out double goku;
21291 layout (xfb_offset = type_size) out double vegeta;
21293 // all the shaders are valid, so remove the following loop(it contains CASE_MAX is enum of valid and invalid)
21294 // for (GLuint c = 0; c < CASE_MAX; ++c)
21296 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
21298 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
21299 (Utils::Shader::FRAGMENT == stage))
21304 testCase test_case = { (CASES)VALID, (Utils::Shader::STAGES)stage, type };
21306 m_test_cases.push_back(test_case);
21314 * @param context Test framework context
21316 XFBBlockStrideTest::XFBBlockStrideTest(deqp::Context& context)
21317 : TestBase(context, "xfb_block_stride", "Test verifies that stride qualifier is respected for blocks")
21321 /** Source for given test case and stage
21323 * @param test_case_index Index of test case
21324 * @param stage Shader stage
21326 * @return Shader source
21328 std::string XFBBlockStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
21330 static const GLchar* var_definition = "layout (xfb_offset = 0, xfb_stride = 128) out Goku {\n"
21335 static const GLchar* var_use = " gokuINDEX.gohan = vec4(1, 0, 0, 0);\n"
21336 " gokuINDEX.goten = vec4(0, 0, 1, 0);\n"
21337 " gokuINDEX.chichi = vec4(0, 1, 0, 0);\n"
21338 " if (vec4(0) == result)\n"
21340 " gokuINDEX.gohan = vec4(0, 1, 1, 1);\n"
21341 " gokuINDEX.goten = vec4(1, 1, 0, 1);\n"
21342 " gokuINDEX.chichi = vec4(1, 0, 1, 1);\n"
21344 static const GLchar* gs_tested =
21345 "#version 430 core\n"
21346 "#extension GL_ARB_enhanced_layouts : require\n"
21348 "layout(points) in;\n"
21349 "layout(triangle_strip, max_vertices = 4) out;\n"
21353 "out gl_PerVertex \n"
21355 " vec4 gl_Position; \n" // gl_Position must be redeclared in separable program mode
21357 "in vec4 tes_gs[];\n"
21358 "out vec4 gs_fs;\n"
21362 " vec4 result = tes_gs[0];\n"
21366 " gs_fs = result;\n"
21367 " gl_Position = vec4(-1, -1, 0, 1);\n"
21369 " gs_fs = result;\n"
21370 " gl_Position = vec4(-1, 1, 0, 1);\n"
21372 " gs_fs = result;\n"
21373 " gl_Position = vec4(1, -1, 0, 1);\n"
21375 " gs_fs = result;\n"
21376 " gl_Position = vec4(1, 1, 0, 1);\n"
21380 static const GLchar* tcs = "#version 430 core\n"
21381 "#extension GL_ARB_enhanced_layouts : require\n"
21383 "layout(vertices = 1) out;\n"
21385 "in vec4 vs_tcs[];\n"
21386 "out vec4 tcs_tes[];\n"
21391 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
21393 " gl_TessLevelOuter[0] = 1.0;\n"
21394 " gl_TessLevelOuter[1] = 1.0;\n"
21395 " gl_TessLevelOuter[2] = 1.0;\n"
21396 " gl_TessLevelOuter[3] = 1.0;\n"
21397 " gl_TessLevelInner[0] = 1.0;\n"
21398 " gl_TessLevelInner[1] = 1.0;\n"
21402 static const GLchar* tcs_tested =
21403 "#version 430 core\n"
21404 "#extension GL_ARB_enhanced_layouts : require\n"
21406 "layout(vertices = 1) out;\n"
21410 "in vec4 vs_tcs[];\n"
21411 "out vec4 tcs_tes[];\n"
21415 " vec4 result = vs_tcs[gl_InvocationID];\n"
21419 " tcs_tes[gl_InvocationID] = result;\n"
21421 " gl_TessLevelOuter[0] = 1.0;\n"
21422 " gl_TessLevelOuter[1] = 1.0;\n"
21423 " gl_TessLevelOuter[2] = 1.0;\n"
21424 " gl_TessLevelOuter[3] = 1.0;\n"
21425 " gl_TessLevelInner[0] = 1.0;\n"
21426 " gl_TessLevelInner[1] = 1.0;\n"
21430 static const GLchar* tes_tested = "#version 430 core\n"
21431 "#extension GL_ARB_enhanced_layouts : require\n"
21433 "layout(isolines, point_mode) in;\n"
21437 "in vec4 tcs_tes[];\n"
21438 "out vec4 tes_gs;\n"
21442 " vec4 result = tcs_tes[0];\n"
21446 " tes_gs += result;\n"
21449 static const GLchar* vs = "#version 430 core\n"
21450 "#extension GL_ARB_enhanced_layouts : require\n"
21453 "out vec4 vs_tcs;\n"
21457 " vs_tcs = in_vs;\n"
21460 static const GLchar* vs_tested = "#version 430 core\n"
21461 "#extension GL_ARB_enhanced_layouts : require\n"
21466 "out vec4 vs_tcs;\n"
21470 " vec4 result = in_vs;\n"
21474 " vs_tcs += result;\n"
21478 std::string source;
21479 Utils::Shader::STAGES test_case = m_test_cases[test_case_index];
21481 if (test_case == stage)
21483 const GLchar* array = "";
21484 const GLchar* index = "";
21485 size_t position = 0;
21487 // It is a compile time error to apply xfb_offset to the declaration of an unsized array(GLSL4.5 spec: Page73)
21488 // change array = "[]" to "[1]"
21491 case Utils::Shader::GEOMETRY:
21492 source = gs_tested;
21497 It is invalid to define transform feedback output in HS
21500 case Utils::Shader::TESS_CTRL:
21501 source = tcs_tested;
21503 index = "[gl_InvocationID]";
21506 case Utils::Shader::TESS_EVAL:
21507 source = tes_tested;
21511 case Utils::Shader::VERTEX:
21512 source = vs_tested;
21515 TCU_FAIL("Invalid enum");
21519 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
21521 Utils::replaceToken("ARRAY", position, array, source);
21522 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
21524 Utils::replaceAllTokens("INDEX", index, source);
21530 case Utils::Shader::GEOMETRY:
21533 case Utils::Shader::VERTEX:
21540 case Utils::Shader::TESS_CTRL:
21543 case Utils::Shader::VERTEX:
21550 case Utils::Shader::TESS_EVAL:
21553 case Utils::Shader::TESS_CTRL:
21556 case Utils::Shader::VERTEX:
21563 case Utils::Shader::VERTEX:
21567 TCU_FAIL("Invalid enum");
21575 /** Get description of test case
21577 * @param test_case_index Index of test case
21579 * @return Test case description
21581 std::string XFBBlockStrideTest::getTestCaseName(GLuint test_case_index)
21583 std::stringstream stream;
21585 stream << "Stage: " << Utils::Shader::GetStageName(m_test_cases[test_case_index]);
21587 return stream.str();
21590 /** Get number of test cases
21592 * @return Number of test cases
21594 GLuint XFBBlockStrideTest::getTestCaseNumber()
21596 return static_cast<GLuint>(m_test_cases.size());
21599 /** Inspects program for xfb stride
21601 * @param program Program to query
21603 * @return true if query results match expected values, false otherwise
21605 bool XFBBlockStrideTest::inspectProgram(Utils::Program& program)
21609 program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE,
21610 1 /* buf_size */, &stride);
21612 return (128 == stride);
21617 * @param test_case_index Id of test case
21619 * @return true if test case pass, false otherwise
21621 bool XFBBlockStrideTest::testCase(GLuint test_case_index)
21623 const std::string& gs_source = getShaderSource(test_case_index, Utils::Shader::GEOMETRY);
21624 Utils::Program program(m_context);
21625 const std::string& tcs_source = getShaderSource(test_case_index, Utils::Shader::TESS_CTRL);
21626 const std::string& tes_source = getShaderSource(test_case_index, Utils::Shader::TESS_EVAL);
21627 bool test_case_result = true;
21628 const std::string& vs_source = getShaderSource(test_case_index, Utils::Shader::VERTEX);
21630 program.Init("" /* cs */, "", gs_source, tcs_source, tes_source, vs_source, true /* separable */);
21632 test_case_result = inspectProgram(program);
21634 return test_case_result;
21637 /** Prepare all test cases
21640 void XFBBlockStrideTest::testInit()
21642 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
21644 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
21645 (Utils::Shader::FRAGMENT == stage))
21650 m_test_cases.push_back((Utils::Shader::STAGES)stage);
21656 * @param context Test context
21658 XFBBlockMemberStrideTest::XFBBlockMemberStrideTest(deqp::Context& context)
21659 : BufferTestBase(context, "xfb_block_member_stride",
21660 "Test verifies that xfb_stride qualifier is respected for block member")
21662 /* Nothing to be done here */
21665 /** Get descriptors of buffers necessary for test
21668 * @param out_descriptors Descriptors of buffers used by test
21670 void XFBBlockMemberStrideTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
21671 bufferDescriptor::Vector& out_descriptors)
21673 const Utils::Type& vec4 = Utils::Type::vec4;
21675 /* Test needs single uniform and xfb */
21676 out_descriptors.resize(2);
21678 /* Get references */
21679 bufferDescriptor& uniform = out_descriptors[0];
21680 bufferDescriptor& xfb = out_descriptors[1];
21683 uniform.m_index = 0;
21687 uniform.m_target = Utils::Buffer::Uniform;
21688 xfb.m_target = Utils::Buffer::Transform_feedback;
21691 static const GLuint vec4_size = 16;
21692 const std::vector<GLubyte>& gohan_data = vec4.GenerateDataPacked();
21693 const std::vector<GLubyte>& goten_data = vec4.GenerateDataPacked();
21694 const std::vector<GLubyte>& chichi_data = vec4.GenerateDataPacked();
21697 uniform.m_initial_data.resize(3 * vec4_size);
21698 memcpy(&uniform.m_initial_data[0] + 0, &gohan_data[0], vec4_size);
21699 memcpy(&uniform.m_initial_data[0] + vec4_size, &goten_data[0], vec4_size);
21700 memcpy(&uniform.m_initial_data[0] + 2 * vec4_size, &chichi_data[0], vec4_size);
21703 xfb.m_initial_data.resize(4 * vec4_size);
21704 xfb.m_expected_data.resize(4 * vec4_size);
21706 for (GLuint i = 0; i < 4 * vec4_size; ++i)
21708 xfb.m_initial_data[i] = (glw::GLubyte)i;
21709 xfb.m_expected_data[i] = (glw::GLubyte)i;
21712 // the xfb_offset of "chichi" should be 32
21713 memcpy(&xfb.m_expected_data[0] + 0, &gohan_data[0], vec4_size);
21714 memcpy(&xfb.m_expected_data[0] + vec4_size, &goten_data[0], vec4_size);
21715 memcpy(&xfb.m_expected_data[0] + 2 * vec4_size, &chichi_data[0], vec4_size);
21718 /** Get body of main function for given shader stage
21721 * @param stage Shader stage
21722 * @param out_assignments Set to empty
21723 * @param out_calculations Set to empty
21725 void XFBBlockMemberStrideTest::getShaderBody(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
21726 std::string& out_assignments, std::string& out_calculations)
21728 out_calculations = "";
21730 static const GLchar* gs = " gohan = uni_gohan;\n"
21731 " goten = uni_goten;\n"
21732 " chichi = uni_chichi;\n";
21733 static const GLchar* fs = " fs_out = gohan + goten + chichi;\n";
21735 const GLchar* assignments = "";
21738 case Utils::Shader::FRAGMENT:
21741 case Utils::Shader::GEOMETRY:
21748 out_assignments = assignments;
21751 /** Get interface of shader
21754 * @param stage Shader stage
21755 * @param out_interface Set to ""
21757 void XFBBlockMemberStrideTest::getShaderInterface(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
21758 std::string& out_interface)
21760 static const GLchar* gs = "layout (xfb_buffer = 0, xfb_offset = 0) out Goku {\n"
21762 " layout (xfb_stride = 32) vec4 goten;\n"
21765 "layout(binding = 0) uniform gs_block {\n"
21766 " vec4 uni_gohan;\n"
21767 " vec4 uni_goten;\n"
21768 " vec4 uni_chichi;\n"
21770 static const GLchar* fs = "in Goku {\n"
21775 "out vec4 fs_out;\n";
21779 case Utils::Shader::FRAGMENT:
21780 out_interface = fs;
21782 case Utils::Shader::GEOMETRY:
21783 out_interface = gs;
21786 out_interface = "";
21791 /** Inspects program to check if all resources are as expected
21794 * @param program Program instance
21795 * @param out_stream Error message
21797 * @return true if everything is ok, false otherwise
21799 bool XFBBlockMemberStrideTest::inspectProgram(GLuint /* test_case_index*/, Utils::Program& program,
21800 std::stringstream& out_stream)
21802 const GLuint gohan_id = program.GetResourceIndex("gohan", GL_TRANSFORM_FEEDBACK_VARYING);
21803 const GLuint goten_id = program.GetResourceIndex("goten", GL_TRANSFORM_FEEDBACK_VARYING);
21804 const GLuint chichi_id = program.GetResourceIndex("chichi", GL_TRANSFORM_FEEDBACK_VARYING);
21806 GLint gohan_offset = 0;
21807 GLint goten_offset = 0;
21808 GLint chichi_offset = 0;
21810 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, gohan_id, GL_OFFSET, 1, &gohan_offset);
21811 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, goten_id, GL_OFFSET, 1, &goten_offset);
21812 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, chichi_id, GL_OFFSET, 1, &chichi_offset);
21814 // the xfb_offset of "chichi" should be 32
21815 if ((0 != gohan_offset) || (16 != goten_offset) || (32 != chichi_offset))
21817 out_stream << "Got wrong offset: [" << gohan_offset << ", " << goten_offset << ", " << chichi_offset
21818 << "] expected: [0, 16, 48]";
21827 * @param context Test framework context
21829 XFBDuplicatedStrideTest::XFBDuplicatedStrideTest(deqp::Context& context)
21830 : NegativeTestBase(context, "xfb_duplicated_stride",
21831 "Test verifies that compiler reports error when conflicting stride qualifiers are used")
21835 /** Source for given test case and stage
21837 * @param test_case_index Index of test case
21838 * @param stage Shader stage
21840 * @return Shader source
21842 std::string XFBDuplicatedStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
21844 static const GLchar* invalid_var_definition = "const uint valid_stride = 64;\n"
21845 "const uint conflicting_stride = 128;\n"
21847 "layout (xfb_buffer = 0, xfb_stride = valid_stride) out;\n"
21848 "layout (xfb_buffer = 0, xfb_stride = conflicting_stride) out;\n";
21849 static const GLchar* valid_var_definition = "const uint valid_stride = 64;\n"
21851 "layout (xfb_buffer = 0, xfb_stride = valid_stride) out;\n"
21852 "layout (xfb_buffer = 0, xfb_stride = valid_stride) out;\n";
21853 static const GLchar* fs = "#version 430 core\n"
21854 "#extension GL_ARB_enhanced_layouts : require\n"
21856 "in vec4 any_fs;\n"
21857 "out vec4 fs_out;\n"
21861 " fs_out = any_fs;\n"
21864 static const GLchar* gs_tested = "#version 430 core\n"
21865 "#extension GL_ARB_enhanced_layouts : require\n"
21867 "layout(points) in;\n"
21868 "layout(triangle_strip, max_vertices = 4) out;\n"
21872 "in vec4 vs_any[];\n"
21873 "out vec4 any_fs;\n"
21877 " vec4 result = vs_any[0];\n"
21881 " any_fs = result;\n"
21882 " gl_Position = vec4(-1, -1, 0, 1);\n"
21884 " any_fs = result;\n"
21885 " gl_Position = vec4(-1, 1, 0, 1);\n"
21887 " any_fs = result;\n"
21888 " gl_Position = vec4(1, -1, 0, 1);\n"
21890 " any_fs = result;\n"
21891 " gl_Position = vec4(1, 1, 0, 1);\n"
21895 static const GLchar* tcs = "#version 430 core\n"
21896 "#extension GL_ARB_enhanced_layouts : require\n"
21898 "layout(vertices = 1) out;\n"
21900 "in vec4 vs_any[];\n"
21901 "out vec4 tcs_tes[];\n"
21906 " tcs_tes[gl_InvocationID] = vs_any[gl_InvocationID];\n"
21908 " gl_TessLevelOuter[0] = 1.0;\n"
21909 " gl_TessLevelOuter[1] = 1.0;\n"
21910 " gl_TessLevelOuter[2] = 1.0;\n"
21911 " gl_TessLevelOuter[3] = 1.0;\n"
21912 " gl_TessLevelInner[0] = 1.0;\n"
21913 " gl_TessLevelInner[1] = 1.0;\n"
21916 static const GLchar* tcs_tested = "#version 430 core\n"
21917 "#extension GL_ARB_enhanced_layouts : require\n"
21919 "layout(vertices = 1) out;\n"
21923 "in vec4 vs_any[];\n"
21924 "out vec4 any_fs[];\n"
21928 " vec4 result = vs_any[gl_InvocationID];\n"
21932 " any_fs[gl_InvocationID] = result;\n"
21934 " gl_TessLevelOuter[0] = 1.0;\n"
21935 " gl_TessLevelOuter[1] = 1.0;\n"
21936 " gl_TessLevelOuter[2] = 1.0;\n"
21937 " gl_TessLevelOuter[3] = 1.0;\n"
21938 " gl_TessLevelInner[0] = 1.0;\n"
21939 " gl_TessLevelInner[1] = 1.0;\n"
21942 static const GLchar* tes_tested = "#version 430 core\n"
21943 "#extension GL_ARB_enhanced_layouts : require\n"
21945 "layout(isolines, point_mode) in;\n"
21949 "in vec4 tcs_tes[];\n"
21950 "out vec4 any_fs;\n"
21954 " vec4 result = tcs_tes[0];\n"
21958 " any_fs = result;\n"
21961 static const GLchar* vs = "#version 430 core\n"
21962 "#extension GL_ARB_enhanced_layouts : require\n"
21965 "out vec4 vs_any;\n"
21969 " vs_any = in_vs;\n"
21972 static const GLchar* vs_tested = "#version 430 core\n"
21973 "#extension GL_ARB_enhanced_layouts : require\n"
21978 "out vec4 any_fs;\n"
21982 " vec4 result = in_vs;\n"
21986 " any_fs += result;\n"
21990 std::string source;
21991 testCase& test_case = m_test_cases[test_case_index];
21993 if (test_case.m_stage == stage)
21995 size_t position = 0;
21996 const GLchar* var_definition = 0;
21997 const GLchar* var_use = "";
21999 switch (test_case.m_case)
22002 var_definition = valid_var_definition;
22005 var_definition = invalid_var_definition;
22008 TCU_FAIL("Invalid enum");
22013 case Utils::Shader::GEOMETRY:
22014 source = gs_tested;
22016 case Utils::Shader::TESS_CTRL:
22017 source = tcs_tested;
22019 case Utils::Shader::TESS_EVAL:
22020 source = tes_tested;
22022 case Utils::Shader::VERTEX:
22023 source = vs_tested;
22026 TCU_FAIL("Invalid enum");
22029 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
22030 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
22034 switch (test_case.m_stage)
22036 case Utils::Shader::GEOMETRY:
22039 case Utils::Shader::FRAGMENT:
22042 case Utils::Shader::VERTEX:
22049 case Utils::Shader::TESS_CTRL:
22052 case Utils::Shader::FRAGMENT:
22055 case Utils::Shader::VERTEX:
22062 case Utils::Shader::TESS_EVAL:
22065 case Utils::Shader::FRAGMENT:
22068 case Utils::Shader::TESS_CTRL:
22071 case Utils::Shader::VERTEX:
22078 case Utils::Shader::VERTEX:
22081 case Utils::Shader::FRAGMENT:
22089 TCU_FAIL("Invalid enum");
22097 /** Get description of test case
22099 * @param test_case_index Index of test case
22101 * @return Test case description
22103 std::string XFBDuplicatedStrideTest::getTestCaseName(GLuint test_case_index)
22105 std::stringstream stream;
22106 testCase& test_case = m_test_cases[test_case_index];
22108 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", case: ";
22110 switch (test_case.m_case)
22116 stream << "invalid";
22119 TCU_FAIL("Invalid enum");
22122 return stream.str();
22125 /** Get number of test cases
22127 * @return Number of test cases
22129 GLuint XFBDuplicatedStrideTest::getTestCaseNumber()
22131 return static_cast<GLuint>(m_test_cases.size());
22134 /** Selects if "compute" stage is relevant for test
22140 bool XFBDuplicatedStrideTest::isComputeRelevant(GLuint /* test_case_index */)
22145 /** Selects if compilation failure is expected result
22147 * @param test_case_index Index of test case
22151 bool XFBDuplicatedStrideTest::isFailureExpected(GLuint test_case_index)
22153 testCase& test_case = m_test_cases[test_case_index];
22155 return (INVALID == test_case.m_case);
22158 /** Prepare all test cases
22161 void XFBDuplicatedStrideTest::testInit()
22163 for (GLuint c = 0; c < CASE_MAX; ++c)
22165 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
22167 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
22168 (Utils::Shader::FRAGMENT == stage))
22173 testCase test_case = { (CASES)c, (Utils::Shader::STAGES)stage };
22175 m_test_cases.push_back(test_case);
22182 * @param context Test framework context
22184 XFBGetProgramResourceAPITest::XFBGetProgramResourceAPITest(deqp::Context& context)
22185 : TestBase(context, "xfb_get_program_resource_api",
22186 "Test verifies that get program resource reports correct results for XFB")
22190 /** Source for given test case and stage
22192 * @param test_case_index Index of test case
22193 * @param stage Shader stage
22195 * @return Shader source
22197 std::string XFBGetProgramResourceAPITest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
22199 static const GLchar* api_var_definition = "out TYPE b0_v1ARRAY;\n"
22200 "out TYPE b1_v1ARRAY;\n"
22201 "out TYPE b0_v3ARRAY;\n"
22202 "out TYPE b0_v0ARRAY;\n";
22203 static const GLchar* xfb_var_definition =
22204 "const uint type_size = SIZE;\n"
22206 "layout (xfb_buffer = 1, xfb_stride = 4 * type_size) out;\n"
22208 "layout (xfb_buffer = 0, xfb_offset = 1 * type_size) out TYPE b0_v1ARRAY;\n"
22209 "layout (xfb_buffer = 1, xfb_offset = 1 * type_size) out TYPE b1_v1ARRAY;\n"
22210 "layout (xfb_buffer = 0, xfb_offset = 3 * type_size) out TYPE b0_v3ARRAY;\n"
22211 "layout (xfb_buffer = 0, xfb_offset = 0 * type_size) out TYPE b0_v0ARRAY;\n";
22212 static const GLchar* var_use = " b0_v1INDEX = TYPE(0);\n"
22213 " b1_v1INDEX = TYPE(1);\n"
22214 " b0_v3INDEX = TYPE(0);\n"
22215 " b0_v0INDEX = TYPE(1);\n"
22216 " if (vec4(0) == result)\n"
22218 " b0_v1INDEX = TYPE(1);\n"
22219 " b1_v1INDEX = TYPE(0);\n"
22220 " b0_v3INDEX = TYPE(1);\n"
22221 " b0_v0INDEX = TYPE(0);\n"
22223 static const GLchar* gs_tested =
22224 "#version 430 core\n"
22225 "#extension GL_ARB_enhanced_layouts : require\n"
22227 "layout(points) in;\n"
22228 "layout(triangle_strip, max_vertices = 4) out;\n"
22232 "out gl_PerVertex \n"
22234 " vec4 gl_Position; \n" // gl_Position must be redeclared in separable program mode
22236 "in vec4 tes_gs[];\n"
22237 "out vec4 gs_fs;\n"
22241 " vec4 result = tes_gs[0];\n"
22245 " gs_fs = result;\n"
22246 " gl_Position = vec4(-1, -1, 0, 1);\n"
22248 " gs_fs = result;\n"
22249 " gl_Position = vec4(-1, 1, 0, 1);\n"
22251 " gs_fs = result;\n"
22252 " gl_Position = vec4(1, -1, 0, 1);\n"
22254 " gs_fs = result;\n"
22255 " gl_Position = vec4(1, 1, 0, 1);\n"
22260 static const GLchar* tcs_tested =
22261 "#version 430 core\n"
22262 "#extension GL_ARB_enhanced_layouts : require\n"
22264 "layout(vertices = 1) out;\n"
22268 "in vec4 vs_tcs[];\n"
22269 "out vec4 tcs_tes[];\n"
22273 " vec4 result = vs_tcs[gl_InvocationID];\n"
22277 " tcs_tes[gl_InvocationID] = result;\n"
22279 " gl_TessLevelOuter[0] = 1.0;\n"
22280 " gl_TessLevelOuter[1] = 1.0;\n"
22281 " gl_TessLevelOuter[2] = 1.0;\n"
22282 " gl_TessLevelOuter[3] = 1.0;\n"
22283 " gl_TessLevelInner[0] = 1.0;\n"
22284 " gl_TessLevelInner[1] = 1.0;\n"
22288 static const GLchar* tes_tested = "#version 430 core\n"
22289 "#extension GL_ARB_enhanced_layouts : require\n"
22291 "layout(isolines, point_mode) in;\n"
22295 "in vec4 tcs_tes[];\n"
22296 "out vec4 tes_gs;\n"
22300 " vec4 result = tcs_tes[0];\n"
22304 " tes_gs = result;\n"
22307 static const GLchar* vs_tested = "#version 430 core\n"
22308 "#extension GL_ARB_enhanced_layouts : require\n"
22313 "out vec4 vs_tcs;\n"
22317 " vec4 result = in_vs;\n"
22321 " vs_tcs = result;\n"
22325 std::string source;
22326 const test_Case& test_case = m_test_cases[test_case_index];
22328 if (test_case.m_stage == stage)
22330 const GLchar* array = "";
22332 const GLchar* index = "";
22333 size_t position = 0;
22335 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
22336 const GLchar* var_definition = 0;
22338 sprintf(buffer, "%d", test_case.m_type.GetSize());
22340 if (XFB == test_case.m_case)
22342 var_definition = xfb_var_definition;
22346 var_definition = api_var_definition;
22349 // It is a compile time error to apply xfb_offset to the declaration of an unsized array(GLSL4.5 spec: Page73)
22350 // change array = "[]" to "[1]"
22353 case Utils::Shader::GEOMETRY:
22354 source = gs_tested;
22358 // It is invalid to output transform feedback varyings in tessellation control shader
22360 case Utils::Shader::TESS_CTRL:
22361 source = tcs_tested;
22363 index = "[gl_InvocationID]";
22366 case Utils::Shader::TESS_EVAL:
22367 source = tes_tested;
22371 case Utils::Shader::VERTEX:
22372 source = vs_tested;
22375 TCU_FAIL("Invalid enum");
22379 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
22380 if (XFB == test_case.m_case)
22383 Utils::replaceToken("SIZE", position, buffer, source);
22385 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
22387 Utils::replaceAllTokens("ARRAY", array, source);
22388 Utils::replaceAllTokens("INDEX", index, source);
22389 Utils::replaceAllTokens("TYPE", type_name, source);
22399 /** Get description of test case
22401 * @param test_case_index Index of test case
22403 * @return Test case description
22405 std::string XFBGetProgramResourceAPITest::getTestCaseName(GLuint test_case_index)
22407 std::stringstream stream;
22408 const test_Case& test_case = m_test_cases[test_case_index];
22410 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
22411 << ", type: " << test_case.m_type.GetGLSLTypeName() << ", case: ";
22413 switch (test_case.m_case)
22416 stream << "interleaved";
22419 stream << "separated";
22425 TCU_FAIL("Invalid enum");
22428 return stream.str();
22431 /** Get number of test cases
22433 * @return Number of test cases
22435 GLuint XFBGetProgramResourceAPITest::getTestCaseNumber()
22437 return static_cast<GLuint>(m_test_cases.size());
22440 /** Inspects program for offset, buffer index, buffer stride and type
22442 * @param test_case_index Index of test case
22443 * @param program Program to query
22445 * @return true if query results match expected values, false otherwise
22447 bool XFBGetProgramResourceAPITest::inspectProgram(glw::GLuint test_case_index, Utils::Program& program)
22449 GLint b0_stride = 0;
22450 GLint b1_stride = 0;
22451 GLint b0_v0_buf = 0;
22452 GLint b0_v0_offset = 0;
22453 GLint b0_v0_type = 0;
22454 GLint b0_v1_buf = 0;
22455 GLint b0_v1_offset = 0;
22456 GLint b0_v1_type = 0;
22457 GLint b0_v3_buf = 0;
22458 GLint b0_v3_offset = 0;
22459 GLint b0_v3_type = 0;
22460 GLint b1_v1_buf = 0;
22461 GLint b1_v1_offset = 0;
22462 GLint b1_v1_type = 0;
22463 const test_Case& test_case = m_test_cases[test_case_index];
22464 const GLenum type_enum = test_case.m_type.GetTypeGLenum();
22465 const GLint type_size = test_case.m_type.GetSize();
22467 GLuint b0_v0_index = program.GetResourceIndex("b0_v0", GL_TRANSFORM_FEEDBACK_VARYING);
22468 GLuint b0_v1_index = program.GetResourceIndex("b0_v1", GL_TRANSFORM_FEEDBACK_VARYING);
22469 GLuint b0_v3_index = program.GetResourceIndex("b0_v3", GL_TRANSFORM_FEEDBACK_VARYING);
22470 GLuint b1_v1_index = program.GetResourceIndex("b1_v1", GL_TRANSFORM_FEEDBACK_VARYING);
22472 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v0_index, GL_OFFSET, 1 /* buf_size */, &b0_v0_offset);
22473 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v1_index, GL_OFFSET, 1 /* buf_size */, &b0_v1_offset);
22474 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v3_index, GL_OFFSET, 1 /* buf_size */, &b0_v3_offset);
22475 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b1_v1_index, GL_OFFSET, 1 /* buf_size */, &b1_v1_offset);
22477 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v0_index, GL_TYPE, 1 /* buf_size */, &b0_v0_type);
22478 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v1_index, GL_TYPE, 1 /* buf_size */, &b0_v1_type);
22479 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v3_index, GL_TYPE, 1 /* buf_size */, &b0_v3_type);
22480 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b1_v1_index, GL_TYPE, 1 /* buf_size */, &b1_v1_type);
22482 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v0_index, GL_TRANSFORM_FEEDBACK_BUFFER_INDEX,
22483 1 /* buf_size */, &b0_v0_buf);
22484 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v1_index, GL_TRANSFORM_FEEDBACK_BUFFER_INDEX,
22485 1 /* buf_size */, &b0_v1_buf);
22486 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v3_index, GL_TRANSFORM_FEEDBACK_BUFFER_INDEX,
22487 1 /* buf_size */, &b0_v3_buf);
22488 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b1_v1_index, GL_TRANSFORM_FEEDBACK_BUFFER_INDEX,
22489 1 /* buf_size */, &b1_v1_buf);
22491 program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, b0_v0_buf, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE, 1 /* buf_size */,
22493 program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, b1_v1_buf, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE, 1 /* buf_size */,
22496 if (SEPARATED != test_case.m_case)
22498 return (((GLint)(4 * type_size) == b0_stride) && ((GLint)(4 * type_size) == b1_stride) &&
22499 ((GLint)(0) == b0_v0_buf) && ((GLint)(0 * type_size) == b0_v0_offset) &&
22500 ((GLint)(type_enum) == b0_v0_type) && ((GLint)(0) == b0_v1_buf) &&
22501 ((GLint)(1 * type_size) == b0_v1_offset) && ((GLint)(type_enum) == b0_v1_type) &&
22502 ((GLint)(0) == b0_v3_buf) && ((GLint)(3 * type_size) == b0_v3_offset) &&
22503 ((GLint)(type_enum) == b0_v3_type) && ((GLint)(1) == b1_v1_buf) &&
22504 ((GLint)(1 * type_size) == b1_v1_offset) && ((GLint)(type_enum) == b1_v1_type));
22508 return (((GLint)(1 * type_size) == b0_stride) && ((GLint)(1 * type_size) == b1_stride) &&
22509 ((GLint)(0) == b0_v0_buf) && ((GLint)(0) == b0_v0_offset) && ((GLint)(type_enum) == b0_v0_type) &&
22510 ((GLint)(1) == b0_v1_buf) && ((GLint)(0) == b0_v1_offset) && ((GLint)(type_enum) == b0_v1_type) &&
22511 ((GLint)(2) == b0_v3_buf) && ((GLint)(0) == b0_v3_offset) && ((GLint)(type_enum) == b0_v3_type) &&
22512 ((GLint)(3) == b1_v1_buf) && ((GLint)(0) == b1_v1_offset) && ((GLint)(type_enum) == b1_v1_type));
22516 /** Insert gl_SkipComponents
22518 * @param num_components How many gl_SkipComponents1 need to be inserted
22519 * @param varyings The transform feedback varyings string vector
22522 void XFBGetProgramResourceAPITest::insertSkipComponents(int num_components, Utils::Program::NameVector& varyings)
22524 int num_component_4 = num_components / 4;
22525 int num_component_1 = num_components % 4;
22526 for (int i = 0; i < num_component_4; i++)
22528 varyings.push_back("gl_SkipComponents4");
22530 switch (num_component_1)
22533 varyings.push_back("gl_SkipComponents1");
22536 varyings.push_back("gl_SkipComponents2");
22539 varyings.push_back("gl_SkipComponents3");
22548 * @param test_case_index Id of test case
22550 * @return true if test case pass, false otherwise
22552 bool XFBGetProgramResourceAPITest::testCase(GLuint test_case_index)
22554 const std::string& gs_source = getShaderSource(test_case_index, Utils::Shader::GEOMETRY);
22555 Utils::Program program(m_context);
22556 const std::string& tcs_source = getShaderSource(test_case_index, Utils::Shader::TESS_CTRL);
22557 const std::string& tes_source = getShaderSource(test_case_index, Utils::Shader::TESS_EVAL);
22558 const test_Case& test_case = m_test_cases[test_case_index];
22559 bool test_case_result = true;
22560 const std::string& vs_source = getShaderSource(test_case_index, Utils::Shader::VERTEX);
22562 // According to spec: gl_SkipComponents1 ~ gl_SkipComponents4 is treated as specifying a one- to four-component floating point output variables with undefined values.
22563 // 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.
22565 if (INTERLEAVED == test_case.m_case)
22568 layout (xfb_buffer = 0, xfb_offset = 1 * type_size) out type b0_v1;
22569 layout (xfb_buffer = 1, xfb_offset = 1 * type_size) out type b1_v1;
22570 layout (xfb_buffer = 0, xfb_offset = 3 * type_size) out type b0_v3;
22571 layout (xfb_buffer = 0, xfb_offset = 0 * type_size) out type b0_v0;
22573 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,
22574 we need to calculate how many "gl_SkipComponents" need to be inserted.
22576 Utils::Program::NameVector captured_varyings;
22577 captured_varyings.push_back("b0_v0");
22578 captured_varyings.push_back("b0_v1");
22579 // Compute how many gl_SkipComponents to be inserted
22580 int numComponents = test_case.m_type.GetSize() / 4;
22581 insertSkipComponents(numComponents, captured_varyings);
22582 captured_varyings.push_back("b0_v3");
22583 captured_varyings.push_back("gl_NextBuffer");
22584 insertSkipComponents(numComponents, captured_varyings);
22585 captured_varyings.push_back("b1_v1");
22586 insertSkipComponents(numComponents * 2, captured_varyings);
22588 program.Init("" /* cs */, "", gs_source, tcs_source, tes_source, vs_source, captured_varyings, true,
22589 true /* separable */);
22591 else if (SEPARATED == test_case.m_case)
22593 Utils::Program::NameVector captured_varyings;
22595 captured_varyings.push_back("b0_v0");
22596 captured_varyings.push_back("b0_v1");
22597 captured_varyings.push_back("b0_v3");
22598 captured_varyings.push_back("b1_v1");
22600 program.Init("" /* cs */, "", gs_source, tcs_source, tes_source, vs_source, captured_varyings, false,
22601 true /* separable */);
22606 program.Init("" /* cs */, "", gs_source, tcs_source, tes_source, vs_source, true /* separable */);
22609 test_case_result = inspectProgram(test_case_index, program);
22611 return test_case_result;
22614 /** Prepare all test cases
22617 void XFBGetProgramResourceAPITest::testInit()
22619 const Functions& gl = m_context.getRenderContext().getFunctions();
22620 const GLuint n_types = getTypesNumber();
22624 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_xfb_int);
22625 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
22627 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, &max_xfb_sep);
22628 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
22630 GLint max_varyings;
22631 gl.getIntegerv(GL_MAX_VARYING_COMPONENTS, &max_varyings);
22633 for (GLuint i = 0; i < n_types; ++i)
22635 // 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,
22636 // 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
22637 // shader valid, we can either skip the dmat4, dmat4x3 or query the implementation-dependent value MAX_VARYING_COMPONENTS before generating the shader
22638 // to guarantee the number of varying not exceeded.
22640 layout (xfb_buffer = 1, xfb_stride = 4 * type_size) out;
22641 layout (xfb_buffer = 0, xfb_offset = 1 * type_size) out type b0_v1;
22642 layout (xfb_buffer = 1, xfb_offset = 1 * type_size) out type b1_v1;
22643 layout (xfb_buffer = 0, xfb_offset = 3 * type_size) out type b0_v3;
22644 layout (xfb_buffer = 0, xfb_offset = 0 * type_size) out type b0_v0;
22648 if (i == 7 || i == 9)
22650 const Utils::Type& type = getType(i);
22651 if (4 * type.GetNumComponents() + 4 > (GLuint)max_varyings)
22655 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
22658 It is invalid to define transform feedback output in HS
22660 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
22661 (Utils::Shader::FRAGMENT == stage))
22666 test_Case test_case_int = { INTERLEAVED, (Utils::Shader::STAGES)stage, type };
22667 test_Case test_case_sep = { SEPARATED, (Utils::Shader::STAGES)stage, type };
22668 test_Case test_case_xfb = { XFB, (Utils::Shader::STAGES)stage, type };
22670 if ((int)type.GetSize() <= max_xfb_int)
22672 m_test_cases.push_back(test_case_xfb);
22673 m_test_cases.push_back(test_case_int);
22676 if ((int)type.GetSize() <= max_xfb_sep)
22678 m_test_cases.push_back(test_case_sep);
22686 * @param context Test context
22688 XFBOverrideQualifiersWithAPITest::XFBOverrideQualifiersWithAPITest(deqp::Context& context)
22689 : BufferTestBase(context, "xfb_override_qualifiers_with_api",
22690 "Test verifies that xfb_offset qualifier is not overriden with API")
22692 /* Nothing to be done here */
22695 /** Get descriptors of buffers necessary for test
22697 * @param test_case_index Index of test case
22698 * @param out_descriptors Descriptors of buffers used by test
22700 void XFBOverrideQualifiersWithAPITest::getBufferDescriptors(glw::GLuint test_case_index,
22701 bufferDescriptor::Vector& out_descriptors)
22703 const Utils::Type& type = getType(test_case_index);
22705 /* Test needs single uniform and xfb */
22706 out_descriptors.resize(2);
22708 /* Get references */
22709 bufferDescriptor& uniform = out_descriptors[0];
22710 bufferDescriptor& xfb = out_descriptors[1];
22713 uniform.m_index = 0;
22717 uniform.m_target = Utils::Buffer::Uniform;
22718 xfb.m_target = Utils::Buffer::Transform_feedback;
22721 const GLuint gen_start = Utils::s_rand;
22722 const std::vector<GLubyte>& vegeta_data = type.GenerateData();
22723 const std::vector<GLubyte>& trunks_data = type.GenerateData();
22724 const std::vector<GLubyte>& goku_data = type.GenerateData();
22725 const std::vector<GLubyte>& gohan_data = type.GenerateData();
22727 Utils::s_rand = gen_start;
22728 const std::vector<GLubyte>& vegeta_data_pck = type.GenerateDataPacked();
22730 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)
22731 how can make them equal ? is it as designed? Add the following statement, which can make sure goku_data_pck equals to goku_data
22733 const std::vector<GLubyte>& goku_data_pck = type.GenerateDataPacked();
22735 const GLuint type_size = static_cast<GLuint>(vegeta_data.size());
22736 const GLuint type_size_pck = static_cast<GLuint>(vegeta_data_pck.size());
22739 uniform.m_initial_data.resize(4 * type_size);
22740 memcpy(&uniform.m_initial_data[0] + 0, &vegeta_data[0], type_size);
22741 memcpy(&uniform.m_initial_data[0] + type_size, &trunks_data[0], type_size);
22742 memcpy(&uniform.m_initial_data[0] + 2 * type_size, &goku_data[0], type_size);
22743 memcpy(&uniform.m_initial_data[0] + 3 * type_size, &gohan_data[0], type_size);
22746 xfb.m_initial_data.resize(4 * type_size_pck);
22747 xfb.m_expected_data.resize(4 * type_size_pck);
22749 for (GLuint i = 0; i < 4 * type_size_pck; ++i)
22751 xfb.m_initial_data[i] = (glw::GLubyte)i;
22752 xfb.m_expected_data[i] = (glw::GLubyte)i;
22755 memcpy(&xfb.m_expected_data[0] + 0, &goku_data_pck[0], type_size_pck);
22756 memcpy(&xfb.m_expected_data[0] + 2 * type_size_pck, &vegeta_data_pck[0], type_size_pck);
22759 /** Get list of names of varyings that will be registered with TransformFeedbackVaryings
22762 * @param captured_varyings List of names
22764 void XFBOverrideQualifiersWithAPITest::getCapturedVaryings(glw::GLuint /* test_case_index */,
22765 Utils::Program::NameVector& captured_varyings)
22767 captured_varyings.resize(2);
22769 captured_varyings[0] = "trunks";
22770 captured_varyings[1] = "gohan";
22773 /** Get body of main function for given shader stage
22775 * @param test_case_index Index of test case
22776 * @param stage Shader stage
22777 * @param out_assignments Set to empty
22778 * @param out_calculations Set to empty
22780 void XFBOverrideQualifiersWithAPITest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
22781 std::string& out_assignments, std::string& out_calculations)
22783 out_calculations = "";
22785 static const GLchar* gs = " vegeta = uni_vegeta;\n"
22786 " trunks = uni_trunks;\n"
22787 " goku = uni_goku;\n"
22788 " gohan = uni_gohan;\n";
22789 static const GLchar* fs = " fs_out = vec4(0);\n"
22790 " if (TYPE(1) == gohan + goku + trunks + vegeta)\n"
22792 " fs_out = vec4(1);\n"
22795 const GLchar* assignments = "";
22798 case Utils::Shader::FRAGMENT:
22801 case Utils::Shader::GEOMETRY:
22808 out_assignments = assignments;
22810 if (Utils::Shader::FRAGMENT == stage)
22812 const Utils::Type& type = getType(test_case_index);
22814 Utils::replaceAllTokens("TYPE", type.GetGLSLTypeName(), out_assignments);
22818 /** Get interface of shader
22820 * @param test_case_index Index of test case
22821 * @param stage Shader stage
22822 * @param out_interface Set to ""
22824 void XFBOverrideQualifiersWithAPITest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
22825 std::string& out_interface)
22827 static const GLchar* gs = "const uint sizeof_type = SIZE;\n"
22829 "layout (xfb_offset = 2 * sizeof_type) flat out TYPE vegeta;\n"
22830 " flat out TYPE trunks;\n"
22831 "layout (xfb_offset = 0) flat out TYPE goku;\n"
22832 " flat out TYPE gohan;\n"
22835 There is no packing qualifier for uniform block gs_block, according to spec, it should be "shared" by default,
22836 the definition equals to "layout(binding=0, shared)", if the block is declared as shared, each block member will
22837 not be packed, and each block member's layout in memory is implementation dependent, so we can't use the API
22838 glBufferData() to update the UBO directly, we need to query each block member's offset first, then upload the
22839 data to the corresponding offset, otherwise we can't get the correct data from UBO; to make the test passed,
22840 we need to add the qualifier std140, and change the declaration as layout(binding=0, std140), which can make
22841 sure all the block members are packed and the application can upload the data by glBufferData() directly.
22843 "layout(binding = 0, std140) uniform gs_block {\n"
22844 " TYPE uni_vegeta;\n"
22845 " TYPE uni_trunks;\n"
22846 " TYPE uni_goku;\n"
22847 " TYPE uni_gohan;\n"
22849 static const GLchar* fs = "flat in TYPE vegeta;\n"
22850 "flat in TYPE trunks;\n"
22851 "flat in TYPE goku;\n"
22852 "flat in TYPE gohan;\n"
22854 "out vec4 fs_out;\n";
22856 const Utils::Type& type = getType(test_case_index);
22860 case Utils::Shader::FRAGMENT:
22861 out_interface = fs;
22863 case Utils::Shader::GEOMETRY:
22864 out_interface = gs;
22867 out_interface = "";
22871 if (Utils::Shader::GEOMETRY == stage)
22874 size_t position = 0;
22875 const GLuint type_size = type.GetSize();
22877 sprintf(buffer, "%d", type_size);
22879 Utils::replaceToken("SIZE", position, buffer, out_interface);
22882 Utils::replaceAllTokens("TYPE", type.GetGLSLTypeName(), out_interface);
22887 * @param test_case_index Index of test case
22889 * @return Name of type test in test_case_index
22891 std::string XFBOverrideQualifiersWithAPITest::getTestCaseName(glw::GLuint test_case_index)
22893 return getTypeName(test_case_index);
22896 /** Returns number of types to test
22898 * @return Number of types, 34
22900 glw::GLuint XFBOverrideQualifiersWithAPITest::getTestCaseNumber()
22902 return getTypesNumber();
22905 /** Inspects program to check if all resources are as expected
22907 * @param test_case_index Index of test case
22908 * @param program Program instance
22909 * @param out_stream Error message
22911 * @return true if everything is ok, false otherwise
22913 bool XFBOverrideQualifiersWithAPITest::inspectProgram(GLuint test_case_index, Utils::Program& program,
22914 std::stringstream& out_stream)
22917 const Utils::Type& type = getType(test_case_index);
22918 const GLuint type_size = type.GetSize();
22920 program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE,
22921 1 /* buf_size */, &stride);
22923 if ((GLint)(3 * type_size) != stride)
22925 out_stream << "Stride is: " << stride << " expected: " << (3 * type_size);
22935 * @param context Test context
22937 XFBVertexStreamsTest::XFBVertexStreamsTest(deqp::Context& context)
22938 : BufferTestBase(context, "xfb_vertex_streams",
22939 "Test verifies that xfb qualifier works with multiple output streams")
22941 /* Nothing to be done here */
22944 /** Get descriptors of buffers necessary for test
22947 * @param out_descriptors Descriptors of buffers used by test
22949 void XFBVertexStreamsTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
22950 bufferDescriptor::Vector& out_descriptors)
22952 const Utils::Type& type = Utils::Type::vec4;
22954 /* Test needs single uniform and three xfbs */
22955 out_descriptors.resize(4);
22957 /* Get references */
22958 bufferDescriptor& uniform = out_descriptors[0];
22959 bufferDescriptor& xfb_1 = out_descriptors[1];
22960 bufferDescriptor& xfb_2 = out_descriptors[2];
22961 bufferDescriptor& xfb_3 = out_descriptors[3];
22964 uniform.m_index = 0;
22970 uniform.m_target = Utils::Buffer::Uniform;
22971 xfb_1.m_target = Utils::Buffer::Transform_feedback;
22972 xfb_2.m_target = Utils::Buffer::Transform_feedback;
22973 xfb_3.m_target = Utils::Buffer::Transform_feedback;
22976 const std::vector<GLubyte>& goku_data = type.GenerateData();
22977 const std::vector<GLubyte>& gohan_data = type.GenerateData();
22978 const std::vector<GLubyte>& goten_data = type.GenerateData();
22979 const std::vector<GLubyte>& picolo_data = type.GenerateData();
22980 const std::vector<GLubyte>& vegeta_data = type.GenerateData();
22981 const std::vector<GLubyte>& bulma_data = type.GenerateData();
22983 const GLuint type_size = static_cast<GLuint>(vegeta_data.size());
22986 uniform.m_initial_data.resize(6 * type_size);
22987 memcpy(&uniform.m_initial_data[0] + 0, &goku_data[0], type_size);
22988 memcpy(&uniform.m_initial_data[0] + type_size, &gohan_data[0], type_size);
22989 memcpy(&uniform.m_initial_data[0] + 2 * type_size, &goten_data[0], type_size);
22990 memcpy(&uniform.m_initial_data[0] + 3 * type_size, &picolo_data[0], type_size);
22991 memcpy(&uniform.m_initial_data[0] + 4 * type_size, &vegeta_data[0], type_size);
22992 memcpy(&uniform.m_initial_data[0] + 5 * type_size, &bulma_data[0], type_size);
22995 static const GLuint xfb_stride = 64;
22996 xfb_1.m_initial_data.resize(xfb_stride);
22997 xfb_1.m_expected_data.resize(xfb_stride);
22998 xfb_2.m_initial_data.resize(xfb_stride);
22999 xfb_2.m_expected_data.resize(xfb_stride);
23000 xfb_3.m_initial_data.resize(xfb_stride);
23001 xfb_3.m_expected_data.resize(xfb_stride);
23003 for (GLuint i = 0; i < xfb_stride; ++i)
23005 xfb_1.m_initial_data[i] = (glw::GLubyte)i;
23006 xfb_1.m_expected_data[i] = (glw::GLubyte)i;
23007 xfb_2.m_initial_data[i] = (glw::GLubyte)i;
23008 xfb_2.m_expected_data[i] = (glw::GLubyte)i;
23009 xfb_3.m_initial_data[i] = (glw::GLubyte)i;
23010 xfb_3.m_expected_data[i] = (glw::GLubyte)i;
23013 memcpy(&xfb_1.m_expected_data[0] + 48, &goku_data[0], type_size);
23014 memcpy(&xfb_1.m_expected_data[0] + 32, &gohan_data[0], type_size);
23015 memcpy(&xfb_1.m_expected_data[0] + 16, &goten_data[0], type_size);
23016 memcpy(&xfb_3.m_expected_data[0] + 48, &picolo_data[0], type_size);
23017 memcpy(&xfb_3.m_expected_data[0] + 32, &vegeta_data[0], type_size);
23018 memcpy(&xfb_2.m_expected_data[0] + 32, &bulma_data[0], type_size);
23021 /** Get body of main function for given shader stage
23024 * @param stage Shader stage
23025 * @param out_assignments Set to empty
23026 * @param out_calculations Set to empty
23028 void XFBVertexStreamsTest::getShaderBody(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
23029 std::string& out_assignments, std::string& out_calculations)
23031 out_calculations = "";
23033 // the shader declares the output variables with different "stream" qualifier, to make the data can export to
23034 // each stream, we must call the function EmitStreamVertex() and EndStreamPrimitive() to make each vertex emitted
23035 // by the GS is assigned to specific stream.
23036 static const GLchar* gs = " goku = uni_goku;\n"
23037 " gohan = uni_gohan;\n"
23038 " goten = uni_goten;\n"
23039 " EmitStreamVertex(0);\n"
23040 " EndStreamPrimitive(0);\n"
23041 " picolo = uni_picolo;\n"
23042 " vegeta = uni_vegeta;\n"
23043 " EmitStreamVertex(1);\n"
23044 " EndStreamPrimitive(1);\n"
23045 " bulma = uni_bulma;\n"
23046 " EmitStreamVertex(2);\n"
23047 " EndStreamPrimitive(2);\n";
23049 static const GLchar* fs = " fs_out = gohan + goku + goten + picolo + vegeta + bulma;\n";
23051 const GLchar* assignments = "";
23054 case Utils::Shader::FRAGMENT:
23057 case Utils::Shader::GEOMETRY:
23064 out_assignments = assignments;
23067 /** Get interface of shader
23070 * @param stage Shader stage
23071 * @param out_interface Set to ""
23073 void XFBVertexStreamsTest::getShaderInterface(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
23074 std::string& out_interface)
23076 static const GLchar* gs = "layout (xfb_buffer = 1, xfb_stride = 64) out;\n"
23077 "layout (xfb_buffer = 2, xfb_stride = 64) out;\n"
23078 "layout (xfb_buffer = 3, xfb_stride = 64) out;\n"
23080 "layout (stream = 0, xfb_buffer = 1, xfb_offset = 48) out vec4 goku;\n"
23081 "layout (stream = 0, xfb_buffer = 1, xfb_offset = 32) out vec4 gohan;\n"
23082 "layout (stream = 0, xfb_buffer = 1, xfb_offset = 16) out vec4 goten;\n"
23083 "layout (stream = 1, xfb_buffer = 3, xfb_offset = 48) out vec4 picolo;\n"
23084 "layout (stream = 1, xfb_buffer = 3, xfb_offset = 32) out vec4 vegeta;\n"
23085 "layout (stream = 2, xfb_buffer = 2, xfb_offset = 32) out vec4 bulma;\n"
23087 "layout(binding = 0) uniform gs_block {\n"
23088 " vec4 uni_goku;\n"
23089 " vec4 uni_gohan;\n"
23090 " vec4 uni_goten;\n"
23091 " vec4 uni_picolo;\n"
23092 " vec4 uni_vegeta;\n"
23093 " vec4 uni_bulma;\n"
23096 Fixed incorrect usage of in/out qualifier, the following variable should be input symbols for fragment shader
23098 static const GLchar* fs = "in vec4 goku;\n"
23101 "in vec4 picolo;\n"
23102 "in vec4 vegeta;\n"
23105 "out vec4 fs_out;\n";
23109 case Utils::Shader::FRAGMENT:
23110 out_interface = fs;
23112 case Utils::Shader::GEOMETRY:
23113 out_interface = gs;
23116 out_interface = "";
23123 * @param context Test framework context
23125 XFBMultipleVertexStreamsTest::XFBMultipleVertexStreamsTest(deqp::Context& context)
23126 : NegativeTestBase(
23127 context, "xfb_multiple_vertex_streams",
23128 "Test verifies that compiler reports error when multiple streams are captured with same xfb_buffer")
23132 /** Source for given test case and stage
23135 * @param stage Shader stage
23137 * @return Shader source
23139 std::string XFBMultipleVertexStreamsTest::getShaderSource(GLuint /* test_case_index */, Utils::Shader::STAGES stage)
23141 static const GLchar* var_definition = "const uint valid_stride = 64;\n"
23143 "layout (xfb_buffer = 1, xfb_stride = valid_stride) out;\n"
23144 "layout (xfb_buffer = 3, xfb_stride = valid_stride) out;\n"
23147 "layout (stream = 0, xfb_buffer = 1, xfb_offset = 48) out vec4 goku;\n"
23148 "layout (stream = 1, xfb_buffer = 1, xfb_offset = 32) out vec4 gohan;\n"
23149 "layout (stream = 2, xfb_buffer = 1, xfb_offset = 16) out vec4 goten;\n";
23150 static const GLchar* var_use = " goku = result / 2;\n"
23151 " gohan = result / 4;\n"
23152 " goten = result / 6;\n";
23153 static const GLchar* fs = "#version 430 core\n"
23154 "#extension GL_ARB_enhanced_layouts : require\n"
23158 "out vec4 fs_out;\n"
23162 " fs_out = gs_fs + goku;\n"
23165 static const GLchar* gs = "#version 430 core\n"
23166 "#extension GL_ARB_enhanced_layouts : require\n"
23168 "layout(points) in;\n"
23169 "layout(triangle_strip, max_vertices = 4) out;\n"
23173 "in vec4 tes_gs[];\n"
23174 "out vec4 gs_fs;\n"
23178 " vec4 result = tes_gs[0];\n"
23182 " gs_fs = result;\n"
23183 " gl_Position = vec4(-1, -1, 0, 1);\n"
23185 " gs_fs = result;\n"
23186 " gl_Position = vec4(-1, 1, 0, 1);\n"
23188 " gs_fs = result;\n"
23189 " gl_Position = vec4(1, -1, 0, 1);\n"
23191 " gs_fs = result;\n"
23192 " gl_Position = vec4(1, 1, 0, 1);\n"
23196 static const GLchar* vs = "#version 430 core\n"
23197 "#extension GL_ARB_enhanced_layouts : require\n"
23200 "out vec4 vs_tcs;\n"
23204 " vs_tcs = in_vs;\n"
23208 std::string source;
23210 if (Utils::Shader::GEOMETRY == stage)
23212 size_t position = 0;
23216 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
23217 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
23223 case Utils::Shader::FRAGMENT:
23226 case Utils::Shader::VERTEX:
23237 /** Selects if "compute" stage is relevant for test
23243 bool XFBMultipleVertexStreamsTest::isComputeRelevant(GLuint /* test_case_index */)
23250 * @param context Test framework context
23252 XFBExceedBufferLimitTest::XFBExceedBufferLimitTest(deqp::Context& context)
23253 : NegativeTestBase(context, "xfb_exceed_buffer_limit",
23254 "Test verifies that compiler reports error when xfb_buffer qualifier exceeds limit")
23258 /** Source for given test case and stage
23260 * @param test_case_index Index of test case
23261 * @param stage Shader stage
23263 * @return Shader source
23265 std::string XFBExceedBufferLimitTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
23267 static const GLchar* block_var_definition = "const uint buffer_index = BUFFER;\n"
23269 "layout (xfb_buffer = buffer_index, xfb_offset = 0) out Goku {\n"
23272 static const GLchar* global_var_definition = "const uint buffer_index = BUFFER;\n"
23274 "layout (xfb_buffer = buffer_index) out;\n";
23275 static const GLchar* vector_var_definition = "const uint buffer_index = BUFFER;\n"
23277 "layout (xfb_buffer = buffer_index) out vec4 gokuARRAY;\n";
23278 static const GLchar* block_use = " gokuINDEX.member = result / 2;\n";
23279 static const GLchar* global_use = "";
23280 static const GLchar* vector_use = " gokuINDEX = result / 2;\n";
23281 static const GLchar* fs = "#version 430 core\n"
23282 "#extension GL_ARB_enhanced_layouts : require\n"
23285 "out vec4 fs_out;\n"
23289 " fs_out = gs_fs;\n"
23292 static const GLchar* gs_tested = "#version 430 core\n"
23293 "#extension GL_ARB_enhanced_layouts : require\n"
23295 "layout(points) in;\n"
23296 "layout(triangle_strip, max_vertices = 4) out;\n"
23300 "in vec4 tes_gs[];\n"
23301 "out vec4 gs_fs;\n"
23305 " vec4 result = tes_gs[0];\n"
23309 " gs_fs = result;\n"
23310 " gl_Position = vec4(-1, -1, 0, 1);\n"
23312 " gs_fs = result;\n"
23313 " gl_Position = vec4(-1, 1, 0, 1);\n"
23315 " gs_fs = result;\n"
23316 " gl_Position = vec4(1, -1, 0, 1);\n"
23318 " gs_fs = result;\n"
23319 " gl_Position = vec4(1, 1, 0, 1);\n"
23323 static const GLchar* tcs = "#version 430 core\n"
23324 "#extension GL_ARB_enhanced_layouts : require\n"
23326 "layout(vertices = 1) out;\n"
23328 "in vec4 vs_tcs[];\n"
23329 "out vec4 tcs_tes[];\n"
23334 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
23336 " gl_TessLevelOuter[0] = 1.0;\n"
23337 " gl_TessLevelOuter[1] = 1.0;\n"
23338 " gl_TessLevelOuter[2] = 1.0;\n"
23339 " gl_TessLevelOuter[3] = 1.0;\n"
23340 " gl_TessLevelInner[0] = 1.0;\n"
23341 " gl_TessLevelInner[1] = 1.0;\n"
23344 static const GLchar* tcs_tested = "#version 430 core\n"
23345 "#extension GL_ARB_enhanced_layouts : require\n"
23347 "layout(vertices = 1) out;\n"
23351 "in vec4 vs_tcs[];\n"
23352 "out vec4 tcs_tes[];\n"
23356 " vec4 result = vs_tcs[gl_InvocationID];\n"
23360 " tcs_tes[gl_InvocationID] = result;\n"
23362 " gl_TessLevelOuter[0] = 1.0;\n"
23363 " gl_TessLevelOuter[1] = 1.0;\n"
23364 " gl_TessLevelOuter[2] = 1.0;\n"
23365 " gl_TessLevelOuter[3] = 1.0;\n"
23366 " gl_TessLevelInner[0] = 1.0;\n"
23367 " gl_TessLevelInner[1] = 1.0;\n"
23370 static const GLchar* tes_tested = "#version 430 core\n"
23371 "#extension GL_ARB_enhanced_layouts : require\n"
23373 "layout(isolines, point_mode) in;\n"
23377 "in vec4 tcs_tes[];\n"
23378 "out vec4 tes_gs;\n"
23382 " vec4 result = tcs_tes[0];\n"
23386 " tes_gs += result;\n"
23389 static const GLchar* vs = "#version 430 core\n"
23390 "#extension GL_ARB_enhanced_layouts : require\n"
23393 "out vec4 vs_tcs;\n"
23397 " vs_tcs = in_vs;\n"
23400 static const GLchar* vs_tested = "#version 430 core\n"
23401 "#extension GL_ARB_enhanced_layouts : require\n"
23406 "out vec4 vs_tcs;\n"
23410 " vec4 result = in_vs;\n"
23414 " vs_tcs = result;\n"
23418 std::string source;
23419 testCase& test_case = m_test_cases[test_case_index];
23421 if (test_case.m_stage == stage)
23423 const GLchar* array = "";
23425 const Functions& gl = m_context.getRenderContext().getFunctions();
23426 const GLchar* index = "";
23427 GLint max_n_xfb = 0;
23428 size_t position = 0;
23430 const GLchar* var_definition = 0;
23431 const GLchar* var_use = 0;
23433 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_n_xfb);
23434 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
23436 sprintf(buffer, "%d", max_n_xfb);
23438 switch (test_case.m_case)
23441 var_definition = block_var_definition;
23442 var_use = block_use;
23445 var_definition = global_var_definition;
23446 var_use = global_use;
23449 var_definition = vector_var_definition;
23450 var_use = vector_use;
23453 TCU_FAIL("Invalid enum");
23458 case Utils::Shader::GEOMETRY:
23459 source = gs_tested;
23463 case Utils::Shader::TESS_CTRL:
23464 source = tcs_tested;
23466 index = "[gl_InvocationID]";
23468 case Utils::Shader::TESS_EVAL:
23469 source = tes_tested;
23473 case Utils::Shader::VERTEX:
23474 source = vs_tested;
23477 TCU_FAIL("Invalid enum");
23481 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
23483 Utils::replaceToken("BUFFER", position, buffer, source);
23484 if (GLOBAL != test_case.m_case)
23486 Utils::replaceToken("ARRAY", position, array, source);
23488 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
23490 Utils::replaceAllTokens("INDEX", index, source);
23494 switch (test_case.m_stage)
23496 case Utils::Shader::GEOMETRY:
23499 case Utils::Shader::FRAGMENT:
23502 case Utils::Shader::VERTEX:
23509 case Utils::Shader::TESS_CTRL:
23512 case Utils::Shader::FRAGMENT:
23515 case Utils::Shader::VERTEX:
23522 case Utils::Shader::TESS_EVAL:
23525 case Utils::Shader::FRAGMENT:
23528 case Utils::Shader::TESS_CTRL:
23531 case Utils::Shader::VERTEX:
23538 case Utils::Shader::VERTEX:
23541 case Utils::Shader::FRAGMENT:
23549 TCU_FAIL("Invalid enum");
23557 /** Get description of test case
23559 * @param test_case_index Index of test case
23561 * @return Test case description
23563 std::string XFBExceedBufferLimitTest::getTestCaseName(GLuint test_case_index)
23565 std::stringstream stream;
23566 testCase& test_case = m_test_cases[test_case_index];
23568 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", case: ";
23570 switch (test_case.m_case)
23576 stream << "GLOBAL";
23579 stream << "VECTOR";
23582 TCU_FAIL("Invalid enum");
23585 return stream.str();
23588 /** Get number of test cases
23590 * @return Number of test cases
23592 GLuint XFBExceedBufferLimitTest::getTestCaseNumber()
23594 return static_cast<GLuint>(m_test_cases.size());
23597 /** Selects if "compute" stage is relevant for test
23603 bool XFBExceedBufferLimitTest::isComputeRelevant(GLuint /* test_case_index */)
23608 /** Prepare all test cases
23611 void XFBExceedBufferLimitTest::testInit()
23613 for (GLuint c = 0; c < CASE_MAX; ++c)
23615 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
23617 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
23618 (Utils::Shader::FRAGMENT == stage))
23623 testCase test_case = { (CASES)c, (Utils::Shader::STAGES)stage };
23625 m_test_cases.push_back(test_case);
23632 * @param context Test framework context
23634 XFBExceedOffsetLimitTest::XFBExceedOffsetLimitTest(deqp::Context& context)
23635 : NegativeTestBase(context, "xfb_exceed_offset_limit",
23636 "Test verifies that compiler reports error when xfb_offset qualifier exceeds limit")
23640 /** Source for given test case and stage
23642 * @param test_case_index Index of test case
23643 * @param stage Shader stage
23645 * @return Shader source
23647 std::string XFBExceedOffsetLimitTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
23649 static const GLchar* block_var_definition = "const uint max_size = SIZE;\n"
23651 "layout (xfb_buffer = 0, xfb_offset = max_size + 16) out Goku {\n"
23654 static const GLchar* global_var_definition = "const uint max_size = SIZE;\n"
23656 "layout (xfb_buffer = 0, xfb_stride = max_size + 16) out;\n";
23657 static const GLchar* vector_var_definition =
23658 "const uint max_size = SIZE;\n"
23660 "layout (xfb_buffer = 0, xfb_offset = max_size + 16) out vec4 gokuARRAY;\n";
23661 static const GLchar* block_use = " gokuINDEX.member = result / 2;\n";
23662 static const GLchar* global_use = "";
23663 static const GLchar* vector_use = " gokuINDEX = result / 2;\n";
23664 static const GLchar* fs = "#version 430 core\n"
23665 "#extension GL_ARB_enhanced_layouts : require\n"
23668 "out vec4 fs_out;\n"
23672 " fs_out = gs_fs;\n"
23675 static const GLchar* gs_tested = "#version 430 core\n"
23676 "#extension GL_ARB_enhanced_layouts : require\n"
23678 "layout(points) in;\n"
23679 "layout(triangle_strip, max_vertices = 4) out;\n"
23683 "in vec4 tes_gs[];\n"
23684 "out vec4 gs_fs;\n"
23688 " vec4 result = tes_gs[0];\n"
23692 " gs_fs = result;\n"
23693 " gl_Position = vec4(-1, -1, 0, 1);\n"
23695 " gs_fs = result;\n"
23696 " gl_Position = vec4(-1, 1, 0, 1);\n"
23698 " gs_fs = result;\n"
23699 " gl_Position = vec4(1, -1, 0, 1);\n"
23701 " gs_fs = result;\n"
23702 " gl_Position = vec4(1, 1, 0, 1);\n"
23706 static const GLchar* tcs = "#version 430 core\n"
23707 "#extension GL_ARB_enhanced_layouts : require\n"
23709 "layout(vertices = 1) out;\n"
23711 "in vec4 vs_tcs[];\n"
23712 "out vec4 tcs_tes[];\n"
23717 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
23719 " gl_TessLevelOuter[0] = 1.0;\n"
23720 " gl_TessLevelOuter[1] = 1.0;\n"
23721 " gl_TessLevelOuter[2] = 1.0;\n"
23722 " gl_TessLevelOuter[3] = 1.0;\n"
23723 " gl_TessLevelInner[0] = 1.0;\n"
23724 " gl_TessLevelInner[1] = 1.0;\n"
23727 static const GLchar* tcs_tested = "#version 430 core\n"
23728 "#extension GL_ARB_enhanced_layouts : require\n"
23730 "layout(vertices = 1) out;\n"
23734 "in vec4 vs_tcs[];\n"
23735 "out vec4 tcs_tes[];\n"
23739 " vec4 result = vs_tcs[gl_InvocationID];\n"
23743 " tcs_tes[gl_InvocationID] = result;\n"
23745 " gl_TessLevelOuter[0] = 1.0;\n"
23746 " gl_TessLevelOuter[1] = 1.0;\n"
23747 " gl_TessLevelOuter[2] = 1.0;\n"
23748 " gl_TessLevelOuter[3] = 1.0;\n"
23749 " gl_TessLevelInner[0] = 1.0;\n"
23750 " gl_TessLevelInner[1] = 1.0;\n"
23753 static const GLchar* tes_tested = "#version 430 core\n"
23754 "#extension GL_ARB_enhanced_layouts : require\n"
23756 "layout(isolines, point_mode) in;\n"
23760 "in vec4 tcs_tes[];\n"
23761 "out vec4 tes_gs;\n"
23765 " vec4 result = tcs_tes[0];\n"
23769 " tes_gs += result;\n"
23772 static const GLchar* vs = "#version 430 core\n"
23773 "#extension GL_ARB_enhanced_layouts : require\n"
23776 "out vec4 vs_tcs;\n"
23780 " vs_tcs = in_vs;\n"
23783 static const GLchar* vs_tested = "#version 430 core\n"
23784 "#extension GL_ARB_enhanced_layouts : require\n"
23789 "out vec4 vs_tcs;\n"
23793 " vec4 result = in_vs;\n"
23797 " vs_tcs = result;\n"
23801 std::string source;
23802 testCase& test_case = m_test_cases[test_case_index];
23804 if (test_case.m_stage == stage)
23806 const GLchar* array = "";
23808 const Functions& gl = m_context.getRenderContext().getFunctions();
23809 const GLchar* index = "";
23810 GLint max_n_xfb_comp = 0;
23811 GLint max_n_xfb_bytes = 0;
23812 size_t position = 0;
23814 const GLchar* var_definition = 0;
23815 const GLchar* var_use = 0;
23817 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_n_xfb_comp);
23818 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
23820 max_n_xfb_bytes = max_n_xfb_comp * 4;
23822 sprintf(buffer, "%d", max_n_xfb_bytes);
23824 switch (test_case.m_case)
23827 var_definition = block_var_definition;
23828 var_use = block_use;
23831 var_definition = global_var_definition;
23832 var_use = global_use;
23835 var_definition = vector_var_definition;
23836 var_use = vector_use;
23839 TCU_FAIL("Invalid enum");
23841 // It is a compile time error to apply xfb_offset to the declaration of an unsized array(GLSL4.5 spec: Page73)
23842 // change array = "[]" to "[1]"
23845 case Utils::Shader::GEOMETRY:
23846 source = gs_tested;
23850 case Utils::Shader::TESS_CTRL:
23851 source = tcs_tested;
23853 index = "[gl_InvocationID]";
23855 case Utils::Shader::TESS_EVAL:
23856 source = tes_tested;
23860 case Utils::Shader::VERTEX:
23861 source = vs_tested;
23864 TCU_FAIL("Invalid enum");
23868 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
23870 Utils::replaceToken("SIZE", position, buffer, source);
23871 if (GLOBAL != test_case.m_case)
23873 Utils::replaceToken("ARRAY", position, array, source);
23875 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
23877 Utils::replaceAllTokens("INDEX", index, source);
23881 switch (test_case.m_stage)
23883 case Utils::Shader::GEOMETRY:
23886 case Utils::Shader::FRAGMENT:
23889 case Utils::Shader::VERTEX:
23896 case Utils::Shader::TESS_CTRL:
23899 case Utils::Shader::FRAGMENT:
23902 case Utils::Shader::VERTEX:
23909 case Utils::Shader::TESS_EVAL:
23912 case Utils::Shader::FRAGMENT:
23915 case Utils::Shader::TESS_CTRL:
23918 case Utils::Shader::VERTEX:
23925 case Utils::Shader::VERTEX:
23928 case Utils::Shader::FRAGMENT:
23936 TCU_FAIL("Invalid enum");
23944 /** Get description of test case
23946 * @param test_case_index Index of test case
23948 * @return Test case description
23950 std::string XFBExceedOffsetLimitTest::getTestCaseName(GLuint test_case_index)
23952 std::stringstream stream;
23953 testCase& test_case = m_test_cases[test_case_index];
23955 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", case: ";
23957 switch (test_case.m_case)
23963 stream << "GLOBAL";
23966 stream << "VECTOR";
23969 TCU_FAIL("Invalid enum");
23972 return stream.str();
23975 /** Get number of test cases
23977 * @return Number of test cases
23979 GLuint XFBExceedOffsetLimitTest::getTestCaseNumber()
23981 return static_cast<GLuint>(m_test_cases.size());
23984 /** Selects if "compute" stage is relevant for test
23990 bool XFBExceedOffsetLimitTest::isComputeRelevant(GLuint /* test_case_index */)
23995 /** Prepare all test cases
23998 void XFBExceedOffsetLimitTest::testInit()
24000 for (GLuint c = 0; c < CASE_MAX; ++c)
24002 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
24004 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
24005 (Utils::Shader::FRAGMENT == stage))
24010 testCase test_case = { (CASES)c, (Utils::Shader::STAGES)stage };
24012 m_test_cases.push_back(test_case);
24019 * @param context Test context
24021 XFBGlobalBufferTest::XFBGlobalBufferTest(deqp::Context& context)
24022 : BufferTestBase(context, "xfb_global_buffer", "Test verifies that global xfb_buffer qualifier is respected")
24024 /* Nothing to be done here */
24027 /** Get descriptors of buffers necessary for test
24029 * @param test_case_index Index of test case
24030 * @param out_descriptors Descriptors of buffers used by test
24032 void XFBGlobalBufferTest::getBufferDescriptors(glw::GLuint test_case_index, bufferDescriptor::Vector& out_descriptors)
24034 // the function "getType(test_case_index)" can't return correct data type, so change code as following:
24035 const Utils::Type& type = m_test_cases[test_case_index].m_type;
24037 /* Test needs single uniform and two xfbs */
24038 out_descriptors.resize(3);
24040 /* Get references */
24041 bufferDescriptor& uniform = out_descriptors[0];
24042 bufferDescriptor& xfb_1 = out_descriptors[1];
24043 bufferDescriptor& xfb_3 = out_descriptors[2];
24046 uniform.m_index = 0;
24051 uniform.m_target = Utils::Buffer::Uniform;
24052 xfb_1.m_target = Utils::Buffer::Transform_feedback;
24053 xfb_3.m_target = Utils::Buffer::Transform_feedback;
24056 const GLuint gen_start = Utils::s_rand;
24057 const std::vector<GLubyte>& chichi_data = type.GenerateData();
24058 const std::vector<GLubyte>& bulma_data = type.GenerateData();
24059 const std::vector<GLubyte>& trunks_data = type.GenerateData();
24060 const std::vector<GLubyte>& bra_data = type.GenerateData();
24061 const std::vector<GLubyte>& gohan_data = type.GenerateData();
24062 const std::vector<GLubyte>& goten_data = type.GenerateData();
24064 Utils::s_rand = gen_start;
24065 const std::vector<GLubyte>& chichi_data_pck = type.GenerateDataPacked();
24066 const std::vector<GLubyte>& bulma_data_pck = type.GenerateDataPacked();
24067 const std::vector<GLubyte>& trunks_data_pck = type.GenerateDataPacked();
24068 const std::vector<GLubyte>& bra_data_pck = type.GenerateDataPacked();
24069 const std::vector<GLubyte>& gohan_data_pck = type.GenerateDataPacked();
24070 const std::vector<GLubyte>& goten_data_pck = type.GenerateDataPacked();
24072 const GLuint type_size = static_cast<GLuint>(chichi_data.size());
24073 const GLuint type_size_pck = static_cast<GLuint>(chichi_data_pck.size());
24076 uniform.m_initial_data.resize(6 * type_size);
24077 memcpy(&uniform.m_initial_data[0] + 0, &chichi_data[0], type_size);
24078 memcpy(&uniform.m_initial_data[0] + type_size, &bulma_data[0], type_size);
24079 memcpy(&uniform.m_initial_data[0] + 2 * type_size, &trunks_data[0], type_size);
24080 memcpy(&uniform.m_initial_data[0] + 3 * type_size, &bra_data[0], type_size);
24081 memcpy(&uniform.m_initial_data[0] + 4 * type_size, &gohan_data[0], type_size);
24082 memcpy(&uniform.m_initial_data[0] + 5 * type_size, &goten_data[0], type_size);
24085 xfb_1.m_initial_data.resize(3 * type_size_pck);
24086 xfb_1.m_expected_data.resize(3 * type_size_pck);
24087 xfb_3.m_initial_data.resize(3 * type_size_pck);
24088 xfb_3.m_expected_data.resize(3 * type_size_pck);
24090 for (GLuint i = 0; i < 3 * type_size_pck; ++i)
24092 xfb_1.m_initial_data[i] = (glw::GLubyte)i;
24093 xfb_1.m_expected_data[i] = (glw::GLubyte)i;
24094 xfb_3.m_initial_data[i] = (glw::GLubyte)i;
24095 xfb_3.m_expected_data[i] = (glw::GLubyte)i;
24098 memcpy(&xfb_3.m_expected_data[0] + 2 * type_size_pck, &chichi_data_pck[0], type_size_pck);
24099 memcpy(&xfb_1.m_expected_data[0] + 0 * type_size_pck, &bulma_data_pck[0], type_size_pck);
24100 memcpy(&xfb_1.m_expected_data[0] + 1 * type_size_pck, &trunks_data_pck[0], type_size_pck);
24101 memcpy(&xfb_1.m_expected_data[0] + 2 * type_size_pck, &bra_data_pck[0], type_size_pck);
24102 memcpy(&xfb_3.m_expected_data[0] + 0 * type_size_pck, &gohan_data_pck[0], type_size_pck);
24103 memcpy(&xfb_3.m_expected_data[0] + 1 * type_size_pck, &goten_data_pck[0], type_size_pck);
24106 /** Source for given test case and stage
24108 * @param test_case_index Index of test case
24109 * @param stage Shader stage
24111 * @return Shader source
24113 std::string XFBGlobalBufferTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
24115 static const GLchar* fs =
24116 "#version 430 core\n"
24117 "#extension GL_ARB_enhanced_layouts : require\n"
24119 "flat in TYPE chichi;\n"
24120 "flat in TYPE bulma;\n"
24130 "out vec4 fs_out;\n"
24134 " fs_out = vec4(1);\n"
24135 " if (TYPE(1) != chichi + bulma + vegeta.trunk + vegeta.bra + goku.gohan + goku.goten)\n"
24137 " fs_out = vec4(0);\n"
24142 static const GLchar* gs = "#version 430 core\n"
24143 "#extension GL_ARB_enhanced_layouts : require\n"
24145 "layout(points) in;\n"
24146 "layout(points, max_vertices = 1) out;\n"
24157 static const GLchar* tcs = "#version 430 core\n"
24158 "#extension GL_ARB_enhanced_layouts : require\n"
24160 "layout(vertices = 1) out;\n"
24165 " gl_TessLevelOuter[0] = 1.0;\n"
24166 " gl_TessLevelOuter[1] = 1.0;\n"
24167 " gl_TessLevelOuter[2] = 1.0;\n"
24168 " gl_TessLevelOuter[3] = 1.0;\n"
24169 " gl_TessLevelInner[0] = 1.0;\n"
24170 " gl_TessLevelInner[1] = 1.0;\n"
24174 static const GLchar* tes = "#version 430 core\n"
24175 "#extension GL_ARB_enhanced_layouts : require\n"
24177 "layout(isolines, point_mode) in;\n"
24187 static const GLchar* vs = "#version 430 core\n"
24188 "#extension GL_ARB_enhanced_layouts : require\n"
24195 static const GLchar* vs_tested = "#version 430 core\n"
24196 "#extension GL_ARB_enhanced_layouts : require\n"
24206 std::string source;
24207 const _testCase& test_case = m_test_cases[test_case_index];
24208 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
24210 if (test_case.m_stage == stage)
24212 std::string assignments = " chichi = uni_chichi;\n"
24213 " bulma = uni_bulma;\n"
24214 " vegeta.trunk = uni_trunk;\n"
24215 " vegeta.bra = uni_bra;\n"
24216 " goku.gohan = uni_gohan;\n"
24217 " goku.goten = uni_goten;\n";
24219 std::string interface = "layout (xfb_buffer = 3) out;\n"
24221 "const uint type_size = SIZE;\n"
24223 "layout ( xfb_offset = 2 * type_size) flat out TYPE chichi;\n"
24224 "layout (xfb_buffer = 1, xfb_offset = 0) flat out TYPE bulma;\n"
24225 "layout (xfb_buffer = 1, xfb_offset = 1 * type_size) out Vegeta {\n"
24229 "layout ( xfb_offset = 0) out Goku {\n"
24234 // Uniform block must be declared with std140, otherwise each block member is not packed
24235 "layout(binding = 0, std140) uniform block {\n"
24236 " TYPE uni_chichi;\n"
24237 " TYPE uni_bulma;\n"
24238 " TYPE uni_trunk;\n"
24240 " TYPE uni_gohan;\n"
24241 " TYPE uni_goten;\n"
24244 /* Prepare interface string */
24247 size_t position = 0;
24248 const GLuint type_size = test_case.m_type.GetSize();
24250 sprintf(buffer, "%d", type_size);
24252 Utils::replaceToken("SIZE", position, buffer, interface);
24253 Utils::replaceAllTokens("TYPE", type_name, interface);
24258 case Utils::Shader::GEOMETRY:
24261 case Utils::Shader::TESS_EVAL:
24264 case Utils::Shader::VERTEX:
24265 source = vs_tested;
24268 TCU_FAIL("Invalid enum");
24271 /* Replace tokens */
24273 size_t position = 0;
24275 Utils::replaceToken("INTERFACE", position, interface.c_str(), source);
24276 Utils::replaceToken("ASSIGNMENTS", position, assignments.c_str(), source);
24281 switch (test_case.m_stage)
24283 case Utils::Shader::GEOMETRY:
24286 case Utils::Shader::FRAGMENT:
24288 Utils::replaceAllTokens("TYPE", type_name, source);
24290 case Utils::Shader::VERTEX:
24297 case Utils::Shader::TESS_EVAL:
24300 case Utils::Shader::FRAGMENT:
24302 Utils::replaceAllTokens("TYPE", type_name, source);
24304 case Utils::Shader::TESS_CTRL:
24307 case Utils::Shader::VERTEX:
24314 case Utils::Shader::VERTEX:
24317 case Utils::Shader::FRAGMENT:
24319 Utils::replaceAllTokens("TYPE", type_name, source);
24326 TCU_FAIL("Invalid enum");
24334 /** Get name of test case
24336 * @param test_case_index Index of test case
24338 * @return Name of case
24340 std::string XFBGlobalBufferTest::getTestCaseName(GLuint test_case_index)
24343 const _testCase& test_case = m_test_cases[test_case_index];
24345 name = "Tested stage: ";
24346 name.append(Utils::Shader::GetStageName(test_case.m_stage));
24347 name.append(". Tested type: ");
24348 name.append(test_case.m_type.GetGLSLTypeName());
24353 /** Get number of cases
24355 * @return Number of test cases
24357 GLuint XFBGlobalBufferTest::getTestCaseNumber()
24359 return static_cast<GLuint>(m_test_cases.size());
24362 /** Prepare set of test cases
24365 void XFBGlobalBufferTest::testInit()
24367 GLuint n_types = getTypesNumber();
24369 for (GLuint i = 0; i < n_types; ++i)
24371 const Utils::Type& type = getType(i);
24373 When the tfx varying is the following type, the number of output exceeds the gl_MaxVaryingComponents, which will
24374 cause a link time error.
24376 if (strcmp(type.GetGLSLTypeName(), "dmat3") == 0 || strcmp(type.GetGLSLTypeName(), "dmat4") == 0 ||
24377 strcmp(type.GetGLSLTypeName(), "dmat3x4") == 0 || strcmp(type.GetGLSLTypeName(), "dmat4x3") == 0)
24381 const _testCase test_cases[] = { { Utils::Shader::VERTEX, type },
24382 { Utils::Shader::GEOMETRY, type },
24383 { Utils::Shader::TESS_EVAL, type } };
24385 m_test_cases.push_back(test_cases[0]);
24386 m_test_cases.push_back(test_cases[1]);
24387 m_test_cases.push_back(test_cases[2]);
24393 * @param context Test context
24395 XFBStrideTest::XFBStrideTest(deqp::Context& context)
24396 : BufferTestBase(context, "xfb_stride", "Test verifies that correct stride is used for all types")
24398 /* Nothing to be done here */
24401 /** Execute drawArrays for single vertex
24403 * @param test_case_index
24407 bool XFBStrideTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
24409 const Functions& gl = m_context.getRenderContext().getFunctions();
24410 GLenum primitive_type = GL_PATCHES;
24411 const testCase& test_case = m_test_cases[test_case_index];
24413 if (Utils::Shader::VERTEX == test_case.m_stage)
24415 primitive_type = GL_POINTS;
24418 gl.disable(GL_RASTERIZER_DISCARD);
24419 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
24421 gl.beginTransformFeedback(GL_POINTS);
24422 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
24424 gl.drawArrays(primitive_type, 0 /* first */, 2 /* count */);
24425 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
24427 gl.endTransformFeedback();
24428 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
24433 /** Get descriptors of buffers necessary for test
24435 * @param test_case_index Index of test case
24436 * @param out_descriptors Descriptors of buffers used by test
24438 void XFBStrideTest::getBufferDescriptors(GLuint test_case_index, bufferDescriptor::Vector& out_descriptors)
24440 const testCase& test_case = m_test_cases[test_case_index];
24441 const Utils::Type& type = test_case.m_type;
24443 /* Test needs single uniform and xfb */
24444 out_descriptors.resize(2);
24446 /* Get references */
24447 bufferDescriptor& uniform = out_descriptors[0];
24448 bufferDescriptor& xfb = out_descriptors[1];
24451 uniform.m_index = 0;
24455 uniform.m_target = Utils::Buffer::Uniform;
24456 xfb.m_target = Utils::Buffer::Transform_feedback;
24459 const GLuint rand_start = Utils::s_rand;
24460 const std::vector<GLubyte>& uniform_data = type.GenerateData();
24462 Utils::s_rand = rand_start;
24463 const std::vector<GLubyte>& xfb_data = type.GenerateDataPacked();
24465 const GLuint uni_type_size = static_cast<GLuint>(uniform_data.size());
24466 const GLuint xfb_type_size = static_cast<GLuint>(xfb_data.size());
24468 Note: If xfb varying output from vertex shader, the variable "goku" will only output once to transform feedback buffer,
24469 if xfb varying output from TES or GS, because the input primitive type in TES is defined as "layout(isolines, point_mode) in;",
24470 the primitive type is line which make the variable "goku" will output twice to transform feedback buffer, so for vertex shader
24471 only one valid data should be initialized in xfb.m_expected_data
24473 const GLuint xfb_data_size = (test_case.m_stage == Utils::Shader::VERTEX) ? xfb_type_size : xfb_type_size * 2;
24475 uniform.m_initial_data.resize(uni_type_size);
24476 memcpy(&uniform.m_initial_data[0] + 0 * uni_type_size, &uniform_data[0], uni_type_size);
24479 xfb.m_initial_data.resize(xfb_data_size);
24480 xfb.m_expected_data.resize(xfb_data_size);
24482 for (GLuint i = 0; i < xfb_data_size; ++i)
24484 xfb.m_initial_data[i] = (glw::GLubyte)i;
24485 xfb.m_expected_data[i] = (glw::GLubyte)i;
24488 if (test_case.m_stage == Utils::Shader::VERTEX)
24490 memcpy(&xfb.m_expected_data[0] + 0 * xfb_type_size, &xfb_data[0], xfb_type_size);
24494 memcpy(&xfb.m_expected_data[0] + 0 * xfb_type_size, &xfb_data[0], xfb_type_size);
24495 memcpy(&xfb.m_expected_data[0] + 1 * xfb_type_size, &xfb_data[0], xfb_type_size);
24499 /** Get body of main function for given shader stage
24501 * @param test_case_index Index of test case
24502 * @param stage Shader stage
24503 * @param out_assignments Set to empty
24504 * @param out_calculations Set to empty
24506 void XFBStrideTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage, std::string& out_assignments,
24507 std::string& out_calculations)
24509 const testCase& test_case = m_test_cases[test_case_index];
24511 out_calculations = "";
24513 static const GLchar* vs_tes_gs = " goku = uni_goku;\n";
24514 static const GLchar* fs = " fs_out = vec4(1, 0.25, 0.5, 0.75);\n"
24515 " if (TYPE(0) == goku)\n"
24517 " fs_out = vec4(1, 0.75, 0.5, 0.5);\n"
24520 const GLchar* assignments = "";
24522 if (test_case.m_stage == stage)
24526 case Utils::Shader::GEOMETRY:
24527 assignments = vs_tes_gs;
24529 case Utils::Shader::TESS_EVAL:
24530 assignments = vs_tes_gs;
24532 case Utils::Shader::VERTEX:
24533 assignments = vs_tes_gs;
24536 TCU_FAIL("Invalid enum");
24543 case Utils::Shader::FRAGMENT:
24546 case Utils::Shader::GEOMETRY:
24547 case Utils::Shader::TESS_CTRL:
24548 case Utils::Shader::TESS_EVAL:
24549 case Utils::Shader::VERTEX:
24552 TCU_FAIL("Invalid enum");
24556 out_assignments = assignments;
24558 if (Utils::Shader::FRAGMENT == stage)
24560 Utils::replaceAllTokens("TYPE", test_case.m_type.GetGLSLTypeName(), out_assignments);
24564 /** Get interface of shader
24566 * @param test_case_index Index of test case
24567 * @param stage Shader stage
24568 * @param out_interface Set to ""
24570 void XFBStrideTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage, std::string& out_interface)
24572 static const GLchar* vs_tes_gs = "layout (xfb_offset = 0) FLAT out TYPE goku;\n"
24574 "layout(std140, binding = 0) uniform Goku {\n"
24575 " TYPE uni_goku;\n"
24577 static const GLchar* fs = "FLAT in TYPE goku;\n"
24579 "out vec4 fs_out;\n";
24581 const testCase& test_case = m_test_cases[test_case_index];
24582 const GLchar* interface = "";
24583 const GLchar* flat = "";
24585 if (test_case.m_stage == stage)
24589 case Utils::Shader::GEOMETRY:
24590 interface = vs_tes_gs;
24592 case Utils::Shader::TESS_EVAL:
24593 interface = vs_tes_gs;
24595 case Utils::Shader::VERTEX:
24596 interface = vs_tes_gs;
24599 TCU_FAIL("Invalid enum");
24606 case Utils::Shader::FRAGMENT:
24609 case Utils::Shader::GEOMETRY:
24610 case Utils::Shader::TESS_CTRL:
24611 case Utils::Shader::TESS_EVAL:
24612 case Utils::Shader::VERTEX:
24615 TCU_FAIL("Invalid enum");
24619 out_interface = interface;
24621 if (Utils::Type::Float != test_case.m_type.m_basic_type)
24626 Utils::replaceAllTokens("FLAT", flat, out_interface);
24627 Utils::replaceAllTokens("TYPE", test_case.m_type.GetGLSLTypeName(), out_interface);
24630 /** Get source code of shader
24632 * @param test_case_index Index of test case
24633 * @param stage Shader stage
24637 std::string XFBStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
24639 std::string source;
24640 const testCase& test_case = m_test_cases[test_case_index];
24642 switch (test_case.m_stage)
24644 case Utils::Shader::VERTEX:
24647 case Utils::Shader::FRAGMENT:
24648 case Utils::Shader::VERTEX:
24649 source = BufferTestBase::getShaderSource(test_case_index, stage);
24656 case Utils::Shader::TESS_EVAL:
24659 case Utils::Shader::FRAGMENT:
24660 case Utils::Shader::TESS_CTRL:
24661 case Utils::Shader::TESS_EVAL:
24662 case Utils::Shader::VERTEX:
24663 source = BufferTestBase::getShaderSource(test_case_index, stage);
24670 case Utils::Shader::GEOMETRY:
24671 source = BufferTestBase::getShaderSource(test_case_index, stage);
24675 TCU_FAIL("Invalid enum");
24683 /** Get name of test case
24685 * @param test_case_index Index of test case
24687 * @return Name of tested stage
24689 std::string XFBStrideTest::getTestCaseName(glw::GLuint test_case_index)
24691 std::stringstream stream;
24692 const testCase& test_case = m_test_cases[test_case_index];
24694 stream << "Type: " << test_case.m_type.GetGLSLTypeName()
24695 << ", stage: " << Utils::Shader::GetStageName(test_case.m_stage);
24697 return stream.str();
24700 /** Returns number of test cases
24704 glw::GLuint XFBStrideTest::getTestCaseNumber()
24706 return static_cast<GLuint>(m_test_cases.size());
24709 /** Prepare all test cases
24712 void XFBStrideTest::testInit()
24714 const GLuint n_types = getTypesNumber();
24716 for (GLuint i = 0; i < n_types; ++i)
24718 const Utils::Type& type = getType(i);
24720 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
24722 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::FRAGMENT == stage) ||
24723 (Utils::Shader::TESS_CTRL == stage))
24728 testCase test_case = { (Utils::Shader::STAGES)stage, type };
24730 m_test_cases.push_back(test_case);
24737 * @param context Test framework context
24739 XFBBlockMemberBufferTest::XFBBlockMemberBufferTest(deqp::Context& context)
24740 : NegativeTestBase(
24741 context, "xfb_block_member_buffer",
24742 "Test verifies that compiler reports error when block member has different xfb_buffer qualifier than buffer")
24746 /** Source for given test case and stage
24748 * @param test_case_index Index of test case
24749 * @param stage Shader stage
24751 * @return Shader source
24753 std::string XFBBlockMemberBufferTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
24755 static const GLchar* var_definition = "layout (xfb_offset = 0) out Goku {\n"
24757 " layout (xfb_buffer = 1) vec4 goten;\n"
24759 static const GLchar* var_use = " gokuINDEX.gohan = result / 2;\n"
24760 " gokuINDEX.goten = result / 4;\n";
24761 static const GLchar* fs = "#version 430 core\n"
24762 "#extension GL_ARB_enhanced_layouts : require\n"
24765 "out vec4 fs_out;\n"
24769 " fs_out = gs_fs;\n"
24772 static const GLchar* gs_tested = "#version 430 core\n"
24773 "#extension GL_ARB_enhanced_layouts : require\n"
24775 "layout(points) in;\n"
24776 "layout(triangle_strip, max_vertices = 4) out;\n"
24780 "in vec4 tes_gs[];\n"
24781 "out vec4 gs_fs;\n"
24785 " vec4 result = tes_gs[0];\n"
24789 " gs_fs = result;\n"
24790 " gl_Position = vec4(-1, -1, 0, 1);\n"
24792 " gs_fs = result;\n"
24793 " gl_Position = vec4(-1, 1, 0, 1);\n"
24795 " gs_fs = result;\n"
24796 " gl_Position = vec4(1, -1, 0, 1);\n"
24798 " gs_fs = result;\n"
24799 " gl_Position = vec4(1, 1, 0, 1);\n"
24803 static const GLchar* tcs = "#version 430 core\n"
24804 "#extension GL_ARB_enhanced_layouts : require\n"
24806 "layout(vertices = 1) out;\n"
24808 "in vec4 vs_tcs[];\n"
24809 "out vec4 tcs_tes[];\n"
24814 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
24816 " gl_TessLevelOuter[0] = 1.0;\n"
24817 " gl_TessLevelOuter[1] = 1.0;\n"
24818 " gl_TessLevelOuter[2] = 1.0;\n"
24819 " gl_TessLevelOuter[3] = 1.0;\n"
24820 " gl_TessLevelInner[0] = 1.0;\n"
24821 " gl_TessLevelInner[1] = 1.0;\n"
24824 static const GLchar* tcs_tested = "#version 430 core\n"
24825 "#extension GL_ARB_enhanced_layouts : require\n"
24827 "layout(vertices = 1) out;\n"
24831 "in vec4 vs_tcs[];\n"
24832 "out vec4 tcs_tes[];\n"
24836 " vec4 result = vs_tcs[gl_InvocationID];\n"
24840 " tcs_tes[gl_InvocationID] = result;\n"
24842 " gl_TessLevelOuter[0] = 1.0;\n"
24843 " gl_TessLevelOuter[1] = 1.0;\n"
24844 " gl_TessLevelOuter[2] = 1.0;\n"
24845 " gl_TessLevelOuter[3] = 1.0;\n"
24846 " gl_TessLevelInner[0] = 1.0;\n"
24847 " gl_TessLevelInner[1] = 1.0;\n"
24850 static const GLchar* tes_tested = "#version 430 core\n"
24851 "#extension GL_ARB_enhanced_layouts : require\n"
24853 "layout(isolines, point_mode) in;\n"
24857 "in vec4 tcs_tes[];\n"
24858 "out vec4 tes_gs;\n"
24862 " vec4 result = tcs_tes[0];\n"
24866 " tes_gs += result;\n"
24869 static const GLchar* vs = "#version 430 core\n"
24870 "#extension GL_ARB_enhanced_layouts : require\n"
24873 "out vec4 vs_tcs;\n"
24877 " vs_tcs = in_vs;\n"
24880 static const GLchar* vs_tested = "#version 430 core\n"
24881 "#extension GL_ARB_enhanced_layouts : require\n"
24886 "out vec4 vs_tcs;\n"
24890 " vec4 result = in_vs;\n"
24894 " vs_tcs = result;\n"
24898 std::string source;
24899 testCase& test_case = m_test_cases[test_case_index];
24901 if (test_case.m_stage == stage)
24903 const GLchar* array = "";
24904 const GLchar* index = "";
24905 size_t position = 0;
24909 case Utils::Shader::GEOMETRY:
24910 source = gs_tested;
24914 case Utils::Shader::TESS_CTRL:
24915 source = tcs_tested;
24917 index = "[gl_InvocationID]";
24919 case Utils::Shader::TESS_EVAL:
24920 source = tes_tested;
24924 case Utils::Shader::VERTEX:
24925 source = vs_tested;
24928 TCU_FAIL("Invalid enum");
24931 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
24933 Utils::replaceToken("ARRAY", position, array, source);
24934 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
24936 Utils::replaceAllTokens("INDEX", index, source);
24940 switch (test_case.m_stage)
24942 case Utils::Shader::GEOMETRY:
24945 case Utils::Shader::FRAGMENT:
24948 case Utils::Shader::VERTEX:
24955 case Utils::Shader::TESS_CTRL:
24958 case Utils::Shader::FRAGMENT:
24961 case Utils::Shader::VERTEX:
24968 case Utils::Shader::TESS_EVAL:
24971 case Utils::Shader::FRAGMENT:
24974 case Utils::Shader::TESS_CTRL:
24977 case Utils::Shader::VERTEX:
24984 case Utils::Shader::VERTEX:
24987 case Utils::Shader::FRAGMENT:
24995 TCU_FAIL("Invalid enum");
25003 /** Get description of test case
25005 * @param test_case_index Index of test case
25007 * @return Test case description
25009 std::string XFBBlockMemberBufferTest::getTestCaseName(GLuint test_case_index)
25011 std::stringstream stream;
25012 testCase& test_case = m_test_cases[test_case_index];
25014 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage);
25016 return stream.str();
25019 /** Get number of test cases
25021 * @return Number of test cases
25023 GLuint XFBBlockMemberBufferTest::getTestCaseNumber()
25025 return static_cast<GLuint>(m_test_cases.size());
25028 /** Selects if "compute" stage is relevant for test
25034 bool XFBBlockMemberBufferTest::isComputeRelevant(GLuint /* test_case_index */)
25039 /** Prepare all test cases
25042 void XFBBlockMemberBufferTest::testInit()
25044 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
25046 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
25047 (Utils::Shader::FRAGMENT == stage))
25052 testCase test_case = { (Utils::Shader::STAGES)stage };
25054 m_test_cases.push_back(test_case);
25060 * @param context Test framework context
25062 XFBOutputOverlappingTest::XFBOutputOverlappingTest(deqp::Context& context)
25063 : NegativeTestBase(context, "xfb_output_overlapping",
25064 "Test verifies that compiler reports error when two xfb qualified outputs overlap")
25068 /** Source for given test case and stage
25070 * @param test_case_index Index of test case
25071 * @param stage Shader stage
25073 * @return Shader source
25075 std::string XFBOutputOverlappingTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
25077 static const GLchar* var_definition = "layout (xfb_offset = OFFSET) out TYPE gohanARRAY;\n"
25078 "layout (xfb_offset = OFFSET) out TYPE gotenARRAY;\n";
25079 static const GLchar* var_use = " gohanINDEX = TYPE(0);\n"
25080 " gotenINDEX = TYPE(1);\n"
25081 " if (vec4(0) == result)\n"
25083 " gohanINDEX = TYPE(1);\n"
25084 " gotenINDEX = TYPE(0);\n"
25086 static const GLchar* fs = "#version 430 core\n"
25087 "#extension GL_ARB_enhanced_layouts : require\n"
25090 "out vec4 fs_out;\n"
25094 " fs_out = gs_fs;\n"
25097 static const GLchar* gs_tested = "#version 430 core\n"
25098 "#extension GL_ARB_enhanced_layouts : require\n"
25100 "layout(points) in;\n"
25101 "layout(triangle_strip, max_vertices = 4) out;\n"
25105 "in vec4 tes_gs[];\n"
25106 "out vec4 gs_fs;\n"
25110 " vec4 result = tes_gs[0];\n"
25114 " gs_fs = result;\n"
25115 " gl_Position = vec4(-1, -1, 0, 1);\n"
25117 " gs_fs = result;\n"
25118 " gl_Position = vec4(-1, 1, 0, 1);\n"
25120 " gs_fs = result;\n"
25121 " gl_Position = vec4(1, -1, 0, 1);\n"
25123 " gs_fs = result;\n"
25124 " gl_Position = vec4(1, 1, 0, 1);\n"
25128 static const GLchar* tcs = "#version 430 core\n"
25129 "#extension GL_ARB_enhanced_layouts : require\n"
25131 "layout(vertices = 1) out;\n"
25133 "in vec4 vs_tcs[];\n"
25134 "out vec4 tcs_tes[];\n"
25139 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
25141 " gl_TessLevelOuter[0] = 1.0;\n"
25142 " gl_TessLevelOuter[1] = 1.0;\n"
25143 " gl_TessLevelOuter[2] = 1.0;\n"
25144 " gl_TessLevelOuter[3] = 1.0;\n"
25145 " gl_TessLevelInner[0] = 1.0;\n"
25146 " gl_TessLevelInner[1] = 1.0;\n"
25149 static const GLchar* tcs_tested = "#version 430 core\n"
25150 "#extension GL_ARB_enhanced_layouts : require\n"
25152 "layout(vertices = 1) out;\n"
25156 "in vec4 vs_tcs[];\n"
25157 "out vec4 tcs_tes[];\n"
25161 " vec4 result = vs_tcs[gl_InvocationID];\n"
25165 " tcs_tes[gl_InvocationID] = result;\n"
25167 " gl_TessLevelOuter[0] = 1.0;\n"
25168 " gl_TessLevelOuter[1] = 1.0;\n"
25169 " gl_TessLevelOuter[2] = 1.0;\n"
25170 " gl_TessLevelOuter[3] = 1.0;\n"
25171 " gl_TessLevelInner[0] = 1.0;\n"
25172 " gl_TessLevelInner[1] = 1.0;\n"
25175 static const GLchar* tes_tested = "#version 430 core\n"
25176 "#extension GL_ARB_enhanced_layouts : require\n"
25178 "layout(isolines, point_mode) in;\n"
25182 "in vec4 tcs_tes[];\n"
25183 "out vec4 tes_gs;\n"
25187 " vec4 result = tcs_tes[0];\n"
25191 " tes_gs += result;\n"
25194 static const GLchar* vs = "#version 430 core\n"
25195 "#extension GL_ARB_enhanced_layouts : require\n"
25198 "out vec4 vs_tcs;\n"
25202 " vs_tcs = in_vs;\n"
25205 static const GLchar* vs_tested = "#version 430 core\n"
25206 "#extension GL_ARB_enhanced_layouts : require\n"
25211 "out vec4 vs_tcs;\n"
25215 " vec4 result = in_vs;\n"
25219 " vs_tcs = result;\n"
25223 std::string source;
25224 testCase& test_case = m_test_cases[test_case_index];
25226 if (test_case.m_stage == stage)
25228 const GLchar* array = "";
25229 GLchar buffer_gohan[16];
25230 GLchar buffer_goten[16];
25231 const GLchar* index = "";
25232 size_t position = 0;
25233 size_t position_start = 0;
25234 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
25236 sprintf(buffer_gohan, "%d", test_case.m_offset_gohan);
25237 sprintf(buffer_goten, "%d", test_case.m_offset_goten);
25241 case Utils::Shader::GEOMETRY:
25242 source = gs_tested;
25246 case Utils::Shader::TESS_CTRL:
25247 source = tcs_tested;
25249 index = "[gl_InvocationID]";
25251 case Utils::Shader::TESS_EVAL:
25252 source = tes_tested;
25256 case Utils::Shader::VERTEX:
25257 source = vs_tested;
25260 TCU_FAIL("Invalid enum");
25263 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
25265 Utils::replaceToken("OFFSET", position, buffer_gohan, source);
25266 Utils::replaceToken("TYPE", position, type_name, source);
25267 Utils::replaceToken("ARRAY", position, array, source);
25268 Utils::replaceToken("OFFSET", position, buffer_goten, source);
25269 Utils::replaceToken("TYPE", position, type_name, source);
25270 Utils::replaceToken("ARRAY", position, array, source);
25271 position_start = position;
25272 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
25273 position = position_start;
25274 Utils::replaceToken("INDEX", position, index, source);
25275 Utils::replaceToken("TYPE", position, type_name, source);
25276 Utils::replaceToken("INDEX", position, index, source);
25277 Utils::replaceToken("TYPE", position, type_name, source);
25278 Utils::replaceToken("INDEX", position, index, source);
25279 Utils::replaceToken("TYPE", position, type_name, source);
25280 Utils::replaceToken("INDEX", position, index, source);
25281 Utils::replaceToken("TYPE", position, type_name, source);
25285 switch (test_case.m_stage)
25287 case Utils::Shader::GEOMETRY:
25290 case Utils::Shader::FRAGMENT:
25293 case Utils::Shader::VERTEX:
25300 case Utils::Shader::TESS_CTRL:
25303 case Utils::Shader::FRAGMENT:
25306 case Utils::Shader::VERTEX:
25313 case Utils::Shader::TESS_EVAL:
25316 case Utils::Shader::FRAGMENT:
25319 case Utils::Shader::TESS_CTRL:
25322 case Utils::Shader::VERTEX:
25329 case Utils::Shader::VERTEX:
25332 case Utils::Shader::FRAGMENT:
25340 TCU_FAIL("Invalid enum");
25348 /** Get description of test case
25350 * @param test_case_index Index of test case
25352 * @return Test case description
25354 std::string XFBOutputOverlappingTest::getTestCaseName(GLuint test_case_index)
25356 std::stringstream stream;
25357 testCase& test_case = m_test_cases[test_case_index];
25359 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
25360 << ", type: " << test_case.m_type.GetGLSLTypeName() << ", offsets: " << test_case.m_offset_gohan << " & "
25361 << test_case.m_offset_goten;
25363 return stream.str();
25366 /** Get number of test cases
25368 * @return Number of test cases
25370 GLuint XFBOutputOverlappingTest::getTestCaseNumber()
25372 return static_cast<GLuint>(m_test_cases.size());
25375 /** Selects if "compute" stage is relevant for test
25381 bool XFBOutputOverlappingTest::isComputeRelevant(GLuint /* test_case_index */)
25386 /** Prepare all test cases
25389 void XFBOutputOverlappingTest::testInit()
25391 const GLuint n_types = getTypesNumber();
25393 for (GLuint i = 0; i < n_types; ++i)
25395 const Utils::Type& type = getType(i);
25396 const GLuint base_alingment = Utils::Type::GetTypeSize(type.m_basic_type);
25398 /* Skip scalars, not applicable as:
25400 * The offset must be a multiple of the size of the first component of the first
25401 * qualified variable or block member, or a compile-time error results.
25403 if ((1 == type.m_n_columns) && (1 == type.m_n_rows))
25408 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
25410 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
25411 (Utils::Shader::FRAGMENT == stage))
25416 testCase test_case = { 0 /* gohan offset */, base_alingment /* goten_offset */,
25417 (Utils::Shader::STAGES)stage, type };
25419 m_test_cases.push_back(test_case);
25426 * @param context Test framework context
25428 XFBInvalidOffsetAlignmentTest::XFBInvalidOffsetAlignmentTest(deqp::Context& context)
25429 : NegativeTestBase(context, "xfb_invalid_offset_alignment",
25430 "Test verifies that compiler reports error when xfb_offset has invalid alignment")
25434 /** Source for given test case and stage
25436 * @param test_case_index Index of test case
25437 * @param stage Shader stage
25439 * @return Shader source
25441 std::string XFBInvalidOffsetAlignmentTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
25443 static const GLchar* var_definition = "layout (xfb_offset = OFFSET) out TYPE gohanARRAY;\n";
25444 static const GLchar* var_use = " gohanINDEX = TYPE(0);\n"
25445 " if (vec4(0) == result)\n"
25447 " gohanINDEX = TYPE(1);\n"
25449 static const GLchar* fs = "#version 430 core\n"
25450 "#extension GL_ARB_enhanced_layouts : require\n"
25453 "out vec4 fs_out;\n"
25457 " fs_out = gs_fs;\n"
25460 static const GLchar* gs_tested = "#version 430 core\n"
25461 "#extension GL_ARB_enhanced_layouts : require\n"
25463 "layout(points) in;\n"
25464 "layout(triangle_strip, max_vertices = 4) out;\n"
25468 "in vec4 tes_gs[];\n"
25469 "out vec4 gs_fs;\n"
25473 " vec4 result = tes_gs[0];\n"
25477 " gs_fs = result;\n"
25478 " gl_Position = vec4(-1, -1, 0, 1);\n"
25480 " gs_fs = result;\n"
25481 " gl_Position = vec4(-1, 1, 0, 1);\n"
25483 " gs_fs = result;\n"
25484 " gl_Position = vec4(1, -1, 0, 1);\n"
25486 " gs_fs = result;\n"
25487 " gl_Position = vec4(1, 1, 0, 1);\n"
25491 static const GLchar* tcs = "#version 430 core\n"
25492 "#extension GL_ARB_enhanced_layouts : require\n"
25494 "layout(vertices = 1) out;\n"
25496 "in vec4 vs_tcs[];\n"
25497 "out vec4 tcs_tes[];\n"
25502 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
25504 " gl_TessLevelOuter[0] = 1.0;\n"
25505 " gl_TessLevelOuter[1] = 1.0;\n"
25506 " gl_TessLevelOuter[2] = 1.0;\n"
25507 " gl_TessLevelOuter[3] = 1.0;\n"
25508 " gl_TessLevelInner[0] = 1.0;\n"
25509 " gl_TessLevelInner[1] = 1.0;\n"
25512 static const GLchar* tcs_tested = "#version 430 core\n"
25513 "#extension GL_ARB_enhanced_layouts : require\n"
25515 "layout(vertices = 1) out;\n"
25519 "in vec4 vs_tcs[];\n"
25520 "out vec4 tcs_tes[];\n"
25524 " vec4 result = vs_tcs[gl_InvocationID];\n"
25528 " tcs_tes[gl_InvocationID] = result;\n"
25530 " gl_TessLevelOuter[0] = 1.0;\n"
25531 " gl_TessLevelOuter[1] = 1.0;\n"
25532 " gl_TessLevelOuter[2] = 1.0;\n"
25533 " gl_TessLevelOuter[3] = 1.0;\n"
25534 " gl_TessLevelInner[0] = 1.0;\n"
25535 " gl_TessLevelInner[1] = 1.0;\n"
25538 static const GLchar* tes_tested = "#version 430 core\n"
25539 "#extension GL_ARB_enhanced_layouts : require\n"
25541 "layout(isolines, point_mode) in;\n"
25545 "in vec4 tcs_tes[];\n"
25546 "out vec4 tes_gs;\n"
25550 " vec4 result = tcs_tes[0];\n"
25554 " tes_gs += result;\n"
25557 static const GLchar* vs = "#version 430 core\n"
25558 "#extension GL_ARB_enhanced_layouts : require\n"
25561 "out vec4 vs_tcs;\n"
25565 " vs_tcs = in_vs;\n"
25568 static const GLchar* vs_tested = "#version 430 core\n"
25569 "#extension GL_ARB_enhanced_layouts : require\n"
25574 "out vec4 vs_tcs;\n"
25578 " vec4 result = in_vs;\n"
25582 " vs_tcs = result;\n"
25586 std::string source;
25587 testCase& test_case = m_test_cases[test_case_index];
25589 if (test_case.m_stage == stage)
25591 const GLchar* array = "";
25593 const GLchar* index = "";
25594 size_t position = 0;
25595 size_t position_start = 0;
25596 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
25598 sprintf(buffer, "%d", test_case.m_offset);
25602 case Utils::Shader::GEOMETRY:
25603 source = gs_tested;
25607 case Utils::Shader::TESS_CTRL:
25608 source = tcs_tested;
25610 index = "[gl_InvocationID]";
25612 case Utils::Shader::TESS_EVAL:
25613 source = tes_tested;
25617 case Utils::Shader::VERTEX:
25618 source = vs_tested;
25621 TCU_FAIL("Invalid enum");
25624 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
25626 Utils::replaceToken("OFFSET", position, buffer, source);
25627 Utils::replaceToken("TYPE", position, type_name, source);
25628 Utils::replaceToken("ARRAY", position, array, source);
25629 position_start = position;
25630 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
25631 position = position_start;
25632 Utils::replaceToken("INDEX", position, index, source);
25633 Utils::replaceToken("TYPE", position, type_name, source);
25634 Utils::replaceToken("INDEX", position, index, source);
25635 Utils::replaceToken("TYPE", position, type_name, source);
25639 switch (test_case.m_stage)
25641 case Utils::Shader::GEOMETRY:
25644 case Utils::Shader::FRAGMENT:
25647 case Utils::Shader::VERTEX:
25654 case Utils::Shader::TESS_CTRL:
25657 case Utils::Shader::FRAGMENT:
25660 case Utils::Shader::VERTEX:
25667 case Utils::Shader::TESS_EVAL:
25670 case Utils::Shader::FRAGMENT:
25673 case Utils::Shader::TESS_CTRL:
25676 case Utils::Shader::VERTEX:
25683 case Utils::Shader::VERTEX:
25686 case Utils::Shader::FRAGMENT:
25694 TCU_FAIL("Invalid enum");
25702 /** Get description of test case
25704 * @param test_case_index Index of test case
25706 * @return Test case description
25708 std::string XFBInvalidOffsetAlignmentTest::getTestCaseName(GLuint test_case_index)
25710 std::stringstream stream;
25711 testCase& test_case = m_test_cases[test_case_index];
25713 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
25714 << ", type: " << test_case.m_type.GetGLSLTypeName() << ", offset: " << test_case.m_offset;
25716 return stream.str();
25719 /** Get number of test cases
25721 * @return Number of test cases
25723 GLuint XFBInvalidOffsetAlignmentTest::getTestCaseNumber()
25725 return static_cast<GLuint>(m_test_cases.size());
25728 /** Selects if "compute" stage is relevant for test
25734 bool XFBInvalidOffsetAlignmentTest::isComputeRelevant(GLuint /* test_case_index */)
25739 /** Prepare all test cases
25742 void XFBInvalidOffsetAlignmentTest::testInit()
25744 const GLuint n_types = getTypesNumber();
25746 for (GLuint i = 0; i < n_types; ++i)
25748 const Utils::Type& type = getType(i);
25749 const GLuint base_alingment = Utils::Type::GetTypeSize(type.m_basic_type);
25751 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
25753 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
25754 (Utils::Shader::FRAGMENT == stage))
25759 for (GLuint offset = base_alingment + 1; offset < 2 * base_alingment; ++offset)
25761 testCase test_case = { offset, (Utils::Shader::STAGES)stage, type };
25763 m_test_cases.push_back(test_case);
25771 * @param context Test context
25773 XFBCaptureInactiveOutputVariableTest::XFBCaptureInactiveOutputVariableTest(deqp::Context& context)
25774 : BufferTestBase(context, "xfb_capture_inactive_output_variable",
25775 "Test verifies that inactive variables are captured")
25777 /* Nothing to be done here */
25780 /** Execute drawArrays for single vertex
25782 * @param test_case_index
25786 bool XFBCaptureInactiveOutputVariableTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
25788 const Functions& gl = m_context.getRenderContext().getFunctions();
25789 GLenum primitive_type = GL_PATCHES;
25791 if (TEST_VS == test_case_index)
25793 primitive_type = GL_POINTS;
25796 gl.disable(GL_RASTERIZER_DISCARD);
25797 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
25799 gl.beginTransformFeedback(GL_POINTS);
25800 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
25802 gl.drawArrays(primitive_type, 0 /* first */, 1 /* count */);
25803 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
25805 gl.endTransformFeedback();
25806 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
25811 /** Get descriptors of buffers necessary for test
25814 * @param out_descriptors Descriptors of buffers used by test
25816 void XFBCaptureInactiveOutputVariableTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
25817 bufferDescriptor::Vector& out_descriptors)
25819 const Utils::Type& type = Utils::Type::vec4;
25821 /* Test needs single uniform and xfb */
25822 out_descriptors.resize(2);
25824 /* Get references */
25825 bufferDescriptor& uniform = out_descriptors[0];
25826 bufferDescriptor& xfb = out_descriptors[1];
25829 uniform.m_index = 0;
25833 uniform.m_target = Utils::Buffer::Uniform;
25834 xfb.m_target = Utils::Buffer::Transform_feedback;
25837 const std::vector<GLubyte>& gohan_data = type.GenerateData();
25838 const std::vector<GLubyte>& goten_data = type.GenerateData();
25840 const GLuint type_size = static_cast<GLuint>(gohan_data.size());
25843 uniform.m_initial_data.resize(2 * type_size);
25844 memcpy(&uniform.m_initial_data[0] + 0, &gohan_data[0], type_size);
25845 memcpy(&uniform.m_initial_data[0] + type_size, &goten_data[0], type_size);
25848 xfb.m_initial_data.resize(3 * type_size);
25849 xfb.m_expected_data.resize(3 * type_size);
25851 for (GLuint i = 0; i < 3 * type_size; ++i)
25853 xfb.m_initial_data[i] = (glw::GLubyte)i;
25854 xfb.m_expected_data[i] = (glw::GLubyte)i;
25857 memcpy(&xfb.m_expected_data[0] + 2 * type_size, &gohan_data[0], type_size);
25858 memcpy(&xfb.m_expected_data[0] + 0 * type_size, &goten_data[0], type_size);
25861 /** Get body of main function for given shader stage
25863 * @param test_case_index Index of test case
25864 * @param stage Shader stage
25865 * @param out_assignments Set to empty
25866 * @param out_calculations Set to empty
25868 void XFBCaptureInactiveOutputVariableTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
25869 std::string& out_assignments, std::string& out_calculations)
25871 out_calculations = "";
25873 static const GLchar* vs_tes_gs = " goten = uni_goten;\n"
25874 " gohan = uni_gohan;\n";
25875 static const GLchar* fs = " fs_out = goku + gohan + goten;\n";
25877 const GLchar* assignments = "";
25881 case Utils::Shader::FRAGMENT:
25885 case Utils::Shader::GEOMETRY:
25886 if (TEST_GS == test_case_index)
25888 assignments = vs_tes_gs;
25892 case Utils::Shader::TESS_CTRL:
25895 case Utils::Shader::TESS_EVAL:
25896 if (TEST_TES == test_case_index)
25898 assignments = vs_tes_gs;
25902 case Utils::Shader::VERTEX:
25903 if (TEST_VS == test_case_index)
25905 assignments = vs_tes_gs;
25910 TCU_FAIL("Invalid enum");
25913 out_assignments = assignments;
25916 /** Get interface of shader
25918 * @param test_case_index Index of test case
25919 * @param stage Shader stage
25920 * @param out_interface Set to ""
25922 void XFBCaptureInactiveOutputVariableTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
25923 std::string& out_interface)
25925 static const GLchar* vs_tes_gs = "const uint sizeof_type = 16;\n"
25927 "layout (xfb_offset = 1 * sizeof_type) out vec4 goku;\n"
25928 "layout (xfb_offset = 2 * sizeof_type) out vec4 gohan;\n"
25929 "layout (xfb_offset = 0 * sizeof_type) out vec4 goten;\n"
25931 "layout(binding = 0) uniform block {\n"
25932 " vec4 uni_gohan;\n"
25933 " vec4 uni_goten;\n"
25935 static const GLchar* fs = "in vec4 goku;\n"
25938 "out vec4 fs_out;\n";
25940 const GLchar* interface = "";
25944 case Utils::Shader::FRAGMENT:
25948 case Utils::Shader::GEOMETRY:
25949 if (TEST_GS == test_case_index)
25951 interface = vs_tes_gs;
25955 case Utils::Shader::TESS_CTRL:
25958 case Utils::Shader::TESS_EVAL:
25959 if (TEST_TES == test_case_index)
25961 interface = vs_tes_gs;
25965 case Utils::Shader::VERTEX:
25966 if (TEST_VS == test_case_index)
25968 interface = vs_tes_gs;
25973 TCU_FAIL("Invalid enum");
25976 out_interface = interface;
25979 /** Get source code of shader
25981 * @param test_case_index Index of test case
25982 * @param stage Shader stage
25986 std::string XFBCaptureInactiveOutputVariableTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
25988 std::string source;
25990 switch (test_case_index)
25995 case Utils::Shader::FRAGMENT:
25996 case Utils::Shader::VERTEX:
25997 source = BufferTestBase::getShaderSource(test_case_index, stage);
26007 case Utils::Shader::FRAGMENT:
26008 case Utils::Shader::TESS_CTRL:
26009 case Utils::Shader::TESS_EVAL:
26010 case Utils::Shader::VERTEX:
26011 source = BufferTestBase::getShaderSource(test_case_index, stage);
26019 source = BufferTestBase::getShaderSource(test_case_index, stage);
26023 TCU_FAIL("Invalid enum");
26031 /** Get name of test case
26033 * @param test_case_index Index of test case
26035 * @return Name of tested stage
26037 std::string XFBCaptureInactiveOutputVariableTest::getTestCaseName(glw::GLuint test_case_index)
26039 const GLchar* name = 0;
26041 switch (test_case_index)
26047 name = "tessellation evaluation";
26053 TCU_FAIL("Invalid enum");
26059 /** Returns number of test cases
26063 glw::GLuint XFBCaptureInactiveOutputVariableTest::getTestCaseNumber()
26068 /** Inspects program to check if all resources are as expected
26071 * @param program Program instance
26072 * @param out_stream Error message
26074 * @return true if everything is ok, false otherwise
26076 bool XFBCaptureInactiveOutputVariableTest::inspectProgram(GLuint /* test_case_index */, Utils::Program& program,
26077 std::stringstream& out_stream)
26080 const Utils::Type& type = Utils::Type::vec4;
26081 const GLuint type_size = type.GetSize();
26083 program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE,
26084 1 /* buf_size */, &stride);
26086 if ((GLint)(3 * type_size) != stride)
26088 out_stream << "Stride is: " << stride << " expected: " << (3 * type_size);
26096 /** Verify contents of buffers
26098 * @param buffers Collection of buffers to be verified
26100 * @return true if everything is as expected, false otherwise
26102 bool XFBCaptureInactiveOutputVariableTest::verifyBuffers(bufferCollection& buffers)
26104 bool result = true;
26106 bufferCollection::pair& pair = buffers.m_vector[1] /* xfb */;
26107 Utils::Buffer* buffer = pair.m_buffer;
26108 bufferDescriptor* descriptor = pair.m_descriptor;
26110 /* Get pointer to contents of buffer */
26112 GLubyte* buffer_data = (GLubyte*)buffer->Map(Utils::Buffer::ReadOnly);
26114 /* Get pointer to expected data */
26115 GLubyte* expected_data = (GLubyte*)&descriptor->m_expected_data[0];
26118 static const GLuint vec4_size = 16;
26120 int res_gohan = memcmp(buffer_data + 2 * vec4_size, expected_data + 2 * vec4_size, vec4_size);
26121 int res_goten = memcmp(buffer_data + 0 * vec4_size, expected_data + 0 * vec4_size, vec4_size);
26123 if ((0 != res_gohan) || (0 != res_goten))
26125 m_context.getTestContext().getLog()
26126 << tcu::TestLog::Message << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
26127 << ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
26132 /* Release buffer mapping */
26140 * @param context Test context
26142 XFBCaptureInactiveOutputComponentTest::XFBCaptureInactiveOutputComponentTest(deqp::Context& context)
26143 : BufferTestBase(context, "xfb_capture_inactive_output_component",
26144 "Test verifies that inactive components are not modified")
26146 /* Nothing to be done here */
26149 /** Execute drawArrays for single vertex
26151 * @param test_case_index
26155 bool XFBCaptureInactiveOutputComponentTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
26157 const Functions& gl = m_context.getRenderContext().getFunctions();
26158 GLenum primitive_type = GL_PATCHES;
26160 if (TEST_VS == test_case_index)
26162 primitive_type = GL_POINTS;
26165 gl.disable(GL_RASTERIZER_DISCARD);
26166 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
26168 gl.beginTransformFeedback(GL_POINTS);
26169 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
26171 gl.drawArrays(primitive_type, 0 /* first */, 1 /* count */);
26172 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
26174 gl.endTransformFeedback();
26175 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
26180 /** Get descriptors of buffers necessary for test
26183 * @param out_descriptors Descriptors of buffers used by test
26185 void XFBCaptureInactiveOutputComponentTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
26186 bufferDescriptor::Vector& out_descriptors)
26188 const Utils::Type& type = Utils::Type::vec4;
26190 /* Test needs single uniform and xfb */
26191 out_descriptors.resize(2);
26193 /* Get references */
26194 bufferDescriptor& uniform = out_descriptors[0];
26195 bufferDescriptor& xfb = out_descriptors[1];
26198 uniform.m_index = 0;
26202 uniform.m_target = Utils::Buffer::Uniform;
26203 xfb.m_target = Utils::Buffer::Transform_feedback;
26206 const std::vector<GLubyte>& goku_data = type.GenerateData();
26207 const std::vector<GLubyte>& gohan_data = type.GenerateData();
26208 const std::vector<GLubyte>& goten_data = type.GenerateData();
26209 const std::vector<GLubyte>& chichi_data = type.GenerateData();
26210 const std::vector<GLubyte>& vegeta_data = type.GenerateData();
26211 const std::vector<GLubyte>& trunks_data = type.GenerateData();
26212 const std::vector<GLubyte>& bra_data = type.GenerateData();
26213 const std::vector<GLubyte>& bulma_data = type.GenerateData();
26215 const GLuint comp_size = Utils::Type::GetTypeSize(type.m_basic_type);
26216 const GLuint type_size = static_cast<GLuint>(gohan_data.size());
26219 uniform.m_initial_data.resize(8 * type_size);
26220 memcpy(&uniform.m_initial_data[0] + 0 * type_size, &goku_data[0], type_size);
26221 memcpy(&uniform.m_initial_data[0] + 1 * type_size, &gohan_data[0], type_size);
26222 memcpy(&uniform.m_initial_data[0] + 2 * type_size, &goten_data[0], type_size);
26223 memcpy(&uniform.m_initial_data[0] + 3 * type_size, &chichi_data[0], type_size);
26224 memcpy(&uniform.m_initial_data[0] + 4 * type_size, &vegeta_data[0], type_size);
26225 memcpy(&uniform.m_initial_data[0] + 5 * type_size, &trunks_data[0], type_size);
26226 memcpy(&uniform.m_initial_data[0] + 6 * type_size, &bra_data[0], type_size);
26227 memcpy(&uniform.m_initial_data[0] + 7 * type_size, &bulma_data[0], type_size);
26230 xfb.m_initial_data.resize(8 * type_size);
26231 xfb.m_expected_data.resize(8 * type_size);
26233 for (GLuint i = 0; i < 8 * type_size; ++i)
26235 xfb.m_initial_data[i] = (glw::GLubyte)i;
26236 xfb.m_expected_data[i] = (glw::GLubyte)i;
26239 /* goku - x, z - 32 */
26240 memcpy(&xfb.m_expected_data[0] + 2 * type_size + 0 * comp_size, &goku_data[0] + 0 * comp_size, comp_size);
26241 memcpy(&xfb.m_expected_data[0] + 2 * type_size + 2 * comp_size, &goku_data[0] + 2 * comp_size, comp_size);
26243 /* gohan - y, w - 0 */
26244 memcpy(&xfb.m_expected_data[0] + 0 * type_size + 1 * comp_size, &gohan_data[0] + 1 * comp_size, comp_size);
26245 memcpy(&xfb.m_expected_data[0] + 0 * type_size + 3 * comp_size, &gohan_data[0] + 3 * comp_size, comp_size);
26247 /* goten - x, y - 16 */
26248 memcpy(&xfb.m_expected_data[0] + 1 * type_size + 0 * comp_size, &goten_data[0] + 0 * comp_size, comp_size);
26249 memcpy(&xfb.m_expected_data[0] + 1 * type_size + 1 * comp_size, &goten_data[0] + 1 * comp_size, comp_size);
26251 /* chichi - z, w - 48 */
26252 memcpy(&xfb.m_expected_data[0] + 3 * type_size + 2 * comp_size, &chichi_data[0] + 2 * comp_size, comp_size);
26253 memcpy(&xfb.m_expected_data[0] + 3 * type_size + 3 * comp_size, &chichi_data[0] + 3 * comp_size, comp_size);
26255 /* vegeta - x - 112 */
26256 memcpy(&xfb.m_expected_data[0] + 7 * type_size + 0 * comp_size, &vegeta_data[0] + 0 * comp_size, comp_size);
26258 /* trunks - y - 96 */
26259 memcpy(&xfb.m_expected_data[0] + 6 * type_size + 1 * comp_size, &trunks_data[0] + 1 * comp_size, comp_size);
26262 memcpy(&xfb.m_expected_data[0] + 5 * type_size + 2 * comp_size, &bra_data[0] + 2 * comp_size, comp_size);
26264 /* bulma - w - 64 */
26265 memcpy(&xfb.m_expected_data[0] + 4 * type_size + 3 * comp_size, &bulma_data[0] + 3 * comp_size, comp_size);
26268 /** Get body of main function for given shader stage
26270 * @param test_case_index Index of test case
26271 * @param stage Shader stage
26272 * @param out_assignments Set to empty
26273 * @param out_calculations Set to empty
26275 void XFBCaptureInactiveOutputComponentTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
26276 std::string& out_assignments, std::string& out_calculations)
26278 out_calculations = "";
26280 static const GLchar* vs_tes_gs = " goku.x = uni_goku.x ;\n"
26281 " goku.z = uni_goku.z ;\n"
26282 " gohan.y = uni_gohan.y ;\n"
26283 " gohan.w = uni_gohan.w ;\n"
26284 " goten.x = uni_goten.x ;\n"
26285 " goten.y = uni_goten.y ;\n"
26286 " chichi.z = uni_chichi.z ;\n"
26287 " chichi.w = uni_chichi.w ;\n"
26288 " vegeta.x = uni_vegeta.x ;\n"
26289 " trunks.y = uni_trunks.y ;\n"
26290 " bra.z = uni_bra.z ;\n"
26291 " bulma.w = uni_bulma.w ;\n";
26292 static const GLchar* fs = " fs_out = goku + gohan + goten + chichi + vegeta + trunks + bra + bulma;\n";
26294 const GLchar* assignments = "";
26298 case Utils::Shader::FRAGMENT:
26302 case Utils::Shader::GEOMETRY:
26303 if (TEST_GS == test_case_index)
26305 assignments = vs_tes_gs;
26309 case Utils::Shader::TESS_CTRL:
26312 case Utils::Shader::TESS_EVAL:
26313 if (TEST_TES == test_case_index)
26315 assignments = vs_tes_gs;
26319 case Utils::Shader::VERTEX:
26320 if (TEST_VS == test_case_index)
26322 assignments = vs_tes_gs;
26327 TCU_FAIL("Invalid enum");
26330 out_assignments = assignments;
26333 /** Get interface of shader
26335 * @param test_case_index Index of test case
26336 * @param stage Shader stage
26337 * @param out_interface Set to ""
26339 void XFBCaptureInactiveOutputComponentTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
26340 std::string& out_interface)
26342 static const GLchar* vs_tes_gs = "const uint sizeof_type = 16;\n"
26344 "layout (xfb_offset = 2 * sizeof_type) out vec4 goku;\n"
26345 "layout (xfb_offset = 0 * sizeof_type) out vec4 gohan;\n"
26346 "layout (xfb_offset = 1 * sizeof_type) out vec4 goten;\n"
26347 "layout (xfb_offset = 3 * sizeof_type) out vec4 chichi;\n"
26348 "layout (xfb_offset = 7 * sizeof_type) out vec4 vegeta;\n"
26349 "layout (xfb_offset = 6 * sizeof_type) out vec4 trunks;\n"
26350 "layout (xfb_offset = 5 * sizeof_type) out vec4 bra;\n"
26351 "layout (xfb_offset = 4 * sizeof_type) out vec4 bulma;\n"
26353 "layout(binding = 0) uniform block {\n"
26354 " vec4 uni_goku;\n"
26355 " vec4 uni_gohan;\n"
26356 " vec4 uni_goten;\n"
26357 " vec4 uni_chichi;\n"
26358 " vec4 uni_vegeta;\n"
26359 " vec4 uni_trunks;\n"
26361 " vec4 uni_bulma;\n"
26363 static const GLchar* fs = "in vec4 vegeta;\n"
26364 "in vec4 trunks;\n"
26370 "in vec4 chichi;\n"
26372 "out vec4 fs_out;\n";
26374 const GLchar* interface = "";
26378 case Utils::Shader::FRAGMENT:
26382 case Utils::Shader::GEOMETRY:
26383 if (TEST_GS == test_case_index)
26385 interface = vs_tes_gs;
26389 case Utils::Shader::TESS_CTRL:
26392 case Utils::Shader::TESS_EVAL:
26393 if (TEST_TES == test_case_index)
26395 interface = vs_tes_gs;
26399 case Utils::Shader::VERTEX:
26400 if (TEST_VS == test_case_index)
26402 interface = vs_tes_gs;
26407 TCU_FAIL("Invalid enum");
26410 out_interface = interface;
26413 /** Get source code of shader
26415 * @param test_case_index Index of test case
26416 * @param stage Shader stage
26420 std::string XFBCaptureInactiveOutputComponentTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
26422 std::string source;
26424 switch (test_case_index)
26429 case Utils::Shader::FRAGMENT:
26430 case Utils::Shader::VERTEX:
26431 source = BufferTestBase::getShaderSource(test_case_index, stage);
26441 case Utils::Shader::FRAGMENT:
26442 case Utils::Shader::TESS_CTRL:
26443 case Utils::Shader::TESS_EVAL:
26444 case Utils::Shader::VERTEX:
26445 source = BufferTestBase::getShaderSource(test_case_index, stage);
26453 source = BufferTestBase::getShaderSource(test_case_index, stage);
26457 TCU_FAIL("Invalid enum");
26465 /** Get name of test case
26467 * @param test_case_index Index of test case
26469 * @return Name of tested stage
26471 std::string XFBCaptureInactiveOutputComponentTest::getTestCaseName(glw::GLuint test_case_index)
26473 const GLchar* name = 0;
26475 switch (test_case_index)
26481 name = "tessellation evaluation";
26487 TCU_FAIL("Invalid enum");
26493 /** Returns number of test cases
26497 glw::GLuint XFBCaptureInactiveOutputComponentTest::getTestCaseNumber()
26502 /** Verify contents of buffers
26504 * @param buffers Collection of buffers to be verified
26506 * @return true if everything is as expected, false otherwise
26508 bool XFBCaptureInactiveOutputComponentTest::verifyBuffers(bufferCollection& buffers)
26510 bool result = true;
26512 bufferCollection::pair& pair = buffers.m_vector[1] /* xfb */;
26513 Utils::Buffer* buffer = pair.m_buffer;
26514 bufferDescriptor* descriptor = pair.m_descriptor;
26516 /* Get pointer to contents of buffer */
26518 GLubyte* buffer_data = (GLubyte*)buffer->Map(Utils::Buffer::ReadOnly);
26520 /* Get pointer to expected data */
26521 GLubyte* expected_data = (GLubyte*)&descriptor->m_expected_data[0];
26524 static const GLuint comp_size = 4;
26525 static const GLuint vec4_size = 16;
26528 memcmp(buffer_data + 2 * vec4_size + 0 * comp_size, expected_data + 2 * vec4_size + 0 * comp_size, comp_size);
26530 memcmp(buffer_data + 2 * vec4_size + 2 * comp_size, expected_data + 2 * vec4_size + 2 * comp_size, comp_size);
26533 memcmp(buffer_data + 0 * vec4_size + 1 * comp_size, expected_data + 0 * vec4_size + 1 * comp_size, comp_size);
26535 memcmp(buffer_data + 0 * vec4_size + 3 * comp_size, expected_data + 0 * vec4_size + 3 * comp_size, comp_size);
26538 memcmp(buffer_data + 1 * vec4_size + 0 * comp_size, expected_data + 1 * vec4_size + 0 * comp_size, comp_size);
26540 memcmp(buffer_data + 1 * vec4_size + 1 * comp_size, expected_data + 1 * vec4_size + 1 * comp_size, comp_size);
26543 memcmp(buffer_data + 3 * vec4_size + 2 * comp_size, expected_data + 3 * vec4_size + 2 * comp_size, comp_size);
26545 memcmp(buffer_data + 3 * vec4_size + 3 * comp_size, expected_data + 3 * vec4_size + 3 * comp_size, comp_size);
26548 memcmp(buffer_data + 7 * vec4_size + 0 * comp_size, expected_data + 7 * vec4_size + 0 * comp_size, comp_size);
26551 memcmp(buffer_data + 6 * vec4_size + 1 * comp_size, expected_data + 6 * vec4_size + 1 * comp_size, comp_size);
26554 memcmp(buffer_data + 5 * vec4_size + 2 * comp_size, expected_data + 5 * vec4_size + 2 * comp_size, comp_size);
26557 memcmp(buffer_data + 4 * vec4_size + 3 * comp_size, expected_data + 4 * vec4_size + 3 * comp_size, comp_size);
26559 if ((0 != res_goku_x) || (0 != res_goku_z) || (0 != res_gohan_y) || (0 != res_gohan_w) || (0 != res_goten_x) ||
26560 (0 != res_goten_y) || (0 != res_chichi_z) || (0 != res_chichi_w) || (0 != res_vegeta_x) ||
26561 (0 != res_trunks_y) || (0 != res_bra_z) || (0 != res_bulma_w))
26563 m_context.getTestContext().getLog()
26564 << tcu::TestLog::Message << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
26565 << ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
26570 /* Release buffer mapping */
26578 * @param context Test context
26580 XFBCaptureInactiveOutputBlockMemberTest::XFBCaptureInactiveOutputBlockMemberTest(deqp::Context& context)
26581 : BufferTestBase(context, "xfb_capture_inactive_output_block_member",
26582 "Test verifies that inactive block members are captured")
26584 /* Nothing to be done here */
26587 /** Execute drawArrays for single vertex
26589 * @param test_case_index
26593 bool XFBCaptureInactiveOutputBlockMemberTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
26595 const Functions& gl = m_context.getRenderContext().getFunctions();
26596 GLenum primitive_type = GL_PATCHES;
26598 if (TEST_VS == test_case_index)
26600 primitive_type = GL_POINTS;
26603 gl.disable(GL_RASTERIZER_DISCARD);
26604 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
26606 gl.beginTransformFeedback(GL_POINTS);
26607 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
26609 gl.drawArrays(primitive_type, 0 /* first */, 1 /* count */);
26610 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
26612 gl.endTransformFeedback();
26613 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
26618 /** Get descriptors of buffers necessary for test
26621 * @param out_descriptors Descriptors of buffers used by test
26623 void XFBCaptureInactiveOutputBlockMemberTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
26624 bufferDescriptor::Vector& out_descriptors)
26626 const Utils::Type& type = Utils::Type::vec4;
26628 /* Test needs single uniform and xfb */
26629 out_descriptors.resize(2);
26631 /* Get references */
26632 bufferDescriptor& uniform = out_descriptors[0];
26633 bufferDescriptor& xfb = out_descriptors[1];
26636 uniform.m_index = 0;
26640 uniform.m_target = Utils::Buffer::Uniform;
26641 xfb.m_target = Utils::Buffer::Transform_feedback;
26644 const std::vector<GLubyte>& gohan_data = type.GenerateData();
26645 const std::vector<GLubyte>& chichi_data = type.GenerateData();
26647 const GLuint type_size = static_cast<GLuint>(gohan_data.size());
26650 uniform.m_initial_data.resize(2 * type_size);
26651 memcpy(&uniform.m_initial_data[0] + 0, &gohan_data[0], type_size);
26652 memcpy(&uniform.m_initial_data[0] + type_size, &chichi_data[0], type_size);
26655 xfb.m_initial_data.resize(4 * type_size);
26656 xfb.m_expected_data.resize(4 * type_size);
26658 for (GLuint i = 0; i < 4 * type_size; ++i)
26660 xfb.m_initial_data[i] = (glw::GLubyte)i;
26661 xfb.m_expected_data[i] = (glw::GLubyte)i;
26664 memcpy(&xfb.m_expected_data[0] + 1 * type_size, &gohan_data[0], type_size);
26665 memcpy(&xfb.m_expected_data[0] + 3 * type_size, &chichi_data[0], type_size);
26668 /** Get body of main function for given shader stage
26670 * @param test_case_index Index of test case
26671 * @param stage Shader stage
26672 * @param out_assignments Set to empty
26673 * @param out_calculations Set to empty
26675 void XFBCaptureInactiveOutputBlockMemberTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
26676 std::string& out_assignments, std::string& out_calculations)
26678 out_calculations = "";
26680 static const GLchar* vs_tes_gs = " chichi = uni_chichi;\n"
26681 " gohan = uni_gohan;\n";
26682 static const GLchar* fs = " fs_out = goten + gohan + chichi;\n";
26684 const GLchar* assignments = "";
26688 case Utils::Shader::FRAGMENT:
26692 case Utils::Shader::GEOMETRY:
26693 if (TEST_GS == test_case_index)
26695 assignments = vs_tes_gs;
26699 case Utils::Shader::TESS_CTRL:
26702 case Utils::Shader::TESS_EVAL:
26703 if (TEST_TES == test_case_index)
26705 assignments = vs_tes_gs;
26709 case Utils::Shader::VERTEX:
26710 if (TEST_VS == test_case_index)
26712 assignments = vs_tes_gs;
26717 TCU_FAIL("Invalid enum");
26720 out_assignments = assignments;
26723 /** Get interface of shader
26725 * @param test_case_index Index of test case
26726 * @param stage Shader stage
26727 * @param out_interface Set to ""
26729 void XFBCaptureInactiveOutputBlockMemberTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
26730 std::string& out_interface)
26732 static const GLchar* vs_tes_gs = "const uint sizeof_type = 16;\n"
26734 "layout (xfb_offset = 1 * sizeof_type) out Goku {\n"
26740 "layout(binding = 0) uniform block {\n"
26741 " vec4 uni_gohan;\n"
26742 " vec4 uni_chichi;\n"
26744 static const GLchar* fs = "in Goku {\n"
26749 "out vec4 fs_out;\n";
26751 const GLchar* interface = "";
26755 case Utils::Shader::FRAGMENT:
26759 case Utils::Shader::GEOMETRY:
26760 if (TEST_GS == test_case_index)
26762 interface = vs_tes_gs;
26766 case Utils::Shader::TESS_CTRL:
26769 case Utils::Shader::TESS_EVAL:
26770 if (TEST_TES == test_case_index)
26772 interface = vs_tes_gs;
26776 case Utils::Shader::VERTEX:
26777 if (TEST_VS == test_case_index)
26779 interface = vs_tes_gs;
26784 TCU_FAIL("Invalid enum");
26787 out_interface = interface;
26790 /** Get source code of shader
26792 * @param test_case_index Index of test case
26793 * @param stage Shader stage
26797 std::string XFBCaptureInactiveOutputBlockMemberTest::getShaderSource(GLuint test_case_index,
26798 Utils::Shader::STAGES stage)
26800 std::string source;
26802 switch (test_case_index)
26807 case Utils::Shader::FRAGMENT:
26808 case Utils::Shader::VERTEX:
26809 source = BufferTestBase::getShaderSource(test_case_index, stage);
26819 case Utils::Shader::FRAGMENT:
26820 case Utils::Shader::TESS_CTRL:
26821 case Utils::Shader::TESS_EVAL:
26822 case Utils::Shader::VERTEX:
26823 source = BufferTestBase::getShaderSource(test_case_index, stage);
26831 source = BufferTestBase::getShaderSource(test_case_index, stage);
26835 TCU_FAIL("Invalid enum");
26843 /** Get name of test case
26845 * @param test_case_index Index of test case
26847 * @return Name of tested stage
26849 std::string XFBCaptureInactiveOutputBlockMemberTest::getTestCaseName(glw::GLuint test_case_index)
26851 const GLchar* name = 0;
26853 switch (test_case_index)
26859 name = "tessellation evaluation";
26865 TCU_FAIL("Invalid enum");
26871 /** Returns number of test cases
26875 glw::GLuint XFBCaptureInactiveOutputBlockMemberTest::getTestCaseNumber()
26880 /** Verify contents of buffers
26882 * @param buffers Collection of buffers to be verified
26884 * @return true if everything is as expected, false otherwise
26886 bool XFBCaptureInactiveOutputBlockMemberTest::verifyBuffers(bufferCollection& buffers)
26888 bool result = true;
26890 bufferCollection::pair& pair = buffers.m_vector[1] /* xfb */;
26891 Utils::Buffer* buffer = pair.m_buffer;
26892 bufferDescriptor* descriptor = pair.m_descriptor;
26894 /* Get pointer to contents of buffer */
26896 GLubyte* buffer_data = (GLubyte*)buffer->Map(Utils::Buffer::ReadOnly);
26898 /* Get pointer to expected data */
26899 GLubyte* expected_data = (GLubyte*)&descriptor->m_expected_data[0];
26902 static const GLuint vec4_size = 16;
26904 int res_before = memcmp(buffer_data, expected_data, vec4_size);
26905 int res_gohan = memcmp(buffer_data + 1 * vec4_size, expected_data + 1 * vec4_size, vec4_size);
26906 int res_chichi = memcmp(buffer_data + 3 * vec4_size, expected_data + 3 * vec4_size, vec4_size);
26908 if ((0 != res_before) || (0 != res_gohan) || (0 != res_chichi))
26910 m_context.getTestContext().getLog()
26911 << tcu::TestLog::Message << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
26912 << ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
26917 /* Release buffer mapping */
26925 * @param context Test context
26927 XFBCaptureStructTest::XFBCaptureStructTest(deqp::Context& context)
26928 : BufferTestBase(context, "xfb_capture_struct", "Test verifies that inactive structure members are captured")
26930 /* Nothing to be done here */
26933 /** Execute drawArrays for single vertex
26935 * @param test_case_index
26939 bool XFBCaptureStructTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
26941 const Functions& gl = m_context.getRenderContext().getFunctions();
26942 GLenum primitive_type = GL_PATCHES;
26944 if (TEST_VS == test_case_index)
26946 primitive_type = GL_POINTS;
26949 gl.disable(GL_RASTERIZER_DISCARD);
26950 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
26952 gl.beginTransformFeedback(GL_POINTS);
26953 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
26955 gl.drawArrays(primitive_type, 0 /* first */, 1 /* count */);
26956 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
26958 gl.endTransformFeedback();
26959 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
26964 /** Get descriptors of buffers necessary for test
26967 * @param out_descriptors Descriptors of buffers used by test
26969 void XFBCaptureStructTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
26970 bufferDescriptor::Vector& out_descriptors)
26972 const Utils::Type& type = Utils::Type::vec4;
26974 /* Test needs single uniform and xfb */
26975 out_descriptors.resize(2);
26977 /* Get references */
26978 bufferDescriptor& uniform = out_descriptors[0];
26979 bufferDescriptor& xfb = out_descriptors[1];
26982 uniform.m_index = 0;
26986 uniform.m_target = Utils::Buffer::Uniform;
26987 xfb.m_target = Utils::Buffer::Transform_feedback;
26990 const std::vector<GLubyte>& gohan_data = type.GenerateData();
26991 const std::vector<GLubyte>& chichi_data = type.GenerateData();
26993 const GLuint type_size = static_cast<GLuint>(gohan_data.size());
26996 uniform.m_initial_data.resize(2 * type_size);
26997 memcpy(&uniform.m_initial_data[0] + 0, &gohan_data[0], type_size);
26998 memcpy(&uniform.m_initial_data[0] + type_size, &chichi_data[0], type_size);
27001 xfb.m_initial_data.resize(4 * type_size);
27002 xfb.m_expected_data.resize(4 * type_size);
27004 for (GLuint i = 0; i < 4 * type_size; ++i)
27006 xfb.m_initial_data[i] = (glw::GLubyte)i;
27007 xfb.m_expected_data[i] = (glw::GLubyte)i;
27010 memcpy(&xfb.m_expected_data[0] + 1 * type_size, &gohan_data[0], type_size);
27011 memcpy(&xfb.m_expected_data[0] + 3 * type_size, &chichi_data[0], type_size);
27014 /** Get body of main function for given shader stage
27016 * @param test_case_index Index of test case
27017 * @param stage Shader stage
27018 * @param out_assignments Set to empty
27019 * @param out_calculations Set to empty
27021 void XFBCaptureStructTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
27022 std::string& out_assignments, std::string& out_calculations)
27024 out_calculations = "";
27026 static const GLchar* vs_tes_gs = " goku.chichi = uni_chichi;\n"
27027 " goku.gohan = uni_gohan;\n";
27028 static const GLchar* fs = " fs_out = goku.goten + goku.gohan + goku.chichi;\n";
27030 const GLchar* assignments = "";
27034 case Utils::Shader::FRAGMENT:
27038 case Utils::Shader::GEOMETRY:
27039 if (TEST_GS == test_case_index)
27041 assignments = vs_tes_gs;
27045 case Utils::Shader::TESS_CTRL:
27048 case Utils::Shader::TESS_EVAL:
27049 if (TEST_TES == test_case_index)
27051 assignments = vs_tes_gs;
27055 case Utils::Shader::VERTEX:
27056 if (TEST_VS == test_case_index)
27058 assignments = vs_tes_gs;
27063 TCU_FAIL("Invalid enum");
27066 out_assignments = assignments;
27069 /** Get interface of shader
27071 * @param test_case_index Index of test case
27072 * @param stage Shader stage
27073 * @param out_interface Set to ""
27075 void XFBCaptureStructTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
27076 std::string& out_interface)
27078 static const GLchar* vs_tes_gs = "const uint sizeof_type = 16;\n"
27086 "layout (xfb_offset = sizeof_type) out Goku goku;\n"
27088 "layout(binding = 0, std140) uniform block {\n"
27089 " vec4 uni_gohan;\n"
27090 " vec4 uni_chichi;\n"
27092 static const GLchar* fs = "struct Goku {\n"
27100 "out vec4 fs_out;\n";
27102 const GLchar* interface = "";
27106 case Utils::Shader::FRAGMENT:
27110 case Utils::Shader::GEOMETRY:
27111 if (TEST_GS == test_case_index)
27113 interface = vs_tes_gs;
27117 case Utils::Shader::TESS_CTRL:
27120 case Utils::Shader::TESS_EVAL:
27121 if (TEST_TES == test_case_index)
27123 interface = vs_tes_gs;
27127 case Utils::Shader::VERTEX:
27128 if (TEST_VS == test_case_index)
27130 interface = vs_tes_gs;
27135 TCU_FAIL("Invalid enum");
27138 out_interface = interface;
27141 /** Get source code of shader
27143 * @param test_case_index Index of test case
27144 * @param stage Shader stage
27148 std::string XFBCaptureStructTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
27150 std::string source;
27152 switch (test_case_index)
27157 case Utils::Shader::FRAGMENT:
27158 case Utils::Shader::VERTEX:
27159 source = BufferTestBase::getShaderSource(test_case_index, stage);
27169 case Utils::Shader::FRAGMENT:
27170 case Utils::Shader::TESS_CTRL:
27171 case Utils::Shader::TESS_EVAL:
27172 case Utils::Shader::VERTEX:
27173 source = BufferTestBase::getShaderSource(test_case_index, stage);
27181 source = BufferTestBase::getShaderSource(test_case_index, stage);
27185 TCU_FAIL("Invalid enum");
27193 /** Get name of test case
27195 * @param test_case_index Index of test case
27197 * @return Name of tested stage
27199 std::string XFBCaptureStructTest::getTestCaseName(glw::GLuint test_case_index)
27201 const GLchar* name = 0;
27203 switch (test_case_index)
27209 name = "tessellation evaluation";
27215 TCU_FAIL("Invalid enum");
27221 /** Returns number of test cases
27225 glw::GLuint XFBCaptureStructTest::getTestCaseNumber()
27230 /** Verify contents of buffers
27232 * @param buffers Collection of buffers to be verified
27234 * @return true if everything is as expected, false otherwise
27236 bool XFBCaptureStructTest::verifyBuffers(bufferCollection& buffers)
27238 bool result = true;
27240 bufferCollection::pair& pair = buffers.m_vector[1] /* xfb */;
27241 Utils::Buffer* buffer = pair.m_buffer;
27242 bufferDescriptor* descriptor = pair.m_descriptor;
27244 /* Get pointer to contents of buffer */
27246 GLubyte* buffer_data = (GLubyte*)buffer->Map(Utils::Buffer::ReadOnly);
27248 /* Get pointer to expected data */
27249 GLubyte* expected_data = (GLubyte*)&descriptor->m_expected_data[0];
27252 static const GLuint vec4_size = 16;
27254 int res_before = memcmp(buffer_data, expected_data, vec4_size);
27255 int res_gohan = memcmp(buffer_data + 1 * vec4_size, expected_data + 1 * vec4_size, vec4_size);
27256 int res_chichi = memcmp(buffer_data + 3 * vec4_size, expected_data + 3 * vec4_size, vec4_size);
27258 if ((0 != res_before) || (0 != res_gohan) || (0 != res_chichi))
27260 m_context.getTestContext().getLog()
27261 << tcu::TestLog::Message << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
27262 << ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
27267 /* Release buffer mapping */
27275 * @param context Test framework context
27277 XFBCaptureUnsizedArrayTest::XFBCaptureUnsizedArrayTest(deqp::Context& context)
27278 : NegativeTestBase(context, "xfb_capture_unsized_array",
27279 "Test verifies that compiler reports error when unsized array is qualified with xfb_offset")
27283 /** Source for given test case and stage
27285 * @param test_case_index Index of test case
27286 * @param stage Shader stage
27288 * @return Shader source
27290 std::string XFBCaptureUnsizedArrayTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
27292 static const GLchar* var_definition = "layout (xfb_offset = 0) out vec4 gokuARRAY[];\n";
27293 static const GLchar* var_use = " gokuINDEX[0] = result / 2;\n";
27294 static const GLchar* fs = "#version 430 core\n"
27295 "#extension GL_ARB_enhanced_layouts : require\n"
27298 "out vec4 fs_out;\n"
27302 " fs_out = gs_fs;\n"
27305 static const GLchar* gs_tested = "#version 430 core\n"
27306 "#extension GL_ARB_enhanced_layouts : require\n"
27308 "layout(points) in;\n"
27309 "layout(triangle_strip, max_vertices = 4) out;\n"
27313 "in vec4 tes_gs[];\n"
27314 "out vec4 gs_fs;\n"
27318 " vec4 result = tes_gs[0];\n"
27322 " gs_fs = result;\n"
27323 " gl_Position = vec4(-1, -1, 0, 1);\n"
27325 " gs_fs = result;\n"
27326 " gl_Position = vec4(-1, 1, 0, 1);\n"
27328 " gs_fs = result;\n"
27329 " gl_Position = vec4(1, -1, 0, 1);\n"
27331 " gs_fs = result;\n"
27332 " gl_Position = vec4(1, 1, 0, 1);\n"
27336 static const GLchar* tcs = "#version 430 core\n"
27337 "#extension GL_ARB_enhanced_layouts : require\n"
27339 "layout(vertices = 1) out;\n"
27341 "in vec4 vs_tcs[];\n"
27342 "out vec4 tcs_tes[];\n"
27347 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
27349 " gl_TessLevelOuter[0] = 1.0;\n"
27350 " gl_TessLevelOuter[1] = 1.0;\n"
27351 " gl_TessLevelOuter[2] = 1.0;\n"
27352 " gl_TessLevelOuter[3] = 1.0;\n"
27353 " gl_TessLevelInner[0] = 1.0;\n"
27354 " gl_TessLevelInner[1] = 1.0;\n"
27357 static const GLchar* tcs_tested = "#version 430 core\n"
27358 "#extension GL_ARB_enhanced_layouts : require\n"
27360 "layout(vertices = 1) out;\n"
27364 "in vec4 vs_tcs[];\n"
27365 "out vec4 tcs_tes[];\n"
27369 " vec4 result = vs_tcs[gl_InvocationID];\n"
27373 " tcs_tes[gl_InvocationID] = result;\n"
27375 " gl_TessLevelOuter[0] = 1.0;\n"
27376 " gl_TessLevelOuter[1] = 1.0;\n"
27377 " gl_TessLevelOuter[2] = 1.0;\n"
27378 " gl_TessLevelOuter[3] = 1.0;\n"
27379 " gl_TessLevelInner[0] = 1.0;\n"
27380 " gl_TessLevelInner[1] = 1.0;\n"
27383 static const GLchar* tes_tested = "#version 430 core\n"
27384 "#extension GL_ARB_enhanced_layouts : require\n"
27386 "layout(isolines, point_mode) in;\n"
27390 "in vec4 tcs_tes[];\n"
27391 "out vec4 tes_gs;\n"
27395 " vec4 result = tcs_tes[0];\n"
27399 " tes_gs += result;\n"
27402 static const GLchar* vs = "#version 430 core\n"
27403 "#extension GL_ARB_enhanced_layouts : require\n"
27406 "out vec4 vs_tcs;\n"
27410 " vs_tcs = in_vs;\n"
27413 static const GLchar* vs_tested = "#version 430 core\n"
27414 "#extension GL_ARB_enhanced_layouts : require\n"
27419 "out vec4 vs_tcs;\n"
27423 " vec4 result = in_vs;\n"
27427 " vs_tcs = result;\n"
27431 std::string source;
27432 testCase& test_case = m_test_cases[test_case_index];
27434 if (test_case.m_stage == stage)
27436 const GLchar* array = "";
27437 const GLchar* index = "";
27438 size_t position = 0;
27442 case Utils::Shader::GEOMETRY:
27443 source = gs_tested;
27447 case Utils::Shader::TESS_CTRL:
27448 source = tcs_tested;
27450 index = "[gl_InvocationID]";
27452 case Utils::Shader::TESS_EVAL:
27453 source = tes_tested;
27457 case Utils::Shader::VERTEX:
27458 source = vs_tested;
27461 TCU_FAIL("Invalid enum");
27464 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
27466 Utils::replaceToken("ARRAY", position, array, source);
27467 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
27469 Utils::replaceAllTokens("INDEX", index, source);
27473 switch (test_case.m_stage)
27475 case Utils::Shader::GEOMETRY:
27478 case Utils::Shader::FRAGMENT:
27481 case Utils::Shader::VERTEX:
27488 case Utils::Shader::TESS_CTRL:
27491 case Utils::Shader::FRAGMENT:
27494 case Utils::Shader::VERTEX:
27501 case Utils::Shader::TESS_EVAL:
27504 case Utils::Shader::FRAGMENT:
27507 case Utils::Shader::TESS_CTRL:
27510 case Utils::Shader::VERTEX:
27517 case Utils::Shader::VERTEX:
27520 case Utils::Shader::FRAGMENT:
27528 TCU_FAIL("Invalid enum");
27536 /** Get description of test case
27538 * @param test_case_index Index of test case
27540 * @return Test case description
27542 std::string XFBCaptureUnsizedArrayTest::getTestCaseName(GLuint test_case_index)
27544 std::stringstream stream;
27545 testCase& test_case = m_test_cases[test_case_index];
27547 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage);
27549 return stream.str();
27552 /** Get number of test cases
27554 * @return Number of test cases
27556 GLuint XFBCaptureUnsizedArrayTest::getTestCaseNumber()
27558 return static_cast<GLuint>(m_test_cases.size());
27561 /** Selects if "compute" stage is relevant for test
27567 bool XFBCaptureUnsizedArrayTest::isComputeRelevant(GLuint /* test_case_index */)
27572 /** Prepare all test cases
27575 void XFBCaptureUnsizedArrayTest::testInit()
27577 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
27579 /* Not aplicable for */
27580 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::FRAGMENT == stage) ||
27581 (Utils::Shader::GEOMETRY == stage) || (Utils::Shader::TESS_EVAL == stage))
27586 testCase test_case = { (Utils::Shader::STAGES)stage };
27588 m_test_cases.push_back(test_case);
27591 } /* EnhancedLayouts namespace */
27595 * @param context Rendering context.
27597 EnhancedLayoutsTests::EnhancedLayoutsTests(deqp::Context& context)
27598 : TestCaseGroup(context, "enhanced_layouts", "Verifies \"enhanced layouts\" functionality")
27600 /* Left blank on purpose */
27603 /** Initializes a texture_storage_multisample test group.
27606 void EnhancedLayoutsTests::init(void)
27608 addChild(new EnhancedLayouts::APIConstantValuesTest(m_context));
27609 addChild(new EnhancedLayouts::APIErrorsTest(m_context));
27610 addChild(new EnhancedLayouts::GLSLContantValuesTest(m_context));
27611 addChild(new EnhancedLayouts::GLSLContantImmutablityTest(m_context));
27612 addChild(new EnhancedLayouts::GLSLConstantIntegralExpressionTest(m_context));
27613 addChild(new EnhancedLayouts::UniformBlockLayoutQualifierConflictTest(m_context));
27614 addChild(new EnhancedLayouts::SSBMemberInvalidOffsetAlignmentTest(m_context));
27615 addChild(new EnhancedLayouts::SSBMemberOverlappingOffsetsTest(m_context));
27616 addChild(new EnhancedLayouts::VaryingExceedingComponentsTest(m_context));
27617 addChild(new EnhancedLayouts::VaryingComponentOfInvalidTypeTest(m_context));
27618 addChild(new EnhancedLayouts::OutputComponentAliasingTest(m_context));
27619 addChild(new EnhancedLayouts::VertexAttribLocationAPITest(m_context));
27620 addChild(new EnhancedLayouts::XFBInputTest(m_context));
27621 addChild(new EnhancedLayouts::XFBAllStagesTest(m_context));
27622 addChild(new EnhancedLayouts::XFBCaptureInactiveOutputVariableTest(m_context));
27623 addChild(new EnhancedLayouts::XFBCaptureInactiveOutputComponentTest(m_context));
27624 addChild(new EnhancedLayouts::XFBCaptureInactiveOutputBlockMemberTest(m_context));
27625 addChild(new EnhancedLayouts::XFBStrideTest(m_context));
27627 addChild(new EnhancedLayouts::UniformBlockMemberOffsetAndAlignTest(m_context));
27628 addChild(new EnhancedLayouts::UniformBlockMemberInvalidOffsetAlignmentTest(m_context));
27629 addChild(new EnhancedLayouts::UniformBlockMemberOverlappingOffsetsTest(m_context));
27630 addChild(new EnhancedLayouts::UniformBlockMemberAlignNonPowerOf2Test(m_context));
27631 addChild(new EnhancedLayouts::SSBLayoutQualifierConflictTest(m_context));
27632 addChild(new EnhancedLayouts::SSBMemberAlignNonPowerOf2Test(m_context));
27633 addChild(new EnhancedLayouts::SSBAlignmentTest(m_context));
27634 addChild(new EnhancedLayouts::VaryingStructureMemberLocationTest(m_context));
27635 addChild(new EnhancedLayouts::VaryingBlockAutomaticMemberLocationsTest(m_context));
27636 addChild(new EnhancedLayouts::VaryingComponentWithoutLocationTest(m_context));
27637 addChild(new EnhancedLayouts::InputComponentAliasingTest(m_context));
27638 addChild(new EnhancedLayouts::VaryingLocationAliasingWithMixedTypesTest(m_context));
27639 addChild(new EnhancedLayouts::VaryingLocationAliasingWithMixedInterpolationTest(m_context));
27640 addChild(new EnhancedLayouts::VaryingLocationAliasingWithMixedAuxiliaryStorageTest(m_context));
27641 addChild(new EnhancedLayouts::XFBStrideOfEmptyListTest(m_context));
27642 addChild(new EnhancedLayouts::XFBStrideOfEmptyListAndAPITest(m_context));
27643 addChild(new EnhancedLayouts::XFBTooSmallStrideTest(m_context));
27644 addChild(new EnhancedLayouts::XFBBlockMemberStrideTest(m_context));
27645 addChild(new EnhancedLayouts::XFBDuplicatedStrideTest(m_context));
27646 addChild(new EnhancedLayouts::XFBGetProgramResourceAPITest(m_context));
27647 addChild(new EnhancedLayouts::XFBMultipleVertexStreamsTest(m_context));
27648 addChild(new EnhancedLayouts::XFBExceedBufferLimitTest(m_context));
27649 addChild(new EnhancedLayouts::XFBExceedOffsetLimitTest(m_context));
27650 addChild(new EnhancedLayouts::XFBBlockMemberBufferTest(m_context));
27651 addChild(new EnhancedLayouts::XFBOutputOverlappingTest(m_context));
27652 addChild(new EnhancedLayouts::XFBInvalidOffsetAlignmentTest(m_context));
27653 addChild(new EnhancedLayouts::XFBCaptureStructTest(m_context));
27654 addChild(new EnhancedLayouts::XFBCaptureUnsizedArrayTest(m_context));
27655 addChild(new EnhancedLayouts::UniformBlockAlignmentTest(m_context));
27656 addChild(new EnhancedLayouts::SSBMemberOffsetAndAlignTest(m_context));
27657 addChild(new EnhancedLayouts::VertexAttribLocationsTest(m_context));
27658 addChild(new EnhancedLayouts::VaryingLocationsTest(m_context));
27659 addChild(new EnhancedLayouts::VaryingArrayLocationsTest(m_context));
27660 addChild(new EnhancedLayouts::VaryingStructureLocationsTest(m_context));
27661 addChild(new EnhancedLayouts::VaryingBlockLocationsTest(m_context));
27662 addChild(new EnhancedLayouts::VaryingBlockMemberLocationsTest(m_context));
27663 addChild(new EnhancedLayouts::XFBVariableStrideTest(m_context));
27664 addChild(new EnhancedLayouts::XFBBlockStrideTest(m_context));
27665 addChild(new EnhancedLayouts::XFBOverrideQualifiersWithAPITest(m_context));
27666 addChild(new EnhancedLayouts::XFBVertexStreamsTest(m_context));
27667 addChild(new EnhancedLayouts::XFBGlobalBufferTest(m_context));
27668 addChild(new EnhancedLayouts::FragmentDataLocationAPITest(m_context));
27669 addChild(new EnhancedLayouts::VaryingLocationLimitTest(m_context));
27670 addChild(new EnhancedLayouts::VaryingComponentsTest(m_context));
27671 addChild(new EnhancedLayouts::VaryingArrayComponentsTest(m_context));
27674 } /* gl4cts namespace */