1 /*-------------------------------------------------------------------------
2 * OpenGL Conformance Test Suite
3 * -----------------------------
5 * Copyright (c) 2015-2016 The Khronos Group Inc.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
22 */ /*-------------------------------------------------------------------*/
25 * \file gl4cEnhancedLayoutsTests.cpp
26 * \brief Implements conformance tests for "Enhanced Layouts" functionality.
27 */ /*-------------------------------------------------------------------*/
29 #include "gl4cEnhancedLayoutsTests.hpp"
31 #include "gluContextInfo.hpp"
32 #include "gluDefs.hpp"
33 #include "gluStrUtil.hpp"
34 #include "glwEnums.hpp"
35 #include "glwFunctions.hpp"
36 #include "tcuTestLog.hpp"
45 #define DEBUG_ENBALE_MESSAGE_CALLBACK 0
46 #define DEBUG_NEG_LOG_ERROR 0
47 #define DEBUG_REPLACE_TOKEN 0
48 #define DEBUG_REPEAT_TEST_CASE 0
49 #define DEBUG_REPEATED_TEST_CASE 0
51 /* Texture test base */
52 #define DEBUG_TTB_VERIFICATION_SNIPPET_STAGE 0
53 #define DEBUG_TTB_VERIFICATION_SNIPPET_VARIABLE 0
56 #define DEBUG_VERTEX_ATTRIB_LOCATIONS_TEST_VARIABLE 0
59 #define WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST 0
60 #define WRKARD_UNIFORMBLOCKMEMBERALIGNNONPOWEROF2TEST 0
61 #define WRKARD_UNIFORMBLOCKALIGNMENT 0
62 #define WRKARD_VARYINGLOCATIONSTEST 0
68 namespace EnhancedLayouts
72 /** Constants used by "random" generators **/
73 static const GLuint s_rand_start = 3;
74 static const GLuint s_rand_max = 16;
75 static const GLuint s_rand_max_half = s_rand_max / 2;
77 /** Seed used by "random" generators **/
78 static GLuint s_rand = s_rand_start;
80 /** Get "random" unsigned int value
84 static GLuint GetRandUint()
86 const GLuint rand = s_rand++;
88 if (s_rand_max <= s_rand)
90 s_rand = s_rand_start;
96 /** Get "random" int value
102 const GLint rand = GetRandUint() - s_rand_max_half;
107 /** Get "random" double value
111 GLdouble GetRandDouble()
113 const GLint rand = GetRandInt();
115 GLdouble result = (GLfloat)rand / (GLdouble)s_rand_max_half;
120 /** Get "random" float value
124 GLfloat GetRandFloat()
126 const GLint rand = GetRandInt();
128 GLfloat result = (GLfloat)rand / (GLfloat)s_rand_max_half;
133 /** String used by list routines **/
134 static const GLchar* const g_list = "LIST";
136 /** Type constants **/
137 const Type Type::_double = Type::GetType(Type::Double, 1, 1);
138 const Type Type::dmat2 = Type::GetType(Type::Double, 2, 2);
139 const Type Type::dmat2x3 = Type::GetType(Type::Double, 2, 3);
140 const Type Type::dmat2x4 = Type::GetType(Type::Double, 2, 4);
141 const Type Type::dmat3x2 = Type::GetType(Type::Double, 3, 2);
142 const Type Type::dmat3 = Type::GetType(Type::Double, 3, 3);
143 const Type Type::dmat3x4 = Type::GetType(Type::Double, 3, 4);
144 const Type Type::dmat4x2 = Type::GetType(Type::Double, 4, 2);
145 const Type Type::dmat4x3 = Type::GetType(Type::Double, 4, 3);
146 const Type Type::dmat4 = Type::GetType(Type::Double, 4, 4);
147 const Type Type::dvec2 = Type::GetType(Type::Double, 1, 2);
148 const Type Type::dvec3 = Type::GetType(Type::Double, 1, 3);
149 const Type Type::dvec4 = Type::GetType(Type::Double, 1, 4);
150 const Type Type::_int = Type::GetType(Type::Int, 1, 1);
151 const Type Type::ivec2 = Type::GetType(Type::Int, 1, 2);
152 const Type Type::ivec3 = Type::GetType(Type::Int, 1, 3);
153 const Type Type::ivec4 = Type::GetType(Type::Int, 1, 4);
154 const Type Type::_float = Type::GetType(Type::Float, 1, 1);
155 const Type Type::mat2 = Type::GetType(Type::Float, 2, 2);
156 const Type Type::mat2x3 = Type::GetType(Type::Float, 2, 3);
157 const Type Type::mat2x4 = Type::GetType(Type::Float, 2, 4);
158 const Type Type::mat3x2 = Type::GetType(Type::Float, 3, 2);
159 const Type Type::mat3 = Type::GetType(Type::Float, 3, 3);
160 const Type Type::mat3x4 = Type::GetType(Type::Float, 3, 4);
161 const Type Type::mat4x2 = Type::GetType(Type::Float, 4, 2);
162 const Type Type::mat4x3 = Type::GetType(Type::Float, 4, 3);
163 const Type Type::mat4 = Type::GetType(Type::Float, 4, 4);
164 const Type Type::vec2 = Type::GetType(Type::Float, 1, 2);
165 const Type Type::vec3 = Type::GetType(Type::Float, 1, 3);
166 const Type Type::vec4 = Type::GetType(Type::Float, 1, 4);
167 const Type Type::uint = Type::GetType(Type::Uint, 1, 1);
168 const Type Type::uvec2 = Type::GetType(Type::Uint, 1, 2);
169 const Type Type::uvec3 = Type::GetType(Type::Uint, 1, 3);
170 const Type Type::uvec4 = Type::GetType(Type::Uint, 1, 4);
172 /** Generate data for type. This routine follows STD140 rules
174 * @return Vector of bytes filled with data
176 std::vector<GLubyte> Type::GenerateData() const
178 const GLuint alignment = GetActualAlignment(0, false);
180 std::vector<GLubyte> data;
181 data.resize(alignment * m_n_columns);
183 for (GLuint column = 0; column < m_n_columns; ++column)
185 GLvoid* ptr = (GLvoid*)&data[column * alignment];
187 switch (m_basic_type)
191 GLdouble* d_ptr = (GLdouble*)ptr;
193 for (GLuint i = 0; i < m_n_rows; ++i)
195 d_ptr[i] = GetRandDouble();
201 GLfloat* f_ptr = (GLfloat*)ptr;
203 for (GLuint i = 0; i < m_n_rows; ++i)
205 f_ptr[i] = GetRandFloat();
211 GLint* i_ptr = (GLint*)ptr;
213 for (GLuint i = 0; i < m_n_rows; ++i)
215 i_ptr[i] = GetRandInt();
221 GLuint* ui_ptr = (GLuint*)ptr;
223 for (GLuint i = 0; i < m_n_rows; ++i)
225 ui_ptr[i] = GetRandUint();
235 /** Generate data for type. This routine packs data tightly.
237 * @return Vector of bytes filled with data
239 std::vector<GLubyte> Type::GenerateDataPacked() const
241 const GLuint basic_size = GetTypeSize(m_basic_type);
242 const GLuint n_elements = m_n_columns * m_n_rows;
243 const GLuint size = basic_size * n_elements;
245 std::vector<GLubyte> data;
248 GLvoid* ptr = (GLvoid*)&data[0];
250 switch (m_basic_type)
254 GLdouble* d_ptr = (GLdouble*)ptr;
256 for (GLuint i = 0; i < n_elements; ++i)
258 d_ptr[i] = GetRandDouble();
264 GLfloat* f_ptr = (GLfloat*)ptr;
266 for (GLuint i = 0; i < n_elements; ++i)
268 f_ptr[i] = GetRandFloat();
274 GLint* i_ptr = (GLint*)ptr;
276 for (GLuint i = 0; i < n_elements; ++i)
278 i_ptr[i] = GetRandInt();
284 GLuint* ui_ptr = (GLuint*)ptr;
286 for (GLuint i = 0; i < n_elements; ++i)
288 ui_ptr[i] = GetRandUint();
297 /** Calculate "actual alignment". It work under assumption that align value is valid
299 * @param align Requested alignment, eg with "align" qualifier
300 * @param is_array Selects if an array of type or single instance should be considered
302 * @return Calculated value
304 GLuint Type::GetActualAlignment(GLuint align, bool is_array) const
306 const GLuint base_alignment = GetBaseAlignment(is_array);
308 return std::max(align, base_alignment);
311 /** Align given ofset with specified alignment
313 * @param offset Offset
314 * @param alignment Alignment
316 * @return Calculated value
318 GLuint align(GLuint offset, GLuint alignment)
320 const GLuint rest = offset % alignment;
324 GLuint missing = alignment - rest;
331 /** Calculate "actual offset"
333 * @param start_offset Requested offset
334 * @param actual_alignment Actual alignemnt
336 * @return Calculated value
338 GLuint Type::GetActualOffset(GLuint start_offset, GLuint actual_alignment)
340 GLuint offset = align(start_offset, actual_alignment);
345 /** Calculate "base alignment" for given type
347 * @param is_array Select if array or single instance should be considered
349 * @return Calculated value
351 GLuint Type::GetBaseAlignment(bool is_array) const
368 GLuint N = GetTypeSize(m_basic_type);
369 GLuint alignment = N * elements;
371 if ((true == is_array) || (1 != m_n_columns))
373 alignment = align(alignment, 16 /* vec4 alignment */);
379 /** Returns string representing GLSL constructor of type with arguments provided in data
381 * @param data Array of values that will be used as construcotr arguments.
382 * It is interpreted as tightly packed array of type matching this type.
384 * @return String in form "Type(args)"
386 std::string Type::GetGLSLConstructor(const GLvoid* data) const
388 const GLchar* type = GetGLSLTypeName();
390 std::stringstream stream;
392 stream << type << "(";
394 /* Scalar or vector */
395 if (1 == m_n_columns)
397 for (GLuint row = 0; row < m_n_rows; ++row)
399 switch (m_basic_type)
402 stream << ((GLdouble*)data)[row];
405 stream << ((GLfloat*)data)[row];
408 stream << ((GLint*)data)[row];
411 stream << ((GLuint*)data)[row];
415 if (row + 1 != m_n_rows)
421 else /* Matrix: mat(vec(), vec() .. ) */
423 const GLuint basic_size = GetTypeSize(m_basic_type);
424 // Very indescoverable defect, the column stride should be calculated by rows, such as mat2x3, which is 2, columns 3 rows, its column stride should be 3 * sizeof(float)
425 const GLuint column_stride = m_n_rows * basic_size;
426 const Type column_type = GetType(m_basic_type, 1, m_n_rows);
428 for (GLuint column = 0; column < m_n_columns; ++column)
430 const GLuint column_offset = column * column_stride;
431 const GLvoid* column_data = (GLubyte*)data + column_offset;
433 stream << column_type.GetGLSLConstructor(column_data);
435 if (column + 1 != m_n_columns)
447 /** Get glsl name of the type
449 * @return Name of glsl type
451 const glw::GLchar* Type::GetGLSLTypeName() const
453 static const GLchar* float_lut[4][4] = {
454 { "float", "vec2", "vec3", "vec4" },
455 { 0, "mat2", "mat2x3", "mat2x4" },
456 { 0, "mat3x2", "mat3", "mat3x4" },
457 { 0, "mat4x2", "mat4x3", "mat4" },
460 static const GLchar* double_lut[4][4] = {
461 { "double", "dvec2", "dvec3", "dvec4" },
462 { 0, "dmat2", "dmat2x3", "dmat2x4" },
463 { 0, "dmat3x2", "dmat3", "dmat3x4" },
464 { 0, "dmat4x2", "dmat4x3", "dmat4" },
467 static const GLchar* int_lut[4] = { "int", "ivec2", "ivec3", "ivec4" };
469 static const GLchar* uint_lut[4] = { "uint", "uvec2", "uvec3", "uvec4" };
471 const GLchar* result = 0;
473 if ((1 > m_n_columns) || (1 > m_n_rows) || (4 < m_n_columns) || (4 < m_n_rows))
478 switch (m_basic_type)
481 result = float_lut[m_n_columns - 1][m_n_rows - 1];
484 result = double_lut[m_n_columns - 1][m_n_rows - 1];
487 result = int_lut[m_n_rows - 1];
490 result = uint_lut[m_n_rows - 1];
493 TCU_FAIL("Invliad enum");
499 /** Get number of locations required for the type
501 * @return Number of columns times:
502 * - 2 when type is double with 3 or 4 rows,
505 GLuint Type::GetLocations() const
507 GLuint n_loc_per_column;
509 /* 1 or 2 doubles any for rest */
510 if ((2 >= m_n_rows) || (Double != m_basic_type))
512 n_loc_per_column = 1;
516 /* 3 and 4 doubles */
517 n_loc_per_column = 2;
520 return n_loc_per_column * m_n_columns;
523 /** Get size of the type in bytes. Note that this routine assumes tightly packing
525 * @return Formula Number of columns * number of rows * sizeof(base_type)
527 GLuint Type::GetSize() const
529 const GLuint basic_type_size = GetTypeSize(m_basic_type);
530 const GLuint n_elements = m_n_columns * m_n_rows;
532 return basic_type_size * n_elements;
535 /** Get GLenum representing the type
539 GLenum Type::GetTypeGLenum() const
541 static const GLenum float_lut[4][4] = {
542 { GL_FLOAT, GL_FLOAT_VEC2, GL_FLOAT_VEC3, GL_FLOAT_VEC4 },
543 { 0, GL_FLOAT_MAT2, GL_FLOAT_MAT2x3, GL_FLOAT_MAT2x4 },
544 { 0, GL_FLOAT_MAT3x2, GL_FLOAT_MAT3, GL_FLOAT_MAT3x4 },
545 { 0, GL_FLOAT_MAT4x2, GL_FLOAT_MAT4x3, GL_FLOAT_MAT4 },
548 static const GLenum double_lut[4][4] = {
549 { GL_DOUBLE, GL_DOUBLE_VEC2, GL_DOUBLE_VEC3, GL_DOUBLE_VEC4 },
550 { 0, GL_DOUBLE_MAT2, GL_DOUBLE_MAT2x3, GL_DOUBLE_MAT2x4 },
551 { 0, GL_DOUBLE_MAT3x2, GL_DOUBLE_MAT3, GL_DOUBLE_MAT3x4 },
552 { 0, GL_DOUBLE_MAT4x2, GL_DOUBLE_MAT4x3, GL_DOUBLE_MAT4 },
555 static const GLenum int_lut[4] = { GL_INT, GL_INT_VEC2, GL_INT_VEC3, GL_INT_VEC4 };
557 static const GLenum uint_lut[4] = { GL_UNSIGNED_INT, GL_UNSIGNED_INT_VEC2, GL_UNSIGNED_INT_VEC3,
558 GL_UNSIGNED_INT_VEC4 };
562 if ((1 > m_n_columns) || (1 > m_n_rows) || (4 < m_n_columns) || (4 < m_n_rows))
567 switch (m_basic_type)
570 result = float_lut[m_n_columns - 1][m_n_rows - 1];
573 result = double_lut[m_n_columns - 1][m_n_rows - 1];
576 result = int_lut[m_n_rows - 1];
579 result = uint_lut[m_n_rows - 1];
582 TCU_FAIL("Invliad enum");
588 /** Calculate the numbe of components consumed by a type
589 * according to 11.1.2.1 Output Variables
591 * @return Calculated number of components for the type
593 GLuint Type::GetNumComponents() const
595 // Rule 3 of Section 7.6.2.2
596 // If the member is a three-component vector with components consuming N
597 // basic machine units, the base alignment is 4N.
598 GLuint num_components = (m_n_rows == 3 ? 4 : m_n_rows) * m_n_columns;
600 if (m_basic_type == Double)
605 return num_components;
608 /** Calculate stride for the type according to std140 rules
610 * @param alignment Alignment of type
611 * @param n_columns Number of columns
612 * @param n_array_elements Number of elements in array
614 * @return Calculated value
616 GLuint Type::CalculateStd140Stride(GLuint alignment, GLuint n_columns, GLuint n_array_elements)
618 GLuint stride = alignment * n_columns;
619 if (0 != n_array_elements)
621 stride *= n_array_elements;
627 /** Check if glsl support matrices for specific basic type
629 * @param type Basic type
631 * @return true if matrices of <type> are supported, false otherwise
633 bool Type::DoesTypeSupportMatrix(TYPES type)
648 TCU_FAIL("Invliad enum");
654 /** Creates instance of Type
656 * @param basic_type Select basic type of instance
657 * @param n_columns Number of columns
658 * @param n_rows Number of rows
660 * @return Type instance
662 Type Type::GetType(TYPES basic_type, glw::GLuint n_columns, glw::GLuint n_rows)
664 Type type = { basic_type, n_columns, n_rows };
669 /** Get Size of given type in bytes
673 * @return Size of type
675 GLuint Type::GetTypeSize(TYPES type)
682 result = sizeof(GLfloat);
685 result = sizeof(GLdouble);
688 result = sizeof(GLint);
691 result = sizeof(GLuint);
694 TCU_FAIL("Invalid enum");
700 /** Get GLenum representing given type
704 * @return GLenum value
706 GLenum Type::GetTypeGLenum(TYPES type)
722 result = GL_UNSIGNED_INT;
725 TCU_FAIL("Invalid enum");
731 /** Get proper glUniformNdv routine for vectors with specified number of rows
733 * @param gl GL functions
734 * @param n_rows Number of rows
736 * @return Function address
738 uniformNdv getUniformNdv(const glw::Functions& gl, glw::GLuint n_rows)
740 uniformNdv result = 0;
745 result = gl.uniform1dv;
748 result = gl.uniform2dv;
751 result = gl.uniform3dv;
754 result = gl.uniform4dv;
757 TCU_FAIL("Invalid number of rows");
763 /** Get proper glUniformNfv routine for vectors with specified number of rows
765 * @param gl GL functions
766 * @param n_rows Number of rows
768 * @return Function address
770 uniformNfv getUniformNfv(const glw::Functions& gl, glw::GLuint n_rows)
772 uniformNfv result = 0;
777 result = gl.uniform1fv;
780 result = gl.uniform2fv;
783 result = gl.uniform3fv;
786 result = gl.uniform4fv;
789 TCU_FAIL("Invalid number of rows");
795 /** Get proper glUniformNiv routine for vectors with specified number of rows
797 * @param gl GL functions
798 * @param n_rows Number of rows
800 * @return Function address
802 uniformNiv getUniformNiv(const glw::Functions& gl, glw::GLuint n_rows)
804 uniformNiv result = 0;
809 result = gl.uniform1iv;
812 result = gl.uniform2iv;
815 result = gl.uniform3iv;
818 result = gl.uniform4iv;
821 TCU_FAIL("Invalid number of rows");
827 /** Get proper glUniformNuiv routine for vectors with specified number of rows
829 * @param gl GL functions
830 * @param n_rows Number of rows
832 * @return Function address
834 uniformNuiv getUniformNuiv(const glw::Functions& gl, glw::GLuint n_rows)
836 uniformNuiv result = 0;
841 result = gl.uniform1uiv;
844 result = gl.uniform2uiv;
847 result = gl.uniform3uiv;
850 result = gl.uniform4uiv;
853 TCU_FAIL("Invalid number of rows");
859 /** Get proper glUniformMatrixNdv routine for matrix with specified number of columns and rows
861 * @param gl GL functions
862 * @param n_rows Number of rows
864 * @return Function address
866 uniformMatrixNdv getUniformMatrixNdv(const glw::Functions& gl, glw::GLuint n_columns, glw::GLuint n_rows)
868 uniformMatrixNdv result = 0;
876 result = gl.uniformMatrix2dv;
879 result = gl.uniformMatrix2x3dv;
882 result = gl.uniformMatrix2x4dv;
885 TCU_FAIL("Invalid number of rows");
892 result = gl.uniformMatrix3x2dv;
895 result = gl.uniformMatrix3dv;
898 result = gl.uniformMatrix3x4dv;
901 TCU_FAIL("Invalid number of rows");
908 result = gl.uniformMatrix4x2dv;
911 result = gl.uniformMatrix4x3dv;
914 result = gl.uniformMatrix4dv;
917 TCU_FAIL("Invalid number of rows");
921 TCU_FAIL("Invalid number of columns");
927 /** Get proper glUniformMatrixNfv routine for vectors with specified number of columns and rows
929 * @param gl GL functions
930 * @param n_rows Number of rows
932 * @return Function address
934 uniformMatrixNfv getUniformMatrixNfv(const glw::Functions& gl, glw::GLuint n_columns, glw::GLuint n_rows)
936 uniformMatrixNfv result = 0;
944 result = gl.uniformMatrix2fv;
947 result = gl.uniformMatrix2x3fv;
950 result = gl.uniformMatrix2x4fv;
953 TCU_FAIL("Invalid number of rows");
960 result = gl.uniformMatrix3x2fv;
963 result = gl.uniformMatrix3fv;
966 result = gl.uniformMatrix3x4fv;
969 TCU_FAIL("Invalid number of rows");
976 result = gl.uniformMatrix4x2fv;
979 result = gl.uniformMatrix4x3fv;
982 result = gl.uniformMatrix4fv;
985 TCU_FAIL("Invalid number of rows");
989 TCU_FAIL("Invalid number of columns");
995 bool verifyVarying(Program& program, const std::string& parent_name, const Variable::Descriptor& desc,
996 std::stringstream& stream, bool is_input)
1000 GLenum interface = GL_PROGRAM_INPUT;
1003 if (false == is_input)
1005 interface = GL_PROGRAM_OUTPUT;
1008 const std::string& name = Utils::Variable::GetReference(parent_name, desc, Utils::Variable::BASIC, 0);
1012 index = program.GetResourceIndex(name, interface);
1014 program.GetResource(interface, index, GL_LOCATION, 1 /* size */, &location);
1015 program.GetResource(interface, index, GL_LOCATION_COMPONENT, 1 /* size */, &component);
1017 catch (std::exception& exc)
1019 stream << "Failed to query program for varying: " << desc.m_name << ". Reason: " << exc.what() << "\n";
1026 if (location != desc.m_expected_location)
1028 stream << "Attribute: " << desc.m_name << " - invalid location: " << location
1029 << " expected: " << desc.m_expected_location << std::endl;
1032 if (component != desc.m_expected_component)
1034 stream << "Attribute: " << desc.m_name << " - invalid component: " << component
1035 << " expected: " << desc.m_expected_component << std::endl;
1042 /** Query program resource for given variable and verify that everything is as expected
1044 * @param program Program object
1045 * @param variable Variable object
1046 * @param stream Stream that will be used to log any error
1047 * @param is_input Selects if varying is input or output
1049 * @return true if verification is positive, false otherwise
1051 bool checkVarying(Program& program, const Variable& variable, std::stringstream& stream, bool is_input)
1055 if (variable.IsBlock())
1057 Utils::Interface* interface = variable.m_descriptor.m_interface;
1058 const size_t n_members = interface->m_members.size();
1060 for (size_t i = 0; i < n_members; ++i)
1062 const Variable::Descriptor& member = interface->m_members[i];
1063 bool member_result = verifyVarying(program, interface->m_name, member, stream, is_input);
1065 if (false == member_result)
1072 To query the the location of struct member by glGetProgramResource, we need pass the variable name "gs_fs_output[0].single",
1073 but in original implementation, the test pass the name "Data.single", which can't get any valid result.
1078 layout (location = 0) in Data gs_fs_output[1];
1080 else if (variable.IsStruct())
1082 Utils::Interface* interface = variable.m_descriptor.m_interface;
1083 const size_t n_members = interface->m_members.size();
1084 std::string structVariable = variable.m_descriptor.m_name;
1085 // If struct variable is an array
1086 if (0 != variable.m_descriptor.m_n_array_elements)
1088 for (GLuint i = 0; i < variable.m_descriptor.m_n_array_elements; i++)
1091 sprintf(buffer, "%d", i);
1092 structVariable.append("[");
1093 structVariable.append(buffer);
1094 structVariable.append("]");
1095 for (size_t j = 0; j < n_members; ++j)
1097 const Variable::Descriptor& member = interface->m_members[j];
1098 bool member_result = verifyVarying(program, structVariable, member, stream, is_input);
1100 if (false == member_result)
1109 for (GLuint i = 0; i < n_members; ++i)
1111 const Variable::Descriptor& member = interface->m_members[i];
1112 bool member_result = verifyVarying(program, structVariable, member, stream, is_input);
1114 if (false == member_result)
1123 result = verifyVarying(program, "", variable.m_descriptor, stream, is_input);
1128 /** Query program resource for given variable and verify that everything is as expected
1130 * @param program Program object
1131 * @param variable Variable object
1132 * @param stream Stream that will be used to log any error
1134 * @return true if verification is positive, false otherwise
1136 bool checkUniform(Program& program, const Utils::Variable& variable, std::stringstream& stream)
1140 if (false == variable.IsBlock())
1142 TCU_FAIL("Not implemented");
1146 Utils::Interface* interface = variable.m_descriptor.m_interface;
1148 size_t size = interface->m_members.size();
1150 std::vector<GLuint> indices;
1151 std::vector<const char*> names;
1152 std::vector<std::string> names_str;
1153 std::vector<GLint> offsets;
1155 indices.resize(size);
1157 names_str.resize(size);
1158 offsets.resize(size);
1160 for (size_t i = 0; i < size; ++i)
1165 const std::string& name =
1166 Utils::Variable::GetReference(interface->m_name, interface->m_members[i], Utils::Variable::BASIC, 0);
1168 if (Utils::Variable::INTERFACE == interface->m_members[i].m_type)
1170 const std::string& member_name = Utils::Variable::GetReference(
1171 name, interface->m_members[i].m_interface->m_members[0], Utils::Variable::BASIC, 0);
1173 names_str[i] = member_name;
1177 names_str[i] = name;
1180 names[i] = names_str[i].c_str();
1185 program.GetUniformIndices(static_cast<glw::GLsizei>(size), &names[0], &indices[0]);
1186 program.GetActiveUniformsiv(static_cast<glw::GLsizei>(size), &indices[0], GL_UNIFORM_OFFSET, &offsets[0]);
1188 catch (std::exception& exc)
1190 stream << "Failed to query program for uniforms in block: " << variable.m_descriptor.m_name
1191 << ". Reason: " << exc.what() << "\n";
1196 for (size_t i = 0; i < size; ++i)
1198 Utils::Variable::Descriptor& desc = interface->m_members[i];
1200 if (offsets[i] != (GLint)desc.m_offset)
1202 stream << "Uniform: " << desc.m_name << " - invalid offset: " << offsets[i]
1203 << " expected: " << desc.m_offset << std::endl;
1212 /** Query program resource for given variable and verify that everything is as expected
1214 * @param program Program object
1215 * @param variable Variable object
1216 * @param stream Stream that will be used to log any error
1218 * @return true if verification is positive, false otherwise
1220 bool checkSSB(Program& program, const Utils::Variable& variable, std::stringstream& stream)
1224 if (false == variable.IsBlock())
1226 TCU_FAIL("Not implemented");
1230 Utils::Interface* interface = variable.m_descriptor.m_interface;
1232 size_t size = interface->m_members.size();
1234 for (size_t i = 0; i < size; ++i)
1237 std::string name_str = "";
1240 const std::string& name =
1241 Utils::Variable::GetReference(interface->m_name, interface->m_members[i], Utils::Variable::BASIC, 0);
1243 if (Utils::Variable::INTERFACE == interface->m_members[i].m_type)
1245 const std::string& member_name = Utils::Variable::GetReference(
1246 name, interface->m_members[i].m_interface->m_members[0], Utils::Variable::BASIC, 0);
1248 name_str = member_name;
1257 index = program.GetResourceIndex(name_str, GL_BUFFER_VARIABLE);
1259 program.GetResource(GL_BUFFER_VARIABLE, index, GL_OFFSET, 1, &offset);
1261 catch (std::exception& exc)
1263 stream << "Failed to query program for buffer variable: " << variable.m_descriptor.m_name
1264 << ". Reason: " << exc.what() << "\n";
1269 Utils::Variable::Descriptor& desc = interface->m_members[i];
1271 if (offset != (GLint)desc.m_offset)
1273 stream << "Uniform: " << desc.m_name << " - invalid offset: " << offset
1274 << " expected: " << desc.m_offset << std::endl;
1283 /** Query program resources at given stage and verifies results
1285 * @param program Program object
1286 * @param program_interface Definition of program interface
1287 * @param stage Stage to be verified
1288 * @param check_inputs Select if inputs should be verified
1289 * @param check_outputs Select if output should be verified
1290 * @param check_uniforms Select if uniforms should be verified
1291 * @param check_ssbs Select if buffers should be verified
1292 * @param stream Stream that will be used to log any error
1294 * @return true if verification is positive, false otherwise
1296 bool checkProgramStage(Program& program, const ProgramInterface& program_interface, Utils::Shader::STAGES stage,
1297 bool check_inputs, bool check_outputs, bool check_uniforms, bool check_ssbs,
1298 std::stringstream& stream)
1300 typedef Variable::PtrVector::const_iterator const_iterator;
1302 const ShaderInterface& interface = program_interface.GetShaderInterface(stage);
1307 if (true == check_inputs)
1309 const Variable::PtrVector& inputs = interface.m_inputs;
1311 for (const_iterator it = inputs.begin(); it != inputs.end(); ++it)
1313 if (false == checkVarying(program, **it, stream, true))
1321 if (true == check_outputs)
1323 const Variable::PtrVector& outputs = interface.m_outputs;
1325 for (const_iterator it = outputs.begin(); it != outputs.end(); ++it)
1327 if (false == checkVarying(program, **it, stream, false))
1335 if (true == check_uniforms)
1337 const Variable::PtrVector& uniforms = interface.m_uniforms;
1339 for (const_iterator it = uniforms.begin(); it != uniforms.end(); ++it)
1341 if (false == checkUniform(program, **it, stream))
1349 if (true == check_ssbs)
1351 const Variable::PtrVector& ssbs = interface.m_ssb_blocks;
1353 for (const_iterator it = ssbs.begin(); it != ssbs.end(); ++it)
1355 if (false == checkSSB(program, **it, stream))
1365 /** Query resources of monolithic compute program and verifies results
1367 * @param program Program object
1368 * @param program_interface Definition of program interface
1369 * @param stream Stream that will be used to log any error
1371 * @return true if verification is positive, false otherwise
1373 bool checkMonolithicComputeProgramInterface(Program& program, const ProgramInterface& program_interface,
1374 std::stringstream& stream)
1378 if (false == checkProgramStage(program, program_interface, Shader::COMPUTE, false, false, true, true, stream))
1387 /** Query resources of monolithic draw program and verifies results
1389 * @param program Program object
1390 * @param program_interface Definition of program interface
1391 * @param stream Stream that will be used to log any error
1393 * @return true if verification is positive, false otherwise
1395 bool checkMonolithicDrawProgramInterface(Program& program, const ProgramInterface& program_interface,
1396 std::stringstream& stream)
1400 if (false == checkProgramStage(program, program_interface, Shader::VERTEX, true, false, true, true, stream))
1409 /** Query resources of separable draw program and verifies results
1411 * @param program Program object
1412 * @param program_interface Definition of program interface
1413 * @param stream Stream that will be used to log any error
1415 * @return true if verification is positive, false otherwise
1417 bool checkSeparableDrawProgramInterface(Program& program, const ProgramInterface& program_interface,
1418 Utils::Shader::STAGES stage, std::stringstream& stream)
1422 if (false == checkProgramStage(program, program_interface, stage, true, true, true, true, stream))
1431 /** Check if extension is supported
1433 * @param context Test context
1434 * @param extension_name Name of extension
1436 * @return true if extension is supported, false otherwise
1438 bool isExtensionSupported(deqp::Context& context, const GLchar* extension_name)
1440 const std::vector<std::string>& extensions = context.getContextInfo().getExtensions();
1442 if (std::find(extensions.begin(), extensions.end(), extension_name) == extensions.end())
1450 /** Check if GL context meets version requirements
1452 * @param gl Functions
1453 * @param required_major Minimum required MAJOR_VERSION
1454 * @param required_minor Minimum required MINOR_VERSION
1456 * @return true if GL context version is at least as requested, false otherwise
1458 bool isGLVersionAtLeast(const Functions& gl, GLint required_major, GLint required_minor)
1460 glw::GLint major = 0;
1461 glw::GLint minor = 0;
1463 gl.getIntegerv(GL_MAJOR_VERSION, &major);
1464 gl.getIntegerv(GL_MINOR_VERSION, &minor);
1466 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
1468 if (major > required_major)
1470 /* Major is higher than required one */
1473 else if (major == required_major)
1475 if (minor >= required_minor)
1477 /* Major is equal to required one */
1478 /* Minor is higher than or equal to required one */
1483 /* Major is equal to required one */
1484 /* Minor is lower than required one */
1490 /* Major is lower than required one */
1495 /** Replace first occurance of <token> with <text> in <string> starting at <search_posistion>
1497 * @param token Token string
1498 * @param search_position Position at which find will start, it is updated to position at which replaced text ends
1499 * @param text String that will be used as replacement for <token>
1500 * @param string String to work on
1502 void replaceToken(const GLchar* token, size_t& search_position, const GLchar* text, std::string& string)
1504 const size_t text_length = strlen(text);
1505 const size_t token_length = strlen(token);
1506 const size_t token_position = string.find(token, search_position);
1508 #if DEBUG_REPLACE_TOKEN
1509 if (std::string::npos == token_position)
1511 string.append("\n\nInvalid token: ");
1512 string.append(token);
1514 TCU_FAIL(string.c_str());
1516 #endif /* DEBUG_REPLACE_TOKEN */
1518 string.replace(token_position, token_length, text, text_length);
1520 search_position = token_position + text_length;
1523 /** Replace all occurances of <token> with <text> in <string>
1525 * @param token Token string
1526 * @param text String that will be used as replacement for <token>
1527 * @param string String to work on
1529 void replaceAllTokens(const GLchar* token, const GLchar* text, std::string& string)
1531 const size_t text_length = strlen(text);
1532 const size_t token_length = strlen(token);
1534 size_t search_position = 0;
1538 const size_t token_position = string.find(token, search_position);
1540 if (std::string::npos == token_position)
1545 search_position = token_position + text_length;
1547 string.replace(token_position, token_length, text, text_length);
1551 /** Rounds up the value to the next power of 2.
1552 * This routine does not work for 0, see the url for explanations.
1554 * @param value Starting point
1556 * @return Calculated value
1558 glw::GLuint roundUpToPowerOf2(glw::GLuint value)
1560 /* Taken from: graphics.stanford.edu/~seander/bithacks.html */
1563 value |= value >> 1;
1564 value |= value >> 2;
1565 value |= value >> 4;
1566 value |= value >> 8;
1567 value |= value >> 16;
1574 /** Insert elements of list into string.
1575 * List in string is represented either by token "LIST" or "SEPARATORLIST".
1576 * If SEPARATORLIST is available, than SEPARATOR is replaced with <separator>.
1577 * LIST is replaced with <element>SEPARATORLIST
1579 * @param element Element to be inserted
1580 * @param separator Separator inserted between elements
1581 * @param search_position Position in string, where search for list should start
1582 * @param string String
1584 void insertElementOfList(const GLchar* element, const GLchar* separator, size_t& search_position, std::string& string)
1586 static const char* list = g_list;
1587 static const char* sep_list = "SEPARATORLIST";
1589 /* Try to get "list" positions */
1590 const size_t list_position = string.find(list, search_position);
1591 const size_t sep_list_position = string.find(sep_list, search_position);
1593 /* There is no list in string */
1594 if (std::string::npos == list_position)
1599 if (9 /* strlen(SEPARATOR) */ == list_position - sep_list_position)
1601 replaceToken("SEPARATOR", search_position, separator, string);
1604 /* Save search_position */
1605 const size_t start_position = search_position;
1607 /* Prepare new element */
1608 replaceToken("LIST", search_position, "ELEMENTSEPARATORLIST", string);
1610 /* Restore search_position */
1611 search_position = start_position;
1613 /* Replace element and separator */
1614 replaceToken("ELEMENT", search_position, element, string);
1617 /** Close list in string.
1618 * If SEPARATORLIST is available, than SEPARATOR is replaced with <separator>
1619 * LIST is replaced with ""
1621 * @param separator Separator inserted between elements
1622 * @param search_position Position in string, where search for list should start
1623 * @param string String
1625 void endList(const glw::GLchar* separator, size_t& search_position, std::string& string)
1627 const size_t sep_position = string.find("SEPARATOR", search_position);
1628 if (std::string::npos != sep_position)
1630 replaceToken("SEPARATOR", search_position, separator, string);
1633 replaceToken("LIST", search_position, "", string);
1636 /* Buffer constants */
1637 const GLuint Buffer::m_invalid_id = -1;
1641 * @param context CTS context.
1643 Buffer::Buffer(deqp::Context& context) : m_id(m_invalid_id), m_buffer(Array), m_context(context)
1655 /** Initialize buffer instance
1657 * @param buffer Buffer type
1658 * @param usage Buffer usage enum
1659 * @param size <size> parameter
1660 * @param data <data> parameter
1662 void Buffer::Init(BUFFERS buffer, USAGE usage, GLsizeiptr size, GLvoid* data)
1664 /* Delete previous buffer instance */
1669 const Functions& gl = m_context.getRenderContext().getFunctions();
1672 Bind(gl, m_id, m_buffer);
1673 Data(gl, m_buffer, usage, size, data);
1676 /** Release buffer instance
1679 void Buffer::Release()
1681 if (m_invalid_id != m_id)
1683 const Functions& gl = m_context.getRenderContext().getFunctions();
1685 gl.deleteBuffers(1, &m_id);
1686 m_id = m_invalid_id;
1690 /** Binds buffer to its target
1693 void Buffer::Bind() const
1695 const Functions& gl = m_context.getRenderContext().getFunctions();
1697 Bind(gl, m_id, m_buffer);
1700 /** Binds indexed buffer
1702 * @param index <index> parameter
1704 void Buffer::BindBase(GLuint index) const
1706 const Functions& gl = m_context.getRenderContext().getFunctions();
1708 BindBase(gl, m_id, m_buffer, index);
1711 /** Binds range of buffer
1713 * @param index <index> parameter
1714 * @param offset <offset> parameter
1715 * @param size <size> parameter
1717 void Buffer::BindRange(GLuint index, GLintptr offset, GLsizeiptr size) const
1719 const Functions& gl = m_context.getRenderContext().getFunctions();
1721 BindRange(gl, m_id, m_buffer, index, offset, size);
1724 /** Allocate memory for buffer and sends initial content
1726 * @param usage Buffer usage enum
1727 * @param size <size> parameter
1728 * @param data <data> parameter
1730 void Buffer::Data(USAGE usage, glw::GLsizeiptr size, glw::GLvoid* data)
1732 const Functions& gl = m_context.getRenderContext().getFunctions();
1734 Data(gl, m_buffer, usage, size, data);
1737 /** Maps contents of buffer into CPU space
1739 * @param access Requested access
1741 * @return Pointer to memory region available for CPU
1743 GLvoid* Buffer::Map(ACCESS access)
1745 const Functions& gl = m_context.getRenderContext().getFunctions();
1747 return Map(gl, m_buffer, access);
1750 /** Allocate memory for buffer and sends initial content
1752 * @param offset Offset in buffer
1753 * @param size <size> parameter
1754 * @param data <data> parameter
1756 void Buffer::SubData(glw::GLintptr offset, glw::GLsizeiptr size, glw::GLvoid* data)
1758 const Functions& gl = m_context.getRenderContext().getFunctions();
1760 SubData(gl, m_buffer, offset, size, data);
1763 /** Maps contents of buffer into CPU space
1765 void Buffer::UnMap()
1767 const Functions& gl = m_context.getRenderContext().getFunctions();
1769 return UnMap(gl, m_buffer);
1772 /** Bind buffer to given target
1774 * @param gl GL functions
1775 * @param id Id of buffer
1776 * @param buffer Buffer enum
1778 void Buffer::Bind(const Functions& gl, GLuint id, BUFFERS buffer)
1780 GLenum target = GetBufferGLenum(buffer);
1782 gl.bindBuffer(target, id);
1783 GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffer");
1786 /** Binds indexed buffer
1788 * @param gl GL functions
1789 * @param id Id of buffer
1790 * @param buffer Buffer enum
1791 * @param index <index> parameter
1793 void Buffer::BindBase(const Functions& gl, GLuint id, BUFFERS buffer, GLuint index)
1795 GLenum target = GetBufferGLenum(buffer);
1797 gl.bindBufferBase(target, index, id);
1798 GLU_EXPECT_NO_ERROR(gl.getError(), "BindBufferBase");
1801 /** Binds buffer range
1803 * @param gl GL functions
1804 * @param id Id of buffer
1805 * @param buffer Buffer enum
1806 * @param index <index> parameter
1807 * @param offset <offset> parameter
1808 * @param size <size> parameter
1810 void Buffer::BindRange(const Functions& gl, GLuint id, BUFFERS buffer, GLuint index, GLintptr offset, GLsizeiptr size)
1812 GLenum target = GetBufferGLenum(buffer);
1814 gl.bindBufferRange(target, index, id, offset, size);
1815 GLU_EXPECT_NO_ERROR(gl.getError(), "BindBufferRange");
1818 /** Allocate memory for buffer and sends initial content
1820 * @param gl GL functions
1821 * @param buffer Buffer enum
1822 * @param usage Buffer usage enum
1823 * @param size <size> parameter
1824 * @param data <data> parameter
1826 void Buffer::Data(const glw::Functions& gl, BUFFERS buffer, USAGE usage, glw::GLsizeiptr size, glw::GLvoid* data)
1828 GLenum target = GetBufferGLenum(buffer);
1829 GLenum gl_usage = GetUsageGLenum(usage);
1831 gl.bufferData(target, size, data, gl_usage);
1832 GLU_EXPECT_NO_ERROR(gl.getError(), "BufferData");
1835 /** Allocate memory for buffer and sends initial content
1837 * @param gl GL functions
1838 * @param buffer Buffer enum
1839 * @param offset Offset in buffer
1840 * @param size <size> parameter
1841 * @param data <data> parameter
1843 void Buffer::SubData(const glw::Functions& gl, BUFFERS buffer, glw::GLintptr offset, glw::GLsizeiptr size,
1846 GLenum target = GetBufferGLenum(buffer);
1848 gl.bufferSubData(target, offset, size, data);
1849 GLU_EXPECT_NO_ERROR(gl.getError(), "BufferSubData");
1854 * @param gl GL functions
1855 * @param out_id Id of buffer
1857 void Buffer::Generate(const Functions& gl, GLuint& out_id)
1859 GLuint id = m_invalid_id;
1861 gl.genBuffers(1, &id);
1862 GLU_EXPECT_NO_ERROR(gl.getError(), "GenBuffers");
1864 if (m_invalid_id == id)
1866 TCU_FAIL("Got invalid id");
1872 /** Maps buffer content
1874 * @param gl GL functions
1875 * @param buffer Buffer enum
1876 * @param access Access rights for mapped region
1878 * @return Mapped memory
1880 void* Buffer::Map(const Functions& gl, BUFFERS buffer, ACCESS access)
1882 GLenum target = GetBufferGLenum(buffer);
1883 GLenum gl_access = GetAccessGLenum(access);
1885 void* result = gl.mapBuffer(target, gl_access);
1886 GLU_EXPECT_NO_ERROR(gl.getError(), "MapBuffer");
1894 void Buffer::UnMap(const Functions& gl, BUFFERS buffer)
1896 GLenum target = GetBufferGLenum(buffer);
1898 gl.unmapBuffer(target);
1899 GLU_EXPECT_NO_ERROR(gl.getError(), "UnmapBuffer");
1902 /** Return GLenum representation of requested access
1904 * @param access Requested access
1906 * @return GLenum value
1908 GLenum Buffer::GetAccessGLenum(ACCESS access)
1915 result = GL_READ_ONLY;
1918 result = GL_WRITE_ONLY;
1921 result = GL_READ_WRITE;
1924 TCU_FAIL("Invalid enum");
1930 /** Return GLenum representation of requested buffer type
1932 * @param buffer Requested buffer type
1934 * @return GLenum value
1936 GLenum Buffer::GetBufferGLenum(BUFFERS buffer)
1943 result = GL_ARRAY_BUFFER;
1946 result = GL_ELEMENT_ARRAY_BUFFER;
1948 case Shader_Storage:
1949 result = GL_SHADER_STORAGE_BUFFER;
1952 result = GL_TEXTURE_BUFFER;
1954 case Transform_feedback:
1955 result = GL_TRANSFORM_FEEDBACK_BUFFER;
1958 result = GL_UNIFORM_BUFFER;
1961 TCU_FAIL("Invalid enum");
1967 /** Return GLenum representation of requested usage
1969 * @param usage Requested usage
1971 * @return GLenum value
1973 GLenum Buffer::GetUsageGLenum(USAGE usage)
1980 result = GL_DYNAMIC_COPY;
1983 result = GL_DYNAMIC_DRAW;
1986 result = GL_DYNAMIC_READ;
1989 result = GL_STATIC_COPY;
1992 result = GL_STATIC_DRAW;
1995 result = GL_STATIC_READ;
1998 result = GL_STREAM_COPY;
2001 result = GL_STREAM_DRAW;
2004 result = GL_STREAM_READ;
2007 TCU_FAIL("Invalid enum");
2013 /** Returns name of buffer target
2015 * @param buffer Target enum
2017 * @return Name of target
2019 const GLchar* Buffer::GetBufferName(BUFFERS buffer)
2021 const GLchar* name = 0;
2031 case Shader_Storage:
2032 name = "Shader_Storage";
2037 case Transform_feedback:
2038 name = "Transform_feedback";
2044 TCU_FAIL("Invalid enum");
2050 /* Framebuffer constants */
2051 const GLuint Framebuffer::m_invalid_id = -1;
2055 * @param context CTS context
2057 Framebuffer::Framebuffer(deqp::Context& context) : m_id(m_invalid_id), m_context(context)
2059 /* Nothing to be done here */
2065 Framebuffer::~Framebuffer()
2070 /** Initialize framebuffer instance
2073 void Framebuffer::Init()
2075 /* Delete previous instance */
2078 const Functions& gl = m_context.getRenderContext().getFunctions();
2083 /** Release framebuffer instance
2086 void Framebuffer::Release()
2088 if (m_invalid_id != m_id)
2090 const Functions& gl = m_context.getRenderContext().getFunctions();
2092 gl.deleteFramebuffers(1, &m_id);
2093 m_id = m_invalid_id;
2097 /** Attach texture to specified attachment
2099 * @param attachment Attachment
2100 * @param texture_id Texture id
2101 * @param width Texture width
2102 * @param height Texture height
2104 void Framebuffer::AttachTexture(GLenum attachment, GLuint texture_id, GLuint width, GLuint height)
2106 const Functions& gl = m_context.getRenderContext().getFunctions();
2108 AttachTexture(gl, attachment, texture_id, width, height);
2111 /** Binds framebuffer to DRAW_FRAMEBUFFER
2114 void Framebuffer::Bind()
2116 const Functions& gl = m_context.getRenderContext().getFunctions();
2121 /** Clear framebuffer
2123 * @param mask <mask> parameter of glClear. Decides which shall be cleared
2125 void Framebuffer::Clear(GLenum mask)
2127 const Functions& gl = m_context.getRenderContext().getFunctions();
2132 /** Specifies clear color
2134 * @param red Red channel
2135 * @param green Green channel
2136 * @param blue Blue channel
2137 * @param alpha Alpha channel
2139 void Framebuffer::ClearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
2141 const Functions& gl = m_context.getRenderContext().getFunctions();
2143 ClearColor(gl, red, green, blue, alpha);
2146 /** Attach texture to specified attachment
2148 * @param gl GL functions
2149 * @param attachment Attachment
2150 * @param texture_id Texture id
2151 * @param width Texture width
2152 * @param height Texture height
2154 void Framebuffer::AttachTexture(const Functions& gl, GLenum attachment, GLuint texture_id, GLuint width, GLuint height)
2156 gl.framebufferTexture(GL_DRAW_FRAMEBUFFER, attachment, texture_id, 0 /* level */);
2157 GLU_EXPECT_NO_ERROR(gl.getError(), "FramebufferTexture");
2159 gl.viewport(0 /* x */, 0 /* y */, width, height);
2160 GLU_EXPECT_NO_ERROR(gl.getError(), "Viewport");
2163 /** Binds framebuffer to DRAW_FRAMEBUFFER
2165 * @param gl GL functions
2166 * @param id ID of framebuffer
2168 void Framebuffer::Bind(const Functions& gl, GLuint id)
2170 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, id);
2171 GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer");
2174 /** Clear framebuffer
2176 * @param gl GL functions
2177 * @param mask <mask> parameter of glClear. Decides which shall be cleared
2179 void Framebuffer::Clear(const Functions& gl, GLenum mask)
2182 GLU_EXPECT_NO_ERROR(gl.getError(), "Clear");
2185 /** Specifies clear color
2187 * @param gl GL functions
2188 * @param red Red channel
2189 * @param green Green channel
2190 * @param blue Blue channel
2191 * @param alpha Alpha channel
2193 void Framebuffer::ClearColor(const Functions& gl, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
2195 gl.clearColor(red, green, blue, alpha);
2196 GLU_EXPECT_NO_ERROR(gl.getError(), "ClearColor");
2199 /** Generate framebuffer
2202 void Framebuffer::Generate(const Functions& gl, GLuint& out_id)
2204 GLuint id = m_invalid_id;
2206 gl.genFramebuffers(1, &id);
2207 GLU_EXPECT_NO_ERROR(gl.getError(), "GenFramebuffers");
2209 if (m_invalid_id == id)
2211 TCU_FAIL("Invalid id");
2217 /* Shader's constants */
2218 const GLuint Shader::m_invalid_id = 0;
2222 * @param context CTS context.
2224 Shader::Shader(deqp::Context& context) : m_id(m_invalid_id), m_context(context)
2226 /* Nothing to be done here */
2237 /** Initialize shader instance
2239 * @param stage Shader stage
2240 * @param source Source code
2242 void Shader::Init(STAGES stage, const std::string& source)
2244 if (true == source.empty())
2246 /* No source == no shader */
2250 /* Delete any previous shader */
2253 /* Create, set source and compile */
2254 const Functions& gl = m_context.getRenderContext().getFunctions();
2256 Create(gl, stage, m_id);
2257 Source(gl, m_id, source);
2263 catch (const CompilationException& exc)
2265 throw InvalidSourceException(exc.what(), source, stage);
2269 /** Release shader instance
2272 void Shader::Release()
2274 if (m_invalid_id != m_id)
2276 const Functions& gl = m_context.getRenderContext().getFunctions();
2278 gl.deleteShader(m_id);
2279 m_id = m_invalid_id;
2285 * @param gl GL functions
2286 * @param id Shader id
2288 void Shader::Compile(const Functions& gl, GLuint id)
2290 GLint status = GL_FALSE;
2293 gl.compileShader(id);
2294 GLU_EXPECT_NO_ERROR(gl.getError(), "CompileShader");
2296 /* Get compilation status */
2297 gl.getShaderiv(id, GL_COMPILE_STATUS, &status);
2298 GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");
2300 /* Log compilation error */
2301 if (GL_TRUE != status)
2303 glw::GLint length = 0;
2304 std::string message;
2306 /* Error log length */
2307 gl.getShaderiv(id, GL_INFO_LOG_LENGTH, &length);
2308 GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");
2310 /* Prepare storage */
2311 message.resize(length, 0);
2314 gl.getShaderInfoLog(id, length, 0, &message[0]);
2315 GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderInfoLog");
2317 throw CompilationException(message.c_str());
2323 * @param gl GL functions
2324 * @param stage Shader stage
2325 * @param out_id Shader id
2327 void Shader::Create(const Functions& gl, STAGES stage, GLuint& out_id)
2329 const GLenum shaderType = GetShaderStageGLenum(stage);
2330 const GLuint id = gl.createShader(shaderType);
2331 GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
2333 if (m_invalid_id == id)
2335 TCU_FAIL("Failed to create shader");
2341 /** Set shader's source code
2343 * @param gl GL functions
2344 * @param id Shader id
2345 * @param source Shader source code
2347 void Shader::Source(const Functions& gl, GLuint id, const std::string& source)
2349 const GLchar* code = source.c_str();
2351 gl.shaderSource(id, 1 /* count */, &code, 0 /* lengths */);
2352 GLU_EXPECT_NO_ERROR(gl.getError(), "ShaderSource");
2355 /** Get GLenum repesenting shader stage
2357 * @param stage Shader stage
2361 GLenum Shader::GetShaderStageGLenum(STAGES stage)
2368 result = GL_COMPUTE_SHADER;
2371 result = GL_FRAGMENT_SHADER;
2374 result = GL_GEOMETRY_SHADER;
2377 result = GL_TESS_CONTROL_SHADER;
2380 result = GL_TESS_EVALUATION_SHADER;
2383 result = GL_VERTEX_SHADER;
2386 TCU_FAIL("Invalid enum");
2392 /** Get string representing name of shader stage
2394 * @param stage Shader stage
2396 * @return String with name of shader stage
2398 const glw::GLchar* Shader::GetStageName(STAGES stage)
2400 const GLchar* result = 0;
2411 result = "tesselation control";
2414 result = "tesselation evaluation";
2417 result = "geomtery";
2420 result = "fragment";
2423 TCU_FAIL("Invalid enum");
2429 /** Logs shader source
2431 * @param context CTS context
2432 * @param source Source of shader
2433 * @param stage Shader stage
2435 void Shader::LogSource(deqp::Context& context, const std::string& source, STAGES stage)
2437 /* Skip empty shaders */
2438 if (true == source.empty())
2443 context.getTestContext().getLog() << tcu::TestLog::Message
2444 << "Shader source. Stage: " << Shader::GetStageName(stage)
2445 << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(source);
2450 * @param message Compilation error message
2452 Shader::CompilationException::CompilationException(const GLchar* message)
2454 m_message = message;
2457 /** Returns error messages
2459 * @return Compilation error message
2461 const char* Shader::CompilationException::what() const throw()
2463 return m_message.c_str();
2468 * @param message Compilation error message
2470 Shader::InvalidSourceException::InvalidSourceException(const GLchar* error_message, const std::string& source,
2472 : m_message(error_message), m_source(source), m_stage(stage)
2476 /** Returns error messages
2478 * @return Compilation error message
2480 const char* Shader::InvalidSourceException::what() const throw()
2482 return "Compilation error";
2485 /** Logs error message and shader sources **/
2486 void Shader::InvalidSourceException::log(deqp::Context& context) const
2488 context.getTestContext().getLog() << tcu::TestLog::Message << "Failed to compile shader: " << m_message.c_str()
2489 << tcu::TestLog::EndMessage;
2491 LogSource(context, m_source, m_stage);
2494 /* Program constants */
2495 const GLuint Pipeline::m_invalid_id = 0;
2499 * @param context CTS context.
2501 Pipeline::Pipeline(deqp::Context& context) : m_id(m_invalid_id), m_context(context)
2503 /* Nothing to be done here */
2509 Pipeline::~Pipeline()
2514 /** Initialize pipline object
2517 void Pipeline::Init()
2521 const Functions& gl = m_context.getRenderContext().getFunctions();
2524 gl.genProgramPipelines(1, &m_id);
2525 GLU_EXPECT_NO_ERROR(gl.getError(), "GenProgramPipelines");
2528 /** Release pipeline object
2531 void Pipeline::Release()
2533 if (m_invalid_id != m_id)
2535 const Functions& gl = m_context.getRenderContext().getFunctions();
2538 gl.deleteProgramPipelines(1, &m_id);
2539 GLU_EXPECT_NO_ERROR(gl.getError(), "DeleteProgramPipelines");
2541 m_id = m_invalid_id;
2548 void Pipeline::Bind()
2550 const Functions& gl = m_context.getRenderContext().getFunctions();
2555 /** Set which stages should be active
2557 * @param program_id Id of program
2558 * @param stages Logical combination of enums representing stages
2560 void Pipeline::UseProgramStages(GLuint program_id, GLenum stages)
2562 const Functions& gl = m_context.getRenderContext().getFunctions();
2564 UseProgramStages(gl, m_id, program_id, stages);
2569 * @param gl Functiions
2570 * @param id Pipeline id
2572 void Pipeline::Bind(const Functions& gl, GLuint id)
2574 gl.bindProgramPipeline(id);
2575 GLU_EXPECT_NO_ERROR(gl.getError(), "BindProgramPipeline");
2578 /** Set which stages should be active
2580 * @param gl Functiions
2581 * @param id Pipeline id
2582 * @param program_id Id of program
2583 * @param stages Logical combination of enums representing stages
2585 void Pipeline::UseProgramStages(const Functions& gl, GLuint id, GLuint program_id, GLenum stages)
2587 gl.useProgramStages(id, stages, program_id);
2588 GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgramStages");
2591 /* Program constants */
2592 const GLuint Program::m_invalid_id = 0;
2596 * @param context CTS context.
2598 Program::Program(deqp::Context& context)
2599 : m_id(m_invalid_id)
2600 , m_compute(context)
2601 , m_fragment(context)
2602 , m_geometry(context)
2603 , m_tess_ctrl(context)
2604 , m_tess_eval(context)
2606 , m_context(context)
2608 /* Nothing to be done here */
2619 /** Initialize program instance
2621 * @param compute_shader Compute shader source code
2622 * @param fragment_shader Fragment shader source code
2623 * @param geometry_shader Geometry shader source code
2624 * @param tesselation_control_shader Tesselation control shader source code
2625 * @param tesselation_evaluation_shader Tesselation evaluation shader source code
2626 * @param vertex_shader Vertex shader source code
2627 * @param captured_varyings Vector of variables to be captured with transfrom feedback
2628 * @param capture_interleaved Select mode of transform feedback (separate or interleaved)
2629 * @param is_separable Selects if monolithic or separable program should be built. Defaults to false
2631 void Program::Init(const std::string& compute_shader, const std::string& fragment_shader,
2632 const std::string& geometry_shader, const std::string& tesselation_control_shader,
2633 const std::string& tesselation_evaluation_shader, const std::string& vertex_shader,
2634 const NameVector& captured_varyings, bool capture_interleaved, bool is_separable)
2636 /* Delete previous program */
2639 /* GL entry points */
2640 const Functions& gl = m_context.getRenderContext().getFunctions();
2642 /* Initialize shaders */
2643 m_compute.Init(Shader::COMPUTE, compute_shader);
2644 m_fragment.Init(Shader::FRAGMENT, fragment_shader);
2645 m_geometry.Init(Shader::GEOMETRY, geometry_shader);
2646 m_tess_ctrl.Init(Shader::TESS_CTRL, tesselation_control_shader);
2647 m_tess_eval.Init(Shader::TESS_EVAL, tesselation_evaluation_shader);
2648 m_vertex.Init(Shader::VERTEX, vertex_shader);
2650 /* Create program, set up transform feedback and attach shaders */
2652 Capture(gl, m_id, captured_varyings, capture_interleaved);
2653 Attach(gl, m_id, m_compute.m_id);
2654 Attach(gl, m_id, m_fragment.m_id);
2655 Attach(gl, m_id, m_geometry.m_id);
2656 Attach(gl, m_id, m_tess_ctrl.m_id);
2657 Attach(gl, m_id, m_tess_eval.m_id);
2658 Attach(gl, m_id, m_vertex.m_id);
2660 /* Set separable parameter */
2661 if (true == is_separable)
2663 gl.programParameteri(m_id, GL_PROGRAM_SEPARABLE, GL_TRUE);
2664 GLU_EXPECT_NO_ERROR(gl.getError(), "ProgramParameteri");
2672 catch (const LinkageException& exc)
2674 throw BuildException(exc.what(), compute_shader, fragment_shader, geometry_shader, tesselation_control_shader,
2675 tesselation_evaluation_shader, vertex_shader);
2679 /** Initialize program instance
2681 * @param compute_shader Compute shader source code
2682 * @param fragment_shader Fragment shader source code
2683 * @param geometry_shader Geometry shader source code
2684 * @param tesselation_control_shader Tesselation control shader source code
2685 * @param tesselation_evaluation_shader Tesselation evaluation shader source code
2686 * @param vertex_shader Vertex shader source code
2687 * @param is_separable Selects if monolithic or separable program should be built. Defaults to false
2689 void Program::Init(const std::string& compute_shader, const std::string& fragment_shader,
2690 const std::string& geometry_shader, const std::string& tesselation_control_shader,
2691 const std::string& tesselation_evaluation_shader, const std::string& vertex_shader,
2694 NameVector captured_varying;
2696 Init(compute_shader, fragment_shader, geometry_shader, tesselation_control_shader, tesselation_evaluation_shader,
2697 vertex_shader, captured_varying, true, is_separable);
2700 /** Release program instance
2703 void Program::Release()
2705 const Functions& gl = m_context.getRenderContext().getFunctions();
2707 if (m_invalid_id != m_id)
2709 Use(gl, m_invalid_id);
2711 gl.deleteProgram(m_id);
2712 m_id = m_invalid_id;
2715 m_compute.Release();
2716 m_fragment.Release();
2717 m_geometry.Release();
2718 m_tess_ctrl.Release();
2719 m_tess_eval.Release();
2723 /** Get <pname> for a set of active uniforms
2725 * @param count Number of indices
2726 * @param indices Indices of uniforms
2727 * @param pname Queired pname
2728 * @param params Array that will be filled with values of parameters
2730 void Program::GetActiveUniformsiv(GLsizei count, const GLuint* indices, GLenum pname, GLint* params) const
2732 const Functions& gl = m_context.getRenderContext().getFunctions();
2734 GetActiveUniformsiv(gl, m_id, count, indices, pname, params);
2737 /** Get location of attribute
2739 * @param name Name of attribute
2741 * @return Result of query
2743 glw::GLint Program::GetAttribLocation(const std::string& name) const
2745 const Functions& gl = m_context.getRenderContext().getFunctions();
2747 return GetAttribLocation(gl, m_id, name);
2752 * @param interface Interface to be queried
2753 * @param index Index of resource
2754 * @param property Property to be queried
2755 * @param buf_size Size of <params> buffer
2756 * @param params Results of query
2758 void Program::GetResource(GLenum interface, GLuint index, GLenum property, GLsizei buf_size, GLint* params) const
2760 const Functions& gl = m_context.getRenderContext().getFunctions();
2762 GetResource(gl, m_id, interface, index, property, buf_size, params);
2765 /** Query for index of resource
2767 * @param name Name of resource
2768 * @param interface Interface to be queried
2770 * @return Result of query
2772 glw::GLuint Program::GetResourceIndex(const std::string& name, GLenum interface) const
2774 const Functions& gl = m_context.getRenderContext().getFunctions();
2776 return GetResourceIndex(gl, m_id, name, interface);
2779 /** Get indices for a set of uniforms
2781 * @param count Count number of uniforms
2782 * @param names Names of uniforms
2783 * @param indices Buffer that will be filled with indices
2785 void Program::GetUniformIndices(GLsizei count, const GLchar** names, GLuint* indices) const
2787 const Functions& gl = m_context.getRenderContext().getFunctions();
2789 GetUniformIndices(gl, m_id, count, names, indices);
2792 /** Get uniform location
2794 * @param name Name of uniform
2796 * @return Results of query
2798 glw::GLint Program::GetUniformLocation(const std::string& name) const
2800 const Functions& gl = m_context.getRenderContext().getFunctions();
2802 return GetUniformLocation(gl, m_id, name);
2805 /** Set program as active
2808 void Program::Use() const
2810 const Functions& gl = m_context.getRenderContext().getFunctions();
2815 /** Attach shader to program
2817 * @param gl GL functions
2818 * @param program_id Id of program
2819 * @param shader_id Id of shader
2821 void Program::Attach(const Functions& gl, GLuint program_id, GLuint shader_id)
2824 if ((m_invalid_id == program_id) || (Shader::m_invalid_id == shader_id))
2829 gl.attachShader(program_id, shader_id);
2830 GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
2833 /** Set up captured varyings
2835 * @param gl GL functions
2836 * @param id Id of program
2837 * @param captured_varyings Vector of varyings
2838 * @param capture_interleaved Selects if interleaved or separate mode should be used
2840 void Program::Capture(const Functions& gl, GLuint id, const NameVector& captured_varyings, bool capture_interleaved)
2842 const size_t n_varyings = captured_varyings.size();
2844 if (0 == n_varyings)
2846 /* empty list, skip */
2850 std::vector<const GLchar*> varying_names;
2851 varying_names.resize(n_varyings);
2853 for (size_t i = 0; i < n_varyings; ++i)
2855 varying_names[i] = captured_varyings[i].c_str();
2859 if (true == capture_interleaved)
2861 mode = GL_INTERLEAVED_ATTRIBS;
2865 mode = GL_SEPARATE_ATTRIBS;
2868 gl.transformFeedbackVaryings(id, static_cast<GLsizei>(n_varyings), &varying_names[0], mode);
2869 GLU_EXPECT_NO_ERROR(gl.getError(), "TransformFeedbackVaryings");
2872 /** Create program instance
2874 * @param gl GL functions
2875 * @param out_id Id of program
2877 void Program::Create(const Functions& gl, GLuint& out_id)
2879 const GLuint id = gl.createProgram();
2880 GLU_EXPECT_NO_ERROR(gl.getError(), "CreateProgram");
2882 if (m_invalid_id == id)
2884 TCU_FAIL("Failed to create program");
2890 /** Get <pname> for a set of active uniforms
2892 * @param gl Functions
2893 * @param program_id Id of program
2894 * @param count Number of indices
2895 * @param indices Indices of uniforms
2896 * @param pname Queired pname
2897 * @param params Array that will be filled with values of parameters
2899 void Program::GetActiveUniformsiv(const Functions& gl, GLuint program_id, GLsizei count, const GLuint* indices,
2900 GLenum pname, GLint* params)
2902 gl.getActiveUniformsiv(program_id, count, indices, pname, params);
2903 GLU_EXPECT_NO_ERROR(gl.getError(), "GetActiveUniformsiv");
2906 /** Get indices for a set of uniforms
2908 * @param gl Functions
2909 * @param program_id Id of program
2910 * @param count Count number of uniforms
2911 * @param names Names of uniforms
2912 * @param indices Buffer that will be filled with indices
2914 void Program::GetUniformIndices(const Functions& gl, GLuint program_id, GLsizei count, const GLchar** names,
2917 gl.getUniformIndices(program_id, count, names, indices);
2918 GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformIndices");
2923 * @param gl GL functions
2924 * @param id Id of program
2926 void Program::Link(const Functions& gl, GLuint id)
2928 GLint status = GL_FALSE;
2931 GLU_EXPECT_NO_ERROR(gl.getError(), "LinkProgram");
2933 /* Get link status */
2934 gl.getProgramiv(id, GL_LINK_STATUS, &status);
2935 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");
2937 /* Log link error */
2938 if (GL_TRUE != status)
2940 glw::GLint length = 0;
2941 std::string message;
2943 /* Get error log length */
2944 gl.getProgramiv(id, GL_INFO_LOG_LENGTH, &length);
2945 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");
2947 message.resize(length, 0);
2950 gl.getProgramInfoLog(id, length, 0, &message[0]);
2951 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramInfoLog");
2953 throw LinkageException(message.c_str());
2957 /** Set generic uniform
2959 * @param gl Functions
2960 * @param type Type of uniform
2961 * @param count Length of array
2962 * @param location Location of uniform
2963 * @param data Data that will be used
2965 void Program::Uniform(const Functions& gl, const Type& type, GLsizei count, GLint location, const GLvoid* data)
2969 TCU_FAIL("Uniform is inactive");
2972 switch (type.m_basic_type)
2975 if (1 == type.m_n_columns)
2977 getUniformNdv(gl, type.m_n_rows)(location, count, (const GLdouble*)data);
2978 GLU_EXPECT_NO_ERROR(gl.getError(), "UniformNdv");
2982 getUniformMatrixNdv(gl, type.m_n_columns, type.m_n_rows)(location, count, false, (const GLdouble*)data);
2983 GLU_EXPECT_NO_ERROR(gl.getError(), "UniformMatrixNdv");
2987 if (1 == type.m_n_columns)
2989 getUniformNfv(gl, type.m_n_rows)(location, count, (const GLfloat*)data);
2990 GLU_EXPECT_NO_ERROR(gl.getError(), "UniformNfv");
2994 getUniformMatrixNfv(gl, type.m_n_columns, type.m_n_rows)(location, count, false, (const GLfloat*)data);
2995 GLU_EXPECT_NO_ERROR(gl.getError(), "UniformMatrixNfv");
2999 getUniformNiv(gl, type.m_n_rows)(location, count, (const GLint*)data);
3000 GLU_EXPECT_NO_ERROR(gl.getError(), "UniformNiv");
3003 getUniformNuiv(gl, type.m_n_rows)(location, count, (const GLuint*)data);
3004 GLU_EXPECT_NO_ERROR(gl.getError(), "UniformNuiv");
3007 TCU_FAIL("Invalid enum");
3013 * @param gl GL functions
3014 * @param id Id of program
3016 void Program::Use(const Functions& gl, GLuint id)
3019 GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram");
3022 /** Get location of attribute
3024 * @param gl GL functions
3025 * @param id Id of program
3026 * @param name Name of attribute
3028 * @return Location of attribute
3030 GLint Program::GetAttribLocation(const Functions& gl, GLuint id, const std::string& name)
3032 GLint location = gl.getAttribLocation(id, name.c_str());
3033 GLU_EXPECT_NO_ERROR(gl.getError(), "GetAttribLocation");
3040 * @param gl GL functions
3041 * @param id Id of program
3042 * @param interface Interface to be queried
3043 * @param index Index of resource
3044 * @param property Property to be queried
3045 * @param buf_size Size of <params> buffer
3046 * @param params Results of query
3048 void Program::GetResource(const Functions& gl, GLuint id, GLenum interface, GLuint index, GLenum property,
3049 GLsizei buf_size, GLint* params)
3051 gl.getProgramResourceiv(id, interface, index, 1 /* propCount */, &property, buf_size /* bufSize */, 0 /* length */,
3053 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramResourceiv");
3056 /** Get index of resource
3058 * @param gl GL functions
3059 * @param id Id of program
3060 * @param name Name of resource
3061 * @param interface Program interface to queried
3063 * @return Location of attribute
3065 GLuint Program::GetResourceIndex(const Functions& gl, GLuint id, const std::string& name, GLenum interface)
3067 GLuint index = gl.getProgramResourceIndex(id, interface, name.c_str());
3068 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramResourceIndex");
3073 /** Get location of attribute
3075 * @param gl GL functions
3076 * @param id Id of program
3077 * @param name Name of attribute
3079 * @return Location of uniform
3081 GLint Program::GetUniformLocation(const Functions& gl, GLuint id, const std::string& name)
3083 GLint location = gl.getUniformLocation(id, name.c_str());
3084 GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformLocation");
3091 * @param error_message Error message
3092 * @param compute_shader Source code for compute stage
3093 * @param fragment_shader Source code for fragment stage
3094 * @param geometry_shader Source code for geometry stage
3095 * @param tess_ctrl_shader Source code for tesselation control stage
3096 * @param tess_eval_shader Source code for tesselation evaluation stage
3097 * @param vertex_shader Source code for vertex stage
3099 Program::BuildException::BuildException(const glw::GLchar* error_message, const std::string compute_shader,
3100 const std::string fragment_shader, const std::string geometry_shader,
3101 const std::string tess_ctrl_shader, const std::string tess_eval_shader,
3102 const std::string vertex_shader)
3103 : m_error_message(error_message)
3104 , m_compute_shader(compute_shader)
3105 , m_fragment_shader(fragment_shader)
3106 , m_geometry_shader(geometry_shader)
3107 , m_tess_ctrl_shader(tess_ctrl_shader)
3108 , m_tess_eval_shader(tess_eval_shader)
3109 , m_vertex_shader(vertex_shader)
3113 /** Overwrites std::exception::what method
3115 * @return Message compossed from error message and shader sources
3117 const char* Program::BuildException::what() const throw()
3119 return "Failed to link program";
3122 /** Logs error message and shader sources **/
3123 void Program::BuildException::log(deqp::Context& context) const
3125 context.getTestContext().getLog() << tcu::TestLog::Message << "Link failure: " << m_error_message
3126 << tcu::TestLog::EndMessage;
3128 Shader::LogSource(context, m_vertex_shader, Shader::VERTEX);
3129 Shader::LogSource(context, m_tess_ctrl_shader, Shader::TESS_CTRL);
3130 Shader::LogSource(context, m_tess_eval_shader, Shader::TESS_EVAL);
3131 Shader::LogSource(context, m_geometry_shader, Shader::GEOMETRY);
3132 Shader::LogSource(context, m_fragment_shader, Shader::FRAGMENT);
3133 Shader::LogSource(context, m_compute_shader, Shader::COMPUTE);
3138 * @param message Linking error message
3140 Program::LinkageException::LinkageException(const glw::GLchar* message) : m_error_message(message)
3142 /* Nothing to be done */
3145 /** Returns error messages
3147 * @return Linking error message
3149 const char* Program::LinkageException::what() const throw()
3151 return m_error_message.c_str();
3154 /* Texture constants */
3155 const GLuint Texture::m_invalid_id = -1;
3159 * @param context CTS context.
3161 Texture::Texture(deqp::Context& context) : m_id(m_invalid_id), m_context(context), m_type(TEX_2D)
3163 /* Nothing to done here */
3174 /** Initialize texture instance
3176 * @param tex_type Type of texture
3177 * @param width Width of texture
3178 * @param height Height of texture
3179 * @param depth Depth of texture
3180 * @param internal_format Internal format of texture
3181 * @param format Format of texture data
3182 * @param type Type of texture data
3183 * @param data Texture data
3185 void Texture::Init(TYPES tex_type, GLuint width, GLuint height, GLuint depth, GLenum internal_format, GLenum format,
3186 GLenum type, GLvoid* data)
3188 const Functions& gl = m_context.getRenderContext().getFunctions();
3190 /* Delete previous texture */
3195 /* Generate, bind, allocate storage and upload data */
3197 Bind(gl, m_id, tex_type);
3198 Storage(gl, tex_type, width, height, depth, internal_format);
3199 Update(gl, tex_type, width, height, depth, format, type, data);
3202 /** Initialize buffer texture
3204 * @param internal_format Internal format of texture
3205 * @param buffer_id Id of buffer that will be used as data source
3207 void Texture::Init(GLenum internal_format, GLuint buffer_id)
3209 const Functions& gl = m_context.getRenderContext().getFunctions();
3211 /* Delete previous texture */
3214 m_type = TEX_BUFFER;
3216 /* Generate, bind and attach buffer */
3218 Bind(gl, m_id, TEX_BUFFER);
3219 TexBuffer(gl, buffer_id, internal_format);
3222 /** Release texture instance
3225 void Texture::Release()
3227 if (m_invalid_id != m_id)
3229 const Functions& gl = m_context.getRenderContext().getFunctions();
3231 gl.deleteTextures(1, &m_id);
3232 m_id = m_invalid_id;
3236 /** Bind texture to its target
3239 void Texture::Bind() const
3241 const Functions& gl = m_context.getRenderContext().getFunctions();
3243 Bind(gl, m_id, m_type);
3246 /** Get texture data
3248 * @param format Format of data
3249 * @param type Type of data
3250 * @param out_data Buffer for data
3252 void Texture::Get(GLenum format, GLenum type, GLvoid* out_data) const
3254 const Functions& gl = m_context.getRenderContext().getFunctions();
3256 Bind(gl, m_id, m_type);
3257 Get(gl, m_type, format, type, out_data);
3260 /** Bind texture to target
3262 * @param gl GL functions
3263 * @param id Id of texture
3264 * @param tex_type Type of texture
3266 void Texture::Bind(const Functions& gl, GLuint id, TYPES tex_type)
3268 GLenum target = GetTargetGLenum(tex_type);
3270 gl.bindTexture(target, id);
3271 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
3274 /** Generate texture instance
3276 * @param gl GL functions
3277 * @param out_id Id of texture
3279 void Texture::Generate(const Functions& gl, GLuint& out_id)
3281 GLuint id = m_invalid_id;
3283 gl.genTextures(1, &id);
3284 GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures");
3286 if (m_invalid_id == id)
3288 TCU_FAIL("Invalid id");
3294 /** Get texture data
3296 * @param gl GL functions
3297 * @param format Format of data
3298 * @param type Type of data
3299 * @param out_data Buffer for data
3301 void Texture::Get(const Functions& gl, TYPES tex_type, GLenum format, GLenum type, GLvoid* out_data)
3303 GLenum target = GetTargetGLenum(tex_type);
3305 if (TEX_CUBE != tex_type)
3307 gl.getTexImage(target, 0 /* level */, format, type, out_data);
3308 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexImage");
3315 if ((GL_RGBA != format) && (GL_UNSIGNED_BYTE != type))
3317 TCU_FAIL("Not implemented");
3320 GLuint texel_size = 4;
3322 gl.getTexLevelParameteriv(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0 /* level */, GL_TEXTURE_WIDTH, &width);
3323 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv");
3325 gl.getTexLevelParameteriv(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0 /* level */, GL_TEXTURE_HEIGHT, &height);
3326 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv");
3328 const GLuint image_size = width * height * texel_size;
3330 gl.getTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0 /* level */, format, type,
3331 (GLvoid*)((GLchar*)out_data + (image_size * 0)));
3332 gl.getTexImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0 /* level */, format, type,
3333 (GLvoid*)((GLchar*)out_data + (image_size * 1)));
3334 gl.getTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0 /* level */, format, type,
3335 (GLvoid*)((GLchar*)out_data + (image_size * 2)));
3336 gl.getTexImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0 /* level */, format, type,
3337 (GLvoid*)((GLchar*)out_data + (image_size * 3)));
3338 gl.getTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0 /* level */, format, type,
3339 (GLvoid*)((GLchar*)out_data + (image_size * 4)));
3340 gl.getTexImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0 /* level */, format, type,
3341 (GLvoid*)((GLchar*)out_data + (image_size * 5)));
3342 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexImage");
3346 /** Allocate storage for texture
3348 * @param gl GL functions
3349 * @param tex_type Type of texture
3350 * @param width Width of texture
3351 * @param height Height of texture
3352 * @param depth Depth of texture
3353 * @param internal_format Internal format of texture
3355 void Texture::Storage(const Functions& gl, TYPES tex_type, GLuint width, GLuint height, GLuint depth,
3356 GLenum internal_format)
3358 static const GLuint levels = 1;
3360 GLenum target = GetTargetGLenum(tex_type);
3365 gl.texStorage1D(target, levels, internal_format, width);
3366 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage1D");
3372 gl.texStorage2D(target, levels, internal_format, width, height);
3373 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2D");
3377 gl.texStorage3D(target, levels, internal_format, width, height, depth);
3378 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage3D");
3381 TCU_FAIL("Invliad enum");
3386 /** Attach buffer as source of texture buffer data
3388 * @param gl GL functions
3389 * @param internal_format Internal format of texture
3390 * @param buffer_id Id of buffer that will be used as data source
3392 void Texture::TexBuffer(const Functions& gl, GLenum internal_format, GLuint& buffer_id)
3394 gl.texBuffer(GL_TEXTURE_BUFFER, internal_format, buffer_id);
3395 GLU_EXPECT_NO_ERROR(gl.getError(), "TexBuffer");
3398 /** Update contents of texture
3400 * @param gl GL functions
3401 * @param tex_type Type of texture
3402 * @param width Width of texture
3403 * @param height Height of texture
3404 * @param format Format of data
3405 * @param type Type of data
3406 * @param data Buffer with image data
3408 void Texture::Update(const Functions& gl, TYPES tex_type, GLuint width, GLuint height, GLuint depth, GLenum format,
3409 GLenum type, GLvoid* data)
3411 static const GLuint level = 0;
3413 GLenum target = GetTargetGLenum(tex_type);
3418 gl.texSubImage1D(target, level, 0 /* x */, width, format, type, data);
3419 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage1D");
3424 gl.texSubImage2D(target, level, 0 /* x */, 0 /* y */, width, height, format, type, data);
3425 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2D");
3428 gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, level, 0 /* x */, 0 /* y */, width, height, format, type,
3430 gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, level, 0 /* x */, 0 /* y */, width, height, format, type,
3432 gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, level, 0 /* x */, 0 /* y */, width, height, format, type,
3434 gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, level, 0 /* x */, 0 /* y */, width, height, format, type,
3436 gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, level, 0 /* x */, 0 /* y */, width, height, format, type,
3438 gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, level, 0 /* x */, 0 /* y */, width, height, format, type,
3440 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2D");
3444 gl.texSubImage3D(target, level, 0 /* x */, 0 /* y */, 0 /* z */, width, height, depth, format, type, data);
3445 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage3D");
3448 TCU_FAIL("Invliad enum");
3453 /** Get target for given texture type
3455 * @param type Type of texture
3459 GLenum Texture::GetTargetGLenum(TYPES type)
3466 result = GL_TEXTURE_BUFFER;
3469 result = GL_TEXTURE_2D;
3472 result = GL_TEXTURE_RECTANGLE;
3475 result = GL_TEXTURE_2D_ARRAY;
3478 result = GL_TEXTURE_3D;
3481 result = GL_TEXTURE_CUBE_MAP;
3484 result = GL_TEXTURE_1D;
3487 result = GL_TEXTURE_1D_ARRAY;
3494 /* VertexArray constants */
3495 const GLuint VertexArray::m_invalid_id = -1;
3499 * @param context CTS context.
3501 VertexArray::VertexArray(deqp::Context& context) : m_id(m_invalid_id), m_context(context)
3508 VertexArray::~VertexArray()
3513 /** Initialize vertex array instance
3516 void VertexArray::Init()
3518 /* Delete previous instance */
3521 const Functions& gl = m_context.getRenderContext().getFunctions();
3526 /** Release vertex array object instance
3529 void VertexArray::Release()
3531 if (m_invalid_id != m_id)
3533 const Functions& gl = m_context.getRenderContext().getFunctions();
3535 gl.deleteVertexArrays(1, &m_id);
3537 m_id = m_invalid_id;
3541 /** Set attribute in VAO
3543 * @param index Index of attribute
3544 * @param type Type of attribute
3545 * @param n_array_elements Arary length
3546 * @param normalized Selectis if values should be normalized
3547 * @param stride Stride
3548 * @param pointer Pointer to data, or offset in buffer
3550 void VertexArray::Attribute(GLuint index, const Type& type, GLuint n_array_elements, GLboolean normalized,
3551 GLsizei stride, const GLvoid* pointer)
3553 const Functions& gl = m_context.getRenderContext().getFunctions();
3555 AttribPointer(gl, index, type, n_array_elements, normalized, stride, pointer);
3556 Enable(gl, index, type, n_array_elements);
3559 /** Binds Vertex array object
3562 void VertexArray::Bind()
3564 const Functions& gl = m_context.getRenderContext().getFunctions();
3569 /** Set attribute in VAO
3571 * @param gl Functions
3572 * @param index Index of attribute
3573 * @param type Type of attribute
3574 * @param n_array_elements Arary length
3575 * @param normalized Selectis if values should be normalized
3576 * @param stride Stride
3577 * @param pointer Pointer to data, or offset in buffer
3579 void VertexArray::AttribPointer(const Functions& gl, GLuint index, const Type& type, GLuint n_array_elements,
3580 GLboolean normalized, GLsizei stride, const GLvoid* pointer)
3582 const GLuint basic_type_size = Type::GetTypeSize(type.m_basic_type);
3583 const GLint size = (GLint)type.m_n_rows;
3584 const GLuint column_size = (GLuint)size * basic_type_size;
3585 const GLenum gl_type = Type::GetTypeGLenum(type.m_basic_type);
3589 /* If attribute is not an array */
3590 if (0 == n_array_elements)
3592 n_array_elements = 1;
3595 /* For each element in array */
3596 for (GLuint element = 0; element < n_array_elements; ++element)
3598 /* For each column in matrix */
3599 for (GLuint column = 1; column <= type.m_n_columns; ++column)
3601 /* Calculate offset */
3602 const GLvoid* ptr = (GLubyte*)pointer + offset;
3604 /* Set up attribute */
3605 switch (type.m_basic_type)
3608 gl.vertexAttribPointer(index, size, gl_type, normalized, stride, ptr);
3609 GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttribPointer");
3613 gl.vertexAttribIPointer(index, size, gl_type, stride, ptr);
3614 GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttribIPointer");
3617 gl.vertexAttribLPointer(index, size, gl_type, stride, ptr);
3618 GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttribLPointer");
3621 TCU_FAIL("Invalid enum");
3625 offset += column_size;
3631 /** Binds Vertex array object
3633 * @param gl GL functions
3634 * @param id ID of vertex array object
3636 void VertexArray::Bind(const glw::Functions& gl, glw::GLuint id)
3638 gl.bindVertexArray(id);
3639 GLU_EXPECT_NO_ERROR(gl.getError(), "BindVertexArray");
3642 /** Disable attribute in VAO
3644 * @param gl Functions
3645 * @param index Index of attribute
3646 * @param type Type of attribute
3647 * @param n_array_elements Arary length
3649 void VertexArray::Disable(const Functions& gl, GLuint index, const Type& type, GLuint n_array_elements)
3651 /* If attribute is not an array */
3652 if (0 == n_array_elements)
3654 n_array_elements = 1;
3657 /* For each element in array */
3658 for (GLuint element = 0; element < n_array_elements; ++element)
3660 /* For each column in matrix */
3661 for (GLuint column = 1; column <= type.m_n_columns; ++column)
3663 /* Enable attribute array */
3664 gl.disableVertexAttribArray(index);
3665 GLU_EXPECT_NO_ERROR(gl.getError(), "DisableVertexAttribArray");
3673 /** Set divisor for attribute
3675 * @param gl Functions
3676 * @param index Index of attribute
3677 * @param divisor New divisor value
3679 void VertexArray::Divisor(const Functions& gl, GLuint index, GLuint divisor)
3681 gl.vertexAttribDivisor(index, divisor);
3682 GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttribDivisor");
3685 /** Enables attribute in VAO
3687 * @param gl Functions
3688 * @param index Index of attribute
3689 * @param type Type of attribute
3690 * @param n_array_elements Arary length
3692 void VertexArray::Enable(const Functions& gl, GLuint index, const Type& type, GLuint n_array_elements)
3694 /* If attribute is not an array */
3695 if (0 == n_array_elements)
3697 n_array_elements = 1;
3700 /* For each element in array */
3701 for (GLuint element = 0; element < n_array_elements; ++element)
3703 /* For each column in matrix */
3704 for (GLuint column = 1; column <= type.m_n_columns; ++column)
3706 /* Enable attribute array */
3707 gl.enableVertexAttribArray(index);
3708 GLU_EXPECT_NO_ERROR(gl.getError(), "EnableVertexAttribArray");
3716 /** Generates Vertex array object
3718 * @param gl GL functions
3719 * @param out_id ID of vertex array object
3721 void VertexArray::Generate(const glw::Functions& gl, glw::GLuint& out_id)
3723 GLuint id = m_invalid_id;
3725 gl.genVertexArrays(1, &id);
3726 GLU_EXPECT_NO_ERROR(gl.getError(), "GenVertexArrays");
3728 if (m_invalid_id == id)
3730 TCU_FAIL("Invalid id");
3736 /* Constatns used by Variable */
3737 const GLint Variable::m_automatic_location = -1;
3739 /** Copy constructor
3742 Variable::Variable(const Variable& var)
3743 : m_data(var.m_data)
3744 , m_data_size(var.m_data_size)
3745 , m_descriptor(var.m_descriptor.m_name.c_str(), var.m_descriptor.m_qualifiers.c_str(),
3746 var.m_descriptor.m_expected_component, var.m_descriptor.m_expected_location,
3747 var.m_descriptor.m_builtin, var.m_descriptor.m_normalized, var.m_descriptor.m_n_array_elements,
3748 var.m_descriptor.m_expected_stride_of_element, var.m_descriptor.m_offset)
3749 , m_storage(var.m_storage)
3751 m_descriptor.m_type = var.m_descriptor.m_type;
3753 if (BUILTIN != var.m_descriptor.m_type)
3755 m_descriptor.m_interface = var.m_descriptor.m_interface;
3759 /** Get code that defines variable
3761 * @param flavour Provides info if variable is array or not
3763 * @return String with code
3765 std::string Variable::GetDefinition(FLAVOUR flavour) const
3767 return m_descriptor.GetDefinition(flavour, m_storage);
3770 /** Calcualtes stride of variable
3772 * @return Calculated value
3774 GLuint Variable::GetStride() const
3776 GLint variable_stride = 0;
3778 if (0 == m_descriptor.m_n_array_elements)
3780 variable_stride = m_descriptor.m_expected_stride_of_element;
3784 variable_stride = m_descriptor.m_expected_stride_of_element * m_descriptor.m_n_array_elements;
3787 return variable_stride;
3790 /** Check if variable is block
3792 * @return true if variable type is block, false otherwise
3794 bool Variable::IsBlock() const
3796 if (BUILTIN == m_descriptor.m_type)
3801 const Interface* interface = m_descriptor.m_interface;
3804 TCU_FAIL("Nullptr");
3807 return (Interface::BLOCK == interface->m_type);
3810 /** Check if variable is struct
3812 * @return true if variable type is struct, false otherwise
3814 bool Variable::IsStruct() const
3816 if (BUILTIN == m_descriptor.m_type)
3821 const Interface* interface = m_descriptor.m_interface;
3824 TCU_FAIL("Nullptr");
3827 return (Interface::STRUCT == interface->m_type);
3829 /** Get code that reference variable
3831 * @param parent_name Name of parent
3832 * @param variable Descriptor of variable
3833 * @param flavour Provides info about how variable should be referenced
3834 * @param array_index Index of array, ignored when variable is not array
3836 * @return String with code
3838 std::string Variable::GetReference(const std::string& parent_name, const Descriptor& variable, FLAVOUR flavour,
3844 if (false == parent_name.empty())
3848 name.append(variable.m_name);
3852 name = variable.m_name;
3858 case Utils::Variable::BASIC:
3861 case Utils::Variable::ARRAY:
3865 case Utils::Variable::INDEXED_BY_INVOCATION_ID:
3866 name.append("[gl_InvocationID]");
3870 /* Assumption that both variables have same lengths */
3871 if (0 != variable.m_n_array_elements)
3874 sprintf(buffer, "%d", array_index);
3876 name.append(buffer);
3883 /** Get "flavour" of varying
3885 * @param stage Stage of shader
3886 * @param direction Selects if varying is in or out
3890 Variable::FLAVOUR Variable::GetFlavour(Shader::STAGES stage, VARYING_DIRECTION direction)
3892 FLAVOUR result = BASIC;
3896 case Shader::GEOMETRY:
3897 case Shader::TESS_EVAL:
3898 if (INPUT == direction)
3903 case Shader::TESS_CTRL:
3904 result = INDEXED_BY_INVOCATION_ID;
3913 /** Constructor, for built-in types
3916 * @param qualifiers Qualifiers
3917 * @param expected_component Expected component of variable
3918 * @param expected_location Expected location
3920 * @param normalized Selects if data should be normalized
3921 * @param n_array_elements Length of array
3922 * @param expected_stride_of_element Expected stride of element
3923 * @param offset Offset
3925 Variable::Descriptor::Descriptor(const GLchar* name, const GLchar* qualifiers, GLint expected_component,
3926 GLint expected_location, const Type& type, GLboolean normalized,
3927 GLuint n_array_elements, GLint expected_stride_of_element, GLuint offset)
3928 : m_expected_component(expected_component)
3929 , m_expected_location(expected_location)
3930 , m_expected_stride_of_element(expected_stride_of_element)
3931 , m_n_array_elements(n_array_elements)
3933 , m_normalized(normalized)
3935 , m_qualifiers(qualifiers)
3941 /** Constructor, for interface types
3944 * @param qualifiers Qualifiers
3945 * @param expected_component Expected component of variable
3946 * @param expected_location Expected location
3947 * @param interface Interface of variable
3948 * @param n_array_elements Length of array
3949 * @param expected_stride_of_element Expected stride of element
3950 * @param offset Offset
3952 Variable::Descriptor::Descriptor(const GLchar* name, const GLchar* qualifiers, GLint expected_componenet,
3953 GLint expected_location, Interface* interface, GLuint n_array_elements,
3954 GLint expected_stride_of_element, GLuint offset)
3955 : m_expected_component(expected_componenet)
3956 , m_expected_location(expected_location)
3957 , m_expected_stride_of_element(expected_stride_of_element)
3958 , m_n_array_elements(n_array_elements)
3960 , m_normalized(GL_FALSE)
3962 , m_qualifiers(qualifiers)
3964 , m_interface(interface)
3968 /** Get definition of variable
3970 * @param flavour Flavour of variable
3971 * @param storage Storage used for variable
3973 * @return code with defintion
3975 std::string Variable::Descriptor::GetDefinition(FLAVOUR flavour, STORAGE storage) const
3977 static const GLchar* basic_template = "QUALIFIERS STORAGETYPE NAMEARRAY;";
3978 static const GLchar* array_template = "QUALIFIERS STORAGETYPE NAME[]ARRAY;";
3979 const GLchar* storage_str = 0;
3981 std::string definition;
3982 size_t position = 0;
3984 /* Select definition template */
3988 definition = basic_template;
3991 case INDEXED_BY_INVOCATION_ID:
3992 definition = array_template;
3995 TCU_FAIL("Invliad enum");
3999 if (BUILTIN != m_type)
4001 if (0 == m_interface)
4003 TCU_FAIL("Nullptr");
4008 if (true == m_qualifiers.empty())
4010 replaceToken("QUALIFIERS ", position, "", definition);
4014 replaceToken("QUALIFIERS", position, m_qualifiers.c_str(), definition);
4017 // According to spec: integer or unsigned integer type must always be declared with flat qualifier
4018 bool flat_qualifier = false;
4019 if (m_type != BUILTIN && m_interface != NULL)
4021 if (m_interface->m_members[0].m_builtin.m_basic_type == Utils::Type::Int ||
4022 m_interface->m_members[0].m_builtin.m_basic_type == Utils::Type::Uint)
4024 flat_qualifier = true;
4031 storage_str = flat_qualifier ? "flat in " : "in ";
4033 case VARYING_OUTPUT:
4034 storage_str = "out ";
4037 storage_str = "uniform ";
4040 storage_str = "buffer ";
4046 TCU_FAIL("Invalid enum");
4050 replaceToken("STORAGE", position, storage_str, definition);
4053 if (BUILTIN == m_type)
4055 replaceToken("TYPE", position, m_builtin.GetGLSLTypeName(), definition);
4059 if (Interface::STRUCT == m_interface->m_type)
4061 replaceToken("TYPE", position, m_interface->m_name.c_str(), definition);
4065 const std::string& block_definition = m_interface->GetDefinition();
4067 replaceToken("TYPE", position, block_definition.c_str(), definition);
4072 replaceToken("NAME", position, m_name.c_str(), definition);
4075 if (0 == m_n_array_elements)
4077 replaceToken("ARRAY", position, "", definition);
4082 sprintf(buffer, "[%d]", m_n_array_elements);
4084 replaceToken("ARRAY", position, buffer, definition);
4091 /** Get definitions for variables collected in vector
4093 * @param vector Collection of variables
4094 * @param flavour Flavour of variables
4096 * @return Code with definitions
4098 std::string GetDefinitions(const Variable::PtrVector& vector, Variable::FLAVOUR flavour)
4100 std::string list = Utils::g_list;
4101 size_t position = 0;
4103 for (GLuint i = 0; i < vector.size(); ++i)
4105 Utils::insertElementOfList(vector[i]->GetDefinition(flavour).c_str(), "\n", position, list);
4108 Utils::endList("", position, list);
4113 /** Get definitions for interfaces collected in vector
4115 * @param vector Collection of interfaces
4117 * @return Code with definitions
4119 std::string GetDefinitions(const Interface::PtrVector& vector)
4121 std::string list = Utils::g_list;
4122 size_t position = 0;
4124 for (GLuint i = 0; i < vector.size(); ++i)
4126 Utils::insertElementOfList(vector[i]->GetDefinition().c_str(), "\n", position, list);
4129 Utils::endList("", position, list);
4137 * @param type Type of interface
4139 Interface::Interface(const GLchar* name, Interface::TYPE type) : m_name(name), m_type(type)
4143 /** Adds member to interface
4145 * @param member Descriptor of new member
4147 * @return Pointer to just created member
4149 Variable::Descriptor* Interface::AddMember(const Variable::Descriptor& member)
4151 m_members.push_back(member);
4153 return &m_members.back();
4156 /** Get definition of interface
4158 * @param Code with definition
4160 std::string Interface::GetDefinition() const
4162 std::string definition;
4163 size_t position = 0;
4165 const GLchar* member_list = " MEMBER_DEFINITION\nMEMBER_LIST";
4167 if (STRUCT == m_type)
4169 definition = "struct NAME {\nMEMBER_LIST};";
4173 definition = "NAME {\nMEMBER_LIST}";
4177 replaceToken("NAME", position, m_name.c_str(), definition);
4180 for (GLuint i = 0; i < m_members.size(); ++i)
4182 const size_t start_position = position;
4183 const std::string& member_definition = m_members[i].GetDefinition(Variable::BASIC, Variable::MEMBER);
4186 replaceToken("MEMBER_LIST", position, member_list, definition);
4188 /* Move back position */
4189 position = start_position;
4191 /* Member definition */
4192 replaceToken("MEMBER_DEFINITION", position, member_definition.c_str(), definition);
4195 /* Remove last member list */
4196 replaceToken("MEMBER_LIST", position, "", definition);
4202 /** Adds member of built-in type to interface
4205 * @param qualifiers Qualifiers
4206 * @param expected_component Expected component of variable
4207 * @param expected_location Expected location
4209 * @param normalized Selects if data should be normalized
4210 * @param n_array_elements Length of array
4211 * @param expected_stride_of_element Expected stride of element
4212 * @param offset Offset
4214 * @return Pointer to just created member
4216 Variable::Descriptor* Interface::Member(const GLchar* name, const GLchar* qualifiers, GLint expected_component,
4217 GLint expected_location, const Type& type, GLboolean normalized,
4218 GLuint n_array_elements, GLint expected_stride_of_element, GLuint offset)
4220 return AddMember(Variable::Descriptor(name, qualifiers, expected_component, expected_location, type, normalized,
4221 n_array_elements, expected_stride_of_element, offset));
4224 /** Adds member of interface type to interface
4227 * @param qualifiers Qualifiers
4228 * @param expected_component Expected component of variable
4229 * @param expected_location Expected location
4231 * @param normalized Selects if data should be normalized
4232 * @param n_array_elements Length of array
4233 * @param expected_stride_of_element Expected stride of element
4234 * @param offset Offset
4236 * @return Pointer to just created member
4238 Variable::Descriptor* Interface::Member(const GLchar* name, const GLchar* qualifiers, GLint expected_component,
4239 GLint expected_location, Interface* nterface, GLuint n_array_elements,
4240 GLint expected_stride_of_element, GLuint offset)
4242 return AddMember(Variable::Descriptor(name, qualifiers, expected_component, expected_location, nterface,
4243 n_array_elements, expected_stride_of_element, offset));
4246 /** Clears contents of vector of pointers
4248 * @tparam T Type of elements
4250 * @param vector Collection to be cleared
4252 template <typename T>
4253 void clearPtrVector(std::vector<T*>& vector)
4255 for (size_t i = 0; i < vector.size(); ++i)
4272 * @param stage Stage described by that interface
4274 ShaderInterface::ShaderInterface(Shader::STAGES stage) : m_stage(stage)
4276 /* Nothing to be done */
4279 /** Get definitions of globals
4281 * @return Code with definitions
4283 std::string ShaderInterface::GetDefinitionsGlobals() const
4288 /** Get definitions of inputs
4290 * @return Code with definitions
4292 std::string ShaderInterface::GetDefinitionsInputs() const
4294 Variable::FLAVOUR flavour = Variable::GetFlavour(m_stage, Variable::INPUT);
4296 return GetDefinitions(m_inputs, flavour);
4299 /** Get definitions of outputs
4301 * @return Code with definitions
4303 std::string ShaderInterface::GetDefinitionsOutputs() const
4305 Variable::FLAVOUR flavour = Variable::GetFlavour(m_stage, Variable::OUTPUT);
4307 return GetDefinitions(m_outputs, flavour);
4310 /** Get definitions of buffers
4312 * @return Code with definitions
4314 std::string ShaderInterface::GetDefinitionsSSBs() const
4316 return GetDefinitions(m_ssb_blocks, Variable::BASIC);
4319 /** Get definitions of uniforms
4321 * @return Code with definitions
4323 std::string ShaderInterface::GetDefinitionsUniforms() const
4325 return GetDefinitions(m_uniforms, Variable::BASIC);
4330 * @param in Input variable
4331 * @param out Output variable
4333 VaryingConnection::VaryingConnection(Variable* in, Variable* out) : m_in(in), m_out(out)
4335 /* NBothing to be done here */
4338 /** Adds new varying connection to given stage
4340 * @param stage Shader stage
4341 * @param in In varying
4342 * @param out Out varying
4344 void VaryingPassthrough::Add(Shader::STAGES stage, Variable* in, Variable* out)
4346 VaryingConnection::Vector& vector = Get(stage);
4348 vector.push_back(VaryingConnection(in, out));
4351 /** Get all passthrough connections for given stage
4353 * @param stage Shader stage
4355 * @return Vector of connections
4357 VaryingConnection::Vector& VaryingPassthrough::Get(Shader::STAGES stage)
4359 VaryingConnection::Vector* result = 0;
4363 case Shader::FRAGMENT:
4364 result = &m_fragment;
4366 case Shader::GEOMETRY:
4367 result = &m_geometry;
4369 case Shader::TESS_CTRL:
4370 result = &m_tess_ctrl;
4372 case Shader::TESS_EVAL:
4373 result = &m_tess_eval;
4375 case Shader::VERTEX:
4379 TCU_FAIL("Invalid enum");
4388 ProgramInterface::ProgramInterface()
4389 : m_compute(Shader::COMPUTE)
4390 , m_vertex(Shader::VERTEX)
4391 , m_tess_ctrl(Shader::TESS_CTRL)
4392 , m_tess_eval(Shader::TESS_EVAL)
4393 , m_geometry(Shader::GEOMETRY)
4394 , m_fragment(Shader::FRAGMENT)
4401 ProgramInterface::~ProgramInterface()
4403 clearPtrVector(m_blocks);
4404 clearPtrVector(m_structures);
4407 /** Adds new interface
4412 * @return Pointer to created interface
4414 Interface* ProgramInterface::AddInterface(const GLchar* name, Interface::TYPE type)
4416 Interface* interface = 0;
4418 if (Interface::STRUCT == type)
4420 interface = new Interface(name, type);
4422 m_structures.push_back(interface);
4426 interface = new Interface(name, type);
4428 m_blocks.push_back(interface);
4434 /** Adds new block interface
4438 * @return Pointer to created interface
4440 Interface* ProgramInterface::Block(const GLchar* name)
4442 return AddInterface(name, Interface::BLOCK);
4445 /** Get interface of given shader stage
4447 * @param stage Shader stage
4449 * @return Reference to stage interface
4451 ShaderInterface& ProgramInterface::GetShaderInterface(Shader::STAGES stage)
4453 ShaderInterface* interface = 0;
4457 case Shader::COMPUTE:
4458 interface = &m_compute;
4460 case Shader::FRAGMENT:
4461 interface = &m_fragment;
4463 case Shader::GEOMETRY:
4464 interface = &m_geometry;
4466 case Shader::TESS_CTRL:
4467 interface = &m_tess_ctrl;
4469 case Shader::TESS_EVAL:
4470 interface = &m_tess_eval;
4472 case Shader::VERTEX:
4473 interface = &m_vertex;
4476 TCU_FAIL("Invalid enum");
4482 /** Get interface of given shader stage
4484 * @param stage Shader stage
4486 * @return Reference to stage interface
4488 const ShaderInterface& ProgramInterface::GetShaderInterface(Shader::STAGES stage) const
4490 const ShaderInterface* interface = 0;
4494 case Shader::COMPUTE:
4495 interface = &m_compute;
4497 case Shader::FRAGMENT:
4498 interface = &m_fragment;
4500 case Shader::GEOMETRY:
4501 interface = &m_geometry;
4503 case Shader::TESS_CTRL:
4504 interface = &m_tess_ctrl;
4506 case Shader::TESS_EVAL:
4507 interface = &m_tess_eval;
4509 case Shader::VERTEX:
4510 interface = &m_vertex;
4513 TCU_FAIL("Invalid enum");
4519 /** Clone interface of Vertex shader stage to other stages
4520 * It creates matching inputs, outputs, uniforms and buffers in other stages.
4521 * There are no additional outputs for FRAGMENT shader generated.
4523 * @param varying_passthrough Collection of varyings connections
4525 void ProgramInterface::CloneVertexInterface(VaryingPassthrough& varying_passthrough)
4527 /* VS outputs >> TCS inputs >> TCS outputs >> .. >> FS inputs */
4528 for (size_t i = 0; i < m_vertex.m_outputs.size(); ++i)
4530 const Variable& vs_var = *m_vertex.m_outputs[i];
4531 const GLchar* prefix = GetStagePrefix(Shader::VERTEX, vs_var.m_storage);
4533 cloneVariableForStage(vs_var, Shader::TESS_CTRL, prefix, varying_passthrough);
4534 cloneVariableForStage(vs_var, Shader::TESS_EVAL, prefix, varying_passthrough);
4535 cloneVariableForStage(vs_var, Shader::GEOMETRY, prefix, varying_passthrough);
4536 cloneVariableForStage(vs_var, Shader::FRAGMENT, prefix, varying_passthrough);
4539 /* Copy uniforms from VS to other stages */
4540 for (size_t i = 0; i < m_vertex.m_uniforms.size(); ++i)
4542 Variable& vs_var = *m_vertex.m_uniforms[i];
4543 const GLchar* prefix = GetStagePrefix(Shader::VERTEX, vs_var.m_storage);
4545 cloneVariableForStage(vs_var, Shader::COMPUTE, prefix, varying_passthrough);
4546 cloneVariableForStage(vs_var, Shader::TESS_CTRL, prefix, varying_passthrough);
4547 cloneVariableForStage(vs_var, Shader::TESS_EVAL, prefix, varying_passthrough);
4548 cloneVariableForStage(vs_var, Shader::GEOMETRY, prefix, varying_passthrough);
4549 cloneVariableForStage(vs_var, Shader::FRAGMENT, prefix, varying_passthrough);
4551 /* Uniform blocks needs unique binding */
4552 if (true == vs_var.IsBlock())
4554 replaceBinding(vs_var, Shader::VERTEX);
4558 /* Copy SSBs from VS to other stages */
4559 for (size_t i = 0; i < m_vertex.m_ssb_blocks.size(); ++i)
4561 Variable& vs_var = *m_vertex.m_ssb_blocks[i];
4562 const GLchar* prefix = GetStagePrefix(Shader::VERTEX, vs_var.m_storage);
4564 cloneVariableForStage(vs_var, Shader::COMPUTE, prefix, varying_passthrough);
4565 cloneVariableForStage(vs_var, Shader::TESS_CTRL, prefix, varying_passthrough);
4566 cloneVariableForStage(vs_var, Shader::TESS_EVAL, prefix, varying_passthrough);
4567 cloneVariableForStage(vs_var, Shader::GEOMETRY, prefix, varying_passthrough);
4568 cloneVariableForStage(vs_var, Shader::FRAGMENT, prefix, varying_passthrough);
4570 /* SSBs blocks needs unique binding */
4571 if (true == vs_var.IsBlock())
4573 replaceBinding(vs_var, Shader::VERTEX);
4577 m_compute.m_globals = m_vertex.m_globals;
4578 m_fragment.m_globals = m_vertex.m_globals;
4579 m_geometry.m_globals = m_vertex.m_globals;
4580 m_tess_ctrl.m_globals = m_vertex.m_globals;
4581 m_tess_eval.m_globals = m_vertex.m_globals;
4584 /** Clone variable for specific stage
4586 * @param variable Variable
4587 * @param stage Requested stage
4588 * @param prefix Prefix used in variable name that is specific for original stage
4589 * @param varying_passthrough Collection of varyings connections
4591 void ProgramInterface::cloneVariableForStage(const Variable& variable, Shader::STAGES stage, const GLchar* prefix,
4592 VaryingPassthrough& varying_passthrough)
4594 switch (variable.m_storage)
4596 case Variable::VARYING_OUTPUT:
4598 Variable* in = cloneVariableForStage(variable, stage, Variable::VARYING_INPUT, prefix);
4600 if (Shader::FRAGMENT != stage)
4602 Variable* out = cloneVariableForStage(variable, stage, Variable::VARYING_OUTPUT, prefix);
4603 varying_passthrough.Add(stage, in, out);
4607 case Variable::UNIFORM:
4609 cloneVariableForStage(variable, stage, variable.m_storage, prefix);
4612 TCU_FAIL("Invalid enum");
4617 /** Clone variable for specific stage
4619 * @param variable Variable
4620 * @param stage Requested stage
4621 * @param storage Storage used by variable
4622 * @param prefix Prefix used in variable name that is specific for original stage
4624 * @return New variable
4626 Variable* ProgramInterface::cloneVariableForStage(const Variable& variable, Shader::STAGES stage,
4627 Variable::STORAGE storage, const GLchar* prefix)
4629 /* Initialize with original variable */
4630 Variable* var = new Variable(variable);
4633 TCU_FAIL("Memory allocation");
4636 /* Set up storage */
4637 var->m_storage = storage;
4640 std::string name = variable.m_descriptor.m_name;
4642 /* Prefix name with stage ID, empty means default block */
4643 if (false == name.empty())
4645 size_t position = 0;
4646 const GLchar* stage_prefix = GetStagePrefix(stage, storage);
4647 Utils::replaceToken(prefix, position, stage_prefix, name);
4649 var->m_descriptor.m_name = name;
4652 const bool is_block = variable.IsBlock();
4653 if (true == is_block)
4655 const Interface* interface = variable.m_descriptor.m_interface;
4657 Interface* block = CloneBlockForStage(*interface, stage, storage, prefix);
4659 var->m_descriptor.m_interface = block;
4662 /* Store variable */
4663 ShaderInterface& si = GetShaderInterface(stage);
4664 Variable* result = 0;
4668 case Variable::VARYING_INPUT:
4669 si.m_inputs.push_back(var);
4670 result = si.m_inputs.back();
4672 case Variable::VARYING_OUTPUT:
4673 si.m_outputs.push_back(var);
4674 result = si.m_outputs.back();
4676 case Variable::UNIFORM:
4677 /* Uniform blocks needs unique binding */
4678 if (true == is_block)
4680 replaceBinding(*var, stage);
4683 si.m_uniforms.push_back(var);
4684 result = si.m_uniforms.back();
4687 /* SSBs needs unique binding */
4688 if (true == is_block)
4690 replaceBinding(*var, stage);
4693 si.m_ssb_blocks.push_back(var);
4694 result = si.m_ssb_blocks.back();
4697 TCU_FAIL("Invalid enum");
4704 /** clone block to specific stage
4706 * @param block Block to be copied
4707 * @param stage Specific stage
4708 * @param storage Storage used by block
4709 * @param prefix Prefix used in block name
4711 * @return New interface
4713 Interface* ProgramInterface::CloneBlockForStage(const Interface& block, Shader::STAGES stage, Variable::STORAGE storage,
4714 const GLchar* prefix)
4717 std::string name = block.m_name;
4719 /* Prefix name with stage ID */
4720 size_t position = 0;
4721 const GLchar* stage_prefix = GetStagePrefix(stage, storage);
4722 Utils::replaceToken(prefix, position, stage_prefix, name);
4724 Interface* ptr = GetBlock(name.c_str());
4728 ptr = AddInterface(name.c_str(), Interface::BLOCK);
4731 ptr->m_members = block.m_members;
4736 /** Get stage specific prefix used in names
4738 * @param stage Stage
4739 * @param storage Storage class
4743 const GLchar* ProgramInterface::GetStagePrefix(Shader::STAGES stage, Variable::STORAGE storage)
4745 static const GLchar* lut[Shader::STAGE_MAX][Variable::STORAGE_MAX] = {
4746 /* IN OUT UNIFORM SSB MEMBER */
4747 /* CS */ { 0, 0, "cs_uni_", "cs_buf_", "" },
4748 /* VS */ { "in_vs_", "vs_tcs_", "vs_uni_", "vs_buf_", "" },
4749 /* TCS */ { "vs_tcs_", "tcs_tes_", "tcs_uni_", "tcs_buf_", "" },
4750 /* TES */ { "tcs_tes_", "tes_gs_", "tes_uni_", "tes_buf_", "" },
4751 /* GS */ { "tes_gs_", "gs_fs_", "gs_uni_", "gs_buf_", "" },
4752 /* FS */ { "gs_fs_", "fs_out_", "fs_uni_", "fs_buf_", "" },
4755 const GLchar* result = 0;
4757 result = lut[stage][storage];
4762 /** Get definitions of all structures used in program interface
4764 * @return String with code
4766 std::string ProgramInterface::GetDefinitionsStructures() const
4768 return GetDefinitions(m_structures);
4771 /** Get interface code for stage
4773 * @param stage Specific stage
4775 * @return String with code
4777 std::string ProgramInterface::GetInterfaceForStage(Shader::STAGES stage) const
4779 size_t position = 0;
4780 std::string interface = "/* Globals */\n"
4783 "/* Structures */\n"
4798 const ShaderInterface& si = GetShaderInterface(stage);
4800 const std::string& structures = GetDefinitionsStructures();
4802 const std::string& globals = si.GetDefinitionsGlobals();
4803 const std::string& inputs = si.GetDefinitionsInputs();
4804 const std::string& outputs = si.GetDefinitionsOutputs();
4805 const std::string& uniforms = si.GetDefinitionsUniforms();
4806 const std::string& ssbs = si.GetDefinitionsSSBs();
4808 replaceToken("GLOBALS", position, globals.c_str(), interface);
4809 replaceToken("STRUCTURES", position, structures.c_str(), interface);
4810 replaceToken("UNIFORMS", position, uniforms.c_str(), interface);
4811 replaceToken("INPUTS", position, inputs.c_str(), interface);
4812 replaceToken("OUTPUTS", position, outputs.c_str(), interface);
4813 replaceToken("STORAGE", position, ssbs.c_str(), interface);
4818 /** Functional object used in find_if algorithm, in search for interface of given name
4821 struct matchInterfaceName
4823 matchInterfaceName(const GLchar* name) : m_name(name)
4827 bool operator()(const Interface* interface)
4829 return 0 == interface->m_name.compare(m_name);
4832 const GLchar* m_name;
4835 /** Finds interface of given name in given vector of interfaces
4837 * @param vector Collection of interfaces
4838 * @param name Requested name
4840 * @return Pointer to interface if available, 0 otherwise
4842 static Interface* findInterfaceByName(Interface::PtrVector& vector, const GLchar* name)
4844 Interface::PtrVector::iterator it = std::find_if(vector.begin(), vector.end(), matchInterfaceName(name));
4846 if (vector.end() != it)
4856 /** Search for block of given name
4858 * @param name Name of block
4860 * @return Pointer to block or 0
4862 Interface* ProgramInterface::GetBlock(const GLchar* name)
4864 return findInterfaceByName(m_blocks, name);
4867 /** Search for structure of given name
4869 * @param name Name of structure
4871 * @return Pointer to structure or 0
4873 Interface* ProgramInterface::GetStructure(const GLchar* name)
4875 return findInterfaceByName(m_structures, name);
4878 /** Adds new sturcture to interface
4880 * @param name Name of structure
4882 * @return Created structure
4884 Interface* ProgramInterface::Structure(const GLchar* name)
4886 return AddInterface(name, Interface::STRUCT);
4889 /** Replace "BINDING" token in qualifiers string to value specific for given stage
4891 * @param variable Variable to modify
4892 * @param stage Requested stage
4894 void ProgramInterface::replaceBinding(Variable& variable, Shader::STAGES stage)
4897 sprintf(binding, "%d", stage);
4898 replaceAllTokens("BINDING", binding, variable.m_descriptor.m_qualifiers);
4900 } /* Utils namespace */
4902 /** Debuging procedure. Logs parameters.
4904 * @param source As specified in GL spec.
4905 * @param type As specified in GL spec.
4906 * @param id As specified in GL spec.
4907 * @param severity As specified in GL spec.
4909 * @param message As specified in GL spec.
4910 * @param info Pointer to instance of Context used by test.
4912 void GLW_APIENTRY debug_proc(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei /* length */,
4913 const GLchar* message, void* info)
4915 deqp::Context* ctx = (deqp::Context*)info;
4917 const GLchar* source_str = "Unknown";
4918 const GLchar* type_str = "Unknown";
4919 const GLchar* severity_str = "Unknown";
4923 case GL_DEBUG_SOURCE_API:
4926 case GL_DEBUG_SOURCE_APPLICATION:
4929 case GL_DEBUG_SOURCE_OTHER:
4932 case GL_DEBUG_SOURCE_SHADER_COMPILER:
4935 case GL_DEBUG_SOURCE_THIRD_PARTY:
4938 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
4947 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
4948 type_str = "DEPRECATED_BEHAVIOR";
4950 case GL_DEBUG_TYPE_ERROR:
4953 case GL_DEBUG_TYPE_MARKER:
4954 type_str = "MARKER";
4956 case GL_DEBUG_TYPE_OTHER:
4959 case GL_DEBUG_TYPE_PERFORMANCE:
4960 type_str = "PERFORMANCE";
4962 case GL_DEBUG_TYPE_POP_GROUP:
4963 type_str = "POP_GROUP";
4965 case GL_DEBUG_TYPE_PORTABILITY:
4966 type_str = "PORTABILITY";
4968 case GL_DEBUG_TYPE_PUSH_GROUP:
4969 type_str = "PUSH_GROUP";
4971 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
4972 type_str = "UNDEFINED_BEHAVIOR";
4980 case GL_DEBUG_SEVERITY_HIGH:
4983 case GL_DEBUG_SEVERITY_LOW:
4986 case GL_DEBUG_SEVERITY_MEDIUM:
4989 case GL_DEBUG_SEVERITY_NOTIFICATION:
4996 ctx->getTestContext().getLog() << tcu::TestLog::Message << "DEBUG_INFO: " << std::setw(3) << source_str << "|"
4997 << severity_str << "|" << std::setw(18) << type_str << "|" << std::setw(12) << id
4998 << ": " << message << tcu::TestLog::EndMessage;
5003 * @param context Test context
5004 * @param test_name Test name
5005 * @param test_description Test description
5007 TestBase::TestBase(deqp::Context& context, const GLchar* test_name, const GLchar* test_description)
5008 : TestCase(context, test_name, test_description)
5010 /* Nothing to be done here */
5015 * @return tcu::TestNode::STOP otherwise
5017 tcu::TestNode::IterateResult TestBase::iterate()
5021 #if DEBUG_ENBALE_MESSAGE_CALLBACK
5022 const Functions& gl = m_context.getRenderContext().getFunctions();
5024 gl.debugMessageCallback(debug_proc, &m_context);
5025 GLU_EXPECT_NO_ERROR(gl.getError(), "DebugMessageCallback");
5026 #endif /* DEBUG_ENBALE_MESSAGE_CALLBACK */
5031 test_result = test();
5033 catch (std::exception& exc)
5035 TCU_FAIL(exc.what());
5039 if (true == test_result)
5041 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
5045 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
5049 return tcu::TestNode::STOP;
5052 /** Get last input location available for given type at specific stage
5054 * @param stage Shader stage
5055 * @param type Input type
5056 * @param array_length Length of input array
5058 * @return Last location index
5060 GLint TestBase::getLastInputLocation(Utils::Shader::STAGES stage, const Utils::Type& type, GLuint array_length)
5062 GLint divide = 4; /* 4 components per location */
5069 case Utils::Shader::FRAGMENT:
5070 pname = GL_MAX_FRAGMENT_INPUT_COMPONENTS;
5072 case Utils::Shader::GEOMETRY:
5073 pname = GL_MAX_GEOMETRY_INPUT_COMPONENTS;
5075 case Utils::Shader::TESS_CTRL:
5076 pname = GL_MAX_TESS_CONTROL_INPUT_COMPONENTS;
5078 case Utils::Shader::TESS_EVAL:
5079 pname = GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS;
5081 case Utils::Shader::VERTEX:
5082 pname = GL_MAX_VERTEX_ATTRIBS;
5086 TCU_FAIL("Invalid enum");
5090 /* Zero means no array, but 1 slot is required */
5091 if (0 == array_length)
5097 const Functions& gl = m_context.getRenderContext().getFunctions();
5099 gl.getIntegerv(pname, ¶m);
5100 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
5103 #if WRKARD_VARYINGLOCATIONSTEST
5105 const GLint n_avl_locations = 16;
5109 const GLint n_avl_locations = param / divide;
5113 const GLuint n_req_location = type.GetLocations() * array_length;
5115 return n_avl_locations - n_req_location; /* last is max - 1 */
5118 /** Get last input location available for given type at specific stage
5120 * @param stage Shader stage
5121 * @param type Input type
5122 * @param array_length Length of input array
5124 * @return Last location index
5126 GLint TestBase::getLastOutputLocation(Utils::Shader::STAGES stage, const Utils::Type& type, GLuint array_length)
5134 case Utils::Shader::GEOMETRY:
5135 pname = GL_MAX_GEOMETRY_OUTPUT_COMPONENTS;
5137 case Utils::Shader::TESS_CTRL:
5138 pname = GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS;
5140 case Utils::Shader::TESS_EVAL:
5141 pname = GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS;
5143 case Utils::Shader::VERTEX:
5144 pname = GL_MAX_VERTEX_OUTPUT_COMPONENTS;
5147 TCU_FAIL("Invalid enum");
5151 /* Zero means no array, but 1 slot is required */
5152 if (0 == array_length)
5158 const Functions& gl = m_context.getRenderContext().getFunctions();
5160 gl.getIntegerv(pname, ¶m);
5161 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
5164 #if WRKARD_VARYINGLOCATIONSTEST
5166 const GLint n_avl_locations = 16;
5170 const GLint n_avl_locations = param / 4; /* 4 components per location */
5174 const GLuint n_req_location = type.GetLocations() * array_length;
5176 return n_avl_locations - n_req_location; /* last is max - 1 */
5179 /** Basic implementation
5183 * @return Empty string
5185 std::string TestBase::getTestCaseName(GLuint /* test_case_index */)
5192 /** Basic implementation
5196 GLuint TestBase::getTestCaseNumber()
5201 /** Check if flat qualifier is required for given type, stage and storage
5203 * @param stage Shader stage
5204 * @param type Input type
5205 * @param storage Storage of variable
5207 * @return Last location index
5209 bool TestBase::isFlatRequired(Utils::Shader::STAGES stage, const Utils::Type& type,
5210 Utils::Variable::STORAGE storage) const
5212 /* Float types do not need flat at all */
5213 if (Utils::Type::Float == type.m_basic_type)
5218 /* Inputs to fragment shader */
5219 if ((Utils::Shader::FRAGMENT == stage) && (Utils::Variable::VARYING_INPUT == storage))
5224 /* Outputs from geometry shader */
5225 if ((Utils::Shader::FRAGMENT == stage) && (Utils::Variable::VARYING_OUTPUT == storage))
5233 /** Basic implementation of testInit method
5236 void TestBase::testInit()
5240 /** Calculate stride for interface
5242 * @param interface Interface
5244 * @return Calculated value
5246 GLuint TestBase::calculateStride(const Utils::Interface& interface) const
5248 const size_t n_members = interface.m_members.size();
5252 for (size_t i = 0; i < n_members; ++i)
5254 const Utils::Variable::Descriptor& member = interface.m_members[i];
5255 const GLuint member_offset = member.m_offset;
5256 const GLuint member_stride = member.m_expected_stride_of_element;
5257 const GLuint member_ends_at = member_offset + member_stride;
5259 stride = std::max(stride, member_ends_at);
5265 /** Generate data for interface. This routine is recursive
5267 * @param interface Interface
5268 * @param offset Offset in out_data
5269 * @param out_data Buffer to be filled
5271 void TestBase::generateData(const Utils::Interface& interface, GLuint offset, std::vector<GLubyte>& out_data) const
5273 const size_t n_members = interface.m_members.size();
5274 GLubyte* ptr = &out_data[offset];
5276 for (size_t i = 0; i < n_members; ++i)
5278 const Utils::Variable::Descriptor& member = interface.m_members[i];
5279 const GLuint member_offset = member.m_offset;
5280 const GLuint n_elements = (0 == member.m_n_array_elements) ? 1 : member.m_n_array_elements;
5282 for (GLuint element = 0; element < n_elements; ++element)
5284 const GLuint element_offset = element * member.m_expected_stride_of_element;
5285 const GLuint data_offfset = member_offset + element_offset;
5287 if (Utils::Variable::BUILTIN == member.m_type)
5289 const std::vector<GLubyte>& data = member.m_builtin.GenerateData();
5291 memcpy(ptr + data_offfset, &data[0], data.size());
5295 generateData(*member.m_interface, offset + data_offfset, out_data);
5301 /** Get type at index
5303 * @param index Index of requested type
5307 Utils::Type TestBase::getType(GLuint index) const
5314 type = Utils::Type::_double;
5317 type = Utils::Type::dmat2;
5320 type = Utils::Type::dmat2x3;
5323 type = Utils::Type::dmat2x4;
5326 type = Utils::Type::dmat3;
5329 type = Utils::Type::dmat3x2;
5332 type = Utils::Type::dmat3x4;
5335 type = Utils::Type::dmat4;
5338 type = Utils::Type::dmat4x2;
5341 type = Utils::Type::dmat4x3;
5344 type = Utils::Type::dvec2;
5347 type = Utils::Type::dvec3;
5350 type = Utils::Type::dvec4;
5353 type = Utils::Type::_float;
5356 type = Utils::Type::mat2;
5359 type = Utils::Type::mat2x3;
5362 type = Utils::Type::mat2x4;
5365 type = Utils::Type::mat3;
5368 type = Utils::Type::mat3x2;
5371 type = Utils::Type::mat3x4;
5374 type = Utils::Type::mat4;
5377 type = Utils::Type::mat4x2;
5380 type = Utils::Type::mat4x3;
5383 type = Utils::Type::vec2;
5386 type = Utils::Type::vec3;
5389 type = Utils::Type::vec4;
5392 type = Utils::Type::_int;
5395 type = Utils::Type::ivec2;
5398 type = Utils::Type::ivec3;
5401 type = Utils::Type::ivec4;
5404 type = Utils::Type::uint;
5407 type = Utils::Type::uvec2;
5410 type = Utils::Type::uvec3;
5413 type = Utils::Type::uvec4;
5416 TCU_FAIL("invalid enum");
5422 /** Get name of type at index
5424 * @param index Index of type
5428 std::string TestBase::getTypeName(GLuint index) const
5430 std::string name = getType(index).GetGLSLTypeName();
5435 /** Get number of types
5439 glw::GLuint TestBase::getTypesNumber() const
5446 * @return true if test pass, false otherwise
5448 bool TestBase::test()
5451 GLuint n_test_cases = 0;
5456 /* GL entry points */
5457 const Functions& gl = m_context.getRenderContext().getFunctions();
5459 /* Tesselation patch set up */
5460 gl.patchParameteri(GL_PATCH_VERTICES, 1);
5461 GLU_EXPECT_NO_ERROR(gl.getError(), "PatchParameteri");
5463 /* Get number of test cases */
5464 n_test_cases = getTestCaseNumber();
5466 #if DEBUG_REPEAT_TEST_CASE
5470 GLuint test_case = DEBUG_REPEATED_TEST_CASE;
5472 #else /* DEBUG_REPEAT_TEST_CASE */
5474 for (GLuint test_case = 0; test_case < n_test_cases; ++test_case)
5477 #endif /* DEBUG_REPEAT_TEST_CASE */
5479 bool case_result = true;
5482 if (false == testCase(test_case))
5484 case_result = false;
5488 if (false == case_result)
5490 const std::string& test_case_name = getTestCaseName(test_case);
5492 if (false == test_case_name.empty())
5494 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Test case (" << test_case_name
5495 << ") failed." << tcu::TestLog::EndMessage;
5499 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Test case (" << test_case
5500 << ") failed." << tcu::TestLog::EndMessage;
5511 /* Constants used by BufferTestBase */
5512 const GLuint BufferTestBase::bufferDescriptor::m_non_indexed = -1;
5516 * @param context Test context
5517 * @param test_name Name of test
5518 * @param test_description Description of test
5520 BufferTestBase::BufferTestBase(deqp::Context& context, const GLchar* test_name, const GLchar* test_description)
5521 : TestBase(context, test_name, test_description)
5525 /** Execute drawArrays for single vertex
5531 bool BufferTestBase::executeDrawCall(bool tesEnabled, GLuint /* test_case_index */)
5533 const Functions& gl = m_context.getRenderContext().getFunctions();
5535 gl.disable(GL_RASTERIZER_DISCARD);
5536 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
5538 gl.beginTransformFeedback(GL_POINTS);
5539 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
5541 // Only TES is existed, glDrawArray can use the parameter GL_PATCHES
5542 if (tesEnabled == false)
5544 gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */);
5548 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
5551 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
5553 gl.endTransformFeedback();
5554 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
5559 /** Get descriptors of buffers necessary for test
5564 void BufferTestBase::getBufferDescriptors(glw::GLuint /* test_case_index */,
5565 bufferDescriptor::Vector& /* out_descriptors */)
5567 /* Nothhing to be done */
5570 /** Get list of names of varyings that will be registered with TransformFeedbackVaryings
5575 void BufferTestBase::getCapturedVaryings(glw::GLuint /* test_case_index */,
5576 Utils::Program::NameVector& /* captured_varyings */)
5578 /* Nothing to be done */
5581 /** Get body of main function for given shader stage
5585 * @param out_assignments Set to empty
5586 * @param out_calculations Set to empty
5588 void BufferTestBase::getShaderBody(glw::GLuint /* test_case_index */, Utils::Shader::STAGES /* stage */,
5589 std::string& out_assignments, std::string& out_calculations)
5591 out_assignments = "";
5592 out_calculations = "";
5595 /** Get interface of shader
5599 * @param out_interface Set to ""
5601 void BufferTestBase::getShaderInterface(glw::GLuint /* test_case_index */, Utils::Shader::STAGES /* stage */,
5602 std::string& out_interface)
5607 /** Get source code of shader
5609 * @param test_case_index Index of test case
5610 * @param stage Shader stage
5614 std::string BufferTestBase::getShaderSource(glw::GLuint test_case_index, Utils::Shader::STAGES stage)
5616 std::string assignments;
5617 std::string calculations;
5618 std::string interface;
5621 getShaderBody(test_case_index, stage, assignments, calculations);
5622 getShaderInterface(test_case_index, stage, interface);
5625 std::string source = getShaderTemplate(stage);
5628 size_t position = 0;
5629 Utils::replaceToken("INTERFACE", position, interface.c_str(), source);
5630 Utils::replaceToken("CALCULATIONS", position, calculations.c_str(), source);
5631 Utils::replaceToken("ASSIGNMENTS", position, assignments.c_str(), source);
5637 /** Inspects program to check if all resources are as expected
5645 bool BufferTestBase::inspectProgram(GLuint /* test_case_index */, Utils::Program& /* program */,
5646 std::stringstream& /* out_stream */)
5653 * @param test_case_index Id of test case
5655 * @return true if test case pass, false otherwise
5657 bool BufferTestBase::testCase(GLuint test_case_index)
5661 bufferCollection buffers;
5662 Utils::Program::NameVector captured_varyings;
5663 bufferDescriptor::Vector descriptors;
5664 Utils::Program program(m_context);
5665 Utils::VertexArray vao(m_context);
5667 /* Get captured varyings */
5668 getCapturedVaryings(test_case_index, captured_varyings);
5670 /* Get shader sources */
5671 const std::string& fragment_shader = getShaderSource(test_case_index, Utils::Shader::FRAGMENT);
5672 const std::string& geometry_shader = getShaderSource(test_case_index, Utils::Shader::GEOMETRY);
5673 const std::string& tess_ctrl_shader = getShaderSource(test_case_index, Utils::Shader::TESS_CTRL);
5674 const std::string& tess_eval_shader = getShaderSource(test_case_index, Utils::Shader::TESS_EVAL);
5675 const std::string& vertex_shader = getShaderSource(test_case_index, Utils::Shader::VERTEX);
5677 /* Set up program */
5678 program.Init("" /* compute_shader */, fragment_shader, geometry_shader, tess_ctrl_shader, tess_eval_shader,
5679 vertex_shader, captured_varyings, true, false /* is_separable */);
5683 std::stringstream stream;
5684 if (false == inspectProgram(test_case_index, program, stream))
5686 m_context.getTestContext().getLog()
5687 << tcu::TestLog::Message
5688 << "Program inspection failed. Test case: " << getTestCaseName(test_case_index)
5689 << ". Reason: " << stream.str() << tcu::TestLog::EndMessage
5690 << tcu::TestLog::KernelSource(vertex_shader) << tcu::TestLog::KernelSource(tess_ctrl_shader)
5691 << tcu::TestLog::KernelSource(tess_eval_shader) << tcu::TestLog::KernelSource(geometry_shader)
5692 << tcu::TestLog::KernelSource(fragment_shader);
5700 /* Set up buffers */
5701 getBufferDescriptors(test_case_index, descriptors);
5703 prepareBuffers(descriptors, buffers);
5710 bool result = executeDrawCall((program.m_tess_eval.m_id != 0), test_case_index);
5713 m_context.getRenderContext().postIterate();
5716 if (false == result)
5718 m_context.getTestContext().getLog()
5719 << tcu::TestLog::KernelSource(vertex_shader) << tcu::TestLog::KernelSource(tess_ctrl_shader)
5720 << tcu::TestLog::KernelSource(tess_eval_shader) << tcu::TestLog::KernelSource(geometry_shader)
5721 << tcu::TestLog::KernelSource(fragment_shader);
5727 if (false == verifyBuffers(buffers))
5729 m_context.getTestContext().getLog()
5730 << tcu::TestLog::KernelSource(vertex_shader) << tcu::TestLog::KernelSource(tess_ctrl_shader)
5731 << tcu::TestLog::KernelSource(tess_eval_shader) << tcu::TestLog::KernelSource(geometry_shader)
5732 << tcu::TestLog::KernelSource(fragment_shader);
5737 catch (Utils::Shader::InvalidSourceException& exc)
5740 TCU_FAIL(exc.what());
5742 catch (Utils::Program::BuildException& exc)
5745 TCU_FAIL(exc.what());
5752 /** Verify contents of buffers
5754 * @param buffers Collection of buffers to be verified
5756 * @return true if everything is as expected, false otherwise
5758 bool BufferTestBase::verifyBuffers(bufferCollection& buffers)
5762 for (bufferCollection::Vector::iterator it = buffers.m_vector.begin(), end = buffers.m_vector.end(); end != it;
5765 bufferCollection::pair& pair = *it;
5766 Utils::Buffer* buffer = pair.m_buffer;
5767 bufferDescriptor* descriptor = pair.m_descriptor;
5768 size_t size = descriptor->m_expected_data.size();
5770 /* Skip buffers that have no expected data */
5776 /* Get pointer to contents of buffer */
5778 GLvoid* buffer_data = buffer->Map(Utils::Buffer::ReadOnly);
5780 /* Get pointer to expected data */
5781 GLvoid* expected_data = &descriptor->m_expected_data[0];
5784 int res = memcmp(buffer_data, expected_data, size);
5788 m_context.getTestContext().getLog()
5789 << tcu::TestLog::Message
5790 << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
5791 << ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
5796 /* Release buffer mapping */
5803 /** Unbinds all uniforms and xfb
5806 void BufferTestBase::cleanBuffers()
5808 const Functions& gl = m_context.getRenderContext().getFunctions();
5813 gl.getIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &max_uni);
5814 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_xfb);
5815 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
5817 for (GLint i = 0; i < max_uni; ++i)
5819 Utils::Buffer::BindBase(gl, 0, Utils::Buffer::Uniform, i);
5822 for (GLint i = 0; i < max_xfb; ++i)
5824 Utils::Buffer::BindBase(gl, 0, Utils::Buffer::Transform_feedback, i);
5828 /** Get template of shader for given stage
5830 * @param stage Stage
5832 * @return Template of shader source
5834 std::string BufferTestBase::getShaderTemplate(Utils::Shader::STAGES stage)
5836 static const GLchar* compute_shader_template = "#version 430 core\n"
5837 "#extension GL_ARB_enhanced_layouts : require\n"
5839 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
5841 "writeonly uniform uimage2D uni_image;\n"
5853 static const GLchar* fragment_shader_template = "#version 430 core\n"
5854 "#extension GL_ARB_enhanced_layouts : require\n"
5866 // max_vertices is set to 3 for the test case "xfb_vertex_streams" declares 3 streams in geometry shader,
5867 // according to spec, max_vertices should be no less than 3 if there are 3 streams in GS.
5868 static const GLchar* geometry_shader_template = "#version 430 core\n"
5869 "#extension GL_ARB_enhanced_layouts : require\n"
5871 "layout(points) in;\n"
5872 "layout(points, max_vertices = 3) out;\n"
5882 " gl_Position = vec4(0, 0, 0, 1);\n"
5887 static const GLchar* tess_ctrl_shader_template = "#version 430 core\n"
5888 "#extension GL_ARB_enhanced_layouts : require\n"
5890 "layout(vertices = 1) out;\n"
5900 " gl_TessLevelOuter[0] = 1.0;\n"
5901 " gl_TessLevelOuter[1] = 1.0;\n"
5902 " gl_TessLevelOuter[2] = 1.0;\n"
5903 " gl_TessLevelOuter[3] = 1.0;\n"
5904 " gl_TessLevelInner[0] = 1.0;\n"
5905 " gl_TessLevelInner[1] = 1.0;\n"
5909 static const GLchar* tess_eval_shader_template = "#version 430 core\n"
5910 "#extension GL_ARB_enhanced_layouts : require\n"
5912 "layout(isolines, point_mode) in;\n"
5924 static const GLchar* vertex_shader_template = "#version 430 core\n"
5925 "#extension GL_ARB_enhanced_layouts : require\n"
5937 const GLchar* result = 0;
5941 case Utils::Shader::COMPUTE:
5942 result = compute_shader_template;
5944 case Utils::Shader::FRAGMENT:
5945 result = fragment_shader_template;
5947 case Utils::Shader::GEOMETRY:
5948 result = geometry_shader_template;
5950 case Utils::Shader::TESS_CTRL:
5951 result = tess_ctrl_shader_template;
5953 case Utils::Shader::TESS_EVAL:
5954 result = tess_eval_shader_template;
5956 case Utils::Shader::VERTEX:
5957 result = vertex_shader_template;
5960 TCU_FAIL("Invalid enum");
5966 /** Prepare buffer according to descriptor
5968 * @param buffer Buffer to prepare
5969 * @param desc Descriptor
5971 void BufferTestBase::prepareBuffer(Utils::Buffer& buffer, bufferDescriptor& desc)
5973 GLsizeiptr size = 0;
5976 if (false == desc.m_initial_data.empty())
5978 size = desc.m_initial_data.size();
5979 data = &desc.m_initial_data[0];
5981 else if (false == desc.m_expected_data.empty())
5983 size = desc.m_expected_data.size();
5986 buffer.Init(desc.m_target, Utils::Buffer::StaticDraw, size, data);
5988 if (bufferDescriptor::m_non_indexed != desc.m_index)
5990 buffer.BindBase(desc.m_index);
5998 /** Prepare collection of buffer
6000 * @param descriptors Collection of descriptors
6001 * @param out_buffers Collection of buffers
6003 void BufferTestBase::prepareBuffers(bufferDescriptor::Vector& descriptors, bufferCollection& out_buffers)
6005 for (bufferDescriptor::Vector::iterator it = descriptors.begin(), end = descriptors.end(); end != it; ++it)
6007 bufferCollection::pair pair;
6009 pair.m_buffer = new Utils::Buffer(m_context);
6010 if (0 == pair.m_buffer)
6012 TCU_FAIL("Memory allocation failed");
6015 pair.m_descriptor = &(*it);
6017 prepareBuffer(*pair.m_buffer, *pair.m_descriptor);
6019 out_buffers.m_vector.push_back(pair);
6026 BufferTestBase::bufferCollection::~bufferCollection()
6028 for (Vector::iterator it = m_vector.begin(), end = m_vector.end(); end != it; ++it)
6030 if (0 != it->m_buffer)
6032 delete it->m_buffer;
6040 * @param context Test context
6041 * @param test_name Name of test
6042 * @param test_description Description of test
6044 NegativeTestBase::NegativeTestBase(deqp::Context& context, const GLchar* test_name, const GLchar* test_description)
6045 : TestBase(context, test_name, test_description)
6049 /** Selects if "compute" stage is relevant for test
6055 bool NegativeTestBase::isComputeRelevant(GLuint /* test_case_index */)
6060 /** Selects if compilation failure is expected result
6066 bool NegativeTestBase::isFailureExpected(GLuint /* test_case_index */)
6073 * @param test_case_index Id of test case
6075 * @return true if test case pass, false otherwise
6077 bool NegativeTestBase::testCase(GLuint test_case_index)
6079 bool test_case_result = true;
6082 if (true == isComputeRelevant(test_case_index))
6084 const std::string& cs_source = getShaderSource(test_case_index, Utils::Shader::COMPUTE);
6085 bool is_build_error = false;
6086 const bool is_failure_expected = isFailureExpected(test_case_index);
6087 Utils::Program program(m_context);
6091 program.Init(cs_source, "" /* fs */, "" /* gs */, "" /* tcs */, "" /* tes */, "" /* vs */,
6092 false /* separable */);
6094 catch (Utils::Shader::InvalidSourceException& exc)
6096 if (false == is_failure_expected)
6098 m_context.getTestContext().getLog()
6099 << tcu::TestLog::Message << "Unexpected error in shader compilation: " << tcu::TestLog::EndMessage;
6103 #if DEBUG_NEG_LOG_ERROR
6107 m_context.getTestContext().getLog()
6108 << tcu::TestLog::Message << "Error in shader compilation was expected, logged for verification: "
6109 << tcu::TestLog::EndMessage;
6113 #endif /* DEBUG_NEG_LOG_ERROR */
6115 is_build_error = true;
6117 catch (Utils::Program::BuildException& exc)
6119 if (false == is_failure_expected)
6121 m_context.getTestContext().getLog()
6122 << tcu::TestLog::Message << "Unexpected error in program linking: " << tcu::TestLog::EndMessage;
6126 #if DEBUG_NEG_LOG_ERROR
6130 m_context.getTestContext().getLog()
6131 << tcu::TestLog::Message
6132 << "Error in program linking was expected, logged for verification: " << tcu::TestLog::EndMessage;
6136 #endif /* DEBUG_NEG_LOG_ERROR */
6138 is_build_error = true;
6141 if (is_build_error != is_failure_expected)
6143 test_case_result = false;
6148 const std::string& fs_source = getShaderSource(test_case_index, Utils::Shader::FRAGMENT);
6149 const std::string& gs_source = getShaderSource(test_case_index, Utils::Shader::GEOMETRY);
6150 bool is_build_error = false;
6151 const bool is_failure_expected = isFailureExpected(test_case_index);
6152 Utils::Program program(m_context);
6153 const std::string& tcs_source = getShaderSource(test_case_index, Utils::Shader::TESS_CTRL);
6154 const std::string& tes_source = getShaderSource(test_case_index, Utils::Shader::TESS_EVAL);
6155 const std::string& vs_source = getShaderSource(test_case_index, Utils::Shader::VERTEX);
6159 program.Init("" /* cs */, fs_source, gs_source, tcs_source, tes_source, vs_source, false /* separable */);
6161 catch (Utils::Shader::InvalidSourceException& exc)
6163 if (false == is_failure_expected)
6165 m_context.getTestContext().getLog()
6166 << tcu::TestLog::Message << "Unexpected error in shader compilation: " << tcu::TestLog::EndMessage;
6170 #if DEBUG_NEG_LOG_ERROR
6174 m_context.getTestContext().getLog()
6175 << tcu::TestLog::Message << "Error in shader compilation was expected, logged for verification: "
6176 << tcu::TestLog::EndMessage;
6180 #endif /* DEBUG_NEG_LOG_ERROR */
6182 is_build_error = true;
6184 catch (Utils::Program::BuildException& exc)
6186 if (false == is_failure_expected)
6188 m_context.getTestContext().getLog()
6189 << tcu::TestLog::Message << "Unexpected error in program linking: " << tcu::TestLog::EndMessage;
6193 #if DEBUG_NEG_LOG_ERROR
6197 m_context.getTestContext().getLog()
6198 << tcu::TestLog::Message
6199 << "Error in program linking was expected, logged for verification: " << tcu::TestLog::EndMessage;
6203 #endif /* DEBUG_NEG_LOG_ERROR */
6205 is_build_error = true;
6208 if (is_build_error != is_failure_expected)
6210 test_case_result = false;
6214 return test_case_result;
6217 /* Constants used by TextureTestBase */
6218 const glw::GLuint TextureTestBase::m_width = 16;
6219 const glw::GLuint TextureTestBase::m_height = 16;
6223 * @param context Test context
6224 * @param test_name Name of test
6225 * @param test_description Description of test
6227 TextureTestBase::TextureTestBase(deqp::Context& context, const GLchar* test_name, const GLchar* test_description)
6228 : TestBase(context, test_name, test_description)
6232 /** Get locations for all inputs with automatic_location
6234 * @param program Program object
6235 * @param program_interface Interface of program
6237 void TextureTestBase::prepareAttribLocation(Utils::Program& program, Utils::ProgramInterface& program_interface)
6239 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
6241 Utils::Variable::PtrVector& inputs = si.m_inputs;
6243 for (Utils::Variable::PtrVector::iterator it = inputs.begin(); inputs.end() != it; ++it)
6245 /* Test does not specify location, query value and set */
6246 if (Utils::Variable::m_automatic_location == (*it)->m_descriptor.m_expected_location)
6248 GLuint index = program.GetResourceIndex((*it)->m_descriptor.m_name, GL_PROGRAM_INPUT);
6251 program.GetResource(GL_PROGRAM_INPUT, index, GL_LOCATION, 1 /* size */, &location);
6253 (*it)->m_descriptor.m_expected_location = location;
6258 /** Verifies contents of drawn image
6261 * @param color_0 Verified image
6263 * @return true if image is filled with 1, false otherwise
6265 bool TextureTestBase::checkResults(glw::GLuint /* test_case_index */, Utils::Texture& color_0)
6267 static const GLuint size = m_width * m_height;
6268 static const GLuint expected_color = 1;
6270 std::vector<GLuint> data;
6273 color_0.Get(GL_RED_INTEGER, GL_UNSIGNED_INT, &data[0]);
6275 for (GLuint i = 0; i < size; ++i)
6277 const GLuint color = data[i];
6279 if (expected_color != color)
6281 m_context.getTestContext().getLog() << tcu::TestLog::Message << "R32UI[" << i << "]:" << color
6282 << tcu::TestLog::EndMessage;
6290 /** Execute dispatch compute for 16x16x1
6294 void TextureTestBase::executeDispatchCall(GLuint /* test_case_index */)
6296 const Functions& gl = m_context.getRenderContext().getFunctions();
6298 gl.dispatchCompute(16 /* x */, 16 /* y */, 1 /* z */);
6299 GLU_EXPECT_NO_ERROR(gl.getError(), "DispatchCompute");
6302 /** Execute drawArrays for single vertex
6306 void TextureTestBase::executeDrawCall(GLuint /* test_case_index */)
6308 const Functions& gl = m_context.getRenderContext().getFunctions();
6310 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
6311 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
6314 /** Prepare code snippet that will pass in variables to out variables
6317 * @param varying_passthrough Collection of connections between in and out variables
6318 * @param stage Shader stage
6320 * @return Code that pass in variables to next stage
6322 std::string TextureTestBase::getPassSnippet(GLuint /* test_case_index */,
6323 Utils::VaryingPassthrough& varying_passthrough, Utils::Shader::STAGES stage)
6325 static const GLchar* separator = "\n ";
6327 /* Skip for compute shader */
6328 if (Utils::Shader::COMPUTE == stage)
6333 Utils::VaryingConnection::Vector& vector = varying_passthrough.Get(stage);
6335 std::string result = Utils::g_list;
6336 size_t position = 0;
6338 for (GLuint i = 0; i < vector.size(); ++i)
6341 Utils::VaryingConnection& connection = vector[i];
6343 Utils::Variable* in = connection.m_in;
6344 Utils::Variable* out = connection.m_out;
6346 Utils::Variable::FLAVOUR in_flavour = Utils::Variable::GetFlavour(stage, Utils::Variable::INPUT);
6347 Utils::Variable::FLAVOUR out_flavour = Utils::Variable::GetFlavour(stage, Utils::Variable::OUTPUT);
6349 const std::string passthrough =
6350 getVariablePassthrough("", in->m_descriptor, in_flavour, "", out->m_descriptor, out_flavour);
6352 Utils::insertElementOfList(passthrough.c_str(), separator, position, result);
6355 Utils::endList("", position, result);
6360 /** Basic implementation of method getProgramInterface
6366 void TextureTestBase::getProgramInterface(GLuint /* test_case_index */,
6367 Utils::ProgramInterface& /* program_interface */,
6368 Utils::VaryingPassthrough& /* varying_passthrough */)
6372 /** Prepare code snippet that will verify in and uniform variables
6375 * @param program_interface Interface of program
6376 * @param stage Shader stage
6378 * @return Code that verify variables
6380 std::string TextureTestBase::getVerificationSnippet(GLuint /* test_case_index */,
6381 Utils::ProgramInterface& program_interface,
6382 Utils::Shader::STAGES stage)
6384 static const GLchar* separator = " ||\n ";
6386 std::string verification = "if (LIST)\n"
6391 /* Get flavour of in and out variables */
6392 Utils::Variable::FLAVOUR in_flavour = Utils::Variable::GetFlavour(stage, Utils::Variable::INPUT);
6394 /* Get interface for shader stage */
6395 Utils::ShaderInterface& si = program_interface.GetShaderInterface(stage);
6397 /* There are no varialbes to verify */
6398 if ((0 == si.m_inputs.size()) && (0 == si.m_uniforms.size()) && (0 == si.m_ssb_blocks.size()))
6403 /* For each in variable insert verification code */
6404 size_t position = 0;
6406 for (GLuint i = 0; i < si.m_inputs.size(); ++i)
6408 const Utils::Variable& var = *si.m_inputs[i];
6409 const std::string& var_verification = getVariableVerifcation("", var.m_data, var.m_descriptor, in_flavour);
6411 Utils::insertElementOfList(var_verification.c_str(), separator, position, verification);
6414 /* For each unifrom variable insert verification code */
6415 for (GLuint i = 0; i < si.m_uniforms.size(); ++i)
6417 const Utils::Variable& var = *si.m_uniforms[i];
6418 const std::string& var_verification =
6419 getVariableVerifcation("", var.m_data, var.m_descriptor, Utils::Variable::BASIC);
6421 Utils::insertElementOfList(var_verification.c_str(), separator, position, verification);
6424 /* For each ssb variable insert verification code */
6425 for (GLuint i = 0; i < si.m_ssb_blocks.size(); ++i)
6427 const Utils::Variable& var = *si.m_ssb_blocks[i];
6428 const std::string& var_verification =
6429 getVariableVerifcation("", var.m_data, var.m_descriptor, Utils::Variable::BASIC);
6431 Utils::insertElementOfList(var_verification.c_str(), separator, position, verification);
6434 Utils::endList("", position, verification);
6436 #if DEBUG_TTB_VERIFICATION_SNIPPET_STAGE
6440 sprintf(buffer, "%d", stage + 10);
6441 Utils::replaceToken("0u", position, buffer, verification);
6444 #elif DEBUG_TTB_VERIFICATION_SNIPPET_VARIABLE
6446 if (Utils::Shader::VERTEX == stage)
6448 Utils::replaceToken("0u", position, "in_vs_first.x", verification);
6452 Utils::replaceToken("0u", position, "31u", verification);
6458 return verification;
6461 /** Selects if "compute" stage is relevant for test
6467 bool TextureTestBase::isComputeRelevant(GLuint /* test_case_index */)
6472 /** Selects if "draw" stages are relevant for test
6478 bool TextureTestBase::isDrawRelevant(GLuint /* test_case_index */)
6483 /** Prepare code that will do assignment of single in to single out
6485 * @param in_parent_name Name of parent in variable
6486 * @param in_variable Descriptor of in variable
6487 * @param in_flavour Flavoud of in variable
6488 * @param out_parent_name Name of parent out variable
6489 * @param out_variable Descriptor of out variable
6490 * @param out_flavour Flavoud of out variable
6492 * @return Code that does OUT = IN
6494 std::string TextureTestBase::getVariablePassthrough(const std::string& in_parent_name,
6495 const Utils::Variable::Descriptor& in_variable,
6496 Utils::Variable::FLAVOUR in_flavour,
6497 const std::string& out_parent_name,
6498 const Utils::Variable::Descriptor& out_variable,
6499 Utils::Variable::FLAVOUR out_flavour)
6503 GLuint member_index = 0;
6504 size_t position = 0;
6505 std::string result = Utils::g_list;
6506 static const GLchar* separator = ";\n ";
6508 /* For each member of each array element */
6511 const std::string in_name = Utils::Variable::GetReference(in_parent_name, in_variable, in_flavour, index);
6512 const std::string out_name = Utils::Variable::GetReference(out_parent_name, out_variable, out_flavour, index);
6513 std::string passthrough;
6515 /* Prepare verification */
6516 if (Utils::Variable::BUILTIN == in_variable.m_type)
6518 size_t pass_position = 0;
6520 passthrough = "OUT = IN;";
6522 Utils::replaceToken("OUT", pass_position, out_name.c_str(), passthrough);
6523 Utils::replaceToken("IN", pass_position, in_name.c_str(), passthrough);
6525 /* Increment index */
6530 const Utils::Interface* in_interface = in_variable.m_interface;
6531 const Utils::Interface* out_interface = out_variable.m_interface;
6533 if ((0 == in_interface) || (0 == out_interface))
6535 TCU_FAIL("Nullptr");
6538 const Utils::Variable::Descriptor& in_member = in_interface->m_members[member_index];
6539 const Utils::Variable::Descriptor& out_member = out_interface->m_members[member_index];
6541 passthrough = getVariablePassthrough(in_name, in_member, Utils::Variable::BASIC, out_name, out_member,
6542 Utils::Variable::BASIC);
6544 /* Increment member_index */
6547 /* Increment index and reset member_index if all members were processed */
6548 if (in_interface->m_members.size() == member_index)
6555 /* Check if loop should end */
6556 if ((index >= in_variable.m_n_array_elements) && (0 == member_index))
6561 Utils::insertElementOfList(passthrough.c_str(), separator, position, result);
6563 } while (true != done);
6565 Utils::endList("", position, result);
6571 /** Get verification of single variable
6573 * @param parent_name Name of parent variable
6574 * @param data Data that should be used as EXPECTED
6575 * @param variable Descriptor of variable
6576 * @param flavour Flavour of variable
6578 * @return Code that does (EXPECTED != VALUE) ||
6580 std::string TextureTestBase::getVariableVerifcation(const std::string& parent_name, const GLvoid* data,
6581 const Utils::Variable::Descriptor& variable,
6582 Utils::Variable::FLAVOUR flavour)
6584 static const GLchar* logic_op = " ||\n ";
6585 const GLuint n_elements = (0 == variable.m_n_array_elements) ? 1 : variable.m_n_array_elements;
6586 size_t position = 0;
6587 std::string result = Utils::g_list;
6588 GLint stride = variable.m_expected_stride_of_element;
6590 /* For each each array element */
6591 for (GLuint element = 0; element < n_elements; ++element)
6593 const std::string name = Utils::Variable::GetReference(parent_name, variable, flavour, element);
6595 /* Calculate data pointer */
6596 GLvoid* data_ptr = (GLvoid*)((GLubyte*)data + element * stride);
6598 /* Prepare verification */
6599 if (Utils::Variable::BUILTIN == variable.m_type)
6601 const std::string& expected = variable.m_builtin.GetGLSLConstructor(data_ptr);
6602 std::string verification;
6603 size_t verification_position = 0;
6605 verification = "(EXPECTED != NAME)";
6607 Utils::replaceToken("EXPECTED", verification_position, expected.c_str(), verification);
6608 Utils::replaceToken("NAME", verification_position, name.c_str(), verification);
6610 Utils::insertElementOfList(verification.c_str(), logic_op, position, result);
6614 const Utils::Interface* interface = variable.m_interface;
6618 TCU_FAIL("Nullptr");
6621 const GLuint n_members = static_cast<GLuint>(interface->m_members.size());
6623 /* for each member */
6624 for (GLuint member_index = 0; member_index < n_members; ++member_index)
6626 const Utils::Variable::Descriptor& member = interface->m_members[member_index];
6628 /* Get verification of member */
6629 const std::string& verification =
6630 getVariableVerifcation(name, (GLubyte*)data_ptr + member.m_offset, member, Utils::Variable::BASIC);
6632 Utils::insertElementOfList(verification.c_str(), logic_op, position, result);
6637 Utils::endList("", position, result);
6642 /** Prepare attributes, vertex array object and array buffer
6644 * @param test_case_index Index of test case
6645 * @param program_interface Interface of program
6646 * @param buffer Array buffer
6647 * @param vao Vertex array object
6649 void TextureTestBase::prepareAttributes(GLuint test_case_index, Utils::ProgramInterface& program_interface,
6650 Utils::Buffer& buffer, Utils::VertexArray& vao)
6652 bool use_component_qualifier = useComponentQualifier(test_case_index);
6654 /* Get shader interface */
6655 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
6657 /* Bind vao and buffer */
6661 /* Skip if there are no input variables in vertex shader */
6662 if (0 == si.m_inputs.size())
6667 /* Calculate vertex stride and check */
6668 GLint vertex_stride = 0;
6670 for (GLuint i = 0; i < si.m_inputs.size(); ++i)
6672 Utils::Variable& variable = *si.m_inputs[i];
6674 GLint variable_size = static_cast<GLuint>(variable.m_data_size);
6676 GLint ends_at = variable_size + variable.m_descriptor.m_offset;
6678 vertex_stride = std::max(vertex_stride, ends_at);
6681 /* Prepare buffer data and set up vao */
6682 std::vector<GLubyte> buffer_data;
6683 buffer_data.resize(vertex_stride);
6685 GLubyte* ptr = &buffer_data[0];
6687 for (GLuint i = 0; i < si.m_inputs.size(); ++i)
6689 Utils::Variable& variable = *si.m_inputs[i];
6691 memcpy(ptr + variable.m_descriptor.m_offset, variable.m_data, variable.m_data_size);
6693 if (false == use_component_qualifier)
6695 vao.Attribute(variable.m_descriptor.m_expected_location, variable.m_descriptor.m_builtin,
6696 variable.m_descriptor.m_n_array_elements, variable.m_descriptor.m_normalized,
6697 variable.GetStride(), (GLvoid*)(intptr_t)variable.m_descriptor.m_offset);
6699 else if (0 == variable.m_descriptor.m_expected_component)
6701 /* Components can only be applied to vectors.
6702 Assumption that test use all 4 components */
6703 const Utils::Type& type =
6704 Utils::Type::GetType(variable.m_descriptor.m_builtin.m_basic_type, 1 /* n_columns */, 4 /* n_rows */);
6706 vao.Attribute(variable.m_descriptor.m_expected_location, type, variable.m_descriptor.m_n_array_elements,
6707 variable.m_descriptor.m_normalized, variable.GetStride(),
6708 (GLvoid*)(intptr_t)variable.m_descriptor.m_offset);
6713 buffer.Data(Utils::Buffer::StaticDraw, vertex_stride, ptr);
6716 /** Get locations for all outputs with automatic_location
6718 * @param program Program object
6719 * @param program_interface Interface of program
6721 void TextureTestBase::prepareFragmentDataLoc(Utils::Program& program, Utils::ProgramInterface& program_interface)
6723 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
6724 Utils::Variable::PtrVector& outputs = si.m_outputs;
6726 for (Utils::Variable::PtrVector::iterator it = outputs.begin(); outputs.end() != it; ++it)
6728 /* Test does not specify location, query value and set */
6729 if (Utils::Variable::m_automatic_location == (*it)->m_descriptor.m_expected_location)
6731 GLuint index = program.GetResourceIndex((*it)->m_descriptor.m_name, GL_PROGRAM_OUTPUT);
6734 program.GetResource(GL_PROGRAM_OUTPUT, index, GL_LOCATION, 1 /* size */, &location);
6736 (*it)->m_descriptor.m_expected_location = location;
6741 /** Prepare framebuffer with single texture as color attachment
6743 * @param framebuffer Framebuffer
6744 * @param color_0_texture Texture that will used as color attachment
6746 void TextureTestBase::prepareFramebuffer(Utils::Framebuffer& framebuffer, Utils::Texture& color_0_texture)
6749 std::vector<GLuint> texture_data;
6750 texture_data.resize(m_width * m_height);
6752 for (GLuint i = 0; i < texture_data.size(); ++i)
6754 texture_data[i] = 0x20406080;
6757 /* Prepare texture */
6758 color_0_texture.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT,
6761 /* Prepare framebuffer */
6764 framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0, color_0_texture.m_id, m_width, m_height);
6766 framebuffer.ClearColor(0.0f, 0.0f, 0.0f, 0.0f);
6767 framebuffer.Clear(GL_COLOR_BUFFER_BIT);
6770 /** Prepare iamge unit for compute shader
6772 * @param location Uniform location
6773 * @param image_texture Texture that will used as color attachment
6775 void TextureTestBase::prepareImage(GLint location, Utils::Texture& image_texture) const
6777 static const GLuint image_unit = 0;
6779 std::vector<GLuint> texture_data;
6780 texture_data.resize(m_width * m_height);
6782 for (GLuint i = 0; i < texture_data.size(); ++i)
6784 texture_data[i] = 0x20406080;
6787 image_texture.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT,
6790 const Functions& gl = m_context.getRenderContext().getFunctions();
6792 gl.bindImageTexture(image_unit, image_texture.m_id, 0 /* level */, GL_FALSE /* layered */, 0 /* Layer */,
6793 GL_WRITE_ONLY, GL_R32UI);
6794 GLU_EXPECT_NO_ERROR(gl.getError(), "BindImageTexture");
6796 Utils::Program::Uniform(gl, Utils::Type::_int, 1 /* count */, location, &image_unit);
6799 /** Basic implementation
6802 * @param si Shader interface
6803 * @param program Program
6804 * @param cs_buffer Buffer for ssb blocks
6806 void TextureTestBase::prepareSSBs(GLuint /* test_case_index */, Utils::ShaderInterface& si, Utils::Program& program,
6807 Utils::Buffer& buffer)
6809 /* Skip if there are no input variables in vertex shader */
6810 if (0 == si.m_ssb_blocks.size())
6815 /* Calculate vertex stride */
6816 GLint ssbs_stride = 0;
6818 for (GLuint i = 0; i < si.m_ssb_blocks.size(); ++i)
6820 Utils::Variable& variable = *si.m_ssb_blocks[i];
6822 if (false == variable.IsBlock())
6827 GLint variable_stride = variable.GetStride();
6829 GLint ends_at = variable_stride + variable.m_descriptor.m_offset;
6831 ssbs_stride = std::max(ssbs_stride, ends_at);
6834 /* Set active program */
6839 buffer.Data(Utils::Buffer::StaticDraw, ssbs_stride, 0);
6841 /* Set up uniforms */
6842 for (GLuint i = 0; i < si.m_ssb_blocks.size(); ++i)
6844 Utils::Variable& variable = *si.m_ssb_blocks[i];
6846 /* prepareUnifor should work fine for ssb blocks */
6847 prepareUniform(program, variable, buffer);
6851 /** Basic implementation
6853 * @param test_case_index Test case index
6854 * @param program_interface Program interface
6855 * @param program Program
6856 * @param cs_buffer Buffer for compute shader stage
6858 void TextureTestBase::prepareSSBs(GLuint test_case_index, Utils::ProgramInterface& program_interface,
6859 Utils::Program& program, Utils::Buffer& cs_buffer)
6861 cs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
6863 Utils::ShaderInterface& cs = program_interface.GetShaderInterface(Utils::Shader::COMPUTE);
6865 prepareSSBs(test_case_index, cs, program, cs_buffer);
6867 cs_buffer.BindBase(Utils::Shader::COMPUTE);
6870 /** Basic implementation
6872 * @param test_case_index Test case index
6873 * @param program_interface Program interface
6874 * @param program Program
6875 * @param fs_buffer Buffer for fragment shader stage
6876 * @param gs_buffer Buffer for geometry shader stage
6877 * @param tcs_buffer Buffer for tesselation control shader stage
6878 * @param tes_buffer Buffer for tesselation evaluation shader stage
6879 * @param vs_buffer Buffer for vertex shader stage
6881 void TextureTestBase::prepareSSBs(GLuint test_case_index, Utils::ProgramInterface& program_interface,
6882 Utils::Program& program, Utils::Buffer& fs_buffer, Utils::Buffer& gs_buffer,
6883 Utils::Buffer& tcs_buffer, Utils::Buffer& tes_buffer, Utils::Buffer& vs_buffer)
6885 fs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
6886 gs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
6887 tcs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
6888 tes_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
6889 vs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
6891 Utils::ShaderInterface& fs = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
6892 Utils::ShaderInterface& gs = program_interface.GetShaderInterface(Utils::Shader::GEOMETRY);
6893 Utils::ShaderInterface& tcs = program_interface.GetShaderInterface(Utils::Shader::TESS_CTRL);
6894 Utils::ShaderInterface& tes = program_interface.GetShaderInterface(Utils::Shader::TESS_EVAL);
6895 Utils::ShaderInterface& vs = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
6897 prepareSSBs(test_case_index, fs, program, fs_buffer);
6898 prepareSSBs(test_case_index, gs, program, gs_buffer);
6899 prepareSSBs(test_case_index, tcs, program, tcs_buffer);
6900 prepareSSBs(test_case_index, tes, program, tes_buffer);
6901 prepareSSBs(test_case_index, vs, program, vs_buffer);
6903 fs_buffer.BindBase(Utils::Shader::FRAGMENT);
6904 gs_buffer.BindBase(Utils::Shader::GEOMETRY);
6905 tcs_buffer.BindBase(Utils::Shader::TESS_CTRL);
6906 tes_buffer.BindBase(Utils::Shader::TESS_EVAL);
6907 vs_buffer.BindBase(Utils::Shader::VERTEX);
6910 /** Updates buffer data with variable
6912 * @param program Program object
6913 * @param variable Variable
6914 * @param buffer Buffer
6916 void TextureTestBase::prepareUniform(Utils::Program& program, Utils::Variable& variable, Utils::Buffer& buffer)
6918 const Functions& gl = m_context.getRenderContext().getFunctions();
6920 GLsizei count = variable.m_descriptor.m_n_array_elements;
6926 if (Utils::Variable::BUILTIN == variable.m_descriptor.m_type)
6928 program.Uniform(gl, variable.m_descriptor.m_builtin, count, variable.m_descriptor.m_expected_location,
6933 const bool is_block = variable.IsBlock();
6935 if (false == is_block)
6937 TCU_FAIL("Not implemented");
6941 buffer.SubData(variable.m_descriptor.m_offset, variable.m_descriptor.m_expected_stride_of_element * count,
6947 /** Basic implementation
6950 * @param si Shader interface
6951 * @param program Program
6952 * @param cs_buffer Buffer for uniform blocks
6954 void TextureTestBase::prepareUniforms(GLuint /* test_case_index */, Utils::ShaderInterface& si, Utils::Program& program,
6955 Utils::Buffer& buffer)
6957 /* Skip if there are no input variables in vertex shader */
6958 if (0 == si.m_uniforms.size())
6963 /* Calculate vertex stride */
6964 GLint uniforms_stride = 0;
6966 for (GLuint i = 0; i < si.m_uniforms.size(); ++i)
6968 Utils::Variable& variable = *si.m_uniforms[i];
6970 if (false == variable.IsBlock())
6975 GLint variable_stride = variable.GetStride();
6977 GLint ends_at = variable_stride + variable.m_descriptor.m_offset;
6979 uniforms_stride = std::max(uniforms_stride, ends_at);
6982 /* Set active program */
6987 buffer.Data(Utils::Buffer::StaticDraw, uniforms_stride, 0);
6989 /* Set up uniforms */
6990 for (GLuint i = 0; i < si.m_uniforms.size(); ++i)
6992 Utils::Variable& variable = *si.m_uniforms[i];
6994 prepareUniform(program, variable, buffer);
6998 /** Basic implementation
7000 * @param test_case_index Test case index
7001 * @param program_interface Program interface
7002 * @param program Program
7003 * @param cs_buffer Buffer for compute shader stage
7005 void TextureTestBase::prepareUniforms(GLuint test_case_index, Utils::ProgramInterface& program_interface,
7006 Utils::Program& program, Utils::Buffer& cs_buffer)
7008 cs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7010 Utils::ShaderInterface& cs = program_interface.GetShaderInterface(Utils::Shader::COMPUTE);
7012 prepareUniforms(test_case_index, cs, program, cs_buffer);
7014 cs_buffer.BindBase(Utils::Shader::COMPUTE);
7017 /** Basic implementation
7019 * @param test_case_index Test case index
7020 * @param program_interface Program interface
7021 * @param program Program
7022 * @param fs_buffer Buffer for fragment shader stage
7023 * @param gs_buffer Buffer for geometry shader stage
7024 * @param tcs_buffer Buffer for tesselation control shader stage
7025 * @param tes_buffer Buffer for tesselation evaluation shader stage
7026 * @param vs_buffer Buffer for vertex shader stage
7028 void TextureTestBase::prepareUniforms(GLuint test_case_index, Utils::ProgramInterface& program_interface,
7029 Utils::Program& program, Utils::Buffer& fs_buffer, Utils::Buffer& gs_buffer,
7030 Utils::Buffer& tcs_buffer, Utils::Buffer& tes_buffer, Utils::Buffer& vs_buffer)
7032 fs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7033 gs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7034 tcs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7035 tes_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7036 vs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7038 Utils::ShaderInterface& fs = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
7039 Utils::ShaderInterface& gs = program_interface.GetShaderInterface(Utils::Shader::GEOMETRY);
7040 Utils::ShaderInterface& tcs = program_interface.GetShaderInterface(Utils::Shader::TESS_CTRL);
7041 Utils::ShaderInterface& tes = program_interface.GetShaderInterface(Utils::Shader::TESS_EVAL);
7042 Utils::ShaderInterface& vs = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
7044 prepareUniforms(test_case_index, fs, program, fs_buffer);
7045 prepareUniforms(test_case_index, gs, program, gs_buffer);
7046 prepareUniforms(test_case_index, tcs, program, tcs_buffer);
7047 prepareUniforms(test_case_index, tes, program, tes_buffer);
7048 prepareUniforms(test_case_index, vs, program, vs_buffer);
7050 fs_buffer.BindBase(Utils::Shader::FRAGMENT);
7051 gs_buffer.BindBase(Utils::Shader::GEOMETRY);
7052 tcs_buffer.BindBase(Utils::Shader::TESS_CTRL);
7053 tes_buffer.BindBase(Utils::Shader::TESS_EVAL);
7054 vs_buffer.BindBase(Utils::Shader::VERTEX);
7057 /** Basic implementation
7059 * @param test_case_index Test case index
7060 * @param program_interface Program interface
7061 * @param program Program
7062 * @param fs_buffer Buffer for fragment shader stage
7063 * @param gs_buffer Buffer for geometry shader stage
7064 * @param tcs_buffer Buffer for tesselation control shader stage
7065 * @param tes_buffer Buffer for tesselation evaluation shader stage
7066 * @param vs_buffer Buffer for vertex shader stage
7068 void TextureTestBase::prepareUniforms(GLuint test_case_index, Utils::ProgramInterface& program_interface,
7069 Utils::Program& fs_program, Utils::Program& gs_program,
7070 Utils::Program& tcs_program, Utils::Program& tes_program,
7071 Utils::Program& vs_program, Utils::Buffer& fs_buffer, Utils::Buffer& gs_buffer,
7072 Utils::Buffer& tcs_buffer, Utils::Buffer& tes_buffer, Utils::Buffer& vs_buffer)
7074 fs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7075 gs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7076 tcs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7077 tes_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7078 vs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7080 Utils::ShaderInterface& fs = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
7081 Utils::ShaderInterface& gs = program_interface.GetShaderInterface(Utils::Shader::GEOMETRY);
7082 Utils::ShaderInterface& tcs = program_interface.GetShaderInterface(Utils::Shader::TESS_CTRL);
7083 Utils::ShaderInterface& tes = program_interface.GetShaderInterface(Utils::Shader::TESS_EVAL);
7084 Utils::ShaderInterface& vs = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
7086 prepareUniforms(test_case_index, fs, fs_program, fs_buffer);
7087 fs_buffer.BindBase(Utils::Shader::FRAGMENT);
7089 prepareUniforms(test_case_index, gs, gs_program, gs_buffer);
7090 gs_buffer.BindBase(Utils::Shader::GEOMETRY);
7092 prepareUniforms(test_case_index, tcs, tcs_program, tcs_buffer);
7093 tcs_buffer.BindBase(Utils::Shader::TESS_CTRL);
7095 prepareUniforms(test_case_index, tes, tes_program, tes_buffer);
7096 tes_buffer.BindBase(Utils::Shader::TESS_EVAL);
7098 prepareUniforms(test_case_index, vs, vs_program, vs_buffer);
7099 vs_buffer.BindBase(Utils::Shader::VERTEX);
7102 /** Prepare source for shader
7104 * @param test_case_index Index of test case
7105 * @param program_interface Interface of program
7106 * @param varying_passthrough Collection of connection between in and out variables
7107 * @param stage Shader stage
7109 * @return Source of shader
7111 std::string TextureTestBase::getShaderSource(GLuint test_case_index, Utils::ProgramInterface& program_interface,
7112 Utils::VaryingPassthrough& varying_passthrough,
7113 Utils::Shader::STAGES stage)
7116 const GLchar* shader_template = getShaderTemplate(stage);
7117 const std::string& shader_interface = program_interface.GetInterfaceForStage(stage);
7119 const std::string& verification = getVerificationSnippet(test_case_index, program_interface, stage);
7121 const std::string& passthrough = getPassSnippet(test_case_index, varying_passthrough, stage);
7123 const GLchar* per_vertex = "";
7125 std::string source = shader_template;
7126 size_t position = 0;
7128 /* Replace tokens in template */
7129 if (Utils::Shader::GEOMETRY == stage)
7131 if (false == useMonolithicProgram(test_case_index))
7133 per_vertex = "out gl_PerVertex {\n"
7134 "vec4 gl_Position;\n"
7139 Utils::replaceToken("PERVERTEX", position, per_vertex, source);
7142 Utils::replaceToken("INTERFACE", position, shader_interface.c_str(), source);
7143 Utils::replaceToken("VERIFICATION", position, verification.c_str(), source);
7145 if (false == verification.empty())
7147 Utils::replaceAllTokens("ELSE", " else ", source);
7151 Utils::replaceAllTokens("ELSE", "", source);
7154 Utils::replaceAllTokens("PASSTHROUGH", passthrough.c_str(), source);
7160 /** Returns template of shader for given stage
7162 * @param stage Shade stage
7164 * @return Proper template
7166 const GLchar* TextureTestBase::getShaderTemplate(Utils::Shader::STAGES stage)
7169 static const GLchar* compute_shader_template =
7170 "#version 430 core\n"
7171 "#extension GL_ARB_enhanced_layouts : require\n"
7173 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
7175 "writeonly uniform uimage2D uni_image;\n"
7181 " uint result = 1u;\n"
7185 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), uvec4(result, 0, 0, 0));\n"
7189 static const GLchar* fragment_shader_template = "#version 430 core\n"
7190 "#extension GL_ARB_enhanced_layouts : require\n"
7192 "flat in uint gs_fs_result;\n"
7193 " out uint fs_out_result;\n"
7199 " uint result = 1u;\n"
7201 " if (1u != gs_fs_result)\n"
7203 " result = gs_fs_result;\n"
7207 " fs_out_result = result;\n"
7212 static const GLchar* geometry_shader_template =
7213 "#version 430 core\n"
7214 "#extension GL_ARB_enhanced_layouts : require\n"
7216 "layout(points) in;\n"
7217 "layout(triangle_strip, max_vertices = 4) out;\n"
7219 " in uint tes_gs_result[];\n"
7220 "flat out uint gs_fs_result;\n"
7222 "PERVERTEX" /* Separable programs require explicit declaration of gl_PerVertex */
7227 " uint result = 1u;\n"
7229 " if (1u != tes_gs_result[0])\n"
7231 " result = tes_gs_result[0];\n"
7235 " gs_fs_result = result;\n"
7237 " gl_Position = vec4(-1, -1, 0, 1);\n"
7239 " gs_fs_result = result;\n"
7241 " gl_Position = vec4(-1, 1, 0, 1);\n"
7243 " gs_fs_result = result;\n"
7245 " gl_Position = vec4(1, -1, 0, 1);\n"
7247 " gs_fs_result = result;\n"
7249 " gl_Position = vec4(1, 1, 0, 1);\n"
7254 static const GLchar* tess_ctrl_shader_template = "#version 430 core\n"
7255 "#extension GL_ARB_enhanced_layouts : require\n"
7257 "layout(vertices = 1) out;\n"
7259 "in uint vs_tcs_result[];\n"
7260 "out uint tcs_tes_result[];\n"
7266 " uint result = 1u;\n"
7268 " if (1u != vs_tcs_result[gl_InvocationID])\n"
7270 " result = vs_tcs_result[gl_InvocationID];\n"
7274 " tcs_tes_result[gl_InvocationID] = result;\n"
7278 " gl_TessLevelOuter[0] = 1.0;\n"
7279 " gl_TessLevelOuter[1] = 1.0;\n"
7280 " gl_TessLevelOuter[2] = 1.0;\n"
7281 " gl_TessLevelOuter[3] = 1.0;\n"
7282 " gl_TessLevelInner[0] = 1.0;\n"
7283 " gl_TessLevelInner[1] = 1.0;\n"
7287 static const GLchar* tess_eval_shader_template = "#version 430 core\n"
7288 "#extension GL_ARB_enhanced_layouts : require\n"
7290 "layout(isolines, point_mode) in;\n"
7292 "in uint tcs_tes_result[];\n"
7293 "out uint tes_gs_result;\n"
7299 " uint result = 1u;\n"
7301 " if (1 != tcs_tes_result[0])\n"
7303 " result = tcs_tes_result[0];\n"
7307 " tes_gs_result = result;\n"
7313 static const GLchar* vertex_shader_template = "#version 430 core\n"
7314 "#extension GL_ARB_enhanced_layouts : require\n"
7316 "out uint vs_tcs_result;\n"
7322 " uint result = 1u;\n"
7326 " vs_tcs_result = result;\n"
7332 const GLchar* result = 0;
7336 case Utils::Shader::COMPUTE:
7337 result = compute_shader_template;
7339 case Utils::Shader::FRAGMENT:
7340 result = fragment_shader_template;
7342 case Utils::Shader::GEOMETRY:
7343 result = geometry_shader_template;
7345 case Utils::Shader::TESS_CTRL:
7346 result = tess_ctrl_shader_template;
7348 case Utils::Shader::TESS_EVAL:
7349 result = tess_eval_shader_template;
7351 case Utils::Shader::VERTEX:
7352 result = vertex_shader_template;
7355 TCU_FAIL("Invalid enum");
7363 * @param test_case_index Id of test case
7365 * @return true if test case pass, false otherwise
7367 bool TextureTestBase::testCase(GLuint test_case_index)
7371 if (true == useMonolithicProgram(test_case_index))
7373 return testMonolithic(test_case_index);
7377 return testSeparable(test_case_index);
7380 catch (Utils::Shader::InvalidSourceException& exc)
7383 TCU_FAIL(exc.what());
7385 catch (Utils::Program::BuildException& exc)
7387 TCU_FAIL(exc.what());
7391 /** Runs "draw" test with monolithic program
7393 * @param test_case_index Id of test case
7395 bool TextureTestBase::testMonolithic(GLuint test_case_index)
7397 Utils::ProgramInterface program_interface;
7398 Utils::VaryingPassthrough varying_passthrough;
7401 const std::string& test_name = getTestCaseName(test_case_index);
7404 getProgramInterface(test_case_index, program_interface, varying_passthrough);
7408 if (true == isDrawRelevant(test_case_index))
7410 Utils::Buffer buffer_attr(m_context);
7411 Utils::Buffer buffer_ssb_fs(m_context);
7412 Utils::Buffer buffer_ssb_gs(m_context);
7413 Utils::Buffer buffer_ssb_tcs(m_context);
7414 Utils::Buffer buffer_ssb_tes(m_context);
7415 Utils::Buffer buffer_ssb_vs(m_context);
7416 Utils::Buffer buffer_u_fs(m_context);
7417 Utils::Buffer buffer_u_gs(m_context);
7418 Utils::Buffer buffer_u_tcs(m_context);
7419 Utils::Buffer buffer_u_tes(m_context);
7420 Utils::Buffer buffer_u_vs(m_context);
7421 Utils::Framebuffer framebuffer(m_context);
7422 Utils::Program program(m_context);
7423 Utils::Texture texture_fb(m_context);
7424 Utils::VertexArray vao(m_context);
7427 const std::string& fragment_shader =
7428 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::FRAGMENT);
7429 const std::string& geometry_shader =
7430 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::GEOMETRY);
7431 const std::string& tess_ctrl_shader =
7432 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::TESS_CTRL);
7433 const std::string& tess_eval_shader =
7434 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::TESS_EVAL);
7435 const std::string& vertex_shader =
7436 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::VERTEX);
7438 program.Init("" /* compute_shader */, fragment_shader, geometry_shader, tess_ctrl_shader, tess_eval_shader,
7439 vertex_shader, false /* is_separable */);
7442 prepareAttribLocation(program, program_interface);
7443 prepareFragmentDataLoc(program, program_interface);
7446 std::stringstream stream;
7447 if (false == Utils::checkMonolithicDrawProgramInterface(program, program_interface, stream))
7449 m_context.getTestContext().getLog()
7450 << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7451 << ". Inspection of draw program interface failed:\n"
7452 << stream.str() << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(vertex_shader)
7453 << tcu::TestLog::KernelSource(tess_ctrl_shader) << tcu::TestLog::KernelSource(tess_eval_shader)
7454 << tcu::TestLog::KernelSource(geometry_shader) << tcu::TestLog::KernelSource(fragment_shader);
7463 buffer_attr.Init(Utils::Buffer::Array, Utils::Buffer::StaticDraw, 0, 0);
7465 prepareAttributes(test_case_index, program_interface, buffer_attr, vao);
7468 prepareUniforms(test_case_index, program_interface, program, buffer_u_fs, buffer_u_gs, buffer_u_tcs,
7469 buffer_u_tes, buffer_u_vs);
7471 prepareSSBs(test_case_index, program_interface, program, buffer_ssb_fs, buffer_ssb_gs, buffer_ssb_tcs,
7472 buffer_ssb_tes, buffer_ssb_vs);
7475 prepareFramebuffer(framebuffer, texture_fb);
7478 executeDrawCall(test_case_index);
7481 m_context.getRenderContext().postIterate();
7485 if (false == checkResults(test_case_index, texture_fb))
7487 m_context.getTestContext().getLog()
7488 << tcu::TestLog::Message << "FAILURE. Test case: " << test_name << ". Draw - invalid results."
7489 << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(vertex_shader)
7490 << tcu::TestLog::KernelSource(tess_ctrl_shader) << tcu::TestLog::KernelSource(tess_eval_shader)
7491 << tcu::TestLog::KernelSource(geometry_shader) << tcu::TestLog::KernelSource(fragment_shader);
7498 if (true == isComputeRelevant(test_case_index))
7500 Utils::Buffer buffer_ssb_cs(m_context);
7501 Utils::Buffer buffer_u_cs(m_context);
7502 Utils::Program program(m_context);
7503 Utils::Texture texture_im(m_context);
7504 Utils::VertexArray vao(m_context);
7507 const std::string& compute_shader =
7508 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::COMPUTE);
7510 program.Init(compute_shader, "" /* fragment_shader */, "" /* geometry_shader */, "" /* tess_ctrl_shader */,
7511 "" /* tess_eval_shader */, "" /* vertex_shader */, false /* is_separable */);
7515 std::stringstream stream;
7517 if (false == Utils::checkMonolithicComputeProgramInterface(program, program_interface, stream))
7519 m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7520 << ". Inspection of compute program interface failed:\n"
7521 << stream.str() << tcu::TestLog::EndMessage;
7535 prepareUniforms(test_case_index, program_interface, program, buffer_u_cs);
7537 prepareSSBs(test_case_index, program_interface, program, buffer_ssb_cs);
7540 GLint image_location = program.GetUniformLocation("uni_image");
7541 prepareImage(image_location, texture_im);
7544 executeDispatchCall(test_case_index);
7547 m_context.getRenderContext().postIterate();
7551 if (false == checkResults(test_case_index, texture_im))
7553 m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7554 << ". Compute - invalid results." << tcu::TestLog::EndMessage
7555 << tcu::TestLog::KernelSource(compute_shader);
7564 /** Runs "draw" test with separable program
7566 * @param test_case_index Id of test case
7568 bool TextureTestBase::testSeparable(GLuint test_case_index)
7570 Utils::ProgramInterface program_interface;
7571 Utils::VaryingPassthrough varying_passthrough;
7574 const std::string& test_name = getTestCaseName(test_case_index);
7577 getProgramInterface(test_case_index, program_interface, varying_passthrough);
7581 if (true == isDrawRelevant(test_case_index))
7583 Utils::Buffer buffer_attr(m_context);
7584 Utils::Buffer buffer_u_fs(m_context);
7585 Utils::Buffer buffer_u_gs(m_context);
7586 Utils::Buffer buffer_u_tcs(m_context);
7587 Utils::Buffer buffer_u_tes(m_context);
7588 Utils::Buffer buffer_u_vs(m_context);
7589 Utils::Framebuffer framebuffer(m_context);
7590 Utils::Pipeline pipeline(m_context);
7591 Utils::Program program_fs(m_context);
7592 Utils::Program program_gs(m_context);
7593 Utils::Program program_tcs(m_context);
7594 Utils::Program program_tes(m_context);
7595 Utils::Program program_vs(m_context);
7596 Utils::Texture texture_fb(m_context);
7597 Utils::VertexArray vao(m_context);
7600 const std::string& fs =
7601 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::FRAGMENT);
7602 const std::string& gs =
7603 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::GEOMETRY);
7604 const std::string& tcs =
7605 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::TESS_CTRL);
7606 const std::string& tes =
7607 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::TESS_EVAL);
7608 const std::string& vs =
7609 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::VERTEX);
7611 program_fs.Init("" /*cs*/, fs, "" /*gs*/, "" /*tcs*/, "" /*tes*/, "" /*vs*/, true /* is_separable */);
7612 program_gs.Init("" /*cs*/, "" /*fs*/, gs, "" /*tcs*/, "" /*tes*/, "" /*vs*/, true /* is_separable */);
7613 program_tcs.Init("" /*cs*/, "" /*fs*/, "" /*gs*/, tcs, "" /*tes*/, "" /*vs*/, true /* is_separable */);
7614 program_tes.Init("" /*cs*/, "" /*fs*/, "" /*gs*/, "" /*tcs*/, tes, "" /*vs*/, true /* is_separable */);
7615 program_vs.Init("" /*cs*/, "" /*fs*/, "" /*gs*/, "" /*tcs*/, "" /*tes*/, vs, true /* is_separable */);
7618 prepareAttribLocation(program_vs, program_interface);
7619 prepareFragmentDataLoc(program_vs, program_interface);
7622 std::stringstream stream;
7624 Utils::checkSeparableDrawProgramInterface(program_vs, program_interface, Utils::Shader::VERTEX, stream)) ||
7625 (false == Utils::checkSeparableDrawProgramInterface(program_fs, program_interface, Utils::Shader::FRAGMENT,
7627 (false == Utils::checkSeparableDrawProgramInterface(program_gs, program_interface, Utils::Shader::GEOMETRY,
7629 (false == Utils::checkSeparableDrawProgramInterface(program_tcs, program_interface,
7630 Utils::Shader::TESS_CTRL, stream)) ||
7631 (false == Utils::checkSeparableDrawProgramInterface(program_tes, program_interface,
7632 Utils::Shader::TESS_EVAL, stream)))
7634 m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7635 << ". Inspection of separable draw program interface failed:\n"
7636 << stream.str() << tcu::TestLog::EndMessage
7637 << tcu::TestLog::KernelSource(vs) << tcu::TestLog::KernelSource(tcs)
7638 << tcu::TestLog::KernelSource(tes) << tcu::TestLog::KernelSource(gs)
7639 << tcu::TestLog::KernelSource(fs);
7646 pipeline.UseProgramStages(program_fs.m_id, GL_FRAGMENT_SHADER_BIT);
7647 pipeline.UseProgramStages(program_gs.m_id, GL_GEOMETRY_SHADER_BIT);
7648 pipeline.UseProgramStages(program_tcs.m_id, GL_TESS_CONTROL_SHADER_BIT);
7649 pipeline.UseProgramStages(program_tes.m_id, GL_TESS_EVALUATION_SHADER_BIT);
7650 pipeline.UseProgramStages(program_vs.m_id, GL_VERTEX_SHADER_BIT);
7655 buffer_attr.Init(Utils::Buffer::Array, Utils::Buffer::StaticDraw, 0, 0);
7657 prepareAttributes(test_case_index, program_interface, buffer_attr, vao);
7660 prepareUniforms(test_case_index, program_interface, program_fs, program_gs, program_tcs, program_tes,
7661 program_vs, buffer_u_fs, buffer_u_gs, buffer_u_tcs, buffer_u_tes, buffer_u_vs);
7663 Utils::Program::Use(m_context.getRenderContext().getFunctions(), Utils::Program::m_invalid_id);
7666 prepareFramebuffer(framebuffer, texture_fb);
7669 executeDrawCall(test_case_index);
7672 m_context.getRenderContext().postIterate();
7676 if (false == checkResults(test_case_index, texture_fb))
7678 m_context.getTestContext().getLog()
7679 << tcu::TestLog::Message << "FAILURE. Test case: " << test_name << ". Draw - invalid results."
7680 << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(vs) << tcu::TestLog::KernelSource(tcs)
7681 << tcu::TestLog::KernelSource(tes) << tcu::TestLog::KernelSource(gs) << tcu::TestLog::KernelSource(fs);
7688 if (true == isComputeRelevant(test_case_index))
7690 Utils::Buffer buffer_u_cs(m_context);
7691 Utils::Program program(m_context);
7692 Utils::Texture texture_im(m_context);
7693 Utils::VertexArray vao(m_context);
7696 const std::string& compute_shader =
7697 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::COMPUTE);
7699 program.Init(compute_shader, "" /* fragment_shader */, "" /* geometry_shader */, "" /* tess_ctrl_shader */,
7700 "" /* tess_eval_shader */, "" /* vertex_shader */, false /* is_separable */);
7704 std::stringstream stream;
7706 if (false == Utils::checkMonolithicComputeProgramInterface(program, program_interface, stream))
7708 m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7709 << ". Inspection of compute program interface failed:\n"
7710 << stream.str() << tcu::TestLog::EndMessage;
7724 prepareUniforms(test_case_index, program_interface, program, buffer_u_cs);
7727 GLint image_location = program.GetUniformLocation("uni_image");
7728 prepareImage(image_location, texture_im);
7731 executeDispatchCall(test_case_index);
7734 m_context.getRenderContext().postIterate();
7738 if (false == checkResults(test_case_index, texture_im))
7740 m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7741 << ". Compute - invalid results." << tcu::TestLog::EndMessage
7742 << tcu::TestLog::KernelSource(compute_shader);
7751 /** Basic implementation
7757 bool TextureTestBase::useComponentQualifier(glw::GLuint /* test_case_index */)
7762 /** Basic implementation
7768 bool TextureTestBase::useMonolithicProgram(GLuint /* test_case_index */)
7775 * @param context Test framework context
7777 APIConstantValuesTest::APIConstantValuesTest(deqp::Context& context)
7778 : TestCase(context, "api_constant_values", "Test verifies values of api constants")
7780 /* Nothing to be done here */
7785 * @return tcu::TestNode::STOP otherwise
7787 tcu::TestNode::IterateResult APIConstantValuesTest::iterate()
7789 static const GLuint expected_comp = 64;
7790 static const GLuint expected_xfb = 4;
7791 static const GLuint expected_sep = 4;
7795 bool test_result = true;
7797 const Functions& gl = m_context.getRenderContext().getFunctions();
7799 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_xfb);
7800 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
7801 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_comp);
7802 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
7803 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, &max_sep);
7804 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
7806 if (expected_xfb > (GLuint)max_xfb)
7808 m_context.getTestContext().getLog() << tcu::TestLog::Message
7809 << "Invalid GL_MAX_TRANSFORM_FEEDBACK_BUFFERS. Got " << max_xfb
7810 << " Expected at least " << expected_xfb << tcu::TestLog::EndMessage;
7812 test_result = false;
7815 if (expected_comp > (GLuint)max_comp)
7817 m_context.getTestContext().getLog()
7818 << tcu::TestLog::Message << "Invalid GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS. Got " << max_comp
7819 << " Expected at least " << expected_comp << tcu::TestLog::EndMessage;
7821 test_result = false;
7824 if (expected_sep > (GLuint)max_sep)
7826 m_context.getTestContext().getLog() << tcu::TestLog::Message
7827 << "Invalid GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS. Got " << max_comp
7828 << " Expected at least " << expected_comp << tcu::TestLog::EndMessage;
7830 test_result = false;
7834 if (true == test_result)
7836 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
7840 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
7844 return tcu::TestNode::STOP;
7849 * @param context Test framework context
7851 APIErrorsTest::APIErrorsTest(deqp::Context& context)
7852 : TestCase(context, "api_errors", "Test verifies errors reeturned by api")
7854 /* Nothing to be done here */
7859 * @return tcu::TestNode::STOP otherwise
7861 tcu::TestNode::IterateResult APIErrorsTest::iterate()
7866 Utils::Program program(m_context);
7867 bool test_result = true;
7869 const Functions& gl = m_context.getRenderContext().getFunctions();
7873 program.Init("" /* cs */, "#version 430 core\n"
7874 "#extension GL_ARB_enhanced_layouts : require\n"
7877 "out vec4 fs_out;\n"
7881 " fs_out = vs_fs;\n"
7884 "" /* gs */, "" /* tcs */, "" /* tes */, "#version 430 core\n"
7885 "#extension GL_ARB_enhanced_layouts : require\n"
7888 "layout (xfb_offset = 16) out vec4 vs_fs;\n"
7895 false /* separable */);
7897 catch (Utils::Shader::InvalidSourceException& exc)
7900 TCU_FAIL(exc.what());
7902 catch (Utils::Program::BuildException& exc)
7904 TCU_FAIL(exc.what());
7908 * - GetProgramInterfaceiv should generate INVALID_OPERATION when
7909 * <programInterface> is TRANSFORM_FEEDBACK_BUFFER and <pname> is one of the
7911 * * MAX_NAME_LENGTH,
7912 * * MAX_NUM_ACTIVE_VARIABLES;
7914 gl.getProgramInterfaceiv(program.m_id, GL_TRANSFORM_FEEDBACK_BUFFER, GL_MAX_NAME_LENGTH, ¶m);
7915 checkError(GL_INVALID_OPERATION, "GetProgramInterfaceiv(GL_TRANSFORM_FEEDBACK_BUFFER, GL_MAX_NAME_LENGTH)",
7919 * - GetProgramResourceIndex should generate INVALID_ENUM when
7920 * <programInterface> is TRANSFORM_FEEDBACK_BUFFER;
7922 gl.getProgramResourceIndex(program.m_id, GL_TRANSFORM_FEEDBACK_BUFFER, "0");
7923 checkError(GL_INVALID_ENUM, "GetProgramResourceIndex(GL_TRANSFORM_FEEDBACK_BUFFER)", test_result);
7925 * - GetProgramResourceName should generate INVALID_ENUM when
7926 * <programInterface> is TRANSFORM_FEEDBACK_BUFFER;
7928 gl.getProgramResourceName(program.m_id, GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, 64 /* bufSize */, &length,
7930 checkError(GL_INVALID_ENUM, "GetProgramResourceName(GL_TRANSFORM_FEEDBACK_BUFFER)", test_result);
7933 if (true == test_result)
7935 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
7939 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
7943 return tcu::TestNode::STOP;
7946 /** Check if error is the expected one.
7948 * @param expected_error Expected error
7949 * @param message Message to log in case of error
7950 * @param test_result Test result, set to false in case of invalid error
7952 void APIErrorsTest::checkError(GLenum expected_error, const GLchar* message, bool& test_result)
7954 const Functions& gl = m_context.getRenderContext().getFunctions();
7956 GLenum error = gl.getError();
7958 if (error != expected_error)
7960 m_context.getTestContext().getLog()
7961 << tcu::TestLog::Message << "Failure. Invalid error. Got " << glu::getErrorStr(error) << " expected "
7962 << glu::getErrorStr(expected_error) << " Msg: " << message << tcu::TestLog::EndMessage;
7964 test_result = false;
7970 * @param context Test framework context
7972 GLSLContantImmutablityTest::GLSLContantImmutablityTest(deqp::Context& context)
7973 : NegativeTestBase(context, "glsl_contant_immutablity", "Test verifies that glsl constants cannot be modified")
7975 /* Nothing to be done here */
7978 /** Source for given test case and stage
7980 * @param test_case_index Index of test case
7981 * @param stage Shader stage
7983 * @return Shader source
7985 std::string GLSLContantImmutablityTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
7987 static const GLchar* cs = "#version 430 core\n"
7988 "#extension GL_ARB_enhanced_layouts : require\n"
7990 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
7992 "writeonly uniform uimage2D uni_image;\n"
7996 " uint result = 1u;\n"
7999 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), uvec4(result, 0, 0, 0));\n"
8002 static const GLchar* fs = "#version 430 core\n"
8003 "#extension GL_ARB_enhanced_layouts : require\n"
8006 "out vec4 fs_out;\n"
8011 " fs_out = gs_fs;\n"
8014 static const GLchar* gs = "#version 430 core\n"
8015 "#extension GL_ARB_enhanced_layouts : require\n"
8017 "layout(points) in;\n"
8018 "layout(triangle_strip, max_vertices = 4) out;\n"
8020 "in vec4 tes_gs[];\n"
8026 " gs_fs = tes_gs[0];\n"
8027 " gl_Position = vec4(-1, -1, 0, 1);\n"
8029 " gs_fs = tes_gs[0];\n"
8030 " gl_Position = vec4(-1, 1, 0, 1);\n"
8032 " gs_fs = tes_gs[0];\n"
8033 " gl_Position = vec4(1, -1, 0, 1);\n"
8035 " gs_fs = tes_gs[0];\n"
8036 " gl_Position = vec4(1, 1, 0, 1);\n"
8040 static const GLchar* tcs = "#version 430 core\n"
8041 "#extension GL_ARB_enhanced_layouts : require\n"
8043 "layout(vertices = 1) out;\n"
8045 "in vec4 vs_tcs[];\n"
8046 "out vec4 tcs_tes[];\n"
8052 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
8054 " gl_TessLevelOuter[0] = 1.0;\n"
8055 " gl_TessLevelOuter[1] = 1.0;\n"
8056 " gl_TessLevelOuter[2] = 1.0;\n"
8057 " gl_TessLevelOuter[3] = 1.0;\n"
8058 " gl_TessLevelInner[0] = 1.0;\n"
8059 " gl_TessLevelInner[1] = 1.0;\n"
8062 static const GLchar* tes = "#version 430 core\n"
8063 "#extension GL_ARB_enhanced_layouts : require\n"
8065 "layout(isolines, point_mode) in;\n"
8067 "in vec4 tcs_tes[];\n"
8068 "out vec4 tes_gs;\n"
8073 " tes_gs = tcs_tes[0];\n"
8076 static const GLchar* vs = "#version 430 core\n"
8077 "#extension GL_ARB_enhanced_layouts : require\n"
8080 "out vec4 vs_tcs;\n"
8085 " vs_tcs = in_vs;\n"
8090 testCase& test_case = m_test_cases[test_case_index];
8092 if (Utils::Shader::COMPUTE == test_case.m_stage)
8094 size_t position = 0;
8098 Utils::replaceToken("CONSTANT", position, getConstantName(test_case.m_constant), source);
8102 std::string assignment = " CONSTANT = 3;\n";
8103 size_t position = 0;
8107 case Utils::Shader::FRAGMENT:
8110 case Utils::Shader::GEOMETRY:
8113 case Utils::Shader::TESS_CTRL:
8116 case Utils::Shader::TESS_EVAL:
8119 case Utils::Shader::VERTEX:
8123 TCU_FAIL("Invalid enum");
8126 if (test_case.m_stage == stage)
8128 Utils::replaceToken("CONSTANT", position, getConstantName(test_case.m_constant), assignment);
8136 Utils::replaceToken("ASSIGNMENT", position, assignment.c_str(), source);
8142 /** Get description of test case
8144 * @param test_case_index Index of test case
8146 * @return Constant name
8148 std::string GLSLContantImmutablityTest::getTestCaseName(GLuint test_case_index)
8150 std::string result = getConstantName(m_test_cases[test_case_index].m_constant);
8155 /** Get number of test cases
8157 * @return Number of test cases
8159 GLuint GLSLContantImmutablityTest::getTestCaseNumber()
8161 return static_cast<GLuint>(m_test_cases.size());
8164 /** Selects if "compute" stage is relevant for test
8166 * @param test_case_index Index of test case
8168 * @return true when tested stage is compute
8170 bool GLSLContantImmutablityTest::isComputeRelevant(GLuint test_case_index)
8172 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
8175 /** Prepare all test cases
8178 void GLSLContantImmutablityTest::testInit()
8180 for (GLuint constant = 0; constant < CONSTANTS_MAX; ++constant)
8182 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
8184 testCase test_case = { (CONSTANTS)constant, (Utils::Shader::STAGES)stage };
8186 m_test_cases.push_back(test_case);
8191 /** Get name of glsl constant
8193 * @param Constant id
8195 * @return Name of constant used in GLSL
8197 const GLchar* GLSLContantImmutablityTest::getConstantName(CONSTANTS constant)
8199 const GLchar* name = "";
8203 case GL_ARB_ENHANCED_LAYOUTS:
8204 name = "GL_ARB_enhanced_layouts";
8207 name = "gl_MaxTransformFeedbackBuffers";
8209 case GL_MAX_XFB_INT_COMP:
8210 name = "gl_MaxTransformFeedbackInterleavedComponents";
8213 TCU_FAIL("Invalid enum");
8221 * @param context Test framework context
8223 GLSLContantValuesTest::GLSLContantValuesTest(deqp::Context& context)
8224 : TextureTestBase(context, "glsl_contant_values", "Test verifies values of constant symbols")
8228 /** Selects if "compute" stage is relevant for test
8234 bool GLSLContantValuesTest::isComputeRelevant(GLuint /* test_case_index */)
8239 /** Prepare code snippet that will verify in and uniform variables
8243 * @param stage Shader stage
8245 * @return Code that verify variables
8247 std::string GLSLContantValuesTest::getVerificationSnippet(GLuint /* test_case_index */,
8248 Utils::ProgramInterface& /* program_interface */,
8249 Utils::Shader::STAGES stage)
8252 const Functions& gl = m_context.getRenderContext().getFunctions();
8254 GLint max_transform_feedback_buffers = 0;
8255 GLint max_transform_feedback_interleaved_components = 0;
8257 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_transform_feedback_buffers);
8258 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8259 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_transform_feedback_interleaved_components);
8260 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8262 std::string verification;
8264 if (Utils::Shader::VERTEX == stage)
8266 verification = "if (1 != GL_ARB_enhanced_layouts)\n"
8270 " else if (MAX_TRANSFORM_FEEDBACK_BUFFERS\n"
8271 " != gl_MaxTransformFeedbackBuffers)\n"
8275 " else if (MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS \n"
8276 " != gl_MaxTransformFeedbackInterleavedComponents)\n"
8281 size_t position = 0;
8284 sprintf(buffer, "%d", max_transform_feedback_buffers);
8285 Utils::replaceToken("MAX_TRANSFORM_FEEDBACK_BUFFERS", position, buffer, verification);
8287 sprintf(buffer, "%d", max_transform_feedback_interleaved_components);
8288 Utils::replaceToken("MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS", position, buffer, verification);
8295 return verification;
8300 * @param context Test framework context
8302 GLSLConstantIntegralExpressionTest::GLSLConstantIntegralExpressionTest(deqp::Context& context)
8303 : TextureTestBase(context, "glsl_constant_integral_expression",
8304 "Test verifies that symbols can be used as constant integral expressions")
8308 /** Get interface of program
8311 * @param program_interface Interface of program
8314 void GLSLConstantIntegralExpressionTest::getProgramInterface(GLuint /* test_case_index */,
8315 Utils::ProgramInterface& program_interface,
8316 Utils::VaryingPassthrough& /* varying_passthrough */)
8319 const Functions& gl = m_context.getRenderContext().getFunctions();
8321 GLint max_transform_feedback_buffers = 0;
8322 GLint max_transform_feedback_interleaved_components = 0;
8324 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_transform_feedback_buffers);
8325 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8326 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_transform_feedback_interleaved_components);
8327 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8329 GLuint gohan_div = std::max(1, max_transform_feedback_buffers / 16);
8330 GLuint goten_div = std::max(1, max_transform_feedback_interleaved_components / 16);
8332 m_gohan_length = max_transform_feedback_buffers / gohan_div;
8333 m_goten_length = max_transform_feedback_interleaved_components / goten_div;
8336 std::string globals = "uniform uint goku [GL_ARB_enhanced_layouts / 1];\n"
8337 "uniform uint gohan[gl_MaxTransformFeedbackBuffers / GOHAN_DIV];\n"
8338 "uniform uint goten[gl_MaxTransformFeedbackInterleavedComponents / GOTEN_DIV];\n";
8340 size_t position = 0;
8343 sprintf(buffer, "%d", gohan_div);
8344 Utils::replaceToken("GOHAN_DIV", position, buffer, globals);
8346 sprintf(buffer, "%d", goten_div);
8347 Utils::replaceToken("GOTEN_DIV", position, buffer, globals);
8349 program_interface.m_vertex.m_globals = globals;
8350 program_interface.m_tess_ctrl.m_globals = globals;
8351 program_interface.m_tess_eval.m_globals = globals;
8352 program_interface.m_geometry.m_globals = globals;
8353 program_interface.m_fragment.m_globals = globals;
8354 program_interface.m_compute.m_globals = globals;
8357 /** Prepare code snippet that will verify in and uniform variables
8363 * @return Code that verify variables
8365 std::string GLSLConstantIntegralExpressionTest::getVerificationSnippet(GLuint /* test_case_index */,
8366 Utils::ProgramInterface& /* program_interface */,
8367 Utils::Shader::STAGES /* stage */)
8369 std::string verification = "{\n"
8370 " uint goku_sum = 0;\n"
8371 " uint gohan_sum = 0;\n"
8372 " uint goten_sum = 0;\n"
8374 " for (uint i = 0u; i < goku.length(); ++i)\n"
8376 " goku_sum += goku[i];\n"
8379 " for (uint i = 0u; i < gohan.length(); ++i)\n"
8381 " gohan_sum += gohan[i];\n"
8384 " for (uint i = 0u; i < goten.length(); ++i)\n"
8386 " goten_sum += goten[i];\n"
8389 " if ( (1u != goku_sum) &&\n"
8390 " (EXPECTED_GOHAN_SUMu != gohan_sum) ||\n"
8391 " (EXPECTED_GOTEN_SUMu != goten_sum) )\n"
8397 size_t position = 0;
8400 sprintf(buffer, "%d", m_gohan_length);
8401 Utils::replaceToken("EXPECTED_GOHAN_SUM", position, buffer, verification);
8403 sprintf(buffer, "%d", m_goten_length);
8404 Utils::replaceToken("EXPECTED_GOTEN_SUM", position, buffer, verification);
8406 return verification;
8409 /** Prepare unifroms
8413 * @param program Program object
8416 void GLSLConstantIntegralExpressionTest::prepareUniforms(GLuint /* test_case_index */,
8417 Utils::ProgramInterface& /* program_interface */,
8418 Utils::Program& program, Utils::Buffer& /* cs_buffer */)
8420 static const GLuint uniform_data[16] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
8422 const Functions& gl = m_context.getRenderContext().getFunctions();
8424 GLint goku_location = program.GetUniformLocation("goku");
8425 GLint gohan_location = program.GetUniformLocation("gohan");
8426 GLint goten_location = program.GetUniformLocation("goten");
8428 program.Uniform(gl, Utils::Type::uint, 1 /* count */, goku_location, uniform_data);
8429 program.Uniform(gl, Utils::Type::uint, m_gohan_length, gohan_location, uniform_data);
8430 program.Uniform(gl, Utils::Type::uint, m_goten_length, goten_location, uniform_data);
8433 /** Prepare unifroms
8435 * @param test_case_index Pass as param to first implemetnation
8436 * @param program_interface Pass as param to first implemetnation
8437 * @param program Pass as param to first implemetnation
8442 * @param vs_buffer Pass as param to first implemetnation
8444 void GLSLConstantIntegralExpressionTest::prepareUniforms(GLuint test_case_index,
8445 Utils::ProgramInterface& program_interface,
8446 Utils::Program& program, Utils::Buffer& /* fs_buffer */,
8447 Utils::Buffer& /* gs_buffer */,
8448 Utils::Buffer& /* tcs_buffer */,
8449 Utils::Buffer& /* tes_buffer */, Utils::Buffer& vs_buffer)
8451 /* Call first implementation */
8452 prepareUniforms(test_case_index, program_interface, program, vs_buffer);
8457 * @param context Test framework context
8459 UniformBlockMemberOffsetAndAlignTest::UniformBlockMemberOffsetAndAlignTest(deqp::Context& context)
8460 : TextureTestBase(context, "uniform_block_member_offset_and_align",
8461 "Test verifies offsets and alignment of uniform buffer members")
8465 /** Get interface of program
8467 * @param test_case_index Test case index
8468 * @param program_interface Interface of program
8469 * @param varying_passthrough Collection of connections between in and out variables
8471 void UniformBlockMemberOffsetAndAlignTest::getProgramInterface(GLuint test_case_index,
8472 Utils::ProgramInterface& program_interface,
8473 Utils::VaryingPassthrough& varying_passthrough)
8475 std::string globals = "const int basic_size = BASIC_SIZE;\n"
8476 "const int type_align = TYPE_ALIGN;\n"
8477 "const int type_size = TYPE_SIZE;\n";
8479 Utils::Type type = getType(test_case_index);
8480 GLuint basic_size = Utils::Type::GetTypeSize(type.m_basic_type);
8481 const GLuint base_align = type.GetBaseAlignment(false);
8482 const GLuint array_align = type.GetBaseAlignment(true);
8483 const GLuint base_stride = Utils::Type::CalculateStd140Stride(base_align, type.m_n_columns, 0);
8484 const GLuint type_align = Utils::roundUpToPowerOf2(base_stride);
8486 /* Calculate offsets */
8487 const GLuint first_offset = 0;
8488 const GLuint second_offset = type.GetActualOffset(base_stride, basic_size / 2);
8490 #if WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST
8492 const GLuint third_offset = type.GetActualOffset(second_offset + base_stride, base_align);
8493 const GLuint fourth_offset = type.GetActualOffset(third_offset + base_stride, base_align);
8494 const GLuint fifth_offset = type.GetActualOffset(fourth_offset + base_stride, base_align);
8495 const GLuint sixth_offset = type.GetActualOffset(fifth_offset + base_stride, array_align);
8496 const GLuint seventh_offset = type.GetActualOffset(sixth_offset + base_stride, array_align);
8497 const GLuint eigth_offset = type.GetActualOffset(seventh_offset + base_stride, array_align);
8499 #else /* WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST */
8501 const GLuint third_offset = type.GetActualOffset(second_offset + base_stride, 2 * type_align);
8502 const GLuint fourth_offset = type.GetActualOffset(3 * type_align + base_stride, base_align);
8503 const GLuint fifth_offset = type.GetActualOffset(fourth_offset + base_stride, base_align);
8504 const GLuint sixth_offset = type.GetActualOffset(fifth_offset + base_stride, array_align);
8505 const GLuint seventh_offset = type.GetActualOffset(sixth_offset + base_stride, array_align);
8506 const GLuint eigth_offset = type.GetActualOffset(seventh_offset + base_stride, 8 * basic_size);
8508 #endif /* WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST */
8511 const std::vector<GLubyte>& first = type.GenerateData();
8512 const std::vector<GLubyte>& second = type.GenerateData();
8513 const std::vector<GLubyte>& third = type.GenerateData();
8514 const std::vector<GLubyte>& fourth = type.GenerateData();
8516 m_data.resize(eigth_offset + base_stride);
8517 GLubyte* ptr = &m_data[0];
8518 memcpy(ptr + first_offset, &first[0], first.size());
8519 memcpy(ptr + second_offset, &second[0], second.size());
8520 memcpy(ptr + third_offset, &third[0], third.size());
8521 memcpy(ptr + fourth_offset, &fourth[0], fourth.size());
8522 memcpy(ptr + fifth_offset, &fourth[0], fourth.size());
8523 memcpy(ptr + sixth_offset, &third[0], third.size());
8524 memcpy(ptr + seventh_offset, &second[0], second.size());
8525 memcpy(ptr + eigth_offset, &first[0], first.size());
8527 /* Prepare globals */
8528 size_t position = 0;
8531 sprintf(buffer, "%d", basic_size);
8532 Utils::replaceToken("BASIC_SIZE", position, buffer, globals);
8534 sprintf(buffer, "%d", type_align);
8535 Utils::replaceToken("TYPE_ALIGN", position, buffer, globals);
8537 sprintf(buffer, "%d", base_stride);
8538 Utils::replaceToken("TYPE_SIZE", position, buffer, globals);
8541 Utils::Interface* vs_uni_block = program_interface.Block("vs_uni_Block");
8543 vs_uni_block->Member("at_first_offset", "layout(offset = 0, align = 8 * basic_size)", 0 /* expected_component */,
8544 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
8547 vs_uni_block->Member("at_second_offset", "layout(offset = type_size, align = basic_size / 2)",
8548 0 /* expected_component */, 0 /* expected_location */, type, false /* normalized */,
8549 0 /* n_array_elements */, base_stride, second_offset);
8551 vs_uni_block->Member("at_third_offset", "layout(align = 2 * type_align)", 0 /* expected_component */,
8552 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
8555 vs_uni_block->Member("at_fourth_offset", "layout(offset = 3 * type_align + type_size)", 0 /* expected_component */,
8556 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
8559 vs_uni_block->Member("at_fifth_offset", "", 0 /* expected_component */, 0 /* expected_location */, type,
8560 false /* normalized */, 0 /* n_array_elements */, base_stride, fifth_offset);
8562 vs_uni_block->Member("at_sixth_offset", "", 0 /* expected_component */, 0 /* expected_location */, type,
8563 false /* normalized */, 2 /* n_array_elements */, array_align * 2, sixth_offset);
8565 vs_uni_block->Member("at_eigth_offset", "layout(align = 8 * basic_size)", 0 /* expected_component */,
8566 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
8569 Utils::ShaderInterface& vs_si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
8572 vs_si.m_globals = globals;
8574 /* Add uniform BLOCK */
8575 vs_si.Uniform("vs_uni_block", "layout (std140, binding = BINDING)", 0, 0, vs_uni_block, 0,
8576 static_cast<glw::GLint>(m_data.size()), 0, &m_data[0], m_data.size());
8579 program_interface.CloneVertexInterface(varying_passthrough);
8584 * @param test_case_index Index of test case
8586 * @return Name of type test in test_case_index
8588 std::string UniformBlockMemberOffsetAndAlignTest::getTestCaseName(glw::GLuint test_case_index)
8590 return getTypeName(test_case_index);
8593 /** Returns number of types to test
8595 * @return Number of types, 34
8597 glw::GLuint UniformBlockMemberOffsetAndAlignTest::getTestCaseNumber()
8599 return getTypesNumber();
8602 /** Prepare code snippet that will verify in and uniform variables
8606 * @param stage Shader stage
8608 * @return Code that verify variables
8610 std::string UniformBlockMemberOffsetAndAlignTest::getVerificationSnippet(
8611 GLuint /* test_case_index */, Utils::ProgramInterface& /* program_interface */, Utils::Shader::STAGES stage)
8613 std::string verification = "if ( (PREFIXblock.at_first_offset != PREFIXblock.at_eigth_offset ) ||\n"
8614 " (PREFIXblock.at_second_offset != PREFIXblock.at_sixth_offset[1]) ||\n"
8615 " (PREFIXblock.at_third_offset != PREFIXblock.at_sixth_offset[0]) ||\n"
8616 " (PREFIXblock.at_fourth_offset != PREFIXblock.at_fifth_offset ) )\n"
8621 const GLchar* prefix = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::UNIFORM);
8623 Utils::replaceAllTokens("PREFIX", prefix, verification);
8625 return verification;
8630 * @param context Test framework context
8632 UniformBlockLayoutQualifierConflictTest::UniformBlockLayoutQualifierConflictTest(deqp::Context& context)
8634 context, "uniform_block_layout_qualifier_conflict",
8635 "Test verifies that std140 is required when offset and/or align qualifiers are used with uniform block")
8637 /* Nothing to be done here */
8640 /** Source for given test case and stage
8642 * @param test_case_index Index of test case
8643 * @param stage Shader stage
8645 * @return Shader source
8647 std::string UniformBlockLayoutQualifierConflictTest::getShaderSource(GLuint test_case_index,
8648 Utils::Shader::STAGES stage)
8650 static const GLchar* cs = "#version 430 core\n"
8651 "#extension GL_ARB_enhanced_layouts : require\n"
8653 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
8655 "LAYOUTuniform Block {\n"
8656 " layout(offset = 16) vec4 boy;\n"
8657 " layout(align = 64) vec4 man;\n"
8660 "writeonly uniform image2D uni_image;\n"
8664 " vec4 result = uni_block.boy + uni_block.man;\n"
8666 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
8669 static const GLchar* fs = "#version 430 core\n"
8670 "#extension GL_ARB_enhanced_layouts : require\n"
8672 "LAYOUTuniform Block {\n"
8673 " layout(offset = 16) vec4 boy;\n"
8674 " layout(align = 64) vec4 man;\n"
8678 "out vec4 fs_out;\n"
8682 " fs_out = gs_fs + uni_block.boy + uni_block.man;\n"
8685 static const GLchar* gs = "#version 430 core\n"
8686 "#extension GL_ARB_enhanced_layouts : require\n"
8688 "layout(points) in;\n"
8689 "layout(triangle_strip, max_vertices = 4) out;\n"
8691 "LAYOUTuniform Block {\n"
8692 " layout(offset = 16) vec4 boy;\n"
8693 " layout(align = 64) vec4 man;\n"
8696 "in vec4 tes_gs[];\n"
8701 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
8702 " gl_Position = vec4(-1, -1, 0, 1);\n"
8704 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
8705 " gl_Position = vec4(-1, 1, 0, 1);\n"
8707 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
8708 " gl_Position = vec4(1, -1, 0, 1);\n"
8710 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
8711 " gl_Position = vec4(1, 1, 0, 1);\n"
8715 static const GLchar* tcs =
8716 "#version 430 core\n"
8717 "#extension GL_ARB_enhanced_layouts : require\n"
8719 "layout(vertices = 1) out;\n"
8721 "LAYOUTuniform Block {\n"
8722 " layout(offset = 16) vec4 boy;\n"
8723 " layout(align = 64) vec4 man;\n"
8726 "in vec4 vs_tcs[];\n"
8727 "out vec4 tcs_tes[];\n"
8732 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID] + uni_block.boy + uni_block.man;\n"
8734 " gl_TessLevelOuter[0] = 1.0;\n"
8735 " gl_TessLevelOuter[1] = 1.0;\n"
8736 " gl_TessLevelOuter[2] = 1.0;\n"
8737 " gl_TessLevelOuter[3] = 1.0;\n"
8738 " gl_TessLevelInner[0] = 1.0;\n"
8739 " gl_TessLevelInner[1] = 1.0;\n"
8742 static const GLchar* tes = "#version 430 core\n"
8743 "#extension GL_ARB_enhanced_layouts : require\n"
8745 "layout(isolines, point_mode) in;\n"
8747 "LAYOUTuniform Block {\n"
8748 " layout(offset = 16) vec4 boy;\n"
8749 " layout(align = 64) vec4 man;\n"
8752 "in vec4 tcs_tes[];\n"
8753 "out vec4 tes_gs;\n"
8757 " tes_gs = tcs_tes[0] + uni_block.boy + uni_block.man;\n"
8760 static const GLchar* vs = "#version 430 core\n"
8761 "#extension GL_ARB_enhanced_layouts : require\n"
8763 "LAYOUTuniform Block {\n"
8764 " layout(offset = 16) vec4 boy;\n"
8765 " layout(align = 64) vec4 man;\n"
8769 "out vec4 vs_tcs;\n"
8773 " vs_tcs = in_vs + uni_block.boy + uni_block.man;\n"
8777 std::string layout = "";
8778 size_t position = 0;
8779 testCase& test_case = m_test_cases[test_case_index];
8780 const GLchar* qualifier = getQualifierName(test_case.m_qualifier);
8783 if (0 != qualifier[0])
8785 size_t layout_position = 0;
8787 layout = "layout (QUALIFIER) ";
8789 Utils::replaceToken("QUALIFIER", layout_position, qualifier, layout);
8794 case Utils::Shader::COMPUTE:
8797 case Utils::Shader::FRAGMENT:
8800 case Utils::Shader::GEOMETRY:
8803 case Utils::Shader::TESS_CTRL:
8806 case Utils::Shader::TESS_EVAL:
8809 case Utils::Shader::VERTEX:
8813 TCU_FAIL("Invalid enum");
8816 if (test_case.m_stage == stage)
8818 Utils::replaceToken("LAYOUT", position, layout.c_str(), source);
8822 Utils::replaceToken("LAYOUT", position, "layout (std140) ", source);
8828 /** Get description of test case
8830 * @param test_case_index Index of test case
8832 * @return Qualifier name
8834 std::string UniformBlockLayoutQualifierConflictTest::getTestCaseName(GLuint test_case_index)
8836 std::string result = getQualifierName(m_test_cases[test_case_index].m_qualifier);
8841 /** Get number of test cases
8843 * @return Number of test cases
8845 GLuint UniformBlockLayoutQualifierConflictTest::getTestCaseNumber()
8847 return static_cast<GLuint>(m_test_cases.size());
8850 /** Selects if "compute" stage is relevant for test
8852 * @param test_case_index Index of test case
8854 * @return true when tested stage is compute
8856 bool UniformBlockLayoutQualifierConflictTest::isComputeRelevant(GLuint test_case_index)
8858 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
8861 /** Selects if compilation failure is expected result
8863 * @param test_case_index Index of test case
8865 * @return false for STD140 cases, true otherwise
8867 bool UniformBlockLayoutQualifierConflictTest::isFailureExpected(GLuint test_case_index)
8869 return (STD140 != m_test_cases[test_case_index].m_qualifier);
8872 /** Prepare all test cases
8875 void UniformBlockLayoutQualifierConflictTest::testInit()
8877 for (GLuint qualifier = 0; qualifier < QUALIFIERS_MAX; ++qualifier)
8879 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
8881 testCase test_case = { (QUALIFIERS)qualifier, (Utils::Shader::STAGES)stage };
8883 m_test_cases.push_back(test_case);
8888 /** Get name of glsl constant
8890 * @param Constant id
8892 * @return Name of constant used in GLSL
8894 const GLchar* UniformBlockLayoutQualifierConflictTest::getQualifierName(QUALIFIERS qualifier)
8896 const GLchar* name = "";
8913 TCU_FAIL("Invalid enum");
8921 * @param context Test framework context
8923 UniformBlockMemberInvalidOffsetAlignmentTest::UniformBlockMemberInvalidOffsetAlignmentTest(deqp::Context& context)
8924 : NegativeTestBase(context, "uniform_block_member_invalid_offset_alignment",
8925 "Test verifies that invalid alignment of offset qualifiers cause compilation failure")
8927 /* Nothing to be done here */
8932 * @param context Test framework context
8933 * @param name Test name
8934 * @param description Test description
8936 UniformBlockMemberInvalidOffsetAlignmentTest::UniformBlockMemberInvalidOffsetAlignmentTest(
8937 deqp::Context& context, const glw::GLchar* name, const glw::GLchar* description)
8938 : NegativeTestBase(context, name, description)
8940 /* Nothing to be done here */
8943 /** Source for given test case and stage
8945 * @param test_case_index Index of test case
8946 * @param stage Shader stage
8948 * @return Shader source
8950 std::string UniformBlockMemberInvalidOffsetAlignmentTest::getShaderSource(GLuint test_case_index,
8951 Utils::Shader::STAGES stage)
8953 static const GLchar* cs = "#version 430 core\n"
8954 "#extension GL_ARB_enhanced_layouts : require\n"
8956 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
8958 "layout (std140) uniform Block {\n"
8959 " layout (offset = OFFSET) TYPE member;\n"
8962 "writeonly uniform image2D uni_image;\n"
8966 " vec4 result = vec4(1, 0, 0.5, 1);\n"
8968 " if (TYPE(1) == block.member)\n"
8970 " result = vec4(1, 1, 1, 1);\n"
8973 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
8976 static const GLchar* fs = "#version 430 core\n"
8977 "#extension GL_ARB_enhanced_layouts : require\n"
8980 "out vec4 fs_out;\n"
8984 " fs_out = gs_fs;\n"
8987 static const GLchar* fs_tested = "#version 430 core\n"
8988 "#extension GL_ARB_enhanced_layouts : require\n"
8990 "layout (std140) uniform Block {\n"
8991 " layout (offset = OFFSET) TYPE member;\n"
8995 "out vec4 fs_out;\n"
8999 " if (TYPE(1) == block.member)\n"
9001 " fs_out = vec4(1, 1, 1, 1);\n"
9004 " fs_out += gs_fs;\n"
9007 static const GLchar* gs = "#version 430 core\n"
9008 "#extension GL_ARB_enhanced_layouts : require\n"
9010 "layout(points) in;\n"
9011 "layout(triangle_strip, max_vertices = 4) out;\n"
9013 "in vec4 tes_gs[];\n"
9018 " gs_fs = tes_gs[0];\n"
9019 " gl_Position = vec4(-1, -1, 0, 1);\n"
9021 " gs_fs = tes_gs[0];\n"
9022 " gl_Position = vec4(-1, 1, 0, 1);\n"
9024 " gs_fs = tes_gs[0];\n"
9025 " gl_Position = vec4(1, -1, 0, 1);\n"
9027 " gs_fs = tes_gs[0];\n"
9028 " gl_Position = vec4(1, 1, 0, 1);\n"
9032 static const GLchar* gs_tested = "#version 430 core\n"
9033 "#extension GL_ARB_enhanced_layouts : require\n"
9035 "layout(points) in;\n"
9036 "layout(triangle_strip, max_vertices = 4) out;\n"
9038 "layout (std140) uniform Block {\n"
9039 " layout (offset = OFFSET) TYPE member;\n"
9042 "in vec4 tes_gs[];\n"
9047 " if (TYPE(1) == block.member)\n"
9049 " gs_fs = vec4(1, 1, 1, 1);\n"
9052 " gs_fs += tes_gs[0];\n"
9053 " gl_Position = vec4(-1, -1, 0, 1);\n"
9055 " gs_fs += tes_gs[0];\n"
9056 " gl_Position = vec4(-1, 1, 0, 1);\n"
9058 " gs_fs += tes_gs[0];\n"
9059 " gl_Position = vec4(1, -1, 0, 1);\n"
9061 " gs_fs += tes_gs[0];\n"
9062 " gl_Position = vec4(1, 1, 0, 1);\n"
9066 static const GLchar* tcs = "#version 430 core\n"
9067 "#extension GL_ARB_enhanced_layouts : require\n"
9069 "layout(vertices = 1) out;\n"
9071 "in vec4 vs_tcs[];\n"
9072 "out vec4 tcs_tes[];\n"
9077 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
9079 " gl_TessLevelOuter[0] = 1.0;\n"
9080 " gl_TessLevelOuter[1] = 1.0;\n"
9081 " gl_TessLevelOuter[2] = 1.0;\n"
9082 " gl_TessLevelOuter[3] = 1.0;\n"
9083 " gl_TessLevelInner[0] = 1.0;\n"
9084 " gl_TessLevelInner[1] = 1.0;\n"
9087 static const GLchar* tcs_tested = "#version 430 core\n"
9088 "#extension GL_ARB_enhanced_layouts : require\n"
9090 "layout(vertices = 1) out;\n"
9092 "layout (std140) uniform Block {\n"
9093 " layout (offset = OFFSET) TYPE member;\n"
9096 "in vec4 vs_tcs[];\n"
9097 "out vec4 tcs_tes[];\n"
9101 " if (TYPE(1) == block.member)\n"
9103 " tcs_tes[gl_InvocationID] = vec4(1, 1, 1, 1);\n"
9107 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
9109 " gl_TessLevelOuter[0] = 1.0;\n"
9110 " gl_TessLevelOuter[1] = 1.0;\n"
9111 " gl_TessLevelOuter[2] = 1.0;\n"
9112 " gl_TessLevelOuter[3] = 1.0;\n"
9113 " gl_TessLevelInner[0] = 1.0;\n"
9114 " gl_TessLevelInner[1] = 1.0;\n"
9117 static const GLchar* tes = "#version 430 core\n"
9118 "#extension GL_ARB_enhanced_layouts : require\n"
9120 "layout(isolines, point_mode) in;\n"
9122 "in vec4 tcs_tes[];\n"
9123 "out vec4 tes_gs;\n"
9127 " tes_gs = tcs_tes[0];\n"
9130 static const GLchar* tes_tested = "#version 430 core\n"
9131 "#extension GL_ARB_enhanced_layouts : require\n"
9133 "layout(isolines, point_mode) in;\n"
9135 "layout (std140) uniform Block {\n"
9136 " layout (offset = OFFSET) TYPE member;\n"
9139 "in vec4 tcs_tes[];\n"
9140 "out vec4 tes_gs;\n"
9144 " if (TYPE(1) == block.member)\n"
9146 " tes_gs = vec4(1, 1, 1, 1);\n"
9149 " tes_gs += tcs_tes[0];\n"
9152 static const GLchar* vs = "#version 430 core\n"
9153 "#extension GL_ARB_enhanced_layouts : require\n"
9156 "out vec4 vs_tcs;\n"
9160 " vs_tcs = in_vs;\n"
9163 static const GLchar* vs_tested = "#version 430 core\n"
9164 "#extension GL_ARB_enhanced_layouts : require\n"
9166 "layout (std140) uniform Block {\n"
9167 " layout (offset = OFFSET) TYPE member;\n"
9171 "out vec4 vs_tcs;\n"
9175 " if (TYPE(1) == block.member)\n"
9177 " vs_tcs = vec4(1, 1, 1, 1);\n"
9180 " vs_tcs += in_vs;\n"
9185 testCase& test_case = m_test_cases[test_case_index];
9187 if (test_case.m_stage == stage)
9190 const GLuint offset = test_case.m_offset;
9191 size_t position = 0;
9192 const Utils::Type& type = test_case.m_type;
9193 const GLchar* type_name = type.GetGLSLTypeName();
9195 sprintf(buffer, "%d", offset);
9199 case Utils::Shader::COMPUTE:
9202 case Utils::Shader::FRAGMENT:
9205 case Utils::Shader::GEOMETRY:
9208 case Utils::Shader::TESS_CTRL:
9209 source = tcs_tested;
9211 case Utils::Shader::TESS_EVAL:
9212 source = tes_tested;
9214 case Utils::Shader::VERTEX:
9218 TCU_FAIL("Invalid enum");
9221 Utils::replaceToken("OFFSET", position, buffer, source);
9222 Utils::replaceToken("TYPE", position, type_name, source);
9223 Utils::replaceToken("TYPE", position, type_name, source);
9229 case Utils::Shader::FRAGMENT:
9232 case Utils::Shader::GEOMETRY:
9235 case Utils::Shader::TESS_CTRL:
9238 case Utils::Shader::TESS_EVAL:
9241 case Utils::Shader::VERTEX:
9245 TCU_FAIL("Invalid enum");
9252 /** Get description of test case
9254 * @param test_case_index Index of test case
9256 * @return Type name and offset
9258 std::string UniformBlockMemberInvalidOffsetAlignmentTest::getTestCaseName(GLuint test_case_index)
9260 std::stringstream stream;
9261 testCase& test_case = m_test_cases[test_case_index];
9263 stream << "Type: " << test_case.m_type.GetGLSLTypeName() << ", offset: " << test_case.m_offset;
9265 return stream.str();
9268 /** Get number of test cases
9270 * @return Number of test cases
9272 GLuint UniformBlockMemberInvalidOffsetAlignmentTest::getTestCaseNumber()
9274 return static_cast<GLuint>(m_test_cases.size());
9277 /** Selects if "compute" stage is relevant for test
9279 * @param test_case_index Index of test case
9281 * @return true when tested stage is compute
9283 bool UniformBlockMemberInvalidOffsetAlignmentTest::isComputeRelevant(GLuint test_case_index)
9285 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
9288 /** Selects if compilation failure is expected result
9290 * @param test_case_index Index of test case
9292 * @return should_fail field from testCase
9294 bool UniformBlockMemberInvalidOffsetAlignmentTest::isFailureExpected(GLuint test_case_index)
9296 return m_test_cases[test_case_index].m_should_fail;
9299 /** Checks if stage is supported
9301 * @param stage ignored
9305 bool UniformBlockMemberInvalidOffsetAlignmentTest::isStageSupported(Utils::Shader::STAGES /* stage */)
9310 /** Prepare all test cases
9313 void UniformBlockMemberInvalidOffsetAlignmentTest::testInit()
9315 const Functions& gl = m_context.getRenderContext().getFunctions();
9317 const GLuint n_types = getTypesNumber();
9318 bool stage_support[Utils::Shader::STAGE_MAX];
9320 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
9322 stage_support[stage] = isStageSupported((Utils::Shader::STAGES)stage);
9325 gl.getIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &max_size);
9326 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
9328 for (GLuint i = 0; i < n_types; ++i)
9330 const Utils::Type& type = getType(i);
9331 const GLuint alignment = type.GetBaseAlignment(false);
9332 const GLuint type_size = type.GetSize();
9333 const GLuint sec_to_end = max_size - 2 * type_size;
9335 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
9337 if (false == stage_support[stage])
9342 for (GLuint offset = 0; offset <= type_size; ++offset)
9344 const GLuint modulo = offset % alignment;
9345 const bool is_aligned = (0 == modulo) ? true : false;
9346 const bool should_fail = !is_aligned;
9348 testCase test_case = { offset, should_fail, (Utils::Shader::STAGES)stage, type };
9350 m_test_cases.push_back(test_case);
9353 for (GLuint offset = sec_to_end; offset <= sec_to_end + type_size; ++offset)
9355 const GLuint modulo = offset % alignment;
9356 const bool is_aligned = (0 == modulo) ? true : false;
9357 const bool should_fail = !is_aligned;
9359 testCase test_case = { offset, should_fail, (Utils::Shader::STAGES)stage, type };
9361 m_test_cases.push_back(test_case);
9369 * @param context Test framework context
9371 UniformBlockMemberOverlappingOffsetsTest::UniformBlockMemberOverlappingOffsetsTest(deqp::Context& context)
9372 : NegativeTestBase(context, "uniform_block_member_overlapping_offsets",
9373 "Test verifies that overlapping offsets qualifiers cause compilation failure")
9375 /* Nothing to be done here */
9380 * @param context Test framework context
9381 * @param name Test name
9382 * @param description Test description
9384 UniformBlockMemberOverlappingOffsetsTest::UniformBlockMemberOverlappingOffsetsTest(deqp::Context& context,
9385 const glw::GLchar* name,
9386 const glw::GLchar* description)
9387 : NegativeTestBase(context, name, description)
9389 /* Nothing to be done here */
9392 /** Source for given test case and stage
9394 * @param test_case_index Index of test case
9395 * @param stage Shader stage
9397 * @return Shader source
9399 std::string UniformBlockMemberOverlappingOffsetsTest::getShaderSource(GLuint test_case_index,
9400 Utils::Shader::STAGES stage)
9402 static const GLchar* cs = "#version 430 core\n"
9403 "#extension GL_ARB_enhanced_layouts : require\n"
9405 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
9407 "layout (std140) uniform Block {\n"
9408 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9409 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9412 "writeonly uniform image2D uni_image;\n"
9416 " vec4 result = vec4(1, 0, 0.5, 1);\n"
9418 " if ((BOY_TYPE(1) == block.boy) ||\n"
9419 " (MAN_TYPE(0) == block.man) )\n"
9421 " result = vec4(1, 1, 1, 1);\n"
9424 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
9427 static const GLchar* fs = "#version 430 core\n"
9428 "#extension GL_ARB_enhanced_layouts : require\n"
9431 "out vec4 fs_out;\n"
9435 " fs_out = gs_fs;\n"
9438 static const GLchar* fs_tested = "#version 430 core\n"
9439 "#extension GL_ARB_enhanced_layouts : require\n"
9441 "layout (std140) uniform Block {\n"
9442 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9443 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9447 "out vec4 fs_out;\n"
9451 " if ((BOY_TYPE(1) == block.boy) ||\n"
9452 " (MAN_TYPE(0) == block.man) )\n"
9454 " fs_out = vec4(1, 1, 1, 1);\n"
9457 " fs_out += gs_fs;\n"
9460 static const GLchar* gs = "#version 430 core\n"
9461 "#extension GL_ARB_enhanced_layouts : require\n"
9463 "layout(points) in;\n"
9464 "layout(triangle_strip, max_vertices = 4) out;\n"
9466 "in vec4 tes_gs[];\n"
9471 " gs_fs = tes_gs[0];\n"
9472 " gl_Position = vec4(-1, -1, 0, 1);\n"
9474 " gs_fs = tes_gs[0];\n"
9475 " gl_Position = vec4(-1, 1, 0, 1);\n"
9477 " gs_fs = tes_gs[0];\n"
9478 " gl_Position = vec4(1, -1, 0, 1);\n"
9480 " gs_fs = tes_gs[0];\n"
9481 " gl_Position = vec4(1, 1, 0, 1);\n"
9485 static const GLchar* gs_tested = "#version 430 core\n"
9486 "#extension GL_ARB_enhanced_layouts : require\n"
9488 "layout(points) in;\n"
9489 "layout(triangle_strip, max_vertices = 4) out;\n"
9491 "layout (std140) uniform Block {\n"
9492 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9493 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9496 "in vec4 tes_gs[];\n"
9501 " if ((BOY_TYPE(1) == block.boy) ||\n"
9502 " (MAN_TYPE(0) == block.man) )\n"
9504 " gs_fs = vec4(1, 1, 1, 1);\n"
9507 " gs_fs += tes_gs[0];\n"
9508 " gl_Position = vec4(-1, -1, 0, 1);\n"
9510 " gs_fs += tes_gs[0];\n"
9511 " gl_Position = vec4(-1, 1, 0, 1);\n"
9513 " gs_fs += tes_gs[0];\n"
9514 " gl_Position = vec4(1, -1, 0, 1);\n"
9516 " gs_fs += tes_gs[0];\n"
9517 " gl_Position = vec4(1, 1, 0, 1);\n"
9521 static const GLchar* tcs = "#version 430 core\n"
9522 "#extension GL_ARB_enhanced_layouts : require\n"
9524 "layout(vertices = 1) out;\n"
9526 "in vec4 vs_tcs[];\n"
9527 "out vec4 tcs_tes[];\n"
9532 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
9534 " gl_TessLevelOuter[0] = 1.0;\n"
9535 " gl_TessLevelOuter[1] = 1.0;\n"
9536 " gl_TessLevelOuter[2] = 1.0;\n"
9537 " gl_TessLevelOuter[3] = 1.0;\n"
9538 " gl_TessLevelInner[0] = 1.0;\n"
9539 " gl_TessLevelInner[1] = 1.0;\n"
9542 static const GLchar* tcs_tested = "#version 430 core\n"
9543 "#extension GL_ARB_enhanced_layouts : require\n"
9545 "layout(vertices = 1) out;\n"
9547 "layout (std140) uniform Block {\n"
9548 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9549 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9552 "in vec4 vs_tcs[];\n"
9553 "out vec4 tcs_tes[];\n"
9557 " if ((BOY_TYPE(1) == block.boy) ||\n"
9558 " (MAN_TYPE(0) == block.man) )\n"
9560 " tcs_tes[gl_InvocationID] = vec4(1, 1, 1, 1);\n"
9564 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
9566 " gl_TessLevelOuter[0] = 1.0;\n"
9567 " gl_TessLevelOuter[1] = 1.0;\n"
9568 " gl_TessLevelOuter[2] = 1.0;\n"
9569 " gl_TessLevelOuter[3] = 1.0;\n"
9570 " gl_TessLevelInner[0] = 1.0;\n"
9571 " gl_TessLevelInner[1] = 1.0;\n"
9574 static const GLchar* tes = "#version 430 core\n"
9575 "#extension GL_ARB_enhanced_layouts : require\n"
9577 "layout(isolines, point_mode) in;\n"
9579 "in vec4 tcs_tes[];\n"
9580 "out vec4 tes_gs;\n"
9584 " tes_gs = tcs_tes[0];\n"
9587 static const GLchar* tes_tested = "#version 430 core\n"
9588 "#extension GL_ARB_enhanced_layouts : require\n"
9590 "layout(isolines, point_mode) in;\n"
9592 "layout (std140) uniform Block {\n"
9593 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9594 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9597 "in vec4 tcs_tes[];\n"
9598 "out vec4 tes_gs;\n"
9602 " if ((BOY_TYPE(1) == block.boy) ||\n"
9603 " (MAN_TYPE(0) == block.man) )\n"
9605 " tes_gs = vec4(1, 1, 1, 1);\n"
9608 " tes_gs += tcs_tes[0];\n"
9611 static const GLchar* vs = "#version 430 core\n"
9612 "#extension GL_ARB_enhanced_layouts : require\n"
9615 "out vec4 vs_tcs;\n"
9619 " vs_tcs = in_vs;\n"
9622 static const GLchar* vs_tested = "#version 430 core\n"
9623 "#extension GL_ARB_enhanced_layouts : require\n"
9625 "layout (std140) uniform Block {\n"
9626 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9627 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9631 "out vec4 vs_tcs;\n"
9635 " if ((BOY_TYPE(1) == block.boy) ||\n"
9636 " (MAN_TYPE(0) == block.man) )\n"
9638 " vs_tcs = vec4(1, 1, 1, 1);\n"
9641 " vs_tcs += in_vs;\n"
9646 testCase& test_case = m_test_cases[test_case_index];
9648 if (test_case.m_stage == stage)
9651 const GLuint boy_offset = test_case.m_boy_offset;
9652 const Utils::Type& boy_type = test_case.m_boy_type;
9653 const GLchar* boy_type_name = boy_type.GetGLSLTypeName();
9654 const GLuint man_offset = test_case.m_man_offset;
9655 const Utils::Type& man_type = test_case.m_man_type;
9656 const GLchar* man_type_name = man_type.GetGLSLTypeName();
9657 size_t position = 0;
9661 case Utils::Shader::COMPUTE:
9664 case Utils::Shader::FRAGMENT:
9667 case Utils::Shader::GEOMETRY:
9670 case Utils::Shader::TESS_CTRL:
9671 source = tcs_tested;
9673 case Utils::Shader::TESS_EVAL:
9674 source = tes_tested;
9676 case Utils::Shader::VERTEX:
9680 TCU_FAIL("Invalid enum");
9683 sprintf(buffer, "%d", boy_offset);
9684 Utils::replaceToken("BOY_OFFSET", position, buffer, source);
9685 Utils::replaceToken("BOY_TYPE", position, boy_type_name, source);
9686 sprintf(buffer, "%d", man_offset);
9687 Utils::replaceToken("MAN_OFFSET", position, buffer, source);
9688 Utils::replaceToken("MAN_TYPE", position, man_type_name, source);
9689 Utils::replaceToken("BOY_TYPE", position, boy_type_name, source);
9690 Utils::replaceToken("MAN_TYPE", position, man_type_name, source);
9696 case Utils::Shader::FRAGMENT:
9699 case Utils::Shader::GEOMETRY:
9702 case Utils::Shader::TESS_CTRL:
9705 case Utils::Shader::TESS_EVAL:
9708 case Utils::Shader::VERTEX:
9712 TCU_FAIL("Invalid enum");
9719 /** Get description of test case
9721 * @param test_case_index Index of test case
9723 * @return Type name and offset
9725 std::string UniformBlockMemberOverlappingOffsetsTest::getTestCaseName(GLuint test_case_index)
9727 std::stringstream stream;
9728 testCase& test_case = m_test_cases[test_case_index];
9730 stream << "Type: " << test_case.m_boy_type.GetGLSLTypeName() << ", offset: " << test_case.m_boy_offset
9731 << ". Type: " << test_case.m_man_type.GetGLSLTypeName() << ", offset: " << test_case.m_man_offset;
9733 return stream.str();
9736 /** Get number of test cases
9738 * @return Number of test cases
9740 GLuint UniformBlockMemberOverlappingOffsetsTest::getTestCaseNumber()
9742 return static_cast<GLuint>(m_test_cases.size());
9745 /** Selects if "compute" stage is relevant for test
9747 * @param test_case_index Index of test case
9749 * @return true when tested stage is compute
9751 bool UniformBlockMemberOverlappingOffsetsTest::isComputeRelevant(GLuint test_case_index)
9753 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
9756 /** Checks if stage is supported
9758 * @param stage ignored
9762 bool UniformBlockMemberOverlappingOffsetsTest::isStageSupported(Utils::Shader::STAGES /* stage */)
9767 /** Prepare all test cases
9770 void UniformBlockMemberOverlappingOffsetsTest::testInit()
9772 const GLuint n_types = getTypesNumber();
9773 bool stage_support[Utils::Shader::STAGE_MAX];
9775 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
9777 stage_support[stage] = isStageSupported((Utils::Shader::STAGES)stage);
9780 for (GLuint i = 0; i < n_types; ++i)
9782 const Utils::Type& boy_type = getType(i);
9783 const GLuint boy_size = boy_type.GetActualAlignment(1 /* align */, false /* is_array*/);
9785 for (GLuint j = 0; j < n_types; ++j)
9787 const Utils::Type& man_type = getType(j);
9788 const GLuint man_align = man_type.GetBaseAlignment(false);
9789 const GLuint man_size = man_type.GetActualAlignment(1 /* align */, false /* is_array*/);
9791 const GLuint boy_offset = lcm(boy_size, man_size);
9792 const GLuint man_after_start = boy_offset + 1;
9793 const GLuint man_after_off = man_type.GetActualOffset(man_after_start, man_size);
9794 const GLuint man_before_start = boy_offset - man_align;
9795 const GLuint man_before_off = man_type.GetActualOffset(man_before_start, man_size);
9797 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
9799 if (false == stage_support[stage])
9804 if ((boy_offset > man_before_off) && (boy_offset < man_before_off + man_size))
9806 testCase test_case = { boy_offset, boy_type, man_before_off, man_type,
9807 (Utils::Shader::STAGES)stage };
9809 m_test_cases.push_back(test_case);
9812 if ((boy_offset < man_after_off) && (boy_offset + boy_size > man_after_off))
9814 testCase test_case = { boy_offset, boy_type, man_after_off, man_type,
9815 (Utils::Shader::STAGES)stage };
9817 m_test_cases.push_back(test_case);
9820 /* Boy offset, should be fine for both types */
9821 testCase test_case = { boy_offset, boy_type, boy_offset, man_type, (Utils::Shader::STAGES)stage };
9823 m_test_cases.push_back(test_case);
9829 /** Find greatest common divisor for a and b
9831 * @param a A argument
9832 * @param b B argument
9834 * @return Found gcd value
9836 GLuint UniformBlockMemberOverlappingOffsetsTest::gcd(GLuint a, GLuint b)
9838 if ((0 != a) && (0 == b))
9844 GLuint greater = std::max(a, b);
9845 GLuint lesser = std::min(a, b);
9847 return gcd(lesser, greater % lesser);
9851 /** Find lowest common multiple for a and b
9853 * @param a A argument
9854 * @param b B argument
9856 * @return Found gcd value
9858 GLuint UniformBlockMemberOverlappingOffsetsTest::lcm(GLuint a, GLuint b)
9860 return (a * b) / gcd(a, b);
9865 * @param context Test framework context
9867 UniformBlockMemberAlignNonPowerOf2Test::UniformBlockMemberAlignNonPowerOf2Test(deqp::Context& context)
9868 : NegativeTestBase(context, "uniform_block_member_align_non_power_of_2",
9869 "Test verifies that align qualifier requires value that is a power of 2")
9871 /* Nothing to be done here */
9876 * @param context Test framework context
9877 * @param name Test name
9878 * @param description Test description
9880 UniformBlockMemberAlignNonPowerOf2Test::UniformBlockMemberAlignNonPowerOf2Test(deqp::Context& context,
9881 const glw::GLchar* name,
9882 const glw::GLchar* description)
9883 : NegativeTestBase(context, name, description)
9885 /* Nothing to be done here */
9888 /** Source for given test case and stage
9890 * @param test_case_index Index of test case
9891 * @param stage Shader stage
9893 * @return Shader source
9895 std::string UniformBlockMemberAlignNonPowerOf2Test::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
9897 static const GLchar* cs = "#version 430 core\n"
9898 "#extension GL_ARB_enhanced_layouts : require\n"
9900 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
9902 "layout (std140) uniform Block {\n"
9904 " layout (align = ALIGN) TYPE man;\n"
9907 "writeonly uniform image2D uni_image;\n"
9911 " vec4 result = vec4(1, 0, 0.5, 1);\n"
9913 " if (TYPE(0) == block.man)\n"
9915 " result = vec4(1, 1, 1, 1) - block.boy;\n"
9918 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
9921 static const GLchar* fs = "#version 430 core\n"
9922 "#extension GL_ARB_enhanced_layouts : require\n"
9925 "out vec4 fs_out;\n"
9929 " fs_out = gs_fs;\n"
9932 static const GLchar* fs_tested = "#version 430 core\n"
9933 "#extension GL_ARB_enhanced_layouts : require\n"
9935 "layout (std140) uniform Block {\n"
9937 " layout (align = ALIGN) TYPE man;\n"
9941 "out vec4 fs_out;\n"
9945 " if (TYPE(0) == block.man)\n"
9947 " fs_out = block.boy;\n"
9950 " fs_out += gs_fs;\n"
9953 static const GLchar* gs = "#version 430 core\n"
9954 "#extension GL_ARB_enhanced_layouts : require\n"
9956 "layout(points) in;\n"
9957 "layout(triangle_strip, max_vertices = 4) out;\n"
9959 "in vec4 tes_gs[];\n"
9964 " gs_fs = tes_gs[0];\n"
9965 " gl_Position = vec4(-1, -1, 0, 1);\n"
9967 " gs_fs = tes_gs[0];\n"
9968 " gl_Position = vec4(-1, 1, 0, 1);\n"
9970 " gs_fs = tes_gs[0];\n"
9971 " gl_Position = vec4(1, -1, 0, 1);\n"
9973 " gs_fs = tes_gs[0];\n"
9974 " gl_Position = vec4(1, 1, 0, 1);\n"
9978 static const GLchar* gs_tested = "#version 430 core\n"
9979 "#extension GL_ARB_enhanced_layouts : require\n"
9981 "layout(points) in;\n"
9982 "layout(triangle_strip, max_vertices = 4) out;\n"
9984 "layout (std140) uniform Block {\n"
9986 " layout (align = ALIGN) TYPE man;\n"
9989 "in vec4 tes_gs[];\n"
9994 " if (TYPE(0) == block.man)\n"
9996 " gs_fs = block.boy;\n"
9999 " gs_fs += tes_gs[0];\n"
10000 " gl_Position = vec4(-1, -1, 0, 1);\n"
10002 " gs_fs += tes_gs[0];\n"
10003 " gl_Position = vec4(-1, 1, 0, 1);\n"
10005 " gs_fs += tes_gs[0];\n"
10006 " gl_Position = vec4(1, -1, 0, 1);\n"
10008 " gs_fs += tes_gs[0];\n"
10009 " gl_Position = vec4(1, 1, 0, 1);\n"
10013 static const GLchar* tcs = "#version 430 core\n"
10014 "#extension GL_ARB_enhanced_layouts : require\n"
10016 "layout(vertices = 1) out;\n"
10018 "in vec4 vs_tcs[];\n"
10019 "out vec4 tcs_tes[];\n"
10024 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
10026 " gl_TessLevelOuter[0] = 1.0;\n"
10027 " gl_TessLevelOuter[1] = 1.0;\n"
10028 " gl_TessLevelOuter[2] = 1.0;\n"
10029 " gl_TessLevelOuter[3] = 1.0;\n"
10030 " gl_TessLevelInner[0] = 1.0;\n"
10031 " gl_TessLevelInner[1] = 1.0;\n"
10034 static const GLchar* tcs_tested = "#version 430 core\n"
10035 "#extension GL_ARB_enhanced_layouts : require\n"
10037 "layout(vertices = 1) out;\n"
10039 "layout (std140) uniform Block {\n"
10041 " layout (align = ALIGN) TYPE man;\n"
10044 "in vec4 vs_tcs[];\n"
10045 "out vec4 tcs_tes[];\n"
10049 " if (TYPE(0) == block.man)\n"
10051 " tcs_tes[gl_InvocationID] = block.boy;\n"
10055 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
10057 " gl_TessLevelOuter[0] = 1.0;\n"
10058 " gl_TessLevelOuter[1] = 1.0;\n"
10059 " gl_TessLevelOuter[2] = 1.0;\n"
10060 " gl_TessLevelOuter[3] = 1.0;\n"
10061 " gl_TessLevelInner[0] = 1.0;\n"
10062 " gl_TessLevelInner[1] = 1.0;\n"
10065 static const GLchar* tes = "#version 430 core\n"
10066 "#extension GL_ARB_enhanced_layouts : require\n"
10068 "layout(isolines, point_mode) in;\n"
10070 "in vec4 tcs_tes[];\n"
10071 "out vec4 tes_gs;\n"
10075 " tes_gs = tcs_tes[0];\n"
10078 static const GLchar* tes_tested = "#version 430 core\n"
10079 "#extension GL_ARB_enhanced_layouts : require\n"
10081 "layout(isolines, point_mode) in;\n"
10083 "layout (std140) uniform Block {\n"
10085 " layout (align = ALIGN) TYPE man;\n"
10088 "in vec4 tcs_tes[];\n"
10089 "out vec4 tes_gs;\n"
10093 " if (TYPE(0) == block.man)\n"
10095 " tes_gs = block.boy;\n"
10098 " tes_gs += tcs_tes[0];\n"
10101 static const GLchar* vs = "#version 430 core\n"
10102 "#extension GL_ARB_enhanced_layouts : require\n"
10105 "out vec4 vs_tcs;\n"
10109 " vs_tcs = in_vs;\n"
10112 static const GLchar* vs_tested = "#version 430 core\n"
10113 "#extension GL_ARB_enhanced_layouts : require\n"
10115 "layout (std140) uniform Block {\n"
10117 " layout (align = ALIGN) TYPE man;\n"
10121 "out vec4 vs_tcs;\n"
10125 " if (TYPE(0) == block.man)\n"
10127 " vs_tcs = block.boy;\n"
10130 " vs_tcs += in_vs;\n"
10134 std::string source;
10135 testCase& test_case = m_test_cases[test_case_index];
10137 if (test_case.m_stage == stage)
10140 const GLuint alignment = test_case.m_alignment;
10141 const Utils::Type& type = test_case.m_type;
10142 const GLchar* type_name = type.GetGLSLTypeName();
10143 size_t position = 0;
10147 case Utils::Shader::COMPUTE:
10150 case Utils::Shader::FRAGMENT:
10151 source = fs_tested;
10153 case Utils::Shader::GEOMETRY:
10154 source = gs_tested;
10156 case Utils::Shader::TESS_CTRL:
10157 source = tcs_tested;
10159 case Utils::Shader::TESS_EVAL:
10160 source = tes_tested;
10162 case Utils::Shader::VERTEX:
10163 source = vs_tested;
10166 TCU_FAIL("Invalid enum");
10169 sprintf(buffer, "%d", alignment);
10170 Utils::replaceToken("ALIGN", position, buffer, source);
10171 Utils::replaceToken("TYPE", position, type_name, source);
10172 Utils::replaceToken("TYPE", position, type_name, source);
10178 case Utils::Shader::FRAGMENT:
10181 case Utils::Shader::GEOMETRY:
10184 case Utils::Shader::TESS_CTRL:
10187 case Utils::Shader::TESS_EVAL:
10190 case Utils::Shader::VERTEX:
10194 TCU_FAIL("Invalid enum");
10201 /** Get description of test case
10203 * @param test_case_index Index of test case
10205 * @return Type name and offset
10207 std::string UniformBlockMemberAlignNonPowerOf2Test::getTestCaseName(GLuint test_case_index)
10209 std::stringstream stream;
10210 testCase& test_case = m_test_cases[test_case_index];
10212 stream << "Type: " << test_case.m_type.GetGLSLTypeName() << ", align: " << test_case.m_alignment;
10214 return stream.str();
10217 /** Get number of test cases
10219 * @return Number of test cases
10221 GLuint UniformBlockMemberAlignNonPowerOf2Test::getTestCaseNumber()
10223 return static_cast<GLuint>(m_test_cases.size());
10226 /** Selects if "compute" stage is relevant for test
10228 * @param test_case_index Index of test case
10230 * @return true when tested stage is compute
10232 bool UniformBlockMemberAlignNonPowerOf2Test::isComputeRelevant(GLuint test_case_index)
10234 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
10237 /** Checks if stage is supported
10243 bool UniformBlockMemberAlignNonPowerOf2Test::isStageSupported(Utils::Shader::STAGES /* stage */)
10248 /** Selects if compilation failure is expected result
10250 * @param test_case_index Index of test case
10252 * @return should_fail field from testCase
10254 bool UniformBlockMemberAlignNonPowerOf2Test::isFailureExpected(GLuint test_case_index)
10256 return m_test_cases[test_case_index].m_should_fail;
10259 /** Prepare all test cases
10262 void UniformBlockMemberAlignNonPowerOf2Test::testInit()
10264 static const GLuint dmat4_size = 128;
10265 const GLuint n_types = getTypesNumber();
10266 bool stage_support[Utils::Shader::STAGE_MAX];
10268 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
10270 stage_support[stage] = isStageSupported((Utils::Shader::STAGES)stage);
10273 for (GLuint j = 0; j < n_types; ++j)
10275 const Utils::Type& type = getType(j);
10277 for (GLuint align = 0; align <= dmat4_size; ++align)
10280 #if WRKARD_UNIFORMBLOCKMEMBERALIGNNONPOWEROF2TEST
10282 const bool should_fail = (0 == align) ? false : !isPowerOf2(align);
10284 #else /* WRKARD_UNIFORMBLOCKMEMBERALIGNNONPOWEROF2TEST */
10286 const bool should_fail = !isPowerOf2(align);
10288 #endif /* WRKARD_UNIFORMBLOCKMEMBERALIGNNONPOWEROF2TEST */
10290 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
10292 if (false == stage_support[stage])
10297 testCase test_case = { align, type, should_fail, (Utils::Shader::STAGES)stage };
10299 m_test_cases.push_back(test_case);
10305 /** Check if value is power of 2
10307 * @param val Tested value
10309 * @return true if val is power of 2, false otherwise
10311 bool UniformBlockMemberAlignNonPowerOf2Test::isPowerOf2(GLuint val)
10318 return (0 == (val & (val - 1)));
10323 * @param context Test framework context
10325 UniformBlockAlignmentTest::UniformBlockAlignmentTest(deqp::Context& context)
10326 : TextureTestBase(context, "uniform_block_alignment", "Test verifies offset and alignment of uniform buffer")
10330 /** Get interface of program
10333 * @param program_interface Interface of program
10334 * @param varying_passthrough Collection of connections between in and out variables
10336 void UniformBlockAlignmentTest::getProgramInterface(GLuint /* test_case_index */,
10337 Utils::ProgramInterface& program_interface,
10338 Utils::VaryingPassthrough& varying_passthrough)
10340 static const Utils::Type vec4 = Utils::Type::vec4;
10342 #if WRKARD_UNIFORMBLOCKALIGNMENT
10344 static const GLuint block_align = 16;
10346 #else /* WRKARD_UNIFORMBLOCKALIGNMENT */
10348 static const GLuint block_align = 64;
10350 #endif /* WRKARD_UNIFORMBLOCKALIGNMENT */
10352 static const GLuint vec4_stride = 16;
10353 static const GLuint data_stride = vec4_stride * 2; /* one vec4 + one scalar aligned to 16 */
10355 /*Fixed a test issue, the fifth_offset should be calculated by block_align, instead of fifth_align, according to spec, the actual
10356 alignment of a member will be the greater of the specified alignment and the base aligment for the member type
10358 const GLuint first_offset = 0; /* vec4 at 0 */
10359 const GLuint second_offset = Utils::Type::GetActualOffset(first_offset + vec4_stride, block_align); /* Data at 32 */
10360 const GLuint third_offset =
10361 Utils::Type::GetActualOffset(second_offset + data_stride, block_align); /* Data[2] at 64 */
10362 const GLuint fourth_offset =
10363 Utils::Type::GetActualOffset(third_offset + data_stride * 2, block_align); /* vec4[3] at 96 */
10364 const GLuint fifth_offset =
10365 Utils::Type::GetActualOffset(fourth_offset + vec4_stride * 3, block_align); /* vec4[2] at 160 */
10366 const GLuint sixth_offset =
10367 Utils::Type::GetActualOffset(fifth_offset + vec4_stride * 2, block_align); /* Data at 192 */
10369 Utils::Interface* structure = program_interface.Structure("Data");
10371 structure->Member("vector", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::vec4,
10372 false /* normalized */, 0 /* n_array_elements */, Utils::Type::vec4.GetSize(), 0 /* offset */);
10374 structure->Member("scalar", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::_float,
10375 false /* normalized */, 0 /* n_array_elements */, Utils::Type::_float.GetSize(),
10376 Utils::Type::vec4.GetSize() /* offset */);
10378 /* Prepare Block */
10379 Utils::Interface* vs_uni_block = program_interface.Block("vs_uni_Block");
10381 vs_uni_block->Member("first", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::vec4,
10382 false /* normalized */, 0 /* n_array_elements */, vec4_stride, first_offset /* offset */);
10384 vs_uni_block->Member("second", "", 0 /* expected_component */, 0 /* expected_location */, structure,
10385 0 /* n_array_elements */, data_stride, second_offset);
10387 vs_uni_block->Member("third", "", 0 /* expected_component */, 0 /* expected_location */, structure,
10388 2 /* n_array_elements */, data_stride, third_offset);
10390 vs_uni_block->Member("fourth", "", 0 /* expected_component */, 0 /* expected_location */, vec4,
10391 false /* normalized */, 3 /* n_array_elements */, vec4_stride, fourth_offset);
10393 vs_uni_block->Member("fifth", "layout(align = 64)", 0 /* expected_component */, 0 /* expected_location */, vec4,
10394 false /* normalized */, 2 /* n_array_elements */, vec4_stride, fifth_offset);
10396 vs_uni_block->Member("sixth", "", 0 /* expected_component */, 0 /* expected_location */, structure,
10397 0 /* n_array_elements */, data_stride, sixth_offset);
10399 const GLuint stride = calculateStride(*vs_uni_block);
10400 m_data.resize(stride);
10401 generateData(*vs_uni_block, 0, m_data);
10403 Utils::ShaderInterface& vs_si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
10405 /* Add uniform BLOCK */
10406 #if WRKARD_UNIFORMBLOCKALIGNMENT
10407 vs_si.Uniform("vs_uni_block", "layout (std140, binding = BINDING)", 0, 0, vs_uni_block, 0,
10408 static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
10409 #else /* WRKARD_UNIFORMBLOCKALIGNMENT */
10410 vs_si.Uniform("vs_uni_block", "layout (std140, binding = BINDING, align = 64)", 0, 0, vs_uni_block, 0,
10411 static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
10412 #endif /* WRKARD_UNIFORMBLOCKALIGNMENT */
10414 program_interface.CloneVertexInterface(varying_passthrough);
10419 * @param context Test framework context
10421 SSBMemberOffsetAndAlignTest::SSBMemberOffsetAndAlignTest(deqp::Context& context)
10422 : TextureTestBase(context, "ssb_member_offset_and_align",
10423 "Test verifies offsets and alignment of storage buffer members")
10427 /** Get interface of program
10429 * @param test_case_index Test case index
10430 * @param program_interface Interface of program
10431 * @param varying_passthrough Collection of connections between in and out variables
10433 void SSBMemberOffsetAndAlignTest::getProgramInterface(GLuint test_case_index,
10434 Utils::ProgramInterface& program_interface,
10435 Utils::VaryingPassthrough& varying_passthrough)
10437 std::string globals = "const int basic_size = BASIC_SIZE;\n"
10438 "const int type_align = TYPE_ALIGN;\n"
10439 "const int type_size = TYPE_SIZE;\n";
10441 Utils::Type type = getType(test_case_index);
10442 GLuint basic_size = Utils::Type::GetTypeSize(type.m_basic_type);
10443 const GLuint base_align = type.GetBaseAlignment(false);
10444 const GLuint array_align = type.GetBaseAlignment(true);
10445 const GLuint base_stride = Utils::Type::CalculateStd140Stride(base_align, type.m_n_columns, 0);
10446 const GLuint type_align = Utils::roundUpToPowerOf2(base_stride);
10448 /* Calculate offsets */
10449 const GLuint first_offset = 0;
10450 const GLuint second_offset = type.GetActualOffset(base_stride, basic_size / 2);
10452 #if WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST
10454 const GLuint third_offset = type.GetActualOffset(second_offset + base_stride, base_align);
10455 const GLuint fourth_offset = type.GetActualOffset(third_offset + base_stride, base_align);
10456 const GLuint fifth_offset = type.GetActualOffset(fourth_offset + base_stride, base_align);
10457 const GLuint sixth_offset = type.GetActualOffset(fifth_offset + base_stride, array_align);
10458 const GLuint seventh_offset = type.GetActualOffset(sixth_offset + base_stride, array_align);
10459 const GLuint eigth_offset = type.GetActualOffset(seventh_offset + base_stride, array_align);
10461 #else /* WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST */
10463 const GLuint third_offset = type.GetActualOffset(second_offset + base_stride, 2 * type_align);
10464 const GLuint fourth_offset = type.GetActualOffset(3 * type_align + base_stride, base_align);
10465 const GLuint fifth_offset = type.GetActualOffset(fourth_offset + base_stride, base_align);
10466 const GLuint sixth_offset = type.GetActualOffset(fifth_offset + base_stride, array_align);
10467 const GLuint seventh_offset = type.GetActualOffset(sixth_offset + base_stride, array_align);
10468 const GLuint eigth_offset = type.GetActualOffset(seventh_offset + base_stride, 8 * basic_size);
10470 #endif /* WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST */
10473 const std::vector<GLubyte>& first = type.GenerateData();
10474 const std::vector<GLubyte>& second = type.GenerateData();
10475 const std::vector<GLubyte>& third = type.GenerateData();
10476 const std::vector<GLubyte>& fourth = type.GenerateData();
10478 m_data.resize(eigth_offset + base_stride);
10479 GLubyte* ptr = &m_data[0];
10480 memcpy(ptr + first_offset, &first[0], first.size());
10481 memcpy(ptr + second_offset, &second[0], second.size());
10482 memcpy(ptr + third_offset, &third[0], third.size());
10483 memcpy(ptr + fourth_offset, &fourth[0], fourth.size());
10484 memcpy(ptr + fifth_offset, &fourth[0], fourth.size());
10485 memcpy(ptr + sixth_offset, &third[0], third.size());
10486 memcpy(ptr + seventh_offset, &second[0], second.size());
10487 memcpy(ptr + eigth_offset, &first[0], first.size());
10489 /* Prepare globals */
10490 size_t position = 0;
10493 sprintf(buffer, "%d", basic_size);
10494 Utils::replaceToken("BASIC_SIZE", position, buffer, globals);
10496 sprintf(buffer, "%d", type_align);
10497 Utils::replaceToken("TYPE_ALIGN", position, buffer, globals);
10499 sprintf(buffer, "%d", base_stride);
10500 Utils::replaceToken("TYPE_SIZE", position, buffer, globals);
10502 /* Prepare Block */
10503 Utils::Interface* vs_buf_block = program_interface.Block("vs_buf_Block");
10505 vs_buf_block->Member("at_first_offset", "layout(offset = 0, align = 8 * basic_size)", 0 /* expected_component */,
10506 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
10509 vs_buf_block->Member("at_second_offset", "layout(offset = type_size, align = basic_size / 2)",
10510 0 /* expected_component */, 0 /* expected_location */, type, false /* normalized */,
10511 0 /* n_array_elements */, base_stride, second_offset);
10513 vs_buf_block->Member("at_third_offset", "layout(align = 2 * type_align)", 0 /* expected_component */,
10514 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
10517 vs_buf_block->Member("at_fourth_offset", "layout(offset = 3 * type_align + type_size)", 0 /* expected_component */,
10518 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
10521 vs_buf_block->Member("at_fifth_offset", "", 0 /* expected_component */, 0 /* expected_location */, type,
10522 false /* normalized */, 0 /* n_array_elements */, base_stride, fifth_offset);
10524 vs_buf_block->Member("at_sixth_offset", "", 0 /* expected_component */, 0 /* expected_location */, type,
10525 false /* normalized */, 2 /* n_array_elements */, array_align * 2, sixth_offset);
10527 vs_buf_block->Member("at_eigth_offset", "layout(align = 8 * basic_size)", 0 /* expected_component */,
10528 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
10531 Utils::ShaderInterface& vs_si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
10534 vs_si.m_globals = globals;
10536 /* Add uniform BLOCK */
10537 vs_si.SSB("vs_buf_block", "layout (std140, binding = BINDING)", 0, 0, vs_buf_block, 0,
10538 static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
10541 program_interface.CloneVertexInterface(varying_passthrough);
10546 * @param test_case_index Index of test case
10548 * @return Name of type test in test_case_index
10550 std::string SSBMemberOffsetAndAlignTest::getTestCaseName(glw::GLuint test_case_index)
10552 return getTypeName(test_case_index);
10555 /** Returns number of types to test
10557 * @return Number of types, 34
10559 glw::GLuint SSBMemberOffsetAndAlignTest::getTestCaseNumber()
10561 return getTypesNumber();
10564 /** Prepare code snippet that will verify in and uniform variables
10568 * @param stage Shader stage
10570 * @return Code that verify variables
10572 std::string SSBMemberOffsetAndAlignTest::getVerificationSnippet(GLuint /* test_case_index */,
10573 Utils::ProgramInterface& /* program_interface */,
10574 Utils::Shader::STAGES stage)
10576 std::string verification = "if ( (PREFIXblock.at_first_offset != PREFIXblock.at_eigth_offset ) ||\n"
10577 " (PREFIXblock.at_second_offset != PREFIXblock.at_sixth_offset[1]) ||\n"
10578 " (PREFIXblock.at_third_offset != PREFIXblock.at_sixth_offset[0]) ||\n"
10579 " (PREFIXblock.at_fourth_offset != PREFIXblock.at_fifth_offset ) )\n"
10584 const GLchar* prefix = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::SSB);
10586 Utils::replaceAllTokens("PREFIX", prefix, verification);
10588 return verification;
10591 /** Selects if "draw" stages are relevant for test
10595 * @return true if all stages support shader storage buffers, false otherwise
10597 bool SSBMemberOffsetAndAlignTest::isDrawRelevant(GLuint /* test_case_index */)
10599 const Functions& gl = m_context.getRenderContext().getFunctions();
10600 GLint gs_supported_buffers = 0;
10601 GLint tcs_supported_buffers = 0;
10602 GLint tes_supported_buffers = 0;
10603 GLint vs_supported_buffers = 0;
10605 gl.getIntegerv(GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS, &gs_supported_buffers);
10606 gl.getIntegerv(GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS, &tcs_supported_buffers);
10607 gl.getIntegerv(GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS, &tes_supported_buffers);
10608 gl.getIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &vs_supported_buffers);
10610 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
10612 return ((1 <= gs_supported_buffers) && (1 <= tcs_supported_buffers) && (1 <= tes_supported_buffers) &&
10613 (1 <= vs_supported_buffers));
10618 * @param context Test framework context
10620 SSBLayoutQualifierConflictTest::SSBLayoutQualifierConflictTest(deqp::Context& context)
10621 : NegativeTestBase(context, "ssb_layout_qualifier_conflict", "Test verifies that std140 or std430 is required when "
10622 "offset and/or align qualifiers are used with storage "
10625 /* Nothing to be done here */
10628 /** Source for given test case and stage
10630 * @param test_case_index Index of test case
10631 * @param stage Shader stage
10633 * @return Shader source
10635 std::string SSBLayoutQualifierConflictTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
10637 static const GLchar* cs = "#version 430 core\n"
10638 "#extension GL_ARB_enhanced_layouts : require\n"
10640 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
10642 "layout (QUALIFIERbinding = BINDING) buffer cs_Block {\n"
10643 " layout(offset = 16) vec4 boy;\n"
10644 " layout(align = 64) vec4 man;\n"
10647 "writeonly uniform image2D uni_image;\n"
10651 " vec4 result = uni_block.boy + uni_block.man;\n"
10653 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
10656 static const GLchar* fs = "#version 430 core\n"
10657 "#extension GL_ARB_enhanced_layouts : require\n"
10659 "layout (QUALIFIERbinding = BINDING) buffer Block {\n"
10660 " layout(offset = 16) vec4 boy;\n"
10661 " layout(align = 64) vec4 man;\n"
10665 "out vec4 fs_out;\n"
10669 " fs_out = gs_fs + uni_block.boy + uni_block.man;\n"
10672 static const GLchar* gs = "#version 430 core\n"
10673 "#extension GL_ARB_enhanced_layouts : require\n"
10675 "layout(points) in;\n"
10676 "layout(triangle_strip, max_vertices = 4) out;\n"
10678 "layout (QUALIFIERbinding = BINDING) buffer gs_Block {\n"
10679 " layout(offset = 16) vec4 boy;\n"
10680 " layout(align = 64) vec4 man;\n"
10683 "in vec4 tes_gs[];\n"
10684 "out vec4 gs_fs;\n"
10688 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
10689 " gl_Position = vec4(-1, -1, 0, 1);\n"
10691 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
10692 " gl_Position = vec4(-1, 1, 0, 1);\n"
10694 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
10695 " gl_Position = vec4(1, -1, 0, 1);\n"
10697 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
10698 " gl_Position = vec4(1, 1, 0, 1);\n"
10702 static const GLchar* tcs =
10703 "#version 430 core\n"
10704 "#extension GL_ARB_enhanced_layouts : require\n"
10706 "layout(vertices = 1) out;\n"
10708 "layout (QUALIFIERbinding = BINDING) buffer tcs_Block {\n"
10709 " layout(offset = 16) vec4 boy;\n"
10710 " layout(align = 64) vec4 man;\n"
10713 "in vec4 vs_tcs[];\n"
10714 "out vec4 tcs_tes[];\n"
10719 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID] + uni_block.boy + uni_block.man;\n"
10721 " gl_TessLevelOuter[0] = 1.0;\n"
10722 " gl_TessLevelOuter[1] = 1.0;\n"
10723 " gl_TessLevelOuter[2] = 1.0;\n"
10724 " gl_TessLevelOuter[3] = 1.0;\n"
10725 " gl_TessLevelInner[0] = 1.0;\n"
10726 " gl_TessLevelInner[1] = 1.0;\n"
10729 static const GLchar* tes = "#version 430 core\n"
10730 "#extension GL_ARB_enhanced_layouts : require\n"
10732 "layout(isolines, point_mode) in;\n"
10734 "layout (QUALIFIERbinding = BINDING) buffer tes_Block {\n"
10735 " layout(offset = 16) vec4 boy;\n"
10736 " layout(align = 64) vec4 man;\n"
10739 "in vec4 tcs_tes[];\n"
10740 "out vec4 tes_gs;\n"
10744 " tes_gs = tcs_tes[0] + uni_block.boy + uni_block.man;\n"
10747 static const GLchar* vs = "#version 430 core\n"
10748 "#extension GL_ARB_enhanced_layouts : require\n"
10750 "layout (QUALIFIERbinding = BINDING) buffer vs_Block {\n"
10751 " layout(offset = 16) vec4 boy;\n"
10752 " layout(align = 64) vec4 man;\n"
10756 "out vec4 vs_tcs;\n"
10760 " vs_tcs = in_vs + uni_block.boy + uni_block.man;\n"
10765 size_t position = 0;
10766 std::string source;
10767 testCase& test_case = m_test_cases[test_case_index];
10768 std::string qualifier = getQualifierName(test_case.m_qualifier);
10770 if (false == qualifier.empty())
10772 qualifier.append(", ");
10775 sprintf(buffer, "%d", stage);
10779 case Utils::Shader::COMPUTE:
10782 case Utils::Shader::FRAGMENT:
10785 case Utils::Shader::GEOMETRY:
10788 case Utils::Shader::TESS_CTRL:
10791 case Utils::Shader::TESS_EVAL:
10794 case Utils::Shader::VERTEX:
10798 TCU_FAIL("Invalid enum");
10801 if (test_case.m_stage == stage)
10803 Utils::replaceToken("QUALIFIER", position, qualifier.c_str(), source);
10807 Utils::replaceToken("QUALIFIER", position, "std140, ", source);
10810 Utils::replaceToken("BINDING", position, buffer, source);
10815 /** Get description of test case
10817 * @param test_case_index Index of test case
10819 * @return Qualifier name
10821 std::string SSBLayoutQualifierConflictTest::getTestCaseName(GLuint test_case_index)
10823 std::string result = getQualifierName(m_test_cases[test_case_index].m_qualifier);
10828 /** Get number of test cases
10830 * @return Number of test cases
10832 GLuint SSBLayoutQualifierConflictTest::getTestCaseNumber()
10834 return static_cast<GLuint>(m_test_cases.size());
10837 /** Selects if "compute" stage is relevant for test
10839 * @param test_case_index Index of test case
10841 * @return true when tested stage is compute
10843 bool SSBLayoutQualifierConflictTest::isComputeRelevant(GLuint test_case_index)
10845 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
10848 /** Selects if compilation failure is expected result
10850 * @param test_case_index Index of test case
10852 * @return false for STD140 and STD430 cases, true otherwise
10854 bool SSBLayoutQualifierConflictTest::isFailureExpected(GLuint test_case_index)
10856 const QUALIFIERS qualifier = m_test_cases[test_case_index].m_qualifier;
10858 return !((STD140 == qualifier) || (STD430 == qualifier));
10861 /** Checks if stage is supported
10863 * @param stage Shader stage
10865 * @return true if supported, false otherwise
10867 bool SSBLayoutQualifierConflictTest::isStageSupported(Utils::Shader::STAGES stage)
10869 const Functions& gl = m_context.getRenderContext().getFunctions();
10870 GLint max_supported_buffers = 0;
10875 case Utils::Shader::COMPUTE:
10876 pname = GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS;
10878 case Utils::Shader::FRAGMENT:
10879 pname = GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS;
10881 case Utils::Shader::GEOMETRY:
10882 pname = GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS;
10884 case Utils::Shader::TESS_CTRL:
10885 pname = GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS;
10887 case Utils::Shader::TESS_EVAL:
10888 pname = GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS;
10890 case Utils::Shader::VERTEX:
10891 pname = GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS;
10894 TCU_FAIL("Invalid enum");
10897 gl.getIntegerv(pname, &max_supported_buffers);
10898 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
10900 return 1 <= max_supported_buffers;
10903 /** Prepare all test cases
10906 void SSBLayoutQualifierConflictTest::testInit()
10908 bool stage_support[Utils::Shader::STAGE_MAX];
10910 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
10912 stage_support[stage] = isStageSupported((Utils::Shader::STAGES)stage);
10915 for (GLuint qualifier = 0; qualifier < QUALIFIERS_MAX; ++qualifier)
10917 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
10919 if (false == stage_support[stage])
10924 testCase test_case = { (QUALIFIERS)qualifier, (Utils::Shader::STAGES)stage };
10926 m_test_cases.push_back(test_case);
10931 /** Get name of glsl constant
10933 * @param Constant id
10935 * @return Name of constant used in GLSL
10937 const GLchar* SSBLayoutQualifierConflictTest::getQualifierName(QUALIFIERS qualifier)
10939 const GLchar* name = "";
10959 TCU_FAIL("Invalid enum");
10967 * @param context Test framework context
10969 SSBMemberInvalidOffsetAlignmentTest::SSBMemberInvalidOffsetAlignmentTest(deqp::Context& context)
10970 : UniformBlockMemberInvalidOffsetAlignmentTest(
10971 context, "ssb_member_invalid_offset_alignment",
10972 "Test verifies that invalid alignment of offset qualifiers cause compilation failure")
10974 /* Nothing to be done here */
10977 /** Source for given test case and stage
10979 * @param test_case_index Index of test case
10980 * @param stage Shader stage
10982 * @return Shader source
10984 std::string SSBMemberInvalidOffsetAlignmentTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
10986 static const GLchar* cs = "#version 430 core\n"
10987 "#extension GL_ARB_enhanced_layouts : require\n"
10989 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
10991 "layout (std140) buffer Block {\n"
10992 " layout (offset = OFFSET) TYPE member;\n"
10995 "writeonly uniform image2D uni_image;\n"
10999 " vec4 result = vec4(1, 0, 0.5, 1);\n"
11001 " if (TYPE(1) == block.member)\n"
11003 " result = vec4(1, 1, 1, 1);\n"
11006 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
11009 static const GLchar* fs = "#version 430 core\n"
11010 "#extension GL_ARB_enhanced_layouts : require\n"
11013 "out vec4 fs_out;\n"
11017 " fs_out = gs_fs;\n"
11020 static const GLchar* fs_tested = "#version 430 core\n"
11021 "#extension GL_ARB_enhanced_layouts : require\n"
11023 "layout (std140) buffer Block {\n"
11024 " layout (offset = OFFSET) TYPE member;\n"
11028 "out vec4 fs_out;\n"
11032 " if (TYPE(1) == block.member)\n"
11034 " fs_out = vec4(1, 1, 1, 1);\n"
11037 " fs_out += gs_fs;\n"
11040 static const GLchar* gs = "#version 430 core\n"
11041 "#extension GL_ARB_enhanced_layouts : require\n"
11043 "layout(points) in;\n"
11044 "layout(triangle_strip, max_vertices = 4) out;\n"
11046 "in vec4 tes_gs[];\n"
11047 "out vec4 gs_fs;\n"
11051 " gs_fs = tes_gs[0];\n"
11052 " gl_Position = vec4(-1, -1, 0, 1);\n"
11054 " gs_fs = tes_gs[0];\n"
11055 " gl_Position = vec4(-1, 1, 0, 1);\n"
11057 " gs_fs = tes_gs[0];\n"
11058 " gl_Position = vec4(1, -1, 0, 1);\n"
11060 " gs_fs = tes_gs[0];\n"
11061 " gl_Position = vec4(1, 1, 0, 1);\n"
11065 static const GLchar* gs_tested = "#version 430 core\n"
11066 "#extension GL_ARB_enhanced_layouts : require\n"
11068 "layout(points) in;\n"
11069 "layout(triangle_strip, max_vertices = 4) out;\n"
11071 "layout (std140) buffer Block {\n"
11072 " layout (offset = OFFSET) TYPE member;\n"
11075 "in vec4 tes_gs[];\n"
11076 "out vec4 gs_fs;\n"
11080 " if (TYPE(1) == block.member)\n"
11082 " gs_fs = vec4(1, 1, 1, 1);\n"
11085 " gs_fs += tes_gs[0];\n"
11086 " gl_Position = vec4(-1, -1, 0, 1);\n"
11088 " gs_fs += tes_gs[0];\n"
11089 " gl_Position = vec4(-1, 1, 0, 1);\n"
11091 " gs_fs += tes_gs[0];\n"
11092 " gl_Position = vec4(1, -1, 0, 1);\n"
11094 " gs_fs += tes_gs[0];\n"
11095 " gl_Position = vec4(1, 1, 0, 1);\n"
11099 static const GLchar* tcs = "#version 430 core\n"
11100 "#extension GL_ARB_enhanced_layouts : require\n"
11102 "layout(vertices = 1) out;\n"
11104 "in vec4 vs_tcs[];\n"
11105 "out vec4 tcs_tes[];\n"
11110 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
11112 " gl_TessLevelOuter[0] = 1.0;\n"
11113 " gl_TessLevelOuter[1] = 1.0;\n"
11114 " gl_TessLevelOuter[2] = 1.0;\n"
11115 " gl_TessLevelOuter[3] = 1.0;\n"
11116 " gl_TessLevelInner[0] = 1.0;\n"
11117 " gl_TessLevelInner[1] = 1.0;\n"
11120 static const GLchar* tcs_tested = "#version 430 core\n"
11121 "#extension GL_ARB_enhanced_layouts : require\n"
11123 "layout(vertices = 1) out;\n"
11125 "layout (std140) buffer Block {\n"
11126 " layout (offset = OFFSET) TYPE member;\n"
11129 "in vec4 vs_tcs[];\n"
11130 "out vec4 tcs_tes[];\n"
11134 " if (TYPE(1) == block.member)\n"
11136 " tcs_tes[gl_InvocationID] = vec4(1, 1, 1, 1);\n"
11140 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
11142 " gl_TessLevelOuter[0] = 1.0;\n"
11143 " gl_TessLevelOuter[1] = 1.0;\n"
11144 " gl_TessLevelOuter[2] = 1.0;\n"
11145 " gl_TessLevelOuter[3] = 1.0;\n"
11146 " gl_TessLevelInner[0] = 1.0;\n"
11147 " gl_TessLevelInner[1] = 1.0;\n"
11150 static const GLchar* tes = "#version 430 core\n"
11151 "#extension GL_ARB_enhanced_layouts : require\n"
11153 "layout(isolines, point_mode) in;\n"
11155 "in vec4 tcs_tes[];\n"
11156 "out vec4 tes_gs;\n"
11160 " tes_gs = tcs_tes[0];\n"
11163 static const GLchar* tes_tested = "#version 430 core\n"
11164 "#extension GL_ARB_enhanced_layouts : require\n"
11166 "layout(isolines, point_mode) in;\n"
11168 "layout (std140) buffer Block {\n"
11169 " layout (offset = OFFSET) TYPE member;\n"
11172 "in vec4 tcs_tes[];\n"
11173 "out vec4 tes_gs;\n"
11177 " if (TYPE(1) == block.member)\n"
11179 " tes_gs = vec4(1, 1, 1, 1);\n"
11182 " tes_gs += tcs_tes[0];\n"
11185 static const GLchar* vs = "#version 430 core\n"
11186 "#extension GL_ARB_enhanced_layouts : require\n"
11189 "out vec4 vs_tcs;\n"
11193 " vs_tcs = in_vs;\n"
11196 static const GLchar* vs_tested = "#version 430 core\n"
11197 "#extension GL_ARB_enhanced_layouts : require\n"
11199 "layout (std140) buffer Block {\n"
11200 " layout (offset = OFFSET) TYPE member;\n"
11204 "out vec4 vs_tcs;\n"
11208 " if (TYPE(1) == block.member)\n"
11210 " vs_tcs = vec4(1, 1, 1, 1);\n"
11213 " vs_tcs += in_vs;\n"
11217 std::string source;
11218 testCase& test_case = m_test_cases[test_case_index];
11220 if (test_case.m_stage == stage)
11223 const GLuint offset = test_case.m_offset;
11224 size_t position = 0;
11225 const Utils::Type& type = test_case.m_type;
11226 const GLchar* type_name = type.GetGLSLTypeName();
11228 sprintf(buffer, "%d", offset);
11232 case Utils::Shader::COMPUTE:
11235 case Utils::Shader::FRAGMENT:
11236 source = fs_tested;
11238 case Utils::Shader::GEOMETRY:
11239 source = gs_tested;
11241 case Utils::Shader::TESS_CTRL:
11242 source = tcs_tested;
11244 case Utils::Shader::TESS_EVAL:
11245 source = tes_tested;
11247 case Utils::Shader::VERTEX:
11248 source = vs_tested;
11251 TCU_FAIL("Invalid enum");
11254 Utils::replaceToken("OFFSET", position, buffer, source);
11255 Utils::replaceToken("TYPE", position, type_name, source);
11256 Utils::replaceToken("TYPE", position, type_name, source);
11262 case Utils::Shader::FRAGMENT:
11265 case Utils::Shader::GEOMETRY:
11268 case Utils::Shader::TESS_CTRL:
11271 case Utils::Shader::TESS_EVAL:
11274 case Utils::Shader::VERTEX:
11278 TCU_FAIL("Invalid enum");
11285 /** Checks if stage is supported
11287 * @param stage Shader stage
11289 * @return true if supported, false otherwise
11291 bool SSBMemberInvalidOffsetAlignmentTest::isStageSupported(Utils::Shader::STAGES stage)
11293 const Functions& gl = m_context.getRenderContext().getFunctions();
11294 GLint max_supported_buffers = 0;
11299 case Utils::Shader::COMPUTE:
11300 pname = GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS;
11302 case Utils::Shader::FRAGMENT:
11303 pname = GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS;
11305 case Utils::Shader::GEOMETRY:
11306 pname = GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS;
11308 case Utils::Shader::TESS_CTRL:
11309 pname = GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS;
11311 case Utils::Shader::TESS_EVAL:
11312 pname = GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS;
11314 case Utils::Shader::VERTEX:
11315 pname = GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS;
11318 TCU_FAIL("Invalid enum");
11321 gl.getIntegerv(pname, &max_supported_buffers);
11322 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
11324 return 1 <= max_supported_buffers;
11329 * @param context Test framework context
11331 SSBMemberOverlappingOffsetsTest::SSBMemberOverlappingOffsetsTest(deqp::Context& context)
11332 : UniformBlockMemberOverlappingOffsetsTest(
11333 context, "ssb_member_overlapping_offsets",
11334 "Test verifies that overlapping offsets qualifiers cause compilation failure")
11336 /* Nothing to be done here */
11339 /** Source for given test case and stage
11341 * @param test_case_index Index of test case
11342 * @param stage Shader stage
11344 * @return Shader source
11346 std::string SSBMemberOverlappingOffsetsTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
11348 static const GLchar* cs = "#version 430 core\n"
11349 "#extension GL_ARB_enhanced_layouts : require\n"
11351 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
11353 "layout (std140) buffer Block {\n"
11354 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11355 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11358 "writeonly uniform image2D uni_image;\n"
11362 " vec4 result = vec4(1, 0, 0.5, 1);\n"
11364 " if ((BOY_TYPE(1) == block.boy) ||\n"
11365 " (MAN_TYPE(0) == block.man) )\n"
11367 " result = vec4(1, 1, 1, 1);\n"
11370 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
11373 static const GLchar* fs = "#version 430 core\n"
11374 "#extension GL_ARB_enhanced_layouts : require\n"
11377 "out vec4 fs_out;\n"
11381 " fs_out = gs_fs;\n"
11384 static const GLchar* fs_tested = "#version 430 core\n"
11385 "#extension GL_ARB_enhanced_layouts : require\n"
11387 "layout (std140) buffer Block {\n"
11388 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11389 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11393 "out vec4 fs_out;\n"
11397 " if ((BOY_TYPE(1) == block.boy) ||\n"
11398 " (MAN_TYPE(0) == block.man) )\n"
11400 " fs_out = vec4(1, 1, 1, 1);\n"
11403 " fs_out += gs_fs;\n"
11406 static const GLchar* gs = "#version 430 core\n"
11407 "#extension GL_ARB_enhanced_layouts : require\n"
11409 "layout(points) in;\n"
11410 "layout(triangle_strip, max_vertices = 4) out;\n"
11412 "in vec4 tes_gs[];\n"
11413 "out vec4 gs_fs;\n"
11417 " gs_fs = tes_gs[0];\n"
11418 " gl_Position = vec4(-1, -1, 0, 1);\n"
11420 " gs_fs = tes_gs[0];\n"
11421 " gl_Position = vec4(-1, 1, 0, 1);\n"
11423 " gs_fs = tes_gs[0];\n"
11424 " gl_Position = vec4(1, -1, 0, 1);\n"
11426 " gs_fs = tes_gs[0];\n"
11427 " gl_Position = vec4(1, 1, 0, 1);\n"
11431 static const GLchar* gs_tested = "#version 430 core\n"
11432 "#extension GL_ARB_enhanced_layouts : require\n"
11434 "layout(points) in;\n"
11435 "layout(triangle_strip, max_vertices = 4) out;\n"
11437 "layout (std140) buffer Block {\n"
11438 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11439 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11442 "in vec4 tes_gs[];\n"
11443 "out vec4 gs_fs;\n"
11447 " if ((BOY_TYPE(1) == block.boy) ||\n"
11448 " (MAN_TYPE(0) == block.man) )\n"
11450 " gs_fs = vec4(1, 1, 1, 1);\n"
11453 " gs_fs += tes_gs[0];\n"
11454 " gl_Position = vec4(-1, -1, 0, 1);\n"
11456 " gs_fs += tes_gs[0];\n"
11457 " gl_Position = vec4(-1, 1, 0, 1);\n"
11459 " gs_fs += tes_gs[0];\n"
11460 " gl_Position = vec4(1, -1, 0, 1);\n"
11462 " gs_fs += tes_gs[0];\n"
11463 " gl_Position = vec4(1, 1, 0, 1);\n"
11467 static const GLchar* tcs = "#version 430 core\n"
11468 "#extension GL_ARB_enhanced_layouts : require\n"
11470 "layout(vertices = 1) out;\n"
11472 "in vec4 vs_tcs[];\n"
11473 "out vec4 tcs_tes[];\n"
11478 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
11480 " gl_TessLevelOuter[0] = 1.0;\n"
11481 " gl_TessLevelOuter[1] = 1.0;\n"
11482 " gl_TessLevelOuter[2] = 1.0;\n"
11483 " gl_TessLevelOuter[3] = 1.0;\n"
11484 " gl_TessLevelInner[0] = 1.0;\n"
11485 " gl_TessLevelInner[1] = 1.0;\n"
11488 static const GLchar* tcs_tested = "#version 430 core\n"
11489 "#extension GL_ARB_enhanced_layouts : require\n"
11491 "layout(vertices = 1) out;\n"
11493 "layout (std140) buffer Block {\n"
11494 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11495 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11498 "in vec4 vs_tcs[];\n"
11499 "out vec4 tcs_tes[];\n"
11503 " if ((BOY_TYPE(1) == block.boy) ||\n"
11504 " (MAN_TYPE(0) == block.man) )\n"
11506 " tcs_tes[gl_InvocationID] = vec4(1, 1, 1, 1);\n"
11510 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
11512 " gl_TessLevelOuter[0] = 1.0;\n"
11513 " gl_TessLevelOuter[1] = 1.0;\n"
11514 " gl_TessLevelOuter[2] = 1.0;\n"
11515 " gl_TessLevelOuter[3] = 1.0;\n"
11516 " gl_TessLevelInner[0] = 1.0;\n"
11517 " gl_TessLevelInner[1] = 1.0;\n"
11520 static const GLchar* tes = "#version 430 core\n"
11521 "#extension GL_ARB_enhanced_layouts : require\n"
11523 "layout(isolines, point_mode) in;\n"
11525 "in vec4 tcs_tes[];\n"
11526 "out vec4 tes_gs;\n"
11530 " tes_gs = tcs_tes[0];\n"
11533 static const GLchar* tes_tested = "#version 430 core\n"
11534 "#extension GL_ARB_enhanced_layouts : require\n"
11536 "layout(isolines, point_mode) in;\n"
11538 "layout (std140) buffer Block {\n"
11539 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11540 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11543 "in vec4 tcs_tes[];\n"
11544 "out vec4 tes_gs;\n"
11548 " if ((BOY_TYPE(1) == block.boy) ||\n"
11549 " (MAN_TYPE(0) == block.man) )\n"
11551 " tes_gs = vec4(1, 1, 1, 1);\n"
11554 " tes_gs += tcs_tes[0];\n"
11557 static const GLchar* vs = "#version 430 core\n"
11558 "#extension GL_ARB_enhanced_layouts : require\n"
11561 "out vec4 vs_tcs;\n"
11565 " vs_tcs = in_vs;\n"
11568 static const GLchar* vs_tested = "#version 430 core\n"
11569 "#extension GL_ARB_enhanced_layouts : require\n"
11571 "layout (std140) buffer Block {\n"
11572 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11573 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11577 "out vec4 vs_tcs;\n"
11581 " if ((BOY_TYPE(1) == block.boy) ||\n"
11582 " (MAN_TYPE(0) == block.man) )\n"
11584 " vs_tcs = vec4(1, 1, 1, 1);\n"
11587 " vs_tcs += in_vs;\n"
11591 std::string source;
11592 testCase& test_case = m_test_cases[test_case_index];
11594 if (test_case.m_stage == stage)
11597 const GLuint boy_offset = test_case.m_boy_offset;
11598 const Utils::Type& boy_type = test_case.m_boy_type;
11599 const GLchar* boy_type_name = boy_type.GetGLSLTypeName();
11600 const GLuint man_offset = test_case.m_man_offset;
11601 const Utils::Type& man_type = test_case.m_man_type;
11602 const GLchar* man_type_name = man_type.GetGLSLTypeName();
11603 size_t position = 0;
11607 case Utils::Shader::COMPUTE:
11610 case Utils::Shader::FRAGMENT:
11611 source = fs_tested;
11613 case Utils::Shader::GEOMETRY:
11614 source = gs_tested;
11616 case Utils::Shader::TESS_CTRL:
11617 source = tcs_tested;
11619 case Utils::Shader::TESS_EVAL:
11620 source = tes_tested;
11622 case Utils::Shader::VERTEX:
11623 source = vs_tested;
11626 TCU_FAIL("Invalid enum");
11629 sprintf(buffer, "%d", boy_offset);
11630 Utils::replaceToken("BOY_OFFSET", position, buffer, source);
11631 Utils::replaceToken("BOY_TYPE", position, boy_type_name, source);
11632 sprintf(buffer, "%d", man_offset);
11633 Utils::replaceToken("MAN_OFFSET", position, buffer, source);
11634 Utils::replaceToken("MAN_TYPE", position, man_type_name, source);
11635 Utils::replaceToken("BOY_TYPE", position, boy_type_name, source);
11636 Utils::replaceToken("MAN_TYPE", position, man_type_name, source);
11642 case Utils::Shader::FRAGMENT:
11645 case Utils::Shader::GEOMETRY:
11648 case Utils::Shader::TESS_CTRL:
11651 case Utils::Shader::TESS_EVAL:
11654 case Utils::Shader::VERTEX:
11658 TCU_FAIL("Invalid enum");
11665 /** Checks if stage is supported
11667 * @param stage Shader stage
11669 * @return true if supported, false otherwise
11671 bool SSBMemberOverlappingOffsetsTest::isStageSupported(Utils::Shader::STAGES stage)
11673 const Functions& gl = m_context.getRenderContext().getFunctions();
11674 GLint max_supported_buffers = 0;
11679 case Utils::Shader::COMPUTE:
11680 pname = GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS;
11682 case Utils::Shader::FRAGMENT:
11683 pname = GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS;
11685 case Utils::Shader::GEOMETRY:
11686 pname = GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS;
11688 case Utils::Shader::TESS_CTRL:
11689 pname = GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS;
11691 case Utils::Shader::TESS_EVAL:
11692 pname = GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS;
11694 case Utils::Shader::VERTEX:
11695 pname = GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS;
11698 TCU_FAIL("Invalid enum");
11701 gl.getIntegerv(pname, &max_supported_buffers);
11702 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
11704 return 1 <= max_supported_buffers;
11709 * @param context Test framework context
11711 SSBMemberAlignNonPowerOf2Test::SSBMemberAlignNonPowerOf2Test(deqp::Context& context)
11712 : UniformBlockMemberAlignNonPowerOf2Test(context, "ssb_member_align_non_power_of_2",
11713 "Test verifies that align qualifier requires value that is a power of 2")
11715 /* Nothing to be done here */
11718 /** Source for given test case and stage
11720 * @param test_case_index Index of test case
11721 * @param stage Shader stage
11723 * @return Shader source
11725 std::string SSBMemberAlignNonPowerOf2Test::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
11727 static const GLchar* cs = "#version 430 core\n"
11728 "#extension GL_ARB_enhanced_layouts : require\n"
11730 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
11732 "layout (std140) buffer Block {\n"
11734 " layout (align = ALIGN) TYPE man;\n"
11737 "writeonly uniform image2D uni_image;\n"
11741 " vec4 result = vec4(1, 0, 0.5, 1);\n"
11743 " if (TYPE(0) == block.man)\n"
11745 " result = vec4(1, 1, 1, 1) - block.boy;\n"
11748 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
11751 static const GLchar* fs = "#version 430 core\n"
11752 "#extension GL_ARB_enhanced_layouts : require\n"
11755 "out vec4 fs_out;\n"
11759 " fs_out = gs_fs;\n"
11762 static const GLchar* fs_tested = "#version 430 core\n"
11763 "#extension GL_ARB_enhanced_layouts : require\n"
11765 "layout (std140) buffer Block {\n"
11767 " layout (align = ALIGN) TYPE man;\n"
11771 "out vec4 fs_out;\n"
11775 " if (TYPE(0) == block.man)\n"
11777 " fs_out = block.boy;\n"
11780 " fs_out += gs_fs;\n"
11783 static const GLchar* gs = "#version 430 core\n"
11784 "#extension GL_ARB_enhanced_layouts : require\n"
11786 "layout(points) in;\n"
11787 "layout(triangle_strip, max_vertices = 4) out;\n"
11789 "in vec4 tes_gs[];\n"
11790 "out vec4 gs_fs;\n"
11794 " gs_fs = tes_gs[0];\n"
11795 " gl_Position = vec4(-1, -1, 0, 1);\n"
11797 " gs_fs = tes_gs[0];\n"
11798 " gl_Position = vec4(-1, 1, 0, 1);\n"
11800 " gs_fs = tes_gs[0];\n"
11801 " gl_Position = vec4(1, -1, 0, 1);\n"
11803 " gs_fs = tes_gs[0];\n"
11804 " gl_Position = vec4(1, 1, 0, 1);\n"
11808 static const GLchar* gs_tested = "#version 430 core\n"
11809 "#extension GL_ARB_enhanced_layouts : require\n"
11811 "layout(points) in;\n"
11812 "layout(triangle_strip, max_vertices = 4) out;\n"
11814 "layout (std140) buffer Block {\n"
11816 " layout (align = ALIGN) TYPE man;\n"
11819 "in vec4 tes_gs[];\n"
11820 "out vec4 gs_fs;\n"
11824 " if (TYPE(0) == block.man)\n"
11826 " gs_fs = block.boy;\n"
11829 " gs_fs += tes_gs[0];\n"
11830 " gl_Position = vec4(-1, -1, 0, 1);\n"
11832 " gs_fs += tes_gs[0];\n"
11833 " gl_Position = vec4(-1, 1, 0, 1);\n"
11835 " gs_fs += tes_gs[0];\n"
11836 " gl_Position = vec4(1, -1, 0, 1);\n"
11838 " gs_fs += tes_gs[0];\n"
11839 " gl_Position = vec4(1, 1, 0, 1);\n"
11843 static const GLchar* tcs = "#version 430 core\n"
11844 "#extension GL_ARB_enhanced_layouts : require\n"
11846 "layout(vertices = 1) out;\n"
11848 "in vec4 vs_tcs[];\n"
11849 "out vec4 tcs_tes[];\n"
11854 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
11856 " gl_TessLevelOuter[0] = 1.0;\n"
11857 " gl_TessLevelOuter[1] = 1.0;\n"
11858 " gl_TessLevelOuter[2] = 1.0;\n"
11859 " gl_TessLevelOuter[3] = 1.0;\n"
11860 " gl_TessLevelInner[0] = 1.0;\n"
11861 " gl_TessLevelInner[1] = 1.0;\n"
11864 static const GLchar* tcs_tested = "#version 430 core\n"
11865 "#extension GL_ARB_enhanced_layouts : require\n"
11867 "layout(vertices = 1) out;\n"
11869 "layout (std140) buffer Block {\n"
11871 " layout (align = ALIGN) TYPE man;\n"
11874 "in vec4 vs_tcs[];\n"
11875 "out vec4 tcs_tes[];\n"
11879 " if (TYPE(0) == block.man)\n"
11881 " tcs_tes[gl_InvocationID] = block.boy;\n"
11885 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
11887 " gl_TessLevelOuter[0] = 1.0;\n"
11888 " gl_TessLevelOuter[1] = 1.0;\n"
11889 " gl_TessLevelOuter[2] = 1.0;\n"
11890 " gl_TessLevelOuter[3] = 1.0;\n"
11891 " gl_TessLevelInner[0] = 1.0;\n"
11892 " gl_TessLevelInner[1] = 1.0;\n"
11895 static const GLchar* tes = "#version 430 core\n"
11896 "#extension GL_ARB_enhanced_layouts : require\n"
11898 "layout(isolines, point_mode) in;\n"
11900 "in vec4 tcs_tes[];\n"
11901 "out vec4 tes_gs;\n"
11905 " tes_gs = tcs_tes[0];\n"
11908 static const GLchar* tes_tested = "#version 430 core\n"
11909 "#extension GL_ARB_enhanced_layouts : require\n"
11911 "layout(isolines, point_mode) in;\n"
11913 "layout (std140) buffer Block {\n"
11915 " layout (align = ALIGN) TYPE man;\n"
11918 "in vec4 tcs_tes[];\n"
11919 "out vec4 tes_gs;\n"
11923 " if (TYPE(0) == block.man)\n"
11925 " tes_gs = block.boy;\n"
11928 " tes_gs += tcs_tes[0];\n"
11931 static const GLchar* vs = "#version 430 core\n"
11932 "#extension GL_ARB_enhanced_layouts : require\n"
11935 "out vec4 vs_tcs;\n"
11939 " vs_tcs = in_vs;\n"
11942 static const GLchar* vs_tested = "#version 430 core\n"
11943 "#extension GL_ARB_enhanced_layouts : require\n"
11945 "layout (std140) buffer Block {\n"
11947 " layout (align = ALIGN) TYPE man;\n"
11951 "out vec4 vs_tcs;\n"
11955 " if (TYPE(0) == block.man)\n"
11957 " vs_tcs = block.boy;\n"
11960 " vs_tcs += in_vs;\n"
11964 std::string source;
11965 testCase& test_case = m_test_cases[test_case_index];
11967 if (test_case.m_stage == stage)
11970 const GLuint alignment = test_case.m_alignment;
11971 const Utils::Type& type = test_case.m_type;
11972 const GLchar* type_name = type.GetGLSLTypeName();
11973 size_t position = 0;
11977 case Utils::Shader::COMPUTE:
11980 case Utils::Shader::FRAGMENT:
11981 source = fs_tested;
11983 case Utils::Shader::GEOMETRY:
11984 source = gs_tested;
11986 case Utils::Shader::TESS_CTRL:
11987 source = tcs_tested;
11989 case Utils::Shader::TESS_EVAL:
11990 source = tes_tested;
11992 case Utils::Shader::VERTEX:
11993 source = vs_tested;
11996 TCU_FAIL("Invalid enum");
11999 sprintf(buffer, "%d", alignment);
12000 Utils::replaceToken("ALIGN", position, buffer, source);
12001 Utils::replaceToken("TYPE", position, type_name, source);
12002 Utils::replaceToken("TYPE", position, type_name, source);
12008 case Utils::Shader::FRAGMENT:
12011 case Utils::Shader::GEOMETRY:
12014 case Utils::Shader::TESS_CTRL:
12017 case Utils::Shader::TESS_EVAL:
12020 case Utils::Shader::VERTEX:
12024 TCU_FAIL("Invalid enum");
12031 /** Checks if stage is supported
12033 * @param stage Shader stage
12035 * @return true if supported, false otherwise
12037 bool SSBMemberAlignNonPowerOf2Test::isStageSupported(Utils::Shader::STAGES stage)
12039 const Functions& gl = m_context.getRenderContext().getFunctions();
12040 GLint max_supported_buffers = 0;
12045 case Utils::Shader::COMPUTE:
12046 pname = GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS;
12048 case Utils::Shader::FRAGMENT:
12049 pname = GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS;
12051 case Utils::Shader::GEOMETRY:
12052 pname = GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS;
12054 case Utils::Shader::TESS_CTRL:
12055 pname = GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS;
12057 case Utils::Shader::TESS_EVAL:
12058 pname = GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS;
12060 case Utils::Shader::VERTEX:
12061 pname = GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS;
12064 TCU_FAIL("Invalid enum");
12067 gl.getIntegerv(pname, &max_supported_buffers);
12068 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
12070 return 1 <= max_supported_buffers;
12075 * @param context Test framework context
12077 SSBAlignmentTest::SSBAlignmentTest(deqp::Context& context)
12078 : TextureTestBase(context, "ssb_alignment", "Test verifies offset and alignment of ssb buffer")
12082 /** Get interface of program
12085 * @param program_interface Interface of program
12086 * @param varying_passthrough Collection of connections between in and out variables
12088 void SSBAlignmentTest::getProgramInterface(GLuint /* test_case_index */, Utils::ProgramInterface& program_interface,
12089 Utils::VaryingPassthrough& varying_passthrough)
12091 static const Utils::Type vec4 = Utils::Type::vec4;
12093 #if WRKARD_UNIFORMBLOCKALIGNMENT
12095 static const GLuint block_align = 16;
12097 #else /* WRKARD_UNIFORMBLOCKALIGNMENT */
12099 static const GLuint block_align = 64;
12101 #endif /* WRKARD_UNIFORMBLOCKALIGNMENT */
12103 static const GLuint fifth_align = 16;
12104 static const GLuint vec4_stride = 16;
12105 static const GLuint data_stride = vec4_stride * 2; /* one vec4 + one scalar aligned to 16 */
12107 const GLuint first_offset = 0; /* vec4 at 0 */
12108 const GLuint second_offset = Utils::Type::GetActualOffset(first_offset + vec4_stride, block_align); /* Data at 32 */
12109 const GLuint third_offset =
12110 Utils::Type::GetActualOffset(second_offset + data_stride, block_align); /* Data[2] at 64 */
12111 const GLuint fourth_offset =
12112 Utils::Type::GetActualOffset(third_offset + data_stride * 2, block_align); /* vec4[3] at 96 */
12113 const GLuint fifth_offset =
12114 Utils::Type::GetActualOffset(fourth_offset + vec4_stride * 3, fifth_align); /* vec4[2] at 160 */
12115 const GLuint sixth_offset =
12116 Utils::Type::GetActualOffset(fifth_offset + vec4_stride * 2, block_align); /* Data at 192 */
12118 Utils::Interface* structure = program_interface.Structure("Data");
12120 structure->Member("vector", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::vec4,
12121 false /* normalized */, 0 /* n_array_elements */, Utils::Type::vec4.GetSize(), 0 /* offset */);
12123 structure->Member("scalar", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::_float,
12124 false /* normalized */, 0 /* n_array_elements */, Utils::Type::_float.GetSize(),
12125 Utils::Type::vec4.GetSize() /* offset */);
12127 /* Prepare Block */
12128 Utils::Interface* vs_buf_Block = program_interface.Block("vs_buf_Block");
12130 vs_buf_Block->Member("first", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::vec4,
12131 false /* normalized */, 0 /* n_array_elements */, vec4_stride, first_offset /* offset */);
12133 vs_buf_Block->Member("second", "", 0 /* expected_component */, 0 /* expected_location */, structure,
12134 0 /* n_array_elements */, data_stride, second_offset);
12136 vs_buf_Block->Member("third", "", 0 /* expected_component */, 0 /* expected_location */, structure,
12137 2 /* n_array_elements */, data_stride, third_offset);
12139 vs_buf_Block->Member("fourth", "", 0 /* expected_component */, 0 /* expected_location */, vec4,
12140 false /* normalized */, 3 /* n_array_elements */, vec4_stride, fourth_offset);
12142 vs_buf_Block->Member("fifth", "layout(align = 16)", 0 /* expected_component */, 0 /* expected_location */, vec4,
12143 false /* normalized */, 2 /* n_array_elements */, vec4_stride, fifth_offset);
12145 vs_buf_Block->Member("sixth", "", 0 /* expected_component */, 0 /* expected_location */, structure,
12146 0 /* n_array_elements */, data_stride, sixth_offset);
12148 const GLuint stride = calculateStride(*vs_buf_Block);
12149 m_data.resize(stride);
12150 generateData(*vs_buf_Block, 0, m_data);
12152 Utils::ShaderInterface& vs_si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
12154 /* Add uniform BLOCK */
12155 #if WRKARD_UNIFORMBLOCKALIGNMENT
12156 vs_si.SSB("vs_buf_block", "layout (std140, binding = BINDING)", 0, 0, vs_buf_Block, 0,
12157 static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
12158 #else /* WRKARD_UNIFORMBLOCKALIGNMENT */
12159 vs_si.SSB("vs_buf_block", "layout (std140, binding = BINDING, align = 64)", 0, 0, vs_buf_Block, 0,
12160 static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
12161 #endif /* WRKARD_UNIFORMBLOCKALIGNMENT */
12163 program_interface.CloneVertexInterface(varying_passthrough);
12166 /** Selects if "draw" stages are relevant for test
12170 * @return true if all stages support shader storage buffers, false otherwise
12172 bool SSBAlignmentTest::isDrawRelevant(GLuint /* test_case_index */)
12174 const Functions& gl = m_context.getRenderContext().getFunctions();
12175 GLint gs_supported_buffers = 0;
12176 GLint tcs_supported_buffers = 0;
12177 GLint tes_supported_buffers = 0;
12178 GLint vs_supported_buffers = 0;
12180 gl.getIntegerv(GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS, &gs_supported_buffers);
12181 gl.getIntegerv(GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS, &tcs_supported_buffers);
12182 gl.getIntegerv(GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS, &tes_supported_buffers);
12183 gl.getIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &vs_supported_buffers);
12185 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
12187 return ((1 <= gs_supported_buffers) && (1 <= tcs_supported_buffers) && (1 <= tes_supported_buffers) &&
12188 (1 <= vs_supported_buffers));
12193 * @param context Test framework context
12195 VaryingLocationsTest::VaryingLocationsTest(deqp::Context& context)
12196 : TextureTestBase(context, "varying_locations", "Test verifies that input and output locations are respected")
12202 * @param context Test context
12203 * @param test_name Name of test
12204 * @param test_description Description of test
12206 VaryingLocationsTest::VaryingLocationsTest(deqp::Context& context, const glw::GLchar* test_name,
12207 const glw::GLchar* test_description)
12208 : TextureTestBase(context, test_name, test_description)
12212 /** Get interface of program
12214 * @param test_case_index Test case
12215 * @param program_interface Interface of program
12216 * @param varying_passthrough Collection of connections between in and out variables
12218 void VaryingLocationsTest::getProgramInterface(GLuint test_case_index, Utils::ProgramInterface& program_interface,
12219 Utils::VaryingPassthrough& varying_passthrough)
12221 const Utils::Type type = getType(test_case_index);
12223 m_first_data = type.GenerateDataPacked();
12224 m_last_data = type.GenerateDataPacked();
12226 prepareShaderStage(Utils::Shader::FRAGMENT, type, program_interface, varying_passthrough);
12227 prepareShaderStage(Utils::Shader::GEOMETRY, type, program_interface, varying_passthrough);
12228 prepareShaderStage(Utils::Shader::TESS_CTRL, type, program_interface, varying_passthrough);
12229 prepareShaderStage(Utils::Shader::TESS_EVAL, type, program_interface, varying_passthrough);
12230 prepareShaderStage(Utils::Shader::VERTEX, type, program_interface, varying_passthrough);
12235 * @param test_case_index Index of test case
12237 * @return Name of type test in test_case_index
12239 std::string VaryingLocationsTest::getTestCaseName(glw::GLuint test_case_index)
12241 return getTypeName(test_case_index);
12244 /** Returns number of types to test
12246 * @return Number of types, 34
12248 glw::GLuint VaryingLocationsTest::getTestCaseNumber()
12250 return getTypesNumber();
12253 /** Selects if "compute" stage is relevant for test
12259 bool VaryingLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
12268 std::string VaryingLocationsTest::prepareGlobals(GLint last_in_loc, GLint last_out_loc)
12271 std::string globals = "const uint first_input_location = 0u;\n"
12272 "const uint first_output_location = 0u;\n"
12273 "const uint last_input_location = LAST_INPUTu;\n"
12274 "const uint last_output_location = LAST_OUTPUTu;\n";
12275 size_t position = 100; /* Skip first part */
12277 sprintf(buffer, "%d", last_in_loc);
12278 Utils::replaceToken("LAST_INPUT", position, buffer, globals);
12280 sprintf(buffer, "%d", last_out_loc);
12281 Utils::replaceToken("LAST_OUTPUT", position, buffer, globals);
12289 void VaryingLocationsTest::prepareShaderStage(Utils::Shader::STAGES stage, const Utils::Type& type,
12290 Utils::ProgramInterface& program_interface,
12291 Utils::VaryingPassthrough& varying_passthrough)
12293 const GLuint array_length = 1;
12294 const GLuint first_in_loc = 0;
12295 const GLuint first_out_loc = 0;
12296 const GLuint last_in_loc = getLastInputLocation(stage, type, array_length);
12297 size_t position = 0;
12299 const GLchar* prefix_in = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::VARYING_INPUT);
12301 const GLchar* prefix_out = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::VARYING_OUTPUT);
12303 const GLchar* qual_first_in = "layout (location = first_input_location)";
12304 const GLchar* qual_first_out = "layout (location = first_output_location)";
12305 const GLchar* qual_last_in = "layout (location = last_input_location)";
12306 const GLchar* qual_last_out = "layout (location = last_output_location)";
12308 Utils::ShaderInterface& si = program_interface.GetShaderInterface(stage);
12309 const GLuint type_size = type.GetSize();
12311 std::string first_in_name = "PREFIXfirst";
12312 std::string first_out_name = "PREFIXfirst";
12313 std::string last_in_name = "PREFIXlast";
12314 std::string last_out_name = "PREFIXlast";
12316 Utils::replaceToken("PREFIX", position, prefix_in, first_in_name);
12318 Utils::replaceToken("PREFIX", position, prefix_out, first_out_name);
12320 Utils::replaceToken("PREFIX", position, prefix_in, last_in_name);
12322 Utils::replaceToken("PREFIX", position, prefix_out, last_out_name);
12324 if (Utils::Shader::FRAGMENT == stage)
12326 qual_first_in = "layout (location = first_input_location) flat";
12327 qual_last_in = "layout (location = last_input_location) flat";
12329 if (Utils::Shader::GEOMETRY == stage)
12331 qual_first_out = "layout (location = first_output_location) flat";
12332 qual_last_out = "layout (location = last_output_location) flat";
12335 Utils::Variable* first_in = si.Input(
12336 first_in_name.c_str(), qual_first_in /* qualifiers */, 0 /* expected_componenet */,
12337 first_in_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */, 0u /* n_array_elements */,
12338 0u /* stride */, 0u /* offset */, (GLvoid*)&m_first_data[0] /* data */, m_first_data.size() /* data_size */);
12340 Utils::Variable* last_in =
12341 si.Input(last_in_name.c_str(), qual_last_in /* qualifiers */, 0 /* expected_componenet */,
12342 last_in_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12343 0u /* n_array_elements */, 0u /* stride */, type_size /* offset */,
12344 (GLvoid*)&m_last_data[0] /* data */, m_last_data.size() /* data_size */);
12346 if (Utils::Shader::FRAGMENT != stage)
12348 const GLuint last_out_loc = getLastOutputLocation(stage, type, array_length);
12350 Utils::Variable* first_out =
12351 si.Output(first_out_name.c_str(), qual_first_out /* qualifiers */, 0 /* expected_componenet */,
12352 first_out_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12353 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)&m_first_data[0] /* data */,
12354 m_first_data.size() /* data_size */);
12356 Utils::Variable* last_out = si.Output(
12357 last_out_name.c_str(), qual_last_out /* qualifiers */, 0 /* expected_componenet */,
12358 last_out_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */, 0u /* n_array_elements */,
12359 0u /* stride */, 0u /* offset */, (GLvoid*)&m_last_data[0] /* data */, m_last_data.size() /* data_size */);
12361 si.m_globals = prepareGlobals(last_in_loc, last_out_loc);
12363 varying_passthrough.Add(stage, first_in, first_out);
12364 varying_passthrough.Add(stage, last_in, last_out);
12368 /* No outputs for fragment shader, so last_output_location can be 0 */
12369 si.m_globals = prepareGlobals(last_in_loc, 0);
12373 /** This test should be run with separable programs
12379 bool VaryingLocationsTest::useMonolithicProgram(GLuint /* test_case_index */)
12384 /* Constants used by VertexAttribLocationsTest */
12385 const GLuint VertexAttribLocationsTest::m_base_vertex = 4;
12386 const GLuint VertexAttribLocationsTest::m_base_instance = 2;
12387 const GLuint VertexAttribLocationsTest::m_loc_vertex = 2;
12388 const GLuint VertexAttribLocationsTest::m_loc_instance = 5;
12389 const GLuint VertexAttribLocationsTest::m_n_instances = 4;
12393 * @param context Test framework context
12395 VertexAttribLocationsTest::VertexAttribLocationsTest(deqp::Context& context)
12396 : TextureTestBase(context, "vertex_attrib_locations",
12397 "Test verifies that attribute locations are respected by drawing operations")
12401 /** Execute proper draw command for test case
12403 * @param test_case_index Index of test case
12405 void VertexAttribLocationsTest::executeDrawCall(GLuint test_case_index)
12407 const Functions& gl = m_context.getRenderContext().getFunctions();
12409 switch (test_case_index)
12412 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
12413 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
12415 case DRAWARRAYSINSTANCED:
12416 gl.drawArraysInstanced(GL_PATCHES, 0 /* first */, 1 /* count */, m_n_instances);
12417 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArraysInstanced");
12420 gl.drawElements(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL);
12421 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElements");
12423 case DRAWELEMENTSBASEVERTEX:
12424 gl.drawElementsBaseVertex(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL, m_base_vertex);
12425 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsBaseVertex");
12427 case DRAWELEMENTSINSTANCED:
12428 gl.drawElementsInstanced(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL, m_n_instances);
12429 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsInstanced");
12431 case DRAWELEMENTSINSTANCEDBASEINSTANCE:
12432 gl.drawElementsInstancedBaseInstance(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL, m_n_instances,
12434 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsInstancedBaseInstance");
12436 case DRAWELEMENTSINSTANCEDBASEVERTEX:
12437 gl.drawElementsInstancedBaseVertex(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL, m_n_instances,
12439 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsInstancedBaseVertex");
12441 case DRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCE:
12442 gl.drawElementsInstancedBaseVertexBaseInstance(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL,
12443 m_n_instances, m_base_vertex, m_base_instance);
12444 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsInstancedBaseVertexBaseInstance");
12447 TCU_FAIL("Invalid enum");
12451 /** Get interface of program
12454 * @param program_interface Interface of program
12457 void VertexAttribLocationsTest::getProgramInterface(GLuint /* test_case_index */,
12458 Utils::ProgramInterface& program_interface,
12459 Utils::VaryingPassthrough& /* varying_passthrough */)
12461 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
12464 si.m_globals = "const uint vertex_index_location = 2;\n"
12465 "const uint instance_index_location = 5;\n";
12468 si.Input("vertex_index" /* name */, "layout (location = vertex_index_location)" /* qualifiers */,
12469 0 /* expected_componenet */, m_loc_vertex /* expected_location */, Utils::Type::uint /* type */,
12470 GL_FALSE /* normalized */, 0u /* n_array_elements */, 16 /* stride */, 0u /* offset */,
12471 (GLvoid*)0 /* data */, 0 /* data_size */);
12472 si.Input("instance_index" /* name */, "layout (location = instance_index_location)" /* qualifiers */,
12473 0 /* expected_componenet */, m_loc_instance /* expected_location */, Utils::Type::uint /* type */,
12474 GL_FALSE /* normalized */, 0u /* n_array_elements */, 16 /* stride */, 16u /* offset */,
12475 (GLvoid*)0 /* data */, 0 /* data_size */);
12478 /** Get name of test case
12480 * @param test_case_index Index of test case
12482 * @return Name of test case
12484 std::string VertexAttribLocationsTest::getTestCaseName(glw::GLuint test_case_index)
12486 std::string result;
12488 switch (test_case_index)
12491 result = "DrawArrays";
12493 case DRAWARRAYSINSTANCED:
12494 result = "DrawArraysInstanced";
12497 result = "DrawElements";
12499 case DRAWELEMENTSBASEVERTEX:
12500 result = "DrawElementsBaseVertex";
12502 case DRAWELEMENTSINSTANCED:
12503 result = "DrawElementsInstanced";
12505 case DRAWELEMENTSINSTANCEDBASEINSTANCE:
12506 result = "DrawElementsInstancedBaseInstance";
12508 case DRAWELEMENTSINSTANCEDBASEVERTEX:
12509 result = "DrawElementsInstancedBaseVertex";
12511 case DRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCE:
12512 result = "DrawElementsInstancedBaseVertexBaseInstance";
12515 TCU_FAIL("Invalid enum");
12521 /** Get number of test cases
12523 * @return Number of test cases
12525 GLuint VertexAttribLocationsTest::getTestCaseNumber()
12527 return TESTCASES_MAX;
12530 /** Prepare code snippet that will verify in and uniform variables
12534 * @param stage Shader stage
12536 * @return Code that verify variables
12538 std::string VertexAttribLocationsTest::getVerificationSnippet(GLuint /* test_case_index */,
12539 Utils::ProgramInterface& /* program_interface */,
12540 Utils::Shader::STAGES stage)
12542 std::string verification;
12544 if (Utils::Shader::VERTEX == stage)
12547 #if DEBUG_VERTEX_ATTRIB_LOCATIONS_TEST_VARIABLE
12549 verification = "if (gl_InstanceID != instance_index)\n"
12553 " else if (gl_VertexID != vertex_index)\n"
12560 verification = "if ((gl_VertexID != vertex_index) ||\n"
12561 " (gl_InstanceID != instance_index) )\n"
12573 return verification;
12576 /** Selects if "compute" stage is relevant for test
12582 bool VertexAttribLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
12587 /** Prepare attributes, vertex array object and array buffer
12590 * @param ignored Interface of program
12591 * @param buffer Array buffer
12592 * @param vao Vertex array object
12594 void VertexAttribLocationsTest::prepareAttributes(GLuint test_case_index /* test_case_index */,
12595 Utils::ProgramInterface& /* program_interface */,
12596 Utils::Buffer& buffer, Utils::VertexArray& vao)
12598 static const GLuint vertex_index_data[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
12599 static const GLuint instance_index_data[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
12601 std::vector<GLuint> buffer_data;
12602 buffer_data.resize(8 + 8); /* vertex_index_data + instance_index_data */
12604 GLubyte* ptr = (GLubyte*)&buffer_data[0];
12607 When case index >=2, the test calls glDrawElement*(), such as glDrawElementsBaseVertex(), glDrawElementsInstanced(), glDrawElementsInstancedBaseInstance() and so on,
12608 So we need to change the buffer type as GL_ELEMENT_ARRAY_BUFFER
12610 if (test_case_index >= 2)
12612 buffer.m_buffer = Utils::Buffer::Element;
12617 vao.Attribute(m_loc_vertex /* vertex_index */, Utils::Type::uint, 0 /* array_elements */, false /* normalized */,
12618 0 /* stride */, 0 /* offset */);
12620 vao.Attribute(m_loc_instance /* instance_index */, Utils::Type::uint, 0 /* array_elements */,
12621 false /* normalized */, 0 /* stride */, (GLvoid*)sizeof(vertex_index_data) /* offset */);
12622 // when test_case_index is 5 or 7, the draw call is glDrawElementsInstancedBaseInstance, glDrawElementsInstancedBaseVertexBaseInstance
12623 // the instancecount is 4, the baseinstance is 2, the divisor should be set 2
12624 bool isBaseInstanced = (test_case_index == DRAWELEMENTSINSTANCEDBASEINSTANCE ||
12625 test_case_index == DRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCE);
12626 vao.Divisor(m_context.getRenderContext().getFunctions() /* gl */, m_loc_instance /* instance_index */,
12627 isBaseInstanced ? 2 : 1 /* divisor. 1 - advance once per instance */);
12629 memcpy(ptr + 0, vertex_index_data, sizeof(vertex_index_data));
12630 memcpy(ptr + sizeof(vertex_index_data), instance_index_data, sizeof(instance_index_data));
12632 buffer.Data(Utils::Buffer::StaticDraw, buffer_data.size() * sizeof(GLuint), ptr);
12635 /** This test should be run with separable programs
12641 bool VertexAttribLocationsTest::useMonolithicProgram(GLuint /* test_case_index */)
12648 * @param context Test framework context
12650 VaryingArrayLocationsTest::VaryingArrayLocationsTest(deqp::Context& context)
12651 : VaryingLocationsTest(context, "varying_array_locations",
12652 "Test verifies that input and output locations are respected for arrays")
12659 void VaryingArrayLocationsTest::prepareShaderStage(Utils::Shader::STAGES stage, const Utils::Type& type,
12660 Utils::ProgramInterface& program_interface,
12661 Utils::VaryingPassthrough& varying_passthrough)
12663 const GLuint array_length = 1u;
12664 const GLuint first_in_loc = 0;
12665 const GLuint first_out_loc = 0;
12666 const GLuint last_in_loc = getLastInputLocation(stage, type, array_length);
12667 size_t position = 0;
12669 const GLchar* prefix_in = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::VARYING_INPUT);
12671 const GLchar* prefix_out = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::VARYING_OUTPUT);
12673 const GLchar* qual_first_in = "layout (location = first_input_location)";
12674 const GLchar* qual_first_out = "layout (location = first_output_location)";
12675 const GLchar* qual_last_in = "layout (location = last_input_location)";
12676 const GLchar* qual_last_out = "layout (location = last_output_location)";
12678 Utils::ShaderInterface& si = program_interface.GetShaderInterface(stage);
12679 const GLuint type_size = type.GetSize();
12681 std::string first_in_name = "PREFIXfirst";
12682 std::string first_out_name = "PREFIXfirst";
12683 std::string last_in_name = "PREFIXlast";
12684 std::string last_out_name = "PREFIXlast";
12686 Utils::replaceToken("PREFIX", position, prefix_in, first_in_name);
12688 Utils::replaceToken("PREFIX", position, prefix_out, first_out_name);
12690 Utils::replaceToken("PREFIX", position, prefix_in, last_in_name);
12692 Utils::replaceToken("PREFIX", position, prefix_out, last_out_name);
12694 if (Utils::Shader::FRAGMENT == stage)
12696 qual_first_in = "layout (location = first_input_location) flat";
12697 qual_last_in = "layout (location = last_input_location) flat";
12699 if (Utils::Shader::GEOMETRY == stage)
12701 qual_first_out = "layout (location = first_output_location) flat";
12702 qual_last_out = "layout (location = last_output_location) flat";
12705 Utils::Variable* first_in =
12706 si.Input(first_in_name.c_str(), qual_first_in /* qualifiers */, 0 /* expected_componenet */,
12707 first_in_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12708 array_length /* n_array_elements */, 0u /* stride */, 0u /* offset */,
12709 (GLvoid*)&m_first_data[0] /* data */, m_first_data.size() /* data_size */);
12711 Utils::Variable* last_in =
12712 si.Input(last_in_name.c_str(), qual_last_in /* qualifiers */, 0 /* expected_componenet */,
12713 last_in_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12714 array_length /* n_array_elements */, 0u /* stride */, type_size /* offset */,
12715 (GLvoid*)&m_last_data[0] /* data */, m_last_data.size() /* data_size */);
12717 if (Utils::Shader::FRAGMENT != stage)
12719 const GLuint last_out_loc = getLastOutputLocation(stage, type, array_length);
12721 Utils::Variable* first_out =
12722 si.Output(first_out_name.c_str(), qual_first_out /* qualifiers */, 0 /* expected_componenet */,
12723 first_out_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_out =
12728 si.Output(last_out_name.c_str(), qual_last_out /* qualifiers */, 0 /* expected_componenet */,
12729 last_out_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12730 array_length /* n_array_elements */, 0u /* stride */, 0u /* offset */,
12731 (GLvoid*)&m_last_data[0] /* data */, m_last_data.size() /* data_size */);
12733 si.m_globals = prepareGlobals(last_in_loc, last_out_loc);
12735 varying_passthrough.Add(stage, first_in, first_out);
12736 varying_passthrough.Add(stage, last_in, last_out);
12740 /* No outputs for fragment shader, so last_output_location can be 0 */
12741 si.m_globals = prepareGlobals(last_in_loc, 0);
12747 * @param context Test framework context
12749 VaryingStructureLocationsTest::VaryingStructureLocationsTest(deqp::Context& context)
12750 : TextureTestBase(context, "varying_structure_locations",
12751 "Test verifies that locations are respected when structures are used as in and out ")
12755 /** Prepare code snippet that will pass in variables to out variables
12758 * @param varying_passthrough Collection of connections between in and out variables
12759 * @param stage Shader stage
12761 * @return Code that pass in variables to next stage
12763 std::string VaryingStructureLocationsTest::getPassSnippet(GLuint /* test_case_index */,
12764 Utils::VaryingPassthrough& varying_passthrough,
12765 Utils::Shader::STAGES stage)
12767 std::string result;
12769 if (Utils::Shader::VERTEX != stage)
12771 result = TextureTestBase::getPassSnippet(0, varying_passthrough, stage);
12775 result = " vs_tcs_output[0].single = vs_in_single[0];\n"
12776 " vs_tcs_output[0].array[0] = vs_in_array[0];\n";
12782 /** Get interface of program
12784 * @param test_case_index Test case
12785 * @param program_interface Interface of program
12786 * @param varying_passthrough Collection of connections between in and out variables
12788 void VaryingStructureLocationsTest::getProgramInterface(GLuint test_case_index,
12789 Utils::ProgramInterface& program_interface,
12790 Utils::VaryingPassthrough& varying_passthrough)
12792 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
12793 const Utils::Type type = getType(test_case_index);
12796 // We should call GenerateDataPacked() to generate data, which can make sure the data in shader is correct
12797 m_single_data = type.GenerateDataPacked();
12798 m_array_data = type.GenerateDataPacked();
12800 m_data.resize(m_single_data.size() + m_array_data.size());
12801 GLubyte* ptr = (GLubyte*)&m_data[0];
12802 memcpy(ptr, &m_single_data[0], m_single_data.size());
12803 memcpy(ptr + m_single_data.size(), &m_array_data[0], m_array_data.size());
12805 Utils::Interface* structure = program_interface.Structure("Data");
12807 structure->Member("single", "" /* qualifiers */, 0 /* component */, 0 /* location */, type, false /* normalized */,
12808 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */);
12810 // the second struct member 's location should not be 0, it is based on by how many the locations the first struct member consumed.
12811 structure->Member("array", "" /* qualifiers */, 0 /* component */, type.GetLocations() /* location */, type,
12812 false /* normalized */, 1u /* n_array_elements */, 0u /* stride */, type.GetSize() /* offset */);
12814 si.Input("vs_in_single", "layout (location = 0)", 0 /* component */, 0 /* location */, type, false /* normalized */,
12815 1u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)&m_single_data[0] /* data */,
12816 m_single_data.size() /* data_size */);
12818 si.Input("vs_in_array", "layout (location = 8)", 0 /* component */, 8 /* location */, type, false /* normalized */,
12819 1u /* n_array_elements */, 0u /* stride */, type.GetSize() /* offset */,
12820 (GLvoid*)&m_array_data[0] /* data */, m_array_data.size() /* data_size */);
12822 si.Output("vs_tcs_output", "layout (location = 0)", 0 /* component */, 0 /* location */, structure,
12823 1u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)&m_data[0] /* data */,
12824 m_data.size() /* data_size */);
12826 program_interface.CloneVertexInterface(varying_passthrough);
12831 * @param test_case_index Index of test case
12833 * @return Name of type test in test_case_index
12835 std::string VaryingStructureLocationsTest::getTestCaseName(glw::GLuint test_case_index)
12837 return getTypeName(test_case_index);
12840 /** Returns number of types to test
12842 * @return Number of types, 34
12844 glw::GLuint VaryingStructureLocationsTest::getTestCaseNumber()
12846 return getTypesNumber();
12849 /** Selects if "compute" stage is relevant for test
12855 bool VaryingStructureLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
12860 /** This test should be run with separable programs
12866 bool VaryingStructureLocationsTest::useMonolithicProgram(GLuint /* test_case_index */)
12873 * @param context Test context
12874 * @param test_name Name of test
12875 * @param test_description Description of test
12877 VaryingStructureMemberLocationTest::VaryingStructureMemberLocationTest(deqp::Context& context)
12878 : NegativeTestBase(context, "varying_structure_member_location",
12879 "Test verifies that compiler does not allow location qualifier on member of strucure")
12883 /** Source for given test case and stage
12885 * @param test_case_index Index of test case
12886 * @param stage Shader stage
12888 * @return Shader source
12890 std::string VaryingStructureMemberLocationTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
12892 static const GLchar* struct_definition = "struct Data {\n"
12894 " layout (location = 4) vec4 goten;\n"
12896 static const GLchar* input_var = "in Data data;\n";
12897 static const GLchar* output_var = "out Data data;\n";
12898 static const GLchar* input_use = " result += data.gohan + data.goten;\n";
12899 static const GLchar* output_use = " data.gohan = result / 2;\n"
12900 " data.goten = result / 4 - data.gohan;\n";
12901 static const GLchar* fs = "#version 430 core\n"
12902 "#extension GL_ARB_enhanced_layouts : require\n"
12905 "out vec4 fs_out;\n"
12909 " fs_out = gs_fs;\n"
12912 static const GLchar* fs_tested = "#version 430 core\n"
12913 "#extension GL_ARB_enhanced_layouts : require\n"
12915 "STRUCT_DEFINITION"
12917 "VARIABLE_DEFINITION"
12920 "out vec4 fs_out;\n"
12924 " vec4 result = gs_fs;\n"
12928 " fs_out += result;\n"
12931 static const GLchar* gs = "#version 430 core\n"
12932 "#extension GL_ARB_enhanced_layouts : require\n"
12934 "layout(points) in;\n"
12935 "layout(triangle_strip, max_vertices = 4) out;\n"
12937 "in vec4 tes_gs[];\n"
12938 "out vec4 gs_fs;\n"
12942 " gs_fs = tes_gs[0];\n"
12943 " gl_Position = vec4(-1, -1, 0, 1);\n"
12945 " gs_fs = tes_gs[0];\n"
12946 " gl_Position = vec4(-1, 1, 0, 1);\n"
12948 " gs_fs = tes_gs[0];\n"
12949 " gl_Position = vec4(1, -1, 0, 1);\n"
12951 " gs_fs = tes_gs[0];\n"
12952 " gl_Position = vec4(1, 1, 0, 1);\n"
12956 static const GLchar* gs_tested = "#version 430 core\n"
12957 "#extension GL_ARB_enhanced_layouts : require\n"
12959 "layout(points) in;\n"
12960 "layout(triangle_strip, max_vertices = 4) out;\n"
12962 "STRUCT_DEFINITION"
12964 "VARIABLE_DEFINITION"
12966 "in vec4 tes_gs[];\n"
12967 "out vec4 gs_fs;\n"
12971 " vec4 result = tes_gs[0];\n"
12975 " gs_fs = result;\n"
12976 " gl_Position = vec4(-1, -1, 0, 1);\n"
12978 " gs_fs = result;\n"
12979 " gl_Position = vec4(-1, 1, 0, 1);\n"
12981 " gs_fs = result;\n"
12982 " gl_Position = vec4(1, -1, 0, 1);\n"
12984 " gs_fs = result;\n"
12985 " gl_Position = vec4(1, 1, 0, 1);\n"
12989 static const GLchar* tcs = "#version 430 core\n"
12990 "#extension GL_ARB_enhanced_layouts : require\n"
12992 "layout(vertices = 1) out;\n"
12994 "in vec4 vs_tcs[];\n"
12995 "out vec4 tcs_tes[];\n"
13000 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
13002 " gl_TessLevelOuter[0] = 1.0;\n"
13003 " gl_TessLevelOuter[1] = 1.0;\n"
13004 " gl_TessLevelOuter[2] = 1.0;\n"
13005 " gl_TessLevelOuter[3] = 1.0;\n"
13006 " gl_TessLevelInner[0] = 1.0;\n"
13007 " gl_TessLevelInner[1] = 1.0;\n"
13010 static const GLchar* tcs_tested = "#version 430 core\n"
13011 "#extension GL_ARB_enhanced_layouts : require\n"
13013 "layout(vertices = 1) out;\n"
13015 "STRUCT_DEFINITION"
13017 "VARIABLE_DEFINITION"
13019 "in vec4 vs_tcs[];\n"
13020 "out vec4 tcs_tes[];\n"
13024 " vec4 result = vs_tcs[gl_InvocationID];\n"
13028 " tcs_tes[gl_InvocationID] = result;\n"
13030 " gl_TessLevelOuter[0] = 1.0;\n"
13031 " gl_TessLevelOuter[1] = 1.0;\n"
13032 " gl_TessLevelOuter[2] = 1.0;\n"
13033 " gl_TessLevelOuter[3] = 1.0;\n"
13034 " gl_TessLevelInner[0] = 1.0;\n"
13035 " gl_TessLevelInner[1] = 1.0;\n"
13038 static const GLchar* tes = "#version 430 core\n"
13039 "#extension GL_ARB_enhanced_layouts : require\n"
13041 "layout(isolines, point_mode) in;\n"
13043 "in vec4 tcs_tes[];\n"
13044 "out vec4 tes_gs;\n"
13048 " tes_gs = tcs_tes[0];\n"
13051 static const GLchar* tes_tested = "#version 430 core\n"
13052 "#extension GL_ARB_enhanced_layouts : require\n"
13054 "layout(isolines, point_mode) in;\n"
13056 "STRUCT_DEFINITION"
13058 "VARIABLE_DEFINITION"
13060 "in vec4 tcs_tes[];\n"
13061 "out vec4 tes_gs;\n"
13065 " vec4 result = tcs_tes[0];\n"
13069 " tes_gs += result;\n"
13072 static const GLchar* vs = "#version 430 core\n"
13073 "#extension GL_ARB_enhanced_layouts : require\n"
13076 "out vec4 vs_tcs;\n"
13080 " vs_tcs = in_vs;\n"
13083 static const GLchar* vs_tested = "#version 430 core\n"
13084 "#extension GL_ARB_enhanced_layouts : require\n"
13086 "STRUCT_DEFINITION"
13088 "VARIABLE_DEFINITION"
13091 "out vec4 vs_tcs;\n"
13095 " vec4 result = in_vs;\n"
13099 " vs_tcs += result;\n"
13103 std::string source;
13104 testCase& test_case = m_test_cases[test_case_index];
13105 const GLchar* var_definition = 0;
13106 const GLchar* var_use = 0;
13108 if (true == test_case.m_is_input)
13110 var_definition = input_var;
13111 var_use = input_use;
13115 var_definition = output_var;
13116 var_use = output_use;
13119 if (test_case.m_stage == stage)
13121 size_t position = 0;
13125 case Utils::Shader::FRAGMENT:
13126 source = fs_tested;
13128 case Utils::Shader::GEOMETRY:
13129 source = gs_tested;
13131 case Utils::Shader::TESS_CTRL:
13132 source = tcs_tested;
13134 case Utils::Shader::TESS_EVAL:
13135 source = tes_tested;
13137 case Utils::Shader::VERTEX:
13138 source = vs_tested;
13141 TCU_FAIL("Invalid enum");
13144 Utils::replaceToken("STRUCT_DEFINITION", position, struct_definition, source);
13145 Utils::replaceToken("VARIABLE_DEFINITION", position, var_definition, source);
13146 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
13152 case Utils::Shader::FRAGMENT:
13155 case Utils::Shader::GEOMETRY:
13158 case Utils::Shader::TESS_CTRL:
13161 case Utils::Shader::TESS_EVAL:
13164 case Utils::Shader::VERTEX:
13168 TCU_FAIL("Invalid enum");
13175 /** Get description of test case
13177 * @param test_case_index Index of test case
13179 * @return Test case description
13181 std::string VaryingStructureMemberLocationTest::getTestCaseName(GLuint test_case_index)
13183 std::stringstream stream;
13184 testCase& test_case = m_test_cases[test_case_index];
13186 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", direction: ";
13188 if (true == test_case.m_is_input)
13194 stream << "output";
13197 return stream.str();
13200 /** Get number of test cases
13202 * @return Number of test cases
13204 GLuint VaryingStructureMemberLocationTest::getTestCaseNumber()
13206 return static_cast<GLuint>(m_test_cases.size());
13209 /** Selects if "compute" stage is relevant for test
13215 bool VaryingStructureMemberLocationTest::isComputeRelevant(GLuint /* test_case_index */)
13220 /** Prepare all test cases
13223 void VaryingStructureMemberLocationTest::testInit()
13225 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
13227 if (Utils::Shader::COMPUTE == stage)
13232 testCase test_case_in = { true, (Utils::Shader::STAGES)stage };
13233 testCase test_case_out = { false, (Utils::Shader::STAGES)stage };
13235 m_test_cases.push_back(test_case_in);
13237 if (Utils::Shader::FRAGMENT != stage)
13239 m_test_cases.push_back(test_case_out);
13246 * @param context Test framework context
13248 VaryingBlockLocationsTest::VaryingBlockLocationsTest(deqp::Context& context)
13249 : TextureTestBase(context, "varying_block_locations",
13250 "Test verifies that locations are respected when blocks are used as in and out ")
13254 /** Prepare code snippet that will pass in variables to out variables
13257 * @param varying_passthrough Collection of connections between in and out variables
13258 * @param stage Shader stage
13260 * @return Code that pass in variables to next stage
13262 std::string VaryingBlockLocationsTest::getPassSnippet(GLuint /* test_case_index */,
13263 Utils::VaryingPassthrough& varying_passthrough,
13264 Utils::Shader::STAGES stage)
13266 std::string result;
13268 if (Utils::Shader::VERTEX != stage)
13270 result = TextureTestBase::getPassSnippet(0, varying_passthrough, stage);
13274 result = "vs_tcs_block.third = vs_in_third;\n"
13275 " vs_tcs_block.fourth = vs_in_fourth;\n"
13276 " vs_tcs_block.fifth = vs_in_fifth;\n";
13282 /** Get interface of program
13285 * @param program_interface Interface of program
13286 * @param varying_passthrough Collection of connections between in and out variables
13288 void VaryingBlockLocationsTest::getProgramInterface(GLuint /* test_case_index */,
13289 Utils::ProgramInterface& program_interface,
13290 Utils::VaryingPassthrough& varying_passthrough)
13292 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
13293 const Utils::Type vec4 = Utils::Type::vec4;
13296 m_third_data = vec4.GenerateData();
13297 m_fourth_data = vec4.GenerateData();
13298 m_fifth_data = vec4.GenerateData();
13300 /* Memory layout is different from location layout */
13301 const GLuint fifth_offset = 0u;
13302 const GLuint third_offset = static_cast<GLuint>(fifth_offset + m_fifth_data.size());
13303 const GLuint fourth_offset = static_cast<GLuint>(third_offset + m_fourth_data.size());
13305 m_data.resize(fourth_offset + m_fourth_data.size());
13306 GLubyte* ptr = (GLubyte*)&m_data[0];
13307 memcpy(ptr + third_offset, &m_third_data[0], m_third_data.size());
13308 memcpy(ptr + fourth_offset, &m_fourth_data[0], m_fourth_data.size());
13309 memcpy(ptr + fifth_offset, &m_fifth_data[0], m_fifth_data.size());
13311 Utils::Interface* block = program_interface.Block("vs_tcs_Block");
13313 block->Member("fifth", "" /* qualifiers */, 0 /* component */, 4 /* location */, vec4, false /* normalized */,
13314 0u /* n_array_elements */, 0u /* stride */, fifth_offset /* offset */);
13316 block->Member("third", "layout (location = 2)" /* qualifiers */, 0 /* component */, 2 /* location */, vec4,
13317 false /* normalized */, 0u /* n_array_elements */, 0u /* stride */, third_offset /* offset */);
13319 block->Member("fourth", "" /* qualifiers */, 0 /* component */, 3 /* location */, vec4, false /* normalized */,
13320 0u /* n_array_elements */, 0u /* stride */, fourth_offset /* offset */);
13322 si.Output("vs_tcs_block", "layout (location = 4)", 0 /* component */, 4 /* location */, block,
13323 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)&m_data[0] /* data */,
13324 m_data.size() /* data_size */);
13326 si.Input("vs_in_third", "layout (location = 0)", 0 /* component */, 0 /* location */, vec4, false /* normalized */,
13327 0u /* n_array_elements */, 0u /* stride */, third_offset /* offset */,
13328 (GLvoid*)&m_third_data[0] /* data */, m_third_data.size() /* data_size */);
13330 si.Input("vs_in_fourth", "layout (location = 1)", 0 /* component */, 1 /* location */, vec4, false /* normalized */,
13331 0u /* n_array_elements */, 0u /* stride */, fourth_offset /* offset */,
13332 (GLvoid*)&m_fourth_data[0] /* data */, m_fourth_data.size() /* data_size */);
13334 si.Input("vs_in_fifth", "layout (location = 2)", 0 /* component */, 2 /* location */, vec4, false /* normalized */,
13335 0u /* n_array_elements */, 0u /* stride */, fifth_offset /* offset */,
13336 (GLvoid*)&m_fifth_data[0] /* data */, m_fifth_data.size() /* data_size */);
13338 program_interface.CloneVertexInterface(varying_passthrough);
13341 /** Selects if "compute" stage is relevant for test
13347 bool VaryingBlockLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
13352 /** This test should be run with separable programs
13358 bool VaryingBlockLocationsTest::useMonolithicProgram(GLuint /* test_case_index */)
13365 * @param context Test framework context
13367 VaryingBlockMemberLocationsTest::VaryingBlockMemberLocationsTest(deqp::Context& context)
13368 : NegativeTestBase(
13369 context, "varying_block_member_locations",
13370 "Test verifies that compilation error is reported when not all members of block are qualified with location")
13374 /** Source for given test case and stage
13376 * @param test_case_index Index of test case
13377 * @param stage Shader stage
13379 * @return Shader source
13381 std::string VaryingBlockMemberLocationsTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
13383 static const GLchar* block_definition_all = "Goku {\n"
13384 " layout (location = 2) vec4 gohan;\n"
13385 " layout (location = 4) vec4 goten;\n"
13386 " layout (location = 6) vec4 chichi;\n"
13388 static const GLchar* block_definition_default = "Goku {\n"
13393 static const GLchar* block_definition_one = "Goku {\n"
13395 " layout (location = 4) vec4 goten;\n"
13398 static const GLchar* input_use = " result += gokuINDEX.gohan + gokuINDEX.goten + gokuINDEX.chichi;\n";
13399 static const GLchar* output_use = " gokuINDEX.gohan = result / 2;\n"
13400 " gokuINDEX.goten = result / 4 - gokuINDEX.gohan;\n"
13401 " gokuINDEX.chichi = result / 8 - gokuINDEX.goten;\n";
13402 static const GLchar* fs = "#version 430 core\n"
13403 "#extension GL_ARB_enhanced_layouts : require\n"
13406 "out vec4 fs_out;\n"
13410 " fs_out = gs_fs;\n"
13413 static const GLchar* fs_tested = "#version 430 core\n"
13414 "#extension GL_ARB_enhanced_layouts : require\n"
13416 "DIRECTION BLOCK_DEFINITION"
13419 "out vec4 fs_out;\n"
13423 " vec4 result = gs_fs;\n"
13427 " fs_out = result;\n"
13430 static const GLchar* gs = "#version 430 core\n"
13431 "#extension GL_ARB_enhanced_layouts : require\n"
13433 "layout(points) in;\n"
13434 "layout(triangle_strip, max_vertices = 4) out;\n"
13436 "in vec4 tes_gs[];\n"
13437 "out vec4 gs_fs;\n"
13441 " gs_fs = tes_gs[0];\n"
13442 " gl_Position = vec4(-1, -1, 0, 1);\n"
13444 " gs_fs = tes_gs[0];\n"
13445 " gl_Position = vec4(-1, 1, 0, 1);\n"
13447 " gs_fs = tes_gs[0];\n"
13448 " gl_Position = vec4(1, -1, 0, 1);\n"
13450 " gs_fs = tes_gs[0];\n"
13451 " gl_Position = vec4(1, 1, 0, 1);\n"
13455 static const GLchar* gs_tested = "#version 430 core\n"
13456 "#extension GL_ARB_enhanced_layouts : require\n"
13458 "layout(points) in;\n"
13459 "layout(triangle_strip, max_vertices = 4) out;\n"
13461 "DIRECTION BLOCK_DEFINITION"
13463 "in vec4 tes_gs[];\n"
13464 "out vec4 gs_fs;\n"
13468 " vec4 result = tes_gs[0];\n"
13472 " gs_fs = result;\n"
13473 " gl_Position = vec4(-1, -1, 0, 1);\n"
13475 " gs_fs = result;\n"
13476 " gl_Position = vec4(-1, 1, 0, 1);\n"
13478 " gs_fs = result;\n"
13479 " gl_Position = vec4(1, -1, 0, 1);\n"
13481 " gs_fs = result;\n"
13482 " gl_Position = vec4(1, 1, 0, 1);\n"
13486 static const GLchar* tcs = "#version 430 core\n"
13487 "#extension GL_ARB_enhanced_layouts : require\n"
13489 "layout(vertices = 1) out;\n"
13491 "in vec4 vs_tcs[];\n"
13492 "out vec4 tcs_tes[];\n"
13497 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
13499 " gl_TessLevelOuter[0] = 1.0;\n"
13500 " gl_TessLevelOuter[1] = 1.0;\n"
13501 " gl_TessLevelOuter[2] = 1.0;\n"
13502 " gl_TessLevelOuter[3] = 1.0;\n"
13503 " gl_TessLevelInner[0] = 1.0;\n"
13504 " gl_TessLevelInner[1] = 1.0;\n"
13507 static const GLchar* tcs_tested = "#version 430 core\n"
13508 "#extension GL_ARB_enhanced_layouts : require\n"
13510 "layout(vertices = 1) out;\n"
13512 "DIRECTION BLOCK_DEFINITION"
13514 "in vec4 vs_tcs[];\n"
13515 "out vec4 tcs_tes[];\n"
13519 " vec4 result = vs_tcs[gl_InvocationID];\n"
13523 " tcs_tes[gl_InvocationID] = result;\n"
13525 " gl_TessLevelOuter[0] = 1.0;\n"
13526 " gl_TessLevelOuter[1] = 1.0;\n"
13527 " gl_TessLevelOuter[2] = 1.0;\n"
13528 " gl_TessLevelOuter[3] = 1.0;\n"
13529 " gl_TessLevelInner[0] = 1.0;\n"
13530 " gl_TessLevelInner[1] = 1.0;\n"
13533 static const GLchar* tes = "#version 430 core\n"
13534 "#extension GL_ARB_enhanced_layouts : require\n"
13536 "layout(isolines, point_mode) in;\n"
13538 "in vec4 tcs_tes[];\n"
13539 "out vec4 tes_gs;\n"
13543 " tes_gs = tcs_tes[0];\n"
13546 static const GLchar* tes_tested = "#version 430 core\n"
13547 "#extension GL_ARB_enhanced_layouts : require\n"
13549 "layout(isolines, point_mode) in;\n"
13551 "DIRECTION BLOCK_DEFINITION"
13553 "in vec4 tcs_tes[];\n"
13554 "out vec4 tes_gs;\n"
13558 " vec4 result = tcs_tes[0];\n"
13562 " tes_gs = result;\n"
13565 static const GLchar* vs = "#version 430 core\n"
13566 "#extension GL_ARB_enhanced_layouts : require\n"
13569 "out vec4 vs_tcs;\n"
13573 " vs_tcs = in_vs;\n"
13576 static const GLchar* vs_tested = "#version 430 core\n"
13577 "#extension GL_ARB_enhanced_layouts : require\n"
13579 "DIRECTION BLOCK_DEFINITION"
13582 "out vec4 vs_tcs;\n"
13586 " vec4 result = in_vs;\n"
13590 " vs_tcs = result;\n"
13594 static const GLchar* shaders_in[6][6] = { /* cs */ { 0, 0, 0, 0, 0, 0 },
13595 /* vs */ { 0, vs_tested, tcs, tes, gs, fs },
13596 /* tcs */ { 0, vs_tested, tcs_tested, tes, gs, fs },
13597 /* tes */ { 0, vs, tcs_tested, tes_tested, gs, fs },
13598 /* gs */ { 0, vs, tcs, tes_tested, gs_tested, fs },
13599 /* fs */ { 0, vs, tcs, tes, gs_tested, fs_tested } };
13601 static const GLchar* shaders_out[6][6] = { /* cs */ { 0, 0, 0, 0, 0, 0 },
13602 /* vs */ { 0, vs_tested, tcs_tested, tes, gs, fs },
13603 /* tcs */ { 0, vs, tcs_tested, tes_tested, gs, fs },
13604 /* tes */ { 0, vs, tcs, tes_tested, gs_tested, fs },
13605 /* gs */ { 0, vs, tcs, tes, gs_tested, fs_tested },
13606 /* fs */ { 0, 0, 0, 0, 0, 0 } };
13608 static const bool require_modifications_in[6][6] = {
13609 /* cs */ { false, false, false, false, false, false },
13610 /* vs */ { false, true, false, false, false, false },
13611 /* tcs */ { false, true, true, false, false, false },
13612 /* tes */ { false, false, true, true, false, false },
13613 /* gs */ { false, false, false, true, true, false },
13614 /* fs */ { false, false, false, false, true, true }
13617 static const bool require_modifications_out[6][6] = {
13618 /* cs */ { false, false, false, false, false, false },
13619 /* vs */ { false, true, true, false, false, false },
13620 /* tcs */ { false, false, true, true, false, false },
13621 /* tes */ { false, false, false, true, true, false },
13622 /* gs */ { false, false, false, false, true, true },
13623 /* fs */ { false, false, false, false, false, false }
13626 const GLchar* array = "";
13627 const GLchar* definition = block_definition_default;
13628 const GLchar* direction = "out";
13629 const GLchar* index = "";
13630 bool require_modifications = false;
13631 std::string source;
13632 testCase& test_case = m_test_cases[test_case_index];
13633 const GLchar* var_use = output_use;
13635 if (true == test_case.m_is_input)
13637 require_modifications = require_modifications_in[test_case.m_stage][stage];
13638 source = shaders_in[test_case.m_stage][stage];
13640 if (test_case.m_stage == stage)
13643 var_use = input_use;
13648 require_modifications = require_modifications_out[test_case.m_stage][stage];
13649 source = shaders_out[test_case.m_stage][stage];
13651 if (test_case.m_stage != stage)
13654 var_use = input_use;
13658 if (test_case.m_stage == stage)
13660 if (true == test_case.m_qualify_all)
13662 definition = block_definition_all;
13666 definition = block_definition_one;
13672 case Utils::Shader::FRAGMENT:
13674 case Utils::Shader::GEOMETRY:
13678 case Utils::Shader::TESS_CTRL:
13680 index = "[gl_InvocationID]";
13682 // geometry shader's input must have one more dimension than tessellation evaluation shader's output,
13683 // the GS input block is an array, so the DS output can't be declared as an array
13684 case Utils::Shader::TESS_EVAL:
13686 if (std::string(direction) == std::string("in")) // match HS output and DS input
13691 else // match DS output and GS input
13698 case Utils::Shader::VERTEX:
13701 TCU_FAIL("Invalid enum");
13704 if (true == require_modifications)
13706 size_t position = 0;
13709 Utils::replaceToken("DIRECTION", position, direction, source);
13711 Utils::replaceToken("BLOCK_DEFINITION", position, definition, source);
13713 Utils::replaceToken("ARRAY", position, array, source);
13714 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
13716 Utils::replaceAllTokens("INDEX", index, source);
13722 case Utils::Shader::FRAGMENT:
13725 case Utils::Shader::GEOMETRY:
13728 case Utils::Shader::TESS_CTRL:
13731 case Utils::Shader::TESS_EVAL:
13734 case Utils::Shader::VERTEX:
13738 TCU_FAIL("Invalid enum");
13745 /** Get description of test case
13747 * @param test_case_index Index of test case
13749 * @return Test case description
13751 std::string VaryingBlockMemberLocationsTest::getTestCaseName(GLuint test_case_index)
13753 std::stringstream stream;
13754 testCase& test_case = m_test_cases[test_case_index];
13756 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", direction: ";
13758 if (true == test_case.m_is_input)
13764 stream << "output";
13767 if (true == test_case.m_qualify_all)
13769 stream << ", all members qualified";
13773 stream << ", not all members qualified";
13776 return stream.str();
13779 /** Get number of test cases
13781 * @return Number of test cases
13783 GLuint VaryingBlockMemberLocationsTest::getTestCaseNumber()
13785 return static_cast<GLuint>(m_test_cases.size());
13788 /** Selects if "compute" stage is relevant for test
13794 bool VaryingBlockMemberLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
13799 /** Selects if compilation failure is expected result
13801 * @param test_case_index Index of test case
13803 * @return false when all members are qualified, true otherwise
13805 bool VaryingBlockMemberLocationsTest::isFailureExpected(GLuint test_case_index)
13807 return (true != m_test_cases[test_case_index].m_qualify_all);
13810 /** Prepare all test cases
13813 void VaryingBlockMemberLocationsTest::testInit()
13815 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
13817 if (Utils::Shader::COMPUTE == stage)
13822 testCase test_case_in_all = { true, true, (Utils::Shader::STAGES)stage };
13823 testCase test_case_in_one = { true, false, (Utils::Shader::STAGES)stage };
13824 testCase test_case_out_all = { false, true, (Utils::Shader::STAGES)stage };
13825 testCase test_case_out_one = { false, false, (Utils::Shader::STAGES)stage };
13827 if (Utils::Shader::VERTEX != stage)
13829 m_test_cases.push_back(test_case_in_all);
13830 m_test_cases.push_back(test_case_in_one);
13833 if (Utils::Shader::FRAGMENT != stage)
13835 m_test_cases.push_back(test_case_out_all);
13836 m_test_cases.push_back(test_case_out_one);
13843 * @param context Test framework context
13845 VaryingBlockAutomaticMemberLocationsTest::VaryingBlockAutomaticMemberLocationsTest(deqp::Context& context)
13846 : NegativeTestBase(
13847 context, "varying_block_automatic_member_locations",
13848 "Test verifies that compiler assigns subsequent locations to block members, even if this casue error")
13852 /** Source for given test case and stage
13854 * @param test_case_index Index of test case
13855 * @param stage Shader stage
13857 * @return Shader source
13859 std::string VaryingBlockAutomaticMemberLocationsTest::getShaderSource(GLuint test_case_index,
13860 Utils::Shader::STAGES stage)
13862 static const GLchar* block_definition = "layout (location = 2) DIRECTION DBZ {\n"
13864 " vec4 gohan[4];\n"
13866 " layout (location = 1) vec4 chichi;\n"
13869 static const GLchar* input_use = " result += dbzINDEX.goku + dbzINDEX.gohan[0] + dbzINDEX.gohan[1] + "
13870 "dbzINDEX.gohan[3] + dbzINDEX.gohan[2] + dbzINDEX.goten + dbzINDEX.chichi + "
13872 static const GLchar* output_use = " dbzINDEX.goku = result;\n"
13873 " dbzINDEX.gohan[0] = result / 2;\n"
13874 " dbzINDEX.gohan[1] = result / 2.25;\n"
13875 " dbzINDEX.gohan[2] = result / 2.5;\n"
13876 " dbzINDEX.gohan[3] = result / 2.75;\n"
13877 " dbzINDEX.goten = result / 4 - dbzINDEX.gohan[0] - dbzINDEX.gohan[1] - "
13878 "dbzINDEX.gohan[2] - dbzINDEX.gohan[3];\n"
13879 " dbzINDEX.chichi = result / 8 - dbzINDEX.goten;\n"
13880 " dbzINDEX.pan = result / 16 - dbzINDEX.chichi;\n";
13881 static const GLchar* fs = "#version 430 core\n"
13882 "#extension GL_ARB_enhanced_layouts : require\n"
13885 "out vec4 fs_out;\n"
13889 " fs_out = gs_fs;\n"
13892 static const GLchar* fs_tested = "#version 430 core\n"
13893 "#extension GL_ARB_enhanced_layouts : require\n"
13898 "out vec4 fs_out;\n"
13902 " vec4 result = gs_fs;\n"
13906 " fs_out += result;\n"
13909 static const GLchar* gs = "#version 430 core\n"
13910 "#extension GL_ARB_enhanced_layouts : require\n"
13912 "layout(points) in;\n"
13913 "layout(triangle_strip, max_vertices = 4) out;\n"
13915 "in vec4 tes_gs[];\n"
13916 "out vec4 gs_fs;\n"
13920 " gs_fs = tes_gs[0];\n"
13921 " gl_Position = vec4(-1, -1, 0, 1);\n"
13923 " gs_fs = tes_gs[0];\n"
13924 " gl_Position = vec4(-1, 1, 0, 1);\n"
13926 " gs_fs = tes_gs[0];\n"
13927 " gl_Position = vec4(1, -1, 0, 1);\n"
13929 " gs_fs = tes_gs[0];\n"
13930 " gl_Position = vec4(1, 1, 0, 1);\n"
13934 static const GLchar* gs_tested = "#version 430 core\n"
13935 "#extension GL_ARB_enhanced_layouts : require\n"
13937 "layout(points) in;\n"
13938 "layout(triangle_strip, max_vertices = 4) out;\n"
13942 "in vec4 tes_gs[];\n"
13943 "out vec4 gs_fs;\n"
13947 " vec4 result = tes_gs[0];\n"
13951 " gs_fs = result;\n"
13952 " gl_Position = vec4(-1, -1, 0, 1);\n"
13954 " gs_fs = result;\n"
13955 " gl_Position = vec4(-1, 1, 0, 1);\n"
13957 " gs_fs = result;\n"
13958 " gl_Position = vec4(1, -1, 0, 1);\n"
13960 " gs_fs = result;\n"
13961 " gl_Position = vec4(1, 1, 0, 1);\n"
13965 static const GLchar* tcs = "#version 430 core\n"
13966 "#extension GL_ARB_enhanced_layouts : require\n"
13968 "layout(vertices = 1) out;\n"
13970 "in vec4 vs_tcs[];\n"
13971 "out vec4 tcs_tes[];\n"
13976 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
13978 " gl_TessLevelOuter[0] = 1.0;\n"
13979 " gl_TessLevelOuter[1] = 1.0;\n"
13980 " gl_TessLevelOuter[2] = 1.0;\n"
13981 " gl_TessLevelOuter[3] = 1.0;\n"
13982 " gl_TessLevelInner[0] = 1.0;\n"
13983 " gl_TessLevelInner[1] = 1.0;\n"
13986 static const GLchar* tcs_tested = "#version 430 core\n"
13987 "#extension GL_ARB_enhanced_layouts : require\n"
13989 "layout(vertices = 1) out;\n"
13993 "in vec4 vs_tcs[];\n"
13994 "out vec4 tcs_tes[];\n"
13998 " vec4 result = vs_tcs[gl_InvocationID];\n"
14002 " tcs_tes[gl_InvocationID] = result;\n"
14004 " gl_TessLevelOuter[0] = 1.0;\n"
14005 " gl_TessLevelOuter[1] = 1.0;\n"
14006 " gl_TessLevelOuter[2] = 1.0;\n"
14007 " gl_TessLevelOuter[3] = 1.0;\n"
14008 " gl_TessLevelInner[0] = 1.0;\n"
14009 " gl_TessLevelInner[1] = 1.0;\n"
14012 static const GLchar* tes = "#version 430 core\n"
14013 "#extension GL_ARB_enhanced_layouts : require\n"
14015 "layout(isolines, point_mode) in;\n"
14017 "in vec4 tcs_tes[];\n"
14018 "out vec4 tes_gs;\n"
14022 " tes_gs = tcs_tes[0];\n"
14025 static const GLchar* tes_tested = "#version 430 core\n"
14026 "#extension GL_ARB_enhanced_layouts : require\n"
14028 "layout(isolines, point_mode) in;\n"
14032 "in vec4 tcs_tes[];\n"
14033 "out vec4 tes_gs;\n"
14037 " vec4 result = tcs_tes[0];\n"
14041 " tes_gs += result;\n"
14044 static const GLchar* vs = "#version 430 core\n"
14045 "#extension GL_ARB_enhanced_layouts : require\n"
14048 "out vec4 vs_tcs;\n"
14052 " vs_tcs = in_vs;\n"
14055 static const GLchar* vs_tested = "#version 430 core\n"
14056 "#extension GL_ARB_enhanced_layouts : require\n"
14061 "out vec4 vs_tcs;\n"
14065 " vec4 result = in_vs;\n"
14069 " vs_tcs += result;\n"
14073 const GLchar* array = "";
14074 const GLchar* direction = "out";
14075 const GLchar* index = "";
14076 std::string source;
14077 testCase& test_case = m_test_cases[test_case_index];
14078 const GLchar* var_use = output_use;
14080 if (true == test_case.m_is_input)
14083 var_use = input_use;
14086 if (test_case.m_stage == stage)
14088 size_t position = 0;
14093 case Utils::Shader::FRAGMENT:
14094 source = fs_tested;
14096 case Utils::Shader::GEOMETRY:
14097 source = gs_tested;
14101 case Utils::Shader::TESS_CTRL:
14102 source = tcs_tested;
14104 index = "[gl_InvocationID]";
14106 case Utils::Shader::TESS_EVAL:
14107 source = tes_tested;
14111 case Utils::Shader::VERTEX:
14112 source = vs_tested;
14115 TCU_FAIL("Invalid enum");
14119 Utils::replaceToken("BLOCK_DEFINITION", position, block_definition, source);
14121 Utils::replaceToken("DIRECTION", position, direction, source);
14122 Utils::replaceToken("ARRAY", position, array, source);
14123 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
14125 Utils::replaceAllTokens("INDEX", index, source);
14131 case Utils::Shader::FRAGMENT:
14134 case Utils::Shader::GEOMETRY:
14137 case Utils::Shader::TESS_CTRL:
14140 case Utils::Shader::TESS_EVAL:
14143 case Utils::Shader::VERTEX:
14147 TCU_FAIL("Invalid enum");
14154 /** Get description of test case
14156 * @param test_case_index Index of test case
14158 * @return Test case description
14160 std::string VaryingBlockAutomaticMemberLocationsTest::getTestCaseName(GLuint test_case_index)
14162 std::stringstream stream;
14163 testCase& test_case = m_test_cases[test_case_index];
14165 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", direction: ";
14167 if (true == test_case.m_is_input)
14173 stream << "output";
14176 return stream.str();
14179 /** Get number of test cases
14181 * @return Number of test cases
14183 GLuint VaryingBlockAutomaticMemberLocationsTest::getTestCaseNumber()
14185 return static_cast<GLuint>(m_test_cases.size());
14188 /** Selects if "compute" stage is relevant for test
14194 bool VaryingBlockAutomaticMemberLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
14199 /** Prepare all test cases
14202 void VaryingBlockAutomaticMemberLocationsTest::testInit()
14204 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
14206 if (Utils::Shader::COMPUTE == stage)
14211 testCase test_case_in = { true, (Utils::Shader::STAGES)stage };
14212 testCase test_case_out = { false, (Utils::Shader::STAGES)stage };
14214 if (Utils::Shader::VERTEX != stage)
14216 m_test_cases.push_back(test_case_in);
14219 if (Utils::Shader::FRAGMENT != stage)
14221 m_test_cases.push_back(test_case_out);
14228 * @param context Test framework context
14230 VaryingLocationLimitTest::VaryingLocationLimitTest(deqp::Context& context)
14231 : NegativeTestBase(context, "varying_location_limit",
14232 "Test verifies that compiler reports error when location qualifier exceed limits")
14236 /** Source for given test case and stage
14238 * @param test_case_index Index of test case
14239 * @param stage Shader stage
14241 * @return Shader source
14243 std::string VaryingLocationLimitTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
14245 static const GLchar* var_definition = "layout (location = LAST + 1) FLAT DIRECTION TYPE gokuARRAY;\n";
14246 static const GLchar* input_use = " if (TYPE(0) == gokuINDEX)\n"
14248 " result += vec4(1, 0.5, 0.25, 0.125);\n"
14250 static const GLchar* output_use = " gokuINDEX = TYPE(0);\n"
14251 " if (vec4(0) == result)\n"
14253 " gokuINDEX = TYPE(1);\n"
14255 static const GLchar* fs = "#version 430 core\n"
14256 "#extension GL_ARB_enhanced_layouts : require\n"
14259 "out vec4 fs_out;\n"
14263 " fs_out = gs_fs;\n"
14266 static const GLchar* fs_tested = "#version 430 core\n"
14267 "#extension GL_ARB_enhanced_layouts : require\n"
14272 "out vec4 fs_out;\n"
14276 " vec4 result = gs_fs;\n"
14280 " fs_out += result;\n"
14283 static const GLchar* gs = "#version 430 core\n"
14284 "#extension GL_ARB_enhanced_layouts : require\n"
14286 "layout(points) in;\n"
14287 "layout(triangle_strip, max_vertices = 4) out;\n"
14289 "in vec4 tes_gs[];\n"
14290 "out vec4 gs_fs;\n"
14294 " gs_fs = tes_gs[0];\n"
14295 " gl_Position = vec4(-1, -1, 0, 1);\n"
14297 " gs_fs = tes_gs[0];\n"
14298 " gl_Position = vec4(-1, 1, 0, 1);\n"
14300 " gs_fs = tes_gs[0];\n"
14301 " gl_Position = vec4(1, -1, 0, 1);\n"
14303 " gs_fs = tes_gs[0];\n"
14304 " gl_Position = vec4(1, 1, 0, 1);\n"
14308 static const GLchar* gs_tested = "#version 430 core\n"
14309 "#extension GL_ARB_enhanced_layouts : require\n"
14311 "layout(points) in;\n"
14312 "layout(triangle_strip, max_vertices = 4) out;\n"
14316 "in vec4 tes_gs[];\n"
14317 "out vec4 gs_fs;\n"
14321 " vec4 result = tes_gs[0];\n"
14325 " gs_fs = result;\n"
14326 " gl_Position = vec4(-1, -1, 0, 1);\n"
14328 " gs_fs = result;\n"
14329 " gl_Position = vec4(-1, 1, 0, 1);\n"
14331 " gs_fs = result;\n"
14332 " gl_Position = vec4(1, -1, 0, 1);\n"
14334 " gs_fs = result;\n"
14335 " gl_Position = vec4(1, 1, 0, 1);\n"
14339 static const GLchar* tcs = "#version 430 core\n"
14340 "#extension GL_ARB_enhanced_layouts : require\n"
14342 "layout(vertices = 1) out;\n"
14344 "in vec4 vs_tcs[];\n"
14345 "out vec4 tcs_tes[];\n"
14350 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
14352 " gl_TessLevelOuter[0] = 1.0;\n"
14353 " gl_TessLevelOuter[1] = 1.0;\n"
14354 " gl_TessLevelOuter[2] = 1.0;\n"
14355 " gl_TessLevelOuter[3] = 1.0;\n"
14356 " gl_TessLevelInner[0] = 1.0;\n"
14357 " gl_TessLevelInner[1] = 1.0;\n"
14360 static const GLchar* tcs_tested = "#version 430 core\n"
14361 "#extension GL_ARB_enhanced_layouts : require\n"
14363 "layout(vertices = 1) out;\n"
14367 "in vec4 vs_tcs[];\n"
14368 "out vec4 tcs_tes[];\n"
14372 " vec4 result = vs_tcs[gl_InvocationID];\n"
14376 " tcs_tes[gl_InvocationID] = result;\n"
14378 " gl_TessLevelOuter[0] = 1.0;\n"
14379 " gl_TessLevelOuter[1] = 1.0;\n"
14380 " gl_TessLevelOuter[2] = 1.0;\n"
14381 " gl_TessLevelOuter[3] = 1.0;\n"
14382 " gl_TessLevelInner[0] = 1.0;\n"
14383 " gl_TessLevelInner[1] = 1.0;\n"
14386 static const GLchar* tes = "#version 430 core\n"
14387 "#extension GL_ARB_enhanced_layouts : require\n"
14389 "layout(isolines, point_mode) in;\n"
14391 "in vec4 tcs_tes[];\n"
14392 "out vec4 tes_gs;\n"
14396 " tes_gs = tcs_tes[0];\n"
14399 static const GLchar* tes_tested = "#version 430 core\n"
14400 "#extension GL_ARB_enhanced_layouts : require\n"
14402 "layout(isolines, point_mode) in;\n"
14406 "in vec4 tcs_tes[];\n"
14407 "out vec4 tes_gs;\n"
14411 " vec4 result = tcs_tes[0];\n"
14415 " tes_gs += result;\n"
14418 static const GLchar* vs = "#version 430 core\n"
14419 "#extension GL_ARB_enhanced_layouts : require\n"
14422 "out vec4 vs_tcs;\n"
14426 " vs_tcs = in_vs;\n"
14429 static const GLchar* vs_tested = "#version 430 core\n"
14430 "#extension GL_ARB_enhanced_layouts : require\n"
14435 "out vec4 vs_tcs;\n"
14439 " vec4 result = in_vs;\n"
14443 " vs_tcs += result;\n"
14447 std::string source;
14448 testCase& test_case = m_test_cases[test_case_index];
14450 if (test_case.m_stage == stage)
14452 const GLchar* array = "";
14454 const GLchar* direction = "in ";
14455 const GLchar* flat = "";
14456 const GLchar* index = "";
14457 GLuint last = getLastInputLocation(stage, test_case.m_type, 0);
14458 size_t position = 0;
14460 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
14461 Utils::Variable::STORAGE storage = Utils::Variable::VARYING_INPUT;
14462 const GLchar* var_use = input_use;
14464 if (false == test_case.m_is_input)
14467 last = getLastOutputLocation(stage, test_case.m_type, 0);
14468 storage = Utils::Variable::VARYING_OUTPUT;
14469 var_use = output_use;
14472 if (true == isFlatRequired(stage, test_case.m_type, storage))
14477 sprintf(buffer, "%d", last);
14481 case Utils::Shader::FRAGMENT:
14482 source = fs_tested;
14484 case Utils::Shader::GEOMETRY:
14485 source = gs_tested;
14489 case Utils::Shader::TESS_CTRL:
14490 source = tcs_tested;
14492 index = "[gl_InvocationID]";
14494 case Utils::Shader::TESS_EVAL:
14495 source = tes_tested;
14499 case Utils::Shader::VERTEX:
14500 source = vs_tested;
14503 TCU_FAIL("Invalid enum");
14507 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
14509 Utils::replaceToken("LAST", position, buffer, source);
14510 Utils::replaceToken("FLAT", position, flat, source);
14511 Utils::replaceToken("DIRECTION", position, direction, source);
14512 Utils::replaceToken("ARRAY", position, array, source);
14513 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
14515 Utils::replaceAllTokens("TYPE", type_name, source);
14516 Utils::replaceAllTokens("INDEX", index, source);
14522 case Utils::Shader::FRAGMENT:
14525 case Utils::Shader::GEOMETRY:
14528 case Utils::Shader::TESS_CTRL:
14531 case Utils::Shader::TESS_EVAL:
14534 case Utils::Shader::VERTEX:
14538 TCU_FAIL("Invalid enum");
14545 /** Get description of test case
14547 * @param test_case_index Index of test case
14549 * @return Test case description
14551 std::string VaryingLocationLimitTest::getTestCaseName(GLuint test_case_index)
14553 std::stringstream stream;
14554 testCase& test_case = m_test_cases[test_case_index];
14556 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
14557 << " type: " << test_case.m_type.GetGLSLTypeName() << ", direction: ";
14559 if (true == test_case.m_is_input)
14565 stream << "output";
14568 return stream.str();
14571 /** Get number of test cases
14573 * @return Number of test cases
14575 GLuint VaryingLocationLimitTest::getTestCaseNumber()
14577 return static_cast<GLuint>(m_test_cases.size());
14580 /** Selects if "compute" stage is relevant for test
14586 bool VaryingLocationLimitTest::isComputeRelevant(GLuint /* test_case_index */)
14591 /** Prepare all test cases
14594 void VaryingLocationLimitTest::testInit()
14596 const GLuint n_types = getTypesNumber();
14598 for (GLuint i = 0; i < n_types; ++i)
14600 const Utils::Type& type = getType(i);
14602 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
14604 if (Utils::Shader::COMPUTE == stage)
14609 testCase test_case_in = { true, type, (Utils::Shader::STAGES)stage };
14610 testCase test_case_out = { false, type, (Utils::Shader::STAGES)stage };
14612 m_test_cases.push_back(test_case_in);
14614 if (Utils::Shader::FRAGMENT != stage)
14616 m_test_cases.push_back(test_case_out);
14624 * @param context Test framework context
14626 VaryingComponentsTest::VaryingComponentsTest(deqp::Context& context)
14627 : VaryingLocationsTest(context, "varying_components",
14628 "Test verifies that input and output components are respected")
14634 * @param context Test framework context
14635 * @param test_name Name of test
14636 * @param test_description Description of test
14638 VaryingComponentsTest::VaryingComponentsTest(deqp::Context& context, const glw::GLchar* test_name,
14639 const glw::GLchar* test_description)
14640 : VaryingLocationsTest(context, test_name, test_description)
14644 /** Get interface of program
14646 * @param test_case_index Test case
14647 * @param program_interface Interface of program
14648 * @param varying_passthrough Collection of connections between in and out variables
14650 void VaryingComponentsTest::getProgramInterface(GLuint test_case_index, Utils::ProgramInterface& program_interface,
14651 Utils::VaryingPassthrough& varying_passthrough)
14653 GLuint array_length = getArrayLength();
14654 const testCase& test_case = m_test_cases[test_case_index];
14655 const Utils::Type vector_type = Utils::Type::GetType(test_case.m_type, 1, 4);
14656 Utils::ShaderInterface si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
14658 /* Zero means no array, however we still need at least 1 slot of data */
14659 if (0 == array_length)
14664 /* Generate data */
14665 const std::vector<GLubyte>& data = vector_type.GenerateDataPacked();
14666 const size_t data_size = data.size();
14668 /* Prepare data for variables */
14669 m_data.resize(array_length * data_size);
14671 GLubyte* dst = &m_data[0];
14672 const GLubyte* src = &data[0];
14674 for (GLuint i = 0; i < array_length; ++i)
14676 memcpy(dst + data_size * i, src, data_size);
14679 /* Prepare interface for each stage */
14680 prepareShaderStage(Utils::Shader::FRAGMENT, vector_type, program_interface, test_case, varying_passthrough);
14681 prepareShaderStage(Utils::Shader::GEOMETRY, vector_type, program_interface, test_case, varying_passthrough);
14682 prepareShaderStage(Utils::Shader::TESS_CTRL, vector_type, program_interface, test_case, varying_passthrough);
14683 prepareShaderStage(Utils::Shader::TESS_EVAL, vector_type, program_interface, test_case, varying_passthrough);
14684 prepareShaderStage(Utils::Shader::VERTEX, vector_type, program_interface, test_case, varying_passthrough);
14689 * @param test_case_index Index of test case
14691 * @return Name of type test in test_case_index
14693 std::string VaryingComponentsTest::getTestCaseName(glw::GLuint test_case_index)
14697 const testCase& test_case = m_test_cases[test_case_index];
14701 switch (test_case.m_type)
14703 case Utils::Type::Double:
14704 name.append(Utils::Type::_double.GetGLSLTypeName());
14706 case Utils::Type::Float:
14707 name.append(Utils::Type::_float.GetGLSLTypeName());
14709 case Utils::Type::Int:
14710 name.append(Utils::Type::_int.GetGLSLTypeName());
14712 case Utils::Type::Uint:
14713 name.append(Utils::Type::uint.GetGLSLTypeName());
14717 name.append(", layout: ");
14719 switch (test_case.m_layout)
14722 name.append("GVEC4");
14725 name.append("SCALAR_GVEC3");
14728 name.append("GVEC3_SCALAR");
14731 name.append("GVEC2_GVEC2");
14733 case GVEC2_SCALAR_SCALAR:
14734 name.append("GVEC2_SCALAR_SCALAR");
14736 case SCALAR_GVEC2_SCALAR:
14737 name.append("SCALAR_GVEC2_SCALAR");
14739 case SCALAR_SCALAR_GVEC2:
14740 name.append("SCALAR_SCALAR_GVEC2");
14742 case SCALAR_SCALAR_SCALAR_SCALAR:
14743 name.append("SCALAR_SCALAR_SCALAR_SCALAR");
14750 /** Returns number of types to test
14752 * @return Number of types, 34
14754 glw::GLuint VaryingComponentsTest::getTestCaseNumber()
14756 return static_cast<GLuint>(m_test_cases.size());
14759 /* Prepare test cases */
14760 void VaryingComponentsTest::testInit()
14762 m_test_cases.push_back(testCase(GVEC4, Utils::Type::Double));
14763 m_test_cases.push_back(testCase(SCALAR_GVEC3, Utils::Type::Double));
14764 m_test_cases.push_back(testCase(GVEC3_SCALAR, Utils::Type::Double));
14765 m_test_cases.push_back(testCase(GVEC2_GVEC2, Utils::Type::Double));
14766 m_test_cases.push_back(testCase(GVEC2_SCALAR_SCALAR, Utils::Type::Double));
14767 m_test_cases.push_back(testCase(SCALAR_GVEC2_SCALAR, Utils::Type::Double));
14768 m_test_cases.push_back(testCase(SCALAR_SCALAR_GVEC2, Utils::Type::Double));
14769 m_test_cases.push_back(testCase(SCALAR_SCALAR_SCALAR_SCALAR, Utils::Type::Double));
14771 m_test_cases.push_back(testCase(GVEC4, Utils::Type::Float));
14772 m_test_cases.push_back(testCase(SCALAR_GVEC3, Utils::Type::Float));
14773 m_test_cases.push_back(testCase(GVEC3_SCALAR, Utils::Type::Float));
14774 m_test_cases.push_back(testCase(GVEC2_GVEC2, Utils::Type::Float));
14775 m_test_cases.push_back(testCase(GVEC2_SCALAR_SCALAR, Utils::Type::Float));
14776 m_test_cases.push_back(testCase(SCALAR_GVEC2_SCALAR, Utils::Type::Float));
14777 m_test_cases.push_back(testCase(SCALAR_SCALAR_GVEC2, Utils::Type::Float));
14778 m_test_cases.push_back(testCase(SCALAR_SCALAR_SCALAR_SCALAR, Utils::Type::Float));
14780 m_test_cases.push_back(testCase(GVEC4, Utils::Type::Int));
14781 m_test_cases.push_back(testCase(SCALAR_GVEC3, Utils::Type::Int));
14782 m_test_cases.push_back(testCase(GVEC3_SCALAR, Utils::Type::Int));
14783 m_test_cases.push_back(testCase(GVEC2_GVEC2, Utils::Type::Int));
14784 m_test_cases.push_back(testCase(GVEC2_SCALAR_SCALAR, Utils::Type::Int));
14785 m_test_cases.push_back(testCase(SCALAR_GVEC2_SCALAR, Utils::Type::Int));
14786 m_test_cases.push_back(testCase(SCALAR_SCALAR_GVEC2, Utils::Type::Int));
14787 m_test_cases.push_back(testCase(SCALAR_SCALAR_SCALAR_SCALAR, Utils::Type::Int));
14789 m_test_cases.push_back(testCase(GVEC4, Utils::Type::Uint));
14790 m_test_cases.push_back(testCase(SCALAR_GVEC3, Utils::Type::Uint));
14791 m_test_cases.push_back(testCase(GVEC3_SCALAR, Utils::Type::Uint));
14792 m_test_cases.push_back(testCase(GVEC2_GVEC2, Utils::Type::Uint));
14793 m_test_cases.push_back(testCase(GVEC2_SCALAR_SCALAR, Utils::Type::Uint));
14794 m_test_cases.push_back(testCase(SCALAR_GVEC2_SCALAR, Utils::Type::Uint));
14795 m_test_cases.push_back(testCase(SCALAR_SCALAR_GVEC2, Utils::Type::Uint));
14796 m_test_cases.push_back(testCase(SCALAR_SCALAR_SCALAR_SCALAR, Utils::Type::Uint));
14799 /** Inform that test use components
14805 bool VaryingComponentsTest::useComponentQualifier(glw::GLuint /* test_case_index */)
14810 /** Get length of arrays that should be used during test
14812 * @return 0u - no array at all
14814 GLuint VaryingComponentsTest::getArrayLength()
14819 std::string VaryingComponentsTest::prepareGlobals(GLuint last_in_location, GLuint last_out_location)
14821 std::string globals = VaryingLocationsTest::prepareGlobals(last_in_location, last_out_location);
14823 globals.append("const uint comp_x = 0u;\n"
14824 "const uint comp_y = 1u;\n"
14825 "const uint comp_z = 2u;\n"
14826 "const uint comp_w = 3u;\n");
14834 std::string VaryingComponentsTest::prepareName(const glw::GLchar* name, glw::GLint location, glw::GLint component,
14835 Utils::Shader::STAGES stage, Utils::Variable::STORAGE storage)
14838 std::string result = "PREFIXNAME_lLOCATION_cCOMPONENT";
14839 size_t position = 0;
14840 const GLchar* prefix = Utils::ProgramInterface::GetStagePrefix(stage, storage);
14842 Utils::replaceToken("PREFIX", position, prefix, result);
14843 Utils::replaceToken("NAME", position, name, result);
14845 sprintf(buffer, "%d", location);
14846 Utils::replaceToken("LOCATION", position, buffer, result);
14848 sprintf(buffer, "%d", component);
14849 Utils::replaceToken("COMPONENT", position, buffer, result);
14854 std::string VaryingComponentsTest::prepareQualifiers(const glw::GLchar* location, const glw::GLchar* component,
14855 const glw::GLchar* interpolation)
14857 size_t position = 0;
14858 std::string qualifiers = "layout (location = LOCATION, component = COMPONENT) INTERPOLATION";
14860 Utils::replaceToken("LOCATION", position, location, qualifiers);
14861 Utils::replaceToken("COMPONENT", position, component, qualifiers);
14862 Utils::replaceToken("INTERPOLATION", position, interpolation, qualifiers);
14870 void VaryingComponentsTest::prepareShaderStage(Utils::Shader::STAGES stage, const Utils::Type& vector_type,
14871 Utils::ProgramInterface& program_interface, const testCase& test_case,
14872 Utils::VaryingPassthrough& varying_passthrough)
14874 const GLuint array_length = getArrayLength();
14875 const Utils::Type& basic_type = Utils::Type::GetType(vector_type.m_basic_type, 1 /* n_cols */, 1 /* n_rows */);
14876 descriptor desc_in[8];
14877 descriptor desc_out[8];
14878 const GLuint first_in_loc = 0;
14879 const GLuint first_out_loc = 0;
14880 const GLchar* interpolation = "";
14881 const GLuint last_in_loc = getLastInputLocation(stage, vector_type, array_length);
14882 GLuint last_out_loc = 0;
14884 Utils::ShaderInterface& si = program_interface.GetShaderInterface(stage);
14886 /* Select interpolation */
14887 if ((Utils::Shader::FRAGMENT == stage) || (Utils::Shader::GEOMETRY == stage))
14889 interpolation = " flat";
14892 if (Utils::Shader::FRAGMENT != stage)
14894 last_out_loc = getLastOutputLocation(stage, vector_type, array_length);
14897 switch (test_case.m_layout)
14901 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 4, "gvec4");
14902 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 4, "gvec4");
14904 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 4, "gvec4");
14905 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 4, "gvec4");
14909 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "scalar");
14910 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "scalar");
14911 desc_in[2].assign(1, "comp_y", first_in_loc, "first_input_location", 3, "gvec3");
14912 desc_in[3].assign(1, "comp_y", last_in_loc, "last_input_location", 3, "gvec3");
14914 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "scalar");
14915 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "scalar");
14916 desc_out[2].assign(1, "comp_y", first_out_loc, "first_output_location", 3, "gvec3");
14917 desc_out[3].assign(1, "comp_y", last_out_loc, "last_output_location", 3, "gvec3");
14921 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 3, "gvec3");
14922 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 3, "gvec3");
14923 desc_in[2].assign(3, "comp_w", first_in_loc, "first_input_location", 1, "scalar");
14924 desc_in[3].assign(3, "comp_w", last_in_loc, "last_input_location", 1, "scalar");
14926 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 3, "gvec3");
14927 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 3, "gvec3");
14928 desc_out[2].assign(3, "comp_w", first_out_loc, "first_output_location", 1, "scalar");
14929 desc_out[3].assign(3, "comp_w", last_out_loc, "last_output_location", 1, "scalar");
14933 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 2, "gvec2");
14934 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 2, "gvec2");
14935 desc_in[2].assign(2, "comp_z", first_in_loc, "first_input_location", 2, "gvec2");
14936 desc_in[3].assign(2, "comp_z", last_in_loc, "last_input_location", 2, "gvec2");
14938 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 2, "gvec2");
14939 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 2, "gvec2");
14940 desc_out[2].assign(2, "comp_z", first_out_loc, "first_output_location", 2, "gvec2");
14941 desc_out[3].assign(2, "comp_z", last_out_loc, "last_output_location", 2, "gvec2");
14943 case GVEC2_SCALAR_SCALAR:
14945 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 2, "gvec2");
14946 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 2, "gvec2");
14947 desc_in[2].assign(2, "comp_z", first_in_loc, "first_input_location", 1, "scalar");
14948 desc_in[3].assign(2, "comp_z", last_in_loc, "last_input_location", 1, "scalar");
14949 desc_in[4].assign(3, "comp_w", first_in_loc, "first_input_location", 1, "scalar");
14950 desc_in[5].assign(3, "comp_w", last_in_loc, "last_input_location", 1, "scalar");
14952 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 2, "gvec2");
14953 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 2, "gvec2");
14954 desc_out[2].assign(2, "comp_z", first_out_loc, "first_output_location", 1, "scalar");
14955 desc_out[3].assign(2, "comp_z", last_out_loc, "last_output_location", 1, "scalar");
14956 desc_out[4].assign(3, "comp_w", first_out_loc, "first_output_location", 1, "scalar");
14957 desc_out[5].assign(3, "comp_w", last_out_loc, "last_output_location", 1, "scalar");
14959 case SCALAR_GVEC2_SCALAR:
14961 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "scalar");
14962 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "scalar");
14963 desc_in[2].assign(1, "comp_y", first_in_loc, "first_input_location", 2, "gvec2");
14964 desc_in[3].assign(1, "comp_y", last_in_loc, "last_input_location", 2, "gvec2");
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", 1, "scalar");
14969 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "scalar");
14970 desc_out[2].assign(1, "comp_y", first_out_loc, "first_output_location", 2, "gvec2");
14971 desc_out[3].assign(1, "comp_y", last_out_loc, "last_output_location", 2, "gvec2");
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_SCALAR_GVEC2:
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", 1, "scalar");
14980 desc_in[3].assign(1, "comp_y", last_in_loc, "last_input_location", 1, "scalar");
14981 desc_in[4].assign(2, "comp_z", first_in_loc, "first_input_location", 2, "gvec2");
14982 desc_in[5].assign(2, "comp_z", last_in_loc, "last_input_location", 2, "gvec2");
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", 1, "scalar");
14987 desc_out[3].assign(1, "comp_y", last_out_loc, "last_output_location", 1, "scalar");
14988 desc_out[4].assign(2, "comp_z", first_out_loc, "first_output_location", 2, "gvec2");
14989 desc_out[5].assign(2, "comp_z", last_out_loc, "last_output_location", 2, "gvec2");
14991 case SCALAR_SCALAR_SCALAR_SCALAR:
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", 1, "scalar");
14998 desc_in[5].assign(2, "comp_z", last_in_loc, "last_input_location", 1, "scalar");
14999 desc_in[6].assign(3, "comp_w", first_in_loc, "first_input_location", 1, "scalar");
15000 desc_in[7].assign(3, "comp_w", last_in_loc, "last_input_location", 1, "scalar");
15002 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "scalar");
15003 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "scalar");
15004 desc_out[2].assign(1, "comp_y", first_out_loc, "first_output_location", 1, "scalar");
15005 desc_out[3].assign(1, "comp_y", last_out_loc, "last_output_location", 1, "scalar");
15006 desc_out[4].assign(2, "comp_z", first_out_loc, "first_output_location", 1, "scalar");
15007 desc_out[5].assign(2, "comp_z", last_out_loc, "last_output_location", 1, "scalar");
15008 desc_out[6].assign(3, "comp_w", first_out_loc, "first_output_location", 1, "scalar");
15009 desc_out[7].assign(3, "comp_w", last_out_loc, "last_output_location", 1, "scalar");
15013 for (GLuint i = 0; i < n_desc; ++i)
15015 const descriptor& in_desc = desc_in[i];
15017 Utils::Variable* in =
15018 prepareVarying(basic_type, in_desc, interpolation, si, stage, Utils::Variable::VARYING_INPUT);
15020 if (Utils::Shader::FRAGMENT != stage)
15022 const descriptor& out_desc = desc_out[i];
15024 Utils::Variable* out =
15025 prepareVarying(basic_type, out_desc, interpolation, si, stage, Utils::Variable::VARYING_OUTPUT);
15027 varying_passthrough.Add(stage, in, out);
15031 si.m_globals = prepareGlobals(last_in_loc, last_out_loc);
15037 Utils::Variable* VaryingComponentsTest::prepareVarying(const Utils::Type& basic_type, const descriptor& desc,
15038 const GLchar* interpolation, Utils::ShaderInterface& si,
15039 Utils::Shader::STAGES stage, Utils::Variable::STORAGE storage)
15041 const GLuint array_length = getArrayLength();
15042 const GLuint component_size = basic_type.GetSize();
15043 const std::string& name = prepareName(desc.m_name, desc.m_location, desc.m_component, stage, storage);
15044 const GLuint offset = desc.m_component * component_size;
15045 const std::string& qual = prepareQualifiers(desc.m_location_str, desc.m_component_str, interpolation);
15046 const GLuint size = desc.m_n_rows * component_size;
15047 const Utils::Type& type = Utils::Type::GetType(basic_type.m_basic_type, 1 /* n_columns */, desc.m_n_rows);
15048 Utils::Variable* var = 0;
15050 if (Utils::Variable::VARYING_INPUT == storage)
15052 var = si.Input(name.c_str(), qual.c_str() /* qualifiers */, desc.m_component /* expected_componenet */,
15053 desc.m_location /* expected_location */, type, /* built_in_type */
15054 GL_FALSE /* normalized */, array_length /* n_array_elements */, 0u /* stride */,
15055 offset /* offset */, (GLvoid*)&m_data[offset] /* data */, size /* data_size */);
15059 var = si.Output(name.c_str(), qual.c_str() /* qualifiers */, desc.m_component /* expected_componenet */,
15060 desc.m_location /* expected_location */, type, /* built_in_type */
15061 GL_FALSE /* normalized */, array_length /* n_array_elements */, 0u /* stride */,
15062 offset /* offset */, (GLvoid*)&m_data[offset] /* data */, size /* data_size */);
15068 void VaryingComponentsTest::descriptor::assign(glw::GLint component, const glw::GLchar* component_str,
15069 glw::GLint location, const glw::GLchar* location_str, glw::GLuint n_rows,
15070 const glw::GLchar* name)
15072 m_component = component;
15073 m_component_str = component_str;
15074 m_location = location;
15075 m_location_str = location_str;
15080 VaryingComponentsTest::testCase::testCase(COMPONENTS_LAYOUT layout, Utils::Type::TYPES type)
15081 : m_layout(layout), m_type(type)
15087 * @param context Test framework context
15089 VaryingArrayComponentsTest::VaryingArrayComponentsTest(deqp::Context& context)
15090 : VaryingComponentsTest(context, "varying_array_components",
15091 "Test verifies that input and output components are respected for arrays")
15095 /** Get length of arrays that should be used during test
15099 GLuint VaryingArrayComponentsTest::getArrayLength()
15106 * @param context Test framework context
15108 VaryingExceedingComponentsTest::VaryingExceedingComponentsTest(deqp::Context& context)
15109 : NegativeTestBase(context, "varying_exceeding_components",
15110 "Test verifies that compiler reports error when component qualifier exceed limits")
15114 /** Source for given test case and stage
15116 * @param test_case_index Index of test case
15117 * @param stage Shader stage
15119 * @return Shader source
15121 std::string VaryingExceedingComponentsTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
15123 static const GLchar* var_definition_arr =
15124 "layout (location = 1, component = COMPONENT) flat DIRECTION TYPE gokuARRAY[1];\n";
15125 static const GLchar* var_definition_one =
15126 "layout (location = 1, component = COMPONENT) flat DIRECTION TYPE gokuARRAY;\n";
15127 static const GLchar* input_use_arr = " if (TYPE(0) == gokuINDEX[0])\n"
15129 " result += vec4(1, 0.5, 0.25, 0.125);\n"
15131 static const GLchar* input_use_one = " if (TYPE(0) == gokuINDEX)\n"
15133 " result += vec4(1, 0.5, 0.25, 0.125);\n"
15135 static const GLchar* output_use_arr = " gokuINDEX[0] = TYPE(0);\n"
15136 " if (vec4(0) == result)\n"
15138 " gokuINDEX[0] = TYPE(1);\n"
15140 static const GLchar* output_use_one = " gokuINDEX = TYPE(0);\n"
15141 " if (vec4(0) == result)\n"
15143 " gokuINDEX = TYPE(1);\n"
15145 static const GLchar* fs = "#version 430 core\n"
15146 "#extension GL_ARB_enhanced_layouts : require\n"
15149 "out vec4 fs_out;\n"
15153 " fs_out = gs_fs;\n"
15156 static const GLchar* fs_tested = "#version 430 core\n"
15157 "#extension GL_ARB_enhanced_layouts : require\n"
15162 "out vec4 fs_out;\n"
15166 " vec4 result = gs_fs;\n"
15170 " fs_out += result;\n"
15173 static const GLchar* gs = "#version 430 core\n"
15174 "#extension GL_ARB_enhanced_layouts : require\n"
15176 "layout(points) in;\n"
15177 "layout(triangle_strip, max_vertices = 4) out;\n"
15179 "in vec4 tes_gs[];\n"
15180 "out vec4 gs_fs;\n"
15184 " gs_fs = tes_gs[0];\n"
15185 " gl_Position = vec4(-1, -1, 0, 1);\n"
15187 " gs_fs = tes_gs[0];\n"
15188 " gl_Position = vec4(-1, 1, 0, 1);\n"
15190 " gs_fs = tes_gs[0];\n"
15191 " gl_Position = vec4(1, -1, 0, 1);\n"
15193 " gs_fs = tes_gs[0];\n"
15194 " gl_Position = vec4(1, 1, 0, 1);\n"
15198 static const GLchar* gs_tested = "#version 430 core\n"
15199 "#extension GL_ARB_enhanced_layouts : require\n"
15201 "layout(points) in;\n"
15202 "layout(triangle_strip, max_vertices = 4) out;\n"
15206 "in vec4 tes_gs[];\n"
15207 "out vec4 gs_fs;\n"
15211 " vec4 result = tes_gs[0];\n"
15215 " gs_fs = result;\n"
15216 " gl_Position = vec4(-1, -1, 0, 1);\n"
15218 " gs_fs = result;\n"
15219 " gl_Position = vec4(-1, 1, 0, 1);\n"
15221 " gs_fs = result;\n"
15222 " gl_Position = vec4(1, -1, 0, 1);\n"
15224 " gs_fs = result;\n"
15225 " gl_Position = vec4(1, 1, 0, 1);\n"
15229 static const GLchar* tcs = "#version 430 core\n"
15230 "#extension GL_ARB_enhanced_layouts : require\n"
15232 "layout(vertices = 1) out;\n"
15234 "in vec4 vs_tcs[];\n"
15235 "out vec4 tcs_tes[];\n"
15240 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
15242 " gl_TessLevelOuter[0] = 1.0;\n"
15243 " gl_TessLevelOuter[1] = 1.0;\n"
15244 " gl_TessLevelOuter[2] = 1.0;\n"
15245 " gl_TessLevelOuter[3] = 1.0;\n"
15246 " gl_TessLevelInner[0] = 1.0;\n"
15247 " gl_TessLevelInner[1] = 1.0;\n"
15250 static const GLchar* tcs_tested = "#version 430 core\n"
15251 "#extension GL_ARB_enhanced_layouts : require\n"
15253 "layout(vertices = 1) out;\n"
15257 "in vec4 vs_tcs[];\n"
15258 "out vec4 tcs_tes[];\n"
15262 " vec4 result = vs_tcs[gl_InvocationID];\n"
15266 " tcs_tes[gl_InvocationID] = result;\n"
15268 " gl_TessLevelOuter[0] = 1.0;\n"
15269 " gl_TessLevelOuter[1] = 1.0;\n"
15270 " gl_TessLevelOuter[2] = 1.0;\n"
15271 " gl_TessLevelOuter[3] = 1.0;\n"
15272 " gl_TessLevelInner[0] = 1.0;\n"
15273 " gl_TessLevelInner[1] = 1.0;\n"
15276 static const GLchar* tes = "#version 430 core\n"
15277 "#extension GL_ARB_enhanced_layouts : require\n"
15279 "layout(isolines, point_mode) in;\n"
15281 "in vec4 tcs_tes[];\n"
15282 "out vec4 tes_gs;\n"
15286 " tes_gs = tcs_tes[0];\n"
15289 static const GLchar* tes_tested = "#version 430 core\n"
15290 "#extension GL_ARB_enhanced_layouts : require\n"
15292 "layout(isolines, point_mode) in;\n"
15296 "in vec4 tcs_tes[];\n"
15297 "out vec4 tes_gs;\n"
15301 " vec4 result = tcs_tes[0];\n"
15305 " tes_gs += result;\n"
15308 static const GLchar* vs = "#version 430 core\n"
15309 "#extension GL_ARB_enhanced_layouts : require\n"
15312 "out vec4 vs_tcs;\n"
15316 " vs_tcs = in_vs;\n"
15319 static const GLchar* vs_tested = "#version 430 core\n"
15320 "#extension GL_ARB_enhanced_layouts : require\n"
15325 "out vec4 vs_tcs;\n"
15329 " vec4 result = in_vs;\n"
15333 " vs_tcs += result;\n"
15337 std::string source;
15338 testCase& test_case = m_test_cases[test_case_index];
15340 if (test_case.m_stage == stage)
15342 const GLchar* array = "";
15344 const GLchar* var_definition = 0;
15345 const GLchar* direction = "in ";
15346 const GLchar* index = "";
15347 size_t position = 0;
15349 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
15350 const GLchar* var_use = 0;
15352 if (false == test_case.m_is_input)
15356 if (false == test_case.m_is_array)
15358 var_definition = var_definition_one;
15359 var_use = output_use_one;
15363 var_definition = var_definition_arr;
15364 var_use = output_use_arr;
15369 if (false == test_case.m_is_array)
15371 var_definition = var_definition_one;
15372 var_use = input_use_one;
15376 var_definition = var_definition_arr;
15377 var_use = input_use_arr;
15381 sprintf(buffer, "%d", test_case.m_component);
15385 case Utils::Shader::FRAGMENT:
15386 source = fs_tested;
15388 case Utils::Shader::GEOMETRY:
15389 source = gs_tested;
15393 case Utils::Shader::TESS_CTRL:
15394 source = tcs_tested;
15396 index = "[gl_InvocationID]";
15398 case Utils::Shader::TESS_EVAL:
15399 source = tes_tested;
15403 case Utils::Shader::VERTEX:
15404 source = vs_tested;
15407 TCU_FAIL("Invalid enum");
15411 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
15413 Utils::replaceToken("COMPONENT", position, buffer, source);
15414 Utils::replaceToken("DIRECTION", position, direction, source);
15415 Utils::replaceToken("ARRAY", position, array, source);
15416 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
15418 Utils::replaceAllTokens("TYPE", type_name, source);
15419 Utils::replaceAllTokens("INDEX", index, source);
15425 case Utils::Shader::FRAGMENT:
15428 case Utils::Shader::GEOMETRY:
15431 case Utils::Shader::TESS_CTRL:
15434 case Utils::Shader::TESS_EVAL:
15437 case Utils::Shader::VERTEX:
15441 TCU_FAIL("Invalid enum");
15448 /** Get description of test case
15450 * @param test_case_index Index of test case
15452 * @return Test case description
15454 std::string VaryingExceedingComponentsTest::getTestCaseName(GLuint test_case_index)
15456 std::stringstream stream;
15457 testCase& test_case = m_test_cases[test_case_index];
15459 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
15460 << " type: " << test_case.m_type.GetGLSLTypeName();
15462 if (true == test_case.m_is_array)
15467 stream << ", direction: ";
15469 if (true == test_case.m_is_input)
15475 stream << "output";
15478 stream << ", component: " << test_case.m_component;
15480 return stream.str();
15483 /** Get number of test cases
15485 * @return Number of test cases
15487 GLuint VaryingExceedingComponentsTest::getTestCaseNumber()
15489 return static_cast<GLuint>(m_test_cases.size());
15492 /** Selects if "compute" stage is relevant for test
15498 bool VaryingExceedingComponentsTest::isComputeRelevant(GLuint /* test_case_index */)
15503 /** Prepare all test cases
15506 void VaryingExceedingComponentsTest::testInit()
15508 static const GLuint n_components_per_location = 4;
15509 const GLuint n_types = getTypesNumber();
15511 for (GLuint i = 0; i < n_types; ++i)
15513 const Utils::Type& type = getType(i);
15514 const GLuint n_req_components = type.m_n_rows;
15515 const GLuint valid_component = n_components_per_location - n_req_components;
15516 const GLuint invalid_component = valid_component + 1;
15518 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
15520 if (Utils::Shader::COMPUTE == stage)
15525 /* Component cannot be used for matrices */
15526 if (1 != type.m_n_columns)
15531 testCase test_case_in_arr = { invalid_component, true, true, (Utils::Shader::STAGES)stage, type };
15532 testCase test_case_in_one = { invalid_component, true, false, (Utils::Shader::STAGES)stage, type };
15533 testCase test_case_out_arr = { invalid_component, false, true, (Utils::Shader::STAGES)stage, type };
15534 testCase test_case_out_one = { invalid_component, false, false, (Utils::Shader::STAGES)stage, type };
15536 m_test_cases.push_back(test_case_in_arr);
15537 m_test_cases.push_back(test_case_in_one);
15539 if (Utils::Shader::FRAGMENT != stage)
15541 m_test_cases.push_back(test_case_out_arr);
15542 m_test_cases.push_back(test_case_out_one);
15550 * @param context Test framework context
15552 VaryingComponentWithoutLocationTest::VaryingComponentWithoutLocationTest(deqp::Context& context)
15553 : NegativeTestBase(context, "varying_component_without_location",
15554 "Test verifies that compiler reports error when component qualifier is used without location")
15558 /** Source for given test case and stage
15560 * @param test_case_index Index of test case
15561 * @param stage Shader stage
15563 * @return Shader source
15565 std::string VaryingComponentWithoutLocationTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
15567 static const GLchar* var_definition = "layout (component = COMPONENT) flat DIRECTION TYPE gokuARRAY;\n";
15568 static const GLchar* input_use = " if (TYPE(0) == gokuINDEX)\n"
15570 " result += vec4(1, 0.5, 0.25, 0.125);\n"
15572 static const GLchar* output_use = " gokuINDEX = TYPE(0);\n"
15573 " if (vec4(0) == result)\n"
15575 " gokuINDEX = TYPE(1);\n"
15577 static const GLchar* fs = "#version 430 core\n"
15578 "#extension GL_ARB_enhanced_layouts : require\n"
15581 "out vec4 fs_out;\n"
15585 " fs_out = gs_fs;\n"
15588 static const GLchar* fs_tested = "#version 430 core\n"
15589 "#extension GL_ARB_enhanced_layouts : require\n"
15594 "out vec4 fs_out;\n"
15598 " vec4 result = gs_fs;\n"
15602 " fs_out += result;\n"
15605 static const GLchar* gs = "#version 430 core\n"
15606 "#extension GL_ARB_enhanced_layouts : require\n"
15608 "layout(points) in;\n"
15609 "layout(triangle_strip, max_vertices = 4) out;\n"
15611 "in vec4 tes_gs[];\n"
15612 "out vec4 gs_fs;\n"
15616 " gs_fs = tes_gs[0];\n"
15617 " gl_Position = vec4(-1, -1, 0, 1);\n"
15619 " gs_fs = tes_gs[0];\n"
15620 " gl_Position = vec4(-1, 1, 0, 1);\n"
15622 " gs_fs = tes_gs[0];\n"
15623 " gl_Position = vec4(1, -1, 0, 1);\n"
15625 " gs_fs = tes_gs[0];\n"
15626 " gl_Position = vec4(1, 1, 0, 1);\n"
15630 static const GLchar* gs_tested = "#version 430 core\n"
15631 "#extension GL_ARB_enhanced_layouts : require\n"
15633 "layout(points) in;\n"
15634 "layout(triangle_strip, max_vertices = 4) out;\n"
15638 "in vec4 tes_gs[];\n"
15639 "out vec4 gs_fs;\n"
15643 " vec4 result = tes_gs[0];\n"
15647 " gs_fs = result;\n"
15648 " gl_Position = vec4(-1, -1, 0, 1);\n"
15650 " gs_fs = result;\n"
15651 " gl_Position = vec4(-1, 1, 0, 1);\n"
15653 " gs_fs = result;\n"
15654 " gl_Position = vec4(1, -1, 0, 1);\n"
15656 " gs_fs = result;\n"
15657 " gl_Position = vec4(1, 1, 0, 1);\n"
15661 static const GLchar* tcs = "#version 430 core\n"
15662 "#extension GL_ARB_enhanced_layouts : require\n"
15664 "layout(vertices = 1) out;\n"
15666 "in vec4 vs_tcs[];\n"
15667 "out vec4 tcs_tes[];\n"
15672 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
15674 " gl_TessLevelOuter[0] = 1.0;\n"
15675 " gl_TessLevelOuter[1] = 1.0;\n"
15676 " gl_TessLevelOuter[2] = 1.0;\n"
15677 " gl_TessLevelOuter[3] = 1.0;\n"
15678 " gl_TessLevelInner[0] = 1.0;\n"
15679 " gl_TessLevelInner[1] = 1.0;\n"
15682 static const GLchar* tcs_tested = "#version 430 core\n"
15683 "#extension GL_ARB_enhanced_layouts : require\n"
15685 "layout(vertices = 1) out;\n"
15689 "in vec4 vs_tcs[];\n"
15690 "out vec4 tcs_tes[];\n"
15694 " vec4 result = vs_tcs[gl_InvocationID];\n"
15698 " tcs_tes[gl_InvocationID] = result;\n"
15700 " gl_TessLevelOuter[0] = 1.0;\n"
15701 " gl_TessLevelOuter[1] = 1.0;\n"
15702 " gl_TessLevelOuter[2] = 1.0;\n"
15703 " gl_TessLevelOuter[3] = 1.0;\n"
15704 " gl_TessLevelInner[0] = 1.0;\n"
15705 " gl_TessLevelInner[1] = 1.0;\n"
15708 static const GLchar* tes = "#version 430 core\n"
15709 "#extension GL_ARB_enhanced_layouts : require\n"
15711 "layout(isolines, point_mode) in;\n"
15713 "in vec4 tcs_tes[];\n"
15714 "out vec4 tes_gs;\n"
15718 " tes_gs = tcs_tes[0];\n"
15721 static const GLchar* tes_tested = "#version 430 core\n"
15722 "#extension GL_ARB_enhanced_layouts : require\n"
15724 "layout(isolines, point_mode) in;\n"
15728 "in vec4 tcs_tes[];\n"
15729 "out vec4 tes_gs;\n"
15733 " vec4 result = tcs_tes[0];\n"
15737 " tes_gs += result;\n"
15740 static const GLchar* vs = "#version 430 core\n"
15741 "#extension GL_ARB_enhanced_layouts : require\n"
15744 "out vec4 vs_tcs;\n"
15748 " vs_tcs = in_vs;\n"
15751 static const GLchar* vs_tested = "#version 430 core\n"
15752 "#extension GL_ARB_enhanced_layouts : require\n"
15757 "out vec4 vs_tcs;\n"
15761 " vec4 result = in_vs;\n"
15765 " vs_tcs += result;\n"
15769 std::string source;
15770 testCase& test_case = m_test_cases[test_case_index];
15772 if (test_case.m_stage == stage)
15774 const GLchar* array = "";
15776 const GLchar* direction = "in ";
15777 const GLchar* index = "";
15778 size_t position = 0;
15780 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
15781 const GLchar* var_use = input_use;
15783 if (false == test_case.m_is_input)
15786 var_use = output_use;
15789 sprintf(buffer, "%d", test_case.m_component);
15793 case Utils::Shader::FRAGMENT:
15794 source = fs_tested;
15796 case Utils::Shader::GEOMETRY:
15797 source = gs_tested;
15801 case Utils::Shader::TESS_CTRL:
15802 source = tcs_tested;
15804 index = "[gl_InvocationID]";
15806 case Utils::Shader::TESS_EVAL:
15807 source = tes_tested;
15811 case Utils::Shader::VERTEX:
15812 source = vs_tested;
15815 TCU_FAIL("Invalid enum");
15819 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
15821 Utils::replaceToken("COMPONENT", position, buffer, source);
15822 Utils::replaceToken("DIRECTION", position, direction, source);
15823 Utils::replaceToken("ARRAY", position, array, source);
15824 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
15826 Utils::replaceAllTokens("TYPE", type_name, source);
15827 Utils::replaceAllTokens("INDEX", index, source);
15833 case Utils::Shader::FRAGMENT:
15836 case Utils::Shader::GEOMETRY:
15839 case Utils::Shader::TESS_CTRL:
15842 case Utils::Shader::TESS_EVAL:
15845 case Utils::Shader::VERTEX:
15849 TCU_FAIL("Invalid enum");
15856 /** Get description of test case
15858 * @param test_case_index Index of test case
15860 * @return Test case description
15862 std::string VaryingComponentWithoutLocationTest::getTestCaseName(GLuint test_case_index)
15864 std::stringstream stream;
15865 testCase& test_case = m_test_cases[test_case_index];
15867 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
15868 << " type: " << test_case.m_type.GetGLSLTypeName() << ", direction: ";
15870 if (true == test_case.m_is_input)
15876 stream << "output";
15879 stream << ", component: " << test_case.m_component;
15881 return stream.str();
15884 /** Get number of test cases
15886 * @return Number of test cases
15888 GLuint VaryingComponentWithoutLocationTest::getTestCaseNumber()
15890 return static_cast<GLuint>(m_test_cases.size());
15893 /** Selects if "compute" stage is relevant for test
15899 bool VaryingComponentWithoutLocationTest::isComputeRelevant(GLuint /* test_case_index */)
15904 /** Prepare all test cases
15907 void VaryingComponentWithoutLocationTest::testInit()
15909 static const GLuint n_components_per_location = 4;
15910 const GLuint n_types = getTypesNumber();
15912 for (GLuint i = 0; i < n_types; ++i)
15914 const Utils::Type& type = getType(i);
15915 const GLuint n_req_components = type.m_n_rows;
15916 const GLuint valid_component = n_components_per_location - n_req_components;
15918 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
15920 if (Utils::Shader::COMPUTE == stage)
15925 /* Component cannot be used for matrices */
15926 if (1 != type.m_n_columns)
15931 testCase test_case_in = { valid_component, true, (Utils::Shader::STAGES)stage, type };
15932 testCase test_case_out = { valid_component, false, (Utils::Shader::STAGES)stage, type };
15934 m_test_cases.push_back(test_case_in);
15936 if (Utils::Shader::FRAGMENT != stage)
15938 m_test_cases.push_back(test_case_out);
15946 * @param context Test framework context
15948 VaryingComponentOfInvalidTypeTest::VaryingComponentOfInvalidTypeTest(deqp::Context& context)
15949 : NegativeTestBase(context, "varying_component_of_invalid_type",
15950 "Test verifies that compiler reports error when component qualifier is used for invalid type")
15954 /** Source for given test case and stage
15956 * @param test_case_index Index of test case
15957 * @param stage Shader stage
15959 * @return Shader source
15961 std::string VaryingComponentOfInvalidTypeTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
15963 static const GLchar* block_definition_arr = "layout (location = 1, component = COMPONENT) flat DIRECTION Goku {\n"
15965 "} gokuARRAY[1];\n";
15966 static const GLchar* block_definition_one = "layout (location = 1, component = COMPONENT) flat DIRECTION Goku {\n"
15969 static const GLchar* matrix_definition_arr =
15970 "layout (location = 1, component = COMPONENT) flat DIRECTION TYPE gokuARRAY[1];\n";
15971 static const GLchar* matrix_definition_one =
15972 "layout (location = 1, component = COMPONENT) flat DIRECTION TYPE gokuARRAY;\n";
15973 static const GLchar* struct_definition_arr =
15978 "layout (location = 1, component = COMPONENT) flat DIRECTION Goku gokuARRAY[1];\n";
15979 static const GLchar* struct_definition_one =
15984 "layout (location = 1, component = COMPONENT) flat DIRECTION Goku gokuARRAY;\n";
15985 static const GLchar* matrix_input_use_arr = " if (TYPE(0) == gokuINDEX[0])\n"
15987 " result += vec4(1, 0.5, 0.25, 0.125);\n"
15989 static const GLchar* matrix_input_use_one = " if (TYPE(0) == gokuINDEX)\n"
15991 " result += vec4(1, 0.5, 0.25, 0.125);\n"
15993 static const GLchar* matrix_output_use_arr = " gokuINDEX[0] = TYPE(0);\n"
15994 " if (vec4(0) == result)\n"
15996 " gokuINDEX[0] = TYPE(1);\n"
15998 static const GLchar* matrix_output_use_one = " gokuINDEX = TYPE(0);\n"
15999 " if (vec4(0) == result)\n"
16001 " gokuINDEX = TYPE(1);\n"
16003 static const GLchar* member_input_use_arr = " if (TYPE(0) == gokuINDEX[0].member)\n"
16005 " result += vec4(1, 0.5, 0.25, 0.125);\n"
16007 static const GLchar* member_input_use_one = " if (TYPE(0) == gokuINDEX.member)\n"
16009 " result += vec4(1, 0.5, 0.25, 0.125);\n"
16011 static const GLchar* member_output_use_arr = " gokuINDEX[0].member = TYPE(0);\n"
16012 " if (vec4(0) == result)\n"
16014 " gokuINDEX[0].member = TYPE(1);\n"
16016 static const GLchar* member_output_use_one = " gokuINDEX.member = TYPE(0);\n"
16017 " if (vec4(0) == result)\n"
16019 " gokuINDEX.member = TYPE(1);\n"
16021 static const GLchar* fs = "#version 430 core\n"
16022 "#extension GL_ARB_enhanced_layouts : require\n"
16025 "out vec4 fs_out;\n"
16029 " fs_out = gs_fs;\n"
16032 static const GLchar* fs_tested = "#version 430 core\n"
16033 "#extension GL_ARB_enhanced_layouts : require\n"
16038 "out vec4 fs_out;\n"
16042 " vec4 result = gs_fs;\n"
16046 " fs_out += result;\n"
16049 static const GLchar* gs = "#version 430 core\n"
16050 "#extension GL_ARB_enhanced_layouts : require\n"
16052 "layout(points) in;\n"
16053 "layout(triangle_strip, max_vertices = 4) out;\n"
16055 "in vec4 tes_gs[];\n"
16056 "out vec4 gs_fs;\n"
16060 " gs_fs = tes_gs[0];\n"
16061 " gl_Position = vec4(-1, -1, 0, 1);\n"
16063 " gs_fs = tes_gs[0];\n"
16064 " gl_Position = vec4(-1, 1, 0, 1);\n"
16066 " gs_fs = tes_gs[0];\n"
16067 " gl_Position = vec4(1, -1, 0, 1);\n"
16069 " gs_fs = tes_gs[0];\n"
16070 " gl_Position = vec4(1, 1, 0, 1);\n"
16074 static const GLchar* gs_tested = "#version 430 core\n"
16075 "#extension GL_ARB_enhanced_layouts : require\n"
16077 "layout(points) in;\n"
16078 "layout(triangle_strip, max_vertices = 4) out;\n"
16082 "in vec4 tes_gs[];\n"
16083 "out vec4 gs_fs;\n"
16087 " vec4 result = tes_gs[0];\n"
16091 " gs_fs = result;\n"
16092 " gl_Position = vec4(-1, -1, 0, 1);\n"
16094 " gs_fs = result;\n"
16095 " gl_Position = vec4(-1, 1, 0, 1);\n"
16097 " gs_fs = result;\n"
16098 " gl_Position = vec4(1, -1, 0, 1);\n"
16100 " gs_fs = result;\n"
16101 " gl_Position = vec4(1, 1, 0, 1);\n"
16105 static const GLchar* tcs = "#version 430 core\n"
16106 "#extension GL_ARB_enhanced_layouts : require\n"
16108 "layout(vertices = 1) out;\n"
16110 "in vec4 vs_tcs[];\n"
16111 "out vec4 tcs_tes[];\n"
16116 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
16118 " gl_TessLevelOuter[0] = 1.0;\n"
16119 " gl_TessLevelOuter[1] = 1.0;\n"
16120 " gl_TessLevelOuter[2] = 1.0;\n"
16121 " gl_TessLevelOuter[3] = 1.0;\n"
16122 " gl_TessLevelInner[0] = 1.0;\n"
16123 " gl_TessLevelInner[1] = 1.0;\n"
16126 static const GLchar* tcs_tested = "#version 430 core\n"
16127 "#extension GL_ARB_enhanced_layouts : require\n"
16129 "layout(vertices = 1) out;\n"
16133 "in vec4 vs_tcs[];\n"
16134 "out vec4 tcs_tes[];\n"
16138 " vec4 result = vs_tcs[gl_InvocationID];\n"
16142 " tcs_tes[gl_InvocationID] = result;\n"
16144 " gl_TessLevelOuter[0] = 1.0;\n"
16145 " gl_TessLevelOuter[1] = 1.0;\n"
16146 " gl_TessLevelOuter[2] = 1.0;\n"
16147 " gl_TessLevelOuter[3] = 1.0;\n"
16148 " gl_TessLevelInner[0] = 1.0;\n"
16149 " gl_TessLevelInner[1] = 1.0;\n"
16152 static const GLchar* tes = "#version 430 core\n"
16153 "#extension GL_ARB_enhanced_layouts : require\n"
16155 "layout(isolines, point_mode) in;\n"
16157 "in vec4 tcs_tes[];\n"
16158 "out vec4 tes_gs;\n"
16162 " tes_gs = tcs_tes[0];\n"
16165 static const GLchar* tes_tested = "#version 430 core\n"
16166 "#extension GL_ARB_enhanced_layouts : require\n"
16168 "layout(isolines, point_mode) in;\n"
16172 "in vec4 tcs_tes[];\n"
16173 "out vec4 tes_gs;\n"
16177 " vec4 result = tcs_tes[0];\n"
16181 " tes_gs += result;\n"
16184 static const GLchar* vs = "#version 430 core\n"
16185 "#extension GL_ARB_enhanced_layouts : require\n"
16188 "out vec4 vs_tcs;\n"
16192 " vs_tcs = in_vs;\n"
16195 static const GLchar* vs_tested = "#version 430 core\n"
16196 "#extension GL_ARB_enhanced_layouts : require\n"
16201 "out vec4 vs_tcs;\n"
16205 " vec4 result = in_vs;\n"
16209 " vs_tcs += result;\n"
16213 std::string source;
16214 testCase& test_case = m_test_cases[test_case_index];
16216 if (test_case.m_stage == stage)
16218 const GLchar* array = "";
16220 const GLchar* var_definition = 0;
16221 const GLchar* direction = "in ";
16222 const GLchar* index = "";
16223 size_t position = 0;
16225 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
16226 const GLchar* var_use = 0;
16228 if (false == test_case.m_is_input)
16232 if (false == test_case.m_is_array)
16234 switch (test_case.m_case)
16237 var_definition = block_definition_one;
16238 var_use = member_output_use_one;
16241 var_definition = matrix_definition_one;
16242 var_use = matrix_output_use_one;
16245 var_definition = struct_definition_one;
16246 var_use = member_output_use_one;
16249 TCU_FAIL("Invalid enum");
16254 switch (test_case.m_case)
16257 var_definition = block_definition_arr;
16258 var_use = member_output_use_arr;
16261 var_definition = matrix_definition_arr;
16262 var_use = matrix_output_use_arr;
16265 var_definition = struct_definition_arr;
16266 var_use = member_output_use_arr;
16269 TCU_FAIL("Invalid enum");
16275 if (false == test_case.m_is_array)
16277 switch (test_case.m_case)
16280 var_definition = block_definition_one;
16281 var_use = member_input_use_one;
16284 var_definition = matrix_definition_one;
16285 var_use = matrix_input_use_one;
16288 var_definition = struct_definition_one;
16289 var_use = member_input_use_one;
16292 TCU_FAIL("Invalid enum");
16297 switch (test_case.m_case)
16300 var_definition = block_definition_arr;
16301 var_use = member_input_use_arr;
16304 var_definition = matrix_definition_arr;
16305 var_use = matrix_input_use_arr;
16308 var_definition = struct_definition_arr;
16309 var_use = member_input_use_arr;
16312 TCU_FAIL("Invalid enum");
16317 sprintf(buffer, "%d", test_case.m_component);
16321 case Utils::Shader::FRAGMENT:
16322 source = fs_tested;
16324 case Utils::Shader::GEOMETRY:
16325 source = gs_tested;
16329 case Utils::Shader::TESS_CTRL:
16330 source = tcs_tested;
16332 index = "[gl_InvocationID]";
16334 case Utils::Shader::TESS_EVAL:
16335 source = tes_tested;
16339 case Utils::Shader::VERTEX:
16340 source = vs_tested;
16343 TCU_FAIL("Invalid enum");
16347 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
16349 Utils::replaceToken("COMPONENT", position, buffer, source);
16350 Utils::replaceToken("DIRECTION", position, direction, source);
16351 Utils::replaceToken("ARRAY", position, array, source);
16352 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
16354 Utils::replaceAllTokens("TYPE", type_name, source);
16355 Utils::replaceAllTokens("INDEX", index, source);
16361 case Utils::Shader::FRAGMENT:
16364 case Utils::Shader::GEOMETRY:
16367 case Utils::Shader::TESS_CTRL:
16370 case Utils::Shader::TESS_EVAL:
16373 case Utils::Shader::VERTEX:
16377 TCU_FAIL("Invalid enum");
16384 /** Get description of test case
16386 * @param test_case_index Index of test case
16388 * @return Test case description
16390 std::string VaryingComponentOfInvalidTypeTest::getTestCaseName(GLuint test_case_index)
16392 std::stringstream stream;
16393 testCase& test_case = m_test_cases[test_case_index];
16395 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
16396 << " type: " << test_case.m_type.GetGLSLTypeName();
16398 if (true == test_case.m_is_array)
16403 stream << ", direction: ";
16405 if (true == test_case.m_is_input)
16411 stream << "output";
16414 stream << ", component: " << test_case.m_component;
16416 return stream.str();
16419 /** Get number of test cases
16421 * @return Number of test cases
16423 GLuint VaryingComponentOfInvalidTypeTest::getTestCaseNumber()
16425 return static_cast<GLuint>(m_test_cases.size());
16428 /** Selects if "compute" stage is relevant for test
16434 bool VaryingComponentOfInvalidTypeTest::isComputeRelevant(GLuint /* test_case_index */)
16439 /** Prepare all test cases
16442 void VaryingComponentOfInvalidTypeTest::testInit()
16444 static const GLuint n_components_per_location = 4;
16445 const GLuint n_types = getTypesNumber();
16447 for (GLuint i = 0; i < n_types; ++i)
16449 const Utils::Type& type = getType(i);
16450 const GLuint n_req_components = type.m_n_rows;
16451 const GLuint valid_component = n_components_per_location - n_req_components;
16453 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
16455 if (Utils::Shader::COMPUTE == stage)
16460 /* Use different CASE for matrices */
16461 if (1 != type.m_n_columns)
16463 testCase test_case_in_arr = { MATRIX, valid_component, true, true, (Utils::Shader::STAGES)stage, type };
16464 testCase test_case_in_one = {
16465 MATRIX, valid_component, false, true, (Utils::Shader::STAGES)stage, type
16467 testCase test_case_out_arr = {
16468 MATRIX, valid_component, true, false, (Utils::Shader::STAGES)stage, type
16470 testCase test_case_out_one = {
16471 MATRIX, valid_component, false, false, (Utils::Shader::STAGES)stage, type
16474 m_test_cases.push_back(test_case_in_arr);
16475 m_test_cases.push_back(test_case_in_one);
16477 if (Utils::Shader::FRAGMENT != stage)
16479 m_test_cases.push_back(test_case_out_arr);
16480 m_test_cases.push_back(test_case_out_one);
16485 for (GLuint c = BLOCK; c < MAX_CASES; ++c)
16487 testCase test_case_in_arr = { (CASES)c, valid_component, true, true, (Utils::Shader::STAGES)stage,
16489 testCase test_case_in_one = { (CASES)c, valid_component, false, true, (Utils::Shader::STAGES)stage,
16491 testCase test_case_out_arr = { (CASES)c, valid_component, true, false, (Utils::Shader::STAGES)stage,
16493 testCase test_case_out_one = {
16494 (CASES)c, valid_component, false, false, (Utils::Shader::STAGES)stage, type
16497 if (Utils::Shader::VERTEX != stage)
16499 m_test_cases.push_back(test_case_in_arr);
16500 m_test_cases.push_back(test_case_in_one);
16503 if (Utils::Shader::FRAGMENT != stage)
16505 m_test_cases.push_back(test_case_out_arr);
16506 m_test_cases.push_back(test_case_out_one);
16516 * @param context Test framework context
16518 InputComponentAliasingTest::InputComponentAliasingTest(deqp::Context& context)
16519 : NegativeTestBase(context, "input_component_aliasing",
16520 "Test verifies that compiler reports component aliasing as error")
16524 /** Source for given test case and stage
16526 * @param test_case_index Index of test case
16527 * @param stage Shader stage
16529 * @return Shader source
16531 std::string InputComponentAliasingTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
16533 static const GLchar* var_definition = "layout (location = 1, component = COMPONENT) FLAT in TYPE gohanARRAY;\n"
16534 "layout (location = 1, component = COMPONENT) FLAT in TYPE gotenARRAY;\n";
16535 static const GLchar* test_one = " if (TYPE(0) == gohanINDEX)\n"
16537 " result += vec4(1, 0.5, 0.25, 0.125);\n"
16539 static const GLchar* test_both = " if (TYPE(0) == gohanINDEX)\n"
16541 " result = vec4(goten.xxxx);\n"
16543 static const GLchar* fs = "#version 430 core\n"
16544 "#extension GL_ARB_enhanced_layouts : require\n"
16547 "out vec4 fs_out;\n"
16551 " fs_out = gs_fs;\n"
16554 static const GLchar* fs_tested = "#version 430 core\n"
16555 "#extension GL_ARB_enhanced_layouts : require\n"
16560 "out vec4 fs_out;\n"
16564 " vec4 result = gs_fs;\n"
16568 " fs_out += result;\n"
16571 static const GLchar* gs = "#version 430 core\n"
16572 "#extension GL_ARB_enhanced_layouts : require\n"
16574 "layout(points) in;\n"
16575 "layout(triangle_strip, max_vertices = 4) out;\n"
16577 "in vec4 tes_gs[];\n"
16578 "out vec4 gs_fs;\n"
16582 " gs_fs = tes_gs[0];\n"
16583 " gl_Position = vec4(-1, -1, 0, 1);\n"
16585 " gs_fs = tes_gs[0];\n"
16586 " gl_Position = vec4(-1, 1, 0, 1);\n"
16588 " gs_fs = tes_gs[0];\n"
16589 " gl_Position = vec4(1, -1, 0, 1);\n"
16591 " gs_fs = tes_gs[0];\n"
16592 " gl_Position = vec4(1, 1, 0, 1);\n"
16596 static const GLchar* gs_tested = "#version 430 core\n"
16597 "#extension GL_ARB_enhanced_layouts : require\n"
16599 "layout(points) in;\n"
16600 "layout(triangle_strip, max_vertices = 4) out;\n"
16604 "in vec4 tes_gs[];\n"
16605 "out vec4 gs_fs;\n"
16609 " vec4 result = tes_gs[0];\n"
16613 " gs_fs = result;\n"
16614 " gl_Position = vec4(-1, -1, 0, 1);\n"
16616 " gs_fs = result;\n"
16617 " gl_Position = vec4(-1, 1, 0, 1);\n"
16619 " gs_fs = result;\n"
16620 " gl_Position = vec4(1, -1, 0, 1);\n"
16622 " gs_fs = result;\n"
16623 " gl_Position = vec4(1, 1, 0, 1);\n"
16627 static const GLchar* tcs = "#version 430 core\n"
16628 "#extension GL_ARB_enhanced_layouts : require\n"
16630 "layout(vertices = 1) out;\n"
16632 "in vec4 vs_tcs[];\n"
16633 "out vec4 tcs_tes[];\n"
16638 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
16640 " gl_TessLevelOuter[0] = 1.0;\n"
16641 " gl_TessLevelOuter[1] = 1.0;\n"
16642 " gl_TessLevelOuter[2] = 1.0;\n"
16643 " gl_TessLevelOuter[3] = 1.0;\n"
16644 " gl_TessLevelInner[0] = 1.0;\n"
16645 " gl_TessLevelInner[1] = 1.0;\n"
16648 static const GLchar* tcs_tested = "#version 430 core\n"
16649 "#extension GL_ARB_enhanced_layouts : require\n"
16651 "layout(vertices = 1) out;\n"
16655 "in vec4 vs_tcs[];\n"
16656 "out vec4 tcs_tes[];\n"
16660 " vec4 result = vs_tcs[gl_InvocationID];\n"
16664 " tcs_tes[gl_InvocationID] = result;\n"
16666 " gl_TessLevelOuter[0] = 1.0;\n"
16667 " gl_TessLevelOuter[1] = 1.0;\n"
16668 " gl_TessLevelOuter[2] = 1.0;\n"
16669 " gl_TessLevelOuter[3] = 1.0;\n"
16670 " gl_TessLevelInner[0] = 1.0;\n"
16671 " gl_TessLevelInner[1] = 1.0;\n"
16674 static const GLchar* tes = "#version 430 core\n"
16675 "#extension GL_ARB_enhanced_layouts : require\n"
16677 "layout(isolines, point_mode) in;\n"
16679 "in vec4 tcs_tes[];\n"
16680 "out vec4 tes_gs;\n"
16684 " tes_gs = tcs_tes[0];\n"
16687 static const GLchar* tes_tested = "#version 430 core\n"
16688 "#extension GL_ARB_enhanced_layouts : require\n"
16690 "layout(isolines, point_mode) in;\n"
16694 "in vec4 tcs_tes[];\n"
16695 "out vec4 tes_gs;\n"
16699 " vec4 result = tcs_tes[0];\n"
16703 " tes_gs += result;\n"
16706 static const GLchar* vs = "#version 430 core\n"
16707 "#extension GL_ARB_enhanced_layouts : require\n"
16710 "out vec4 vs_tcs;\n"
16714 " vs_tcs = in_vs;\n"
16717 static const GLchar* vs_tested = "#version 430 core\n"
16718 "#extension GL_ARB_enhanced_layouts : require\n"
16723 "out vec4 vs_tcs;\n"
16727 " vec4 result = in_vs;\n"
16731 " vs_tcs += result;\n"
16735 std::string source;
16736 testCase& test_case = m_test_cases[test_case_index];
16738 if (test_case.m_stage == stage)
16740 const GLchar* array = "";
16741 GLchar buffer_gohan[16];
16742 GLchar buffer_goten[16];
16743 const GLchar* flat = "";
16744 const GLchar* index = "";
16745 const bool is_flat_req = isFlatRequired(stage, test_case.m_type, Utils::Variable::VARYING_INPUT);
16746 size_t position = 0;
16748 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
16749 const GLchar* var_use = test_one;
16751 if (true == test_case.m_use_both)
16753 var_use = test_both;
16756 if (true == is_flat_req)
16761 sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
16762 sprintf(buffer_goten, "%d", test_case.m_component_goten);
16766 case Utils::Shader::FRAGMENT:
16767 source = fs_tested;
16769 case Utils::Shader::GEOMETRY:
16770 source = gs_tested;
16774 case Utils::Shader::TESS_CTRL:
16775 source = tcs_tested;
16777 index = "[gl_InvocationID]";
16779 case Utils::Shader::TESS_EVAL:
16780 source = tes_tested;
16784 case Utils::Shader::VERTEX:
16785 source = vs_tested;
16788 TCU_FAIL("Invalid enum");
16792 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
16794 Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
16795 Utils::replaceToken("ARRAY", position, array, source);
16796 Utils::replaceToken("COMPONENT", position, buffer_goten, source);
16797 Utils::replaceToken("ARRAY", position, array, source);
16798 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
16800 Utils::replaceAllTokens("FLAT", flat, source);
16801 Utils::replaceAllTokens("TYPE", type_name, source);
16802 Utils::replaceAllTokens("INDEX", index, source);
16808 case Utils::Shader::FRAGMENT:
16811 case Utils::Shader::GEOMETRY:
16814 case Utils::Shader::TESS_CTRL:
16817 case Utils::Shader::TESS_EVAL:
16820 case Utils::Shader::VERTEX:
16824 TCU_FAIL("Invalid enum");
16831 /** Get description of test case
16833 * @param test_case_index Index of test case
16835 * @return Test case description
16837 std::string InputComponentAliasingTest::getTestCaseName(GLuint test_case_index)
16839 std::stringstream stream;
16840 testCase& test_case = m_test_cases[test_case_index];
16842 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
16843 << " type: " << test_case.m_type.GetGLSLTypeName() << ", components: " << test_case.m_component_gohan
16844 << " & " << test_case.m_component_goten;
16846 return stream.str();
16849 /** Get number of test cases
16851 * @return Number of test cases
16853 GLuint InputComponentAliasingTest::getTestCaseNumber()
16855 return static_cast<GLuint>(m_test_cases.size());
16858 /** Selects if "compute" stage is relevant for test
16864 bool InputComponentAliasingTest::isComputeRelevant(GLuint /* test_case_index */)
16869 /** Selects if compilation failure is expected result
16871 * @param test_case_index Index of test case
16873 * @return false for VS that use only single variable, true otherwise
16875 bool InputComponentAliasingTest::isFailureExpected(GLuint test_case_index)
16877 testCase& test_case = m_test_cases[test_case_index];
16879 return !((Utils::Shader::VERTEX == test_case.m_stage) && (false == test_case.m_use_both));
16882 /** Prepare all test cases
16885 void InputComponentAliasingTest::testInit()
16887 static const GLuint n_components_per_location = 4;
16888 const GLuint n_types = getTypesNumber();
16890 for (GLuint i = 0; i < n_types; ++i)
16892 const Utils::Type& type = getType(i);
16893 const GLuint n_req_components = type.m_n_rows;
16894 const GLuint valid_component = n_components_per_location - n_req_components;
16896 /* Skip matrices */
16897 if (1 != type.m_n_columns)
16902 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
16904 if (Utils::Shader::COMPUTE == stage)
16909 for (GLuint gohan = 0; gohan <= valid_component; ++gohan)
16911 const GLint first_aliasing = gohan - n_req_components + 1;
16912 const GLint last_aliasing = gohan + n_req_components - 1;
16914 const GLuint goten_start = std::max(0, first_aliasing);
16915 const GLuint goten_stop = std::min((GLint)valid_component, last_aliasing);
16917 for (GLuint goten = goten_start; goten <= goten_stop; ++goten)
16919 testCase test_case = { gohan, goten, (Utils::Shader::STAGES)stage, type, false };
16921 m_test_cases.push_back(test_case);
16923 if (Utils::Shader::VERTEX == test_case.m_stage)
16925 test_case.m_use_both = true;
16927 m_test_cases.push_back(test_case);
16937 * @param context Test framework context
16939 OutputComponentAliasingTest::OutputComponentAliasingTest(deqp::Context& context)
16940 : NegativeTestBase(context, "output_component_aliasing",
16941 "Test verifies that compiler reports component aliasing as error")
16945 /** Source for given test case and stage
16947 * @param test_case_index Index of test case
16948 * @param stage Shader stage
16950 * @return Shader source
16952 std::string OutputComponentAliasingTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
16954 static const GLchar* var_definition = "layout (location = 1, component = COMPONENT) flat out TYPE gohanARRAY;\n"
16955 "layout (location = 1, component = COMPONENT) flat out TYPE gotenARRAY;\n";
16956 static const GLchar* l_test = " gohanINDEX = TYPE(1);\n"
16957 " gotenINDEX = TYPE(0);\n";
16958 static const GLchar* fs = "#version 430 core\n"
16959 "#extension GL_ARB_enhanced_layouts : require\n"
16962 "out vec4 fs_out;\n"
16966 " fs_out = gs_fs;\n"
16969 static const GLchar* fs_tested = "#version 430 core\n"
16970 "#extension GL_ARB_enhanced_layouts : require\n"
16975 "out vec4 fs_out;\n"
16979 " vec4 result = gs_fs;\n"
16983 " fs_out += result;\n"
16986 static const GLchar* gs = "#version 430 core\n"
16987 "#extension GL_ARB_enhanced_layouts : require\n"
16989 "layout(points) in;\n"
16990 "layout(triangle_strip, max_vertices = 4) out;\n"
16992 "in vec4 tes_gs[];\n"
16993 "out vec4 gs_fs;\n"
16997 " gs_fs = tes_gs[0];\n"
16998 " gl_Position = vec4(-1, -1, 0, 1);\n"
17000 " gs_fs = tes_gs[0];\n"
17001 " gl_Position = vec4(-1, 1, 0, 1);\n"
17003 " gs_fs = tes_gs[0];\n"
17004 " gl_Position = vec4(1, -1, 0, 1);\n"
17006 " gs_fs = tes_gs[0];\n"
17007 " gl_Position = vec4(1, 1, 0, 1);\n"
17011 static const GLchar* gs_tested = "#version 430 core\n"
17012 "#extension GL_ARB_enhanced_layouts : require\n"
17014 "layout(points) in;\n"
17015 "layout(triangle_strip, max_vertices = 4) out;\n"
17019 "in vec4 tes_gs[];\n"
17020 "out vec4 gs_fs;\n"
17024 " vec4 result = tes_gs[0];\n"
17028 " gs_fs = result;\n"
17029 " gl_Position = vec4(-1, -1, 0, 1);\n"
17031 " gs_fs = result;\n"
17032 " gl_Position = vec4(-1, 1, 0, 1);\n"
17034 " gs_fs = result;\n"
17035 " gl_Position = vec4(1, -1, 0, 1);\n"
17037 " gs_fs = result;\n"
17038 " gl_Position = vec4(1, 1, 0, 1);\n"
17042 static const GLchar* tcs = "#version 430 core\n"
17043 "#extension GL_ARB_enhanced_layouts : require\n"
17045 "layout(vertices = 1) out;\n"
17047 "in vec4 vs_tcs[];\n"
17048 "out vec4 tcs_tes[];\n"
17053 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
17055 " gl_TessLevelOuter[0] = 1.0;\n"
17056 " gl_TessLevelOuter[1] = 1.0;\n"
17057 " gl_TessLevelOuter[2] = 1.0;\n"
17058 " gl_TessLevelOuter[3] = 1.0;\n"
17059 " gl_TessLevelInner[0] = 1.0;\n"
17060 " gl_TessLevelInner[1] = 1.0;\n"
17063 static const GLchar* tcs_tested = "#version 430 core\n"
17064 "#extension GL_ARB_enhanced_layouts : require\n"
17066 "layout(vertices = 1) out;\n"
17070 "in vec4 vs_tcs[];\n"
17071 "out vec4 tcs_tes[];\n"
17075 " vec4 result = vs_tcs[gl_InvocationID];\n"
17079 " tcs_tes[gl_InvocationID] = result;\n"
17081 " gl_TessLevelOuter[0] = 1.0;\n"
17082 " gl_TessLevelOuter[1] = 1.0;\n"
17083 " gl_TessLevelOuter[2] = 1.0;\n"
17084 " gl_TessLevelOuter[3] = 1.0;\n"
17085 " gl_TessLevelInner[0] = 1.0;\n"
17086 " gl_TessLevelInner[1] = 1.0;\n"
17089 static const GLchar* tes = "#version 430 core\n"
17090 "#extension GL_ARB_enhanced_layouts : require\n"
17092 "layout(isolines, point_mode) in;\n"
17094 "in vec4 tcs_tes[];\n"
17095 "out vec4 tes_gs;\n"
17099 " tes_gs = tcs_tes[0];\n"
17102 static const GLchar* tes_tested = "#version 430 core\n"
17103 "#extension GL_ARB_enhanced_layouts : require\n"
17105 "layout(isolines, point_mode) in;\n"
17109 "in vec4 tcs_tes[];\n"
17110 "out vec4 tes_gs;\n"
17114 " vec4 result = tcs_tes[0];\n"
17118 " tes_gs += result;\n"
17121 static const GLchar* vs = "#version 430 core\n"
17122 "#extension GL_ARB_enhanced_layouts : require\n"
17125 "out vec4 vs_tcs;\n"
17129 " vs_tcs = in_vs;\n"
17132 static const GLchar* vs_tested = "#version 430 core\n"
17133 "#extension GL_ARB_enhanced_layouts : require\n"
17138 "out vec4 vs_tcs;\n"
17142 " vec4 result = in_vs;\n"
17146 " vs_tcs += result;\n"
17150 std::string source;
17151 testCase& test_case = m_test_cases[test_case_index];
17153 if (test_case.m_stage == stage)
17155 const GLchar* array = "";
17156 GLchar buffer_gohan[16];
17157 GLchar buffer_goten[16];
17158 const GLchar* index = "";
17159 size_t position = 0;
17161 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
17163 sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
17164 sprintf(buffer_goten, "%d", test_case.m_component_goten);
17168 case Utils::Shader::FRAGMENT:
17169 source = fs_tested;
17171 case Utils::Shader::GEOMETRY:
17172 source = gs_tested;
17176 case Utils::Shader::TESS_CTRL:
17177 source = tcs_tested;
17179 index = "[gl_InvocationID]";
17181 case Utils::Shader::TESS_EVAL:
17182 source = tes_tested;
17186 case Utils::Shader::VERTEX:
17187 source = vs_tested;
17190 TCU_FAIL("Invalid enum");
17194 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
17196 Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
17197 Utils::replaceToken("ARRAY", position, array, source);
17198 Utils::replaceToken("COMPONENT", position, buffer_goten, source);
17199 Utils::replaceToken("ARRAY", position, array, source);
17200 Utils::replaceToken("VARIABLE_USE", position, l_test, source);
17202 Utils::replaceAllTokens("TYPE", type_name, source);
17203 Utils::replaceAllTokens("INDEX", index, source);
17209 case Utils::Shader::FRAGMENT:
17212 case Utils::Shader::GEOMETRY:
17215 case Utils::Shader::TESS_CTRL:
17218 case Utils::Shader::TESS_EVAL:
17221 case Utils::Shader::VERTEX:
17225 TCU_FAIL("Invalid enum");
17232 /** Get description of test case
17234 * @param test_case_index Index of test case
17236 * @return Test case description
17238 std::string OutputComponentAliasingTest::getTestCaseName(GLuint test_case_index)
17240 std::stringstream stream;
17241 testCase& test_case = m_test_cases[test_case_index];
17243 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
17244 << " type: " << test_case.m_type.GetGLSLTypeName() << ", components: " << test_case.m_component_gohan
17245 << " & " << test_case.m_component_goten;
17247 return stream.str();
17250 /** Get number of test cases
17252 * @return Number of test cases
17254 GLuint OutputComponentAliasingTest::getTestCaseNumber()
17256 return static_cast<GLuint>(m_test_cases.size());
17259 /** Selects if "compute" stage is relevant for test
17265 bool OutputComponentAliasingTest::isComputeRelevant(GLuint /* test_case_index */)
17270 /** Prepare all test cases
17273 void OutputComponentAliasingTest::testInit()
17275 static const GLuint n_components_per_location = 4;
17276 const GLuint n_types = getTypesNumber();
17278 for (GLuint i = 0; i < n_types; ++i)
17280 const Utils::Type& type = getType(i);
17281 const GLuint n_req_components = type.m_n_rows;
17282 const GLuint valid_component = n_components_per_location - n_req_components;
17284 /* Skip matrices */
17285 if (1 != type.m_n_columns)
17290 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
17292 if (Utils::Shader::COMPUTE == stage)
17297 if ((Utils::Shader::FRAGMENT == stage) && (Utils::Type::Double == type.m_basic_type))
17302 for (GLuint gohan = 0; gohan <= valid_component; ++gohan)
17304 const GLint first_aliasing = gohan - n_req_components + 1;
17305 const GLint last_aliasing = gohan + n_req_components - 1;
17307 const GLuint goten_start = std::max(0, first_aliasing);
17308 const GLuint goten_stop = std::min((GLint)valid_component, last_aliasing);
17310 for (GLuint goten = goten_start; goten <= goten_stop; ++goten)
17312 testCase test_case = { gohan, goten, (Utils::Shader::STAGES)stage, type };
17314 m_test_cases.push_back(test_case);
17323 * @param context Test framework context
17325 VaryingLocationAliasingWithMixedTypesTest::VaryingLocationAliasingWithMixedTypesTest(deqp::Context& context)
17326 : NegativeTestBase(context, "varying_location_aliasing_with_mixed_types",
17327 "Test verifies that compiler reports error when float/int types are mixed at one location")
17331 /** Source for given test case and stage
17333 * @param test_case_index Index of test case
17334 * @param stage Shader stage
17336 * @return Shader source
17338 std::string VaryingLocationAliasingWithMixedTypesTest::getShaderSource(GLuint test_case_index,
17339 Utils::Shader::STAGES stage)
17341 static const GLchar* var_definition =
17342 "layout (location = 1, component = COMPONENT) FLAT DIRECTION TYPE gohanARRAY;\n"
17343 "layout (location = 1, component = COMPONENT) FLAT DIRECTION TYPE gotenARRAY;\n";
17344 static const GLchar* input_use = " if ((TYPE(0) == gohanINDEX) &&\n"
17345 " (TYPE(1) == gotenINDEX) )\n"
17347 " result += vec4(1, 0.5, 0.25, 0.125);\n"
17349 static const GLchar* output_use = " gohanINDEX = TYPE(0);\n"
17350 " gotenINDEX = TYPE(1);\n"
17351 " if (vec4(0) == result)\n"
17353 " gohanINDEX = TYPE(1);\n"
17354 " gotenINDEX = TYPE(0);\n"
17356 static const GLchar* fs = "#version 430 core\n"
17357 "#extension GL_ARB_enhanced_layouts : require\n"
17360 "out vec4 fs_out;\n"
17364 " fs_out = gs_fs;\n"
17367 static const GLchar* fs_tested = "#version 430 core\n"
17368 "#extension GL_ARB_enhanced_layouts : require\n"
17373 "out vec4 fs_out;\n"
17377 " vec4 result = gs_fs;\n"
17381 " fs_out += result;\n"
17384 static const GLchar* gs = "#version 430 core\n"
17385 "#extension GL_ARB_enhanced_layouts : require\n"
17387 "layout(points) in;\n"
17388 "layout(triangle_strip, max_vertices = 4) out;\n"
17390 "in vec4 tes_gs[];\n"
17391 "out vec4 gs_fs;\n"
17395 " gs_fs = tes_gs[0];\n"
17396 " gl_Position = vec4(-1, -1, 0, 1);\n"
17398 " gs_fs = tes_gs[0];\n"
17399 " gl_Position = vec4(-1, 1, 0, 1);\n"
17401 " gs_fs = tes_gs[0];\n"
17402 " gl_Position = vec4(1, -1, 0, 1);\n"
17404 " gs_fs = tes_gs[0];\n"
17405 " gl_Position = vec4(1, 1, 0, 1);\n"
17409 static const GLchar* gs_tested = "#version 430 core\n"
17410 "#extension GL_ARB_enhanced_layouts : require\n"
17412 "layout(points) in;\n"
17413 "layout(triangle_strip, max_vertices = 4) out;\n"
17417 "in vec4 tes_gs[];\n"
17418 "out vec4 gs_fs;\n"
17422 " vec4 result = tes_gs[0];\n"
17426 " gs_fs = result;\n"
17427 " gl_Position = vec4(-1, -1, 0, 1);\n"
17429 " gs_fs = result;\n"
17430 " gl_Position = vec4(-1, 1, 0, 1);\n"
17432 " gs_fs = result;\n"
17433 " gl_Position = vec4(1, -1, 0, 1);\n"
17435 " gs_fs = result;\n"
17436 " gl_Position = vec4(1, 1, 0, 1);\n"
17440 static const GLchar* tcs = "#version 430 core\n"
17441 "#extension GL_ARB_enhanced_layouts : require\n"
17443 "layout(vertices = 1) out;\n"
17445 "in vec4 vs_tcs[];\n"
17446 "out vec4 tcs_tes[];\n"
17451 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
17453 " gl_TessLevelOuter[0] = 1.0;\n"
17454 " gl_TessLevelOuter[1] = 1.0;\n"
17455 " gl_TessLevelOuter[2] = 1.0;\n"
17456 " gl_TessLevelOuter[3] = 1.0;\n"
17457 " gl_TessLevelInner[0] = 1.0;\n"
17458 " gl_TessLevelInner[1] = 1.0;\n"
17461 static const GLchar* tcs_tested = "#version 430 core\n"
17462 "#extension GL_ARB_enhanced_layouts : require\n"
17464 "layout(vertices = 1) out;\n"
17468 "in vec4 vs_tcs[];\n"
17469 "out vec4 tcs_tes[];\n"
17473 " vec4 result = vs_tcs[gl_InvocationID];\n"
17477 " tcs_tes[gl_InvocationID] = result;\n"
17479 " gl_TessLevelOuter[0] = 1.0;\n"
17480 " gl_TessLevelOuter[1] = 1.0;\n"
17481 " gl_TessLevelOuter[2] = 1.0;\n"
17482 " gl_TessLevelOuter[3] = 1.0;\n"
17483 " gl_TessLevelInner[0] = 1.0;\n"
17484 " gl_TessLevelInner[1] = 1.0;\n"
17487 static const GLchar* tes = "#version 430 core\n"
17488 "#extension GL_ARB_enhanced_layouts : require\n"
17490 "layout(isolines, point_mode) in;\n"
17492 "in vec4 tcs_tes[];\n"
17493 "out vec4 tes_gs;\n"
17497 " tes_gs = tcs_tes[0];\n"
17500 static const GLchar* tes_tested = "#version 430 core\n"
17501 "#extension GL_ARB_enhanced_layouts : require\n"
17503 "layout(isolines, point_mode) in;\n"
17507 "in vec4 tcs_tes[];\n"
17508 "out vec4 tes_gs;\n"
17512 " vec4 result = tcs_tes[0];\n"
17516 " tes_gs += result;\n"
17519 static const GLchar* vs = "#version 430 core\n"
17520 "#extension GL_ARB_enhanced_layouts : require\n"
17523 "out vec4 vs_tcs;\n"
17527 " vs_tcs = in_vs;\n"
17530 static const GLchar* vs_tested = "#version 430 core\n"
17531 "#extension GL_ARB_enhanced_layouts : require\n"
17536 "out vec4 vs_tcs;\n"
17540 " vec4 result = in_vs;\n"
17544 " vs_tcs += result;\n"
17548 std::string source;
17549 testCase& test_case = m_test_cases[test_case_index];
17551 if (test_case.m_stage == stage)
17553 const GLchar* array = "";
17554 GLchar buffer_gohan[16];
17555 GLchar buffer_goten[16];
17556 const GLchar* direction = "in ";
17557 const GLchar* flat_gohan = "";
17558 const GLchar* flat_goten = "";
17559 const GLchar* index = "";
17560 size_t position = 0;
17562 const GLchar* type_gohan_name = test_case.m_type_gohan.GetGLSLTypeName();
17563 const GLchar* type_goten_name = test_case.m_type_goten.GetGLSLTypeName();
17564 Utils::Variable::STORAGE storage = Utils::Variable::VARYING_INPUT;
17565 const GLchar* var_use = input_use;
17567 if (false == test_case.m_is_input)
17570 storage = Utils::Variable::VARYING_OUTPUT;
17571 var_use = output_use;
17574 if (true == isFlatRequired(stage, test_case.m_type_gohan, storage))
17576 flat_gohan = "flat";
17579 if (true == isFlatRequired(stage, test_case.m_type_goten, storage))
17581 flat_goten = "flat";
17584 sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
17585 sprintf(buffer_goten, "%d", test_case.m_component_goten);
17589 case Utils::Shader::FRAGMENT:
17590 source = fs_tested;
17592 case Utils::Shader::GEOMETRY:
17593 source = gs_tested;
17597 case Utils::Shader::TESS_CTRL:
17598 source = tcs_tested;
17600 index = "[gl_InvocationID]";
17602 case Utils::Shader::TESS_EVAL:
17603 source = tes_tested;
17607 case Utils::Shader::VERTEX:
17608 source = vs_tested;
17611 TCU_FAIL("Invalid enum");
17615 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
17617 Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
17618 Utils::replaceToken("FLAT", position, flat_gohan, source);
17619 Utils::replaceToken("DIRECTION", position, direction, source);
17620 Utils::replaceToken("TYPE", position, type_gohan_name, source);
17621 Utils::replaceToken("ARRAY", position, array, source);
17622 Utils::replaceToken("COMPONENT", position, buffer_goten, source);
17623 Utils::replaceToken("FLAT", position, flat_goten, source);
17624 Utils::replaceToken("DIRECTION", position, direction, source);
17625 Utils::replaceToken("TYPE", position, type_goten_name, source);
17626 Utils::replaceToken("ARRAY", position, array, source);
17629 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
17631 if (true == test_case.m_is_input)
17633 Utils::replaceToken("TYPE", position, type_gohan_name, source);
17634 Utils::replaceToken("TYPE", position, type_goten_name, source);
17638 Utils::replaceToken("TYPE", position, type_gohan_name, source);
17639 Utils::replaceToken("TYPE", position, type_goten_name, source);
17640 Utils::replaceToken("TYPE", position, type_gohan_name, source);
17641 Utils::replaceToken("TYPE", position, type_goten_name, source);
17644 Utils::replaceAllTokens("INDEX", index, source);
17650 case Utils::Shader::FRAGMENT:
17653 case Utils::Shader::GEOMETRY:
17656 case Utils::Shader::TESS_CTRL:
17659 case Utils::Shader::TESS_EVAL:
17662 case Utils::Shader::VERTEX:
17666 TCU_FAIL("Invalid enum");
17673 /** Get description of test case
17675 * @param test_case_index Index of test case
17677 * @return Test case description
17679 std::string VaryingLocationAliasingWithMixedTypesTest::getTestCaseName(GLuint test_case_index)
17681 std::stringstream stream;
17682 testCase& test_case = m_test_cases[test_case_index];
17684 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", "
17685 << test_case.m_type_gohan.GetGLSLTypeName() << " at " << test_case.m_component_gohan << ", "
17686 << test_case.m_type_goten.GetGLSLTypeName() << " at " << test_case.m_component_goten << ". Direction: ";
17688 if (true == test_case.m_is_input)
17694 stream << "output";
17697 return stream.str();
17700 /** Get number of test cases
17702 * @return Number of test cases
17704 GLuint VaryingLocationAliasingWithMixedTypesTest::getTestCaseNumber()
17706 return static_cast<GLuint>(m_test_cases.size());
17709 /** Selects if "compute" stage is relevant for test
17715 bool VaryingLocationAliasingWithMixedTypesTest::isComputeRelevant(GLuint /* test_case_index */)
17720 /** Prepare all test cases
17723 void VaryingLocationAliasingWithMixedTypesTest::testInit()
17725 static const GLuint n_components_per_location = 4;
17726 const GLuint n_types = getTypesNumber();
17728 for (GLuint i = 0; i < n_types; ++i)
17730 const Utils::Type& type_gohan = getType(i);
17731 const bool is_float_type_gohan = isFloatType(type_gohan);
17733 /* Skip matrices */
17734 if (1 != type_gohan.m_n_columns)
17739 for (GLuint j = 0; j < n_types; ++j)
17741 const Utils::Type& type_goten = getType(j);
17742 const bool is_float_type_goten = isFloatType(type_goten);
17744 /* Skip matrices */
17745 if (1 != type_goten.m_n_columns)
17750 /* Skip valid combinations */
17751 if (is_float_type_gohan == is_float_type_goten)
17756 const GLuint n_req_components_gohan = type_gohan.m_n_rows;
17757 const GLuint n_req_components_goten = type_goten.m_n_rows;
17758 const GLuint valid_component_gohan = n_components_per_location - n_req_components_gohan;
17759 const GLuint valid_component_goten = n_components_per_location - n_req_components_goten;
17761 /* Skip pairs that cannot fit into one location */
17762 if (n_components_per_location < (n_req_components_gohan + n_req_components_goten))
17767 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
17769 /* Skip compute shader */
17770 if (Utils::Shader::COMPUTE == stage)
17775 for (GLuint gohan = 0; gohan <= valid_component_gohan; ++gohan)
17777 const GLint first_aliasing = gohan - n_req_components_goten + 1;
17778 const GLint last_aliasing = gohan + n_req_components_gohan - 1;
17780 const GLuint goten_lower_limit = std::max(0, first_aliasing);
17781 const GLuint goten_upper_limit = last_aliasing + 1;
17783 /* Compoennets before gohan */
17784 for (GLuint goten = 0; goten < goten_lower_limit; ++goten)
17786 testCase test_case_in = { gohan, goten, true, (Utils::Shader::STAGES)stage,
17787 type_gohan, type_goten };
17788 testCase test_case_out = { gohan, goten, false, (Utils::Shader::STAGES)stage,
17789 type_gohan, type_goten };
17791 m_test_cases.push_back(test_case_in);
17793 /* Skip double outputs in fragment shader */
17794 if ((Utils::Shader::FRAGMENT != stage) || ((Utils::Type::Double != type_gohan.m_basic_type) &&
17795 (Utils::Type::Double != type_goten.m_basic_type)))
17797 m_test_cases.push_back(test_case_out);
17801 /* Components after gohan */
17802 for (GLuint goten = goten_upper_limit; goten <= valid_component_goten; ++goten)
17804 testCase test_case_in = { gohan, goten, true, (Utils::Shader::STAGES)stage,
17805 type_gohan, type_goten };
17806 testCase test_case_out = { gohan, goten, false, (Utils::Shader::STAGES)stage,
17807 type_gohan, type_goten };
17809 m_test_cases.push_back(test_case_in);
17811 /* Skip double outputs in fragment shader */
17812 if ((Utils::Shader::FRAGMENT != stage) || ((Utils::Type::Double != type_gohan.m_basic_type) &&
17813 (Utils::Type::Double != type_goten.m_basic_type)))
17815 m_test_cases.push_back(test_case_out);
17824 /** Check if given type is float
17826 * @param type Type in question
17828 * @return true if tpye is float, false otherwise
17830 bool VaryingLocationAliasingWithMixedTypesTest::isFloatType(const Utils::Type& type)
17832 bool is_float = false;
17834 if ((Utils::Type::Double == type.m_basic_type) || (Utils::Type::Float == type.m_basic_type))
17844 * @param context Test framework context
17846 VaryingLocationAliasingWithMixedInterpolationTest::VaryingLocationAliasingWithMixedInterpolationTest(
17847 deqp::Context& context)
17848 : NegativeTestBase(
17849 context, "varying_location_aliasing_with_mixed_interpolation",
17850 "Test verifies that compiler reports error when interpolation qualifiers are mixed at one location")
17854 /** Source for given test case and stage
17856 * @param test_case_index Index of test case
17857 * @param stage Shader stage
17859 * @return Shader source
17861 std::string VaryingLocationAliasingWithMixedInterpolationTest::getShaderSource(GLuint test_case_index,
17862 Utils::Shader::STAGES stage)
17864 static const GLchar* var_definition =
17865 "layout (location = 1, component = COMPONENT) INTERPOLATION DIRECTION TYPE gohanARRAY;\n"
17866 "layout (location = 1, component = COMPONENT) INTERPOLATION DIRECTION TYPE gotenARRAY;\n";
17867 static const GLchar* input_use = " if ((TYPE(0) == gohanINDEX) &&\n"
17868 " (TYPE(1) == gotenINDEX) )\n"
17870 " result += vec4(1, 0.5, 0.25, 0.125);\n"
17872 static const GLchar* output_use = " gohanINDEX = TYPE(0);\n"
17873 " gotenINDEX = TYPE(1);\n"
17874 " if (vec4(0) == result)\n"
17876 " gohanINDEX = TYPE(1);\n"
17877 " gotenINDEX = TYPE(0);\n"
17879 static const GLchar* fs = "#version 430 core\n"
17880 "#extension GL_ARB_enhanced_layouts : require\n"
17883 "out vec4 fs_out;\n"
17887 " fs_out = gs_fs;\n"
17890 static const GLchar* fs_tested = "#version 430 core\n"
17891 "#extension GL_ARB_enhanced_layouts : require\n"
17896 "out vec4 fs_out;\n"
17900 " vec4 result = gs_fs;\n"
17904 " fs_out = result;\n"
17907 static const GLchar* gs = "#version 430 core\n"
17908 "#extension GL_ARB_enhanced_layouts : require\n"
17910 "layout(points) in;\n"
17911 "layout(triangle_strip, max_vertices = 4) out;\n"
17913 "in vec4 tes_gs[];\n"
17914 "out vec4 gs_fs;\n"
17918 " gs_fs = tes_gs[0];\n"
17919 " gl_Position = vec4(-1, -1, 0, 1);\n"
17921 " gs_fs = tes_gs[0];\n"
17922 " gl_Position = vec4(-1, 1, 0, 1);\n"
17924 " gs_fs = tes_gs[0];\n"
17925 " gl_Position = vec4(1, -1, 0, 1);\n"
17927 " gs_fs = tes_gs[0];\n"
17928 " gl_Position = vec4(1, 1, 0, 1);\n"
17932 static const GLchar* gs_tested = "#version 430 core\n"
17933 "#extension GL_ARB_enhanced_layouts : require\n"
17935 "layout(points) in;\n"
17936 "layout(triangle_strip, max_vertices = 4) out;\n"
17940 "in vec4 tes_gs[];\n"
17941 "out vec4 gs_fs;\n"
17945 " vec4 result = tes_gs[0];\n"
17949 " gs_fs = result;\n"
17950 " gl_Position = vec4(-1, -1, 0, 1);\n"
17952 " gs_fs = result;\n"
17953 " gl_Position = vec4(-1, 1, 0, 1);\n"
17955 " gs_fs = result;\n"
17956 " gl_Position = vec4(1, -1, 0, 1);\n"
17958 " gs_fs = result;\n"
17959 " gl_Position = vec4(1, 1, 0, 1);\n"
17963 static const GLchar* tcs = "#version 430 core\n"
17964 "#extension GL_ARB_enhanced_layouts : require\n"
17966 "layout(vertices = 1) out;\n"
17968 "in vec4 vs_tcs[];\n"
17969 "out vec4 tcs_tes[];\n"
17974 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
17976 " gl_TessLevelOuter[0] = 1.0;\n"
17977 " gl_TessLevelOuter[1] = 1.0;\n"
17978 " gl_TessLevelOuter[2] = 1.0;\n"
17979 " gl_TessLevelOuter[3] = 1.0;\n"
17980 " gl_TessLevelInner[0] = 1.0;\n"
17981 " gl_TessLevelInner[1] = 1.0;\n"
17984 static const GLchar* tcs_tested = "#version 430 core\n"
17985 "#extension GL_ARB_enhanced_layouts : require\n"
17987 "layout(vertices = 1) out;\n"
17991 "in vec4 vs_tcs[];\n"
17992 "out vec4 tcs_tes[];\n"
17996 " vec4 result = vs_tcs[gl_InvocationID];\n"
18000 " tcs_tes[gl_InvocationID] = result;\n"
18002 " gl_TessLevelOuter[0] = 1.0;\n"
18003 " gl_TessLevelOuter[1] = 1.0;\n"
18004 " gl_TessLevelOuter[2] = 1.0;\n"
18005 " gl_TessLevelOuter[3] = 1.0;\n"
18006 " gl_TessLevelInner[0] = 1.0;\n"
18007 " gl_TessLevelInner[1] = 1.0;\n"
18010 static const GLchar* tes = "#version 430 core\n"
18011 "#extension GL_ARB_enhanced_layouts : require\n"
18013 "layout(isolines, point_mode) in;\n"
18015 "in vec4 tcs_tes[];\n"
18016 "out vec4 tes_gs;\n"
18020 " tes_gs = tcs_tes[0];\n"
18023 static const GLchar* tes_tested = "#version 430 core\n"
18024 "#extension GL_ARB_enhanced_layouts : require\n"
18026 "layout(isolines, point_mode) in;\n"
18030 "in vec4 tcs_tes[];\n"
18031 "out vec4 tes_gs;\n"
18035 " vec4 result = tcs_tes[0];\n"
18039 " tes_gs += result;\n"
18042 static const GLchar* vs = "#version 430 core\n"
18043 "#extension GL_ARB_enhanced_layouts : require\n"
18046 "out vec4 vs_tcs;\n"
18050 " vs_tcs = in_vs;\n"
18053 static const GLchar* vs_tested = "#version 430 core\n"
18054 "#extension GL_ARB_enhanced_layouts : require\n"
18059 "out vec4 vs_tcs;\n"
18063 " vec4 result = in_vs;\n"
18067 " vs_tcs += result;\n"
18071 std::string source;
18072 testCase& test_case = m_test_cases[test_case_index];
18074 if (test_case.m_stage == stage)
18076 const GLchar* array = "";
18077 GLchar buffer_gohan[16];
18078 GLchar buffer_goten[16];
18079 const GLchar* direction = "in ";
18080 const GLchar* index = "";
18081 const GLchar* int_gohan = getInterpolationQualifier(test_case.m_interpolation_gohan);
18082 const GLchar* int_goten = getInterpolationQualifier(test_case.m_interpolation_goten);
18083 size_t position = 0;
18085 const GLchar* type_gohan_name = test_case.m_type_gohan.GetGLSLTypeName();
18086 const GLchar* type_goten_name = test_case.m_type_goten.GetGLSLTypeName();
18087 const GLchar* var_use = input_use;
18089 if (false == test_case.m_is_input)
18093 var_use = output_use;
18096 sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
18097 sprintf(buffer_goten, "%d", test_case.m_component_goten);
18101 case Utils::Shader::FRAGMENT:
18102 source = fs_tested;
18104 case Utils::Shader::GEOMETRY:
18105 source = gs_tested;
18109 case Utils::Shader::TESS_CTRL:
18110 source = tcs_tested;
18112 index = "[gl_InvocationID]";
18114 case Utils::Shader::TESS_EVAL:
18115 source = tes_tested;
18119 case Utils::Shader::VERTEX:
18120 source = vs_tested;
18123 TCU_FAIL("Invalid enum");
18127 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
18129 Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
18130 Utils::replaceToken("INTERPOLATION", position, int_gohan, source);
18131 Utils::replaceToken("DIRECTION", position, direction, source);
18132 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18133 Utils::replaceToken("ARRAY", position, array, source);
18134 Utils::replaceToken("COMPONENT", position, buffer_goten, source);
18135 Utils::replaceToken("INTERPOLATION", position, int_goten, source);
18136 Utils::replaceToken("DIRECTION", position, direction, source);
18137 Utils::replaceToken("TYPE", position, type_goten_name, source);
18138 Utils::replaceToken("ARRAY", position, array, source);
18141 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
18143 if (true == test_case.m_is_input)
18145 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18146 Utils::replaceToken("TYPE", position, type_goten_name, source);
18150 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18151 Utils::replaceToken("TYPE", position, type_goten_name, source);
18152 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18153 Utils::replaceToken("TYPE", position, type_goten_name, source);
18156 Utils::replaceAllTokens("INDEX", index, source);
18162 case Utils::Shader::FRAGMENT:
18165 case Utils::Shader::GEOMETRY:
18168 case Utils::Shader::TESS_CTRL:
18171 case Utils::Shader::TESS_EVAL:
18174 case Utils::Shader::VERTEX:
18178 TCU_FAIL("Invalid enum");
18185 /** Get description of test case
18187 * @param test_case_index Index of test case
18189 * @return Test case description
18191 std::string VaryingLocationAliasingWithMixedInterpolationTest::getTestCaseName(GLuint test_case_index)
18193 std::stringstream stream;
18194 testCase& test_case = m_test_cases[test_case_index];
18196 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", "
18197 << getInterpolationQualifier(test_case.m_interpolation_gohan) << " "
18198 << test_case.m_type_gohan.GetGLSLTypeName() << " at " << test_case.m_component_gohan << ", "
18199 << getInterpolationQualifier(test_case.m_interpolation_goten) << " "
18200 << test_case.m_type_goten.GetGLSLTypeName() << " at " << test_case.m_component_goten << ". Direction: ";
18202 if (true == test_case.m_is_input)
18208 stream << "output";
18211 return stream.str();
18214 /** Get number of test cases
18216 * @return Number of test cases
18218 GLuint VaryingLocationAliasingWithMixedInterpolationTest::getTestCaseNumber()
18220 return static_cast<GLuint>(m_test_cases.size());
18223 /** Selects if "compute" stage is relevant for test
18229 bool VaryingLocationAliasingWithMixedInterpolationTest::isComputeRelevant(GLuint /* test_case_index */)
18234 /** Prepare all test cases
18237 void VaryingLocationAliasingWithMixedInterpolationTest::testInit()
18239 static const GLuint n_components_per_location = 4;
18240 const GLuint n_types = getTypesNumber();
18242 for (GLuint i = 0; i < n_types; ++i)
18244 const Utils::Type& type_gohan = getType(i);
18245 const bool is_float_type_gohan = isFloatType(type_gohan);
18247 /* Skip matrices */
18248 if (1 != type_gohan.m_n_columns)
18253 for (GLuint j = 0; j < n_types; ++j)
18255 const Utils::Type& type_goten = getType(j);
18256 const bool is_float_type_goten = isFloatType(type_goten);
18258 /* Skip matrices */
18259 if (1 != type_goten.m_n_columns)
18264 /* Skip invalid combinations */
18265 if (is_float_type_gohan != is_float_type_goten)
18270 const GLuint n_req_components_gohan = type_gohan.m_n_rows;
18271 const GLuint n_req_components_goten = type_goten.m_n_rows;
18273 /* Skip pairs that cannot fit into one location */
18274 if (n_components_per_location < (n_req_components_gohan + n_req_components_goten))
18279 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
18281 /* Skip compute shader */
18282 if (Utils::Shader::COMPUTE == stage)
18287 const GLuint gohan = 0;
18288 const GLuint goten = gohan + n_req_components_gohan;
18290 for (GLuint int_gohan = 0; int_gohan < INTERPOLATION_MAX; ++int_gohan)
18292 for (GLuint int_goten = 0; int_goten < INTERPOLATION_MAX; ++int_goten)
18294 const bool is_gohan_double = (Utils::Type::Double == type_gohan.m_basic_type) ? true : false;
18295 const bool is_goten_double = (Utils::Type::Double == type_goten.m_basic_type) ? true : false;
18296 const bool is_gohan_flat = (FLAT == int_gohan) ? true : false;
18297 const bool is_goten_flat = (FLAT == int_goten) ? true : false;
18298 const bool is_gohan_accepted_as_fs_in =
18299 (is_gohan_double && is_gohan_flat) || (!is_gohan_double);
18300 const bool is_goten_accepted_as_fs_in =
18301 (is_goten_double && is_goten_flat) || (!is_goten_double);
18302 const bool is_comb_accepted_as_fs_in = is_gohan_accepted_as_fs_in && is_goten_accepted_as_fs_in;
18304 /* Skip when both are the same */
18305 if (int_gohan == int_goten)
18310 testCase test_case_in = { gohan,
18312 (INTERPOLATIONS)int_gohan,
18313 (INTERPOLATIONS)int_goten,
18315 (Utils::Shader::STAGES)stage,
18319 testCase test_case_out = { gohan,
18321 (INTERPOLATIONS)int_gohan,
18322 (INTERPOLATIONS)int_goten,
18324 (Utils::Shader::STAGES)stage,
18330 * fragment shader when not flat double is used
18332 if ((Utils::Shader::VERTEX != stage) &&
18333 ((Utils::Shader::FRAGMENT != stage) || (true == is_comb_accepted_as_fs_in)))
18335 m_test_cases.push_back(test_case_in);
18338 /* Skip outputs in fragment shader */
18339 if (Utils::Shader::FRAGMENT != stage)
18341 m_test_cases.push_back(test_case_out);
18350 /** Get interpolation qualifier
18352 * @param interpolation Enumeration
18354 * @return GLSL qualifier
18356 const GLchar* VaryingLocationAliasingWithMixedInterpolationTest::getInterpolationQualifier(INTERPOLATIONS interpolation)
18358 const GLchar* result = 0;
18360 switch (interpolation)
18368 case NO_PERSPECTIVE:
18369 result = "noperspective";
18372 TCU_FAIL("Invalid enum");
18378 /** Check if given type is float
18380 * @param type Type in question
18382 * @return true if tpye is float, false otherwise
18384 bool VaryingLocationAliasingWithMixedInterpolationTest::isFloatType(const Utils::Type& type)
18386 bool is_float = false;
18388 if ((Utils::Type::Double == type.m_basic_type) || (Utils::Type::Float == type.m_basic_type))
18398 * @param context Test framework context
18400 VaryingLocationAliasingWithMixedAuxiliaryStorageTest::VaryingLocationAliasingWithMixedAuxiliaryStorageTest(
18401 deqp::Context& context)
18402 : NegativeTestBase(
18403 context, "varying_location_aliasing_with_mixed_auxiliary_storage",
18404 "Test verifies that compiler reports error when auxiliary storage qualifiers are mixed at one location")
18408 /** Source for given test case and stage
18410 * @param test_case_index Index of test case
18411 * @param stage Shader stage
18413 * @return Shader source
18415 std::string VaryingLocationAliasingWithMixedAuxiliaryStorageTest::getShaderSource(GLuint test_case_index,
18416 Utils::Shader::STAGES stage)
18418 static const GLchar* var_definition =
18419 "layout (location = 1, component = COMPONENT) AUX INTERPOLATION DIRECTION TYPE gohanARRAY;\n"
18420 "layout (location = 1, component = COMPONENT) AUX INTERPOLATION DIRECTION TYPE gotenARRAY;\n";
18421 static const GLchar* input_use = " if ((TYPE(0) == gohanINDEX_GOHAN) &&\n"
18422 " (TYPE(1) == gotenINDEX_GOTEN) )\n"
18424 " result += vec4(1, 0.5, 0.25, 0.125);\n"
18426 static const GLchar* output_use = " gohanINDEX_GOHAN = TYPE(0);\n"
18427 " gotenINDEX_GOTEN = TYPE(1);\n"
18428 " if (vec4(0) == result)\n"
18430 " gohanINDEX_GOHAN = TYPE(1);\n"
18431 " gotenINDEX_GOTEN = TYPE(0);\n"
18433 static const GLchar* fs = "#version 430 core\n"
18434 "#extension GL_ARB_enhanced_layouts : require\n"
18437 "out vec4 fs_out;\n"
18441 " fs_out = gs_fs;\n"
18444 static const GLchar* fs_tested = "#version 430 core\n"
18445 "#extension GL_ARB_enhanced_layouts : require\n"
18450 "out vec4 fs_out;\n"
18454 " vec4 result = gs_fs;\n"
18458 " fs_out = result;\n"
18461 static const GLchar* gs = "#version 430 core\n"
18462 "#extension GL_ARB_enhanced_layouts : require\n"
18464 "layout(points) in;\n"
18465 "layout(triangle_strip, max_vertices = 4) out;\n"
18467 "in vec4 tes_gs[];\n"
18468 "out vec4 gs_fs;\n"
18472 " gs_fs = tes_gs[0];\n"
18473 " gl_Position = vec4(-1, -1, 0, 1);\n"
18475 " gs_fs = tes_gs[0];\n"
18476 " gl_Position = vec4(-1, 1, 0, 1);\n"
18478 " gs_fs = tes_gs[0];\n"
18479 " gl_Position = vec4(1, -1, 0, 1);\n"
18481 " gs_fs = tes_gs[0];\n"
18482 " gl_Position = vec4(1, 1, 0, 1);\n"
18486 static const GLchar* gs_tested = "#version 430 core\n"
18487 "#extension GL_ARB_enhanced_layouts : require\n"
18489 "layout(points) in;\n"
18490 "layout(triangle_strip, max_vertices = 4) out;\n"
18494 "in vec4 tes_gs[];\n"
18495 "out vec4 gs_fs;\n"
18499 " vec4 result = tes_gs[0];\n"
18503 " gs_fs = result;\n"
18504 " gl_Position = vec4(-1, -1, 0, 1);\n"
18506 " gs_fs = result;\n"
18507 " gl_Position = vec4(-1, 1, 0, 1);\n"
18509 " gs_fs = result;\n"
18510 " gl_Position = vec4(1, -1, 0, 1);\n"
18512 " gs_fs = result;\n"
18513 " gl_Position = vec4(1, 1, 0, 1);\n"
18517 static const GLchar* tcs = "#version 430 core\n"
18518 "#extension GL_ARB_enhanced_layouts : require\n"
18520 "layout(vertices = 1) out;\n"
18522 "in vec4 vs_tcs[];\n"
18523 "out vec4 tcs_tes[];\n"
18528 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
18530 " gl_TessLevelOuter[0] = 1.0;\n"
18531 " gl_TessLevelOuter[1] = 1.0;\n"
18532 " gl_TessLevelOuter[2] = 1.0;\n"
18533 " gl_TessLevelOuter[3] = 1.0;\n"
18534 " gl_TessLevelInner[0] = 1.0;\n"
18535 " gl_TessLevelInner[1] = 1.0;\n"
18538 static const GLchar* tcs_tested = "#version 430 core\n"
18539 "#extension GL_ARB_enhanced_layouts : require\n"
18541 "layout(vertices = 1) out;\n"
18545 "in vec4 vs_tcs[];\n"
18546 "out vec4 tcs_tes[];\n"
18550 " vec4 result = vs_tcs[gl_InvocationID];\n"
18554 " tcs_tes[gl_InvocationID] = result;\n"
18556 " gl_TessLevelOuter[0] = 1.0;\n"
18557 " gl_TessLevelOuter[1] = 1.0;\n"
18558 " gl_TessLevelOuter[2] = 1.0;\n"
18559 " gl_TessLevelOuter[3] = 1.0;\n"
18560 " gl_TessLevelInner[0] = 1.0;\n"
18561 " gl_TessLevelInner[1] = 1.0;\n"
18564 static const GLchar* tes = "#version 430 core\n"
18565 "#extension GL_ARB_enhanced_layouts : require\n"
18567 "layout(isolines, point_mode) in;\n"
18569 "in vec4 tcs_tes[];\n"
18570 "out vec4 tes_gs;\n"
18574 " tes_gs = tcs_tes[0];\n"
18577 static const GLchar* tes_tested = "#version 430 core\n"
18578 "#extension GL_ARB_enhanced_layouts : require\n"
18580 "layout(isolines, point_mode) in;\n"
18584 "in vec4 tcs_tes[];\n"
18585 "out vec4 tes_gs;\n"
18589 " vec4 result = tcs_tes[0];\n"
18593 " tes_gs += result;\n"
18596 static const GLchar* vs = "#version 430 core\n"
18597 "#extension GL_ARB_enhanced_layouts : require\n"
18600 "out vec4 vs_tcs;\n"
18604 " vs_tcs = in_vs;\n"
18607 static const GLchar* vs_tested = "#version 430 core\n"
18608 "#extension GL_ARB_enhanced_layouts : require\n"
18613 "out vec4 vs_tcs;\n"
18617 " vec4 result = in_vs;\n"
18621 " vs_tcs += result;\n"
18625 std::string source;
18626 testCase& test_case = m_test_cases[test_case_index];
18628 if (test_case.m_stage == stage)
18630 const GLchar* array_gohan = "";
18631 const GLchar* array_goten = "";
18632 const GLchar* aux_gohan = getAuxiliaryQualifier(test_case.m_aux_gohan);
18633 const GLchar* aux_goten = getAuxiliaryQualifier(test_case.m_aux_goten);
18634 GLchar buffer_gohan[16];
18635 GLchar buffer_goten[16];
18636 const GLchar* direction = "in ";
18637 const GLchar* index_gohan = "";
18638 const GLchar* index_goten = "";
18639 const GLchar* int_gohan = test_case.m_int_gohan;
18640 const GLchar* int_goten = test_case.m_int_goten;
18641 size_t position = 0;
18643 const GLchar* type_gohan_name = test_case.m_type_gohan.GetGLSLTypeName();
18644 const GLchar* type_goten_name = test_case.m_type_goten.GetGLSLTypeName();
18645 const GLchar* var_use = input_use;
18647 if (false == test_case.m_is_input)
18651 var_use = output_use;
18654 sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
18655 sprintf(buffer_goten, "%d", test_case.m_component_goten);
18659 case Utils::Shader::FRAGMENT:
18660 source = fs_tested;
18662 case Utils::Shader::GEOMETRY:
18663 source = gs_tested;
18664 array_gohan = "[]";
18665 index_gohan = "[0]";
18666 array_goten = "[]";
18667 index_goten = "[0]";
18669 case Utils::Shader::TESS_CTRL:
18670 source = tcs_tested;
18671 if (PATCH != test_case.m_aux_gohan)
18673 array_gohan = "[]";
18674 index_gohan = "[gl_InvocationID]";
18676 if (PATCH != test_case.m_aux_goten)
18678 array_goten = "[]";
18679 index_goten = "[gl_InvocationID]";
18682 case Utils::Shader::TESS_EVAL:
18683 source = tes_tested;
18684 array_gohan = "[]";
18685 index_gohan = "[0]";
18686 array_goten = "[]";
18687 index_goten = "[0]";
18689 case Utils::Shader::VERTEX:
18690 source = vs_tested;
18693 TCU_FAIL("Invalid enum");
18697 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
18699 Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
18700 Utils::replaceToken("AUX", position, aux_gohan, source);
18701 Utils::replaceToken("INTERPOLATION", position, int_gohan, source);
18702 Utils::replaceToken("DIRECTION", position, direction, source);
18703 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18704 Utils::replaceToken("ARRAY", position, array_gohan, source);
18705 Utils::replaceToken("COMPONENT", position, buffer_goten, source);
18706 Utils::replaceToken("AUX", position, aux_goten, source);
18707 Utils::replaceToken("INTERPOLATION", position, int_goten, source);
18708 Utils::replaceToken("DIRECTION", position, direction, source);
18709 Utils::replaceToken("TYPE", position, type_goten_name, source);
18710 Utils::replaceToken("ARRAY", position, array_goten, source);
18713 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
18715 if (true == test_case.m_is_input)
18717 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18718 Utils::replaceToken("TYPE", position, type_goten_name, source);
18722 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18723 Utils::replaceToken("TYPE", position, type_goten_name, source);
18724 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18725 Utils::replaceToken("TYPE", position, type_goten_name, source);
18728 Utils::replaceAllTokens("INDEX_GOHAN", index_gohan, source);
18729 Utils::replaceAllTokens("INDEX_GOTEN", index_goten, source);
18735 case Utils::Shader::FRAGMENT:
18738 case Utils::Shader::GEOMETRY:
18741 case Utils::Shader::TESS_CTRL:
18744 case Utils::Shader::TESS_EVAL:
18747 case Utils::Shader::VERTEX:
18751 TCU_FAIL("Invalid enum");
18758 /** Get description of test case
18760 * @param test_case_index Index of test case
18762 * @return Test case description
18764 std::string VaryingLocationAliasingWithMixedAuxiliaryStorageTest::getTestCaseName(GLuint test_case_index)
18766 std::stringstream stream;
18767 testCase& test_case = m_test_cases[test_case_index];
18769 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", "
18770 << getAuxiliaryQualifier(test_case.m_aux_gohan) << " " << test_case.m_type_gohan.GetGLSLTypeName() << " at "
18771 << test_case.m_component_gohan << ", " << getAuxiliaryQualifier(test_case.m_aux_goten) << " "
18772 << test_case.m_type_goten.GetGLSLTypeName() << " at " << test_case.m_component_goten << ". Direction: ";
18774 if (true == test_case.m_is_input)
18780 stream << "output";
18783 return stream.str();
18786 /** Get number of test cases
18788 * @return Number of test cases
18790 GLuint VaryingLocationAliasingWithMixedAuxiliaryStorageTest::getTestCaseNumber()
18792 return static_cast<GLuint>(m_test_cases.size());
18795 /** Selects if "compute" stage is relevant for test
18801 bool VaryingLocationAliasingWithMixedAuxiliaryStorageTest::isComputeRelevant(GLuint /* test_case_index */)
18806 /** Prepare all test cases
18809 void VaryingLocationAliasingWithMixedAuxiliaryStorageTest::testInit()
18811 static const GLuint n_components_per_location = 4;
18812 const GLuint n_types = getTypesNumber();
18814 for (GLuint i = 0; i < n_types; ++i)
18816 const Utils::Type& type_gohan = getType(i);
18817 const bool is_float_type_gohan = isFloatType(type_gohan);
18819 /* Skip matrices */
18820 if (1 != type_gohan.m_n_columns)
18825 for (GLuint j = 0; j < n_types; ++j)
18827 const Utils::Type& type_goten = getType(j);
18828 const bool is_flat_req_gohan = (Utils::Type::Float == type_gohan.m_basic_type) ? false : true;
18829 const bool is_flat_req_goten = (Utils::Type::Float == type_goten.m_basic_type) ? false : true;
18830 const bool is_float_type_goten = isFloatType(type_goten);
18832 /* Skip matrices */
18833 if (1 != type_goten.m_n_columns)
18838 /* Skip invalid combinations */
18839 if (is_float_type_gohan != is_float_type_goten)
18844 const GLuint n_req_components_gohan = type_gohan.m_n_rows;
18845 const GLuint n_req_components_goten = type_goten.m_n_rows;
18847 /* Skip pairs that cannot fit into one location */
18848 if (n_components_per_location < (n_req_components_gohan + n_req_components_goten))
18853 const GLuint gohan = 0;
18854 const GLuint goten = gohan + n_req_components_gohan;
18856 const GLchar* fs_int_gohan = is_flat_req_gohan ? "flat" : "";
18857 const GLchar* fs_int_goten = is_flat_req_goten ? "flat" : "";
18859 testCase test_case_tcs_np = { gohan, goten, NONE, PATCH, "", "", false, Utils::Shader::TESS_CTRL,
18860 type_gohan, type_goten };
18862 testCase test_case_tcs_pn = { gohan, goten, PATCH, NONE, "", "", false, Utils::Shader::TESS_CTRL,
18863 type_gohan, type_goten };
18865 testCase test_case_tes_np = { gohan, goten, NONE, PATCH, "", "", true, Utils::Shader::TESS_EVAL,
18866 type_gohan, type_goten };
18868 testCase test_case_tes_pn = { gohan, goten, PATCH, NONE, "", "", true, Utils::Shader::TESS_EVAL,
18869 type_gohan, type_goten };
18871 testCase test_case_fs_nc = { gohan, goten, NONE, CENTROID,
18872 fs_int_gohan, fs_int_goten, true, Utils::Shader::FRAGMENT,
18873 type_gohan, type_goten };
18875 testCase test_case_fs_cn = { gohan, goten, CENTROID, NONE,
18876 fs_int_gohan, fs_int_goten, true, Utils::Shader::FRAGMENT,
18877 type_gohan, type_goten };
18879 testCase test_case_fs_ns = { gohan, goten, NONE, SAMPLE,
18880 fs_int_gohan, fs_int_goten, true, Utils::Shader::FRAGMENT,
18881 type_gohan, type_goten };
18883 testCase test_case_fs_sn = { gohan, goten, SAMPLE, NONE,
18884 fs_int_gohan, fs_int_goten, true, Utils::Shader::FRAGMENT,
18885 type_gohan, type_goten };
18887 testCase test_case_fs_cs = { gohan, goten, CENTROID, SAMPLE,
18888 fs_int_gohan, fs_int_goten, true, Utils::Shader::FRAGMENT,
18889 type_gohan, type_goten };
18891 testCase test_case_fs_sc = { gohan, goten, SAMPLE, CENTROID,
18892 fs_int_gohan, fs_int_goten, true, Utils::Shader::FRAGMENT,
18893 type_gohan, type_goten };
18895 m_test_cases.push_back(test_case_tcs_np);
18896 m_test_cases.push_back(test_case_tcs_pn);
18897 m_test_cases.push_back(test_case_tes_np);
18898 m_test_cases.push_back(test_case_tes_pn);
18899 m_test_cases.push_back(test_case_fs_nc);
18900 m_test_cases.push_back(test_case_fs_cn);
18901 m_test_cases.push_back(test_case_fs_ns);
18902 m_test_cases.push_back(test_case_fs_sn);
18903 m_test_cases.push_back(test_case_fs_cs);
18904 m_test_cases.push_back(test_case_fs_sc);
18909 /** Get auxiliary storage qualifier
18911 * @param aux Enumeration
18913 * @return GLSL qualifier
18915 const GLchar* VaryingLocationAliasingWithMixedAuxiliaryStorageTest::getAuxiliaryQualifier(AUXILIARIES aux)
18917 const GLchar* result = 0;
18928 result = "centroid";
18934 TCU_FAIL("Invalid enum");
18940 /** Check if given type is float
18942 * @param type Type in question
18944 * @return true if tpye is float, false otherwise
18946 bool VaryingLocationAliasingWithMixedAuxiliaryStorageTest::isFloatType(const Utils::Type& type)
18948 bool is_float = false;
18950 if ((Utils::Type::Double == type.m_basic_type) || (Utils::Type::Float == type.m_basic_type))
18958 /* Constants used by VertexAttribLocationAPITest */
18959 const GLuint VertexAttribLocationAPITest::m_goten_location = 6;
18963 * @param context Test framework context
18965 VertexAttribLocationAPITest::VertexAttribLocationAPITest(deqp::Context& context)
18966 : TextureTestBase(context, "vertex_attrib_location_api",
18967 "Test verifies that attribute locations API works as expected")
18971 /** Does BindAttribLocation for "goten" and relink program
18973 * @param program Program object
18974 * @param program_interface Interface of program
18976 void VertexAttribLocationAPITest::prepareAttribLocation(Utils::Program& program,
18977 Utils::ProgramInterface& program_interface)
18979 const Functions& gl = m_context.getRenderContext().getFunctions();
18981 gl.bindAttribLocation(program.m_id, m_goten_location, "goten");
18982 GLU_EXPECT_NO_ERROR(gl.getError(), "BindAttribLocation");
18984 program.Link(gl, program.m_id);
18986 /* We still need to get locations for gohan and chichi */
18987 TextureTestBase::prepareAttribLocation(program, program_interface);
18990 /** Get interface of program
18993 * @param program_interface Interface of program
18996 void VertexAttribLocationAPITest::getProgramInterface(GLuint /* test_case_index */,
18997 Utils::ProgramInterface& program_interface,
18998 Utils::VaryingPassthrough& /* varying_passthrough */)
19000 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
19001 const Utils::Type& type = Utils::Type::vec4;
19002 const GLuint type_size = type.GetSize();
19005 const GLuint chichi_offset = 0;
19006 const GLuint goten_offset = chichi_offset + type_size;
19007 const GLuint gohan_offset = goten_offset + type_size;
19008 const GLuint goku_offset = gohan_offset + type_size;
19011 const GLuint goku_location = 2;
19012 const GLuint goten_location = m_goten_location;
19014 /* Generate data */
19015 m_goku_data = type.GenerateDataPacked();
19016 m_gohan_data = type.GenerateDataPacked();
19017 m_goten_data = type.GenerateDataPacked();
19018 m_chichi_data = type.GenerateDataPacked();
19021 si.m_globals = "const uint GOKU_LOCATION = 2;\n";
19024 si.Input("goku" /* name */, "layout (location = GOKU_LOCATION)" /* qualifiers */, 0 /* expected_componenet */,
19025 goku_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19026 0u /* n_array_elements */, 0u /* stride */, goku_offset /* offset */, (GLvoid*)&m_goku_data[0] /* data */,
19027 m_goku_data.size() /* data_size */);
19029 si.Input("gohan" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19030 Utils::Variable::m_automatic_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19031 0u /* n_array_elements */, 0u /* stride */, gohan_offset /* offset */,
19032 (GLvoid*)&m_gohan_data[0] /* data */, m_gohan_data.size() /* data_size */);
19034 si.Input("goten" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19035 goten_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19036 0u /* n_array_elements */, 0u /* stride */, goten_offset /* offset */,
19037 (GLvoid*)&m_goten_data[0] /* data */, m_goten_data.size() /* data_size */);
19039 si.Input("chichi" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19040 Utils::Variable::m_automatic_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19041 0u /* n_array_elements */, 0u /* stride */, chichi_offset /* offset */,
19042 (GLvoid*)&m_chichi_data[0] /* data */, m_chichi_data.size() /* data_size */);
19045 /** Selects if "compute" stage is relevant for test
19051 bool VertexAttribLocationAPITest::isComputeRelevant(GLuint /* test_case_index */)
19056 /* Constants used by FragmentDataLocationAPITest */
19057 const GLuint FragmentDataLocationAPITest::m_goten_location = 6;
19061 * @param context Test framework context
19063 FragmentDataLocationAPITest::FragmentDataLocationAPITest(deqp::Context& context)
19064 : TextureTestBase(context, "fragment_data_location_api",
19065 "Test verifies that fragment data locations API works as expected")
19069 , m_chichi(context)
19073 /** Verifies contents of drawn images
19078 * @return true if images are filled with expected values, false otherwise
19080 bool FragmentDataLocationAPITest::checkResults(glw::GLuint /* test_case_index */, Utils::Texture& /* color_0 */)
19082 static const GLuint size = m_width * m_height;
19083 static const GLuint expected_goku = 0xff000000;
19084 static const GLuint expected_gohan = 0xff0000ff;
19085 static const GLuint expected_goten = 0xff00ff00;
19086 static const GLuint expected_chichi = 0xffff0000;
19088 std::vector<GLuint> data;
19091 m_goku.Get(GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
19093 for (GLuint i = 0; i < size; ++i)
19095 const GLuint color = data[i];
19097 if (expected_goku != color)
19099 m_context.getTestContext().getLog() << tcu::TestLog::Message << "RGBA8[" << i << "]:" << color
19100 << tcu::TestLog::EndMessage;
19105 m_gohan.Get(GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
19107 for (GLuint i = 0; i < size; ++i)
19109 const GLuint color = data[i];
19111 if (expected_gohan != color)
19113 m_context.getTestContext().getLog() << tcu::TestLog::Message << "RGBA8[" << i << "]:" << color
19114 << tcu::TestLog::EndMessage;
19119 m_goten.Get(GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
19121 for (GLuint i = 0; i < size; ++i)
19123 const GLuint color = data[i];
19125 if (expected_goten != color)
19127 m_context.getTestContext().getLog() << tcu::TestLog::Message << "RGBA8[" << i << "]:" << color
19128 << tcu::TestLog::EndMessage;
19133 m_chichi.Get(GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
19135 for (GLuint i = 0; i < size; ++i)
19137 const GLuint color = data[i];
19139 if (expected_chichi != color)
19141 m_context.getTestContext().getLog() << tcu::TestLog::Message << "RGBA8[" << i << "]:" << color
19142 << tcu::TestLog::EndMessage;
19150 /** Prepare code snippet that will set out variables
19154 * @param stage Shader stage
19156 * @return Code that pass in variables to next stage
19158 std::string FragmentDataLocationAPITest::getPassSnippet(GLuint /* test_case_index */,
19159 Utils::VaryingPassthrough& /* varying_passthrough */,
19160 Utils::Shader::STAGES stage)
19162 std::string result;
19164 /* Skip for compute shader */
19165 if (Utils::Shader::FRAGMENT != stage)
19171 result = "chichi = vec4(0, 0, 1, 1);\n"
19172 " goku = vec4(0, 0, 0, 1);\n"
19173 " goten = vec4(0, 1, 0, 1);\n"
19174 " gohan = vec4(1, 0, 0, 1);\n";
19180 /** Get interface of program
19183 * @param program_interface Interface of program
19186 void FragmentDataLocationAPITest::getProgramInterface(GLuint /* test_case_index */,
19187 Utils::ProgramInterface& program_interface,
19188 Utils::VaryingPassthrough& /* varying_passthrough */)
19190 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
19191 const Utils::Type& type = Utils::Type::vec4;
19194 m_goku_location = 2;
19197 si.m_globals = "const uint GOKU_LOCATION = 2;\n";
19200 si.Output("goku" /* name */, "layout (location = GOKU_LOCATION)" /* qualifiers */, 0 /* expected_componenet */,
19201 m_goku_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19202 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)0 /* data */, 0u /* data_size */);
19204 si.Output("gohan" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19205 Utils::Variable::m_automatic_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19206 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)0 /* data */, 0u /* data_size */);
19208 si.Output("goten" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19209 m_goten_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19210 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)0 /* data */, 0u /* data_size */);
19212 si.Output("chichi" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19213 Utils::Variable::m_automatic_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19214 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)0 /* data */, 0u /* data_size */);
19217 /** Selects if "compute" stage is relevant for test
19223 bool FragmentDataLocationAPITest::isComputeRelevant(GLuint /* test_case_index */)
19228 /** Get locations for all outputs with automatic_location
19230 * @param program Program object
19231 * @param program_interface Interface of program
19233 void FragmentDataLocationAPITest::prepareFragmentDataLoc(Utils::Program& program,
19234 Utils::ProgramInterface& program_interface)
19236 /* Bind location of goten */
19237 const Functions& gl = m_context.getRenderContext().getFunctions();
19239 gl.bindFragDataLocation(program.m_id, m_goten_location, "goten");
19240 GLU_EXPECT_NO_ERROR(gl.getError(), "BindFragDataLocation");
19242 program.Link(gl, program.m_id);
19244 /* Prepare locations for gohan and chichi */
19245 TextureTestBase::prepareFragmentDataLoc(program, program_interface);
19247 /* Get all locations */
19248 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
19250 Utils::Variable::PtrVector& outputs = si.m_outputs;
19252 for (Utils::Variable::PtrVector::iterator it = outputs.begin(); outputs.end() != it; ++it)
19254 const Utils::Variable::Descriptor& desc = (*it)->m_descriptor;
19256 if (0 == desc.m_name.compare("gohan"))
19258 m_gohan_location = desc.m_expected_location;
19260 else if (0 == desc.m_name.compare("chichi"))
19262 m_chichi_location = desc.m_expected_location;
19265 /* Locations of goku and goten are fixed */
19269 /** Prepare framebuffer with single texture as color attachment
19271 * @param framebuffer Framebuffer
19272 * @param color_0_texture Texture that will used as color attachment
19274 void FragmentDataLocationAPITest::prepareFramebuffer(Utils::Framebuffer& framebuffer, Utils::Texture& color_0_texture)
19276 /* Let parent prepare its stuff */
19277 TextureTestBase::prepareFramebuffer(framebuffer, color_0_texture);
19280 std::vector<GLuint> texture_data;
19281 texture_data.resize(m_width * m_height);
19283 for (GLuint i = 0; i < texture_data.size(); ++i)
19285 texture_data[i] = 0x20406080;
19288 /* Prepare textures */
19289 m_goku.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]);
19291 m_gohan.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]);
19293 m_goten.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]);
19295 m_chichi.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]);
19297 /* Attach textures to framebuffer */
19298 framebuffer.Bind();
19299 framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0 + m_goku_location, m_goku.m_id, m_width, m_height);
19300 framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0 + m_gohan_location, m_gohan.m_id, m_width, m_height);
19301 framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0 + m_goten_location, m_goten.m_id, m_width, m_height);
19302 framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0 + m_chichi_location, m_chichi.m_id, m_width, m_height);
19304 /* Set up drawbuffers */
19305 const Functions& gl = m_context.getRenderContext().getFunctions();
19306 // 1. There are only 4 outputs in fragment shader, so only need to do buffer mapping for 4 attachments,
19307 // 2. another issue is each output variable has a location, it is the fragment color index, so the index of
19308 // GL_COLOR_ATTACHMENT in glDrawBuffers() should keep the same with the location, to make test correct,
19309 // we needt to change the above code of glDrawBuffers() as :
19310 GLint buffers_size = 4;
19311 GLenum buffers[] = { GLenum(GL_COLOR_ATTACHMENT0 + m_chichi_location),
19312 GLenum(GL_COLOR_ATTACHMENT0 + m_goku_location),
19313 GLenum(GL_COLOR_ATTACHMENT0 + m_goten_location),
19314 GLenum(GL_COLOR_ATTACHMENT0 + m_gohan_location) };
19315 gl.drawBuffers(buffers_size, buffers);
19316 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawBuffers");
19321 * @param context Test framework context
19323 XFBInputTest::XFBInputTest(deqp::Context& context)
19324 : NegativeTestBase(context, "xfb_input",
19325 "Test verifies that compiler reports error when xfb qualifiers are used with input")
19329 /** Source for given test case and stage
19331 * @param test_case_index Index of test case
19332 * @param stage Shader stage
19334 * @return Shader source
19336 std::string XFBInputTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
19338 static const GLchar* buffer_var_definition = "layout (xfb_buffer = 2) in vec4 gohanARRAY;\n";
19339 static const GLchar* offset_var_definition = "layout (xfb_offset = 16) in vec4 gohanARRAY;\n";
19340 static const GLchar* stride_var_definition = "layout (xfb_stride = 32) in vec4 gohanARRAY;\n";
19341 static const GLchar* input_use = " result += gohanINDEX;\n";
19342 static const GLchar* fs = "#version 430 core\n"
19343 "#extension GL_ARB_enhanced_layouts : require\n"
19346 "out vec4 fs_out;\n"
19350 " fs_out = gs_fs;\n"
19353 static const GLchar* fs_tested = "#version 430 core\n"
19354 "#extension GL_ARB_enhanced_layouts : require\n"
19359 "out vec4 fs_out;\n"
19363 " vec4 result = gs_fs;\n"
19367 " fs_out = result;\n"
19370 static const GLchar* gs = "#version 430 core\n"
19371 "#extension GL_ARB_enhanced_layouts : require\n"
19373 "layout(points) in;\n"
19374 "layout(triangle_strip, max_vertices = 4) out;\n"
19376 "in vec4 tes_gs[];\n"
19377 "out vec4 gs_fs;\n"
19381 " gs_fs = tes_gs[0];\n"
19382 " gl_Position = vec4(-1, -1, 0, 1);\n"
19384 " gs_fs = tes_gs[0];\n"
19385 " gl_Position = vec4(-1, 1, 0, 1);\n"
19387 " gs_fs = tes_gs[0];\n"
19388 " gl_Position = vec4(1, -1, 0, 1);\n"
19390 " gs_fs = tes_gs[0];\n"
19391 " gl_Position = vec4(1, 1, 0, 1);\n"
19395 static const GLchar* gs_tested = "#version 430 core\n"
19396 "#extension GL_ARB_enhanced_layouts : require\n"
19398 "layout(points) in;\n"
19399 "layout(triangle_strip, max_vertices = 4) out;\n"
19403 "in vec4 tes_gs[];\n"
19404 "out vec4 gs_fs;\n"
19408 " vec4 result = tes_gs[0];\n"
19412 " gs_fs = result;\n"
19413 " gl_Position = vec4(-1, -1, 0, 1);\n"
19415 " gs_fs = result;\n"
19416 " gl_Position = vec4(-1, 1, 0, 1);\n"
19418 " gs_fs = result;\n"
19419 " gl_Position = vec4(1, -1, 0, 1);\n"
19421 " gs_fs = result;\n"
19422 " gl_Position = vec4(1, 1, 0, 1);\n"
19426 static const GLchar* tcs = "#version 430 core\n"
19427 "#extension GL_ARB_enhanced_layouts : require\n"
19429 "layout(vertices = 1) out;\n"
19431 "in vec4 vs_tcs[];\n"
19432 "out vec4 tcs_tes[];\n"
19437 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
19439 " gl_TessLevelOuter[0] = 1.0;\n"
19440 " gl_TessLevelOuter[1] = 1.0;\n"
19441 " gl_TessLevelOuter[2] = 1.0;\n"
19442 " gl_TessLevelOuter[3] = 1.0;\n"
19443 " gl_TessLevelInner[0] = 1.0;\n"
19444 " gl_TessLevelInner[1] = 1.0;\n"
19447 static const GLchar* tcs_tested = "#version 430 core\n"
19448 "#extension GL_ARB_enhanced_layouts : require\n"
19450 "layout(vertices = 1) out;\n"
19454 "in vec4 vs_tcs[];\n"
19455 "out vec4 tcs_tes[];\n"
19459 " vec4 result = vs_tcs[gl_InvocationID];\n"
19463 " tcs_tes[gl_InvocationID] = result;\n"
19465 " gl_TessLevelOuter[0] = 1.0;\n"
19466 " gl_TessLevelOuter[1] = 1.0;\n"
19467 " gl_TessLevelOuter[2] = 1.0;\n"
19468 " gl_TessLevelOuter[3] = 1.0;\n"
19469 " gl_TessLevelInner[0] = 1.0;\n"
19470 " gl_TessLevelInner[1] = 1.0;\n"
19473 static const GLchar* tes = "#version 430 core\n"
19474 "#extension GL_ARB_enhanced_layouts : require\n"
19476 "layout(isolines, point_mode) in;\n"
19478 "in vec4 tcs_tes[];\n"
19479 "out vec4 tes_gs;\n"
19483 " tes_gs = tcs_tes[0];\n"
19486 static const GLchar* tes_tested = "#version 430 core\n"
19487 "#extension GL_ARB_enhanced_layouts : require\n"
19489 "layout(isolines, point_mode) in;\n"
19493 "in vec4 tcs_tes[];\n"
19494 "out vec4 tes_gs;\n"
19498 " vec4 result = tcs_tes[0];\n"
19502 " tes_gs += result;\n"
19505 static const GLchar* vs = "#version 430 core\n"
19506 "#extension GL_ARB_enhanced_layouts : require\n"
19509 "out vec4 vs_tcs;\n"
19513 " vs_tcs = in_vs;\n"
19516 static const GLchar* vs_tested = "#version 430 core\n"
19517 "#extension GL_ARB_enhanced_layouts : require\n"
19522 "out vec4 vs_tcs;\n"
19526 " vec4 result = in_vs;\n"
19530 " vs_tcs += result;\n"
19534 std::string source;
19535 testCase& test_case = m_test_cases[test_case_index];
19537 if (test_case.m_stage == stage)
19539 const GLchar* array = "";
19540 const GLchar* index = "";
19541 size_t position = 0;
19543 const GLchar* var_definition = 0;
19544 const GLchar* var_use = input_use;
19546 switch (test_case.m_qualifier)
19549 var_definition = buffer_var_definition;
19552 var_definition = offset_var_definition;
19555 var_definition = stride_var_definition;
19558 TCU_FAIL("Invalid enum");
19563 case Utils::Shader::FRAGMENT:
19564 source = fs_tested;
19566 case Utils::Shader::GEOMETRY:
19567 source = gs_tested;
19571 case Utils::Shader::TESS_CTRL:
19572 source = tcs_tested;
19574 index = "[gl_InvocationID]";
19576 case Utils::Shader::TESS_EVAL:
19577 source = tes_tested;
19581 case Utils::Shader::VERTEX:
19582 source = vs_tested;
19585 TCU_FAIL("Invalid enum");
19589 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
19591 Utils::replaceToken("ARRAY", position, array, source);
19592 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
19594 Utils::replaceAllTokens("INDEX", index, source);
19600 case Utils::Shader::FRAGMENT:
19603 case Utils::Shader::GEOMETRY:
19606 case Utils::Shader::TESS_CTRL:
19609 case Utils::Shader::TESS_EVAL:
19612 case Utils::Shader::VERTEX:
19616 TCU_FAIL("Invalid enum");
19623 /** Get description of test case
19625 * @param test_case_index Index of test case
19627 * @return Test case description
19629 std::string XFBInputTest::getTestCaseName(GLuint test_case_index)
19631 std::stringstream stream;
19632 testCase& test_case = m_test_cases[test_case_index];
19634 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", qualifier: ";
19636 switch (test_case.m_qualifier)
19639 stream << "xfb_buffer";
19642 stream << "xfb_offset";
19645 stream << "xfb_stride";
19648 TCU_FAIL("Invalid enum");
19651 return stream.str();
19654 /** Get number of test cases
19656 * @return Number of test cases
19658 GLuint XFBInputTest::getTestCaseNumber()
19660 return static_cast<GLuint>(m_test_cases.size());
19663 /** Selects if "compute" stage is relevant for test
19669 bool XFBInputTest::isComputeRelevant(GLuint /* test_case_index */)
19674 /** Prepare all test cases
19677 void XFBInputTest::testInit()
19679 for (GLuint qualifier = 0; qualifier < QUALIFIERS_MAX; ++qualifier)
19681 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
19683 if (Utils::Shader::COMPUTE == stage)
19688 testCase test_case = { (QUALIFIERS)qualifier, (Utils::Shader::STAGES)stage };
19690 m_test_cases.push_back(test_case);
19695 /* Constants used by XFBAllStagesTest */
19696 const GLuint XFBAllStagesTest::m_gs_index = 3;
19700 * @param context Test context
19702 XFBAllStagesTest::XFBAllStagesTest(deqp::Context& context)
19703 : BufferTestBase(context, "xfb_all_stages",
19704 "Test verifies that only last stage in vertex processing can output to transform feedback")
19706 /* Nothing to be done here */
19709 /** Get descriptors of buffers necessary for test
19712 * @param out_descriptors Descriptors of buffers used by test
19714 void XFBAllStagesTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
19715 bufferDescriptor::Vector& out_descriptors)
19717 static const GLuint n_stages = 4;
19718 const Utils::Type& vec4 = Utils::Type::vec4;
19723 /* Test uses single uniform and xfb per stage + uniform for fragment shader */
19724 out_descriptors.resize(n_stages * 2 + 1);
19727 for (GLuint i = 0; i < n_stages; ++i)
19729 /* Get references */
19730 bufferDescriptor& uniform = out_descriptors[i + 0];
19731 bufferDescriptor& xfb = out_descriptors[i + n_stages];
19734 uniform.m_index = i;
19738 uniform.m_target = Utils::Buffer::Uniform;
19739 xfb.m_target = Utils::Buffer::Transform_feedback;
19742 const tcu::Vec4 var(Utils::GetRandFloat(), Utils::GetRandFloat(), Utils::GetRandFloat(), Utils::GetRandFloat());
19746 uniform.m_initial_data.resize(vec4.GetSize());
19747 memcpy(&uniform.m_initial_data[0], var.getPtr(), vec4.GetSize());
19749 xfb.m_initial_data = vec4.GenerateDataPacked();
19751 if (m_gs_index != i)
19753 xfb.m_expected_data = xfb.m_initial_data;
19757 xfb.m_expected_data.resize(vec4.GetSize());
19758 memcpy(&xfb.m_expected_data[0], sum.getPtr(), vec4.GetSize());
19764 /* Get reference */
19765 bufferDescriptor& uniform = out_descriptors[n_stages * 2];
19768 uniform.m_index = n_stages;
19771 uniform.m_target = Utils::Buffer::Uniform;
19774 const tcu::Vec4 var(Utils::GetRandFloat(), Utils::GetRandFloat(), Utils::GetRandFloat(), Utils::GetRandFloat());
19776 uniform.m_initial_data.resize(vec4.GetSize());
19777 memcpy(&uniform.m_initial_data[0], var.getPtr(), vec4.GetSize());
19781 /** Get body of main function for given shader stage
19784 * @param stage Shader stage
19785 * @param out_assignments Set to empty
19786 * @param out_calculations Set to empty
19788 void XFBAllStagesTest::getShaderBody(glw::GLuint /* test_case_index */, Utils::Shader::STAGES stage,
19789 std::string& out_assignments, std::string& out_calculations)
19791 out_calculations = "";
19793 static const GLchar* vs = " vs_tcs = uni_vs;\n";
19794 static const GLchar* tcs = " tcs_tes[gl_InvocationID] = uni_tcs + vs_tcs[gl_InvocationID];\n";
19795 static const GLchar* tes = " tes_gs = uni_tes + tcs_tes[0];\n";
19796 static const GLchar* gs = " gs_fs = uni_gs + tes_gs[0];\n";
19797 static const GLchar* fs = " fs_out = uni_fs + gs_fs;\n";
19799 const GLchar* assignments = 0;
19802 case Utils::Shader::FRAGMENT:
19805 case Utils::Shader::GEOMETRY:
19808 case Utils::Shader::TESS_CTRL:
19811 case Utils::Shader::TESS_EVAL:
19814 case Utils::Shader::VERTEX:
19818 TCU_FAIL("Invalid enum");
19821 out_assignments = assignments;
19824 /** Get interface of shader
19827 * @param stage Shader stage
19828 * @param out_interface Set to ""
19830 void XFBAllStagesTest::getShaderInterface(glw::GLuint /* test_case_index */, Utils::Shader::STAGES stage,
19831 std::string& out_interface)
19833 static const GLchar* vs = "layout(xfb_buffer = 0, xfb_offset = 0) out vec4 vs_tcs;\n"
19834 "layout(binding = 0) uniform vs_block {\n"
19837 static const GLchar* tcs = " in vec4 vs_tcs[];\n"
19838 "layout(xfb_buffer = 1, xfb_offset = 0) out vec4 tcs_tes[1];\n"
19839 "layout(binding = 1) uniform tcs_block {\n"
19842 static const GLchar* tes = " in vec4 tcs_tes[];\n"
19843 "layout(xfb_buffer = 2, xfb_offset = 0) out vec4 tes_gs;\n"
19844 "layout(binding = 2) uniform tes_block {\n"
19847 static const GLchar* gs = " in vec4 tes_gs[];\n"
19848 "layout(xfb_buffer = 3, xfb_offset = 0) out vec4 gs_fs;\n"
19849 "layout(binding = 3) uniform gs_block {\n"
19852 static const GLchar* fs = " in vec4 gs_fs;\n"
19853 " out vec4 fs_out;\n"
19854 "layout(binding = 4) uniform fs_block {\n"
19858 const GLchar* interface = 0;
19861 case Utils::Shader::FRAGMENT:
19864 case Utils::Shader::GEOMETRY:
19867 case Utils::Shader::TESS_CTRL:
19870 case Utils::Shader::TESS_EVAL:
19873 case Utils::Shader::VERTEX:
19877 TCU_FAIL("Invalid enum");
19880 out_interface = interface;
19883 /* Constants used by XFBStrideOfEmptyListTest */
19884 const GLuint XFBStrideOfEmptyListTest::m_stride = 64;
19888 * @param context Test context
19890 XFBStrideOfEmptyListTest::XFBStrideOfEmptyListTest(deqp::Context& context)
19891 : BufferTestBase(context, "xfb_stride_of_empty_list",
19892 "Test verifies that xfb_stride qualifier is respected when no xfb_offset is specified")
19894 /* Nothing to be done here */
19897 /** Execute drawArrays for single vertex
19899 * @param test_case_index Index of test case
19901 * @return true if proper error is reported
19903 bool XFBStrideOfEmptyListTest::executeDrawCall(GLuint test_case_index)
19905 const Functions& gl = m_context.getRenderContext().getFunctions();
19906 bool result = true;
19909 gl.disable(GL_RASTERIZER_DISCARD);
19910 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
19912 gl.beginTransformFeedback(GL_POINTS);
19913 GLenum error = gl.getError();
19914 switch (test_case_index)
19917 if (GL_NO_ERROR != error)
19919 gl.endTransformFeedback();
19920 GLU_EXPECT_NO_ERROR(error, "BeginTransformFeedback");
19923 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
19924 error = gl.getError();
19926 gl.endTransformFeedback();
19927 GLU_EXPECT_NO_ERROR(error, "DrawArrays");
19928 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
19932 case FIRST_MISSING:
19933 if (GL_NO_ERROR == error)
19935 gl.endTransformFeedback();
19938 if (GL_INVALID_OPERATION != error)
19940 m_context.getTestContext().getLog()
19941 << tcu::TestLog::Message << "XFB at index 0, that is written by GS, is missing. It was expected that "
19942 "INVALID_OPERATION will generated by BeginTransformFeedback. Got: "
19943 << glu::getErrorStr(error) << tcu::TestLog::EndMessage;
19950 case SECOND_MISSING:
19951 if (GL_NO_ERROR == error)
19953 gl.endTransformFeedback();
19956 if (GL_INVALID_OPERATION != error)
19958 m_context.getTestContext().getLog()
19959 << tcu::TestLog::Message << "XFB at index 1, that is declared as empty, is missing. It was expected "
19960 "that INVALID_OPERATION will generated by BeginTransformFeedback. Got: "
19961 << glu::getErrorStr(error) << tcu::TestLog::EndMessage;
19973 /** Get descriptors of buffers necessary for test
19975 * @param test_case_index Index of test case
19976 * @param out_descriptors Descriptors of buffers used by test
19978 void XFBStrideOfEmptyListTest::getBufferDescriptors(glw::GLuint test_case_index,
19979 bufferDescriptor::Vector& out_descriptors)
19981 switch (test_case_index)
19985 /* Test needs single uniform and two xfbs */
19986 out_descriptors.resize(3);
19988 /* Get references */
19989 bufferDescriptor& uniform = out_descriptors[0];
19990 bufferDescriptor& xfb_0 = out_descriptors[1];
19991 bufferDescriptor& xfb_1 = out_descriptors[2];
19994 uniform.m_index = 0;
19999 uniform.m_target = Utils::Buffer::Uniform;
20000 xfb_0.m_target = Utils::Buffer::Transform_feedback;
20001 xfb_1.m_target = Utils::Buffer::Transform_feedback;
20004 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20006 xfb_0.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20007 xfb_0.m_expected_data = uniform.m_initial_data;
20009 /* Data, contents are the same as no modification is expected */
20010 xfb_1.m_initial_data.resize(m_stride);
20011 xfb_1.m_expected_data.resize(m_stride);
20013 for (GLuint i = 0; i < m_stride; ++i)
20015 xfb_1.m_initial_data[0] = (glw::GLubyte)i;
20016 xfb_1.m_expected_data[0] = (glw::GLubyte)i;
20022 case FIRST_MISSING:
20024 /* Test needs single uniform and two xfbs */
20025 out_descriptors.resize(2);
20027 /* Get references */
20028 bufferDescriptor& uniform = out_descriptors[0];
20029 bufferDescriptor& xfb_1 = out_descriptors[1];
20032 uniform.m_index = 0;
20036 uniform.m_target = Utils::Buffer::Uniform;
20037 xfb_1.m_target = Utils::Buffer::Transform_feedback;
20040 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20042 /* Draw call will not be executed, contents does not matter */
20043 xfb_1.m_initial_data.resize(m_stride);
20048 case SECOND_MISSING:
20050 /* Test needs single uniform and two xfbs */
20051 out_descriptors.resize(2);
20053 /* Get references */
20054 bufferDescriptor& uniform = out_descriptors[0];
20055 bufferDescriptor& xfb_0 = out_descriptors[1];
20058 uniform.m_index = 0;
20062 uniform.m_target = Utils::Buffer::Uniform;
20063 xfb_0.m_target = Utils::Buffer::Transform_feedback;
20066 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20068 /* Draw call will not be executed, contents does not matter */
20069 xfb_0.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20076 /** Get body of main function for given shader stage
20079 * @param stage Shader stage
20080 * @param out_assignments Set to empty
20081 * @param out_calculations Set to empty
20083 void XFBStrideOfEmptyListTest::getShaderBody(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
20084 std::string& out_assignments, std::string& out_calculations)
20086 out_calculations = "";
20088 static const GLchar* gs = " gs_fs = uni_gs;\n";
20089 static const GLchar* fs = " fs_out = vec4(gs_fs);\n";
20091 const GLchar* assignments = "";
20094 case Utils::Shader::FRAGMENT:
20097 case Utils::Shader::GEOMETRY:
20104 out_assignments = assignments;
20107 /** Get interface of shader
20110 * @param stage Shader stage
20111 * @param out_interface Set to ""
20113 void XFBStrideOfEmptyListTest::getShaderInterface(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
20114 std::string& out_interface)
20116 static const GLchar* gs = "layout (xfb_buffer = 0, xfb_offset = 0) out vec4 gs_fs;\n"
20117 "layout (xfb_buffer = 1, xfb_stride = 64) out;\n"
20119 "layout (binding = 0) uniform gs_block {\n"
20122 static const GLchar* fs = "in vec4 gs_fs;\n"
20123 "out vec4 fs_out;\n";
20127 case Utils::Shader::FRAGMENT:
20128 out_interface = fs;
20130 case Utils::Shader::GEOMETRY:
20131 out_interface = gs;
20134 out_interface = "";
20139 /** Returns buffer details in human readable form.
20141 * @param test_case_index Index of test case
20143 * @return Case description
20145 std::string XFBStrideOfEmptyListTest::getTestCaseName(GLuint test_case_index)
20147 std::string result;
20149 switch (test_case_index)
20152 result = "Valid case";
20154 case FIRST_MISSING:
20155 result = "Missing xfb at index 0";
20157 case SECOND_MISSING:
20158 result = "Missing xfb at index 1";
20161 TCU_FAIL("Invalid enum");
20167 /** Get number of test cases
20171 GLuint XFBStrideOfEmptyListTest::getTestCaseNumber()
20176 /* Constants used by XFBStrideOfEmptyListTest */
20177 const GLuint XFBStrideOfEmptyListAndAPITest::m_stride = 64;
20181 * @param context Test context
20183 XFBStrideOfEmptyListAndAPITest::XFBStrideOfEmptyListAndAPITest(deqp::Context& context)
20184 : BufferTestBase(context, "xfb_stride_of_empty_list_and_api",
20185 "Test verifies that xfb_stride qualifier is not overriden by API")
20187 /* Nothing to be done here */
20190 /** Execute drawArrays for single vertex
20192 * @param test_case_index Index of test case
20194 * @return true if proper error is reported
20196 bool XFBStrideOfEmptyListAndAPITest::executeDrawCall(GLuint test_case_index)
20198 const Functions& gl = m_context.getRenderContext().getFunctions();
20199 bool result = true;
20202 gl.disable(GL_RASTERIZER_DISCARD);
20203 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
20205 gl.beginTransformFeedback(GL_POINTS);
20206 GLenum error = gl.getError();
20207 switch (test_case_index)
20210 if (GL_NO_ERROR != error)
20212 gl.endTransformFeedback();
20213 GLU_EXPECT_NO_ERROR(error, "BeginTransformFeedback");
20216 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
20217 error = gl.getError();
20219 gl.endTransformFeedback();
20220 GLU_EXPECT_NO_ERROR(error, "DrawArrays");
20221 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
20225 case FIRST_MISSING:
20226 if (GL_NO_ERROR == error)
20228 gl.endTransformFeedback();
20231 if (GL_INVALID_OPERATION != error)
20233 m_context.getTestContext().getLog()
20234 << tcu::TestLog::Message << "XFB at index 0, that is declared as empty, is missing. It was expected "
20235 "that INVALID_OPERATION will generated by BeginTransformFeedback. Got: "
20236 << glu::getErrorStr(error) << tcu::TestLog::EndMessage;
20243 case SECOND_MISSING:
20244 if (GL_NO_ERROR == error)
20246 gl.endTransformFeedback();
20249 if (GL_INVALID_OPERATION != error)
20251 m_context.getTestContext().getLog()
20252 << tcu::TestLog::Message << "XFB at index 1, that is written by GS, is missing. It was expected that "
20253 "INVALID_OPERATION will generated by BeginTransformFeedback. Got: "
20254 << glu::getErrorStr(error) << tcu::TestLog::EndMessage;
20266 /** Get descriptors of buffers necessary for test
20268 * @param test_case_index Index of test case
20269 * @param out_descriptors Descriptors of buffers used by test
20271 void XFBStrideOfEmptyListAndAPITest::getBufferDescriptors(glw::GLuint test_case_index,
20272 bufferDescriptor::Vector& out_descriptors)
20274 switch (test_case_index)
20278 /* Test needs single uniform and two xfbs */
20279 out_descriptors.resize(3);
20281 /* Get references */
20282 bufferDescriptor& uniform = out_descriptors[0];
20283 bufferDescriptor& xfb_0 = out_descriptors[1];
20284 bufferDescriptor& xfb_1 = out_descriptors[2];
20287 uniform.m_index = 0;
20292 uniform.m_target = Utils::Buffer::Uniform;
20293 xfb_0.m_target = Utils::Buffer::Transform_feedback;
20294 xfb_1.m_target = Utils::Buffer::Transform_feedback;
20297 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20299 /* Data, contents are the same as no modification is expected */
20300 xfb_0.m_initial_data.resize(m_stride);
20301 xfb_0.m_expected_data.resize(m_stride);
20303 for (GLuint i = 0; i < m_stride; ++i)
20305 xfb_0.m_initial_data[0] = (glw::GLubyte)i;
20306 xfb_0.m_expected_data[0] = (glw::GLubyte)i;
20309 xfb_1.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20310 xfb_1.m_expected_data = uniform.m_initial_data;
20315 case FIRST_MISSING:
20317 /* Test needs single uniform and two xfbs */
20318 out_descriptors.resize(2);
20320 /* Get references */
20321 bufferDescriptor& uniform = out_descriptors[0];
20322 bufferDescriptor& xfb_1 = out_descriptors[1];
20325 uniform.m_index = 0;
20329 uniform.m_target = Utils::Buffer::Uniform;
20330 xfb_1.m_target = Utils::Buffer::Transform_feedback;
20333 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20335 /* Draw call will not be executed, contents does not matter */
20336 xfb_1.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20341 case SECOND_MISSING:
20343 /* Test needs single uniform and two xfbs */
20344 out_descriptors.resize(2);
20346 /* Get references */
20347 bufferDescriptor& uniform = out_descriptors[0];
20348 bufferDescriptor& xfb_0 = out_descriptors[1];
20351 uniform.m_index = 0;
20355 uniform.m_target = Utils::Buffer::Uniform;
20356 xfb_0.m_target = Utils::Buffer::Transform_feedback;
20359 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20361 /* Draw call will not be executed, contents does not matter */
20362 xfb_0.m_initial_data.resize(m_stride);
20369 /** Get list of names of varyings that will be registered with TransformFeedbackVaryings
20372 * @param captured_varyings Vector of varying names to be captured
20374 void XFBStrideOfEmptyListAndAPITest::getCapturedVaryings(glw::GLuint /* test_case_index */,
20375 Utils::Program::NameVector& captured_varyings)
20377 captured_varyings.push_back("gs_fs");
20380 /** Get body of main function for given shader stage
20383 * @param stage Shader stage
20384 * @param out_assignments Set to empty
20385 * @param out_calculations Set to empty
20387 void XFBStrideOfEmptyListAndAPITest::getShaderBody(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
20388 std::string& out_assignments, std::string& out_calculations)
20390 out_calculations = "";
20392 static const GLchar* gs = " gs_fs = uni_gs;\n";
20393 static const GLchar* fs = " fs_out = vec4(gs_fs);\n";
20395 const GLchar* assignments = "";
20398 case Utils::Shader::FRAGMENT:
20401 case Utils::Shader::GEOMETRY:
20408 out_assignments = assignments;
20411 /** Get interface of shader
20414 * @param stage Shader stage
20415 * @param out_interface Set to ""
20417 void XFBStrideOfEmptyListAndAPITest::getShaderInterface(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
20418 std::string& out_interface)
20420 static const GLchar* gs = "layout (xfb_buffer = 0, xfb_stride = 64) out;\n"
20421 "layout (xfb_buffer = 1, xfb_offset = 0) out vec4 gs_fs;\n"
20423 "layout(binding = 0) uniform gs_block {\n"
20426 static const GLchar* fs = "in vec4 gs_fs;\n"
20427 "out vec4 fs_out;\n";
20431 case Utils::Shader::FRAGMENT:
20432 out_interface = fs;
20434 case Utils::Shader::GEOMETRY:
20435 out_interface = gs;
20438 out_interface = "";
20443 /** Returns buffer details in human readable form.
20445 * @param test_case_index Index of test case
20447 * @return Case description
20449 std::string XFBStrideOfEmptyListAndAPITest::getTestCaseName(GLuint test_case_index)
20451 std::string result;
20453 switch (test_case_index)
20456 result = "Valid case";
20458 case FIRST_MISSING:
20459 result = "Missing xfb at index 0";
20461 case SECOND_MISSING:
20462 result = "Missing xfb at index 1";
20465 TCU_FAIL("Invalid enum");
20471 /** Get number of test cases
20475 GLuint XFBStrideOfEmptyListAndAPITest::getTestCaseNumber()
20482 * @param context Test framework context
20484 XFBTooSmallStrideTest::XFBTooSmallStrideTest(deqp::Context& context)
20485 : NegativeTestBase(context, "xfb_too_small_stride",
20486 "Test verifies that compiler reports error when xfb_stride sets not enough space")
20490 /** Source for given test case and stage
20492 * @param test_case_index Index of test case
20493 * @param stage Shader stage
20495 * @return Shader source
20497 std::string XFBTooSmallStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
20499 static const GLchar* array_var_definition = "layout (xfb_buffer = 0, xfb_stride = 32) out;\n"
20501 "layout (xfb_offset = 16) out vec4 gohanARRAY[4];\n";
20502 static const GLchar* block_var_definition = "layout (xfb_buffer = 0, xfb_stride = 32) out;\n"
20504 "layout (xfb_offset = 0) out Goku {\n"
20509 static const GLchar* offset_var_definition = "layout (xfb_buffer = 0, xfb_stride = 40) out;\n"
20511 "layout (xfb_offset = 32) out vec4 gohanARRAY;\n";
20512 // 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;"
20513 // To make the shader failed to compile, change xfb_stride to a value that is smaller than 32
20514 static const GLchar* stride_var_definition = "layout (xfb_buffer = 0, xfb_stride = 28) out;\n"
20516 "layout (xfb_offset = 16, xfb_stride = 28) out vec4 gohanARRAY;\n";
20517 static const GLchar* array_use = " gohanINDEX[0] = result / 2;\n"
20518 " gohanINDEX[1] = result / 4;\n"
20519 " gohanINDEX[2] = result / 6;\n"
20520 " gohanINDEX[3] = result / 8;\n";
20521 static const GLchar* block_use = " gokuINDEX.gohan = result / 2;\n"
20522 " gokuINDEX.goten = result / 4;\n"
20523 " gokuINDEX.chichi = result / 6;\n";
20524 static const GLchar* output_use = "gohanINDEX = result / 4;\n";
20525 static const GLchar* fs = "#version 430 core\n"
20526 "#extension GL_ARB_enhanced_layouts : require\n"
20529 "out vec4 fs_out;\n"
20533 " fs_out = gs_fs;\n"
20536 static const GLchar* gs_tested = "#version 430 core\n"
20537 "#extension GL_ARB_enhanced_layouts : require\n"
20539 "layout(points) in;\n"
20540 "layout(triangle_strip, max_vertices = 4) out;\n"
20544 "in vec4 tes_gs[];\n"
20545 "out vec4 gs_fs;\n"
20549 " vec4 result = tes_gs[0];\n"
20553 " gs_fs = result;\n"
20554 " gl_Position = vec4(-1, -1, 0, 1);\n"
20556 " gs_fs = result;\n"
20557 " gl_Position = vec4(-1, 1, 0, 1);\n"
20559 " gs_fs = result;\n"
20560 " gl_Position = vec4(1, -1, 0, 1);\n"
20562 " gs_fs = result;\n"
20563 " gl_Position = vec4(1, 1, 0, 1);\n"
20567 static const GLchar* tcs = "#version 430 core\n"
20568 "#extension GL_ARB_enhanced_layouts : require\n"
20570 "layout(vertices = 1) out;\n"
20572 "in vec4 vs_tcs[];\n"
20573 "out vec4 tcs_tes[];\n"
20578 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
20580 " gl_TessLevelOuter[0] = 1.0;\n"
20581 " gl_TessLevelOuter[1] = 1.0;\n"
20582 " gl_TessLevelOuter[2] = 1.0;\n"
20583 " gl_TessLevelOuter[3] = 1.0;\n"
20584 " gl_TessLevelInner[0] = 1.0;\n"
20585 " gl_TessLevelInner[1] = 1.0;\n"
20588 static const GLchar* tcs_tested = "#version 430 core\n"
20589 "#extension GL_ARB_enhanced_layouts : require\n"
20591 "layout(vertices = 1) out;\n"
20595 "in vec4 vs_tcs[];\n"
20596 "out vec4 tcs_tes[];\n"
20600 " vec4 result = vs_tcs[gl_InvocationID];\n"
20604 " tcs_tes[gl_InvocationID] = result;\n"
20606 " gl_TessLevelOuter[0] = 1.0;\n"
20607 " gl_TessLevelOuter[1] = 1.0;\n"
20608 " gl_TessLevelOuter[2] = 1.0;\n"
20609 " gl_TessLevelOuter[3] = 1.0;\n"
20610 " gl_TessLevelInner[0] = 1.0;\n"
20611 " gl_TessLevelInner[1] = 1.0;\n"
20614 static const GLchar* tes_tested = "#version 430 core\n"
20615 "#extension GL_ARB_enhanced_layouts : require\n"
20617 "layout(isolines, point_mode) in;\n"
20621 "in vec4 tcs_tes[];\n"
20622 "out vec4 tes_gs;\n"
20626 " vec4 result = tcs_tes[0];\n"
20630 " tes_gs += result;\n"
20633 static const GLchar* vs = "#version 430 core\n"
20634 "#extension GL_ARB_enhanced_layouts : require\n"
20637 "out vec4 vs_tcs;\n"
20641 " vs_tcs = in_vs;\n"
20644 static const GLchar* vs_tested = "#version 430 core\n"
20645 "#extension GL_ARB_enhanced_layouts : require\n"
20650 "out vec4 vs_tcs;\n"
20654 " vec4 result = in_vs;\n"
20658 " vs_tcs += result;\n"
20662 std::string source;
20663 testCase& test_case = m_test_cases[test_case_index];
20665 if (test_case.m_stage == stage)
20667 const GLchar* array = "";
20668 const GLchar* index = "";
20669 size_t position = 0;
20671 const GLchar* var_definition = 0;
20672 const GLchar* var_use = 0;
20674 switch (test_case.m_case)
20677 var_definition = offset_var_definition;
20678 var_use = output_use;
20681 var_definition = stride_var_definition;
20682 var_use = output_use;
20685 var_definition = block_var_definition;
20686 var_use = block_use;
20689 var_definition = array_var_definition;
20690 var_use = array_use;
20693 TCU_FAIL("Invalid enum");
20698 case Utils::Shader::GEOMETRY:
20699 source = gs_tested;
20703 case Utils::Shader::TESS_CTRL:
20704 source = tcs_tested;
20706 index = "[gl_InvocationID]";
20708 case Utils::Shader::TESS_EVAL:
20709 source = tes_tested;
20713 case Utils::Shader::VERTEX:
20714 source = vs_tested;
20717 TCU_FAIL("Invalid enum");
20721 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
20723 Utils::replaceToken("ARRAY", position, array, source);
20724 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
20726 Utils::replaceAllTokens("INDEX", index, source);
20730 switch (test_case.m_stage)
20732 case Utils::Shader::GEOMETRY:
20735 case Utils::Shader::FRAGMENT:
20738 case Utils::Shader::VERTEX:
20745 case Utils::Shader::TESS_CTRL:
20748 case Utils::Shader::FRAGMENT:
20751 case Utils::Shader::VERTEX:
20758 case Utils::Shader::TESS_EVAL:
20761 case Utils::Shader::FRAGMENT:
20764 case Utils::Shader::TESS_CTRL:
20767 case Utils::Shader::VERTEX:
20774 case Utils::Shader::VERTEX:
20777 case Utils::Shader::FRAGMENT:
20785 TCU_FAIL("Invalid enum");
20793 /** Get description of test case
20795 * @param test_case_index Index of test case
20797 * @return Test case description
20799 std::string XFBTooSmallStrideTest::getTestCaseName(GLuint test_case_index)
20801 std::stringstream stream;
20802 testCase& test_case = m_test_cases[test_case_index];
20804 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", case: ";
20806 switch (test_case.m_case)
20809 stream << "buffer stride: 40, vec4 offset: 32";
20812 stream << "buffer stride: 32, vec4 off 16 stride: 32";
20815 stream << "buffer stride: 32, block 3xvec4 offset 0";
20818 stream << "buffer stride: 32, vec4[4] offset 16";
20821 TCU_FAIL("Invalid enum");
20824 return stream.str();
20827 /** Get number of test cases
20829 * @return Number of test cases
20831 GLuint XFBTooSmallStrideTest::getTestCaseNumber()
20833 return static_cast<GLuint>(m_test_cases.size());
20836 /** Selects if "compute" stage is relevant for test
20842 bool XFBTooSmallStrideTest::isComputeRelevant(GLuint /* test_case_index */)
20847 /** Prepare all test cases
20850 void XFBTooSmallStrideTest::testInit()
20852 for (GLuint c = 0; c < CASE_MAX; ++c)
20854 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
20857 It is invalid to define transform feedback output in TCS, according to spec:
20858 The data captured in transform feedback mode depends on the active programs on each of the shader stages.
20859 If a program is active for the geometry shader stage, transform feedback captures the vertices of each
20860 primitive emitted by the geometry shader. Otherwise, if a program is active for the tessellation evaluation
20861 shader stage, transform feedback captures each primitive produced by the tessellation primitive generator,
20862 whose vertices are processed by the tessellation evaluation shader. Otherwise, transform feedback captures
20863 each primitive processed by the vertex shader.
20865 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
20866 (Utils::Shader::FRAGMENT == stage))
20871 testCase test_case = { (CASES)c, (Utils::Shader::STAGES)stage };
20873 m_test_cases.push_back(test_case);
20880 * @param context Test framework context
20882 XFBVariableStrideTest::XFBVariableStrideTest(deqp::Context& context)
20883 : NegativeTestBase(context, "xfb_variable_stride", "Test verifies that stride qualifier is respected")
20887 /** Source for given test case and stage
20889 * @param test_case_index Index of test case
20890 * @param stage Shader stage
20892 * @return Shader source
20894 std::string XFBVariableStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
20896 static const GLchar* invalid_var_definition =
20897 "const uint type_size = SIZE;\n"
20899 "layout (xfb_offset = 0, xfb_stride = 2 * type_size) out TYPE gokuARRAY;\n"
20900 "layout (xfb_offset = type_size) out TYPE vegetaARRAY;\n";
20901 static const GLchar* valid_var_definition =
20902 "const uint type_size = SIZE;\n"
20904 "layout (xfb_offset = 0, xfb_stride = 2 * type_size) out TYPE gokuARRAY;\n";
20905 static const GLchar* invalid_use = " gokuINDEX = TYPE(1);\n"
20906 " vegetaINDEX = TYPE(0);\n"
20907 " if (vec4(0) == result)\n"
20909 " gokuINDEX = TYPE(0);\n"
20910 " vegetaINDEX = TYPE(1);\n"
20912 static const GLchar* valid_use = " gokuINDEX = TYPE(1);\n"
20913 " if (vec4(0) == result)\n"
20915 " gokuINDEX = TYPE(0);\n"
20917 static const GLchar* fs = "#version 430 core\n"
20918 "#extension GL_ARB_enhanced_layouts : require\n"
20920 "in vec4 any_fs;\n"
20921 "out vec4 fs_out;\n"
20925 " fs_out = any_fs;\n"
20928 static const GLchar* gs_tested = "#version 430 core\n"
20929 "#extension GL_ARB_enhanced_layouts : require\n"
20931 "layout(points) in;\n"
20932 "layout(triangle_strip, max_vertices = 4) out;\n"
20936 "in vec4 vs_any[];\n"
20937 "out vec4 any_fs;\n"
20941 " vec4 result = vs_any[0];\n"
20945 " any_fs = result;\n"
20946 " gl_Position = vec4(-1, -1, 0, 1);\n"
20948 " any_fs = result;\n"
20949 " gl_Position = vec4(-1, 1, 0, 1);\n"
20951 " any_fs = result;\n"
20952 " gl_Position = vec4(1, -1, 0, 1);\n"
20954 " any_fs = result;\n"
20955 " gl_Position = vec4(1, 1, 0, 1);\n"
20959 static const GLchar* tcs = "#version 430 core\n"
20960 "#extension GL_ARB_enhanced_layouts : require\n"
20962 "layout(vertices = 1) out;\n"
20964 "in vec4 vs_any[];\n"
20965 "out vec4 tcs_tes[];\n"
20970 " tcs_tes[gl_InvocationID] = vs_any[gl_InvocationID];\n"
20972 " gl_TessLevelOuter[0] = 1.0;\n"
20973 " gl_TessLevelOuter[1] = 1.0;\n"
20974 " gl_TessLevelOuter[2] = 1.0;\n"
20975 " gl_TessLevelOuter[3] = 1.0;\n"
20976 " gl_TessLevelInner[0] = 1.0;\n"
20977 " gl_TessLevelInner[1] = 1.0;\n"
20980 static const GLchar* tcs_tested = "#version 430 core\n"
20981 "#extension GL_ARB_enhanced_layouts : require\n"
20983 "layout(vertices = 1) out;\n"
20987 "in vec4 vs_any[];\n"
20988 "out vec4 any_fs[];\n"
20992 " vec4 result = vs_any[gl_InvocationID];\n"
20996 " any_fs[gl_InvocationID] = result;\n"
20998 " gl_TessLevelOuter[0] = 1.0;\n"
20999 " gl_TessLevelOuter[1] = 1.0;\n"
21000 " gl_TessLevelOuter[2] = 1.0;\n"
21001 " gl_TessLevelOuter[3] = 1.0;\n"
21002 " gl_TessLevelInner[0] = 1.0;\n"
21003 " gl_TessLevelInner[1] = 1.0;\n"
21006 static const GLchar* tes_tested = "#version 430 core\n"
21007 "#extension GL_ARB_enhanced_layouts : require\n"
21009 "layout(isolines, point_mode) in;\n"
21013 "in vec4 tcs_tes[];\n"
21014 "out vec4 any_fs;\n"
21018 " vec4 result = tcs_tes[0];\n"
21022 " any_fs = result;\n"
21025 static const GLchar* vs = "#version 430 core\n"
21026 "#extension GL_ARB_enhanced_layouts : require\n"
21029 "out vec4 vs_any;\n"
21033 " vs_any = in_vs;\n"
21036 static const GLchar* vs_tested = "#version 430 core\n"
21037 "#extension GL_ARB_enhanced_layouts : require\n"
21042 "out vec4 any_fs;\n"
21046 " vec4 result = in_vs;\n"
21050 " any_fs = result;\n"
21054 std::string source;
21055 testCase& test_case = m_test_cases[test_case_index];
21057 if (test_case.m_stage == stage)
21059 const GLchar* array = "";
21061 const GLchar* index = "";
21062 size_t position = 0;
21064 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
21065 const GLchar* var_definition = 0;
21066 const GLchar* var_use = 0;
21068 sprintf(buffer, "%d", test_case.m_type.GetSize());
21070 switch (test_case.m_case)
21073 var_definition = valid_var_definition;
21074 var_use = valid_use;
21077 var_definition = invalid_var_definition;
21078 var_use = invalid_use;
21081 TCU_FAIL("Invalid enum");
21086 case Utils::Shader::GEOMETRY:
21087 source = gs_tested;
21091 case Utils::Shader::TESS_CTRL:
21092 source = tcs_tested;
21094 index = "[gl_InvocationID]";
21096 case Utils::Shader::TESS_EVAL:
21097 source = tes_tested;
21101 case Utils::Shader::VERTEX:
21102 source = vs_tested;
21105 TCU_FAIL("Invalid enum");
21109 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
21111 Utils::replaceToken("SIZE", position, buffer, source);
21112 Utils::replaceToken("ARRAY", position, array, source);
21113 if (INVALID == test_case.m_case)
21115 Utils::replaceToken("ARRAY", position, array, source);
21117 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
21119 Utils::replaceAllTokens("TYPE", type_name, source);
21120 Utils::replaceAllTokens("INDEX", index, source);
21124 switch (test_case.m_stage)
21126 case Utils::Shader::GEOMETRY:
21129 case Utils::Shader::FRAGMENT:
21132 case Utils::Shader::VERTEX:
21139 case Utils::Shader::TESS_CTRL:
21142 case Utils::Shader::FRAGMENT:
21145 case Utils::Shader::VERTEX:
21152 case Utils::Shader::TESS_EVAL:
21155 case Utils::Shader::FRAGMENT:
21158 case Utils::Shader::TESS_CTRL:
21161 case Utils::Shader::VERTEX:
21168 case Utils::Shader::VERTEX:
21171 case Utils::Shader::FRAGMENT:
21179 TCU_FAIL("Invalid enum");
21187 /** Get description of test case
21189 * @param test_case_index Index of test case
21191 * @return Test case description
21193 std::string XFBVariableStrideTest::getTestCaseName(GLuint test_case_index)
21195 std::stringstream stream;
21196 testCase& test_case = m_test_cases[test_case_index];
21198 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
21199 << ", type: " << test_case.m_type.GetGLSLTypeName() << ", case: ";
21201 switch (test_case.m_case)
21207 stream << "invalid";
21210 TCU_FAIL("Invalid enum");
21213 return stream.str();
21216 /** Get number of test cases
21218 * @return Number of test cases
21220 GLuint XFBVariableStrideTest::getTestCaseNumber()
21222 return static_cast<GLuint>(m_test_cases.size());
21225 /** Selects if "compute" stage is relevant for test
21231 bool XFBVariableStrideTest::isComputeRelevant(GLuint /* test_case_index */)
21236 /** Selects if compilation failure is expected result
21238 * @param test_case_index Index of test case
21242 bool XFBVariableStrideTest::isFailureExpected(GLuint test_case_index)
21244 testCase& test_case = m_test_cases[test_case_index];
21246 return (INVALID == test_case.m_case);
21249 /** Prepare all test cases
21252 void XFBVariableStrideTest::testInit()
21254 const GLuint n_types = getTypesNumber();
21256 for (GLuint i = 0; i < n_types; ++i)
21258 const Utils::Type& type = getType(i);
21261 Some of the cases are declared as following are considered as invalid,
21262 but accoring to spec, the following declaration is valid: shaders in the
21263 transform feedback capturing mode have an initial global default of layout(xfb_buffer=0) out,
21264 so for the first variable's declaration, the xfb_stride = 16 is applied on buffer 0, for the
21265 second variable, its buffer is also inherited from global buffer 0, and its offset does not overflows
21268 The xfb_stride is the memory width of given buffer, not for variable even though xfb_stride
21269 is declared on the variable. It seems that the writter of this case misunderstand the concept of
21270 xfb_stride, because spec describes that xfb_stride can be declared multiple times for the same buffer,
21271 it is a compile or link-time error to have different values specified for the stride for the same buffer.
21274 layout (xfb_offset = 0, xfb_stride = 2 * type_size) out double goku;
21275 layout (xfb_offset = type_size) out double vegeta;
21277 // all the shaders are valid, so remove the following loop(it contains CASE_MAX is enum of valid and invalid)
21278 // for (GLuint c = 0; c < CASE_MAX; ++c)
21280 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
21282 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
21283 (Utils::Shader::FRAGMENT == stage))
21288 testCase test_case = { (CASES)VALID, (Utils::Shader::STAGES)stage, type };
21290 m_test_cases.push_back(test_case);
21298 * @param context Test framework context
21300 XFBBlockStrideTest::XFBBlockStrideTest(deqp::Context& context)
21301 : TestBase(context, "xfb_block_stride", "Test verifies that stride qualifier is respected for blocks")
21305 /** Source for given test case and stage
21307 * @param test_case_index Index of test case
21308 * @param stage Shader stage
21310 * @return Shader source
21312 std::string XFBBlockStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
21314 static const GLchar* var_definition = "layout (xfb_offset = 0, xfb_stride = 128) out Goku {\n"
21319 static const GLchar* var_use = " gokuINDEX.gohan = vec4(1, 0, 0, 0);\n"
21320 " gokuINDEX.goten = vec4(0, 0, 1, 0);\n"
21321 " gokuINDEX.chichi = vec4(0, 1, 0, 0);\n"
21322 " if (vec4(0) == result)\n"
21324 " gokuINDEX.gohan = vec4(0, 1, 1, 1);\n"
21325 " gokuINDEX.goten = vec4(1, 1, 0, 1);\n"
21326 " gokuINDEX.chichi = vec4(1, 0, 1, 1);\n"
21328 static const GLchar* gs_tested =
21329 "#version 430 core\n"
21330 "#extension GL_ARB_enhanced_layouts : require\n"
21332 "layout(points) in;\n"
21333 "layout(triangle_strip, max_vertices = 4) out;\n"
21337 "out gl_PerVertex \n"
21339 " vec4 gl_Position; \n" // gl_Position must be redeclared in separable program mode
21341 "in vec4 tes_gs[];\n"
21342 "out vec4 gs_fs;\n"
21346 " vec4 result = tes_gs[0];\n"
21350 " gs_fs = result;\n"
21351 " gl_Position = vec4(-1, -1, 0, 1);\n"
21353 " gs_fs = result;\n"
21354 " gl_Position = vec4(-1, 1, 0, 1);\n"
21356 " gs_fs = result;\n"
21357 " gl_Position = vec4(1, -1, 0, 1);\n"
21359 " gs_fs = result;\n"
21360 " gl_Position = vec4(1, 1, 0, 1);\n"
21364 static const GLchar* tcs = "#version 430 core\n"
21365 "#extension GL_ARB_enhanced_layouts : require\n"
21367 "layout(vertices = 1) out;\n"
21369 "in vec4 vs_tcs[];\n"
21370 "out vec4 tcs_tes[];\n"
21375 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
21377 " gl_TessLevelOuter[0] = 1.0;\n"
21378 " gl_TessLevelOuter[1] = 1.0;\n"
21379 " gl_TessLevelOuter[2] = 1.0;\n"
21380 " gl_TessLevelOuter[3] = 1.0;\n"
21381 " gl_TessLevelInner[0] = 1.0;\n"
21382 " gl_TessLevelInner[1] = 1.0;\n"
21386 static const GLchar* tcs_tested =
21387 "#version 430 core\n"
21388 "#extension GL_ARB_enhanced_layouts : require\n"
21390 "layout(vertices = 1) out;\n"
21394 "in vec4 vs_tcs[];\n"
21395 "out vec4 tcs_tes[];\n"
21399 " vec4 result = vs_tcs[gl_InvocationID];\n"
21403 " tcs_tes[gl_InvocationID] = result;\n"
21405 " gl_TessLevelOuter[0] = 1.0;\n"
21406 " gl_TessLevelOuter[1] = 1.0;\n"
21407 " gl_TessLevelOuter[2] = 1.0;\n"
21408 " gl_TessLevelOuter[3] = 1.0;\n"
21409 " gl_TessLevelInner[0] = 1.0;\n"
21410 " gl_TessLevelInner[1] = 1.0;\n"
21414 static const GLchar* tes_tested = "#version 430 core\n"
21415 "#extension GL_ARB_enhanced_layouts : require\n"
21417 "layout(isolines, point_mode) in;\n"
21421 "in vec4 tcs_tes[];\n"
21422 "out vec4 tes_gs;\n"
21426 " vec4 result = tcs_tes[0];\n"
21430 " tes_gs += result;\n"
21433 static const GLchar* vs = "#version 430 core\n"
21434 "#extension GL_ARB_enhanced_layouts : require\n"
21437 "out vec4 vs_tcs;\n"
21441 " vs_tcs = in_vs;\n"
21444 static const GLchar* vs_tested = "#version 430 core\n"
21445 "#extension GL_ARB_enhanced_layouts : require\n"
21450 "out vec4 vs_tcs;\n"
21454 " vec4 result = in_vs;\n"
21458 " vs_tcs += result;\n"
21462 std::string source;
21463 Utils::Shader::STAGES test_case = m_test_cases[test_case_index];
21465 if (test_case == stage)
21467 const GLchar* array = "";
21468 const GLchar* index = "";
21469 size_t position = 0;
21471 // It is a compile time error to apply xfb_offset to the declaration of an unsized array(GLSL4.5 spec: Page73)
21472 // change array = "[]" to "[1]"
21475 case Utils::Shader::GEOMETRY:
21476 source = gs_tested;
21481 It is invalid to define transform feedback output in HS
21484 case Utils::Shader::TESS_CTRL:
21485 source = tcs_tested;
21487 index = "[gl_InvocationID]";
21490 case Utils::Shader::TESS_EVAL:
21491 source = tes_tested;
21495 case Utils::Shader::VERTEX:
21496 source = vs_tested;
21499 TCU_FAIL("Invalid enum");
21503 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
21505 Utils::replaceToken("ARRAY", position, array, source);
21506 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
21508 Utils::replaceAllTokens("INDEX", index, source);
21514 case Utils::Shader::GEOMETRY:
21517 case Utils::Shader::VERTEX:
21524 case Utils::Shader::TESS_CTRL:
21527 case Utils::Shader::VERTEX:
21534 case Utils::Shader::TESS_EVAL:
21537 case Utils::Shader::TESS_CTRL:
21540 case Utils::Shader::VERTEX:
21547 case Utils::Shader::VERTEX:
21551 TCU_FAIL("Invalid enum");
21559 /** Get description of test case
21561 * @param test_case_index Index of test case
21563 * @return Test case description
21565 std::string XFBBlockStrideTest::getTestCaseName(GLuint test_case_index)
21567 std::stringstream stream;
21569 stream << "Stage: " << Utils::Shader::GetStageName(m_test_cases[test_case_index]);
21571 return stream.str();
21574 /** Get number of test cases
21576 * @return Number of test cases
21578 GLuint XFBBlockStrideTest::getTestCaseNumber()
21580 return static_cast<GLuint>(m_test_cases.size());
21583 /** Inspects program for xfb stride
21585 * @param program Program to query
21587 * @return true if query results match expected values, false otherwise
21589 bool XFBBlockStrideTest::inspectProgram(Utils::Program& program)
21593 program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE,
21594 1 /* buf_size */, &stride);
21596 return (128 == stride);
21601 * @param test_case_index Id of test case
21603 * @return true if test case pass, false otherwise
21605 bool XFBBlockStrideTest::testCase(GLuint test_case_index)
21607 const std::string& gs_source = getShaderSource(test_case_index, Utils::Shader::GEOMETRY);
21608 Utils::Program program(m_context);
21609 const std::string& tcs_source = getShaderSource(test_case_index, Utils::Shader::TESS_CTRL);
21610 const std::string& tes_source = getShaderSource(test_case_index, Utils::Shader::TESS_EVAL);
21611 bool test_case_result = true;
21612 const std::string& vs_source = getShaderSource(test_case_index, Utils::Shader::VERTEX);
21614 program.Init("" /* cs */, "", gs_source, tcs_source, tes_source, vs_source, true /* separable */);
21616 test_case_result = inspectProgram(program);
21618 return test_case_result;
21621 /** Prepare all test cases
21624 void XFBBlockStrideTest::testInit()
21626 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
21628 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
21629 (Utils::Shader::FRAGMENT == stage))
21634 m_test_cases.push_back((Utils::Shader::STAGES)stage);
21640 * @param context Test context
21642 XFBBlockMemberStrideTest::XFBBlockMemberStrideTest(deqp::Context& context)
21643 : BufferTestBase(context, "xfb_block_member_stride",
21644 "Test verifies that xfb_stride qualifier is respected for block member")
21646 /* Nothing to be done here */
21649 /** Get descriptors of buffers necessary for test
21652 * @param out_descriptors Descriptors of buffers used by test
21654 void XFBBlockMemberStrideTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
21655 bufferDescriptor::Vector& out_descriptors)
21657 const Utils::Type& vec4 = Utils::Type::vec4;
21659 /* Test needs single uniform and xfb */
21660 out_descriptors.resize(2);
21662 /* Get references */
21663 bufferDescriptor& uniform = out_descriptors[0];
21664 bufferDescriptor& xfb = out_descriptors[1];
21667 uniform.m_index = 0;
21671 uniform.m_target = Utils::Buffer::Uniform;
21672 xfb.m_target = Utils::Buffer::Transform_feedback;
21675 static const GLuint vec4_size = 16;
21676 const std::vector<GLubyte>& gohan_data = vec4.GenerateDataPacked();
21677 const std::vector<GLubyte>& goten_data = vec4.GenerateDataPacked();
21678 const std::vector<GLubyte>& chichi_data = vec4.GenerateDataPacked();
21681 uniform.m_initial_data.resize(3 * vec4_size);
21682 memcpy(&uniform.m_initial_data[0] + 0, &gohan_data[0], vec4_size);
21683 memcpy(&uniform.m_initial_data[0] + vec4_size, &goten_data[0], vec4_size);
21684 memcpy(&uniform.m_initial_data[0] + 2 * vec4_size, &chichi_data[0], vec4_size);
21687 xfb.m_initial_data.resize(4 * vec4_size);
21688 xfb.m_expected_data.resize(4 * vec4_size);
21690 for (GLuint i = 0; i < 4 * vec4_size; ++i)
21692 xfb.m_initial_data[i] = (glw::GLubyte)i;
21693 xfb.m_expected_data[i] = (glw::GLubyte)i;
21696 // the xfb_offset of "chichi" should be 32
21697 memcpy(&xfb.m_expected_data[0] + 0, &gohan_data[0], vec4_size);
21698 memcpy(&xfb.m_expected_data[0] + vec4_size, &goten_data[0], vec4_size);
21699 memcpy(&xfb.m_expected_data[0] + 2 * vec4_size, &chichi_data[0], vec4_size);
21702 /** Get body of main function for given shader stage
21705 * @param stage Shader stage
21706 * @param out_assignments Set to empty
21707 * @param out_calculations Set to empty
21709 void XFBBlockMemberStrideTest::getShaderBody(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
21710 std::string& out_assignments, std::string& out_calculations)
21712 out_calculations = "";
21714 static const GLchar* gs = " gohan = uni_gohan;\n"
21715 " goten = uni_goten;\n"
21716 " chichi = uni_chichi;\n";
21717 static const GLchar* fs = " fs_out = gohan + goten + chichi;\n";
21719 const GLchar* assignments = "";
21722 case Utils::Shader::FRAGMENT:
21725 case Utils::Shader::GEOMETRY:
21732 out_assignments = assignments;
21735 /** Get interface of shader
21738 * @param stage Shader stage
21739 * @param out_interface Set to ""
21741 void XFBBlockMemberStrideTest::getShaderInterface(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
21742 std::string& out_interface)
21744 static const GLchar* gs = "layout (xfb_buffer = 0, xfb_offset = 0) out Goku {\n"
21746 " layout (xfb_stride = 32) vec4 goten;\n"
21749 "layout(binding = 0) uniform gs_block {\n"
21750 " vec4 uni_gohan;\n"
21751 " vec4 uni_goten;\n"
21752 " vec4 uni_chichi;\n"
21754 static const GLchar* fs = "in Goku {\n"
21759 "out vec4 fs_out;\n";
21763 case Utils::Shader::FRAGMENT:
21764 out_interface = fs;
21766 case Utils::Shader::GEOMETRY:
21767 out_interface = gs;
21770 out_interface = "";
21775 /** Inspects program to check if all resources are as expected
21778 * @param program Program instance
21779 * @param out_stream Error message
21781 * @return true if everything is ok, false otherwise
21783 bool XFBBlockMemberStrideTest::inspectProgram(GLuint /* test_case_index*/, Utils::Program& program,
21784 std::stringstream& out_stream)
21786 const GLuint gohan_id = program.GetResourceIndex("gohan", GL_TRANSFORM_FEEDBACK_VARYING);
21787 const GLuint goten_id = program.GetResourceIndex("goten", GL_TRANSFORM_FEEDBACK_VARYING);
21788 const GLuint chichi_id = program.GetResourceIndex("chichi", GL_TRANSFORM_FEEDBACK_VARYING);
21790 GLint gohan_offset = 0;
21791 GLint goten_offset = 0;
21792 GLint chichi_offset = 0;
21794 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, gohan_id, GL_OFFSET, 1, &gohan_offset);
21795 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, goten_id, GL_OFFSET, 1, &goten_offset);
21796 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, chichi_id, GL_OFFSET, 1, &chichi_offset);
21798 // the xfb_offset of "chichi" should be 32
21799 if ((0 != gohan_offset) || (16 != goten_offset) || (32 != chichi_offset))
21801 out_stream << "Got wrong offset: [" << gohan_offset << ", " << goten_offset << ", " << chichi_offset
21802 << "] expected: [0, 16, 48]";
21811 * @param context Test framework context
21813 XFBDuplicatedStrideTest::XFBDuplicatedStrideTest(deqp::Context& context)
21814 : NegativeTestBase(context, "xfb_duplicated_stride",
21815 "Test verifies that compiler reports error when conflicting stride qualifiers are used")
21819 /** Source for given test case and stage
21821 * @param test_case_index Index of test case
21822 * @param stage Shader stage
21824 * @return Shader source
21826 std::string XFBDuplicatedStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
21828 static const GLchar* invalid_var_definition = "const uint valid_stride = 64;\n"
21829 "const uint conflicting_stride = 128;\n"
21831 "layout (xfb_buffer = 0, xfb_stride = valid_stride) out;\n"
21832 "layout (xfb_buffer = 0, xfb_stride = conflicting_stride) out;\n";
21833 static const GLchar* valid_var_definition = "const uint valid_stride = 64;\n"
21835 "layout (xfb_buffer = 0, xfb_stride = valid_stride) out;\n"
21836 "layout (xfb_buffer = 0, xfb_stride = valid_stride) out;\n";
21837 static const GLchar* fs = "#version 430 core\n"
21838 "#extension GL_ARB_enhanced_layouts : require\n"
21840 "in vec4 any_fs;\n"
21841 "out vec4 fs_out;\n"
21845 " fs_out = any_fs;\n"
21848 static const GLchar* gs_tested = "#version 430 core\n"
21849 "#extension GL_ARB_enhanced_layouts : require\n"
21851 "layout(points) in;\n"
21852 "layout(triangle_strip, max_vertices = 4) out;\n"
21856 "in vec4 vs_any[];\n"
21857 "out vec4 any_fs;\n"
21861 " vec4 result = vs_any[0];\n"
21865 " any_fs = result;\n"
21866 " gl_Position = vec4(-1, -1, 0, 1);\n"
21868 " any_fs = result;\n"
21869 " gl_Position = vec4(-1, 1, 0, 1);\n"
21871 " any_fs = result;\n"
21872 " gl_Position = vec4(1, -1, 0, 1);\n"
21874 " any_fs = result;\n"
21875 " gl_Position = vec4(1, 1, 0, 1);\n"
21879 static const GLchar* tcs = "#version 430 core\n"
21880 "#extension GL_ARB_enhanced_layouts : require\n"
21882 "layout(vertices = 1) out;\n"
21884 "in vec4 vs_any[];\n"
21885 "out vec4 tcs_tes[];\n"
21890 " tcs_tes[gl_InvocationID] = vs_any[gl_InvocationID];\n"
21892 " gl_TessLevelOuter[0] = 1.0;\n"
21893 " gl_TessLevelOuter[1] = 1.0;\n"
21894 " gl_TessLevelOuter[2] = 1.0;\n"
21895 " gl_TessLevelOuter[3] = 1.0;\n"
21896 " gl_TessLevelInner[0] = 1.0;\n"
21897 " gl_TessLevelInner[1] = 1.0;\n"
21900 static const GLchar* tcs_tested = "#version 430 core\n"
21901 "#extension GL_ARB_enhanced_layouts : require\n"
21903 "layout(vertices = 1) out;\n"
21907 "in vec4 vs_any[];\n"
21908 "out vec4 any_fs[];\n"
21912 " vec4 result = vs_any[gl_InvocationID];\n"
21916 " any_fs[gl_InvocationID] = result;\n"
21918 " gl_TessLevelOuter[0] = 1.0;\n"
21919 " gl_TessLevelOuter[1] = 1.0;\n"
21920 " gl_TessLevelOuter[2] = 1.0;\n"
21921 " gl_TessLevelOuter[3] = 1.0;\n"
21922 " gl_TessLevelInner[0] = 1.0;\n"
21923 " gl_TessLevelInner[1] = 1.0;\n"
21926 static const GLchar* tes_tested = "#version 430 core\n"
21927 "#extension GL_ARB_enhanced_layouts : require\n"
21929 "layout(isolines, point_mode) in;\n"
21933 "in vec4 tcs_tes[];\n"
21934 "out vec4 any_fs;\n"
21938 " vec4 result = tcs_tes[0];\n"
21942 " any_fs = result;\n"
21945 static const GLchar* vs = "#version 430 core\n"
21946 "#extension GL_ARB_enhanced_layouts : require\n"
21949 "out vec4 vs_any;\n"
21953 " vs_any = in_vs;\n"
21956 static const GLchar* vs_tested = "#version 430 core\n"
21957 "#extension GL_ARB_enhanced_layouts : require\n"
21962 "out vec4 any_fs;\n"
21966 " vec4 result = in_vs;\n"
21970 " any_fs += result;\n"
21974 std::string source;
21975 testCase& test_case = m_test_cases[test_case_index];
21977 if (test_case.m_stage == stage)
21979 size_t position = 0;
21980 const GLchar* var_definition = 0;
21981 const GLchar* var_use = "";
21983 switch (test_case.m_case)
21986 var_definition = valid_var_definition;
21989 var_definition = invalid_var_definition;
21992 TCU_FAIL("Invalid enum");
21997 case Utils::Shader::GEOMETRY:
21998 source = gs_tested;
22000 case Utils::Shader::TESS_CTRL:
22001 source = tcs_tested;
22003 case Utils::Shader::TESS_EVAL:
22004 source = tes_tested;
22006 case Utils::Shader::VERTEX:
22007 source = vs_tested;
22010 TCU_FAIL("Invalid enum");
22013 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
22014 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
22018 switch (test_case.m_stage)
22020 case Utils::Shader::GEOMETRY:
22023 case Utils::Shader::FRAGMENT:
22026 case Utils::Shader::VERTEX:
22033 case Utils::Shader::TESS_CTRL:
22036 case Utils::Shader::FRAGMENT:
22039 case Utils::Shader::VERTEX:
22046 case Utils::Shader::TESS_EVAL:
22049 case Utils::Shader::FRAGMENT:
22052 case Utils::Shader::TESS_CTRL:
22055 case Utils::Shader::VERTEX:
22062 case Utils::Shader::VERTEX:
22065 case Utils::Shader::FRAGMENT:
22073 TCU_FAIL("Invalid enum");
22081 /** Get description of test case
22083 * @param test_case_index Index of test case
22085 * @return Test case description
22087 std::string XFBDuplicatedStrideTest::getTestCaseName(GLuint test_case_index)
22089 std::stringstream stream;
22090 testCase& test_case = m_test_cases[test_case_index];
22092 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", case: ";
22094 switch (test_case.m_case)
22100 stream << "invalid";
22103 TCU_FAIL("Invalid enum");
22106 return stream.str();
22109 /** Get number of test cases
22111 * @return Number of test cases
22113 GLuint XFBDuplicatedStrideTest::getTestCaseNumber()
22115 return static_cast<GLuint>(m_test_cases.size());
22118 /** Selects if "compute" stage is relevant for test
22124 bool XFBDuplicatedStrideTest::isComputeRelevant(GLuint /* test_case_index */)
22129 /** Selects if compilation failure is expected result
22131 * @param test_case_index Index of test case
22135 bool XFBDuplicatedStrideTest::isFailureExpected(GLuint test_case_index)
22137 testCase& test_case = m_test_cases[test_case_index];
22139 return (INVALID == test_case.m_case);
22142 /** Prepare all test cases
22145 void XFBDuplicatedStrideTest::testInit()
22147 for (GLuint c = 0; c < CASE_MAX; ++c)
22149 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
22151 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
22152 (Utils::Shader::FRAGMENT == stage))
22157 testCase test_case = { (CASES)c, (Utils::Shader::STAGES)stage };
22159 m_test_cases.push_back(test_case);
22166 * @param context Test framework context
22168 XFBGetProgramResourceAPITest::XFBGetProgramResourceAPITest(deqp::Context& context)
22169 : TestBase(context, "xfb_get_program_resource_api",
22170 "Test verifies that get program resource reports correct results for XFB")
22174 /** Source for given test case and stage
22176 * @param test_case_index Index of test case
22177 * @param stage Shader stage
22179 * @return Shader source
22181 std::string XFBGetProgramResourceAPITest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
22183 static const GLchar* api_var_definition = "out TYPE b0_v1ARRAY;\n"
22184 "out TYPE b1_v1ARRAY;\n"
22185 "out TYPE b0_v3ARRAY;\n"
22186 "out TYPE b0_v0ARRAY;\n";
22187 static const GLchar* xfb_var_definition =
22188 "const uint type_size = SIZE;\n"
22190 "layout (xfb_buffer = 1, xfb_stride = 4 * type_size) out;\n"
22192 "layout (xfb_buffer = 0, xfb_offset = 1 * type_size) out TYPE b0_v1ARRAY;\n"
22193 "layout (xfb_buffer = 1, xfb_offset = 1 * type_size) out TYPE b1_v1ARRAY;\n"
22194 "layout (xfb_buffer = 0, xfb_offset = 3 * type_size) out TYPE b0_v3ARRAY;\n"
22195 "layout (xfb_buffer = 0, xfb_offset = 0 * type_size) out TYPE b0_v0ARRAY;\n";
22196 static const GLchar* var_use = " b0_v1INDEX = TYPE(0);\n"
22197 " b1_v1INDEX = TYPE(1);\n"
22198 " b0_v3INDEX = TYPE(0);\n"
22199 " b0_v0INDEX = TYPE(1);\n"
22200 " if (vec4(0) == result)\n"
22202 " b0_v1INDEX = TYPE(1);\n"
22203 " b1_v1INDEX = TYPE(0);\n"
22204 " b0_v3INDEX = TYPE(1);\n"
22205 " b0_v0INDEX = TYPE(0);\n"
22207 static const GLchar* gs_tested =
22208 "#version 430 core\n"
22209 "#extension GL_ARB_enhanced_layouts : require\n"
22211 "layout(points) in;\n"
22212 "layout(triangle_strip, max_vertices = 4) out;\n"
22216 "out gl_PerVertex \n"
22218 " vec4 gl_Position; \n" // gl_Position must be redeclared in separable program mode
22220 "in vec4 tes_gs[];\n"
22221 "out vec4 gs_fs;\n"
22225 " vec4 result = tes_gs[0];\n"
22229 " gs_fs = result;\n"
22230 " gl_Position = vec4(-1, -1, 0, 1);\n"
22232 " gs_fs = result;\n"
22233 " gl_Position = vec4(-1, 1, 0, 1);\n"
22235 " gs_fs = result;\n"
22236 " gl_Position = vec4(1, -1, 0, 1);\n"
22238 " gs_fs = result;\n"
22239 " gl_Position = vec4(1, 1, 0, 1);\n"
22244 static const GLchar* tcs_tested =
22245 "#version 430 core\n"
22246 "#extension GL_ARB_enhanced_layouts : require\n"
22248 "layout(vertices = 1) out;\n"
22252 "in vec4 vs_tcs[];\n"
22253 "out vec4 tcs_tes[];\n"
22257 " vec4 result = vs_tcs[gl_InvocationID];\n"
22261 " tcs_tes[gl_InvocationID] = result;\n"
22263 " gl_TessLevelOuter[0] = 1.0;\n"
22264 " gl_TessLevelOuter[1] = 1.0;\n"
22265 " gl_TessLevelOuter[2] = 1.0;\n"
22266 " gl_TessLevelOuter[3] = 1.0;\n"
22267 " gl_TessLevelInner[0] = 1.0;\n"
22268 " gl_TessLevelInner[1] = 1.0;\n"
22272 static const GLchar* tes_tested = "#version 430 core\n"
22273 "#extension GL_ARB_enhanced_layouts : require\n"
22275 "layout(isolines, point_mode) in;\n"
22279 "in vec4 tcs_tes[];\n"
22280 "out vec4 tes_gs;\n"
22284 " vec4 result = tcs_tes[0];\n"
22288 " tes_gs = result;\n"
22291 static const GLchar* vs_tested = "#version 430 core\n"
22292 "#extension GL_ARB_enhanced_layouts : require\n"
22297 "out vec4 vs_tcs;\n"
22301 " vec4 result = in_vs;\n"
22305 " vs_tcs = result;\n"
22309 std::string source;
22310 const test_Case& test_case = m_test_cases[test_case_index];
22312 if (test_case.m_stage == stage)
22314 const GLchar* array = "";
22316 const GLchar* index = "";
22317 size_t position = 0;
22319 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
22320 const GLchar* var_definition = 0;
22322 sprintf(buffer, "%d", test_case.m_type.GetSize());
22324 if (XFB == test_case.m_case)
22326 var_definition = xfb_var_definition;
22330 var_definition = api_var_definition;
22333 // It is a compile time error to apply xfb_offset to the declaration of an unsized array(GLSL4.5 spec: Page73)
22334 // change array = "[]" to "[1]"
22337 case Utils::Shader::GEOMETRY:
22338 source = gs_tested;
22342 // It is invalid to output transform feedback varyings in tessellation control shader
22344 case Utils::Shader::TESS_CTRL:
22345 source = tcs_tested;
22347 index = "[gl_InvocationID]";
22350 case Utils::Shader::TESS_EVAL:
22351 source = tes_tested;
22355 case Utils::Shader::VERTEX:
22356 source = vs_tested;
22359 TCU_FAIL("Invalid enum");
22363 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
22364 if (XFB == test_case.m_case)
22367 Utils::replaceToken("SIZE", position, buffer, source);
22369 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
22371 Utils::replaceAllTokens("ARRAY", array, source);
22372 Utils::replaceAllTokens("INDEX", index, source);
22373 Utils::replaceAllTokens("TYPE", type_name, source);
22383 /** Get description of test case
22385 * @param test_case_index Index of test case
22387 * @return Test case description
22389 std::string XFBGetProgramResourceAPITest::getTestCaseName(GLuint test_case_index)
22391 std::stringstream stream;
22392 const test_Case& test_case = m_test_cases[test_case_index];
22394 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
22395 << ", type: " << test_case.m_type.GetGLSLTypeName() << ", case: ";
22397 switch (test_case.m_case)
22400 stream << "interleaved";
22403 stream << "separated";
22409 TCU_FAIL("Invalid enum");
22412 return stream.str();
22415 /** Get number of test cases
22417 * @return Number of test cases
22419 GLuint XFBGetProgramResourceAPITest::getTestCaseNumber()
22421 return static_cast<GLuint>(m_test_cases.size());
22424 /** Inspects program for offset, buffer index, buffer stride and type
22426 * @param test_case_index Index of test case
22427 * @param program Program to query
22429 * @return true if query results match expected values, false otherwise
22431 bool XFBGetProgramResourceAPITest::inspectProgram(glw::GLuint test_case_index, Utils::Program& program)
22433 GLint b0_stride = 0;
22434 GLint b1_stride = 0;
22435 GLint b0_v0_buf = 0;
22436 GLint b0_v0_offset = 0;
22437 GLint b0_v0_type = 0;
22438 GLint b0_v1_buf = 0;
22439 GLint b0_v1_offset = 0;
22440 GLint b0_v1_type = 0;
22441 GLint b0_v3_buf = 0;
22442 GLint b0_v3_offset = 0;
22443 GLint b0_v3_type = 0;
22444 GLint b1_v1_buf = 0;
22445 GLint b1_v1_offset = 0;
22446 GLint b1_v1_type = 0;
22447 const test_Case& test_case = m_test_cases[test_case_index];
22448 const GLenum type_enum = test_case.m_type.GetTypeGLenum();
22449 const GLint type_size = test_case.m_type.GetSize();
22451 GLuint b0_v0_index = program.GetResourceIndex("b0_v0", GL_TRANSFORM_FEEDBACK_VARYING);
22452 GLuint b0_v1_index = program.GetResourceIndex("b0_v1", GL_TRANSFORM_FEEDBACK_VARYING);
22453 GLuint b0_v3_index = program.GetResourceIndex("b0_v3", GL_TRANSFORM_FEEDBACK_VARYING);
22454 GLuint b1_v1_index = program.GetResourceIndex("b1_v1", GL_TRANSFORM_FEEDBACK_VARYING);
22456 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v0_index, GL_OFFSET, 1 /* buf_size */, &b0_v0_offset);
22457 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v1_index, GL_OFFSET, 1 /* buf_size */, &b0_v1_offset);
22458 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v3_index, GL_OFFSET, 1 /* buf_size */, &b0_v3_offset);
22459 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b1_v1_index, GL_OFFSET, 1 /* buf_size */, &b1_v1_offset);
22461 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v0_index, GL_TYPE, 1 /* buf_size */, &b0_v0_type);
22462 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v1_index, GL_TYPE, 1 /* buf_size */, &b0_v1_type);
22463 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v3_index, GL_TYPE, 1 /* buf_size */, &b0_v3_type);
22464 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b1_v1_index, GL_TYPE, 1 /* buf_size */, &b1_v1_type);
22466 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v0_index, GL_TRANSFORM_FEEDBACK_BUFFER_INDEX,
22467 1 /* buf_size */, &b0_v0_buf);
22468 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v1_index, GL_TRANSFORM_FEEDBACK_BUFFER_INDEX,
22469 1 /* buf_size */, &b0_v1_buf);
22470 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v3_index, GL_TRANSFORM_FEEDBACK_BUFFER_INDEX,
22471 1 /* buf_size */, &b0_v3_buf);
22472 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b1_v1_index, GL_TRANSFORM_FEEDBACK_BUFFER_INDEX,
22473 1 /* buf_size */, &b1_v1_buf);
22475 program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, b0_v0_buf, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE, 1 /* buf_size */,
22477 program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, b1_v1_buf, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE, 1 /* buf_size */,
22480 if (SEPARATED != test_case.m_case)
22482 return (((GLint)(4 * type_size) == b0_stride) && ((GLint)(4 * type_size) == b1_stride) &&
22483 ((GLint)(0) == b0_v0_buf) && ((GLint)(0 * type_size) == b0_v0_offset) &&
22484 ((GLint)(type_enum) == b0_v0_type) && ((GLint)(0) == b0_v1_buf) &&
22485 ((GLint)(1 * type_size) == b0_v1_offset) && ((GLint)(type_enum) == b0_v1_type) &&
22486 ((GLint)(0) == b0_v3_buf) && ((GLint)(3 * type_size) == b0_v3_offset) &&
22487 ((GLint)(type_enum) == b0_v3_type) && ((GLint)(1) == b1_v1_buf) &&
22488 ((GLint)(1 * type_size) == b1_v1_offset) && ((GLint)(type_enum) == b1_v1_type));
22492 return (((GLint)(1 * type_size) == b0_stride) && ((GLint)(1 * type_size) == b1_stride) &&
22493 ((GLint)(0) == b0_v0_buf) && ((GLint)(0) == b0_v0_offset) && ((GLint)(type_enum) == b0_v0_type) &&
22494 ((GLint)(1) == b0_v1_buf) && ((GLint)(0) == b0_v1_offset) && ((GLint)(type_enum) == b0_v1_type) &&
22495 ((GLint)(2) == b0_v3_buf) && ((GLint)(0) == b0_v3_offset) && ((GLint)(type_enum) == b0_v3_type) &&
22496 ((GLint)(3) == b1_v1_buf) && ((GLint)(0) == b1_v1_offset) && ((GLint)(type_enum) == b1_v1_type));
22500 /** Insert gl_SkipComponents
22502 * @param num_components How many gl_SkipComponents1 need to be inserted
22503 * @param varyings The transform feedback varyings string vector
22506 void XFBGetProgramResourceAPITest::insertSkipComponents(int num_components, Utils::Program::NameVector& varyings)
22508 int num_component_4 = num_components / 4;
22509 int num_component_1 = num_components % 4;
22510 for (int i = 0; i < num_component_4; i++)
22512 varyings.push_back("gl_SkipComponents4");
22514 switch (num_component_1)
22517 varyings.push_back("gl_SkipComponents1");
22520 varyings.push_back("gl_SkipComponents2");
22523 varyings.push_back("gl_SkipComponents3");
22532 * @param test_case_index Id of test case
22534 * @return true if test case pass, false otherwise
22536 bool XFBGetProgramResourceAPITest::testCase(GLuint test_case_index)
22538 const std::string& gs_source = getShaderSource(test_case_index, Utils::Shader::GEOMETRY);
22539 Utils::Program program(m_context);
22540 const std::string& tcs_source = getShaderSource(test_case_index, Utils::Shader::TESS_CTRL);
22541 const std::string& tes_source = getShaderSource(test_case_index, Utils::Shader::TESS_EVAL);
22542 const test_Case& test_case = m_test_cases[test_case_index];
22543 bool test_case_result = true;
22544 const std::string& vs_source = getShaderSource(test_case_index, Utils::Shader::VERTEX);
22546 // According to spec: gl_SkipComponents1 ~ gl_SkipComponents4 is treated as specifying a one- to four-component floating point output variables with undefined values.
22547 // 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.
22549 if (INTERLEAVED == test_case.m_case)
22552 layout (xfb_buffer = 0, xfb_offset = 1 * type_size) out type b0_v1;
22553 layout (xfb_buffer = 1, xfb_offset = 1 * type_size) out type b1_v1;
22554 layout (xfb_buffer = 0, xfb_offset = 3 * type_size) out type b0_v3;
22555 layout (xfb_buffer = 0, xfb_offset = 0 * type_size) out type b0_v0;
22557 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,
22558 we need to calculate how many "gl_SkipComponents" need to be inserted.
22560 Utils::Program::NameVector captured_varyings;
22561 captured_varyings.push_back("b0_v0");
22562 captured_varyings.push_back("b0_v1");
22563 // Compute how many gl_SkipComponents to be inserted
22564 int numComponents = test_case.m_type.GetSize() / 4;
22565 insertSkipComponents(numComponents, captured_varyings);
22566 captured_varyings.push_back("b0_v3");
22567 captured_varyings.push_back("gl_NextBuffer");
22568 insertSkipComponents(numComponents, captured_varyings);
22569 captured_varyings.push_back("b1_v1");
22570 insertSkipComponents(numComponents * 2, captured_varyings);
22572 program.Init("" /* cs */, "", gs_source, tcs_source, tes_source, vs_source, captured_varyings, true,
22573 true /* separable */);
22575 else if (SEPARATED == test_case.m_case)
22577 Utils::Program::NameVector captured_varyings;
22579 captured_varyings.push_back("b0_v0");
22580 captured_varyings.push_back("b0_v1");
22581 captured_varyings.push_back("b0_v3");
22582 captured_varyings.push_back("b1_v1");
22584 program.Init("" /* cs */, "", gs_source, tcs_source, tes_source, vs_source, captured_varyings, false,
22585 true /* separable */);
22590 program.Init("" /* cs */, "", gs_source, tcs_source, tes_source, vs_source, true /* separable */);
22593 test_case_result = inspectProgram(test_case_index, program);
22595 return test_case_result;
22598 /** Prepare all test cases
22601 void XFBGetProgramResourceAPITest::testInit()
22603 const Functions& gl = m_context.getRenderContext().getFunctions();
22604 const GLuint n_types = getTypesNumber();
22608 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_xfb_int);
22609 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
22611 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, &max_xfb_sep);
22612 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
22614 GLint max_varyings;
22615 gl.getIntegerv(GL_MAX_VARYING_COMPONENTS, &max_varyings);
22617 for (GLuint i = 0; i < n_types; ++i)
22619 // 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,
22620 // 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
22621 // shader valid, we can either skip the dmat4, dmat4x3 or query the implementation-dependent value MAX_VARYING_COMPONENTS before generating the shader
22622 // to guarantee the number of varying not exceeded.
22624 layout (xfb_buffer = 1, xfb_stride = 4 * type_size) out;
22625 layout (xfb_buffer = 0, xfb_offset = 1 * type_size) out type b0_v1;
22626 layout (xfb_buffer = 1, xfb_offset = 1 * type_size) out type b1_v1;
22627 layout (xfb_buffer = 0, xfb_offset = 3 * type_size) out type b0_v3;
22628 layout (xfb_buffer = 0, xfb_offset = 0 * type_size) out type b0_v0;
22632 if (i == 7 || i == 9)
22634 const Utils::Type& type = getType(i);
22635 if (4 * type.GetNumComponents() + 4 > (GLuint)max_varyings)
22639 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
22642 It is invalid to define transform feedback output in HS
22644 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
22645 (Utils::Shader::FRAGMENT == stage))
22650 test_Case test_case_int = { INTERLEAVED, (Utils::Shader::STAGES)stage, type };
22651 test_Case test_case_sep = { SEPARATED, (Utils::Shader::STAGES)stage, type };
22652 test_Case test_case_xfb = { XFB, (Utils::Shader::STAGES)stage, type };
22654 if ((int)type.GetSize() <= max_xfb_int)
22656 m_test_cases.push_back(test_case_xfb);
22657 m_test_cases.push_back(test_case_int);
22660 if ((int)type.GetSize() <= max_xfb_sep)
22662 m_test_cases.push_back(test_case_sep);
22670 * @param context Test context
22672 XFBOverrideQualifiersWithAPITest::XFBOverrideQualifiersWithAPITest(deqp::Context& context)
22673 : BufferTestBase(context, "xfb_override_qualifiers_with_api",
22674 "Test verifies that xfb_offset qualifier is not overriden with API")
22676 /* Nothing to be done here */
22679 /** Get descriptors of buffers necessary for test
22681 * @param test_case_index Index of test case
22682 * @param out_descriptors Descriptors of buffers used by test
22684 void XFBOverrideQualifiersWithAPITest::getBufferDescriptors(glw::GLuint test_case_index,
22685 bufferDescriptor::Vector& out_descriptors)
22687 const Utils::Type& type = getType(test_case_index);
22689 /* Test needs single uniform and xfb */
22690 out_descriptors.resize(2);
22692 /* Get references */
22693 bufferDescriptor& uniform = out_descriptors[0];
22694 bufferDescriptor& xfb = out_descriptors[1];
22697 uniform.m_index = 0;
22701 uniform.m_target = Utils::Buffer::Uniform;
22702 xfb.m_target = Utils::Buffer::Transform_feedback;
22705 const GLuint gen_start = Utils::s_rand;
22706 const std::vector<GLubyte>& vegeta_data = type.GenerateData();
22707 const std::vector<GLubyte>& trunks_data = type.GenerateData();
22708 const std::vector<GLubyte>& goku_data = type.GenerateData();
22709 const std::vector<GLubyte>& gohan_data = type.GenerateData();
22711 Utils::s_rand = gen_start;
22712 const std::vector<GLubyte>& vegeta_data_pck = type.GenerateDataPacked();
22714 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)
22715 how can make them equal ? is it as designed? Add the following statement, which can make sure goku_data_pck equals to goku_data
22717 const std::vector<GLubyte>& goku_data_pck = type.GenerateDataPacked();
22719 const GLuint type_size = static_cast<GLuint>(vegeta_data.size());
22720 const GLuint type_size_pck = static_cast<GLuint>(vegeta_data_pck.size());
22723 uniform.m_initial_data.resize(4 * type_size);
22724 memcpy(&uniform.m_initial_data[0] + 0, &vegeta_data[0], type_size);
22725 memcpy(&uniform.m_initial_data[0] + type_size, &trunks_data[0], type_size);
22726 memcpy(&uniform.m_initial_data[0] + 2 * type_size, &goku_data[0], type_size);
22727 memcpy(&uniform.m_initial_data[0] + 3 * type_size, &gohan_data[0], type_size);
22730 xfb.m_initial_data.resize(4 * type_size_pck);
22731 xfb.m_expected_data.resize(4 * type_size_pck);
22733 for (GLuint i = 0; i < 4 * type_size_pck; ++i)
22735 xfb.m_initial_data[i] = (glw::GLubyte)i;
22736 xfb.m_expected_data[i] = (glw::GLubyte)i;
22739 memcpy(&xfb.m_expected_data[0] + 0, &goku_data_pck[0], type_size_pck);
22740 memcpy(&xfb.m_expected_data[0] + 2 * type_size_pck, &vegeta_data_pck[0], type_size_pck);
22743 /** Get list of names of varyings that will be registered with TransformFeedbackVaryings
22746 * @param captured_varyings List of names
22748 void XFBOverrideQualifiersWithAPITest::getCapturedVaryings(glw::GLuint /* test_case_index */,
22749 Utils::Program::NameVector& captured_varyings)
22751 captured_varyings.resize(2);
22753 captured_varyings[0] = "trunks";
22754 captured_varyings[1] = "gohan";
22757 /** Get body of main function for given shader stage
22759 * @param test_case_index Index of test case
22760 * @param stage Shader stage
22761 * @param out_assignments Set to empty
22762 * @param out_calculations Set to empty
22764 void XFBOverrideQualifiersWithAPITest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
22765 std::string& out_assignments, std::string& out_calculations)
22767 out_calculations = "";
22769 static const GLchar* gs = " vegeta = uni_vegeta;\n"
22770 " trunks = uni_trunks;\n"
22771 " goku = uni_goku;\n"
22772 " gohan = uni_gohan;\n";
22773 static const GLchar* fs = " fs_out = vec4(0);\n"
22774 " if (TYPE(1) == gohan + goku + trunks + vegeta)\n"
22776 " fs_out = vec4(1);\n"
22779 const GLchar* assignments = "";
22782 case Utils::Shader::FRAGMENT:
22785 case Utils::Shader::GEOMETRY:
22792 out_assignments = assignments;
22794 if (Utils::Shader::FRAGMENT == stage)
22796 const Utils::Type& type = getType(test_case_index);
22798 Utils::replaceAllTokens("TYPE", type.GetGLSLTypeName(), out_assignments);
22802 /** Get interface of shader
22804 * @param test_case_index Index of test case
22805 * @param stage Shader stage
22806 * @param out_interface Set to ""
22808 void XFBOverrideQualifiersWithAPITest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
22809 std::string& out_interface)
22811 static const GLchar* gs = "const uint sizeof_type = SIZE;\n"
22813 "layout (xfb_offset = 2 * sizeof_type) flat out TYPE vegeta;\n"
22814 " flat out TYPE trunks;\n"
22815 "layout (xfb_offset = 0) flat out TYPE goku;\n"
22816 " flat out TYPE gohan;\n"
22819 There is no packing qualifier for uniform block gs_block, according to spec, it should be "shared" by default,
22820 the definition equals to "layout(binding=0, shared)", if the block is declared as shared, each block member will
22821 not be packed, and each block member's layout in memory is implementation dependent, so we can't use the API
22822 glBufferData() to update the UBO directly, we need to query each block member's offset first, then upload the
22823 data to the corresponding offset, otherwise we can't get the correct data from UBO; to make the test passed,
22824 we need to add the qualifier std140, and change the declaration as layout(binding=0, std140), which can make
22825 sure all the block members are packed and the application can upload the data by glBufferData() directly.
22827 "layout(binding = 0, std140) uniform gs_block {\n"
22828 " TYPE uni_vegeta;\n"
22829 " TYPE uni_trunks;\n"
22830 " TYPE uni_goku;\n"
22831 " TYPE uni_gohan;\n"
22833 static const GLchar* fs = "flat in TYPE vegeta;\n"
22834 "flat in TYPE trunks;\n"
22835 "flat in TYPE goku;\n"
22836 "flat in TYPE gohan;\n"
22838 "out vec4 fs_out;\n";
22840 const Utils::Type& type = getType(test_case_index);
22844 case Utils::Shader::FRAGMENT:
22845 out_interface = fs;
22847 case Utils::Shader::GEOMETRY:
22848 out_interface = gs;
22851 out_interface = "";
22855 if (Utils::Shader::GEOMETRY == stage)
22858 size_t position = 0;
22859 const GLuint type_size = type.GetSize();
22861 sprintf(buffer, "%d", type_size);
22863 Utils::replaceToken("SIZE", position, buffer, out_interface);
22866 Utils::replaceAllTokens("TYPE", type.GetGLSLTypeName(), out_interface);
22871 * @param test_case_index Index of test case
22873 * @return Name of type test in test_case_index
22875 std::string XFBOverrideQualifiersWithAPITest::getTestCaseName(glw::GLuint test_case_index)
22877 return getTypeName(test_case_index);
22880 /** Returns number of types to test
22882 * @return Number of types, 34
22884 glw::GLuint XFBOverrideQualifiersWithAPITest::getTestCaseNumber()
22886 return getTypesNumber();
22889 /** Inspects program to check if all resources are as expected
22891 * @param test_case_index Index of test case
22892 * @param program Program instance
22893 * @param out_stream Error message
22895 * @return true if everything is ok, false otherwise
22897 bool XFBOverrideQualifiersWithAPITest::inspectProgram(GLuint test_case_index, Utils::Program& program,
22898 std::stringstream& out_stream)
22901 const Utils::Type& type = getType(test_case_index);
22902 const GLuint type_size = type.GetSize();
22904 program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE,
22905 1 /* buf_size */, &stride);
22907 if ((GLint)(3 * type_size) != stride)
22909 out_stream << "Stride is: " << stride << " expected: " << (3 * type_size);
22919 * @param context Test context
22921 XFBVertexStreamsTest::XFBVertexStreamsTest(deqp::Context& context)
22922 : BufferTestBase(context, "xfb_vertex_streams",
22923 "Test verifies that xfb qualifier works with multiple output streams")
22925 /* Nothing to be done here */
22928 /** Get descriptors of buffers necessary for test
22931 * @param out_descriptors Descriptors of buffers used by test
22933 void XFBVertexStreamsTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
22934 bufferDescriptor::Vector& out_descriptors)
22936 const Utils::Type& type = Utils::Type::vec4;
22938 /* Test needs single uniform and three xfbs */
22939 out_descriptors.resize(4);
22941 /* Get references */
22942 bufferDescriptor& uniform = out_descriptors[0];
22943 bufferDescriptor& xfb_1 = out_descriptors[1];
22944 bufferDescriptor& xfb_2 = out_descriptors[2];
22945 bufferDescriptor& xfb_3 = out_descriptors[3];
22948 uniform.m_index = 0;
22954 uniform.m_target = Utils::Buffer::Uniform;
22955 xfb_1.m_target = Utils::Buffer::Transform_feedback;
22956 xfb_2.m_target = Utils::Buffer::Transform_feedback;
22957 xfb_3.m_target = Utils::Buffer::Transform_feedback;
22960 const std::vector<GLubyte>& goku_data = type.GenerateData();
22961 const std::vector<GLubyte>& gohan_data = type.GenerateData();
22962 const std::vector<GLubyte>& goten_data = type.GenerateData();
22963 const std::vector<GLubyte>& picolo_data = type.GenerateData();
22964 const std::vector<GLubyte>& vegeta_data = type.GenerateData();
22965 const std::vector<GLubyte>& bulma_data = type.GenerateData();
22967 const GLuint type_size = static_cast<GLuint>(vegeta_data.size());
22970 uniform.m_initial_data.resize(6 * type_size);
22971 memcpy(&uniform.m_initial_data[0] + 0, &goku_data[0], type_size);
22972 memcpy(&uniform.m_initial_data[0] + type_size, &gohan_data[0], type_size);
22973 memcpy(&uniform.m_initial_data[0] + 2 * type_size, &goten_data[0], type_size);
22974 memcpy(&uniform.m_initial_data[0] + 3 * type_size, &picolo_data[0], type_size);
22975 memcpy(&uniform.m_initial_data[0] + 4 * type_size, &vegeta_data[0], type_size);
22976 memcpy(&uniform.m_initial_data[0] + 5 * type_size, &bulma_data[0], type_size);
22979 static const GLuint xfb_stride = 64;
22980 xfb_1.m_initial_data.resize(xfb_stride);
22981 xfb_1.m_expected_data.resize(xfb_stride);
22982 xfb_2.m_initial_data.resize(xfb_stride);
22983 xfb_2.m_expected_data.resize(xfb_stride);
22984 xfb_3.m_initial_data.resize(xfb_stride);
22985 xfb_3.m_expected_data.resize(xfb_stride);
22987 for (GLuint i = 0; i < xfb_stride; ++i)
22989 xfb_1.m_initial_data[i] = (glw::GLubyte)i;
22990 xfb_1.m_expected_data[i] = (glw::GLubyte)i;
22991 xfb_2.m_initial_data[i] = (glw::GLubyte)i;
22992 xfb_2.m_expected_data[i] = (glw::GLubyte)i;
22993 xfb_3.m_initial_data[i] = (glw::GLubyte)i;
22994 xfb_3.m_expected_data[i] = (glw::GLubyte)i;
22997 memcpy(&xfb_1.m_expected_data[0] + 48, &goku_data[0], type_size);
22998 memcpy(&xfb_1.m_expected_data[0] + 32, &gohan_data[0], type_size);
22999 memcpy(&xfb_1.m_expected_data[0] + 16, &goten_data[0], type_size);
23000 memcpy(&xfb_3.m_expected_data[0] + 48, &picolo_data[0], type_size);
23001 memcpy(&xfb_3.m_expected_data[0] + 32, &vegeta_data[0], type_size);
23002 memcpy(&xfb_2.m_expected_data[0] + 32, &bulma_data[0], type_size);
23005 /** Get body of main function for given shader stage
23008 * @param stage Shader stage
23009 * @param out_assignments Set to empty
23010 * @param out_calculations Set to empty
23012 void XFBVertexStreamsTest::getShaderBody(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
23013 std::string& out_assignments, std::string& out_calculations)
23015 out_calculations = "";
23017 // the shader declares the output variables with different "stream" qualifier, to make the data can export to
23018 // each stream, we must call the function EmitStreamVertex() and EndStreamPrimitive() to make each vertex emitted
23019 // by the GS is assigned to specific stream.
23020 static const GLchar* gs = " goku = uni_goku;\n"
23021 " gohan = uni_gohan;\n"
23022 " goten = uni_goten;\n"
23023 " EmitStreamVertex(0);\n"
23024 " EndStreamPrimitive(0);\n"
23025 " picolo = uni_picolo;\n"
23026 " vegeta = uni_vegeta;\n"
23027 " EmitStreamVertex(1);\n"
23028 " EndStreamPrimitive(1);\n"
23029 " bulma = uni_bulma;\n"
23030 " EmitStreamVertex(2);\n"
23031 " EndStreamPrimitive(2);\n";
23033 static const GLchar* fs = " fs_out = gohan + goku + goten + picolo + vegeta + bulma;\n";
23035 const GLchar* assignments = "";
23038 case Utils::Shader::FRAGMENT:
23041 case Utils::Shader::GEOMETRY:
23048 out_assignments = assignments;
23051 /** Get interface of shader
23054 * @param stage Shader stage
23055 * @param out_interface Set to ""
23057 void XFBVertexStreamsTest::getShaderInterface(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
23058 std::string& out_interface)
23060 static const GLchar* gs = "layout (xfb_buffer = 1, xfb_stride = 64) out;\n"
23061 "layout (xfb_buffer = 2, xfb_stride = 64) out;\n"
23062 "layout (xfb_buffer = 3, xfb_stride = 64) out;\n"
23064 "layout (stream = 0, xfb_buffer = 1, xfb_offset = 48) out vec4 goku;\n"
23065 "layout (stream = 0, xfb_buffer = 1, xfb_offset = 32) out vec4 gohan;\n"
23066 "layout (stream = 0, xfb_buffer = 1, xfb_offset = 16) out vec4 goten;\n"
23067 "layout (stream = 1, xfb_buffer = 3, xfb_offset = 48) out vec4 picolo;\n"
23068 "layout (stream = 1, xfb_buffer = 3, xfb_offset = 32) out vec4 vegeta;\n"
23069 "layout (stream = 2, xfb_buffer = 2, xfb_offset = 32) out vec4 bulma;\n"
23071 "layout(binding = 0) uniform gs_block {\n"
23072 " vec4 uni_goku;\n"
23073 " vec4 uni_gohan;\n"
23074 " vec4 uni_goten;\n"
23075 " vec4 uni_picolo;\n"
23076 " vec4 uni_vegeta;\n"
23077 " vec4 uni_bulma;\n"
23080 Fixed incorrect usage of in/out qualifier, the following variable should be input symbols for fragment shader
23082 static const GLchar* fs = "in vec4 goku;\n"
23085 "in vec4 picolo;\n"
23086 "in vec4 vegeta;\n"
23089 "out vec4 fs_out;\n";
23093 case Utils::Shader::FRAGMENT:
23094 out_interface = fs;
23096 case Utils::Shader::GEOMETRY:
23097 out_interface = gs;
23100 out_interface = "";
23107 * @param context Test framework context
23109 XFBMultipleVertexStreamsTest::XFBMultipleVertexStreamsTest(deqp::Context& context)
23110 : NegativeTestBase(
23111 context, "xfb_multiple_vertex_streams",
23112 "Test verifies that compiler reports error when multiple streams are captured with same xfb_buffer")
23116 /** Source for given test case and stage
23119 * @param stage Shader stage
23121 * @return Shader source
23123 std::string XFBMultipleVertexStreamsTest::getShaderSource(GLuint /* test_case_index */, Utils::Shader::STAGES stage)
23125 static const GLchar* var_definition = "const uint valid_stride = 64;\n"
23127 "layout (xfb_buffer = 1, xfb_stride = valid_stride) out;\n"
23128 "layout (xfb_buffer = 3, xfb_stride = valid_stride) out;\n"
23131 "layout (stream = 0, xfb_buffer = 1, xfb_offset = 48) out vec4 goku;\n"
23132 "layout (stream = 1, xfb_buffer = 1, xfb_offset = 32) out vec4 gohan;\n"
23133 "layout (stream = 2, xfb_buffer = 1, xfb_offset = 16) out vec4 goten;\n";
23134 static const GLchar* var_use = " goku = result / 2;\n"
23135 " gohan = result / 4;\n"
23136 " goten = result / 6;\n";
23137 static const GLchar* fs = "#version 430 core\n"
23138 "#extension GL_ARB_enhanced_layouts : require\n"
23142 "out vec4 fs_out;\n"
23146 " fs_out = gs_fs + goku;\n"
23149 static const GLchar* gs = "#version 430 core\n"
23150 "#extension GL_ARB_enhanced_layouts : require\n"
23152 "layout(points) in;\n"
23153 "layout(triangle_strip, max_vertices = 4) out;\n"
23157 "in vec4 tes_gs[];\n"
23158 "out vec4 gs_fs;\n"
23162 " vec4 result = tes_gs[0];\n"
23166 " gs_fs = result;\n"
23167 " gl_Position = vec4(-1, -1, 0, 1);\n"
23169 " gs_fs = result;\n"
23170 " gl_Position = vec4(-1, 1, 0, 1);\n"
23172 " gs_fs = result;\n"
23173 " gl_Position = vec4(1, -1, 0, 1);\n"
23175 " gs_fs = result;\n"
23176 " gl_Position = vec4(1, 1, 0, 1);\n"
23180 static const GLchar* vs = "#version 430 core\n"
23181 "#extension GL_ARB_enhanced_layouts : require\n"
23184 "out vec4 vs_tcs;\n"
23188 " vs_tcs = in_vs;\n"
23192 std::string source;
23194 if (Utils::Shader::GEOMETRY == stage)
23196 size_t position = 0;
23200 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
23201 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
23207 case Utils::Shader::FRAGMENT:
23210 case Utils::Shader::VERTEX:
23221 /** Selects if "compute" stage is relevant for test
23227 bool XFBMultipleVertexStreamsTest::isComputeRelevant(GLuint /* test_case_index */)
23234 * @param context Test framework context
23236 XFBExceedBufferLimitTest::XFBExceedBufferLimitTest(deqp::Context& context)
23237 : NegativeTestBase(context, "xfb_exceed_buffer_limit",
23238 "Test verifies that compiler reports error when xfb_buffer qualifier exceeds limit")
23242 /** Source for given test case and stage
23244 * @param test_case_index Index of test case
23245 * @param stage Shader stage
23247 * @return Shader source
23249 std::string XFBExceedBufferLimitTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
23251 static const GLchar* block_var_definition = "const uint buffer_index = BUFFER;\n"
23253 "layout (xfb_buffer = buffer_index, xfb_offset = 0) out Goku {\n"
23256 static const GLchar* global_var_definition = "const uint buffer_index = BUFFER;\n"
23258 "layout (xfb_buffer = buffer_index) out;\n";
23259 static const GLchar* vector_var_definition = "const uint buffer_index = BUFFER;\n"
23261 "layout (xfb_buffer = buffer_index) out vec4 gokuARRAY;\n";
23262 static const GLchar* block_use = " gokuINDEX.member = result / 2;\n";
23263 static const GLchar* global_use = "";
23264 static const GLchar* vector_use = " gokuINDEX = result / 2;\n";
23265 static const GLchar* fs = "#version 430 core\n"
23266 "#extension GL_ARB_enhanced_layouts : require\n"
23269 "out vec4 fs_out;\n"
23273 " fs_out = gs_fs;\n"
23276 static const GLchar* gs_tested = "#version 430 core\n"
23277 "#extension GL_ARB_enhanced_layouts : require\n"
23279 "layout(points) in;\n"
23280 "layout(triangle_strip, max_vertices = 4) out;\n"
23284 "in vec4 tes_gs[];\n"
23285 "out vec4 gs_fs;\n"
23289 " vec4 result = tes_gs[0];\n"
23293 " gs_fs = result;\n"
23294 " gl_Position = vec4(-1, -1, 0, 1);\n"
23296 " gs_fs = result;\n"
23297 " gl_Position = vec4(-1, 1, 0, 1);\n"
23299 " gs_fs = result;\n"
23300 " gl_Position = vec4(1, -1, 0, 1);\n"
23302 " gs_fs = result;\n"
23303 " gl_Position = vec4(1, 1, 0, 1);\n"
23307 static const GLchar* tcs = "#version 430 core\n"
23308 "#extension GL_ARB_enhanced_layouts : require\n"
23310 "layout(vertices = 1) out;\n"
23312 "in vec4 vs_tcs[];\n"
23313 "out vec4 tcs_tes[];\n"
23318 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
23320 " gl_TessLevelOuter[0] = 1.0;\n"
23321 " gl_TessLevelOuter[1] = 1.0;\n"
23322 " gl_TessLevelOuter[2] = 1.0;\n"
23323 " gl_TessLevelOuter[3] = 1.0;\n"
23324 " gl_TessLevelInner[0] = 1.0;\n"
23325 " gl_TessLevelInner[1] = 1.0;\n"
23328 static const GLchar* tcs_tested = "#version 430 core\n"
23329 "#extension GL_ARB_enhanced_layouts : require\n"
23331 "layout(vertices = 1) out;\n"
23335 "in vec4 vs_tcs[];\n"
23336 "out vec4 tcs_tes[];\n"
23340 " vec4 result = vs_tcs[gl_InvocationID];\n"
23344 " tcs_tes[gl_InvocationID] = result;\n"
23346 " gl_TessLevelOuter[0] = 1.0;\n"
23347 " gl_TessLevelOuter[1] = 1.0;\n"
23348 " gl_TessLevelOuter[2] = 1.0;\n"
23349 " gl_TessLevelOuter[3] = 1.0;\n"
23350 " gl_TessLevelInner[0] = 1.0;\n"
23351 " gl_TessLevelInner[1] = 1.0;\n"
23354 static const GLchar* tes_tested = "#version 430 core\n"
23355 "#extension GL_ARB_enhanced_layouts : require\n"
23357 "layout(isolines, point_mode) in;\n"
23361 "in vec4 tcs_tes[];\n"
23362 "out vec4 tes_gs;\n"
23366 " vec4 result = tcs_tes[0];\n"
23370 " tes_gs += result;\n"
23373 static const GLchar* vs = "#version 430 core\n"
23374 "#extension GL_ARB_enhanced_layouts : require\n"
23377 "out vec4 vs_tcs;\n"
23381 " vs_tcs = in_vs;\n"
23384 static const GLchar* vs_tested = "#version 430 core\n"
23385 "#extension GL_ARB_enhanced_layouts : require\n"
23390 "out vec4 vs_tcs;\n"
23394 " vec4 result = in_vs;\n"
23398 " vs_tcs = result;\n"
23402 std::string source;
23403 testCase& test_case = m_test_cases[test_case_index];
23405 if (test_case.m_stage == stage)
23407 const GLchar* array = "";
23409 const Functions& gl = m_context.getRenderContext().getFunctions();
23410 const GLchar* index = "";
23411 GLint max_n_xfb = 0;
23412 size_t position = 0;
23414 const GLchar* var_definition = 0;
23415 const GLchar* var_use = 0;
23417 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_n_xfb);
23418 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
23420 sprintf(buffer, "%d", max_n_xfb);
23422 switch (test_case.m_case)
23425 var_definition = block_var_definition;
23426 var_use = block_use;
23429 var_definition = global_var_definition;
23430 var_use = global_use;
23433 var_definition = vector_var_definition;
23434 var_use = vector_use;
23437 TCU_FAIL("Invalid enum");
23442 case Utils::Shader::GEOMETRY:
23443 source = gs_tested;
23447 case Utils::Shader::TESS_CTRL:
23448 source = tcs_tested;
23450 index = "[gl_InvocationID]";
23452 case Utils::Shader::TESS_EVAL:
23453 source = tes_tested;
23457 case Utils::Shader::VERTEX:
23458 source = vs_tested;
23461 TCU_FAIL("Invalid enum");
23465 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
23467 Utils::replaceToken("BUFFER", position, buffer, source);
23468 if (GLOBAL != test_case.m_case)
23470 Utils::replaceToken("ARRAY", position, array, source);
23472 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
23474 Utils::replaceAllTokens("INDEX", index, source);
23478 switch (test_case.m_stage)
23480 case Utils::Shader::GEOMETRY:
23483 case Utils::Shader::FRAGMENT:
23486 case Utils::Shader::VERTEX:
23493 case Utils::Shader::TESS_CTRL:
23496 case Utils::Shader::FRAGMENT:
23499 case Utils::Shader::VERTEX:
23506 case Utils::Shader::TESS_EVAL:
23509 case Utils::Shader::FRAGMENT:
23512 case Utils::Shader::TESS_CTRL:
23515 case Utils::Shader::VERTEX:
23522 case Utils::Shader::VERTEX:
23525 case Utils::Shader::FRAGMENT:
23533 TCU_FAIL("Invalid enum");
23541 /** Get description of test case
23543 * @param test_case_index Index of test case
23545 * @return Test case description
23547 std::string XFBExceedBufferLimitTest::getTestCaseName(GLuint test_case_index)
23549 std::stringstream stream;
23550 testCase& test_case = m_test_cases[test_case_index];
23552 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", case: ";
23554 switch (test_case.m_case)
23560 stream << "GLOBAL";
23563 stream << "VECTOR";
23566 TCU_FAIL("Invalid enum");
23569 return stream.str();
23572 /** Get number of test cases
23574 * @return Number of test cases
23576 GLuint XFBExceedBufferLimitTest::getTestCaseNumber()
23578 return static_cast<GLuint>(m_test_cases.size());
23581 /** Selects if "compute" stage is relevant for test
23587 bool XFBExceedBufferLimitTest::isComputeRelevant(GLuint /* test_case_index */)
23592 /** Prepare all test cases
23595 void XFBExceedBufferLimitTest::testInit()
23597 for (GLuint c = 0; c < CASE_MAX; ++c)
23599 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
23601 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
23602 (Utils::Shader::FRAGMENT == stage))
23607 testCase test_case = { (CASES)c, (Utils::Shader::STAGES)stage };
23609 m_test_cases.push_back(test_case);
23616 * @param context Test framework context
23618 XFBExceedOffsetLimitTest::XFBExceedOffsetLimitTest(deqp::Context& context)
23619 : NegativeTestBase(context, "xfb_exceed_offset_limit",
23620 "Test verifies that compiler reports error when xfb_offset qualifier exceeds limit")
23624 /** Source for given test case and stage
23626 * @param test_case_index Index of test case
23627 * @param stage Shader stage
23629 * @return Shader source
23631 std::string XFBExceedOffsetLimitTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
23633 static const GLchar* block_var_definition = "const uint max_size = SIZE;\n"
23635 "layout (xfb_buffer = 0, xfb_offset = max_size + 16) out Goku {\n"
23638 static const GLchar* global_var_definition = "const uint max_size = SIZE;\n"
23640 "layout (xfb_buffer = 0, xfb_stride = max_size + 16) out;\n";
23641 static const GLchar* vector_var_definition =
23642 "const uint max_size = SIZE;\n"
23644 "layout (xfb_buffer = 0, xfb_offset = max_size + 16) out vec4 gokuARRAY;\n";
23645 static const GLchar* block_use = " gokuINDEX.member = result / 2;\n";
23646 static const GLchar* global_use = "";
23647 static const GLchar* vector_use = " gokuINDEX = result / 2;\n";
23648 static const GLchar* fs = "#version 430 core\n"
23649 "#extension GL_ARB_enhanced_layouts : require\n"
23652 "out vec4 fs_out;\n"
23656 " fs_out = gs_fs;\n"
23659 static const GLchar* gs_tested = "#version 430 core\n"
23660 "#extension GL_ARB_enhanced_layouts : require\n"
23662 "layout(points) in;\n"
23663 "layout(triangle_strip, max_vertices = 4) out;\n"
23667 "in vec4 tes_gs[];\n"
23668 "out vec4 gs_fs;\n"
23672 " vec4 result = tes_gs[0];\n"
23676 " gs_fs = result;\n"
23677 " gl_Position = vec4(-1, -1, 0, 1);\n"
23679 " gs_fs = result;\n"
23680 " gl_Position = vec4(-1, 1, 0, 1);\n"
23682 " gs_fs = result;\n"
23683 " gl_Position = vec4(1, -1, 0, 1);\n"
23685 " gs_fs = result;\n"
23686 " gl_Position = vec4(1, 1, 0, 1);\n"
23690 static const GLchar* tcs = "#version 430 core\n"
23691 "#extension GL_ARB_enhanced_layouts : require\n"
23693 "layout(vertices = 1) out;\n"
23695 "in vec4 vs_tcs[];\n"
23696 "out vec4 tcs_tes[];\n"
23701 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
23703 " gl_TessLevelOuter[0] = 1.0;\n"
23704 " gl_TessLevelOuter[1] = 1.0;\n"
23705 " gl_TessLevelOuter[2] = 1.0;\n"
23706 " gl_TessLevelOuter[3] = 1.0;\n"
23707 " gl_TessLevelInner[0] = 1.0;\n"
23708 " gl_TessLevelInner[1] = 1.0;\n"
23711 static const GLchar* tcs_tested = "#version 430 core\n"
23712 "#extension GL_ARB_enhanced_layouts : require\n"
23714 "layout(vertices = 1) out;\n"
23718 "in vec4 vs_tcs[];\n"
23719 "out vec4 tcs_tes[];\n"
23723 " vec4 result = vs_tcs[gl_InvocationID];\n"
23727 " tcs_tes[gl_InvocationID] = result;\n"
23729 " gl_TessLevelOuter[0] = 1.0;\n"
23730 " gl_TessLevelOuter[1] = 1.0;\n"
23731 " gl_TessLevelOuter[2] = 1.0;\n"
23732 " gl_TessLevelOuter[3] = 1.0;\n"
23733 " gl_TessLevelInner[0] = 1.0;\n"
23734 " gl_TessLevelInner[1] = 1.0;\n"
23737 static const GLchar* tes_tested = "#version 430 core\n"
23738 "#extension GL_ARB_enhanced_layouts : require\n"
23740 "layout(isolines, point_mode) in;\n"
23744 "in vec4 tcs_tes[];\n"
23745 "out vec4 tes_gs;\n"
23749 " vec4 result = tcs_tes[0];\n"
23753 " tes_gs += result;\n"
23756 static const GLchar* vs = "#version 430 core\n"
23757 "#extension GL_ARB_enhanced_layouts : require\n"
23760 "out vec4 vs_tcs;\n"
23764 " vs_tcs = in_vs;\n"
23767 static const GLchar* vs_tested = "#version 430 core\n"
23768 "#extension GL_ARB_enhanced_layouts : require\n"
23773 "out vec4 vs_tcs;\n"
23777 " vec4 result = in_vs;\n"
23781 " vs_tcs = result;\n"
23785 std::string source;
23786 testCase& test_case = m_test_cases[test_case_index];
23788 if (test_case.m_stage == stage)
23790 const GLchar* array = "";
23792 const Functions& gl = m_context.getRenderContext().getFunctions();
23793 const GLchar* index = "";
23794 GLint max_n_xfb_comp = 0;
23795 GLint max_n_xfb_bytes = 0;
23796 size_t position = 0;
23798 const GLchar* var_definition = 0;
23799 const GLchar* var_use = 0;
23801 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_n_xfb_comp);
23802 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
23804 max_n_xfb_bytes = max_n_xfb_comp * 4;
23806 sprintf(buffer, "%d", max_n_xfb_bytes);
23808 switch (test_case.m_case)
23811 var_definition = block_var_definition;
23812 var_use = block_use;
23815 var_definition = global_var_definition;
23816 var_use = global_use;
23819 var_definition = vector_var_definition;
23820 var_use = vector_use;
23823 TCU_FAIL("Invalid enum");
23825 // It is a compile time error to apply xfb_offset to the declaration of an unsized array(GLSL4.5 spec: Page73)
23826 // change array = "[]" to "[1]"
23829 case Utils::Shader::GEOMETRY:
23830 source = gs_tested;
23834 case Utils::Shader::TESS_CTRL:
23835 source = tcs_tested;
23837 index = "[gl_InvocationID]";
23839 case Utils::Shader::TESS_EVAL:
23840 source = tes_tested;
23844 case Utils::Shader::VERTEX:
23845 source = vs_tested;
23848 TCU_FAIL("Invalid enum");
23852 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
23854 Utils::replaceToken("SIZE", position, buffer, source);
23855 if (GLOBAL != test_case.m_case)
23857 Utils::replaceToken("ARRAY", position, array, source);
23859 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
23861 Utils::replaceAllTokens("INDEX", index, source);
23865 switch (test_case.m_stage)
23867 case Utils::Shader::GEOMETRY:
23870 case Utils::Shader::FRAGMENT:
23873 case Utils::Shader::VERTEX:
23880 case Utils::Shader::TESS_CTRL:
23883 case Utils::Shader::FRAGMENT:
23886 case Utils::Shader::VERTEX:
23893 case Utils::Shader::TESS_EVAL:
23896 case Utils::Shader::FRAGMENT:
23899 case Utils::Shader::TESS_CTRL:
23902 case Utils::Shader::VERTEX:
23909 case Utils::Shader::VERTEX:
23912 case Utils::Shader::FRAGMENT:
23920 TCU_FAIL("Invalid enum");
23928 /** Get description of test case
23930 * @param test_case_index Index of test case
23932 * @return Test case description
23934 std::string XFBExceedOffsetLimitTest::getTestCaseName(GLuint test_case_index)
23936 std::stringstream stream;
23937 testCase& test_case = m_test_cases[test_case_index];
23939 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", case: ";
23941 switch (test_case.m_case)
23947 stream << "GLOBAL";
23950 stream << "VECTOR";
23953 TCU_FAIL("Invalid enum");
23956 return stream.str();
23959 /** Get number of test cases
23961 * @return Number of test cases
23963 GLuint XFBExceedOffsetLimitTest::getTestCaseNumber()
23965 return static_cast<GLuint>(m_test_cases.size());
23968 /** Selects if "compute" stage is relevant for test
23974 bool XFBExceedOffsetLimitTest::isComputeRelevant(GLuint /* test_case_index */)
23979 /** Prepare all test cases
23982 void XFBExceedOffsetLimitTest::testInit()
23984 for (GLuint c = 0; c < CASE_MAX; ++c)
23986 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
23988 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
23989 (Utils::Shader::FRAGMENT == stage))
23994 testCase test_case = { (CASES)c, (Utils::Shader::STAGES)stage };
23996 m_test_cases.push_back(test_case);
24003 * @param context Test context
24005 XFBGlobalBufferTest::XFBGlobalBufferTest(deqp::Context& context)
24006 : BufferTestBase(context, "xfb_global_buffer", "Test verifies that global xfb_buffer qualifier is respected")
24008 /* Nothing to be done here */
24011 /** Get descriptors of buffers necessary for test
24013 * @param test_case_index Index of test case
24014 * @param out_descriptors Descriptors of buffers used by test
24016 void XFBGlobalBufferTest::getBufferDescriptors(glw::GLuint test_case_index, bufferDescriptor::Vector& out_descriptors)
24018 // the function "getType(test_case_index)" can't return correct data type, so change code as following:
24019 const Utils::Type& type = m_test_cases[test_case_index].m_type;
24021 /* Test needs single uniform and two xfbs */
24022 out_descriptors.resize(3);
24024 /* Get references */
24025 bufferDescriptor& uniform = out_descriptors[0];
24026 bufferDescriptor& xfb_1 = out_descriptors[1];
24027 bufferDescriptor& xfb_3 = out_descriptors[2];
24030 uniform.m_index = 0;
24035 uniform.m_target = Utils::Buffer::Uniform;
24036 xfb_1.m_target = Utils::Buffer::Transform_feedback;
24037 xfb_3.m_target = Utils::Buffer::Transform_feedback;
24040 const GLuint gen_start = Utils::s_rand;
24041 const std::vector<GLubyte>& chichi_data = type.GenerateData();
24042 const std::vector<GLubyte>& bulma_data = type.GenerateData();
24043 const std::vector<GLubyte>& trunks_data = type.GenerateData();
24044 const std::vector<GLubyte>& bra_data = type.GenerateData();
24045 const std::vector<GLubyte>& gohan_data = type.GenerateData();
24046 const std::vector<GLubyte>& goten_data = type.GenerateData();
24048 Utils::s_rand = gen_start;
24049 const std::vector<GLubyte>& chichi_data_pck = type.GenerateDataPacked();
24050 const std::vector<GLubyte>& bulma_data_pck = type.GenerateDataPacked();
24051 const std::vector<GLubyte>& trunks_data_pck = type.GenerateDataPacked();
24052 const std::vector<GLubyte>& bra_data_pck = type.GenerateDataPacked();
24053 const std::vector<GLubyte>& gohan_data_pck = type.GenerateDataPacked();
24054 const std::vector<GLubyte>& goten_data_pck = type.GenerateDataPacked();
24056 const GLuint type_size = static_cast<GLuint>(chichi_data.size());
24057 const GLuint type_size_pck = static_cast<GLuint>(chichi_data_pck.size());
24060 uniform.m_initial_data.resize(6 * type_size);
24061 memcpy(&uniform.m_initial_data[0] + 0, &chichi_data[0], type_size);
24062 memcpy(&uniform.m_initial_data[0] + type_size, &bulma_data[0], type_size);
24063 memcpy(&uniform.m_initial_data[0] + 2 * type_size, &trunks_data[0], type_size);
24064 memcpy(&uniform.m_initial_data[0] + 3 * type_size, &bra_data[0], type_size);
24065 memcpy(&uniform.m_initial_data[0] + 4 * type_size, &gohan_data[0], type_size);
24066 memcpy(&uniform.m_initial_data[0] + 5 * type_size, &goten_data[0], type_size);
24069 xfb_1.m_initial_data.resize(3 * type_size_pck);
24070 xfb_1.m_expected_data.resize(3 * type_size_pck);
24071 xfb_3.m_initial_data.resize(3 * type_size_pck);
24072 xfb_3.m_expected_data.resize(3 * type_size_pck);
24074 for (GLuint i = 0; i < 3 * type_size_pck; ++i)
24076 xfb_1.m_initial_data[i] = (glw::GLubyte)i;
24077 xfb_1.m_expected_data[i] = (glw::GLubyte)i;
24078 xfb_3.m_initial_data[i] = (glw::GLubyte)i;
24079 xfb_3.m_expected_data[i] = (glw::GLubyte)i;
24082 memcpy(&xfb_3.m_expected_data[0] + 2 * type_size_pck, &chichi_data_pck[0], type_size_pck);
24083 memcpy(&xfb_1.m_expected_data[0] + 0 * type_size_pck, &bulma_data_pck[0], type_size_pck);
24084 memcpy(&xfb_1.m_expected_data[0] + 1 * type_size_pck, &trunks_data_pck[0], type_size_pck);
24085 memcpy(&xfb_1.m_expected_data[0] + 2 * type_size_pck, &bra_data_pck[0], type_size_pck);
24086 memcpy(&xfb_3.m_expected_data[0] + 0 * type_size_pck, &gohan_data_pck[0], type_size_pck);
24087 memcpy(&xfb_3.m_expected_data[0] + 1 * type_size_pck, &goten_data_pck[0], type_size_pck);
24090 /** Source for given test case and stage
24092 * @param test_case_index Index of test case
24093 * @param stage Shader stage
24095 * @return Shader source
24097 std::string XFBGlobalBufferTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
24099 static const GLchar* fs =
24100 "#version 430 core\n"
24101 "#extension GL_ARB_enhanced_layouts : require\n"
24103 "flat in TYPE chichi;\n"
24104 "flat in TYPE bulma;\n"
24114 "out vec4 fs_out;\n"
24118 " fs_out = vec4(1);\n"
24119 " if (TYPE(1) != chichi + bulma + vegeta.trunk + vegeta.bra + goku.gohan + goku.goten)\n"
24121 " fs_out = vec4(0);\n"
24126 static const GLchar* gs = "#version 430 core\n"
24127 "#extension GL_ARB_enhanced_layouts : require\n"
24129 "layout(points) in;\n"
24130 "layout(points, max_vertices = 1) out;\n"
24141 static const GLchar* tcs = "#version 430 core\n"
24142 "#extension GL_ARB_enhanced_layouts : require\n"
24144 "layout(vertices = 1) out;\n"
24149 " gl_TessLevelOuter[0] = 1.0;\n"
24150 " gl_TessLevelOuter[1] = 1.0;\n"
24151 " gl_TessLevelOuter[2] = 1.0;\n"
24152 " gl_TessLevelOuter[3] = 1.0;\n"
24153 " gl_TessLevelInner[0] = 1.0;\n"
24154 " gl_TessLevelInner[1] = 1.0;\n"
24158 static const GLchar* tes = "#version 430 core\n"
24159 "#extension GL_ARB_enhanced_layouts : require\n"
24161 "layout(isolines, point_mode) in;\n"
24171 static const GLchar* vs = "#version 430 core\n"
24172 "#extension GL_ARB_enhanced_layouts : require\n"
24179 static const GLchar* vs_tested = "#version 430 core\n"
24180 "#extension GL_ARB_enhanced_layouts : require\n"
24190 std::string source;
24191 const _testCase& test_case = m_test_cases[test_case_index];
24192 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
24194 if (test_case.m_stage == stage)
24196 std::string assignments = " chichi = uni_chichi;\n"
24197 " bulma = uni_bulma;\n"
24198 " vegeta.trunk = uni_trunk;\n"
24199 " vegeta.bra = uni_bra;\n"
24200 " goku.gohan = uni_gohan;\n"
24201 " goku.goten = uni_goten;\n";
24203 std::string interface = "layout (xfb_buffer = 3) out;\n"
24205 "const uint type_size = SIZE;\n"
24207 "layout ( xfb_offset = 2 * type_size) flat out TYPE chichi;\n"
24208 "layout (xfb_buffer = 1, xfb_offset = 0) flat out TYPE bulma;\n"
24209 "layout (xfb_buffer = 1, xfb_offset = 1 * type_size) out Vegeta {\n"
24213 "layout ( xfb_offset = 0) out Goku {\n"
24218 // Uniform block must be declared with std140, otherwise each block member is not packed
24219 "layout(binding = 0, std140) uniform block {\n"
24220 " TYPE uni_chichi;\n"
24221 " TYPE uni_bulma;\n"
24222 " TYPE uni_trunk;\n"
24224 " TYPE uni_gohan;\n"
24225 " TYPE uni_goten;\n"
24228 /* Prepare interface string */
24231 size_t position = 0;
24232 const GLuint type_size = test_case.m_type.GetSize();
24234 sprintf(buffer, "%d", type_size);
24236 Utils::replaceToken("SIZE", position, buffer, interface);
24237 Utils::replaceAllTokens("TYPE", type_name, interface);
24242 case Utils::Shader::GEOMETRY:
24245 case Utils::Shader::TESS_EVAL:
24248 case Utils::Shader::VERTEX:
24249 source = vs_tested;
24252 TCU_FAIL("Invalid enum");
24255 /* Replace tokens */
24257 size_t position = 0;
24259 Utils::replaceToken("INTERFACE", position, interface.c_str(), source);
24260 Utils::replaceToken("ASSIGNMENTS", position, assignments.c_str(), source);
24265 switch (test_case.m_stage)
24267 case Utils::Shader::GEOMETRY:
24270 case Utils::Shader::FRAGMENT:
24272 Utils::replaceAllTokens("TYPE", type_name, source);
24274 case Utils::Shader::VERTEX:
24281 case Utils::Shader::TESS_EVAL:
24284 case Utils::Shader::FRAGMENT:
24286 Utils::replaceAllTokens("TYPE", type_name, source);
24288 case Utils::Shader::TESS_CTRL:
24291 case Utils::Shader::VERTEX:
24298 case Utils::Shader::VERTEX:
24301 case Utils::Shader::FRAGMENT:
24303 Utils::replaceAllTokens("TYPE", type_name, source);
24310 TCU_FAIL("Invalid enum");
24318 /** Get name of test case
24320 * @param test_case_index Index of test case
24322 * @return Name of case
24324 std::string XFBGlobalBufferTest::getTestCaseName(GLuint test_case_index)
24327 const _testCase& test_case = m_test_cases[test_case_index];
24329 name = "Tested stage: ";
24330 name.append(Utils::Shader::GetStageName(test_case.m_stage));
24331 name.append(". Tested type: ");
24332 name.append(test_case.m_type.GetGLSLTypeName());
24337 /** Get number of cases
24339 * @return Number of test cases
24341 GLuint XFBGlobalBufferTest::getTestCaseNumber()
24343 return static_cast<GLuint>(m_test_cases.size());
24346 /** Prepare set of test cases
24349 void XFBGlobalBufferTest::testInit()
24351 GLuint n_types = getTypesNumber();
24353 for (GLuint i = 0; i < n_types; ++i)
24355 const Utils::Type& type = getType(i);
24357 When the tfx varying is the following type, the number of output exceeds the gl_MaxVaryingComponents, which will
24358 cause a link time error.
24360 if (strcmp(type.GetGLSLTypeName(), "dmat3") == 0 || strcmp(type.GetGLSLTypeName(), "dmat4") == 0 ||
24361 strcmp(type.GetGLSLTypeName(), "dmat3x4") == 0 || strcmp(type.GetGLSLTypeName(), "dmat4x3") == 0)
24365 const _testCase test_cases[] = { { Utils::Shader::VERTEX, type },
24366 { Utils::Shader::GEOMETRY, type },
24367 { Utils::Shader::TESS_EVAL, type } };
24369 m_test_cases.push_back(test_cases[0]);
24370 m_test_cases.push_back(test_cases[1]);
24371 m_test_cases.push_back(test_cases[2]);
24377 * @param context Test context
24379 XFBStrideTest::XFBStrideTest(deqp::Context& context)
24380 : BufferTestBase(context, "xfb_stride", "Test verifies that correct stride is used for all types")
24382 /* Nothing to be done here */
24385 /** Execute drawArrays for single vertex
24387 * @param test_case_index
24391 bool XFBStrideTest::executeDrawCall(GLuint test_case_index)
24393 const Functions& gl = m_context.getRenderContext().getFunctions();
24394 GLenum primitive_type = GL_PATCHES;
24395 const testCase& test_case = m_test_cases[test_case_index];
24397 if (Utils::Shader::VERTEX == test_case.m_stage)
24399 primitive_type = GL_POINTS;
24402 gl.disable(GL_RASTERIZER_DISCARD);
24403 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
24405 gl.beginTransformFeedback(GL_POINTS);
24406 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
24408 gl.drawArrays(primitive_type, 0 /* first */, 2 /* count */);
24409 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
24411 gl.endTransformFeedback();
24412 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
24417 /** Get descriptors of buffers necessary for test
24419 * @param test_case_index Index of test case
24420 * @param out_descriptors Descriptors of buffers used by test
24422 void XFBStrideTest::getBufferDescriptors(GLuint test_case_index, bufferDescriptor::Vector& out_descriptors)
24424 const testCase& test_case = m_test_cases[test_case_index];
24425 const Utils::Type& type = test_case.m_type;
24427 /* Test needs single uniform and xfb */
24428 out_descriptors.resize(2);
24430 /* Get references */
24431 bufferDescriptor& uniform = out_descriptors[0];
24432 bufferDescriptor& xfb = out_descriptors[1];
24435 uniform.m_index = 0;
24439 uniform.m_target = Utils::Buffer::Uniform;
24440 xfb.m_target = Utils::Buffer::Transform_feedback;
24443 const GLuint rand_start = Utils::s_rand;
24444 const std::vector<GLubyte>& uniform_data = type.GenerateData();
24446 Utils::s_rand = rand_start;
24447 const std::vector<GLubyte>& xfb_data = type.GenerateDataPacked();
24449 const GLuint uni_type_size = static_cast<GLuint>(uniform_data.size());
24450 const GLuint xfb_type_size = static_cast<GLuint>(xfb_data.size());
24452 Note: If xfb varying output from vertex shader, the variable "goku" will only output once to transform feedback buffer,
24453 if xfb varying output from TES or GS, because the input primitive type in TES is defined as "layout(isolines, point_mode) in;",
24454 the primitive type is line which make the variable "goku" will output twice to transform feedback buffer, so for vertex shader
24455 only one valid data should be initialized in xfb.m_expected_data
24457 const GLuint xfb_data_size = (test_case.m_stage == Utils::Shader::VERTEX) ? xfb_type_size : xfb_type_size * 2;
24459 uniform.m_initial_data.resize(uni_type_size);
24460 memcpy(&uniform.m_initial_data[0] + 0 * uni_type_size, &uniform_data[0], uni_type_size);
24463 xfb.m_initial_data.resize(xfb_data_size);
24464 xfb.m_expected_data.resize(xfb_data_size);
24466 for (GLuint i = 0; i < xfb_data_size; ++i)
24468 xfb.m_initial_data[i] = (glw::GLubyte)i;
24469 xfb.m_expected_data[i] = (glw::GLubyte)i;
24472 if (test_case.m_stage == Utils::Shader::VERTEX)
24474 memcpy(&xfb.m_expected_data[0] + 0 * xfb_type_size, &xfb_data[0], xfb_type_size);
24478 memcpy(&xfb.m_expected_data[0] + 0 * xfb_type_size, &xfb_data[0], xfb_type_size);
24479 memcpy(&xfb.m_expected_data[0] + 1 * xfb_type_size, &xfb_data[0], xfb_type_size);
24483 /** Get body of main function for given shader stage
24485 * @param test_case_index Index of test case
24486 * @param stage Shader stage
24487 * @param out_assignments Set to empty
24488 * @param out_calculations Set to empty
24490 void XFBStrideTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage, std::string& out_assignments,
24491 std::string& out_calculations)
24493 const testCase& test_case = m_test_cases[test_case_index];
24495 out_calculations = "";
24497 static const GLchar* vs_tes_gs = " goku = uni_goku;\n";
24498 static const GLchar* fs = " fs_out = vec4(1, 0.25, 0.5, 0.75);\n"
24499 " if (TYPE(0) == goku)\n"
24501 " fs_out = vec4(1, 0.75, 0.5, 0.5);\n"
24504 const GLchar* assignments = "";
24506 if (test_case.m_stage == stage)
24510 case Utils::Shader::GEOMETRY:
24511 assignments = vs_tes_gs;
24513 case Utils::Shader::TESS_EVAL:
24514 assignments = vs_tes_gs;
24516 case Utils::Shader::VERTEX:
24517 assignments = vs_tes_gs;
24520 TCU_FAIL("Invalid enum");
24527 case Utils::Shader::FRAGMENT:
24530 case Utils::Shader::GEOMETRY:
24531 case Utils::Shader::TESS_CTRL:
24532 case Utils::Shader::TESS_EVAL:
24533 case Utils::Shader::VERTEX:
24536 TCU_FAIL("Invalid enum");
24540 out_assignments = assignments;
24542 if (Utils::Shader::FRAGMENT == stage)
24544 Utils::replaceAllTokens("TYPE", test_case.m_type.GetGLSLTypeName(), out_assignments);
24548 /** Get interface of shader
24550 * @param test_case_index Index of test case
24551 * @param stage Shader stage
24552 * @param out_interface Set to ""
24554 void XFBStrideTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage, std::string& out_interface)
24556 static const GLchar* vs_tes_gs = "layout (xfb_offset = 0) FLAT out TYPE goku;\n"
24558 "layout(std140, binding = 0) uniform Goku {\n"
24559 " TYPE uni_goku;\n"
24561 static const GLchar* fs = "FLAT in TYPE goku;\n"
24563 "out vec4 fs_out;\n";
24565 const testCase& test_case = m_test_cases[test_case_index];
24566 const GLchar* interface = "";
24567 const GLchar* flat = "";
24569 if (test_case.m_stage == stage)
24573 case Utils::Shader::GEOMETRY:
24574 interface = vs_tes_gs;
24576 case Utils::Shader::TESS_EVAL:
24577 interface = vs_tes_gs;
24579 case Utils::Shader::VERTEX:
24580 interface = vs_tes_gs;
24583 TCU_FAIL("Invalid enum");
24590 case Utils::Shader::FRAGMENT:
24593 case Utils::Shader::GEOMETRY:
24594 case Utils::Shader::TESS_CTRL:
24595 case Utils::Shader::TESS_EVAL:
24596 case Utils::Shader::VERTEX:
24599 TCU_FAIL("Invalid enum");
24603 out_interface = interface;
24605 if (Utils::Type::Float != test_case.m_type.m_basic_type)
24610 Utils::replaceAllTokens("FLAT", flat, out_interface);
24611 Utils::replaceAllTokens("TYPE", test_case.m_type.GetGLSLTypeName(), out_interface);
24614 /** Get source code of shader
24616 * @param test_case_index Index of test case
24617 * @param stage Shader stage
24621 std::string XFBStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
24623 std::string source;
24624 const testCase& test_case = m_test_cases[test_case_index];
24626 switch (test_case.m_stage)
24628 case Utils::Shader::VERTEX:
24631 case Utils::Shader::FRAGMENT:
24632 case Utils::Shader::VERTEX:
24633 source = BufferTestBase::getShaderSource(test_case_index, stage);
24640 case Utils::Shader::TESS_EVAL:
24643 case Utils::Shader::FRAGMENT:
24644 case Utils::Shader::TESS_CTRL:
24645 case Utils::Shader::TESS_EVAL:
24646 case Utils::Shader::VERTEX:
24647 source = BufferTestBase::getShaderSource(test_case_index, stage);
24654 case Utils::Shader::GEOMETRY:
24655 source = BufferTestBase::getShaderSource(test_case_index, stage);
24659 TCU_FAIL("Invalid enum");
24667 /** Get name of test case
24669 * @param test_case_index Index of test case
24671 * @return Name of tested stage
24673 std::string XFBStrideTest::getTestCaseName(glw::GLuint test_case_index)
24675 std::stringstream stream;
24676 const testCase& test_case = m_test_cases[test_case_index];
24678 stream << "Type: " << test_case.m_type.GetGLSLTypeName()
24679 << ", stage: " << Utils::Shader::GetStageName(test_case.m_stage);
24681 return stream.str();
24684 /** Returns number of test cases
24688 glw::GLuint XFBStrideTest::getTestCaseNumber()
24690 return static_cast<GLuint>(m_test_cases.size());
24693 /** Prepare all test cases
24696 void XFBStrideTest::testInit()
24698 const GLuint n_types = getTypesNumber();
24700 for (GLuint i = 0; i < n_types; ++i)
24702 const Utils::Type& type = getType(i);
24704 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
24706 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::FRAGMENT == stage) ||
24707 (Utils::Shader::TESS_CTRL == stage))
24712 testCase test_case = { (Utils::Shader::STAGES)stage, type };
24714 m_test_cases.push_back(test_case);
24721 * @param context Test framework context
24723 XFBBlockMemberBufferTest::XFBBlockMemberBufferTest(deqp::Context& context)
24724 : NegativeTestBase(
24725 context, "xfb_block_member_buffer",
24726 "Test verifies that compiler reports error when block member has different xfb_buffer qualifier than buffer")
24730 /** Source for given test case and stage
24732 * @param test_case_index Index of test case
24733 * @param stage Shader stage
24735 * @return Shader source
24737 std::string XFBBlockMemberBufferTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
24739 static const GLchar* var_definition = "layout (xfb_offset = 0) out Goku {\n"
24741 " layout (xfb_buffer = 1) vec4 goten;\n"
24743 static const GLchar* var_use = " gokuINDEX.gohan = result / 2;\n"
24744 " gokuINDEX.goten = result / 4;\n";
24745 static const GLchar* fs = "#version 430 core\n"
24746 "#extension GL_ARB_enhanced_layouts : require\n"
24749 "out vec4 fs_out;\n"
24753 " fs_out = gs_fs;\n"
24756 static const GLchar* gs_tested = "#version 430 core\n"
24757 "#extension GL_ARB_enhanced_layouts : require\n"
24759 "layout(points) in;\n"
24760 "layout(triangle_strip, max_vertices = 4) out;\n"
24764 "in vec4 tes_gs[];\n"
24765 "out vec4 gs_fs;\n"
24769 " vec4 result = tes_gs[0];\n"
24773 " gs_fs = result;\n"
24774 " gl_Position = vec4(-1, -1, 0, 1);\n"
24776 " gs_fs = result;\n"
24777 " gl_Position = vec4(-1, 1, 0, 1);\n"
24779 " gs_fs = result;\n"
24780 " gl_Position = vec4(1, -1, 0, 1);\n"
24782 " gs_fs = result;\n"
24783 " gl_Position = vec4(1, 1, 0, 1);\n"
24787 static const GLchar* tcs = "#version 430 core\n"
24788 "#extension GL_ARB_enhanced_layouts : require\n"
24790 "layout(vertices = 1) out;\n"
24792 "in vec4 vs_tcs[];\n"
24793 "out vec4 tcs_tes[];\n"
24798 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
24800 " gl_TessLevelOuter[0] = 1.0;\n"
24801 " gl_TessLevelOuter[1] = 1.0;\n"
24802 " gl_TessLevelOuter[2] = 1.0;\n"
24803 " gl_TessLevelOuter[3] = 1.0;\n"
24804 " gl_TessLevelInner[0] = 1.0;\n"
24805 " gl_TessLevelInner[1] = 1.0;\n"
24808 static const GLchar* tcs_tested = "#version 430 core\n"
24809 "#extension GL_ARB_enhanced_layouts : require\n"
24811 "layout(vertices = 1) out;\n"
24815 "in vec4 vs_tcs[];\n"
24816 "out vec4 tcs_tes[];\n"
24820 " vec4 result = vs_tcs[gl_InvocationID];\n"
24824 " tcs_tes[gl_InvocationID] = result;\n"
24826 " gl_TessLevelOuter[0] = 1.0;\n"
24827 " gl_TessLevelOuter[1] = 1.0;\n"
24828 " gl_TessLevelOuter[2] = 1.0;\n"
24829 " gl_TessLevelOuter[3] = 1.0;\n"
24830 " gl_TessLevelInner[0] = 1.0;\n"
24831 " gl_TessLevelInner[1] = 1.0;\n"
24834 static const GLchar* tes_tested = "#version 430 core\n"
24835 "#extension GL_ARB_enhanced_layouts : require\n"
24837 "layout(isolines, point_mode) in;\n"
24841 "in vec4 tcs_tes[];\n"
24842 "out vec4 tes_gs;\n"
24846 " vec4 result = tcs_tes[0];\n"
24850 " tes_gs += result;\n"
24853 static const GLchar* vs = "#version 430 core\n"
24854 "#extension GL_ARB_enhanced_layouts : require\n"
24857 "out vec4 vs_tcs;\n"
24861 " vs_tcs = in_vs;\n"
24864 static const GLchar* vs_tested = "#version 430 core\n"
24865 "#extension GL_ARB_enhanced_layouts : require\n"
24870 "out vec4 vs_tcs;\n"
24874 " vec4 result = in_vs;\n"
24878 " vs_tcs = result;\n"
24882 std::string source;
24883 testCase& test_case = m_test_cases[test_case_index];
24885 if (test_case.m_stage == stage)
24887 const GLchar* array = "";
24888 const GLchar* index = "";
24889 size_t position = 0;
24893 case Utils::Shader::GEOMETRY:
24894 source = gs_tested;
24898 case Utils::Shader::TESS_CTRL:
24899 source = tcs_tested;
24901 index = "[gl_InvocationID]";
24903 case Utils::Shader::TESS_EVAL:
24904 source = tes_tested;
24908 case Utils::Shader::VERTEX:
24909 source = vs_tested;
24912 TCU_FAIL("Invalid enum");
24915 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
24917 Utils::replaceToken("ARRAY", position, array, source);
24918 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
24920 Utils::replaceAllTokens("INDEX", index, source);
24924 switch (test_case.m_stage)
24926 case Utils::Shader::GEOMETRY:
24929 case Utils::Shader::FRAGMENT:
24932 case Utils::Shader::VERTEX:
24939 case Utils::Shader::TESS_CTRL:
24942 case Utils::Shader::FRAGMENT:
24945 case Utils::Shader::VERTEX:
24952 case Utils::Shader::TESS_EVAL:
24955 case Utils::Shader::FRAGMENT:
24958 case Utils::Shader::TESS_CTRL:
24961 case Utils::Shader::VERTEX:
24968 case Utils::Shader::VERTEX:
24971 case Utils::Shader::FRAGMENT:
24979 TCU_FAIL("Invalid enum");
24987 /** Get description of test case
24989 * @param test_case_index Index of test case
24991 * @return Test case description
24993 std::string XFBBlockMemberBufferTest::getTestCaseName(GLuint test_case_index)
24995 std::stringstream stream;
24996 testCase& test_case = m_test_cases[test_case_index];
24998 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage);
25000 return stream.str();
25003 /** Get number of test cases
25005 * @return Number of test cases
25007 GLuint XFBBlockMemberBufferTest::getTestCaseNumber()
25009 return static_cast<GLuint>(m_test_cases.size());
25012 /** Selects if "compute" stage is relevant for test
25018 bool XFBBlockMemberBufferTest::isComputeRelevant(GLuint /* test_case_index */)
25023 /** Prepare all test cases
25026 void XFBBlockMemberBufferTest::testInit()
25028 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
25030 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
25031 (Utils::Shader::FRAGMENT == stage))
25036 testCase test_case = { (Utils::Shader::STAGES)stage };
25038 m_test_cases.push_back(test_case);
25044 * @param context Test framework context
25046 XFBOutputOverlappingTest::XFBOutputOverlappingTest(deqp::Context& context)
25047 : NegativeTestBase(context, "xfb_output_overlapping",
25048 "Test verifies that compiler reports error when two xfb qualified outputs overlap")
25052 /** Source for given test case and stage
25054 * @param test_case_index Index of test case
25055 * @param stage Shader stage
25057 * @return Shader source
25059 std::string XFBOutputOverlappingTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
25061 static const GLchar* var_definition = "layout (xfb_offset = OFFSET) out TYPE gohanARRAY;\n"
25062 "layout (xfb_offset = OFFSET) out TYPE gotenARRAY;\n";
25063 static const GLchar* var_use = " gohanINDEX = TYPE(0);\n"
25064 " gotenINDEX = TYPE(1);\n"
25065 " if (vec4(0) == result)\n"
25067 " gohanINDEX = TYPE(1);\n"
25068 " gotenINDEX = TYPE(0);\n"
25070 static const GLchar* fs = "#version 430 core\n"
25071 "#extension GL_ARB_enhanced_layouts : require\n"
25074 "out vec4 fs_out;\n"
25078 " fs_out = gs_fs;\n"
25081 static const GLchar* gs_tested = "#version 430 core\n"
25082 "#extension GL_ARB_enhanced_layouts : require\n"
25084 "layout(points) in;\n"
25085 "layout(triangle_strip, max_vertices = 4) out;\n"
25089 "in vec4 tes_gs[];\n"
25090 "out vec4 gs_fs;\n"
25094 " vec4 result = tes_gs[0];\n"
25098 " gs_fs = result;\n"
25099 " gl_Position = vec4(-1, -1, 0, 1);\n"
25101 " gs_fs = result;\n"
25102 " gl_Position = vec4(-1, 1, 0, 1);\n"
25104 " gs_fs = result;\n"
25105 " gl_Position = vec4(1, -1, 0, 1);\n"
25107 " gs_fs = result;\n"
25108 " gl_Position = vec4(1, 1, 0, 1);\n"
25112 static const GLchar* tcs = "#version 430 core\n"
25113 "#extension GL_ARB_enhanced_layouts : require\n"
25115 "layout(vertices = 1) out;\n"
25117 "in vec4 vs_tcs[];\n"
25118 "out vec4 tcs_tes[];\n"
25123 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
25125 " gl_TessLevelOuter[0] = 1.0;\n"
25126 " gl_TessLevelOuter[1] = 1.0;\n"
25127 " gl_TessLevelOuter[2] = 1.0;\n"
25128 " gl_TessLevelOuter[3] = 1.0;\n"
25129 " gl_TessLevelInner[0] = 1.0;\n"
25130 " gl_TessLevelInner[1] = 1.0;\n"
25133 static const GLchar* tcs_tested = "#version 430 core\n"
25134 "#extension GL_ARB_enhanced_layouts : require\n"
25136 "layout(vertices = 1) out;\n"
25140 "in vec4 vs_tcs[];\n"
25141 "out vec4 tcs_tes[];\n"
25145 " vec4 result = vs_tcs[gl_InvocationID];\n"
25149 " tcs_tes[gl_InvocationID] = result;\n"
25151 " gl_TessLevelOuter[0] = 1.0;\n"
25152 " gl_TessLevelOuter[1] = 1.0;\n"
25153 " gl_TessLevelOuter[2] = 1.0;\n"
25154 " gl_TessLevelOuter[3] = 1.0;\n"
25155 " gl_TessLevelInner[0] = 1.0;\n"
25156 " gl_TessLevelInner[1] = 1.0;\n"
25159 static const GLchar* tes_tested = "#version 430 core\n"
25160 "#extension GL_ARB_enhanced_layouts : require\n"
25162 "layout(isolines, point_mode) in;\n"
25166 "in vec4 tcs_tes[];\n"
25167 "out vec4 tes_gs;\n"
25171 " vec4 result = tcs_tes[0];\n"
25175 " tes_gs += result;\n"
25178 static const GLchar* vs = "#version 430 core\n"
25179 "#extension GL_ARB_enhanced_layouts : require\n"
25182 "out vec4 vs_tcs;\n"
25186 " vs_tcs = in_vs;\n"
25189 static const GLchar* vs_tested = "#version 430 core\n"
25190 "#extension GL_ARB_enhanced_layouts : require\n"
25195 "out vec4 vs_tcs;\n"
25199 " vec4 result = in_vs;\n"
25203 " vs_tcs = result;\n"
25207 std::string source;
25208 testCase& test_case = m_test_cases[test_case_index];
25210 if (test_case.m_stage == stage)
25212 const GLchar* array = "";
25213 GLchar buffer_gohan[16];
25214 GLchar buffer_goten[16];
25215 const GLchar* index = "";
25216 size_t position = 0;
25217 size_t position_start = 0;
25218 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
25220 sprintf(buffer_gohan, "%d", test_case.m_offset_gohan);
25221 sprintf(buffer_goten, "%d", test_case.m_offset_goten);
25225 case Utils::Shader::GEOMETRY:
25226 source = gs_tested;
25230 case Utils::Shader::TESS_CTRL:
25231 source = tcs_tested;
25233 index = "[gl_InvocationID]";
25235 case Utils::Shader::TESS_EVAL:
25236 source = tes_tested;
25240 case Utils::Shader::VERTEX:
25241 source = vs_tested;
25244 TCU_FAIL("Invalid enum");
25247 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
25249 Utils::replaceToken("OFFSET", position, buffer_gohan, source);
25250 Utils::replaceToken("TYPE", position, type_name, source);
25251 Utils::replaceToken("ARRAY", position, array, source);
25252 Utils::replaceToken("OFFSET", position, buffer_goten, source);
25253 Utils::replaceToken("TYPE", position, type_name, source);
25254 Utils::replaceToken("ARRAY", position, array, source);
25255 position_start = position;
25256 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
25257 position = position_start;
25258 Utils::replaceToken("INDEX", position, index, source);
25259 Utils::replaceToken("TYPE", position, type_name, source);
25260 Utils::replaceToken("INDEX", position, index, source);
25261 Utils::replaceToken("TYPE", position, type_name, source);
25262 Utils::replaceToken("INDEX", position, index, source);
25263 Utils::replaceToken("TYPE", position, type_name, source);
25264 Utils::replaceToken("INDEX", position, index, source);
25265 Utils::replaceToken("TYPE", position, type_name, source);
25269 switch (test_case.m_stage)
25271 case Utils::Shader::GEOMETRY:
25274 case Utils::Shader::FRAGMENT:
25277 case Utils::Shader::VERTEX:
25284 case Utils::Shader::TESS_CTRL:
25287 case Utils::Shader::FRAGMENT:
25290 case Utils::Shader::VERTEX:
25297 case Utils::Shader::TESS_EVAL:
25300 case Utils::Shader::FRAGMENT:
25303 case Utils::Shader::TESS_CTRL:
25306 case Utils::Shader::VERTEX:
25313 case Utils::Shader::VERTEX:
25316 case Utils::Shader::FRAGMENT:
25324 TCU_FAIL("Invalid enum");
25332 /** Get description of test case
25334 * @param test_case_index Index of test case
25336 * @return Test case description
25338 std::string XFBOutputOverlappingTest::getTestCaseName(GLuint test_case_index)
25340 std::stringstream stream;
25341 testCase& test_case = m_test_cases[test_case_index];
25343 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
25344 << ", type: " << test_case.m_type.GetGLSLTypeName() << ", offsets: " << test_case.m_offset_gohan << " & "
25345 << test_case.m_offset_goten;
25347 return stream.str();
25350 /** Get number of test cases
25352 * @return Number of test cases
25354 GLuint XFBOutputOverlappingTest::getTestCaseNumber()
25356 return static_cast<GLuint>(m_test_cases.size());
25359 /** Selects if "compute" stage is relevant for test
25365 bool XFBOutputOverlappingTest::isComputeRelevant(GLuint /* test_case_index */)
25370 /** Prepare all test cases
25373 void XFBOutputOverlappingTest::testInit()
25375 const GLuint n_types = getTypesNumber();
25377 for (GLuint i = 0; i < n_types; ++i)
25379 const Utils::Type& type = getType(i);
25380 const GLuint base_alingment = Utils::Type::GetTypeSize(type.m_basic_type);
25382 /* Skip scalars, not applicable as:
25384 * The offset must be a multiple of the size of the first component of the first
25385 * qualified variable or block member, or a compile-time error results.
25387 if ((1 == type.m_n_columns) && (1 == type.m_n_rows))
25392 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
25394 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
25395 (Utils::Shader::FRAGMENT == stage))
25400 testCase test_case = { 0 /* gohan offset */, base_alingment /* goten_offset */,
25401 (Utils::Shader::STAGES)stage, type };
25403 m_test_cases.push_back(test_case);
25410 * @param context Test framework context
25412 XFBInvalidOffsetAlignmentTest::XFBInvalidOffsetAlignmentTest(deqp::Context& context)
25413 : NegativeTestBase(context, "xfb_invalid_offset_alignment",
25414 "Test verifies that compiler reports error when xfb_offset has invalid alignment")
25418 /** Source for given test case and stage
25420 * @param test_case_index Index of test case
25421 * @param stage Shader stage
25423 * @return Shader source
25425 std::string XFBInvalidOffsetAlignmentTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
25427 static const GLchar* var_definition = "layout (xfb_offset = OFFSET) out TYPE gohanARRAY;\n";
25428 static const GLchar* var_use = " gohanINDEX = TYPE(0);\n"
25429 " if (vec4(0) == result)\n"
25431 " gohanINDEX = TYPE(1);\n"
25433 static const GLchar* fs = "#version 430 core\n"
25434 "#extension GL_ARB_enhanced_layouts : require\n"
25437 "out vec4 fs_out;\n"
25441 " fs_out = gs_fs;\n"
25444 static const GLchar* gs_tested = "#version 430 core\n"
25445 "#extension GL_ARB_enhanced_layouts : require\n"
25447 "layout(points) in;\n"
25448 "layout(triangle_strip, max_vertices = 4) out;\n"
25452 "in vec4 tes_gs[];\n"
25453 "out vec4 gs_fs;\n"
25457 " vec4 result = tes_gs[0];\n"
25461 " gs_fs = result;\n"
25462 " gl_Position = vec4(-1, -1, 0, 1);\n"
25464 " gs_fs = result;\n"
25465 " gl_Position = vec4(-1, 1, 0, 1);\n"
25467 " gs_fs = result;\n"
25468 " gl_Position = vec4(1, -1, 0, 1);\n"
25470 " gs_fs = result;\n"
25471 " gl_Position = vec4(1, 1, 0, 1);\n"
25475 static const GLchar* tcs = "#version 430 core\n"
25476 "#extension GL_ARB_enhanced_layouts : require\n"
25478 "layout(vertices = 1) out;\n"
25480 "in vec4 vs_tcs[];\n"
25481 "out vec4 tcs_tes[];\n"
25486 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
25488 " gl_TessLevelOuter[0] = 1.0;\n"
25489 " gl_TessLevelOuter[1] = 1.0;\n"
25490 " gl_TessLevelOuter[2] = 1.0;\n"
25491 " gl_TessLevelOuter[3] = 1.0;\n"
25492 " gl_TessLevelInner[0] = 1.0;\n"
25493 " gl_TessLevelInner[1] = 1.0;\n"
25496 static const GLchar* tcs_tested = "#version 430 core\n"
25497 "#extension GL_ARB_enhanced_layouts : require\n"
25499 "layout(vertices = 1) out;\n"
25503 "in vec4 vs_tcs[];\n"
25504 "out vec4 tcs_tes[];\n"
25508 " vec4 result = vs_tcs[gl_InvocationID];\n"
25512 " tcs_tes[gl_InvocationID] = result;\n"
25514 " gl_TessLevelOuter[0] = 1.0;\n"
25515 " gl_TessLevelOuter[1] = 1.0;\n"
25516 " gl_TessLevelOuter[2] = 1.0;\n"
25517 " gl_TessLevelOuter[3] = 1.0;\n"
25518 " gl_TessLevelInner[0] = 1.0;\n"
25519 " gl_TessLevelInner[1] = 1.0;\n"
25522 static const GLchar* tes_tested = "#version 430 core\n"
25523 "#extension GL_ARB_enhanced_layouts : require\n"
25525 "layout(isolines, point_mode) in;\n"
25529 "in vec4 tcs_tes[];\n"
25530 "out vec4 tes_gs;\n"
25534 " vec4 result = tcs_tes[0];\n"
25538 " tes_gs += result;\n"
25541 static const GLchar* vs = "#version 430 core\n"
25542 "#extension GL_ARB_enhanced_layouts : require\n"
25545 "out vec4 vs_tcs;\n"
25549 " vs_tcs = in_vs;\n"
25552 static const GLchar* vs_tested = "#version 430 core\n"
25553 "#extension GL_ARB_enhanced_layouts : require\n"
25558 "out vec4 vs_tcs;\n"
25562 " vec4 result = in_vs;\n"
25566 " vs_tcs = result;\n"
25570 std::string source;
25571 testCase& test_case = m_test_cases[test_case_index];
25573 if (test_case.m_stage == stage)
25575 const GLchar* array = "";
25577 const GLchar* index = "";
25578 size_t position = 0;
25579 size_t position_start = 0;
25580 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
25582 sprintf(buffer, "%d", test_case.m_offset);
25586 case Utils::Shader::GEOMETRY:
25587 source = gs_tested;
25591 case Utils::Shader::TESS_CTRL:
25592 source = tcs_tested;
25594 index = "[gl_InvocationID]";
25596 case Utils::Shader::TESS_EVAL:
25597 source = tes_tested;
25601 case Utils::Shader::VERTEX:
25602 source = vs_tested;
25605 TCU_FAIL("Invalid enum");
25608 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
25610 Utils::replaceToken("OFFSET", position, buffer, source);
25611 Utils::replaceToken("TYPE", position, type_name, source);
25612 Utils::replaceToken("ARRAY", position, array, source);
25613 position_start = position;
25614 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
25615 position = position_start;
25616 Utils::replaceToken("INDEX", position, index, source);
25617 Utils::replaceToken("TYPE", position, type_name, source);
25618 Utils::replaceToken("INDEX", position, index, source);
25619 Utils::replaceToken("TYPE", position, type_name, source);
25623 switch (test_case.m_stage)
25625 case Utils::Shader::GEOMETRY:
25628 case Utils::Shader::FRAGMENT:
25631 case Utils::Shader::VERTEX:
25638 case Utils::Shader::TESS_CTRL:
25641 case Utils::Shader::FRAGMENT:
25644 case Utils::Shader::VERTEX:
25651 case Utils::Shader::TESS_EVAL:
25654 case Utils::Shader::FRAGMENT:
25657 case Utils::Shader::TESS_CTRL:
25660 case Utils::Shader::VERTEX:
25667 case Utils::Shader::VERTEX:
25670 case Utils::Shader::FRAGMENT:
25678 TCU_FAIL("Invalid enum");
25686 /** Get description of test case
25688 * @param test_case_index Index of test case
25690 * @return Test case description
25692 std::string XFBInvalidOffsetAlignmentTest::getTestCaseName(GLuint test_case_index)
25694 std::stringstream stream;
25695 testCase& test_case = m_test_cases[test_case_index];
25697 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
25698 << ", type: " << test_case.m_type.GetGLSLTypeName() << ", offset: " << test_case.m_offset;
25700 return stream.str();
25703 /** Get number of test cases
25705 * @return Number of test cases
25707 GLuint XFBInvalidOffsetAlignmentTest::getTestCaseNumber()
25709 return static_cast<GLuint>(m_test_cases.size());
25712 /** Selects if "compute" stage is relevant for test
25718 bool XFBInvalidOffsetAlignmentTest::isComputeRelevant(GLuint /* test_case_index */)
25723 /** Prepare all test cases
25726 void XFBInvalidOffsetAlignmentTest::testInit()
25728 const GLuint n_types = getTypesNumber();
25730 for (GLuint i = 0; i < n_types; ++i)
25732 const Utils::Type& type = getType(i);
25733 const GLuint base_alingment = Utils::Type::GetTypeSize(type.m_basic_type);
25735 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
25737 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
25738 (Utils::Shader::FRAGMENT == stage))
25743 for (GLuint offset = base_alingment + 1; offset < 2 * base_alingment; ++offset)
25745 testCase test_case = { offset, (Utils::Shader::STAGES)stage, type };
25747 m_test_cases.push_back(test_case);
25755 * @param context Test context
25757 XFBCaptureInactiveOutputVariableTest::XFBCaptureInactiveOutputVariableTest(deqp::Context& context)
25758 : BufferTestBase(context, "xfb_capture_inactive_output_variable",
25759 "Test verifies that inactive variables are captured")
25761 /* Nothing to be done here */
25764 /** Execute drawArrays for single vertex
25766 * @param test_case_index
25770 bool XFBCaptureInactiveOutputVariableTest::executeDrawCall(GLuint test_case_index)
25772 const Functions& gl = m_context.getRenderContext().getFunctions();
25773 GLenum primitive_type = GL_PATCHES;
25775 if (TEST_VS == test_case_index)
25777 primitive_type = GL_POINTS;
25780 gl.disable(GL_RASTERIZER_DISCARD);
25781 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
25783 gl.beginTransformFeedback(GL_POINTS);
25784 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
25786 gl.drawArrays(primitive_type, 0 /* first */, 1 /* count */);
25787 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
25789 gl.endTransformFeedback();
25790 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
25795 /** Get descriptors of buffers necessary for test
25798 * @param out_descriptors Descriptors of buffers used by test
25800 void XFBCaptureInactiveOutputVariableTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
25801 bufferDescriptor::Vector& out_descriptors)
25803 const Utils::Type& type = Utils::Type::vec4;
25805 /* Test needs single uniform and xfb */
25806 out_descriptors.resize(2);
25808 /* Get references */
25809 bufferDescriptor& uniform = out_descriptors[0];
25810 bufferDescriptor& xfb = out_descriptors[1];
25813 uniform.m_index = 0;
25817 uniform.m_target = Utils::Buffer::Uniform;
25818 xfb.m_target = Utils::Buffer::Transform_feedback;
25821 const std::vector<GLubyte>& gohan_data = type.GenerateData();
25822 const std::vector<GLubyte>& goten_data = type.GenerateData();
25824 const GLuint type_size = static_cast<GLuint>(gohan_data.size());
25827 uniform.m_initial_data.resize(2 * type_size);
25828 memcpy(&uniform.m_initial_data[0] + 0, &gohan_data[0], type_size);
25829 memcpy(&uniform.m_initial_data[0] + type_size, &goten_data[0], type_size);
25832 xfb.m_initial_data.resize(3 * type_size);
25833 xfb.m_expected_data.resize(3 * type_size);
25835 for (GLuint i = 0; i < 3 * type_size; ++i)
25837 xfb.m_initial_data[i] = (glw::GLubyte)i;
25838 xfb.m_expected_data[i] = (glw::GLubyte)i;
25841 memcpy(&xfb.m_expected_data[0] + 2 * type_size, &gohan_data[0], type_size);
25842 memcpy(&xfb.m_expected_data[0] + 0 * type_size, &goten_data[0], type_size);
25845 /** Get body of main function for given shader stage
25847 * @param test_case_index Index of test case
25848 * @param stage Shader stage
25849 * @param out_assignments Set to empty
25850 * @param out_calculations Set to empty
25852 void XFBCaptureInactiveOutputVariableTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
25853 std::string& out_assignments, std::string& out_calculations)
25855 out_calculations = "";
25857 static const GLchar* vs_tes_gs = " goten = uni_goten;\n"
25858 " gohan = uni_gohan;\n";
25859 static const GLchar* fs = " fs_out = goku + gohan + goten;\n";
25861 const GLchar* assignments = "";
25865 case Utils::Shader::FRAGMENT:
25869 case Utils::Shader::GEOMETRY:
25870 if (TEST_GS == test_case_index)
25872 assignments = vs_tes_gs;
25876 case Utils::Shader::TESS_CTRL:
25879 case Utils::Shader::TESS_EVAL:
25880 if (TEST_TES == test_case_index)
25882 assignments = vs_tes_gs;
25886 case Utils::Shader::VERTEX:
25887 if (TEST_VS == test_case_index)
25889 assignments = vs_tes_gs;
25894 TCU_FAIL("Invalid enum");
25897 out_assignments = assignments;
25900 /** Get interface of shader
25902 * @param test_case_index Index of test case
25903 * @param stage Shader stage
25904 * @param out_interface Set to ""
25906 void XFBCaptureInactiveOutputVariableTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
25907 std::string& out_interface)
25909 static const GLchar* vs_tes_gs = "const uint sizeof_type = 16;\n"
25911 "layout (xfb_offset = 1 * sizeof_type) out vec4 goku;\n"
25912 "layout (xfb_offset = 2 * sizeof_type) out vec4 gohan;\n"
25913 "layout (xfb_offset = 0 * sizeof_type) out vec4 goten;\n"
25915 "layout(binding = 0) uniform block {\n"
25916 " vec4 uni_gohan;\n"
25917 " vec4 uni_goten;\n"
25919 static const GLchar* fs = "in vec4 goku;\n"
25922 "out vec4 fs_out;\n";
25924 const GLchar* interface = "";
25928 case Utils::Shader::FRAGMENT:
25932 case Utils::Shader::GEOMETRY:
25933 if (TEST_GS == test_case_index)
25935 interface = vs_tes_gs;
25939 case Utils::Shader::TESS_CTRL:
25942 case Utils::Shader::TESS_EVAL:
25943 if (TEST_TES == test_case_index)
25945 interface = vs_tes_gs;
25949 case Utils::Shader::VERTEX:
25950 if (TEST_VS == test_case_index)
25952 interface = vs_tes_gs;
25957 TCU_FAIL("Invalid enum");
25960 out_interface = interface;
25963 /** Get source code of shader
25965 * @param test_case_index Index of test case
25966 * @param stage Shader stage
25970 std::string XFBCaptureInactiveOutputVariableTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
25972 std::string source;
25974 switch (test_case_index)
25979 case Utils::Shader::FRAGMENT:
25980 case Utils::Shader::VERTEX:
25981 source = BufferTestBase::getShaderSource(test_case_index, stage);
25991 case Utils::Shader::FRAGMENT:
25992 case Utils::Shader::TESS_CTRL:
25993 case Utils::Shader::TESS_EVAL:
25994 case Utils::Shader::VERTEX:
25995 source = BufferTestBase::getShaderSource(test_case_index, stage);
26003 source = BufferTestBase::getShaderSource(test_case_index, stage);
26007 TCU_FAIL("Invalid enum");
26015 /** Get name of test case
26017 * @param test_case_index Index of test case
26019 * @return Name of tested stage
26021 std::string XFBCaptureInactiveOutputVariableTest::getTestCaseName(glw::GLuint test_case_index)
26023 const GLchar* name = 0;
26025 switch (test_case_index)
26031 name = "tesselation evaluation";
26037 TCU_FAIL("Invalid enum");
26043 /** Returns number of test cases
26047 glw::GLuint XFBCaptureInactiveOutputVariableTest::getTestCaseNumber()
26052 /** Inspects program to check if all resources are as expected
26055 * @param program Program instance
26056 * @param out_stream Error message
26058 * @return true if everything is ok, false otherwise
26060 bool XFBCaptureInactiveOutputVariableTest::inspectProgram(GLuint /* test_case_index */, Utils::Program& program,
26061 std::stringstream& out_stream)
26064 const Utils::Type& type = Utils::Type::vec4;
26065 const GLuint type_size = type.GetSize();
26067 program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE,
26068 1 /* buf_size */, &stride);
26070 if ((GLint)(3 * type_size) != stride)
26072 out_stream << "Stride is: " << stride << " expected: " << (3 * type_size);
26080 /** Verify contents of buffers
26082 * @param buffers Collection of buffers to be verified
26084 * @return true if everything is as expected, false otherwise
26086 bool XFBCaptureInactiveOutputVariableTest::verifyBuffers(bufferCollection& buffers)
26088 bool result = true;
26090 bufferCollection::pair& pair = buffers.m_vector[1] /* xfb */;
26091 Utils::Buffer* buffer = pair.m_buffer;
26092 bufferDescriptor* descriptor = pair.m_descriptor;
26094 /* Get pointer to contents of buffer */
26096 GLubyte* buffer_data = (GLubyte*)buffer->Map(Utils::Buffer::ReadOnly);
26098 /* Get pointer to expected data */
26099 GLubyte* expected_data = (GLubyte*)&descriptor->m_expected_data[0];
26102 static const GLuint vec4_size = 16;
26104 int res_gohan = memcmp(buffer_data + 2 * vec4_size, expected_data + 2 * vec4_size, vec4_size);
26105 int res_goten = memcmp(buffer_data + 0 * vec4_size, expected_data + 0 * vec4_size, vec4_size);
26107 if ((0 != res_gohan) || (0 != res_goten))
26109 m_context.getTestContext().getLog()
26110 << tcu::TestLog::Message << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
26111 << ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
26116 /* Release buffer mapping */
26124 * @param context Test context
26126 XFBCaptureInactiveOutputComponentTest::XFBCaptureInactiveOutputComponentTest(deqp::Context& context)
26127 : BufferTestBase(context, "xfb_capture_inactive_output_component",
26128 "Test verifies that inactive components are not modified")
26130 /* Nothing to be done here */
26133 /** Execute drawArrays for single vertex
26135 * @param test_case_index
26139 bool XFBCaptureInactiveOutputComponentTest::executeDrawCall(GLuint test_case_index)
26141 const Functions& gl = m_context.getRenderContext().getFunctions();
26142 GLenum primitive_type = GL_PATCHES;
26144 if (TEST_VS == test_case_index)
26146 primitive_type = GL_POINTS;
26149 gl.disable(GL_RASTERIZER_DISCARD);
26150 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
26152 gl.beginTransformFeedback(GL_POINTS);
26153 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
26155 gl.drawArrays(primitive_type, 0 /* first */, 1 /* count */);
26156 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
26158 gl.endTransformFeedback();
26159 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
26164 /** Get descriptors of buffers necessary for test
26167 * @param out_descriptors Descriptors of buffers used by test
26169 void XFBCaptureInactiveOutputComponentTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
26170 bufferDescriptor::Vector& out_descriptors)
26172 const Utils::Type& type = Utils::Type::vec4;
26174 /* Test needs single uniform and xfb */
26175 out_descriptors.resize(2);
26177 /* Get references */
26178 bufferDescriptor& uniform = out_descriptors[0];
26179 bufferDescriptor& xfb = out_descriptors[1];
26182 uniform.m_index = 0;
26186 uniform.m_target = Utils::Buffer::Uniform;
26187 xfb.m_target = Utils::Buffer::Transform_feedback;
26190 const std::vector<GLubyte>& goku_data = type.GenerateData();
26191 const std::vector<GLubyte>& gohan_data = type.GenerateData();
26192 const std::vector<GLubyte>& goten_data = type.GenerateData();
26193 const std::vector<GLubyte>& chichi_data = type.GenerateData();
26194 const std::vector<GLubyte>& vegeta_data = type.GenerateData();
26195 const std::vector<GLubyte>& trunks_data = type.GenerateData();
26196 const std::vector<GLubyte>& bra_data = type.GenerateData();
26197 const std::vector<GLubyte>& bulma_data = type.GenerateData();
26199 const GLuint comp_size = Utils::Type::GetTypeSize(type.m_basic_type);
26200 const GLuint type_size = static_cast<GLuint>(gohan_data.size());
26203 uniform.m_initial_data.resize(8 * type_size);
26204 memcpy(&uniform.m_initial_data[0] + 0 * type_size, &goku_data[0], type_size);
26205 memcpy(&uniform.m_initial_data[0] + 1 * type_size, &gohan_data[0], type_size);
26206 memcpy(&uniform.m_initial_data[0] + 2 * type_size, &goten_data[0], type_size);
26207 memcpy(&uniform.m_initial_data[0] + 3 * type_size, &chichi_data[0], type_size);
26208 memcpy(&uniform.m_initial_data[0] + 4 * type_size, &vegeta_data[0], type_size);
26209 memcpy(&uniform.m_initial_data[0] + 5 * type_size, &trunks_data[0], type_size);
26210 memcpy(&uniform.m_initial_data[0] + 6 * type_size, &bra_data[0], type_size);
26211 memcpy(&uniform.m_initial_data[0] + 7 * type_size, &bulma_data[0], type_size);
26214 xfb.m_initial_data.resize(8 * type_size);
26215 xfb.m_expected_data.resize(8 * type_size);
26217 for (GLuint i = 0; i < 8 * type_size; ++i)
26219 xfb.m_initial_data[i] = (glw::GLubyte)i;
26220 xfb.m_expected_data[i] = (glw::GLubyte)i;
26223 /* goku - x, z - 32 */
26224 memcpy(&xfb.m_expected_data[0] + 2 * type_size + 0 * comp_size, &goku_data[0] + 0 * comp_size, comp_size);
26225 memcpy(&xfb.m_expected_data[0] + 2 * type_size + 2 * comp_size, &goku_data[0] + 2 * comp_size, comp_size);
26227 /* gohan - y, w - 0 */
26228 memcpy(&xfb.m_expected_data[0] + 0 * type_size + 1 * comp_size, &gohan_data[0] + 1 * comp_size, comp_size);
26229 memcpy(&xfb.m_expected_data[0] + 0 * type_size + 3 * comp_size, &gohan_data[0] + 3 * comp_size, comp_size);
26231 /* goten - x, y - 16 */
26232 memcpy(&xfb.m_expected_data[0] + 1 * type_size + 0 * comp_size, &goten_data[0] + 0 * comp_size, comp_size);
26233 memcpy(&xfb.m_expected_data[0] + 1 * type_size + 1 * comp_size, &goten_data[0] + 1 * comp_size, comp_size);
26235 /* chichi - z, w - 48 */
26236 memcpy(&xfb.m_expected_data[0] + 3 * type_size + 2 * comp_size, &chichi_data[0] + 2 * comp_size, comp_size);
26237 memcpy(&xfb.m_expected_data[0] + 3 * type_size + 3 * comp_size, &chichi_data[0] + 3 * comp_size, comp_size);
26239 /* vegeta - x - 112 */
26240 memcpy(&xfb.m_expected_data[0] + 7 * type_size + 0 * comp_size, &vegeta_data[0] + 0 * comp_size, comp_size);
26242 /* trunks - y - 96 */
26243 memcpy(&xfb.m_expected_data[0] + 6 * type_size + 1 * comp_size, &trunks_data[0] + 1 * comp_size, comp_size);
26246 memcpy(&xfb.m_expected_data[0] + 5 * type_size + 2 * comp_size, &bra_data[0] + 2 * comp_size, comp_size);
26248 /* bulma - w - 64 */
26249 memcpy(&xfb.m_expected_data[0] + 4 * type_size + 3 * comp_size, &bulma_data[0] + 3 * comp_size, comp_size);
26252 /** Get body of main function for given shader stage
26254 * @param test_case_index Index of test case
26255 * @param stage Shader stage
26256 * @param out_assignments Set to empty
26257 * @param out_calculations Set to empty
26259 void XFBCaptureInactiveOutputComponentTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
26260 std::string& out_assignments, std::string& out_calculations)
26262 out_calculations = "";
26264 static const GLchar* vs_tes_gs = " goku.x = uni_goku.x ;\n"
26265 " goku.z = uni_goku.z ;\n"
26266 " gohan.y = uni_gohan.y ;\n"
26267 " gohan.w = uni_gohan.w ;\n"
26268 " goten.x = uni_goten.x ;\n"
26269 " goten.y = uni_goten.y ;\n"
26270 " chichi.z = uni_chichi.z ;\n"
26271 " chichi.w = uni_chichi.w ;\n"
26272 " vegeta.x = uni_vegeta.x ;\n"
26273 " trunks.y = uni_trunks.y ;\n"
26274 " bra.z = uni_bra.z ;\n"
26275 " bulma.w = uni_bulma.w ;\n";
26276 static const GLchar* fs = " fs_out = goku + gohan + goten + chichi + vegeta + trunks + bra + bulma;\n";
26278 const GLchar* assignments = "";
26282 case Utils::Shader::FRAGMENT:
26286 case Utils::Shader::GEOMETRY:
26287 if (TEST_GS == test_case_index)
26289 assignments = vs_tes_gs;
26293 case Utils::Shader::TESS_CTRL:
26296 case Utils::Shader::TESS_EVAL:
26297 if (TEST_TES == test_case_index)
26299 assignments = vs_tes_gs;
26303 case Utils::Shader::VERTEX:
26304 if (TEST_VS == test_case_index)
26306 assignments = vs_tes_gs;
26311 TCU_FAIL("Invalid enum");
26314 out_assignments = assignments;
26317 /** Get interface of shader
26319 * @param test_case_index Index of test case
26320 * @param stage Shader stage
26321 * @param out_interface Set to ""
26323 void XFBCaptureInactiveOutputComponentTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
26324 std::string& out_interface)
26326 static const GLchar* vs_tes_gs = "const uint sizeof_type = 16;\n"
26328 "layout (xfb_offset = 2 * sizeof_type) out vec4 goku;\n"
26329 "layout (xfb_offset = 0 * sizeof_type) out vec4 gohan;\n"
26330 "layout (xfb_offset = 1 * sizeof_type) out vec4 goten;\n"
26331 "layout (xfb_offset = 3 * sizeof_type) out vec4 chichi;\n"
26332 "layout (xfb_offset = 7 * sizeof_type) out vec4 vegeta;\n"
26333 "layout (xfb_offset = 6 * sizeof_type) out vec4 trunks;\n"
26334 "layout (xfb_offset = 5 * sizeof_type) out vec4 bra;\n"
26335 "layout (xfb_offset = 4 * sizeof_type) out vec4 bulma;\n"
26337 "layout(binding = 0) uniform block {\n"
26338 " vec4 uni_goku;\n"
26339 " vec4 uni_gohan;\n"
26340 " vec4 uni_goten;\n"
26341 " vec4 uni_chichi;\n"
26342 " vec4 uni_vegeta;\n"
26343 " vec4 uni_trunks;\n"
26345 " vec4 uni_bulma;\n"
26347 static const GLchar* fs = "in vec4 vegeta;\n"
26348 "in vec4 trunks;\n"
26354 "in vec4 chichi;\n"
26356 "out vec4 fs_out;\n";
26358 const GLchar* interface = "";
26362 case Utils::Shader::FRAGMENT:
26366 case Utils::Shader::GEOMETRY:
26367 if (TEST_GS == test_case_index)
26369 interface = vs_tes_gs;
26373 case Utils::Shader::TESS_CTRL:
26376 case Utils::Shader::TESS_EVAL:
26377 if (TEST_TES == test_case_index)
26379 interface = vs_tes_gs;
26383 case Utils::Shader::VERTEX:
26384 if (TEST_VS == test_case_index)
26386 interface = vs_tes_gs;
26391 TCU_FAIL("Invalid enum");
26394 out_interface = interface;
26397 /** Get source code of shader
26399 * @param test_case_index Index of test case
26400 * @param stage Shader stage
26404 std::string XFBCaptureInactiveOutputComponentTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
26406 std::string source;
26408 switch (test_case_index)
26413 case Utils::Shader::FRAGMENT:
26414 case Utils::Shader::VERTEX:
26415 source = BufferTestBase::getShaderSource(test_case_index, stage);
26425 case Utils::Shader::FRAGMENT:
26426 case Utils::Shader::TESS_CTRL:
26427 case Utils::Shader::TESS_EVAL:
26428 case Utils::Shader::VERTEX:
26429 source = BufferTestBase::getShaderSource(test_case_index, stage);
26437 source = BufferTestBase::getShaderSource(test_case_index, stage);
26441 TCU_FAIL("Invalid enum");
26449 /** Get name of test case
26451 * @param test_case_index Index of test case
26453 * @return Name of tested stage
26455 std::string XFBCaptureInactiveOutputComponentTest::getTestCaseName(glw::GLuint test_case_index)
26457 const GLchar* name = 0;
26459 switch (test_case_index)
26465 name = "tesselation evaluation";
26471 TCU_FAIL("Invalid enum");
26477 /** Returns number of test cases
26481 glw::GLuint XFBCaptureInactiveOutputComponentTest::getTestCaseNumber()
26486 /** Verify contents of buffers
26488 * @param buffers Collection of buffers to be verified
26490 * @return true if everything is as expected, false otherwise
26492 bool XFBCaptureInactiveOutputComponentTest::verifyBuffers(bufferCollection& buffers)
26494 bool result = true;
26496 bufferCollection::pair& pair = buffers.m_vector[1] /* xfb */;
26497 Utils::Buffer* buffer = pair.m_buffer;
26498 bufferDescriptor* descriptor = pair.m_descriptor;
26500 /* Get pointer to contents of buffer */
26502 GLubyte* buffer_data = (GLubyte*)buffer->Map(Utils::Buffer::ReadOnly);
26504 /* Get pointer to expected data */
26505 GLubyte* expected_data = (GLubyte*)&descriptor->m_expected_data[0];
26508 static const GLuint comp_size = 4;
26509 static const GLuint vec4_size = 16;
26512 memcmp(buffer_data + 2 * vec4_size + 0 * comp_size, expected_data + 2 * vec4_size + 0 * comp_size, comp_size);
26514 memcmp(buffer_data + 2 * vec4_size + 2 * comp_size, expected_data + 2 * vec4_size + 2 * comp_size, comp_size);
26517 memcmp(buffer_data + 0 * vec4_size + 1 * comp_size, expected_data + 0 * vec4_size + 1 * comp_size, comp_size);
26519 memcmp(buffer_data + 0 * vec4_size + 3 * comp_size, expected_data + 0 * vec4_size + 3 * comp_size, comp_size);
26522 memcmp(buffer_data + 1 * vec4_size + 0 * comp_size, expected_data + 1 * vec4_size + 0 * comp_size, comp_size);
26524 memcmp(buffer_data + 1 * vec4_size + 1 * comp_size, expected_data + 1 * vec4_size + 1 * comp_size, comp_size);
26527 memcmp(buffer_data + 3 * vec4_size + 2 * comp_size, expected_data + 3 * vec4_size + 2 * comp_size, comp_size);
26529 memcmp(buffer_data + 3 * vec4_size + 3 * comp_size, expected_data + 3 * vec4_size + 3 * comp_size, comp_size);
26532 memcmp(buffer_data + 7 * vec4_size + 0 * comp_size, expected_data + 7 * vec4_size + 0 * comp_size, comp_size);
26535 memcmp(buffer_data + 6 * vec4_size + 1 * comp_size, expected_data + 6 * vec4_size + 1 * comp_size, comp_size);
26538 memcmp(buffer_data + 5 * vec4_size + 2 * comp_size, expected_data + 5 * vec4_size + 2 * comp_size, comp_size);
26541 memcmp(buffer_data + 4 * vec4_size + 3 * comp_size, expected_data + 4 * vec4_size + 3 * comp_size, comp_size);
26543 if ((0 != res_goku_x) || (0 != res_goku_z) || (0 != res_gohan_y) || (0 != res_gohan_w) || (0 != res_goten_x) ||
26544 (0 != res_goten_y) || (0 != res_chichi_z) || (0 != res_chichi_w) || (0 != res_vegeta_x) ||
26545 (0 != res_trunks_y) || (0 != res_bra_z) || (0 != res_bulma_w))
26547 m_context.getTestContext().getLog()
26548 << tcu::TestLog::Message << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
26549 << ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
26554 /* Release buffer mapping */
26562 * @param context Test context
26564 XFBCaptureInactiveOutputBlockMemberTest::XFBCaptureInactiveOutputBlockMemberTest(deqp::Context& context)
26565 : BufferTestBase(context, "xfb_capture_inactive_output_block_member",
26566 "Test verifies that inactive block members are captured")
26568 /* Nothing to be done here */
26571 /** Execute drawArrays for single vertex
26573 * @param test_case_index
26577 bool XFBCaptureInactiveOutputBlockMemberTest::executeDrawCall(GLuint test_case_index)
26579 const Functions& gl = m_context.getRenderContext().getFunctions();
26580 GLenum primitive_type = GL_PATCHES;
26582 if (TEST_VS == test_case_index)
26584 primitive_type = GL_POINTS;
26587 gl.disable(GL_RASTERIZER_DISCARD);
26588 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
26590 gl.beginTransformFeedback(GL_POINTS);
26591 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
26593 gl.drawArrays(primitive_type, 0 /* first */, 1 /* count */);
26594 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
26596 gl.endTransformFeedback();
26597 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
26602 /** Get descriptors of buffers necessary for test
26605 * @param out_descriptors Descriptors of buffers used by test
26607 void XFBCaptureInactiveOutputBlockMemberTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
26608 bufferDescriptor::Vector& out_descriptors)
26610 const Utils::Type& type = Utils::Type::vec4;
26612 /* Test needs single uniform and xfb */
26613 out_descriptors.resize(2);
26615 /* Get references */
26616 bufferDescriptor& uniform = out_descriptors[0];
26617 bufferDescriptor& xfb = out_descriptors[1];
26620 uniform.m_index = 0;
26624 uniform.m_target = Utils::Buffer::Uniform;
26625 xfb.m_target = Utils::Buffer::Transform_feedback;
26628 const std::vector<GLubyte>& gohan_data = type.GenerateData();
26629 const std::vector<GLubyte>& chichi_data = type.GenerateData();
26631 const GLuint type_size = static_cast<GLuint>(gohan_data.size());
26634 uniform.m_initial_data.resize(2 * type_size);
26635 memcpy(&uniform.m_initial_data[0] + 0, &gohan_data[0], type_size);
26636 memcpy(&uniform.m_initial_data[0] + type_size, &chichi_data[0], type_size);
26639 xfb.m_initial_data.resize(4 * type_size);
26640 xfb.m_expected_data.resize(4 * type_size);
26642 for (GLuint i = 0; i < 4 * type_size; ++i)
26644 xfb.m_initial_data[i] = (glw::GLubyte)i;
26645 xfb.m_expected_data[i] = (glw::GLubyte)i;
26648 memcpy(&xfb.m_expected_data[0] + 1 * type_size, &gohan_data[0], type_size);
26649 memcpy(&xfb.m_expected_data[0] + 3 * type_size, &chichi_data[0], type_size);
26652 /** Get body of main function for given shader stage
26654 * @param test_case_index Index of test case
26655 * @param stage Shader stage
26656 * @param out_assignments Set to empty
26657 * @param out_calculations Set to empty
26659 void XFBCaptureInactiveOutputBlockMemberTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
26660 std::string& out_assignments, std::string& out_calculations)
26662 out_calculations = "";
26664 static const GLchar* vs_tes_gs = " chichi = uni_chichi;\n"
26665 " gohan = uni_gohan;\n";
26666 static const GLchar* fs = " fs_out = goten + gohan + chichi;\n";
26668 const GLchar* assignments = "";
26672 case Utils::Shader::FRAGMENT:
26676 case Utils::Shader::GEOMETRY:
26677 if (TEST_GS == test_case_index)
26679 assignments = vs_tes_gs;
26683 case Utils::Shader::TESS_CTRL:
26686 case Utils::Shader::TESS_EVAL:
26687 if (TEST_TES == test_case_index)
26689 assignments = vs_tes_gs;
26693 case Utils::Shader::VERTEX:
26694 if (TEST_VS == test_case_index)
26696 assignments = vs_tes_gs;
26701 TCU_FAIL("Invalid enum");
26704 out_assignments = assignments;
26707 /** Get interface of shader
26709 * @param test_case_index Index of test case
26710 * @param stage Shader stage
26711 * @param out_interface Set to ""
26713 void XFBCaptureInactiveOutputBlockMemberTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
26714 std::string& out_interface)
26716 static const GLchar* vs_tes_gs = "const uint sizeof_type = 16;\n"
26718 "layout (xfb_offset = 1 * sizeof_type) out Goku {\n"
26724 "layout(binding = 0) uniform block {\n"
26725 " vec4 uni_gohan;\n"
26726 " vec4 uni_chichi;\n"
26728 static const GLchar* fs = "in Goku {\n"
26733 "out vec4 fs_out;\n";
26735 const GLchar* interface = "";
26739 case Utils::Shader::FRAGMENT:
26743 case Utils::Shader::GEOMETRY:
26744 if (TEST_GS == test_case_index)
26746 interface = vs_tes_gs;
26750 case Utils::Shader::TESS_CTRL:
26753 case Utils::Shader::TESS_EVAL:
26754 if (TEST_TES == test_case_index)
26756 interface = vs_tes_gs;
26760 case Utils::Shader::VERTEX:
26761 if (TEST_VS == test_case_index)
26763 interface = vs_tes_gs;
26768 TCU_FAIL("Invalid enum");
26771 out_interface = interface;
26774 /** Get source code of shader
26776 * @param test_case_index Index of test case
26777 * @param stage Shader stage
26781 std::string XFBCaptureInactiveOutputBlockMemberTest::getShaderSource(GLuint test_case_index,
26782 Utils::Shader::STAGES stage)
26784 std::string source;
26786 switch (test_case_index)
26791 case Utils::Shader::FRAGMENT:
26792 case Utils::Shader::VERTEX:
26793 source = BufferTestBase::getShaderSource(test_case_index, stage);
26803 case Utils::Shader::FRAGMENT:
26804 case Utils::Shader::TESS_CTRL:
26805 case Utils::Shader::TESS_EVAL:
26806 case Utils::Shader::VERTEX:
26807 source = BufferTestBase::getShaderSource(test_case_index, stage);
26815 source = BufferTestBase::getShaderSource(test_case_index, stage);
26819 TCU_FAIL("Invalid enum");
26827 /** Get name of test case
26829 * @param test_case_index Index of test case
26831 * @return Name of tested stage
26833 std::string XFBCaptureInactiveOutputBlockMemberTest::getTestCaseName(glw::GLuint test_case_index)
26835 const GLchar* name = 0;
26837 switch (test_case_index)
26843 name = "tesselation evaluation";
26849 TCU_FAIL("Invalid enum");
26855 /** Returns number of test cases
26859 glw::GLuint XFBCaptureInactiveOutputBlockMemberTest::getTestCaseNumber()
26864 /** Verify contents of buffers
26866 * @param buffers Collection of buffers to be verified
26868 * @return true if everything is as expected, false otherwise
26870 bool XFBCaptureInactiveOutputBlockMemberTest::verifyBuffers(bufferCollection& buffers)
26872 bool result = true;
26874 bufferCollection::pair& pair = buffers.m_vector[1] /* xfb */;
26875 Utils::Buffer* buffer = pair.m_buffer;
26876 bufferDescriptor* descriptor = pair.m_descriptor;
26878 /* Get pointer to contents of buffer */
26880 GLubyte* buffer_data = (GLubyte*)buffer->Map(Utils::Buffer::ReadOnly);
26882 /* Get pointer to expected data */
26883 GLubyte* expected_data = (GLubyte*)&descriptor->m_expected_data[0];
26886 static const GLuint vec4_size = 16;
26888 int res_before = memcmp(buffer_data, expected_data, vec4_size);
26889 int res_gohan = memcmp(buffer_data + 1 * vec4_size, expected_data + 1 * vec4_size, vec4_size);
26890 int res_chichi = memcmp(buffer_data + 3 * vec4_size, expected_data + 3 * vec4_size, vec4_size);
26892 if ((0 != res_before) || (0 != res_gohan) || (0 != res_chichi))
26894 m_context.getTestContext().getLog()
26895 << tcu::TestLog::Message << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
26896 << ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
26901 /* Release buffer mapping */
26909 * @param context Test context
26911 XFBCaptureStructTest::XFBCaptureStructTest(deqp::Context& context)
26912 : BufferTestBase(context, "xfb_capture_struct", "Test verifies that inactive structure members are captured")
26914 /* Nothing to be done here */
26917 /** Execute drawArrays for single vertex
26919 * @param test_case_index
26923 bool XFBCaptureStructTest::executeDrawCall(GLuint test_case_index)
26925 const Functions& gl = m_context.getRenderContext().getFunctions();
26926 GLenum primitive_type = GL_PATCHES;
26928 if (TEST_VS == test_case_index)
26930 primitive_type = GL_POINTS;
26933 gl.disable(GL_RASTERIZER_DISCARD);
26934 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
26936 gl.beginTransformFeedback(GL_POINTS);
26937 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
26939 gl.drawArrays(primitive_type, 0 /* first */, 1 /* count */);
26940 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
26942 gl.endTransformFeedback();
26943 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
26948 /** Get descriptors of buffers necessary for test
26951 * @param out_descriptors Descriptors of buffers used by test
26953 void XFBCaptureStructTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
26954 bufferDescriptor::Vector& out_descriptors)
26956 const Utils::Type& type = Utils::Type::vec4;
26958 /* Test needs single uniform and xfb */
26959 out_descriptors.resize(2);
26961 /* Get references */
26962 bufferDescriptor& uniform = out_descriptors[0];
26963 bufferDescriptor& xfb = out_descriptors[1];
26966 uniform.m_index = 0;
26970 uniform.m_target = Utils::Buffer::Uniform;
26971 xfb.m_target = Utils::Buffer::Transform_feedback;
26974 const std::vector<GLubyte>& gohan_data = type.GenerateData();
26975 const std::vector<GLubyte>& chichi_data = type.GenerateData();
26977 const GLuint type_size = static_cast<GLuint>(gohan_data.size());
26980 uniform.m_initial_data.resize(2 * type_size);
26981 memcpy(&uniform.m_initial_data[0] + 0, &gohan_data[0], type_size);
26982 memcpy(&uniform.m_initial_data[0] + type_size, &chichi_data[0], type_size);
26985 xfb.m_initial_data.resize(4 * type_size);
26986 xfb.m_expected_data.resize(4 * type_size);
26988 for (GLuint i = 0; i < 4 * type_size; ++i)
26990 xfb.m_initial_data[i] = (glw::GLubyte)i;
26991 xfb.m_expected_data[i] = (glw::GLubyte)i;
26994 memcpy(&xfb.m_expected_data[0] + 1 * type_size, &gohan_data[0], type_size);
26995 memcpy(&xfb.m_expected_data[0] + 3 * type_size, &chichi_data[0], type_size);
26998 /** Get body of main function for given shader stage
27000 * @param test_case_index Index of test case
27001 * @param stage Shader stage
27002 * @param out_assignments Set to empty
27003 * @param out_calculations Set to empty
27005 void XFBCaptureStructTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
27006 std::string& out_assignments, std::string& out_calculations)
27008 out_calculations = "";
27010 static const GLchar* vs_tes_gs = " goku.chichi = uni_chichi;\n"
27011 " goku.gohan = uni_gohan;\n";
27012 static const GLchar* fs = " fs_out = goku.goten + goku.gohan + goku.chichi;\n";
27014 const GLchar* assignments = "";
27018 case Utils::Shader::FRAGMENT:
27022 case Utils::Shader::GEOMETRY:
27023 if (TEST_GS == test_case_index)
27025 assignments = vs_tes_gs;
27029 case Utils::Shader::TESS_CTRL:
27032 case Utils::Shader::TESS_EVAL:
27033 if (TEST_TES == test_case_index)
27035 assignments = vs_tes_gs;
27039 case Utils::Shader::VERTEX:
27040 if (TEST_VS == test_case_index)
27042 assignments = vs_tes_gs;
27047 TCU_FAIL("Invalid enum");
27050 out_assignments = assignments;
27053 /** Get interface of shader
27055 * @param test_case_index Index of test case
27056 * @param stage Shader stage
27057 * @param out_interface Set to ""
27059 void XFBCaptureStructTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
27060 std::string& out_interface)
27062 static const GLchar* vs_tes_gs = "const uint sizeof_type = 16;\n"
27070 "layout (xfb_offset = sizeof_type) out Goku goku;\n"
27072 "layout(binding = 0, std140) uniform block {\n"
27073 " vec4 uni_gohan;\n"
27074 " vec4 uni_chichi;\n"
27076 static const GLchar* fs = "struct Goku {\n"
27084 "out vec4 fs_out;\n";
27086 const GLchar* interface = "";
27090 case Utils::Shader::FRAGMENT:
27094 case Utils::Shader::GEOMETRY:
27095 if (TEST_GS == test_case_index)
27097 interface = vs_tes_gs;
27101 case Utils::Shader::TESS_CTRL:
27104 case Utils::Shader::TESS_EVAL:
27105 if (TEST_TES == test_case_index)
27107 interface = vs_tes_gs;
27111 case Utils::Shader::VERTEX:
27112 if (TEST_VS == test_case_index)
27114 interface = vs_tes_gs;
27119 TCU_FAIL("Invalid enum");
27122 out_interface = interface;
27125 /** Get source code of shader
27127 * @param test_case_index Index of test case
27128 * @param stage Shader stage
27132 std::string XFBCaptureStructTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
27134 std::string source;
27136 switch (test_case_index)
27141 case Utils::Shader::FRAGMENT:
27142 case Utils::Shader::VERTEX:
27143 source = BufferTestBase::getShaderSource(test_case_index, stage);
27153 case Utils::Shader::FRAGMENT:
27154 case Utils::Shader::TESS_CTRL:
27155 case Utils::Shader::TESS_EVAL:
27156 case Utils::Shader::VERTEX:
27157 source = BufferTestBase::getShaderSource(test_case_index, stage);
27165 source = BufferTestBase::getShaderSource(test_case_index, stage);
27169 TCU_FAIL("Invalid enum");
27177 /** Get name of test case
27179 * @param test_case_index Index of test case
27181 * @return Name of tested stage
27183 std::string XFBCaptureStructTest::getTestCaseName(glw::GLuint test_case_index)
27185 const GLchar* name = 0;
27187 switch (test_case_index)
27193 name = "tesselation evaluation";
27199 TCU_FAIL("Invalid enum");
27205 /** Returns number of test cases
27209 glw::GLuint XFBCaptureStructTest::getTestCaseNumber()
27214 /** Verify contents of buffers
27216 * @param buffers Collection of buffers to be verified
27218 * @return true if everything is as expected, false otherwise
27220 bool XFBCaptureStructTest::verifyBuffers(bufferCollection& buffers)
27222 bool result = true;
27224 bufferCollection::pair& pair = buffers.m_vector[1] /* xfb */;
27225 Utils::Buffer* buffer = pair.m_buffer;
27226 bufferDescriptor* descriptor = pair.m_descriptor;
27228 /* Get pointer to contents of buffer */
27230 GLubyte* buffer_data = (GLubyte*)buffer->Map(Utils::Buffer::ReadOnly);
27232 /* Get pointer to expected data */
27233 GLubyte* expected_data = (GLubyte*)&descriptor->m_expected_data[0];
27236 static const GLuint vec4_size = 16;
27238 int res_before = memcmp(buffer_data, expected_data, vec4_size);
27239 int res_gohan = memcmp(buffer_data + 1 * vec4_size, expected_data + 1 * vec4_size, vec4_size);
27240 int res_chichi = memcmp(buffer_data + 3 * vec4_size, expected_data + 3 * vec4_size, vec4_size);
27242 if ((0 != res_before) || (0 != res_gohan) || (0 != res_chichi))
27244 m_context.getTestContext().getLog()
27245 << tcu::TestLog::Message << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
27246 << ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
27251 /* Release buffer mapping */
27259 * @param context Test framework context
27261 XFBCaptureUnsizedArrayTest::XFBCaptureUnsizedArrayTest(deqp::Context& context)
27262 : NegativeTestBase(context, "xfb_capture_unsized_array",
27263 "Test verifies that compiler reports error when unsized array is qualified with xfb_offset")
27267 /** Source for given test case and stage
27269 * @param test_case_index Index of test case
27270 * @param stage Shader stage
27272 * @return Shader source
27274 std::string XFBCaptureUnsizedArrayTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
27276 static const GLchar* var_definition = "layout (xfb_offset = 0) out vec4 gokuARRAY[];\n";
27277 static const GLchar* var_use = " gokuINDEX[0] = result / 2;\n";
27278 static const GLchar* fs = "#version 430 core\n"
27279 "#extension GL_ARB_enhanced_layouts : require\n"
27282 "out vec4 fs_out;\n"
27286 " fs_out = gs_fs;\n"
27289 static const GLchar* gs_tested = "#version 430 core\n"
27290 "#extension GL_ARB_enhanced_layouts : require\n"
27292 "layout(points) in;\n"
27293 "layout(triangle_strip, max_vertices = 4) out;\n"
27297 "in vec4 tes_gs[];\n"
27298 "out vec4 gs_fs;\n"
27302 " vec4 result = tes_gs[0];\n"
27306 " gs_fs = result;\n"
27307 " gl_Position = vec4(-1, -1, 0, 1);\n"
27309 " gs_fs = result;\n"
27310 " gl_Position = vec4(-1, 1, 0, 1);\n"
27312 " gs_fs = result;\n"
27313 " gl_Position = vec4(1, -1, 0, 1);\n"
27315 " gs_fs = result;\n"
27316 " gl_Position = vec4(1, 1, 0, 1);\n"
27320 static const GLchar* tcs = "#version 430 core\n"
27321 "#extension GL_ARB_enhanced_layouts : require\n"
27323 "layout(vertices = 1) out;\n"
27325 "in vec4 vs_tcs[];\n"
27326 "out vec4 tcs_tes[];\n"
27331 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
27333 " gl_TessLevelOuter[0] = 1.0;\n"
27334 " gl_TessLevelOuter[1] = 1.0;\n"
27335 " gl_TessLevelOuter[2] = 1.0;\n"
27336 " gl_TessLevelOuter[3] = 1.0;\n"
27337 " gl_TessLevelInner[0] = 1.0;\n"
27338 " gl_TessLevelInner[1] = 1.0;\n"
27341 static const GLchar* tcs_tested = "#version 430 core\n"
27342 "#extension GL_ARB_enhanced_layouts : require\n"
27344 "layout(vertices = 1) out;\n"
27348 "in vec4 vs_tcs[];\n"
27349 "out vec4 tcs_tes[];\n"
27353 " vec4 result = vs_tcs[gl_InvocationID];\n"
27357 " tcs_tes[gl_InvocationID] = result;\n"
27359 " gl_TessLevelOuter[0] = 1.0;\n"
27360 " gl_TessLevelOuter[1] = 1.0;\n"
27361 " gl_TessLevelOuter[2] = 1.0;\n"
27362 " gl_TessLevelOuter[3] = 1.0;\n"
27363 " gl_TessLevelInner[0] = 1.0;\n"
27364 " gl_TessLevelInner[1] = 1.0;\n"
27367 static const GLchar* tes_tested = "#version 430 core\n"
27368 "#extension GL_ARB_enhanced_layouts : require\n"
27370 "layout(isolines, point_mode) in;\n"
27374 "in vec4 tcs_tes[];\n"
27375 "out vec4 tes_gs;\n"
27379 " vec4 result = tcs_tes[0];\n"
27383 " tes_gs += result;\n"
27386 static const GLchar* vs = "#version 430 core\n"
27387 "#extension GL_ARB_enhanced_layouts : require\n"
27390 "out vec4 vs_tcs;\n"
27394 " vs_tcs = in_vs;\n"
27397 static const GLchar* vs_tested = "#version 430 core\n"
27398 "#extension GL_ARB_enhanced_layouts : require\n"
27403 "out vec4 vs_tcs;\n"
27407 " vec4 result = in_vs;\n"
27411 " vs_tcs = result;\n"
27415 std::string source;
27416 testCase& test_case = m_test_cases[test_case_index];
27418 if (test_case.m_stage == stage)
27420 const GLchar* array = "";
27421 const GLchar* index = "";
27422 size_t position = 0;
27426 case Utils::Shader::GEOMETRY:
27427 source = gs_tested;
27431 case Utils::Shader::TESS_CTRL:
27432 source = tcs_tested;
27434 index = "[gl_InvocationID]";
27436 case Utils::Shader::TESS_EVAL:
27437 source = tes_tested;
27441 case Utils::Shader::VERTEX:
27442 source = vs_tested;
27445 TCU_FAIL("Invalid enum");
27448 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
27450 Utils::replaceToken("ARRAY", position, array, source);
27451 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
27453 Utils::replaceAllTokens("INDEX", index, source);
27457 switch (test_case.m_stage)
27459 case Utils::Shader::GEOMETRY:
27462 case Utils::Shader::FRAGMENT:
27465 case Utils::Shader::VERTEX:
27472 case Utils::Shader::TESS_CTRL:
27475 case Utils::Shader::FRAGMENT:
27478 case Utils::Shader::VERTEX:
27485 case Utils::Shader::TESS_EVAL:
27488 case Utils::Shader::FRAGMENT:
27491 case Utils::Shader::TESS_CTRL:
27494 case Utils::Shader::VERTEX:
27501 case Utils::Shader::VERTEX:
27504 case Utils::Shader::FRAGMENT:
27512 TCU_FAIL("Invalid enum");
27520 /** Get description of test case
27522 * @param test_case_index Index of test case
27524 * @return Test case description
27526 std::string XFBCaptureUnsizedArrayTest::getTestCaseName(GLuint test_case_index)
27528 std::stringstream stream;
27529 testCase& test_case = m_test_cases[test_case_index];
27531 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage);
27533 return stream.str();
27536 /** Get number of test cases
27538 * @return Number of test cases
27540 GLuint XFBCaptureUnsizedArrayTest::getTestCaseNumber()
27542 return static_cast<GLuint>(m_test_cases.size());
27545 /** Selects if "compute" stage is relevant for test
27551 bool XFBCaptureUnsizedArrayTest::isComputeRelevant(GLuint /* test_case_index */)
27556 /** Prepare all test cases
27559 void XFBCaptureUnsizedArrayTest::testInit()
27561 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
27563 /* Not aplicable for */
27564 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::FRAGMENT == stage) ||
27565 (Utils::Shader::GEOMETRY == stage) || (Utils::Shader::TESS_EVAL == stage))
27570 testCase test_case = { (Utils::Shader::STAGES)stage };
27572 m_test_cases.push_back(test_case);
27575 } /* EnhancedLayouts namespace */
27579 * @param context Rendering context.
27581 EnhancedLayoutsTests::EnhancedLayoutsTests(deqp::Context& context)
27582 : TestCaseGroup(context, "enhanced_layouts", "Verifies \"enhanced layouts\" functionality")
27584 /* Left blank on purpose */
27587 /** Initializes a texture_storage_multisample test group.
27590 void EnhancedLayoutsTests::init(void)
27592 addChild(new EnhancedLayouts::APIConstantValuesTest(m_context));
27593 addChild(new EnhancedLayouts::APIErrorsTest(m_context));
27594 addChild(new EnhancedLayouts::GLSLContantValuesTest(m_context));
27595 addChild(new EnhancedLayouts::GLSLContantImmutablityTest(m_context));
27596 addChild(new EnhancedLayouts::GLSLConstantIntegralExpressionTest(m_context));
27597 addChild(new EnhancedLayouts::UniformBlockLayoutQualifierConflictTest(m_context));
27598 addChild(new EnhancedLayouts::SSBMemberInvalidOffsetAlignmentTest(m_context));
27599 addChild(new EnhancedLayouts::SSBMemberOverlappingOffsetsTest(m_context));
27600 addChild(new EnhancedLayouts::VaryingExceedingComponentsTest(m_context));
27601 addChild(new EnhancedLayouts::VaryingComponentOfInvalidTypeTest(m_context));
27602 addChild(new EnhancedLayouts::OutputComponentAliasingTest(m_context));
27603 addChild(new EnhancedLayouts::VertexAttribLocationAPITest(m_context));
27604 addChild(new EnhancedLayouts::XFBInputTest(m_context));
27605 addChild(new EnhancedLayouts::XFBAllStagesTest(m_context));
27606 addChild(new EnhancedLayouts::XFBCaptureInactiveOutputVariableTest(m_context));
27607 addChild(new EnhancedLayouts::XFBCaptureInactiveOutputComponentTest(m_context));
27608 addChild(new EnhancedLayouts::XFBCaptureInactiveOutputBlockMemberTest(m_context));
27609 addChild(new EnhancedLayouts::XFBStrideTest(m_context));
27611 addChild(new EnhancedLayouts::UniformBlockMemberOffsetAndAlignTest(m_context));
27612 addChild(new EnhancedLayouts::UniformBlockMemberInvalidOffsetAlignmentTest(m_context));
27613 addChild(new EnhancedLayouts::UniformBlockMemberOverlappingOffsetsTest(m_context));
27614 addChild(new EnhancedLayouts::UniformBlockMemberAlignNonPowerOf2Test(m_context));
27615 addChild(new EnhancedLayouts::SSBLayoutQualifierConflictTest(m_context));
27616 addChild(new EnhancedLayouts::SSBMemberAlignNonPowerOf2Test(m_context));
27617 addChild(new EnhancedLayouts::SSBAlignmentTest(m_context));
27618 addChild(new EnhancedLayouts::VaryingStructureMemberLocationTest(m_context));
27619 addChild(new EnhancedLayouts::VaryingBlockAutomaticMemberLocationsTest(m_context));
27620 addChild(new EnhancedLayouts::VaryingComponentWithoutLocationTest(m_context));
27621 addChild(new EnhancedLayouts::InputComponentAliasingTest(m_context));
27622 addChild(new EnhancedLayouts::VaryingLocationAliasingWithMixedTypesTest(m_context));
27623 addChild(new EnhancedLayouts::VaryingLocationAliasingWithMixedInterpolationTest(m_context));
27624 addChild(new EnhancedLayouts::VaryingLocationAliasingWithMixedAuxiliaryStorageTest(m_context));
27625 addChild(new EnhancedLayouts::XFBStrideOfEmptyListTest(m_context));
27626 addChild(new EnhancedLayouts::XFBStrideOfEmptyListAndAPITest(m_context));
27627 addChild(new EnhancedLayouts::XFBTooSmallStrideTest(m_context));
27628 addChild(new EnhancedLayouts::XFBBlockMemberStrideTest(m_context));
27629 addChild(new EnhancedLayouts::XFBDuplicatedStrideTest(m_context));
27630 addChild(new EnhancedLayouts::XFBGetProgramResourceAPITest(m_context));
27631 addChild(new EnhancedLayouts::XFBMultipleVertexStreamsTest(m_context));
27632 addChild(new EnhancedLayouts::XFBExceedBufferLimitTest(m_context));
27633 addChild(new EnhancedLayouts::XFBExceedOffsetLimitTest(m_context));
27634 addChild(new EnhancedLayouts::XFBBlockMemberBufferTest(m_context));
27635 addChild(new EnhancedLayouts::XFBOutputOverlappingTest(m_context));
27636 addChild(new EnhancedLayouts::XFBInvalidOffsetAlignmentTest(m_context));
27637 addChild(new EnhancedLayouts::XFBCaptureStructTest(m_context));
27638 addChild(new EnhancedLayouts::XFBCaptureUnsizedArrayTest(m_context));
27639 addChild(new EnhancedLayouts::UniformBlockAlignmentTest(m_context));
27640 addChild(new EnhancedLayouts::SSBMemberOffsetAndAlignTest(m_context));
27641 addChild(new EnhancedLayouts::VertexAttribLocationsTest(m_context));
27642 addChild(new EnhancedLayouts::VaryingLocationsTest(m_context));
27643 addChild(new EnhancedLayouts::VaryingArrayLocationsTest(m_context));
27644 addChild(new EnhancedLayouts::VaryingStructureLocationsTest(m_context));
27645 addChild(new EnhancedLayouts::VaryingBlockLocationsTest(m_context));
27646 addChild(new EnhancedLayouts::VaryingBlockMemberLocationsTest(m_context));
27647 addChild(new EnhancedLayouts::XFBVariableStrideTest(m_context));
27648 addChild(new EnhancedLayouts::XFBBlockStrideTest(m_context));
27649 addChild(new EnhancedLayouts::XFBOverrideQualifiersWithAPITest(m_context));
27650 addChild(new EnhancedLayouts::XFBVertexStreamsTest(m_context));
27651 addChild(new EnhancedLayouts::XFBGlobalBufferTest(m_context));
27652 addChild(new EnhancedLayouts::FragmentDataLocationAPITest(m_context));
27653 addChild(new EnhancedLayouts::VaryingLocationLimitTest(m_context));
27654 addChild(new EnhancedLayouts::VaryingComponentsTest(m_context));
27655 addChild(new EnhancedLayouts::VaryingArrayComponentsTest(m_context));
27658 } /* gl4cts namespace */