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.
524 * Note that this routine doesn't consider arrays and assumes
525 * column_major matrices.
528 * - If std140 packaging and matrix; number of columns * base alignment
529 * - Otherwise; number of elements * sizeof(base_type)
531 GLuint Type::GetSize(const bool is_std140) const
533 const GLuint basic_type_size = GetTypeSize(m_basic_type);
534 const GLuint n_elements = m_n_columns * m_n_rows;
536 if (is_std140 && m_n_columns > 1)
538 return m_n_columns * GetBaseAlignment(false);
541 return basic_type_size * n_elements;
544 /** Get GLenum representing the type
548 GLenum Type::GetTypeGLenum() const
550 static const GLenum float_lut[4][4] = {
551 { GL_FLOAT, GL_FLOAT_VEC2, GL_FLOAT_VEC3, GL_FLOAT_VEC4 },
552 { 0, GL_FLOAT_MAT2, GL_FLOAT_MAT2x3, GL_FLOAT_MAT2x4 },
553 { 0, GL_FLOAT_MAT3x2, GL_FLOAT_MAT3, GL_FLOAT_MAT3x4 },
554 { 0, GL_FLOAT_MAT4x2, GL_FLOAT_MAT4x3, GL_FLOAT_MAT4 },
557 static const GLenum double_lut[4][4] = {
558 { GL_DOUBLE, GL_DOUBLE_VEC2, GL_DOUBLE_VEC3, GL_DOUBLE_VEC4 },
559 { 0, GL_DOUBLE_MAT2, GL_DOUBLE_MAT2x3, GL_DOUBLE_MAT2x4 },
560 { 0, GL_DOUBLE_MAT3x2, GL_DOUBLE_MAT3, GL_DOUBLE_MAT3x4 },
561 { 0, GL_DOUBLE_MAT4x2, GL_DOUBLE_MAT4x3, GL_DOUBLE_MAT4 },
564 static const GLenum int_lut[4] = { GL_INT, GL_INT_VEC2, GL_INT_VEC3, GL_INT_VEC4 };
566 static const GLenum uint_lut[4] = { GL_UNSIGNED_INT, GL_UNSIGNED_INT_VEC2, GL_UNSIGNED_INT_VEC3,
567 GL_UNSIGNED_INT_VEC4 };
571 if ((1 > m_n_columns) || (1 > m_n_rows) || (4 < m_n_columns) || (4 < m_n_rows))
576 switch (m_basic_type)
579 result = float_lut[m_n_columns - 1][m_n_rows - 1];
582 result = double_lut[m_n_columns - 1][m_n_rows - 1];
585 result = int_lut[m_n_rows - 1];
588 result = uint_lut[m_n_rows - 1];
591 TCU_FAIL("Invliad enum");
597 /** Calculate the numbe of components consumed by a type
598 * according to 11.1.2.1 Output Variables
600 * @return Calculated number of components for the type
602 GLuint Type::GetNumComponents() const
604 // Rule 3 of Section 7.6.2.2
605 // If the member is a three-component vector with components consuming N
606 // basic machine units, the base alignment is 4N.
607 GLuint num_components = (m_n_rows == 3 ? 4 : m_n_rows) * m_n_columns;
609 if (m_basic_type == Double)
614 return num_components;
617 /** Calculate stride for the type according to std140 rules
619 * @param alignment Alignment of type
620 * @param n_columns Number of columns
621 * @param n_array_elements Number of elements in array
623 * @return Calculated value
625 GLuint Type::CalculateStd140Stride(GLuint alignment, GLuint n_columns, GLuint n_array_elements)
627 GLuint stride = alignment * n_columns;
628 if (0 != n_array_elements)
630 stride *= n_array_elements;
636 /** Check if glsl support matrices for specific basic type
638 * @param type Basic type
640 * @return true if matrices of <type> are supported, false otherwise
642 bool Type::DoesTypeSupportMatrix(TYPES type)
657 TCU_FAIL("Invliad enum");
663 /** Creates instance of Type
665 * @param basic_type Select basic type of instance
666 * @param n_columns Number of columns
667 * @param n_rows Number of rows
669 * @return Type instance
671 Type Type::GetType(TYPES basic_type, glw::GLuint n_columns, glw::GLuint n_rows)
673 Type type = { basic_type, n_columns, n_rows };
678 /** Get Size of given type in bytes
682 * @return Size of type
684 GLuint Type::GetTypeSize(TYPES type)
691 result = sizeof(GLfloat);
694 result = sizeof(GLdouble);
697 result = sizeof(GLint);
700 result = sizeof(GLuint);
703 TCU_FAIL("Invalid enum");
709 /** Get GLenum representing given type
713 * @return GLenum value
715 GLenum Type::GetTypeGLenum(TYPES type)
731 result = GL_UNSIGNED_INT;
734 TCU_FAIL("Invalid enum");
740 /** Get proper glUniformNdv routine for vectors with specified number of rows
742 * @param gl GL functions
743 * @param n_rows Number of rows
745 * @return Function address
747 uniformNdv getUniformNdv(const glw::Functions& gl, glw::GLuint n_rows)
749 uniformNdv result = 0;
754 result = gl.uniform1dv;
757 result = gl.uniform2dv;
760 result = gl.uniform3dv;
763 result = gl.uniform4dv;
766 TCU_FAIL("Invalid number of rows");
772 /** Get proper glUniformNfv routine for vectors with specified number of rows
774 * @param gl GL functions
775 * @param n_rows Number of rows
777 * @return Function address
779 uniformNfv getUniformNfv(const glw::Functions& gl, glw::GLuint n_rows)
781 uniformNfv result = 0;
786 result = gl.uniform1fv;
789 result = gl.uniform2fv;
792 result = gl.uniform3fv;
795 result = gl.uniform4fv;
798 TCU_FAIL("Invalid number of rows");
804 /** Get proper glUniformNiv routine for vectors with specified number of rows
806 * @param gl GL functions
807 * @param n_rows Number of rows
809 * @return Function address
811 uniformNiv getUniformNiv(const glw::Functions& gl, glw::GLuint n_rows)
813 uniformNiv result = 0;
818 result = gl.uniform1iv;
821 result = gl.uniform2iv;
824 result = gl.uniform3iv;
827 result = gl.uniform4iv;
830 TCU_FAIL("Invalid number of rows");
836 /** Get proper glUniformNuiv routine for vectors with specified number of rows
838 * @param gl GL functions
839 * @param n_rows Number of rows
841 * @return Function address
843 uniformNuiv getUniformNuiv(const glw::Functions& gl, glw::GLuint n_rows)
845 uniformNuiv result = 0;
850 result = gl.uniform1uiv;
853 result = gl.uniform2uiv;
856 result = gl.uniform3uiv;
859 result = gl.uniform4uiv;
862 TCU_FAIL("Invalid number of rows");
868 /** Get proper glUniformMatrixNdv routine for matrix with specified number of columns and rows
870 * @param gl GL functions
871 * @param n_rows Number of rows
873 * @return Function address
875 uniformMatrixNdv getUniformMatrixNdv(const glw::Functions& gl, glw::GLuint n_columns, glw::GLuint n_rows)
877 uniformMatrixNdv result = 0;
885 result = gl.uniformMatrix2dv;
888 result = gl.uniformMatrix2x3dv;
891 result = gl.uniformMatrix2x4dv;
894 TCU_FAIL("Invalid number of rows");
901 result = gl.uniformMatrix3x2dv;
904 result = gl.uniformMatrix3dv;
907 result = gl.uniformMatrix3x4dv;
910 TCU_FAIL("Invalid number of rows");
917 result = gl.uniformMatrix4x2dv;
920 result = gl.uniformMatrix4x3dv;
923 result = gl.uniformMatrix4dv;
926 TCU_FAIL("Invalid number of rows");
930 TCU_FAIL("Invalid number of columns");
936 /** Get proper glUniformMatrixNfv routine for vectors with specified number of columns and rows
938 * @param gl GL functions
939 * @param n_rows Number of rows
941 * @return Function address
943 uniformMatrixNfv getUniformMatrixNfv(const glw::Functions& gl, glw::GLuint n_columns, glw::GLuint n_rows)
945 uniformMatrixNfv result = 0;
953 result = gl.uniformMatrix2fv;
956 result = gl.uniformMatrix2x3fv;
959 result = gl.uniformMatrix2x4fv;
962 TCU_FAIL("Invalid number of rows");
969 result = gl.uniformMatrix3x2fv;
972 result = gl.uniformMatrix3fv;
975 result = gl.uniformMatrix3x4fv;
978 TCU_FAIL("Invalid number of rows");
985 result = gl.uniformMatrix4x2fv;
988 result = gl.uniformMatrix4x3fv;
991 result = gl.uniformMatrix4fv;
994 TCU_FAIL("Invalid number of rows");
998 TCU_FAIL("Invalid number of columns");
1004 bool verifyVarying(Program& program, const std::string& parent_name, const Variable::Descriptor& desc,
1005 std::stringstream& stream, bool is_input)
1007 GLint component = 0;
1009 GLenum interface = GL_PROGRAM_INPUT;
1012 if (false == is_input)
1014 interface = GL_PROGRAM_OUTPUT;
1017 const std::string& name = Utils::Variable::GetReference(parent_name, desc, Utils::Variable::BASIC, 0);
1021 index = program.GetResourceIndex(name, interface);
1023 program.GetResource(interface, index, GL_LOCATION, 1 /* size */, &location);
1024 program.GetResource(interface, index, GL_LOCATION_COMPONENT, 1 /* size */, &component);
1026 catch (std::exception& exc)
1028 stream << "Failed to query program for varying: " << desc.m_name << ". Reason: " << exc.what() << "\n";
1035 if (location != desc.m_expected_location)
1037 stream << "Attribute: " << desc.m_name << " - invalid location: " << location
1038 << " expected: " << desc.m_expected_location << std::endl;
1041 if (component != desc.m_expected_component)
1043 stream << "Attribute: " << desc.m_name << " - invalid component: " << component
1044 << " expected: " << desc.m_expected_component << std::endl;
1051 /** Query program resource for given variable and verify that everything is as expected
1053 * @param program Program object
1054 * @param variable Variable object
1055 * @param stream Stream that will be used to log any error
1056 * @param is_input Selects if varying is input or output
1058 * @return true if verification is positive, false otherwise
1060 bool checkVarying(Program& program, const Variable& variable, std::stringstream& stream, bool is_input)
1064 if (variable.IsBlock())
1066 Utils::Interface* interface = variable.m_descriptor.m_interface;
1067 const size_t n_members = interface->m_members.size();
1069 for (size_t i = 0; i < n_members; ++i)
1071 const Variable::Descriptor& member = interface->m_members[i];
1072 bool member_result = verifyVarying(program, interface->m_name, member, stream, is_input);
1074 if (false == member_result)
1081 To query the the location of struct member by glGetProgramResource, we need pass the variable name "gs_fs_output[0].single",
1082 but in original implementation, the test pass the name "Data.single", which can't get any valid result.
1087 layout (location = 0) in Data gs_fs_output[1];
1089 else if (variable.IsStruct())
1091 Utils::Interface* interface = variable.m_descriptor.m_interface;
1092 const size_t n_members = interface->m_members.size();
1093 std::string structVariable = variable.m_descriptor.m_name;
1094 // If struct variable is an array
1095 if (0 != variable.m_descriptor.m_n_array_elements)
1097 for (GLuint i = 0; i < variable.m_descriptor.m_n_array_elements; i++)
1100 sprintf(buffer, "%d", i);
1101 structVariable.append("[");
1102 structVariable.append(buffer);
1103 structVariable.append("]");
1104 for (size_t j = 0; j < n_members; ++j)
1106 const Variable::Descriptor& member = interface->m_members[j];
1107 bool member_result = verifyVarying(program, structVariable, member, stream, is_input);
1109 if (false == member_result)
1118 for (GLuint i = 0; i < n_members; ++i)
1120 const Variable::Descriptor& member = interface->m_members[i];
1121 bool member_result = verifyVarying(program, structVariable, member, stream, is_input);
1123 if (false == member_result)
1132 result = verifyVarying(program, "", variable.m_descriptor, stream, is_input);
1137 /** Query program resource for given variable and verify that everything is as expected
1139 * @param program Program object
1140 * @param variable Variable object
1141 * @param stream Stream that will be used to log any error
1143 * @return true if verification is positive, false otherwise
1145 bool checkUniform(Program& program, const Utils::Variable& variable, std::stringstream& stream)
1149 if (false == variable.IsBlock())
1151 TCU_FAIL("Not implemented");
1155 Utils::Interface* interface = variable.m_descriptor.m_interface;
1157 size_t size = interface->m_members.size();
1159 std::vector<GLuint> indices;
1160 std::vector<const char*> names;
1161 std::vector<std::string> names_str;
1162 std::vector<GLint> offsets;
1164 indices.resize(size);
1166 names_str.resize(size);
1167 offsets.resize(size);
1169 for (size_t i = 0; i < size; ++i)
1174 const std::string& name =
1175 Utils::Variable::GetReference(interface->m_name, interface->m_members[i], Utils::Variable::BASIC, 0);
1177 if (Utils::Variable::INTERFACE == interface->m_members[i].m_type)
1179 const std::string& member_name = Utils::Variable::GetReference(
1180 name, interface->m_members[i].m_interface->m_members[0], Utils::Variable::BASIC, 0);
1182 names_str[i] = member_name;
1186 names_str[i] = name;
1189 names[i] = names_str[i].c_str();
1194 program.GetUniformIndices(static_cast<glw::GLsizei>(size), &names[0], &indices[0]);
1195 program.GetActiveUniformsiv(static_cast<glw::GLsizei>(size), &indices[0], GL_UNIFORM_OFFSET, &offsets[0]);
1197 catch (std::exception& exc)
1199 stream << "Failed to query program for uniforms in block: " << variable.m_descriptor.m_name
1200 << ". Reason: " << exc.what() << "\n";
1205 for (size_t i = 0; i < size; ++i)
1207 Utils::Variable::Descriptor& desc = interface->m_members[i];
1209 if (offsets[i] != (GLint)desc.m_offset)
1211 stream << "Uniform: " << desc.m_name << " - invalid offset: " << offsets[i]
1212 << " expected: " << desc.m_offset << std::endl;
1221 /** Query program resource for given variable and verify that everything is as expected
1223 * @param program Program object
1224 * @param variable Variable object
1225 * @param stream Stream that will be used to log any error
1227 * @return true if verification is positive, false otherwise
1229 bool checkSSB(Program& program, const Utils::Variable& variable, std::stringstream& stream)
1233 if (false == variable.IsBlock())
1235 TCU_FAIL("Not implemented");
1239 Utils::Interface* interface = variable.m_descriptor.m_interface;
1241 size_t size = interface->m_members.size();
1243 for (size_t i = 0; i < size; ++i)
1246 std::string name_str = "";
1249 const std::string& name =
1250 Utils::Variable::GetReference(interface->m_name, interface->m_members[i], Utils::Variable::BASIC, 0);
1252 if (Utils::Variable::INTERFACE == interface->m_members[i].m_type)
1254 const std::string& member_name = Utils::Variable::GetReference(
1255 name, interface->m_members[i].m_interface->m_members[0], Utils::Variable::BASIC, 0);
1257 name_str = member_name;
1266 index = program.GetResourceIndex(name_str, GL_BUFFER_VARIABLE);
1268 program.GetResource(GL_BUFFER_VARIABLE, index, GL_OFFSET, 1, &offset);
1270 catch (std::exception& exc)
1272 stream << "Failed to query program for buffer variable: " << variable.m_descriptor.m_name
1273 << ". Reason: " << exc.what() << "\n";
1278 Utils::Variable::Descriptor& desc = interface->m_members[i];
1280 if (offset != (GLint)desc.m_offset)
1282 stream << "Uniform: " << desc.m_name << " - invalid offset: " << offset
1283 << " expected: " << desc.m_offset << std::endl;
1292 /** Query program resources at given stage and verifies results
1294 * @param program Program object
1295 * @param program_interface Definition of program interface
1296 * @param stage Stage to be verified
1297 * @param check_inputs Select if inputs should be verified
1298 * @param check_outputs Select if output should be verified
1299 * @param check_uniforms Select if uniforms should be verified
1300 * @param check_ssbs Select if buffers should be verified
1301 * @param stream Stream that will be used to log any error
1303 * @return true if verification is positive, false otherwise
1305 bool checkProgramStage(Program& program, const ProgramInterface& program_interface, Utils::Shader::STAGES stage,
1306 bool check_inputs, bool check_outputs, bool check_uniforms, bool check_ssbs,
1307 std::stringstream& stream)
1309 typedef Variable::PtrVector::const_iterator const_iterator;
1311 const ShaderInterface& interface = program_interface.GetShaderInterface(stage);
1316 if (true == check_inputs)
1318 const Variable::PtrVector& inputs = interface.m_inputs;
1320 for (const_iterator it = inputs.begin(); it != inputs.end(); ++it)
1322 if (false == checkVarying(program, **it, stream, true))
1330 if (true == check_outputs)
1332 const Variable::PtrVector& outputs = interface.m_outputs;
1334 for (const_iterator it = outputs.begin(); it != outputs.end(); ++it)
1336 if (false == checkVarying(program, **it, stream, false))
1344 if (true == check_uniforms)
1346 const Variable::PtrVector& uniforms = interface.m_uniforms;
1348 for (const_iterator it = uniforms.begin(); it != uniforms.end(); ++it)
1350 if (false == checkUniform(program, **it, stream))
1358 if (true == check_ssbs)
1360 const Variable::PtrVector& ssbs = interface.m_ssb_blocks;
1362 for (const_iterator it = ssbs.begin(); it != ssbs.end(); ++it)
1364 if (false == checkSSB(program, **it, stream))
1374 /** Query resources of monolithic compute program and verifies results
1376 * @param program Program object
1377 * @param program_interface Definition of program interface
1378 * @param stream Stream that will be used to log any error
1380 * @return true if verification is positive, false otherwise
1382 bool checkMonolithicComputeProgramInterface(Program& program, const ProgramInterface& program_interface,
1383 std::stringstream& stream)
1387 if (false == checkProgramStage(program, program_interface, Shader::COMPUTE, false, false, true, true, stream))
1396 /** Query resources of monolithic draw program and verifies results
1398 * @param program Program object
1399 * @param program_interface Definition of program interface
1400 * @param stream Stream that will be used to log any error
1402 * @return true if verification is positive, false otherwise
1404 bool checkMonolithicDrawProgramInterface(Program& program, const ProgramInterface& program_interface,
1405 std::stringstream& stream)
1409 if (false == checkProgramStage(program, program_interface, Shader::VERTEX, true, false, true, true, stream))
1418 /** Query resources of separable draw program and verifies results
1420 * @param program Program object
1421 * @param program_interface Definition of program interface
1422 * @param stream Stream that will be used to log any error
1424 * @return true if verification is positive, false otherwise
1426 bool checkSeparableDrawProgramInterface(Program& program, const ProgramInterface& program_interface,
1427 Utils::Shader::STAGES stage, std::stringstream& stream)
1431 if (false == checkProgramStage(program, program_interface, stage, true, true, true, true, stream))
1440 /** Check if extension is supported
1442 * @param context Test context
1443 * @param extension_name Name of extension
1445 * @return true if extension is supported, false otherwise
1447 bool isExtensionSupported(deqp::Context& context, const GLchar* extension_name)
1449 const std::vector<std::string>& extensions = context.getContextInfo().getExtensions();
1451 if (std::find(extensions.begin(), extensions.end(), extension_name) == extensions.end())
1459 /** Check if GL context meets version requirements
1461 * @param gl Functions
1462 * @param required_major Minimum required MAJOR_VERSION
1463 * @param required_minor Minimum required MINOR_VERSION
1465 * @return true if GL context version is at least as requested, false otherwise
1467 bool isGLVersionAtLeast(const Functions& gl, GLint required_major, GLint required_minor)
1469 glw::GLint major = 0;
1470 glw::GLint minor = 0;
1472 gl.getIntegerv(GL_MAJOR_VERSION, &major);
1473 gl.getIntegerv(GL_MINOR_VERSION, &minor);
1475 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
1477 if (major > required_major)
1479 /* Major is higher than required one */
1482 else if (major == required_major)
1484 if (minor >= required_minor)
1486 /* Major is equal to required one */
1487 /* Minor is higher than or equal to required one */
1492 /* Major is equal to required one */
1493 /* Minor is lower than required one */
1499 /* Major is lower than required one */
1504 /** Replace first occurance of <token> with <text> in <string> starting at <search_posistion>
1506 * @param token Token string
1507 * @param search_position Position at which find will start, it is updated to position at which replaced text ends
1508 * @param text String that will be used as replacement for <token>
1509 * @param string String to work on
1511 void replaceToken(const GLchar* token, size_t& search_position, const GLchar* text, std::string& string)
1513 const size_t text_length = strlen(text);
1514 const size_t token_length = strlen(token);
1515 const size_t token_position = string.find(token, search_position);
1517 #if DEBUG_REPLACE_TOKEN
1518 if (std::string::npos == token_position)
1520 string.append("\n\nInvalid token: ");
1521 string.append(token);
1523 TCU_FAIL(string.c_str());
1525 #endif /* DEBUG_REPLACE_TOKEN */
1527 string.replace(token_position, token_length, text, text_length);
1529 search_position = token_position + text_length;
1532 /** Replace all occurances of <token> with <text> in <string>
1534 * @param token Token string
1535 * @param text String that will be used as replacement for <token>
1536 * @param string String to work on
1538 void replaceAllTokens(const GLchar* token, const GLchar* text, std::string& string)
1540 const size_t text_length = strlen(text);
1541 const size_t token_length = strlen(token);
1543 size_t search_position = 0;
1547 const size_t token_position = string.find(token, search_position);
1549 if (std::string::npos == token_position)
1554 search_position = token_position + text_length;
1556 string.replace(token_position, token_length, text, text_length);
1560 /** Rounds up the value to the next power of 2.
1561 * This routine does not work for 0, see the url for explanations.
1563 * @param value Starting point
1565 * @return Calculated value
1567 glw::GLuint roundUpToPowerOf2(glw::GLuint value)
1569 /* Taken from: graphics.stanford.edu/~seander/bithacks.html */
1572 value |= value >> 1;
1573 value |= value >> 2;
1574 value |= value >> 4;
1575 value |= value >> 8;
1576 value |= value >> 16;
1583 /** Insert elements of list into string.
1584 * List in string is represented either by token "LIST" or "SEPARATORLIST".
1585 * If SEPARATORLIST is available, than SEPARATOR is replaced with <separator>.
1586 * LIST is replaced with <element>SEPARATORLIST
1588 * @param element Element to be inserted
1589 * @param separator Separator inserted between elements
1590 * @param search_position Position in string, where search for list should start
1591 * @param string String
1593 void insertElementOfList(const GLchar* element, const GLchar* separator, size_t& search_position, std::string& string)
1595 static const char* list = g_list;
1596 static const char* sep_list = "SEPARATORLIST";
1598 /* Try to get "list" positions */
1599 const size_t list_position = string.find(list, search_position);
1600 const size_t sep_list_position = string.find(sep_list, search_position);
1602 /* There is no list in string */
1603 if (std::string::npos == list_position)
1608 if (9 /* strlen(SEPARATOR) */ == list_position - sep_list_position)
1610 replaceToken("SEPARATOR", search_position, separator, string);
1613 /* Save search_position */
1614 const size_t start_position = search_position;
1616 /* Prepare new element */
1617 replaceToken("LIST", search_position, "ELEMENTSEPARATORLIST", string);
1619 /* Restore search_position */
1620 search_position = start_position;
1622 /* Replace element and separator */
1623 replaceToken("ELEMENT", search_position, element, string);
1626 /** Close list in string.
1627 * If SEPARATORLIST is available, than SEPARATOR is replaced with <separator>
1628 * LIST is replaced with ""
1630 * @param separator Separator inserted between elements
1631 * @param search_position Position in string, where search for list should start
1632 * @param string String
1634 void endList(const glw::GLchar* separator, size_t& search_position, std::string& string)
1636 const size_t sep_position = string.find("SEPARATOR", search_position);
1637 if (std::string::npos != sep_position)
1639 replaceToken("SEPARATOR", search_position, separator, string);
1642 replaceToken("LIST", search_position, "", string);
1645 /* Buffer constants */
1646 const GLuint Buffer::m_invalid_id = -1;
1650 * @param context CTS context.
1652 Buffer::Buffer(deqp::Context& context) : m_id(m_invalid_id), m_buffer(Array), m_context(context)
1664 /** Initialize buffer instance
1666 * @param buffer Buffer type
1667 * @param usage Buffer usage enum
1668 * @param size <size> parameter
1669 * @param data <data> parameter
1671 void Buffer::Init(BUFFERS buffer, USAGE usage, GLsizeiptr size, GLvoid* data)
1673 /* Delete previous buffer instance */
1678 const Functions& gl = m_context.getRenderContext().getFunctions();
1681 Bind(gl, m_id, m_buffer);
1682 Data(gl, m_buffer, usage, size, data);
1685 /** Release buffer instance
1688 void Buffer::Release()
1690 if (m_invalid_id != m_id)
1692 const Functions& gl = m_context.getRenderContext().getFunctions();
1694 gl.deleteBuffers(1, &m_id);
1695 m_id = m_invalid_id;
1699 /** Binds buffer to its target
1702 void Buffer::Bind() const
1704 const Functions& gl = m_context.getRenderContext().getFunctions();
1706 Bind(gl, m_id, m_buffer);
1709 /** Binds indexed buffer
1711 * @param index <index> parameter
1713 void Buffer::BindBase(GLuint index) const
1715 const Functions& gl = m_context.getRenderContext().getFunctions();
1717 BindBase(gl, m_id, m_buffer, index);
1720 /** Binds range of buffer
1722 * @param index <index> parameter
1723 * @param offset <offset> parameter
1724 * @param size <size> parameter
1726 void Buffer::BindRange(GLuint index, GLintptr offset, GLsizeiptr size) const
1728 const Functions& gl = m_context.getRenderContext().getFunctions();
1730 BindRange(gl, m_id, m_buffer, index, offset, size);
1733 /** Allocate memory for buffer and sends initial content
1735 * @param usage Buffer usage enum
1736 * @param size <size> parameter
1737 * @param data <data> parameter
1739 void Buffer::Data(USAGE usage, glw::GLsizeiptr size, glw::GLvoid* data)
1741 const Functions& gl = m_context.getRenderContext().getFunctions();
1743 Data(gl, m_buffer, usage, size, data);
1746 /** Maps contents of buffer into CPU space
1748 * @param access Requested access
1750 * @return Pointer to memory region available for CPU
1752 GLvoid* Buffer::Map(ACCESS access)
1754 const Functions& gl = m_context.getRenderContext().getFunctions();
1756 return Map(gl, m_buffer, access);
1759 /** Allocate memory for buffer and sends initial content
1761 * @param offset Offset in buffer
1762 * @param size <size> parameter
1763 * @param data <data> parameter
1765 void Buffer::SubData(glw::GLintptr offset, glw::GLsizeiptr size, glw::GLvoid* data)
1767 const Functions& gl = m_context.getRenderContext().getFunctions();
1769 SubData(gl, m_buffer, offset, size, data);
1772 /** Maps contents of buffer into CPU space
1774 void Buffer::UnMap()
1776 const Functions& gl = m_context.getRenderContext().getFunctions();
1778 return UnMap(gl, m_buffer);
1781 /** Bind buffer to given target
1783 * @param gl GL functions
1784 * @param id Id of buffer
1785 * @param buffer Buffer enum
1787 void Buffer::Bind(const Functions& gl, GLuint id, BUFFERS buffer)
1789 GLenum target = GetBufferGLenum(buffer);
1791 gl.bindBuffer(target, id);
1792 GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffer");
1795 /** Binds indexed buffer
1797 * @param gl GL functions
1798 * @param id Id of buffer
1799 * @param buffer Buffer enum
1800 * @param index <index> parameter
1802 void Buffer::BindBase(const Functions& gl, GLuint id, BUFFERS buffer, GLuint index)
1804 GLenum target = GetBufferGLenum(buffer);
1806 gl.bindBufferBase(target, index, id);
1807 GLU_EXPECT_NO_ERROR(gl.getError(), "BindBufferBase");
1810 /** Binds buffer range
1812 * @param gl GL functions
1813 * @param id Id of buffer
1814 * @param buffer Buffer enum
1815 * @param index <index> parameter
1816 * @param offset <offset> parameter
1817 * @param size <size> parameter
1819 void Buffer::BindRange(const Functions& gl, GLuint id, BUFFERS buffer, GLuint index, GLintptr offset, GLsizeiptr size)
1821 GLenum target = GetBufferGLenum(buffer);
1823 gl.bindBufferRange(target, index, id, offset, size);
1824 GLU_EXPECT_NO_ERROR(gl.getError(), "BindBufferRange");
1827 /** Allocate memory for buffer and sends initial content
1829 * @param gl GL functions
1830 * @param buffer Buffer enum
1831 * @param usage Buffer usage enum
1832 * @param size <size> parameter
1833 * @param data <data> parameter
1835 void Buffer::Data(const glw::Functions& gl, BUFFERS buffer, USAGE usage, glw::GLsizeiptr size, glw::GLvoid* data)
1837 GLenum target = GetBufferGLenum(buffer);
1838 GLenum gl_usage = GetUsageGLenum(usage);
1840 gl.bufferData(target, size, data, gl_usage);
1841 GLU_EXPECT_NO_ERROR(gl.getError(), "BufferData");
1844 /** Allocate memory for buffer and sends initial content
1846 * @param gl GL functions
1847 * @param buffer Buffer enum
1848 * @param offset Offset in buffer
1849 * @param size <size> parameter
1850 * @param data <data> parameter
1852 void Buffer::SubData(const glw::Functions& gl, BUFFERS buffer, glw::GLintptr offset, glw::GLsizeiptr size,
1855 GLenum target = GetBufferGLenum(buffer);
1857 gl.bufferSubData(target, offset, size, data);
1858 GLU_EXPECT_NO_ERROR(gl.getError(), "BufferSubData");
1863 * @param gl GL functions
1864 * @param out_id Id of buffer
1866 void Buffer::Generate(const Functions& gl, GLuint& out_id)
1868 GLuint id = m_invalid_id;
1870 gl.genBuffers(1, &id);
1871 GLU_EXPECT_NO_ERROR(gl.getError(), "GenBuffers");
1873 if (m_invalid_id == id)
1875 TCU_FAIL("Got invalid id");
1881 /** Maps buffer content
1883 * @param gl GL functions
1884 * @param buffer Buffer enum
1885 * @param access Access rights for mapped region
1887 * @return Mapped memory
1889 void* Buffer::Map(const Functions& gl, BUFFERS buffer, ACCESS access)
1891 GLenum target = GetBufferGLenum(buffer);
1892 GLenum gl_access = GetAccessGLenum(access);
1894 void* result = gl.mapBuffer(target, gl_access);
1895 GLU_EXPECT_NO_ERROR(gl.getError(), "MapBuffer");
1903 void Buffer::UnMap(const Functions& gl, BUFFERS buffer)
1905 GLenum target = GetBufferGLenum(buffer);
1907 gl.unmapBuffer(target);
1908 GLU_EXPECT_NO_ERROR(gl.getError(), "UnmapBuffer");
1911 /** Return GLenum representation of requested access
1913 * @param access Requested access
1915 * @return GLenum value
1917 GLenum Buffer::GetAccessGLenum(ACCESS access)
1924 result = GL_READ_ONLY;
1927 result = GL_WRITE_ONLY;
1930 result = GL_READ_WRITE;
1933 TCU_FAIL("Invalid enum");
1939 /** Return GLenum representation of requested buffer type
1941 * @param buffer Requested buffer type
1943 * @return GLenum value
1945 GLenum Buffer::GetBufferGLenum(BUFFERS buffer)
1952 result = GL_ARRAY_BUFFER;
1955 result = GL_ELEMENT_ARRAY_BUFFER;
1957 case Shader_Storage:
1958 result = GL_SHADER_STORAGE_BUFFER;
1961 result = GL_TEXTURE_BUFFER;
1963 case Transform_feedback:
1964 result = GL_TRANSFORM_FEEDBACK_BUFFER;
1967 result = GL_UNIFORM_BUFFER;
1970 TCU_FAIL("Invalid enum");
1976 /** Return GLenum representation of requested usage
1978 * @param usage Requested usage
1980 * @return GLenum value
1982 GLenum Buffer::GetUsageGLenum(USAGE usage)
1989 result = GL_DYNAMIC_COPY;
1992 result = GL_DYNAMIC_DRAW;
1995 result = GL_DYNAMIC_READ;
1998 result = GL_STATIC_COPY;
2001 result = GL_STATIC_DRAW;
2004 result = GL_STATIC_READ;
2007 result = GL_STREAM_COPY;
2010 result = GL_STREAM_DRAW;
2013 result = GL_STREAM_READ;
2016 TCU_FAIL("Invalid enum");
2022 /** Returns name of buffer target
2024 * @param buffer Target enum
2026 * @return Name of target
2028 const GLchar* Buffer::GetBufferName(BUFFERS buffer)
2030 const GLchar* name = 0;
2040 case Shader_Storage:
2041 name = "Shader_Storage";
2046 case Transform_feedback:
2047 name = "Transform_feedback";
2053 TCU_FAIL("Invalid enum");
2059 /* Framebuffer constants */
2060 const GLuint Framebuffer::m_invalid_id = -1;
2064 * @param context CTS context
2066 Framebuffer::Framebuffer(deqp::Context& context) : m_id(m_invalid_id), m_context(context)
2068 /* Nothing to be done here */
2074 Framebuffer::~Framebuffer()
2079 /** Initialize framebuffer instance
2082 void Framebuffer::Init()
2084 /* Delete previous instance */
2087 const Functions& gl = m_context.getRenderContext().getFunctions();
2092 /** Release framebuffer instance
2095 void Framebuffer::Release()
2097 if (m_invalid_id != m_id)
2099 const Functions& gl = m_context.getRenderContext().getFunctions();
2101 gl.deleteFramebuffers(1, &m_id);
2102 m_id = m_invalid_id;
2106 /** Attach texture to specified attachment
2108 * @param attachment Attachment
2109 * @param texture_id Texture id
2110 * @param width Texture width
2111 * @param height Texture height
2113 void Framebuffer::AttachTexture(GLenum attachment, GLuint texture_id, GLuint width, GLuint height)
2115 const Functions& gl = m_context.getRenderContext().getFunctions();
2117 AttachTexture(gl, attachment, texture_id, width, height);
2120 /** Binds framebuffer to DRAW_FRAMEBUFFER
2123 void Framebuffer::Bind()
2125 const Functions& gl = m_context.getRenderContext().getFunctions();
2130 /** Clear framebuffer
2132 * @param mask <mask> parameter of glClear. Decides which shall be cleared
2134 void Framebuffer::Clear(GLenum mask)
2136 const Functions& gl = m_context.getRenderContext().getFunctions();
2141 /** Specifies clear color
2143 * @param red Red channel
2144 * @param green Green channel
2145 * @param blue Blue channel
2146 * @param alpha Alpha channel
2148 void Framebuffer::ClearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
2150 const Functions& gl = m_context.getRenderContext().getFunctions();
2152 ClearColor(gl, red, green, blue, alpha);
2155 /** Attach texture to specified attachment
2157 * @param gl GL functions
2158 * @param attachment Attachment
2159 * @param texture_id Texture id
2160 * @param width Texture width
2161 * @param height Texture height
2163 void Framebuffer::AttachTexture(const Functions& gl, GLenum attachment, GLuint texture_id, GLuint width, GLuint height)
2165 gl.framebufferTexture(GL_DRAW_FRAMEBUFFER, attachment, texture_id, 0 /* level */);
2166 GLU_EXPECT_NO_ERROR(gl.getError(), "FramebufferTexture");
2168 gl.viewport(0 /* x */, 0 /* y */, width, height);
2169 GLU_EXPECT_NO_ERROR(gl.getError(), "Viewport");
2172 /** Binds framebuffer to DRAW_FRAMEBUFFER
2174 * @param gl GL functions
2175 * @param id ID of framebuffer
2177 void Framebuffer::Bind(const Functions& gl, GLuint id)
2179 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, id);
2180 GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer");
2183 /** Clear framebuffer
2185 * @param gl GL functions
2186 * @param mask <mask> parameter of glClear. Decides which shall be cleared
2188 void Framebuffer::Clear(const Functions& gl, GLenum mask)
2191 GLU_EXPECT_NO_ERROR(gl.getError(), "Clear");
2194 /** Specifies clear color
2196 * @param gl GL functions
2197 * @param red Red channel
2198 * @param green Green channel
2199 * @param blue Blue channel
2200 * @param alpha Alpha channel
2202 void Framebuffer::ClearColor(const Functions& gl, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
2204 gl.clearColor(red, green, blue, alpha);
2205 GLU_EXPECT_NO_ERROR(gl.getError(), "ClearColor");
2208 /** Generate framebuffer
2211 void Framebuffer::Generate(const Functions& gl, GLuint& out_id)
2213 GLuint id = m_invalid_id;
2215 gl.genFramebuffers(1, &id);
2216 GLU_EXPECT_NO_ERROR(gl.getError(), "GenFramebuffers");
2218 if (m_invalid_id == id)
2220 TCU_FAIL("Invalid id");
2226 /* Shader's constants */
2227 const GLuint Shader::m_invalid_id = 0;
2231 * @param context CTS context.
2233 Shader::Shader(deqp::Context& context) : m_id(m_invalid_id), m_context(context)
2235 /* Nothing to be done here */
2246 /** Initialize shader instance
2248 * @param stage Shader stage
2249 * @param source Source code
2251 void Shader::Init(STAGES stage, const std::string& source)
2253 if (true == source.empty())
2255 /* No source == no shader */
2259 /* Delete any previous shader */
2262 /* Create, set source and compile */
2263 const Functions& gl = m_context.getRenderContext().getFunctions();
2265 Create(gl, stage, m_id);
2266 Source(gl, m_id, source);
2272 catch (const CompilationException& exc)
2274 throw InvalidSourceException(exc.what(), source, stage);
2278 /** Release shader instance
2281 void Shader::Release()
2283 if (m_invalid_id != m_id)
2285 const Functions& gl = m_context.getRenderContext().getFunctions();
2287 gl.deleteShader(m_id);
2288 m_id = m_invalid_id;
2294 * @param gl GL functions
2295 * @param id Shader id
2297 void Shader::Compile(const Functions& gl, GLuint id)
2299 GLint status = GL_FALSE;
2302 gl.compileShader(id);
2303 GLU_EXPECT_NO_ERROR(gl.getError(), "CompileShader");
2305 /* Get compilation status */
2306 gl.getShaderiv(id, GL_COMPILE_STATUS, &status);
2307 GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");
2309 /* Log compilation error */
2310 if (GL_TRUE != status)
2312 glw::GLint length = 0;
2313 std::string message;
2315 /* Error log length */
2316 gl.getShaderiv(id, GL_INFO_LOG_LENGTH, &length);
2317 GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");
2319 /* Prepare storage */
2320 message.resize(length, 0);
2323 gl.getShaderInfoLog(id, length, 0, &message[0]);
2324 GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderInfoLog");
2326 throw CompilationException(message.c_str());
2332 * @param gl GL functions
2333 * @param stage Shader stage
2334 * @param out_id Shader id
2336 void Shader::Create(const Functions& gl, STAGES stage, GLuint& out_id)
2338 const GLenum shaderType = GetShaderStageGLenum(stage);
2339 const GLuint id = gl.createShader(shaderType);
2340 GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
2342 if (m_invalid_id == id)
2344 TCU_FAIL("Failed to create shader");
2350 /** Set shader's source code
2352 * @param gl GL functions
2353 * @param id Shader id
2354 * @param source Shader source code
2356 void Shader::Source(const Functions& gl, GLuint id, const std::string& source)
2358 const GLchar* code = source.c_str();
2360 gl.shaderSource(id, 1 /* count */, &code, 0 /* lengths */);
2361 GLU_EXPECT_NO_ERROR(gl.getError(), "ShaderSource");
2364 /** Get GLenum repesenting shader stage
2366 * @param stage Shader stage
2370 GLenum Shader::GetShaderStageGLenum(STAGES stage)
2377 result = GL_COMPUTE_SHADER;
2380 result = GL_FRAGMENT_SHADER;
2383 result = GL_GEOMETRY_SHADER;
2386 result = GL_TESS_CONTROL_SHADER;
2389 result = GL_TESS_EVALUATION_SHADER;
2392 result = GL_VERTEX_SHADER;
2395 TCU_FAIL("Invalid enum");
2401 /** Get string representing name of shader stage
2403 * @param stage Shader stage
2405 * @return String with name of shader stage
2407 const glw::GLchar* Shader::GetStageName(STAGES stage)
2409 const GLchar* result = 0;
2420 result = "tessellation control";
2423 result = "tessellation evaluation";
2426 result = "geometry";
2429 result = "fragment";
2432 TCU_FAIL("Invalid enum");
2438 /** Logs shader source
2440 * @param context CTS context
2441 * @param source Source of shader
2442 * @param stage Shader stage
2444 void Shader::LogSource(deqp::Context& context, const std::string& source, STAGES stage)
2446 /* Skip empty shaders */
2447 if (true == source.empty())
2452 context.getTestContext().getLog() << tcu::TestLog::Message
2453 << "Shader source. Stage: " << Shader::GetStageName(stage)
2454 << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(source);
2459 * @param message Compilation error message
2461 Shader::CompilationException::CompilationException(const GLchar* message)
2463 m_message = message;
2466 /** Returns error messages
2468 * @return Compilation error message
2470 const char* Shader::CompilationException::what() const throw()
2472 return m_message.c_str();
2477 * @param message Compilation error message
2479 Shader::InvalidSourceException::InvalidSourceException(const GLchar* error_message, const std::string& source,
2481 : m_message(error_message), m_source(source), m_stage(stage)
2485 /** Returns error messages
2487 * @return Compilation error message
2489 const char* Shader::InvalidSourceException::what() const throw()
2491 return "Compilation error";
2494 /** Logs error message and shader sources **/
2495 void Shader::InvalidSourceException::log(deqp::Context& context) const
2497 context.getTestContext().getLog() << tcu::TestLog::Message << "Failed to compile shader: " << m_message.c_str()
2498 << tcu::TestLog::EndMessage;
2500 LogSource(context, m_source, m_stage);
2503 /* Program constants */
2504 const GLuint Pipeline::m_invalid_id = 0;
2508 * @param context CTS context.
2510 Pipeline::Pipeline(deqp::Context& context) : m_id(m_invalid_id), m_context(context)
2512 /* Nothing to be done here */
2518 Pipeline::~Pipeline()
2523 /** Initialize pipline object
2526 void Pipeline::Init()
2530 const Functions& gl = m_context.getRenderContext().getFunctions();
2533 gl.genProgramPipelines(1, &m_id);
2534 GLU_EXPECT_NO_ERROR(gl.getError(), "GenProgramPipelines");
2537 /** Release pipeline object
2540 void Pipeline::Release()
2542 if (m_invalid_id != m_id)
2544 const Functions& gl = m_context.getRenderContext().getFunctions();
2547 gl.deleteProgramPipelines(1, &m_id);
2548 GLU_EXPECT_NO_ERROR(gl.getError(), "DeleteProgramPipelines");
2550 m_id = m_invalid_id;
2557 void Pipeline::Bind()
2559 const Functions& gl = m_context.getRenderContext().getFunctions();
2564 /** Set which stages should be active
2566 * @param program_id Id of program
2567 * @param stages Logical combination of enums representing stages
2569 void Pipeline::UseProgramStages(GLuint program_id, GLenum stages)
2571 const Functions& gl = m_context.getRenderContext().getFunctions();
2573 UseProgramStages(gl, m_id, program_id, stages);
2578 * @param gl Functiions
2579 * @param id Pipeline id
2581 void Pipeline::Bind(const Functions& gl, GLuint id)
2583 gl.bindProgramPipeline(id);
2584 GLU_EXPECT_NO_ERROR(gl.getError(), "BindProgramPipeline");
2587 /** Set which stages should be active
2589 * @param gl Functiions
2590 * @param id Pipeline id
2591 * @param program_id Id of program
2592 * @param stages Logical combination of enums representing stages
2594 void Pipeline::UseProgramStages(const Functions& gl, GLuint id, GLuint program_id, GLenum stages)
2596 gl.useProgramStages(id, stages, program_id);
2597 GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgramStages");
2600 /* Program constants */
2601 const GLuint Program::m_invalid_id = 0;
2605 * @param context CTS context.
2607 Program::Program(deqp::Context& context)
2608 : m_id(m_invalid_id)
2609 , m_compute(context)
2610 , m_fragment(context)
2611 , m_geometry(context)
2612 , m_tess_ctrl(context)
2613 , m_tess_eval(context)
2615 , m_context(context)
2617 /* Nothing to be done here */
2628 /** Initialize program instance
2630 * @param compute_shader Compute shader source code
2631 * @param fragment_shader Fragment shader source code
2632 * @param geometry_shader Geometry shader source code
2633 * @param tessellation_control_shader Tessellation control shader source code
2634 * @param tessellation_evaluation_shader Tessellation evaluation shader source code
2635 * @param vertex_shader Vertex shader source code
2636 * @param captured_varyings Vector of variables to be captured with transfrom feedback
2637 * @param capture_interleaved Select mode of transform feedback (separate or interleaved)
2638 * @param is_separable Selects if monolithic or separable program should be built. Defaults to false
2640 void Program::Init(const std::string& compute_shader, const std::string& fragment_shader,
2641 const std::string& geometry_shader, const std::string& tessellation_control_shader,
2642 const std::string& tessellation_evaluation_shader, const std::string& vertex_shader,
2643 const NameVector& captured_varyings, bool capture_interleaved, bool is_separable)
2645 /* Delete previous program */
2648 /* GL entry points */
2649 const Functions& gl = m_context.getRenderContext().getFunctions();
2651 /* Initialize shaders */
2652 m_compute.Init(Shader::COMPUTE, compute_shader);
2653 m_fragment.Init(Shader::FRAGMENT, fragment_shader);
2654 m_geometry.Init(Shader::GEOMETRY, geometry_shader);
2655 m_tess_ctrl.Init(Shader::TESS_CTRL, tessellation_control_shader);
2656 m_tess_eval.Init(Shader::TESS_EVAL, tessellation_evaluation_shader);
2657 m_vertex.Init(Shader::VERTEX, vertex_shader);
2659 /* Create program, set up transform feedback and attach shaders */
2661 Capture(gl, m_id, captured_varyings, capture_interleaved);
2662 Attach(gl, m_id, m_compute.m_id);
2663 Attach(gl, m_id, m_fragment.m_id);
2664 Attach(gl, m_id, m_geometry.m_id);
2665 Attach(gl, m_id, m_tess_ctrl.m_id);
2666 Attach(gl, m_id, m_tess_eval.m_id);
2667 Attach(gl, m_id, m_vertex.m_id);
2669 /* Set separable parameter */
2670 if (true == is_separable)
2672 gl.programParameteri(m_id, GL_PROGRAM_SEPARABLE, GL_TRUE);
2673 GLU_EXPECT_NO_ERROR(gl.getError(), "ProgramParameteri");
2681 catch (const LinkageException& exc)
2683 throw BuildException(exc.what(), compute_shader, fragment_shader, geometry_shader, tessellation_control_shader,
2684 tessellation_evaluation_shader, vertex_shader);
2688 /** Initialize program instance
2690 * @param compute_shader Compute shader source code
2691 * @param fragment_shader Fragment shader source code
2692 * @param geometry_shader Geometry shader source code
2693 * @param tessellation_control_shader Tessellation control shader source code
2694 * @param tessellation_evaluation_shader Tessellation evaluation shader source code
2695 * @param vertex_shader Vertex shader source code
2696 * @param is_separable Selects if monolithic or separable program should be built. Defaults to false
2698 void Program::Init(const std::string& compute_shader, const std::string& fragment_shader,
2699 const std::string& geometry_shader, const std::string& tessellation_control_shader,
2700 const std::string& tessellation_evaluation_shader, const std::string& vertex_shader,
2703 NameVector captured_varying;
2705 Init(compute_shader, fragment_shader, geometry_shader, tessellation_control_shader, tessellation_evaluation_shader,
2706 vertex_shader, captured_varying, true, is_separable);
2709 /** Release program instance
2712 void Program::Release()
2714 const Functions& gl = m_context.getRenderContext().getFunctions();
2716 if (m_invalid_id != m_id)
2718 Use(gl, m_invalid_id);
2720 gl.deleteProgram(m_id);
2721 m_id = m_invalid_id;
2724 m_compute.Release();
2725 m_fragment.Release();
2726 m_geometry.Release();
2727 m_tess_ctrl.Release();
2728 m_tess_eval.Release();
2732 /** Get <pname> for a set of active uniforms
2734 * @param count Number of indices
2735 * @param indices Indices of uniforms
2736 * @param pname Queired pname
2737 * @param params Array that will be filled with values of parameters
2739 void Program::GetActiveUniformsiv(GLsizei count, const GLuint* indices, GLenum pname, GLint* params) const
2741 const Functions& gl = m_context.getRenderContext().getFunctions();
2743 GetActiveUniformsiv(gl, m_id, count, indices, pname, params);
2746 /** Get location of attribute
2748 * @param name Name of attribute
2750 * @return Result of query
2752 glw::GLint Program::GetAttribLocation(const std::string& name) const
2754 const Functions& gl = m_context.getRenderContext().getFunctions();
2756 return GetAttribLocation(gl, m_id, name);
2761 * @param interface Interface to be queried
2762 * @param index Index of resource
2763 * @param property Property to be queried
2764 * @param buf_size Size of <params> buffer
2765 * @param params Results of query
2767 void Program::GetResource(GLenum interface, GLuint index, GLenum property, GLsizei buf_size, GLint* params) const
2769 const Functions& gl = m_context.getRenderContext().getFunctions();
2771 GetResource(gl, m_id, interface, index, property, buf_size, params);
2774 /** Query for index of resource
2776 * @param name Name of resource
2777 * @param interface Interface to be queried
2779 * @return Result of query
2781 glw::GLuint Program::GetResourceIndex(const std::string& name, GLenum interface) const
2783 const Functions& gl = m_context.getRenderContext().getFunctions();
2785 return GetResourceIndex(gl, m_id, name, interface);
2788 /** Get indices for a set of uniforms
2790 * @param count Count number of uniforms
2791 * @param names Names of uniforms
2792 * @param indices Buffer that will be filled with indices
2794 void Program::GetUniformIndices(GLsizei count, const GLchar** names, GLuint* indices) const
2796 const Functions& gl = m_context.getRenderContext().getFunctions();
2798 GetUniformIndices(gl, m_id, count, names, indices);
2801 /** Get uniform location
2803 * @param name Name of uniform
2805 * @return Results of query
2807 glw::GLint Program::GetUniformLocation(const std::string& name) const
2809 const Functions& gl = m_context.getRenderContext().getFunctions();
2811 return GetUniformLocation(gl, m_id, name);
2814 /** Set program as active
2817 void Program::Use() const
2819 const Functions& gl = m_context.getRenderContext().getFunctions();
2824 /** Attach shader to program
2826 * @param gl GL functions
2827 * @param program_id Id of program
2828 * @param shader_id Id of shader
2830 void Program::Attach(const Functions& gl, GLuint program_id, GLuint shader_id)
2833 if ((m_invalid_id == program_id) || (Shader::m_invalid_id == shader_id))
2838 gl.attachShader(program_id, shader_id);
2839 GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
2842 /** Set up captured varyings
2844 * @param gl GL functions
2845 * @param id Id of program
2846 * @param captured_varyings Vector of varyings
2847 * @param capture_interleaved Selects if interleaved or separate mode should be used
2849 void Program::Capture(const Functions& gl, GLuint id, const NameVector& captured_varyings, bool capture_interleaved)
2851 const size_t n_varyings = captured_varyings.size();
2853 if (0 == n_varyings)
2855 /* empty list, skip */
2859 std::vector<const GLchar*> varying_names;
2860 varying_names.resize(n_varyings);
2862 for (size_t i = 0; i < n_varyings; ++i)
2864 varying_names[i] = captured_varyings[i].c_str();
2868 if (true == capture_interleaved)
2870 mode = GL_INTERLEAVED_ATTRIBS;
2874 mode = GL_SEPARATE_ATTRIBS;
2877 gl.transformFeedbackVaryings(id, static_cast<GLsizei>(n_varyings), &varying_names[0], mode);
2878 GLU_EXPECT_NO_ERROR(gl.getError(), "TransformFeedbackVaryings");
2881 /** Create program instance
2883 * @param gl GL functions
2884 * @param out_id Id of program
2886 void Program::Create(const Functions& gl, GLuint& out_id)
2888 const GLuint id = gl.createProgram();
2889 GLU_EXPECT_NO_ERROR(gl.getError(), "CreateProgram");
2891 if (m_invalid_id == id)
2893 TCU_FAIL("Failed to create program");
2899 /** Get <pname> for a set of active uniforms
2901 * @param gl Functions
2902 * @param program_id Id of program
2903 * @param count Number of indices
2904 * @param indices Indices of uniforms
2905 * @param pname Queired pname
2906 * @param params Array that will be filled with values of parameters
2908 void Program::GetActiveUniformsiv(const Functions& gl, GLuint program_id, GLsizei count, const GLuint* indices,
2909 GLenum pname, GLint* params)
2911 gl.getActiveUniformsiv(program_id, count, indices, pname, params);
2912 GLU_EXPECT_NO_ERROR(gl.getError(), "GetActiveUniformsiv");
2915 /** Get indices for a set of uniforms
2917 * @param gl Functions
2918 * @param program_id Id of program
2919 * @param count Count number of uniforms
2920 * @param names Names of uniforms
2921 * @param indices Buffer that will be filled with indices
2923 void Program::GetUniformIndices(const Functions& gl, GLuint program_id, GLsizei count, const GLchar** names,
2926 gl.getUniformIndices(program_id, count, names, indices);
2927 GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformIndices");
2932 * @param gl GL functions
2933 * @param id Id of program
2935 void Program::Link(const Functions& gl, GLuint id)
2937 GLint status = GL_FALSE;
2940 GLU_EXPECT_NO_ERROR(gl.getError(), "LinkProgram");
2942 /* Get link status */
2943 gl.getProgramiv(id, GL_LINK_STATUS, &status);
2944 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");
2946 /* Log link error */
2947 if (GL_TRUE != status)
2949 glw::GLint length = 0;
2950 std::string message;
2952 /* Get error log length */
2953 gl.getProgramiv(id, GL_INFO_LOG_LENGTH, &length);
2954 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");
2956 message.resize(length, 0);
2959 gl.getProgramInfoLog(id, length, 0, &message[0]);
2960 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramInfoLog");
2962 throw LinkageException(message.c_str());
2966 /** Set generic uniform
2968 * @param gl Functions
2969 * @param type Type of uniform
2970 * @param count Length of array
2971 * @param location Location of uniform
2972 * @param data Data that will be used
2974 void Program::Uniform(const Functions& gl, const Type& type, GLsizei count, GLint location, const GLvoid* data)
2978 TCU_FAIL("Uniform is inactive");
2981 switch (type.m_basic_type)
2984 if (1 == type.m_n_columns)
2986 getUniformNdv(gl, type.m_n_rows)(location, count, (const GLdouble*)data);
2987 GLU_EXPECT_NO_ERROR(gl.getError(), "UniformNdv");
2991 getUniformMatrixNdv(gl, type.m_n_columns, type.m_n_rows)(location, count, false, (const GLdouble*)data);
2992 GLU_EXPECT_NO_ERROR(gl.getError(), "UniformMatrixNdv");
2996 if (1 == type.m_n_columns)
2998 getUniformNfv(gl, type.m_n_rows)(location, count, (const GLfloat*)data);
2999 GLU_EXPECT_NO_ERROR(gl.getError(), "UniformNfv");
3003 getUniformMatrixNfv(gl, type.m_n_columns, type.m_n_rows)(location, count, false, (const GLfloat*)data);
3004 GLU_EXPECT_NO_ERROR(gl.getError(), "UniformMatrixNfv");
3008 getUniformNiv(gl, type.m_n_rows)(location, count, (const GLint*)data);
3009 GLU_EXPECT_NO_ERROR(gl.getError(), "UniformNiv");
3012 getUniformNuiv(gl, type.m_n_rows)(location, count, (const GLuint*)data);
3013 GLU_EXPECT_NO_ERROR(gl.getError(), "UniformNuiv");
3016 TCU_FAIL("Invalid enum");
3022 * @param gl GL functions
3023 * @param id Id of program
3025 void Program::Use(const Functions& gl, GLuint id)
3028 GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram");
3031 /** Get location of attribute
3033 * @param gl GL functions
3034 * @param id Id of program
3035 * @param name Name of attribute
3037 * @return Location of attribute
3039 GLint Program::GetAttribLocation(const Functions& gl, GLuint id, const std::string& name)
3041 GLint location = gl.getAttribLocation(id, name.c_str());
3042 GLU_EXPECT_NO_ERROR(gl.getError(), "GetAttribLocation");
3049 * @param gl GL functions
3050 * @param id Id of program
3051 * @param interface Interface to be queried
3052 * @param index Index of resource
3053 * @param property Property to be queried
3054 * @param buf_size Size of <params> buffer
3055 * @param params Results of query
3057 void Program::GetResource(const Functions& gl, GLuint id, GLenum interface, GLuint index, GLenum property,
3058 GLsizei buf_size, GLint* params)
3060 gl.getProgramResourceiv(id, interface, index, 1 /* propCount */, &property, buf_size /* bufSize */, 0 /* length */,
3062 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramResourceiv");
3065 /** Get index of resource
3067 * @param gl GL functions
3068 * @param id Id of program
3069 * @param name Name of resource
3070 * @param interface Program interface to queried
3072 * @return Location of attribute
3074 GLuint Program::GetResourceIndex(const Functions& gl, GLuint id, const std::string& name, GLenum interface)
3076 GLuint index = gl.getProgramResourceIndex(id, interface, name.c_str());
3077 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramResourceIndex");
3082 /** Get location of attribute
3084 * @param gl GL functions
3085 * @param id Id of program
3086 * @param name Name of attribute
3088 * @return Location of uniform
3090 GLint Program::GetUniformLocation(const Functions& gl, GLuint id, const std::string& name)
3092 GLint location = gl.getUniformLocation(id, name.c_str());
3093 GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformLocation");
3100 * @param error_message Error message
3101 * @param compute_shader Source code for compute stage
3102 * @param fragment_shader Source code for fragment stage
3103 * @param geometry_shader Source code for geometry stage
3104 * @param tess_ctrl_shader Source code for tessellation control stage
3105 * @param tess_eval_shader Source code for tessellation evaluation stage
3106 * @param vertex_shader Source code for vertex stage
3108 Program::BuildException::BuildException(const glw::GLchar* error_message, const std::string compute_shader,
3109 const std::string fragment_shader, const std::string geometry_shader,
3110 const std::string tess_ctrl_shader, const std::string tess_eval_shader,
3111 const std::string vertex_shader)
3112 : m_error_message(error_message)
3113 , m_compute_shader(compute_shader)
3114 , m_fragment_shader(fragment_shader)
3115 , m_geometry_shader(geometry_shader)
3116 , m_tess_ctrl_shader(tess_ctrl_shader)
3117 , m_tess_eval_shader(tess_eval_shader)
3118 , m_vertex_shader(vertex_shader)
3122 /** Overwrites std::exception::what method
3124 * @return Message compossed from error message and shader sources
3126 const char* Program::BuildException::what() const throw()
3128 return "Failed to link program";
3131 /** Logs error message and shader sources **/
3132 void Program::BuildException::log(deqp::Context& context) const
3134 context.getTestContext().getLog() << tcu::TestLog::Message << "Link failure: " << m_error_message
3135 << tcu::TestLog::EndMessage;
3137 Shader::LogSource(context, m_vertex_shader, Shader::VERTEX);
3138 Shader::LogSource(context, m_tess_ctrl_shader, Shader::TESS_CTRL);
3139 Shader::LogSource(context, m_tess_eval_shader, Shader::TESS_EVAL);
3140 Shader::LogSource(context, m_geometry_shader, Shader::GEOMETRY);
3141 Shader::LogSource(context, m_fragment_shader, Shader::FRAGMENT);
3142 Shader::LogSource(context, m_compute_shader, Shader::COMPUTE);
3147 * @param message Linking error message
3149 Program::LinkageException::LinkageException(const glw::GLchar* message) : m_error_message(message)
3151 /* Nothing to be done */
3154 /** Returns error messages
3156 * @return Linking error message
3158 const char* Program::LinkageException::what() const throw()
3160 return m_error_message.c_str();
3163 /* Texture constants */
3164 const GLuint Texture::m_invalid_id = -1;
3168 * @param context CTS context.
3170 Texture::Texture(deqp::Context& context) : m_id(m_invalid_id), m_context(context), m_type(TEX_2D)
3172 /* Nothing to done here */
3183 /** Initialize texture instance
3185 * @param tex_type Type of texture
3186 * @param width Width of texture
3187 * @param height Height of texture
3188 * @param depth Depth of texture
3189 * @param internal_format Internal format of texture
3190 * @param format Format of texture data
3191 * @param type Type of texture data
3192 * @param data Texture data
3194 void Texture::Init(TYPES tex_type, GLuint width, GLuint height, GLuint depth, GLenum internal_format, GLenum format,
3195 GLenum type, GLvoid* data)
3197 const Functions& gl = m_context.getRenderContext().getFunctions();
3199 /* Delete previous texture */
3204 /* Generate, bind, allocate storage and upload data */
3206 Bind(gl, m_id, tex_type);
3207 Storage(gl, tex_type, width, height, depth, internal_format);
3208 Update(gl, tex_type, width, height, depth, format, type, data);
3211 /** Initialize buffer texture
3213 * @param internal_format Internal format of texture
3214 * @param buffer_id Id of buffer that will be used as data source
3216 void Texture::Init(GLenum internal_format, GLuint buffer_id)
3218 const Functions& gl = m_context.getRenderContext().getFunctions();
3220 /* Delete previous texture */
3223 m_type = TEX_BUFFER;
3225 /* Generate, bind and attach buffer */
3227 Bind(gl, m_id, TEX_BUFFER);
3228 TexBuffer(gl, buffer_id, internal_format);
3231 /** Release texture instance
3234 void Texture::Release()
3236 if (m_invalid_id != m_id)
3238 const Functions& gl = m_context.getRenderContext().getFunctions();
3240 gl.deleteTextures(1, &m_id);
3241 m_id = m_invalid_id;
3245 /** Bind texture to its target
3248 void Texture::Bind() const
3250 const Functions& gl = m_context.getRenderContext().getFunctions();
3252 Bind(gl, m_id, m_type);
3255 /** Get texture data
3257 * @param format Format of data
3258 * @param type Type of data
3259 * @param out_data Buffer for data
3261 void Texture::Get(GLenum format, GLenum type, GLvoid* out_data) const
3263 const Functions& gl = m_context.getRenderContext().getFunctions();
3265 Bind(gl, m_id, m_type);
3266 Get(gl, m_type, format, type, out_data);
3269 /** Bind texture to target
3271 * @param gl GL functions
3272 * @param id Id of texture
3273 * @param tex_type Type of texture
3275 void Texture::Bind(const Functions& gl, GLuint id, TYPES tex_type)
3277 GLenum target = GetTargetGLenum(tex_type);
3279 gl.bindTexture(target, id);
3280 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
3283 /** Generate texture instance
3285 * @param gl GL functions
3286 * @param out_id Id of texture
3288 void Texture::Generate(const Functions& gl, GLuint& out_id)
3290 GLuint id = m_invalid_id;
3292 gl.genTextures(1, &id);
3293 GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures");
3295 if (m_invalid_id == id)
3297 TCU_FAIL("Invalid id");
3303 /** Get texture data
3305 * @param gl GL functions
3306 * @param format Format of data
3307 * @param type Type of data
3308 * @param out_data Buffer for data
3310 void Texture::Get(const Functions& gl, TYPES tex_type, GLenum format, GLenum type, GLvoid* out_data)
3312 GLenum target = GetTargetGLenum(tex_type);
3314 if (TEX_CUBE != tex_type)
3316 gl.getTexImage(target, 0 /* level */, format, type, out_data);
3317 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexImage");
3324 if ((GL_RGBA != format) && (GL_UNSIGNED_BYTE != type))
3326 TCU_FAIL("Not implemented");
3329 GLuint texel_size = 4;
3331 gl.getTexLevelParameteriv(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0 /* level */, GL_TEXTURE_WIDTH, &width);
3332 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv");
3334 gl.getTexLevelParameteriv(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0 /* level */, GL_TEXTURE_HEIGHT, &height);
3335 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv");
3337 const GLuint image_size = width * height * texel_size;
3339 gl.getTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0 /* level */, format, type,
3340 (GLvoid*)((GLchar*)out_data + (image_size * 0)));
3341 gl.getTexImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0 /* level */, format, type,
3342 (GLvoid*)((GLchar*)out_data + (image_size * 1)));
3343 gl.getTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0 /* level */, format, type,
3344 (GLvoid*)((GLchar*)out_data + (image_size * 2)));
3345 gl.getTexImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0 /* level */, format, type,
3346 (GLvoid*)((GLchar*)out_data + (image_size * 3)));
3347 gl.getTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0 /* level */, format, type,
3348 (GLvoid*)((GLchar*)out_data + (image_size * 4)));
3349 gl.getTexImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0 /* level */, format, type,
3350 (GLvoid*)((GLchar*)out_data + (image_size * 5)));
3351 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexImage");
3355 /** Allocate storage for texture
3357 * @param gl GL functions
3358 * @param tex_type Type of texture
3359 * @param width Width of texture
3360 * @param height Height of texture
3361 * @param depth Depth of texture
3362 * @param internal_format Internal format of texture
3364 void Texture::Storage(const Functions& gl, TYPES tex_type, GLuint width, GLuint height, GLuint depth,
3365 GLenum internal_format)
3367 static const GLuint levels = 1;
3369 GLenum target = GetTargetGLenum(tex_type);
3374 gl.texStorage1D(target, levels, internal_format, width);
3375 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage1D");
3381 gl.texStorage2D(target, levels, internal_format, width, height);
3382 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2D");
3386 gl.texStorage3D(target, levels, internal_format, width, height, depth);
3387 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage3D");
3390 TCU_FAIL("Invliad enum");
3395 /** Attach buffer as source of texture buffer data
3397 * @param gl GL functions
3398 * @param internal_format Internal format of texture
3399 * @param buffer_id Id of buffer that will be used as data source
3401 void Texture::TexBuffer(const Functions& gl, GLenum internal_format, GLuint& buffer_id)
3403 gl.texBuffer(GL_TEXTURE_BUFFER, internal_format, buffer_id);
3404 GLU_EXPECT_NO_ERROR(gl.getError(), "TexBuffer");
3407 /** Update contents of texture
3409 * @param gl GL functions
3410 * @param tex_type Type of texture
3411 * @param width Width of texture
3412 * @param height Height of texture
3413 * @param format Format of data
3414 * @param type Type of data
3415 * @param data Buffer with image data
3417 void Texture::Update(const Functions& gl, TYPES tex_type, GLuint width, GLuint height, GLuint depth, GLenum format,
3418 GLenum type, GLvoid* data)
3420 static const GLuint level = 0;
3422 GLenum target = GetTargetGLenum(tex_type);
3427 gl.texSubImage1D(target, level, 0 /* x */, width, format, type, data);
3428 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage1D");
3433 gl.texSubImage2D(target, level, 0 /* x */, 0 /* y */, width, height, format, type, data);
3434 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2D");
3437 gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, level, 0 /* x */, 0 /* y */, width, height, format, type,
3439 gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, level, 0 /* x */, 0 /* y */, width, height, format, type,
3441 gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, level, 0 /* x */, 0 /* y */, width, height, format, type,
3443 gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, level, 0 /* x */, 0 /* y */, width, height, format, type,
3445 gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, level, 0 /* x */, 0 /* y */, width, height, format, type,
3447 gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, level, 0 /* x */, 0 /* y */, width, height, format, type,
3449 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2D");
3453 gl.texSubImage3D(target, level, 0 /* x */, 0 /* y */, 0 /* z */, width, height, depth, format, type, data);
3454 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage3D");
3457 TCU_FAIL("Invliad enum");
3462 /** Get target for given texture type
3464 * @param type Type of texture
3468 GLenum Texture::GetTargetGLenum(TYPES type)
3475 result = GL_TEXTURE_BUFFER;
3478 result = GL_TEXTURE_2D;
3481 result = GL_TEXTURE_RECTANGLE;
3484 result = GL_TEXTURE_2D_ARRAY;
3487 result = GL_TEXTURE_3D;
3490 result = GL_TEXTURE_CUBE_MAP;
3493 result = GL_TEXTURE_1D;
3496 result = GL_TEXTURE_1D_ARRAY;
3503 /* VertexArray constants */
3504 const GLuint VertexArray::m_invalid_id = -1;
3508 * @param context CTS context.
3510 VertexArray::VertexArray(deqp::Context& context) : m_id(m_invalid_id), m_context(context)
3517 VertexArray::~VertexArray()
3522 /** Initialize vertex array instance
3525 void VertexArray::Init()
3527 /* Delete previous instance */
3530 const Functions& gl = m_context.getRenderContext().getFunctions();
3535 /** Release vertex array object instance
3538 void VertexArray::Release()
3540 if (m_invalid_id != m_id)
3542 const Functions& gl = m_context.getRenderContext().getFunctions();
3544 gl.deleteVertexArrays(1, &m_id);
3546 m_id = m_invalid_id;
3550 /** Set attribute in VAO
3552 * @param index Index of attribute
3553 * @param type Type of attribute
3554 * @param n_array_elements Arary length
3555 * @param normalized Selectis if values should be normalized
3556 * @param stride Stride
3557 * @param pointer Pointer to data, or offset in buffer
3559 void VertexArray::Attribute(GLuint index, const Type& type, GLuint n_array_elements, GLboolean normalized,
3560 GLsizei stride, const GLvoid* pointer)
3562 const Functions& gl = m_context.getRenderContext().getFunctions();
3564 AttribPointer(gl, index, type, n_array_elements, normalized, stride, pointer);
3565 Enable(gl, index, type, n_array_elements);
3568 /** Binds Vertex array object
3571 void VertexArray::Bind()
3573 const Functions& gl = m_context.getRenderContext().getFunctions();
3578 /** Set attribute in VAO
3580 * @param gl Functions
3581 * @param index Index of attribute
3582 * @param type Type of attribute
3583 * @param n_array_elements Arary length
3584 * @param normalized Selectis if values should be normalized
3585 * @param stride Stride
3586 * @param pointer Pointer to data, or offset in buffer
3588 void VertexArray::AttribPointer(const Functions& gl, GLuint index, const Type& type, GLuint n_array_elements,
3589 GLboolean normalized, GLsizei stride, const GLvoid* pointer)
3591 const GLuint basic_type_size = Type::GetTypeSize(type.m_basic_type);
3592 const GLint size = (GLint)type.m_n_rows;
3593 const GLuint column_size = (GLuint)size * basic_type_size;
3594 const GLenum gl_type = Type::GetTypeGLenum(type.m_basic_type);
3598 /* If attribute is not an array */
3599 if (0 == n_array_elements)
3601 n_array_elements = 1;
3604 /* For each element in array */
3605 for (GLuint element = 0; element < n_array_elements; ++element)
3607 /* For each column in matrix */
3608 for (GLuint column = 1; column <= type.m_n_columns; ++column)
3610 /* Calculate offset */
3611 const GLvoid* ptr = (GLubyte*)pointer + offset;
3613 /* Set up attribute */
3614 switch (type.m_basic_type)
3617 gl.vertexAttribPointer(index, size, gl_type, normalized, stride, ptr);
3618 GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttribPointer");
3622 gl.vertexAttribIPointer(index, size, gl_type, stride, ptr);
3623 GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttribIPointer");
3626 gl.vertexAttribLPointer(index, size, gl_type, stride, ptr);
3627 GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttribLPointer");
3630 TCU_FAIL("Invalid enum");
3634 offset += column_size;
3640 /** Binds Vertex array object
3642 * @param gl GL functions
3643 * @param id ID of vertex array object
3645 void VertexArray::Bind(const glw::Functions& gl, glw::GLuint id)
3647 gl.bindVertexArray(id);
3648 GLU_EXPECT_NO_ERROR(gl.getError(), "BindVertexArray");
3651 /** Disable attribute in VAO
3653 * @param gl Functions
3654 * @param index Index of attribute
3655 * @param type Type of attribute
3656 * @param n_array_elements Arary length
3658 void VertexArray::Disable(const Functions& gl, GLuint index, const Type& type, GLuint n_array_elements)
3660 /* If attribute is not an array */
3661 if (0 == n_array_elements)
3663 n_array_elements = 1;
3666 /* For each element in array */
3667 for (GLuint element = 0; element < n_array_elements; ++element)
3669 /* For each column in matrix */
3670 for (GLuint column = 1; column <= type.m_n_columns; ++column)
3672 /* Enable attribute array */
3673 gl.disableVertexAttribArray(index);
3674 GLU_EXPECT_NO_ERROR(gl.getError(), "DisableVertexAttribArray");
3682 /** Set divisor for attribute
3684 * @param gl Functions
3685 * @param index Index of attribute
3686 * @param divisor New divisor value
3688 void VertexArray::Divisor(const Functions& gl, GLuint index, GLuint divisor)
3690 gl.vertexAttribDivisor(index, divisor);
3691 GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttribDivisor");
3694 /** Enables attribute in VAO
3696 * @param gl Functions
3697 * @param index Index of attribute
3698 * @param type Type of attribute
3699 * @param n_array_elements Arary length
3701 void VertexArray::Enable(const Functions& gl, GLuint index, const Type& type, GLuint n_array_elements)
3703 /* If attribute is not an array */
3704 if (0 == n_array_elements)
3706 n_array_elements = 1;
3709 /* For each element in array */
3710 for (GLuint element = 0; element < n_array_elements; ++element)
3712 /* For each column in matrix */
3713 for (GLuint column = 1; column <= type.m_n_columns; ++column)
3715 /* Enable attribute array */
3716 gl.enableVertexAttribArray(index);
3717 GLU_EXPECT_NO_ERROR(gl.getError(), "EnableVertexAttribArray");
3725 /** Generates Vertex array object
3727 * @param gl GL functions
3728 * @param out_id ID of vertex array object
3730 void VertexArray::Generate(const glw::Functions& gl, glw::GLuint& out_id)
3732 GLuint id = m_invalid_id;
3734 gl.genVertexArrays(1, &id);
3735 GLU_EXPECT_NO_ERROR(gl.getError(), "GenVertexArrays");
3737 if (m_invalid_id == id)
3739 TCU_FAIL("Invalid id");
3745 /* Constatns used by Variable */
3746 const GLint Variable::m_automatic_location = -1;
3748 /** Copy constructor
3751 Variable::Variable(const Variable& var)
3752 : m_data(var.m_data)
3753 , m_data_size(var.m_data_size)
3754 , m_descriptor(var.m_descriptor.m_name.c_str(), var.m_descriptor.m_qualifiers.c_str(),
3755 var.m_descriptor.m_expected_component, var.m_descriptor.m_expected_location,
3756 var.m_descriptor.m_builtin, var.m_descriptor.m_normalized, var.m_descriptor.m_n_array_elements,
3757 var.m_descriptor.m_expected_stride_of_element, var.m_descriptor.m_offset)
3758 , m_storage(var.m_storage)
3760 m_descriptor.m_type = var.m_descriptor.m_type;
3762 if (BUILTIN != var.m_descriptor.m_type)
3764 m_descriptor.m_interface = var.m_descriptor.m_interface;
3768 /** Get code that defines variable
3770 * @param flavour Provides info if variable is array or not
3772 * @return String with code
3774 std::string Variable::GetDefinition(FLAVOUR flavour) const
3776 return m_descriptor.GetDefinition(flavour, m_storage);
3779 /** Calcualtes stride of variable
3781 * @return Calculated value
3783 GLuint Variable::GetStride() const
3785 GLint variable_stride = 0;
3787 if (0 == m_descriptor.m_n_array_elements)
3789 variable_stride = m_descriptor.m_expected_stride_of_element;
3793 variable_stride = m_descriptor.m_expected_stride_of_element * m_descriptor.m_n_array_elements;
3796 return variable_stride;
3799 /** Check if variable is block
3801 * @return true if variable type is block, false otherwise
3803 bool Variable::IsBlock() const
3805 if (BUILTIN == m_descriptor.m_type)
3810 const Interface* interface = m_descriptor.m_interface;
3813 TCU_FAIL("Nullptr");
3816 return (Interface::BLOCK == interface->m_type);
3819 /** Check if variable is struct
3821 * @return true if variable type is struct, false otherwise
3823 bool Variable::IsStruct() const
3825 if (BUILTIN == m_descriptor.m_type)
3830 const Interface* interface = m_descriptor.m_interface;
3833 TCU_FAIL("Nullptr");
3836 return (Interface::STRUCT == interface->m_type);
3838 /** Get code that reference variable
3840 * @param parent_name Name of parent
3841 * @param variable Descriptor of variable
3842 * @param flavour Provides info about how variable should be referenced
3843 * @param array_index Index of array, ignored when variable is not array
3845 * @return String with code
3847 std::string Variable::GetReference(const std::string& parent_name, const Descriptor& variable, FLAVOUR flavour,
3853 if (false == parent_name.empty())
3857 name.append(variable.m_name);
3861 name = variable.m_name;
3867 case Utils::Variable::BASIC:
3870 case Utils::Variable::ARRAY:
3874 case Utils::Variable::INDEXED_BY_INVOCATION_ID:
3875 name.append("[gl_InvocationID]");
3879 /* Assumption that both variables have same lengths */
3880 if (0 != variable.m_n_array_elements)
3883 sprintf(buffer, "%d", array_index);
3885 name.append(buffer);
3892 /** Get "flavour" of varying
3894 * @param stage Stage of shader
3895 * @param direction Selects if varying is in or out
3899 Variable::FLAVOUR Variable::GetFlavour(Shader::STAGES stage, VARYING_DIRECTION direction)
3901 FLAVOUR result = BASIC;
3905 case Shader::GEOMETRY:
3906 case Shader::TESS_EVAL:
3907 if (INPUT == direction)
3912 case Shader::TESS_CTRL:
3913 result = INDEXED_BY_INVOCATION_ID;
3922 /** Constructor, for built-in types
3925 * @param qualifiers Qualifiers
3926 * @param expected_component Expected component of variable
3927 * @param expected_location Expected location
3929 * @param normalized Selects if data should be normalized
3930 * @param n_array_elements Length of array
3931 * @param expected_stride_of_element Expected stride of element
3932 * @param offset Offset
3934 Variable::Descriptor::Descriptor(const GLchar* name, const GLchar* qualifiers, GLint expected_component,
3935 GLint expected_location, const Type& type, GLboolean normalized,
3936 GLuint n_array_elements, GLint expected_stride_of_element, GLuint offset)
3937 : m_expected_component(expected_component)
3938 , m_expected_location(expected_location)
3939 , m_expected_stride_of_element(expected_stride_of_element)
3940 , m_n_array_elements(n_array_elements)
3942 , m_normalized(normalized)
3944 , m_qualifiers(qualifiers)
3950 /** Constructor, for interface types
3953 * @param qualifiers Qualifiers
3954 * @param expected_component Expected component of variable
3955 * @param expected_location Expected location
3956 * @param interface Interface of variable
3957 * @param n_array_elements Length of array
3958 * @param expected_stride_of_element Expected stride of element
3959 * @param offset Offset
3961 Variable::Descriptor::Descriptor(const GLchar* name, const GLchar* qualifiers, GLint expected_componenet,
3962 GLint expected_location, Interface* interface, GLuint n_array_elements,
3963 GLint expected_stride_of_element, GLuint offset)
3964 : m_expected_component(expected_componenet)
3965 , m_expected_location(expected_location)
3966 , m_expected_stride_of_element(expected_stride_of_element)
3967 , m_n_array_elements(n_array_elements)
3969 , m_normalized(GL_FALSE)
3971 , m_qualifiers(qualifiers)
3973 , m_interface(interface)
3977 /** Get definition of variable
3979 * @param flavour Flavour of variable
3980 * @param storage Storage used for variable
3982 * @return code with defintion
3984 std::string Variable::Descriptor::GetDefinition(FLAVOUR flavour, STORAGE storage) const
3986 static const GLchar* basic_template = "QUALIFIERS STORAGETYPE NAMEARRAY;";
3987 static const GLchar* array_template = "QUALIFIERS STORAGETYPE NAME[]ARRAY;";
3988 const GLchar* storage_str = 0;
3990 std::string definition;
3991 size_t position = 0;
3993 /* Select definition template */
3997 definition = basic_template;
4000 case INDEXED_BY_INVOCATION_ID:
4001 definition = array_template;
4004 TCU_FAIL("Invliad enum");
4008 if (BUILTIN != m_type)
4010 if (0 == m_interface)
4012 TCU_FAIL("Nullptr");
4017 if (true == m_qualifiers.empty())
4019 replaceToken("QUALIFIERS ", position, "", definition);
4023 replaceToken("QUALIFIERS", position, m_qualifiers.c_str(), definition);
4026 // According to spec: integer or unsigned integer type must always be declared with flat qualifier
4027 bool flat_qualifier = false;
4028 if (m_type != BUILTIN && m_interface != NULL)
4030 if (m_interface->m_members[0].m_builtin.m_basic_type == Utils::Type::Int ||
4031 m_interface->m_members[0].m_builtin.m_basic_type == Utils::Type::Uint)
4033 flat_qualifier = true;
4040 storage_str = flat_qualifier ? "flat in " : "in ";
4042 case VARYING_OUTPUT:
4043 storage_str = "out ";
4046 storage_str = "uniform ";
4049 storage_str = "buffer ";
4055 TCU_FAIL("Invalid enum");
4059 replaceToken("STORAGE", position, storage_str, definition);
4062 if (BUILTIN == m_type)
4064 replaceToken("TYPE", position, m_builtin.GetGLSLTypeName(), definition);
4068 if (Interface::STRUCT == m_interface->m_type)
4070 replaceToken("TYPE", position, m_interface->m_name.c_str(), definition);
4074 const std::string& block_definition = m_interface->GetDefinition();
4076 replaceToken("TYPE", position, block_definition.c_str(), definition);
4081 replaceToken("NAME", position, m_name.c_str(), definition);
4084 if (0 == m_n_array_elements)
4086 replaceToken("ARRAY", position, "", definition);
4091 sprintf(buffer, "[%d]", m_n_array_elements);
4093 replaceToken("ARRAY", position, buffer, definition);
4100 /** Get definitions for variables collected in vector
4102 * @param vector Collection of variables
4103 * @param flavour Flavour of variables
4105 * @return Code with definitions
4107 std::string GetDefinitions(const Variable::PtrVector& vector, Variable::FLAVOUR flavour)
4109 std::string list = Utils::g_list;
4110 size_t position = 0;
4112 for (GLuint i = 0; i < vector.size(); ++i)
4114 Utils::insertElementOfList(vector[i]->GetDefinition(flavour).c_str(), "\n", position, list);
4117 Utils::endList("", position, list);
4122 /** Get definitions for interfaces collected in vector
4124 * @param vector Collection of interfaces
4126 * @return Code with definitions
4128 std::string GetDefinitions(const Interface::PtrVector& vector)
4130 std::string list = Utils::g_list;
4131 size_t position = 0;
4133 for (GLuint i = 0; i < vector.size(); ++i)
4135 Utils::insertElementOfList(vector[i]->GetDefinition().c_str(), "\n", position, list);
4138 Utils::endList("", position, list);
4146 * @param type Type of interface
4148 Interface::Interface(const GLchar* name, Interface::TYPE type) : m_name(name), m_type(type)
4152 /** Adds member to interface
4154 * @param member Descriptor of new member
4156 * @return Pointer to just created member
4158 Variable::Descriptor* Interface::AddMember(const Variable::Descriptor& member)
4160 m_members.push_back(member);
4162 return &m_members.back();
4165 /** Get definition of interface
4167 * @param Code with definition
4169 std::string Interface::GetDefinition() const
4171 std::string definition;
4172 size_t position = 0;
4174 const GLchar* member_list = " MEMBER_DEFINITION\nMEMBER_LIST";
4176 if (STRUCT == m_type)
4178 definition = "struct NAME {\nMEMBER_LIST};";
4182 definition = "NAME {\nMEMBER_LIST}";
4186 replaceToken("NAME", position, m_name.c_str(), definition);
4189 for (GLuint i = 0; i < m_members.size(); ++i)
4191 const size_t start_position = position;
4192 const std::string& member_definition = m_members[i].GetDefinition(Variable::BASIC, Variable::MEMBER);
4195 replaceToken("MEMBER_LIST", position, member_list, definition);
4197 /* Move back position */
4198 position = start_position;
4200 /* Member definition */
4201 replaceToken("MEMBER_DEFINITION", position, member_definition.c_str(), definition);
4204 /* Remove last member list */
4205 replaceToken("MEMBER_LIST", position, "", definition);
4211 /** Adds member of built-in type to interface
4214 * @param qualifiers Qualifiers
4215 * @param expected_component Expected component of variable
4216 * @param expected_location Expected location
4218 * @param normalized Selects if data should be normalized
4219 * @param n_array_elements Length of array
4220 * @param expected_stride_of_element Expected stride of element
4221 * @param offset Offset
4223 * @return Pointer to just created member
4225 Variable::Descriptor* Interface::Member(const GLchar* name, const GLchar* qualifiers, GLint expected_component,
4226 GLint expected_location, const Type& type, GLboolean normalized,
4227 GLuint n_array_elements, GLint expected_stride_of_element, GLuint offset)
4229 return AddMember(Variable::Descriptor(name, qualifiers, expected_component, expected_location, type, normalized,
4230 n_array_elements, expected_stride_of_element, offset));
4233 /** Adds member of interface type to interface
4236 * @param qualifiers Qualifiers
4237 * @param expected_component Expected component of variable
4238 * @param expected_location Expected location
4240 * @param normalized Selects if data should be normalized
4241 * @param n_array_elements Length of array
4242 * @param expected_stride_of_element Expected stride of element
4243 * @param offset Offset
4245 * @return Pointer to just created member
4247 Variable::Descriptor* Interface::Member(const GLchar* name, const GLchar* qualifiers, GLint expected_component,
4248 GLint expected_location, Interface* nterface, GLuint n_array_elements,
4249 GLint expected_stride_of_element, GLuint offset)
4251 return AddMember(Variable::Descriptor(name, qualifiers, expected_component, expected_location, nterface,
4252 n_array_elements, expected_stride_of_element, offset));
4255 /** Clears contents of vector of pointers
4257 * @tparam T Type of elements
4259 * @param vector Collection to be cleared
4261 template <typename T>
4262 void clearPtrVector(std::vector<T*>& vector)
4264 for (size_t i = 0; i < vector.size(); ++i)
4281 * @param stage Stage described by that interface
4283 ShaderInterface::ShaderInterface(Shader::STAGES stage) : m_stage(stage)
4285 /* Nothing to be done */
4288 /** Get definitions of globals
4290 * @return Code with definitions
4292 std::string ShaderInterface::GetDefinitionsGlobals() const
4297 /** Get definitions of inputs
4299 * @return Code with definitions
4301 std::string ShaderInterface::GetDefinitionsInputs() const
4303 Variable::FLAVOUR flavour = Variable::GetFlavour(m_stage, Variable::INPUT);
4305 return GetDefinitions(m_inputs, flavour);
4308 /** Get definitions of outputs
4310 * @return Code with definitions
4312 std::string ShaderInterface::GetDefinitionsOutputs() const
4314 Variable::FLAVOUR flavour = Variable::GetFlavour(m_stage, Variable::OUTPUT);
4316 return GetDefinitions(m_outputs, flavour);
4319 /** Get definitions of buffers
4321 * @return Code with definitions
4323 std::string ShaderInterface::GetDefinitionsSSBs() const
4325 return GetDefinitions(m_ssb_blocks, Variable::BASIC);
4328 /** Get definitions of uniforms
4330 * @return Code with definitions
4332 std::string ShaderInterface::GetDefinitionsUniforms() const
4334 return GetDefinitions(m_uniforms, Variable::BASIC);
4339 * @param in Input variable
4340 * @param out Output variable
4342 VaryingConnection::VaryingConnection(Variable* in, Variable* out) : m_in(in), m_out(out)
4344 /* NBothing to be done here */
4347 /** Adds new varying connection to given stage
4349 * @param stage Shader stage
4350 * @param in In varying
4351 * @param out Out varying
4353 void VaryingPassthrough::Add(Shader::STAGES stage, Variable* in, Variable* out)
4355 VaryingConnection::Vector& vector = Get(stage);
4357 vector.push_back(VaryingConnection(in, out));
4360 /** Get all passthrough connections for given stage
4362 * @param stage Shader stage
4364 * @return Vector of connections
4366 VaryingConnection::Vector& VaryingPassthrough::Get(Shader::STAGES stage)
4368 VaryingConnection::Vector* result = 0;
4372 case Shader::FRAGMENT:
4373 result = &m_fragment;
4375 case Shader::GEOMETRY:
4376 result = &m_geometry;
4378 case Shader::TESS_CTRL:
4379 result = &m_tess_ctrl;
4381 case Shader::TESS_EVAL:
4382 result = &m_tess_eval;
4384 case Shader::VERTEX:
4388 TCU_FAIL("Invalid enum");
4397 ProgramInterface::ProgramInterface()
4398 : m_compute(Shader::COMPUTE)
4399 , m_vertex(Shader::VERTEX)
4400 , m_tess_ctrl(Shader::TESS_CTRL)
4401 , m_tess_eval(Shader::TESS_EVAL)
4402 , m_geometry(Shader::GEOMETRY)
4403 , m_fragment(Shader::FRAGMENT)
4410 ProgramInterface::~ProgramInterface()
4412 clearPtrVector(m_blocks);
4413 clearPtrVector(m_structures);
4416 /** Adds new interface
4421 * @return Pointer to created interface
4423 Interface* ProgramInterface::AddInterface(const GLchar* name, Interface::TYPE type)
4425 Interface* interface = 0;
4427 if (Interface::STRUCT == type)
4429 interface = new Interface(name, type);
4431 m_structures.push_back(interface);
4435 interface = new Interface(name, type);
4437 m_blocks.push_back(interface);
4443 /** Adds new block interface
4447 * @return Pointer to created interface
4449 Interface* ProgramInterface::Block(const GLchar* name)
4451 return AddInterface(name, Interface::BLOCK);
4454 /** Get interface of given shader stage
4456 * @param stage Shader stage
4458 * @return Reference to stage interface
4460 ShaderInterface& ProgramInterface::GetShaderInterface(Shader::STAGES stage)
4462 ShaderInterface* interface = 0;
4466 case Shader::COMPUTE:
4467 interface = &m_compute;
4469 case Shader::FRAGMENT:
4470 interface = &m_fragment;
4472 case Shader::GEOMETRY:
4473 interface = &m_geometry;
4475 case Shader::TESS_CTRL:
4476 interface = &m_tess_ctrl;
4478 case Shader::TESS_EVAL:
4479 interface = &m_tess_eval;
4481 case Shader::VERTEX:
4482 interface = &m_vertex;
4485 TCU_FAIL("Invalid enum");
4491 /** Get interface of given shader stage
4493 * @param stage Shader stage
4495 * @return Reference to stage interface
4497 const ShaderInterface& ProgramInterface::GetShaderInterface(Shader::STAGES stage) const
4499 const ShaderInterface* interface = 0;
4503 case Shader::COMPUTE:
4504 interface = &m_compute;
4506 case Shader::FRAGMENT:
4507 interface = &m_fragment;
4509 case Shader::GEOMETRY:
4510 interface = &m_geometry;
4512 case Shader::TESS_CTRL:
4513 interface = &m_tess_ctrl;
4515 case Shader::TESS_EVAL:
4516 interface = &m_tess_eval;
4518 case Shader::VERTEX:
4519 interface = &m_vertex;
4522 TCU_FAIL("Invalid enum");
4528 /** Clone interface of Vertex shader stage to other stages
4529 * It creates matching inputs, outputs, uniforms and buffers in other stages.
4530 * There are no additional outputs for FRAGMENT shader generated.
4532 * @param varying_passthrough Collection of varyings connections
4534 void ProgramInterface::CloneVertexInterface(VaryingPassthrough& varying_passthrough)
4536 /* VS outputs >> TCS inputs >> TCS outputs >> .. >> FS inputs */
4537 for (size_t i = 0; i < m_vertex.m_outputs.size(); ++i)
4539 const Variable& vs_var = *m_vertex.m_outputs[i];
4540 const GLchar* prefix = GetStagePrefix(Shader::VERTEX, vs_var.m_storage);
4542 cloneVariableForStage(vs_var, Shader::TESS_CTRL, prefix, varying_passthrough);
4543 cloneVariableForStage(vs_var, Shader::TESS_EVAL, prefix, varying_passthrough);
4544 cloneVariableForStage(vs_var, Shader::GEOMETRY, prefix, varying_passthrough);
4545 cloneVariableForStage(vs_var, Shader::FRAGMENT, prefix, varying_passthrough);
4548 /* Copy uniforms from VS to other stages */
4549 for (size_t i = 0; i < m_vertex.m_uniforms.size(); ++i)
4551 Variable& vs_var = *m_vertex.m_uniforms[i];
4552 const GLchar* prefix = GetStagePrefix(Shader::VERTEX, vs_var.m_storage);
4554 cloneVariableForStage(vs_var, Shader::COMPUTE, prefix, varying_passthrough);
4555 cloneVariableForStage(vs_var, Shader::TESS_CTRL, prefix, varying_passthrough);
4556 cloneVariableForStage(vs_var, Shader::TESS_EVAL, prefix, varying_passthrough);
4557 cloneVariableForStage(vs_var, Shader::GEOMETRY, prefix, varying_passthrough);
4558 cloneVariableForStage(vs_var, Shader::FRAGMENT, prefix, varying_passthrough);
4560 /* Uniform blocks needs unique binding */
4561 if (true == vs_var.IsBlock())
4563 replaceBinding(vs_var, Shader::VERTEX);
4567 /* Copy SSBs from VS to other stages */
4568 for (size_t i = 0; i < m_vertex.m_ssb_blocks.size(); ++i)
4570 Variable& vs_var = *m_vertex.m_ssb_blocks[i];
4571 const GLchar* prefix = GetStagePrefix(Shader::VERTEX, vs_var.m_storage);
4573 cloneVariableForStage(vs_var, Shader::COMPUTE, prefix, varying_passthrough);
4574 cloneVariableForStage(vs_var, Shader::TESS_CTRL, prefix, varying_passthrough);
4575 cloneVariableForStage(vs_var, Shader::TESS_EVAL, prefix, varying_passthrough);
4576 cloneVariableForStage(vs_var, Shader::GEOMETRY, prefix, varying_passthrough);
4577 cloneVariableForStage(vs_var, Shader::FRAGMENT, prefix, varying_passthrough);
4579 /* SSBs blocks needs unique binding */
4580 if (true == vs_var.IsBlock())
4582 replaceBinding(vs_var, Shader::VERTEX);
4586 m_compute.m_globals = m_vertex.m_globals;
4587 m_fragment.m_globals = m_vertex.m_globals;
4588 m_geometry.m_globals = m_vertex.m_globals;
4589 m_tess_ctrl.m_globals = m_vertex.m_globals;
4590 m_tess_eval.m_globals = m_vertex.m_globals;
4593 /** Clone variable for specific stage
4595 * @param variable Variable
4596 * @param stage Requested stage
4597 * @param prefix Prefix used in variable name that is specific for original stage
4598 * @param varying_passthrough Collection of varyings connections
4600 void ProgramInterface::cloneVariableForStage(const Variable& variable, Shader::STAGES stage, const GLchar* prefix,
4601 VaryingPassthrough& varying_passthrough)
4603 switch (variable.m_storage)
4605 case Variable::VARYING_OUTPUT:
4607 Variable* in = cloneVariableForStage(variable, stage, Variable::VARYING_INPUT, prefix);
4609 if (Shader::FRAGMENT != stage)
4611 Variable* out = cloneVariableForStage(variable, stage, Variable::VARYING_OUTPUT, prefix);
4612 varying_passthrough.Add(stage, in, out);
4616 case Variable::UNIFORM:
4618 cloneVariableForStage(variable, stage, variable.m_storage, prefix);
4621 TCU_FAIL("Invalid enum");
4626 /** Clone variable for specific stage
4628 * @param variable Variable
4629 * @param stage Requested stage
4630 * @param storage Storage used by variable
4631 * @param prefix Prefix used in variable name that is specific for original stage
4633 * @return New variable
4635 Variable* ProgramInterface::cloneVariableForStage(const Variable& variable, Shader::STAGES stage,
4636 Variable::STORAGE storage, const GLchar* prefix)
4638 /* Initialize with original variable */
4639 Variable* var = new Variable(variable);
4642 TCU_FAIL("Memory allocation");
4645 /* Set up storage */
4646 var->m_storage = storage;
4649 std::string name = variable.m_descriptor.m_name;
4651 /* Prefix name with stage ID, empty means default block */
4652 if (false == name.empty())
4654 size_t position = 0;
4655 const GLchar* stage_prefix = GetStagePrefix(stage, storage);
4656 Utils::replaceToken(prefix, position, stage_prefix, name);
4658 var->m_descriptor.m_name = name;
4661 const bool is_block = variable.IsBlock();
4662 if (true == is_block)
4664 const Interface* interface = variable.m_descriptor.m_interface;
4666 Interface* block = CloneBlockForStage(*interface, stage, storage, prefix);
4668 var->m_descriptor.m_interface = block;
4671 /* Store variable */
4672 ShaderInterface& si = GetShaderInterface(stage);
4673 Variable* result = 0;
4677 case Variable::VARYING_INPUT:
4678 si.m_inputs.push_back(var);
4679 result = si.m_inputs.back();
4681 case Variable::VARYING_OUTPUT:
4682 si.m_outputs.push_back(var);
4683 result = si.m_outputs.back();
4685 case Variable::UNIFORM:
4686 /* Uniform blocks needs unique binding */
4687 if (true == is_block)
4689 replaceBinding(*var, stage);
4692 si.m_uniforms.push_back(var);
4693 result = si.m_uniforms.back();
4696 /* SSBs needs unique binding */
4697 if (true == is_block)
4699 replaceBinding(*var, stage);
4702 si.m_ssb_blocks.push_back(var);
4703 result = si.m_ssb_blocks.back();
4706 TCU_FAIL("Invalid enum");
4713 /** clone block to specific stage
4715 * @param block Block to be copied
4716 * @param stage Specific stage
4717 * @param storage Storage used by block
4718 * @param prefix Prefix used in block name
4720 * @return New interface
4722 Interface* ProgramInterface::CloneBlockForStage(const Interface& block, Shader::STAGES stage, Variable::STORAGE storage,
4723 const GLchar* prefix)
4726 std::string name = block.m_name;
4728 /* Prefix name with stage ID */
4729 size_t position = 0;
4730 const GLchar* stage_prefix = GetStagePrefix(stage, storage);
4731 Utils::replaceToken(prefix, position, stage_prefix, name);
4733 Interface* ptr = GetBlock(name.c_str());
4737 ptr = AddInterface(name.c_str(), Interface::BLOCK);
4740 ptr->m_members = block.m_members;
4745 /** Get stage specific prefix used in names
4747 * @param stage Stage
4748 * @param storage Storage class
4752 const GLchar* ProgramInterface::GetStagePrefix(Shader::STAGES stage, Variable::STORAGE storage)
4754 static const GLchar* lut[Shader::STAGE_MAX][Variable::STORAGE_MAX] = {
4755 /* IN OUT UNIFORM SSB MEMBER */
4756 /* CS */ { 0, 0, "cs_uni_", "cs_buf_", "" },
4757 /* VS */ { "in_vs_", "vs_tcs_", "vs_uni_", "vs_buf_", "" },
4758 /* TCS */ { "vs_tcs_", "tcs_tes_", "tcs_uni_", "tcs_buf_", "" },
4759 /* TES */ { "tcs_tes_", "tes_gs_", "tes_uni_", "tes_buf_", "" },
4760 /* GS */ { "tes_gs_", "gs_fs_", "gs_uni_", "gs_buf_", "" },
4761 /* FS */ { "gs_fs_", "fs_out_", "fs_uni_", "fs_buf_", "" },
4764 const GLchar* result = 0;
4766 result = lut[stage][storage];
4771 /** Get definitions of all structures used in program interface
4773 * @return String with code
4775 std::string ProgramInterface::GetDefinitionsStructures() const
4777 return GetDefinitions(m_structures);
4780 /** Get interface code for stage
4782 * @param stage Specific stage
4784 * @return String with code
4786 std::string ProgramInterface::GetInterfaceForStage(Shader::STAGES stage) const
4788 size_t position = 0;
4789 std::string interface = "/* Globals */\n"
4792 "/* Structures */\n"
4807 const ShaderInterface& si = GetShaderInterface(stage);
4809 const std::string& structures = GetDefinitionsStructures();
4811 const std::string& globals = si.GetDefinitionsGlobals();
4812 const std::string& inputs = si.GetDefinitionsInputs();
4813 const std::string& outputs = si.GetDefinitionsOutputs();
4814 const std::string& uniforms = si.GetDefinitionsUniforms();
4815 const std::string& ssbs = si.GetDefinitionsSSBs();
4817 replaceToken("GLOBALS", position, globals.c_str(), interface);
4818 replaceToken("STRUCTURES", position, structures.c_str(), interface);
4819 replaceToken("UNIFORMS", position, uniforms.c_str(), interface);
4820 replaceToken("INPUTS", position, inputs.c_str(), interface);
4821 replaceToken("OUTPUTS", position, outputs.c_str(), interface);
4822 replaceToken("STORAGE", position, ssbs.c_str(), interface);
4827 /** Functional object used in find_if algorithm, in search for interface of given name
4830 struct matchInterfaceName
4832 matchInterfaceName(const GLchar* name) : m_name(name)
4836 bool operator()(const Interface* interface)
4838 return 0 == interface->m_name.compare(m_name);
4841 const GLchar* m_name;
4844 /** Finds interface of given name in given vector of interfaces
4846 * @param vector Collection of interfaces
4847 * @param name Requested name
4849 * @return Pointer to interface if available, 0 otherwise
4851 static Interface* findInterfaceByName(Interface::PtrVector& vector, const GLchar* name)
4853 Interface::PtrVector::iterator it = std::find_if(vector.begin(), vector.end(), matchInterfaceName(name));
4855 if (vector.end() != it)
4865 /** Search for block of given name
4867 * @param name Name of block
4869 * @return Pointer to block or 0
4871 Interface* ProgramInterface::GetBlock(const GLchar* name)
4873 return findInterfaceByName(m_blocks, name);
4876 /** Search for structure of given name
4878 * @param name Name of structure
4880 * @return Pointer to structure or 0
4882 Interface* ProgramInterface::GetStructure(const GLchar* name)
4884 return findInterfaceByName(m_structures, name);
4887 /** Adds new sturcture to interface
4889 * @param name Name of structure
4891 * @return Created structure
4893 Interface* ProgramInterface::Structure(const GLchar* name)
4895 return AddInterface(name, Interface::STRUCT);
4898 /** Replace "BINDING" token in qualifiers string to value specific for given stage
4900 * @param variable Variable to modify
4901 * @param stage Requested stage
4903 void ProgramInterface::replaceBinding(Variable& variable, Shader::STAGES stage)
4906 sprintf(binding, "%d", stage);
4907 replaceAllTokens("BINDING", binding, variable.m_descriptor.m_qualifiers);
4909 } /* Utils namespace */
4911 /** Debuging procedure. Logs parameters.
4913 * @param source As specified in GL spec.
4914 * @param type As specified in GL spec.
4915 * @param id As specified in GL spec.
4916 * @param severity As specified in GL spec.
4918 * @param message As specified in GL spec.
4919 * @param info Pointer to instance of Context used by test.
4921 void GLW_APIENTRY debug_proc(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei /* length */,
4922 const GLchar* message, void* info)
4924 deqp::Context* ctx = (deqp::Context*)info;
4926 const GLchar* source_str = "Unknown";
4927 const GLchar* type_str = "Unknown";
4928 const GLchar* severity_str = "Unknown";
4932 case GL_DEBUG_SOURCE_API:
4935 case GL_DEBUG_SOURCE_APPLICATION:
4938 case GL_DEBUG_SOURCE_OTHER:
4941 case GL_DEBUG_SOURCE_SHADER_COMPILER:
4944 case GL_DEBUG_SOURCE_THIRD_PARTY:
4947 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
4956 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
4957 type_str = "DEPRECATED_BEHAVIOR";
4959 case GL_DEBUG_TYPE_ERROR:
4962 case GL_DEBUG_TYPE_MARKER:
4963 type_str = "MARKER";
4965 case GL_DEBUG_TYPE_OTHER:
4968 case GL_DEBUG_TYPE_PERFORMANCE:
4969 type_str = "PERFORMANCE";
4971 case GL_DEBUG_TYPE_POP_GROUP:
4972 type_str = "POP_GROUP";
4974 case GL_DEBUG_TYPE_PORTABILITY:
4975 type_str = "PORTABILITY";
4977 case GL_DEBUG_TYPE_PUSH_GROUP:
4978 type_str = "PUSH_GROUP";
4980 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
4981 type_str = "UNDEFINED_BEHAVIOR";
4989 case GL_DEBUG_SEVERITY_HIGH:
4992 case GL_DEBUG_SEVERITY_LOW:
4995 case GL_DEBUG_SEVERITY_MEDIUM:
4998 case GL_DEBUG_SEVERITY_NOTIFICATION:
5005 ctx->getTestContext().getLog() << tcu::TestLog::Message << "DEBUG_INFO: " << std::setw(3) << source_str << "|"
5006 << severity_str << "|" << std::setw(18) << type_str << "|" << std::setw(12) << id
5007 << ": " << message << tcu::TestLog::EndMessage;
5012 * @param context Test context
5013 * @param test_name Test name
5014 * @param test_description Test description
5016 TestBase::TestBase(deqp::Context& context, const GLchar* test_name, const GLchar* test_description)
5017 : TestCase(context, test_name, test_description)
5019 /* Nothing to be done here */
5024 * @return tcu::TestNode::STOP otherwise
5026 tcu::TestNode::IterateResult TestBase::iterate()
5030 #if DEBUG_ENBALE_MESSAGE_CALLBACK
5031 const Functions& gl = m_context.getRenderContext().getFunctions();
5033 gl.debugMessageCallback(debug_proc, &m_context);
5034 GLU_EXPECT_NO_ERROR(gl.getError(), "DebugMessageCallback");
5035 #endif /* DEBUG_ENBALE_MESSAGE_CALLBACK */
5040 test_result = test();
5042 catch (std::exception& exc)
5044 TCU_FAIL(exc.what());
5048 if (true == test_result)
5050 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
5054 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
5058 return tcu::TestNode::STOP;
5061 /** Get last input location available for given type at specific stage
5063 * @param stage Shader stage
5064 * @param type Input type
5065 * @param array_length Length of input array
5067 * @return Last location index
5069 GLint TestBase::getLastInputLocation(Utils::Shader::STAGES stage, const Utils::Type& type, GLuint array_length)
5071 GLint divide = 4; /* 4 components per location */
5078 case Utils::Shader::FRAGMENT:
5079 pname = GL_MAX_FRAGMENT_INPUT_COMPONENTS;
5081 case Utils::Shader::GEOMETRY:
5082 pname = GL_MAX_GEOMETRY_INPUT_COMPONENTS;
5084 case Utils::Shader::TESS_CTRL:
5085 pname = GL_MAX_TESS_CONTROL_INPUT_COMPONENTS;
5087 case Utils::Shader::TESS_EVAL:
5088 pname = GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS;
5090 case Utils::Shader::VERTEX:
5091 pname = GL_MAX_VERTEX_ATTRIBS;
5095 TCU_FAIL("Invalid enum");
5099 /* Zero means no array, but 1 slot is required */
5100 if (0 == array_length)
5106 const Functions& gl = m_context.getRenderContext().getFunctions();
5108 gl.getIntegerv(pname, ¶m);
5109 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
5112 #if WRKARD_VARYINGLOCATIONSTEST
5114 const GLint n_avl_locations = 16;
5118 const GLint n_avl_locations = param / divide;
5122 const GLuint n_req_location = type.GetLocations() * array_length;
5124 return n_avl_locations - n_req_location; /* last is max - 1 */
5127 /** Get last input location available for given type at specific stage
5129 * @param stage Shader stage
5130 * @param type Input type
5131 * @param array_length Length of input array
5133 * @return Last location index
5135 GLint TestBase::getLastOutputLocation(Utils::Shader::STAGES stage, const Utils::Type& type, GLuint array_length)
5143 case Utils::Shader::GEOMETRY:
5144 pname = GL_MAX_GEOMETRY_OUTPUT_COMPONENTS;
5146 case Utils::Shader::TESS_CTRL:
5147 pname = GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS;
5149 case Utils::Shader::TESS_EVAL:
5150 pname = GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS;
5152 case Utils::Shader::VERTEX:
5153 pname = GL_MAX_VERTEX_OUTPUT_COMPONENTS;
5156 TCU_FAIL("Invalid enum");
5160 /* Zero means no array, but 1 slot is required */
5161 if (0 == array_length)
5167 const Functions& gl = m_context.getRenderContext().getFunctions();
5169 gl.getIntegerv(pname, ¶m);
5170 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
5173 #if WRKARD_VARYINGLOCATIONSTEST
5175 const GLint n_avl_locations = 16;
5179 const GLint n_avl_locations = param / 4; /* 4 components per location */
5183 const GLuint n_req_location = type.GetLocations() * array_length;
5185 return n_avl_locations - n_req_location; /* last is max - 1 */
5188 /** Basic implementation
5192 * @return Empty string
5194 std::string TestBase::getTestCaseName(GLuint /* test_case_index */)
5201 /** Basic implementation
5205 GLuint TestBase::getTestCaseNumber()
5210 /** Check if flat qualifier is required for given type, stage and storage
5212 * @param stage Shader stage
5213 * @param type Input type
5214 * @param storage Storage of variable
5216 * @return Last location index
5218 bool TestBase::isFlatRequired(Utils::Shader::STAGES stage, const Utils::Type& type,
5219 Utils::Variable::STORAGE storage) const
5221 /* Float types do not need flat at all */
5222 if (Utils::Type::Float == type.m_basic_type)
5227 /* Inputs to fragment shader */
5228 if ((Utils::Shader::FRAGMENT == stage) && (Utils::Variable::VARYING_INPUT == storage))
5233 /* Outputs from geometry shader */
5234 if ((Utils::Shader::FRAGMENT == stage) && (Utils::Variable::VARYING_OUTPUT == storage))
5242 /** Basic implementation of testInit method
5245 void TestBase::testInit()
5249 /** Calculate stride for interface
5251 * @param interface Interface
5253 * @return Calculated value
5255 GLuint TestBase::calculateStride(const Utils::Interface& interface) const
5257 const size_t n_members = interface.m_members.size();
5261 for (size_t i = 0; i < n_members; ++i)
5263 const Utils::Variable::Descriptor& member = interface.m_members[i];
5264 const GLuint member_offset = member.m_offset;
5265 const GLuint member_stride = member.m_expected_stride_of_element;
5266 const GLuint member_ends_at = member_offset + member_stride;
5268 stride = std::max(stride, member_ends_at);
5274 /** Generate data for interface. This routine is recursive
5276 * @param interface Interface
5277 * @param offset Offset in out_data
5278 * @param out_data Buffer to be filled
5280 void TestBase::generateData(const Utils::Interface& interface, GLuint offset, std::vector<GLubyte>& out_data) const
5282 const size_t n_members = interface.m_members.size();
5283 GLubyte* ptr = &out_data[offset];
5285 for (size_t i = 0; i < n_members; ++i)
5287 const Utils::Variable::Descriptor& member = interface.m_members[i];
5288 const GLuint member_offset = member.m_offset;
5289 const GLuint n_elements = (0 == member.m_n_array_elements) ? 1 : member.m_n_array_elements;
5291 for (GLuint element = 0; element < n_elements; ++element)
5293 const GLuint element_offset = element * member.m_expected_stride_of_element;
5294 const GLuint data_offfset = member_offset + element_offset;
5296 if (Utils::Variable::BUILTIN == member.m_type)
5298 const std::vector<GLubyte>& data = member.m_builtin.GenerateData();
5300 memcpy(ptr + data_offfset, &data[0], data.size());
5304 generateData(*member.m_interface, offset + data_offfset, out_data);
5310 /** Get type at index
5312 * @param index Index of requested type
5316 Utils::Type TestBase::getType(GLuint index) const
5323 type = Utils::Type::_double;
5326 type = Utils::Type::dmat2;
5329 type = Utils::Type::dmat2x3;
5332 type = Utils::Type::dmat2x4;
5335 type = Utils::Type::dmat3;
5338 type = Utils::Type::dmat3x2;
5341 type = Utils::Type::dmat3x4;
5344 type = Utils::Type::dmat4;
5347 type = Utils::Type::dmat4x2;
5350 type = Utils::Type::dmat4x3;
5353 type = Utils::Type::dvec2;
5356 type = Utils::Type::dvec3;
5359 type = Utils::Type::dvec4;
5362 type = Utils::Type::_float;
5365 type = Utils::Type::mat2;
5368 type = Utils::Type::mat2x3;
5371 type = Utils::Type::mat2x4;
5374 type = Utils::Type::mat3;
5377 type = Utils::Type::mat3x2;
5380 type = Utils::Type::mat3x4;
5383 type = Utils::Type::mat4;
5386 type = Utils::Type::mat4x2;
5389 type = Utils::Type::mat4x3;
5392 type = Utils::Type::vec2;
5395 type = Utils::Type::vec3;
5398 type = Utils::Type::vec4;
5401 type = Utils::Type::_int;
5404 type = Utils::Type::ivec2;
5407 type = Utils::Type::ivec3;
5410 type = Utils::Type::ivec4;
5413 type = Utils::Type::uint;
5416 type = Utils::Type::uvec2;
5419 type = Utils::Type::uvec3;
5422 type = Utils::Type::uvec4;
5425 TCU_FAIL("invalid enum");
5431 /** Get name of type at index
5433 * @param index Index of type
5437 std::string TestBase::getTypeName(GLuint index) const
5439 std::string name = getType(index).GetGLSLTypeName();
5444 /** Get number of types
5448 glw::GLuint TestBase::getTypesNumber() const
5455 * @return true if test pass, false otherwise
5457 bool TestBase::test()
5460 GLuint n_test_cases = 0;
5465 /* GL entry points */
5466 const Functions& gl = m_context.getRenderContext().getFunctions();
5468 /* Tessellation patch set up */
5469 gl.patchParameteri(GL_PATCH_VERTICES, 1);
5470 GLU_EXPECT_NO_ERROR(gl.getError(), "PatchParameteri");
5472 /* Get number of test cases */
5473 n_test_cases = getTestCaseNumber();
5475 #if DEBUG_REPEAT_TEST_CASE
5479 GLuint test_case = DEBUG_REPEATED_TEST_CASE;
5481 #else /* DEBUG_REPEAT_TEST_CASE */
5483 for (GLuint test_case = 0; test_case < n_test_cases; ++test_case)
5486 #endif /* DEBUG_REPEAT_TEST_CASE */
5488 bool case_result = true;
5491 if (false == testCase(test_case))
5493 case_result = false;
5497 if (false == case_result)
5499 const std::string& test_case_name = getTestCaseName(test_case);
5501 if (false == test_case_name.empty())
5503 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Test case (" << test_case_name
5504 << ") failed." << tcu::TestLog::EndMessage;
5508 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Test case (" << test_case
5509 << ") failed." << tcu::TestLog::EndMessage;
5520 /* Constants used by BufferTestBase */
5521 const GLuint BufferTestBase::bufferDescriptor::m_non_indexed = -1;
5525 * @param context Test context
5526 * @param test_name Name of test
5527 * @param test_description Description of test
5529 BufferTestBase::BufferTestBase(deqp::Context& context, const GLchar* test_name, const GLchar* test_description)
5530 : TestBase(context, test_name, test_description)
5534 /** Execute drawArrays for single vertex
5540 bool BufferTestBase::executeDrawCall(bool tesEnabled, GLuint /* test_case_index */)
5542 const Functions& gl = m_context.getRenderContext().getFunctions();
5544 gl.disable(GL_RASTERIZER_DISCARD);
5545 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
5547 gl.beginTransformFeedback(GL_POINTS);
5548 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
5550 // Only TES is existed, glDrawArray can use the parameter GL_PATCHES
5551 if (tesEnabled == false)
5553 gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */);
5557 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
5560 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
5562 gl.endTransformFeedback();
5563 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
5568 /** Get descriptors of buffers necessary for test
5573 void BufferTestBase::getBufferDescriptors(glw::GLuint /* test_case_index */,
5574 bufferDescriptor::Vector& /* out_descriptors */)
5576 /* Nothhing to be done */
5579 /** Get list of names of varyings that will be registered with TransformFeedbackVaryings
5584 void BufferTestBase::getCapturedVaryings(glw::GLuint /* test_case_index */,
5585 Utils::Program::NameVector& /* captured_varyings */)
5587 /* Nothing to be done */
5590 /** Get body of main function for given shader stage
5594 * @param out_assignments Set to empty
5595 * @param out_calculations Set to empty
5597 void BufferTestBase::getShaderBody(glw::GLuint /* test_case_index */, Utils::Shader::STAGES /* stage */,
5598 std::string& out_assignments, std::string& out_calculations)
5600 out_assignments = "";
5601 out_calculations = "";
5604 /** Get interface of shader
5608 * @param out_interface Set to ""
5610 void BufferTestBase::getShaderInterface(glw::GLuint /* test_case_index */, Utils::Shader::STAGES /* stage */,
5611 std::string& out_interface)
5616 /** Get source code of shader
5618 * @param test_case_index Index of test case
5619 * @param stage Shader stage
5623 std::string BufferTestBase::getShaderSource(glw::GLuint test_case_index, Utils::Shader::STAGES stage)
5625 std::string assignments;
5626 std::string calculations;
5627 std::string interface;
5630 getShaderBody(test_case_index, stage, assignments, calculations);
5631 getShaderInterface(test_case_index, stage, interface);
5634 std::string source = getShaderTemplate(stage);
5637 size_t position = 0;
5638 Utils::replaceToken("INTERFACE", position, interface.c_str(), source);
5639 Utils::replaceToken("CALCULATIONS", position, calculations.c_str(), source);
5640 Utils::replaceToken("ASSIGNMENTS", position, assignments.c_str(), source);
5646 /** Inspects program to check if all resources are as expected
5654 bool BufferTestBase::inspectProgram(GLuint /* test_case_index */, Utils::Program& /* program */,
5655 std::stringstream& /* out_stream */)
5662 * @param test_case_index Id of test case
5664 * @return true if test case pass, false otherwise
5666 bool BufferTestBase::testCase(GLuint test_case_index)
5670 bufferCollection buffers;
5671 Utils::Program::NameVector captured_varyings;
5672 bufferDescriptor::Vector descriptors;
5673 Utils::Program program(m_context);
5674 Utils::VertexArray vao(m_context);
5676 /* Get captured varyings */
5677 getCapturedVaryings(test_case_index, captured_varyings);
5679 /* Get shader sources */
5680 const std::string& fragment_shader = getShaderSource(test_case_index, Utils::Shader::FRAGMENT);
5681 const std::string& geometry_shader = getShaderSource(test_case_index, Utils::Shader::GEOMETRY);
5682 const std::string& tess_ctrl_shader = getShaderSource(test_case_index, Utils::Shader::TESS_CTRL);
5683 const std::string& tess_eval_shader = getShaderSource(test_case_index, Utils::Shader::TESS_EVAL);
5684 const std::string& vertex_shader = getShaderSource(test_case_index, Utils::Shader::VERTEX);
5686 /* Set up program */
5687 program.Init("" /* compute_shader */, fragment_shader, geometry_shader, tess_ctrl_shader, tess_eval_shader,
5688 vertex_shader, captured_varyings, true, false /* is_separable */);
5692 std::stringstream stream;
5693 if (false == inspectProgram(test_case_index, program, stream))
5695 m_context.getTestContext().getLog()
5696 << tcu::TestLog::Message
5697 << "Program inspection failed. Test case: " << getTestCaseName(test_case_index)
5698 << ". Reason: " << stream.str() << tcu::TestLog::EndMessage
5699 << tcu::TestLog::KernelSource(vertex_shader) << tcu::TestLog::KernelSource(tess_ctrl_shader)
5700 << tcu::TestLog::KernelSource(tess_eval_shader) << tcu::TestLog::KernelSource(geometry_shader)
5701 << tcu::TestLog::KernelSource(fragment_shader);
5709 /* Set up buffers */
5710 getBufferDescriptors(test_case_index, descriptors);
5712 prepareBuffers(descriptors, buffers);
5719 bool result = executeDrawCall((program.m_tess_eval.m_id != 0), test_case_index);
5722 m_context.getRenderContext().postIterate();
5725 if (false == result)
5727 m_context.getTestContext().getLog()
5728 << tcu::TestLog::KernelSource(vertex_shader) << tcu::TestLog::KernelSource(tess_ctrl_shader)
5729 << tcu::TestLog::KernelSource(tess_eval_shader) << tcu::TestLog::KernelSource(geometry_shader)
5730 << tcu::TestLog::KernelSource(fragment_shader);
5736 if (false == verifyBuffers(buffers))
5738 m_context.getTestContext().getLog()
5739 << tcu::TestLog::KernelSource(vertex_shader) << tcu::TestLog::KernelSource(tess_ctrl_shader)
5740 << tcu::TestLog::KernelSource(tess_eval_shader) << tcu::TestLog::KernelSource(geometry_shader)
5741 << tcu::TestLog::KernelSource(fragment_shader);
5746 catch (Utils::Shader::InvalidSourceException& exc)
5749 TCU_FAIL(exc.what());
5751 catch (Utils::Program::BuildException& exc)
5754 TCU_FAIL(exc.what());
5761 /** Verify contents of buffers
5763 * @param buffers Collection of buffers to be verified
5765 * @return true if everything is as expected, false otherwise
5767 bool BufferTestBase::verifyBuffers(bufferCollection& buffers)
5771 for (bufferCollection::Vector::iterator it = buffers.m_vector.begin(), end = buffers.m_vector.end(); end != it;
5774 bufferCollection::pair& pair = *it;
5775 Utils::Buffer* buffer = pair.m_buffer;
5776 bufferDescriptor* descriptor = pair.m_descriptor;
5777 size_t size = descriptor->m_expected_data.size();
5779 /* Skip buffers that have no expected data */
5785 /* Get pointer to contents of buffer */
5787 GLvoid* buffer_data = buffer->Map(Utils::Buffer::ReadOnly);
5789 /* Get pointer to expected data */
5790 GLvoid* expected_data = &descriptor->m_expected_data[0];
5793 int res = memcmp(buffer_data, expected_data, size);
5797 m_context.getTestContext().getLog()
5798 << tcu::TestLog::Message
5799 << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
5800 << ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
5805 /* Release buffer mapping */
5812 /** Unbinds all uniforms and xfb
5815 void BufferTestBase::cleanBuffers()
5817 const Functions& gl = m_context.getRenderContext().getFunctions();
5822 gl.getIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &max_uni);
5823 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_xfb);
5824 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
5826 for (GLint i = 0; i < max_uni; ++i)
5828 Utils::Buffer::BindBase(gl, 0, Utils::Buffer::Uniform, i);
5831 for (GLint i = 0; i < max_xfb; ++i)
5833 Utils::Buffer::BindBase(gl, 0, Utils::Buffer::Transform_feedback, i);
5837 /** Get template of shader for given stage
5839 * @param stage Stage
5841 * @return Template of shader source
5843 std::string BufferTestBase::getShaderTemplate(Utils::Shader::STAGES stage)
5845 static const GLchar* compute_shader_template = "#version 430 core\n"
5846 "#extension GL_ARB_enhanced_layouts : require\n"
5848 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
5850 "writeonly uniform uimage2D uni_image;\n"
5862 static const GLchar* fragment_shader_template = "#version 430 core\n"
5863 "#extension GL_ARB_enhanced_layouts : require\n"
5875 // max_vertices is set to 3 for the test case "xfb_vertex_streams" declares 3 streams in geometry shader,
5876 // according to spec, max_vertices should be no less than 3 if there are 3 streams in GS.
5877 static const GLchar* geometry_shader_template = "#version 430 core\n"
5878 "#extension GL_ARB_enhanced_layouts : require\n"
5880 "layout(points) in;\n"
5881 "layout(points, max_vertices = 3) out;\n"
5891 " gl_Position = vec4(0, 0, 0, 1);\n"
5896 static const GLchar* tess_ctrl_shader_template = "#version 430 core\n"
5897 "#extension GL_ARB_enhanced_layouts : require\n"
5899 "layout(vertices = 1) out;\n"
5909 " gl_TessLevelOuter[0] = 1.0;\n"
5910 " gl_TessLevelOuter[1] = 1.0;\n"
5911 " gl_TessLevelOuter[2] = 1.0;\n"
5912 " gl_TessLevelOuter[3] = 1.0;\n"
5913 " gl_TessLevelInner[0] = 1.0;\n"
5914 " gl_TessLevelInner[1] = 1.0;\n"
5918 static const GLchar* tess_eval_shader_template = "#version 430 core\n"
5919 "#extension GL_ARB_enhanced_layouts : require\n"
5921 "layout(isolines, point_mode) in;\n"
5933 static const GLchar* vertex_shader_template = "#version 430 core\n"
5934 "#extension GL_ARB_enhanced_layouts : require\n"
5946 const GLchar* result = 0;
5950 case Utils::Shader::COMPUTE:
5951 result = compute_shader_template;
5953 case Utils::Shader::FRAGMENT:
5954 result = fragment_shader_template;
5956 case Utils::Shader::GEOMETRY:
5957 result = geometry_shader_template;
5959 case Utils::Shader::TESS_CTRL:
5960 result = tess_ctrl_shader_template;
5962 case Utils::Shader::TESS_EVAL:
5963 result = tess_eval_shader_template;
5965 case Utils::Shader::VERTEX:
5966 result = vertex_shader_template;
5969 TCU_FAIL("Invalid enum");
5975 /** Prepare buffer according to descriptor
5977 * @param buffer Buffer to prepare
5978 * @param desc Descriptor
5980 void BufferTestBase::prepareBuffer(Utils::Buffer& buffer, bufferDescriptor& desc)
5982 GLsizeiptr size = 0;
5985 if (false == desc.m_initial_data.empty())
5987 size = desc.m_initial_data.size();
5988 data = &desc.m_initial_data[0];
5990 else if (false == desc.m_expected_data.empty())
5992 size = desc.m_expected_data.size();
5995 buffer.Init(desc.m_target, Utils::Buffer::StaticDraw, size, data);
5997 if (bufferDescriptor::m_non_indexed != desc.m_index)
5999 buffer.BindBase(desc.m_index);
6007 /** Prepare collection of buffer
6009 * @param descriptors Collection of descriptors
6010 * @param out_buffers Collection of buffers
6012 void BufferTestBase::prepareBuffers(bufferDescriptor::Vector& descriptors, bufferCollection& out_buffers)
6014 for (bufferDescriptor::Vector::iterator it = descriptors.begin(), end = descriptors.end(); end != it; ++it)
6016 bufferCollection::pair pair;
6018 pair.m_buffer = new Utils::Buffer(m_context);
6019 if (0 == pair.m_buffer)
6021 TCU_FAIL("Memory allocation failed");
6024 pair.m_descriptor = &(*it);
6026 prepareBuffer(*pair.m_buffer, *pair.m_descriptor);
6028 out_buffers.m_vector.push_back(pair);
6035 BufferTestBase::bufferCollection::~bufferCollection()
6037 for (Vector::iterator it = m_vector.begin(), end = m_vector.end(); end != it; ++it)
6039 if (0 != it->m_buffer)
6041 delete it->m_buffer;
6049 * @param context Test context
6050 * @param test_name Name of test
6051 * @param test_description Description of test
6053 NegativeTestBase::NegativeTestBase(deqp::Context& context, const GLchar* test_name, const GLchar* test_description)
6054 : TestBase(context, test_name, test_description)
6058 /** Selects if "compute" stage is relevant for test
6064 bool NegativeTestBase::isComputeRelevant(GLuint /* test_case_index */)
6069 /** Selects if compilation failure is expected result
6075 bool NegativeTestBase::isFailureExpected(GLuint /* test_case_index */)
6082 * @param test_case_index Id of test case
6084 * @return true if test case pass, false otherwise
6086 bool NegativeTestBase::testCase(GLuint test_case_index)
6088 bool test_case_result = true;
6091 if (true == isComputeRelevant(test_case_index))
6093 const std::string& cs_source = getShaderSource(test_case_index, Utils::Shader::COMPUTE);
6094 bool is_build_error = false;
6095 const bool is_failure_expected = isFailureExpected(test_case_index);
6096 Utils::Program program(m_context);
6100 program.Init(cs_source, "" /* fs */, "" /* gs */, "" /* tcs */, "" /* tes */, "" /* vs */,
6101 false /* separable */);
6103 catch (Utils::Shader::InvalidSourceException& exc)
6105 if (false == is_failure_expected)
6107 m_context.getTestContext().getLog()
6108 << tcu::TestLog::Message << "Unexpected error in shader compilation: " << tcu::TestLog::EndMessage;
6112 #if DEBUG_NEG_LOG_ERROR
6116 m_context.getTestContext().getLog()
6117 << tcu::TestLog::Message << "Error in shader compilation was expected, logged for verification: "
6118 << tcu::TestLog::EndMessage;
6122 #endif /* DEBUG_NEG_LOG_ERROR */
6124 is_build_error = true;
6126 catch (Utils::Program::BuildException& exc)
6128 if (false == is_failure_expected)
6130 m_context.getTestContext().getLog()
6131 << tcu::TestLog::Message << "Unexpected error in program linking: " << tcu::TestLog::EndMessage;
6135 #if DEBUG_NEG_LOG_ERROR
6139 m_context.getTestContext().getLog()
6140 << tcu::TestLog::Message
6141 << "Error in program linking was expected, logged for verification: " << tcu::TestLog::EndMessage;
6145 #endif /* DEBUG_NEG_LOG_ERROR */
6147 is_build_error = true;
6150 if (is_build_error != is_failure_expected)
6152 if (!is_build_error)
6154 m_context.getTestContext().getLog()
6155 << tcu::TestLog::Message << "Unexpected success: " << tcu::TestLog::EndMessage;
6156 Utils::Shader::LogSource(m_context, cs_source, Utils::Shader::COMPUTE);
6158 test_case_result = false;
6163 const std::string& fs_source = getShaderSource(test_case_index, Utils::Shader::FRAGMENT);
6164 const std::string& gs_source = getShaderSource(test_case_index, Utils::Shader::GEOMETRY);
6165 bool is_build_error = false;
6166 const bool is_failure_expected = isFailureExpected(test_case_index);
6167 Utils::Program program(m_context);
6168 const std::string& tcs_source = getShaderSource(test_case_index, Utils::Shader::TESS_CTRL);
6169 const std::string& tes_source = getShaderSource(test_case_index, Utils::Shader::TESS_EVAL);
6170 const std::string& vs_source = getShaderSource(test_case_index, Utils::Shader::VERTEX);
6174 program.Init("" /* cs */, fs_source, gs_source, tcs_source, tes_source, vs_source, false /* separable */);
6176 catch (Utils::Shader::InvalidSourceException& exc)
6178 if (false == is_failure_expected)
6180 m_context.getTestContext().getLog()
6181 << tcu::TestLog::Message << "Unexpected error in shader compilation: " << tcu::TestLog::EndMessage;
6185 #if DEBUG_NEG_LOG_ERROR
6189 m_context.getTestContext().getLog()
6190 << tcu::TestLog::Message << "Error in shader compilation was expected, logged for verification: "
6191 << tcu::TestLog::EndMessage;
6195 #endif /* DEBUG_NEG_LOG_ERROR */
6197 is_build_error = true;
6199 catch (Utils::Program::BuildException& exc)
6201 if (false == is_failure_expected)
6203 m_context.getTestContext().getLog()
6204 << tcu::TestLog::Message << "Unexpected error in program linking: " << tcu::TestLog::EndMessage;
6208 #if DEBUG_NEG_LOG_ERROR
6212 m_context.getTestContext().getLog()
6213 << tcu::TestLog::Message
6214 << "Error in program linking was expected, logged for verification: " << tcu::TestLog::EndMessage;
6218 #endif /* DEBUG_NEG_LOG_ERROR */
6220 is_build_error = true;
6223 if (is_build_error != is_failure_expected)
6225 if (!is_build_error)
6227 m_context.getTestContext().getLog()
6228 << tcu::TestLog::Message << "Unexpected success: " << tcu::TestLog::EndMessage;
6229 Utils::Shader::LogSource(m_context, vs_source, Utils::Shader::VERTEX);
6230 Utils::Shader::LogSource(m_context, tcs_source, Utils::Shader::TESS_CTRL);
6231 Utils::Shader::LogSource(m_context, tes_source, Utils::Shader::TESS_EVAL);
6232 Utils::Shader::LogSource(m_context, gs_source, Utils::Shader::GEOMETRY);
6233 Utils::Shader::LogSource(m_context, fs_source, Utils::Shader::FRAGMENT);
6235 test_case_result = false;
6239 return test_case_result;
6242 /* Constants used by TextureTestBase */
6243 const glw::GLuint TextureTestBase::m_width = 16;
6244 const glw::GLuint TextureTestBase::m_height = 16;
6248 * @param context Test context
6249 * @param test_name Name of test
6250 * @param test_description Description of test
6252 TextureTestBase::TextureTestBase(deqp::Context& context, const GLchar* test_name, const GLchar* test_description)
6253 : TestBase(context, test_name, test_description)
6257 /** Get locations for all inputs with automatic_location
6259 * @param program Program object
6260 * @param program_interface Interface of program
6262 void TextureTestBase::prepareAttribLocation(Utils::Program& program, Utils::ProgramInterface& program_interface)
6264 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
6266 Utils::Variable::PtrVector& inputs = si.m_inputs;
6268 for (Utils::Variable::PtrVector::iterator it = inputs.begin(); inputs.end() != it; ++it)
6270 /* Test does not specify location, query value and set */
6271 if (Utils::Variable::m_automatic_location == (*it)->m_descriptor.m_expected_location)
6273 GLuint index = program.GetResourceIndex((*it)->m_descriptor.m_name, GL_PROGRAM_INPUT);
6276 program.GetResource(GL_PROGRAM_INPUT, index, GL_LOCATION, 1 /* size */, &location);
6278 (*it)->m_descriptor.m_expected_location = location;
6283 /** Verifies contents of drawn image
6286 * @param color_0 Verified image
6288 * @return true if image is filled with 1, false otherwise
6290 bool TextureTestBase::checkResults(glw::GLuint /* test_case_index */, Utils::Texture& color_0)
6292 static const GLuint size = m_width * m_height;
6293 static const GLuint expected_color = 1;
6295 std::vector<GLuint> data;
6298 color_0.Get(GL_RED_INTEGER, GL_UNSIGNED_INT, &data[0]);
6300 for (GLuint i = 0; i < size; ++i)
6302 const GLuint color = data[i];
6304 if (expected_color != color)
6306 m_context.getTestContext().getLog() << tcu::TestLog::Message << "R32UI[" << i << "]:" << color
6307 << tcu::TestLog::EndMessage;
6315 /** Execute dispatch compute for 16x16x1
6319 void TextureTestBase::executeDispatchCall(GLuint /* test_case_index */)
6321 const Functions& gl = m_context.getRenderContext().getFunctions();
6323 gl.dispatchCompute(16 /* x */, 16 /* y */, 1 /* z */);
6324 GLU_EXPECT_NO_ERROR(gl.getError(), "DispatchCompute");
6327 /** Execute drawArrays for single vertex
6331 void TextureTestBase::executeDrawCall(GLuint /* test_case_index */)
6333 const Functions& gl = m_context.getRenderContext().getFunctions();
6335 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
6336 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
6339 /** Prepare code snippet that will pass in variables to out variables
6342 * @param varying_passthrough Collection of connections between in and out variables
6343 * @param stage Shader stage
6345 * @return Code that pass in variables to next stage
6347 std::string TextureTestBase::getPassSnippet(GLuint /* test_case_index */,
6348 Utils::VaryingPassthrough& varying_passthrough, Utils::Shader::STAGES stage)
6350 static const GLchar* separator = "\n ";
6352 /* Skip for compute shader */
6353 if (Utils::Shader::COMPUTE == stage)
6358 Utils::VaryingConnection::Vector& vector = varying_passthrough.Get(stage);
6360 std::string result = Utils::g_list;
6361 size_t position = 0;
6363 for (GLuint i = 0; i < vector.size(); ++i)
6366 Utils::VaryingConnection& connection = vector[i];
6368 Utils::Variable* in = connection.m_in;
6369 Utils::Variable* out = connection.m_out;
6371 Utils::Variable::FLAVOUR in_flavour = Utils::Variable::GetFlavour(stage, Utils::Variable::INPUT);
6372 Utils::Variable::FLAVOUR out_flavour = Utils::Variable::GetFlavour(stage, Utils::Variable::OUTPUT);
6374 const std::string passthrough =
6375 getVariablePassthrough("", in->m_descriptor, in_flavour, "", out->m_descriptor, out_flavour);
6377 Utils::insertElementOfList(passthrough.c_str(), separator, position, result);
6380 Utils::endList("", position, result);
6385 /** Basic implementation of method getProgramInterface
6391 void TextureTestBase::getProgramInterface(GLuint /* test_case_index */,
6392 Utils::ProgramInterface& /* program_interface */,
6393 Utils::VaryingPassthrough& /* varying_passthrough */)
6397 /** Prepare code snippet that will verify in and uniform variables
6400 * @param program_interface Interface of program
6401 * @param stage Shader stage
6403 * @return Code that verify variables
6405 std::string TextureTestBase::getVerificationSnippet(GLuint /* test_case_index */,
6406 Utils::ProgramInterface& program_interface,
6407 Utils::Shader::STAGES stage)
6409 static const GLchar* separator = " ||\n ";
6411 std::string verification = "if (LIST)\n"
6416 /* Get flavour of in and out variables */
6417 Utils::Variable::FLAVOUR in_flavour = Utils::Variable::GetFlavour(stage, Utils::Variable::INPUT);
6419 /* Get interface for shader stage */
6420 Utils::ShaderInterface& si = program_interface.GetShaderInterface(stage);
6422 /* There are no varialbes to verify */
6423 if ((0 == si.m_inputs.size()) && (0 == si.m_uniforms.size()) && (0 == si.m_ssb_blocks.size()))
6428 /* For each in variable insert verification code */
6429 size_t position = 0;
6431 for (GLuint i = 0; i < si.m_inputs.size(); ++i)
6433 const Utils::Variable& var = *si.m_inputs[i];
6434 const std::string& var_verification = getVariableVerifcation("", var.m_data, var.m_descriptor, in_flavour);
6436 Utils::insertElementOfList(var_verification.c_str(), separator, position, verification);
6439 /* For each unifrom variable insert verification code */
6440 for (GLuint i = 0; i < si.m_uniforms.size(); ++i)
6442 const Utils::Variable& var = *si.m_uniforms[i];
6443 const std::string& var_verification =
6444 getVariableVerifcation("", var.m_data, var.m_descriptor, Utils::Variable::BASIC);
6446 Utils::insertElementOfList(var_verification.c_str(), separator, position, verification);
6449 /* For each ssb variable insert verification code */
6450 for (GLuint i = 0; i < si.m_ssb_blocks.size(); ++i)
6452 const Utils::Variable& var = *si.m_ssb_blocks[i];
6453 const std::string& var_verification =
6454 getVariableVerifcation("", var.m_data, var.m_descriptor, Utils::Variable::BASIC);
6456 Utils::insertElementOfList(var_verification.c_str(), separator, position, verification);
6459 Utils::endList("", position, verification);
6461 #if DEBUG_TTB_VERIFICATION_SNIPPET_STAGE
6465 sprintf(buffer, "%d", stage + 10);
6466 Utils::replaceToken("0u", position, buffer, verification);
6469 #elif DEBUG_TTB_VERIFICATION_SNIPPET_VARIABLE
6471 if (Utils::Shader::VERTEX == stage)
6473 Utils::replaceToken("0u", position, "in_vs_first.x", verification);
6477 Utils::replaceToken("0u", position, "31u", verification);
6483 return verification;
6486 /** Selects if "compute" stage is relevant for test
6492 bool TextureTestBase::isComputeRelevant(GLuint /* test_case_index */)
6497 /** Selects if "draw" stages are relevant for test
6503 bool TextureTestBase::isDrawRelevant(GLuint /* test_case_index */)
6508 /** Prepare code that will do assignment of single in to single out
6510 * @param in_parent_name Name of parent in variable
6511 * @param in_variable Descriptor of in variable
6512 * @param in_flavour Flavoud of in variable
6513 * @param out_parent_name Name of parent out variable
6514 * @param out_variable Descriptor of out variable
6515 * @param out_flavour Flavoud of out variable
6517 * @return Code that does OUT = IN
6519 std::string TextureTestBase::getVariablePassthrough(const std::string& in_parent_name,
6520 const Utils::Variable::Descriptor& in_variable,
6521 Utils::Variable::FLAVOUR in_flavour,
6522 const std::string& out_parent_name,
6523 const Utils::Variable::Descriptor& out_variable,
6524 Utils::Variable::FLAVOUR out_flavour)
6528 GLuint member_index = 0;
6529 size_t position = 0;
6530 std::string result = Utils::g_list;
6531 static const GLchar* separator = ";\n ";
6533 /* For each member of each array element */
6536 const std::string in_name = Utils::Variable::GetReference(in_parent_name, in_variable, in_flavour, index);
6537 const std::string out_name = Utils::Variable::GetReference(out_parent_name, out_variable, out_flavour, index);
6538 std::string passthrough;
6540 /* Prepare verification */
6541 if (Utils::Variable::BUILTIN == in_variable.m_type)
6543 size_t pass_position = 0;
6545 passthrough = "OUT = IN;";
6547 Utils::replaceToken("OUT", pass_position, out_name.c_str(), passthrough);
6548 Utils::replaceToken("IN", pass_position, in_name.c_str(), passthrough);
6550 /* Increment index */
6555 const Utils::Interface* in_interface = in_variable.m_interface;
6556 const Utils::Interface* out_interface = out_variable.m_interface;
6558 if ((0 == in_interface) || (0 == out_interface))
6560 TCU_FAIL("Nullptr");
6563 const Utils::Variable::Descriptor& in_member = in_interface->m_members[member_index];
6564 const Utils::Variable::Descriptor& out_member = out_interface->m_members[member_index];
6566 passthrough = getVariablePassthrough(in_name, in_member, Utils::Variable::BASIC, out_name, out_member,
6567 Utils::Variable::BASIC);
6569 /* Increment member_index */
6572 /* Increment index and reset member_index if all members were processed */
6573 if (in_interface->m_members.size() == member_index)
6580 /* Check if loop should end */
6581 if ((index >= in_variable.m_n_array_elements) && (0 == member_index))
6586 Utils::insertElementOfList(passthrough.c_str(), separator, position, result);
6588 } while (true != done);
6590 Utils::endList("", position, result);
6596 /** Get verification of single variable
6598 * @param parent_name Name of parent variable
6599 * @param data Data that should be used as EXPECTED
6600 * @param variable Descriptor of variable
6601 * @param flavour Flavour of variable
6603 * @return Code that does (EXPECTED != VALUE) ||
6605 std::string TextureTestBase::getVariableVerifcation(const std::string& parent_name, const GLvoid* data,
6606 const Utils::Variable::Descriptor& variable,
6607 Utils::Variable::FLAVOUR flavour)
6609 static const GLchar* logic_op = " ||\n ";
6610 const GLuint n_elements = (0 == variable.m_n_array_elements) ? 1 : variable.m_n_array_elements;
6611 size_t position = 0;
6612 std::string result = Utils::g_list;
6613 GLint stride = variable.m_expected_stride_of_element;
6615 /* For each each array element */
6616 for (GLuint element = 0; element < n_elements; ++element)
6618 const std::string name = Utils::Variable::GetReference(parent_name, variable, flavour, element);
6620 /* Calculate data pointer */
6621 GLvoid* data_ptr = (GLvoid*)((GLubyte*)data + element * stride);
6623 /* Prepare verification */
6624 if (Utils::Variable::BUILTIN == variable.m_type)
6626 const std::string& expected = variable.m_builtin.GetGLSLConstructor(data_ptr);
6627 std::string verification;
6628 size_t verification_position = 0;
6630 verification = "(EXPECTED != NAME)";
6632 Utils::replaceToken("EXPECTED", verification_position, expected.c_str(), verification);
6633 Utils::replaceToken("NAME", verification_position, name.c_str(), verification);
6635 Utils::insertElementOfList(verification.c_str(), logic_op, position, result);
6639 const Utils::Interface* interface = variable.m_interface;
6643 TCU_FAIL("Nullptr");
6646 const GLuint n_members = static_cast<GLuint>(interface->m_members.size());
6648 /* for each member */
6649 for (GLuint member_index = 0; member_index < n_members; ++member_index)
6651 const Utils::Variable::Descriptor& member = interface->m_members[member_index];
6653 /* Get verification of member */
6654 const std::string& verification =
6655 getVariableVerifcation(name, (GLubyte*)data_ptr + member.m_offset, member, Utils::Variable::BASIC);
6657 Utils::insertElementOfList(verification.c_str(), logic_op, position, result);
6662 Utils::endList("", position, result);
6667 /** Prepare attributes, vertex array object and array buffer
6669 * @param test_case_index Index of test case
6670 * @param program_interface Interface of program
6671 * @param buffer Array buffer
6672 * @param vao Vertex array object
6674 void TextureTestBase::prepareAttributes(GLuint test_case_index, Utils::ProgramInterface& program_interface,
6675 Utils::Buffer& buffer, Utils::VertexArray& vao)
6677 bool use_component_qualifier = useComponentQualifier(test_case_index);
6679 /* Get shader interface */
6680 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
6682 /* Bind vao and buffer */
6686 /* Skip if there are no input variables in vertex shader */
6687 if (0 == si.m_inputs.size())
6692 /* Calculate vertex stride and check */
6693 GLint vertex_stride = 0;
6695 for (GLuint i = 0; i < si.m_inputs.size(); ++i)
6697 Utils::Variable& variable = *si.m_inputs[i];
6699 GLint variable_size = static_cast<GLuint>(variable.m_data_size);
6701 GLint ends_at = variable_size + variable.m_descriptor.m_offset;
6703 vertex_stride = std::max(vertex_stride, ends_at);
6706 /* Prepare buffer data and set up vao */
6707 std::vector<GLubyte> buffer_data;
6708 buffer_data.resize(vertex_stride);
6710 GLubyte* ptr = &buffer_data[0];
6712 for (GLuint i = 0; i < si.m_inputs.size(); ++i)
6714 Utils::Variable& variable = *si.m_inputs[i];
6716 memcpy(ptr + variable.m_descriptor.m_offset, variable.m_data, variable.m_data_size);
6718 if (false == use_component_qualifier)
6720 vao.Attribute(variable.m_descriptor.m_expected_location, variable.m_descriptor.m_builtin,
6721 variable.m_descriptor.m_n_array_elements, variable.m_descriptor.m_normalized,
6722 variable.GetStride(), (GLvoid*)(intptr_t)variable.m_descriptor.m_offset);
6724 else if (0 == variable.m_descriptor.m_expected_component)
6726 /* Components can only be applied to vectors.
6727 Assumption that test use all 4 components */
6728 const Utils::Type& type =
6729 Utils::Type::GetType(variable.m_descriptor.m_builtin.m_basic_type, 1 /* n_columns */, 4 /* n_rows */);
6731 vao.Attribute(variable.m_descriptor.m_expected_location, type, variable.m_descriptor.m_n_array_elements,
6732 variable.m_descriptor.m_normalized, variable.GetStride(),
6733 (GLvoid*)(intptr_t)variable.m_descriptor.m_offset);
6738 buffer.Data(Utils::Buffer::StaticDraw, vertex_stride, ptr);
6741 /** Get locations for all outputs with automatic_location
6743 * @param program Program object
6744 * @param program_interface Interface of program
6746 void TextureTestBase::prepareFragmentDataLoc(Utils::Program& program, Utils::ProgramInterface& program_interface)
6748 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
6749 Utils::Variable::PtrVector& outputs = si.m_outputs;
6751 for (Utils::Variable::PtrVector::iterator it = outputs.begin(); outputs.end() != it; ++it)
6753 /* Test does not specify location, query value and set */
6754 if (Utils::Variable::m_automatic_location == (*it)->m_descriptor.m_expected_location)
6756 GLuint index = program.GetResourceIndex((*it)->m_descriptor.m_name, GL_PROGRAM_OUTPUT);
6759 program.GetResource(GL_PROGRAM_OUTPUT, index, GL_LOCATION, 1 /* size */, &location);
6761 (*it)->m_descriptor.m_expected_location = location;
6766 /** Prepare framebuffer with single texture as color attachment
6768 * @param framebuffer Framebuffer
6769 * @param color_0_texture Texture that will used as color attachment
6771 void TextureTestBase::prepareFramebuffer(Utils::Framebuffer& framebuffer, Utils::Texture& color_0_texture)
6774 std::vector<GLuint> texture_data;
6775 texture_data.resize(m_width * m_height);
6777 for (GLuint i = 0; i < texture_data.size(); ++i)
6779 texture_data[i] = 0x20406080;
6782 /* Prepare texture */
6783 color_0_texture.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT,
6786 /* Prepare framebuffer */
6789 framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0, color_0_texture.m_id, m_width, m_height);
6791 framebuffer.ClearColor(0.0f, 0.0f, 0.0f, 0.0f);
6792 framebuffer.Clear(GL_COLOR_BUFFER_BIT);
6795 /** Prepare iamge unit for compute shader
6797 * @param location Uniform location
6798 * @param image_texture Texture that will used as color attachment
6800 void TextureTestBase::prepareImage(GLint location, Utils::Texture& image_texture) const
6802 static const GLuint image_unit = 0;
6804 std::vector<GLuint> texture_data;
6805 texture_data.resize(m_width * m_height);
6807 for (GLuint i = 0; i < texture_data.size(); ++i)
6809 texture_data[i] = 0x20406080;
6812 image_texture.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT,
6815 const Functions& gl = m_context.getRenderContext().getFunctions();
6817 gl.bindImageTexture(image_unit, image_texture.m_id, 0 /* level */, GL_FALSE /* layered */, 0 /* Layer */,
6818 GL_WRITE_ONLY, GL_R32UI);
6819 GLU_EXPECT_NO_ERROR(gl.getError(), "BindImageTexture");
6821 Utils::Program::Uniform(gl, Utils::Type::_int, 1 /* count */, location, &image_unit);
6824 /** Basic implementation
6827 * @param si Shader interface
6828 * @param program Program
6829 * @param cs_buffer Buffer for ssb blocks
6831 void TextureTestBase::prepareSSBs(GLuint /* test_case_index */, Utils::ShaderInterface& si, Utils::Program& program,
6832 Utils::Buffer& buffer)
6834 /* Skip if there are no input variables in vertex shader */
6835 if (0 == si.m_ssb_blocks.size())
6840 /* Calculate vertex stride */
6841 GLint ssbs_stride = 0;
6843 for (GLuint i = 0; i < si.m_ssb_blocks.size(); ++i)
6845 Utils::Variable& variable = *si.m_ssb_blocks[i];
6847 if (false == variable.IsBlock())
6852 GLint variable_stride = variable.GetStride();
6854 GLint ends_at = variable_stride + variable.m_descriptor.m_offset;
6856 ssbs_stride = std::max(ssbs_stride, ends_at);
6859 /* Set active program */
6864 buffer.Data(Utils::Buffer::StaticDraw, ssbs_stride, 0);
6866 /* Set up uniforms */
6867 for (GLuint i = 0; i < si.m_ssb_blocks.size(); ++i)
6869 Utils::Variable& variable = *si.m_ssb_blocks[i];
6871 /* prepareUnifor should work fine for ssb blocks */
6872 prepareUniform(program, variable, buffer);
6876 /** Basic implementation
6878 * @param test_case_index Test case index
6879 * @param program_interface Program interface
6880 * @param program Program
6881 * @param cs_buffer Buffer for compute shader stage
6883 void TextureTestBase::prepareSSBs(GLuint test_case_index, Utils::ProgramInterface& program_interface,
6884 Utils::Program& program, Utils::Buffer& cs_buffer)
6886 cs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
6888 Utils::ShaderInterface& cs = program_interface.GetShaderInterface(Utils::Shader::COMPUTE);
6890 prepareSSBs(test_case_index, cs, program, cs_buffer);
6892 cs_buffer.BindBase(Utils::Shader::COMPUTE);
6895 /** Basic implementation
6897 * @param test_case_index Test case index
6898 * @param program_interface Program interface
6899 * @param program Program
6900 * @param fs_buffer Buffer for fragment shader stage
6901 * @param gs_buffer Buffer for geometry shader stage
6902 * @param tcs_buffer Buffer for tessellation control shader stage
6903 * @param tes_buffer Buffer for tessellation evaluation shader stage
6904 * @param vs_buffer Buffer for vertex shader stage
6906 void TextureTestBase::prepareSSBs(GLuint test_case_index, Utils::ProgramInterface& program_interface,
6907 Utils::Program& program, Utils::Buffer& fs_buffer, Utils::Buffer& gs_buffer,
6908 Utils::Buffer& tcs_buffer, Utils::Buffer& tes_buffer, Utils::Buffer& vs_buffer)
6910 fs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
6911 gs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
6912 tcs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
6913 tes_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
6914 vs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
6916 Utils::ShaderInterface& fs = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
6917 Utils::ShaderInterface& gs = program_interface.GetShaderInterface(Utils::Shader::GEOMETRY);
6918 Utils::ShaderInterface& tcs = program_interface.GetShaderInterface(Utils::Shader::TESS_CTRL);
6919 Utils::ShaderInterface& tes = program_interface.GetShaderInterface(Utils::Shader::TESS_EVAL);
6920 Utils::ShaderInterface& vs = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
6922 prepareSSBs(test_case_index, fs, program, fs_buffer);
6923 prepareSSBs(test_case_index, gs, program, gs_buffer);
6924 prepareSSBs(test_case_index, tcs, program, tcs_buffer);
6925 prepareSSBs(test_case_index, tes, program, tes_buffer);
6926 prepareSSBs(test_case_index, vs, program, vs_buffer);
6928 fs_buffer.BindBase(Utils::Shader::FRAGMENT);
6929 gs_buffer.BindBase(Utils::Shader::GEOMETRY);
6930 tcs_buffer.BindBase(Utils::Shader::TESS_CTRL);
6931 tes_buffer.BindBase(Utils::Shader::TESS_EVAL);
6932 vs_buffer.BindBase(Utils::Shader::VERTEX);
6935 /** Updates buffer data with variable
6937 * @param program Program object
6938 * @param variable Variable
6939 * @param buffer Buffer
6941 void TextureTestBase::prepareUniform(Utils::Program& program, Utils::Variable& variable, Utils::Buffer& buffer)
6943 const Functions& gl = m_context.getRenderContext().getFunctions();
6945 GLsizei count = variable.m_descriptor.m_n_array_elements;
6951 if (Utils::Variable::BUILTIN == variable.m_descriptor.m_type)
6953 program.Uniform(gl, variable.m_descriptor.m_builtin, count, variable.m_descriptor.m_expected_location,
6958 const bool is_block = variable.IsBlock();
6960 if (false == is_block)
6962 TCU_FAIL("Not implemented");
6966 buffer.SubData(variable.m_descriptor.m_offset, variable.m_descriptor.m_expected_stride_of_element * count,
6972 /** Basic implementation
6975 * @param si Shader interface
6976 * @param program Program
6977 * @param cs_buffer Buffer for uniform blocks
6979 void TextureTestBase::prepareUniforms(GLuint /* test_case_index */, Utils::ShaderInterface& si, Utils::Program& program,
6980 Utils::Buffer& buffer)
6982 /* Skip if there are no input variables in vertex shader */
6983 if (0 == si.m_uniforms.size())
6988 /* Calculate vertex stride */
6989 GLint uniforms_stride = 0;
6991 for (GLuint i = 0; i < si.m_uniforms.size(); ++i)
6993 Utils::Variable& variable = *si.m_uniforms[i];
6995 if (false == variable.IsBlock())
7000 GLint variable_stride = variable.GetStride();
7002 GLint ends_at = variable_stride + variable.m_descriptor.m_offset;
7004 uniforms_stride = std::max(uniforms_stride, ends_at);
7007 /* Set active program */
7012 buffer.Data(Utils::Buffer::StaticDraw, uniforms_stride, 0);
7014 /* Set up uniforms */
7015 for (GLuint i = 0; i < si.m_uniforms.size(); ++i)
7017 Utils::Variable& variable = *si.m_uniforms[i];
7019 prepareUniform(program, variable, buffer);
7023 /** Basic implementation
7025 * @param test_case_index Test case index
7026 * @param program_interface Program interface
7027 * @param program Program
7028 * @param cs_buffer Buffer for compute shader stage
7030 void TextureTestBase::prepareUniforms(GLuint test_case_index, Utils::ProgramInterface& program_interface,
7031 Utils::Program& program, Utils::Buffer& cs_buffer)
7033 cs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7035 Utils::ShaderInterface& cs = program_interface.GetShaderInterface(Utils::Shader::COMPUTE);
7037 prepareUniforms(test_case_index, cs, program, cs_buffer);
7039 cs_buffer.BindBase(Utils::Shader::COMPUTE);
7042 /** Basic implementation
7044 * @param test_case_index Test case index
7045 * @param program_interface Program interface
7046 * @param program Program
7047 * @param fs_buffer Buffer for fragment shader stage
7048 * @param gs_buffer Buffer for geometry shader stage
7049 * @param tcs_buffer Buffer for tessellation control shader stage
7050 * @param tes_buffer Buffer for tessellation evaluation shader stage
7051 * @param vs_buffer Buffer for vertex shader stage
7053 void TextureTestBase::prepareUniforms(GLuint test_case_index, Utils::ProgramInterface& program_interface,
7054 Utils::Program& program, Utils::Buffer& fs_buffer, Utils::Buffer& gs_buffer,
7055 Utils::Buffer& tcs_buffer, Utils::Buffer& tes_buffer, Utils::Buffer& vs_buffer)
7057 fs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7058 gs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7059 tcs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7060 tes_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7061 vs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7063 Utils::ShaderInterface& fs = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
7064 Utils::ShaderInterface& gs = program_interface.GetShaderInterface(Utils::Shader::GEOMETRY);
7065 Utils::ShaderInterface& tcs = program_interface.GetShaderInterface(Utils::Shader::TESS_CTRL);
7066 Utils::ShaderInterface& tes = program_interface.GetShaderInterface(Utils::Shader::TESS_EVAL);
7067 Utils::ShaderInterface& vs = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
7069 prepareUniforms(test_case_index, fs, program, fs_buffer);
7070 prepareUniforms(test_case_index, gs, program, gs_buffer);
7071 prepareUniforms(test_case_index, tcs, program, tcs_buffer);
7072 prepareUniforms(test_case_index, tes, program, tes_buffer);
7073 prepareUniforms(test_case_index, vs, program, vs_buffer);
7075 fs_buffer.BindBase(Utils::Shader::FRAGMENT);
7076 gs_buffer.BindBase(Utils::Shader::GEOMETRY);
7077 tcs_buffer.BindBase(Utils::Shader::TESS_CTRL);
7078 tes_buffer.BindBase(Utils::Shader::TESS_EVAL);
7079 vs_buffer.BindBase(Utils::Shader::VERTEX);
7082 /** Basic implementation
7084 * @param test_case_index Test case index
7085 * @param program_interface Program interface
7086 * @param program Program
7087 * @param fs_buffer Buffer for fragment shader stage
7088 * @param gs_buffer Buffer for geometry shader stage
7089 * @param tcs_buffer Buffer for tessellation control shader stage
7090 * @param tes_buffer Buffer for tessellation evaluation shader stage
7091 * @param vs_buffer Buffer for vertex shader stage
7093 void TextureTestBase::prepareUniforms(GLuint test_case_index, Utils::ProgramInterface& program_interface,
7094 Utils::Program& fs_program, Utils::Program& gs_program,
7095 Utils::Program& tcs_program, Utils::Program& tes_program,
7096 Utils::Program& vs_program, Utils::Buffer& fs_buffer, Utils::Buffer& gs_buffer,
7097 Utils::Buffer& tcs_buffer, Utils::Buffer& tes_buffer, Utils::Buffer& vs_buffer)
7099 fs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7100 gs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7101 tcs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7102 tes_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7103 vs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7105 Utils::ShaderInterface& fs = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
7106 Utils::ShaderInterface& gs = program_interface.GetShaderInterface(Utils::Shader::GEOMETRY);
7107 Utils::ShaderInterface& tcs = program_interface.GetShaderInterface(Utils::Shader::TESS_CTRL);
7108 Utils::ShaderInterface& tes = program_interface.GetShaderInterface(Utils::Shader::TESS_EVAL);
7109 Utils::ShaderInterface& vs = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
7111 prepareUniforms(test_case_index, fs, fs_program, fs_buffer);
7112 fs_buffer.BindBase(Utils::Shader::FRAGMENT);
7114 prepareUniforms(test_case_index, gs, gs_program, gs_buffer);
7115 gs_buffer.BindBase(Utils::Shader::GEOMETRY);
7117 prepareUniforms(test_case_index, tcs, tcs_program, tcs_buffer);
7118 tcs_buffer.BindBase(Utils::Shader::TESS_CTRL);
7120 prepareUniforms(test_case_index, tes, tes_program, tes_buffer);
7121 tes_buffer.BindBase(Utils::Shader::TESS_EVAL);
7123 prepareUniforms(test_case_index, vs, vs_program, vs_buffer);
7124 vs_buffer.BindBase(Utils::Shader::VERTEX);
7127 /** Prepare source for shader
7129 * @param test_case_index Index of test case
7130 * @param program_interface Interface of program
7131 * @param varying_passthrough Collection of connection between in and out variables
7132 * @param stage Shader stage
7134 * @return Source of shader
7136 std::string TextureTestBase::getShaderSource(GLuint test_case_index, Utils::ProgramInterface& program_interface,
7137 Utils::VaryingPassthrough& varying_passthrough,
7138 Utils::Shader::STAGES stage)
7141 const GLchar* shader_template = getShaderTemplate(stage);
7142 const std::string& shader_interface = program_interface.GetInterfaceForStage(stage);
7144 const std::string& verification = getVerificationSnippet(test_case_index, program_interface, stage);
7146 const std::string& passthrough = getPassSnippet(test_case_index, varying_passthrough, stage);
7148 const GLchar* per_vertex = "";
7150 std::string source = shader_template;
7151 size_t position = 0;
7153 /* Replace tokens in template */
7154 if (Utils::Shader::GEOMETRY == stage)
7156 if (false == useMonolithicProgram(test_case_index))
7158 per_vertex = "out gl_PerVertex {\n"
7159 "vec4 gl_Position;\n"
7164 Utils::replaceToken("PERVERTEX", position, per_vertex, source);
7167 Utils::replaceToken("INTERFACE", position, shader_interface.c_str(), source);
7168 Utils::replaceToken("VERIFICATION", position, verification.c_str(), source);
7170 if (false == verification.empty())
7172 Utils::replaceAllTokens("ELSE", " else ", source);
7176 Utils::replaceAllTokens("ELSE", "", source);
7179 Utils::replaceAllTokens("PASSTHROUGH", passthrough.c_str(), source);
7185 /** Returns template of shader for given stage
7187 * @param stage Shade stage
7189 * @return Proper template
7191 const GLchar* TextureTestBase::getShaderTemplate(Utils::Shader::STAGES stage)
7194 static const GLchar* compute_shader_template =
7195 "#version 430 core\n"
7196 "#extension GL_ARB_enhanced_layouts : require\n"
7198 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
7200 "writeonly uniform uimage2D uni_image;\n"
7206 " uint result = 1u;\n"
7210 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), uvec4(result, 0, 0, 0));\n"
7214 static const GLchar* fragment_shader_template = "#version 430 core\n"
7215 "#extension GL_ARB_enhanced_layouts : require\n"
7217 "flat in uint gs_fs_result;\n"
7218 " out uint fs_out_result;\n"
7224 " uint result = 1u;\n"
7226 " if (1u != gs_fs_result)\n"
7228 " result = gs_fs_result;\n"
7232 " fs_out_result = result;\n"
7237 static const GLchar* geometry_shader_template =
7238 "#version 430 core\n"
7239 "#extension GL_ARB_enhanced_layouts : require\n"
7241 "layout(points) in;\n"
7242 "layout(triangle_strip, max_vertices = 4) out;\n"
7244 " in uint tes_gs_result[];\n"
7245 "flat out uint gs_fs_result;\n"
7247 "PERVERTEX" /* Separable programs require explicit declaration of gl_PerVertex */
7252 " uint result = 1u;\n"
7254 " if (1u != tes_gs_result[0])\n"
7256 " result = tes_gs_result[0];\n"
7260 " gs_fs_result = result;\n"
7262 " gl_Position = vec4(-1, -1, 0, 1);\n"
7264 " gs_fs_result = result;\n"
7266 " gl_Position = vec4(-1, 1, 0, 1);\n"
7268 " gs_fs_result = result;\n"
7270 " gl_Position = vec4(1, -1, 0, 1);\n"
7272 " gs_fs_result = result;\n"
7274 " gl_Position = vec4(1, 1, 0, 1);\n"
7279 static const GLchar* tess_ctrl_shader_template = "#version 430 core\n"
7280 "#extension GL_ARB_enhanced_layouts : require\n"
7282 "layout(vertices = 1) out;\n"
7284 "in uint vs_tcs_result[];\n"
7285 "out uint tcs_tes_result[];\n"
7291 " uint result = 1u;\n"
7293 " if (1u != vs_tcs_result[gl_InvocationID])\n"
7295 " result = vs_tcs_result[gl_InvocationID];\n"
7299 " tcs_tes_result[gl_InvocationID] = result;\n"
7303 " gl_TessLevelOuter[0] = 1.0;\n"
7304 " gl_TessLevelOuter[1] = 1.0;\n"
7305 " gl_TessLevelOuter[2] = 1.0;\n"
7306 " gl_TessLevelOuter[3] = 1.0;\n"
7307 " gl_TessLevelInner[0] = 1.0;\n"
7308 " gl_TessLevelInner[1] = 1.0;\n"
7312 static const GLchar* tess_eval_shader_template = "#version 430 core\n"
7313 "#extension GL_ARB_enhanced_layouts : require\n"
7315 "layout(isolines, point_mode) in;\n"
7317 "in uint tcs_tes_result[];\n"
7318 "out uint tes_gs_result;\n"
7324 " uint result = 1u;\n"
7326 " if (1 != tcs_tes_result[0])\n"
7328 " result = tcs_tes_result[0];\n"
7332 " tes_gs_result = result;\n"
7338 static const GLchar* vertex_shader_template = "#version 430 core\n"
7339 "#extension GL_ARB_enhanced_layouts : require\n"
7341 "out uint vs_tcs_result;\n"
7347 " uint result = 1u;\n"
7351 " vs_tcs_result = result;\n"
7357 const GLchar* result = 0;
7361 case Utils::Shader::COMPUTE:
7362 result = compute_shader_template;
7364 case Utils::Shader::FRAGMENT:
7365 result = fragment_shader_template;
7367 case Utils::Shader::GEOMETRY:
7368 result = geometry_shader_template;
7370 case Utils::Shader::TESS_CTRL:
7371 result = tess_ctrl_shader_template;
7373 case Utils::Shader::TESS_EVAL:
7374 result = tess_eval_shader_template;
7376 case Utils::Shader::VERTEX:
7377 result = vertex_shader_template;
7380 TCU_FAIL("Invalid enum");
7388 * @param test_case_index Id of test case
7390 * @return true if test case pass, false otherwise
7392 bool TextureTestBase::testCase(GLuint test_case_index)
7396 if (true == useMonolithicProgram(test_case_index))
7398 return testMonolithic(test_case_index);
7402 return testSeparable(test_case_index);
7405 catch (Utils::Shader::InvalidSourceException& exc)
7408 TCU_FAIL(exc.what());
7410 catch (Utils::Program::BuildException& exc)
7412 TCU_FAIL(exc.what());
7416 /** Runs "draw" test with monolithic program
7418 * @param test_case_index Id of test case
7420 bool TextureTestBase::testMonolithic(GLuint test_case_index)
7422 Utils::ProgramInterface program_interface;
7423 Utils::VaryingPassthrough varying_passthrough;
7426 const std::string& test_name = getTestCaseName(test_case_index);
7429 getProgramInterface(test_case_index, program_interface, varying_passthrough);
7433 if (true == isDrawRelevant(test_case_index))
7435 Utils::Buffer buffer_attr(m_context);
7436 Utils::Buffer buffer_ssb_fs(m_context);
7437 Utils::Buffer buffer_ssb_gs(m_context);
7438 Utils::Buffer buffer_ssb_tcs(m_context);
7439 Utils::Buffer buffer_ssb_tes(m_context);
7440 Utils::Buffer buffer_ssb_vs(m_context);
7441 Utils::Buffer buffer_u_fs(m_context);
7442 Utils::Buffer buffer_u_gs(m_context);
7443 Utils::Buffer buffer_u_tcs(m_context);
7444 Utils::Buffer buffer_u_tes(m_context);
7445 Utils::Buffer buffer_u_vs(m_context);
7446 Utils::Framebuffer framebuffer(m_context);
7447 Utils::Program program(m_context);
7448 Utils::Texture texture_fb(m_context);
7449 Utils::VertexArray vao(m_context);
7452 const std::string& fragment_shader =
7453 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::FRAGMENT);
7454 const std::string& geometry_shader =
7455 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::GEOMETRY);
7456 const std::string& tess_ctrl_shader =
7457 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::TESS_CTRL);
7458 const std::string& tess_eval_shader =
7459 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::TESS_EVAL);
7460 const std::string& vertex_shader =
7461 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::VERTEX);
7463 program.Init("" /* compute_shader */, fragment_shader, geometry_shader, tess_ctrl_shader, tess_eval_shader,
7464 vertex_shader, false /* is_separable */);
7467 prepareAttribLocation(program, program_interface);
7468 prepareFragmentDataLoc(program, program_interface);
7471 std::stringstream stream;
7472 if (false == Utils::checkMonolithicDrawProgramInterface(program, program_interface, stream))
7474 m_context.getTestContext().getLog()
7475 << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7476 << ". Inspection of draw program interface failed:\n"
7477 << stream.str() << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(vertex_shader)
7478 << tcu::TestLog::KernelSource(tess_ctrl_shader) << tcu::TestLog::KernelSource(tess_eval_shader)
7479 << tcu::TestLog::KernelSource(geometry_shader) << tcu::TestLog::KernelSource(fragment_shader);
7488 buffer_attr.Init(Utils::Buffer::Array, Utils::Buffer::StaticDraw, 0, 0);
7490 prepareAttributes(test_case_index, program_interface, buffer_attr, vao);
7493 prepareUniforms(test_case_index, program_interface, program, buffer_u_fs, buffer_u_gs, buffer_u_tcs,
7494 buffer_u_tes, buffer_u_vs);
7496 prepareSSBs(test_case_index, program_interface, program, buffer_ssb_fs, buffer_ssb_gs, buffer_ssb_tcs,
7497 buffer_ssb_tes, buffer_ssb_vs);
7500 prepareFramebuffer(framebuffer, texture_fb);
7503 executeDrawCall(test_case_index);
7506 m_context.getRenderContext().postIterate();
7510 if (false == checkResults(test_case_index, texture_fb))
7512 m_context.getTestContext().getLog()
7513 << tcu::TestLog::Message << "FAILURE. Test case: " << test_name << ". Draw - invalid results."
7514 << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(vertex_shader)
7515 << tcu::TestLog::KernelSource(tess_ctrl_shader) << tcu::TestLog::KernelSource(tess_eval_shader)
7516 << tcu::TestLog::KernelSource(geometry_shader) << tcu::TestLog::KernelSource(fragment_shader);
7523 if (true == isComputeRelevant(test_case_index))
7525 Utils::Buffer buffer_ssb_cs(m_context);
7526 Utils::Buffer buffer_u_cs(m_context);
7527 Utils::Program program(m_context);
7528 Utils::Texture texture_im(m_context);
7529 Utils::VertexArray vao(m_context);
7532 const std::string& compute_shader =
7533 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::COMPUTE);
7535 program.Init(compute_shader, "" /* fragment_shader */, "" /* geometry_shader */, "" /* tess_ctrl_shader */,
7536 "" /* tess_eval_shader */, "" /* vertex_shader */, false /* is_separable */);
7540 std::stringstream stream;
7542 if (false == Utils::checkMonolithicComputeProgramInterface(program, program_interface, stream))
7544 m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7545 << ". Inspection of compute program interface failed:\n"
7546 << stream.str() << tcu::TestLog::EndMessage;
7560 prepareUniforms(test_case_index, program_interface, program, buffer_u_cs);
7562 prepareSSBs(test_case_index, program_interface, program, buffer_ssb_cs);
7565 GLint image_location = program.GetUniformLocation("uni_image");
7566 prepareImage(image_location, texture_im);
7569 executeDispatchCall(test_case_index);
7572 m_context.getRenderContext().postIterate();
7576 if (false == checkResults(test_case_index, texture_im))
7578 m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7579 << ". Compute - invalid results." << tcu::TestLog::EndMessage
7580 << tcu::TestLog::KernelSource(compute_shader);
7589 /** Runs "draw" test with separable program
7591 * @param test_case_index Id of test case
7593 bool TextureTestBase::testSeparable(GLuint test_case_index)
7595 Utils::ProgramInterface program_interface;
7596 Utils::VaryingPassthrough varying_passthrough;
7599 const std::string& test_name = getTestCaseName(test_case_index);
7602 getProgramInterface(test_case_index, program_interface, varying_passthrough);
7606 if (true == isDrawRelevant(test_case_index))
7608 Utils::Buffer buffer_attr(m_context);
7609 Utils::Buffer buffer_u_fs(m_context);
7610 Utils::Buffer buffer_u_gs(m_context);
7611 Utils::Buffer buffer_u_tcs(m_context);
7612 Utils::Buffer buffer_u_tes(m_context);
7613 Utils::Buffer buffer_u_vs(m_context);
7614 Utils::Framebuffer framebuffer(m_context);
7615 Utils::Pipeline pipeline(m_context);
7616 Utils::Program program_fs(m_context);
7617 Utils::Program program_gs(m_context);
7618 Utils::Program program_tcs(m_context);
7619 Utils::Program program_tes(m_context);
7620 Utils::Program program_vs(m_context);
7621 Utils::Texture texture_fb(m_context);
7622 Utils::VertexArray vao(m_context);
7625 const std::string& fs =
7626 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::FRAGMENT);
7627 const std::string& gs =
7628 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::GEOMETRY);
7629 const std::string& tcs =
7630 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::TESS_CTRL);
7631 const std::string& tes =
7632 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::TESS_EVAL);
7633 const std::string& vs =
7634 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::VERTEX);
7636 program_fs.Init("" /*cs*/, fs, "" /*gs*/, "" /*tcs*/, "" /*tes*/, "" /*vs*/, true /* is_separable */);
7637 program_gs.Init("" /*cs*/, "" /*fs*/, gs, "" /*tcs*/, "" /*tes*/, "" /*vs*/, true /* is_separable */);
7638 program_tcs.Init("" /*cs*/, "" /*fs*/, "" /*gs*/, tcs, "" /*tes*/, "" /*vs*/, true /* is_separable */);
7639 program_tes.Init("" /*cs*/, "" /*fs*/, "" /*gs*/, "" /*tcs*/, tes, "" /*vs*/, true /* is_separable */);
7640 program_vs.Init("" /*cs*/, "" /*fs*/, "" /*gs*/, "" /*tcs*/, "" /*tes*/, vs, true /* is_separable */);
7643 prepareAttribLocation(program_vs, program_interface);
7644 prepareFragmentDataLoc(program_vs, program_interface);
7647 std::stringstream stream;
7649 Utils::checkSeparableDrawProgramInterface(program_vs, program_interface, Utils::Shader::VERTEX, stream)) ||
7650 (false == Utils::checkSeparableDrawProgramInterface(program_fs, program_interface, Utils::Shader::FRAGMENT,
7652 (false == Utils::checkSeparableDrawProgramInterface(program_gs, program_interface, Utils::Shader::GEOMETRY,
7654 (false == Utils::checkSeparableDrawProgramInterface(program_tcs, program_interface,
7655 Utils::Shader::TESS_CTRL, stream)) ||
7656 (false == Utils::checkSeparableDrawProgramInterface(program_tes, program_interface,
7657 Utils::Shader::TESS_EVAL, stream)))
7659 m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7660 << ". Inspection of separable draw program interface failed:\n"
7661 << stream.str() << tcu::TestLog::EndMessage
7662 << tcu::TestLog::KernelSource(vs) << tcu::TestLog::KernelSource(tcs)
7663 << tcu::TestLog::KernelSource(tes) << tcu::TestLog::KernelSource(gs)
7664 << tcu::TestLog::KernelSource(fs);
7671 pipeline.UseProgramStages(program_fs.m_id, GL_FRAGMENT_SHADER_BIT);
7672 pipeline.UseProgramStages(program_gs.m_id, GL_GEOMETRY_SHADER_BIT);
7673 pipeline.UseProgramStages(program_tcs.m_id, GL_TESS_CONTROL_SHADER_BIT);
7674 pipeline.UseProgramStages(program_tes.m_id, GL_TESS_EVALUATION_SHADER_BIT);
7675 pipeline.UseProgramStages(program_vs.m_id, GL_VERTEX_SHADER_BIT);
7680 buffer_attr.Init(Utils::Buffer::Array, Utils::Buffer::StaticDraw, 0, 0);
7682 prepareAttributes(test_case_index, program_interface, buffer_attr, vao);
7685 prepareUniforms(test_case_index, program_interface, program_fs, program_gs, program_tcs, program_tes,
7686 program_vs, buffer_u_fs, buffer_u_gs, buffer_u_tcs, buffer_u_tes, buffer_u_vs);
7688 Utils::Program::Use(m_context.getRenderContext().getFunctions(), Utils::Program::m_invalid_id);
7691 prepareFramebuffer(framebuffer, texture_fb);
7694 executeDrawCall(test_case_index);
7697 m_context.getRenderContext().postIterate();
7701 if (false == checkResults(test_case_index, texture_fb))
7703 m_context.getTestContext().getLog()
7704 << tcu::TestLog::Message << "FAILURE. Test case: " << test_name << ". Draw - invalid results."
7705 << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(vs) << tcu::TestLog::KernelSource(tcs)
7706 << tcu::TestLog::KernelSource(tes) << tcu::TestLog::KernelSource(gs) << tcu::TestLog::KernelSource(fs);
7713 if (true == isComputeRelevant(test_case_index))
7715 Utils::Buffer buffer_u_cs(m_context);
7716 Utils::Program program(m_context);
7717 Utils::Texture texture_im(m_context);
7718 Utils::VertexArray vao(m_context);
7721 const std::string& compute_shader =
7722 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::COMPUTE);
7724 program.Init(compute_shader, "" /* fragment_shader */, "" /* geometry_shader */, "" /* tess_ctrl_shader */,
7725 "" /* tess_eval_shader */, "" /* vertex_shader */, false /* is_separable */);
7729 std::stringstream stream;
7731 if (false == Utils::checkMonolithicComputeProgramInterface(program, program_interface, stream))
7733 m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7734 << ". Inspection of compute program interface failed:\n"
7735 << stream.str() << tcu::TestLog::EndMessage;
7749 prepareUniforms(test_case_index, program_interface, program, buffer_u_cs);
7752 GLint image_location = program.GetUniformLocation("uni_image");
7753 prepareImage(image_location, texture_im);
7756 executeDispatchCall(test_case_index);
7759 m_context.getRenderContext().postIterate();
7763 if (false == checkResults(test_case_index, texture_im))
7765 m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7766 << ". Compute - invalid results." << tcu::TestLog::EndMessage
7767 << tcu::TestLog::KernelSource(compute_shader);
7776 /** Basic implementation
7782 bool TextureTestBase::useComponentQualifier(glw::GLuint /* test_case_index */)
7787 /** Basic implementation
7793 bool TextureTestBase::useMonolithicProgram(GLuint /* test_case_index */)
7800 * @param context Test framework context
7802 APIConstantValuesTest::APIConstantValuesTest(deqp::Context& context)
7803 : TestCase(context, "api_constant_values", "Test verifies values of api constants")
7805 /* Nothing to be done here */
7810 * @return tcu::TestNode::STOP otherwise
7812 tcu::TestNode::IterateResult APIConstantValuesTest::iterate()
7814 static const GLuint expected_comp = 64;
7815 static const GLuint expected_xfb = 4;
7816 static const GLuint expected_sep = 4;
7820 bool test_result = true;
7822 const Functions& gl = m_context.getRenderContext().getFunctions();
7824 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_xfb);
7825 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
7826 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_comp);
7827 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
7828 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, &max_sep);
7829 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
7831 if (expected_xfb > (GLuint)max_xfb)
7833 m_context.getTestContext().getLog() << tcu::TestLog::Message
7834 << "Invalid GL_MAX_TRANSFORM_FEEDBACK_BUFFERS. Got " << max_xfb
7835 << " Expected at least " << expected_xfb << tcu::TestLog::EndMessage;
7837 test_result = false;
7840 if (expected_comp > (GLuint)max_comp)
7842 m_context.getTestContext().getLog()
7843 << tcu::TestLog::Message << "Invalid GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS. Got " << max_comp
7844 << " Expected at least " << expected_comp << tcu::TestLog::EndMessage;
7846 test_result = false;
7849 if (expected_sep > (GLuint)max_sep)
7851 m_context.getTestContext().getLog() << tcu::TestLog::Message
7852 << "Invalid GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS. Got " << max_comp
7853 << " Expected at least " << expected_comp << tcu::TestLog::EndMessage;
7855 test_result = false;
7859 if (true == test_result)
7861 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
7865 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
7869 return tcu::TestNode::STOP;
7874 * @param context Test framework context
7876 APIErrorsTest::APIErrorsTest(deqp::Context& context)
7877 : TestCase(context, "api_errors", "Test verifies errors reeturned by api")
7879 /* Nothing to be done here */
7884 * @return tcu::TestNode::STOP otherwise
7886 tcu::TestNode::IterateResult APIErrorsTest::iterate()
7891 Utils::Program program(m_context);
7892 bool test_result = true;
7894 const Functions& gl = m_context.getRenderContext().getFunctions();
7898 program.Init("" /* cs */, "#version 430 core\n"
7899 "#extension GL_ARB_enhanced_layouts : require\n"
7902 "out vec4 fs_out;\n"
7906 " fs_out = vs_fs;\n"
7909 "" /* gs */, "" /* tcs */, "" /* tes */, "#version 430 core\n"
7910 "#extension GL_ARB_enhanced_layouts : require\n"
7913 "layout (xfb_offset = 16) out vec4 vs_fs;\n"
7920 false /* separable */);
7922 catch (Utils::Shader::InvalidSourceException& exc)
7925 TCU_FAIL(exc.what());
7927 catch (Utils::Program::BuildException& exc)
7929 TCU_FAIL(exc.what());
7933 * - GetProgramInterfaceiv should generate INVALID_OPERATION when
7934 * <programInterface> is TRANSFORM_FEEDBACK_BUFFER and <pname> is one of the
7936 * * MAX_NAME_LENGTH,
7937 * * MAX_NUM_ACTIVE_VARIABLES;
7939 gl.getProgramInterfaceiv(program.m_id, GL_TRANSFORM_FEEDBACK_BUFFER, GL_MAX_NAME_LENGTH, ¶m);
7940 checkError(GL_INVALID_OPERATION, "GetProgramInterfaceiv(GL_TRANSFORM_FEEDBACK_BUFFER, GL_MAX_NAME_LENGTH)",
7944 * - GetProgramResourceIndex should generate INVALID_ENUM when
7945 * <programInterface> is TRANSFORM_FEEDBACK_BUFFER;
7947 gl.getProgramResourceIndex(program.m_id, GL_TRANSFORM_FEEDBACK_BUFFER, "0");
7948 checkError(GL_INVALID_ENUM, "GetProgramResourceIndex(GL_TRANSFORM_FEEDBACK_BUFFER)", test_result);
7950 * - GetProgramResourceName should generate INVALID_ENUM when
7951 * <programInterface> is TRANSFORM_FEEDBACK_BUFFER;
7953 gl.getProgramResourceName(program.m_id, GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, 64 /* bufSize */, &length,
7955 checkError(GL_INVALID_ENUM, "GetProgramResourceName(GL_TRANSFORM_FEEDBACK_BUFFER)", test_result);
7958 if (true == test_result)
7960 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
7964 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
7968 return tcu::TestNode::STOP;
7971 /** Check if error is the expected one.
7973 * @param expected_error Expected error
7974 * @param message Message to log in case of error
7975 * @param test_result Test result, set to false in case of invalid error
7977 void APIErrorsTest::checkError(GLenum expected_error, const GLchar* message, bool& test_result)
7979 const Functions& gl = m_context.getRenderContext().getFunctions();
7981 GLenum error = gl.getError();
7983 if (error != expected_error)
7985 m_context.getTestContext().getLog()
7986 << tcu::TestLog::Message << "Failure. Invalid error. Got " << glu::getErrorStr(error) << " expected "
7987 << glu::getErrorStr(expected_error) << " Msg: " << message << tcu::TestLog::EndMessage;
7989 test_result = false;
7995 * @param context Test framework context
7997 GLSLContantImmutablityTest::GLSLContantImmutablityTest(deqp::Context& context)
7998 : NegativeTestBase(context, "glsl_contant_immutablity", "Test verifies that glsl constants cannot be modified")
8000 /* Nothing to be done here */
8003 /** Source for given test case and stage
8005 * @param test_case_index Index of test case
8006 * @param stage Shader stage
8008 * @return Shader source
8010 std::string GLSLContantImmutablityTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
8012 static const GLchar* cs = "#version 430 core\n"
8013 "#extension GL_ARB_enhanced_layouts : require\n"
8015 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
8017 "writeonly uniform uimage2D uni_image;\n"
8021 " uint result = 1u;\n"
8024 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), uvec4(result, 0, 0, 0));\n"
8027 static const GLchar* fs = "#version 430 core\n"
8028 "#extension GL_ARB_enhanced_layouts : require\n"
8031 "out vec4 fs_out;\n"
8036 " fs_out = gs_fs;\n"
8039 static const GLchar* gs = "#version 430 core\n"
8040 "#extension GL_ARB_enhanced_layouts : require\n"
8042 "layout(points) in;\n"
8043 "layout(triangle_strip, max_vertices = 4) out;\n"
8045 "in vec4 tes_gs[];\n"
8051 " gs_fs = tes_gs[0];\n"
8052 " gl_Position = vec4(-1, -1, 0, 1);\n"
8054 " gs_fs = tes_gs[0];\n"
8055 " gl_Position = vec4(-1, 1, 0, 1);\n"
8057 " gs_fs = tes_gs[0];\n"
8058 " gl_Position = vec4(1, -1, 0, 1);\n"
8060 " gs_fs = tes_gs[0];\n"
8061 " gl_Position = vec4(1, 1, 0, 1);\n"
8065 static const GLchar* tcs = "#version 430 core\n"
8066 "#extension GL_ARB_enhanced_layouts : require\n"
8068 "layout(vertices = 1) out;\n"
8070 "in vec4 vs_tcs[];\n"
8071 "out vec4 tcs_tes[];\n"
8077 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
8079 " gl_TessLevelOuter[0] = 1.0;\n"
8080 " gl_TessLevelOuter[1] = 1.0;\n"
8081 " gl_TessLevelOuter[2] = 1.0;\n"
8082 " gl_TessLevelOuter[3] = 1.0;\n"
8083 " gl_TessLevelInner[0] = 1.0;\n"
8084 " gl_TessLevelInner[1] = 1.0;\n"
8087 static const GLchar* tes = "#version 430 core\n"
8088 "#extension GL_ARB_enhanced_layouts : require\n"
8090 "layout(isolines, point_mode) in;\n"
8092 "in vec4 tcs_tes[];\n"
8093 "out vec4 tes_gs;\n"
8098 " tes_gs = tcs_tes[0];\n"
8101 static const GLchar* vs = "#version 430 core\n"
8102 "#extension GL_ARB_enhanced_layouts : require\n"
8105 "out vec4 vs_tcs;\n"
8110 " vs_tcs = in_vs;\n"
8115 testCase& test_case = m_test_cases[test_case_index];
8117 if (Utils::Shader::COMPUTE == test_case.m_stage)
8119 size_t position = 0;
8123 Utils::replaceToken("CONSTANT", position, getConstantName(test_case.m_constant), source);
8127 std::string assignment = " CONSTANT = 3;\n";
8128 size_t position = 0;
8132 case Utils::Shader::FRAGMENT:
8135 case Utils::Shader::GEOMETRY:
8138 case Utils::Shader::TESS_CTRL:
8141 case Utils::Shader::TESS_EVAL:
8144 case Utils::Shader::VERTEX:
8148 TCU_FAIL("Invalid enum");
8151 if (test_case.m_stage == stage)
8153 Utils::replaceToken("CONSTANT", position, getConstantName(test_case.m_constant), assignment);
8161 Utils::replaceToken("ASSIGNMENT", position, assignment.c_str(), source);
8167 /** Get description of test case
8169 * @param test_case_index Index of test case
8171 * @return Constant name
8173 std::string GLSLContantImmutablityTest::getTestCaseName(GLuint test_case_index)
8175 std::string result = getConstantName(m_test_cases[test_case_index].m_constant);
8180 /** Get number of test cases
8182 * @return Number of test cases
8184 GLuint GLSLContantImmutablityTest::getTestCaseNumber()
8186 return static_cast<GLuint>(m_test_cases.size());
8189 /** Selects if "compute" stage is relevant for test
8191 * @param test_case_index Index of test case
8193 * @return true when tested stage is compute
8195 bool GLSLContantImmutablityTest::isComputeRelevant(GLuint test_case_index)
8197 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
8200 /** Prepare all test cases
8203 void GLSLContantImmutablityTest::testInit()
8205 for (GLuint constant = 0; constant < CONSTANTS_MAX; ++constant)
8207 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
8209 testCase test_case = { (CONSTANTS)constant, (Utils::Shader::STAGES)stage };
8211 m_test_cases.push_back(test_case);
8216 /** Get name of glsl constant
8218 * @param Constant id
8220 * @return Name of constant used in GLSL
8222 const GLchar* GLSLContantImmutablityTest::getConstantName(CONSTANTS constant)
8224 const GLchar* name = "";
8228 case GL_ARB_ENHANCED_LAYOUTS:
8229 name = "GL_ARB_enhanced_layouts";
8232 name = "gl_MaxTransformFeedbackBuffers";
8234 case GL_MAX_XFB_INT_COMP:
8235 name = "gl_MaxTransformFeedbackInterleavedComponents";
8238 TCU_FAIL("Invalid enum");
8246 * @param context Test framework context
8248 GLSLContantValuesTest::GLSLContantValuesTest(deqp::Context& context)
8249 : TextureTestBase(context, "glsl_contant_values", "Test verifies values of constant symbols")
8253 /** Selects if "compute" stage is relevant for test
8259 bool GLSLContantValuesTest::isComputeRelevant(GLuint /* test_case_index */)
8264 /** Prepare code snippet that will verify in and uniform variables
8268 * @param stage Shader stage
8270 * @return Code that verify variables
8272 std::string GLSLContantValuesTest::getVerificationSnippet(GLuint /* test_case_index */,
8273 Utils::ProgramInterface& /* program_interface */,
8274 Utils::Shader::STAGES stage)
8277 const Functions& gl = m_context.getRenderContext().getFunctions();
8279 GLint max_transform_feedback_buffers = 0;
8280 GLint max_transform_feedback_interleaved_components = 0;
8282 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_transform_feedback_buffers);
8283 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8284 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_transform_feedback_interleaved_components);
8285 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8287 std::string verification;
8289 if (Utils::Shader::VERTEX == stage)
8291 verification = "if (1 != GL_ARB_enhanced_layouts)\n"
8295 " else if (MAX_TRANSFORM_FEEDBACK_BUFFERS\n"
8296 " != gl_MaxTransformFeedbackBuffers)\n"
8300 " else if (MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS \n"
8301 " != gl_MaxTransformFeedbackInterleavedComponents)\n"
8306 size_t position = 0;
8309 sprintf(buffer, "%d", max_transform_feedback_buffers);
8310 Utils::replaceToken("MAX_TRANSFORM_FEEDBACK_BUFFERS", position, buffer, verification);
8312 sprintf(buffer, "%d", max_transform_feedback_interleaved_components);
8313 Utils::replaceToken("MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS", position, buffer, verification);
8320 return verification;
8325 * @param context Test framework context
8327 GLSLConstantIntegralExpressionTest::GLSLConstantIntegralExpressionTest(deqp::Context& context)
8328 : TextureTestBase(context, "glsl_constant_integral_expression",
8329 "Test verifies that symbols can be used as constant integral expressions")
8333 /** Get interface of program
8336 * @param program_interface Interface of program
8339 void GLSLConstantIntegralExpressionTest::getProgramInterface(GLuint /* test_case_index */,
8340 Utils::ProgramInterface& program_interface,
8341 Utils::VaryingPassthrough& /* varying_passthrough */)
8344 const Functions& gl = m_context.getRenderContext().getFunctions();
8346 GLint max_transform_feedback_buffers = 0;
8347 GLint max_transform_feedback_interleaved_components = 0;
8349 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_transform_feedback_buffers);
8350 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8351 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_transform_feedback_interleaved_components);
8352 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8354 GLuint gohan_div = std::max(1, max_transform_feedback_buffers / 16);
8355 GLuint goten_div = std::max(1, max_transform_feedback_interleaved_components / 16);
8357 m_gohan_length = max_transform_feedback_buffers / gohan_div;
8358 m_goten_length = max_transform_feedback_interleaved_components / goten_div;
8361 std::string globals = "uniform uint goku [GL_ARB_enhanced_layouts / 1];\n"
8362 "uniform uint gohan[gl_MaxTransformFeedbackBuffers / GOHAN_DIV];\n"
8363 "uniform uint goten[gl_MaxTransformFeedbackInterleavedComponents / GOTEN_DIV];\n";
8365 size_t position = 0;
8368 sprintf(buffer, "%d", gohan_div);
8369 Utils::replaceToken("GOHAN_DIV", position, buffer, globals);
8371 sprintf(buffer, "%d", goten_div);
8372 Utils::replaceToken("GOTEN_DIV", position, buffer, globals);
8374 program_interface.m_vertex.m_globals = globals;
8375 program_interface.m_tess_ctrl.m_globals = globals;
8376 program_interface.m_tess_eval.m_globals = globals;
8377 program_interface.m_geometry.m_globals = globals;
8378 program_interface.m_fragment.m_globals = globals;
8379 program_interface.m_compute.m_globals = globals;
8382 /** Prepare code snippet that will verify in and uniform variables
8388 * @return Code that verify variables
8390 std::string GLSLConstantIntegralExpressionTest::getVerificationSnippet(GLuint /* test_case_index */,
8391 Utils::ProgramInterface& /* program_interface */,
8392 Utils::Shader::STAGES /* stage */)
8394 std::string verification = "{\n"
8395 " uint goku_sum = 0;\n"
8396 " uint gohan_sum = 0;\n"
8397 " uint goten_sum = 0;\n"
8399 " for (uint i = 0u; i < goku.length(); ++i)\n"
8401 " goku_sum += goku[i];\n"
8404 " for (uint i = 0u; i < gohan.length(); ++i)\n"
8406 " gohan_sum += gohan[i];\n"
8409 " for (uint i = 0u; i < goten.length(); ++i)\n"
8411 " goten_sum += goten[i];\n"
8414 " if ( (1u != goku_sum) &&\n"
8415 " (EXPECTED_GOHAN_SUMu != gohan_sum) ||\n"
8416 " (EXPECTED_GOTEN_SUMu != goten_sum) )\n"
8422 size_t position = 0;
8425 sprintf(buffer, "%d", m_gohan_length);
8426 Utils::replaceToken("EXPECTED_GOHAN_SUM", position, buffer, verification);
8428 sprintf(buffer, "%d", m_goten_length);
8429 Utils::replaceToken("EXPECTED_GOTEN_SUM", position, buffer, verification);
8431 return verification;
8434 /** Prepare unifroms
8438 * @param program Program object
8441 void GLSLConstantIntegralExpressionTest::prepareUniforms(GLuint /* test_case_index */,
8442 Utils::ProgramInterface& /* program_interface */,
8443 Utils::Program& program, Utils::Buffer& /* cs_buffer */)
8445 static const GLuint uniform_data[16] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
8447 const Functions& gl = m_context.getRenderContext().getFunctions();
8449 GLint goku_location = program.GetUniformLocation("goku");
8450 GLint gohan_location = program.GetUniformLocation("gohan");
8451 GLint goten_location = program.GetUniformLocation("goten");
8453 program.Uniform(gl, Utils::Type::uint, 1 /* count */, goku_location, uniform_data);
8454 program.Uniform(gl, Utils::Type::uint, m_gohan_length, gohan_location, uniform_data);
8455 program.Uniform(gl, Utils::Type::uint, m_goten_length, goten_location, uniform_data);
8458 /** Prepare unifroms
8460 * @param test_case_index Pass as param to first implemetnation
8461 * @param program_interface Pass as param to first implemetnation
8462 * @param program Pass as param to first implemetnation
8467 * @param vs_buffer Pass as param to first implemetnation
8469 void GLSLConstantIntegralExpressionTest::prepareUniforms(GLuint test_case_index,
8470 Utils::ProgramInterface& program_interface,
8471 Utils::Program& program, Utils::Buffer& /* fs_buffer */,
8472 Utils::Buffer& /* gs_buffer */,
8473 Utils::Buffer& /* tcs_buffer */,
8474 Utils::Buffer& /* tes_buffer */, Utils::Buffer& vs_buffer)
8476 /* Call first implementation */
8477 prepareUniforms(test_case_index, program_interface, program, vs_buffer);
8482 * @param context Test framework context
8484 UniformBlockMemberOffsetAndAlignTest::UniformBlockMemberOffsetAndAlignTest(deqp::Context& context)
8485 : TextureTestBase(context, "uniform_block_member_offset_and_align",
8486 "Test verifies offsets and alignment of uniform buffer members")
8490 /** Get interface of program
8492 * @param test_case_index Test case index
8493 * @param program_interface Interface of program
8494 * @param varying_passthrough Collection of connections between in and out variables
8496 void UniformBlockMemberOffsetAndAlignTest::getProgramInterface(GLuint test_case_index,
8497 Utils::ProgramInterface& program_interface,
8498 Utils::VaryingPassthrough& varying_passthrough)
8500 std::string globals = "const int basic_size = BASIC_SIZE;\n"
8501 "const int type_align = TYPE_ALIGN;\n"
8502 "const int type_size = TYPE_SIZE;\n";
8504 Utils::Type type = getType(test_case_index);
8505 GLuint basic_size = Utils::Type::GetTypeSize(type.m_basic_type);
8506 const GLuint base_align = type.GetBaseAlignment(false);
8507 const GLuint array_align = type.GetBaseAlignment(true);
8508 const GLuint base_stride = Utils::Type::CalculateStd140Stride(base_align, type.m_n_columns, 0);
8509 const GLuint type_align = Utils::roundUpToPowerOf2(base_stride);
8511 /* Calculate offsets */
8512 const GLuint first_offset = 0;
8513 const GLuint second_offset = type.GetActualOffset(base_stride, basic_size / 2);
8515 #if WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST
8517 const GLuint third_offset = type.GetActualOffset(second_offset + base_stride, base_align);
8518 const GLuint fourth_offset = type.GetActualOffset(third_offset + base_stride, base_align);
8519 const GLuint fifth_offset = type.GetActualOffset(fourth_offset + base_stride, base_align);
8520 const GLuint sixth_offset = type.GetActualOffset(fifth_offset + base_stride, array_align);
8521 const GLuint seventh_offset = type.GetActualOffset(sixth_offset + base_stride, array_align);
8522 const GLuint eigth_offset = type.GetActualOffset(seventh_offset + base_stride, array_align);
8524 #else /* WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST */
8526 const GLuint third_offset = type.GetActualOffset(second_offset + base_stride, 2 * type_align);
8527 const GLuint fourth_offset = type.GetActualOffset(3 * type_align + base_stride, base_align);
8528 const GLuint fifth_offset = type.GetActualOffset(fourth_offset + base_stride, base_align);
8529 const GLuint sixth_offset = type.GetActualOffset(fifth_offset + base_stride, array_align);
8530 const GLuint seventh_offset = type.GetActualOffset(sixth_offset + base_stride, array_align);
8531 const GLuint eigth_offset = type.GetActualOffset(seventh_offset + base_stride, 8 * basic_size);
8533 #endif /* WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST */
8536 const std::vector<GLubyte>& first = type.GenerateData();
8537 const std::vector<GLubyte>& second = type.GenerateData();
8538 const std::vector<GLubyte>& third = type.GenerateData();
8539 const std::vector<GLubyte>& fourth = type.GenerateData();
8541 m_data.resize(eigth_offset + base_stride);
8542 GLubyte* ptr = &m_data[0];
8543 memcpy(ptr + first_offset, &first[0], first.size());
8544 memcpy(ptr + second_offset, &second[0], second.size());
8545 memcpy(ptr + third_offset, &third[0], third.size());
8546 memcpy(ptr + fourth_offset, &fourth[0], fourth.size());
8547 memcpy(ptr + fifth_offset, &fourth[0], fourth.size());
8548 memcpy(ptr + sixth_offset, &third[0], third.size());
8549 memcpy(ptr + seventh_offset, &second[0], second.size());
8550 memcpy(ptr + eigth_offset, &first[0], first.size());
8552 /* Prepare globals */
8553 size_t position = 0;
8556 sprintf(buffer, "%d", basic_size);
8557 Utils::replaceToken("BASIC_SIZE", position, buffer, globals);
8559 sprintf(buffer, "%d", type_align);
8560 Utils::replaceToken("TYPE_ALIGN", position, buffer, globals);
8562 sprintf(buffer, "%d", base_stride);
8563 Utils::replaceToken("TYPE_SIZE", position, buffer, globals);
8566 Utils::Interface* vs_uni_block = program_interface.Block("vs_uni_Block");
8568 vs_uni_block->Member("at_first_offset", "layout(offset = 0, align = 8 * basic_size)", 0 /* expected_component */,
8569 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
8572 vs_uni_block->Member("at_second_offset", "layout(offset = type_size, align = basic_size / 2)",
8573 0 /* expected_component */, 0 /* expected_location */, type, false /* normalized */,
8574 0 /* n_array_elements */, base_stride, second_offset);
8576 vs_uni_block->Member("at_third_offset", "layout(align = 2 * type_align)", 0 /* expected_component */,
8577 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
8580 vs_uni_block->Member("at_fourth_offset", "layout(offset = 3 * type_align + type_size)", 0 /* expected_component */,
8581 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
8584 vs_uni_block->Member("at_fifth_offset", "", 0 /* expected_component */, 0 /* expected_location */, type,
8585 false /* normalized */, 0 /* n_array_elements */, base_stride, fifth_offset);
8587 vs_uni_block->Member("at_sixth_offset", "", 0 /* expected_component */, 0 /* expected_location */, type,
8588 false /* normalized */, 2 /* n_array_elements */, array_align * 2, sixth_offset);
8590 vs_uni_block->Member("at_eigth_offset", "layout(align = 8 * basic_size)", 0 /* expected_component */,
8591 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
8594 Utils::ShaderInterface& vs_si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
8597 vs_si.m_globals = globals;
8599 /* Add uniform BLOCK */
8600 vs_si.Uniform("vs_uni_block", "layout (std140, binding = BINDING)", 0, 0, vs_uni_block, 0,
8601 static_cast<glw::GLint>(m_data.size()), 0, &m_data[0], m_data.size());
8604 program_interface.CloneVertexInterface(varying_passthrough);
8609 * @param test_case_index Index of test case
8611 * @return Name of type test in test_case_index
8613 std::string UniformBlockMemberOffsetAndAlignTest::getTestCaseName(glw::GLuint test_case_index)
8615 return getTypeName(test_case_index);
8618 /** Returns number of types to test
8620 * @return Number of types, 34
8622 glw::GLuint UniformBlockMemberOffsetAndAlignTest::getTestCaseNumber()
8624 return getTypesNumber();
8627 /** Prepare code snippet that will verify in and uniform variables
8631 * @param stage Shader stage
8633 * @return Code that verify variables
8635 std::string UniformBlockMemberOffsetAndAlignTest::getVerificationSnippet(
8636 GLuint /* test_case_index */, Utils::ProgramInterface& /* program_interface */, Utils::Shader::STAGES stage)
8638 std::string verification = "if ( (PREFIXblock.at_first_offset != PREFIXblock.at_eigth_offset ) ||\n"
8639 " (PREFIXblock.at_second_offset != PREFIXblock.at_sixth_offset[1]) ||\n"
8640 " (PREFIXblock.at_third_offset != PREFIXblock.at_sixth_offset[0]) ||\n"
8641 " (PREFIXblock.at_fourth_offset != PREFIXblock.at_fifth_offset ) )\n"
8646 const GLchar* prefix = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::UNIFORM);
8648 Utils::replaceAllTokens("PREFIX", prefix, verification);
8650 return verification;
8655 * @param context Test framework context
8657 UniformBlockLayoutQualifierConflictTest::UniformBlockLayoutQualifierConflictTest(deqp::Context& context)
8659 context, "uniform_block_layout_qualifier_conflict",
8660 "Test verifies that std140 is required when offset and/or align qualifiers are used with uniform block")
8662 /* Nothing to be done here */
8665 /** Source for given test case and stage
8667 * @param test_case_index Index of test case
8668 * @param stage Shader stage
8670 * @return Shader source
8672 std::string UniformBlockLayoutQualifierConflictTest::getShaderSource(GLuint test_case_index,
8673 Utils::Shader::STAGES stage)
8675 static const GLchar* cs = "#version 430 core\n"
8676 "#extension GL_ARB_enhanced_layouts : require\n"
8678 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
8680 "LAYOUTuniform Block {\n"
8681 " layout(offset = 16) vec4 boy;\n"
8682 " layout(align = 64) vec4 man;\n"
8685 "writeonly uniform image2D uni_image;\n"
8689 " vec4 result = uni_block.boy + uni_block.man;\n"
8691 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
8694 static const GLchar* fs = "#version 430 core\n"
8695 "#extension GL_ARB_enhanced_layouts : require\n"
8697 "LAYOUTuniform Block {\n"
8698 " layout(offset = 16) vec4 boy;\n"
8699 " layout(align = 64) vec4 man;\n"
8703 "out vec4 fs_out;\n"
8707 " fs_out = gs_fs + uni_block.boy + uni_block.man;\n"
8710 static const GLchar* gs = "#version 430 core\n"
8711 "#extension GL_ARB_enhanced_layouts : require\n"
8713 "layout(points) in;\n"
8714 "layout(triangle_strip, max_vertices = 4) out;\n"
8716 "LAYOUTuniform Block {\n"
8717 " layout(offset = 16) vec4 boy;\n"
8718 " layout(align = 64) vec4 man;\n"
8721 "in vec4 tes_gs[];\n"
8726 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
8727 " gl_Position = vec4(-1, -1, 0, 1);\n"
8729 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
8730 " gl_Position = vec4(-1, 1, 0, 1);\n"
8732 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
8733 " gl_Position = vec4(1, -1, 0, 1);\n"
8735 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
8736 " gl_Position = vec4(1, 1, 0, 1);\n"
8740 static const GLchar* tcs =
8741 "#version 430 core\n"
8742 "#extension GL_ARB_enhanced_layouts : require\n"
8744 "layout(vertices = 1) out;\n"
8746 "LAYOUTuniform Block {\n"
8747 " layout(offset = 16) vec4 boy;\n"
8748 " layout(align = 64) vec4 man;\n"
8751 "in vec4 vs_tcs[];\n"
8752 "out vec4 tcs_tes[];\n"
8757 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID] + uni_block.boy + uni_block.man;\n"
8759 " gl_TessLevelOuter[0] = 1.0;\n"
8760 " gl_TessLevelOuter[1] = 1.0;\n"
8761 " gl_TessLevelOuter[2] = 1.0;\n"
8762 " gl_TessLevelOuter[3] = 1.0;\n"
8763 " gl_TessLevelInner[0] = 1.0;\n"
8764 " gl_TessLevelInner[1] = 1.0;\n"
8767 static const GLchar* tes = "#version 430 core\n"
8768 "#extension GL_ARB_enhanced_layouts : require\n"
8770 "layout(isolines, point_mode) in;\n"
8772 "LAYOUTuniform Block {\n"
8773 " layout(offset = 16) vec4 boy;\n"
8774 " layout(align = 64) vec4 man;\n"
8777 "in vec4 tcs_tes[];\n"
8778 "out vec4 tes_gs;\n"
8782 " tes_gs = tcs_tes[0] + uni_block.boy + uni_block.man;\n"
8785 static const GLchar* vs = "#version 430 core\n"
8786 "#extension GL_ARB_enhanced_layouts : require\n"
8788 "LAYOUTuniform Block {\n"
8789 " layout(offset = 16) vec4 boy;\n"
8790 " layout(align = 64) vec4 man;\n"
8794 "out vec4 vs_tcs;\n"
8798 " vs_tcs = in_vs + uni_block.boy + uni_block.man;\n"
8802 std::string layout = "";
8803 size_t position = 0;
8804 testCase& test_case = m_test_cases[test_case_index];
8805 const GLchar* qualifier = getQualifierName(test_case.m_qualifier);
8808 if (0 != qualifier[0])
8810 size_t layout_position = 0;
8812 layout = "layout (QUALIFIER) ";
8814 Utils::replaceToken("QUALIFIER", layout_position, qualifier, layout);
8819 case Utils::Shader::COMPUTE:
8822 case Utils::Shader::FRAGMENT:
8825 case Utils::Shader::GEOMETRY:
8828 case Utils::Shader::TESS_CTRL:
8831 case Utils::Shader::TESS_EVAL:
8834 case Utils::Shader::VERTEX:
8838 TCU_FAIL("Invalid enum");
8841 if (test_case.m_stage == stage)
8843 Utils::replaceToken("LAYOUT", position, layout.c_str(), source);
8847 Utils::replaceToken("LAYOUT", position, "layout (std140) ", source);
8853 /** Get description of test case
8855 * @param test_case_index Index of test case
8857 * @return Qualifier name
8859 std::string UniformBlockLayoutQualifierConflictTest::getTestCaseName(GLuint test_case_index)
8861 std::string result = getQualifierName(m_test_cases[test_case_index].m_qualifier);
8866 /** Get number of test cases
8868 * @return Number of test cases
8870 GLuint UniformBlockLayoutQualifierConflictTest::getTestCaseNumber()
8872 return static_cast<GLuint>(m_test_cases.size());
8875 /** Selects if "compute" stage is relevant for test
8877 * @param test_case_index Index of test case
8879 * @return true when tested stage is compute
8881 bool UniformBlockLayoutQualifierConflictTest::isComputeRelevant(GLuint test_case_index)
8883 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
8886 /** Selects if compilation failure is expected result
8888 * @param test_case_index Index of test case
8890 * @return false for STD140 cases, true otherwise
8892 bool UniformBlockLayoutQualifierConflictTest::isFailureExpected(GLuint test_case_index)
8894 return (STD140 != m_test_cases[test_case_index].m_qualifier);
8897 /** Prepare all test cases
8900 void UniformBlockLayoutQualifierConflictTest::testInit()
8902 for (GLuint qualifier = 0; qualifier < QUALIFIERS_MAX; ++qualifier)
8904 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
8906 testCase test_case = { (QUALIFIERS)qualifier, (Utils::Shader::STAGES)stage };
8908 m_test_cases.push_back(test_case);
8913 /** Get name of glsl constant
8915 * @param Constant id
8917 * @return Name of constant used in GLSL
8919 const GLchar* UniformBlockLayoutQualifierConflictTest::getQualifierName(QUALIFIERS qualifier)
8921 const GLchar* name = "";
8938 TCU_FAIL("Invalid enum");
8946 * @param context Test framework context
8948 UniformBlockMemberInvalidOffsetAlignmentTest::UniformBlockMemberInvalidOffsetAlignmentTest(deqp::Context& context)
8949 : NegativeTestBase(context, "uniform_block_member_invalid_offset_alignment",
8950 "Test verifies that invalid alignment of offset qualifiers cause compilation failure")
8952 /* Nothing to be done here */
8957 * @param context Test framework context
8958 * @param name Test name
8959 * @param description Test description
8961 UniformBlockMemberInvalidOffsetAlignmentTest::UniformBlockMemberInvalidOffsetAlignmentTest(
8962 deqp::Context& context, const glw::GLchar* name, const glw::GLchar* description)
8963 : NegativeTestBase(context, name, description)
8965 /* Nothing to be done here */
8968 /** Source for given test case and stage
8970 * @param test_case_index Index of test case
8971 * @param stage Shader stage
8973 * @return Shader source
8975 std::string UniformBlockMemberInvalidOffsetAlignmentTest::getShaderSource(GLuint test_case_index,
8976 Utils::Shader::STAGES stage)
8978 static const GLchar* cs = "#version 430 core\n"
8979 "#extension GL_ARB_enhanced_layouts : require\n"
8981 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
8983 "layout (std140) uniform Block {\n"
8984 " layout (offset = OFFSET) TYPE member;\n"
8987 "writeonly uniform image2D uni_image;\n"
8991 " vec4 result = vec4(1, 0, 0.5, 1);\n"
8993 " if (TYPE(1) == block.member)\n"
8995 " result = vec4(1, 1, 1, 1);\n"
8998 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
9001 static const GLchar* fs = "#version 430 core\n"
9002 "#extension GL_ARB_enhanced_layouts : require\n"
9005 "out vec4 fs_out;\n"
9009 " fs_out = gs_fs;\n"
9012 static const GLchar* fs_tested = "#version 430 core\n"
9013 "#extension GL_ARB_enhanced_layouts : require\n"
9015 "layout (std140) uniform Block {\n"
9016 " layout (offset = OFFSET) TYPE member;\n"
9020 "out vec4 fs_out;\n"
9024 " if (TYPE(1) == block.member)\n"
9026 " fs_out = vec4(1, 1, 1, 1);\n"
9029 " fs_out += gs_fs;\n"
9032 static const GLchar* gs = "#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 "in vec4 tes_gs[];\n"
9043 " gs_fs = tes_gs[0];\n"
9044 " gl_Position = vec4(-1, -1, 0, 1);\n"
9046 " gs_fs = tes_gs[0];\n"
9047 " gl_Position = vec4(-1, 1, 0, 1);\n"
9049 " gs_fs = tes_gs[0];\n"
9050 " gl_Position = vec4(1, -1, 0, 1);\n"
9052 " gs_fs = tes_gs[0];\n"
9053 " gl_Position = vec4(1, 1, 0, 1);\n"
9057 static const GLchar* gs_tested = "#version 430 core\n"
9058 "#extension GL_ARB_enhanced_layouts : require\n"
9060 "layout(points) in;\n"
9061 "layout(triangle_strip, max_vertices = 4) out;\n"
9063 "layout (std140) uniform Block {\n"
9064 " layout (offset = OFFSET) TYPE member;\n"
9067 "in vec4 tes_gs[];\n"
9072 " if (TYPE(1) == block.member)\n"
9074 " gs_fs = vec4(1, 1, 1, 1);\n"
9077 " gs_fs += tes_gs[0];\n"
9078 " gl_Position = vec4(-1, -1, 0, 1);\n"
9080 " gs_fs += tes_gs[0];\n"
9081 " gl_Position = vec4(-1, 1, 0, 1);\n"
9083 " gs_fs += tes_gs[0];\n"
9084 " gl_Position = vec4(1, -1, 0, 1);\n"
9086 " gs_fs += tes_gs[0];\n"
9087 " gl_Position = vec4(1, 1, 0, 1);\n"
9091 static const GLchar* tcs = "#version 430 core\n"
9092 "#extension GL_ARB_enhanced_layouts : require\n"
9094 "layout(vertices = 1) out;\n"
9096 "in vec4 vs_tcs[];\n"
9097 "out vec4 tcs_tes[];\n"
9102 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
9104 " gl_TessLevelOuter[0] = 1.0;\n"
9105 " gl_TessLevelOuter[1] = 1.0;\n"
9106 " gl_TessLevelOuter[2] = 1.0;\n"
9107 " gl_TessLevelOuter[3] = 1.0;\n"
9108 " gl_TessLevelInner[0] = 1.0;\n"
9109 " gl_TessLevelInner[1] = 1.0;\n"
9112 static const GLchar* tcs_tested = "#version 430 core\n"
9113 "#extension GL_ARB_enhanced_layouts : require\n"
9115 "layout(vertices = 1) out;\n"
9117 "layout (std140) uniform Block {\n"
9118 " layout (offset = OFFSET) TYPE member;\n"
9121 "in vec4 vs_tcs[];\n"
9122 "out vec4 tcs_tes[];\n"
9126 " if (TYPE(1) == block.member)\n"
9128 " tcs_tes[gl_InvocationID] = vec4(1, 1, 1, 1);\n"
9132 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
9134 " gl_TessLevelOuter[0] = 1.0;\n"
9135 " gl_TessLevelOuter[1] = 1.0;\n"
9136 " gl_TessLevelOuter[2] = 1.0;\n"
9137 " gl_TessLevelOuter[3] = 1.0;\n"
9138 " gl_TessLevelInner[0] = 1.0;\n"
9139 " gl_TessLevelInner[1] = 1.0;\n"
9142 static const GLchar* tes = "#version 430 core\n"
9143 "#extension GL_ARB_enhanced_layouts : require\n"
9145 "layout(isolines, point_mode) in;\n"
9147 "in vec4 tcs_tes[];\n"
9148 "out vec4 tes_gs;\n"
9152 " tes_gs = tcs_tes[0];\n"
9155 static const GLchar* tes_tested = "#version 430 core\n"
9156 "#extension GL_ARB_enhanced_layouts : require\n"
9158 "layout(isolines, point_mode) in;\n"
9160 "layout (std140) uniform Block {\n"
9161 " layout (offset = OFFSET) TYPE member;\n"
9164 "in vec4 tcs_tes[];\n"
9165 "out vec4 tes_gs;\n"
9169 " if (TYPE(1) == block.member)\n"
9171 " tes_gs = vec4(1, 1, 1, 1);\n"
9174 " tes_gs += tcs_tes[0];\n"
9177 static const GLchar* vs = "#version 430 core\n"
9178 "#extension GL_ARB_enhanced_layouts : require\n"
9181 "out vec4 vs_tcs;\n"
9185 " vs_tcs = in_vs;\n"
9188 static const GLchar* vs_tested = "#version 430 core\n"
9189 "#extension GL_ARB_enhanced_layouts : require\n"
9191 "layout (std140) uniform Block {\n"
9192 " layout (offset = OFFSET) TYPE member;\n"
9196 "out vec4 vs_tcs;\n"
9200 " if (TYPE(1) == block.member)\n"
9202 " vs_tcs = vec4(1, 1, 1, 1);\n"
9205 " vs_tcs += in_vs;\n"
9210 testCase& test_case = m_test_cases[test_case_index];
9212 if (test_case.m_stage == stage)
9215 const GLuint offset = test_case.m_offset;
9216 size_t position = 0;
9217 const Utils::Type& type = test_case.m_type;
9218 const GLchar* type_name = type.GetGLSLTypeName();
9220 sprintf(buffer, "%d", offset);
9224 case Utils::Shader::COMPUTE:
9227 case Utils::Shader::FRAGMENT:
9230 case Utils::Shader::GEOMETRY:
9233 case Utils::Shader::TESS_CTRL:
9234 source = tcs_tested;
9236 case Utils::Shader::TESS_EVAL:
9237 source = tes_tested;
9239 case Utils::Shader::VERTEX:
9243 TCU_FAIL("Invalid enum");
9246 Utils::replaceToken("OFFSET", position, buffer, source);
9247 Utils::replaceToken("TYPE", position, type_name, source);
9248 Utils::replaceToken("TYPE", position, type_name, source);
9254 case Utils::Shader::FRAGMENT:
9257 case Utils::Shader::GEOMETRY:
9260 case Utils::Shader::TESS_CTRL:
9263 case Utils::Shader::TESS_EVAL:
9266 case Utils::Shader::VERTEX:
9270 TCU_FAIL("Invalid enum");
9277 /** Get description of test case
9279 * @param test_case_index Index of test case
9281 * @return Type name and offset
9283 std::string UniformBlockMemberInvalidOffsetAlignmentTest::getTestCaseName(GLuint test_case_index)
9285 std::stringstream stream;
9286 testCase& test_case = m_test_cases[test_case_index];
9288 stream << "Type: " << test_case.m_type.GetGLSLTypeName() << ", offset: " << test_case.m_offset;
9290 return stream.str();
9293 /** Get number of test cases
9295 * @return Number of test cases
9297 GLuint UniformBlockMemberInvalidOffsetAlignmentTest::getTestCaseNumber()
9299 return static_cast<GLuint>(m_test_cases.size());
9302 /** Selects if "compute" stage is relevant for test
9304 * @param test_case_index Index of test case
9306 * @return true when tested stage is compute
9308 bool UniformBlockMemberInvalidOffsetAlignmentTest::isComputeRelevant(GLuint test_case_index)
9310 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
9313 /** Selects if compilation failure is expected result
9315 * @param test_case_index Index of test case
9317 * @return should_fail field from testCase
9319 bool UniformBlockMemberInvalidOffsetAlignmentTest::isFailureExpected(GLuint test_case_index)
9321 return m_test_cases[test_case_index].m_should_fail;
9324 /** Checks if stage is supported
9326 * @param stage ignored
9330 bool UniformBlockMemberInvalidOffsetAlignmentTest::isStageSupported(Utils::Shader::STAGES /* stage */)
9335 /** Prepare all test cases
9338 void UniformBlockMemberInvalidOffsetAlignmentTest::testInit()
9340 const Functions& gl = m_context.getRenderContext().getFunctions();
9342 const GLuint n_types = getTypesNumber();
9343 bool stage_support[Utils::Shader::STAGE_MAX];
9345 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
9347 stage_support[stage] = isStageSupported((Utils::Shader::STAGES)stage);
9350 gl.getIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &max_size);
9351 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
9353 for (GLuint i = 0; i < n_types; ++i)
9355 const Utils::Type& type = getType(i);
9356 const GLuint alignment = type.GetBaseAlignment(false);
9357 const GLuint type_size = type.GetSize(true);
9358 const GLuint sec_to_end = max_size - 2 * type_size;
9360 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
9362 if (false == stage_support[stage])
9367 for (GLuint offset = 0; offset <= type_size; ++offset)
9369 const GLuint modulo = offset % alignment;
9370 const bool is_aligned = (0 == modulo) ? true : false;
9371 const bool should_fail = !is_aligned;
9373 testCase test_case = { offset, should_fail, (Utils::Shader::STAGES)stage, type };
9375 m_test_cases.push_back(test_case);
9378 for (GLuint offset = sec_to_end; offset <= sec_to_end + type_size; ++offset)
9380 const GLuint modulo = offset % alignment;
9381 const bool is_aligned = (0 == modulo) ? true : false;
9382 const bool should_fail = !is_aligned;
9384 testCase test_case = { offset, should_fail, (Utils::Shader::STAGES)stage, type };
9386 m_test_cases.push_back(test_case);
9394 * @param context Test framework context
9396 UniformBlockMemberOverlappingOffsetsTest::UniformBlockMemberOverlappingOffsetsTest(deqp::Context& context)
9397 : NegativeTestBase(context, "uniform_block_member_overlapping_offsets",
9398 "Test verifies that overlapping offsets qualifiers cause compilation failure")
9400 /* Nothing to be done here */
9405 * @param context Test framework context
9406 * @param name Test name
9407 * @param description Test description
9409 UniformBlockMemberOverlappingOffsetsTest::UniformBlockMemberOverlappingOffsetsTest(deqp::Context& context,
9410 const glw::GLchar* name,
9411 const glw::GLchar* description)
9412 : NegativeTestBase(context, name, description)
9414 /* Nothing to be done here */
9417 /** Source for given test case and stage
9419 * @param test_case_index Index of test case
9420 * @param stage Shader stage
9422 * @return Shader source
9424 std::string UniformBlockMemberOverlappingOffsetsTest::getShaderSource(GLuint test_case_index,
9425 Utils::Shader::STAGES stage)
9427 static const GLchar* cs = "#version 430 core\n"
9428 "#extension GL_ARB_enhanced_layouts : require\n"
9430 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
9432 "layout (std140) uniform Block {\n"
9433 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9434 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9437 "writeonly uniform image2D uni_image;\n"
9441 " vec4 result = vec4(1, 0, 0.5, 1);\n"
9443 " if ((BOY_TYPE(1) == block.boy) ||\n"
9444 " (MAN_TYPE(0) == block.man) )\n"
9446 " result = vec4(1, 1, 1, 1);\n"
9449 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
9452 static const GLchar* fs = "#version 430 core\n"
9453 "#extension GL_ARB_enhanced_layouts : require\n"
9456 "out vec4 fs_out;\n"
9460 " fs_out = gs_fs;\n"
9463 static const GLchar* fs_tested = "#version 430 core\n"
9464 "#extension GL_ARB_enhanced_layouts : require\n"
9466 "layout (std140) uniform Block {\n"
9467 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9468 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9472 "out vec4 fs_out;\n"
9476 " if ((BOY_TYPE(1) == block.boy) ||\n"
9477 " (MAN_TYPE(0) == block.man) )\n"
9479 " fs_out = vec4(1, 1, 1, 1);\n"
9482 " fs_out += gs_fs;\n"
9485 static const GLchar* gs = "#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 "in vec4 tes_gs[];\n"
9496 " gs_fs = tes_gs[0];\n"
9497 " gl_Position = vec4(-1, -1, 0, 1);\n"
9499 " gs_fs = tes_gs[0];\n"
9500 " gl_Position = vec4(-1, 1, 0, 1);\n"
9502 " gs_fs = tes_gs[0];\n"
9503 " gl_Position = vec4(1, -1, 0, 1);\n"
9505 " gs_fs = tes_gs[0];\n"
9506 " gl_Position = vec4(1, 1, 0, 1);\n"
9510 static const GLchar* gs_tested = "#version 430 core\n"
9511 "#extension GL_ARB_enhanced_layouts : require\n"
9513 "layout(points) in;\n"
9514 "layout(triangle_strip, max_vertices = 4) out;\n"
9516 "layout (std140) uniform Block {\n"
9517 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9518 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9521 "in vec4 tes_gs[];\n"
9526 " if ((BOY_TYPE(1) == block.boy) ||\n"
9527 " (MAN_TYPE(0) == block.man) )\n"
9529 " gs_fs = vec4(1, 1, 1, 1);\n"
9532 " gs_fs += tes_gs[0];\n"
9533 " gl_Position = vec4(-1, -1, 0, 1);\n"
9535 " gs_fs += tes_gs[0];\n"
9536 " gl_Position = vec4(-1, 1, 0, 1);\n"
9538 " gs_fs += tes_gs[0];\n"
9539 " gl_Position = vec4(1, -1, 0, 1);\n"
9541 " gs_fs += tes_gs[0];\n"
9542 " gl_Position = vec4(1, 1, 0, 1);\n"
9546 static const GLchar* tcs = "#version 430 core\n"
9547 "#extension GL_ARB_enhanced_layouts : require\n"
9549 "layout(vertices = 1) out;\n"
9551 "in vec4 vs_tcs[];\n"
9552 "out vec4 tcs_tes[];\n"
9557 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
9559 " gl_TessLevelOuter[0] = 1.0;\n"
9560 " gl_TessLevelOuter[1] = 1.0;\n"
9561 " gl_TessLevelOuter[2] = 1.0;\n"
9562 " gl_TessLevelOuter[3] = 1.0;\n"
9563 " gl_TessLevelInner[0] = 1.0;\n"
9564 " gl_TessLevelInner[1] = 1.0;\n"
9567 static const GLchar* tcs_tested = "#version 430 core\n"
9568 "#extension GL_ARB_enhanced_layouts : require\n"
9570 "layout(vertices = 1) out;\n"
9572 "layout (std140) uniform Block {\n"
9573 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9574 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9577 "in vec4 vs_tcs[];\n"
9578 "out vec4 tcs_tes[];\n"
9582 " if ((BOY_TYPE(1) == block.boy) ||\n"
9583 " (MAN_TYPE(0) == block.man) )\n"
9585 " tcs_tes[gl_InvocationID] = vec4(1, 1, 1, 1);\n"
9589 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
9591 " gl_TessLevelOuter[0] = 1.0;\n"
9592 " gl_TessLevelOuter[1] = 1.0;\n"
9593 " gl_TessLevelOuter[2] = 1.0;\n"
9594 " gl_TessLevelOuter[3] = 1.0;\n"
9595 " gl_TessLevelInner[0] = 1.0;\n"
9596 " gl_TessLevelInner[1] = 1.0;\n"
9599 static const GLchar* tes = "#version 430 core\n"
9600 "#extension GL_ARB_enhanced_layouts : require\n"
9602 "layout(isolines, point_mode) in;\n"
9604 "in vec4 tcs_tes[];\n"
9605 "out vec4 tes_gs;\n"
9609 " tes_gs = tcs_tes[0];\n"
9612 static const GLchar* tes_tested = "#version 430 core\n"
9613 "#extension GL_ARB_enhanced_layouts : require\n"
9615 "layout(isolines, point_mode) in;\n"
9617 "layout (std140) uniform Block {\n"
9618 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9619 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9622 "in vec4 tcs_tes[];\n"
9623 "out vec4 tes_gs;\n"
9627 " if ((BOY_TYPE(1) == block.boy) ||\n"
9628 " (MAN_TYPE(0) == block.man) )\n"
9630 " tes_gs = vec4(1, 1, 1, 1);\n"
9633 " tes_gs += tcs_tes[0];\n"
9636 static const GLchar* vs = "#version 430 core\n"
9637 "#extension GL_ARB_enhanced_layouts : require\n"
9640 "out vec4 vs_tcs;\n"
9644 " vs_tcs = in_vs;\n"
9647 static const GLchar* vs_tested = "#version 430 core\n"
9648 "#extension GL_ARB_enhanced_layouts : require\n"
9650 "layout (std140) uniform Block {\n"
9651 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9652 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9656 "out vec4 vs_tcs;\n"
9660 " if ((BOY_TYPE(1) == block.boy) ||\n"
9661 " (MAN_TYPE(0) == block.man) )\n"
9663 " vs_tcs = vec4(1, 1, 1, 1);\n"
9666 " vs_tcs += in_vs;\n"
9671 testCase& test_case = m_test_cases[test_case_index];
9673 if (test_case.m_stage == stage)
9676 const GLuint boy_offset = test_case.m_boy_offset;
9677 const Utils::Type& boy_type = test_case.m_boy_type;
9678 const GLchar* boy_type_name = boy_type.GetGLSLTypeName();
9679 const GLuint man_offset = test_case.m_man_offset;
9680 const Utils::Type& man_type = test_case.m_man_type;
9681 const GLchar* man_type_name = man_type.GetGLSLTypeName();
9682 size_t position = 0;
9686 case Utils::Shader::COMPUTE:
9689 case Utils::Shader::FRAGMENT:
9692 case Utils::Shader::GEOMETRY:
9695 case Utils::Shader::TESS_CTRL:
9696 source = tcs_tested;
9698 case Utils::Shader::TESS_EVAL:
9699 source = tes_tested;
9701 case Utils::Shader::VERTEX:
9705 TCU_FAIL("Invalid enum");
9708 sprintf(buffer, "%d", boy_offset);
9709 Utils::replaceToken("BOY_OFFSET", position, buffer, source);
9710 Utils::replaceToken("BOY_TYPE", position, boy_type_name, source);
9711 sprintf(buffer, "%d", man_offset);
9712 Utils::replaceToken("MAN_OFFSET", position, buffer, source);
9713 Utils::replaceToken("MAN_TYPE", position, man_type_name, source);
9714 Utils::replaceToken("BOY_TYPE", position, boy_type_name, source);
9715 Utils::replaceToken("MAN_TYPE", position, man_type_name, source);
9721 case Utils::Shader::FRAGMENT:
9724 case Utils::Shader::GEOMETRY:
9727 case Utils::Shader::TESS_CTRL:
9730 case Utils::Shader::TESS_EVAL:
9733 case Utils::Shader::VERTEX:
9737 TCU_FAIL("Invalid enum");
9744 /** Get description of test case
9746 * @param test_case_index Index of test case
9748 * @return Type name and offset
9750 std::string UniformBlockMemberOverlappingOffsetsTest::getTestCaseName(GLuint test_case_index)
9752 std::stringstream stream;
9753 testCase& test_case = m_test_cases[test_case_index];
9755 stream << "Type: " << test_case.m_boy_type.GetGLSLTypeName() << ", offset: " << test_case.m_boy_offset
9756 << ". Type: " << test_case.m_man_type.GetGLSLTypeName() << ", offset: " << test_case.m_man_offset;
9758 return stream.str();
9761 /** Get number of test cases
9763 * @return Number of test cases
9765 GLuint UniformBlockMemberOverlappingOffsetsTest::getTestCaseNumber()
9767 return static_cast<GLuint>(m_test_cases.size());
9770 /** Selects if "compute" stage is relevant for test
9772 * @param test_case_index Index of test case
9774 * @return true when tested stage is compute
9776 bool UniformBlockMemberOverlappingOffsetsTest::isComputeRelevant(GLuint test_case_index)
9778 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
9781 /** Checks if stage is supported
9783 * @param stage ignored
9787 bool UniformBlockMemberOverlappingOffsetsTest::isStageSupported(Utils::Shader::STAGES /* stage */)
9792 /** Prepare all test cases
9795 void UniformBlockMemberOverlappingOffsetsTest::testInit()
9797 const GLuint n_types = getTypesNumber();
9798 bool stage_support[Utils::Shader::STAGE_MAX];
9800 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
9802 stage_support[stage] = isStageSupported((Utils::Shader::STAGES)stage);
9805 for (GLuint i = 0; i < n_types; ++i)
9807 const Utils::Type& boy_type = getType(i);
9808 const GLuint boy_size = boy_type.GetActualAlignment(1 /* align */, false /* is_array*/);
9810 for (GLuint j = 0; j < n_types; ++j)
9812 const Utils::Type& man_type = getType(j);
9813 const GLuint man_align = man_type.GetBaseAlignment(false);
9814 const GLuint man_size = man_type.GetActualAlignment(1 /* align */, false /* is_array*/);
9816 const GLuint boy_offset = lcm(boy_size, man_size);
9817 const GLuint man_after_start = boy_offset + 1;
9818 const GLuint man_after_off = man_type.GetActualOffset(man_after_start, man_size);
9819 const GLuint man_before_start = boy_offset - man_align;
9820 const GLuint man_before_off = man_type.GetActualOffset(man_before_start, man_size);
9822 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
9824 if (false == stage_support[stage])
9829 if ((boy_offset > man_before_off) && (boy_offset < man_before_off + man_size))
9831 testCase test_case = { boy_offset, boy_type, man_before_off, man_type,
9832 (Utils::Shader::STAGES)stage };
9834 m_test_cases.push_back(test_case);
9837 if ((boy_offset < man_after_off) && (boy_offset + boy_size > man_after_off))
9839 testCase test_case = { boy_offset, boy_type, man_after_off, man_type,
9840 (Utils::Shader::STAGES)stage };
9842 m_test_cases.push_back(test_case);
9845 /* Boy offset, should be fine for both types */
9846 testCase test_case = { boy_offset, boy_type, boy_offset, man_type, (Utils::Shader::STAGES)stage };
9848 m_test_cases.push_back(test_case);
9854 /** Find greatest common divisor for a and b
9856 * @param a A argument
9857 * @param b B argument
9859 * @return Found gcd value
9861 GLuint UniformBlockMemberOverlappingOffsetsTest::gcd(GLuint a, GLuint b)
9863 if ((0 != a) && (0 == b))
9869 GLuint greater = std::max(a, b);
9870 GLuint lesser = std::min(a, b);
9872 return gcd(lesser, greater % lesser);
9876 /** Find lowest common multiple for a and b
9878 * @param a A argument
9879 * @param b B argument
9881 * @return Found gcd value
9883 GLuint UniformBlockMemberOverlappingOffsetsTest::lcm(GLuint a, GLuint b)
9885 return (a * b) / gcd(a, b);
9890 * @param context Test framework context
9892 UniformBlockMemberAlignNonPowerOf2Test::UniformBlockMemberAlignNonPowerOf2Test(deqp::Context& context)
9893 : NegativeTestBase(context, "uniform_block_member_align_non_power_of_2",
9894 "Test verifies that align qualifier requires value that is a power of 2")
9896 /* Nothing to be done here */
9901 * @param context Test framework context
9902 * @param name Test name
9903 * @param description Test description
9905 UniformBlockMemberAlignNonPowerOf2Test::UniformBlockMemberAlignNonPowerOf2Test(deqp::Context& context,
9906 const glw::GLchar* name,
9907 const glw::GLchar* description)
9908 : NegativeTestBase(context, name, description)
9910 /* Nothing to be done here */
9913 /** Source for given test case and stage
9915 * @param test_case_index Index of test case
9916 * @param stage Shader stage
9918 * @return Shader source
9920 std::string UniformBlockMemberAlignNonPowerOf2Test::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
9922 static const GLchar* cs = "#version 430 core\n"
9923 "#extension GL_ARB_enhanced_layouts : require\n"
9925 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
9927 "layout (std140) uniform Block {\n"
9929 " layout (align = ALIGN) TYPE man;\n"
9932 "writeonly uniform image2D uni_image;\n"
9936 " vec4 result = vec4(1, 0, 0.5, 1);\n"
9938 " if (TYPE(0) == block.man)\n"
9940 " result = vec4(1, 1, 1, 1) - block.boy;\n"
9943 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
9946 static const GLchar* fs = "#version 430 core\n"
9947 "#extension GL_ARB_enhanced_layouts : require\n"
9950 "out vec4 fs_out;\n"
9954 " fs_out = gs_fs;\n"
9957 static const GLchar* fs_tested = "#version 430 core\n"
9958 "#extension GL_ARB_enhanced_layouts : require\n"
9960 "layout (std140) uniform Block {\n"
9962 " layout (align = ALIGN) TYPE man;\n"
9966 "out vec4 fs_out;\n"
9970 " if (TYPE(0) == block.man)\n"
9972 " fs_out = block.boy;\n"
9975 " fs_out += gs_fs;\n"
9978 static const GLchar* gs = "#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 "in vec4 tes_gs[];\n"
9989 " gs_fs = tes_gs[0];\n"
9990 " gl_Position = vec4(-1, -1, 0, 1);\n"
9992 " gs_fs = tes_gs[0];\n"
9993 " gl_Position = vec4(-1, 1, 0, 1);\n"
9995 " gs_fs = tes_gs[0];\n"
9996 " gl_Position = vec4(1, -1, 0, 1);\n"
9998 " gs_fs = tes_gs[0];\n"
9999 " gl_Position = vec4(1, 1, 0, 1);\n"
10003 static const GLchar* gs_tested = "#version 430 core\n"
10004 "#extension GL_ARB_enhanced_layouts : require\n"
10006 "layout(points) in;\n"
10007 "layout(triangle_strip, max_vertices = 4) out;\n"
10009 "layout (std140) uniform Block {\n"
10011 " layout (align = ALIGN) TYPE man;\n"
10014 "in vec4 tes_gs[];\n"
10015 "out vec4 gs_fs;\n"
10019 " if (TYPE(0) == block.man)\n"
10021 " gs_fs = block.boy;\n"
10024 " gs_fs += tes_gs[0];\n"
10025 " gl_Position = vec4(-1, -1, 0, 1);\n"
10027 " gs_fs += tes_gs[0];\n"
10028 " gl_Position = vec4(-1, 1, 0, 1);\n"
10030 " gs_fs += tes_gs[0];\n"
10031 " gl_Position = vec4(1, -1, 0, 1);\n"
10033 " gs_fs += tes_gs[0];\n"
10034 " gl_Position = vec4(1, 1, 0, 1);\n"
10038 static const GLchar* tcs = "#version 430 core\n"
10039 "#extension GL_ARB_enhanced_layouts : require\n"
10041 "layout(vertices = 1) out;\n"
10043 "in vec4 vs_tcs[];\n"
10044 "out vec4 tcs_tes[];\n"
10049 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
10051 " gl_TessLevelOuter[0] = 1.0;\n"
10052 " gl_TessLevelOuter[1] = 1.0;\n"
10053 " gl_TessLevelOuter[2] = 1.0;\n"
10054 " gl_TessLevelOuter[3] = 1.0;\n"
10055 " gl_TessLevelInner[0] = 1.0;\n"
10056 " gl_TessLevelInner[1] = 1.0;\n"
10059 static const GLchar* tcs_tested = "#version 430 core\n"
10060 "#extension GL_ARB_enhanced_layouts : require\n"
10062 "layout(vertices = 1) out;\n"
10064 "layout (std140) uniform Block {\n"
10066 " layout (align = ALIGN) TYPE man;\n"
10069 "in vec4 vs_tcs[];\n"
10070 "out vec4 tcs_tes[];\n"
10074 " if (TYPE(0) == block.man)\n"
10076 " tcs_tes[gl_InvocationID] = block.boy;\n"
10080 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
10082 " gl_TessLevelOuter[0] = 1.0;\n"
10083 " gl_TessLevelOuter[1] = 1.0;\n"
10084 " gl_TessLevelOuter[2] = 1.0;\n"
10085 " gl_TessLevelOuter[3] = 1.0;\n"
10086 " gl_TessLevelInner[0] = 1.0;\n"
10087 " gl_TessLevelInner[1] = 1.0;\n"
10090 static const GLchar* tes = "#version 430 core\n"
10091 "#extension GL_ARB_enhanced_layouts : require\n"
10093 "layout(isolines, point_mode) in;\n"
10095 "in vec4 tcs_tes[];\n"
10096 "out vec4 tes_gs;\n"
10100 " tes_gs = tcs_tes[0];\n"
10103 static const GLchar* tes_tested = "#version 430 core\n"
10104 "#extension GL_ARB_enhanced_layouts : require\n"
10106 "layout(isolines, point_mode) in;\n"
10108 "layout (std140) uniform Block {\n"
10110 " layout (align = ALIGN) TYPE man;\n"
10113 "in vec4 tcs_tes[];\n"
10114 "out vec4 tes_gs;\n"
10118 " if (TYPE(0) == block.man)\n"
10120 " tes_gs = block.boy;\n"
10123 " tes_gs += tcs_tes[0];\n"
10126 static const GLchar* vs = "#version 430 core\n"
10127 "#extension GL_ARB_enhanced_layouts : require\n"
10130 "out vec4 vs_tcs;\n"
10134 " vs_tcs = in_vs;\n"
10137 static const GLchar* vs_tested = "#version 430 core\n"
10138 "#extension GL_ARB_enhanced_layouts : require\n"
10140 "layout (std140) uniform Block {\n"
10142 " layout (align = ALIGN) TYPE man;\n"
10146 "out vec4 vs_tcs;\n"
10150 " if (TYPE(0) == block.man)\n"
10152 " vs_tcs = block.boy;\n"
10155 " vs_tcs += in_vs;\n"
10159 std::string source;
10160 testCase& test_case = m_test_cases[test_case_index];
10162 if (test_case.m_stage == stage)
10165 const GLuint alignment = test_case.m_alignment;
10166 const Utils::Type& type = test_case.m_type;
10167 const GLchar* type_name = type.GetGLSLTypeName();
10168 size_t position = 0;
10172 case Utils::Shader::COMPUTE:
10175 case Utils::Shader::FRAGMENT:
10176 source = fs_tested;
10178 case Utils::Shader::GEOMETRY:
10179 source = gs_tested;
10181 case Utils::Shader::TESS_CTRL:
10182 source = tcs_tested;
10184 case Utils::Shader::TESS_EVAL:
10185 source = tes_tested;
10187 case Utils::Shader::VERTEX:
10188 source = vs_tested;
10191 TCU_FAIL("Invalid enum");
10194 sprintf(buffer, "%d", alignment);
10195 Utils::replaceToken("ALIGN", position, buffer, source);
10196 Utils::replaceToken("TYPE", position, type_name, source);
10197 Utils::replaceToken("TYPE", position, type_name, source);
10203 case Utils::Shader::FRAGMENT:
10206 case Utils::Shader::GEOMETRY:
10209 case Utils::Shader::TESS_CTRL:
10212 case Utils::Shader::TESS_EVAL:
10215 case Utils::Shader::VERTEX:
10219 TCU_FAIL("Invalid enum");
10226 /** Get description of test case
10228 * @param test_case_index Index of test case
10230 * @return Type name and offset
10232 std::string UniformBlockMemberAlignNonPowerOf2Test::getTestCaseName(GLuint test_case_index)
10234 std::stringstream stream;
10235 testCase& test_case = m_test_cases[test_case_index];
10237 stream << "Type: " << test_case.m_type.GetGLSLTypeName() << ", align: " << test_case.m_alignment;
10239 return stream.str();
10242 /** Get number of test cases
10244 * @return Number of test cases
10246 GLuint UniformBlockMemberAlignNonPowerOf2Test::getTestCaseNumber()
10248 return static_cast<GLuint>(m_test_cases.size());
10251 /** Selects if "compute" stage is relevant for test
10253 * @param test_case_index Index of test case
10255 * @return true when tested stage is compute
10257 bool UniformBlockMemberAlignNonPowerOf2Test::isComputeRelevant(GLuint test_case_index)
10259 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
10262 /** Checks if stage is supported
10268 bool UniformBlockMemberAlignNonPowerOf2Test::isStageSupported(Utils::Shader::STAGES /* stage */)
10273 /** Selects if compilation failure is expected result
10275 * @param test_case_index Index of test case
10277 * @return should_fail field from testCase
10279 bool UniformBlockMemberAlignNonPowerOf2Test::isFailureExpected(GLuint test_case_index)
10281 return m_test_cases[test_case_index].m_should_fail;
10284 /** Prepare all test cases
10287 void UniformBlockMemberAlignNonPowerOf2Test::testInit()
10289 static const GLuint dmat4_size = 128;
10290 const GLuint n_types = getTypesNumber();
10291 bool stage_support[Utils::Shader::STAGE_MAX];
10293 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
10295 stage_support[stage] = isStageSupported((Utils::Shader::STAGES)stage);
10298 for (GLuint j = 0; j < n_types; ++j)
10300 const Utils::Type& type = getType(j);
10302 for (GLuint align = 0; align <= dmat4_size; ++align)
10305 #if WRKARD_UNIFORMBLOCKMEMBERALIGNNONPOWEROF2TEST
10307 const bool should_fail = (0 == align) ? false : !isPowerOf2(align);
10309 #else /* WRKARD_UNIFORMBLOCKMEMBERALIGNNONPOWEROF2TEST */
10311 const bool should_fail = !isPowerOf2(align);
10313 #endif /* WRKARD_UNIFORMBLOCKMEMBERALIGNNONPOWEROF2TEST */
10315 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
10317 if (false == stage_support[stage])
10322 testCase test_case = { align, type, should_fail, (Utils::Shader::STAGES)stage };
10324 m_test_cases.push_back(test_case);
10330 /** Check if value is power of 2
10332 * @param val Tested value
10334 * @return true if val is power of 2, false otherwise
10336 bool UniformBlockMemberAlignNonPowerOf2Test::isPowerOf2(GLuint val)
10343 return (0 == (val & (val - 1)));
10348 * @param context Test framework context
10350 UniformBlockAlignmentTest::UniformBlockAlignmentTest(deqp::Context& context)
10351 : TextureTestBase(context, "uniform_block_alignment", "Test verifies offset and alignment of uniform buffer")
10355 /** Get interface of program
10358 * @param program_interface Interface of program
10359 * @param varying_passthrough Collection of connections between in and out variables
10361 void UniformBlockAlignmentTest::getProgramInterface(GLuint /* test_case_index */,
10362 Utils::ProgramInterface& program_interface,
10363 Utils::VaryingPassthrough& varying_passthrough)
10365 static const Utils::Type vec4 = Utils::Type::vec4;
10367 #if WRKARD_UNIFORMBLOCKALIGNMENT
10369 static const GLuint block_align = 16;
10371 #else /* WRKARD_UNIFORMBLOCKALIGNMENT */
10373 static const GLuint block_align = 64;
10375 #endif /* WRKARD_UNIFORMBLOCKALIGNMENT */
10377 static const GLuint vec4_stride = 16;
10378 static const GLuint data_stride = vec4_stride * 2; /* one vec4 + one scalar aligned to 16 */
10380 /*Fixed a test issue, the fifth_offset should be calculated by block_align, instead of fifth_align, according to spec, the actual
10381 alignment of a member will be the greater of the specified alignment and the base aligment for the member type
10383 const GLuint first_offset = 0; /* vec4 at 0 */
10384 const GLuint second_offset = Utils::Type::GetActualOffset(first_offset + vec4_stride, block_align); /* Data at 32 */
10385 const GLuint third_offset =
10386 Utils::Type::GetActualOffset(second_offset + data_stride, block_align); /* Data[2] at 64 */
10387 const GLuint fourth_offset =
10388 Utils::Type::GetActualOffset(third_offset + data_stride * 2, block_align); /* vec4[3] at 96 */
10389 const GLuint fifth_offset =
10390 Utils::Type::GetActualOffset(fourth_offset + vec4_stride * 3, block_align); /* vec4[2] at 160 */
10391 const GLuint sixth_offset =
10392 Utils::Type::GetActualOffset(fifth_offset + vec4_stride * 2, block_align); /* Data at 192 */
10394 Utils::Interface* structure = program_interface.Structure("Data");
10396 structure->Member("vector", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::vec4,
10397 false /* normalized */, 0 /* n_array_elements */, Utils::Type::vec4.GetSize(), 0 /* offset */);
10399 structure->Member("scalar", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::_float,
10400 false /* normalized */, 0 /* n_array_elements */, Utils::Type::_float.GetSize(),
10401 Utils::Type::vec4.GetSize() /* offset */);
10403 /* Prepare Block */
10404 Utils::Interface* vs_uni_block = program_interface.Block("vs_uni_Block");
10406 vs_uni_block->Member("first", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::vec4,
10407 false /* normalized */, 0 /* n_array_elements */, vec4_stride, first_offset /* offset */);
10409 vs_uni_block->Member("second", "", 0 /* expected_component */, 0 /* expected_location */, structure,
10410 0 /* n_array_elements */, data_stride, second_offset);
10412 vs_uni_block->Member("third", "", 0 /* expected_component */, 0 /* expected_location */, structure,
10413 2 /* n_array_elements */, data_stride, third_offset);
10415 vs_uni_block->Member("fourth", "", 0 /* expected_component */, 0 /* expected_location */, vec4,
10416 false /* normalized */, 3 /* n_array_elements */, vec4_stride, fourth_offset);
10418 vs_uni_block->Member("fifth", "layout(align = 64)", 0 /* expected_component */, 0 /* expected_location */, vec4,
10419 false /* normalized */, 2 /* n_array_elements */, vec4_stride, fifth_offset);
10421 vs_uni_block->Member("sixth", "", 0 /* expected_component */, 0 /* expected_location */, structure,
10422 0 /* n_array_elements */, data_stride, sixth_offset);
10424 const GLuint stride = calculateStride(*vs_uni_block);
10425 m_data.resize(stride);
10426 generateData(*vs_uni_block, 0, m_data);
10428 Utils::ShaderInterface& vs_si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
10430 /* Add uniform BLOCK */
10431 #if WRKARD_UNIFORMBLOCKALIGNMENT
10432 vs_si.Uniform("vs_uni_block", "layout (std140, binding = BINDING)", 0, 0, vs_uni_block, 0,
10433 static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
10434 #else /* WRKARD_UNIFORMBLOCKALIGNMENT */
10435 vs_si.Uniform("vs_uni_block", "layout (std140, binding = BINDING, align = 64)", 0, 0, vs_uni_block, 0,
10436 static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
10437 #endif /* WRKARD_UNIFORMBLOCKALIGNMENT */
10439 program_interface.CloneVertexInterface(varying_passthrough);
10444 * @param context Test framework context
10446 SSBMemberOffsetAndAlignTest::SSBMemberOffsetAndAlignTest(deqp::Context& context)
10447 : TextureTestBase(context, "ssb_member_offset_and_align",
10448 "Test verifies offsets and alignment of storage buffer members")
10452 /** Get interface of program
10454 * @param test_case_index Test case index
10455 * @param program_interface Interface of program
10456 * @param varying_passthrough Collection of connections between in and out variables
10458 void SSBMemberOffsetAndAlignTest::getProgramInterface(GLuint test_case_index,
10459 Utils::ProgramInterface& program_interface,
10460 Utils::VaryingPassthrough& varying_passthrough)
10462 std::string globals = "const int basic_size = BASIC_SIZE;\n"
10463 "const int type_align = TYPE_ALIGN;\n"
10464 "const int type_size = TYPE_SIZE;\n";
10466 Utils::Type type = getType(test_case_index);
10467 GLuint basic_size = Utils::Type::GetTypeSize(type.m_basic_type);
10468 const GLuint base_align = type.GetBaseAlignment(false);
10469 const GLuint array_align = type.GetBaseAlignment(true);
10470 const GLuint base_stride = Utils::Type::CalculateStd140Stride(base_align, type.m_n_columns, 0);
10471 const GLuint type_align = Utils::roundUpToPowerOf2(base_stride);
10473 /* Calculate offsets */
10474 const GLuint first_offset = 0;
10475 const GLuint second_offset = type.GetActualOffset(base_stride, basic_size / 2);
10477 #if WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST
10479 const GLuint third_offset = type.GetActualOffset(second_offset + base_stride, base_align);
10480 const GLuint fourth_offset = type.GetActualOffset(third_offset + base_stride, base_align);
10481 const GLuint fifth_offset = type.GetActualOffset(fourth_offset + base_stride, base_align);
10482 const GLuint sixth_offset = type.GetActualOffset(fifth_offset + base_stride, array_align);
10483 const GLuint seventh_offset = type.GetActualOffset(sixth_offset + base_stride, array_align);
10484 const GLuint eigth_offset = type.GetActualOffset(seventh_offset + base_stride, array_align);
10486 #else /* WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST */
10488 const GLuint third_offset = type.GetActualOffset(second_offset + base_stride, 2 * type_align);
10489 const GLuint fourth_offset = type.GetActualOffset(3 * type_align + base_stride, base_align);
10490 const GLuint fifth_offset = type.GetActualOffset(fourth_offset + base_stride, base_align);
10491 const GLuint sixth_offset = type.GetActualOffset(fifth_offset + base_stride, array_align);
10492 const GLuint seventh_offset = type.GetActualOffset(sixth_offset + base_stride, array_align);
10493 const GLuint eigth_offset = type.GetActualOffset(seventh_offset + base_stride, 8 * basic_size);
10495 #endif /* WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST */
10498 const std::vector<GLubyte>& first = type.GenerateData();
10499 const std::vector<GLubyte>& second = type.GenerateData();
10500 const std::vector<GLubyte>& third = type.GenerateData();
10501 const std::vector<GLubyte>& fourth = type.GenerateData();
10503 m_data.resize(eigth_offset + base_stride);
10504 GLubyte* ptr = &m_data[0];
10505 memcpy(ptr + first_offset, &first[0], first.size());
10506 memcpy(ptr + second_offset, &second[0], second.size());
10507 memcpy(ptr + third_offset, &third[0], third.size());
10508 memcpy(ptr + fourth_offset, &fourth[0], fourth.size());
10509 memcpy(ptr + fifth_offset, &fourth[0], fourth.size());
10510 memcpy(ptr + sixth_offset, &third[0], third.size());
10511 memcpy(ptr + seventh_offset, &second[0], second.size());
10512 memcpy(ptr + eigth_offset, &first[0], first.size());
10514 /* Prepare globals */
10515 size_t position = 0;
10518 sprintf(buffer, "%d", basic_size);
10519 Utils::replaceToken("BASIC_SIZE", position, buffer, globals);
10521 sprintf(buffer, "%d", type_align);
10522 Utils::replaceToken("TYPE_ALIGN", position, buffer, globals);
10524 sprintf(buffer, "%d", base_stride);
10525 Utils::replaceToken("TYPE_SIZE", position, buffer, globals);
10527 /* Prepare Block */
10528 Utils::Interface* vs_buf_block = program_interface.Block("vs_buf_Block");
10530 vs_buf_block->Member("at_first_offset", "layout(offset = 0, align = 8 * basic_size)", 0 /* expected_component */,
10531 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
10534 vs_buf_block->Member("at_second_offset", "layout(offset = type_size, align = basic_size / 2)",
10535 0 /* expected_component */, 0 /* expected_location */, type, false /* normalized */,
10536 0 /* n_array_elements */, base_stride, second_offset);
10538 vs_buf_block->Member("at_third_offset", "layout(align = 2 * type_align)", 0 /* expected_component */,
10539 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
10542 vs_buf_block->Member("at_fourth_offset", "layout(offset = 3 * type_align + type_size)", 0 /* expected_component */,
10543 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
10546 vs_buf_block->Member("at_fifth_offset", "", 0 /* expected_component */, 0 /* expected_location */, type,
10547 false /* normalized */, 0 /* n_array_elements */, base_stride, fifth_offset);
10549 vs_buf_block->Member("at_sixth_offset", "", 0 /* expected_component */, 0 /* expected_location */, type,
10550 false /* normalized */, 2 /* n_array_elements */, array_align * 2, sixth_offset);
10552 vs_buf_block->Member("at_eigth_offset", "layout(align = 8 * basic_size)", 0 /* expected_component */,
10553 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
10556 Utils::ShaderInterface& vs_si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
10559 vs_si.m_globals = globals;
10561 /* Add uniform BLOCK */
10562 vs_si.SSB("vs_buf_block", "layout (std140, binding = BINDING)", 0, 0, vs_buf_block, 0,
10563 static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
10566 program_interface.CloneVertexInterface(varying_passthrough);
10571 * @param test_case_index Index of test case
10573 * @return Name of type test in test_case_index
10575 std::string SSBMemberOffsetAndAlignTest::getTestCaseName(glw::GLuint test_case_index)
10577 return getTypeName(test_case_index);
10580 /** Returns number of types to test
10582 * @return Number of types, 34
10584 glw::GLuint SSBMemberOffsetAndAlignTest::getTestCaseNumber()
10586 return getTypesNumber();
10589 /** Prepare code snippet that will verify in and uniform variables
10593 * @param stage Shader stage
10595 * @return Code that verify variables
10597 std::string SSBMemberOffsetAndAlignTest::getVerificationSnippet(GLuint /* test_case_index */,
10598 Utils::ProgramInterface& /* program_interface */,
10599 Utils::Shader::STAGES stage)
10601 std::string verification = "if ( (PREFIXblock.at_first_offset != PREFIXblock.at_eigth_offset ) ||\n"
10602 " (PREFIXblock.at_second_offset != PREFIXblock.at_sixth_offset[1]) ||\n"
10603 " (PREFIXblock.at_third_offset != PREFIXblock.at_sixth_offset[0]) ||\n"
10604 " (PREFIXblock.at_fourth_offset != PREFIXblock.at_fifth_offset ) )\n"
10609 const GLchar* prefix = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::SSB);
10611 Utils::replaceAllTokens("PREFIX", prefix, verification);
10613 return verification;
10616 /** Selects if "draw" stages are relevant for test
10620 * @return true if all stages support shader storage buffers, false otherwise
10622 bool SSBMemberOffsetAndAlignTest::isDrawRelevant(GLuint /* test_case_index */)
10624 const Functions& gl = m_context.getRenderContext().getFunctions();
10625 GLint gs_supported_buffers = 0;
10626 GLint tcs_supported_buffers = 0;
10627 GLint tes_supported_buffers = 0;
10628 GLint vs_supported_buffers = 0;
10630 gl.getIntegerv(GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS, &gs_supported_buffers);
10631 gl.getIntegerv(GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS, &tcs_supported_buffers);
10632 gl.getIntegerv(GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS, &tes_supported_buffers);
10633 gl.getIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &vs_supported_buffers);
10635 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
10637 return ((1 <= gs_supported_buffers) && (1 <= tcs_supported_buffers) && (1 <= tes_supported_buffers) &&
10638 (1 <= vs_supported_buffers));
10643 * @param context Test framework context
10645 SSBLayoutQualifierConflictTest::SSBLayoutQualifierConflictTest(deqp::Context& context)
10646 : NegativeTestBase(context, "ssb_layout_qualifier_conflict", "Test verifies that std140 or std430 is required when "
10647 "offset and/or align qualifiers are used with storage "
10650 /* Nothing to be done here */
10653 /** Source for given test case and stage
10655 * @param test_case_index Index of test case
10656 * @param stage Shader stage
10658 * @return Shader source
10660 std::string SSBLayoutQualifierConflictTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
10662 static const GLchar* cs = "#version 430 core\n"
10663 "#extension GL_ARB_enhanced_layouts : require\n"
10665 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
10667 "layout (QUALIFIERbinding = BINDING) buffer cs_Block {\n"
10668 " layout(offset = 16) vec4 boy;\n"
10669 " layout(align = 64) vec4 man;\n"
10672 "writeonly uniform image2D uni_image;\n"
10676 " vec4 result = uni_block.boy + uni_block.man;\n"
10678 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
10681 static const GLchar* fs = "#version 430 core\n"
10682 "#extension GL_ARB_enhanced_layouts : require\n"
10684 "layout (QUALIFIERbinding = BINDING) buffer Block {\n"
10685 " layout(offset = 16) vec4 boy;\n"
10686 " layout(align = 64) vec4 man;\n"
10690 "out vec4 fs_out;\n"
10694 " fs_out = gs_fs + uni_block.boy + uni_block.man;\n"
10697 static const GLchar* gs = "#version 430 core\n"
10698 "#extension GL_ARB_enhanced_layouts : require\n"
10700 "layout(points) in;\n"
10701 "layout(triangle_strip, max_vertices = 4) out;\n"
10703 "layout (QUALIFIERbinding = BINDING) buffer gs_Block {\n"
10704 " layout(offset = 16) vec4 boy;\n"
10705 " layout(align = 64) vec4 man;\n"
10708 "in vec4 tes_gs[];\n"
10709 "out vec4 gs_fs;\n"
10713 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
10714 " gl_Position = vec4(-1, -1, 0, 1);\n"
10716 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
10717 " gl_Position = vec4(-1, 1, 0, 1);\n"
10719 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
10720 " gl_Position = vec4(1, -1, 0, 1);\n"
10722 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
10723 " gl_Position = vec4(1, 1, 0, 1);\n"
10727 static const GLchar* tcs =
10728 "#version 430 core\n"
10729 "#extension GL_ARB_enhanced_layouts : require\n"
10731 "layout(vertices = 1) out;\n"
10733 "layout (QUALIFIERbinding = BINDING) buffer tcs_Block {\n"
10734 " layout(offset = 16) vec4 boy;\n"
10735 " layout(align = 64) vec4 man;\n"
10738 "in vec4 vs_tcs[];\n"
10739 "out vec4 tcs_tes[];\n"
10744 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID] + uni_block.boy + uni_block.man;\n"
10746 " gl_TessLevelOuter[0] = 1.0;\n"
10747 " gl_TessLevelOuter[1] = 1.0;\n"
10748 " gl_TessLevelOuter[2] = 1.0;\n"
10749 " gl_TessLevelOuter[3] = 1.0;\n"
10750 " gl_TessLevelInner[0] = 1.0;\n"
10751 " gl_TessLevelInner[1] = 1.0;\n"
10754 static const GLchar* tes = "#version 430 core\n"
10755 "#extension GL_ARB_enhanced_layouts : require\n"
10757 "layout(isolines, point_mode) in;\n"
10759 "layout (QUALIFIERbinding = BINDING) buffer tes_Block {\n"
10760 " layout(offset = 16) vec4 boy;\n"
10761 " layout(align = 64) vec4 man;\n"
10764 "in vec4 tcs_tes[];\n"
10765 "out vec4 tes_gs;\n"
10769 " tes_gs = tcs_tes[0] + uni_block.boy + uni_block.man;\n"
10772 static const GLchar* vs = "#version 430 core\n"
10773 "#extension GL_ARB_enhanced_layouts : require\n"
10775 "layout (QUALIFIERbinding = BINDING) buffer vs_Block {\n"
10776 " layout(offset = 16) vec4 boy;\n"
10777 " layout(align = 64) vec4 man;\n"
10781 "out vec4 vs_tcs;\n"
10785 " vs_tcs = in_vs + uni_block.boy + uni_block.man;\n"
10790 size_t position = 0;
10791 std::string source;
10792 testCase& test_case = m_test_cases[test_case_index];
10793 std::string qualifier = getQualifierName(test_case.m_qualifier);
10795 if (false == qualifier.empty())
10797 qualifier.append(", ");
10800 sprintf(buffer, "%d", stage);
10804 case Utils::Shader::COMPUTE:
10807 case Utils::Shader::FRAGMENT:
10810 case Utils::Shader::GEOMETRY:
10813 case Utils::Shader::TESS_CTRL:
10816 case Utils::Shader::TESS_EVAL:
10819 case Utils::Shader::VERTEX:
10823 TCU_FAIL("Invalid enum");
10826 if (test_case.m_stage == stage)
10828 Utils::replaceToken("QUALIFIER", position, qualifier.c_str(), source);
10832 Utils::replaceToken("QUALIFIER", position, "std140, ", source);
10835 Utils::replaceToken("BINDING", position, buffer, source);
10840 /** Get description of test case
10842 * @param test_case_index Index of test case
10844 * @return Qualifier name
10846 std::string SSBLayoutQualifierConflictTest::getTestCaseName(GLuint test_case_index)
10848 std::string result = getQualifierName(m_test_cases[test_case_index].m_qualifier);
10853 /** Get number of test cases
10855 * @return Number of test cases
10857 GLuint SSBLayoutQualifierConflictTest::getTestCaseNumber()
10859 return static_cast<GLuint>(m_test_cases.size());
10862 /** Selects if "compute" stage is relevant for test
10864 * @param test_case_index Index of test case
10866 * @return true when tested stage is compute
10868 bool SSBLayoutQualifierConflictTest::isComputeRelevant(GLuint test_case_index)
10870 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
10873 /** Selects if compilation failure is expected result
10875 * @param test_case_index Index of test case
10877 * @return false for STD140 and STD430 cases, true otherwise
10879 bool SSBLayoutQualifierConflictTest::isFailureExpected(GLuint test_case_index)
10881 const QUALIFIERS qualifier = m_test_cases[test_case_index].m_qualifier;
10883 return !((STD140 == qualifier) || (STD430 == qualifier));
10886 /** Checks if stage is supported
10888 * @param stage Shader stage
10890 * @return true if supported, false otherwise
10892 bool SSBLayoutQualifierConflictTest::isStageSupported(Utils::Shader::STAGES stage)
10894 const Functions& gl = m_context.getRenderContext().getFunctions();
10895 GLint max_supported_buffers = 0;
10900 case Utils::Shader::COMPUTE:
10901 pname = GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS;
10903 case Utils::Shader::FRAGMENT:
10904 pname = GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS;
10906 case Utils::Shader::GEOMETRY:
10907 pname = GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS;
10909 case Utils::Shader::TESS_CTRL:
10910 pname = GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS;
10912 case Utils::Shader::TESS_EVAL:
10913 pname = GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS;
10915 case Utils::Shader::VERTEX:
10916 pname = GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS;
10919 TCU_FAIL("Invalid enum");
10922 gl.getIntegerv(pname, &max_supported_buffers);
10923 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
10925 return 1 <= max_supported_buffers;
10928 /** Prepare all test cases
10931 void SSBLayoutQualifierConflictTest::testInit()
10933 bool stage_support[Utils::Shader::STAGE_MAX];
10935 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
10937 stage_support[stage] = isStageSupported((Utils::Shader::STAGES)stage);
10940 for (GLuint qualifier = 0; qualifier < QUALIFIERS_MAX; ++qualifier)
10942 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
10944 if (false == stage_support[stage])
10949 testCase test_case = { (QUALIFIERS)qualifier, (Utils::Shader::STAGES)stage };
10951 m_test_cases.push_back(test_case);
10956 /** Get name of glsl constant
10958 * @param Constant id
10960 * @return Name of constant used in GLSL
10962 const GLchar* SSBLayoutQualifierConflictTest::getQualifierName(QUALIFIERS qualifier)
10964 const GLchar* name = "";
10984 TCU_FAIL("Invalid enum");
10992 * @param context Test framework context
10994 SSBMemberInvalidOffsetAlignmentTest::SSBMemberInvalidOffsetAlignmentTest(deqp::Context& context)
10995 : UniformBlockMemberInvalidOffsetAlignmentTest(
10996 context, "ssb_member_invalid_offset_alignment",
10997 "Test verifies that invalid alignment of offset qualifiers cause compilation failure")
10999 /* Nothing to be done here */
11002 /** Source for given test case and stage
11004 * @param test_case_index Index of test case
11005 * @param stage Shader stage
11007 * @return Shader source
11009 std::string SSBMemberInvalidOffsetAlignmentTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
11011 static const GLchar* cs = "#version 430 core\n"
11012 "#extension GL_ARB_enhanced_layouts : require\n"
11014 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
11016 "layout (std140) buffer Block {\n"
11017 " layout (offset = OFFSET) TYPE member;\n"
11020 "writeonly uniform image2D uni_image;\n"
11024 " vec4 result = vec4(1, 0, 0.5, 1);\n"
11026 " if (TYPE(1) == block.member)\n"
11028 " result = vec4(1, 1, 1, 1);\n"
11031 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
11034 static const GLchar* fs = "#version 430 core\n"
11035 "#extension GL_ARB_enhanced_layouts : require\n"
11038 "out vec4 fs_out;\n"
11042 " fs_out = gs_fs;\n"
11045 static const GLchar* fs_tested = "#version 430 core\n"
11046 "#extension GL_ARB_enhanced_layouts : require\n"
11048 "layout (std140) buffer Block {\n"
11049 " layout (offset = OFFSET) TYPE member;\n"
11053 "out vec4 fs_out;\n"
11057 " if (TYPE(1) == block.member)\n"
11059 " fs_out = vec4(1, 1, 1, 1);\n"
11062 " fs_out += gs_fs;\n"
11065 static const GLchar* gs = "#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 "in vec4 tes_gs[];\n"
11072 "out vec4 gs_fs;\n"
11076 " gs_fs = tes_gs[0];\n"
11077 " gl_Position = vec4(-1, -1, 0, 1);\n"
11079 " gs_fs = tes_gs[0];\n"
11080 " gl_Position = vec4(-1, 1, 0, 1);\n"
11082 " gs_fs = tes_gs[0];\n"
11083 " gl_Position = vec4(1, -1, 0, 1);\n"
11085 " gs_fs = tes_gs[0];\n"
11086 " gl_Position = vec4(1, 1, 0, 1);\n"
11090 static const GLchar* gs_tested = "#version 430 core\n"
11091 "#extension GL_ARB_enhanced_layouts : require\n"
11093 "layout(points) in;\n"
11094 "layout(triangle_strip, max_vertices = 4) out;\n"
11096 "layout (std140) buffer Block {\n"
11097 " layout (offset = OFFSET) TYPE member;\n"
11100 "in vec4 tes_gs[];\n"
11101 "out vec4 gs_fs;\n"
11105 " if (TYPE(1) == block.member)\n"
11107 " gs_fs = vec4(1, 1, 1, 1);\n"
11110 " gs_fs += tes_gs[0];\n"
11111 " gl_Position = vec4(-1, -1, 0, 1);\n"
11113 " gs_fs += tes_gs[0];\n"
11114 " gl_Position = vec4(-1, 1, 0, 1);\n"
11116 " gs_fs += tes_gs[0];\n"
11117 " gl_Position = vec4(1, -1, 0, 1);\n"
11119 " gs_fs += tes_gs[0];\n"
11120 " gl_Position = vec4(1, 1, 0, 1);\n"
11124 static const GLchar* tcs = "#version 430 core\n"
11125 "#extension GL_ARB_enhanced_layouts : require\n"
11127 "layout(vertices = 1) out;\n"
11129 "in vec4 vs_tcs[];\n"
11130 "out vec4 tcs_tes[];\n"
11135 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
11137 " gl_TessLevelOuter[0] = 1.0;\n"
11138 " gl_TessLevelOuter[1] = 1.0;\n"
11139 " gl_TessLevelOuter[2] = 1.0;\n"
11140 " gl_TessLevelOuter[3] = 1.0;\n"
11141 " gl_TessLevelInner[0] = 1.0;\n"
11142 " gl_TessLevelInner[1] = 1.0;\n"
11145 static const GLchar* tcs_tested = "#version 430 core\n"
11146 "#extension GL_ARB_enhanced_layouts : require\n"
11148 "layout(vertices = 1) out;\n"
11150 "layout (std140) buffer Block {\n"
11151 " layout (offset = OFFSET) TYPE member;\n"
11154 "in vec4 vs_tcs[];\n"
11155 "out vec4 tcs_tes[];\n"
11159 " if (TYPE(1) == block.member)\n"
11161 " tcs_tes[gl_InvocationID] = vec4(1, 1, 1, 1);\n"
11165 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
11167 " gl_TessLevelOuter[0] = 1.0;\n"
11168 " gl_TessLevelOuter[1] = 1.0;\n"
11169 " gl_TessLevelOuter[2] = 1.0;\n"
11170 " gl_TessLevelOuter[3] = 1.0;\n"
11171 " gl_TessLevelInner[0] = 1.0;\n"
11172 " gl_TessLevelInner[1] = 1.0;\n"
11175 static const GLchar* tes = "#version 430 core\n"
11176 "#extension GL_ARB_enhanced_layouts : require\n"
11178 "layout(isolines, point_mode) in;\n"
11180 "in vec4 tcs_tes[];\n"
11181 "out vec4 tes_gs;\n"
11185 " tes_gs = tcs_tes[0];\n"
11188 static const GLchar* tes_tested = "#version 430 core\n"
11189 "#extension GL_ARB_enhanced_layouts : require\n"
11191 "layout(isolines, point_mode) in;\n"
11193 "layout (std140) buffer Block {\n"
11194 " layout (offset = OFFSET) TYPE member;\n"
11197 "in vec4 tcs_tes[];\n"
11198 "out vec4 tes_gs;\n"
11202 " if (TYPE(1) == block.member)\n"
11204 " tes_gs = vec4(1, 1, 1, 1);\n"
11207 " tes_gs += tcs_tes[0];\n"
11210 static const GLchar* vs = "#version 430 core\n"
11211 "#extension GL_ARB_enhanced_layouts : require\n"
11214 "out vec4 vs_tcs;\n"
11218 " vs_tcs = in_vs;\n"
11221 static const GLchar* vs_tested = "#version 430 core\n"
11222 "#extension GL_ARB_enhanced_layouts : require\n"
11224 "layout (std140) buffer Block {\n"
11225 " layout (offset = OFFSET) TYPE member;\n"
11229 "out vec4 vs_tcs;\n"
11233 " if (TYPE(1) == block.member)\n"
11235 " vs_tcs = vec4(1, 1, 1, 1);\n"
11238 " vs_tcs += in_vs;\n"
11242 std::string source;
11243 testCase& test_case = m_test_cases[test_case_index];
11245 if (test_case.m_stage == stage)
11248 const GLuint offset = test_case.m_offset;
11249 size_t position = 0;
11250 const Utils::Type& type = test_case.m_type;
11251 const GLchar* type_name = type.GetGLSLTypeName();
11253 sprintf(buffer, "%d", offset);
11257 case Utils::Shader::COMPUTE:
11260 case Utils::Shader::FRAGMENT:
11261 source = fs_tested;
11263 case Utils::Shader::GEOMETRY:
11264 source = gs_tested;
11266 case Utils::Shader::TESS_CTRL:
11267 source = tcs_tested;
11269 case Utils::Shader::TESS_EVAL:
11270 source = tes_tested;
11272 case Utils::Shader::VERTEX:
11273 source = vs_tested;
11276 TCU_FAIL("Invalid enum");
11279 Utils::replaceToken("OFFSET", position, buffer, source);
11280 Utils::replaceToken("TYPE", position, type_name, source);
11281 Utils::replaceToken("TYPE", position, type_name, source);
11287 case Utils::Shader::FRAGMENT:
11290 case Utils::Shader::GEOMETRY:
11293 case Utils::Shader::TESS_CTRL:
11296 case Utils::Shader::TESS_EVAL:
11299 case Utils::Shader::VERTEX:
11303 TCU_FAIL("Invalid enum");
11310 /** Checks if stage is supported
11312 * @param stage Shader stage
11314 * @return true if supported, false otherwise
11316 bool SSBMemberInvalidOffsetAlignmentTest::isStageSupported(Utils::Shader::STAGES stage)
11318 const Functions& gl = m_context.getRenderContext().getFunctions();
11319 GLint max_supported_buffers = 0;
11324 case Utils::Shader::COMPUTE:
11325 pname = GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS;
11327 case Utils::Shader::FRAGMENT:
11328 pname = GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS;
11330 case Utils::Shader::GEOMETRY:
11331 pname = GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS;
11333 case Utils::Shader::TESS_CTRL:
11334 pname = GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS;
11336 case Utils::Shader::TESS_EVAL:
11337 pname = GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS;
11339 case Utils::Shader::VERTEX:
11340 pname = GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS;
11343 TCU_FAIL("Invalid enum");
11346 gl.getIntegerv(pname, &max_supported_buffers);
11347 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
11349 return 1 <= max_supported_buffers;
11354 * @param context Test framework context
11356 SSBMemberOverlappingOffsetsTest::SSBMemberOverlappingOffsetsTest(deqp::Context& context)
11357 : UniformBlockMemberOverlappingOffsetsTest(
11358 context, "ssb_member_overlapping_offsets",
11359 "Test verifies that overlapping offsets qualifiers cause compilation failure")
11361 /* Nothing to be done here */
11364 /** Source for given test case and stage
11366 * @param test_case_index Index of test case
11367 * @param stage Shader stage
11369 * @return Shader source
11371 std::string SSBMemberOverlappingOffsetsTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
11373 static const GLchar* cs = "#version 430 core\n"
11374 "#extension GL_ARB_enhanced_layouts : require\n"
11376 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
11378 "layout (std140) buffer Block {\n"
11379 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11380 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11383 "writeonly uniform image2D uni_image;\n"
11387 " vec4 result = vec4(1, 0, 0.5, 1);\n"
11389 " if ((BOY_TYPE(1) == block.boy) ||\n"
11390 " (MAN_TYPE(0) == block.man) )\n"
11392 " result = vec4(1, 1, 1, 1);\n"
11395 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
11398 static const GLchar* fs = "#version 430 core\n"
11399 "#extension GL_ARB_enhanced_layouts : require\n"
11402 "out vec4 fs_out;\n"
11406 " fs_out = gs_fs;\n"
11409 static const GLchar* fs_tested = "#version 430 core\n"
11410 "#extension GL_ARB_enhanced_layouts : require\n"
11412 "layout (std140) buffer Block {\n"
11413 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11414 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11418 "out vec4 fs_out;\n"
11422 " if ((BOY_TYPE(1) == block.boy) ||\n"
11423 " (MAN_TYPE(0) == block.man) )\n"
11425 " fs_out = vec4(1, 1, 1, 1);\n"
11428 " fs_out += gs_fs;\n"
11431 static const GLchar* gs = "#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 "in vec4 tes_gs[];\n"
11438 "out vec4 gs_fs;\n"
11442 " gs_fs = tes_gs[0];\n"
11443 " gl_Position = vec4(-1, -1, 0, 1);\n"
11445 " gs_fs = tes_gs[0];\n"
11446 " gl_Position = vec4(-1, 1, 0, 1);\n"
11448 " gs_fs = tes_gs[0];\n"
11449 " gl_Position = vec4(1, -1, 0, 1);\n"
11451 " gs_fs = tes_gs[0];\n"
11452 " gl_Position = vec4(1, 1, 0, 1);\n"
11456 static const GLchar* gs_tested = "#version 430 core\n"
11457 "#extension GL_ARB_enhanced_layouts : require\n"
11459 "layout(points) in;\n"
11460 "layout(triangle_strip, max_vertices = 4) out;\n"
11462 "layout (std140) buffer Block {\n"
11463 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11464 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11467 "in vec4 tes_gs[];\n"
11468 "out vec4 gs_fs;\n"
11472 " if ((BOY_TYPE(1) == block.boy) ||\n"
11473 " (MAN_TYPE(0) == block.man) )\n"
11475 " gs_fs = vec4(1, 1, 1, 1);\n"
11478 " gs_fs += tes_gs[0];\n"
11479 " gl_Position = vec4(-1, -1, 0, 1);\n"
11481 " gs_fs += tes_gs[0];\n"
11482 " gl_Position = vec4(-1, 1, 0, 1);\n"
11484 " gs_fs += tes_gs[0];\n"
11485 " gl_Position = vec4(1, -1, 0, 1);\n"
11487 " gs_fs += tes_gs[0];\n"
11488 " gl_Position = vec4(1, 1, 0, 1);\n"
11492 static const GLchar* tcs = "#version 430 core\n"
11493 "#extension GL_ARB_enhanced_layouts : require\n"
11495 "layout(vertices = 1) out;\n"
11497 "in vec4 vs_tcs[];\n"
11498 "out vec4 tcs_tes[];\n"
11503 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
11505 " gl_TessLevelOuter[0] = 1.0;\n"
11506 " gl_TessLevelOuter[1] = 1.0;\n"
11507 " gl_TessLevelOuter[2] = 1.0;\n"
11508 " gl_TessLevelOuter[3] = 1.0;\n"
11509 " gl_TessLevelInner[0] = 1.0;\n"
11510 " gl_TessLevelInner[1] = 1.0;\n"
11513 static const GLchar* tcs_tested = "#version 430 core\n"
11514 "#extension GL_ARB_enhanced_layouts : require\n"
11516 "layout(vertices = 1) out;\n"
11518 "layout (std140) buffer Block {\n"
11519 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11520 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11523 "in vec4 vs_tcs[];\n"
11524 "out vec4 tcs_tes[];\n"
11528 " if ((BOY_TYPE(1) == block.boy) ||\n"
11529 " (MAN_TYPE(0) == block.man) )\n"
11531 " tcs_tes[gl_InvocationID] = vec4(1, 1, 1, 1);\n"
11535 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
11537 " gl_TessLevelOuter[0] = 1.0;\n"
11538 " gl_TessLevelOuter[1] = 1.0;\n"
11539 " gl_TessLevelOuter[2] = 1.0;\n"
11540 " gl_TessLevelOuter[3] = 1.0;\n"
11541 " gl_TessLevelInner[0] = 1.0;\n"
11542 " gl_TessLevelInner[1] = 1.0;\n"
11545 static const GLchar* tes = "#version 430 core\n"
11546 "#extension GL_ARB_enhanced_layouts : require\n"
11548 "layout(isolines, point_mode) in;\n"
11550 "in vec4 tcs_tes[];\n"
11551 "out vec4 tes_gs;\n"
11555 " tes_gs = tcs_tes[0];\n"
11558 static const GLchar* tes_tested = "#version 430 core\n"
11559 "#extension GL_ARB_enhanced_layouts : require\n"
11561 "layout(isolines, point_mode) in;\n"
11563 "layout (std140) buffer Block {\n"
11564 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11565 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11568 "in vec4 tcs_tes[];\n"
11569 "out vec4 tes_gs;\n"
11573 " if ((BOY_TYPE(1) == block.boy) ||\n"
11574 " (MAN_TYPE(0) == block.man) )\n"
11576 " tes_gs = vec4(1, 1, 1, 1);\n"
11579 " tes_gs += tcs_tes[0];\n"
11582 static const GLchar* vs = "#version 430 core\n"
11583 "#extension GL_ARB_enhanced_layouts : require\n"
11586 "out vec4 vs_tcs;\n"
11590 " vs_tcs = in_vs;\n"
11593 static const GLchar* vs_tested = "#version 430 core\n"
11594 "#extension GL_ARB_enhanced_layouts : require\n"
11596 "layout (std140) buffer Block {\n"
11597 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11598 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11602 "out vec4 vs_tcs;\n"
11606 " if ((BOY_TYPE(1) == block.boy) ||\n"
11607 " (MAN_TYPE(0) == block.man) )\n"
11609 " vs_tcs = vec4(1, 1, 1, 1);\n"
11612 " vs_tcs += in_vs;\n"
11616 std::string source;
11617 testCase& test_case = m_test_cases[test_case_index];
11619 if (test_case.m_stage == stage)
11622 const GLuint boy_offset = test_case.m_boy_offset;
11623 const Utils::Type& boy_type = test_case.m_boy_type;
11624 const GLchar* boy_type_name = boy_type.GetGLSLTypeName();
11625 const GLuint man_offset = test_case.m_man_offset;
11626 const Utils::Type& man_type = test_case.m_man_type;
11627 const GLchar* man_type_name = man_type.GetGLSLTypeName();
11628 size_t position = 0;
11632 case Utils::Shader::COMPUTE:
11635 case Utils::Shader::FRAGMENT:
11636 source = fs_tested;
11638 case Utils::Shader::GEOMETRY:
11639 source = gs_tested;
11641 case Utils::Shader::TESS_CTRL:
11642 source = tcs_tested;
11644 case Utils::Shader::TESS_EVAL:
11645 source = tes_tested;
11647 case Utils::Shader::VERTEX:
11648 source = vs_tested;
11651 TCU_FAIL("Invalid enum");
11654 sprintf(buffer, "%d", boy_offset);
11655 Utils::replaceToken("BOY_OFFSET", position, buffer, source);
11656 Utils::replaceToken("BOY_TYPE", position, boy_type_name, source);
11657 sprintf(buffer, "%d", man_offset);
11658 Utils::replaceToken("MAN_OFFSET", position, buffer, source);
11659 Utils::replaceToken("MAN_TYPE", position, man_type_name, source);
11660 Utils::replaceToken("BOY_TYPE", position, boy_type_name, source);
11661 Utils::replaceToken("MAN_TYPE", position, man_type_name, source);
11667 case Utils::Shader::FRAGMENT:
11670 case Utils::Shader::GEOMETRY:
11673 case Utils::Shader::TESS_CTRL:
11676 case Utils::Shader::TESS_EVAL:
11679 case Utils::Shader::VERTEX:
11683 TCU_FAIL("Invalid enum");
11690 /** Checks if stage is supported
11692 * @param stage Shader stage
11694 * @return true if supported, false otherwise
11696 bool SSBMemberOverlappingOffsetsTest::isStageSupported(Utils::Shader::STAGES stage)
11698 const Functions& gl = m_context.getRenderContext().getFunctions();
11699 GLint max_supported_buffers = 0;
11704 case Utils::Shader::COMPUTE:
11705 pname = GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS;
11707 case Utils::Shader::FRAGMENT:
11708 pname = GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS;
11710 case Utils::Shader::GEOMETRY:
11711 pname = GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS;
11713 case Utils::Shader::TESS_CTRL:
11714 pname = GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS;
11716 case Utils::Shader::TESS_EVAL:
11717 pname = GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS;
11719 case Utils::Shader::VERTEX:
11720 pname = GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS;
11723 TCU_FAIL("Invalid enum");
11726 gl.getIntegerv(pname, &max_supported_buffers);
11727 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
11729 return 1 <= max_supported_buffers;
11734 * @param context Test framework context
11736 SSBMemberAlignNonPowerOf2Test::SSBMemberAlignNonPowerOf2Test(deqp::Context& context)
11737 : UniformBlockMemberAlignNonPowerOf2Test(context, "ssb_member_align_non_power_of_2",
11738 "Test verifies that align qualifier requires value that is a power of 2")
11740 /* Nothing to be done here */
11743 /** Source for given test case and stage
11745 * @param test_case_index Index of test case
11746 * @param stage Shader stage
11748 * @return Shader source
11750 std::string SSBMemberAlignNonPowerOf2Test::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
11752 static const GLchar* cs = "#version 430 core\n"
11753 "#extension GL_ARB_enhanced_layouts : require\n"
11755 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
11757 "layout (std140) buffer Block {\n"
11759 " layout (align = ALIGN) TYPE man;\n"
11762 "writeonly uniform image2D uni_image;\n"
11766 " vec4 result = vec4(1, 0, 0.5, 1);\n"
11768 " if (TYPE(0) == block.man)\n"
11770 " result = vec4(1, 1, 1, 1) - block.boy;\n"
11773 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
11776 static const GLchar* fs = "#version 430 core\n"
11777 "#extension GL_ARB_enhanced_layouts : require\n"
11780 "out vec4 fs_out;\n"
11784 " fs_out = gs_fs;\n"
11787 static const GLchar* fs_tested = "#version 430 core\n"
11788 "#extension GL_ARB_enhanced_layouts : require\n"
11790 "layout (std140) buffer Block {\n"
11792 " layout (align = ALIGN) TYPE man;\n"
11796 "out vec4 fs_out;\n"
11800 " if (TYPE(0) == block.man)\n"
11802 " fs_out = block.boy;\n"
11805 " fs_out += gs_fs;\n"
11808 static const GLchar* gs = "#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 "in vec4 tes_gs[];\n"
11815 "out vec4 gs_fs;\n"
11819 " gs_fs = tes_gs[0];\n"
11820 " gl_Position = vec4(-1, -1, 0, 1);\n"
11822 " gs_fs = tes_gs[0];\n"
11823 " gl_Position = vec4(-1, 1, 0, 1);\n"
11825 " gs_fs = tes_gs[0];\n"
11826 " gl_Position = vec4(1, -1, 0, 1);\n"
11828 " gs_fs = tes_gs[0];\n"
11829 " gl_Position = vec4(1, 1, 0, 1);\n"
11833 static const GLchar* gs_tested = "#version 430 core\n"
11834 "#extension GL_ARB_enhanced_layouts : require\n"
11836 "layout(points) in;\n"
11837 "layout(triangle_strip, max_vertices = 4) out;\n"
11839 "layout (std140) buffer Block {\n"
11841 " layout (align = ALIGN) TYPE man;\n"
11844 "in vec4 tes_gs[];\n"
11845 "out vec4 gs_fs;\n"
11849 " if (TYPE(0) == block.man)\n"
11851 " gs_fs = block.boy;\n"
11854 " gs_fs += tes_gs[0];\n"
11855 " gl_Position = vec4(-1, -1, 0, 1);\n"
11857 " gs_fs += tes_gs[0];\n"
11858 " gl_Position = vec4(-1, 1, 0, 1);\n"
11860 " gs_fs += tes_gs[0];\n"
11861 " gl_Position = vec4(1, -1, 0, 1);\n"
11863 " gs_fs += tes_gs[0];\n"
11864 " gl_Position = vec4(1, 1, 0, 1);\n"
11868 static const GLchar* tcs = "#version 430 core\n"
11869 "#extension GL_ARB_enhanced_layouts : require\n"
11871 "layout(vertices = 1) out;\n"
11873 "in vec4 vs_tcs[];\n"
11874 "out vec4 tcs_tes[];\n"
11879 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
11881 " gl_TessLevelOuter[0] = 1.0;\n"
11882 " gl_TessLevelOuter[1] = 1.0;\n"
11883 " gl_TessLevelOuter[2] = 1.0;\n"
11884 " gl_TessLevelOuter[3] = 1.0;\n"
11885 " gl_TessLevelInner[0] = 1.0;\n"
11886 " gl_TessLevelInner[1] = 1.0;\n"
11889 static const GLchar* tcs_tested = "#version 430 core\n"
11890 "#extension GL_ARB_enhanced_layouts : require\n"
11892 "layout(vertices = 1) out;\n"
11894 "layout (std140) buffer Block {\n"
11896 " layout (align = ALIGN) TYPE man;\n"
11899 "in vec4 vs_tcs[];\n"
11900 "out vec4 tcs_tes[];\n"
11904 " if (TYPE(0) == block.man)\n"
11906 " tcs_tes[gl_InvocationID] = block.boy;\n"
11910 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
11912 " gl_TessLevelOuter[0] = 1.0;\n"
11913 " gl_TessLevelOuter[1] = 1.0;\n"
11914 " gl_TessLevelOuter[2] = 1.0;\n"
11915 " gl_TessLevelOuter[3] = 1.0;\n"
11916 " gl_TessLevelInner[0] = 1.0;\n"
11917 " gl_TessLevelInner[1] = 1.0;\n"
11920 static const GLchar* tes = "#version 430 core\n"
11921 "#extension GL_ARB_enhanced_layouts : require\n"
11923 "layout(isolines, point_mode) in;\n"
11925 "in vec4 tcs_tes[];\n"
11926 "out vec4 tes_gs;\n"
11930 " tes_gs = tcs_tes[0];\n"
11933 static const GLchar* tes_tested = "#version 430 core\n"
11934 "#extension GL_ARB_enhanced_layouts : require\n"
11936 "layout(isolines, point_mode) in;\n"
11938 "layout (std140) buffer Block {\n"
11940 " layout (align = ALIGN) TYPE man;\n"
11943 "in vec4 tcs_tes[];\n"
11944 "out vec4 tes_gs;\n"
11948 " if (TYPE(0) == block.man)\n"
11950 " tes_gs = block.boy;\n"
11953 " tes_gs += tcs_tes[0];\n"
11956 static const GLchar* vs = "#version 430 core\n"
11957 "#extension GL_ARB_enhanced_layouts : require\n"
11960 "out vec4 vs_tcs;\n"
11964 " vs_tcs = in_vs;\n"
11967 static const GLchar* vs_tested = "#version 430 core\n"
11968 "#extension GL_ARB_enhanced_layouts : require\n"
11970 "layout (std140) buffer Block {\n"
11972 " layout (align = ALIGN) TYPE man;\n"
11976 "out vec4 vs_tcs;\n"
11980 " if (TYPE(0) == block.man)\n"
11982 " vs_tcs = block.boy;\n"
11985 " vs_tcs += in_vs;\n"
11989 std::string source;
11990 testCase& test_case = m_test_cases[test_case_index];
11992 if (test_case.m_stage == stage)
11995 const GLuint alignment = test_case.m_alignment;
11996 const Utils::Type& type = test_case.m_type;
11997 const GLchar* type_name = type.GetGLSLTypeName();
11998 size_t position = 0;
12002 case Utils::Shader::COMPUTE:
12005 case Utils::Shader::FRAGMENT:
12006 source = fs_tested;
12008 case Utils::Shader::GEOMETRY:
12009 source = gs_tested;
12011 case Utils::Shader::TESS_CTRL:
12012 source = tcs_tested;
12014 case Utils::Shader::TESS_EVAL:
12015 source = tes_tested;
12017 case Utils::Shader::VERTEX:
12018 source = vs_tested;
12021 TCU_FAIL("Invalid enum");
12024 sprintf(buffer, "%d", alignment);
12025 Utils::replaceToken("ALIGN", position, buffer, source);
12026 Utils::replaceToken("TYPE", position, type_name, source);
12027 Utils::replaceToken("TYPE", position, type_name, source);
12033 case Utils::Shader::FRAGMENT:
12036 case Utils::Shader::GEOMETRY:
12039 case Utils::Shader::TESS_CTRL:
12042 case Utils::Shader::TESS_EVAL:
12045 case Utils::Shader::VERTEX:
12049 TCU_FAIL("Invalid enum");
12056 /** Checks if stage is supported
12058 * @param stage Shader stage
12060 * @return true if supported, false otherwise
12062 bool SSBMemberAlignNonPowerOf2Test::isStageSupported(Utils::Shader::STAGES stage)
12064 const Functions& gl = m_context.getRenderContext().getFunctions();
12065 GLint max_supported_buffers = 0;
12070 case Utils::Shader::COMPUTE:
12071 pname = GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS;
12073 case Utils::Shader::FRAGMENT:
12074 pname = GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS;
12076 case Utils::Shader::GEOMETRY:
12077 pname = GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS;
12079 case Utils::Shader::TESS_CTRL:
12080 pname = GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS;
12082 case Utils::Shader::TESS_EVAL:
12083 pname = GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS;
12085 case Utils::Shader::VERTEX:
12086 pname = GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS;
12089 TCU_FAIL("Invalid enum");
12092 gl.getIntegerv(pname, &max_supported_buffers);
12093 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
12095 return 1 <= max_supported_buffers;
12100 * @param context Test framework context
12102 SSBAlignmentTest::SSBAlignmentTest(deqp::Context& context)
12103 : TextureTestBase(context, "ssb_alignment", "Test verifies offset and alignment of ssb buffer")
12107 /** Get interface of program
12110 * @param program_interface Interface of program
12111 * @param varying_passthrough Collection of connections between in and out variables
12113 void SSBAlignmentTest::getProgramInterface(GLuint /* test_case_index */, Utils::ProgramInterface& program_interface,
12114 Utils::VaryingPassthrough& varying_passthrough)
12116 static const Utils::Type vec4 = Utils::Type::vec4;
12118 #if WRKARD_UNIFORMBLOCKALIGNMENT
12120 static const GLuint block_align = 16;
12122 #else /* WRKARD_UNIFORMBLOCKALIGNMENT */
12124 static const GLuint block_align = 64;
12126 #endif /* WRKARD_UNIFORMBLOCKALIGNMENT */
12128 static const GLuint fifth_align = 16;
12129 static const GLuint vec4_stride = 16;
12130 static const GLuint data_stride = vec4_stride * 2; /* one vec4 + one scalar aligned to 16 */
12132 const GLuint first_offset = 0; /* vec4 at 0 */
12133 const GLuint second_offset = Utils::Type::GetActualOffset(first_offset + vec4_stride, block_align); /* Data at 32 */
12134 const GLuint third_offset =
12135 Utils::Type::GetActualOffset(second_offset + data_stride, block_align); /* Data[2] at 64 */
12136 const GLuint fourth_offset =
12137 Utils::Type::GetActualOffset(third_offset + data_stride * 2, block_align); /* vec4[3] at 96 */
12138 const GLuint fifth_offset =
12139 Utils::Type::GetActualOffset(fourth_offset + vec4_stride * 3, fifth_align); /* vec4[2] at 160 */
12140 const GLuint sixth_offset =
12141 Utils::Type::GetActualOffset(fifth_offset + vec4_stride * 2, block_align); /* Data at 192 */
12143 Utils::Interface* structure = program_interface.Structure("Data");
12145 structure->Member("vector", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::vec4,
12146 false /* normalized */, 0 /* n_array_elements */, Utils::Type::vec4.GetSize(), 0 /* offset */);
12148 structure->Member("scalar", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::_float,
12149 false /* normalized */, 0 /* n_array_elements */, Utils::Type::_float.GetSize(),
12150 Utils::Type::vec4.GetSize() /* offset */);
12152 /* Prepare Block */
12153 Utils::Interface* vs_buf_Block = program_interface.Block("vs_buf_Block");
12155 vs_buf_Block->Member("first", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::vec4,
12156 false /* normalized */, 0 /* n_array_elements */, vec4_stride, first_offset /* offset */);
12158 vs_buf_Block->Member("second", "", 0 /* expected_component */, 0 /* expected_location */, structure,
12159 0 /* n_array_elements */, data_stride, second_offset);
12161 vs_buf_Block->Member("third", "", 0 /* expected_component */, 0 /* expected_location */, structure,
12162 2 /* n_array_elements */, data_stride, third_offset);
12164 vs_buf_Block->Member("fourth", "", 0 /* expected_component */, 0 /* expected_location */, vec4,
12165 false /* normalized */, 3 /* n_array_elements */, vec4_stride, fourth_offset);
12167 vs_buf_Block->Member("fifth", "layout(align = 16)", 0 /* expected_component */, 0 /* expected_location */, vec4,
12168 false /* normalized */, 2 /* n_array_elements */, vec4_stride, fifth_offset);
12170 vs_buf_Block->Member("sixth", "", 0 /* expected_component */, 0 /* expected_location */, structure,
12171 0 /* n_array_elements */, data_stride, sixth_offset);
12173 const GLuint stride = calculateStride(*vs_buf_Block);
12174 m_data.resize(stride);
12175 generateData(*vs_buf_Block, 0, m_data);
12177 Utils::ShaderInterface& vs_si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
12179 /* Add uniform BLOCK */
12180 #if WRKARD_UNIFORMBLOCKALIGNMENT
12181 vs_si.SSB("vs_buf_block", "layout (std140, binding = BINDING)", 0, 0, vs_buf_Block, 0,
12182 static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
12183 #else /* WRKARD_UNIFORMBLOCKALIGNMENT */
12184 vs_si.SSB("vs_buf_block", "layout (std140, binding = BINDING, align = 64)", 0, 0, vs_buf_Block, 0,
12185 static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
12186 #endif /* WRKARD_UNIFORMBLOCKALIGNMENT */
12188 program_interface.CloneVertexInterface(varying_passthrough);
12191 /** Selects if "draw" stages are relevant for test
12195 * @return true if all stages support shader storage buffers, false otherwise
12197 bool SSBAlignmentTest::isDrawRelevant(GLuint /* test_case_index */)
12199 const Functions& gl = m_context.getRenderContext().getFunctions();
12200 GLint gs_supported_buffers = 0;
12201 GLint tcs_supported_buffers = 0;
12202 GLint tes_supported_buffers = 0;
12203 GLint vs_supported_buffers = 0;
12205 gl.getIntegerv(GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS, &gs_supported_buffers);
12206 gl.getIntegerv(GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS, &tcs_supported_buffers);
12207 gl.getIntegerv(GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS, &tes_supported_buffers);
12208 gl.getIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &vs_supported_buffers);
12210 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
12212 return ((1 <= gs_supported_buffers) && (1 <= tcs_supported_buffers) && (1 <= tes_supported_buffers) &&
12213 (1 <= vs_supported_buffers));
12218 * @param context Test framework context
12220 VaryingLocationsTest::VaryingLocationsTest(deqp::Context& context)
12221 : TextureTestBase(context, "varying_locations", "Test verifies that input and output locations are respected")
12227 * @param context Test context
12228 * @param test_name Name of test
12229 * @param test_description Description of test
12231 VaryingLocationsTest::VaryingLocationsTest(deqp::Context& context, const glw::GLchar* test_name,
12232 const glw::GLchar* test_description)
12233 : TextureTestBase(context, test_name, test_description)
12237 /** Get interface of program
12239 * @param test_case_index Test case
12240 * @param program_interface Interface of program
12241 * @param varying_passthrough Collection of connections between in and out variables
12243 void VaryingLocationsTest::getProgramInterface(GLuint test_case_index, Utils::ProgramInterface& program_interface,
12244 Utils::VaryingPassthrough& varying_passthrough)
12246 const Utils::Type type = getType(test_case_index);
12248 m_first_data = type.GenerateDataPacked();
12249 m_last_data = type.GenerateDataPacked();
12251 prepareShaderStage(Utils::Shader::FRAGMENT, type, program_interface, varying_passthrough);
12252 prepareShaderStage(Utils::Shader::GEOMETRY, type, program_interface, varying_passthrough);
12253 prepareShaderStage(Utils::Shader::TESS_CTRL, type, program_interface, varying_passthrough);
12254 prepareShaderStage(Utils::Shader::TESS_EVAL, type, program_interface, varying_passthrough);
12255 prepareShaderStage(Utils::Shader::VERTEX, type, program_interface, varying_passthrough);
12260 * @param test_case_index Index of test case
12262 * @return Name of type test in test_case_index
12264 std::string VaryingLocationsTest::getTestCaseName(glw::GLuint test_case_index)
12266 return getTypeName(test_case_index);
12269 /** Returns number of types to test
12271 * @return Number of types, 34
12273 glw::GLuint VaryingLocationsTest::getTestCaseNumber()
12275 return getTypesNumber();
12278 /** Selects if "compute" stage is relevant for test
12284 bool VaryingLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
12293 std::string VaryingLocationsTest::prepareGlobals(GLint last_in_loc, GLint last_out_loc)
12296 std::string globals = "const uint first_input_location = 0u;\n"
12297 "const uint first_output_location = 0u;\n"
12298 "const uint last_input_location = LAST_INPUTu;\n"
12299 "const uint last_output_location = LAST_OUTPUTu;\n";
12300 size_t position = 100; /* Skip first part */
12302 sprintf(buffer, "%d", last_in_loc);
12303 Utils::replaceToken("LAST_INPUT", position, buffer, globals);
12305 sprintf(buffer, "%d", last_out_loc);
12306 Utils::replaceToken("LAST_OUTPUT", position, buffer, globals);
12314 void VaryingLocationsTest::prepareShaderStage(Utils::Shader::STAGES stage, const Utils::Type& type,
12315 Utils::ProgramInterface& program_interface,
12316 Utils::VaryingPassthrough& varying_passthrough)
12318 const GLuint array_length = 1;
12319 const GLuint first_in_loc = 0;
12320 const GLuint first_out_loc = 0;
12321 const GLuint last_in_loc = getLastInputLocation(stage, type, array_length);
12322 size_t position = 0;
12324 const GLchar* prefix_in = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::VARYING_INPUT);
12326 const GLchar* prefix_out = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::VARYING_OUTPUT);
12328 const GLchar* qual_first_in = "layout (location = first_input_location)";
12329 const GLchar* qual_first_out = "layout (location = first_output_location)";
12330 const GLchar* qual_last_in = "layout (location = last_input_location)";
12331 const GLchar* qual_last_out = "layout (location = last_output_location)";
12333 Utils::ShaderInterface& si = program_interface.GetShaderInterface(stage);
12334 const GLuint type_size = type.GetSize();
12336 std::string first_in_name = "PREFIXfirst";
12337 std::string first_out_name = "PREFIXfirst";
12338 std::string last_in_name = "PREFIXlast";
12339 std::string last_out_name = "PREFIXlast";
12341 Utils::replaceToken("PREFIX", position, prefix_in, first_in_name);
12343 Utils::replaceToken("PREFIX", position, prefix_out, first_out_name);
12345 Utils::replaceToken("PREFIX", position, prefix_in, last_in_name);
12347 Utils::replaceToken("PREFIX", position, prefix_out, last_out_name);
12349 if (Utils::Shader::FRAGMENT == stage)
12351 qual_first_in = "layout (location = first_input_location) flat";
12352 qual_last_in = "layout (location = last_input_location) flat";
12354 if (Utils::Shader::GEOMETRY == stage)
12356 qual_first_out = "layout (location = first_output_location) flat";
12357 qual_last_out = "layout (location = last_output_location) flat";
12360 Utils::Variable* first_in = si.Input(
12361 first_in_name.c_str(), qual_first_in /* qualifiers */, 0 /* expected_componenet */,
12362 first_in_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */, 0u /* n_array_elements */,
12363 0u /* stride */, 0u /* offset */, (GLvoid*)&m_first_data[0] /* data */, m_first_data.size() /* data_size */);
12365 Utils::Variable* last_in =
12366 si.Input(last_in_name.c_str(), qual_last_in /* qualifiers */, 0 /* expected_componenet */,
12367 last_in_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12368 0u /* n_array_elements */, 0u /* stride */, type_size /* offset */,
12369 (GLvoid*)&m_last_data[0] /* data */, m_last_data.size() /* data_size */);
12371 if (Utils::Shader::FRAGMENT != stage)
12373 const GLuint last_out_loc = getLastOutputLocation(stage, type, array_length);
12375 Utils::Variable* first_out =
12376 si.Output(first_out_name.c_str(), qual_first_out /* qualifiers */, 0 /* expected_componenet */,
12377 first_out_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12378 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)&m_first_data[0] /* data */,
12379 m_first_data.size() /* data_size */);
12381 Utils::Variable* last_out = si.Output(
12382 last_out_name.c_str(), qual_last_out /* qualifiers */, 0 /* expected_componenet */,
12383 last_out_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */, 0u /* n_array_elements */,
12384 0u /* stride */, 0u /* offset */, (GLvoid*)&m_last_data[0] /* data */, m_last_data.size() /* data_size */);
12386 si.m_globals = prepareGlobals(last_in_loc, last_out_loc);
12388 varying_passthrough.Add(stage, first_in, first_out);
12389 varying_passthrough.Add(stage, last_in, last_out);
12393 /* No outputs for fragment shader, so last_output_location can be 0 */
12394 si.m_globals = prepareGlobals(last_in_loc, 0);
12398 /** This test should be run with separable programs
12404 bool VaryingLocationsTest::useMonolithicProgram(GLuint /* test_case_index */)
12409 /* Constants used by VertexAttribLocationsTest */
12410 const GLuint VertexAttribLocationsTest::m_base_vertex = 4;
12411 const GLuint VertexAttribLocationsTest::m_base_instance = 2;
12412 const GLuint VertexAttribLocationsTest::m_loc_vertex = 2;
12413 const GLuint VertexAttribLocationsTest::m_loc_instance = 5;
12414 const GLuint VertexAttribLocationsTest::m_n_instances = 4;
12418 * @param context Test framework context
12420 VertexAttribLocationsTest::VertexAttribLocationsTest(deqp::Context& context)
12421 : TextureTestBase(context, "vertex_attrib_locations",
12422 "Test verifies that attribute locations are respected by drawing operations")
12426 /** Execute proper draw command for test case
12428 * @param test_case_index Index of test case
12430 void VertexAttribLocationsTest::executeDrawCall(GLuint test_case_index)
12432 const Functions& gl = m_context.getRenderContext().getFunctions();
12434 switch (test_case_index)
12437 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
12438 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
12440 case DRAWARRAYSINSTANCED:
12441 gl.drawArraysInstanced(GL_PATCHES, 0 /* first */, 1 /* count */, m_n_instances);
12442 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArraysInstanced");
12445 gl.drawElements(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL);
12446 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElements");
12448 case DRAWELEMENTSBASEVERTEX:
12449 gl.drawElementsBaseVertex(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL, m_base_vertex);
12450 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsBaseVertex");
12452 case DRAWELEMENTSINSTANCED:
12453 gl.drawElementsInstanced(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL, m_n_instances);
12454 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsInstanced");
12456 case DRAWELEMENTSINSTANCEDBASEINSTANCE:
12457 gl.drawElementsInstancedBaseInstance(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL, m_n_instances,
12459 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsInstancedBaseInstance");
12461 case DRAWELEMENTSINSTANCEDBASEVERTEX:
12462 gl.drawElementsInstancedBaseVertex(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL, m_n_instances,
12464 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsInstancedBaseVertex");
12466 case DRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCE:
12467 gl.drawElementsInstancedBaseVertexBaseInstance(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL,
12468 m_n_instances, m_base_vertex, m_base_instance);
12469 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsInstancedBaseVertexBaseInstance");
12472 TCU_FAIL("Invalid enum");
12476 /** Get interface of program
12479 * @param program_interface Interface of program
12482 void VertexAttribLocationsTest::getProgramInterface(GLuint /* test_case_index */,
12483 Utils::ProgramInterface& program_interface,
12484 Utils::VaryingPassthrough& /* varying_passthrough */)
12486 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
12489 si.m_globals = "const uint vertex_index_location = 2;\n"
12490 "const uint instance_index_location = 5;\n";
12493 si.Input("vertex_index" /* name */, "layout (location = vertex_index_location)" /* qualifiers */,
12494 0 /* expected_componenet */, m_loc_vertex /* expected_location */, Utils::Type::uint /* type */,
12495 GL_FALSE /* normalized */, 0u /* n_array_elements */, 16 /* stride */, 0u /* offset */,
12496 (GLvoid*)0 /* data */, 0 /* data_size */);
12497 si.Input("instance_index" /* name */, "layout (location = instance_index_location)" /* qualifiers */,
12498 0 /* expected_componenet */, m_loc_instance /* expected_location */, Utils::Type::uint /* type */,
12499 GL_FALSE /* normalized */, 0u /* n_array_elements */, 16 /* stride */, 16u /* offset */,
12500 (GLvoid*)0 /* data */, 0 /* data_size */);
12503 /** Get name of test case
12505 * @param test_case_index Index of test case
12507 * @return Name of test case
12509 std::string VertexAttribLocationsTest::getTestCaseName(glw::GLuint test_case_index)
12511 std::string result;
12513 switch (test_case_index)
12516 result = "DrawArrays";
12518 case DRAWARRAYSINSTANCED:
12519 result = "DrawArraysInstanced";
12522 result = "DrawElements";
12524 case DRAWELEMENTSBASEVERTEX:
12525 result = "DrawElementsBaseVertex";
12527 case DRAWELEMENTSINSTANCED:
12528 result = "DrawElementsInstanced";
12530 case DRAWELEMENTSINSTANCEDBASEINSTANCE:
12531 result = "DrawElementsInstancedBaseInstance";
12533 case DRAWELEMENTSINSTANCEDBASEVERTEX:
12534 result = "DrawElementsInstancedBaseVertex";
12536 case DRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCE:
12537 result = "DrawElementsInstancedBaseVertexBaseInstance";
12540 TCU_FAIL("Invalid enum");
12546 /** Get number of test cases
12548 * @return Number of test cases
12550 GLuint VertexAttribLocationsTest::getTestCaseNumber()
12552 return TESTCASES_MAX;
12555 /** Prepare code snippet that will verify in and uniform variables
12559 * @param stage Shader stage
12561 * @return Code that verify variables
12563 std::string VertexAttribLocationsTest::getVerificationSnippet(GLuint /* test_case_index */,
12564 Utils::ProgramInterface& /* program_interface */,
12565 Utils::Shader::STAGES stage)
12567 std::string verification;
12569 if (Utils::Shader::VERTEX == stage)
12572 #if DEBUG_VERTEX_ATTRIB_LOCATIONS_TEST_VARIABLE
12574 verification = "if (gl_InstanceID != instance_index)\n"
12578 " else if (gl_VertexID != vertex_index)\n"
12585 verification = "if ((gl_VertexID != vertex_index) ||\n"
12586 " (gl_InstanceID != instance_index) )\n"
12598 return verification;
12601 /** Selects if "compute" stage is relevant for test
12607 bool VertexAttribLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
12612 /** Prepare attributes, vertex array object and array buffer
12615 * @param ignored Interface of program
12616 * @param buffer Array buffer
12617 * @param vao Vertex array object
12619 void VertexAttribLocationsTest::prepareAttributes(GLuint test_case_index /* test_case_index */,
12620 Utils::ProgramInterface& /* program_interface */,
12621 Utils::Buffer& buffer, Utils::VertexArray& vao)
12623 static const GLuint vertex_index_data[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
12624 static const GLuint instance_index_data[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
12626 std::vector<GLuint> buffer_data;
12627 buffer_data.resize(8 + 8); /* vertex_index_data + instance_index_data */
12629 GLubyte* ptr = (GLubyte*)&buffer_data[0];
12632 When case index >=2, the test calls glDrawElement*(), such as glDrawElementsBaseVertex(), glDrawElementsInstanced(), glDrawElementsInstancedBaseInstance() and so on,
12633 So we need to change the buffer type as GL_ELEMENT_ARRAY_BUFFER
12635 if (test_case_index >= 2)
12637 buffer.m_buffer = Utils::Buffer::Element;
12642 vao.Attribute(m_loc_vertex /* vertex_index */, Utils::Type::uint, 0 /* array_elements */, false /* normalized */,
12643 0 /* stride */, 0 /* offset */);
12645 vao.Attribute(m_loc_instance /* instance_index */, Utils::Type::uint, 0 /* array_elements */,
12646 false /* normalized */, 0 /* stride */, (GLvoid*)sizeof(vertex_index_data) /* offset */);
12647 // when test_case_index is 5 or 7, the draw call is glDrawElementsInstancedBaseInstance, glDrawElementsInstancedBaseVertexBaseInstance
12648 // the instancecount is 4, the baseinstance is 2, the divisor should be set 2
12649 bool isBaseInstanced = (test_case_index == DRAWELEMENTSINSTANCEDBASEINSTANCE ||
12650 test_case_index == DRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCE);
12651 vao.Divisor(m_context.getRenderContext().getFunctions() /* gl */, m_loc_instance /* instance_index */,
12652 isBaseInstanced ? 2 : 1 /* divisor. 1 - advance once per instance */);
12654 memcpy(ptr + 0, vertex_index_data, sizeof(vertex_index_data));
12655 memcpy(ptr + sizeof(vertex_index_data), instance_index_data, sizeof(instance_index_data));
12657 buffer.Data(Utils::Buffer::StaticDraw, buffer_data.size() * sizeof(GLuint), ptr);
12660 /** This test should be run with separable programs
12666 bool VertexAttribLocationsTest::useMonolithicProgram(GLuint /* test_case_index */)
12673 * @param context Test framework context
12675 VaryingArrayLocationsTest::VaryingArrayLocationsTest(deqp::Context& context)
12676 : VaryingLocationsTest(context, "varying_array_locations",
12677 "Test verifies that input and output locations are respected for arrays")
12684 void VaryingArrayLocationsTest::prepareShaderStage(Utils::Shader::STAGES stage, const Utils::Type& type,
12685 Utils::ProgramInterface& program_interface,
12686 Utils::VaryingPassthrough& varying_passthrough)
12688 const GLuint array_length = 1u;
12689 const GLuint first_in_loc = 0;
12690 const GLuint first_out_loc = 0;
12691 const GLuint last_in_loc = getLastInputLocation(stage, type, array_length);
12692 size_t position = 0;
12694 const GLchar* prefix_in = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::VARYING_INPUT);
12696 const GLchar* prefix_out = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::VARYING_OUTPUT);
12698 const GLchar* qual_first_in = "layout (location = first_input_location)";
12699 const GLchar* qual_first_out = "layout (location = first_output_location)";
12700 const GLchar* qual_last_in = "layout (location = last_input_location)";
12701 const GLchar* qual_last_out = "layout (location = last_output_location)";
12703 Utils::ShaderInterface& si = program_interface.GetShaderInterface(stage);
12704 const GLuint type_size = type.GetSize();
12706 std::string first_in_name = "PREFIXfirst";
12707 std::string first_out_name = "PREFIXfirst";
12708 std::string last_in_name = "PREFIXlast";
12709 std::string last_out_name = "PREFIXlast";
12711 Utils::replaceToken("PREFIX", position, prefix_in, first_in_name);
12713 Utils::replaceToken("PREFIX", position, prefix_out, first_out_name);
12715 Utils::replaceToken("PREFIX", position, prefix_in, last_in_name);
12717 Utils::replaceToken("PREFIX", position, prefix_out, last_out_name);
12719 if (Utils::Shader::FRAGMENT == stage)
12721 qual_first_in = "layout (location = first_input_location) flat";
12722 qual_last_in = "layout (location = last_input_location) flat";
12724 if (Utils::Shader::GEOMETRY == stage)
12726 qual_first_out = "layout (location = first_output_location) flat";
12727 qual_last_out = "layout (location = last_output_location) flat";
12730 Utils::Variable* first_in =
12731 si.Input(first_in_name.c_str(), qual_first_in /* qualifiers */, 0 /* expected_componenet */,
12732 first_in_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12733 array_length /* n_array_elements */, 0u /* stride */, 0u /* offset */,
12734 (GLvoid*)&m_first_data[0] /* data */, m_first_data.size() /* data_size */);
12736 Utils::Variable* last_in =
12737 si.Input(last_in_name.c_str(), qual_last_in /* qualifiers */, 0 /* expected_componenet */,
12738 last_in_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12739 array_length /* n_array_elements */, 0u /* stride */, type_size /* offset */,
12740 (GLvoid*)&m_last_data[0] /* data */, m_last_data.size() /* data_size */);
12742 if (Utils::Shader::FRAGMENT != stage)
12744 const GLuint last_out_loc = getLastOutputLocation(stage, type, array_length);
12746 Utils::Variable* first_out =
12747 si.Output(first_out_name.c_str(), qual_first_out /* qualifiers */, 0 /* expected_componenet */,
12748 first_out_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12749 array_length /* n_array_elements */, 0u /* stride */, 0u /* offset */,
12750 (GLvoid*)&m_first_data[0] /* data */, m_first_data.size() /* data_size */);
12752 Utils::Variable* last_out =
12753 si.Output(last_out_name.c_str(), qual_last_out /* qualifiers */, 0 /* expected_componenet */,
12754 last_out_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12755 array_length /* n_array_elements */, 0u /* stride */, 0u /* offset */,
12756 (GLvoid*)&m_last_data[0] /* data */, m_last_data.size() /* data_size */);
12758 si.m_globals = prepareGlobals(last_in_loc, last_out_loc);
12760 varying_passthrough.Add(stage, first_in, first_out);
12761 varying_passthrough.Add(stage, last_in, last_out);
12765 /* No outputs for fragment shader, so last_output_location can be 0 */
12766 si.m_globals = prepareGlobals(last_in_loc, 0);
12772 * @param context Test framework context
12774 VaryingStructureLocationsTest::VaryingStructureLocationsTest(deqp::Context& context)
12775 : TextureTestBase(context, "varying_structure_locations",
12776 "Test verifies that locations are respected when structures are used as in and out ")
12780 /** Prepare code snippet that will pass in variables to out variables
12783 * @param varying_passthrough Collection of connections between in and out variables
12784 * @param stage Shader stage
12786 * @return Code that pass in variables to next stage
12788 std::string VaryingStructureLocationsTest::getPassSnippet(GLuint /* test_case_index */,
12789 Utils::VaryingPassthrough& varying_passthrough,
12790 Utils::Shader::STAGES stage)
12792 std::string result;
12794 if (Utils::Shader::VERTEX != stage)
12796 result = TextureTestBase::getPassSnippet(0, varying_passthrough, stage);
12800 result = " vs_tcs_output[0].single = vs_in_single[0];\n"
12801 " vs_tcs_output[0].array[0] = vs_in_array[0];\n";
12807 /** Get interface of program
12809 * @param test_case_index Test case
12810 * @param program_interface Interface of program
12811 * @param varying_passthrough Collection of connections between in and out variables
12813 void VaryingStructureLocationsTest::getProgramInterface(GLuint test_case_index,
12814 Utils::ProgramInterface& program_interface,
12815 Utils::VaryingPassthrough& varying_passthrough)
12817 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
12818 const Utils::Type type = getType(test_case_index);
12821 // We should call GenerateDataPacked() to generate data, which can make sure the data in shader is correct
12822 m_single_data = type.GenerateDataPacked();
12823 m_array_data = type.GenerateDataPacked();
12825 m_data.resize(m_single_data.size() + m_array_data.size());
12826 GLubyte* ptr = (GLubyte*)&m_data[0];
12827 memcpy(ptr, &m_single_data[0], m_single_data.size());
12828 memcpy(ptr + m_single_data.size(), &m_array_data[0], m_array_data.size());
12830 Utils::Interface* structure = program_interface.Structure("Data");
12832 structure->Member("single", "" /* qualifiers */, 0 /* component */, 0 /* location */, type, false /* normalized */,
12833 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */);
12835 // the second struct member 's location should not be 0, it is based on by how many the locations the first struct member consumed.
12836 structure->Member("array", "" /* qualifiers */, 0 /* component */, type.GetLocations() /* location */, type,
12837 false /* normalized */, 1u /* n_array_elements */, 0u /* stride */, type.GetSize() /* offset */);
12839 si.Input("vs_in_single", "layout (location = 0)", 0 /* component */, 0 /* location */, type, false /* normalized */,
12840 1u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)&m_single_data[0] /* data */,
12841 m_single_data.size() /* data_size */);
12843 si.Input("vs_in_array", "layout (location = 8)", 0 /* component */, 8 /* location */, type, false /* normalized */,
12844 1u /* n_array_elements */, 0u /* stride */, type.GetSize() /* offset */,
12845 (GLvoid*)&m_array_data[0] /* data */, m_array_data.size() /* data_size */);
12847 si.Output("vs_tcs_output", "layout (location = 0)", 0 /* component */, 0 /* location */, structure,
12848 1u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)&m_data[0] /* data */,
12849 m_data.size() /* data_size */);
12851 program_interface.CloneVertexInterface(varying_passthrough);
12856 * @param test_case_index Index of test case
12858 * @return Name of type test in test_case_index
12860 std::string VaryingStructureLocationsTest::getTestCaseName(glw::GLuint test_case_index)
12862 return getTypeName(test_case_index);
12865 /** Returns number of types to test
12867 * @return Number of types, 34
12869 glw::GLuint VaryingStructureLocationsTest::getTestCaseNumber()
12871 return getTypesNumber();
12874 /** Selects if "compute" stage is relevant for test
12880 bool VaryingStructureLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
12885 /** This test should be run with separable programs
12891 bool VaryingStructureLocationsTest::useMonolithicProgram(GLuint /* test_case_index */)
12898 * @param context Test context
12899 * @param test_name Name of test
12900 * @param test_description Description of test
12902 VaryingStructureMemberLocationTest::VaryingStructureMemberLocationTest(deqp::Context& context)
12903 : NegativeTestBase(context, "varying_structure_member_location",
12904 "Test verifies that compiler does not allow location qualifier on member of strucure")
12908 /** Source for given test case and stage
12910 * @param test_case_index Index of test case
12911 * @param stage Shader stage
12913 * @return Shader source
12915 std::string VaryingStructureMemberLocationTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
12917 static const GLchar* struct_definition = "struct Data {\n"
12919 " layout (location = 4) vec4 goten;\n"
12921 static const GLchar* input_var = "in Data data;\n";
12922 static const GLchar* output_var = "out Data data;\n";
12923 static const GLchar* input_use = " result += data.gohan + data.goten;\n";
12924 static const GLchar* output_use = " data.gohan = result / 2;\n"
12925 " data.goten = result / 4 - data.gohan;\n";
12926 static const GLchar* fs = "#version 430 core\n"
12927 "#extension GL_ARB_enhanced_layouts : require\n"
12930 "out vec4 fs_out;\n"
12934 " fs_out = gs_fs;\n"
12937 static const GLchar* fs_tested = "#version 430 core\n"
12938 "#extension GL_ARB_enhanced_layouts : require\n"
12940 "STRUCT_DEFINITION"
12942 "VARIABLE_DEFINITION"
12945 "out vec4 fs_out;\n"
12949 " vec4 result = gs_fs;\n"
12953 " fs_out += result;\n"
12956 static const GLchar* gs = "#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 "in vec4 tes_gs[];\n"
12963 "out vec4 gs_fs;\n"
12967 " gs_fs = tes_gs[0];\n"
12968 " gl_Position = vec4(-1, -1, 0, 1);\n"
12970 " gs_fs = tes_gs[0];\n"
12971 " gl_Position = vec4(-1, 1, 0, 1);\n"
12973 " gs_fs = tes_gs[0];\n"
12974 " gl_Position = vec4(1, -1, 0, 1);\n"
12976 " gs_fs = tes_gs[0];\n"
12977 " gl_Position = vec4(1, 1, 0, 1);\n"
12981 static const GLchar* gs_tested = "#version 430 core\n"
12982 "#extension GL_ARB_enhanced_layouts : require\n"
12984 "layout(points) in;\n"
12985 "layout(triangle_strip, max_vertices = 4) out;\n"
12987 "STRUCT_DEFINITION"
12989 "VARIABLE_DEFINITION"
12991 "in vec4 tes_gs[];\n"
12992 "out vec4 gs_fs;\n"
12996 " vec4 result = tes_gs[0];\n"
13000 " gs_fs = result;\n"
13001 " gl_Position = vec4(-1, -1, 0, 1);\n"
13003 " gs_fs = result;\n"
13004 " gl_Position = vec4(-1, 1, 0, 1);\n"
13006 " gs_fs = result;\n"
13007 " gl_Position = vec4(1, -1, 0, 1);\n"
13009 " gs_fs = result;\n"
13010 " gl_Position = vec4(1, 1, 0, 1);\n"
13014 static const GLchar* tcs = "#version 430 core\n"
13015 "#extension GL_ARB_enhanced_layouts : require\n"
13017 "layout(vertices = 1) out;\n"
13019 "in vec4 vs_tcs[];\n"
13020 "out vec4 tcs_tes[];\n"
13025 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
13027 " gl_TessLevelOuter[0] = 1.0;\n"
13028 " gl_TessLevelOuter[1] = 1.0;\n"
13029 " gl_TessLevelOuter[2] = 1.0;\n"
13030 " gl_TessLevelOuter[3] = 1.0;\n"
13031 " gl_TessLevelInner[0] = 1.0;\n"
13032 " gl_TessLevelInner[1] = 1.0;\n"
13035 static const GLchar* tcs_tested = "#version 430 core\n"
13036 "#extension GL_ARB_enhanced_layouts : require\n"
13038 "layout(vertices = 1) out;\n"
13040 "STRUCT_DEFINITION"
13042 "VARIABLE_DEFINITION"
13044 "in vec4 vs_tcs[];\n"
13045 "out vec4 tcs_tes[];\n"
13049 " vec4 result = vs_tcs[gl_InvocationID];\n"
13053 " tcs_tes[gl_InvocationID] = result;\n"
13055 " gl_TessLevelOuter[0] = 1.0;\n"
13056 " gl_TessLevelOuter[1] = 1.0;\n"
13057 " gl_TessLevelOuter[2] = 1.0;\n"
13058 " gl_TessLevelOuter[3] = 1.0;\n"
13059 " gl_TessLevelInner[0] = 1.0;\n"
13060 " gl_TessLevelInner[1] = 1.0;\n"
13063 static const GLchar* tes = "#version 430 core\n"
13064 "#extension GL_ARB_enhanced_layouts : require\n"
13066 "layout(isolines, point_mode) in;\n"
13068 "in vec4 tcs_tes[];\n"
13069 "out vec4 tes_gs;\n"
13073 " tes_gs = tcs_tes[0];\n"
13076 static const GLchar* tes_tested = "#version 430 core\n"
13077 "#extension GL_ARB_enhanced_layouts : require\n"
13079 "layout(isolines, point_mode) in;\n"
13081 "STRUCT_DEFINITION"
13083 "VARIABLE_DEFINITION"
13085 "in vec4 tcs_tes[];\n"
13086 "out vec4 tes_gs;\n"
13090 " vec4 result = tcs_tes[0];\n"
13094 " tes_gs += result;\n"
13097 static const GLchar* vs = "#version 430 core\n"
13098 "#extension GL_ARB_enhanced_layouts : require\n"
13101 "out vec4 vs_tcs;\n"
13105 " vs_tcs = in_vs;\n"
13108 static const GLchar* vs_tested = "#version 430 core\n"
13109 "#extension GL_ARB_enhanced_layouts : require\n"
13111 "STRUCT_DEFINITION"
13113 "VARIABLE_DEFINITION"
13116 "out vec4 vs_tcs;\n"
13120 " vec4 result = in_vs;\n"
13124 " vs_tcs += result;\n"
13128 std::string source;
13129 testCase& test_case = m_test_cases[test_case_index];
13130 const GLchar* var_definition = 0;
13131 const GLchar* var_use = 0;
13133 if (true == test_case.m_is_input)
13135 var_definition = input_var;
13136 var_use = input_use;
13140 var_definition = output_var;
13141 var_use = output_use;
13144 if (test_case.m_stage == stage)
13146 size_t position = 0;
13150 case Utils::Shader::FRAGMENT:
13151 source = fs_tested;
13153 case Utils::Shader::GEOMETRY:
13154 source = gs_tested;
13156 case Utils::Shader::TESS_CTRL:
13157 source = tcs_tested;
13159 case Utils::Shader::TESS_EVAL:
13160 source = tes_tested;
13162 case Utils::Shader::VERTEX:
13163 source = vs_tested;
13166 TCU_FAIL("Invalid enum");
13169 Utils::replaceToken("STRUCT_DEFINITION", position, struct_definition, source);
13170 Utils::replaceToken("VARIABLE_DEFINITION", position, var_definition, source);
13171 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
13177 case Utils::Shader::FRAGMENT:
13180 case Utils::Shader::GEOMETRY:
13183 case Utils::Shader::TESS_CTRL:
13186 case Utils::Shader::TESS_EVAL:
13189 case Utils::Shader::VERTEX:
13193 TCU_FAIL("Invalid enum");
13200 /** Get description of test case
13202 * @param test_case_index Index of test case
13204 * @return Test case description
13206 std::string VaryingStructureMemberLocationTest::getTestCaseName(GLuint test_case_index)
13208 std::stringstream stream;
13209 testCase& test_case = m_test_cases[test_case_index];
13211 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", direction: ";
13213 if (true == test_case.m_is_input)
13219 stream << "output";
13222 return stream.str();
13225 /** Get number of test cases
13227 * @return Number of test cases
13229 GLuint VaryingStructureMemberLocationTest::getTestCaseNumber()
13231 return static_cast<GLuint>(m_test_cases.size());
13234 /** Selects if "compute" stage is relevant for test
13240 bool VaryingStructureMemberLocationTest::isComputeRelevant(GLuint /* test_case_index */)
13245 /** Prepare all test cases
13248 void VaryingStructureMemberLocationTest::testInit()
13250 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
13252 if (Utils::Shader::COMPUTE == stage)
13257 testCase test_case_in = { true, (Utils::Shader::STAGES)stage };
13258 testCase test_case_out = { false, (Utils::Shader::STAGES)stage };
13260 m_test_cases.push_back(test_case_in);
13262 if (Utils::Shader::FRAGMENT != stage)
13264 m_test_cases.push_back(test_case_out);
13271 * @param context Test framework context
13273 VaryingBlockLocationsTest::VaryingBlockLocationsTest(deqp::Context& context)
13274 : TextureTestBase(context, "varying_block_locations",
13275 "Test verifies that locations are respected when blocks are used as in and out ")
13279 /** Prepare code snippet that will pass in variables to out variables
13282 * @param varying_passthrough Collection of connections between in and out variables
13283 * @param stage Shader stage
13285 * @return Code that pass in variables to next stage
13287 std::string VaryingBlockLocationsTest::getPassSnippet(GLuint /* test_case_index */,
13288 Utils::VaryingPassthrough& varying_passthrough,
13289 Utils::Shader::STAGES stage)
13291 std::string result;
13293 if (Utils::Shader::VERTEX != stage)
13295 result = TextureTestBase::getPassSnippet(0, varying_passthrough, stage);
13299 result = "vs_tcs_block.third = vs_in_third;\n"
13300 " vs_tcs_block.fourth = vs_in_fourth;\n"
13301 " vs_tcs_block.fifth = vs_in_fifth;\n";
13307 /** Get interface of program
13310 * @param program_interface Interface of program
13311 * @param varying_passthrough Collection of connections between in and out variables
13313 void VaryingBlockLocationsTest::getProgramInterface(GLuint /* test_case_index */,
13314 Utils::ProgramInterface& program_interface,
13315 Utils::VaryingPassthrough& varying_passthrough)
13317 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
13318 const Utils::Type vec4 = Utils::Type::vec4;
13321 m_third_data = vec4.GenerateData();
13322 m_fourth_data = vec4.GenerateData();
13323 m_fifth_data = vec4.GenerateData();
13325 /* Memory layout is different from location layout */
13326 const GLuint fifth_offset = 0u;
13327 const GLuint third_offset = static_cast<GLuint>(fifth_offset + m_fifth_data.size());
13328 const GLuint fourth_offset = static_cast<GLuint>(third_offset + m_fourth_data.size());
13330 m_data.resize(fourth_offset + m_fourth_data.size());
13331 GLubyte* ptr = (GLubyte*)&m_data[0];
13332 memcpy(ptr + third_offset, &m_third_data[0], m_third_data.size());
13333 memcpy(ptr + fourth_offset, &m_fourth_data[0], m_fourth_data.size());
13334 memcpy(ptr + fifth_offset, &m_fifth_data[0], m_fifth_data.size());
13336 Utils::Interface* block = program_interface.Block("vs_tcs_Block");
13338 block->Member("fifth", "" /* qualifiers */, 0 /* component */, 4 /* location */, vec4, false /* normalized */,
13339 0u /* n_array_elements */, 0u /* stride */, fifth_offset /* offset */);
13341 block->Member("third", "layout (location = 2)" /* qualifiers */, 0 /* component */, 2 /* location */, vec4,
13342 false /* normalized */, 0u /* n_array_elements */, 0u /* stride */, third_offset /* offset */);
13344 block->Member("fourth", "" /* qualifiers */, 0 /* component */, 3 /* location */, vec4, false /* normalized */,
13345 0u /* n_array_elements */, 0u /* stride */, fourth_offset /* offset */);
13347 si.Output("vs_tcs_block", "layout (location = 4)", 0 /* component */, 4 /* location */, block,
13348 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)&m_data[0] /* data */,
13349 m_data.size() /* data_size */);
13351 si.Input("vs_in_third", "layout (location = 0)", 0 /* component */, 0 /* location */, vec4, false /* normalized */,
13352 0u /* n_array_elements */, 0u /* stride */, third_offset /* offset */,
13353 (GLvoid*)&m_third_data[0] /* data */, m_third_data.size() /* data_size */);
13355 si.Input("vs_in_fourth", "layout (location = 1)", 0 /* component */, 1 /* location */, vec4, false /* normalized */,
13356 0u /* n_array_elements */, 0u /* stride */, fourth_offset /* offset */,
13357 (GLvoid*)&m_fourth_data[0] /* data */, m_fourth_data.size() /* data_size */);
13359 si.Input("vs_in_fifth", "layout (location = 2)", 0 /* component */, 2 /* location */, vec4, false /* normalized */,
13360 0u /* n_array_elements */, 0u /* stride */, fifth_offset /* offset */,
13361 (GLvoid*)&m_fifth_data[0] /* data */, m_fifth_data.size() /* data_size */);
13363 program_interface.CloneVertexInterface(varying_passthrough);
13366 /** Selects if "compute" stage is relevant for test
13372 bool VaryingBlockLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
13377 /** This test should be run with separable programs
13383 bool VaryingBlockLocationsTest::useMonolithicProgram(GLuint /* test_case_index */)
13390 * @param context Test framework context
13392 VaryingBlockMemberLocationsTest::VaryingBlockMemberLocationsTest(deqp::Context& context)
13393 : NegativeTestBase(
13394 context, "varying_block_member_locations",
13395 "Test verifies that compilation error is reported when not all members of block are qualified with location")
13399 /** Source for given test case and stage
13401 * @param test_case_index Index of test case
13402 * @param stage Shader stage
13404 * @return Shader source
13406 std::string VaryingBlockMemberLocationsTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
13408 static const GLchar* block_definition_all = "Goku {\n"
13409 " layout (location = 2) vec4 gohan;\n"
13410 " layout (location = 4) vec4 goten;\n"
13411 " layout (location = 6) vec4 chichi;\n"
13413 static const GLchar* block_definition_default = "Goku {\n"
13418 static const GLchar* block_definition_one = "Goku {\n"
13420 " layout (location = 4) vec4 goten;\n"
13423 static const GLchar* input_use = " result += gokuINDEX.gohan + gokuINDEX.goten + gokuINDEX.chichi;\n";
13424 static const GLchar* output_use = " gokuINDEX.gohan = result / 2;\n"
13425 " gokuINDEX.goten = result / 4 - gokuINDEX.gohan;\n"
13426 " gokuINDEX.chichi = result / 8 - gokuINDEX.goten;\n";
13427 static const GLchar* fs = "#version 430 core\n"
13428 "#extension GL_ARB_enhanced_layouts : require\n"
13431 "out vec4 fs_out;\n"
13435 " fs_out = gs_fs;\n"
13438 static const GLchar* fs_tested = "#version 430 core\n"
13439 "#extension GL_ARB_enhanced_layouts : require\n"
13441 "DIRECTION BLOCK_DEFINITION"
13444 "out vec4 fs_out;\n"
13448 " vec4 result = gs_fs;\n"
13452 " fs_out = result;\n"
13455 static const GLchar* gs = "#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 "in vec4 tes_gs[];\n"
13462 "out vec4 gs_fs;\n"
13466 " gs_fs = tes_gs[0];\n"
13467 " gl_Position = vec4(-1, -1, 0, 1);\n"
13469 " gs_fs = tes_gs[0];\n"
13470 " gl_Position = vec4(-1, 1, 0, 1);\n"
13472 " gs_fs = tes_gs[0];\n"
13473 " gl_Position = vec4(1, -1, 0, 1);\n"
13475 " gs_fs = tes_gs[0];\n"
13476 " gl_Position = vec4(1, 1, 0, 1);\n"
13480 static const GLchar* gs_tested = "#version 430 core\n"
13481 "#extension GL_ARB_enhanced_layouts : require\n"
13483 "layout(points) in;\n"
13484 "layout(triangle_strip, max_vertices = 4) out;\n"
13486 "DIRECTION BLOCK_DEFINITION"
13488 "in vec4 tes_gs[];\n"
13489 "out vec4 gs_fs;\n"
13493 " vec4 result = tes_gs[0];\n"
13497 " gs_fs = result;\n"
13498 " gl_Position = vec4(-1, -1, 0, 1);\n"
13500 " gs_fs = result;\n"
13501 " gl_Position = vec4(-1, 1, 0, 1);\n"
13503 " gs_fs = result;\n"
13504 " gl_Position = vec4(1, -1, 0, 1);\n"
13506 " gs_fs = result;\n"
13507 " gl_Position = vec4(1, 1, 0, 1);\n"
13511 static const GLchar* tcs = "#version 430 core\n"
13512 "#extension GL_ARB_enhanced_layouts : require\n"
13514 "layout(vertices = 1) out;\n"
13516 "in vec4 vs_tcs[];\n"
13517 "out vec4 tcs_tes[];\n"
13522 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
13524 " gl_TessLevelOuter[0] = 1.0;\n"
13525 " gl_TessLevelOuter[1] = 1.0;\n"
13526 " gl_TessLevelOuter[2] = 1.0;\n"
13527 " gl_TessLevelOuter[3] = 1.0;\n"
13528 " gl_TessLevelInner[0] = 1.0;\n"
13529 " gl_TessLevelInner[1] = 1.0;\n"
13532 static const GLchar* tcs_tested = "#version 430 core\n"
13533 "#extension GL_ARB_enhanced_layouts : require\n"
13535 "layout(vertices = 1) out;\n"
13537 "DIRECTION BLOCK_DEFINITION"
13539 "in vec4 vs_tcs[];\n"
13540 "out vec4 tcs_tes[];\n"
13544 " vec4 result = vs_tcs[gl_InvocationID];\n"
13548 " tcs_tes[gl_InvocationID] = result;\n"
13550 " gl_TessLevelOuter[0] = 1.0;\n"
13551 " gl_TessLevelOuter[1] = 1.0;\n"
13552 " gl_TessLevelOuter[2] = 1.0;\n"
13553 " gl_TessLevelOuter[3] = 1.0;\n"
13554 " gl_TessLevelInner[0] = 1.0;\n"
13555 " gl_TessLevelInner[1] = 1.0;\n"
13558 static const GLchar* tes = "#version 430 core\n"
13559 "#extension GL_ARB_enhanced_layouts : require\n"
13561 "layout(isolines, point_mode) in;\n"
13563 "in vec4 tcs_tes[];\n"
13564 "out vec4 tes_gs;\n"
13568 " tes_gs = tcs_tes[0];\n"
13571 static const GLchar* tes_tested = "#version 430 core\n"
13572 "#extension GL_ARB_enhanced_layouts : require\n"
13574 "layout(isolines, point_mode) in;\n"
13576 "DIRECTION BLOCK_DEFINITION"
13578 "in vec4 tcs_tes[];\n"
13579 "out vec4 tes_gs;\n"
13583 " vec4 result = tcs_tes[0];\n"
13587 " tes_gs = result;\n"
13590 static const GLchar* vs = "#version 430 core\n"
13591 "#extension GL_ARB_enhanced_layouts : require\n"
13594 "out vec4 vs_tcs;\n"
13598 " vs_tcs = in_vs;\n"
13601 static const GLchar* vs_tested = "#version 430 core\n"
13602 "#extension GL_ARB_enhanced_layouts : require\n"
13604 "DIRECTION BLOCK_DEFINITION"
13607 "out vec4 vs_tcs;\n"
13611 " vec4 result = in_vs;\n"
13615 " vs_tcs = result;\n"
13619 static const GLchar* shaders_in[6][6] = { /* cs */ { 0, 0, 0, 0, 0, 0 },
13620 /* vs */ { 0, vs_tested, tcs, tes, gs, fs },
13621 /* tcs */ { 0, vs_tested, tcs_tested, tes, gs, fs },
13622 /* tes */ { 0, vs, tcs_tested, tes_tested, gs, fs },
13623 /* gs */ { 0, vs, tcs, tes_tested, gs_tested, fs },
13624 /* fs */ { 0, vs, tcs, tes, gs_tested, fs_tested } };
13626 static const GLchar* shaders_out[6][6] = { /* cs */ { 0, 0, 0, 0, 0, 0 },
13627 /* vs */ { 0, vs_tested, tcs_tested, tes, gs, fs },
13628 /* tcs */ { 0, vs, tcs_tested, tes_tested, gs, fs },
13629 /* tes */ { 0, vs, tcs, tes_tested, gs_tested, fs },
13630 /* gs */ { 0, vs, tcs, tes, gs_tested, fs_tested },
13631 /* fs */ { 0, 0, 0, 0, 0, 0 } };
13633 static const bool require_modifications_in[6][6] = {
13634 /* cs */ { false, false, false, false, false, false },
13635 /* vs */ { false, true, false, false, false, false },
13636 /* tcs */ { false, true, true, false, false, false },
13637 /* tes */ { false, false, true, true, false, false },
13638 /* gs */ { false, false, false, true, true, false },
13639 /* fs */ { false, false, false, false, true, true }
13642 static const bool require_modifications_out[6][6] = {
13643 /* cs */ { false, false, false, false, false, false },
13644 /* vs */ { false, true, true, false, false, false },
13645 /* tcs */ { false, false, true, true, false, false },
13646 /* tes */ { false, false, false, true, true, false },
13647 /* gs */ { false, false, false, false, true, true },
13648 /* fs */ { false, false, false, false, false, false }
13651 const GLchar* array = "";
13652 const GLchar* definition = block_definition_default;
13653 const GLchar* direction = "out";
13654 const GLchar* index = "";
13655 bool require_modifications = false;
13656 std::string source;
13657 testCase& test_case = m_test_cases[test_case_index];
13658 const GLchar* var_use = output_use;
13660 if (true == test_case.m_is_input)
13662 require_modifications = require_modifications_in[test_case.m_stage][stage];
13663 source = shaders_in[test_case.m_stage][stage];
13665 if (test_case.m_stage == stage)
13668 var_use = input_use;
13673 require_modifications = require_modifications_out[test_case.m_stage][stage];
13674 source = shaders_out[test_case.m_stage][stage];
13676 if (test_case.m_stage != stage)
13679 var_use = input_use;
13683 if (test_case.m_stage == stage)
13685 if (true == test_case.m_qualify_all)
13687 definition = block_definition_all;
13691 definition = block_definition_one;
13697 case Utils::Shader::FRAGMENT:
13699 case Utils::Shader::GEOMETRY:
13703 case Utils::Shader::TESS_CTRL:
13705 index = "[gl_InvocationID]";
13707 // geometry shader's input must have one more dimension than tessellation evaluation shader's output,
13708 // the GS input block is an array, so the DS output can't be declared as an array
13709 case Utils::Shader::TESS_EVAL:
13711 if (std::string(direction) == std::string("in")) // match HS output and DS input
13716 else // match DS output and GS input
13723 case Utils::Shader::VERTEX:
13726 TCU_FAIL("Invalid enum");
13729 if (true == require_modifications)
13731 size_t position = 0;
13734 Utils::replaceToken("DIRECTION", position, direction, source);
13736 Utils::replaceToken("BLOCK_DEFINITION", position, definition, source);
13738 Utils::replaceToken("ARRAY", position, array, source);
13739 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
13741 Utils::replaceAllTokens("INDEX", index, source);
13747 case Utils::Shader::FRAGMENT:
13750 case Utils::Shader::GEOMETRY:
13753 case Utils::Shader::TESS_CTRL:
13756 case Utils::Shader::TESS_EVAL:
13759 case Utils::Shader::VERTEX:
13763 TCU_FAIL("Invalid enum");
13770 /** Get description of test case
13772 * @param test_case_index Index of test case
13774 * @return Test case description
13776 std::string VaryingBlockMemberLocationsTest::getTestCaseName(GLuint test_case_index)
13778 std::stringstream stream;
13779 testCase& test_case = m_test_cases[test_case_index];
13781 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", direction: ";
13783 if (true == test_case.m_is_input)
13789 stream << "output";
13792 if (true == test_case.m_qualify_all)
13794 stream << ", all members qualified";
13798 stream << ", not all members qualified";
13801 return stream.str();
13804 /** Get number of test cases
13806 * @return Number of test cases
13808 GLuint VaryingBlockMemberLocationsTest::getTestCaseNumber()
13810 return static_cast<GLuint>(m_test_cases.size());
13813 /** Selects if "compute" stage is relevant for test
13819 bool VaryingBlockMemberLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
13824 /** Selects if compilation failure is expected result
13826 * @param test_case_index Index of test case
13828 * @return false when all members are qualified, true otherwise
13830 bool VaryingBlockMemberLocationsTest::isFailureExpected(GLuint test_case_index)
13832 return (true != m_test_cases[test_case_index].m_qualify_all);
13835 /** Prepare all test cases
13838 void VaryingBlockMemberLocationsTest::testInit()
13840 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
13842 if (Utils::Shader::COMPUTE == stage)
13847 testCase test_case_in_all = { true, true, (Utils::Shader::STAGES)stage };
13848 testCase test_case_in_one = { true, false, (Utils::Shader::STAGES)stage };
13849 testCase test_case_out_all = { false, true, (Utils::Shader::STAGES)stage };
13850 testCase test_case_out_one = { false, false, (Utils::Shader::STAGES)stage };
13852 if (Utils::Shader::VERTEX != stage)
13854 m_test_cases.push_back(test_case_in_all);
13855 m_test_cases.push_back(test_case_in_one);
13858 if (Utils::Shader::FRAGMENT != stage)
13860 m_test_cases.push_back(test_case_out_all);
13861 m_test_cases.push_back(test_case_out_one);
13868 * @param context Test framework context
13870 VaryingBlockAutomaticMemberLocationsTest::VaryingBlockAutomaticMemberLocationsTest(deqp::Context& context)
13871 : NegativeTestBase(
13872 context, "varying_block_automatic_member_locations",
13873 "Test verifies that compiler assigns subsequent locations to block members, even if this causes errors")
13877 /** Source for given test case and stage
13879 * @param test_case_index Index of test case
13880 * @param stage Shader stage
13882 * @return Shader source
13884 std::string VaryingBlockAutomaticMemberLocationsTest::getShaderSource(GLuint test_case_index,
13885 Utils::Shader::STAGES stage)
13887 static const GLchar* block_definition = "layout (location = 2) DIRECTION DBZ {\n"
13889 " vec4 gohan[4];\n"
13891 " layout (location = 1) vec4 chichi;\n"
13894 static const GLchar* input_use = " result += dbzINDEX.goku + dbzINDEX.gohan[0] + dbzINDEX.gohan[1] + "
13895 "dbzINDEX.gohan[3] + dbzINDEX.gohan[2] + dbzINDEX.goten + dbzINDEX.chichi + "
13897 static const GLchar* output_use = " dbzINDEX.goku = result;\n"
13898 " dbzINDEX.gohan[0] = result / 2;\n"
13899 " dbzINDEX.gohan[1] = result / 2.25;\n"
13900 " dbzINDEX.gohan[2] = result / 2.5;\n"
13901 " dbzINDEX.gohan[3] = result / 2.75;\n"
13902 " dbzINDEX.goten = result / 4 - dbzINDEX.gohan[0] - dbzINDEX.gohan[1] - "
13903 "dbzINDEX.gohan[2] - dbzINDEX.gohan[3];\n"
13904 " dbzINDEX.chichi = result / 8 - dbzINDEX.goten;\n"
13905 " dbzINDEX.pan = result / 16 - dbzINDEX.chichi;\n";
13906 static const GLchar* fs = "#version 430 core\n"
13907 "#extension GL_ARB_enhanced_layouts : require\n"
13910 "out vec4 fs_out;\n"
13914 " fs_out = gs_fs;\n"
13917 static const GLchar* fs_tested = "#version 430 core\n"
13918 "#extension GL_ARB_enhanced_layouts : require\n"
13923 "out vec4 fs_out;\n"
13927 " vec4 result = gs_fs;\n"
13931 " fs_out += result;\n"
13934 static const GLchar* gs = "#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"
13940 "in vec4 tes_gs[];\n"
13941 "out vec4 gs_fs;\n"
13945 " gs_fs = tes_gs[0];\n"
13946 " gl_Position = vec4(-1, -1, 0, 1);\n"
13948 " gs_fs = tes_gs[0];\n"
13949 " gl_Position = vec4(-1, 1, 0, 1);\n"
13951 " gs_fs = tes_gs[0];\n"
13952 " gl_Position = vec4(1, -1, 0, 1);\n"
13954 " gs_fs = tes_gs[0];\n"
13955 " gl_Position = vec4(1, 1, 0, 1);\n"
13959 static const GLchar* gs_tested = "#version 430 core\n"
13960 "#extension GL_ARB_enhanced_layouts : require\n"
13962 "layout(points) in;\n"
13963 "layout(triangle_strip, max_vertices = 4) out;\n"
13967 "in vec4 tes_gs[];\n"
13968 "out vec4 gs_fs;\n"
13972 " vec4 result = tes_gs[0];\n"
13976 " gs_fs = result;\n"
13977 " gl_Position = vec4(-1, -1, 0, 1);\n"
13979 " gs_fs = result;\n"
13980 " gl_Position = vec4(-1, 1, 0, 1);\n"
13982 " gs_fs = result;\n"
13983 " gl_Position = vec4(1, -1, 0, 1);\n"
13985 " gs_fs = result;\n"
13986 " gl_Position = vec4(1, 1, 0, 1);\n"
13990 static const GLchar* tcs = "#version 430 core\n"
13991 "#extension GL_ARB_enhanced_layouts : require\n"
13993 "layout(vertices = 1) out;\n"
13995 "in vec4 vs_tcs[];\n"
13996 "out vec4 tcs_tes[];\n"
14001 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
14003 " gl_TessLevelOuter[0] = 1.0;\n"
14004 " gl_TessLevelOuter[1] = 1.0;\n"
14005 " gl_TessLevelOuter[2] = 1.0;\n"
14006 " gl_TessLevelOuter[3] = 1.0;\n"
14007 " gl_TessLevelInner[0] = 1.0;\n"
14008 " gl_TessLevelInner[1] = 1.0;\n"
14011 static const GLchar* tcs_tested = "#version 430 core\n"
14012 "#extension GL_ARB_enhanced_layouts : require\n"
14014 "layout(vertices = 1) out;\n"
14018 "in vec4 vs_tcs[];\n"
14019 "out vec4 tcs_tes[];\n"
14023 " vec4 result = vs_tcs[gl_InvocationID];\n"
14027 " tcs_tes[gl_InvocationID] = result;\n"
14029 " gl_TessLevelOuter[0] = 1.0;\n"
14030 " gl_TessLevelOuter[1] = 1.0;\n"
14031 " gl_TessLevelOuter[2] = 1.0;\n"
14032 " gl_TessLevelOuter[3] = 1.0;\n"
14033 " gl_TessLevelInner[0] = 1.0;\n"
14034 " gl_TessLevelInner[1] = 1.0;\n"
14037 static const GLchar* tes = "#version 430 core\n"
14038 "#extension GL_ARB_enhanced_layouts : require\n"
14040 "layout(isolines, point_mode) in;\n"
14042 "in vec4 tcs_tes[];\n"
14043 "out vec4 tes_gs;\n"
14047 " tes_gs = tcs_tes[0];\n"
14050 static const GLchar* tes_tested = "#version 430 core\n"
14051 "#extension GL_ARB_enhanced_layouts : require\n"
14053 "layout(isolines, point_mode) in;\n"
14057 "in vec4 tcs_tes[];\n"
14058 "out vec4 tes_gs;\n"
14062 " vec4 result = tcs_tes[0];\n"
14066 " tes_gs += result;\n"
14069 static const GLchar* vs = "#version 430 core\n"
14070 "#extension GL_ARB_enhanced_layouts : require\n"
14073 "out vec4 vs_tcs;\n"
14077 " vs_tcs = in_vs;\n"
14080 static const GLchar* vs_tested = "#version 430 core\n"
14081 "#extension GL_ARB_enhanced_layouts : require\n"
14086 "out vec4 vs_tcs;\n"
14090 " vec4 result = in_vs;\n"
14094 " vs_tcs += result;\n"
14098 const GLchar* array = "";
14099 const GLchar* direction = "out";
14100 const GLchar* index = "";
14101 std::string source;
14102 testCase& test_case = m_test_cases[test_case_index];
14103 const GLchar* var_use = output_use;
14105 if (true == test_case.m_is_input)
14108 var_use = input_use;
14111 if (test_case.m_stage == stage)
14113 size_t position = 0;
14118 case Utils::Shader::FRAGMENT:
14119 source = fs_tested;
14121 case Utils::Shader::GEOMETRY:
14122 source = gs_tested;
14126 case Utils::Shader::TESS_CTRL:
14127 source = tcs_tested;
14129 index = "[gl_InvocationID]";
14131 case Utils::Shader::TESS_EVAL:
14132 source = tes_tested;
14136 case Utils::Shader::VERTEX:
14137 source = vs_tested;
14140 TCU_FAIL("Invalid enum");
14144 Utils::replaceToken("BLOCK_DEFINITION", position, block_definition, source);
14146 Utils::replaceToken("DIRECTION", position, direction, source);
14147 Utils::replaceToken("ARRAY", position, array, source);
14148 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
14150 Utils::replaceAllTokens("INDEX", index, source);
14156 case Utils::Shader::FRAGMENT:
14159 case Utils::Shader::GEOMETRY:
14162 case Utils::Shader::TESS_CTRL:
14165 case Utils::Shader::TESS_EVAL:
14168 case Utils::Shader::VERTEX:
14172 TCU_FAIL("Invalid enum");
14179 /** Get description of test case
14181 * @param test_case_index Index of test case
14183 * @return Test case description
14185 std::string VaryingBlockAutomaticMemberLocationsTest::getTestCaseName(GLuint test_case_index)
14187 std::stringstream stream;
14188 testCase& test_case = m_test_cases[test_case_index];
14190 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", direction: ";
14192 if (true == test_case.m_is_input)
14198 stream << "output";
14201 return stream.str();
14204 /** Get number of test cases
14206 * @return Number of test cases
14208 GLuint VaryingBlockAutomaticMemberLocationsTest::getTestCaseNumber()
14210 return static_cast<GLuint>(m_test_cases.size());
14213 /** Selects if "compute" stage is relevant for test
14219 bool VaryingBlockAutomaticMemberLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
14224 /** Prepare all test cases
14227 void VaryingBlockAutomaticMemberLocationsTest::testInit()
14229 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
14231 if (Utils::Shader::COMPUTE == stage)
14236 testCase test_case_in = { true, (Utils::Shader::STAGES)stage };
14237 testCase test_case_out = { false, (Utils::Shader::STAGES)stage };
14239 if (Utils::Shader::VERTEX != stage)
14241 m_test_cases.push_back(test_case_in);
14244 if (Utils::Shader::FRAGMENT != stage)
14246 m_test_cases.push_back(test_case_out);
14253 * @param context Test framework context
14255 VaryingLocationLimitTest::VaryingLocationLimitTest(deqp::Context& context)
14256 : NegativeTestBase(context, "varying_location_limit",
14257 "Test verifies that compiler reports error when location qualifier exceed limits")
14261 /** Source for given test case and stage
14263 * @param test_case_index Index of test case
14264 * @param stage Shader stage
14266 * @return Shader source
14268 std::string VaryingLocationLimitTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
14270 static const GLchar* var_definition = "layout (location = LAST + 1) FLAT DIRECTION TYPE gokuARRAY;\n";
14271 static const GLchar* input_use = " if (TYPE(0) == gokuINDEX)\n"
14273 " result += vec4(1, 0.5, 0.25, 0.125);\n"
14275 static const GLchar* output_use = " gokuINDEX = TYPE(0);\n"
14276 " if (vec4(0) == result)\n"
14278 " gokuINDEX = TYPE(1);\n"
14280 static const GLchar* fs = "#version 430 core\n"
14281 "#extension GL_ARB_enhanced_layouts : require\n"
14284 "out vec4 fs_out;\n"
14288 " fs_out = gs_fs;\n"
14291 static const GLchar* fs_tested = "#version 430 core\n"
14292 "#extension GL_ARB_enhanced_layouts : require\n"
14297 "out vec4 fs_out;\n"
14301 " vec4 result = gs_fs;\n"
14305 " fs_out += result;\n"
14308 static const GLchar* gs = "#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"
14314 "in vec4 tes_gs[];\n"
14315 "out vec4 gs_fs;\n"
14319 " gs_fs = tes_gs[0];\n"
14320 " gl_Position = vec4(-1, -1, 0, 1);\n"
14322 " gs_fs = tes_gs[0];\n"
14323 " gl_Position = vec4(-1, 1, 0, 1);\n"
14325 " gs_fs = tes_gs[0];\n"
14326 " gl_Position = vec4(1, -1, 0, 1);\n"
14328 " gs_fs = tes_gs[0];\n"
14329 " gl_Position = vec4(1, 1, 0, 1);\n"
14333 static const GLchar* gs_tested = "#version 430 core\n"
14334 "#extension GL_ARB_enhanced_layouts : require\n"
14336 "layout(points) in;\n"
14337 "layout(triangle_strip, max_vertices = 4) out;\n"
14341 "in vec4 tes_gs[];\n"
14342 "out vec4 gs_fs;\n"
14346 " vec4 result = tes_gs[0];\n"
14350 " gs_fs = result;\n"
14351 " gl_Position = vec4(-1, -1, 0, 1);\n"
14353 " gs_fs = result;\n"
14354 " gl_Position = vec4(-1, 1, 0, 1);\n"
14356 " gs_fs = result;\n"
14357 " gl_Position = vec4(1, -1, 0, 1);\n"
14359 " gs_fs = result;\n"
14360 " gl_Position = vec4(1, 1, 0, 1);\n"
14364 static const GLchar* tcs = "#version 430 core\n"
14365 "#extension GL_ARB_enhanced_layouts : require\n"
14367 "layout(vertices = 1) out;\n"
14369 "in vec4 vs_tcs[];\n"
14370 "out vec4 tcs_tes[];\n"
14375 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
14377 " gl_TessLevelOuter[0] = 1.0;\n"
14378 " gl_TessLevelOuter[1] = 1.0;\n"
14379 " gl_TessLevelOuter[2] = 1.0;\n"
14380 " gl_TessLevelOuter[3] = 1.0;\n"
14381 " gl_TessLevelInner[0] = 1.0;\n"
14382 " gl_TessLevelInner[1] = 1.0;\n"
14385 static const GLchar* tcs_tested = "#version 430 core\n"
14386 "#extension GL_ARB_enhanced_layouts : require\n"
14388 "layout(vertices = 1) out;\n"
14392 "in vec4 vs_tcs[];\n"
14393 "out vec4 tcs_tes[];\n"
14397 " vec4 result = vs_tcs[gl_InvocationID];\n"
14401 " tcs_tes[gl_InvocationID] = result;\n"
14403 " gl_TessLevelOuter[0] = 1.0;\n"
14404 " gl_TessLevelOuter[1] = 1.0;\n"
14405 " gl_TessLevelOuter[2] = 1.0;\n"
14406 " gl_TessLevelOuter[3] = 1.0;\n"
14407 " gl_TessLevelInner[0] = 1.0;\n"
14408 " gl_TessLevelInner[1] = 1.0;\n"
14411 static const GLchar* tes = "#version 430 core\n"
14412 "#extension GL_ARB_enhanced_layouts : require\n"
14414 "layout(isolines, point_mode) in;\n"
14416 "in vec4 tcs_tes[];\n"
14417 "out vec4 tes_gs;\n"
14421 " tes_gs = tcs_tes[0];\n"
14424 static const GLchar* tes_tested = "#version 430 core\n"
14425 "#extension GL_ARB_enhanced_layouts : require\n"
14427 "layout(isolines, point_mode) in;\n"
14431 "in vec4 tcs_tes[];\n"
14432 "out vec4 tes_gs;\n"
14436 " vec4 result = tcs_tes[0];\n"
14440 " tes_gs += result;\n"
14443 static const GLchar* vs = "#version 430 core\n"
14444 "#extension GL_ARB_enhanced_layouts : require\n"
14447 "out vec4 vs_tcs;\n"
14451 " vs_tcs = in_vs;\n"
14454 static const GLchar* vs_tested = "#version 430 core\n"
14455 "#extension GL_ARB_enhanced_layouts : require\n"
14460 "out vec4 vs_tcs;\n"
14464 " vec4 result = in_vs;\n"
14468 " vs_tcs += result;\n"
14472 std::string source;
14473 testCase& test_case = m_test_cases[test_case_index];
14475 if (test_case.m_stage == stage)
14477 const GLchar* array = "";
14479 const GLchar* direction = "in ";
14480 const GLchar* flat = "";
14481 const GLchar* index = "";
14482 GLuint last = getLastInputLocation(stage, test_case.m_type, 0);
14483 size_t position = 0;
14485 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
14486 Utils::Variable::STORAGE storage = Utils::Variable::VARYING_INPUT;
14487 const GLchar* var_use = input_use;
14489 if (false == test_case.m_is_input)
14492 last = getLastOutputLocation(stage, test_case.m_type, 0);
14493 storage = Utils::Variable::VARYING_OUTPUT;
14494 var_use = output_use;
14497 if (true == isFlatRequired(stage, test_case.m_type, storage))
14502 sprintf(buffer, "%d", last);
14506 case Utils::Shader::FRAGMENT:
14507 source = fs_tested;
14509 case Utils::Shader::GEOMETRY:
14510 source = gs_tested;
14514 case Utils::Shader::TESS_CTRL:
14515 source = tcs_tested;
14517 index = "[gl_InvocationID]";
14519 case Utils::Shader::TESS_EVAL:
14520 source = tes_tested;
14524 case Utils::Shader::VERTEX:
14525 source = vs_tested;
14528 TCU_FAIL("Invalid enum");
14532 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
14534 Utils::replaceToken("LAST", position, buffer, source);
14535 Utils::replaceToken("FLAT", position, flat, source);
14536 Utils::replaceToken("DIRECTION", position, direction, source);
14537 Utils::replaceToken("ARRAY", position, array, source);
14538 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
14540 Utils::replaceAllTokens("TYPE", type_name, source);
14541 Utils::replaceAllTokens("INDEX", index, source);
14547 case Utils::Shader::FRAGMENT:
14550 case Utils::Shader::GEOMETRY:
14553 case Utils::Shader::TESS_CTRL:
14556 case Utils::Shader::TESS_EVAL:
14559 case Utils::Shader::VERTEX:
14563 TCU_FAIL("Invalid enum");
14570 /** Get description of test case
14572 * @param test_case_index Index of test case
14574 * @return Test case description
14576 std::string VaryingLocationLimitTest::getTestCaseName(GLuint test_case_index)
14578 std::stringstream stream;
14579 testCase& test_case = m_test_cases[test_case_index];
14581 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
14582 << " type: " << test_case.m_type.GetGLSLTypeName() << ", direction: ";
14584 if (true == test_case.m_is_input)
14590 stream << "output";
14593 return stream.str();
14596 /** Get number of test cases
14598 * @return Number of test cases
14600 GLuint VaryingLocationLimitTest::getTestCaseNumber()
14602 return static_cast<GLuint>(m_test_cases.size());
14605 /** Selects if "compute" stage is relevant for test
14611 bool VaryingLocationLimitTest::isComputeRelevant(GLuint /* test_case_index */)
14616 /** Prepare all test cases
14619 void VaryingLocationLimitTest::testInit()
14621 const GLuint n_types = getTypesNumber();
14623 for (GLuint i = 0; i < n_types; ++i)
14625 const Utils::Type& type = getType(i);
14627 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
14629 if (Utils::Shader::COMPUTE == stage)
14634 testCase test_case_in = { true, type, (Utils::Shader::STAGES)stage };
14635 testCase test_case_out = { false, type, (Utils::Shader::STAGES)stage };
14637 m_test_cases.push_back(test_case_in);
14639 if (Utils::Shader::FRAGMENT != stage)
14641 m_test_cases.push_back(test_case_out);
14649 * @param context Test framework context
14651 VaryingComponentsTest::VaryingComponentsTest(deqp::Context& context)
14652 : VaryingLocationsTest(context, "varying_components",
14653 "Test verifies that input and output components are respected")
14659 * @param context Test framework context
14660 * @param test_name Name of test
14661 * @param test_description Description of test
14663 VaryingComponentsTest::VaryingComponentsTest(deqp::Context& context, const glw::GLchar* test_name,
14664 const glw::GLchar* test_description)
14665 : VaryingLocationsTest(context, test_name, test_description)
14669 /** Get interface of program
14671 * @param test_case_index Test case
14672 * @param program_interface Interface of program
14673 * @param varying_passthrough Collection of connections between in and out variables
14675 void VaryingComponentsTest::getProgramInterface(GLuint test_case_index, Utils::ProgramInterface& program_interface,
14676 Utils::VaryingPassthrough& varying_passthrough)
14678 GLuint array_length = getArrayLength();
14679 const testCase& test_case = m_test_cases[test_case_index];
14680 const Utils::Type vector_type = Utils::Type::GetType(test_case.m_type, 1, 4);
14681 Utils::ShaderInterface si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
14683 /* Zero means no array, however we still need at least 1 slot of data */
14684 if (0 == array_length)
14689 /* Generate data */
14690 const std::vector<GLubyte>& data = vector_type.GenerateDataPacked();
14691 const size_t data_size = data.size();
14693 /* Prepare data for variables */
14694 m_data.resize(array_length * data_size);
14696 GLubyte* dst = &m_data[0];
14697 const GLubyte* src = &data[0];
14699 for (GLuint i = 0; i < array_length; ++i)
14701 memcpy(dst + data_size * i, src, data_size);
14704 /* Prepare interface for each stage */
14705 prepareShaderStage(Utils::Shader::FRAGMENT, vector_type, program_interface, test_case, varying_passthrough);
14706 prepareShaderStage(Utils::Shader::GEOMETRY, vector_type, program_interface, test_case, varying_passthrough);
14707 prepareShaderStage(Utils::Shader::TESS_CTRL, vector_type, program_interface, test_case, varying_passthrough);
14708 prepareShaderStage(Utils::Shader::TESS_EVAL, vector_type, program_interface, test_case, varying_passthrough);
14709 prepareShaderStage(Utils::Shader::VERTEX, vector_type, program_interface, test_case, varying_passthrough);
14714 * @param test_case_index Index of test case
14716 * @return Name of type test in test_case_index
14718 std::string VaryingComponentsTest::getTestCaseName(glw::GLuint test_case_index)
14722 const testCase& test_case = m_test_cases[test_case_index];
14726 switch (test_case.m_type)
14728 case Utils::Type::Double:
14729 name.append(Utils::Type::_double.GetGLSLTypeName());
14731 case Utils::Type::Float:
14732 name.append(Utils::Type::_float.GetGLSLTypeName());
14734 case Utils::Type::Int:
14735 name.append(Utils::Type::_int.GetGLSLTypeName());
14737 case Utils::Type::Uint:
14738 name.append(Utils::Type::uint.GetGLSLTypeName());
14742 name.append(", layout: ");
14744 switch (test_case.m_layout)
14747 name.append("GVEC4");
14750 name.append("SCALAR_GVEC3");
14753 name.append("GVEC3_SCALAR");
14756 name.append("GVEC2_GVEC2");
14758 case GVEC2_SCALAR_SCALAR:
14759 name.append("GVEC2_SCALAR_SCALAR");
14761 case SCALAR_GVEC2_SCALAR:
14762 name.append("SCALAR_GVEC2_SCALAR");
14764 case SCALAR_SCALAR_GVEC2:
14765 name.append("SCALAR_SCALAR_GVEC2");
14767 case SCALAR_SCALAR_SCALAR_SCALAR:
14768 name.append("SCALAR_SCALAR_SCALAR_SCALAR");
14775 /** Returns number of types to test
14777 * @return Number of types, 34
14779 glw::GLuint VaryingComponentsTest::getTestCaseNumber()
14781 return static_cast<GLuint>(m_test_cases.size());
14784 /* Prepare test cases */
14785 void VaryingComponentsTest::testInit()
14787 m_test_cases.push_back(testCase(GVEC4, Utils::Type::Double));
14788 m_test_cases.push_back(testCase(SCALAR_GVEC3, Utils::Type::Double));
14789 m_test_cases.push_back(testCase(GVEC3_SCALAR, Utils::Type::Double));
14790 m_test_cases.push_back(testCase(GVEC2_GVEC2, Utils::Type::Double));
14791 m_test_cases.push_back(testCase(GVEC2_SCALAR_SCALAR, Utils::Type::Double));
14792 m_test_cases.push_back(testCase(SCALAR_GVEC2_SCALAR, Utils::Type::Double));
14793 m_test_cases.push_back(testCase(SCALAR_SCALAR_GVEC2, Utils::Type::Double));
14794 m_test_cases.push_back(testCase(SCALAR_SCALAR_SCALAR_SCALAR, Utils::Type::Double));
14796 m_test_cases.push_back(testCase(GVEC4, Utils::Type::Float));
14797 m_test_cases.push_back(testCase(SCALAR_GVEC3, Utils::Type::Float));
14798 m_test_cases.push_back(testCase(GVEC3_SCALAR, Utils::Type::Float));
14799 m_test_cases.push_back(testCase(GVEC2_GVEC2, Utils::Type::Float));
14800 m_test_cases.push_back(testCase(GVEC2_SCALAR_SCALAR, Utils::Type::Float));
14801 m_test_cases.push_back(testCase(SCALAR_GVEC2_SCALAR, Utils::Type::Float));
14802 m_test_cases.push_back(testCase(SCALAR_SCALAR_GVEC2, Utils::Type::Float));
14803 m_test_cases.push_back(testCase(SCALAR_SCALAR_SCALAR_SCALAR, Utils::Type::Float));
14805 m_test_cases.push_back(testCase(GVEC4, Utils::Type::Int));
14806 m_test_cases.push_back(testCase(SCALAR_GVEC3, Utils::Type::Int));
14807 m_test_cases.push_back(testCase(GVEC3_SCALAR, Utils::Type::Int));
14808 m_test_cases.push_back(testCase(GVEC2_GVEC2, Utils::Type::Int));
14809 m_test_cases.push_back(testCase(GVEC2_SCALAR_SCALAR, Utils::Type::Int));
14810 m_test_cases.push_back(testCase(SCALAR_GVEC2_SCALAR, Utils::Type::Int));
14811 m_test_cases.push_back(testCase(SCALAR_SCALAR_GVEC2, Utils::Type::Int));
14812 m_test_cases.push_back(testCase(SCALAR_SCALAR_SCALAR_SCALAR, Utils::Type::Int));
14814 m_test_cases.push_back(testCase(GVEC4, Utils::Type::Uint));
14815 m_test_cases.push_back(testCase(SCALAR_GVEC3, Utils::Type::Uint));
14816 m_test_cases.push_back(testCase(GVEC3_SCALAR, Utils::Type::Uint));
14817 m_test_cases.push_back(testCase(GVEC2_GVEC2, Utils::Type::Uint));
14818 m_test_cases.push_back(testCase(GVEC2_SCALAR_SCALAR, Utils::Type::Uint));
14819 m_test_cases.push_back(testCase(SCALAR_GVEC2_SCALAR, Utils::Type::Uint));
14820 m_test_cases.push_back(testCase(SCALAR_SCALAR_GVEC2, Utils::Type::Uint));
14821 m_test_cases.push_back(testCase(SCALAR_SCALAR_SCALAR_SCALAR, Utils::Type::Uint));
14824 /** Inform that test use components
14830 bool VaryingComponentsTest::useComponentQualifier(glw::GLuint /* test_case_index */)
14835 /** Get length of arrays that should be used during test
14837 * @return 0u - no array at all
14839 GLuint VaryingComponentsTest::getArrayLength()
14844 std::string VaryingComponentsTest::prepareGlobals(GLuint last_in_location, GLuint last_out_location)
14846 std::string globals = VaryingLocationsTest::prepareGlobals(last_in_location, last_out_location);
14848 globals.append("const uint comp_x = 0u;\n"
14849 "const uint comp_y = 1u;\n"
14850 "const uint comp_z = 2u;\n"
14851 "const uint comp_w = 3u;\n");
14859 std::string VaryingComponentsTest::prepareName(const glw::GLchar* name, glw::GLint location, glw::GLint component,
14860 Utils::Shader::STAGES stage, Utils::Variable::STORAGE storage)
14863 std::string result = "PREFIXNAME_lLOCATION_cCOMPONENT";
14864 size_t position = 0;
14865 const GLchar* prefix = Utils::ProgramInterface::GetStagePrefix(stage, storage);
14867 Utils::replaceToken("PREFIX", position, prefix, result);
14868 Utils::replaceToken("NAME", position, name, result);
14870 sprintf(buffer, "%d", location);
14871 Utils::replaceToken("LOCATION", position, buffer, result);
14873 sprintf(buffer, "%d", component);
14874 Utils::replaceToken("COMPONENT", position, buffer, result);
14879 std::string VaryingComponentsTest::prepareQualifiers(const glw::GLchar* location, const glw::GLchar* component,
14880 const glw::GLchar* interpolation)
14882 size_t position = 0;
14883 std::string qualifiers = "layout (location = LOCATION, component = COMPONENT) INTERPOLATION";
14885 Utils::replaceToken("LOCATION", position, location, qualifiers);
14886 Utils::replaceToken("COMPONENT", position, component, qualifiers);
14887 Utils::replaceToken("INTERPOLATION", position, interpolation, qualifiers);
14895 void VaryingComponentsTest::prepareShaderStage(Utils::Shader::STAGES stage, const Utils::Type& vector_type,
14896 Utils::ProgramInterface& program_interface, const testCase& test_case,
14897 Utils::VaryingPassthrough& varying_passthrough)
14899 const GLuint array_length = getArrayLength();
14900 const Utils::Type& basic_type = Utils::Type::GetType(vector_type.m_basic_type, 1 /* n_cols */, 1 /* n_rows */);
14901 descriptor desc_in[8];
14902 descriptor desc_out[8];
14903 const GLuint first_in_loc = 0;
14904 const GLuint first_out_loc = 0;
14905 const GLchar* interpolation = "";
14906 const GLuint last_in_loc = getLastInputLocation(stage, vector_type, array_length);
14907 GLuint last_out_loc = 0;
14909 Utils::ShaderInterface& si = program_interface.GetShaderInterface(stage);
14911 /* Select interpolation */
14912 if ((Utils::Shader::FRAGMENT == stage) || (Utils::Shader::GEOMETRY == stage))
14914 interpolation = " flat";
14917 if (Utils::Shader::FRAGMENT != stage)
14919 last_out_loc = getLastOutputLocation(stage, vector_type, array_length);
14922 switch (test_case.m_layout)
14926 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 4, "gvec4");
14927 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 4, "gvec4");
14929 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 4, "gvec4");
14930 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 4, "gvec4");
14934 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "scalar");
14935 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "scalar");
14936 desc_in[2].assign(1, "comp_y", first_in_loc, "first_input_location", 3, "gvec3");
14937 desc_in[3].assign(1, "comp_y", last_in_loc, "last_input_location", 3, "gvec3");
14939 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "scalar");
14940 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "scalar");
14941 desc_out[2].assign(1, "comp_y", first_out_loc, "first_output_location", 3, "gvec3");
14942 desc_out[3].assign(1, "comp_y", last_out_loc, "last_output_location", 3, "gvec3");
14946 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 3, "gvec3");
14947 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 3, "gvec3");
14948 desc_in[2].assign(3, "comp_w", first_in_loc, "first_input_location", 1, "scalar");
14949 desc_in[3].assign(3, "comp_w", last_in_loc, "last_input_location", 1, "scalar");
14951 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 3, "gvec3");
14952 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 3, "gvec3");
14953 desc_out[2].assign(3, "comp_w", first_out_loc, "first_output_location", 1, "scalar");
14954 desc_out[3].assign(3, "comp_w", last_out_loc, "last_output_location", 1, "scalar");
14958 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 2, "gvec2");
14959 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 2, "gvec2");
14960 desc_in[2].assign(2, "comp_z", first_in_loc, "first_input_location", 2, "gvec2");
14961 desc_in[3].assign(2, "comp_z", last_in_loc, "last_input_location", 2, "gvec2");
14963 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 2, "gvec2");
14964 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 2, "gvec2");
14965 desc_out[2].assign(2, "comp_z", first_out_loc, "first_output_location", 2, "gvec2");
14966 desc_out[3].assign(2, "comp_z", last_out_loc, "last_output_location", 2, "gvec2");
14968 case GVEC2_SCALAR_SCALAR:
14970 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 2, "gvec2");
14971 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 2, "gvec2");
14972 desc_in[2].assign(2, "comp_z", first_in_loc, "first_input_location", 1, "scalar");
14973 desc_in[3].assign(2, "comp_z", last_in_loc, "last_input_location", 1, "scalar");
14974 desc_in[4].assign(3, "comp_w", first_in_loc, "first_input_location", 1, "scalar");
14975 desc_in[5].assign(3, "comp_w", last_in_loc, "last_input_location", 1, "scalar");
14977 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 2, "gvec2");
14978 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 2, "gvec2");
14979 desc_out[2].assign(2, "comp_z", first_out_loc, "first_output_location", 1, "scalar");
14980 desc_out[3].assign(2, "comp_z", last_out_loc, "last_output_location", 1, "scalar");
14981 desc_out[4].assign(3, "comp_w", first_out_loc, "first_output_location", 1, "scalar");
14982 desc_out[5].assign(3, "comp_w", last_out_loc, "last_output_location", 1, "scalar");
14984 case SCALAR_GVEC2_SCALAR:
14986 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "scalar");
14987 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "scalar");
14988 desc_in[2].assign(1, "comp_y", first_in_loc, "first_input_location", 2, "gvec2");
14989 desc_in[3].assign(1, "comp_y", last_in_loc, "last_input_location", 2, "gvec2");
14990 desc_in[4].assign(3, "comp_w", first_in_loc, "first_input_location", 1, "scalar");
14991 desc_in[5].assign(3, "comp_w", last_in_loc, "last_input_location", 1, "scalar");
14993 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "scalar");
14994 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "scalar");
14995 desc_out[2].assign(1, "comp_y", first_out_loc, "first_output_location", 2, "gvec2");
14996 desc_out[3].assign(1, "comp_y", last_out_loc, "last_output_location", 2, "gvec2");
14997 desc_out[4].assign(3, "comp_w", first_out_loc, "first_output_location", 1, "scalar");
14998 desc_out[5].assign(3, "comp_w", last_out_loc, "last_output_location", 1, "scalar");
15000 case SCALAR_SCALAR_GVEC2:
15002 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "scalar");
15003 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "scalar");
15004 desc_in[2].assign(1, "comp_y", first_in_loc, "first_input_location", 1, "scalar");
15005 desc_in[3].assign(1, "comp_y", last_in_loc, "last_input_location", 1, "scalar");
15006 desc_in[4].assign(2, "comp_z", first_in_loc, "first_input_location", 2, "gvec2");
15007 desc_in[5].assign(2, "comp_z", last_in_loc, "last_input_location", 2, "gvec2");
15009 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "scalar");
15010 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "scalar");
15011 desc_out[2].assign(1, "comp_y", first_out_loc, "first_output_location", 1, "scalar");
15012 desc_out[3].assign(1, "comp_y", last_out_loc, "last_output_location", 1, "scalar");
15013 desc_out[4].assign(2, "comp_z", first_out_loc, "first_output_location", 2, "gvec2");
15014 desc_out[5].assign(2, "comp_z", last_out_loc, "last_output_location", 2, "gvec2");
15016 case SCALAR_SCALAR_SCALAR_SCALAR:
15018 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "scalar");
15019 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "scalar");
15020 desc_in[2].assign(1, "comp_y", first_in_loc, "first_input_location", 1, "scalar");
15021 desc_in[3].assign(1, "comp_y", last_in_loc, "last_input_location", 1, "scalar");
15022 desc_in[4].assign(2, "comp_z", first_in_loc, "first_input_location", 1, "scalar");
15023 desc_in[5].assign(2, "comp_z", last_in_loc, "last_input_location", 1, "scalar");
15024 desc_in[6].assign(3, "comp_w", first_in_loc, "first_input_location", 1, "scalar");
15025 desc_in[7].assign(3, "comp_w", last_in_loc, "last_input_location", 1, "scalar");
15027 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "scalar");
15028 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "scalar");
15029 desc_out[2].assign(1, "comp_y", first_out_loc, "first_output_location", 1, "scalar");
15030 desc_out[3].assign(1, "comp_y", last_out_loc, "last_output_location", 1, "scalar");
15031 desc_out[4].assign(2, "comp_z", first_out_loc, "first_output_location", 1, "scalar");
15032 desc_out[5].assign(2, "comp_z", last_out_loc, "last_output_location", 1, "scalar");
15033 desc_out[6].assign(3, "comp_w", first_out_loc, "first_output_location", 1, "scalar");
15034 desc_out[7].assign(3, "comp_w", last_out_loc, "last_output_location", 1, "scalar");
15038 for (GLuint i = 0; i < n_desc; ++i)
15040 const descriptor& in_desc = desc_in[i];
15042 Utils::Variable* in =
15043 prepareVarying(basic_type, in_desc, interpolation, si, stage, Utils::Variable::VARYING_INPUT);
15045 if (Utils::Shader::FRAGMENT != stage)
15047 const descriptor& out_desc = desc_out[i];
15049 Utils::Variable* out =
15050 prepareVarying(basic_type, out_desc, interpolation, si, stage, Utils::Variable::VARYING_OUTPUT);
15052 varying_passthrough.Add(stage, in, out);
15056 si.m_globals = prepareGlobals(last_in_loc, last_out_loc);
15062 Utils::Variable* VaryingComponentsTest::prepareVarying(const Utils::Type& basic_type, const descriptor& desc,
15063 const GLchar* interpolation, Utils::ShaderInterface& si,
15064 Utils::Shader::STAGES stage, Utils::Variable::STORAGE storage)
15066 const GLuint array_length = getArrayLength();
15067 const GLuint component_size = basic_type.GetSize();
15068 const std::string& name = prepareName(desc.m_name, desc.m_location, desc.m_component, stage, storage);
15069 const GLuint offset = desc.m_component * component_size;
15070 const std::string& qual = prepareQualifiers(desc.m_location_str, desc.m_component_str, interpolation);
15071 const GLuint size = desc.m_n_rows * component_size;
15072 const Utils::Type& type = Utils::Type::GetType(basic_type.m_basic_type, 1 /* n_columns */, desc.m_n_rows);
15073 Utils::Variable* var = 0;
15075 if (Utils::Variable::VARYING_INPUT == storage)
15077 var = si.Input(name.c_str(), qual.c_str() /* qualifiers */, desc.m_component /* expected_componenet */,
15078 desc.m_location /* expected_location */, type, /* built_in_type */
15079 GL_FALSE /* normalized */, array_length /* n_array_elements */, 0u /* stride */,
15080 offset /* offset */, (GLvoid*)&m_data[offset] /* data */, size /* data_size */);
15084 var = si.Output(name.c_str(), qual.c_str() /* qualifiers */, desc.m_component /* expected_componenet */,
15085 desc.m_location /* expected_location */, type, /* built_in_type */
15086 GL_FALSE /* normalized */, array_length /* n_array_elements */, 0u /* stride */,
15087 offset /* offset */, (GLvoid*)&m_data[offset] /* data */, size /* data_size */);
15093 void VaryingComponentsTest::descriptor::assign(glw::GLint component, const glw::GLchar* component_str,
15094 glw::GLint location, const glw::GLchar* location_str, glw::GLuint n_rows,
15095 const glw::GLchar* name)
15097 m_component = component;
15098 m_component_str = component_str;
15099 m_location = location;
15100 m_location_str = location_str;
15105 VaryingComponentsTest::testCase::testCase(COMPONENTS_LAYOUT layout, Utils::Type::TYPES type)
15106 : m_layout(layout), m_type(type)
15112 * @param context Test framework context
15114 VaryingArrayComponentsTest::VaryingArrayComponentsTest(deqp::Context& context)
15115 : VaryingComponentsTest(context, "varying_array_components",
15116 "Test verifies that input and output components are respected for arrays")
15120 /** Get length of arrays that should be used during test
15124 GLuint VaryingArrayComponentsTest::getArrayLength()
15131 * @param context Test framework context
15133 VaryingExceedingComponentsTest::VaryingExceedingComponentsTest(deqp::Context& context)
15134 : NegativeTestBase(context, "varying_exceeding_components",
15135 "Test verifies that compiler reports error when component qualifier exceed limits")
15139 /** Source for given test case and stage
15141 * @param test_case_index Index of test case
15142 * @param stage Shader stage
15144 * @return Shader source
15146 std::string VaryingExceedingComponentsTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
15148 static const GLchar* var_definition_arr =
15149 "layout (location = 1, component = COMPONENT) flat DIRECTION TYPE gokuARRAY[1];\n";
15150 static const GLchar* var_definition_one =
15151 "layout (location = 1, component = COMPONENT) flat DIRECTION TYPE gokuARRAY;\n";
15152 static const GLchar* input_use_arr = " if (TYPE(0) == gokuINDEX[0])\n"
15154 " result += vec4(1, 0.5, 0.25, 0.125);\n"
15156 static const GLchar* input_use_one = " if (TYPE(0) == gokuINDEX)\n"
15158 " result += vec4(1, 0.5, 0.25, 0.125);\n"
15160 static const GLchar* output_use_arr = " gokuINDEX[0] = TYPE(0);\n"
15161 " if (vec4(0) == result)\n"
15163 " gokuINDEX[0] = TYPE(1);\n"
15165 static const GLchar* output_use_one = " gokuINDEX = TYPE(0);\n"
15166 " if (vec4(0) == result)\n"
15168 " gokuINDEX = TYPE(1);\n"
15170 static const GLchar* fs = "#version 430 core\n"
15171 "#extension GL_ARB_enhanced_layouts : require\n"
15174 "out vec4 fs_out;\n"
15178 " fs_out = gs_fs;\n"
15181 static const GLchar* fs_tested = "#version 430 core\n"
15182 "#extension GL_ARB_enhanced_layouts : require\n"
15187 "out vec4 fs_out;\n"
15191 " vec4 result = gs_fs;\n"
15195 " fs_out += result;\n"
15198 static const GLchar* gs = "#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"
15204 "in vec4 tes_gs[];\n"
15205 "out vec4 gs_fs;\n"
15209 " gs_fs = tes_gs[0];\n"
15210 " gl_Position = vec4(-1, -1, 0, 1);\n"
15212 " gs_fs = tes_gs[0];\n"
15213 " gl_Position = vec4(-1, 1, 0, 1);\n"
15215 " gs_fs = tes_gs[0];\n"
15216 " gl_Position = vec4(1, -1, 0, 1);\n"
15218 " gs_fs = tes_gs[0];\n"
15219 " gl_Position = vec4(1, 1, 0, 1);\n"
15223 static const GLchar* gs_tested = "#version 430 core\n"
15224 "#extension GL_ARB_enhanced_layouts : require\n"
15226 "layout(points) in;\n"
15227 "layout(triangle_strip, max_vertices = 4) out;\n"
15231 "in vec4 tes_gs[];\n"
15232 "out vec4 gs_fs;\n"
15236 " vec4 result = tes_gs[0];\n"
15240 " gs_fs = result;\n"
15241 " gl_Position = vec4(-1, -1, 0, 1);\n"
15243 " gs_fs = result;\n"
15244 " gl_Position = vec4(-1, 1, 0, 1);\n"
15246 " gs_fs = result;\n"
15247 " gl_Position = vec4(1, -1, 0, 1);\n"
15249 " gs_fs = result;\n"
15250 " gl_Position = vec4(1, 1, 0, 1);\n"
15254 static const GLchar* tcs = "#version 430 core\n"
15255 "#extension GL_ARB_enhanced_layouts : require\n"
15257 "layout(vertices = 1) out;\n"
15259 "in vec4 vs_tcs[];\n"
15260 "out vec4 tcs_tes[];\n"
15265 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
15267 " gl_TessLevelOuter[0] = 1.0;\n"
15268 " gl_TessLevelOuter[1] = 1.0;\n"
15269 " gl_TessLevelOuter[2] = 1.0;\n"
15270 " gl_TessLevelOuter[3] = 1.0;\n"
15271 " gl_TessLevelInner[0] = 1.0;\n"
15272 " gl_TessLevelInner[1] = 1.0;\n"
15275 static const GLchar* tcs_tested = "#version 430 core\n"
15276 "#extension GL_ARB_enhanced_layouts : require\n"
15278 "layout(vertices = 1) out;\n"
15282 "in vec4 vs_tcs[];\n"
15283 "out vec4 tcs_tes[];\n"
15287 " vec4 result = vs_tcs[gl_InvocationID];\n"
15291 " tcs_tes[gl_InvocationID] = result;\n"
15293 " gl_TessLevelOuter[0] = 1.0;\n"
15294 " gl_TessLevelOuter[1] = 1.0;\n"
15295 " gl_TessLevelOuter[2] = 1.0;\n"
15296 " gl_TessLevelOuter[3] = 1.0;\n"
15297 " gl_TessLevelInner[0] = 1.0;\n"
15298 " gl_TessLevelInner[1] = 1.0;\n"
15301 static const GLchar* tes = "#version 430 core\n"
15302 "#extension GL_ARB_enhanced_layouts : require\n"
15304 "layout(isolines, point_mode) in;\n"
15306 "in vec4 tcs_tes[];\n"
15307 "out vec4 tes_gs;\n"
15311 " tes_gs = tcs_tes[0];\n"
15314 static const GLchar* tes_tested = "#version 430 core\n"
15315 "#extension GL_ARB_enhanced_layouts : require\n"
15317 "layout(isolines, point_mode) in;\n"
15321 "in vec4 tcs_tes[];\n"
15322 "out vec4 tes_gs;\n"
15326 " vec4 result = tcs_tes[0];\n"
15330 " tes_gs += result;\n"
15333 static const GLchar* vs = "#version 430 core\n"
15334 "#extension GL_ARB_enhanced_layouts : require\n"
15337 "out vec4 vs_tcs;\n"
15341 " vs_tcs = in_vs;\n"
15344 static const GLchar* vs_tested = "#version 430 core\n"
15345 "#extension GL_ARB_enhanced_layouts : require\n"
15350 "out vec4 vs_tcs;\n"
15354 " vec4 result = in_vs;\n"
15358 " vs_tcs += result;\n"
15362 std::string source;
15363 testCase& test_case = m_test_cases[test_case_index];
15365 if (test_case.m_stage == stage)
15367 const GLchar* array = "";
15369 const GLchar* var_definition = 0;
15370 const GLchar* direction = "in ";
15371 const GLchar* index = "";
15372 size_t position = 0;
15374 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
15375 const GLchar* var_use = 0;
15377 if (false == test_case.m_is_input)
15381 if (false == test_case.m_is_array)
15383 var_definition = var_definition_one;
15384 var_use = output_use_one;
15388 var_definition = var_definition_arr;
15389 var_use = output_use_arr;
15394 if (false == test_case.m_is_array)
15396 var_definition = var_definition_one;
15397 var_use = input_use_one;
15401 var_definition = var_definition_arr;
15402 var_use = input_use_arr;
15406 sprintf(buffer, "%d", test_case.m_component);
15410 case Utils::Shader::FRAGMENT:
15411 source = fs_tested;
15413 case Utils::Shader::GEOMETRY:
15414 source = gs_tested;
15418 case Utils::Shader::TESS_CTRL:
15419 source = tcs_tested;
15421 index = "[gl_InvocationID]";
15423 case Utils::Shader::TESS_EVAL:
15424 source = tes_tested;
15428 case Utils::Shader::VERTEX:
15429 source = vs_tested;
15432 TCU_FAIL("Invalid enum");
15436 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
15438 Utils::replaceToken("COMPONENT", position, buffer, source);
15439 Utils::replaceToken("DIRECTION", position, direction, source);
15440 Utils::replaceToken("ARRAY", position, array, source);
15441 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
15443 Utils::replaceAllTokens("TYPE", type_name, source);
15444 Utils::replaceAllTokens("INDEX", index, source);
15450 case Utils::Shader::FRAGMENT:
15453 case Utils::Shader::GEOMETRY:
15456 case Utils::Shader::TESS_CTRL:
15459 case Utils::Shader::TESS_EVAL:
15462 case Utils::Shader::VERTEX:
15466 TCU_FAIL("Invalid enum");
15473 /** Get description of test case
15475 * @param test_case_index Index of test case
15477 * @return Test case description
15479 std::string VaryingExceedingComponentsTest::getTestCaseName(GLuint test_case_index)
15481 std::stringstream stream;
15482 testCase& test_case = m_test_cases[test_case_index];
15484 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
15485 << " type: " << test_case.m_type.GetGLSLTypeName();
15487 if (true == test_case.m_is_array)
15492 stream << ", direction: ";
15494 if (true == test_case.m_is_input)
15500 stream << "output";
15503 stream << ", component: " << test_case.m_component;
15505 return stream.str();
15508 /** Get number of test cases
15510 * @return Number of test cases
15512 GLuint VaryingExceedingComponentsTest::getTestCaseNumber()
15514 return static_cast<GLuint>(m_test_cases.size());
15517 /** Selects if "compute" stage is relevant for test
15523 bool VaryingExceedingComponentsTest::isComputeRelevant(GLuint /* test_case_index */)
15528 /** Prepare all test cases
15531 void VaryingExceedingComponentsTest::testInit()
15533 static const GLuint n_components_per_location = 4;
15534 const GLuint n_types = getTypesNumber();
15536 for (GLuint i = 0; i < n_types; ++i)
15538 const Utils::Type& type = getType(i);
15539 const GLuint n_req_components = type.m_n_rows;
15540 const GLuint valid_component = n_components_per_location - n_req_components;
15541 const GLuint invalid_component = valid_component + 1;
15543 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
15545 if (Utils::Shader::COMPUTE == stage)
15550 /* Component cannot be used for matrices */
15551 if (1 != type.m_n_columns)
15556 testCase test_case_in_arr = { invalid_component, true, true, (Utils::Shader::STAGES)stage, type };
15557 testCase test_case_in_one = { invalid_component, true, false, (Utils::Shader::STAGES)stage, type };
15558 testCase test_case_out_arr = { invalid_component, false, true, (Utils::Shader::STAGES)stage, type };
15559 testCase test_case_out_one = { invalid_component, false, false, (Utils::Shader::STAGES)stage, type };
15561 m_test_cases.push_back(test_case_in_arr);
15562 m_test_cases.push_back(test_case_in_one);
15564 if (Utils::Shader::FRAGMENT != stage)
15566 m_test_cases.push_back(test_case_out_arr);
15567 m_test_cases.push_back(test_case_out_one);
15575 * @param context Test framework context
15577 VaryingComponentWithoutLocationTest::VaryingComponentWithoutLocationTest(deqp::Context& context)
15578 : NegativeTestBase(context, "varying_component_without_location",
15579 "Test verifies that compiler reports error when component qualifier is used without location")
15583 /** Source for given test case and stage
15585 * @param test_case_index Index of test case
15586 * @param stage Shader stage
15588 * @return Shader source
15590 std::string VaryingComponentWithoutLocationTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
15592 static const GLchar* var_definition = "layout (component = COMPONENT) FLAT DIRECTION TYPE gokuARRAY;\n";
15593 static const GLchar* input_use = " if (TYPE(0) == gokuINDEX)\n"
15595 " result += vec4(1, 0.5, 0.25, 0.125);\n"
15597 static const GLchar* output_use = " gokuINDEX = TYPE(0);\n"
15598 " if (vec4(0) == result)\n"
15600 " gokuINDEX = TYPE(1);\n"
15602 static const GLchar* fs = "#version 430 core\n"
15603 "#extension GL_ARB_enhanced_layouts : require\n"
15606 "out vec4 fs_out;\n"
15610 " fs_out = gs_fs;\n"
15613 static const GLchar* fs_tested = "#version 430 core\n"
15614 "#extension GL_ARB_enhanced_layouts : require\n"
15619 "out vec4 fs_out;\n"
15623 " vec4 result = gs_fs;\n"
15627 " fs_out = result;\n"
15630 static const GLchar* gs = "#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"
15636 "in vec4 tes_gs[];\n"
15637 "out vec4 gs_fs;\n"
15641 " gs_fs = tes_gs[0];\n"
15642 " gl_Position = vec4(-1, -1, 0, 1);\n"
15644 " gs_fs = tes_gs[0];\n"
15645 " gl_Position = vec4(-1, 1, 0, 1);\n"
15647 " gs_fs = tes_gs[0];\n"
15648 " gl_Position = vec4(1, -1, 0, 1);\n"
15650 " gs_fs = tes_gs[0];\n"
15651 " gl_Position = vec4(1, 1, 0, 1);\n"
15655 static const GLchar* gs_tested = "#version 430 core\n"
15656 "#extension GL_ARB_enhanced_layouts : require\n"
15658 "layout(points) in;\n"
15659 "layout(triangle_strip, max_vertices = 4) out;\n"
15663 "in vec4 tes_gs[];\n"
15664 "out vec4 gs_fs;\n"
15668 " vec4 result = tes_gs[0];\n"
15672 " gs_fs = result;\n"
15673 " gl_Position = vec4(-1, -1, 0, 1);\n"
15675 " gs_fs = result;\n"
15676 " gl_Position = vec4(-1, 1, 0, 1);\n"
15678 " gs_fs = result;\n"
15679 " gl_Position = vec4(1, -1, 0, 1);\n"
15681 " gs_fs = result;\n"
15682 " gl_Position = vec4(1, 1, 0, 1);\n"
15686 static const GLchar* tcs = "#version 430 core\n"
15687 "#extension GL_ARB_enhanced_layouts : require\n"
15689 "layout(vertices = 1) out;\n"
15691 "in vec4 vs_tcs[];\n"
15692 "out vec4 tcs_tes[];\n"
15697 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
15699 " gl_TessLevelOuter[0] = 1.0;\n"
15700 " gl_TessLevelOuter[1] = 1.0;\n"
15701 " gl_TessLevelOuter[2] = 1.0;\n"
15702 " gl_TessLevelOuter[3] = 1.0;\n"
15703 " gl_TessLevelInner[0] = 1.0;\n"
15704 " gl_TessLevelInner[1] = 1.0;\n"
15707 static const GLchar* tcs_tested = "#version 430 core\n"
15708 "#extension GL_ARB_enhanced_layouts : require\n"
15710 "layout(vertices = 1) out;\n"
15714 "in vec4 vs_tcs[];\n"
15715 "out vec4 tcs_tes[];\n"
15719 " vec4 result = vs_tcs[gl_InvocationID];\n"
15723 " tcs_tes[gl_InvocationID] = result;\n"
15725 " gl_TessLevelOuter[0] = 1.0;\n"
15726 " gl_TessLevelOuter[1] = 1.0;\n"
15727 " gl_TessLevelOuter[2] = 1.0;\n"
15728 " gl_TessLevelOuter[3] = 1.0;\n"
15729 " gl_TessLevelInner[0] = 1.0;\n"
15730 " gl_TessLevelInner[1] = 1.0;\n"
15733 static const GLchar* tes = "#version 430 core\n"
15734 "#extension GL_ARB_enhanced_layouts : require\n"
15736 "layout(isolines, point_mode) in;\n"
15738 "in vec4 tcs_tes[];\n"
15739 "out vec4 tes_gs;\n"
15743 " tes_gs = tcs_tes[0];\n"
15746 static const GLchar* tes_tested = "#version 430 core\n"
15747 "#extension GL_ARB_enhanced_layouts : require\n"
15749 "layout(isolines, point_mode) in;\n"
15753 "in vec4 tcs_tes[];\n"
15754 "out vec4 tes_gs;\n"
15758 " vec4 result = tcs_tes[0];\n"
15762 " tes_gs = result;\n"
15765 static const GLchar* vs = "#version 430 core\n"
15766 "#extension GL_ARB_enhanced_layouts : require\n"
15769 "out vec4 vs_tcs;\n"
15773 " vs_tcs = in_vs;\n"
15776 static const GLchar* vs_tested = "#version 430 core\n"
15777 "#extension GL_ARB_enhanced_layouts : require\n"
15782 "out vec4 vs_tcs;\n"
15786 " vec4 result = in_vs;\n"
15790 " vs_tcs = result;\n"
15794 std::string source;
15795 testCase& test_case = m_test_cases[test_case_index];
15797 if (test_case.m_stage == stage)
15799 const GLchar* array = "";
15801 const GLchar* direction = "in ";
15802 const GLchar* index = "";
15803 size_t position = 0;
15805 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
15806 const GLchar* var_use = input_use;
15807 const GLchar* flat = "flat";
15809 if (false == test_case.m_is_input)
15812 var_use = output_use;
15815 sprintf(buffer, "%d", test_case.m_component);
15819 case Utils::Shader::FRAGMENT:
15820 source = fs_tested;
15822 case Utils::Shader::GEOMETRY:
15823 source = gs_tested;
15827 case Utils::Shader::TESS_CTRL:
15828 source = tcs_tested;
15830 index = "[gl_InvocationID]";
15832 case Utils::Shader::TESS_EVAL:
15833 source = tes_tested;
15837 case Utils::Shader::VERTEX:
15838 source = vs_tested;
15842 TCU_FAIL("Invalid enum");
15846 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
15848 Utils::replaceToken("COMPONENT", position, buffer, source);
15849 Utils::replaceToken("FLAT", position, flat, source);
15850 Utils::replaceToken("DIRECTION", position, direction, source);
15851 Utils::replaceToken("ARRAY", position, array, source);
15852 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
15854 Utils::replaceAllTokens("TYPE", type_name, source);
15855 Utils::replaceAllTokens("INDEX", index, source);
15861 case Utils::Shader::FRAGMENT:
15864 case Utils::Shader::GEOMETRY:
15867 case Utils::Shader::TESS_CTRL:
15870 case Utils::Shader::TESS_EVAL:
15873 case Utils::Shader::VERTEX:
15877 TCU_FAIL("Invalid enum");
15884 /** Get description of test case
15886 * @param test_case_index Index of test case
15888 * @return Test case description
15890 std::string VaryingComponentWithoutLocationTest::getTestCaseName(GLuint test_case_index)
15892 std::stringstream stream;
15893 testCase& test_case = m_test_cases[test_case_index];
15895 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
15896 << " type: " << test_case.m_type.GetGLSLTypeName() << ", direction: ";
15898 if (true == test_case.m_is_input)
15904 stream << "output";
15907 stream << ", component: " << test_case.m_component;
15909 return stream.str();
15912 /** Get number of test cases
15914 * @return Number of test cases
15916 GLuint VaryingComponentWithoutLocationTest::getTestCaseNumber()
15918 return static_cast<GLuint>(m_test_cases.size());
15921 /** Selects if "compute" stage is relevant for test
15927 bool VaryingComponentWithoutLocationTest::isComputeRelevant(GLuint /* test_case_index */)
15932 /** Prepare all test cases
15935 void VaryingComponentWithoutLocationTest::testInit()
15937 static const GLuint n_components_per_location = 4;
15938 const GLuint n_types = getTypesNumber();
15940 for (GLuint i = 0; i < n_types; ++i)
15942 const Utils::Type& type = getType(i);
15943 const GLuint n_req_components = type.m_n_rows;
15944 const GLuint valid_component = n_components_per_location - n_req_components;
15946 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
15948 if (Utils::Shader::COMPUTE == stage)
15953 /* Component cannot be used for matrices */
15954 if (1 != type.m_n_columns)
15959 testCase test_case_in = { valid_component, true, (Utils::Shader::STAGES)stage, type };
15960 testCase test_case_out = { valid_component, false, (Utils::Shader::STAGES)stage, type };
15962 m_test_cases.push_back(test_case_in);
15964 if (Utils::Shader::FRAGMENT != stage)
15966 m_test_cases.push_back(test_case_out);
15974 * @param context Test framework context
15976 VaryingComponentOfInvalidTypeTest::VaryingComponentOfInvalidTypeTest(deqp::Context& context)
15977 : NegativeTestBase(context, "varying_component_of_invalid_type",
15978 "Test verifies that compiler reports error when component qualifier is used for invalid type")
15982 /** Source for given test case and stage
15984 * @param test_case_index Index of test case
15985 * @param stage Shader stage
15987 * @return Shader source
15989 std::string VaryingComponentOfInvalidTypeTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
15991 static const GLchar* block_definition_arr = "layout (location = 1, component = COMPONENT) flat DIRECTION Goku {\n"
15993 "} gokuARRAY[1];\n";
15994 static const GLchar* block_definition_one = "layout (location = 1, component = COMPONENT) flat DIRECTION Goku {\n"
15997 static const GLchar* matrix_definition_arr =
15998 "layout (location = 1, component = COMPONENT) flat DIRECTION TYPE gokuARRAY[1];\n";
15999 static const GLchar* matrix_definition_one =
16000 "layout (location = 1, component = COMPONENT) flat DIRECTION TYPE gokuARRAY;\n";
16001 static const GLchar* struct_definition_arr =
16006 "layout (location = 1, component = COMPONENT) flat DIRECTION Goku gokuARRAY[1];\n";
16007 static const GLchar* struct_definition_one =
16012 "layout (location = 1, component = COMPONENT) flat DIRECTION Goku gokuARRAY;\n";
16013 static const GLchar* matrix_input_use_arr = " if (TYPE(0) == gokuINDEX[0])\n"
16015 " result += vec4(1, 0.5, 0.25, 0.125);\n"
16017 static const GLchar* matrix_input_use_one = " if (TYPE(0) == gokuINDEX)\n"
16019 " result += vec4(1, 0.5, 0.25, 0.125);\n"
16021 static const GLchar* matrix_output_use_arr = " gokuINDEX[0] = TYPE(0);\n"
16022 " if (vec4(0) == result)\n"
16024 " gokuINDEX[0] = TYPE(1);\n"
16026 static const GLchar* matrix_output_use_one = " gokuINDEX = TYPE(0);\n"
16027 " if (vec4(0) == result)\n"
16029 " gokuINDEX = TYPE(1);\n"
16031 static const GLchar* member_input_use_arr = " if (TYPE(0) == gokuINDEX[0].member)\n"
16033 " result += vec4(1, 0.5, 0.25, 0.125);\n"
16035 static const GLchar* member_input_use_one = " if (TYPE(0) == gokuINDEX.member)\n"
16037 " result += vec4(1, 0.5, 0.25, 0.125);\n"
16039 static const GLchar* member_output_use_arr = " gokuINDEX[0].member = TYPE(0);\n"
16040 " if (vec4(0) == result)\n"
16042 " gokuINDEX[0].member = TYPE(1);\n"
16044 static const GLchar* member_output_use_one = " gokuINDEX.member = TYPE(0);\n"
16045 " if (vec4(0) == result)\n"
16047 " gokuINDEX.member = TYPE(1);\n"
16049 static const GLchar* fs = "#version 430 core\n"
16050 "#extension GL_ARB_enhanced_layouts : require\n"
16053 "out vec4 fs_out;\n"
16057 " fs_out = gs_fs;\n"
16060 static const GLchar* fs_tested = "#version 430 core\n"
16061 "#extension GL_ARB_enhanced_layouts : require\n"
16066 "out vec4 fs_out;\n"
16070 " vec4 result = gs_fs;\n"
16074 " fs_out += result;\n"
16077 static const GLchar* gs = "#version 430 core\n"
16078 "#extension GL_ARB_enhanced_layouts : require\n"
16080 "layout(points) in;\n"
16081 "layout(triangle_strip, max_vertices = 4) out;\n"
16083 "in vec4 tes_gs[];\n"
16084 "out vec4 gs_fs;\n"
16088 " gs_fs = tes_gs[0];\n"
16089 " gl_Position = vec4(-1, -1, 0, 1);\n"
16091 " gs_fs = tes_gs[0];\n"
16092 " gl_Position = vec4(-1, 1, 0, 1);\n"
16094 " gs_fs = tes_gs[0];\n"
16095 " gl_Position = vec4(1, -1, 0, 1);\n"
16097 " gs_fs = tes_gs[0];\n"
16098 " gl_Position = vec4(1, 1, 0, 1);\n"
16102 static const GLchar* gs_tested = "#version 430 core\n"
16103 "#extension GL_ARB_enhanced_layouts : require\n"
16105 "layout(points) in;\n"
16106 "layout(triangle_strip, max_vertices = 4) out;\n"
16110 "in vec4 tes_gs[];\n"
16111 "out vec4 gs_fs;\n"
16115 " vec4 result = tes_gs[0];\n"
16119 " gs_fs = result;\n"
16120 " gl_Position = vec4(-1, -1, 0, 1);\n"
16122 " gs_fs = result;\n"
16123 " gl_Position = vec4(-1, 1, 0, 1);\n"
16125 " gs_fs = result;\n"
16126 " gl_Position = vec4(1, -1, 0, 1);\n"
16128 " gs_fs = result;\n"
16129 " gl_Position = vec4(1, 1, 0, 1);\n"
16133 static const GLchar* tcs = "#version 430 core\n"
16134 "#extension GL_ARB_enhanced_layouts : require\n"
16136 "layout(vertices = 1) out;\n"
16138 "in vec4 vs_tcs[];\n"
16139 "out vec4 tcs_tes[];\n"
16144 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
16146 " gl_TessLevelOuter[0] = 1.0;\n"
16147 " gl_TessLevelOuter[1] = 1.0;\n"
16148 " gl_TessLevelOuter[2] = 1.0;\n"
16149 " gl_TessLevelOuter[3] = 1.0;\n"
16150 " gl_TessLevelInner[0] = 1.0;\n"
16151 " gl_TessLevelInner[1] = 1.0;\n"
16154 static const GLchar* tcs_tested = "#version 430 core\n"
16155 "#extension GL_ARB_enhanced_layouts : require\n"
16157 "layout(vertices = 1) out;\n"
16161 "in vec4 vs_tcs[];\n"
16162 "out vec4 tcs_tes[];\n"
16166 " vec4 result = vs_tcs[gl_InvocationID];\n"
16170 " tcs_tes[gl_InvocationID] = result;\n"
16172 " gl_TessLevelOuter[0] = 1.0;\n"
16173 " gl_TessLevelOuter[1] = 1.0;\n"
16174 " gl_TessLevelOuter[2] = 1.0;\n"
16175 " gl_TessLevelOuter[3] = 1.0;\n"
16176 " gl_TessLevelInner[0] = 1.0;\n"
16177 " gl_TessLevelInner[1] = 1.0;\n"
16180 static const GLchar* tes = "#version 430 core\n"
16181 "#extension GL_ARB_enhanced_layouts : require\n"
16183 "layout(isolines, point_mode) in;\n"
16185 "in vec4 tcs_tes[];\n"
16186 "out vec4 tes_gs;\n"
16190 " tes_gs = tcs_tes[0];\n"
16193 static const GLchar* tes_tested = "#version 430 core\n"
16194 "#extension GL_ARB_enhanced_layouts : require\n"
16196 "layout(isolines, point_mode) in;\n"
16200 "in vec4 tcs_tes[];\n"
16201 "out vec4 tes_gs;\n"
16205 " vec4 result = tcs_tes[0];\n"
16209 " tes_gs += result;\n"
16212 static const GLchar* vs = "#version 430 core\n"
16213 "#extension GL_ARB_enhanced_layouts : require\n"
16216 "out vec4 vs_tcs;\n"
16220 " vs_tcs = in_vs;\n"
16223 static const GLchar* vs_tested = "#version 430 core\n"
16224 "#extension GL_ARB_enhanced_layouts : require\n"
16229 "out vec4 vs_tcs;\n"
16233 " vec4 result = in_vs;\n"
16237 " vs_tcs += result;\n"
16241 std::string source;
16242 testCase& test_case = m_test_cases[test_case_index];
16244 if (test_case.m_stage == stage)
16246 const GLchar* array = "";
16248 const GLchar* var_definition = 0;
16249 const GLchar* direction = "in ";
16250 const GLchar* index = "";
16251 size_t position = 0;
16253 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
16254 const GLchar* var_use = 0;
16256 if (false == test_case.m_is_input)
16260 if (false == test_case.m_is_array)
16262 switch (test_case.m_case)
16265 var_definition = block_definition_one;
16266 var_use = member_output_use_one;
16269 var_definition = matrix_definition_one;
16270 var_use = matrix_output_use_one;
16273 var_definition = struct_definition_one;
16274 var_use = member_output_use_one;
16277 TCU_FAIL("Invalid enum");
16282 switch (test_case.m_case)
16285 var_definition = block_definition_arr;
16286 var_use = member_output_use_arr;
16289 var_definition = matrix_definition_arr;
16290 var_use = matrix_output_use_arr;
16293 var_definition = struct_definition_arr;
16294 var_use = member_output_use_arr;
16297 TCU_FAIL("Invalid enum");
16303 if (false == test_case.m_is_array)
16305 switch (test_case.m_case)
16308 var_definition = block_definition_one;
16309 var_use = member_input_use_one;
16312 var_definition = matrix_definition_one;
16313 var_use = matrix_input_use_one;
16316 var_definition = struct_definition_one;
16317 var_use = member_input_use_one;
16320 TCU_FAIL("Invalid enum");
16325 switch (test_case.m_case)
16328 var_definition = block_definition_arr;
16329 var_use = member_input_use_arr;
16332 var_definition = matrix_definition_arr;
16333 var_use = matrix_input_use_arr;
16336 var_definition = struct_definition_arr;
16337 var_use = member_input_use_arr;
16340 TCU_FAIL("Invalid enum");
16345 sprintf(buffer, "%d", test_case.m_component);
16349 case Utils::Shader::FRAGMENT:
16350 source = fs_tested;
16352 case Utils::Shader::GEOMETRY:
16353 source = gs_tested;
16357 case Utils::Shader::TESS_CTRL:
16358 source = tcs_tested;
16360 index = "[gl_InvocationID]";
16362 case Utils::Shader::TESS_EVAL:
16363 source = tes_tested;
16367 case Utils::Shader::VERTEX:
16368 source = vs_tested;
16371 TCU_FAIL("Invalid enum");
16375 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
16377 Utils::replaceToken("COMPONENT", position, buffer, source);
16378 Utils::replaceToken("DIRECTION", position, direction, source);
16379 Utils::replaceToken("ARRAY", position, array, source);
16380 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
16382 Utils::replaceAllTokens("TYPE", type_name, source);
16383 Utils::replaceAllTokens("INDEX", index, source);
16389 case Utils::Shader::FRAGMENT:
16392 case Utils::Shader::GEOMETRY:
16395 case Utils::Shader::TESS_CTRL:
16398 case Utils::Shader::TESS_EVAL:
16401 case Utils::Shader::VERTEX:
16405 TCU_FAIL("Invalid enum");
16412 /** Get description of test case
16414 * @param test_case_index Index of test case
16416 * @return Test case description
16418 std::string VaryingComponentOfInvalidTypeTest::getTestCaseName(GLuint test_case_index)
16420 std::stringstream stream;
16421 testCase& test_case = m_test_cases[test_case_index];
16423 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
16424 << " type: " << test_case.m_type.GetGLSLTypeName();
16426 if (true == test_case.m_is_array)
16431 stream << ", direction: ";
16433 if (true == test_case.m_is_input)
16439 stream << "output";
16442 stream << ", component: " << test_case.m_component;
16444 return stream.str();
16447 /** Get number of test cases
16449 * @return Number of test cases
16451 GLuint VaryingComponentOfInvalidTypeTest::getTestCaseNumber()
16453 return static_cast<GLuint>(m_test_cases.size());
16456 /** Selects if "compute" stage is relevant for test
16462 bool VaryingComponentOfInvalidTypeTest::isComputeRelevant(GLuint /* test_case_index */)
16467 /** Prepare all test cases
16470 void VaryingComponentOfInvalidTypeTest::testInit()
16472 static const GLuint n_components_per_location = 4;
16473 const GLuint n_types = getTypesNumber();
16475 for (GLuint i = 0; i < n_types; ++i)
16477 const Utils::Type& type = getType(i);
16478 const GLuint n_req_components = type.m_n_rows;
16479 const GLuint valid_component = n_components_per_location - n_req_components;
16481 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
16483 if (Utils::Shader::COMPUTE == stage)
16488 /* Use different CASE for matrices */
16489 if (1 != type.m_n_columns)
16491 testCase test_case_in_arr = { MATRIX, valid_component, true, true, (Utils::Shader::STAGES)stage, type };
16492 testCase test_case_in_one = {
16493 MATRIX, valid_component, false, true, (Utils::Shader::STAGES)stage, type
16495 testCase test_case_out_arr = {
16496 MATRIX, valid_component, true, false, (Utils::Shader::STAGES)stage, type
16498 testCase test_case_out_one = {
16499 MATRIX, valid_component, false, false, (Utils::Shader::STAGES)stage, type
16502 m_test_cases.push_back(test_case_in_arr);
16503 m_test_cases.push_back(test_case_in_one);
16505 if (Utils::Shader::FRAGMENT != stage)
16507 m_test_cases.push_back(test_case_out_arr);
16508 m_test_cases.push_back(test_case_out_one);
16513 for (GLuint c = BLOCK; c < MAX_CASES; ++c)
16515 testCase test_case_in_arr = { (CASES)c, valid_component, true, true, (Utils::Shader::STAGES)stage,
16517 testCase test_case_in_one = { (CASES)c, valid_component, false, true, (Utils::Shader::STAGES)stage,
16519 testCase test_case_out_arr = { (CASES)c, valid_component, true, false, (Utils::Shader::STAGES)stage,
16521 testCase test_case_out_one = {
16522 (CASES)c, valid_component, false, false, (Utils::Shader::STAGES)stage, type
16525 if (Utils::Shader::VERTEX != stage)
16527 m_test_cases.push_back(test_case_in_arr);
16528 m_test_cases.push_back(test_case_in_one);
16531 if (Utils::Shader::FRAGMENT != stage)
16533 m_test_cases.push_back(test_case_out_arr);
16534 m_test_cases.push_back(test_case_out_one);
16544 * @param context Test framework context
16546 InputComponentAliasingTest::InputComponentAliasingTest(deqp::Context& context)
16547 : NegativeTestBase(context, "input_component_aliasing",
16548 "Test verifies that compiler reports component aliasing as error")
16552 /** Source for given test case and stage
16554 * @param test_case_index Index of test case
16555 * @param stage Shader stage
16557 * @return Shader source
16559 std::string InputComponentAliasingTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
16561 static const GLchar* var_definition = "layout (location = 1, component = COMPONENT) FLAT in TYPE gohanARRAY;\n"
16562 "layout (location = 1, component = COMPONENT) FLAT in TYPE gotenARRAY;\n";
16563 static const GLchar* test_one = " if (TYPE(0) == gohanINDEX)\n"
16565 " result += vec4(1, 0.5, 0.25, 0.125);\n"
16567 static const GLchar* test_both = " if (TYPE(0) == gohanINDEX)\n"
16569 " result = vec4(goten.xxxx);\n"
16571 static const GLchar* fs = "#version 430 core\n"
16572 "#extension GL_ARB_enhanced_layouts : require\n"
16575 "out vec4 fs_out;\n"
16579 " fs_out = gs_fs;\n"
16582 static const GLchar* fs_tested = "#version 430 core\n"
16583 "#extension GL_ARB_enhanced_layouts : require\n"
16588 "out vec4 fs_out;\n"
16592 " vec4 result = gs_fs;\n"
16596 " fs_out += result;\n"
16599 static const GLchar* gs = "#version 430 core\n"
16600 "#extension GL_ARB_enhanced_layouts : require\n"
16602 "layout(points) in;\n"
16603 "layout(triangle_strip, max_vertices = 4) out;\n"
16605 "in vec4 tes_gs[];\n"
16606 "out vec4 gs_fs;\n"
16610 " gs_fs = tes_gs[0];\n"
16611 " gl_Position = vec4(-1, -1, 0, 1);\n"
16613 " gs_fs = tes_gs[0];\n"
16614 " gl_Position = vec4(-1, 1, 0, 1);\n"
16616 " gs_fs = tes_gs[0];\n"
16617 " gl_Position = vec4(1, -1, 0, 1);\n"
16619 " gs_fs = tes_gs[0];\n"
16620 " gl_Position = vec4(1, 1, 0, 1);\n"
16624 static const GLchar* gs_tested = "#version 430 core\n"
16625 "#extension GL_ARB_enhanced_layouts : require\n"
16627 "layout(points) in;\n"
16628 "layout(triangle_strip, max_vertices = 4) out;\n"
16632 "in vec4 tes_gs[];\n"
16633 "out vec4 gs_fs;\n"
16637 " vec4 result = tes_gs[0];\n"
16641 " gs_fs = result;\n"
16642 " gl_Position = vec4(-1, -1, 0, 1);\n"
16644 " gs_fs = result;\n"
16645 " gl_Position = vec4(-1, 1, 0, 1);\n"
16647 " gs_fs = result;\n"
16648 " gl_Position = vec4(1, -1, 0, 1);\n"
16650 " gs_fs = result;\n"
16651 " gl_Position = vec4(1, 1, 0, 1);\n"
16655 static const GLchar* tcs = "#version 430 core\n"
16656 "#extension GL_ARB_enhanced_layouts : require\n"
16658 "layout(vertices = 1) out;\n"
16660 "in vec4 vs_tcs[];\n"
16661 "out vec4 tcs_tes[];\n"
16666 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
16668 " gl_TessLevelOuter[0] = 1.0;\n"
16669 " gl_TessLevelOuter[1] = 1.0;\n"
16670 " gl_TessLevelOuter[2] = 1.0;\n"
16671 " gl_TessLevelOuter[3] = 1.0;\n"
16672 " gl_TessLevelInner[0] = 1.0;\n"
16673 " gl_TessLevelInner[1] = 1.0;\n"
16676 static const GLchar* tcs_tested = "#version 430 core\n"
16677 "#extension GL_ARB_enhanced_layouts : require\n"
16679 "layout(vertices = 1) out;\n"
16683 "in vec4 vs_tcs[];\n"
16684 "out vec4 tcs_tes[];\n"
16688 " vec4 result = vs_tcs[gl_InvocationID];\n"
16692 " tcs_tes[gl_InvocationID] = result;\n"
16694 " gl_TessLevelOuter[0] = 1.0;\n"
16695 " gl_TessLevelOuter[1] = 1.0;\n"
16696 " gl_TessLevelOuter[2] = 1.0;\n"
16697 " gl_TessLevelOuter[3] = 1.0;\n"
16698 " gl_TessLevelInner[0] = 1.0;\n"
16699 " gl_TessLevelInner[1] = 1.0;\n"
16702 static const GLchar* tes = "#version 430 core\n"
16703 "#extension GL_ARB_enhanced_layouts : require\n"
16705 "layout(isolines, point_mode) in;\n"
16707 "in vec4 tcs_tes[];\n"
16708 "out vec4 tes_gs;\n"
16712 " tes_gs = tcs_tes[0];\n"
16715 static const GLchar* tes_tested = "#version 430 core\n"
16716 "#extension GL_ARB_enhanced_layouts : require\n"
16718 "layout(isolines, point_mode) in;\n"
16722 "in vec4 tcs_tes[];\n"
16723 "out vec4 tes_gs;\n"
16727 " vec4 result = tcs_tes[0];\n"
16731 " tes_gs += result;\n"
16734 static const GLchar* vs = "#version 430 core\n"
16735 "#extension GL_ARB_enhanced_layouts : require\n"
16738 "out vec4 vs_tcs;\n"
16742 " vs_tcs = in_vs;\n"
16745 static const GLchar* vs_tested = "#version 430 core\n"
16746 "#extension GL_ARB_enhanced_layouts : require\n"
16751 "out vec4 vs_tcs;\n"
16755 " vec4 result = in_vs;\n"
16759 " vs_tcs += result;\n"
16763 std::string source;
16764 testCase& test_case = m_test_cases[test_case_index];
16766 if (test_case.m_stage == stage)
16768 const GLchar* array = "";
16769 GLchar buffer_gohan[16];
16770 GLchar buffer_goten[16];
16771 const GLchar* flat = "";
16772 const GLchar* index = "";
16773 const bool is_flat_req = isFlatRequired(stage, test_case.m_type, Utils::Variable::VARYING_INPUT);
16774 size_t position = 0;
16776 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
16777 const GLchar* var_use = test_one;
16779 if (true == test_case.m_use_both)
16781 var_use = test_both;
16784 if (true == is_flat_req)
16789 sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
16790 sprintf(buffer_goten, "%d", test_case.m_component_goten);
16794 case Utils::Shader::FRAGMENT:
16795 source = fs_tested;
16797 case Utils::Shader::GEOMETRY:
16798 source = gs_tested;
16802 case Utils::Shader::TESS_CTRL:
16803 source = tcs_tested;
16805 index = "[gl_InvocationID]";
16807 case Utils::Shader::TESS_EVAL:
16808 source = tes_tested;
16812 case Utils::Shader::VERTEX:
16813 source = vs_tested;
16816 TCU_FAIL("Invalid enum");
16820 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
16822 Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
16823 Utils::replaceToken("ARRAY", position, array, source);
16824 Utils::replaceToken("COMPONENT", position, buffer_goten, source);
16825 Utils::replaceToken("ARRAY", position, array, source);
16826 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
16828 Utils::replaceAllTokens("FLAT", flat, source);
16829 Utils::replaceAllTokens("TYPE", type_name, source);
16830 Utils::replaceAllTokens("INDEX", index, source);
16836 case Utils::Shader::FRAGMENT:
16839 case Utils::Shader::GEOMETRY:
16842 case Utils::Shader::TESS_CTRL:
16845 case Utils::Shader::TESS_EVAL:
16848 case Utils::Shader::VERTEX:
16852 TCU_FAIL("Invalid enum");
16859 /** Get description of test case
16861 * @param test_case_index Index of test case
16863 * @return Test case description
16865 std::string InputComponentAliasingTest::getTestCaseName(GLuint test_case_index)
16867 std::stringstream stream;
16868 testCase& test_case = m_test_cases[test_case_index];
16870 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
16871 << " type: " << test_case.m_type.GetGLSLTypeName() << ", components: " << test_case.m_component_gohan
16872 << " & " << test_case.m_component_goten;
16874 return stream.str();
16877 /** Get number of test cases
16879 * @return Number of test cases
16881 GLuint InputComponentAliasingTest::getTestCaseNumber()
16883 return static_cast<GLuint>(m_test_cases.size());
16886 /** Selects if "compute" stage is relevant for test
16892 bool InputComponentAliasingTest::isComputeRelevant(GLuint /* test_case_index */)
16897 /** Selects if compilation failure is expected result
16899 * @param test_case_index Index of test case
16901 * @return false for VS that use only single variable, true otherwise
16903 bool InputComponentAliasingTest::isFailureExpected(GLuint test_case_index)
16905 testCase& test_case = m_test_cases[test_case_index];
16907 return !((Utils::Shader::VERTEX == test_case.m_stage) && (false == test_case.m_use_both));
16910 /** Prepare all test cases
16913 void InputComponentAliasingTest::testInit()
16915 static const GLuint n_components_per_location = 4;
16916 const GLuint n_types = getTypesNumber();
16918 for (GLuint i = 0; i < n_types; ++i)
16920 const Utils::Type& type = getType(i);
16921 const GLuint n_req_components = type.m_n_rows;
16922 const GLuint valid_component = n_components_per_location - n_req_components;
16924 /* Skip matrices */
16925 if (1 != type.m_n_columns)
16930 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
16932 if (Utils::Shader::COMPUTE == stage)
16937 for (GLuint gohan = 0; gohan <= valid_component; ++gohan)
16939 const GLint first_aliasing = gohan - n_req_components + 1;
16940 const GLint last_aliasing = gohan + n_req_components - 1;
16942 const GLuint goten_start = std::max(0, first_aliasing);
16943 const GLuint goten_stop = std::min((GLint)valid_component, last_aliasing);
16945 for (GLuint goten = goten_start; goten <= goten_stop; ++goten)
16947 testCase test_case = { gohan, goten, (Utils::Shader::STAGES)stage, type, false };
16949 m_test_cases.push_back(test_case);
16951 if (Utils::Shader::VERTEX == test_case.m_stage)
16953 test_case.m_use_both = true;
16955 m_test_cases.push_back(test_case);
16965 * @param context Test framework context
16967 OutputComponentAliasingTest::OutputComponentAliasingTest(deqp::Context& context)
16968 : NegativeTestBase(context, "output_component_aliasing",
16969 "Test verifies that compiler reports component aliasing as error")
16973 /** Source for given test case and stage
16975 * @param test_case_index Index of test case
16976 * @param stage Shader stage
16978 * @return Shader source
16980 std::string OutputComponentAliasingTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
16982 static const GLchar* var_definition = "layout (location = 1, component = COMPONENT) flat out TYPE gohanARRAY;\n"
16983 "layout (location = 1, component = COMPONENT) flat out TYPE gotenARRAY;\n";
16984 static const GLchar* l_test = " gohanINDEX = TYPE(1);\n"
16985 " gotenINDEX = TYPE(0);\n";
16986 static const GLchar* fs = "#version 430 core\n"
16987 "#extension GL_ARB_enhanced_layouts : require\n"
16990 "out vec4 fs_out;\n"
16994 " fs_out = gs_fs;\n"
16997 static const GLchar* fs_tested = "#version 430 core\n"
16998 "#extension GL_ARB_enhanced_layouts : require\n"
17003 "out vec4 fs_out;\n"
17007 " vec4 result = gs_fs;\n"
17011 " fs_out += result;\n"
17014 static const GLchar* gs = "#version 430 core\n"
17015 "#extension GL_ARB_enhanced_layouts : require\n"
17017 "layout(points) in;\n"
17018 "layout(triangle_strip, max_vertices = 4) out;\n"
17020 "in vec4 tes_gs[];\n"
17021 "out vec4 gs_fs;\n"
17025 " gs_fs = tes_gs[0];\n"
17026 " gl_Position = vec4(-1, -1, 0, 1);\n"
17028 " gs_fs = tes_gs[0];\n"
17029 " gl_Position = vec4(-1, 1, 0, 1);\n"
17031 " gs_fs = tes_gs[0];\n"
17032 " gl_Position = vec4(1, -1, 0, 1);\n"
17034 " gs_fs = tes_gs[0];\n"
17035 " gl_Position = vec4(1, 1, 0, 1);\n"
17039 static const GLchar* gs_tested = "#version 430 core\n"
17040 "#extension GL_ARB_enhanced_layouts : require\n"
17042 "layout(points) in;\n"
17043 "layout(triangle_strip, max_vertices = 4) out;\n"
17047 "in vec4 tes_gs[];\n"
17048 "out vec4 gs_fs;\n"
17052 " vec4 result = tes_gs[0];\n"
17056 " gs_fs = result;\n"
17057 " gl_Position = vec4(-1, -1, 0, 1);\n"
17059 " gs_fs = result;\n"
17060 " gl_Position = vec4(-1, 1, 0, 1);\n"
17062 " gs_fs = result;\n"
17063 " gl_Position = vec4(1, -1, 0, 1);\n"
17065 " gs_fs = result;\n"
17066 " gl_Position = vec4(1, 1, 0, 1);\n"
17070 static const GLchar* tcs = "#version 430 core\n"
17071 "#extension GL_ARB_enhanced_layouts : require\n"
17073 "layout(vertices = 1) out;\n"
17075 "in vec4 vs_tcs[];\n"
17076 "out vec4 tcs_tes[];\n"
17081 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
17083 " gl_TessLevelOuter[0] = 1.0;\n"
17084 " gl_TessLevelOuter[1] = 1.0;\n"
17085 " gl_TessLevelOuter[2] = 1.0;\n"
17086 " gl_TessLevelOuter[3] = 1.0;\n"
17087 " gl_TessLevelInner[0] = 1.0;\n"
17088 " gl_TessLevelInner[1] = 1.0;\n"
17091 static const GLchar* tcs_tested = "#version 430 core\n"
17092 "#extension GL_ARB_enhanced_layouts : require\n"
17094 "layout(vertices = 1) out;\n"
17098 "in vec4 vs_tcs[];\n"
17099 "out vec4 tcs_tes[];\n"
17103 " vec4 result = vs_tcs[gl_InvocationID];\n"
17107 " tcs_tes[gl_InvocationID] = result;\n"
17109 " gl_TessLevelOuter[0] = 1.0;\n"
17110 " gl_TessLevelOuter[1] = 1.0;\n"
17111 " gl_TessLevelOuter[2] = 1.0;\n"
17112 " gl_TessLevelOuter[3] = 1.0;\n"
17113 " gl_TessLevelInner[0] = 1.0;\n"
17114 " gl_TessLevelInner[1] = 1.0;\n"
17117 static const GLchar* tes = "#version 430 core\n"
17118 "#extension GL_ARB_enhanced_layouts : require\n"
17120 "layout(isolines, point_mode) in;\n"
17122 "in vec4 tcs_tes[];\n"
17123 "out vec4 tes_gs;\n"
17127 " tes_gs = tcs_tes[0];\n"
17130 static const GLchar* tes_tested = "#version 430 core\n"
17131 "#extension GL_ARB_enhanced_layouts : require\n"
17133 "layout(isolines, point_mode) in;\n"
17137 "in vec4 tcs_tes[];\n"
17138 "out vec4 tes_gs;\n"
17142 " vec4 result = tcs_tes[0];\n"
17146 " tes_gs += result;\n"
17149 static const GLchar* vs = "#version 430 core\n"
17150 "#extension GL_ARB_enhanced_layouts : require\n"
17153 "out vec4 vs_tcs;\n"
17157 " vs_tcs = in_vs;\n"
17160 static const GLchar* vs_tested = "#version 430 core\n"
17161 "#extension GL_ARB_enhanced_layouts : require\n"
17166 "out vec4 vs_tcs;\n"
17170 " vec4 result = in_vs;\n"
17174 " vs_tcs += result;\n"
17178 std::string source;
17179 testCase& test_case = m_test_cases[test_case_index];
17181 if (test_case.m_stage == stage)
17183 const GLchar* array = "";
17184 GLchar buffer_gohan[16];
17185 GLchar buffer_goten[16];
17186 const GLchar* index = "";
17187 size_t position = 0;
17189 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
17191 sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
17192 sprintf(buffer_goten, "%d", test_case.m_component_goten);
17196 case Utils::Shader::FRAGMENT:
17197 source = fs_tested;
17199 case Utils::Shader::GEOMETRY:
17200 source = gs_tested;
17204 case Utils::Shader::TESS_CTRL:
17205 source = tcs_tested;
17207 index = "[gl_InvocationID]";
17209 case Utils::Shader::TESS_EVAL:
17210 source = tes_tested;
17214 case Utils::Shader::VERTEX:
17215 source = vs_tested;
17218 TCU_FAIL("Invalid enum");
17222 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
17224 Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
17225 Utils::replaceToken("ARRAY", position, array, source);
17226 Utils::replaceToken("COMPONENT", position, buffer_goten, source);
17227 Utils::replaceToken("ARRAY", position, array, source);
17228 Utils::replaceToken("VARIABLE_USE", position, l_test, source);
17230 Utils::replaceAllTokens("TYPE", type_name, source);
17231 Utils::replaceAllTokens("INDEX", index, source);
17237 case Utils::Shader::FRAGMENT:
17240 case Utils::Shader::GEOMETRY:
17243 case Utils::Shader::TESS_CTRL:
17246 case Utils::Shader::TESS_EVAL:
17249 case Utils::Shader::VERTEX:
17253 TCU_FAIL("Invalid enum");
17260 /** Get description of test case
17262 * @param test_case_index Index of test case
17264 * @return Test case description
17266 std::string OutputComponentAliasingTest::getTestCaseName(GLuint test_case_index)
17268 std::stringstream stream;
17269 testCase& test_case = m_test_cases[test_case_index];
17271 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
17272 << " type: " << test_case.m_type.GetGLSLTypeName() << ", components: " << test_case.m_component_gohan
17273 << " & " << test_case.m_component_goten;
17275 return stream.str();
17278 /** Get number of test cases
17280 * @return Number of test cases
17282 GLuint OutputComponentAliasingTest::getTestCaseNumber()
17284 return static_cast<GLuint>(m_test_cases.size());
17287 /** Selects if "compute" stage is relevant for test
17293 bool OutputComponentAliasingTest::isComputeRelevant(GLuint /* test_case_index */)
17298 /** Prepare all test cases
17301 void OutputComponentAliasingTest::testInit()
17303 static const GLuint n_components_per_location = 4;
17304 const GLuint n_types = getTypesNumber();
17306 for (GLuint i = 0; i < n_types; ++i)
17308 const Utils::Type& type = getType(i);
17309 const GLuint n_req_components = type.m_n_rows;
17310 const GLuint valid_component = n_components_per_location - n_req_components;
17312 /* Skip matrices */
17313 if (1 != type.m_n_columns)
17318 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
17320 if (Utils::Shader::COMPUTE == stage)
17325 if ((Utils::Shader::FRAGMENT == stage) && (Utils::Type::Double == type.m_basic_type))
17330 for (GLuint gohan = 0; gohan <= valid_component; ++gohan)
17332 const GLint first_aliasing = gohan - n_req_components + 1;
17333 const GLint last_aliasing = gohan + n_req_components - 1;
17335 const GLuint goten_start = std::max(0, first_aliasing);
17336 const GLuint goten_stop = std::min((GLint)valid_component, last_aliasing);
17338 for (GLuint goten = goten_start; goten <= goten_stop; ++goten)
17340 testCase test_case = { gohan, goten, (Utils::Shader::STAGES)stage, type };
17342 m_test_cases.push_back(test_case);
17351 * @param context Test framework context
17353 VaryingLocationAliasingWithMixedTypesTest::VaryingLocationAliasingWithMixedTypesTest(deqp::Context& context)
17354 : NegativeTestBase(context, "varying_location_aliasing_with_mixed_types",
17355 "Test verifies that compiler reports error when float/int types are mixed at one location")
17359 /** Source for given test case and stage
17361 * @param test_case_index Index of test case
17362 * @param stage Shader stage
17364 * @return Shader source
17366 std::string VaryingLocationAliasingWithMixedTypesTest::getShaderSource(GLuint test_case_index,
17367 Utils::Shader::STAGES stage)
17369 static const GLchar* var_definition =
17370 "layout (location = 1, component = COMPONENT) FLAT DIRECTION TYPE gohanARRAY;\n"
17371 "layout (location = 1, component = COMPONENT) FLAT DIRECTION TYPE gotenARRAY;\n";
17372 static const GLchar* input_use = " if ((TYPE(0) == gohanINDEX) &&\n"
17373 " (TYPE(1) == gotenINDEX) )\n"
17375 " result += vec4(1, 0.5, 0.25, 0.125);\n"
17377 static const GLchar* output_use = " gohanINDEX = TYPE(0);\n"
17378 " gotenINDEX = TYPE(1);\n"
17379 " if (vec4(0) == result)\n"
17381 " gohanINDEX = TYPE(1);\n"
17382 " gotenINDEX = TYPE(0);\n"
17384 static const GLchar* fs = "#version 430 core\n"
17385 "#extension GL_ARB_enhanced_layouts : require\n"
17388 "out vec4 fs_out;\n"
17392 " fs_out = gs_fs;\n"
17395 static const GLchar* fs_tested = "#version 430 core\n"
17396 "#extension GL_ARB_enhanced_layouts : require\n"
17401 "out vec4 fs_out;\n"
17405 " vec4 result = gs_fs;\n"
17409 " fs_out += result;\n"
17412 static const GLchar* gs = "#version 430 core\n"
17413 "#extension GL_ARB_enhanced_layouts : require\n"
17415 "layout(points) in;\n"
17416 "layout(triangle_strip, max_vertices = 4) out;\n"
17418 "in vec4 tes_gs[];\n"
17419 "out vec4 gs_fs;\n"
17423 " gs_fs = tes_gs[0];\n"
17424 " gl_Position = vec4(-1, -1, 0, 1);\n"
17426 " gs_fs = tes_gs[0];\n"
17427 " gl_Position = vec4(-1, 1, 0, 1);\n"
17429 " gs_fs = tes_gs[0];\n"
17430 " gl_Position = vec4(1, -1, 0, 1);\n"
17432 " gs_fs = tes_gs[0];\n"
17433 " gl_Position = vec4(1, 1, 0, 1);\n"
17437 static const GLchar* gs_tested = "#version 430 core\n"
17438 "#extension GL_ARB_enhanced_layouts : require\n"
17440 "layout(points) in;\n"
17441 "layout(triangle_strip, max_vertices = 4) out;\n"
17445 "in vec4 tes_gs[];\n"
17446 "out vec4 gs_fs;\n"
17450 " vec4 result = tes_gs[0];\n"
17454 " gs_fs = result;\n"
17455 " gl_Position = vec4(-1, -1, 0, 1);\n"
17457 " gs_fs = result;\n"
17458 " gl_Position = vec4(-1, 1, 0, 1);\n"
17460 " gs_fs = result;\n"
17461 " gl_Position = vec4(1, -1, 0, 1);\n"
17463 " gs_fs = result;\n"
17464 " gl_Position = vec4(1, 1, 0, 1);\n"
17468 static const GLchar* tcs = "#version 430 core\n"
17469 "#extension GL_ARB_enhanced_layouts : require\n"
17471 "layout(vertices = 1) out;\n"
17473 "in vec4 vs_tcs[];\n"
17474 "out vec4 tcs_tes[];\n"
17479 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
17481 " gl_TessLevelOuter[0] = 1.0;\n"
17482 " gl_TessLevelOuter[1] = 1.0;\n"
17483 " gl_TessLevelOuter[2] = 1.0;\n"
17484 " gl_TessLevelOuter[3] = 1.0;\n"
17485 " gl_TessLevelInner[0] = 1.0;\n"
17486 " gl_TessLevelInner[1] = 1.0;\n"
17489 static const GLchar* tcs_tested = "#version 430 core\n"
17490 "#extension GL_ARB_enhanced_layouts : require\n"
17492 "layout(vertices = 1) out;\n"
17496 "in vec4 vs_tcs[];\n"
17497 "out vec4 tcs_tes[];\n"
17501 " vec4 result = vs_tcs[gl_InvocationID];\n"
17505 " tcs_tes[gl_InvocationID] = result;\n"
17507 " gl_TessLevelOuter[0] = 1.0;\n"
17508 " gl_TessLevelOuter[1] = 1.0;\n"
17509 " gl_TessLevelOuter[2] = 1.0;\n"
17510 " gl_TessLevelOuter[3] = 1.0;\n"
17511 " gl_TessLevelInner[0] = 1.0;\n"
17512 " gl_TessLevelInner[1] = 1.0;\n"
17515 static const GLchar* tes = "#version 430 core\n"
17516 "#extension GL_ARB_enhanced_layouts : require\n"
17518 "layout(isolines, point_mode) in;\n"
17520 "in vec4 tcs_tes[];\n"
17521 "out vec4 tes_gs;\n"
17525 " tes_gs = tcs_tes[0];\n"
17528 static const GLchar* tes_tested = "#version 430 core\n"
17529 "#extension GL_ARB_enhanced_layouts : require\n"
17531 "layout(isolines, point_mode) in;\n"
17535 "in vec4 tcs_tes[];\n"
17536 "out vec4 tes_gs;\n"
17540 " vec4 result = tcs_tes[0];\n"
17544 " tes_gs += result;\n"
17547 static const GLchar* vs = "#version 430 core\n"
17548 "#extension GL_ARB_enhanced_layouts : require\n"
17551 "out vec4 vs_tcs;\n"
17555 " vs_tcs = in_vs;\n"
17558 static const GLchar* vs_tested = "#version 430 core\n"
17559 "#extension GL_ARB_enhanced_layouts : require\n"
17564 "out vec4 vs_tcs;\n"
17568 " vec4 result = in_vs;\n"
17572 " vs_tcs += result;\n"
17576 std::string source;
17577 testCase& test_case = m_test_cases[test_case_index];
17579 if (test_case.m_stage == stage)
17581 const GLchar* array = "";
17582 GLchar buffer_gohan[16];
17583 GLchar buffer_goten[16];
17584 const GLchar* direction = "in ";
17585 const GLchar* flat_gohan = "";
17586 const GLchar* flat_goten = "";
17587 const GLchar* index = "";
17588 size_t position = 0;
17590 const GLchar* type_gohan_name = test_case.m_type_gohan.GetGLSLTypeName();
17591 const GLchar* type_goten_name = test_case.m_type_goten.GetGLSLTypeName();
17592 Utils::Variable::STORAGE storage = Utils::Variable::VARYING_INPUT;
17593 const GLchar* var_use = input_use;
17595 if (false == test_case.m_is_input)
17598 storage = Utils::Variable::VARYING_OUTPUT;
17599 var_use = output_use;
17602 if (true == isFlatRequired(stage, test_case.m_type_gohan, storage))
17604 flat_gohan = "flat";
17607 if (true == isFlatRequired(stage, test_case.m_type_goten, storage))
17609 flat_goten = "flat";
17612 sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
17613 sprintf(buffer_goten, "%d", test_case.m_component_goten);
17617 case Utils::Shader::FRAGMENT:
17618 source = fs_tested;
17620 case Utils::Shader::GEOMETRY:
17621 source = gs_tested;
17625 case Utils::Shader::TESS_CTRL:
17626 source = tcs_tested;
17628 index = "[gl_InvocationID]";
17630 case Utils::Shader::TESS_EVAL:
17631 source = tes_tested;
17635 case Utils::Shader::VERTEX:
17636 source = vs_tested;
17639 TCU_FAIL("Invalid enum");
17643 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
17645 Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
17646 Utils::replaceToken("FLAT", position, flat_gohan, source);
17647 Utils::replaceToken("DIRECTION", position, direction, source);
17648 Utils::replaceToken("TYPE", position, type_gohan_name, source);
17649 Utils::replaceToken("ARRAY", position, array, source);
17650 Utils::replaceToken("COMPONENT", position, buffer_goten, source);
17651 Utils::replaceToken("FLAT", position, flat_goten, source);
17652 Utils::replaceToken("DIRECTION", position, direction, source);
17653 Utils::replaceToken("TYPE", position, type_goten_name, source);
17654 Utils::replaceToken("ARRAY", position, array, source);
17657 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
17659 if (true == test_case.m_is_input)
17661 Utils::replaceToken("TYPE", position, type_gohan_name, source);
17662 Utils::replaceToken("TYPE", position, type_goten_name, source);
17666 Utils::replaceToken("TYPE", position, type_gohan_name, source);
17667 Utils::replaceToken("TYPE", position, type_goten_name, source);
17668 Utils::replaceToken("TYPE", position, type_gohan_name, source);
17669 Utils::replaceToken("TYPE", position, type_goten_name, source);
17672 Utils::replaceAllTokens("INDEX", index, source);
17678 case Utils::Shader::FRAGMENT:
17681 case Utils::Shader::GEOMETRY:
17684 case Utils::Shader::TESS_CTRL:
17687 case Utils::Shader::TESS_EVAL:
17690 case Utils::Shader::VERTEX:
17694 TCU_FAIL("Invalid enum");
17701 /** Get description of test case
17703 * @param test_case_index Index of test case
17705 * @return Test case description
17707 std::string VaryingLocationAliasingWithMixedTypesTest::getTestCaseName(GLuint test_case_index)
17709 std::stringstream stream;
17710 testCase& test_case = m_test_cases[test_case_index];
17712 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", "
17713 << test_case.m_type_gohan.GetGLSLTypeName() << " at " << test_case.m_component_gohan << ", "
17714 << test_case.m_type_goten.GetGLSLTypeName() << " at " << test_case.m_component_goten << ". Direction: ";
17716 if (true == test_case.m_is_input)
17722 stream << "output";
17725 return stream.str();
17728 /** Get number of test cases
17730 * @return Number of test cases
17732 GLuint VaryingLocationAliasingWithMixedTypesTest::getTestCaseNumber()
17734 return static_cast<GLuint>(m_test_cases.size());
17737 /** Selects if "compute" stage is relevant for test
17743 bool VaryingLocationAliasingWithMixedTypesTest::isComputeRelevant(GLuint /* test_case_index */)
17748 /** Prepare all test cases
17751 void VaryingLocationAliasingWithMixedTypesTest::testInit()
17753 static const GLuint n_components_per_location = 4;
17754 const GLuint n_types = getTypesNumber();
17756 for (GLuint i = 0; i < n_types; ++i)
17758 const Utils::Type& type_gohan = getType(i);
17759 const bool is_float_type_gohan = isFloatType(type_gohan);
17761 /* Skip matrices */
17762 if (1 != type_gohan.m_n_columns)
17767 for (GLuint j = 0; j < n_types; ++j)
17769 const Utils::Type& type_goten = getType(j);
17770 const bool is_float_type_goten = isFloatType(type_goten);
17772 /* Skip matrices */
17773 if (1 != type_goten.m_n_columns)
17778 /* Skip valid combinations */
17779 if (is_float_type_gohan == is_float_type_goten)
17784 const GLuint n_req_components_gohan = type_gohan.m_n_rows;
17785 const GLuint n_req_components_goten = type_goten.m_n_rows;
17786 const GLuint valid_component_gohan = n_components_per_location - n_req_components_gohan;
17787 const GLuint valid_component_goten = n_components_per_location - n_req_components_goten;
17789 /* Skip pairs that cannot fit into one location */
17790 if (n_components_per_location < (n_req_components_gohan + n_req_components_goten))
17795 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
17797 /* Skip compute shader */
17798 if (Utils::Shader::COMPUTE == stage)
17803 for (GLuint gohan = 0; gohan <= valid_component_gohan; ++gohan)
17805 const GLint first_aliasing = gohan - n_req_components_goten + 1;
17806 const GLint last_aliasing = gohan + n_req_components_gohan - 1;
17808 const GLuint goten_lower_limit = std::max(0, first_aliasing);
17809 const GLuint goten_upper_limit = last_aliasing + 1;
17811 /* Compoennets before gohan */
17812 for (GLuint goten = 0; goten < goten_lower_limit; ++goten)
17814 testCase test_case_in = { gohan, goten, true, (Utils::Shader::STAGES)stage,
17815 type_gohan, type_goten };
17816 testCase test_case_out = { gohan, goten, false, (Utils::Shader::STAGES)stage,
17817 type_gohan, type_goten };
17819 m_test_cases.push_back(test_case_in);
17821 /* Skip double outputs in fragment shader */
17822 if ((Utils::Shader::FRAGMENT != stage) || ((Utils::Type::Double != type_gohan.m_basic_type) &&
17823 (Utils::Type::Double != type_goten.m_basic_type)))
17825 m_test_cases.push_back(test_case_out);
17829 /* Components after gohan */
17830 for (GLuint goten = goten_upper_limit; goten <= valid_component_goten; ++goten)
17832 testCase test_case_in = { gohan, goten, true, (Utils::Shader::STAGES)stage,
17833 type_gohan, type_goten };
17834 testCase test_case_out = { gohan, goten, false, (Utils::Shader::STAGES)stage,
17835 type_gohan, type_goten };
17837 m_test_cases.push_back(test_case_in);
17839 /* Skip double outputs in fragment shader */
17840 if ((Utils::Shader::FRAGMENT != stage) || ((Utils::Type::Double != type_gohan.m_basic_type) &&
17841 (Utils::Type::Double != type_goten.m_basic_type)))
17843 m_test_cases.push_back(test_case_out);
17852 /** Check if given type is float
17854 * @param type Type in question
17856 * @return true if tpye is float, false otherwise
17858 bool VaryingLocationAliasingWithMixedTypesTest::isFloatType(const Utils::Type& type)
17860 bool is_float = false;
17862 if ((Utils::Type::Double == type.m_basic_type) || (Utils::Type::Float == type.m_basic_type))
17872 * @param context Test framework context
17874 VaryingLocationAliasingWithMixedInterpolationTest::VaryingLocationAliasingWithMixedInterpolationTest(
17875 deqp::Context& context)
17876 : NegativeTestBase(
17877 context, "varying_location_aliasing_with_mixed_interpolation",
17878 "Test verifies that compiler reports error when interpolation qualifiers are mixed at one location")
17882 /** Source for given test case and stage
17884 * @param test_case_index Index of test case
17885 * @param stage Shader stage
17887 * @return Shader source
17889 std::string VaryingLocationAliasingWithMixedInterpolationTest::getShaderSource(GLuint test_case_index,
17890 Utils::Shader::STAGES stage)
17892 static const GLchar* var_definition =
17893 "layout (location = 1, component = COMPONENT) INTERPOLATION DIRECTION TYPE gohanARRAY;\n"
17894 "layout (location = 1, component = COMPONENT) INTERPOLATION DIRECTION TYPE gotenARRAY;\n";
17895 static const GLchar* input_use = " if ((TYPE(0) == gohanINDEX) &&\n"
17896 " (TYPE(1) == gotenINDEX) )\n"
17898 " result += vec4(1, 0.5, 0.25, 0.125);\n"
17900 static const GLchar* output_use = " gohanINDEX = TYPE(0);\n"
17901 " gotenINDEX = TYPE(1);\n"
17902 " if (vec4(0) == result)\n"
17904 " gohanINDEX = TYPE(1);\n"
17905 " gotenINDEX = TYPE(0);\n"
17907 static const GLchar* fs = "#version 430 core\n"
17908 "#extension GL_ARB_enhanced_layouts : require\n"
17911 "out vec4 fs_out;\n"
17915 " fs_out = gs_fs;\n"
17918 static const GLchar* fs_tested = "#version 430 core\n"
17919 "#extension GL_ARB_enhanced_layouts : require\n"
17924 "out vec4 fs_out;\n"
17928 " vec4 result = gs_fs;\n"
17932 " fs_out = result;\n"
17935 static const GLchar* gs = "#version 430 core\n"
17936 "#extension GL_ARB_enhanced_layouts : require\n"
17938 "layout(points) in;\n"
17939 "layout(triangle_strip, max_vertices = 4) out;\n"
17941 "in vec4 tes_gs[];\n"
17942 "out vec4 gs_fs;\n"
17946 " gs_fs = tes_gs[0];\n"
17947 " gl_Position = vec4(-1, -1, 0, 1);\n"
17949 " gs_fs = tes_gs[0];\n"
17950 " gl_Position = vec4(-1, 1, 0, 1);\n"
17952 " gs_fs = tes_gs[0];\n"
17953 " gl_Position = vec4(1, -1, 0, 1);\n"
17955 " gs_fs = tes_gs[0];\n"
17956 " gl_Position = vec4(1, 1, 0, 1);\n"
17960 static const GLchar* gs_tested = "#version 430 core\n"
17961 "#extension GL_ARB_enhanced_layouts : require\n"
17963 "layout(points) in;\n"
17964 "layout(triangle_strip, max_vertices = 4) out;\n"
17968 "in vec4 tes_gs[];\n"
17969 "out vec4 gs_fs;\n"
17973 " vec4 result = tes_gs[0];\n"
17977 " gs_fs = result;\n"
17978 " gl_Position = vec4(-1, -1, 0, 1);\n"
17980 " gs_fs = result;\n"
17981 " gl_Position = vec4(-1, 1, 0, 1);\n"
17983 " gs_fs = result;\n"
17984 " gl_Position = vec4(1, -1, 0, 1);\n"
17986 " gs_fs = result;\n"
17987 " gl_Position = vec4(1, 1, 0, 1);\n"
17991 static const GLchar* tcs = "#version 430 core\n"
17992 "#extension GL_ARB_enhanced_layouts : require\n"
17994 "layout(vertices = 1) out;\n"
17996 "in vec4 vs_tcs[];\n"
17997 "out vec4 tcs_tes[];\n"
18002 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
18004 " gl_TessLevelOuter[0] = 1.0;\n"
18005 " gl_TessLevelOuter[1] = 1.0;\n"
18006 " gl_TessLevelOuter[2] = 1.0;\n"
18007 " gl_TessLevelOuter[3] = 1.0;\n"
18008 " gl_TessLevelInner[0] = 1.0;\n"
18009 " gl_TessLevelInner[1] = 1.0;\n"
18012 static const GLchar* tcs_tested = "#version 430 core\n"
18013 "#extension GL_ARB_enhanced_layouts : require\n"
18015 "layout(vertices = 1) out;\n"
18019 "in vec4 vs_tcs[];\n"
18020 "out vec4 tcs_tes[];\n"
18024 " vec4 result = vs_tcs[gl_InvocationID];\n"
18028 " tcs_tes[gl_InvocationID] = result;\n"
18030 " gl_TessLevelOuter[0] = 1.0;\n"
18031 " gl_TessLevelOuter[1] = 1.0;\n"
18032 " gl_TessLevelOuter[2] = 1.0;\n"
18033 " gl_TessLevelOuter[3] = 1.0;\n"
18034 " gl_TessLevelInner[0] = 1.0;\n"
18035 " gl_TessLevelInner[1] = 1.0;\n"
18038 static const GLchar* tes = "#version 430 core\n"
18039 "#extension GL_ARB_enhanced_layouts : require\n"
18041 "layout(isolines, point_mode) in;\n"
18043 "in vec4 tcs_tes[];\n"
18044 "out vec4 tes_gs;\n"
18048 " tes_gs = tcs_tes[0];\n"
18051 static const GLchar* tes_tested = "#version 430 core\n"
18052 "#extension GL_ARB_enhanced_layouts : require\n"
18054 "layout(isolines, point_mode) in;\n"
18058 "in vec4 tcs_tes[];\n"
18059 "out vec4 tes_gs;\n"
18063 " vec4 result = tcs_tes[0];\n"
18067 " tes_gs += result;\n"
18070 static const GLchar* vs = "#version 430 core\n"
18071 "#extension GL_ARB_enhanced_layouts : require\n"
18074 "out vec4 vs_tcs;\n"
18078 " vs_tcs = in_vs;\n"
18081 static const GLchar* vs_tested = "#version 430 core\n"
18082 "#extension GL_ARB_enhanced_layouts : require\n"
18087 "out vec4 vs_tcs;\n"
18091 " vec4 result = in_vs;\n"
18095 " vs_tcs += result;\n"
18099 std::string source;
18100 testCase& test_case = m_test_cases[test_case_index];
18102 if (test_case.m_stage == stage)
18104 const GLchar* array = "";
18105 GLchar buffer_gohan[16];
18106 GLchar buffer_goten[16];
18107 const GLchar* direction = "in ";
18108 const GLchar* index = "";
18109 const GLchar* int_gohan = getInterpolationQualifier(test_case.m_interpolation_gohan);
18110 const GLchar* int_goten = getInterpolationQualifier(test_case.m_interpolation_goten);
18111 size_t position = 0;
18113 const GLchar* type_gohan_name = test_case.m_type_gohan.GetGLSLTypeName();
18114 const GLchar* type_goten_name = test_case.m_type_goten.GetGLSLTypeName();
18115 const GLchar* var_use = input_use;
18117 if (false == test_case.m_is_input)
18121 var_use = output_use;
18124 sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
18125 sprintf(buffer_goten, "%d", test_case.m_component_goten);
18129 case Utils::Shader::FRAGMENT:
18130 source = fs_tested;
18132 case Utils::Shader::GEOMETRY:
18133 source = gs_tested;
18137 case Utils::Shader::TESS_CTRL:
18138 source = tcs_tested;
18140 index = "[gl_InvocationID]";
18142 case Utils::Shader::TESS_EVAL:
18143 source = tes_tested;
18147 case Utils::Shader::VERTEX:
18148 source = vs_tested;
18151 TCU_FAIL("Invalid enum");
18155 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
18157 Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
18158 Utils::replaceToken("INTERPOLATION", position, int_gohan, source);
18159 Utils::replaceToken("DIRECTION", position, direction, source);
18160 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18161 Utils::replaceToken("ARRAY", position, array, source);
18162 Utils::replaceToken("COMPONENT", position, buffer_goten, source);
18163 Utils::replaceToken("INTERPOLATION", position, int_goten, source);
18164 Utils::replaceToken("DIRECTION", position, direction, source);
18165 Utils::replaceToken("TYPE", position, type_goten_name, source);
18166 Utils::replaceToken("ARRAY", position, array, source);
18169 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
18171 if (true == test_case.m_is_input)
18173 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18174 Utils::replaceToken("TYPE", position, type_goten_name, source);
18178 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18179 Utils::replaceToken("TYPE", position, type_goten_name, source);
18180 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18181 Utils::replaceToken("TYPE", position, type_goten_name, source);
18184 Utils::replaceAllTokens("INDEX", index, source);
18190 case Utils::Shader::FRAGMENT:
18193 case Utils::Shader::GEOMETRY:
18196 case Utils::Shader::TESS_CTRL:
18199 case Utils::Shader::TESS_EVAL:
18202 case Utils::Shader::VERTEX:
18206 TCU_FAIL("Invalid enum");
18213 /** Get description of test case
18215 * @param test_case_index Index of test case
18217 * @return Test case description
18219 std::string VaryingLocationAliasingWithMixedInterpolationTest::getTestCaseName(GLuint test_case_index)
18221 std::stringstream stream;
18222 testCase& test_case = m_test_cases[test_case_index];
18224 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", "
18225 << getInterpolationQualifier(test_case.m_interpolation_gohan) << " "
18226 << test_case.m_type_gohan.GetGLSLTypeName() << " at " << test_case.m_component_gohan << ", "
18227 << getInterpolationQualifier(test_case.m_interpolation_goten) << " "
18228 << test_case.m_type_goten.GetGLSLTypeName() << " at " << test_case.m_component_goten << ". Direction: ";
18230 if (true == test_case.m_is_input)
18236 stream << "output";
18239 return stream.str();
18242 /** Get number of test cases
18244 * @return Number of test cases
18246 GLuint VaryingLocationAliasingWithMixedInterpolationTest::getTestCaseNumber()
18248 return static_cast<GLuint>(m_test_cases.size());
18251 /** Selects if "compute" stage is relevant for test
18257 bool VaryingLocationAliasingWithMixedInterpolationTest::isComputeRelevant(GLuint /* test_case_index */)
18262 /** Prepare all test cases
18265 void VaryingLocationAliasingWithMixedInterpolationTest::testInit()
18267 static const GLuint n_components_per_location = 4;
18268 const GLuint n_types = getTypesNumber();
18270 for (GLuint i = 0; i < n_types; ++i)
18272 const Utils::Type& type_gohan = getType(i);
18273 const bool is_float_type_gohan = isFloatType(type_gohan);
18275 /* Skip matrices */
18276 if (1 != type_gohan.m_n_columns)
18281 for (GLuint j = 0; j < n_types; ++j)
18283 const Utils::Type& type_goten = getType(j);
18284 const bool is_float_type_goten = isFloatType(type_goten);
18286 /* Skip matrices */
18287 if (1 != type_goten.m_n_columns)
18292 /* Skip invalid combinations */
18293 if (is_float_type_gohan != is_float_type_goten)
18298 const GLuint n_req_components_gohan = type_gohan.m_n_rows;
18299 const GLuint n_req_components_goten = type_goten.m_n_rows;
18301 /* Skip pairs that cannot fit into one location */
18302 if (n_components_per_location < (n_req_components_gohan + n_req_components_goten))
18307 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
18309 /* Skip compute shader */
18310 if (Utils::Shader::COMPUTE == stage)
18315 const GLuint gohan = 0;
18316 const GLuint goten = gohan + n_req_components_gohan;
18318 for (GLuint int_gohan = 0; int_gohan < INTERPOLATION_MAX; ++int_gohan)
18320 for (GLuint int_goten = 0; int_goten < INTERPOLATION_MAX; ++int_goten)
18322 const bool is_gohan_double = (Utils::Type::Double == type_gohan.m_basic_type) ? true : false;
18323 const bool is_goten_double = (Utils::Type::Double == type_goten.m_basic_type) ? true : false;
18324 const bool is_gohan_flat = (FLAT == int_gohan) ? true : false;
18325 const bool is_goten_flat = (FLAT == int_goten) ? true : false;
18326 const bool is_gohan_accepted_as_fs_in =
18327 (is_gohan_double && is_gohan_flat) || (!is_gohan_double);
18328 const bool is_goten_accepted_as_fs_in =
18329 (is_goten_double && is_goten_flat) || (!is_goten_double);
18330 const bool is_comb_accepted_as_fs_in = is_gohan_accepted_as_fs_in && is_goten_accepted_as_fs_in;
18332 /* Skip when both are the same */
18333 if (int_gohan == int_goten)
18338 testCase test_case_in = { gohan,
18340 (INTERPOLATIONS)int_gohan,
18341 (INTERPOLATIONS)int_goten,
18343 (Utils::Shader::STAGES)stage,
18347 testCase test_case_out = { gohan,
18349 (INTERPOLATIONS)int_gohan,
18350 (INTERPOLATIONS)int_goten,
18352 (Utils::Shader::STAGES)stage,
18358 * fragment shader when not flat double is used
18360 if ((Utils::Shader::VERTEX != stage) &&
18361 ((Utils::Shader::FRAGMENT != stage) || (true == is_comb_accepted_as_fs_in)))
18363 m_test_cases.push_back(test_case_in);
18366 /* Skip outputs in fragment shader */
18367 if (Utils::Shader::FRAGMENT != stage)
18369 m_test_cases.push_back(test_case_out);
18378 /** Get interpolation qualifier
18380 * @param interpolation Enumeration
18382 * @return GLSL qualifier
18384 const GLchar* VaryingLocationAliasingWithMixedInterpolationTest::getInterpolationQualifier(INTERPOLATIONS interpolation)
18386 const GLchar* result = 0;
18388 switch (interpolation)
18396 case NO_PERSPECTIVE:
18397 result = "noperspective";
18400 TCU_FAIL("Invalid enum");
18406 /** Check if given type is float
18408 * @param type Type in question
18410 * @return true if tpye is float, false otherwise
18412 bool VaryingLocationAliasingWithMixedInterpolationTest::isFloatType(const Utils::Type& type)
18414 bool is_float = false;
18416 if ((Utils::Type::Double == type.m_basic_type) || (Utils::Type::Float == type.m_basic_type))
18426 * @param context Test framework context
18428 VaryingLocationAliasingWithMixedAuxiliaryStorageTest::VaryingLocationAliasingWithMixedAuxiliaryStorageTest(
18429 deqp::Context& context)
18430 : NegativeTestBase(
18431 context, "varying_location_aliasing_with_mixed_auxiliary_storage",
18432 "Test verifies that compiler reports error when auxiliary storage qualifiers are mixed at one location")
18436 /** Source for given test case and stage
18438 * @param test_case_index Index of test case
18439 * @param stage Shader stage
18441 * @return Shader source
18443 std::string VaryingLocationAliasingWithMixedAuxiliaryStorageTest::getShaderSource(GLuint test_case_index,
18444 Utils::Shader::STAGES stage)
18446 static const GLchar* var_definition =
18447 "layout (location = 1, component = COMPONENT) AUX INTERPOLATION DIRECTION TYPE gohanARRAY;\n"
18448 "layout (location = 1, component = COMPONENT) AUX INTERPOLATION DIRECTION TYPE gotenARRAY;\n";
18449 static const GLchar* input_use = " if ((TYPE(0) == gohanINDEX_GOHAN) &&\n"
18450 " (TYPE(1) == gotenINDEX_GOTEN) )\n"
18452 " result += vec4(1, 0.5, 0.25, 0.125);\n"
18454 static const GLchar* output_use = " gohanINDEX_GOHAN = TYPE(0);\n"
18455 " gotenINDEX_GOTEN = TYPE(1);\n"
18456 " if (vec4(0) == result)\n"
18458 " gohanINDEX_GOHAN = TYPE(1);\n"
18459 " gotenINDEX_GOTEN = TYPE(0);\n"
18461 static const GLchar* fs = "#version 430 core\n"
18462 "#extension GL_ARB_enhanced_layouts : require\n"
18465 "out vec4 fs_out;\n"
18469 " fs_out = gs_fs;\n"
18472 static const GLchar* fs_tested = "#version 430 core\n"
18473 "#extension GL_ARB_enhanced_layouts : require\n"
18478 "out vec4 fs_out;\n"
18482 " vec4 result = gs_fs;\n"
18486 " fs_out = result;\n"
18489 static const GLchar* gs = "#version 430 core\n"
18490 "#extension GL_ARB_enhanced_layouts : require\n"
18492 "layout(points) in;\n"
18493 "layout(triangle_strip, max_vertices = 4) out;\n"
18495 "in vec4 tes_gs[];\n"
18496 "out vec4 gs_fs;\n"
18500 " gs_fs = tes_gs[0];\n"
18501 " gl_Position = vec4(-1, -1, 0, 1);\n"
18503 " gs_fs = tes_gs[0];\n"
18504 " gl_Position = vec4(-1, 1, 0, 1);\n"
18506 " gs_fs = tes_gs[0];\n"
18507 " gl_Position = vec4(1, -1, 0, 1);\n"
18509 " gs_fs = tes_gs[0];\n"
18510 " gl_Position = vec4(1, 1, 0, 1);\n"
18514 static const GLchar* gs_tested = "#version 430 core\n"
18515 "#extension GL_ARB_enhanced_layouts : require\n"
18517 "layout(points) in;\n"
18518 "layout(triangle_strip, max_vertices = 4) out;\n"
18522 "in vec4 tes_gs[];\n"
18523 "out vec4 gs_fs;\n"
18527 " vec4 result = tes_gs[0];\n"
18531 " gs_fs = result;\n"
18532 " gl_Position = vec4(-1, -1, 0, 1);\n"
18534 " gs_fs = result;\n"
18535 " gl_Position = vec4(-1, 1, 0, 1);\n"
18537 " gs_fs = result;\n"
18538 " gl_Position = vec4(1, -1, 0, 1);\n"
18540 " gs_fs = result;\n"
18541 " gl_Position = vec4(1, 1, 0, 1);\n"
18545 static const GLchar* tcs = "#version 430 core\n"
18546 "#extension GL_ARB_enhanced_layouts : require\n"
18548 "layout(vertices = 1) out;\n"
18550 "in vec4 vs_tcs[];\n"
18551 "out vec4 tcs_tes[];\n"
18556 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
18558 " gl_TessLevelOuter[0] = 1.0;\n"
18559 " gl_TessLevelOuter[1] = 1.0;\n"
18560 " gl_TessLevelOuter[2] = 1.0;\n"
18561 " gl_TessLevelOuter[3] = 1.0;\n"
18562 " gl_TessLevelInner[0] = 1.0;\n"
18563 " gl_TessLevelInner[1] = 1.0;\n"
18566 static const GLchar* tcs_tested = "#version 430 core\n"
18567 "#extension GL_ARB_enhanced_layouts : require\n"
18569 "layout(vertices = 1) out;\n"
18573 "in vec4 vs_tcs[];\n"
18574 "out vec4 tcs_tes[];\n"
18578 " vec4 result = vs_tcs[gl_InvocationID];\n"
18582 " tcs_tes[gl_InvocationID] = result;\n"
18584 " gl_TessLevelOuter[0] = 1.0;\n"
18585 " gl_TessLevelOuter[1] = 1.0;\n"
18586 " gl_TessLevelOuter[2] = 1.0;\n"
18587 " gl_TessLevelOuter[3] = 1.0;\n"
18588 " gl_TessLevelInner[0] = 1.0;\n"
18589 " gl_TessLevelInner[1] = 1.0;\n"
18592 static const GLchar* tes = "#version 430 core\n"
18593 "#extension GL_ARB_enhanced_layouts : require\n"
18595 "layout(isolines, point_mode) in;\n"
18597 "in vec4 tcs_tes[];\n"
18598 "out vec4 tes_gs;\n"
18602 " tes_gs = tcs_tes[0];\n"
18605 static const GLchar* tes_tested = "#version 430 core\n"
18606 "#extension GL_ARB_enhanced_layouts : require\n"
18608 "layout(isolines, point_mode) in;\n"
18612 "in vec4 tcs_tes[];\n"
18613 "out vec4 tes_gs;\n"
18617 " vec4 result = tcs_tes[0];\n"
18621 " tes_gs += result;\n"
18624 static const GLchar* vs = "#version 430 core\n"
18625 "#extension GL_ARB_enhanced_layouts : require\n"
18628 "out vec4 vs_tcs;\n"
18632 " vs_tcs = in_vs;\n"
18635 static const GLchar* vs_tested = "#version 430 core\n"
18636 "#extension GL_ARB_enhanced_layouts : require\n"
18641 "out vec4 vs_tcs;\n"
18645 " vec4 result = in_vs;\n"
18649 " vs_tcs += result;\n"
18653 std::string source;
18654 testCase& test_case = m_test_cases[test_case_index];
18656 if (test_case.m_stage == stage)
18658 const GLchar* array_gohan = "";
18659 const GLchar* array_goten = "";
18660 const GLchar* aux_gohan = getAuxiliaryQualifier(test_case.m_aux_gohan);
18661 const GLchar* aux_goten = getAuxiliaryQualifier(test_case.m_aux_goten);
18662 GLchar buffer_gohan[16];
18663 GLchar buffer_goten[16];
18664 const GLchar* direction = "in ";
18665 const GLchar* index_gohan = "";
18666 const GLchar* index_goten = "";
18667 const GLchar* int_gohan = test_case.m_int_gohan;
18668 const GLchar* int_goten = test_case.m_int_goten;
18669 size_t position = 0;
18671 const GLchar* type_gohan_name = test_case.m_type_gohan.GetGLSLTypeName();
18672 const GLchar* type_goten_name = test_case.m_type_goten.GetGLSLTypeName();
18673 const GLchar* var_use = input_use;
18675 if (false == test_case.m_is_input)
18679 var_use = output_use;
18682 sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
18683 sprintf(buffer_goten, "%d", test_case.m_component_goten);
18687 case Utils::Shader::FRAGMENT:
18688 source = fs_tested;
18690 case Utils::Shader::GEOMETRY:
18691 source = gs_tested;
18692 array_gohan = "[]";
18693 index_gohan = "[0]";
18694 array_goten = "[]";
18695 index_goten = "[0]";
18697 case Utils::Shader::TESS_CTRL:
18698 source = tcs_tested;
18699 if (PATCH != test_case.m_aux_gohan)
18701 array_gohan = "[]";
18702 index_gohan = "[gl_InvocationID]";
18704 if (PATCH != test_case.m_aux_goten)
18706 array_goten = "[]";
18707 index_goten = "[gl_InvocationID]";
18710 case Utils::Shader::TESS_EVAL:
18711 source = tes_tested;
18712 array_gohan = "[]";
18713 index_gohan = "[0]";
18714 array_goten = "[]";
18715 index_goten = "[0]";
18717 case Utils::Shader::VERTEX:
18718 source = vs_tested;
18721 TCU_FAIL("Invalid enum");
18725 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
18727 Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
18728 Utils::replaceToken("AUX", position, aux_gohan, source);
18729 Utils::replaceToken("INTERPOLATION", position, int_gohan, source);
18730 Utils::replaceToken("DIRECTION", position, direction, source);
18731 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18732 Utils::replaceToken("ARRAY", position, array_gohan, source);
18733 Utils::replaceToken("COMPONENT", position, buffer_goten, source);
18734 Utils::replaceToken("AUX", position, aux_goten, source);
18735 Utils::replaceToken("INTERPOLATION", position, int_goten, source);
18736 Utils::replaceToken("DIRECTION", position, direction, source);
18737 Utils::replaceToken("TYPE", position, type_goten_name, source);
18738 Utils::replaceToken("ARRAY", position, array_goten, source);
18741 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
18743 if (true == test_case.m_is_input)
18745 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18746 Utils::replaceToken("TYPE", position, type_goten_name, source);
18750 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18751 Utils::replaceToken("TYPE", position, type_goten_name, source);
18752 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18753 Utils::replaceToken("TYPE", position, type_goten_name, source);
18756 Utils::replaceAllTokens("INDEX_GOHAN", index_gohan, source);
18757 Utils::replaceAllTokens("INDEX_GOTEN", index_goten, source);
18763 case Utils::Shader::FRAGMENT:
18766 case Utils::Shader::GEOMETRY:
18769 case Utils::Shader::TESS_CTRL:
18772 case Utils::Shader::TESS_EVAL:
18775 case Utils::Shader::VERTEX:
18779 TCU_FAIL("Invalid enum");
18786 /** Get description of test case
18788 * @param test_case_index Index of test case
18790 * @return Test case description
18792 std::string VaryingLocationAliasingWithMixedAuxiliaryStorageTest::getTestCaseName(GLuint test_case_index)
18794 std::stringstream stream;
18795 testCase& test_case = m_test_cases[test_case_index];
18797 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", "
18798 << getAuxiliaryQualifier(test_case.m_aux_gohan) << " " << test_case.m_type_gohan.GetGLSLTypeName() << " at "
18799 << test_case.m_component_gohan << ", " << getAuxiliaryQualifier(test_case.m_aux_goten) << " "
18800 << test_case.m_type_goten.GetGLSLTypeName() << " at " << test_case.m_component_goten << ". Direction: ";
18802 if (true == test_case.m_is_input)
18808 stream << "output";
18811 return stream.str();
18814 /** Get number of test cases
18816 * @return Number of test cases
18818 GLuint VaryingLocationAliasingWithMixedAuxiliaryStorageTest::getTestCaseNumber()
18820 return static_cast<GLuint>(m_test_cases.size());
18823 /** Selects if "compute" stage is relevant for test
18829 bool VaryingLocationAliasingWithMixedAuxiliaryStorageTest::isComputeRelevant(GLuint /* test_case_index */)
18834 /** Prepare all test cases
18837 void VaryingLocationAliasingWithMixedAuxiliaryStorageTest::testInit()
18839 static const GLuint n_components_per_location = 4;
18840 const GLuint n_types = getTypesNumber();
18842 for (GLuint i = 0; i < n_types; ++i)
18844 const Utils::Type& type_gohan = getType(i);
18845 const bool is_float_type_gohan = isFloatType(type_gohan);
18847 /* Skip matrices */
18848 if (1 != type_gohan.m_n_columns)
18853 for (GLuint j = 0; j < n_types; ++j)
18855 const Utils::Type& type_goten = getType(j);
18856 const bool is_flat_req_gohan = (Utils::Type::Float == type_gohan.m_basic_type) ? false : true;
18857 const bool is_flat_req_goten = (Utils::Type::Float == type_goten.m_basic_type) ? false : true;
18858 const bool is_float_type_goten = isFloatType(type_goten);
18860 /* Skip matrices */
18861 if (1 != type_goten.m_n_columns)
18866 /* Skip invalid combinations */
18867 if (is_float_type_gohan != is_float_type_goten)
18872 const GLuint n_req_components_gohan = type_gohan.m_n_rows;
18873 const GLuint n_req_components_goten = type_goten.m_n_rows;
18875 /* Skip pairs that cannot fit into one location */
18876 if (n_components_per_location < (n_req_components_gohan + n_req_components_goten))
18881 const GLuint gohan = 0;
18882 const GLuint goten = gohan + n_req_components_gohan;
18884 const GLchar* fs_int_gohan = is_flat_req_gohan ? "flat" : "";
18885 const GLchar* fs_int_goten = is_flat_req_goten ? "flat" : "";
18887 testCase test_case_tcs_np = { gohan, goten, NONE, PATCH, "", "", false, Utils::Shader::TESS_CTRL,
18888 type_gohan, type_goten };
18890 testCase test_case_tcs_pn = { gohan, goten, PATCH, NONE, "", "", false, Utils::Shader::TESS_CTRL,
18891 type_gohan, type_goten };
18893 testCase test_case_tes_np = { gohan, goten, NONE, PATCH, "", "", true, Utils::Shader::TESS_EVAL,
18894 type_gohan, type_goten };
18896 testCase test_case_tes_pn = { gohan, goten, PATCH, NONE, "", "", true, Utils::Shader::TESS_EVAL,
18897 type_gohan, type_goten };
18899 testCase test_case_fs_nc = { gohan, goten, NONE, CENTROID,
18900 fs_int_gohan, fs_int_goten, true, Utils::Shader::FRAGMENT,
18901 type_gohan, type_goten };
18903 testCase test_case_fs_cn = { gohan, goten, CENTROID, NONE,
18904 fs_int_gohan, fs_int_goten, true, Utils::Shader::FRAGMENT,
18905 type_gohan, type_goten };
18907 testCase test_case_fs_ns = { gohan, goten, NONE, SAMPLE,
18908 fs_int_gohan, fs_int_goten, true, Utils::Shader::FRAGMENT,
18909 type_gohan, type_goten };
18911 testCase test_case_fs_sn = { gohan, goten, SAMPLE, NONE,
18912 fs_int_gohan, fs_int_goten, true, Utils::Shader::FRAGMENT,
18913 type_gohan, type_goten };
18915 testCase test_case_fs_cs = { gohan, goten, CENTROID, SAMPLE,
18916 fs_int_gohan, fs_int_goten, true, Utils::Shader::FRAGMENT,
18917 type_gohan, type_goten };
18919 testCase test_case_fs_sc = { gohan, goten, SAMPLE, CENTROID,
18920 fs_int_gohan, fs_int_goten, true, Utils::Shader::FRAGMENT,
18921 type_gohan, type_goten };
18923 m_test_cases.push_back(test_case_tcs_np);
18924 m_test_cases.push_back(test_case_tcs_pn);
18925 m_test_cases.push_back(test_case_tes_np);
18926 m_test_cases.push_back(test_case_tes_pn);
18927 m_test_cases.push_back(test_case_fs_nc);
18928 m_test_cases.push_back(test_case_fs_cn);
18929 m_test_cases.push_back(test_case_fs_ns);
18930 m_test_cases.push_back(test_case_fs_sn);
18931 m_test_cases.push_back(test_case_fs_cs);
18932 m_test_cases.push_back(test_case_fs_sc);
18937 /** Get auxiliary storage qualifier
18939 * @param aux Enumeration
18941 * @return GLSL qualifier
18943 const GLchar* VaryingLocationAliasingWithMixedAuxiliaryStorageTest::getAuxiliaryQualifier(AUXILIARIES aux)
18945 const GLchar* result = 0;
18956 result = "centroid";
18962 TCU_FAIL("Invalid enum");
18968 /** Check if given type is float
18970 * @param type Type in question
18972 * @return true if tpye is float, false otherwise
18974 bool VaryingLocationAliasingWithMixedAuxiliaryStorageTest::isFloatType(const Utils::Type& type)
18976 bool is_float = false;
18978 if ((Utils::Type::Double == type.m_basic_type) || (Utils::Type::Float == type.m_basic_type))
18986 /* Constants used by VertexAttribLocationAPITest */
18987 const GLuint VertexAttribLocationAPITest::m_goten_location = 6;
18991 * @param context Test framework context
18993 VertexAttribLocationAPITest::VertexAttribLocationAPITest(deqp::Context& context)
18994 : TextureTestBase(context, "vertex_attrib_location_api",
18995 "Test verifies that attribute locations API works as expected")
18999 /** Does BindAttribLocation for "goten" and relink program
19001 * @param program Program object
19002 * @param program_interface Interface of program
19004 void VertexAttribLocationAPITest::prepareAttribLocation(Utils::Program& program,
19005 Utils::ProgramInterface& program_interface)
19007 const Functions& gl = m_context.getRenderContext().getFunctions();
19009 gl.bindAttribLocation(program.m_id, m_goten_location, "goten");
19010 GLU_EXPECT_NO_ERROR(gl.getError(), "BindAttribLocation");
19012 program.Link(gl, program.m_id);
19014 /* We still need to get locations for gohan and chichi */
19015 TextureTestBase::prepareAttribLocation(program, program_interface);
19018 /** Get interface of program
19021 * @param program_interface Interface of program
19024 void VertexAttribLocationAPITest::getProgramInterface(GLuint /* test_case_index */,
19025 Utils::ProgramInterface& program_interface,
19026 Utils::VaryingPassthrough& /* varying_passthrough */)
19028 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
19029 const Utils::Type& type = Utils::Type::vec4;
19030 const GLuint type_size = type.GetSize();
19033 const GLuint chichi_offset = 0;
19034 const GLuint goten_offset = chichi_offset + type_size;
19035 const GLuint gohan_offset = goten_offset + type_size;
19036 const GLuint goku_offset = gohan_offset + type_size;
19039 const GLuint goku_location = 2;
19040 const GLuint goten_location = m_goten_location;
19042 /* Generate data */
19043 m_goku_data = type.GenerateDataPacked();
19044 m_gohan_data = type.GenerateDataPacked();
19045 m_goten_data = type.GenerateDataPacked();
19046 m_chichi_data = type.GenerateDataPacked();
19049 si.m_globals = "const uint GOKU_LOCATION = 2;\n";
19052 si.Input("goku" /* name */, "layout (location = GOKU_LOCATION)" /* qualifiers */, 0 /* expected_componenet */,
19053 goku_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19054 0u /* n_array_elements */, 0u /* stride */, goku_offset /* offset */, (GLvoid*)&m_goku_data[0] /* data */,
19055 m_goku_data.size() /* data_size */);
19057 si.Input("gohan" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19058 Utils::Variable::m_automatic_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19059 0u /* n_array_elements */, 0u /* stride */, gohan_offset /* offset */,
19060 (GLvoid*)&m_gohan_data[0] /* data */, m_gohan_data.size() /* data_size */);
19062 si.Input("goten" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19063 goten_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19064 0u /* n_array_elements */, 0u /* stride */, goten_offset /* offset */,
19065 (GLvoid*)&m_goten_data[0] /* data */, m_goten_data.size() /* data_size */);
19067 si.Input("chichi" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19068 Utils::Variable::m_automatic_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19069 0u /* n_array_elements */, 0u /* stride */, chichi_offset /* offset */,
19070 (GLvoid*)&m_chichi_data[0] /* data */, m_chichi_data.size() /* data_size */);
19073 /** Selects if "compute" stage is relevant for test
19079 bool VertexAttribLocationAPITest::isComputeRelevant(GLuint /* test_case_index */)
19084 /* Constants used by FragmentDataLocationAPITest */
19085 const GLuint FragmentDataLocationAPITest::m_goten_location = 6;
19089 * @param context Test framework context
19091 FragmentDataLocationAPITest::FragmentDataLocationAPITest(deqp::Context& context)
19092 : TextureTestBase(context, "fragment_data_location_api",
19093 "Test verifies that fragment data locations API works as expected")
19097 , m_chichi(context)
19101 /** Verifies contents of drawn images
19106 * @return true if images are filled with expected values, false otherwise
19108 bool FragmentDataLocationAPITest::checkResults(glw::GLuint /* test_case_index */, Utils::Texture& /* color_0 */)
19110 static const GLuint size = m_width * m_height;
19111 static const GLuint expected_goku = 0xff000000;
19112 static const GLuint expected_gohan = 0xff0000ff;
19113 static const GLuint expected_goten = 0xff00ff00;
19114 static const GLuint expected_chichi = 0xffff0000;
19116 std::vector<GLuint> data;
19119 m_goku.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_goku != color)
19127 m_context.getTestContext().getLog() << tcu::TestLog::Message << "RGBA8[" << i << "]:" << color
19128 << tcu::TestLog::EndMessage;
19133 m_gohan.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_gohan != color)
19141 m_context.getTestContext().getLog() << tcu::TestLog::Message << "RGBA8[" << i << "]:" << color
19142 << tcu::TestLog::EndMessage;
19147 m_goten.Get(GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
19149 for (GLuint i = 0; i < size; ++i)
19151 const GLuint color = data[i];
19153 if (expected_goten != color)
19155 m_context.getTestContext().getLog() << tcu::TestLog::Message << "RGBA8[" << i << "]:" << color
19156 << tcu::TestLog::EndMessage;
19161 m_chichi.Get(GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
19163 for (GLuint i = 0; i < size; ++i)
19165 const GLuint color = data[i];
19167 if (expected_chichi != color)
19169 m_context.getTestContext().getLog() << tcu::TestLog::Message << "RGBA8[" << i << "]:" << color
19170 << tcu::TestLog::EndMessage;
19178 /** Prepare code snippet that will set out variables
19182 * @param stage Shader stage
19184 * @return Code that pass in variables to next stage
19186 std::string FragmentDataLocationAPITest::getPassSnippet(GLuint /* test_case_index */,
19187 Utils::VaryingPassthrough& /* varying_passthrough */,
19188 Utils::Shader::STAGES stage)
19190 std::string result;
19192 /* Skip for compute shader */
19193 if (Utils::Shader::FRAGMENT != stage)
19199 result = "chichi = vec4(0, 0, 1, 1);\n"
19200 " goku = vec4(0, 0, 0, 1);\n"
19201 " goten = vec4(0, 1, 0, 1);\n"
19202 " gohan = vec4(1, 0, 0, 1);\n";
19208 /** Get interface of program
19211 * @param program_interface Interface of program
19214 void FragmentDataLocationAPITest::getProgramInterface(GLuint /* test_case_index */,
19215 Utils::ProgramInterface& program_interface,
19216 Utils::VaryingPassthrough& /* varying_passthrough */)
19218 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
19219 const Utils::Type& type = Utils::Type::vec4;
19222 m_goku_location = 2;
19225 si.m_globals = "const uint GOKU_LOCATION = 2;\n";
19228 si.Output("goku" /* name */, "layout (location = GOKU_LOCATION)" /* qualifiers */, 0 /* expected_componenet */,
19229 m_goku_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19230 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)0 /* data */, 0u /* data_size */);
19232 si.Output("gohan" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19233 Utils::Variable::m_automatic_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19234 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)0 /* data */, 0u /* data_size */);
19236 si.Output("goten" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19237 m_goten_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19238 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)0 /* data */, 0u /* data_size */);
19240 si.Output("chichi" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19241 Utils::Variable::m_automatic_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19242 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)0 /* data */, 0u /* data_size */);
19245 /** Selects if "compute" stage is relevant for test
19251 bool FragmentDataLocationAPITest::isComputeRelevant(GLuint /* test_case_index */)
19256 /** Get locations for all outputs with automatic_location
19258 * @param program Program object
19259 * @param program_interface Interface of program
19261 void FragmentDataLocationAPITest::prepareFragmentDataLoc(Utils::Program& program,
19262 Utils::ProgramInterface& program_interface)
19264 /* Bind location of goten */
19265 const Functions& gl = m_context.getRenderContext().getFunctions();
19267 gl.bindFragDataLocation(program.m_id, m_goten_location, "goten");
19268 GLU_EXPECT_NO_ERROR(gl.getError(), "BindFragDataLocation");
19270 program.Link(gl, program.m_id);
19272 /* Prepare locations for gohan and chichi */
19273 TextureTestBase::prepareFragmentDataLoc(program, program_interface);
19275 /* Get all locations */
19276 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
19278 Utils::Variable::PtrVector& outputs = si.m_outputs;
19280 for (Utils::Variable::PtrVector::iterator it = outputs.begin(); outputs.end() != it; ++it)
19282 const Utils::Variable::Descriptor& desc = (*it)->m_descriptor;
19284 if (0 == desc.m_name.compare("gohan"))
19286 m_gohan_location = desc.m_expected_location;
19288 else if (0 == desc.m_name.compare("chichi"))
19290 m_chichi_location = desc.m_expected_location;
19293 /* Locations of goku and goten are fixed */
19297 /** Prepare framebuffer with single texture as color attachment
19299 * @param framebuffer Framebuffer
19300 * @param color_0_texture Texture that will used as color attachment
19302 void FragmentDataLocationAPITest::prepareFramebuffer(Utils::Framebuffer& framebuffer, Utils::Texture& color_0_texture)
19304 /* Let parent prepare its stuff */
19305 TextureTestBase::prepareFramebuffer(framebuffer, color_0_texture);
19308 std::vector<GLuint> texture_data;
19309 texture_data.resize(m_width * m_height);
19311 for (GLuint i = 0; i < texture_data.size(); ++i)
19313 texture_data[i] = 0x20406080;
19316 /* Prepare textures */
19317 m_goku.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]);
19319 m_gohan.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]);
19321 m_goten.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]);
19323 m_chichi.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]);
19325 /* Attach textures to framebuffer */
19326 framebuffer.Bind();
19327 framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0 + m_goku_location, m_goku.m_id, m_width, m_height);
19328 framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0 + m_gohan_location, m_gohan.m_id, m_width, m_height);
19329 framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0 + m_goten_location, m_goten.m_id, m_width, m_height);
19330 framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0 + m_chichi_location, m_chichi.m_id, m_width, m_height);
19332 /* Set up drawbuffers */
19333 const Functions& gl = m_context.getRenderContext().getFunctions();
19334 // 1. There are only 4 outputs in fragment shader, so only need to do buffer mapping for 4 attachments,
19335 // 2. another issue is each output variable has a location, it is the fragment color index, so the index of
19336 // GL_COLOR_ATTACHMENT in glDrawBuffers() should keep the same with the location, to make test correct,
19337 // we needt to change the above code of glDrawBuffers() as :
19338 GLint buffers_size = 4;
19339 GLenum buffers[] = { GLenum(GL_COLOR_ATTACHMENT0 + m_chichi_location),
19340 GLenum(GL_COLOR_ATTACHMENT0 + m_goku_location),
19341 GLenum(GL_COLOR_ATTACHMENT0 + m_goten_location),
19342 GLenum(GL_COLOR_ATTACHMENT0 + m_gohan_location) };
19343 gl.drawBuffers(buffers_size, buffers);
19344 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawBuffers");
19349 * @param context Test framework context
19351 XFBInputTest::XFBInputTest(deqp::Context& context)
19352 : NegativeTestBase(context, "xfb_input",
19353 "Test verifies that compiler reports error when xfb qualifiers are used with input")
19357 /** Source for given test case and stage
19359 * @param test_case_index Index of test case
19360 * @param stage Shader stage
19362 * @return Shader source
19364 std::string XFBInputTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
19366 static const GLchar* buffer_var_definition = "layout (xfb_buffer = 2) in vec4 gohanARRAY;\n";
19367 static const GLchar* offset_var_definition = "layout (xfb_offset = 16) in vec4 gohanARRAY;\n";
19368 static const GLchar* stride_var_definition = "layout (xfb_stride = 32) in vec4 gohanARRAY;\n";
19369 static const GLchar* input_use = " result += gohanINDEX;\n";
19370 static const GLchar* fs = "#version 430 core\n"
19371 "#extension GL_ARB_enhanced_layouts : require\n"
19374 "out vec4 fs_out;\n"
19378 " fs_out = gs_fs;\n"
19381 static const GLchar* fs_tested = "#version 430 core\n"
19382 "#extension GL_ARB_enhanced_layouts : require\n"
19387 "out vec4 fs_out;\n"
19391 " vec4 result = gs_fs;\n"
19395 " fs_out = result;\n"
19398 static const GLchar* gs = "#version 430 core\n"
19399 "#extension GL_ARB_enhanced_layouts : require\n"
19401 "layout(points) in;\n"
19402 "layout(triangle_strip, max_vertices = 4) out;\n"
19404 "in vec4 tes_gs[];\n"
19405 "out vec4 gs_fs;\n"
19409 " gs_fs = tes_gs[0];\n"
19410 " gl_Position = vec4(-1, -1, 0, 1);\n"
19412 " gs_fs = tes_gs[0];\n"
19413 " gl_Position = vec4(-1, 1, 0, 1);\n"
19415 " gs_fs = tes_gs[0];\n"
19416 " gl_Position = vec4(1, -1, 0, 1);\n"
19418 " gs_fs = tes_gs[0];\n"
19419 " gl_Position = vec4(1, 1, 0, 1);\n"
19423 static const GLchar* gs_tested = "#version 430 core\n"
19424 "#extension GL_ARB_enhanced_layouts : require\n"
19426 "layout(points) in;\n"
19427 "layout(triangle_strip, max_vertices = 4) out;\n"
19431 "in vec4 tes_gs[];\n"
19432 "out vec4 gs_fs;\n"
19436 " vec4 result = tes_gs[0];\n"
19440 " gs_fs = result;\n"
19441 " gl_Position = vec4(-1, -1, 0, 1);\n"
19443 " gs_fs = result;\n"
19444 " gl_Position = vec4(-1, 1, 0, 1);\n"
19446 " gs_fs = result;\n"
19447 " gl_Position = vec4(1, -1, 0, 1);\n"
19449 " gs_fs = result;\n"
19450 " gl_Position = vec4(1, 1, 0, 1);\n"
19454 static const GLchar* tcs = "#version 430 core\n"
19455 "#extension GL_ARB_enhanced_layouts : require\n"
19457 "layout(vertices = 1) out;\n"
19459 "in vec4 vs_tcs[];\n"
19460 "out vec4 tcs_tes[];\n"
19465 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
19467 " gl_TessLevelOuter[0] = 1.0;\n"
19468 " gl_TessLevelOuter[1] = 1.0;\n"
19469 " gl_TessLevelOuter[2] = 1.0;\n"
19470 " gl_TessLevelOuter[3] = 1.0;\n"
19471 " gl_TessLevelInner[0] = 1.0;\n"
19472 " gl_TessLevelInner[1] = 1.0;\n"
19475 static const GLchar* tcs_tested = "#version 430 core\n"
19476 "#extension GL_ARB_enhanced_layouts : require\n"
19478 "layout(vertices = 1) out;\n"
19482 "in vec4 vs_tcs[];\n"
19483 "out vec4 tcs_tes[];\n"
19487 " vec4 result = vs_tcs[gl_InvocationID];\n"
19491 " tcs_tes[gl_InvocationID] = result;\n"
19493 " gl_TessLevelOuter[0] = 1.0;\n"
19494 " gl_TessLevelOuter[1] = 1.0;\n"
19495 " gl_TessLevelOuter[2] = 1.0;\n"
19496 " gl_TessLevelOuter[3] = 1.0;\n"
19497 " gl_TessLevelInner[0] = 1.0;\n"
19498 " gl_TessLevelInner[1] = 1.0;\n"
19501 static const GLchar* tes = "#version 430 core\n"
19502 "#extension GL_ARB_enhanced_layouts : require\n"
19504 "layout(isolines, point_mode) in;\n"
19506 "in vec4 tcs_tes[];\n"
19507 "out vec4 tes_gs;\n"
19511 " tes_gs = tcs_tes[0];\n"
19514 static const GLchar* tes_tested = "#version 430 core\n"
19515 "#extension GL_ARB_enhanced_layouts : require\n"
19517 "layout(isolines, point_mode) in;\n"
19521 "in vec4 tcs_tes[];\n"
19522 "out vec4 tes_gs;\n"
19526 " vec4 result = tcs_tes[0];\n"
19530 " tes_gs += result;\n"
19533 static const GLchar* vs = "#version 430 core\n"
19534 "#extension GL_ARB_enhanced_layouts : require\n"
19537 "out vec4 vs_tcs;\n"
19541 " vs_tcs = in_vs;\n"
19544 static const GLchar* vs_tested = "#version 430 core\n"
19545 "#extension GL_ARB_enhanced_layouts : require\n"
19550 "out vec4 vs_tcs;\n"
19554 " vec4 result = in_vs;\n"
19558 " vs_tcs += result;\n"
19562 std::string source;
19563 testCase& test_case = m_test_cases[test_case_index];
19565 if (test_case.m_stage == stage)
19567 const GLchar* array = "";
19568 const GLchar* index = "";
19569 size_t position = 0;
19571 const GLchar* var_definition = 0;
19572 const GLchar* var_use = input_use;
19574 switch (test_case.m_qualifier)
19577 var_definition = buffer_var_definition;
19580 var_definition = offset_var_definition;
19583 var_definition = stride_var_definition;
19586 TCU_FAIL("Invalid enum");
19591 case Utils::Shader::FRAGMENT:
19592 source = fs_tested;
19594 case Utils::Shader::GEOMETRY:
19595 source = gs_tested;
19599 case Utils::Shader::TESS_CTRL:
19600 source = tcs_tested;
19602 index = "[gl_InvocationID]";
19604 case Utils::Shader::TESS_EVAL:
19605 source = tes_tested;
19609 case Utils::Shader::VERTEX:
19610 source = vs_tested;
19613 TCU_FAIL("Invalid enum");
19617 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
19619 Utils::replaceToken("ARRAY", position, array, source);
19620 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
19622 Utils::replaceAllTokens("INDEX", index, source);
19628 case Utils::Shader::FRAGMENT:
19631 case Utils::Shader::GEOMETRY:
19634 case Utils::Shader::TESS_CTRL:
19637 case Utils::Shader::TESS_EVAL:
19640 case Utils::Shader::VERTEX:
19644 TCU_FAIL("Invalid enum");
19651 /** Get description of test case
19653 * @param test_case_index Index of test case
19655 * @return Test case description
19657 std::string XFBInputTest::getTestCaseName(GLuint test_case_index)
19659 std::stringstream stream;
19660 testCase& test_case = m_test_cases[test_case_index];
19662 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", qualifier: ";
19664 switch (test_case.m_qualifier)
19667 stream << "xfb_buffer";
19670 stream << "xfb_offset";
19673 stream << "xfb_stride";
19676 TCU_FAIL("Invalid enum");
19679 return stream.str();
19682 /** Get number of test cases
19684 * @return Number of test cases
19686 GLuint XFBInputTest::getTestCaseNumber()
19688 return static_cast<GLuint>(m_test_cases.size());
19691 /** Selects if "compute" stage is relevant for test
19697 bool XFBInputTest::isComputeRelevant(GLuint /* test_case_index */)
19702 /** Prepare all test cases
19705 void XFBInputTest::testInit()
19707 for (GLuint qualifier = 0; qualifier < QUALIFIERS_MAX; ++qualifier)
19709 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
19711 if (Utils::Shader::COMPUTE == stage)
19716 testCase test_case = { (QUALIFIERS)qualifier, (Utils::Shader::STAGES)stage };
19718 m_test_cases.push_back(test_case);
19723 /* Constants used by XFBAllStagesTest */
19724 const GLuint XFBAllStagesTest::m_gs_index = 3;
19728 * @param context Test context
19730 XFBAllStagesTest::XFBAllStagesTest(deqp::Context& context)
19731 : BufferTestBase(context, "xfb_all_stages",
19732 "Test verifies that only last stage in vertex processing can output to transform feedback")
19734 /* Nothing to be done here */
19737 /** Get descriptors of buffers necessary for test
19740 * @param out_descriptors Descriptors of buffers used by test
19742 void XFBAllStagesTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
19743 bufferDescriptor::Vector& out_descriptors)
19745 static const GLuint n_stages = 4;
19746 const Utils::Type& vec4 = Utils::Type::vec4;
19751 /* Test uses single uniform and xfb per stage + uniform for fragment shader */
19752 out_descriptors.resize(n_stages * 2 + 1);
19755 for (GLuint i = 0; i < n_stages; ++i)
19757 /* Get references */
19758 bufferDescriptor& uniform = out_descriptors[i + 0];
19759 bufferDescriptor& xfb = out_descriptors[i + n_stages];
19762 uniform.m_index = i;
19766 uniform.m_target = Utils::Buffer::Uniform;
19767 xfb.m_target = Utils::Buffer::Transform_feedback;
19770 const tcu::Vec4 var(Utils::GetRandFloat(), Utils::GetRandFloat(), Utils::GetRandFloat(), Utils::GetRandFloat());
19774 uniform.m_initial_data.resize(vec4.GetSize());
19775 memcpy(&uniform.m_initial_data[0], var.getPtr(), vec4.GetSize());
19777 xfb.m_initial_data = vec4.GenerateDataPacked();
19779 if (m_gs_index != i)
19781 xfb.m_expected_data = xfb.m_initial_data;
19785 xfb.m_expected_data.resize(vec4.GetSize());
19786 memcpy(&xfb.m_expected_data[0], sum.getPtr(), vec4.GetSize());
19792 /* Get reference */
19793 bufferDescriptor& uniform = out_descriptors[n_stages * 2];
19796 uniform.m_index = n_stages;
19799 uniform.m_target = Utils::Buffer::Uniform;
19802 const tcu::Vec4 var(Utils::GetRandFloat(), Utils::GetRandFloat(), Utils::GetRandFloat(), Utils::GetRandFloat());
19804 uniform.m_initial_data.resize(vec4.GetSize());
19805 memcpy(&uniform.m_initial_data[0], var.getPtr(), vec4.GetSize());
19809 /** Get body of main function for given shader stage
19812 * @param stage Shader stage
19813 * @param out_assignments Set to empty
19814 * @param out_calculations Set to empty
19816 void XFBAllStagesTest::getShaderBody(glw::GLuint /* test_case_index */, Utils::Shader::STAGES stage,
19817 std::string& out_assignments, std::string& out_calculations)
19819 out_calculations = "";
19821 static const GLchar* vs = " vs_tcs = uni_vs;\n";
19822 static const GLchar* tcs = " tcs_tes[gl_InvocationID] = uni_tcs + vs_tcs[gl_InvocationID];\n";
19823 static const GLchar* tes = " tes_gs = uni_tes + tcs_tes[0];\n";
19824 static const GLchar* gs = " gs_fs = uni_gs + tes_gs[0];\n";
19825 static const GLchar* fs = " fs_out = uni_fs + gs_fs;\n";
19827 const GLchar* assignments = 0;
19830 case Utils::Shader::FRAGMENT:
19833 case Utils::Shader::GEOMETRY:
19836 case Utils::Shader::TESS_CTRL:
19839 case Utils::Shader::TESS_EVAL:
19842 case Utils::Shader::VERTEX:
19846 TCU_FAIL("Invalid enum");
19849 out_assignments = assignments;
19852 /** Get interface of shader
19855 * @param stage Shader stage
19856 * @param out_interface Set to ""
19858 void XFBAllStagesTest::getShaderInterface(glw::GLuint /* test_case_index */, Utils::Shader::STAGES stage,
19859 std::string& out_interface)
19861 static const GLchar* vs = "layout(xfb_buffer = 0, xfb_offset = 0) out vec4 vs_tcs;\n"
19862 "layout(binding = 0) uniform vs_block {\n"
19865 static const GLchar* tcs = " in vec4 vs_tcs[];\n"
19866 "layout(xfb_buffer = 1, xfb_offset = 0) out vec4 tcs_tes[1];\n"
19867 "layout(binding = 1) uniform tcs_block {\n"
19870 static const GLchar* tes = " in vec4 tcs_tes[];\n"
19871 "layout(xfb_buffer = 2, xfb_offset = 0) out vec4 tes_gs;\n"
19872 "layout(binding = 2) uniform tes_block {\n"
19875 static const GLchar* gs = " in vec4 tes_gs[];\n"
19876 "layout(xfb_buffer = 3, xfb_offset = 0) out vec4 gs_fs;\n"
19877 "layout(binding = 3) uniform gs_block {\n"
19880 static const GLchar* fs = " in vec4 gs_fs;\n"
19881 " out vec4 fs_out;\n"
19882 "layout(binding = 4) uniform fs_block {\n"
19886 const GLchar* interface = 0;
19889 case Utils::Shader::FRAGMENT:
19892 case Utils::Shader::GEOMETRY:
19895 case Utils::Shader::TESS_CTRL:
19898 case Utils::Shader::TESS_EVAL:
19901 case Utils::Shader::VERTEX:
19905 TCU_FAIL("Invalid enum");
19908 out_interface = interface;
19911 /* Constants used by XFBStrideOfEmptyListTest */
19912 const GLuint XFBStrideOfEmptyListTest::m_stride = 64;
19916 * @param context Test context
19918 XFBStrideOfEmptyListTest::XFBStrideOfEmptyListTest(deqp::Context& context)
19919 : BufferTestBase(context, "xfb_stride_of_empty_list",
19920 "Test verifies that xfb_stride qualifier is respected when no xfb_offset is specified")
19922 /* Nothing to be done here */
19925 /** Execute drawArrays for single vertex
19927 * @param test_case_index Index of test case
19929 * @return true if proper error is reported
19931 bool XFBStrideOfEmptyListTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
19933 const Functions& gl = m_context.getRenderContext().getFunctions();
19934 bool result = true;
19937 gl.disable(GL_RASTERIZER_DISCARD);
19938 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
19940 gl.beginTransformFeedback(GL_POINTS);
19941 GLenum error = gl.getError();
19942 switch (test_case_index)
19945 if (GL_NO_ERROR != error)
19947 gl.endTransformFeedback();
19948 GLU_EXPECT_NO_ERROR(error, "BeginTransformFeedback");
19951 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
19952 error = gl.getError();
19954 gl.endTransformFeedback();
19955 GLU_EXPECT_NO_ERROR(error, "DrawArrays");
19956 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
19960 case FIRST_MISSING:
19961 if (GL_NO_ERROR == error)
19963 gl.endTransformFeedback();
19966 if (GL_INVALID_OPERATION != error)
19968 m_context.getTestContext().getLog()
19969 << tcu::TestLog::Message << "XFB at index 0, that is written by GS, is missing. It was expected that "
19970 "INVALID_OPERATION will generated by BeginTransformFeedback. Got: "
19971 << glu::getErrorStr(error) << tcu::TestLog::EndMessage;
19978 case SECOND_MISSING:
19979 if (GL_NO_ERROR == error)
19981 gl.endTransformFeedback();
19984 if (GL_INVALID_OPERATION != error)
19986 m_context.getTestContext().getLog()
19987 << tcu::TestLog::Message << "XFB at index 1, that is declared as empty, is missing. It was expected "
19988 "that INVALID_OPERATION will generated by BeginTransformFeedback. Got: "
19989 << glu::getErrorStr(error) << tcu::TestLog::EndMessage;
20001 /** Get descriptors of buffers necessary for test
20003 * @param test_case_index Index of test case
20004 * @param out_descriptors Descriptors of buffers used by test
20006 void XFBStrideOfEmptyListTest::getBufferDescriptors(glw::GLuint test_case_index,
20007 bufferDescriptor::Vector& out_descriptors)
20009 switch (test_case_index)
20013 /* Test needs single uniform and two xfbs */
20014 out_descriptors.resize(3);
20016 /* Get references */
20017 bufferDescriptor& uniform = out_descriptors[0];
20018 bufferDescriptor& xfb_0 = out_descriptors[1];
20019 bufferDescriptor& xfb_1 = out_descriptors[2];
20022 uniform.m_index = 0;
20027 uniform.m_target = Utils::Buffer::Uniform;
20028 xfb_0.m_target = Utils::Buffer::Transform_feedback;
20029 xfb_1.m_target = Utils::Buffer::Transform_feedback;
20032 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20034 xfb_0.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20035 xfb_0.m_expected_data = uniform.m_initial_data;
20037 /* Data, contents are the same as no modification is expected */
20038 xfb_1.m_initial_data.resize(m_stride);
20039 xfb_1.m_expected_data.resize(m_stride);
20041 for (GLuint i = 0; i < m_stride; ++i)
20043 xfb_1.m_initial_data[0] = (glw::GLubyte)i;
20044 xfb_1.m_expected_data[0] = (glw::GLubyte)i;
20050 case FIRST_MISSING:
20052 /* Test needs single uniform and two xfbs */
20053 out_descriptors.resize(2);
20055 /* Get references */
20056 bufferDescriptor& uniform = out_descriptors[0];
20057 bufferDescriptor& xfb_1 = out_descriptors[1];
20060 uniform.m_index = 0;
20064 uniform.m_target = Utils::Buffer::Uniform;
20065 xfb_1.m_target = Utils::Buffer::Transform_feedback;
20068 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20070 /* Draw call will not be executed, contents does not matter */
20071 xfb_1.m_initial_data.resize(m_stride);
20076 case SECOND_MISSING:
20078 /* Test needs single uniform and two xfbs */
20079 out_descriptors.resize(2);
20081 /* Get references */
20082 bufferDescriptor& uniform = out_descriptors[0];
20083 bufferDescriptor& xfb_0 = out_descriptors[1];
20086 uniform.m_index = 0;
20090 uniform.m_target = Utils::Buffer::Uniform;
20091 xfb_0.m_target = Utils::Buffer::Transform_feedback;
20094 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20096 /* Draw call will not be executed, contents does not matter */
20097 xfb_0.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20104 /** Get body of main function for given shader stage
20107 * @param stage Shader stage
20108 * @param out_assignments Set to empty
20109 * @param out_calculations Set to empty
20111 void XFBStrideOfEmptyListTest::getShaderBody(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
20112 std::string& out_assignments, std::string& out_calculations)
20114 out_calculations = "";
20116 static const GLchar* gs = " gs_fs = uni_gs;\n";
20117 static const GLchar* fs = " fs_out = vec4(gs_fs);\n";
20119 const GLchar* assignments = "";
20122 case Utils::Shader::FRAGMENT:
20125 case Utils::Shader::GEOMETRY:
20132 out_assignments = assignments;
20135 /** Get interface of shader
20138 * @param stage Shader stage
20139 * @param out_interface Set to ""
20141 void XFBStrideOfEmptyListTest::getShaderInterface(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
20142 std::string& out_interface)
20144 static const GLchar* gs = "layout (xfb_buffer = 0, xfb_offset = 0) out vec4 gs_fs;\n"
20145 "layout (xfb_buffer = 1, xfb_stride = 64) out;\n"
20147 "layout (binding = 0) uniform gs_block {\n"
20150 static const GLchar* fs = "in vec4 gs_fs;\n"
20151 "out vec4 fs_out;\n";
20155 case Utils::Shader::FRAGMENT:
20156 out_interface = fs;
20158 case Utils::Shader::GEOMETRY:
20159 out_interface = gs;
20162 out_interface = "";
20167 /** Returns buffer details in human readable form.
20169 * @param test_case_index Index of test case
20171 * @return Case description
20173 std::string XFBStrideOfEmptyListTest::getTestCaseName(GLuint test_case_index)
20175 std::string result;
20177 switch (test_case_index)
20180 result = "Valid case";
20182 case FIRST_MISSING:
20183 result = "Missing xfb at index 0";
20185 case SECOND_MISSING:
20186 result = "Missing xfb at index 1";
20189 TCU_FAIL("Invalid enum");
20195 /** Get number of test cases
20199 GLuint XFBStrideOfEmptyListTest::getTestCaseNumber()
20204 /* Constants used by XFBStrideOfEmptyListTest */
20205 const GLuint XFBStrideOfEmptyListAndAPITest::m_stride = 64;
20209 * @param context Test context
20211 XFBStrideOfEmptyListAndAPITest::XFBStrideOfEmptyListAndAPITest(deqp::Context& context)
20212 : BufferTestBase(context, "xfb_stride_of_empty_list_and_api",
20213 "Test verifies that xfb_stride qualifier is not overriden by API")
20215 /* Nothing to be done here */
20218 /** Execute drawArrays for single vertex
20220 * @param test_case_index Index of test case
20222 * @return true if proper error is reported
20224 bool XFBStrideOfEmptyListAndAPITest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
20226 const Functions& gl = m_context.getRenderContext().getFunctions();
20227 bool result = true;
20230 gl.disable(GL_RASTERIZER_DISCARD);
20231 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
20233 gl.beginTransformFeedback(GL_POINTS);
20234 GLenum error = gl.getError();
20235 switch (test_case_index)
20238 if (GL_NO_ERROR != error)
20240 gl.endTransformFeedback();
20241 GLU_EXPECT_NO_ERROR(error, "BeginTransformFeedback");
20244 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
20245 error = gl.getError();
20247 gl.endTransformFeedback();
20248 GLU_EXPECT_NO_ERROR(error, "DrawArrays");
20249 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
20253 case FIRST_MISSING:
20254 if (GL_NO_ERROR == error)
20256 gl.endTransformFeedback();
20259 if (GL_INVALID_OPERATION != error)
20261 m_context.getTestContext().getLog()
20262 << tcu::TestLog::Message << "XFB at index 0, that is declared as empty, is missing. It was expected "
20263 "that INVALID_OPERATION will generated by BeginTransformFeedback. Got: "
20264 << glu::getErrorStr(error) << tcu::TestLog::EndMessage;
20271 case SECOND_MISSING:
20272 if (GL_NO_ERROR == error)
20274 gl.endTransformFeedback();
20277 if (GL_INVALID_OPERATION != error)
20279 m_context.getTestContext().getLog()
20280 << tcu::TestLog::Message << "XFB at index 1, that is written by GS, is missing. It was expected that "
20281 "INVALID_OPERATION will generated by BeginTransformFeedback. Got: "
20282 << glu::getErrorStr(error) << tcu::TestLog::EndMessage;
20294 /** Get descriptors of buffers necessary for test
20296 * @param test_case_index Index of test case
20297 * @param out_descriptors Descriptors of buffers used by test
20299 void XFBStrideOfEmptyListAndAPITest::getBufferDescriptors(glw::GLuint test_case_index,
20300 bufferDescriptor::Vector& out_descriptors)
20302 switch (test_case_index)
20306 /* Test needs single uniform and two xfbs */
20307 out_descriptors.resize(3);
20309 /* Get references */
20310 bufferDescriptor& uniform = out_descriptors[0];
20311 bufferDescriptor& xfb_0 = out_descriptors[1];
20312 bufferDescriptor& xfb_1 = out_descriptors[2];
20315 uniform.m_index = 0;
20320 uniform.m_target = Utils::Buffer::Uniform;
20321 xfb_0.m_target = Utils::Buffer::Transform_feedback;
20322 xfb_1.m_target = Utils::Buffer::Transform_feedback;
20325 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20327 /* Data, contents are the same as no modification is expected */
20328 xfb_0.m_initial_data.resize(m_stride);
20329 xfb_0.m_expected_data.resize(m_stride);
20331 for (GLuint i = 0; i < m_stride; ++i)
20333 xfb_0.m_initial_data[0] = (glw::GLubyte)i;
20334 xfb_0.m_expected_data[0] = (glw::GLubyte)i;
20337 xfb_1.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20338 xfb_1.m_expected_data = uniform.m_initial_data;
20343 case FIRST_MISSING:
20345 /* Test needs single uniform and two xfbs */
20346 out_descriptors.resize(2);
20348 /* Get references */
20349 bufferDescriptor& uniform = out_descriptors[0];
20350 bufferDescriptor& xfb_1 = out_descriptors[1];
20353 uniform.m_index = 0;
20357 uniform.m_target = Utils::Buffer::Uniform;
20358 xfb_1.m_target = Utils::Buffer::Transform_feedback;
20361 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20363 /* Draw call will not be executed, contents does not matter */
20364 xfb_1.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20369 case SECOND_MISSING:
20371 /* Test needs single uniform and two xfbs */
20372 out_descriptors.resize(2);
20374 /* Get references */
20375 bufferDescriptor& uniform = out_descriptors[0];
20376 bufferDescriptor& xfb_0 = out_descriptors[1];
20379 uniform.m_index = 0;
20383 uniform.m_target = Utils::Buffer::Uniform;
20384 xfb_0.m_target = Utils::Buffer::Transform_feedback;
20387 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20389 /* Draw call will not be executed, contents does not matter */
20390 xfb_0.m_initial_data.resize(m_stride);
20397 /** Get list of names of varyings that will be registered with TransformFeedbackVaryings
20400 * @param captured_varyings Vector of varying names to be captured
20402 void XFBStrideOfEmptyListAndAPITest::getCapturedVaryings(glw::GLuint /* test_case_index */,
20403 Utils::Program::NameVector& captured_varyings)
20405 captured_varyings.push_back("gs_fs");
20408 /** Get body of main function for given shader stage
20411 * @param stage Shader stage
20412 * @param out_assignments Set to empty
20413 * @param out_calculations Set to empty
20415 void XFBStrideOfEmptyListAndAPITest::getShaderBody(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
20416 std::string& out_assignments, std::string& out_calculations)
20418 out_calculations = "";
20420 static const GLchar* gs = " gs_fs = uni_gs;\n";
20421 static const GLchar* fs = " fs_out = vec4(gs_fs);\n";
20423 const GLchar* assignments = "";
20426 case Utils::Shader::FRAGMENT:
20429 case Utils::Shader::GEOMETRY:
20436 out_assignments = assignments;
20439 /** Get interface of shader
20442 * @param stage Shader stage
20443 * @param out_interface Set to ""
20445 void XFBStrideOfEmptyListAndAPITest::getShaderInterface(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
20446 std::string& out_interface)
20448 static const GLchar* gs = "layout (xfb_buffer = 0, xfb_stride = 64) out;\n"
20449 "layout (xfb_buffer = 1, xfb_offset = 0) out vec4 gs_fs;\n"
20451 "layout(binding = 0) uniform gs_block {\n"
20454 static const GLchar* fs = "in vec4 gs_fs;\n"
20455 "out vec4 fs_out;\n";
20459 case Utils::Shader::FRAGMENT:
20460 out_interface = fs;
20462 case Utils::Shader::GEOMETRY:
20463 out_interface = gs;
20466 out_interface = "";
20471 /** Returns buffer details in human readable form.
20473 * @param test_case_index Index of test case
20475 * @return Case description
20477 std::string XFBStrideOfEmptyListAndAPITest::getTestCaseName(GLuint test_case_index)
20479 std::string result;
20481 switch (test_case_index)
20484 result = "Valid case";
20486 case FIRST_MISSING:
20487 result = "Missing xfb at index 0";
20489 case SECOND_MISSING:
20490 result = "Missing xfb at index 1";
20493 TCU_FAIL("Invalid enum");
20499 /** Get number of test cases
20503 GLuint XFBStrideOfEmptyListAndAPITest::getTestCaseNumber()
20510 * @param context Test framework context
20512 XFBTooSmallStrideTest::XFBTooSmallStrideTest(deqp::Context& context)
20513 : NegativeTestBase(context, "xfb_too_small_stride",
20514 "Test verifies that compiler reports error when xfb_stride sets not enough space")
20518 /** Source for given test case and stage
20520 * @param test_case_index Index of test case
20521 * @param stage Shader stage
20523 * @return Shader source
20525 std::string XFBTooSmallStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
20527 static const GLchar* array_var_definition = "layout (xfb_buffer = 0, xfb_stride = 32) out;\n"
20529 "layout (xfb_offset = 16) out vec4 gohanARRAY[4];\n";
20530 static const GLchar* block_var_definition = "layout (xfb_buffer = 0, xfb_stride = 32) out;\n"
20532 "layout (xfb_offset = 0) out Goku {\n"
20537 static const GLchar* offset_var_definition = "layout (xfb_buffer = 0, xfb_stride = 40) out;\n"
20539 "layout (xfb_offset = 32) out vec4 gohanARRAY;\n";
20540 // 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;"
20541 // To make the shader failed to compile, change xfb_stride to a value that is smaller than 32
20542 static const GLchar* stride_var_definition = "layout (xfb_buffer = 0, xfb_stride = 28) out;\n"
20544 "layout (xfb_offset = 16, xfb_stride = 28) out vec4 gohanARRAY;\n";
20545 static const GLchar* array_use = " gohanINDEX[0] = result / 2;\n"
20546 " gohanINDEX[1] = result / 4;\n"
20547 " gohanINDEX[2] = result / 6;\n"
20548 " gohanINDEX[3] = result / 8;\n";
20549 static const GLchar* block_use = " gokuINDEX.gohan = result / 2;\n"
20550 " gokuINDEX.goten = result / 4;\n"
20551 " gokuINDEX.chichi = result / 6;\n";
20552 static const GLchar* output_use = "gohanINDEX = result / 4;\n";
20553 static const GLchar* fs = "#version 430 core\n"
20554 "#extension GL_ARB_enhanced_layouts : require\n"
20557 "out vec4 fs_out;\n"
20561 " fs_out = gs_fs;\n"
20564 static const GLchar* gs_tested = "#version 430 core\n"
20565 "#extension GL_ARB_enhanced_layouts : require\n"
20567 "layout(points) in;\n"
20568 "layout(triangle_strip, max_vertices = 4) out;\n"
20572 "in vec4 tes_gs[];\n"
20573 "out vec4 gs_fs;\n"
20577 " vec4 result = tes_gs[0];\n"
20581 " gs_fs = result;\n"
20582 " gl_Position = vec4(-1, -1, 0, 1);\n"
20584 " gs_fs = result;\n"
20585 " gl_Position = vec4(-1, 1, 0, 1);\n"
20587 " gs_fs = result;\n"
20588 " gl_Position = vec4(1, -1, 0, 1);\n"
20590 " gs_fs = result;\n"
20591 " gl_Position = vec4(1, 1, 0, 1);\n"
20595 static const GLchar* tcs = "#version 430 core\n"
20596 "#extension GL_ARB_enhanced_layouts : require\n"
20598 "layout(vertices = 1) out;\n"
20600 "in vec4 vs_tcs[];\n"
20601 "out vec4 tcs_tes[];\n"
20606 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
20608 " gl_TessLevelOuter[0] = 1.0;\n"
20609 " gl_TessLevelOuter[1] = 1.0;\n"
20610 " gl_TessLevelOuter[2] = 1.0;\n"
20611 " gl_TessLevelOuter[3] = 1.0;\n"
20612 " gl_TessLevelInner[0] = 1.0;\n"
20613 " gl_TessLevelInner[1] = 1.0;\n"
20616 static const GLchar* tcs_tested = "#version 430 core\n"
20617 "#extension GL_ARB_enhanced_layouts : require\n"
20619 "layout(vertices = 1) out;\n"
20623 "in vec4 vs_tcs[];\n"
20624 "out vec4 tcs_tes[];\n"
20628 " vec4 result = vs_tcs[gl_InvocationID];\n"
20632 " tcs_tes[gl_InvocationID] = result;\n"
20634 " gl_TessLevelOuter[0] = 1.0;\n"
20635 " gl_TessLevelOuter[1] = 1.0;\n"
20636 " gl_TessLevelOuter[2] = 1.0;\n"
20637 " gl_TessLevelOuter[3] = 1.0;\n"
20638 " gl_TessLevelInner[0] = 1.0;\n"
20639 " gl_TessLevelInner[1] = 1.0;\n"
20642 static const GLchar* tes_tested = "#version 430 core\n"
20643 "#extension GL_ARB_enhanced_layouts : require\n"
20645 "layout(isolines, point_mode) in;\n"
20649 "in vec4 tcs_tes[];\n"
20650 "out vec4 tes_gs;\n"
20654 " vec4 result = tcs_tes[0];\n"
20658 " tes_gs += result;\n"
20661 static const GLchar* vs = "#version 430 core\n"
20662 "#extension GL_ARB_enhanced_layouts : require\n"
20665 "out vec4 vs_tcs;\n"
20669 " vs_tcs = in_vs;\n"
20672 static const GLchar* vs_tested = "#version 430 core\n"
20673 "#extension GL_ARB_enhanced_layouts : require\n"
20678 "out vec4 vs_tcs;\n"
20682 " vec4 result = in_vs;\n"
20686 " vs_tcs += result;\n"
20690 std::string source;
20691 testCase& test_case = m_test_cases[test_case_index];
20693 if (test_case.m_stage == stage)
20695 const GLchar* array = "";
20696 const GLchar* index = "";
20697 size_t position = 0;
20699 const GLchar* var_definition = 0;
20700 const GLchar* var_use = 0;
20702 switch (test_case.m_case)
20705 var_definition = offset_var_definition;
20706 var_use = output_use;
20709 var_definition = stride_var_definition;
20710 var_use = output_use;
20713 var_definition = block_var_definition;
20714 var_use = block_use;
20717 var_definition = array_var_definition;
20718 var_use = array_use;
20721 TCU_FAIL("Invalid enum");
20726 case Utils::Shader::GEOMETRY:
20727 source = gs_tested;
20731 case Utils::Shader::TESS_CTRL:
20732 source = tcs_tested;
20734 index = "[gl_InvocationID]";
20736 case Utils::Shader::TESS_EVAL:
20737 source = tes_tested;
20741 case Utils::Shader::VERTEX:
20742 source = vs_tested;
20745 TCU_FAIL("Invalid enum");
20749 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
20751 Utils::replaceToken("ARRAY", position, array, source);
20752 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
20754 Utils::replaceAllTokens("INDEX", index, source);
20758 switch (test_case.m_stage)
20760 case Utils::Shader::GEOMETRY:
20763 case Utils::Shader::FRAGMENT:
20766 case Utils::Shader::VERTEX:
20773 case Utils::Shader::TESS_CTRL:
20776 case Utils::Shader::FRAGMENT:
20779 case Utils::Shader::VERTEX:
20786 case Utils::Shader::TESS_EVAL:
20789 case Utils::Shader::FRAGMENT:
20792 case Utils::Shader::TESS_CTRL:
20795 case Utils::Shader::VERTEX:
20802 case Utils::Shader::VERTEX:
20805 case Utils::Shader::FRAGMENT:
20813 TCU_FAIL("Invalid enum");
20821 /** Get description of test case
20823 * @param test_case_index Index of test case
20825 * @return Test case description
20827 std::string XFBTooSmallStrideTest::getTestCaseName(GLuint test_case_index)
20829 std::stringstream stream;
20830 testCase& test_case = m_test_cases[test_case_index];
20832 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", case: ";
20834 switch (test_case.m_case)
20837 stream << "buffer stride: 40, vec4 offset: 32";
20840 stream << "buffer stride: 32, vec4 off 16 stride: 32";
20843 stream << "buffer stride: 32, block 3xvec4 offset 0";
20846 stream << "buffer stride: 32, vec4[4] offset 16";
20849 TCU_FAIL("Invalid enum");
20852 return stream.str();
20855 /** Get number of test cases
20857 * @return Number of test cases
20859 GLuint XFBTooSmallStrideTest::getTestCaseNumber()
20861 return static_cast<GLuint>(m_test_cases.size());
20864 /** Selects if "compute" stage is relevant for test
20870 bool XFBTooSmallStrideTest::isComputeRelevant(GLuint /* test_case_index */)
20875 /** Prepare all test cases
20878 void XFBTooSmallStrideTest::testInit()
20880 for (GLuint c = 0; c < CASE_MAX; ++c)
20882 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
20885 It is invalid to define transform feedback output in TCS, according to spec:
20886 The data captured in transform feedback mode depends on the active programs on each of the shader stages.
20887 If a program is active for the geometry shader stage, transform feedback captures the vertices of each
20888 primitive emitted by the geometry shader. Otherwise, if a program is active for the tessellation evaluation
20889 shader stage, transform feedback captures each primitive produced by the tessellation primitive generator,
20890 whose vertices are processed by the tessellation evaluation shader. Otherwise, transform feedback captures
20891 each primitive processed by the vertex shader.
20893 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
20894 (Utils::Shader::FRAGMENT == stage))
20899 testCase test_case = { (CASES)c, (Utils::Shader::STAGES)stage };
20901 m_test_cases.push_back(test_case);
20908 * @param context Test framework context
20910 XFBVariableStrideTest::XFBVariableStrideTest(deqp::Context& context)
20911 : NegativeTestBase(context, "xfb_variable_stride", "Test verifies that stride qualifier is respected")
20915 /** Source for given test case and stage
20917 * @param test_case_index Index of test case
20918 * @param stage Shader stage
20920 * @return Shader source
20922 std::string XFBVariableStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
20924 static const GLchar* invalid_var_definition =
20925 "const uint type_size = SIZE;\n"
20927 "layout (xfb_offset = 0, xfb_stride = 2 * type_size) out TYPE gokuARRAY;\n"
20928 "layout (xfb_offset = type_size) out TYPE vegetaARRAY;\n";
20929 static const GLchar* valid_var_definition =
20930 "const uint type_size = SIZE;\n"
20932 "layout (xfb_offset = 0, xfb_stride = 2 * type_size) out TYPE gokuARRAY;\n";
20933 static const GLchar* invalid_use = " gokuINDEX = TYPE(1);\n"
20934 " vegetaINDEX = TYPE(0);\n"
20935 " if (vec4(0) == result)\n"
20937 " gokuINDEX = TYPE(0);\n"
20938 " vegetaINDEX = TYPE(1);\n"
20940 static const GLchar* valid_use = " gokuINDEX = TYPE(1);\n"
20941 " if (vec4(0) == result)\n"
20943 " gokuINDEX = TYPE(0);\n"
20945 static const GLchar* fs = "#version 430 core\n"
20946 "#extension GL_ARB_enhanced_layouts : require\n"
20948 "in vec4 any_fs;\n"
20949 "out vec4 fs_out;\n"
20953 " fs_out = any_fs;\n"
20956 static const GLchar* gs_tested = "#version 430 core\n"
20957 "#extension GL_ARB_enhanced_layouts : require\n"
20959 "layout(points) in;\n"
20960 "layout(triangle_strip, max_vertices = 4) out;\n"
20964 "in vec4 vs_any[];\n"
20965 "out vec4 any_fs;\n"
20969 " vec4 result = vs_any[0];\n"
20973 " any_fs = result;\n"
20974 " gl_Position = vec4(-1, -1, 0, 1);\n"
20976 " any_fs = result;\n"
20977 " gl_Position = vec4(-1, 1, 0, 1);\n"
20979 " any_fs = result;\n"
20980 " gl_Position = vec4(1, -1, 0, 1);\n"
20982 " any_fs = result;\n"
20983 " gl_Position = vec4(1, 1, 0, 1);\n"
20987 static const GLchar* tcs = "#version 430 core\n"
20988 "#extension GL_ARB_enhanced_layouts : require\n"
20990 "layout(vertices = 1) out;\n"
20992 "in vec4 vs_any[];\n"
20993 "out vec4 tcs_tes[];\n"
20998 " tcs_tes[gl_InvocationID] = vs_any[gl_InvocationID];\n"
21000 " gl_TessLevelOuter[0] = 1.0;\n"
21001 " gl_TessLevelOuter[1] = 1.0;\n"
21002 " gl_TessLevelOuter[2] = 1.0;\n"
21003 " gl_TessLevelOuter[3] = 1.0;\n"
21004 " gl_TessLevelInner[0] = 1.0;\n"
21005 " gl_TessLevelInner[1] = 1.0;\n"
21008 static const GLchar* tcs_tested = "#version 430 core\n"
21009 "#extension GL_ARB_enhanced_layouts : require\n"
21011 "layout(vertices = 1) out;\n"
21015 "in vec4 vs_any[];\n"
21016 "out vec4 any_fs[];\n"
21020 " vec4 result = vs_any[gl_InvocationID];\n"
21024 " any_fs[gl_InvocationID] = result;\n"
21026 " gl_TessLevelOuter[0] = 1.0;\n"
21027 " gl_TessLevelOuter[1] = 1.0;\n"
21028 " gl_TessLevelOuter[2] = 1.0;\n"
21029 " gl_TessLevelOuter[3] = 1.0;\n"
21030 " gl_TessLevelInner[0] = 1.0;\n"
21031 " gl_TessLevelInner[1] = 1.0;\n"
21034 static const GLchar* tes_tested = "#version 430 core\n"
21035 "#extension GL_ARB_enhanced_layouts : require\n"
21037 "layout(isolines, point_mode) in;\n"
21041 "in vec4 tcs_tes[];\n"
21042 "out vec4 any_fs;\n"
21046 " vec4 result = tcs_tes[0];\n"
21050 " any_fs = result;\n"
21053 static const GLchar* vs = "#version 430 core\n"
21054 "#extension GL_ARB_enhanced_layouts : require\n"
21057 "out vec4 vs_any;\n"
21061 " vs_any = in_vs;\n"
21064 static const GLchar* vs_tested = "#version 430 core\n"
21065 "#extension GL_ARB_enhanced_layouts : require\n"
21070 "out vec4 any_fs;\n"
21074 " vec4 result = in_vs;\n"
21078 " any_fs = result;\n"
21082 std::string source;
21083 testCase& test_case = m_test_cases[test_case_index];
21085 if (test_case.m_stage == stage)
21087 const GLchar* array = "";
21089 const GLchar* index = "";
21090 size_t position = 0;
21092 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
21093 const GLchar* var_definition = 0;
21094 const GLchar* var_use = 0;
21096 sprintf(buffer, "%d", test_case.m_type.GetSize());
21098 switch (test_case.m_case)
21101 var_definition = valid_var_definition;
21102 var_use = valid_use;
21105 var_definition = invalid_var_definition;
21106 var_use = invalid_use;
21109 TCU_FAIL("Invalid enum");
21114 case Utils::Shader::GEOMETRY:
21115 source = gs_tested;
21119 case Utils::Shader::TESS_CTRL:
21120 source = tcs_tested;
21122 index = "[gl_InvocationID]";
21124 case Utils::Shader::TESS_EVAL:
21125 source = tes_tested;
21129 case Utils::Shader::VERTEX:
21130 source = vs_tested;
21133 TCU_FAIL("Invalid enum");
21137 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
21139 Utils::replaceToken("SIZE", position, buffer, source);
21140 Utils::replaceToken("ARRAY", position, array, source);
21141 if (INVALID == test_case.m_case)
21143 Utils::replaceToken("ARRAY", position, array, source);
21145 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
21147 Utils::replaceAllTokens("TYPE", type_name, source);
21148 Utils::replaceAllTokens("INDEX", index, source);
21152 switch (test_case.m_stage)
21154 case Utils::Shader::GEOMETRY:
21157 case Utils::Shader::FRAGMENT:
21160 case Utils::Shader::VERTEX:
21167 case Utils::Shader::TESS_CTRL:
21170 case Utils::Shader::FRAGMENT:
21173 case Utils::Shader::VERTEX:
21180 case Utils::Shader::TESS_EVAL:
21183 case Utils::Shader::FRAGMENT:
21186 case Utils::Shader::TESS_CTRL:
21189 case Utils::Shader::VERTEX:
21196 case Utils::Shader::VERTEX:
21199 case Utils::Shader::FRAGMENT:
21207 TCU_FAIL("Invalid enum");
21215 /** Get description of test case
21217 * @param test_case_index Index of test case
21219 * @return Test case description
21221 std::string XFBVariableStrideTest::getTestCaseName(GLuint test_case_index)
21223 std::stringstream stream;
21224 testCase& test_case = m_test_cases[test_case_index];
21226 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
21227 << ", type: " << test_case.m_type.GetGLSLTypeName() << ", case: ";
21229 switch (test_case.m_case)
21235 stream << "invalid";
21238 TCU_FAIL("Invalid enum");
21241 return stream.str();
21244 /** Get number of test cases
21246 * @return Number of test cases
21248 GLuint XFBVariableStrideTest::getTestCaseNumber()
21250 return static_cast<GLuint>(m_test_cases.size());
21253 /** Selects if "compute" stage is relevant for test
21259 bool XFBVariableStrideTest::isComputeRelevant(GLuint /* test_case_index */)
21264 /** Selects if compilation failure is expected result
21266 * @param test_case_index Index of test case
21270 bool XFBVariableStrideTest::isFailureExpected(GLuint test_case_index)
21272 testCase& test_case = m_test_cases[test_case_index];
21274 return (INVALID == test_case.m_case);
21277 /** Prepare all test cases
21280 void XFBVariableStrideTest::testInit()
21282 const GLuint n_types = getTypesNumber();
21284 for (GLuint i = 0; i < n_types; ++i)
21286 const Utils::Type& type = getType(i);
21289 Some of the cases are declared as following are considered as invalid,
21290 but accoring to spec, the following declaration is valid: shaders in the
21291 transform feedback capturing mode have an initial global default of layout(xfb_buffer=0) out,
21292 so for the first variable's declaration, the xfb_stride = 16 is applied on buffer 0, for the
21293 second variable, its buffer is also inherited from global buffer 0, and its offset does not overflows
21296 The xfb_stride is the memory width of given buffer, not for variable even though xfb_stride
21297 is declared on the variable. It seems that the writter of this case misunderstand the concept of
21298 xfb_stride, because spec describes that xfb_stride can be declared multiple times for the same buffer,
21299 it is a compile or link-time error to have different values specified for the stride for the same buffer.
21302 layout (xfb_offset = 0, xfb_stride = 2 * type_size) out double goku;
21303 layout (xfb_offset = type_size) out double vegeta;
21305 // all the shaders are valid, so remove the following loop(it contains CASE_MAX is enum of valid and invalid)
21306 // for (GLuint c = 0; c < CASE_MAX; ++c)
21308 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
21310 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
21311 (Utils::Shader::FRAGMENT == stage))
21316 testCase test_case = { (CASES)VALID, (Utils::Shader::STAGES)stage, type };
21318 m_test_cases.push_back(test_case);
21326 * @param context Test framework context
21328 XFBBlockStrideTest::XFBBlockStrideTest(deqp::Context& context)
21329 : TestBase(context, "xfb_block_stride", "Test verifies that stride qualifier is respected for blocks")
21333 /** Source for given test case and stage
21335 * @param test_case_index Index of test case
21336 * @param stage Shader stage
21338 * @return Shader source
21340 std::string XFBBlockStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
21342 static const GLchar* var_definition = "layout (xfb_offset = 0, xfb_stride = 128) out Goku {\n"
21347 static const GLchar* var_use = " gokuINDEX.gohan = vec4(1, 0, 0, 0);\n"
21348 " gokuINDEX.goten = vec4(0, 0, 1, 0);\n"
21349 " gokuINDEX.chichi = vec4(0, 1, 0, 0);\n"
21350 " if (vec4(0) == result)\n"
21352 " gokuINDEX.gohan = vec4(0, 1, 1, 1);\n"
21353 " gokuINDEX.goten = vec4(1, 1, 0, 1);\n"
21354 " gokuINDEX.chichi = vec4(1, 0, 1, 1);\n"
21356 static const GLchar* gs_tested =
21357 "#version 430 core\n"
21358 "#extension GL_ARB_enhanced_layouts : require\n"
21360 "layout(points) in;\n"
21361 "layout(triangle_strip, max_vertices = 4) out;\n"
21365 "out gl_PerVertex \n"
21367 " vec4 gl_Position; \n" // gl_Position must be redeclared in separable program mode
21369 "in vec4 tes_gs[];\n"
21370 "out vec4 gs_fs;\n"
21374 " vec4 result = tes_gs[0];\n"
21378 " gs_fs = result;\n"
21379 " gl_Position = vec4(-1, -1, 0, 1);\n"
21381 " gs_fs = result;\n"
21382 " gl_Position = vec4(-1, 1, 0, 1);\n"
21384 " gs_fs = result;\n"
21385 " gl_Position = vec4(1, -1, 0, 1);\n"
21387 " gs_fs = result;\n"
21388 " gl_Position = vec4(1, 1, 0, 1);\n"
21392 static const GLchar* tcs = "#version 430 core\n"
21393 "#extension GL_ARB_enhanced_layouts : require\n"
21395 "layout(vertices = 1) out;\n"
21397 "in vec4 vs_tcs[];\n"
21398 "out vec4 tcs_tes[];\n"
21403 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\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* tcs_tested =
21415 "#version 430 core\n"
21416 "#extension GL_ARB_enhanced_layouts : require\n"
21418 "layout(vertices = 1) out;\n"
21422 "in vec4 vs_tcs[];\n"
21423 "out vec4 tcs_tes[];\n"
21427 " vec4 result = vs_tcs[gl_InvocationID];\n"
21431 " tcs_tes[gl_InvocationID] = result;\n"
21433 " gl_TessLevelOuter[0] = 1.0;\n"
21434 " gl_TessLevelOuter[1] = 1.0;\n"
21435 " gl_TessLevelOuter[2] = 1.0;\n"
21436 " gl_TessLevelOuter[3] = 1.0;\n"
21437 " gl_TessLevelInner[0] = 1.0;\n"
21438 " gl_TessLevelInner[1] = 1.0;\n"
21442 static const GLchar* tes_tested = "#version 430 core\n"
21443 "#extension GL_ARB_enhanced_layouts : require\n"
21445 "layout(isolines, point_mode) in;\n"
21449 "in vec4 tcs_tes[];\n"
21450 "out vec4 tes_gs;\n"
21454 " vec4 result = tcs_tes[0];\n"
21458 " tes_gs += result;\n"
21461 static const GLchar* vs = "#version 430 core\n"
21462 "#extension GL_ARB_enhanced_layouts : require\n"
21465 "out vec4 vs_tcs;\n"
21469 " vs_tcs = in_vs;\n"
21472 static const GLchar* vs_tested = "#version 430 core\n"
21473 "#extension GL_ARB_enhanced_layouts : require\n"
21478 "out vec4 vs_tcs;\n"
21482 " vec4 result = in_vs;\n"
21486 " vs_tcs += result;\n"
21490 std::string source;
21491 Utils::Shader::STAGES test_case = m_test_cases[test_case_index];
21493 if (test_case == stage)
21495 const GLchar* array = "";
21496 const GLchar* index = "";
21497 size_t position = 0;
21499 // It is a compile time error to apply xfb_offset to the declaration of an unsized array(GLSL4.5 spec: Page73)
21500 // change array = "[]" to "[1]"
21503 case Utils::Shader::GEOMETRY:
21504 source = gs_tested;
21509 It is invalid to define transform feedback output in HS
21512 case Utils::Shader::TESS_CTRL:
21513 source = tcs_tested;
21515 index = "[gl_InvocationID]";
21518 case Utils::Shader::TESS_EVAL:
21519 source = tes_tested;
21523 case Utils::Shader::VERTEX:
21524 source = vs_tested;
21527 TCU_FAIL("Invalid enum");
21531 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
21533 Utils::replaceToken("ARRAY", position, array, source);
21534 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
21536 Utils::replaceAllTokens("INDEX", index, source);
21542 case Utils::Shader::GEOMETRY:
21545 case Utils::Shader::VERTEX:
21552 case Utils::Shader::TESS_CTRL:
21555 case Utils::Shader::VERTEX:
21562 case Utils::Shader::TESS_EVAL:
21565 case Utils::Shader::TESS_CTRL:
21568 case Utils::Shader::VERTEX:
21575 case Utils::Shader::VERTEX:
21579 TCU_FAIL("Invalid enum");
21587 /** Get description of test case
21589 * @param test_case_index Index of test case
21591 * @return Test case description
21593 std::string XFBBlockStrideTest::getTestCaseName(GLuint test_case_index)
21595 std::stringstream stream;
21597 stream << "Stage: " << Utils::Shader::GetStageName(m_test_cases[test_case_index]);
21599 return stream.str();
21602 /** Get number of test cases
21604 * @return Number of test cases
21606 GLuint XFBBlockStrideTest::getTestCaseNumber()
21608 return static_cast<GLuint>(m_test_cases.size());
21611 /** Inspects program for xfb stride
21613 * @param program Program to query
21615 * @return true if query results match expected values, false otherwise
21617 bool XFBBlockStrideTest::inspectProgram(Utils::Program& program)
21621 program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE,
21622 1 /* buf_size */, &stride);
21624 return (128 == stride);
21629 * @param test_case_index Id of test case
21631 * @return true if test case pass, false otherwise
21633 bool XFBBlockStrideTest::testCase(GLuint test_case_index)
21635 const std::string& gs_source = getShaderSource(test_case_index, Utils::Shader::GEOMETRY);
21636 Utils::Program program(m_context);
21637 const std::string& tcs_source = getShaderSource(test_case_index, Utils::Shader::TESS_CTRL);
21638 const std::string& tes_source = getShaderSource(test_case_index, Utils::Shader::TESS_EVAL);
21639 bool test_case_result = true;
21640 const std::string& vs_source = getShaderSource(test_case_index, Utils::Shader::VERTEX);
21642 program.Init("" /* cs */, "", gs_source, tcs_source, tes_source, vs_source, true /* separable */);
21644 test_case_result = inspectProgram(program);
21646 return test_case_result;
21649 /** Prepare all test cases
21652 void XFBBlockStrideTest::testInit()
21654 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
21656 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
21657 (Utils::Shader::FRAGMENT == stage))
21662 m_test_cases.push_back((Utils::Shader::STAGES)stage);
21668 * @param context Test context
21670 XFBBlockMemberStrideTest::XFBBlockMemberStrideTest(deqp::Context& context)
21671 : BufferTestBase(context, "xfb_block_member_stride",
21672 "Test verifies that xfb_stride qualifier is respected for block member")
21674 /* Nothing to be done here */
21677 /** Get descriptors of buffers necessary for test
21680 * @param out_descriptors Descriptors of buffers used by test
21682 void XFBBlockMemberStrideTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
21683 bufferDescriptor::Vector& out_descriptors)
21685 const Utils::Type& vec4 = Utils::Type::vec4;
21687 /* Test needs single uniform and xfb */
21688 out_descriptors.resize(2);
21690 /* Get references */
21691 bufferDescriptor& uniform = out_descriptors[0];
21692 bufferDescriptor& xfb = out_descriptors[1];
21695 uniform.m_index = 0;
21699 uniform.m_target = Utils::Buffer::Uniform;
21700 xfb.m_target = Utils::Buffer::Transform_feedback;
21703 static const GLuint vec4_size = 16;
21704 const std::vector<GLubyte>& gohan_data = vec4.GenerateDataPacked();
21705 const std::vector<GLubyte>& goten_data = vec4.GenerateDataPacked();
21706 const std::vector<GLubyte>& chichi_data = vec4.GenerateDataPacked();
21709 uniform.m_initial_data.resize(3 * vec4_size);
21710 memcpy(&uniform.m_initial_data[0] + 0, &gohan_data[0], vec4_size);
21711 memcpy(&uniform.m_initial_data[0] + vec4_size, &goten_data[0], vec4_size);
21712 memcpy(&uniform.m_initial_data[0] + 2 * vec4_size, &chichi_data[0], vec4_size);
21715 xfb.m_initial_data.resize(4 * vec4_size);
21716 xfb.m_expected_data.resize(4 * vec4_size);
21718 for (GLuint i = 0; i < 4 * vec4_size; ++i)
21720 xfb.m_initial_data[i] = (glw::GLubyte)i;
21721 xfb.m_expected_data[i] = (glw::GLubyte)i;
21724 // the xfb_offset of "chichi" should be 32
21725 memcpy(&xfb.m_expected_data[0] + 0, &gohan_data[0], vec4_size);
21726 memcpy(&xfb.m_expected_data[0] + vec4_size, &goten_data[0], vec4_size);
21727 memcpy(&xfb.m_expected_data[0] + 2 * vec4_size, &chichi_data[0], vec4_size);
21730 /** Get body of main function for given shader stage
21733 * @param stage Shader stage
21734 * @param out_assignments Set to empty
21735 * @param out_calculations Set to empty
21737 void XFBBlockMemberStrideTest::getShaderBody(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
21738 std::string& out_assignments, std::string& out_calculations)
21740 out_calculations = "";
21742 static const GLchar* gs = " gohan = uni_gohan;\n"
21743 " goten = uni_goten;\n"
21744 " chichi = uni_chichi;\n";
21745 static const GLchar* fs = " fs_out = gohan + goten + chichi;\n";
21747 const GLchar* assignments = "";
21750 case Utils::Shader::FRAGMENT:
21753 case Utils::Shader::GEOMETRY:
21760 out_assignments = assignments;
21763 /** Get interface of shader
21766 * @param stage Shader stage
21767 * @param out_interface Set to ""
21769 void XFBBlockMemberStrideTest::getShaderInterface(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
21770 std::string& out_interface)
21772 static const GLchar* gs = "layout (xfb_buffer = 0, xfb_offset = 0) out Goku {\n"
21774 " layout (xfb_stride = 32) vec4 goten;\n"
21777 "layout(binding = 0) uniform gs_block {\n"
21778 " vec4 uni_gohan;\n"
21779 " vec4 uni_goten;\n"
21780 " vec4 uni_chichi;\n"
21782 static const GLchar* fs = "in Goku {\n"
21787 "out vec4 fs_out;\n";
21791 case Utils::Shader::FRAGMENT:
21792 out_interface = fs;
21794 case Utils::Shader::GEOMETRY:
21795 out_interface = gs;
21798 out_interface = "";
21803 /** Inspects program to check if all resources are as expected
21806 * @param program Program instance
21807 * @param out_stream Error message
21809 * @return true if everything is ok, false otherwise
21811 bool XFBBlockMemberStrideTest::inspectProgram(GLuint /* test_case_index*/, Utils::Program& program,
21812 std::stringstream& out_stream)
21814 const GLuint gohan_id = program.GetResourceIndex("gohan", GL_TRANSFORM_FEEDBACK_VARYING);
21815 const GLuint goten_id = program.GetResourceIndex("goten", GL_TRANSFORM_FEEDBACK_VARYING);
21816 const GLuint chichi_id = program.GetResourceIndex("chichi", GL_TRANSFORM_FEEDBACK_VARYING);
21818 GLint gohan_offset = 0;
21819 GLint goten_offset = 0;
21820 GLint chichi_offset = 0;
21822 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, gohan_id, GL_OFFSET, 1, &gohan_offset);
21823 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, goten_id, GL_OFFSET, 1, &goten_offset);
21824 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, chichi_id, GL_OFFSET, 1, &chichi_offset);
21826 // the xfb_offset of "chichi" should be 32
21827 if ((0 != gohan_offset) || (16 != goten_offset) || (32 != chichi_offset))
21829 out_stream << "Got wrong offset: [" << gohan_offset << ", " << goten_offset << ", " << chichi_offset
21830 << "] expected: [0, 16, 48]";
21839 * @param context Test framework context
21841 XFBDuplicatedStrideTest::XFBDuplicatedStrideTest(deqp::Context& context)
21842 : NegativeTestBase(context, "xfb_duplicated_stride",
21843 "Test verifies that compiler reports error when conflicting stride qualifiers are used")
21847 /** Source for given test case and stage
21849 * @param test_case_index Index of test case
21850 * @param stage Shader stage
21852 * @return Shader source
21854 std::string XFBDuplicatedStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
21856 static const GLchar* invalid_var_definition = "const uint valid_stride = 64;\n"
21857 "const uint conflicting_stride = 128;\n"
21859 "layout (xfb_buffer = 0, xfb_stride = valid_stride) out;\n"
21860 "layout (xfb_buffer = 0, xfb_stride = conflicting_stride) out;\n";
21861 static const GLchar* valid_var_definition = "const uint valid_stride = 64;\n"
21863 "layout (xfb_buffer = 0, xfb_stride = valid_stride) out;\n"
21864 "layout (xfb_buffer = 0, xfb_stride = valid_stride) out;\n";
21865 static const GLchar* fs = "#version 430 core\n"
21866 "#extension GL_ARB_enhanced_layouts : require\n"
21868 "in vec4 any_fs;\n"
21869 "out vec4 fs_out;\n"
21873 " fs_out = any_fs;\n"
21876 static const GLchar* gs_tested = "#version 430 core\n"
21877 "#extension GL_ARB_enhanced_layouts : require\n"
21879 "layout(points) in;\n"
21880 "layout(triangle_strip, max_vertices = 4) out;\n"
21884 "in vec4 vs_any[];\n"
21885 "out vec4 any_fs;\n"
21889 " vec4 result = vs_any[0];\n"
21893 " any_fs = result;\n"
21894 " gl_Position = vec4(-1, -1, 0, 1);\n"
21896 " any_fs = result;\n"
21897 " gl_Position = vec4(-1, 1, 0, 1);\n"
21899 " any_fs = result;\n"
21900 " gl_Position = vec4(1, -1, 0, 1);\n"
21902 " any_fs = result;\n"
21903 " gl_Position = vec4(1, 1, 0, 1);\n"
21907 static const GLchar* tcs = "#version 430 core\n"
21908 "#extension GL_ARB_enhanced_layouts : require\n"
21910 "layout(vertices = 1) out;\n"
21912 "in vec4 vs_any[];\n"
21913 "out vec4 tcs_tes[];\n"
21918 " tcs_tes[gl_InvocationID] = vs_any[gl_InvocationID];\n"
21920 " gl_TessLevelOuter[0] = 1.0;\n"
21921 " gl_TessLevelOuter[1] = 1.0;\n"
21922 " gl_TessLevelOuter[2] = 1.0;\n"
21923 " gl_TessLevelOuter[3] = 1.0;\n"
21924 " gl_TessLevelInner[0] = 1.0;\n"
21925 " gl_TessLevelInner[1] = 1.0;\n"
21928 static const GLchar* tcs_tested = "#version 430 core\n"
21929 "#extension GL_ARB_enhanced_layouts : require\n"
21931 "layout(vertices = 1) out;\n"
21935 "in vec4 vs_any[];\n"
21936 "out vec4 any_fs[];\n"
21940 " vec4 result = vs_any[gl_InvocationID];\n"
21944 " any_fs[gl_InvocationID] = result;\n"
21946 " gl_TessLevelOuter[0] = 1.0;\n"
21947 " gl_TessLevelOuter[1] = 1.0;\n"
21948 " gl_TessLevelOuter[2] = 1.0;\n"
21949 " gl_TessLevelOuter[3] = 1.0;\n"
21950 " gl_TessLevelInner[0] = 1.0;\n"
21951 " gl_TessLevelInner[1] = 1.0;\n"
21954 static const GLchar* tes_tested = "#version 430 core\n"
21955 "#extension GL_ARB_enhanced_layouts : require\n"
21957 "layout(isolines, point_mode) in;\n"
21961 "in vec4 tcs_tes[];\n"
21962 "out vec4 any_fs;\n"
21966 " vec4 result = tcs_tes[0];\n"
21970 " any_fs = result;\n"
21973 static const GLchar* vs = "#version 430 core\n"
21974 "#extension GL_ARB_enhanced_layouts : require\n"
21977 "out vec4 vs_any;\n"
21981 " vs_any = in_vs;\n"
21984 static const GLchar* vs_tested = "#version 430 core\n"
21985 "#extension GL_ARB_enhanced_layouts : require\n"
21990 "out vec4 any_fs;\n"
21994 " vec4 result = in_vs;\n"
21998 " any_fs += result;\n"
22002 std::string source;
22003 testCase& test_case = m_test_cases[test_case_index];
22005 if (test_case.m_stage == stage)
22007 size_t position = 0;
22008 const GLchar* var_definition = 0;
22009 const GLchar* var_use = "";
22011 switch (test_case.m_case)
22014 var_definition = valid_var_definition;
22017 var_definition = invalid_var_definition;
22020 TCU_FAIL("Invalid enum");
22025 case Utils::Shader::GEOMETRY:
22026 source = gs_tested;
22028 case Utils::Shader::TESS_CTRL:
22029 source = tcs_tested;
22031 case Utils::Shader::TESS_EVAL:
22032 source = tes_tested;
22034 case Utils::Shader::VERTEX:
22035 source = vs_tested;
22038 TCU_FAIL("Invalid enum");
22041 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
22042 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
22046 switch (test_case.m_stage)
22048 case Utils::Shader::GEOMETRY:
22051 case Utils::Shader::FRAGMENT:
22054 case Utils::Shader::VERTEX:
22061 case Utils::Shader::TESS_CTRL:
22064 case Utils::Shader::FRAGMENT:
22067 case Utils::Shader::VERTEX:
22074 case Utils::Shader::TESS_EVAL:
22077 case Utils::Shader::FRAGMENT:
22080 case Utils::Shader::TESS_CTRL:
22083 case Utils::Shader::VERTEX:
22090 case Utils::Shader::VERTEX:
22093 case Utils::Shader::FRAGMENT:
22101 TCU_FAIL("Invalid enum");
22109 /** Get description of test case
22111 * @param test_case_index Index of test case
22113 * @return Test case description
22115 std::string XFBDuplicatedStrideTest::getTestCaseName(GLuint test_case_index)
22117 std::stringstream stream;
22118 testCase& test_case = m_test_cases[test_case_index];
22120 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", case: ";
22122 switch (test_case.m_case)
22128 stream << "invalid";
22131 TCU_FAIL("Invalid enum");
22134 return stream.str();
22137 /** Get number of test cases
22139 * @return Number of test cases
22141 GLuint XFBDuplicatedStrideTest::getTestCaseNumber()
22143 return static_cast<GLuint>(m_test_cases.size());
22146 /** Selects if "compute" stage is relevant for test
22152 bool XFBDuplicatedStrideTest::isComputeRelevant(GLuint /* test_case_index */)
22157 /** Selects if compilation failure is expected result
22159 * @param test_case_index Index of test case
22163 bool XFBDuplicatedStrideTest::isFailureExpected(GLuint test_case_index)
22165 testCase& test_case = m_test_cases[test_case_index];
22167 return (INVALID == test_case.m_case);
22170 /** Prepare all test cases
22173 void XFBDuplicatedStrideTest::testInit()
22175 for (GLuint c = 0; c < CASE_MAX; ++c)
22177 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
22179 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
22180 (Utils::Shader::FRAGMENT == stage))
22185 testCase test_case = { (CASES)c, (Utils::Shader::STAGES)stage };
22187 m_test_cases.push_back(test_case);
22194 * @param context Test framework context
22196 XFBGetProgramResourceAPITest::XFBGetProgramResourceAPITest(deqp::Context& context)
22197 : TestBase(context, "xfb_get_program_resource_api",
22198 "Test verifies that get program resource reports correct results for XFB")
22202 /** Source for given test case and stage
22204 * @param test_case_index Index of test case
22205 * @param stage Shader stage
22207 * @return Shader source
22209 std::string XFBGetProgramResourceAPITest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
22211 static const GLchar* api_var_definition = "out TYPE b0_v1ARRAY;\n"
22212 "out TYPE b1_v1ARRAY;\n"
22213 "out TYPE b0_v3ARRAY;\n"
22214 "out TYPE b0_v0ARRAY;\n";
22215 static const GLchar* xfb_var_definition =
22216 "const uint type_size = SIZE;\n"
22218 "layout (xfb_buffer = 1, xfb_stride = 4 * type_size) out;\n"
22220 "layout (xfb_buffer = 0, xfb_offset = 1 * type_size) out TYPE b0_v1ARRAY;\n"
22221 "layout (xfb_buffer = 1, xfb_offset = 1 * type_size) out TYPE b1_v1ARRAY;\n"
22222 "layout (xfb_buffer = 0, xfb_offset = 3 * type_size) out TYPE b0_v3ARRAY;\n"
22223 "layout (xfb_buffer = 0, xfb_offset = 0 * type_size) out TYPE b0_v0ARRAY;\n";
22224 static const GLchar* var_use = " b0_v1INDEX = TYPE(0);\n"
22225 " b1_v1INDEX = TYPE(1);\n"
22226 " b0_v3INDEX = TYPE(0);\n"
22227 " b0_v0INDEX = TYPE(1);\n"
22228 " if (vec4(0) == result)\n"
22230 " b0_v1INDEX = TYPE(1);\n"
22231 " b1_v1INDEX = TYPE(0);\n"
22232 " b0_v3INDEX = TYPE(1);\n"
22233 " b0_v0INDEX = TYPE(0);\n"
22235 static const GLchar* gs_tested =
22236 "#version 430 core\n"
22237 "#extension GL_ARB_enhanced_layouts : require\n"
22239 "layout(points) in;\n"
22240 "layout(triangle_strip, max_vertices = 4) out;\n"
22244 "out gl_PerVertex \n"
22246 " vec4 gl_Position; \n" // gl_Position must be redeclared in separable program mode
22248 "in vec4 tes_gs[];\n"
22249 "out vec4 gs_fs;\n"
22253 " vec4 result = tes_gs[0];\n"
22257 " gs_fs = result;\n"
22258 " gl_Position = vec4(-1, -1, 0, 1);\n"
22260 " gs_fs = result;\n"
22261 " gl_Position = vec4(-1, 1, 0, 1);\n"
22263 " gs_fs = result;\n"
22264 " gl_Position = vec4(1, -1, 0, 1);\n"
22266 " gs_fs = result;\n"
22267 " gl_Position = vec4(1, 1, 0, 1);\n"
22272 static const GLchar* tcs_tested =
22273 "#version 430 core\n"
22274 "#extension GL_ARB_enhanced_layouts : require\n"
22276 "layout(vertices = 1) out;\n"
22280 "in vec4 vs_tcs[];\n"
22281 "out vec4 tcs_tes[];\n"
22285 " vec4 result = vs_tcs[gl_InvocationID];\n"
22289 " tcs_tes[gl_InvocationID] = result;\n"
22291 " gl_TessLevelOuter[0] = 1.0;\n"
22292 " gl_TessLevelOuter[1] = 1.0;\n"
22293 " gl_TessLevelOuter[2] = 1.0;\n"
22294 " gl_TessLevelOuter[3] = 1.0;\n"
22295 " gl_TessLevelInner[0] = 1.0;\n"
22296 " gl_TessLevelInner[1] = 1.0;\n"
22300 static const GLchar* tes_tested = "#version 430 core\n"
22301 "#extension GL_ARB_enhanced_layouts : require\n"
22303 "layout(isolines, point_mode) in;\n"
22307 "in vec4 tcs_tes[];\n"
22308 "out vec4 tes_gs;\n"
22312 " vec4 result = tcs_tes[0];\n"
22316 " tes_gs = result;\n"
22319 static const GLchar* vs_tested = "#version 430 core\n"
22320 "#extension GL_ARB_enhanced_layouts : require\n"
22325 "out vec4 vs_tcs;\n"
22329 " vec4 result = in_vs;\n"
22333 " vs_tcs = result;\n"
22337 std::string source;
22338 const test_Case& test_case = m_test_cases[test_case_index];
22340 if (test_case.m_stage == stage)
22342 const GLchar* array = "";
22344 const GLchar* index = "";
22345 size_t position = 0;
22347 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
22348 const GLchar* var_definition = 0;
22350 sprintf(buffer, "%d", test_case.m_type.GetSize());
22352 if (XFB == test_case.m_case)
22354 var_definition = xfb_var_definition;
22358 var_definition = api_var_definition;
22361 // It is a compile time error to apply xfb_offset to the declaration of an unsized array(GLSL4.5 spec: Page73)
22362 // change array = "[]" to "[1]"
22365 case Utils::Shader::GEOMETRY:
22366 source = gs_tested;
22370 // It is invalid to output transform feedback varyings in tessellation control shader
22372 case Utils::Shader::TESS_CTRL:
22373 source = tcs_tested;
22375 index = "[gl_InvocationID]";
22378 case Utils::Shader::TESS_EVAL:
22379 source = tes_tested;
22383 case Utils::Shader::VERTEX:
22384 source = vs_tested;
22387 TCU_FAIL("Invalid enum");
22391 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
22392 if (XFB == test_case.m_case)
22395 Utils::replaceToken("SIZE", position, buffer, source);
22397 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
22399 Utils::replaceAllTokens("ARRAY", array, source);
22400 Utils::replaceAllTokens("INDEX", index, source);
22401 Utils::replaceAllTokens("TYPE", type_name, source);
22411 /** Get description of test case
22413 * @param test_case_index Index of test case
22415 * @return Test case description
22417 std::string XFBGetProgramResourceAPITest::getTestCaseName(GLuint test_case_index)
22419 std::stringstream stream;
22420 const test_Case& test_case = m_test_cases[test_case_index];
22422 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
22423 << ", type: " << test_case.m_type.GetGLSLTypeName() << ", case: ";
22425 switch (test_case.m_case)
22428 stream << "interleaved";
22431 stream << "separated";
22437 TCU_FAIL("Invalid enum");
22440 return stream.str();
22443 /** Get number of test cases
22445 * @return Number of test cases
22447 GLuint XFBGetProgramResourceAPITest::getTestCaseNumber()
22449 return static_cast<GLuint>(m_test_cases.size());
22452 /** Inspects program for offset, buffer index, buffer stride and type
22454 * @param test_case_index Index of test case
22455 * @param program Program to query
22457 * @return true if query results match expected values, false otherwise
22459 bool XFBGetProgramResourceAPITest::inspectProgram(glw::GLuint test_case_index, Utils::Program& program)
22461 GLint b0_stride = 0;
22462 GLint b1_stride = 0;
22463 GLint b0_v0_buf = 0;
22464 GLint b0_v0_offset = 0;
22465 GLint b0_v0_type = 0;
22466 GLint b0_v1_buf = 0;
22467 GLint b0_v1_offset = 0;
22468 GLint b0_v1_type = 0;
22469 GLint b0_v3_buf = 0;
22470 GLint b0_v3_offset = 0;
22471 GLint b0_v3_type = 0;
22472 GLint b1_v1_buf = 0;
22473 GLint b1_v1_offset = 0;
22474 GLint b1_v1_type = 0;
22475 const test_Case& test_case = m_test_cases[test_case_index];
22476 const GLenum type_enum = test_case.m_type.GetTypeGLenum();
22477 const GLint type_size = test_case.m_type.GetSize();
22479 GLuint b0_v0_index = program.GetResourceIndex("b0_v0", GL_TRANSFORM_FEEDBACK_VARYING);
22480 GLuint b0_v1_index = program.GetResourceIndex("b0_v1", GL_TRANSFORM_FEEDBACK_VARYING);
22481 GLuint b0_v3_index = program.GetResourceIndex("b0_v3", GL_TRANSFORM_FEEDBACK_VARYING);
22482 GLuint b1_v1_index = program.GetResourceIndex("b1_v1", GL_TRANSFORM_FEEDBACK_VARYING);
22484 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v0_index, GL_OFFSET, 1 /* buf_size */, &b0_v0_offset);
22485 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v1_index, GL_OFFSET, 1 /* buf_size */, &b0_v1_offset);
22486 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v3_index, GL_OFFSET, 1 /* buf_size */, &b0_v3_offset);
22487 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b1_v1_index, GL_OFFSET, 1 /* buf_size */, &b1_v1_offset);
22489 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v0_index, GL_TYPE, 1 /* buf_size */, &b0_v0_type);
22490 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v1_index, GL_TYPE, 1 /* buf_size */, &b0_v1_type);
22491 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v3_index, GL_TYPE, 1 /* buf_size */, &b0_v3_type);
22492 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b1_v1_index, GL_TYPE, 1 /* buf_size */, &b1_v1_type);
22494 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v0_index, GL_TRANSFORM_FEEDBACK_BUFFER_INDEX,
22495 1 /* buf_size */, &b0_v0_buf);
22496 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v1_index, GL_TRANSFORM_FEEDBACK_BUFFER_INDEX,
22497 1 /* buf_size */, &b0_v1_buf);
22498 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v3_index, GL_TRANSFORM_FEEDBACK_BUFFER_INDEX,
22499 1 /* buf_size */, &b0_v3_buf);
22500 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b1_v1_index, GL_TRANSFORM_FEEDBACK_BUFFER_INDEX,
22501 1 /* buf_size */, &b1_v1_buf);
22503 program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, b0_v0_buf, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE, 1 /* buf_size */,
22505 program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, b1_v1_buf, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE, 1 /* buf_size */,
22508 if (SEPARATED != test_case.m_case)
22510 return (((GLint)(4 * type_size) == b0_stride) && ((GLint)(4 * type_size) == b1_stride) &&
22511 ((GLint)(0) == b0_v0_buf) && ((GLint)(0 * type_size) == b0_v0_offset) &&
22512 ((GLint)(type_enum) == b0_v0_type) && ((GLint)(0) == b0_v1_buf) &&
22513 ((GLint)(1 * type_size) == b0_v1_offset) && ((GLint)(type_enum) == b0_v1_type) &&
22514 ((GLint)(0) == b0_v3_buf) && ((GLint)(3 * type_size) == b0_v3_offset) &&
22515 ((GLint)(type_enum) == b0_v3_type) && ((GLint)(1) == b1_v1_buf) &&
22516 ((GLint)(1 * type_size) == b1_v1_offset) && ((GLint)(type_enum) == b1_v1_type));
22520 return (((GLint)(1 * type_size) == b0_stride) && ((GLint)(1 * type_size) == b1_stride) &&
22521 ((GLint)(0) == b0_v0_buf) && ((GLint)(0) == b0_v0_offset) && ((GLint)(type_enum) == b0_v0_type) &&
22522 ((GLint)(1) == b0_v1_buf) && ((GLint)(0) == b0_v1_offset) && ((GLint)(type_enum) == b0_v1_type) &&
22523 ((GLint)(2) == b0_v3_buf) && ((GLint)(0) == b0_v3_offset) && ((GLint)(type_enum) == b0_v3_type) &&
22524 ((GLint)(3) == b1_v1_buf) && ((GLint)(0) == b1_v1_offset) && ((GLint)(type_enum) == b1_v1_type));
22528 /** Insert gl_SkipComponents
22530 * @param num_components How many gl_SkipComponents1 need to be inserted
22531 * @param varyings The transform feedback varyings string vector
22534 void XFBGetProgramResourceAPITest::insertSkipComponents(int num_components, Utils::Program::NameVector& varyings)
22536 int num_component_4 = num_components / 4;
22537 int num_component_1 = num_components % 4;
22538 for (int i = 0; i < num_component_4; i++)
22540 varyings.push_back("gl_SkipComponents4");
22542 switch (num_component_1)
22545 varyings.push_back("gl_SkipComponents1");
22548 varyings.push_back("gl_SkipComponents2");
22551 varyings.push_back("gl_SkipComponents3");
22560 * @param test_case_index Id of test case
22562 * @return true if test case pass, false otherwise
22564 bool XFBGetProgramResourceAPITest::testCase(GLuint test_case_index)
22566 const std::string& gs_source = getShaderSource(test_case_index, Utils::Shader::GEOMETRY);
22567 Utils::Program program(m_context);
22568 const std::string& tcs_source = getShaderSource(test_case_index, Utils::Shader::TESS_CTRL);
22569 const std::string& tes_source = getShaderSource(test_case_index, Utils::Shader::TESS_EVAL);
22570 const test_Case& test_case = m_test_cases[test_case_index];
22571 bool test_case_result = true;
22572 const std::string& vs_source = getShaderSource(test_case_index, Utils::Shader::VERTEX);
22574 // According to spec: gl_SkipComponents1 ~ gl_SkipComponents4 is treated as specifying a one- to four-component floating point output variables with undefined values.
22575 // 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.
22577 if (INTERLEAVED == test_case.m_case)
22580 layout (xfb_buffer = 0, xfb_offset = 1 * type_size) out type b0_v1;
22581 layout (xfb_buffer = 1, xfb_offset = 1 * type_size) out type b1_v1;
22582 layout (xfb_buffer = 0, xfb_offset = 3 * type_size) out type b0_v3;
22583 layout (xfb_buffer = 0, xfb_offset = 0 * type_size) out type b0_v0;
22585 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,
22586 we need to calculate how many "gl_SkipComponents" need to be inserted.
22588 Utils::Program::NameVector captured_varyings;
22589 captured_varyings.push_back("b0_v0");
22590 captured_varyings.push_back("b0_v1");
22591 // Compute how many gl_SkipComponents to be inserted
22592 int numComponents = test_case.m_type.GetSize() / 4;
22593 insertSkipComponents(numComponents, captured_varyings);
22594 captured_varyings.push_back("b0_v3");
22595 captured_varyings.push_back("gl_NextBuffer");
22596 insertSkipComponents(numComponents, captured_varyings);
22597 captured_varyings.push_back("b1_v1");
22598 insertSkipComponents(numComponents * 2, captured_varyings);
22600 program.Init("" /* cs */, "", gs_source, tcs_source, tes_source, vs_source, captured_varyings, true,
22601 true /* separable */);
22603 else if (SEPARATED == test_case.m_case)
22605 Utils::Program::NameVector captured_varyings;
22607 captured_varyings.push_back("b0_v0");
22608 captured_varyings.push_back("b0_v1");
22609 captured_varyings.push_back("b0_v3");
22610 captured_varyings.push_back("b1_v1");
22612 program.Init("" /* cs */, "", gs_source, tcs_source, tes_source, vs_source, captured_varyings, false,
22613 true /* separable */);
22618 program.Init("" /* cs */, "", gs_source, tcs_source, tes_source, vs_source, true /* separable */);
22621 test_case_result = inspectProgram(test_case_index, program);
22623 return test_case_result;
22626 /** Prepare all test cases
22629 void XFBGetProgramResourceAPITest::testInit()
22631 const Functions& gl = m_context.getRenderContext().getFunctions();
22632 const GLuint n_types = getTypesNumber();
22636 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_xfb_int);
22637 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
22639 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, &max_xfb_sep);
22640 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
22642 GLint max_varyings;
22643 gl.getIntegerv(GL_MAX_VARYING_COMPONENTS, &max_varyings);
22645 for (GLuint i = 0; i < n_types; ++i)
22647 // 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,
22648 // 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
22649 // shader valid, we can either skip the dmat4, dmat4x3 or query the implementation-dependent value MAX_VARYING_COMPONENTS before generating the shader
22650 // to guarantee the number of varying not exceeded.
22652 layout (xfb_buffer = 1, xfb_stride = 4 * type_size) out;
22653 layout (xfb_buffer = 0, xfb_offset = 1 * type_size) out type b0_v1;
22654 layout (xfb_buffer = 1, xfb_offset = 1 * type_size) out type b1_v1;
22655 layout (xfb_buffer = 0, xfb_offset = 3 * type_size) out type b0_v3;
22656 layout (xfb_buffer = 0, xfb_offset = 0 * type_size) out type b0_v0;
22660 if (i == 7 || i == 9)
22662 const Utils::Type& type = getType(i);
22663 if (4 * type.GetNumComponents() + 4 > (GLuint)max_varyings)
22667 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
22670 It is invalid to define transform feedback output in HS
22672 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
22673 (Utils::Shader::FRAGMENT == stage))
22678 test_Case test_case_int = { INTERLEAVED, (Utils::Shader::STAGES)stage, type };
22679 test_Case test_case_sep = { SEPARATED, (Utils::Shader::STAGES)stage, type };
22680 test_Case test_case_xfb = { XFB, (Utils::Shader::STAGES)stage, type };
22682 if ((int)type.GetSize() <= max_xfb_int)
22684 m_test_cases.push_back(test_case_xfb);
22685 m_test_cases.push_back(test_case_int);
22688 if ((int)type.GetSize() <= max_xfb_sep)
22690 m_test_cases.push_back(test_case_sep);
22698 * @param context Test context
22700 XFBOverrideQualifiersWithAPITest::XFBOverrideQualifiersWithAPITest(deqp::Context& context)
22701 : BufferTestBase(context, "xfb_override_qualifiers_with_api",
22702 "Test verifies that xfb_offset qualifier is not overriden with API")
22704 /* Nothing to be done here */
22707 /** Get descriptors of buffers necessary for test
22709 * @param test_case_index Index of test case
22710 * @param out_descriptors Descriptors of buffers used by test
22712 void XFBOverrideQualifiersWithAPITest::getBufferDescriptors(glw::GLuint test_case_index,
22713 bufferDescriptor::Vector& out_descriptors)
22715 const Utils::Type& type = getType(test_case_index);
22717 /* Test needs single uniform and xfb */
22718 out_descriptors.resize(2);
22720 /* Get references */
22721 bufferDescriptor& uniform = out_descriptors[0];
22722 bufferDescriptor& xfb = out_descriptors[1];
22725 uniform.m_index = 0;
22729 uniform.m_target = Utils::Buffer::Uniform;
22730 xfb.m_target = Utils::Buffer::Transform_feedback;
22733 const GLuint gen_start = Utils::s_rand;
22734 const std::vector<GLubyte>& vegeta_data = type.GenerateData();
22735 const std::vector<GLubyte>& trunks_data = type.GenerateData();
22736 const std::vector<GLubyte>& goku_data = type.GenerateData();
22737 const std::vector<GLubyte>& gohan_data = type.GenerateData();
22739 Utils::s_rand = gen_start;
22740 const std::vector<GLubyte>& vegeta_data_pck = type.GenerateDataPacked();
22742 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)
22743 how can make them equal ? is it as designed? Add the following statement, which can make sure goku_data_pck equals to goku_data
22745 const std::vector<GLubyte>& goku_data_pck = type.GenerateDataPacked();
22747 const GLuint type_size = static_cast<GLuint>(vegeta_data.size());
22748 const GLuint type_size_pck = static_cast<GLuint>(vegeta_data_pck.size());
22751 uniform.m_initial_data.resize(4 * type_size);
22752 memcpy(&uniform.m_initial_data[0] + 0, &vegeta_data[0], type_size);
22753 memcpy(&uniform.m_initial_data[0] + type_size, &trunks_data[0], type_size);
22754 memcpy(&uniform.m_initial_data[0] + 2 * type_size, &goku_data[0], type_size);
22755 memcpy(&uniform.m_initial_data[0] + 3 * type_size, &gohan_data[0], type_size);
22758 xfb.m_initial_data.resize(4 * type_size_pck);
22759 xfb.m_expected_data.resize(4 * type_size_pck);
22761 for (GLuint i = 0; i < 4 * type_size_pck; ++i)
22763 xfb.m_initial_data[i] = (glw::GLubyte)i;
22764 xfb.m_expected_data[i] = (glw::GLubyte)i;
22767 memcpy(&xfb.m_expected_data[0] + 0, &goku_data_pck[0], type_size_pck);
22768 memcpy(&xfb.m_expected_data[0] + 2 * type_size_pck, &vegeta_data_pck[0], type_size_pck);
22771 /** Get list of names of varyings that will be registered with TransformFeedbackVaryings
22774 * @param captured_varyings List of names
22776 void XFBOverrideQualifiersWithAPITest::getCapturedVaryings(glw::GLuint /* test_case_index */,
22777 Utils::Program::NameVector& captured_varyings)
22779 captured_varyings.resize(2);
22781 captured_varyings[0] = "trunks";
22782 captured_varyings[1] = "gohan";
22785 /** Get body of main function for given shader stage
22787 * @param test_case_index Index of test case
22788 * @param stage Shader stage
22789 * @param out_assignments Set to empty
22790 * @param out_calculations Set to empty
22792 void XFBOverrideQualifiersWithAPITest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
22793 std::string& out_assignments, std::string& out_calculations)
22795 out_calculations = "";
22797 static const GLchar* gs = " vegeta = uni_vegeta;\n"
22798 " trunks = uni_trunks;\n"
22799 " goku = uni_goku;\n"
22800 " gohan = uni_gohan;\n";
22801 static const GLchar* fs = " fs_out = vec4(0);\n"
22802 " if (TYPE(1) == gohan + goku + trunks + vegeta)\n"
22804 " fs_out = vec4(1);\n"
22807 const GLchar* assignments = "";
22810 case Utils::Shader::FRAGMENT:
22813 case Utils::Shader::GEOMETRY:
22820 out_assignments = assignments;
22822 if (Utils::Shader::FRAGMENT == stage)
22824 const Utils::Type& type = getType(test_case_index);
22826 Utils::replaceAllTokens("TYPE", type.GetGLSLTypeName(), out_assignments);
22830 /** Get interface of shader
22832 * @param test_case_index Index of test case
22833 * @param stage Shader stage
22834 * @param out_interface Set to ""
22836 void XFBOverrideQualifiersWithAPITest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
22837 std::string& out_interface)
22839 static const GLchar* gs = "const uint sizeof_type = SIZE;\n"
22841 "layout (xfb_offset = 2 * sizeof_type) flat out TYPE vegeta;\n"
22842 " flat out TYPE trunks;\n"
22843 "layout (xfb_offset = 0) flat out TYPE goku;\n"
22844 " flat out TYPE gohan;\n"
22847 There is no packing qualifier for uniform block gs_block, according to spec, it should be "shared" by default,
22848 the definition equals to "layout(binding=0, shared)", if the block is declared as shared, each block member will
22849 not be packed, and each block member's layout in memory is implementation dependent, so we can't use the API
22850 glBufferData() to update the UBO directly, we need to query each block member's offset first, then upload the
22851 data to the corresponding offset, otherwise we can't get the correct data from UBO; to make the test passed,
22852 we need to add the qualifier std140, and change the declaration as layout(binding=0, std140), which can make
22853 sure all the block members are packed and the application can upload the data by glBufferData() directly.
22855 "layout(binding = 0, std140) uniform gs_block {\n"
22856 " TYPE uni_vegeta;\n"
22857 " TYPE uni_trunks;\n"
22858 " TYPE uni_goku;\n"
22859 " TYPE uni_gohan;\n"
22861 static const GLchar* fs = "flat in TYPE vegeta;\n"
22862 "flat in TYPE trunks;\n"
22863 "flat in TYPE goku;\n"
22864 "flat in TYPE gohan;\n"
22866 "out vec4 fs_out;\n";
22868 const Utils::Type& type = getType(test_case_index);
22872 case Utils::Shader::FRAGMENT:
22873 out_interface = fs;
22875 case Utils::Shader::GEOMETRY:
22876 out_interface = gs;
22879 out_interface = "";
22883 if (Utils::Shader::GEOMETRY == stage)
22886 size_t position = 0;
22887 const GLuint type_size = type.GetSize();
22889 sprintf(buffer, "%d", type_size);
22891 Utils::replaceToken("SIZE", position, buffer, out_interface);
22894 Utils::replaceAllTokens("TYPE", type.GetGLSLTypeName(), out_interface);
22899 * @param test_case_index Index of test case
22901 * @return Name of type test in test_case_index
22903 std::string XFBOverrideQualifiersWithAPITest::getTestCaseName(glw::GLuint test_case_index)
22905 return getTypeName(test_case_index);
22908 /** Returns number of types to test
22910 * @return Number of types, 34
22912 glw::GLuint XFBOverrideQualifiersWithAPITest::getTestCaseNumber()
22914 return getTypesNumber();
22917 /** Inspects program to check if all resources are as expected
22919 * @param test_case_index Index of test case
22920 * @param program Program instance
22921 * @param out_stream Error message
22923 * @return true if everything is ok, false otherwise
22925 bool XFBOverrideQualifiersWithAPITest::inspectProgram(GLuint test_case_index, Utils::Program& program,
22926 std::stringstream& out_stream)
22929 const Utils::Type& type = getType(test_case_index);
22930 const GLuint type_size = type.GetSize();
22932 program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE,
22933 1 /* buf_size */, &stride);
22935 if ((GLint)(3 * type_size) != stride)
22937 out_stream << "Stride is: " << stride << " expected: " << (3 * type_size);
22947 * @param context Test context
22949 XFBVertexStreamsTest::XFBVertexStreamsTest(deqp::Context& context)
22950 : BufferTestBase(context, "xfb_vertex_streams",
22951 "Test verifies that xfb qualifier works with multiple output streams")
22953 /* Nothing to be done here */
22956 /** Get descriptors of buffers necessary for test
22959 * @param out_descriptors Descriptors of buffers used by test
22961 void XFBVertexStreamsTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
22962 bufferDescriptor::Vector& out_descriptors)
22964 const Utils::Type& type = Utils::Type::vec4;
22966 /* Test needs single uniform and three xfbs */
22967 out_descriptors.resize(4);
22969 /* Get references */
22970 bufferDescriptor& uniform = out_descriptors[0];
22971 bufferDescriptor& xfb_1 = out_descriptors[1];
22972 bufferDescriptor& xfb_2 = out_descriptors[2];
22973 bufferDescriptor& xfb_3 = out_descriptors[3];
22976 uniform.m_index = 0;
22982 uniform.m_target = Utils::Buffer::Uniform;
22983 xfb_1.m_target = Utils::Buffer::Transform_feedback;
22984 xfb_2.m_target = Utils::Buffer::Transform_feedback;
22985 xfb_3.m_target = Utils::Buffer::Transform_feedback;
22988 const std::vector<GLubyte>& goku_data = type.GenerateData();
22989 const std::vector<GLubyte>& gohan_data = type.GenerateData();
22990 const std::vector<GLubyte>& goten_data = type.GenerateData();
22991 const std::vector<GLubyte>& picolo_data = type.GenerateData();
22992 const std::vector<GLubyte>& vegeta_data = type.GenerateData();
22993 const std::vector<GLubyte>& bulma_data = type.GenerateData();
22995 const GLuint type_size = static_cast<GLuint>(vegeta_data.size());
22998 uniform.m_initial_data.resize(6 * type_size);
22999 memcpy(&uniform.m_initial_data[0] + 0, &goku_data[0], type_size);
23000 memcpy(&uniform.m_initial_data[0] + type_size, &gohan_data[0], type_size);
23001 memcpy(&uniform.m_initial_data[0] + 2 * type_size, &goten_data[0], type_size);
23002 memcpy(&uniform.m_initial_data[0] + 3 * type_size, &picolo_data[0], type_size);
23003 memcpy(&uniform.m_initial_data[0] + 4 * type_size, &vegeta_data[0], type_size);
23004 memcpy(&uniform.m_initial_data[0] + 5 * type_size, &bulma_data[0], type_size);
23007 static const GLuint xfb_stride = 64;
23008 xfb_1.m_initial_data.resize(xfb_stride);
23009 xfb_1.m_expected_data.resize(xfb_stride);
23010 xfb_2.m_initial_data.resize(xfb_stride);
23011 xfb_2.m_expected_data.resize(xfb_stride);
23012 xfb_3.m_initial_data.resize(xfb_stride);
23013 xfb_3.m_expected_data.resize(xfb_stride);
23015 for (GLuint i = 0; i < xfb_stride; ++i)
23017 xfb_1.m_initial_data[i] = (glw::GLubyte)i;
23018 xfb_1.m_expected_data[i] = (glw::GLubyte)i;
23019 xfb_2.m_initial_data[i] = (glw::GLubyte)i;
23020 xfb_2.m_expected_data[i] = (glw::GLubyte)i;
23021 xfb_3.m_initial_data[i] = (glw::GLubyte)i;
23022 xfb_3.m_expected_data[i] = (glw::GLubyte)i;
23025 memcpy(&xfb_1.m_expected_data[0] + 48, &goku_data[0], type_size);
23026 memcpy(&xfb_1.m_expected_data[0] + 32, &gohan_data[0], type_size);
23027 memcpy(&xfb_1.m_expected_data[0] + 16, &goten_data[0], type_size);
23028 memcpy(&xfb_3.m_expected_data[0] + 48, &picolo_data[0], type_size);
23029 memcpy(&xfb_3.m_expected_data[0] + 32, &vegeta_data[0], type_size);
23030 memcpy(&xfb_2.m_expected_data[0] + 32, &bulma_data[0], type_size);
23033 /** Get body of main function for given shader stage
23036 * @param stage Shader stage
23037 * @param out_assignments Set to empty
23038 * @param out_calculations Set to empty
23040 void XFBVertexStreamsTest::getShaderBody(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
23041 std::string& out_assignments, std::string& out_calculations)
23043 out_calculations = "";
23045 // the shader declares the output variables with different "stream" qualifier, to make the data can export to
23046 // each stream, we must call the function EmitStreamVertex() and EndStreamPrimitive() to make each vertex emitted
23047 // by the GS is assigned to specific stream.
23048 static const GLchar* gs = " goku = uni_goku;\n"
23049 " gohan = uni_gohan;\n"
23050 " goten = uni_goten;\n"
23051 " EmitStreamVertex(0);\n"
23052 " EndStreamPrimitive(0);\n"
23053 " picolo = uni_picolo;\n"
23054 " vegeta = uni_vegeta;\n"
23055 " EmitStreamVertex(1);\n"
23056 " EndStreamPrimitive(1);\n"
23057 " bulma = uni_bulma;\n"
23058 " EmitStreamVertex(2);\n"
23059 " EndStreamPrimitive(2);\n";
23061 static const GLchar* fs = " fs_out = gohan + goku + goten + picolo + vegeta + bulma;\n";
23063 const GLchar* assignments = "";
23066 case Utils::Shader::FRAGMENT:
23069 case Utils::Shader::GEOMETRY:
23076 out_assignments = assignments;
23079 /** Get interface of shader
23082 * @param stage Shader stage
23083 * @param out_interface Set to ""
23085 void XFBVertexStreamsTest::getShaderInterface(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
23086 std::string& out_interface)
23088 static const GLchar* gs = "layout (xfb_buffer = 1, xfb_stride = 64) out;\n"
23089 "layout (xfb_buffer = 2, xfb_stride = 64) out;\n"
23090 "layout (xfb_buffer = 3, xfb_stride = 64) out;\n"
23092 "layout (stream = 0, xfb_buffer = 1, xfb_offset = 48) out vec4 goku;\n"
23093 "layout (stream = 0, xfb_buffer = 1, xfb_offset = 32) out vec4 gohan;\n"
23094 "layout (stream = 0, xfb_buffer = 1, xfb_offset = 16) out vec4 goten;\n"
23095 "layout (stream = 1, xfb_buffer = 3, xfb_offset = 48) out vec4 picolo;\n"
23096 "layout (stream = 1, xfb_buffer = 3, xfb_offset = 32) out vec4 vegeta;\n"
23097 "layout (stream = 2, xfb_buffer = 2, xfb_offset = 32) out vec4 bulma;\n"
23099 "layout(binding = 0) uniform gs_block {\n"
23100 " vec4 uni_goku;\n"
23101 " vec4 uni_gohan;\n"
23102 " vec4 uni_goten;\n"
23103 " vec4 uni_picolo;\n"
23104 " vec4 uni_vegeta;\n"
23105 " vec4 uni_bulma;\n"
23108 Fixed incorrect usage of in/out qualifier, the following variable should be input symbols for fragment shader
23110 static const GLchar* fs = "in vec4 goku;\n"
23113 "in vec4 picolo;\n"
23114 "in vec4 vegeta;\n"
23117 "out vec4 fs_out;\n";
23121 case Utils::Shader::FRAGMENT:
23122 out_interface = fs;
23124 case Utils::Shader::GEOMETRY:
23125 out_interface = gs;
23128 out_interface = "";
23135 * @param context Test framework context
23137 XFBMultipleVertexStreamsTest::XFBMultipleVertexStreamsTest(deqp::Context& context)
23138 : NegativeTestBase(
23139 context, "xfb_multiple_vertex_streams",
23140 "Test verifies that compiler reports error when multiple streams are captured with same xfb_buffer")
23144 /** Source for given test case and stage
23147 * @param stage Shader stage
23149 * @return Shader source
23151 std::string XFBMultipleVertexStreamsTest::getShaderSource(GLuint /* test_case_index */, Utils::Shader::STAGES stage)
23153 static const GLchar* var_definition = "const uint valid_stride = 64;\n"
23155 "layout (xfb_buffer = 1, xfb_stride = valid_stride) out;\n"
23156 "layout (xfb_buffer = 3, xfb_stride = valid_stride) out;\n"
23159 "layout (stream = 0, xfb_buffer = 1, xfb_offset = 48) out vec4 goku;\n"
23160 "layout (stream = 1, xfb_buffer = 1, xfb_offset = 32) out vec4 gohan;\n"
23161 "layout (stream = 2, xfb_buffer = 1, xfb_offset = 16) out vec4 goten;\n";
23162 static const GLchar* var_use = " goku = result / 2;\n"
23163 " gohan = result / 4;\n"
23164 " goten = result / 6;\n";
23165 static const GLchar* fs = "#version 430 core\n"
23166 "#extension GL_ARB_enhanced_layouts : require\n"
23170 "out vec4 fs_out;\n"
23174 " fs_out = gs_fs + goku;\n"
23177 static const GLchar* gs = "#version 430 core\n"
23178 "#extension GL_ARB_enhanced_layouts : require\n"
23180 "layout(points) in;\n"
23181 "layout(triangle_strip, max_vertices = 4) out;\n"
23185 "in vec4 tes_gs[];\n"
23186 "out vec4 gs_fs;\n"
23190 " vec4 result = tes_gs[0];\n"
23194 " gs_fs = result;\n"
23195 " gl_Position = vec4(-1, -1, 0, 1);\n"
23197 " gs_fs = result;\n"
23198 " gl_Position = vec4(-1, 1, 0, 1);\n"
23200 " gs_fs = result;\n"
23201 " gl_Position = vec4(1, -1, 0, 1);\n"
23203 " gs_fs = result;\n"
23204 " gl_Position = vec4(1, 1, 0, 1);\n"
23208 static const GLchar* vs = "#version 430 core\n"
23209 "#extension GL_ARB_enhanced_layouts : require\n"
23212 "out vec4 vs_tcs;\n"
23216 " vs_tcs = in_vs;\n"
23220 std::string source;
23222 if (Utils::Shader::GEOMETRY == stage)
23224 size_t position = 0;
23228 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
23229 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
23235 case Utils::Shader::FRAGMENT:
23238 case Utils::Shader::VERTEX:
23249 /** Selects if "compute" stage is relevant for test
23255 bool XFBMultipleVertexStreamsTest::isComputeRelevant(GLuint /* test_case_index */)
23262 * @param context Test framework context
23264 XFBExceedBufferLimitTest::XFBExceedBufferLimitTest(deqp::Context& context)
23265 : NegativeTestBase(context, "xfb_exceed_buffer_limit",
23266 "Test verifies that compiler reports error when xfb_buffer qualifier exceeds limit")
23270 /** Source for given test case and stage
23272 * @param test_case_index Index of test case
23273 * @param stage Shader stage
23275 * @return Shader source
23277 std::string XFBExceedBufferLimitTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
23279 static const GLchar* block_var_definition = "const uint buffer_index = BUFFER;\n"
23281 "layout (xfb_buffer = buffer_index, xfb_offset = 0) out Goku {\n"
23284 static const GLchar* global_var_definition = "const uint buffer_index = BUFFER;\n"
23286 "layout (xfb_buffer = buffer_index) out;\n";
23287 static const GLchar* vector_var_definition = "const uint buffer_index = BUFFER;\n"
23289 "layout (xfb_buffer = buffer_index) out vec4 gokuARRAY;\n";
23290 static const GLchar* block_use = " gokuINDEX.member = result / 2;\n";
23291 static const GLchar* global_use = "";
23292 static const GLchar* vector_use = " gokuINDEX = result / 2;\n";
23293 static const GLchar* fs = "#version 430 core\n"
23294 "#extension GL_ARB_enhanced_layouts : require\n"
23297 "out vec4 fs_out;\n"
23301 " fs_out = gs_fs;\n"
23304 static const GLchar* gs_tested = "#version 430 core\n"
23305 "#extension GL_ARB_enhanced_layouts : require\n"
23307 "layout(points) in;\n"
23308 "layout(triangle_strip, max_vertices = 4) out;\n"
23312 "in vec4 tes_gs[];\n"
23313 "out vec4 gs_fs;\n"
23317 " vec4 result = tes_gs[0];\n"
23321 " gs_fs = result;\n"
23322 " gl_Position = vec4(-1, -1, 0, 1);\n"
23324 " gs_fs = result;\n"
23325 " gl_Position = vec4(-1, 1, 0, 1);\n"
23327 " gs_fs = result;\n"
23328 " gl_Position = vec4(1, -1, 0, 1);\n"
23330 " gs_fs = result;\n"
23331 " gl_Position = vec4(1, 1, 0, 1);\n"
23335 static const GLchar* tcs = "#version 430 core\n"
23336 "#extension GL_ARB_enhanced_layouts : require\n"
23338 "layout(vertices = 1) out;\n"
23340 "in vec4 vs_tcs[];\n"
23341 "out vec4 tcs_tes[];\n"
23346 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
23348 " gl_TessLevelOuter[0] = 1.0;\n"
23349 " gl_TessLevelOuter[1] = 1.0;\n"
23350 " gl_TessLevelOuter[2] = 1.0;\n"
23351 " gl_TessLevelOuter[3] = 1.0;\n"
23352 " gl_TessLevelInner[0] = 1.0;\n"
23353 " gl_TessLevelInner[1] = 1.0;\n"
23356 static const GLchar* tcs_tested = "#version 430 core\n"
23357 "#extension GL_ARB_enhanced_layouts : require\n"
23359 "layout(vertices = 1) out;\n"
23363 "in vec4 vs_tcs[];\n"
23364 "out vec4 tcs_tes[];\n"
23368 " vec4 result = vs_tcs[gl_InvocationID];\n"
23372 " tcs_tes[gl_InvocationID] = result;\n"
23374 " gl_TessLevelOuter[0] = 1.0;\n"
23375 " gl_TessLevelOuter[1] = 1.0;\n"
23376 " gl_TessLevelOuter[2] = 1.0;\n"
23377 " gl_TessLevelOuter[3] = 1.0;\n"
23378 " gl_TessLevelInner[0] = 1.0;\n"
23379 " gl_TessLevelInner[1] = 1.0;\n"
23382 static const GLchar* tes_tested = "#version 430 core\n"
23383 "#extension GL_ARB_enhanced_layouts : require\n"
23385 "layout(isolines, point_mode) in;\n"
23389 "in vec4 tcs_tes[];\n"
23390 "out vec4 tes_gs;\n"
23394 " vec4 result = tcs_tes[0];\n"
23398 " tes_gs += result;\n"
23401 static const GLchar* vs = "#version 430 core\n"
23402 "#extension GL_ARB_enhanced_layouts : require\n"
23405 "out vec4 vs_tcs;\n"
23409 " vs_tcs = in_vs;\n"
23412 static const GLchar* vs_tested = "#version 430 core\n"
23413 "#extension GL_ARB_enhanced_layouts : require\n"
23418 "out vec4 vs_tcs;\n"
23422 " vec4 result = in_vs;\n"
23426 " vs_tcs = result;\n"
23430 std::string source;
23431 testCase& test_case = m_test_cases[test_case_index];
23433 if (test_case.m_stage == stage)
23435 const GLchar* array = "";
23437 const Functions& gl = m_context.getRenderContext().getFunctions();
23438 const GLchar* index = "";
23439 GLint max_n_xfb = 0;
23440 size_t position = 0;
23442 const GLchar* var_definition = 0;
23443 const GLchar* var_use = 0;
23445 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_n_xfb);
23446 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
23448 sprintf(buffer, "%d", max_n_xfb);
23450 switch (test_case.m_case)
23453 var_definition = block_var_definition;
23454 var_use = block_use;
23457 var_definition = global_var_definition;
23458 var_use = global_use;
23461 var_definition = vector_var_definition;
23462 var_use = vector_use;
23465 TCU_FAIL("Invalid enum");
23470 case Utils::Shader::GEOMETRY:
23471 source = gs_tested;
23475 case Utils::Shader::TESS_CTRL:
23476 source = tcs_tested;
23478 index = "[gl_InvocationID]";
23480 case Utils::Shader::TESS_EVAL:
23481 source = tes_tested;
23485 case Utils::Shader::VERTEX:
23486 source = vs_tested;
23489 TCU_FAIL("Invalid enum");
23493 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
23495 Utils::replaceToken("BUFFER", position, buffer, source);
23496 if (GLOBAL != test_case.m_case)
23498 Utils::replaceToken("ARRAY", position, array, source);
23500 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
23502 Utils::replaceAllTokens("INDEX", index, source);
23506 switch (test_case.m_stage)
23508 case Utils::Shader::GEOMETRY:
23511 case Utils::Shader::FRAGMENT:
23514 case Utils::Shader::VERTEX:
23521 case Utils::Shader::TESS_CTRL:
23524 case Utils::Shader::FRAGMENT:
23527 case Utils::Shader::VERTEX:
23534 case Utils::Shader::TESS_EVAL:
23537 case Utils::Shader::FRAGMENT:
23540 case Utils::Shader::TESS_CTRL:
23543 case Utils::Shader::VERTEX:
23550 case Utils::Shader::VERTEX:
23553 case Utils::Shader::FRAGMENT:
23561 TCU_FAIL("Invalid enum");
23569 /** Get description of test case
23571 * @param test_case_index Index of test case
23573 * @return Test case description
23575 std::string XFBExceedBufferLimitTest::getTestCaseName(GLuint test_case_index)
23577 std::stringstream stream;
23578 testCase& test_case = m_test_cases[test_case_index];
23580 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", case: ";
23582 switch (test_case.m_case)
23588 stream << "GLOBAL";
23591 stream << "VECTOR";
23594 TCU_FAIL("Invalid enum");
23597 return stream.str();
23600 /** Get number of test cases
23602 * @return Number of test cases
23604 GLuint XFBExceedBufferLimitTest::getTestCaseNumber()
23606 return static_cast<GLuint>(m_test_cases.size());
23609 /** Selects if "compute" stage is relevant for test
23615 bool XFBExceedBufferLimitTest::isComputeRelevant(GLuint /* test_case_index */)
23620 /** Prepare all test cases
23623 void XFBExceedBufferLimitTest::testInit()
23625 for (GLuint c = 0; c < CASE_MAX; ++c)
23627 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
23629 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
23630 (Utils::Shader::FRAGMENT == stage))
23635 testCase test_case = { (CASES)c, (Utils::Shader::STAGES)stage };
23637 m_test_cases.push_back(test_case);
23644 * @param context Test framework context
23646 XFBExceedOffsetLimitTest::XFBExceedOffsetLimitTest(deqp::Context& context)
23647 : NegativeTestBase(context, "xfb_exceed_offset_limit",
23648 "Test verifies that compiler reports error when xfb_offset qualifier exceeds limit")
23652 /** Source for given test case and stage
23654 * @param test_case_index Index of test case
23655 * @param stage Shader stage
23657 * @return Shader source
23659 std::string XFBExceedOffsetLimitTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
23661 static const GLchar* block_var_definition = "const uint max_size = SIZE;\n"
23663 "layout (xfb_buffer = 0, xfb_offset = max_size + 16) out Goku {\n"
23666 static const GLchar* global_var_definition = "const uint max_size = SIZE;\n"
23668 "layout (xfb_buffer = 0, xfb_stride = max_size + 16) out;\n";
23669 static const GLchar* vector_var_definition =
23670 "const uint max_size = SIZE;\n"
23672 "layout (xfb_buffer = 0, xfb_offset = max_size + 16) out vec4 gokuARRAY;\n";
23673 static const GLchar* block_use = " gokuINDEX.member = result / 2;\n";
23674 static const GLchar* global_use = "";
23675 static const GLchar* vector_use = " gokuINDEX = result / 2;\n";
23676 static const GLchar* fs = "#version 430 core\n"
23677 "#extension GL_ARB_enhanced_layouts : require\n"
23680 "out vec4 fs_out;\n"
23684 " fs_out = gs_fs;\n"
23687 static const GLchar* gs_tested = "#version 430 core\n"
23688 "#extension GL_ARB_enhanced_layouts : require\n"
23690 "layout(points) in;\n"
23691 "layout(triangle_strip, max_vertices = 4) out;\n"
23695 "in vec4 tes_gs[];\n"
23696 "out vec4 gs_fs;\n"
23700 " vec4 result = tes_gs[0];\n"
23704 " gs_fs = result;\n"
23705 " gl_Position = vec4(-1, -1, 0, 1);\n"
23707 " gs_fs = result;\n"
23708 " gl_Position = vec4(-1, 1, 0, 1);\n"
23710 " gs_fs = result;\n"
23711 " gl_Position = vec4(1, -1, 0, 1);\n"
23713 " gs_fs = result;\n"
23714 " gl_Position = vec4(1, 1, 0, 1);\n"
23718 static const GLchar* tcs = "#version 430 core\n"
23719 "#extension GL_ARB_enhanced_layouts : require\n"
23721 "layout(vertices = 1) out;\n"
23723 "in vec4 vs_tcs[];\n"
23724 "out vec4 tcs_tes[];\n"
23729 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
23731 " gl_TessLevelOuter[0] = 1.0;\n"
23732 " gl_TessLevelOuter[1] = 1.0;\n"
23733 " gl_TessLevelOuter[2] = 1.0;\n"
23734 " gl_TessLevelOuter[3] = 1.0;\n"
23735 " gl_TessLevelInner[0] = 1.0;\n"
23736 " gl_TessLevelInner[1] = 1.0;\n"
23739 static const GLchar* tcs_tested = "#version 430 core\n"
23740 "#extension GL_ARB_enhanced_layouts : require\n"
23742 "layout(vertices = 1) out;\n"
23746 "in vec4 vs_tcs[];\n"
23747 "out vec4 tcs_tes[];\n"
23751 " vec4 result = vs_tcs[gl_InvocationID];\n"
23755 " tcs_tes[gl_InvocationID] = result;\n"
23757 " gl_TessLevelOuter[0] = 1.0;\n"
23758 " gl_TessLevelOuter[1] = 1.0;\n"
23759 " gl_TessLevelOuter[2] = 1.0;\n"
23760 " gl_TessLevelOuter[3] = 1.0;\n"
23761 " gl_TessLevelInner[0] = 1.0;\n"
23762 " gl_TessLevelInner[1] = 1.0;\n"
23765 static const GLchar* tes_tested = "#version 430 core\n"
23766 "#extension GL_ARB_enhanced_layouts : require\n"
23768 "layout(isolines, point_mode) in;\n"
23772 "in vec4 tcs_tes[];\n"
23773 "out vec4 tes_gs;\n"
23777 " vec4 result = tcs_tes[0];\n"
23781 " tes_gs += result;\n"
23784 static const GLchar* vs = "#version 430 core\n"
23785 "#extension GL_ARB_enhanced_layouts : require\n"
23788 "out vec4 vs_tcs;\n"
23792 " vs_tcs = in_vs;\n"
23795 static const GLchar* vs_tested = "#version 430 core\n"
23796 "#extension GL_ARB_enhanced_layouts : require\n"
23801 "out vec4 vs_tcs;\n"
23805 " vec4 result = in_vs;\n"
23809 " vs_tcs = result;\n"
23813 std::string source;
23814 testCase& test_case = m_test_cases[test_case_index];
23816 if (test_case.m_stage == stage)
23818 const GLchar* array = "";
23820 const Functions& gl = m_context.getRenderContext().getFunctions();
23821 const GLchar* index = "";
23822 GLint max_n_xfb_comp = 0;
23823 GLint max_n_xfb_bytes = 0;
23824 size_t position = 0;
23826 const GLchar* var_definition = 0;
23827 const GLchar* var_use = 0;
23829 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_n_xfb_comp);
23830 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
23832 max_n_xfb_bytes = max_n_xfb_comp * 4;
23834 sprintf(buffer, "%d", max_n_xfb_bytes);
23836 switch (test_case.m_case)
23839 var_definition = block_var_definition;
23840 var_use = block_use;
23843 var_definition = global_var_definition;
23844 var_use = global_use;
23847 var_definition = vector_var_definition;
23848 var_use = vector_use;
23851 TCU_FAIL("Invalid enum");
23853 // It is a compile time error to apply xfb_offset to the declaration of an unsized array(GLSL4.5 spec: Page73)
23854 // change array = "[]" to "[1]"
23857 case Utils::Shader::GEOMETRY:
23858 source = gs_tested;
23862 case Utils::Shader::TESS_CTRL:
23863 source = tcs_tested;
23865 index = "[gl_InvocationID]";
23867 case Utils::Shader::TESS_EVAL:
23868 source = tes_tested;
23872 case Utils::Shader::VERTEX:
23873 source = vs_tested;
23876 TCU_FAIL("Invalid enum");
23880 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
23882 Utils::replaceToken("SIZE", position, buffer, source);
23883 if (GLOBAL != test_case.m_case)
23885 Utils::replaceToken("ARRAY", position, array, source);
23887 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
23889 Utils::replaceAllTokens("INDEX", index, source);
23893 switch (test_case.m_stage)
23895 case Utils::Shader::GEOMETRY:
23898 case Utils::Shader::FRAGMENT:
23901 case Utils::Shader::VERTEX:
23908 case Utils::Shader::TESS_CTRL:
23911 case Utils::Shader::FRAGMENT:
23914 case Utils::Shader::VERTEX:
23921 case Utils::Shader::TESS_EVAL:
23924 case Utils::Shader::FRAGMENT:
23927 case Utils::Shader::TESS_CTRL:
23930 case Utils::Shader::VERTEX:
23937 case Utils::Shader::VERTEX:
23940 case Utils::Shader::FRAGMENT:
23948 TCU_FAIL("Invalid enum");
23956 /** Get description of test case
23958 * @param test_case_index Index of test case
23960 * @return Test case description
23962 std::string XFBExceedOffsetLimitTest::getTestCaseName(GLuint test_case_index)
23964 std::stringstream stream;
23965 testCase& test_case = m_test_cases[test_case_index];
23967 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", case: ";
23969 switch (test_case.m_case)
23975 stream << "GLOBAL";
23978 stream << "VECTOR";
23981 TCU_FAIL("Invalid enum");
23984 return stream.str();
23987 /** Get number of test cases
23989 * @return Number of test cases
23991 GLuint XFBExceedOffsetLimitTest::getTestCaseNumber()
23993 return static_cast<GLuint>(m_test_cases.size());
23996 /** Selects if "compute" stage is relevant for test
24002 bool XFBExceedOffsetLimitTest::isComputeRelevant(GLuint /* test_case_index */)
24007 /** Prepare all test cases
24010 void XFBExceedOffsetLimitTest::testInit()
24012 for (GLuint c = 0; c < CASE_MAX; ++c)
24014 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
24016 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
24017 (Utils::Shader::FRAGMENT == stage))
24022 testCase test_case = { (CASES)c, (Utils::Shader::STAGES)stage };
24024 m_test_cases.push_back(test_case);
24031 * @param context Test context
24033 XFBGlobalBufferTest::XFBGlobalBufferTest(deqp::Context& context)
24034 : BufferTestBase(context, "xfb_global_buffer", "Test verifies that global xfb_buffer qualifier is respected")
24036 /* Nothing to be done here */
24039 /** Get descriptors of buffers necessary for test
24041 * @param test_case_index Index of test case
24042 * @param out_descriptors Descriptors of buffers used by test
24044 void XFBGlobalBufferTest::getBufferDescriptors(glw::GLuint test_case_index, bufferDescriptor::Vector& out_descriptors)
24046 // the function "getType(test_case_index)" can't return correct data type, so change code as following:
24047 const Utils::Type& type = m_test_cases[test_case_index].m_type;
24049 /* Test needs single uniform and two xfbs */
24050 out_descriptors.resize(3);
24052 /* Get references */
24053 bufferDescriptor& uniform = out_descriptors[0];
24054 bufferDescriptor& xfb_1 = out_descriptors[1];
24055 bufferDescriptor& xfb_3 = out_descriptors[2];
24058 uniform.m_index = 0;
24063 uniform.m_target = Utils::Buffer::Uniform;
24064 xfb_1.m_target = Utils::Buffer::Transform_feedback;
24065 xfb_3.m_target = Utils::Buffer::Transform_feedback;
24068 const GLuint gen_start = Utils::s_rand;
24069 const std::vector<GLubyte>& chichi_data = type.GenerateData();
24070 const std::vector<GLubyte>& bulma_data = type.GenerateData();
24071 const std::vector<GLubyte>& trunks_data = type.GenerateData();
24072 const std::vector<GLubyte>& bra_data = type.GenerateData();
24073 const std::vector<GLubyte>& gohan_data = type.GenerateData();
24074 const std::vector<GLubyte>& goten_data = type.GenerateData();
24076 Utils::s_rand = gen_start;
24077 const std::vector<GLubyte>& chichi_data_pck = type.GenerateDataPacked();
24078 const std::vector<GLubyte>& bulma_data_pck = type.GenerateDataPacked();
24079 const std::vector<GLubyte>& trunks_data_pck = type.GenerateDataPacked();
24080 const std::vector<GLubyte>& bra_data_pck = type.GenerateDataPacked();
24081 const std::vector<GLubyte>& gohan_data_pck = type.GenerateDataPacked();
24082 const std::vector<GLubyte>& goten_data_pck = type.GenerateDataPacked();
24084 const GLuint type_size = static_cast<GLuint>(chichi_data.size());
24085 const GLuint type_size_pck = static_cast<GLuint>(chichi_data_pck.size());
24088 uniform.m_initial_data.resize(6 * type_size);
24089 memcpy(&uniform.m_initial_data[0] + 0, &chichi_data[0], type_size);
24090 memcpy(&uniform.m_initial_data[0] + type_size, &bulma_data[0], type_size);
24091 memcpy(&uniform.m_initial_data[0] + 2 * type_size, &trunks_data[0], type_size);
24092 memcpy(&uniform.m_initial_data[0] + 3 * type_size, &bra_data[0], type_size);
24093 memcpy(&uniform.m_initial_data[0] + 4 * type_size, &gohan_data[0], type_size);
24094 memcpy(&uniform.m_initial_data[0] + 5 * type_size, &goten_data[0], type_size);
24097 xfb_1.m_initial_data.resize(3 * type_size_pck);
24098 xfb_1.m_expected_data.resize(3 * type_size_pck);
24099 xfb_3.m_initial_data.resize(3 * type_size_pck);
24100 xfb_3.m_expected_data.resize(3 * type_size_pck);
24102 for (GLuint i = 0; i < 3 * type_size_pck; ++i)
24104 xfb_1.m_initial_data[i] = (glw::GLubyte)i;
24105 xfb_1.m_expected_data[i] = (glw::GLubyte)i;
24106 xfb_3.m_initial_data[i] = (glw::GLubyte)i;
24107 xfb_3.m_expected_data[i] = (glw::GLubyte)i;
24110 memcpy(&xfb_3.m_expected_data[0] + 2 * type_size_pck, &chichi_data_pck[0], type_size_pck);
24111 memcpy(&xfb_1.m_expected_data[0] + 0 * type_size_pck, &bulma_data_pck[0], type_size_pck);
24112 memcpy(&xfb_1.m_expected_data[0] + 1 * type_size_pck, &trunks_data_pck[0], type_size_pck);
24113 memcpy(&xfb_1.m_expected_data[0] + 2 * type_size_pck, &bra_data_pck[0], type_size_pck);
24114 memcpy(&xfb_3.m_expected_data[0] + 0 * type_size_pck, &gohan_data_pck[0], type_size_pck);
24115 memcpy(&xfb_3.m_expected_data[0] + 1 * type_size_pck, &goten_data_pck[0], type_size_pck);
24118 /** Source for given test case and stage
24120 * @param test_case_index Index of test case
24121 * @param stage Shader stage
24123 * @return Shader source
24125 std::string XFBGlobalBufferTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
24127 static const GLchar* fs =
24128 "#version 430 core\n"
24129 "#extension GL_ARB_enhanced_layouts : require\n"
24131 "flat in TYPE chichi;\n"
24132 "flat in TYPE bulma;\n"
24142 "out vec4 fs_out;\n"
24146 " fs_out = vec4(1);\n"
24147 " if (TYPE(1) != chichi + bulma + vegeta.trunk + vegeta.bra + goku.gohan + goku.goten)\n"
24149 " fs_out = vec4(0);\n"
24154 static const GLchar* gs = "#version 430 core\n"
24155 "#extension GL_ARB_enhanced_layouts : require\n"
24157 "layout(points) in;\n"
24158 "layout(points, max_vertices = 1) out;\n"
24169 static const GLchar* tcs = "#version 430 core\n"
24170 "#extension GL_ARB_enhanced_layouts : require\n"
24172 "layout(vertices = 1) out;\n"
24177 " gl_TessLevelOuter[0] = 1.0;\n"
24178 " gl_TessLevelOuter[1] = 1.0;\n"
24179 " gl_TessLevelOuter[2] = 1.0;\n"
24180 " gl_TessLevelOuter[3] = 1.0;\n"
24181 " gl_TessLevelInner[0] = 1.0;\n"
24182 " gl_TessLevelInner[1] = 1.0;\n"
24186 static const GLchar* tes = "#version 430 core\n"
24187 "#extension GL_ARB_enhanced_layouts : require\n"
24189 "layout(isolines, point_mode) in;\n"
24199 static const GLchar* vs = "#version 430 core\n"
24200 "#extension GL_ARB_enhanced_layouts : require\n"
24207 static const GLchar* vs_tested = "#version 430 core\n"
24208 "#extension GL_ARB_enhanced_layouts : require\n"
24218 std::string source;
24219 const _testCase& test_case = m_test_cases[test_case_index];
24220 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
24222 if (test_case.m_stage == stage)
24224 std::string assignments = " chichi = uni_chichi;\n"
24225 " bulma = uni_bulma;\n"
24226 " vegeta.trunk = uni_trunk;\n"
24227 " vegeta.bra = uni_bra;\n"
24228 " goku.gohan = uni_gohan;\n"
24229 " goku.goten = uni_goten;\n";
24231 std::string interface = "layout (xfb_buffer = 3) out;\n"
24233 "const uint type_size = SIZE;\n"
24235 "layout ( xfb_offset = 2 * type_size) flat out TYPE chichi;\n"
24236 "layout (xfb_buffer = 1, xfb_offset = 0) flat out TYPE bulma;\n"
24237 "layout (xfb_buffer = 1, xfb_offset = 1 * type_size) out Vegeta {\n"
24241 "layout ( xfb_offset = 0) out Goku {\n"
24246 // Uniform block must be declared with std140, otherwise each block member is not packed
24247 "layout(binding = 0, std140) uniform block {\n"
24248 " TYPE uni_chichi;\n"
24249 " TYPE uni_bulma;\n"
24250 " TYPE uni_trunk;\n"
24252 " TYPE uni_gohan;\n"
24253 " TYPE uni_goten;\n"
24256 /* Prepare interface string */
24259 size_t position = 0;
24260 const GLuint type_size = test_case.m_type.GetSize();
24262 sprintf(buffer, "%d", type_size);
24264 Utils::replaceToken("SIZE", position, buffer, interface);
24265 Utils::replaceAllTokens("TYPE", type_name, interface);
24270 case Utils::Shader::GEOMETRY:
24273 case Utils::Shader::TESS_EVAL:
24276 case Utils::Shader::VERTEX:
24277 source = vs_tested;
24280 TCU_FAIL("Invalid enum");
24283 /* Replace tokens */
24285 size_t position = 0;
24287 Utils::replaceToken("INTERFACE", position, interface.c_str(), source);
24288 Utils::replaceToken("ASSIGNMENTS", position, assignments.c_str(), source);
24293 switch (test_case.m_stage)
24295 case Utils::Shader::GEOMETRY:
24298 case Utils::Shader::FRAGMENT:
24300 Utils::replaceAllTokens("TYPE", type_name, source);
24302 case Utils::Shader::VERTEX:
24309 case Utils::Shader::TESS_EVAL:
24312 case Utils::Shader::FRAGMENT:
24314 Utils::replaceAllTokens("TYPE", type_name, source);
24316 case Utils::Shader::TESS_CTRL:
24319 case Utils::Shader::VERTEX:
24326 case Utils::Shader::VERTEX:
24329 case Utils::Shader::FRAGMENT:
24331 Utils::replaceAllTokens("TYPE", type_name, source);
24338 TCU_FAIL("Invalid enum");
24346 /** Get name of test case
24348 * @param test_case_index Index of test case
24350 * @return Name of case
24352 std::string XFBGlobalBufferTest::getTestCaseName(GLuint test_case_index)
24355 const _testCase& test_case = m_test_cases[test_case_index];
24357 name = "Tested stage: ";
24358 name.append(Utils::Shader::GetStageName(test_case.m_stage));
24359 name.append(". Tested type: ");
24360 name.append(test_case.m_type.GetGLSLTypeName());
24365 /** Get number of cases
24367 * @return Number of test cases
24369 GLuint XFBGlobalBufferTest::getTestCaseNumber()
24371 return static_cast<GLuint>(m_test_cases.size());
24374 /** Prepare set of test cases
24377 void XFBGlobalBufferTest::testInit()
24379 GLuint n_types = getTypesNumber();
24381 for (GLuint i = 0; i < n_types; ++i)
24383 const Utils::Type& type = getType(i);
24385 When the tfx varying is the following type, the number of output exceeds the gl_MaxVaryingComponents, which will
24386 cause a link time error.
24388 if (strcmp(type.GetGLSLTypeName(), "dmat3") == 0 || strcmp(type.GetGLSLTypeName(), "dmat4") == 0 ||
24389 strcmp(type.GetGLSLTypeName(), "dmat3x4") == 0 || strcmp(type.GetGLSLTypeName(), "dmat4x3") == 0)
24393 const _testCase test_cases[] = { { Utils::Shader::VERTEX, type },
24394 { Utils::Shader::GEOMETRY, type },
24395 { Utils::Shader::TESS_EVAL, type } };
24397 m_test_cases.push_back(test_cases[0]);
24398 m_test_cases.push_back(test_cases[1]);
24399 m_test_cases.push_back(test_cases[2]);
24405 * @param context Test context
24407 XFBStrideTest::XFBStrideTest(deqp::Context& context)
24408 : BufferTestBase(context, "xfb_stride", "Test verifies that correct stride is used for all types")
24410 /* Nothing to be done here */
24413 /** Execute drawArrays for single vertex
24415 * @param test_case_index
24419 bool XFBStrideTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
24421 const Functions& gl = m_context.getRenderContext().getFunctions();
24422 GLenum primitive_type = GL_PATCHES;
24423 const testCase& test_case = m_test_cases[test_case_index];
24425 if (Utils::Shader::VERTEX == test_case.m_stage)
24427 primitive_type = GL_POINTS;
24430 gl.disable(GL_RASTERIZER_DISCARD);
24431 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
24433 gl.beginTransformFeedback(GL_POINTS);
24434 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
24436 gl.drawArrays(primitive_type, 0 /* first */, 2 /* count */);
24437 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
24439 gl.endTransformFeedback();
24440 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
24445 /** Get descriptors of buffers necessary for test
24447 * @param test_case_index Index of test case
24448 * @param out_descriptors Descriptors of buffers used by test
24450 void XFBStrideTest::getBufferDescriptors(GLuint test_case_index, bufferDescriptor::Vector& out_descriptors)
24452 const testCase& test_case = m_test_cases[test_case_index];
24453 const Utils::Type& type = test_case.m_type;
24455 /* Test needs single uniform and xfb */
24456 out_descriptors.resize(2);
24458 /* Get references */
24459 bufferDescriptor& uniform = out_descriptors[0];
24460 bufferDescriptor& xfb = out_descriptors[1];
24463 uniform.m_index = 0;
24467 uniform.m_target = Utils::Buffer::Uniform;
24468 xfb.m_target = Utils::Buffer::Transform_feedback;
24471 const GLuint rand_start = Utils::s_rand;
24472 const std::vector<GLubyte>& uniform_data = type.GenerateData();
24474 Utils::s_rand = rand_start;
24475 const std::vector<GLubyte>& xfb_data = type.GenerateDataPacked();
24477 const GLuint uni_type_size = static_cast<GLuint>(uniform_data.size());
24478 const GLuint xfb_type_size = static_cast<GLuint>(xfb_data.size());
24480 Note: If xfb varying output from vertex shader, the variable "goku" will only output once to transform feedback buffer,
24481 if xfb varying output from TES or GS, because the input primitive type in TES is defined as "layout(isolines, point_mode) in;",
24482 the primitive type is line which make the variable "goku" will output twice to transform feedback buffer, so for vertex shader
24483 only one valid data should be initialized in xfb.m_expected_data
24485 const GLuint xfb_data_size = (test_case.m_stage == Utils::Shader::VERTEX) ? xfb_type_size : xfb_type_size * 2;
24487 uniform.m_initial_data.resize(uni_type_size);
24488 memcpy(&uniform.m_initial_data[0] + 0 * uni_type_size, &uniform_data[0], uni_type_size);
24491 xfb.m_initial_data.resize(xfb_data_size);
24492 xfb.m_expected_data.resize(xfb_data_size);
24494 for (GLuint i = 0; i < xfb_data_size; ++i)
24496 xfb.m_initial_data[i] = (glw::GLubyte)i;
24497 xfb.m_expected_data[i] = (glw::GLubyte)i;
24500 if (test_case.m_stage == Utils::Shader::VERTEX)
24502 memcpy(&xfb.m_expected_data[0] + 0 * xfb_type_size, &xfb_data[0], xfb_type_size);
24506 memcpy(&xfb.m_expected_data[0] + 0 * xfb_type_size, &xfb_data[0], xfb_type_size);
24507 memcpy(&xfb.m_expected_data[0] + 1 * xfb_type_size, &xfb_data[0], xfb_type_size);
24511 /** Get body of main function for given shader stage
24513 * @param test_case_index Index of test case
24514 * @param stage Shader stage
24515 * @param out_assignments Set to empty
24516 * @param out_calculations Set to empty
24518 void XFBStrideTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage, std::string& out_assignments,
24519 std::string& out_calculations)
24521 const testCase& test_case = m_test_cases[test_case_index];
24523 out_calculations = "";
24525 static const GLchar* vs_tes_gs = " goku = uni_goku;\n";
24526 static const GLchar* fs = " fs_out = vec4(1, 0.25, 0.5, 0.75);\n"
24527 " if (TYPE(0) == goku)\n"
24529 " fs_out = vec4(1, 0.75, 0.5, 0.5);\n"
24532 const GLchar* assignments = "";
24534 if (test_case.m_stage == stage)
24538 case Utils::Shader::GEOMETRY:
24539 assignments = vs_tes_gs;
24541 case Utils::Shader::TESS_EVAL:
24542 assignments = vs_tes_gs;
24544 case Utils::Shader::VERTEX:
24545 assignments = vs_tes_gs;
24548 TCU_FAIL("Invalid enum");
24555 case Utils::Shader::FRAGMENT:
24558 case Utils::Shader::GEOMETRY:
24559 case Utils::Shader::TESS_CTRL:
24560 case Utils::Shader::TESS_EVAL:
24561 case Utils::Shader::VERTEX:
24564 TCU_FAIL("Invalid enum");
24568 out_assignments = assignments;
24570 if (Utils::Shader::FRAGMENT == stage)
24572 Utils::replaceAllTokens("TYPE", test_case.m_type.GetGLSLTypeName(), out_assignments);
24576 /** Get interface of shader
24578 * @param test_case_index Index of test case
24579 * @param stage Shader stage
24580 * @param out_interface Set to ""
24582 void XFBStrideTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage, std::string& out_interface)
24584 static const GLchar* vs_tes_gs = "layout (xfb_offset = 0) FLAT out TYPE goku;\n"
24586 "layout(std140, binding = 0) uniform Goku {\n"
24587 " TYPE uni_goku;\n"
24589 static const GLchar* fs = "FLAT in TYPE goku;\n"
24591 "out vec4 fs_out;\n";
24593 const testCase& test_case = m_test_cases[test_case_index];
24594 const GLchar* interface = "";
24595 const GLchar* flat = "";
24597 if (test_case.m_stage == stage)
24601 case Utils::Shader::GEOMETRY:
24602 interface = vs_tes_gs;
24604 case Utils::Shader::TESS_EVAL:
24605 interface = vs_tes_gs;
24607 case Utils::Shader::VERTEX:
24608 interface = vs_tes_gs;
24611 TCU_FAIL("Invalid enum");
24618 case Utils::Shader::FRAGMENT:
24621 case Utils::Shader::GEOMETRY:
24622 case Utils::Shader::TESS_CTRL:
24623 case Utils::Shader::TESS_EVAL:
24624 case Utils::Shader::VERTEX:
24627 TCU_FAIL("Invalid enum");
24631 out_interface = interface;
24633 if (Utils::Type::Float != test_case.m_type.m_basic_type)
24638 Utils::replaceAllTokens("FLAT", flat, out_interface);
24639 Utils::replaceAllTokens("TYPE", test_case.m_type.GetGLSLTypeName(), out_interface);
24642 /** Get source code of shader
24644 * @param test_case_index Index of test case
24645 * @param stage Shader stage
24649 std::string XFBStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
24651 std::string source;
24652 const testCase& test_case = m_test_cases[test_case_index];
24654 switch (test_case.m_stage)
24656 case Utils::Shader::VERTEX:
24659 case Utils::Shader::FRAGMENT:
24660 case Utils::Shader::VERTEX:
24661 source = BufferTestBase::getShaderSource(test_case_index, stage);
24668 case Utils::Shader::TESS_EVAL:
24671 case Utils::Shader::FRAGMENT:
24672 case Utils::Shader::TESS_CTRL:
24673 case Utils::Shader::TESS_EVAL:
24674 case Utils::Shader::VERTEX:
24675 source = BufferTestBase::getShaderSource(test_case_index, stage);
24682 case Utils::Shader::GEOMETRY:
24683 source = BufferTestBase::getShaderSource(test_case_index, stage);
24687 TCU_FAIL("Invalid enum");
24695 /** Get name of test case
24697 * @param test_case_index Index of test case
24699 * @return Name of tested stage
24701 std::string XFBStrideTest::getTestCaseName(glw::GLuint test_case_index)
24703 std::stringstream stream;
24704 const testCase& test_case = m_test_cases[test_case_index];
24706 stream << "Type: " << test_case.m_type.GetGLSLTypeName()
24707 << ", stage: " << Utils::Shader::GetStageName(test_case.m_stage);
24709 return stream.str();
24712 /** Returns number of test cases
24716 glw::GLuint XFBStrideTest::getTestCaseNumber()
24718 return static_cast<GLuint>(m_test_cases.size());
24721 /** Prepare all test cases
24724 void XFBStrideTest::testInit()
24726 const GLuint n_types = getTypesNumber();
24728 for (GLuint i = 0; i < n_types; ++i)
24730 const Utils::Type& type = getType(i);
24732 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
24734 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::FRAGMENT == stage) ||
24735 (Utils::Shader::TESS_CTRL == stage))
24740 testCase test_case = { (Utils::Shader::STAGES)stage, type };
24742 m_test_cases.push_back(test_case);
24749 * @param context Test framework context
24751 XFBBlockMemberBufferTest::XFBBlockMemberBufferTest(deqp::Context& context)
24752 : NegativeTestBase(
24753 context, "xfb_block_member_buffer",
24754 "Test verifies that compiler reports error when block member has different xfb_buffer qualifier than buffer")
24758 /** Source for given test case and stage
24760 * @param test_case_index Index of test case
24761 * @param stage Shader stage
24763 * @return Shader source
24765 std::string XFBBlockMemberBufferTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
24767 static const GLchar* var_definition = "layout (xfb_offset = 0) out Goku {\n"
24769 " layout (xfb_buffer = 1) vec4 goten;\n"
24771 static const GLchar* var_use = " gokuINDEX.gohan = result / 2;\n"
24772 " gokuINDEX.goten = result / 4;\n";
24773 static const GLchar* fs = "#version 430 core\n"
24774 "#extension GL_ARB_enhanced_layouts : require\n"
24777 "out vec4 fs_out;\n"
24781 " fs_out = gs_fs;\n"
24784 static const GLchar* gs_tested = "#version 430 core\n"
24785 "#extension GL_ARB_enhanced_layouts : require\n"
24787 "layout(points) in;\n"
24788 "layout(triangle_strip, max_vertices = 4) out;\n"
24792 "in vec4 tes_gs[];\n"
24793 "out vec4 gs_fs;\n"
24797 " vec4 result = tes_gs[0];\n"
24801 " gs_fs = result;\n"
24802 " gl_Position = vec4(-1, -1, 0, 1);\n"
24804 " gs_fs = result;\n"
24805 " gl_Position = vec4(-1, 1, 0, 1);\n"
24807 " gs_fs = result;\n"
24808 " gl_Position = vec4(1, -1, 0, 1);\n"
24810 " gs_fs = result;\n"
24811 " gl_Position = vec4(1, 1, 0, 1);\n"
24815 static const GLchar* tcs = "#version 430 core\n"
24816 "#extension GL_ARB_enhanced_layouts : require\n"
24818 "layout(vertices = 1) out;\n"
24820 "in vec4 vs_tcs[];\n"
24821 "out vec4 tcs_tes[];\n"
24826 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
24828 " gl_TessLevelOuter[0] = 1.0;\n"
24829 " gl_TessLevelOuter[1] = 1.0;\n"
24830 " gl_TessLevelOuter[2] = 1.0;\n"
24831 " gl_TessLevelOuter[3] = 1.0;\n"
24832 " gl_TessLevelInner[0] = 1.0;\n"
24833 " gl_TessLevelInner[1] = 1.0;\n"
24836 static const GLchar* tcs_tested = "#version 430 core\n"
24837 "#extension GL_ARB_enhanced_layouts : require\n"
24839 "layout(vertices = 1) out;\n"
24843 "in vec4 vs_tcs[];\n"
24844 "out vec4 tcs_tes[];\n"
24848 " vec4 result = vs_tcs[gl_InvocationID];\n"
24852 " tcs_tes[gl_InvocationID] = result;\n"
24854 " gl_TessLevelOuter[0] = 1.0;\n"
24855 " gl_TessLevelOuter[1] = 1.0;\n"
24856 " gl_TessLevelOuter[2] = 1.0;\n"
24857 " gl_TessLevelOuter[3] = 1.0;\n"
24858 " gl_TessLevelInner[0] = 1.0;\n"
24859 " gl_TessLevelInner[1] = 1.0;\n"
24862 static const GLchar* tes_tested = "#version 430 core\n"
24863 "#extension GL_ARB_enhanced_layouts : require\n"
24865 "layout(isolines, point_mode) in;\n"
24869 "in vec4 tcs_tes[];\n"
24870 "out vec4 tes_gs;\n"
24874 " vec4 result = tcs_tes[0];\n"
24878 " tes_gs += result;\n"
24881 static const GLchar* vs = "#version 430 core\n"
24882 "#extension GL_ARB_enhanced_layouts : require\n"
24885 "out vec4 vs_tcs;\n"
24889 " vs_tcs = in_vs;\n"
24892 static const GLchar* vs_tested = "#version 430 core\n"
24893 "#extension GL_ARB_enhanced_layouts : require\n"
24898 "out vec4 vs_tcs;\n"
24902 " vec4 result = in_vs;\n"
24906 " vs_tcs = result;\n"
24910 std::string source;
24911 testCase& test_case = m_test_cases[test_case_index];
24913 if (test_case.m_stage == stage)
24915 const GLchar* array = "";
24916 const GLchar* index = "";
24917 size_t position = 0;
24921 case Utils::Shader::GEOMETRY:
24922 source = gs_tested;
24926 case Utils::Shader::TESS_CTRL:
24927 source = tcs_tested;
24929 index = "[gl_InvocationID]";
24931 case Utils::Shader::TESS_EVAL:
24932 source = tes_tested;
24936 case Utils::Shader::VERTEX:
24937 source = vs_tested;
24940 TCU_FAIL("Invalid enum");
24943 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
24945 Utils::replaceToken("ARRAY", position, array, source);
24946 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
24948 Utils::replaceAllTokens("INDEX", index, source);
24952 switch (test_case.m_stage)
24954 case Utils::Shader::GEOMETRY:
24957 case Utils::Shader::FRAGMENT:
24960 case Utils::Shader::VERTEX:
24967 case Utils::Shader::TESS_CTRL:
24970 case Utils::Shader::FRAGMENT:
24973 case Utils::Shader::VERTEX:
24980 case Utils::Shader::TESS_EVAL:
24983 case Utils::Shader::FRAGMENT:
24986 case Utils::Shader::TESS_CTRL:
24989 case Utils::Shader::VERTEX:
24996 case Utils::Shader::VERTEX:
24999 case Utils::Shader::FRAGMENT:
25007 TCU_FAIL("Invalid enum");
25015 /** Get description of test case
25017 * @param test_case_index Index of test case
25019 * @return Test case description
25021 std::string XFBBlockMemberBufferTest::getTestCaseName(GLuint test_case_index)
25023 std::stringstream stream;
25024 testCase& test_case = m_test_cases[test_case_index];
25026 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage);
25028 return stream.str();
25031 /** Get number of test cases
25033 * @return Number of test cases
25035 GLuint XFBBlockMemberBufferTest::getTestCaseNumber()
25037 return static_cast<GLuint>(m_test_cases.size());
25040 /** Selects if "compute" stage is relevant for test
25046 bool XFBBlockMemberBufferTest::isComputeRelevant(GLuint /* test_case_index */)
25051 /** Prepare all test cases
25054 void XFBBlockMemberBufferTest::testInit()
25056 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
25058 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
25059 (Utils::Shader::FRAGMENT == stage))
25064 testCase test_case = { (Utils::Shader::STAGES)stage };
25066 m_test_cases.push_back(test_case);
25072 * @param context Test framework context
25074 XFBOutputOverlappingTest::XFBOutputOverlappingTest(deqp::Context& context)
25075 : NegativeTestBase(context, "xfb_output_overlapping",
25076 "Test verifies that compiler reports error when two xfb qualified outputs overlap")
25080 /** Source for given test case and stage
25082 * @param test_case_index Index of test case
25083 * @param stage Shader stage
25085 * @return Shader source
25087 std::string XFBOutputOverlappingTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
25089 static const GLchar* var_definition = "layout (xfb_offset = OFFSET) out TYPE gohanARRAY;\n"
25090 "layout (xfb_offset = OFFSET) out TYPE gotenARRAY;\n";
25091 static const GLchar* var_use = " gohanINDEX = TYPE(0);\n"
25092 " gotenINDEX = TYPE(1);\n"
25093 " if (vec4(0) == result)\n"
25095 " gohanINDEX = TYPE(1);\n"
25096 " gotenINDEX = TYPE(0);\n"
25098 static const GLchar* fs = "#version 430 core\n"
25099 "#extension GL_ARB_enhanced_layouts : require\n"
25102 "out vec4 fs_out;\n"
25106 " fs_out = gs_fs;\n"
25109 static const GLchar* gs_tested = "#version 430 core\n"
25110 "#extension GL_ARB_enhanced_layouts : require\n"
25112 "layout(points) in;\n"
25113 "layout(triangle_strip, max_vertices = 4) out;\n"
25117 "in vec4 tes_gs[];\n"
25118 "out vec4 gs_fs;\n"
25122 " vec4 result = tes_gs[0];\n"
25126 " gs_fs = result;\n"
25127 " gl_Position = vec4(-1, -1, 0, 1);\n"
25129 " gs_fs = result;\n"
25130 " gl_Position = vec4(-1, 1, 0, 1);\n"
25132 " gs_fs = result;\n"
25133 " gl_Position = vec4(1, -1, 0, 1);\n"
25135 " gs_fs = result;\n"
25136 " gl_Position = vec4(1, 1, 0, 1);\n"
25140 static const GLchar* tcs = "#version 430 core\n"
25141 "#extension GL_ARB_enhanced_layouts : require\n"
25143 "layout(vertices = 1) out;\n"
25145 "in vec4 vs_tcs[];\n"
25146 "out vec4 tcs_tes[];\n"
25151 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
25153 " gl_TessLevelOuter[0] = 1.0;\n"
25154 " gl_TessLevelOuter[1] = 1.0;\n"
25155 " gl_TessLevelOuter[2] = 1.0;\n"
25156 " gl_TessLevelOuter[3] = 1.0;\n"
25157 " gl_TessLevelInner[0] = 1.0;\n"
25158 " gl_TessLevelInner[1] = 1.0;\n"
25161 static const GLchar* tcs_tested = "#version 430 core\n"
25162 "#extension GL_ARB_enhanced_layouts : require\n"
25164 "layout(vertices = 1) out;\n"
25168 "in vec4 vs_tcs[];\n"
25169 "out vec4 tcs_tes[];\n"
25173 " vec4 result = vs_tcs[gl_InvocationID];\n"
25177 " tcs_tes[gl_InvocationID] = result;\n"
25179 " gl_TessLevelOuter[0] = 1.0;\n"
25180 " gl_TessLevelOuter[1] = 1.0;\n"
25181 " gl_TessLevelOuter[2] = 1.0;\n"
25182 " gl_TessLevelOuter[3] = 1.0;\n"
25183 " gl_TessLevelInner[0] = 1.0;\n"
25184 " gl_TessLevelInner[1] = 1.0;\n"
25187 static const GLchar* tes_tested = "#version 430 core\n"
25188 "#extension GL_ARB_enhanced_layouts : require\n"
25190 "layout(isolines, point_mode) in;\n"
25194 "in vec4 tcs_tes[];\n"
25195 "out vec4 tes_gs;\n"
25199 " vec4 result = tcs_tes[0];\n"
25203 " tes_gs += result;\n"
25206 static const GLchar* vs = "#version 430 core\n"
25207 "#extension GL_ARB_enhanced_layouts : require\n"
25210 "out vec4 vs_tcs;\n"
25214 " vs_tcs = in_vs;\n"
25217 static const GLchar* vs_tested = "#version 430 core\n"
25218 "#extension GL_ARB_enhanced_layouts : require\n"
25223 "out vec4 vs_tcs;\n"
25227 " vec4 result = in_vs;\n"
25231 " vs_tcs = result;\n"
25235 std::string source;
25236 testCase& test_case = m_test_cases[test_case_index];
25238 if (test_case.m_stage == stage)
25240 const GLchar* array = "";
25241 GLchar buffer_gohan[16];
25242 GLchar buffer_goten[16];
25243 const GLchar* index = "";
25244 size_t position = 0;
25245 size_t position_start = 0;
25246 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
25248 sprintf(buffer_gohan, "%d", test_case.m_offset_gohan);
25249 sprintf(buffer_goten, "%d", test_case.m_offset_goten);
25253 case Utils::Shader::GEOMETRY:
25254 source = gs_tested;
25258 case Utils::Shader::TESS_CTRL:
25259 source = tcs_tested;
25261 index = "[gl_InvocationID]";
25263 case Utils::Shader::TESS_EVAL:
25264 source = tes_tested;
25268 case Utils::Shader::VERTEX:
25269 source = vs_tested;
25272 TCU_FAIL("Invalid enum");
25275 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
25277 Utils::replaceToken("OFFSET", position, buffer_gohan, source);
25278 Utils::replaceToken("TYPE", position, type_name, source);
25279 Utils::replaceToken("ARRAY", position, array, source);
25280 Utils::replaceToken("OFFSET", position, buffer_goten, source);
25281 Utils::replaceToken("TYPE", position, type_name, source);
25282 Utils::replaceToken("ARRAY", position, array, source);
25283 position_start = position;
25284 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
25285 position = position_start;
25286 Utils::replaceToken("INDEX", position, index, source);
25287 Utils::replaceToken("TYPE", position, type_name, source);
25288 Utils::replaceToken("INDEX", position, index, source);
25289 Utils::replaceToken("TYPE", position, type_name, source);
25290 Utils::replaceToken("INDEX", position, index, source);
25291 Utils::replaceToken("TYPE", position, type_name, source);
25292 Utils::replaceToken("INDEX", position, index, source);
25293 Utils::replaceToken("TYPE", position, type_name, source);
25297 switch (test_case.m_stage)
25299 case Utils::Shader::GEOMETRY:
25302 case Utils::Shader::FRAGMENT:
25305 case Utils::Shader::VERTEX:
25312 case Utils::Shader::TESS_CTRL:
25315 case Utils::Shader::FRAGMENT:
25318 case Utils::Shader::VERTEX:
25325 case Utils::Shader::TESS_EVAL:
25328 case Utils::Shader::FRAGMENT:
25331 case Utils::Shader::TESS_CTRL:
25334 case Utils::Shader::VERTEX:
25341 case Utils::Shader::VERTEX:
25344 case Utils::Shader::FRAGMENT:
25352 TCU_FAIL("Invalid enum");
25360 /** Get description of test case
25362 * @param test_case_index Index of test case
25364 * @return Test case description
25366 std::string XFBOutputOverlappingTest::getTestCaseName(GLuint test_case_index)
25368 std::stringstream stream;
25369 testCase& test_case = m_test_cases[test_case_index];
25371 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
25372 << ", type: " << test_case.m_type.GetGLSLTypeName() << ", offsets: " << test_case.m_offset_gohan << " & "
25373 << test_case.m_offset_goten;
25375 return stream.str();
25378 /** Get number of test cases
25380 * @return Number of test cases
25382 GLuint XFBOutputOverlappingTest::getTestCaseNumber()
25384 return static_cast<GLuint>(m_test_cases.size());
25387 /** Selects if "compute" stage is relevant for test
25393 bool XFBOutputOverlappingTest::isComputeRelevant(GLuint /* test_case_index */)
25398 /** Prepare all test cases
25401 void XFBOutputOverlappingTest::testInit()
25403 const GLuint n_types = getTypesNumber();
25405 for (GLuint i = 0; i < n_types; ++i)
25407 const Utils::Type& type = getType(i);
25408 const GLuint base_alingment = Utils::Type::GetTypeSize(type.m_basic_type);
25410 /* Skip scalars, not applicable as:
25412 * The offset must be a multiple of the size of the first component of the first
25413 * qualified variable or block member, or a compile-time error results.
25415 if ((1 == type.m_n_columns) && (1 == type.m_n_rows))
25420 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
25422 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
25423 (Utils::Shader::FRAGMENT == stage))
25428 testCase test_case = { 0 /* gohan offset */, base_alingment /* goten_offset */,
25429 (Utils::Shader::STAGES)stage, type };
25431 m_test_cases.push_back(test_case);
25438 * @param context Test framework context
25440 XFBInvalidOffsetAlignmentTest::XFBInvalidOffsetAlignmentTest(deqp::Context& context)
25441 : NegativeTestBase(context, "xfb_invalid_offset_alignment",
25442 "Test verifies that compiler reports error when xfb_offset has invalid alignment")
25446 /** Source for given test case and stage
25448 * @param test_case_index Index of test case
25449 * @param stage Shader stage
25451 * @return Shader source
25453 std::string XFBInvalidOffsetAlignmentTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
25455 static const GLchar* var_definition = "layout (xfb_offset = OFFSET) out TYPE gohanARRAY;\n";
25456 static const GLchar* var_use = " gohanINDEX = TYPE(0);\n"
25457 " if (vec4(0) == result)\n"
25459 " gohanINDEX = TYPE(1);\n"
25461 static const GLchar* fs = "#version 430 core\n"
25462 "#extension GL_ARB_enhanced_layouts : require\n"
25465 "out vec4 fs_out;\n"
25469 " fs_out = gs_fs;\n"
25472 static const GLchar* gs_tested = "#version 430 core\n"
25473 "#extension GL_ARB_enhanced_layouts : require\n"
25475 "layout(points) in;\n"
25476 "layout(triangle_strip, max_vertices = 4) out;\n"
25480 "in vec4 tes_gs[];\n"
25481 "out vec4 gs_fs;\n"
25485 " vec4 result = tes_gs[0];\n"
25489 " gs_fs = result;\n"
25490 " gl_Position = vec4(-1, -1, 0, 1);\n"
25492 " gs_fs = result;\n"
25493 " gl_Position = vec4(-1, 1, 0, 1);\n"
25495 " gs_fs = result;\n"
25496 " gl_Position = vec4(1, -1, 0, 1);\n"
25498 " gs_fs = result;\n"
25499 " gl_Position = vec4(1, 1, 0, 1);\n"
25503 static const GLchar* tcs = "#version 430 core\n"
25504 "#extension GL_ARB_enhanced_layouts : require\n"
25506 "layout(vertices = 1) out;\n"
25508 "in vec4 vs_tcs[];\n"
25509 "out vec4 tcs_tes[];\n"
25514 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
25516 " gl_TessLevelOuter[0] = 1.0;\n"
25517 " gl_TessLevelOuter[1] = 1.0;\n"
25518 " gl_TessLevelOuter[2] = 1.0;\n"
25519 " gl_TessLevelOuter[3] = 1.0;\n"
25520 " gl_TessLevelInner[0] = 1.0;\n"
25521 " gl_TessLevelInner[1] = 1.0;\n"
25524 static const GLchar* tcs_tested = "#version 430 core\n"
25525 "#extension GL_ARB_enhanced_layouts : require\n"
25527 "layout(vertices = 1) out;\n"
25531 "in vec4 vs_tcs[];\n"
25532 "out vec4 tcs_tes[];\n"
25536 " vec4 result = vs_tcs[gl_InvocationID];\n"
25540 " tcs_tes[gl_InvocationID] = result;\n"
25542 " gl_TessLevelOuter[0] = 1.0;\n"
25543 " gl_TessLevelOuter[1] = 1.0;\n"
25544 " gl_TessLevelOuter[2] = 1.0;\n"
25545 " gl_TessLevelOuter[3] = 1.0;\n"
25546 " gl_TessLevelInner[0] = 1.0;\n"
25547 " gl_TessLevelInner[1] = 1.0;\n"
25550 static const GLchar* tes_tested = "#version 430 core\n"
25551 "#extension GL_ARB_enhanced_layouts : require\n"
25553 "layout(isolines, point_mode) in;\n"
25557 "in vec4 tcs_tes[];\n"
25558 "out vec4 tes_gs;\n"
25562 " vec4 result = tcs_tes[0];\n"
25566 " tes_gs += result;\n"
25569 static const GLchar* vs = "#version 430 core\n"
25570 "#extension GL_ARB_enhanced_layouts : require\n"
25573 "out vec4 vs_tcs;\n"
25577 " vs_tcs = in_vs;\n"
25580 static const GLchar* vs_tested = "#version 430 core\n"
25581 "#extension GL_ARB_enhanced_layouts : require\n"
25586 "out vec4 vs_tcs;\n"
25590 " vec4 result = in_vs;\n"
25594 " vs_tcs = result;\n"
25598 std::string source;
25599 testCase& test_case = m_test_cases[test_case_index];
25601 if (test_case.m_stage == stage)
25603 const GLchar* array = "";
25605 const GLchar* index = "";
25606 size_t position = 0;
25607 size_t position_start = 0;
25608 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
25610 sprintf(buffer, "%d", test_case.m_offset);
25614 case Utils::Shader::GEOMETRY:
25615 source = gs_tested;
25619 case Utils::Shader::TESS_CTRL:
25620 source = tcs_tested;
25622 index = "[gl_InvocationID]";
25624 case Utils::Shader::TESS_EVAL:
25625 source = tes_tested;
25629 case Utils::Shader::VERTEX:
25630 source = vs_tested;
25633 TCU_FAIL("Invalid enum");
25636 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
25638 Utils::replaceToken("OFFSET", position, buffer, source);
25639 Utils::replaceToken("TYPE", position, type_name, source);
25640 Utils::replaceToken("ARRAY", position, array, source);
25641 position_start = position;
25642 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
25643 position = position_start;
25644 Utils::replaceToken("INDEX", position, index, source);
25645 Utils::replaceToken("TYPE", position, type_name, source);
25646 Utils::replaceToken("INDEX", position, index, source);
25647 Utils::replaceToken("TYPE", position, type_name, source);
25651 switch (test_case.m_stage)
25653 case Utils::Shader::GEOMETRY:
25656 case Utils::Shader::FRAGMENT:
25659 case Utils::Shader::VERTEX:
25666 case Utils::Shader::TESS_CTRL:
25669 case Utils::Shader::FRAGMENT:
25672 case Utils::Shader::VERTEX:
25679 case Utils::Shader::TESS_EVAL:
25682 case Utils::Shader::FRAGMENT:
25685 case Utils::Shader::TESS_CTRL:
25688 case Utils::Shader::VERTEX:
25695 case Utils::Shader::VERTEX:
25698 case Utils::Shader::FRAGMENT:
25706 TCU_FAIL("Invalid enum");
25714 /** Get description of test case
25716 * @param test_case_index Index of test case
25718 * @return Test case description
25720 std::string XFBInvalidOffsetAlignmentTest::getTestCaseName(GLuint test_case_index)
25722 std::stringstream stream;
25723 testCase& test_case = m_test_cases[test_case_index];
25725 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
25726 << ", type: " << test_case.m_type.GetGLSLTypeName() << ", offset: " << test_case.m_offset;
25728 return stream.str();
25731 /** Get number of test cases
25733 * @return Number of test cases
25735 GLuint XFBInvalidOffsetAlignmentTest::getTestCaseNumber()
25737 return static_cast<GLuint>(m_test_cases.size());
25740 /** Selects if "compute" stage is relevant for test
25746 bool XFBInvalidOffsetAlignmentTest::isComputeRelevant(GLuint /* test_case_index */)
25751 /** Prepare all test cases
25754 void XFBInvalidOffsetAlignmentTest::testInit()
25756 const GLuint n_types = getTypesNumber();
25758 for (GLuint i = 0; i < n_types; ++i)
25760 const Utils::Type& type = getType(i);
25761 const GLuint base_alingment = Utils::Type::GetTypeSize(type.m_basic_type);
25763 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
25765 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
25766 (Utils::Shader::FRAGMENT == stage))
25771 for (GLuint offset = base_alingment + 1; offset < 2 * base_alingment; ++offset)
25773 testCase test_case = { offset, (Utils::Shader::STAGES)stage, type };
25775 m_test_cases.push_back(test_case);
25783 * @param context Test context
25785 XFBCaptureInactiveOutputVariableTest::XFBCaptureInactiveOutputVariableTest(deqp::Context& context)
25786 : BufferTestBase(context, "xfb_capture_inactive_output_variable",
25787 "Test verifies that inactive variables are captured")
25789 /* Nothing to be done here */
25792 /** Execute drawArrays for single vertex
25794 * @param test_case_index
25798 bool XFBCaptureInactiveOutputVariableTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
25800 const Functions& gl = m_context.getRenderContext().getFunctions();
25801 GLenum primitive_type = GL_PATCHES;
25803 if (TEST_VS == test_case_index)
25805 primitive_type = GL_POINTS;
25808 gl.disable(GL_RASTERIZER_DISCARD);
25809 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
25811 gl.beginTransformFeedback(GL_POINTS);
25812 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
25814 gl.drawArrays(primitive_type, 0 /* first */, 1 /* count */);
25815 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
25817 gl.endTransformFeedback();
25818 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
25823 /** Get descriptors of buffers necessary for test
25826 * @param out_descriptors Descriptors of buffers used by test
25828 void XFBCaptureInactiveOutputVariableTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
25829 bufferDescriptor::Vector& out_descriptors)
25831 const Utils::Type& type = Utils::Type::vec4;
25833 /* Test needs single uniform and xfb */
25834 out_descriptors.resize(2);
25836 /* Get references */
25837 bufferDescriptor& uniform = out_descriptors[0];
25838 bufferDescriptor& xfb = out_descriptors[1];
25841 uniform.m_index = 0;
25845 uniform.m_target = Utils::Buffer::Uniform;
25846 xfb.m_target = Utils::Buffer::Transform_feedback;
25849 const std::vector<GLubyte>& gohan_data = type.GenerateData();
25850 const std::vector<GLubyte>& goten_data = type.GenerateData();
25852 const GLuint type_size = static_cast<GLuint>(gohan_data.size());
25855 uniform.m_initial_data.resize(2 * type_size);
25856 memcpy(&uniform.m_initial_data[0] + 0, &gohan_data[0], type_size);
25857 memcpy(&uniform.m_initial_data[0] + type_size, &goten_data[0], type_size);
25860 xfb.m_initial_data.resize(3 * type_size);
25861 xfb.m_expected_data.resize(3 * type_size);
25863 for (GLuint i = 0; i < 3 * type_size; ++i)
25865 xfb.m_initial_data[i] = (glw::GLubyte)i;
25866 xfb.m_expected_data[i] = (glw::GLubyte)i;
25869 memcpy(&xfb.m_expected_data[0] + 2 * type_size, &gohan_data[0], type_size);
25870 memcpy(&xfb.m_expected_data[0] + 0 * type_size, &goten_data[0], type_size);
25873 /** Get body of main function for given shader stage
25875 * @param test_case_index Index of test case
25876 * @param stage Shader stage
25877 * @param out_assignments Set to empty
25878 * @param out_calculations Set to empty
25880 void XFBCaptureInactiveOutputVariableTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
25881 std::string& out_assignments, std::string& out_calculations)
25883 out_calculations = "";
25885 static const GLchar* vs_tes_gs = " goten = uni_goten;\n"
25886 " gohan = uni_gohan;\n";
25887 static const GLchar* fs = " fs_out = goku + gohan + goten;\n";
25889 const GLchar* assignments = "";
25893 case Utils::Shader::FRAGMENT:
25897 case Utils::Shader::GEOMETRY:
25898 if (TEST_GS == test_case_index)
25900 assignments = vs_tes_gs;
25904 case Utils::Shader::TESS_CTRL:
25907 case Utils::Shader::TESS_EVAL:
25908 if (TEST_TES == test_case_index)
25910 assignments = vs_tes_gs;
25914 case Utils::Shader::VERTEX:
25915 if (TEST_VS == test_case_index)
25917 assignments = vs_tes_gs;
25922 TCU_FAIL("Invalid enum");
25925 out_assignments = assignments;
25928 /** Get interface of shader
25930 * @param test_case_index Index of test case
25931 * @param stage Shader stage
25932 * @param out_interface Set to ""
25934 void XFBCaptureInactiveOutputVariableTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
25935 std::string& out_interface)
25937 static const GLchar* vs_tes_gs = "const uint sizeof_type = 16;\n"
25939 "layout (xfb_offset = 1 * sizeof_type) out vec4 goku;\n"
25940 "layout (xfb_offset = 2 * sizeof_type) out vec4 gohan;\n"
25941 "layout (xfb_offset = 0 * sizeof_type) out vec4 goten;\n"
25943 "layout(binding = 0) uniform block {\n"
25944 " vec4 uni_gohan;\n"
25945 " vec4 uni_goten;\n"
25947 static const GLchar* fs = "in vec4 goku;\n"
25950 "out vec4 fs_out;\n";
25952 const GLchar* interface = "";
25956 case Utils::Shader::FRAGMENT:
25960 case Utils::Shader::GEOMETRY:
25961 if (TEST_GS == test_case_index)
25963 interface = vs_tes_gs;
25967 case Utils::Shader::TESS_CTRL:
25970 case Utils::Shader::TESS_EVAL:
25971 if (TEST_TES == test_case_index)
25973 interface = vs_tes_gs;
25977 case Utils::Shader::VERTEX:
25978 if (TEST_VS == test_case_index)
25980 interface = vs_tes_gs;
25985 TCU_FAIL("Invalid enum");
25988 out_interface = interface;
25991 /** Get source code of shader
25993 * @param test_case_index Index of test case
25994 * @param stage Shader stage
25998 std::string XFBCaptureInactiveOutputVariableTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
26000 std::string source;
26002 switch (test_case_index)
26007 case Utils::Shader::FRAGMENT:
26008 case Utils::Shader::VERTEX:
26009 source = BufferTestBase::getShaderSource(test_case_index, stage);
26019 case Utils::Shader::FRAGMENT:
26020 case Utils::Shader::TESS_CTRL:
26021 case Utils::Shader::TESS_EVAL:
26022 case Utils::Shader::VERTEX:
26023 source = BufferTestBase::getShaderSource(test_case_index, stage);
26031 source = BufferTestBase::getShaderSource(test_case_index, stage);
26035 TCU_FAIL("Invalid enum");
26043 /** Get name of test case
26045 * @param test_case_index Index of test case
26047 * @return Name of tested stage
26049 std::string XFBCaptureInactiveOutputVariableTest::getTestCaseName(glw::GLuint test_case_index)
26051 const GLchar* name = 0;
26053 switch (test_case_index)
26059 name = "tessellation evaluation";
26065 TCU_FAIL("Invalid enum");
26071 /** Returns number of test cases
26075 glw::GLuint XFBCaptureInactiveOutputVariableTest::getTestCaseNumber()
26080 /** Inspects program to check if all resources are as expected
26083 * @param program Program instance
26084 * @param out_stream Error message
26086 * @return true if everything is ok, false otherwise
26088 bool XFBCaptureInactiveOutputVariableTest::inspectProgram(GLuint /* test_case_index */, Utils::Program& program,
26089 std::stringstream& out_stream)
26092 const Utils::Type& type = Utils::Type::vec4;
26093 const GLuint type_size = type.GetSize();
26095 program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE,
26096 1 /* buf_size */, &stride);
26098 if ((GLint)(3 * type_size) != stride)
26100 out_stream << "Stride is: " << stride << " expected: " << (3 * type_size);
26108 /** Verify contents of buffers
26110 * @param buffers Collection of buffers to be verified
26112 * @return true if everything is as expected, false otherwise
26114 bool XFBCaptureInactiveOutputVariableTest::verifyBuffers(bufferCollection& buffers)
26116 bool result = true;
26118 bufferCollection::pair& pair = buffers.m_vector[1] /* xfb */;
26119 Utils::Buffer* buffer = pair.m_buffer;
26120 bufferDescriptor* descriptor = pair.m_descriptor;
26122 /* Get pointer to contents of buffer */
26124 GLubyte* buffer_data = (GLubyte*)buffer->Map(Utils::Buffer::ReadOnly);
26126 /* Get pointer to expected data */
26127 GLubyte* expected_data = (GLubyte*)&descriptor->m_expected_data[0];
26130 static const GLuint vec4_size = 16;
26132 int res_gohan = memcmp(buffer_data + 2 * vec4_size, expected_data + 2 * vec4_size, vec4_size);
26133 int res_goten = memcmp(buffer_data + 0 * vec4_size, expected_data + 0 * vec4_size, vec4_size);
26135 if ((0 != res_gohan) || (0 != res_goten))
26137 m_context.getTestContext().getLog()
26138 << tcu::TestLog::Message << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
26139 << ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
26144 /* Release buffer mapping */
26152 * @param context Test context
26154 XFBCaptureInactiveOutputComponentTest::XFBCaptureInactiveOutputComponentTest(deqp::Context& context)
26155 : BufferTestBase(context, "xfb_capture_inactive_output_component",
26156 "Test verifies that inactive components are not modified")
26158 /* Nothing to be done here */
26161 /** Execute drawArrays for single vertex
26163 * @param test_case_index
26167 bool XFBCaptureInactiveOutputComponentTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
26169 const Functions& gl = m_context.getRenderContext().getFunctions();
26170 GLenum primitive_type = GL_PATCHES;
26172 if (TEST_VS == test_case_index)
26174 primitive_type = GL_POINTS;
26177 gl.disable(GL_RASTERIZER_DISCARD);
26178 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
26180 gl.beginTransformFeedback(GL_POINTS);
26181 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
26183 gl.drawArrays(primitive_type, 0 /* first */, 1 /* count */);
26184 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
26186 gl.endTransformFeedback();
26187 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
26192 /** Get descriptors of buffers necessary for test
26195 * @param out_descriptors Descriptors of buffers used by test
26197 void XFBCaptureInactiveOutputComponentTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
26198 bufferDescriptor::Vector& out_descriptors)
26200 const Utils::Type& type = Utils::Type::vec4;
26202 /* Test needs single uniform and xfb */
26203 out_descriptors.resize(2);
26205 /* Get references */
26206 bufferDescriptor& uniform = out_descriptors[0];
26207 bufferDescriptor& xfb = out_descriptors[1];
26210 uniform.m_index = 0;
26214 uniform.m_target = Utils::Buffer::Uniform;
26215 xfb.m_target = Utils::Buffer::Transform_feedback;
26218 const std::vector<GLubyte>& goku_data = type.GenerateData();
26219 const std::vector<GLubyte>& gohan_data = type.GenerateData();
26220 const std::vector<GLubyte>& goten_data = type.GenerateData();
26221 const std::vector<GLubyte>& chichi_data = type.GenerateData();
26222 const std::vector<GLubyte>& vegeta_data = type.GenerateData();
26223 const std::vector<GLubyte>& trunks_data = type.GenerateData();
26224 const std::vector<GLubyte>& bra_data = type.GenerateData();
26225 const std::vector<GLubyte>& bulma_data = type.GenerateData();
26227 const GLuint comp_size = Utils::Type::GetTypeSize(type.m_basic_type);
26228 const GLuint type_size = static_cast<GLuint>(gohan_data.size());
26231 uniform.m_initial_data.resize(8 * type_size);
26232 memcpy(&uniform.m_initial_data[0] + 0 * type_size, &goku_data[0], type_size);
26233 memcpy(&uniform.m_initial_data[0] + 1 * type_size, &gohan_data[0], type_size);
26234 memcpy(&uniform.m_initial_data[0] + 2 * type_size, &goten_data[0], type_size);
26235 memcpy(&uniform.m_initial_data[0] + 3 * type_size, &chichi_data[0], type_size);
26236 memcpy(&uniform.m_initial_data[0] + 4 * type_size, &vegeta_data[0], type_size);
26237 memcpy(&uniform.m_initial_data[0] + 5 * type_size, &trunks_data[0], type_size);
26238 memcpy(&uniform.m_initial_data[0] + 6 * type_size, &bra_data[0], type_size);
26239 memcpy(&uniform.m_initial_data[0] + 7 * type_size, &bulma_data[0], type_size);
26242 xfb.m_initial_data.resize(8 * type_size);
26243 xfb.m_expected_data.resize(8 * type_size);
26245 for (GLuint i = 0; i < 8 * type_size; ++i)
26247 xfb.m_initial_data[i] = (glw::GLubyte)i;
26248 xfb.m_expected_data[i] = (glw::GLubyte)i;
26251 /* goku - x, z - 32 */
26252 memcpy(&xfb.m_expected_data[0] + 2 * type_size + 0 * comp_size, &goku_data[0] + 0 * comp_size, comp_size);
26253 memcpy(&xfb.m_expected_data[0] + 2 * type_size + 2 * comp_size, &goku_data[0] + 2 * comp_size, comp_size);
26255 /* gohan - y, w - 0 */
26256 memcpy(&xfb.m_expected_data[0] + 0 * type_size + 1 * comp_size, &gohan_data[0] + 1 * comp_size, comp_size);
26257 memcpy(&xfb.m_expected_data[0] + 0 * type_size + 3 * comp_size, &gohan_data[0] + 3 * comp_size, comp_size);
26259 /* goten - x, y - 16 */
26260 memcpy(&xfb.m_expected_data[0] + 1 * type_size + 0 * comp_size, &goten_data[0] + 0 * comp_size, comp_size);
26261 memcpy(&xfb.m_expected_data[0] + 1 * type_size + 1 * comp_size, &goten_data[0] + 1 * comp_size, comp_size);
26263 /* chichi - z, w - 48 */
26264 memcpy(&xfb.m_expected_data[0] + 3 * type_size + 2 * comp_size, &chichi_data[0] + 2 * comp_size, comp_size);
26265 memcpy(&xfb.m_expected_data[0] + 3 * type_size + 3 * comp_size, &chichi_data[0] + 3 * comp_size, comp_size);
26267 /* vegeta - x - 112 */
26268 memcpy(&xfb.m_expected_data[0] + 7 * type_size + 0 * comp_size, &vegeta_data[0] + 0 * comp_size, comp_size);
26270 /* trunks - y - 96 */
26271 memcpy(&xfb.m_expected_data[0] + 6 * type_size + 1 * comp_size, &trunks_data[0] + 1 * comp_size, comp_size);
26274 memcpy(&xfb.m_expected_data[0] + 5 * type_size + 2 * comp_size, &bra_data[0] + 2 * comp_size, comp_size);
26276 /* bulma - w - 64 */
26277 memcpy(&xfb.m_expected_data[0] + 4 * type_size + 3 * comp_size, &bulma_data[0] + 3 * comp_size, comp_size);
26280 /** Get body of main function for given shader stage
26282 * @param test_case_index Index of test case
26283 * @param stage Shader stage
26284 * @param out_assignments Set to empty
26285 * @param out_calculations Set to empty
26287 void XFBCaptureInactiveOutputComponentTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
26288 std::string& out_assignments, std::string& out_calculations)
26290 out_calculations = "";
26292 static const GLchar* vs_tes_gs = " goku.x = uni_goku.x ;\n"
26293 " goku.z = uni_goku.z ;\n"
26294 " gohan.y = uni_gohan.y ;\n"
26295 " gohan.w = uni_gohan.w ;\n"
26296 " goten.x = uni_goten.x ;\n"
26297 " goten.y = uni_goten.y ;\n"
26298 " chichi.z = uni_chichi.z ;\n"
26299 " chichi.w = uni_chichi.w ;\n"
26300 " vegeta.x = uni_vegeta.x ;\n"
26301 " trunks.y = uni_trunks.y ;\n"
26302 " bra.z = uni_bra.z ;\n"
26303 " bulma.w = uni_bulma.w ;\n";
26304 static const GLchar* fs = " fs_out = goku + gohan + goten + chichi + vegeta + trunks + bra + bulma;\n";
26306 const GLchar* assignments = "";
26310 case Utils::Shader::FRAGMENT:
26314 case Utils::Shader::GEOMETRY:
26315 if (TEST_GS == test_case_index)
26317 assignments = vs_tes_gs;
26321 case Utils::Shader::TESS_CTRL:
26324 case Utils::Shader::TESS_EVAL:
26325 if (TEST_TES == test_case_index)
26327 assignments = vs_tes_gs;
26331 case Utils::Shader::VERTEX:
26332 if (TEST_VS == test_case_index)
26334 assignments = vs_tes_gs;
26339 TCU_FAIL("Invalid enum");
26342 out_assignments = assignments;
26345 /** Get interface of shader
26347 * @param test_case_index Index of test case
26348 * @param stage Shader stage
26349 * @param out_interface Set to ""
26351 void XFBCaptureInactiveOutputComponentTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
26352 std::string& out_interface)
26354 static const GLchar* vs_tes_gs = "const uint sizeof_type = 16;\n"
26356 "layout (xfb_offset = 2 * sizeof_type) out vec4 goku;\n"
26357 "layout (xfb_offset = 0 * sizeof_type) out vec4 gohan;\n"
26358 "layout (xfb_offset = 1 * sizeof_type) out vec4 goten;\n"
26359 "layout (xfb_offset = 3 * sizeof_type) out vec4 chichi;\n"
26360 "layout (xfb_offset = 7 * sizeof_type) out vec4 vegeta;\n"
26361 "layout (xfb_offset = 6 * sizeof_type) out vec4 trunks;\n"
26362 "layout (xfb_offset = 5 * sizeof_type) out vec4 bra;\n"
26363 "layout (xfb_offset = 4 * sizeof_type) out vec4 bulma;\n"
26365 "layout(binding = 0) uniform block {\n"
26366 " vec4 uni_goku;\n"
26367 " vec4 uni_gohan;\n"
26368 " vec4 uni_goten;\n"
26369 " vec4 uni_chichi;\n"
26370 " vec4 uni_vegeta;\n"
26371 " vec4 uni_trunks;\n"
26373 " vec4 uni_bulma;\n"
26375 static const GLchar* fs = "in vec4 vegeta;\n"
26376 "in vec4 trunks;\n"
26382 "in vec4 chichi;\n"
26384 "out vec4 fs_out;\n";
26386 const GLchar* interface = "";
26390 case Utils::Shader::FRAGMENT:
26394 case Utils::Shader::GEOMETRY:
26395 if (TEST_GS == test_case_index)
26397 interface = vs_tes_gs;
26401 case Utils::Shader::TESS_CTRL:
26404 case Utils::Shader::TESS_EVAL:
26405 if (TEST_TES == test_case_index)
26407 interface = vs_tes_gs;
26411 case Utils::Shader::VERTEX:
26412 if (TEST_VS == test_case_index)
26414 interface = vs_tes_gs;
26419 TCU_FAIL("Invalid enum");
26422 out_interface = interface;
26425 /** Get source code of shader
26427 * @param test_case_index Index of test case
26428 * @param stage Shader stage
26432 std::string XFBCaptureInactiveOutputComponentTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
26434 std::string source;
26436 switch (test_case_index)
26441 case Utils::Shader::FRAGMENT:
26442 case Utils::Shader::VERTEX:
26443 source = BufferTestBase::getShaderSource(test_case_index, stage);
26453 case Utils::Shader::FRAGMENT:
26454 case Utils::Shader::TESS_CTRL:
26455 case Utils::Shader::TESS_EVAL:
26456 case Utils::Shader::VERTEX:
26457 source = BufferTestBase::getShaderSource(test_case_index, stage);
26465 source = BufferTestBase::getShaderSource(test_case_index, stage);
26469 TCU_FAIL("Invalid enum");
26477 /** Get name of test case
26479 * @param test_case_index Index of test case
26481 * @return Name of tested stage
26483 std::string XFBCaptureInactiveOutputComponentTest::getTestCaseName(glw::GLuint test_case_index)
26485 const GLchar* name = 0;
26487 switch (test_case_index)
26493 name = "tessellation evaluation";
26499 TCU_FAIL("Invalid enum");
26505 /** Returns number of test cases
26509 glw::GLuint XFBCaptureInactiveOutputComponentTest::getTestCaseNumber()
26514 /** Verify contents of buffers
26516 * @param buffers Collection of buffers to be verified
26518 * @return true if everything is as expected, false otherwise
26520 bool XFBCaptureInactiveOutputComponentTest::verifyBuffers(bufferCollection& buffers)
26522 bool result = true;
26524 bufferCollection::pair& pair = buffers.m_vector[1] /* xfb */;
26525 Utils::Buffer* buffer = pair.m_buffer;
26526 bufferDescriptor* descriptor = pair.m_descriptor;
26528 /* Get pointer to contents of buffer */
26530 GLubyte* buffer_data = (GLubyte*)buffer->Map(Utils::Buffer::ReadOnly);
26532 /* Get pointer to expected data */
26533 GLubyte* expected_data = (GLubyte*)&descriptor->m_expected_data[0];
26536 static const GLuint comp_size = 4;
26537 static const GLuint vec4_size = 16;
26540 memcmp(buffer_data + 2 * vec4_size + 0 * comp_size, expected_data + 2 * vec4_size + 0 * comp_size, comp_size);
26542 memcmp(buffer_data + 2 * vec4_size + 2 * comp_size, expected_data + 2 * vec4_size + 2 * comp_size, comp_size);
26545 memcmp(buffer_data + 0 * vec4_size + 1 * comp_size, expected_data + 0 * vec4_size + 1 * comp_size, comp_size);
26547 memcmp(buffer_data + 0 * vec4_size + 3 * comp_size, expected_data + 0 * vec4_size + 3 * comp_size, comp_size);
26550 memcmp(buffer_data + 1 * vec4_size + 0 * comp_size, expected_data + 1 * vec4_size + 0 * comp_size, comp_size);
26552 memcmp(buffer_data + 1 * vec4_size + 1 * comp_size, expected_data + 1 * vec4_size + 1 * comp_size, comp_size);
26555 memcmp(buffer_data + 3 * vec4_size + 2 * comp_size, expected_data + 3 * vec4_size + 2 * comp_size, comp_size);
26557 memcmp(buffer_data + 3 * vec4_size + 3 * comp_size, expected_data + 3 * vec4_size + 3 * comp_size, comp_size);
26560 memcmp(buffer_data + 7 * vec4_size + 0 * comp_size, expected_data + 7 * vec4_size + 0 * comp_size, comp_size);
26563 memcmp(buffer_data + 6 * vec4_size + 1 * comp_size, expected_data + 6 * vec4_size + 1 * comp_size, comp_size);
26566 memcmp(buffer_data + 5 * vec4_size + 2 * comp_size, expected_data + 5 * vec4_size + 2 * comp_size, comp_size);
26569 memcmp(buffer_data + 4 * vec4_size + 3 * comp_size, expected_data + 4 * vec4_size + 3 * comp_size, comp_size);
26571 if ((0 != res_goku_x) || (0 != res_goku_z) || (0 != res_gohan_y) || (0 != res_gohan_w) || (0 != res_goten_x) ||
26572 (0 != res_goten_y) || (0 != res_chichi_z) || (0 != res_chichi_w) || (0 != res_vegeta_x) ||
26573 (0 != res_trunks_y) || (0 != res_bra_z) || (0 != res_bulma_w))
26575 m_context.getTestContext().getLog()
26576 << tcu::TestLog::Message << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
26577 << ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
26582 /* Release buffer mapping */
26590 * @param context Test context
26592 XFBCaptureInactiveOutputBlockMemberTest::XFBCaptureInactiveOutputBlockMemberTest(deqp::Context& context)
26593 : BufferTestBase(context, "xfb_capture_inactive_output_block_member",
26594 "Test verifies that inactive block members are captured")
26596 /* Nothing to be done here */
26599 /** Execute drawArrays for single vertex
26601 * @param test_case_index
26605 bool XFBCaptureInactiveOutputBlockMemberTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
26607 const Functions& gl = m_context.getRenderContext().getFunctions();
26608 GLenum primitive_type = GL_PATCHES;
26610 if (TEST_VS == test_case_index)
26612 primitive_type = GL_POINTS;
26615 gl.disable(GL_RASTERIZER_DISCARD);
26616 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
26618 gl.beginTransformFeedback(GL_POINTS);
26619 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
26621 gl.drawArrays(primitive_type, 0 /* first */, 1 /* count */);
26622 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
26624 gl.endTransformFeedback();
26625 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
26630 /** Get descriptors of buffers necessary for test
26633 * @param out_descriptors Descriptors of buffers used by test
26635 void XFBCaptureInactiveOutputBlockMemberTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
26636 bufferDescriptor::Vector& out_descriptors)
26638 const Utils::Type& type = Utils::Type::vec4;
26640 /* Test needs single uniform and xfb */
26641 out_descriptors.resize(2);
26643 /* Get references */
26644 bufferDescriptor& uniform = out_descriptors[0];
26645 bufferDescriptor& xfb = out_descriptors[1];
26648 uniform.m_index = 0;
26652 uniform.m_target = Utils::Buffer::Uniform;
26653 xfb.m_target = Utils::Buffer::Transform_feedback;
26656 const std::vector<GLubyte>& gohan_data = type.GenerateData();
26657 const std::vector<GLubyte>& chichi_data = type.GenerateData();
26659 const GLuint type_size = static_cast<GLuint>(gohan_data.size());
26662 uniform.m_initial_data.resize(2 * type_size);
26663 memcpy(&uniform.m_initial_data[0] + 0, &gohan_data[0], type_size);
26664 memcpy(&uniform.m_initial_data[0] + type_size, &chichi_data[0], type_size);
26667 xfb.m_initial_data.resize(4 * type_size);
26668 xfb.m_expected_data.resize(4 * type_size);
26670 for (GLuint i = 0; i < 4 * type_size; ++i)
26672 xfb.m_initial_data[i] = (glw::GLubyte)i;
26673 xfb.m_expected_data[i] = (glw::GLubyte)i;
26676 memcpy(&xfb.m_expected_data[0] + 1 * type_size, &gohan_data[0], type_size);
26677 memcpy(&xfb.m_expected_data[0] + 3 * type_size, &chichi_data[0], type_size);
26680 /** Get body of main function for given shader stage
26682 * @param test_case_index Index of test case
26683 * @param stage Shader stage
26684 * @param out_assignments Set to empty
26685 * @param out_calculations Set to empty
26687 void XFBCaptureInactiveOutputBlockMemberTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
26688 std::string& out_assignments, std::string& out_calculations)
26690 out_calculations = "";
26692 static const GLchar* vs_tes_gs = " chichi = uni_chichi;\n"
26693 " gohan = uni_gohan;\n";
26694 static const GLchar* fs = " fs_out = goten + gohan + chichi;\n";
26696 const GLchar* assignments = "";
26700 case Utils::Shader::FRAGMENT:
26704 case Utils::Shader::GEOMETRY:
26705 if (TEST_GS == test_case_index)
26707 assignments = vs_tes_gs;
26711 case Utils::Shader::TESS_CTRL:
26714 case Utils::Shader::TESS_EVAL:
26715 if (TEST_TES == test_case_index)
26717 assignments = vs_tes_gs;
26721 case Utils::Shader::VERTEX:
26722 if (TEST_VS == test_case_index)
26724 assignments = vs_tes_gs;
26729 TCU_FAIL("Invalid enum");
26732 out_assignments = assignments;
26735 /** Get interface of shader
26737 * @param test_case_index Index of test case
26738 * @param stage Shader stage
26739 * @param out_interface Set to ""
26741 void XFBCaptureInactiveOutputBlockMemberTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
26742 std::string& out_interface)
26744 static const GLchar* vs_tes_gs = "const uint sizeof_type = 16;\n"
26746 "layout (xfb_offset = 1 * sizeof_type) out Goku {\n"
26752 "layout(binding = 0) uniform block {\n"
26753 " vec4 uni_gohan;\n"
26754 " vec4 uni_chichi;\n"
26756 static const GLchar* fs = "in Goku {\n"
26761 "out vec4 fs_out;\n";
26763 const GLchar* interface = "";
26767 case Utils::Shader::FRAGMENT:
26771 case Utils::Shader::GEOMETRY:
26772 if (TEST_GS == test_case_index)
26774 interface = vs_tes_gs;
26778 case Utils::Shader::TESS_CTRL:
26781 case Utils::Shader::TESS_EVAL:
26782 if (TEST_TES == test_case_index)
26784 interface = vs_tes_gs;
26788 case Utils::Shader::VERTEX:
26789 if (TEST_VS == test_case_index)
26791 interface = vs_tes_gs;
26796 TCU_FAIL("Invalid enum");
26799 out_interface = interface;
26802 /** Get source code of shader
26804 * @param test_case_index Index of test case
26805 * @param stage Shader stage
26809 std::string XFBCaptureInactiveOutputBlockMemberTest::getShaderSource(GLuint test_case_index,
26810 Utils::Shader::STAGES stage)
26812 std::string source;
26814 switch (test_case_index)
26819 case Utils::Shader::FRAGMENT:
26820 case Utils::Shader::VERTEX:
26821 source = BufferTestBase::getShaderSource(test_case_index, stage);
26831 case Utils::Shader::FRAGMENT:
26832 case Utils::Shader::TESS_CTRL:
26833 case Utils::Shader::TESS_EVAL:
26834 case Utils::Shader::VERTEX:
26835 source = BufferTestBase::getShaderSource(test_case_index, stage);
26843 source = BufferTestBase::getShaderSource(test_case_index, stage);
26847 TCU_FAIL("Invalid enum");
26855 /** Get name of test case
26857 * @param test_case_index Index of test case
26859 * @return Name of tested stage
26861 std::string XFBCaptureInactiveOutputBlockMemberTest::getTestCaseName(glw::GLuint test_case_index)
26863 const GLchar* name = 0;
26865 switch (test_case_index)
26871 name = "tessellation evaluation";
26877 TCU_FAIL("Invalid enum");
26883 /** Returns number of test cases
26887 glw::GLuint XFBCaptureInactiveOutputBlockMemberTest::getTestCaseNumber()
26892 /** Verify contents of buffers
26894 * @param buffers Collection of buffers to be verified
26896 * @return true if everything is as expected, false otherwise
26898 bool XFBCaptureInactiveOutputBlockMemberTest::verifyBuffers(bufferCollection& buffers)
26900 bool result = true;
26902 bufferCollection::pair& pair = buffers.m_vector[1] /* xfb */;
26903 Utils::Buffer* buffer = pair.m_buffer;
26904 bufferDescriptor* descriptor = pair.m_descriptor;
26906 /* Get pointer to contents of buffer */
26908 GLubyte* buffer_data = (GLubyte*)buffer->Map(Utils::Buffer::ReadOnly);
26910 /* Get pointer to expected data */
26911 GLubyte* expected_data = (GLubyte*)&descriptor->m_expected_data[0];
26914 static const GLuint vec4_size = 16;
26916 int res_before = memcmp(buffer_data, expected_data, vec4_size);
26917 int res_gohan = memcmp(buffer_data + 1 * vec4_size, expected_data + 1 * vec4_size, vec4_size);
26918 int res_chichi = memcmp(buffer_data + 3 * vec4_size, expected_data + 3 * vec4_size, vec4_size);
26920 if ((0 != res_before) || (0 != res_gohan) || (0 != res_chichi))
26922 m_context.getTestContext().getLog()
26923 << tcu::TestLog::Message << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
26924 << ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
26929 /* Release buffer mapping */
26937 * @param context Test context
26939 XFBCaptureStructTest::XFBCaptureStructTest(deqp::Context& context)
26940 : BufferTestBase(context, "xfb_capture_struct", "Test verifies that inactive structure members are captured")
26942 /* Nothing to be done here */
26945 /** Execute drawArrays for single vertex
26947 * @param test_case_index
26951 bool XFBCaptureStructTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
26953 const Functions& gl = m_context.getRenderContext().getFunctions();
26954 GLenum primitive_type = GL_PATCHES;
26956 if (TEST_VS == test_case_index)
26958 primitive_type = GL_POINTS;
26961 gl.disable(GL_RASTERIZER_DISCARD);
26962 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
26964 gl.beginTransformFeedback(GL_POINTS);
26965 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
26967 gl.drawArrays(primitive_type, 0 /* first */, 1 /* count */);
26968 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
26970 gl.endTransformFeedback();
26971 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
26976 /** Get descriptors of buffers necessary for test
26979 * @param out_descriptors Descriptors of buffers used by test
26981 void XFBCaptureStructTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
26982 bufferDescriptor::Vector& out_descriptors)
26984 const Utils::Type& type = Utils::Type::vec4;
26986 /* Test needs single uniform and xfb */
26987 out_descriptors.resize(2);
26989 /* Get references */
26990 bufferDescriptor& uniform = out_descriptors[0];
26991 bufferDescriptor& xfb = out_descriptors[1];
26994 uniform.m_index = 0;
26998 uniform.m_target = Utils::Buffer::Uniform;
26999 xfb.m_target = Utils::Buffer::Transform_feedback;
27002 const std::vector<GLubyte>& gohan_data = type.GenerateData();
27003 const std::vector<GLubyte>& chichi_data = type.GenerateData();
27005 const GLuint type_size = static_cast<GLuint>(gohan_data.size());
27008 uniform.m_initial_data.resize(2 * type_size);
27009 memcpy(&uniform.m_initial_data[0] + 0, &gohan_data[0], type_size);
27010 memcpy(&uniform.m_initial_data[0] + type_size, &chichi_data[0], type_size);
27013 xfb.m_initial_data.resize(4 * type_size);
27014 xfb.m_expected_data.resize(4 * type_size);
27016 for (GLuint i = 0; i < 4 * type_size; ++i)
27018 xfb.m_initial_data[i] = (glw::GLubyte)i;
27019 xfb.m_expected_data[i] = (glw::GLubyte)i;
27022 memcpy(&xfb.m_expected_data[0] + 1 * type_size, &gohan_data[0], type_size);
27023 memcpy(&xfb.m_expected_data[0] + 3 * type_size, &chichi_data[0], type_size);
27026 /** Get body of main function for given shader stage
27028 * @param test_case_index Index of test case
27029 * @param stage Shader stage
27030 * @param out_assignments Set to empty
27031 * @param out_calculations Set to empty
27033 void XFBCaptureStructTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
27034 std::string& out_assignments, std::string& out_calculations)
27036 out_calculations = "";
27038 static const GLchar* vs_tes_gs = " goku.chichi = uni_chichi;\n"
27039 " goku.gohan = uni_gohan;\n";
27040 static const GLchar* fs = " fs_out = goku.goten + goku.gohan + goku.chichi;\n";
27042 const GLchar* assignments = "";
27046 case Utils::Shader::FRAGMENT:
27050 case Utils::Shader::GEOMETRY:
27051 if (TEST_GS == test_case_index)
27053 assignments = vs_tes_gs;
27057 case Utils::Shader::TESS_CTRL:
27060 case Utils::Shader::TESS_EVAL:
27061 if (TEST_TES == test_case_index)
27063 assignments = vs_tes_gs;
27067 case Utils::Shader::VERTEX:
27068 if (TEST_VS == test_case_index)
27070 assignments = vs_tes_gs;
27075 TCU_FAIL("Invalid enum");
27078 out_assignments = assignments;
27081 /** Get interface of shader
27083 * @param test_case_index Index of test case
27084 * @param stage Shader stage
27085 * @param out_interface Set to ""
27087 void XFBCaptureStructTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
27088 std::string& out_interface)
27090 static const GLchar* vs_tes_gs = "const uint sizeof_type = 16;\n"
27098 "layout (xfb_offset = sizeof_type) out Goku goku;\n"
27100 "layout(binding = 0, std140) uniform block {\n"
27101 " vec4 uni_gohan;\n"
27102 " vec4 uni_chichi;\n"
27104 static const GLchar* fs = "struct Goku {\n"
27112 "out vec4 fs_out;\n";
27114 const GLchar* interface = "";
27118 case Utils::Shader::FRAGMENT:
27122 case Utils::Shader::GEOMETRY:
27123 if (TEST_GS == test_case_index)
27125 interface = vs_tes_gs;
27129 case Utils::Shader::TESS_CTRL:
27132 case Utils::Shader::TESS_EVAL:
27133 if (TEST_TES == test_case_index)
27135 interface = vs_tes_gs;
27139 case Utils::Shader::VERTEX:
27140 if (TEST_VS == test_case_index)
27142 interface = vs_tes_gs;
27147 TCU_FAIL("Invalid enum");
27150 out_interface = interface;
27153 /** Get source code of shader
27155 * @param test_case_index Index of test case
27156 * @param stage Shader stage
27160 std::string XFBCaptureStructTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
27162 std::string source;
27164 switch (test_case_index)
27169 case Utils::Shader::FRAGMENT:
27170 case Utils::Shader::VERTEX:
27171 source = BufferTestBase::getShaderSource(test_case_index, stage);
27181 case Utils::Shader::FRAGMENT:
27182 case Utils::Shader::TESS_CTRL:
27183 case Utils::Shader::TESS_EVAL:
27184 case Utils::Shader::VERTEX:
27185 source = BufferTestBase::getShaderSource(test_case_index, stage);
27193 source = BufferTestBase::getShaderSource(test_case_index, stage);
27197 TCU_FAIL("Invalid enum");
27205 /** Get name of test case
27207 * @param test_case_index Index of test case
27209 * @return Name of tested stage
27211 std::string XFBCaptureStructTest::getTestCaseName(glw::GLuint test_case_index)
27213 const GLchar* name = 0;
27215 switch (test_case_index)
27221 name = "tessellation evaluation";
27227 TCU_FAIL("Invalid enum");
27233 /** Returns number of test cases
27237 glw::GLuint XFBCaptureStructTest::getTestCaseNumber()
27242 /** Verify contents of buffers
27244 * @param buffers Collection of buffers to be verified
27246 * @return true if everything is as expected, false otherwise
27248 bool XFBCaptureStructTest::verifyBuffers(bufferCollection& buffers)
27250 bool result = true;
27252 bufferCollection::pair& pair = buffers.m_vector[1] /* xfb */;
27253 Utils::Buffer* buffer = pair.m_buffer;
27254 bufferDescriptor* descriptor = pair.m_descriptor;
27256 /* Get pointer to contents of buffer */
27258 GLubyte* buffer_data = (GLubyte*)buffer->Map(Utils::Buffer::ReadOnly);
27260 /* Get pointer to expected data */
27261 GLubyte* expected_data = (GLubyte*)&descriptor->m_expected_data[0];
27264 static const GLuint vec4_size = 16;
27266 int res_before = memcmp(buffer_data, expected_data, vec4_size);
27267 int res_gohan = memcmp(buffer_data + 1 * vec4_size, expected_data + 1 * vec4_size, vec4_size);
27268 int res_chichi = memcmp(buffer_data + 3 * vec4_size, expected_data + 3 * vec4_size, vec4_size);
27270 if ((0 != res_before) || (0 != res_gohan) || (0 != res_chichi))
27272 m_context.getTestContext().getLog()
27273 << tcu::TestLog::Message << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
27274 << ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
27279 /* Release buffer mapping */
27287 * @param context Test framework context
27289 XFBCaptureUnsizedArrayTest::XFBCaptureUnsizedArrayTest(deqp::Context& context)
27290 : NegativeTestBase(context, "xfb_capture_unsized_array",
27291 "Test verifies that compiler reports error when unsized array is qualified with xfb_offset")
27295 /** Source for given test case and stage
27297 * @param test_case_index Index of test case
27298 * @param stage Shader stage
27300 * @return Shader source
27302 std::string XFBCaptureUnsizedArrayTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
27304 static const GLchar* var_definition = "layout (xfb_offset = 0) out vec4 gokuARRAY[];\n";
27305 static const GLchar* var_use = " gokuINDEX[0] = result / 2;\n";
27306 static const GLchar* fs = "#version 430 core\n"
27307 "#extension GL_ARB_enhanced_layouts : require\n"
27310 "out vec4 fs_out;\n"
27314 " fs_out = gs_fs;\n"
27317 static const GLchar* gs_tested = "#version 430 core\n"
27318 "#extension GL_ARB_enhanced_layouts : require\n"
27320 "layout(points) in;\n"
27321 "layout(triangle_strip, max_vertices = 4) out;\n"
27325 "in vec4 tes_gs[];\n"
27326 "out vec4 gs_fs;\n"
27330 " vec4 result = tes_gs[0];\n"
27334 " gs_fs = result;\n"
27335 " gl_Position = vec4(-1, -1, 0, 1);\n"
27337 " gs_fs = result;\n"
27338 " gl_Position = vec4(-1, 1, 0, 1);\n"
27340 " gs_fs = result;\n"
27341 " gl_Position = vec4(1, -1, 0, 1);\n"
27343 " gs_fs = result;\n"
27344 " gl_Position = vec4(1, 1, 0, 1);\n"
27348 static const GLchar* tcs = "#version 430 core\n"
27349 "#extension GL_ARB_enhanced_layouts : require\n"
27351 "layout(vertices = 1) out;\n"
27353 "in vec4 vs_tcs[];\n"
27354 "out vec4 tcs_tes[];\n"
27359 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
27361 " gl_TessLevelOuter[0] = 1.0;\n"
27362 " gl_TessLevelOuter[1] = 1.0;\n"
27363 " gl_TessLevelOuter[2] = 1.0;\n"
27364 " gl_TessLevelOuter[3] = 1.0;\n"
27365 " gl_TessLevelInner[0] = 1.0;\n"
27366 " gl_TessLevelInner[1] = 1.0;\n"
27369 static const GLchar* tcs_tested = "#version 430 core\n"
27370 "#extension GL_ARB_enhanced_layouts : require\n"
27372 "layout(vertices = 1) out;\n"
27376 "in vec4 vs_tcs[];\n"
27377 "out vec4 tcs_tes[];\n"
27381 " vec4 result = vs_tcs[gl_InvocationID];\n"
27385 " tcs_tes[gl_InvocationID] = result;\n"
27387 " gl_TessLevelOuter[0] = 1.0;\n"
27388 " gl_TessLevelOuter[1] = 1.0;\n"
27389 " gl_TessLevelOuter[2] = 1.0;\n"
27390 " gl_TessLevelOuter[3] = 1.0;\n"
27391 " gl_TessLevelInner[0] = 1.0;\n"
27392 " gl_TessLevelInner[1] = 1.0;\n"
27395 static const GLchar* tes_tested = "#version 430 core\n"
27396 "#extension GL_ARB_enhanced_layouts : require\n"
27398 "layout(isolines, point_mode) in;\n"
27402 "in vec4 tcs_tes[];\n"
27403 "out vec4 tes_gs;\n"
27407 " vec4 result = tcs_tes[0];\n"
27411 " tes_gs += result;\n"
27414 static const GLchar* vs = "#version 430 core\n"
27415 "#extension GL_ARB_enhanced_layouts : require\n"
27418 "out vec4 vs_tcs;\n"
27422 " vs_tcs = in_vs;\n"
27425 static const GLchar* vs_tested = "#version 430 core\n"
27426 "#extension GL_ARB_enhanced_layouts : require\n"
27431 "out vec4 vs_tcs;\n"
27435 " vec4 result = in_vs;\n"
27439 " vs_tcs = result;\n"
27443 std::string source;
27444 testCase& test_case = m_test_cases[test_case_index];
27446 if (test_case.m_stage == stage)
27448 const GLchar* array = "";
27449 const GLchar* index = "";
27450 size_t position = 0;
27454 case Utils::Shader::GEOMETRY:
27455 source = gs_tested;
27459 case Utils::Shader::TESS_CTRL:
27460 source = tcs_tested;
27462 index = "[gl_InvocationID]";
27464 case Utils::Shader::TESS_EVAL:
27465 source = tes_tested;
27469 case Utils::Shader::VERTEX:
27470 source = vs_tested;
27473 TCU_FAIL("Invalid enum");
27476 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
27478 Utils::replaceToken("ARRAY", position, array, source);
27479 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
27481 Utils::replaceAllTokens("INDEX", index, source);
27485 switch (test_case.m_stage)
27487 case Utils::Shader::GEOMETRY:
27490 case Utils::Shader::FRAGMENT:
27493 case Utils::Shader::VERTEX:
27500 case Utils::Shader::TESS_CTRL:
27503 case Utils::Shader::FRAGMENT:
27506 case Utils::Shader::VERTEX:
27513 case Utils::Shader::TESS_EVAL:
27516 case Utils::Shader::FRAGMENT:
27519 case Utils::Shader::TESS_CTRL:
27522 case Utils::Shader::VERTEX:
27529 case Utils::Shader::VERTEX:
27532 case Utils::Shader::FRAGMENT:
27540 TCU_FAIL("Invalid enum");
27548 /** Get description of test case
27550 * @param test_case_index Index of test case
27552 * @return Test case description
27554 std::string XFBCaptureUnsizedArrayTest::getTestCaseName(GLuint test_case_index)
27556 std::stringstream stream;
27557 testCase& test_case = m_test_cases[test_case_index];
27559 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage);
27561 return stream.str();
27564 /** Get number of test cases
27566 * @return Number of test cases
27568 GLuint XFBCaptureUnsizedArrayTest::getTestCaseNumber()
27570 return static_cast<GLuint>(m_test_cases.size());
27573 /** Selects if "compute" stage is relevant for test
27579 bool XFBCaptureUnsizedArrayTest::isComputeRelevant(GLuint /* test_case_index */)
27584 /** Prepare all test cases
27587 void XFBCaptureUnsizedArrayTest::testInit()
27589 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
27591 /* Not aplicable for */
27592 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::FRAGMENT == stage) ||
27593 (Utils::Shader::GEOMETRY == stage) || (Utils::Shader::TESS_EVAL == stage))
27598 testCase test_case = { (Utils::Shader::STAGES)stage };
27600 m_test_cases.push_back(test_case);
27603 } /* EnhancedLayouts namespace */
27607 * @param context Rendering context.
27609 EnhancedLayoutsTests::EnhancedLayoutsTests(deqp::Context& context)
27610 : TestCaseGroup(context, "enhanced_layouts", "Verifies \"enhanced layouts\" functionality")
27612 /* Left blank on purpose */
27615 /** Initializes a texture_storage_multisample test group.
27618 void EnhancedLayoutsTests::init(void)
27620 addChild(new EnhancedLayouts::APIConstantValuesTest(m_context));
27621 addChild(new EnhancedLayouts::APIErrorsTest(m_context));
27622 addChild(new EnhancedLayouts::GLSLContantValuesTest(m_context));
27623 addChild(new EnhancedLayouts::GLSLContantImmutablityTest(m_context));
27624 addChild(new EnhancedLayouts::GLSLConstantIntegralExpressionTest(m_context));
27625 addChild(new EnhancedLayouts::UniformBlockLayoutQualifierConflictTest(m_context));
27626 addChild(new EnhancedLayouts::SSBMemberInvalidOffsetAlignmentTest(m_context));
27627 addChild(new EnhancedLayouts::SSBMemberOverlappingOffsetsTest(m_context));
27628 addChild(new EnhancedLayouts::VaryingExceedingComponentsTest(m_context));
27629 addChild(new EnhancedLayouts::VaryingComponentOfInvalidTypeTest(m_context));
27630 addChild(new EnhancedLayouts::OutputComponentAliasingTest(m_context));
27631 addChild(new EnhancedLayouts::VertexAttribLocationAPITest(m_context));
27632 addChild(new EnhancedLayouts::XFBInputTest(m_context));
27633 addChild(new EnhancedLayouts::XFBAllStagesTest(m_context));
27634 addChild(new EnhancedLayouts::XFBCaptureInactiveOutputVariableTest(m_context));
27635 addChild(new EnhancedLayouts::XFBCaptureInactiveOutputComponentTest(m_context));
27636 addChild(new EnhancedLayouts::XFBCaptureInactiveOutputBlockMemberTest(m_context));
27637 addChild(new EnhancedLayouts::XFBStrideTest(m_context));
27639 addChild(new EnhancedLayouts::UniformBlockMemberOffsetAndAlignTest(m_context));
27640 addChild(new EnhancedLayouts::UniformBlockMemberInvalidOffsetAlignmentTest(m_context));
27641 addChild(new EnhancedLayouts::UniformBlockMemberOverlappingOffsetsTest(m_context));
27642 addChild(new EnhancedLayouts::UniformBlockMemberAlignNonPowerOf2Test(m_context));
27643 addChild(new EnhancedLayouts::SSBLayoutQualifierConflictTest(m_context));
27644 addChild(new EnhancedLayouts::SSBMemberAlignNonPowerOf2Test(m_context));
27645 addChild(new EnhancedLayouts::SSBAlignmentTest(m_context));
27646 addChild(new EnhancedLayouts::VaryingStructureMemberLocationTest(m_context));
27647 addChild(new EnhancedLayouts::VaryingBlockAutomaticMemberLocationsTest(m_context));
27648 addChild(new EnhancedLayouts::VaryingComponentWithoutLocationTest(m_context));
27649 addChild(new EnhancedLayouts::InputComponentAliasingTest(m_context));
27650 addChild(new EnhancedLayouts::VaryingLocationAliasingWithMixedTypesTest(m_context));
27651 addChild(new EnhancedLayouts::VaryingLocationAliasingWithMixedInterpolationTest(m_context));
27652 addChild(new EnhancedLayouts::VaryingLocationAliasingWithMixedAuxiliaryStorageTest(m_context));
27653 addChild(new EnhancedLayouts::XFBStrideOfEmptyListTest(m_context));
27654 addChild(new EnhancedLayouts::XFBStrideOfEmptyListAndAPITest(m_context));
27655 addChild(new EnhancedLayouts::XFBTooSmallStrideTest(m_context));
27656 addChild(new EnhancedLayouts::XFBBlockMemberStrideTest(m_context));
27657 addChild(new EnhancedLayouts::XFBDuplicatedStrideTest(m_context));
27658 addChild(new EnhancedLayouts::XFBGetProgramResourceAPITest(m_context));
27659 addChild(new EnhancedLayouts::XFBMultipleVertexStreamsTest(m_context));
27660 addChild(new EnhancedLayouts::XFBExceedBufferLimitTest(m_context));
27661 addChild(new EnhancedLayouts::XFBExceedOffsetLimitTest(m_context));
27662 addChild(new EnhancedLayouts::XFBBlockMemberBufferTest(m_context));
27663 addChild(new EnhancedLayouts::XFBOutputOverlappingTest(m_context));
27664 addChild(new EnhancedLayouts::XFBInvalidOffsetAlignmentTest(m_context));
27665 addChild(new EnhancedLayouts::XFBCaptureStructTest(m_context));
27666 addChild(new EnhancedLayouts::XFBCaptureUnsizedArrayTest(m_context));
27667 addChild(new EnhancedLayouts::UniformBlockAlignmentTest(m_context));
27668 addChild(new EnhancedLayouts::SSBMemberOffsetAndAlignTest(m_context));
27669 addChild(new EnhancedLayouts::VertexAttribLocationsTest(m_context));
27670 addChild(new EnhancedLayouts::VaryingLocationsTest(m_context));
27671 addChild(new EnhancedLayouts::VaryingArrayLocationsTest(m_context));
27672 addChild(new EnhancedLayouts::VaryingStructureLocationsTest(m_context));
27673 addChild(new EnhancedLayouts::VaryingBlockLocationsTest(m_context));
27674 addChild(new EnhancedLayouts::VaryingBlockMemberLocationsTest(m_context));
27675 addChild(new EnhancedLayouts::XFBVariableStrideTest(m_context));
27676 addChild(new EnhancedLayouts::XFBBlockStrideTest(m_context));
27677 addChild(new EnhancedLayouts::XFBOverrideQualifiersWithAPITest(m_context));
27678 addChild(new EnhancedLayouts::XFBVertexStreamsTest(m_context));
27679 addChild(new EnhancedLayouts::XFBGlobalBufferTest(m_context));
27680 addChild(new EnhancedLayouts::FragmentDataLocationAPITest(m_context));
27681 addChild(new EnhancedLayouts::VaryingLocationLimitTest(m_context));
27682 addChild(new EnhancedLayouts::VaryingComponentsTest(m_context));
27683 addChild(new EnhancedLayouts::VaryingArrayComponentsTest(m_context));
27686 } /* gl4cts namespace */