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,
503 * - 1 otherwise or if it's a vertex shader input.
505 GLuint Type::GetLocations(bool is_vs_input) 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) || is_vs_input)
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: int, uint, and double 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 ||
4032 m_interface->m_members[0].m_builtin.m_basic_type == Utils::Type::Double)
4034 flat_qualifier = true;
4041 storage_str = flat_qualifier ? "flat in " : "in ";
4043 case VARYING_OUTPUT:
4044 storage_str = "out ";
4047 storage_str = "uniform ";
4050 storage_str = "buffer ";
4056 TCU_FAIL("Invalid enum");
4060 replaceToken("STORAGE", position, storage_str, definition);
4063 if (BUILTIN == m_type)
4065 replaceToken("TYPE", position, m_builtin.GetGLSLTypeName(), definition);
4069 if (Interface::STRUCT == m_interface->m_type)
4071 replaceToken("TYPE", position, m_interface->m_name.c_str(), definition);
4075 const std::string& block_definition = m_interface->GetDefinition();
4077 replaceToken("TYPE", position, block_definition.c_str(), definition);
4082 replaceToken("NAME", position, m_name.c_str(), definition);
4085 if (0 == m_n_array_elements)
4087 replaceToken("ARRAY", position, "", definition);
4092 sprintf(buffer, "[%d]", m_n_array_elements);
4094 replaceToken("ARRAY", position, buffer, definition);
4101 /** Get definitions for variables collected in vector
4103 * @param vector Collection of variables
4104 * @param flavour Flavour of variables
4106 * @return Code with definitions
4108 std::string GetDefinitions(const Variable::PtrVector& vector, Variable::FLAVOUR flavour)
4110 std::string list = Utils::g_list;
4111 size_t position = 0;
4113 for (GLuint i = 0; i < vector.size(); ++i)
4115 Utils::insertElementOfList(vector[i]->GetDefinition(flavour).c_str(), "\n", position, list);
4118 Utils::endList("", position, list);
4123 /** Get definitions for interfaces collected in vector
4125 * @param vector Collection of interfaces
4127 * @return Code with definitions
4129 std::string GetDefinitions(const Interface::PtrVector& vector)
4131 std::string list = Utils::g_list;
4132 size_t position = 0;
4134 for (GLuint i = 0; i < vector.size(); ++i)
4136 Utils::insertElementOfList(vector[i]->GetDefinition().c_str(), "\n", position, list);
4139 Utils::endList("", position, list);
4147 * @param type Type of interface
4149 Interface::Interface(const GLchar* name, Interface::TYPE type) : m_name(name), m_type(type)
4153 /** Adds member to interface
4155 * @param member Descriptor of new member
4157 * @return Pointer to just created member
4159 Variable::Descriptor* Interface::AddMember(const Variable::Descriptor& member)
4161 m_members.push_back(member);
4163 return &m_members.back();
4166 /** Get definition of interface
4168 * @param Code with definition
4170 std::string Interface::GetDefinition() const
4172 std::string definition;
4173 size_t position = 0;
4175 const GLchar* member_list = " MEMBER_DEFINITION\nMEMBER_LIST";
4177 if (STRUCT == m_type)
4179 definition = "struct NAME {\nMEMBER_LIST};";
4183 definition = "NAME {\nMEMBER_LIST}";
4187 replaceToken("NAME", position, m_name.c_str(), definition);
4190 for (GLuint i = 0; i < m_members.size(); ++i)
4192 const size_t start_position = position;
4193 const std::string& member_definition = m_members[i].GetDefinition(Variable::BASIC, Variable::MEMBER);
4196 replaceToken("MEMBER_LIST", position, member_list, definition);
4198 /* Move back position */
4199 position = start_position;
4201 /* Member definition */
4202 replaceToken("MEMBER_DEFINITION", position, member_definition.c_str(), definition);
4205 /* Remove last member list */
4206 replaceToken("MEMBER_LIST", position, "", definition);
4212 /** Adds member of built-in type to interface
4215 * @param qualifiers Qualifiers
4216 * @param expected_component Expected component of variable
4217 * @param expected_location Expected location
4219 * @param normalized Selects if data should be normalized
4220 * @param n_array_elements Length of array
4221 * @param expected_stride_of_element Expected stride of element
4222 * @param offset Offset
4224 * @return Pointer to just created member
4226 Variable::Descriptor* Interface::Member(const GLchar* name, const GLchar* qualifiers, GLint expected_component,
4227 GLint expected_location, const Type& type, GLboolean normalized,
4228 GLuint n_array_elements, GLint expected_stride_of_element, GLuint offset)
4230 return AddMember(Variable::Descriptor(name, qualifiers, expected_component, expected_location, type, normalized,
4231 n_array_elements, expected_stride_of_element, offset));
4234 /** Adds member of interface type to interface
4237 * @param qualifiers Qualifiers
4238 * @param expected_component Expected component of variable
4239 * @param expected_location Expected location
4241 * @param normalized Selects if data should be normalized
4242 * @param n_array_elements Length of array
4243 * @param expected_stride_of_element Expected stride of element
4244 * @param offset Offset
4246 * @return Pointer to just created member
4248 Variable::Descriptor* Interface::Member(const GLchar* name, const GLchar* qualifiers, GLint expected_component,
4249 GLint expected_location, Interface* nterface, GLuint n_array_elements,
4250 GLint expected_stride_of_element, GLuint offset)
4252 return AddMember(Variable::Descriptor(name, qualifiers, expected_component, expected_location, nterface,
4253 n_array_elements, expected_stride_of_element, offset));
4256 /** Clears contents of vector of pointers
4258 * @tparam T Type of elements
4260 * @param vector Collection to be cleared
4262 template <typename T>
4263 void clearPtrVector(std::vector<T*>& vector)
4265 for (size_t i = 0; i < vector.size(); ++i)
4282 * @param stage Stage described by that interface
4284 ShaderInterface::ShaderInterface(Shader::STAGES stage) : m_stage(stage)
4286 /* Nothing to be done */
4289 /** Get definitions of globals
4291 * @return Code with definitions
4293 std::string ShaderInterface::GetDefinitionsGlobals() const
4298 /** Get definitions of inputs
4300 * @return Code with definitions
4302 std::string ShaderInterface::GetDefinitionsInputs() const
4304 Variable::FLAVOUR flavour = Variable::GetFlavour(m_stage, Variable::INPUT);
4306 return GetDefinitions(m_inputs, flavour);
4309 /** Get definitions of outputs
4311 * @return Code with definitions
4313 std::string ShaderInterface::GetDefinitionsOutputs() const
4315 Variable::FLAVOUR flavour = Variable::GetFlavour(m_stage, Variable::OUTPUT);
4317 return GetDefinitions(m_outputs, flavour);
4320 /** Get definitions of buffers
4322 * @return Code with definitions
4324 std::string ShaderInterface::GetDefinitionsSSBs() const
4326 return GetDefinitions(m_ssb_blocks, Variable::BASIC);
4329 /** Get definitions of uniforms
4331 * @return Code with definitions
4333 std::string ShaderInterface::GetDefinitionsUniforms() const
4335 return GetDefinitions(m_uniforms, Variable::BASIC);
4340 * @param in Input variable
4341 * @param out Output variable
4343 VaryingConnection::VaryingConnection(Variable* in, Variable* out) : m_in(in), m_out(out)
4345 /* NBothing to be done here */
4348 /** Adds new varying connection to given stage
4350 * @param stage Shader stage
4351 * @param in In varying
4352 * @param out Out varying
4354 void VaryingPassthrough::Add(Shader::STAGES stage, Variable* in, Variable* out)
4356 VaryingConnection::Vector& vector = Get(stage);
4358 vector.push_back(VaryingConnection(in, out));
4361 /** Get all passthrough connections for given stage
4363 * @param stage Shader stage
4365 * @return Vector of connections
4367 VaryingConnection::Vector& VaryingPassthrough::Get(Shader::STAGES stage)
4369 VaryingConnection::Vector* result = 0;
4373 case Shader::FRAGMENT:
4374 result = &m_fragment;
4376 case Shader::GEOMETRY:
4377 result = &m_geometry;
4379 case Shader::TESS_CTRL:
4380 result = &m_tess_ctrl;
4382 case Shader::TESS_EVAL:
4383 result = &m_tess_eval;
4385 case Shader::VERTEX:
4389 TCU_FAIL("Invalid enum");
4398 ProgramInterface::ProgramInterface()
4399 : m_compute(Shader::COMPUTE)
4400 , m_vertex(Shader::VERTEX)
4401 , m_tess_ctrl(Shader::TESS_CTRL)
4402 , m_tess_eval(Shader::TESS_EVAL)
4403 , m_geometry(Shader::GEOMETRY)
4404 , m_fragment(Shader::FRAGMENT)
4411 ProgramInterface::~ProgramInterface()
4413 clearPtrVector(m_blocks);
4414 clearPtrVector(m_structures);
4417 /** Adds new interface
4422 * @return Pointer to created interface
4424 Interface* ProgramInterface::AddInterface(const GLchar* name, Interface::TYPE type)
4426 Interface* interface = 0;
4428 if (Interface::STRUCT == type)
4430 interface = new Interface(name, type);
4432 m_structures.push_back(interface);
4436 interface = new Interface(name, type);
4438 m_blocks.push_back(interface);
4444 /** Adds new block interface
4448 * @return Pointer to created interface
4450 Interface* ProgramInterface::Block(const GLchar* name)
4452 return AddInterface(name, Interface::BLOCK);
4455 /** Get interface of given shader stage
4457 * @param stage Shader stage
4459 * @return Reference to stage interface
4461 ShaderInterface& ProgramInterface::GetShaderInterface(Shader::STAGES stage)
4463 ShaderInterface* interface = 0;
4467 case Shader::COMPUTE:
4468 interface = &m_compute;
4470 case Shader::FRAGMENT:
4471 interface = &m_fragment;
4473 case Shader::GEOMETRY:
4474 interface = &m_geometry;
4476 case Shader::TESS_CTRL:
4477 interface = &m_tess_ctrl;
4479 case Shader::TESS_EVAL:
4480 interface = &m_tess_eval;
4482 case Shader::VERTEX:
4483 interface = &m_vertex;
4486 TCU_FAIL("Invalid enum");
4492 /** Get interface of given shader stage
4494 * @param stage Shader stage
4496 * @return Reference to stage interface
4498 const ShaderInterface& ProgramInterface::GetShaderInterface(Shader::STAGES stage) const
4500 const ShaderInterface* interface = 0;
4504 case Shader::COMPUTE:
4505 interface = &m_compute;
4507 case Shader::FRAGMENT:
4508 interface = &m_fragment;
4510 case Shader::GEOMETRY:
4511 interface = &m_geometry;
4513 case Shader::TESS_CTRL:
4514 interface = &m_tess_ctrl;
4516 case Shader::TESS_EVAL:
4517 interface = &m_tess_eval;
4519 case Shader::VERTEX:
4520 interface = &m_vertex;
4523 TCU_FAIL("Invalid enum");
4529 /** Clone interface of Vertex shader stage to other stages
4530 * It creates matching inputs, outputs, uniforms and buffers in other stages.
4531 * There are no additional outputs for FRAGMENT shader generated.
4533 * @param varying_passthrough Collection of varyings connections
4535 void ProgramInterface::CloneVertexInterface(VaryingPassthrough& varying_passthrough)
4537 /* VS outputs >> TCS inputs >> TCS outputs >> .. >> FS inputs */
4538 for (size_t i = 0; i < m_vertex.m_outputs.size(); ++i)
4540 const Variable& vs_var = *m_vertex.m_outputs[i];
4541 const GLchar* prefix = GetStagePrefix(Shader::VERTEX, vs_var.m_storage);
4543 cloneVariableForStage(vs_var, Shader::TESS_CTRL, prefix, varying_passthrough);
4544 cloneVariableForStage(vs_var, Shader::TESS_EVAL, prefix, varying_passthrough);
4545 cloneVariableForStage(vs_var, Shader::GEOMETRY, prefix, varying_passthrough);
4546 cloneVariableForStage(vs_var, Shader::FRAGMENT, prefix, varying_passthrough);
4549 /* Copy uniforms from VS to other stages */
4550 for (size_t i = 0; i < m_vertex.m_uniforms.size(); ++i)
4552 Variable& vs_var = *m_vertex.m_uniforms[i];
4553 const GLchar* prefix = GetStagePrefix(Shader::VERTEX, vs_var.m_storage);
4555 cloneVariableForStage(vs_var, Shader::COMPUTE, prefix, varying_passthrough);
4556 cloneVariableForStage(vs_var, Shader::TESS_CTRL, prefix, varying_passthrough);
4557 cloneVariableForStage(vs_var, Shader::TESS_EVAL, prefix, varying_passthrough);
4558 cloneVariableForStage(vs_var, Shader::GEOMETRY, prefix, varying_passthrough);
4559 cloneVariableForStage(vs_var, Shader::FRAGMENT, prefix, varying_passthrough);
4561 /* Uniform blocks needs unique binding */
4562 if (true == vs_var.IsBlock())
4564 replaceBinding(vs_var, Shader::VERTEX);
4568 /* Copy SSBs from VS to other stages */
4569 for (size_t i = 0; i < m_vertex.m_ssb_blocks.size(); ++i)
4571 Variable& vs_var = *m_vertex.m_ssb_blocks[i];
4572 const GLchar* prefix = GetStagePrefix(Shader::VERTEX, vs_var.m_storage);
4574 cloneVariableForStage(vs_var, Shader::COMPUTE, prefix, varying_passthrough);
4575 cloneVariableForStage(vs_var, Shader::TESS_CTRL, prefix, varying_passthrough);
4576 cloneVariableForStage(vs_var, Shader::TESS_EVAL, prefix, varying_passthrough);
4577 cloneVariableForStage(vs_var, Shader::GEOMETRY, prefix, varying_passthrough);
4578 cloneVariableForStage(vs_var, Shader::FRAGMENT, prefix, varying_passthrough);
4580 /* SSBs blocks needs unique binding */
4581 if (true == vs_var.IsBlock())
4583 replaceBinding(vs_var, Shader::VERTEX);
4587 m_compute.m_globals = m_vertex.m_globals;
4588 m_fragment.m_globals = m_vertex.m_globals;
4589 m_geometry.m_globals = m_vertex.m_globals;
4590 m_tess_ctrl.m_globals = m_vertex.m_globals;
4591 m_tess_eval.m_globals = m_vertex.m_globals;
4594 /** Clone variable for specific stage
4596 * @param variable Variable
4597 * @param stage Requested stage
4598 * @param prefix Prefix used in variable name that is specific for original stage
4599 * @param varying_passthrough Collection of varyings connections
4601 void ProgramInterface::cloneVariableForStage(const Variable& variable, Shader::STAGES stage, const GLchar* prefix,
4602 VaryingPassthrough& varying_passthrough)
4604 switch (variable.m_storage)
4606 case Variable::VARYING_OUTPUT:
4608 Variable* in = cloneVariableForStage(variable, stage, Variable::VARYING_INPUT, prefix);
4610 if (Shader::FRAGMENT != stage)
4612 Variable* out = cloneVariableForStage(variable, stage, Variable::VARYING_OUTPUT, prefix);
4613 varying_passthrough.Add(stage, in, out);
4617 case Variable::UNIFORM:
4619 cloneVariableForStage(variable, stage, variable.m_storage, prefix);
4622 TCU_FAIL("Invalid enum");
4627 /** Clone variable for specific stage
4629 * @param variable Variable
4630 * @param stage Requested stage
4631 * @param storage Storage used by variable
4632 * @param prefix Prefix used in variable name that is specific for original stage
4634 * @return New variable
4636 Variable* ProgramInterface::cloneVariableForStage(const Variable& variable, Shader::STAGES stage,
4637 Variable::STORAGE storage, const GLchar* prefix)
4639 /* Initialize with original variable */
4640 Variable* var = new Variable(variable);
4643 TCU_FAIL("Memory allocation");
4646 /* Set up storage */
4647 var->m_storage = storage;
4650 std::string name = variable.m_descriptor.m_name;
4652 /* Prefix name with stage ID, empty means default block */
4653 if (false == name.empty())
4655 size_t position = 0;
4656 const GLchar* stage_prefix = GetStagePrefix(stage, storage);
4657 Utils::replaceToken(prefix, position, stage_prefix, name);
4659 var->m_descriptor.m_name = name;
4662 const bool is_block = variable.IsBlock();
4663 if (true == is_block)
4665 const Interface* interface = variable.m_descriptor.m_interface;
4667 Interface* block = CloneBlockForStage(*interface, stage, storage, prefix);
4669 var->m_descriptor.m_interface = block;
4672 /* Store variable */
4673 ShaderInterface& si = GetShaderInterface(stage);
4674 Variable* result = 0;
4678 case Variable::VARYING_INPUT:
4679 si.m_inputs.push_back(var);
4680 result = si.m_inputs.back();
4682 case Variable::VARYING_OUTPUT:
4683 si.m_outputs.push_back(var);
4684 result = si.m_outputs.back();
4686 case Variable::UNIFORM:
4687 /* Uniform blocks needs unique binding */
4688 if (true == is_block)
4690 replaceBinding(*var, stage);
4693 si.m_uniforms.push_back(var);
4694 result = si.m_uniforms.back();
4697 /* SSBs needs unique binding */
4698 if (true == is_block)
4700 replaceBinding(*var, stage);
4703 si.m_ssb_blocks.push_back(var);
4704 result = si.m_ssb_blocks.back();
4707 TCU_FAIL("Invalid enum");
4714 /** clone block to specific stage
4716 * @param block Block to be copied
4717 * @param stage Specific stage
4718 * @param storage Storage used by block
4719 * @param prefix Prefix used in block name
4721 * @return New interface
4723 Interface* ProgramInterface::CloneBlockForStage(const Interface& block, Shader::STAGES stage, Variable::STORAGE storage,
4724 const GLchar* prefix)
4727 std::string name = block.m_name;
4729 /* Prefix name with stage ID */
4730 size_t position = 0;
4731 const GLchar* stage_prefix = GetStagePrefix(stage, storage);
4732 Utils::replaceToken(prefix, position, stage_prefix, name);
4734 Interface* ptr = GetBlock(name.c_str());
4738 ptr = AddInterface(name.c_str(), Interface::BLOCK);
4741 ptr->m_members = block.m_members;
4746 /** Get stage specific prefix used in names
4748 * @param stage Stage
4749 * @param storage Storage class
4753 const GLchar* ProgramInterface::GetStagePrefix(Shader::STAGES stage, Variable::STORAGE storage)
4755 static const GLchar* lut[Shader::STAGE_MAX][Variable::STORAGE_MAX] = {
4756 /* IN OUT UNIFORM SSB MEMBER */
4757 /* CS */ { 0, 0, "cs_uni_", "cs_buf_", "" },
4758 /* VS */ { "in_vs_", "vs_tcs_", "vs_uni_", "vs_buf_", "" },
4759 /* TCS */ { "vs_tcs_", "tcs_tes_", "tcs_uni_", "tcs_buf_", "" },
4760 /* TES */ { "tcs_tes_", "tes_gs_", "tes_uni_", "tes_buf_", "" },
4761 /* GS */ { "tes_gs_", "gs_fs_", "gs_uni_", "gs_buf_", "" },
4762 /* FS */ { "gs_fs_", "fs_out_", "fs_uni_", "fs_buf_", "" },
4765 const GLchar* result = 0;
4767 result = lut[stage][storage];
4772 /** Get definitions of all structures used in program interface
4774 * @return String with code
4776 std::string ProgramInterface::GetDefinitionsStructures() const
4778 return GetDefinitions(m_structures);
4781 /** Get interface code for stage
4783 * @param stage Specific stage
4785 * @return String with code
4787 std::string ProgramInterface::GetInterfaceForStage(Shader::STAGES stage) const
4789 size_t position = 0;
4790 std::string interface = "/* Globals */\n"
4793 "/* Structures */\n"
4808 const ShaderInterface& si = GetShaderInterface(stage);
4810 const std::string& structures = GetDefinitionsStructures();
4812 const std::string& globals = si.GetDefinitionsGlobals();
4813 const std::string& inputs = si.GetDefinitionsInputs();
4814 const std::string& outputs = si.GetDefinitionsOutputs();
4815 const std::string& uniforms = si.GetDefinitionsUniforms();
4816 const std::string& ssbs = si.GetDefinitionsSSBs();
4818 replaceToken("GLOBALS", position, globals.c_str(), interface);
4819 replaceToken("STRUCTURES", position, structures.c_str(), interface);
4820 replaceToken("UNIFORMS", position, uniforms.c_str(), interface);
4821 replaceToken("INPUTS", position, inputs.c_str(), interface);
4822 replaceToken("OUTPUTS", position, outputs.c_str(), interface);
4823 replaceToken("STORAGE", position, ssbs.c_str(), interface);
4828 /** Functional object used in find_if algorithm, in search for interface of given name
4831 struct matchInterfaceName
4833 matchInterfaceName(const GLchar* name) : m_name(name)
4837 bool operator()(const Interface* interface)
4839 return 0 == interface->m_name.compare(m_name);
4842 const GLchar* m_name;
4845 /** Finds interface of given name in given vector of interfaces
4847 * @param vector Collection of interfaces
4848 * @param name Requested name
4850 * @return Pointer to interface if available, 0 otherwise
4852 static Interface* findInterfaceByName(Interface::PtrVector& vector, const GLchar* name)
4854 Interface::PtrVector::iterator it = std::find_if(vector.begin(), vector.end(), matchInterfaceName(name));
4856 if (vector.end() != it)
4866 /** Search for block of given name
4868 * @param name Name of block
4870 * @return Pointer to block or 0
4872 Interface* ProgramInterface::GetBlock(const GLchar* name)
4874 return findInterfaceByName(m_blocks, name);
4877 /** Search for structure of given name
4879 * @param name Name of structure
4881 * @return Pointer to structure or 0
4883 Interface* ProgramInterface::GetStructure(const GLchar* name)
4885 return findInterfaceByName(m_structures, name);
4888 /** Adds new sturcture to interface
4890 * @param name Name of structure
4892 * @return Created structure
4894 Interface* ProgramInterface::Structure(const GLchar* name)
4896 return AddInterface(name, Interface::STRUCT);
4899 /** Replace "BINDING" token in qualifiers string to value specific for given stage
4901 * @param variable Variable to modify
4902 * @param stage Requested stage
4904 void ProgramInterface::replaceBinding(Variable& variable, Shader::STAGES stage)
4907 sprintf(binding, "%d", stage);
4908 replaceAllTokens("BINDING", binding, variable.m_descriptor.m_qualifiers);
4910 } /* Utils namespace */
4912 /** Debuging procedure. Logs parameters.
4914 * @param source As specified in GL spec.
4915 * @param type As specified in GL spec.
4916 * @param id As specified in GL spec.
4917 * @param severity As specified in GL spec.
4919 * @param message As specified in GL spec.
4920 * @param info Pointer to instance of Context used by test.
4922 void GLW_APIENTRY debug_proc(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei /* length */,
4923 const GLchar* message, void* info)
4925 deqp::Context* ctx = (deqp::Context*)info;
4927 const GLchar* source_str = "Unknown";
4928 const GLchar* type_str = "Unknown";
4929 const GLchar* severity_str = "Unknown";
4933 case GL_DEBUG_SOURCE_API:
4936 case GL_DEBUG_SOURCE_APPLICATION:
4939 case GL_DEBUG_SOURCE_OTHER:
4942 case GL_DEBUG_SOURCE_SHADER_COMPILER:
4945 case GL_DEBUG_SOURCE_THIRD_PARTY:
4948 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
4957 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
4958 type_str = "DEPRECATED_BEHAVIOR";
4960 case GL_DEBUG_TYPE_ERROR:
4963 case GL_DEBUG_TYPE_MARKER:
4964 type_str = "MARKER";
4966 case GL_DEBUG_TYPE_OTHER:
4969 case GL_DEBUG_TYPE_PERFORMANCE:
4970 type_str = "PERFORMANCE";
4972 case GL_DEBUG_TYPE_POP_GROUP:
4973 type_str = "POP_GROUP";
4975 case GL_DEBUG_TYPE_PORTABILITY:
4976 type_str = "PORTABILITY";
4978 case GL_DEBUG_TYPE_PUSH_GROUP:
4979 type_str = "PUSH_GROUP";
4981 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
4982 type_str = "UNDEFINED_BEHAVIOR";
4990 case GL_DEBUG_SEVERITY_HIGH:
4993 case GL_DEBUG_SEVERITY_LOW:
4996 case GL_DEBUG_SEVERITY_MEDIUM:
4999 case GL_DEBUG_SEVERITY_NOTIFICATION:
5006 ctx->getTestContext().getLog() << tcu::TestLog::Message << "DEBUG_INFO: " << std::setw(3) << source_str << "|"
5007 << severity_str << "|" << std::setw(18) << type_str << "|" << std::setw(12) << id
5008 << ": " << message << tcu::TestLog::EndMessage;
5013 * @param context Test context
5014 * @param test_name Test name
5015 * @param test_description Test description
5017 TestBase::TestBase(deqp::Context& context, const GLchar* test_name, const GLchar* test_description)
5018 : TestCase(context, test_name, test_description)
5020 /* Nothing to be done here */
5025 * @return tcu::TestNode::STOP otherwise
5027 tcu::TestNode::IterateResult TestBase::iterate()
5031 #if DEBUG_ENBALE_MESSAGE_CALLBACK
5032 const Functions& gl = m_context.getRenderContext().getFunctions();
5034 gl.debugMessageCallback(debug_proc, &m_context);
5035 GLU_EXPECT_NO_ERROR(gl.getError(), "DebugMessageCallback");
5036 #endif /* DEBUG_ENBALE_MESSAGE_CALLBACK */
5041 test_result = test();
5043 catch (std::exception& exc)
5045 TCU_FAIL(exc.what());
5049 if (true == test_result)
5051 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
5055 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
5059 return tcu::TestNode::STOP;
5062 /** Get last input location available for given type at specific stage
5064 * @param stage Shader stage
5065 * @param type Input type
5066 * @param array_length Length of input array
5068 * @return Last location index
5070 GLint TestBase::getLastInputLocation(Utils::Shader::STAGES stage, const Utils::Type& type, GLuint array_length)
5072 GLint divide = 4; /* 4 components per location */
5075 GLint paramPrev = 0;
5076 GLenum pnamePrev = 0;
5081 case Utils::Shader::FRAGMENT:
5082 pname = GL_MAX_FRAGMENT_INPUT_COMPONENTS;
5083 pnamePrev = GL_MAX_GEOMETRY_OUTPUT_COMPONENTS;
5085 case Utils::Shader::GEOMETRY:
5086 pname = GL_MAX_GEOMETRY_INPUT_COMPONENTS;
5087 pnamePrev = GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS;
5089 case Utils::Shader::TESS_CTRL:
5090 pname = GL_MAX_TESS_CONTROL_INPUT_COMPONENTS;
5091 pnamePrev = GL_MAX_VERTEX_OUTPUT_COMPONENTS;
5093 case Utils::Shader::TESS_EVAL:
5094 pname = GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS;
5095 pnamePrev = GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS;
5097 case Utils::Shader::VERTEX:
5098 pname = GL_MAX_VERTEX_ATTRIBS;
5102 TCU_FAIL("Invalid enum");
5106 /* Zero means no array, but 1 slot is required */
5107 if (0 == array_length)
5113 const Functions& gl = m_context.getRenderContext().getFunctions();
5115 gl.getIntegerv(pname, ¶m);
5116 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
5119 gl.getIntegerv(pnamePrev, ¶mPrev);
5120 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
5122 /* Don't read from a location that doesn't exist in the previous stage */
5123 param = de::min(param, paramPrev);
5127 #if WRKARD_VARYINGLOCATIONSTEST
5129 const GLint n_avl_locations = 16;
5133 const GLint n_avl_locations = param / divide;
5137 const GLuint n_req_location = type.GetLocations(stage == Utils::Shader::VERTEX) * array_length;
5139 return n_avl_locations - n_req_location; /* last is max - 1 */
5142 /** Get last output location available for given type at specific stage
5144 * @param stage Shader stage
5145 * @param type Input type
5146 * @param array_length Length of input array
5148 * @return Last location index
5150 GLint TestBase::getLastOutputLocation(Utils::Shader::STAGES stage, const Utils::Type& type, GLuint array_length)
5154 GLint paramNext = 0;
5155 GLenum pnameNext = 0;
5160 case Utils::Shader::GEOMETRY:
5161 pname = GL_MAX_GEOMETRY_OUTPUT_COMPONENTS;
5162 pnameNext = GL_MAX_FRAGMENT_INPUT_COMPONENTS;
5164 case Utils::Shader::TESS_CTRL:
5165 pname = GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS;
5166 pnameNext = GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS;
5168 case Utils::Shader::TESS_EVAL:
5169 pname = GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS;
5170 pnameNext = GL_MAX_GEOMETRY_INPUT_COMPONENTS;
5172 case Utils::Shader::VERTEX:
5173 pname = GL_MAX_VERTEX_OUTPUT_COMPONENTS;
5174 pnameNext = GL_MAX_TESS_CONTROL_INPUT_COMPONENTS;
5177 TCU_FAIL("Invalid enum");
5181 /* Zero means no array, but 1 slot is required */
5182 if (0 == array_length)
5188 const Functions& gl = m_context.getRenderContext().getFunctions();
5190 gl.getIntegerv(pname, ¶m);
5191 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
5193 gl.getIntegerv(pnameNext, ¶mNext);
5194 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
5197 #if WRKARD_VARYINGLOCATIONSTEST
5199 const GLint n_avl_locations = 16;
5203 /* Don't write to a location that doesn't exist in the next stage */
5204 param = de::min(param, paramNext);
5206 const GLint n_avl_locations = param / 4; /* 4 components per location */
5210 const GLuint n_req_location = type.GetLocations() * array_length;
5212 return n_avl_locations - n_req_location; /* last is max - 1 */
5215 /** Basic implementation
5219 * @return Empty string
5221 std::string TestBase::getTestCaseName(GLuint /* test_case_index */)
5228 /** Basic implementation
5232 GLuint TestBase::getTestCaseNumber()
5237 /** Check if flat qualifier is required for given type, stage and storage
5239 * @param stage Shader stage
5240 * @param type Input type
5241 * @param storage Storage of variable
5243 * @return Last location index
5245 bool TestBase::isFlatRequired(Utils::Shader::STAGES stage, const Utils::Type& type,
5246 Utils::Variable::STORAGE storage) const
5248 /* Float types do not need flat at all */
5249 if (Utils::Type::Float == type.m_basic_type)
5254 /* Inputs to fragment shader */
5255 if ((Utils::Shader::FRAGMENT == stage) && (Utils::Variable::VARYING_INPUT == storage))
5260 /* Outputs from geometry shader */
5261 if ((Utils::Shader::FRAGMENT == stage) && (Utils::Variable::VARYING_OUTPUT == storage))
5269 /** Basic implementation of testInit method
5272 void TestBase::testInit()
5276 /** Calculate stride for interface
5278 * @param interface Interface
5280 * @return Calculated value
5282 GLuint TestBase::calculateStride(const Utils::Interface& interface) const
5284 const size_t n_members = interface.m_members.size();
5288 for (size_t i = 0; i < n_members; ++i)
5290 const Utils::Variable::Descriptor& member = interface.m_members[i];
5291 const GLuint member_offset = member.m_offset;
5292 const GLuint member_stride = member.m_expected_stride_of_element;
5293 const GLuint member_ends_at = member_offset + member_stride;
5295 stride = std::max(stride, member_ends_at);
5301 /** Generate data for interface. This routine is recursive
5303 * @param interface Interface
5304 * @param offset Offset in out_data
5305 * @param out_data Buffer to be filled
5307 void TestBase::generateData(const Utils::Interface& interface, GLuint offset, std::vector<GLubyte>& out_data) const
5309 const size_t n_members = interface.m_members.size();
5310 GLubyte* ptr = &out_data[offset];
5312 for (size_t i = 0; i < n_members; ++i)
5314 const Utils::Variable::Descriptor& member = interface.m_members[i];
5315 const GLuint member_offset = member.m_offset;
5316 const GLuint n_elements = (0 == member.m_n_array_elements) ? 1 : member.m_n_array_elements;
5318 for (GLuint element = 0; element < n_elements; ++element)
5320 const GLuint element_offset = element * member.m_expected_stride_of_element;
5321 const GLuint data_offfset = member_offset + element_offset;
5323 if (Utils::Variable::BUILTIN == member.m_type)
5325 const std::vector<GLubyte>& data = member.m_builtin.GenerateData();
5327 memcpy(ptr + data_offfset, &data[0], data.size());
5331 generateData(*member.m_interface, offset + data_offfset, out_data);
5337 /** Get type at index
5339 * @param index Index of requested type
5343 Utils::Type TestBase::getType(GLuint index) const
5350 type = Utils::Type::_double;
5353 type = Utils::Type::dmat2;
5356 type = Utils::Type::dmat2x3;
5359 type = Utils::Type::dmat2x4;
5362 type = Utils::Type::dmat3;
5365 type = Utils::Type::dmat3x2;
5368 type = Utils::Type::dmat3x4;
5371 type = Utils::Type::dmat4;
5374 type = Utils::Type::dmat4x2;
5377 type = Utils::Type::dmat4x3;
5380 type = Utils::Type::dvec2;
5383 type = Utils::Type::dvec3;
5386 type = Utils::Type::dvec4;
5389 type = Utils::Type::_float;
5392 type = Utils::Type::mat2;
5395 type = Utils::Type::mat2x3;
5398 type = Utils::Type::mat2x4;
5401 type = Utils::Type::mat3;
5404 type = Utils::Type::mat3x2;
5407 type = Utils::Type::mat3x4;
5410 type = Utils::Type::mat4;
5413 type = Utils::Type::mat4x2;
5416 type = Utils::Type::mat4x3;
5419 type = Utils::Type::vec2;
5422 type = Utils::Type::vec3;
5425 type = Utils::Type::vec4;
5428 type = Utils::Type::_int;
5431 type = Utils::Type::ivec2;
5434 type = Utils::Type::ivec3;
5437 type = Utils::Type::ivec4;
5440 type = Utils::Type::uint;
5443 type = Utils::Type::uvec2;
5446 type = Utils::Type::uvec3;
5449 type = Utils::Type::uvec4;
5452 TCU_FAIL("invalid enum");
5458 /** Get name of type at index
5460 * @param index Index of type
5464 std::string TestBase::getTypeName(GLuint index) const
5466 std::string name = getType(index).GetGLSLTypeName();
5471 /** Get number of types
5475 glw::GLuint TestBase::getTypesNumber() const
5482 * @return true if test pass, false otherwise
5484 bool TestBase::test()
5487 GLuint n_test_cases = 0;
5492 /* GL entry points */
5493 const Functions& gl = m_context.getRenderContext().getFunctions();
5495 /* Tessellation patch set up */
5496 gl.patchParameteri(GL_PATCH_VERTICES, 1);
5497 GLU_EXPECT_NO_ERROR(gl.getError(), "PatchParameteri");
5499 /* Get number of test cases */
5500 n_test_cases = getTestCaseNumber();
5502 #if DEBUG_REPEAT_TEST_CASE
5506 GLuint test_case = DEBUG_REPEATED_TEST_CASE;
5508 #else /* DEBUG_REPEAT_TEST_CASE */
5510 for (GLuint test_case = 0; test_case < n_test_cases; ++test_case)
5513 #endif /* DEBUG_REPEAT_TEST_CASE */
5515 bool case_result = true;
5518 if (false == testCase(test_case))
5520 case_result = false;
5524 if (false == case_result)
5526 const std::string& test_case_name = getTestCaseName(test_case);
5528 if (false == test_case_name.empty())
5530 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Test case (" << test_case_name
5531 << ") failed." << tcu::TestLog::EndMessage;
5535 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Test case (" << test_case
5536 << ") failed." << tcu::TestLog::EndMessage;
5547 /* Constants used by BufferTestBase */
5548 const GLuint BufferTestBase::bufferDescriptor::m_non_indexed = -1;
5552 * @param context Test context
5553 * @param test_name Name of test
5554 * @param test_description Description of test
5556 BufferTestBase::BufferTestBase(deqp::Context& context, const GLchar* test_name, const GLchar* test_description)
5557 : TestBase(context, test_name, test_description)
5561 /** Execute drawArrays for single vertex
5567 bool BufferTestBase::executeDrawCall(bool tesEnabled, GLuint /* test_case_index */)
5569 const Functions& gl = m_context.getRenderContext().getFunctions();
5571 gl.disable(GL_RASTERIZER_DISCARD);
5572 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
5574 gl.beginTransformFeedback(GL_POINTS);
5575 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
5577 // Only TES is existed, glDrawArray can use the parameter GL_PATCHES
5578 if (tesEnabled == false)
5580 gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */);
5584 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
5587 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
5589 gl.endTransformFeedback();
5590 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
5595 /** Get descriptors of buffers necessary for test
5600 void BufferTestBase::getBufferDescriptors(glw::GLuint /* test_case_index */,
5601 bufferDescriptor::Vector& /* out_descriptors */)
5603 /* Nothhing to be done */
5606 /** Get list of names of varyings that will be registered with TransformFeedbackVaryings
5611 void BufferTestBase::getCapturedVaryings(glw::GLuint /* test_case_index */,
5612 Utils::Program::NameVector& /* captured_varyings */)
5614 /* Nothing to be done */
5617 /** Get body of main function for given shader stage
5621 * @param out_assignments Set to empty
5622 * @param out_calculations Set to empty
5624 void BufferTestBase::getShaderBody(glw::GLuint /* test_case_index */, Utils::Shader::STAGES /* stage */,
5625 std::string& out_assignments, std::string& out_calculations)
5627 out_assignments = "";
5628 out_calculations = "";
5631 /** Get interface of shader
5635 * @param out_interface Set to ""
5637 void BufferTestBase::getShaderInterface(glw::GLuint /* test_case_index */, Utils::Shader::STAGES /* stage */,
5638 std::string& out_interface)
5643 /** Get source code of shader
5645 * @param test_case_index Index of test case
5646 * @param stage Shader stage
5650 std::string BufferTestBase::getShaderSource(glw::GLuint test_case_index, Utils::Shader::STAGES stage)
5652 std::string assignments;
5653 std::string calculations;
5654 std::string interface;
5657 getShaderBody(test_case_index, stage, assignments, calculations);
5658 getShaderInterface(test_case_index, stage, interface);
5661 std::string source = getShaderTemplate(stage);
5664 size_t position = 0;
5665 Utils::replaceToken("INTERFACE", position, interface.c_str(), source);
5666 Utils::replaceToken("CALCULATIONS", position, calculations.c_str(), source);
5667 Utils::replaceToken("ASSIGNMENTS", position, assignments.c_str(), source);
5673 /** Inspects program to check if all resources are as expected
5681 bool BufferTestBase::inspectProgram(GLuint /* test_case_index */, Utils::Program& /* program */,
5682 std::stringstream& /* out_stream */)
5689 * @param test_case_index Id of test case
5691 * @return true if test case pass, false otherwise
5693 bool BufferTestBase::testCase(GLuint test_case_index)
5697 bufferCollection buffers;
5698 Utils::Program::NameVector captured_varyings;
5699 bufferDescriptor::Vector descriptors;
5700 Utils::Program program(m_context);
5701 Utils::VertexArray vao(m_context);
5703 /* Get captured varyings */
5704 getCapturedVaryings(test_case_index, captured_varyings);
5706 /* Get shader sources */
5707 const std::string& fragment_shader = getShaderSource(test_case_index, Utils::Shader::FRAGMENT);
5708 const std::string& geometry_shader = getShaderSource(test_case_index, Utils::Shader::GEOMETRY);
5709 const std::string& tess_ctrl_shader = getShaderSource(test_case_index, Utils::Shader::TESS_CTRL);
5710 const std::string& tess_eval_shader = getShaderSource(test_case_index, Utils::Shader::TESS_EVAL);
5711 const std::string& vertex_shader = getShaderSource(test_case_index, Utils::Shader::VERTEX);
5713 /* Set up program */
5714 program.Init("" /* compute_shader */, fragment_shader, geometry_shader, tess_ctrl_shader, tess_eval_shader,
5715 vertex_shader, captured_varyings, true, false /* is_separable */);
5719 std::stringstream stream;
5720 if (false == inspectProgram(test_case_index, program, stream))
5722 m_context.getTestContext().getLog()
5723 << tcu::TestLog::Message
5724 << "Program inspection failed. Test case: " << getTestCaseName(test_case_index)
5725 << ". Reason: " << stream.str() << tcu::TestLog::EndMessage
5726 << tcu::TestLog::KernelSource(vertex_shader) << tcu::TestLog::KernelSource(tess_ctrl_shader)
5727 << tcu::TestLog::KernelSource(tess_eval_shader) << tcu::TestLog::KernelSource(geometry_shader)
5728 << tcu::TestLog::KernelSource(fragment_shader);
5736 /* Set up buffers */
5737 getBufferDescriptors(test_case_index, descriptors);
5739 prepareBuffers(descriptors, buffers);
5746 bool result = executeDrawCall((program.m_tess_eval.m_id != 0), test_case_index);
5749 m_context.getRenderContext().postIterate();
5752 if (false == result)
5754 m_context.getTestContext().getLog()
5755 << tcu::TestLog::KernelSource(vertex_shader) << tcu::TestLog::KernelSource(tess_ctrl_shader)
5756 << tcu::TestLog::KernelSource(tess_eval_shader) << tcu::TestLog::KernelSource(geometry_shader)
5757 << tcu::TestLog::KernelSource(fragment_shader);
5763 if (false == verifyBuffers(buffers))
5765 m_context.getTestContext().getLog()
5766 << tcu::TestLog::KernelSource(vertex_shader) << tcu::TestLog::KernelSource(tess_ctrl_shader)
5767 << tcu::TestLog::KernelSource(tess_eval_shader) << tcu::TestLog::KernelSource(geometry_shader)
5768 << tcu::TestLog::KernelSource(fragment_shader);
5773 catch (Utils::Shader::InvalidSourceException& exc)
5776 TCU_FAIL(exc.what());
5778 catch (Utils::Program::BuildException& exc)
5781 TCU_FAIL(exc.what());
5788 /** Verify contents of buffers
5790 * @param buffers Collection of buffers to be verified
5792 * @return true if everything is as expected, false otherwise
5794 bool BufferTestBase::verifyBuffers(bufferCollection& buffers)
5798 for (bufferCollection::Vector::iterator it = buffers.m_vector.begin(), end = buffers.m_vector.end(); end != it;
5801 bufferCollection::pair& pair = *it;
5802 Utils::Buffer* buffer = pair.m_buffer;
5803 bufferDescriptor* descriptor = pair.m_descriptor;
5804 size_t size = descriptor->m_expected_data.size();
5806 /* Skip buffers that have no expected data */
5812 /* Get pointer to contents of buffer */
5814 GLvoid* buffer_data = buffer->Map(Utils::Buffer::ReadOnly);
5816 /* Get pointer to expected data */
5817 GLvoid* expected_data = &descriptor->m_expected_data[0];
5820 int res = memcmp(buffer_data, expected_data, size);
5824 m_context.getTestContext().getLog()
5825 << tcu::TestLog::Message
5826 << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
5827 << ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
5832 /* Release buffer mapping */
5839 /** Unbinds all uniforms and xfb
5842 void BufferTestBase::cleanBuffers()
5844 const Functions& gl = m_context.getRenderContext().getFunctions();
5849 gl.getIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &max_uni);
5850 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_xfb);
5851 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
5853 for (GLint i = 0; i < max_uni; ++i)
5855 Utils::Buffer::BindBase(gl, 0, Utils::Buffer::Uniform, i);
5858 for (GLint i = 0; i < max_xfb; ++i)
5860 Utils::Buffer::BindBase(gl, 0, Utils::Buffer::Transform_feedback, i);
5864 /** Get template of shader for given stage
5866 * @param stage Stage
5868 * @return Template of shader source
5870 std::string BufferTestBase::getShaderTemplate(Utils::Shader::STAGES stage)
5872 static const GLchar* compute_shader_template = "#version 430 core\n"
5873 "#extension GL_ARB_enhanced_layouts : require\n"
5875 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
5877 "writeonly uniform uimage2D uni_image;\n"
5889 static const GLchar* fragment_shader_template = "#version 430 core\n"
5890 "#extension GL_ARB_enhanced_layouts : require\n"
5902 // max_vertices is set to 3 for the test case "xfb_vertex_streams" declares 3 streams in geometry shader,
5903 // according to spec, max_vertices should be no less than 3 if there are 3 streams in GS.
5904 static const GLchar* geometry_shader_template = "#version 430 core\n"
5905 "#extension GL_ARB_enhanced_layouts : require\n"
5907 "layout(points) in;\n"
5908 "layout(points, max_vertices = 3) out;\n"
5918 " gl_Position = vec4(0, 0, 0, 1);\n"
5923 static const GLchar* tess_ctrl_shader_template = "#version 430 core\n"
5924 "#extension GL_ARB_enhanced_layouts : require\n"
5926 "layout(vertices = 1) out;\n"
5936 " gl_TessLevelOuter[0] = 1.0;\n"
5937 " gl_TessLevelOuter[1] = 1.0;\n"
5938 " gl_TessLevelOuter[2] = 1.0;\n"
5939 " gl_TessLevelOuter[3] = 1.0;\n"
5940 " gl_TessLevelInner[0] = 1.0;\n"
5941 " gl_TessLevelInner[1] = 1.0;\n"
5945 static const GLchar* tess_eval_shader_template = "#version 430 core\n"
5946 "#extension GL_ARB_enhanced_layouts : require\n"
5948 "layout(isolines, point_mode) in;\n"
5960 static const GLchar* vertex_shader_template = "#version 430 core\n"
5961 "#extension GL_ARB_enhanced_layouts : require\n"
5973 const GLchar* result = 0;
5977 case Utils::Shader::COMPUTE:
5978 result = compute_shader_template;
5980 case Utils::Shader::FRAGMENT:
5981 result = fragment_shader_template;
5983 case Utils::Shader::GEOMETRY:
5984 result = geometry_shader_template;
5986 case Utils::Shader::TESS_CTRL:
5987 result = tess_ctrl_shader_template;
5989 case Utils::Shader::TESS_EVAL:
5990 result = tess_eval_shader_template;
5992 case Utils::Shader::VERTEX:
5993 result = vertex_shader_template;
5996 TCU_FAIL("Invalid enum");
6002 /** Prepare buffer according to descriptor
6004 * @param buffer Buffer to prepare
6005 * @param desc Descriptor
6007 void BufferTestBase::prepareBuffer(Utils::Buffer& buffer, bufferDescriptor& desc)
6009 GLsizeiptr size = 0;
6012 if (false == desc.m_initial_data.empty())
6014 size = desc.m_initial_data.size();
6015 data = &desc.m_initial_data[0];
6017 else if (false == desc.m_expected_data.empty())
6019 size = desc.m_expected_data.size();
6022 buffer.Init(desc.m_target, Utils::Buffer::StaticDraw, size, data);
6024 if (bufferDescriptor::m_non_indexed != desc.m_index)
6026 buffer.BindBase(desc.m_index);
6034 /** Prepare collection of buffer
6036 * @param descriptors Collection of descriptors
6037 * @param out_buffers Collection of buffers
6039 void BufferTestBase::prepareBuffers(bufferDescriptor::Vector& descriptors, bufferCollection& out_buffers)
6041 for (bufferDescriptor::Vector::iterator it = descriptors.begin(), end = descriptors.end(); end != it; ++it)
6043 bufferCollection::pair pair;
6045 pair.m_buffer = new Utils::Buffer(m_context);
6046 if (0 == pair.m_buffer)
6048 TCU_FAIL("Memory allocation failed");
6051 pair.m_descriptor = &(*it);
6053 prepareBuffer(*pair.m_buffer, *pair.m_descriptor);
6055 out_buffers.m_vector.push_back(pair);
6062 BufferTestBase::bufferCollection::~bufferCollection()
6064 for (Vector::iterator it = m_vector.begin(), end = m_vector.end(); end != it; ++it)
6066 if (0 != it->m_buffer)
6068 delete it->m_buffer;
6076 * @param context Test context
6077 * @param test_name Name of test
6078 * @param test_description Description of test
6080 NegativeTestBase::NegativeTestBase(deqp::Context& context, const GLchar* test_name, const GLchar* test_description)
6081 : TestBase(context, test_name, test_description)
6085 /** Selects if "compute" stage is relevant for test
6091 bool NegativeTestBase::isComputeRelevant(GLuint /* test_case_index */)
6096 /** Selects if compilation failure is expected result
6102 bool NegativeTestBase::isFailureExpected(GLuint /* test_case_index */)
6109 * @param test_case_index Id of test case
6111 * @return true if test case pass, false otherwise
6113 bool NegativeTestBase::testCase(GLuint test_case_index)
6115 bool test_case_result = true;
6118 if (true == isComputeRelevant(test_case_index))
6120 const std::string& cs_source = getShaderSource(test_case_index, Utils::Shader::COMPUTE);
6121 bool is_build_error = false;
6122 const bool is_failure_expected = isFailureExpected(test_case_index);
6123 Utils::Program program(m_context);
6127 program.Init(cs_source, "" /* fs */, "" /* gs */, "" /* tcs */, "" /* tes */, "" /* vs */,
6128 false /* separable */);
6130 catch (Utils::Shader::InvalidSourceException& exc)
6132 if (false == is_failure_expected)
6134 m_context.getTestContext().getLog()
6135 << tcu::TestLog::Message << "Unexpected error in shader compilation: " << tcu::TestLog::EndMessage;
6139 #if DEBUG_NEG_LOG_ERROR
6143 m_context.getTestContext().getLog()
6144 << tcu::TestLog::Message << "Error in shader compilation was expected, logged for verification: "
6145 << tcu::TestLog::EndMessage;
6149 #endif /* DEBUG_NEG_LOG_ERROR */
6151 is_build_error = true;
6153 catch (Utils::Program::BuildException& exc)
6155 if (false == is_failure_expected)
6157 m_context.getTestContext().getLog()
6158 << tcu::TestLog::Message << "Unexpected error in program linking: " << tcu::TestLog::EndMessage;
6162 #if DEBUG_NEG_LOG_ERROR
6166 m_context.getTestContext().getLog()
6167 << tcu::TestLog::Message
6168 << "Error in program linking was expected, logged for verification: " << tcu::TestLog::EndMessage;
6172 #endif /* DEBUG_NEG_LOG_ERROR */
6174 is_build_error = true;
6177 if (is_build_error != is_failure_expected)
6179 if (!is_build_error)
6181 m_context.getTestContext().getLog()
6182 << tcu::TestLog::Message << "Unexpected success: " << tcu::TestLog::EndMessage;
6183 Utils::Shader::LogSource(m_context, cs_source, Utils::Shader::COMPUTE);
6185 test_case_result = false;
6190 const std::string& fs_source = getShaderSource(test_case_index, Utils::Shader::FRAGMENT);
6191 const std::string& gs_source = getShaderSource(test_case_index, Utils::Shader::GEOMETRY);
6192 bool is_build_error = false;
6193 const bool is_failure_expected = isFailureExpected(test_case_index);
6194 Utils::Program program(m_context);
6195 const std::string& tcs_source = getShaderSource(test_case_index, Utils::Shader::TESS_CTRL);
6196 const std::string& tes_source = getShaderSource(test_case_index, Utils::Shader::TESS_EVAL);
6197 const std::string& vs_source = getShaderSource(test_case_index, Utils::Shader::VERTEX);
6201 program.Init("" /* cs */, fs_source, gs_source, tcs_source, tes_source, vs_source, false /* separable */);
6203 catch (Utils::Shader::InvalidSourceException& exc)
6205 if (false == is_failure_expected)
6207 m_context.getTestContext().getLog()
6208 << tcu::TestLog::Message << "Unexpected error in shader compilation: " << tcu::TestLog::EndMessage;
6212 #if DEBUG_NEG_LOG_ERROR
6216 m_context.getTestContext().getLog()
6217 << tcu::TestLog::Message << "Error in shader compilation was expected, logged for verification: "
6218 << tcu::TestLog::EndMessage;
6222 #endif /* DEBUG_NEG_LOG_ERROR */
6224 is_build_error = true;
6226 catch (Utils::Program::BuildException& exc)
6228 if (false == is_failure_expected)
6230 m_context.getTestContext().getLog()
6231 << tcu::TestLog::Message << "Unexpected error in program linking: " << tcu::TestLog::EndMessage;
6235 #if DEBUG_NEG_LOG_ERROR
6239 m_context.getTestContext().getLog()
6240 << tcu::TestLog::Message
6241 << "Error in program linking was expected, logged for verification: " << tcu::TestLog::EndMessage;
6245 #endif /* DEBUG_NEG_LOG_ERROR */
6247 is_build_error = true;
6250 if (is_build_error != is_failure_expected)
6252 if (!is_build_error)
6254 m_context.getTestContext().getLog()
6255 << tcu::TestLog::Message << "Unexpected success: " << tcu::TestLog::EndMessage;
6256 Utils::Shader::LogSource(m_context, vs_source, Utils::Shader::VERTEX);
6257 Utils::Shader::LogSource(m_context, tcs_source, Utils::Shader::TESS_CTRL);
6258 Utils::Shader::LogSource(m_context, tes_source, Utils::Shader::TESS_EVAL);
6259 Utils::Shader::LogSource(m_context, gs_source, Utils::Shader::GEOMETRY);
6260 Utils::Shader::LogSource(m_context, fs_source, Utils::Shader::FRAGMENT);
6262 test_case_result = false;
6266 return test_case_result;
6269 /* Constants used by TextureTestBase */
6270 const glw::GLuint TextureTestBase::m_width = 16;
6271 const glw::GLuint TextureTestBase::m_height = 16;
6275 * @param context Test context
6276 * @param test_name Name of test
6277 * @param test_description Description of test
6279 TextureTestBase::TextureTestBase(deqp::Context& context, const GLchar* test_name, const GLchar* test_description)
6280 : TestBase(context, test_name, test_description)
6284 /** Get locations for all inputs with automatic_location
6286 * @param program Program object
6287 * @param program_interface Interface of program
6289 void TextureTestBase::prepareAttribLocation(Utils::Program& program, Utils::ProgramInterface& program_interface)
6291 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
6293 Utils::Variable::PtrVector& inputs = si.m_inputs;
6295 for (Utils::Variable::PtrVector::iterator it = inputs.begin(); inputs.end() != it; ++it)
6297 /* Test does not specify location, query value and set */
6298 if (Utils::Variable::m_automatic_location == (*it)->m_descriptor.m_expected_location)
6300 GLuint index = program.GetResourceIndex((*it)->m_descriptor.m_name, GL_PROGRAM_INPUT);
6303 program.GetResource(GL_PROGRAM_INPUT, index, GL_LOCATION, 1 /* size */, &location);
6305 (*it)->m_descriptor.m_expected_location = location;
6310 /** Verifies contents of drawn image
6313 * @param color_0 Verified image
6315 * @return true if image is filled with 1, false otherwise
6317 bool TextureTestBase::checkResults(glw::GLuint /* test_case_index */, Utils::Texture& color_0)
6319 static const GLuint size = m_width * m_height;
6320 static const GLuint expected_color = 1;
6322 std::vector<GLuint> data;
6325 color_0.Get(GL_RED_INTEGER, GL_UNSIGNED_INT, &data[0]);
6327 for (GLuint i = 0; i < size; ++i)
6329 const GLuint color = data[i];
6331 if (expected_color != color)
6333 m_context.getTestContext().getLog() << tcu::TestLog::Message << "R32UI[" << i << "]:" << color
6334 << tcu::TestLog::EndMessage;
6342 /** Execute dispatch compute for 16x16x1
6346 void TextureTestBase::executeDispatchCall(GLuint /* test_case_index */)
6348 const Functions& gl = m_context.getRenderContext().getFunctions();
6350 gl.dispatchCompute(16 /* x */, 16 /* y */, 1 /* z */);
6351 GLU_EXPECT_NO_ERROR(gl.getError(), "DispatchCompute");
6354 /** Execute drawArrays for single vertex
6358 void TextureTestBase::executeDrawCall(GLuint /* test_case_index */)
6360 const Functions& gl = m_context.getRenderContext().getFunctions();
6362 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
6363 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
6366 /** Prepare code snippet that will pass in variables to out variables
6369 * @param varying_passthrough Collection of connections between in and out variables
6370 * @param stage Shader stage
6372 * @return Code that pass in variables to next stage
6374 std::string TextureTestBase::getPassSnippet(GLuint /* test_case_index */,
6375 Utils::VaryingPassthrough& varying_passthrough, Utils::Shader::STAGES stage)
6377 static const GLchar* separator = "\n ";
6379 /* Skip for compute shader */
6380 if (Utils::Shader::COMPUTE == stage)
6385 Utils::VaryingConnection::Vector& vector = varying_passthrough.Get(stage);
6387 std::string result = Utils::g_list;
6388 size_t position = 0;
6390 for (GLuint i = 0; i < vector.size(); ++i)
6393 Utils::VaryingConnection& connection = vector[i];
6395 Utils::Variable* in = connection.m_in;
6396 Utils::Variable* out = connection.m_out;
6398 Utils::Variable::FLAVOUR in_flavour = Utils::Variable::GetFlavour(stage, Utils::Variable::INPUT);
6399 Utils::Variable::FLAVOUR out_flavour = Utils::Variable::GetFlavour(stage, Utils::Variable::OUTPUT);
6401 const std::string passthrough =
6402 getVariablePassthrough("", in->m_descriptor, in_flavour, "", out->m_descriptor, out_flavour);
6404 Utils::insertElementOfList(passthrough.c_str(), separator, position, result);
6407 Utils::endList("", position, result);
6412 /** Basic implementation of method getProgramInterface
6418 void TextureTestBase::getProgramInterface(GLuint /* test_case_index */,
6419 Utils::ProgramInterface& /* program_interface */,
6420 Utils::VaryingPassthrough& /* varying_passthrough */)
6424 /** Prepare code snippet that will verify in and uniform variables
6427 * @param program_interface Interface of program
6428 * @param stage Shader stage
6430 * @return Code that verify variables
6432 std::string TextureTestBase::getVerificationSnippet(GLuint /* test_case_index */,
6433 Utils::ProgramInterface& program_interface,
6434 Utils::Shader::STAGES stage)
6436 static const GLchar* separator = " ||\n ";
6438 std::string verification = "if (LIST)\n"
6443 /* Get flavour of in and out variables */
6444 Utils::Variable::FLAVOUR in_flavour = Utils::Variable::GetFlavour(stage, Utils::Variable::INPUT);
6446 /* Get interface for shader stage */
6447 Utils::ShaderInterface& si = program_interface.GetShaderInterface(stage);
6449 /* There are no varialbes to verify */
6450 if ((0 == si.m_inputs.size()) && (0 == si.m_uniforms.size()) && (0 == si.m_ssb_blocks.size()))
6455 /* For each in variable insert verification code */
6456 size_t position = 0;
6458 for (GLuint i = 0; i < si.m_inputs.size(); ++i)
6460 const Utils::Variable& var = *si.m_inputs[i];
6461 const std::string& var_verification = getVariableVerification("", var.m_data, var.m_descriptor, in_flavour);
6463 Utils::insertElementOfList(var_verification.c_str(), separator, position, verification);
6466 /* For each unifrom variable insert verification code */
6467 for (GLuint i = 0; i < si.m_uniforms.size(); ++i)
6469 const Utils::Variable& var = *si.m_uniforms[i];
6470 const std::string& var_verification =
6471 getVariableVerification("", var.m_data, var.m_descriptor, Utils::Variable::BASIC);
6473 Utils::insertElementOfList(var_verification.c_str(), separator, position, verification);
6476 /* For each ssb variable insert verification code */
6477 for (GLuint i = 0; i < si.m_ssb_blocks.size(); ++i)
6479 const Utils::Variable& var = *si.m_ssb_blocks[i];
6480 const std::string& var_verification =
6481 getVariableVerification("", var.m_data, var.m_descriptor, Utils::Variable::BASIC);
6483 Utils::insertElementOfList(var_verification.c_str(), separator, position, verification);
6486 Utils::endList("", position, verification);
6488 #if DEBUG_TTB_VERIFICATION_SNIPPET_STAGE
6492 sprintf(buffer, "%d", stage + 10);
6493 Utils::replaceToken("0u", position, buffer, verification);
6496 #elif DEBUG_TTB_VERIFICATION_SNIPPET_VARIABLE
6498 if (Utils::Shader::VERTEX == stage)
6500 Utils::replaceToken("0u", position, "in_vs_first.x", verification);
6504 Utils::replaceToken("0u", position, "31u", verification);
6510 return verification;
6513 /** Selects if "compute" stage is relevant for test
6519 bool TextureTestBase::isComputeRelevant(GLuint /* test_case_index */)
6524 /** Selects if "draw" stages are relevant for test
6530 bool TextureTestBase::isDrawRelevant(GLuint /* test_case_index */)
6535 /** Prepare code that will do assignment of single in to single out
6537 * @param in_parent_name Name of parent in variable
6538 * @param in_variable Descriptor of in variable
6539 * @param in_flavour Flavoud of in variable
6540 * @param out_parent_name Name of parent out variable
6541 * @param out_variable Descriptor of out variable
6542 * @param out_flavour Flavoud of out variable
6544 * @return Code that does OUT = IN
6546 std::string TextureTestBase::getVariablePassthrough(const std::string& in_parent_name,
6547 const Utils::Variable::Descriptor& in_variable,
6548 Utils::Variable::FLAVOUR in_flavour,
6549 const std::string& out_parent_name,
6550 const Utils::Variable::Descriptor& out_variable,
6551 Utils::Variable::FLAVOUR out_flavour)
6555 GLuint member_index = 0;
6556 size_t position = 0;
6557 std::string result = Utils::g_list;
6558 static const GLchar* separator = ";\n ";
6560 /* For each member of each array element */
6563 const std::string in_name = Utils::Variable::GetReference(in_parent_name, in_variable, in_flavour, index);
6564 const std::string out_name = Utils::Variable::GetReference(out_parent_name, out_variable, out_flavour, index);
6565 std::string passthrough;
6567 /* Prepare verification */
6568 if (Utils::Variable::BUILTIN == in_variable.m_type)
6570 size_t pass_position = 0;
6572 passthrough = "OUT = IN;";
6574 Utils::replaceToken("OUT", pass_position, out_name.c_str(), passthrough);
6575 Utils::replaceToken("IN", pass_position, in_name.c_str(), passthrough);
6577 /* Increment index */
6582 const Utils::Interface* in_interface = in_variable.m_interface;
6583 const Utils::Interface* out_interface = out_variable.m_interface;
6585 if ((0 == in_interface) || (0 == out_interface))
6587 TCU_FAIL("Nullptr");
6590 const Utils::Variable::Descriptor& in_member = in_interface->m_members[member_index];
6591 const Utils::Variable::Descriptor& out_member = out_interface->m_members[member_index];
6593 passthrough = getVariablePassthrough(in_name, in_member, Utils::Variable::BASIC, out_name, out_member,
6594 Utils::Variable::BASIC);
6596 /* Increment member_index */
6599 /* Increment index and reset member_index if all members were processed */
6600 if (in_interface->m_members.size() == member_index)
6607 /* Check if loop should end */
6608 if ((index >= in_variable.m_n_array_elements) && (0 == member_index))
6613 Utils::insertElementOfList(passthrough.c_str(), separator, position, result);
6615 } while (true != done);
6617 Utils::endList("", position, result);
6623 /** Get verification of single variable
6625 * @param parent_name Name of parent variable
6626 * @param data Data that should be used as EXPECTED
6627 * @param variable Descriptor of variable
6628 * @param flavour Flavour of variable
6630 * @return Code that does (EXPECTED != VALUE) ||
6632 std::string TextureTestBase::getVariableVerification(const std::string& parent_name, const GLvoid* data,
6633 const Utils::Variable::Descriptor& variable,
6634 Utils::Variable::FLAVOUR flavour)
6636 static const GLchar* logic_op = " ||\n ";
6637 const GLuint n_elements = (0 == variable.m_n_array_elements) ? 1 : variable.m_n_array_elements;
6638 size_t position = 0;
6639 std::string result = Utils::g_list;
6640 GLint stride = variable.m_expected_stride_of_element;
6642 /* For each each array element */
6643 for (GLuint element = 0; element < n_elements; ++element)
6645 const std::string name = Utils::Variable::GetReference(parent_name, variable, flavour, element);
6647 /* Calculate data pointer */
6648 GLvoid* data_ptr = (GLvoid*)((GLubyte*)data + element * stride);
6650 /* Prepare verification */
6651 if (Utils::Variable::BUILTIN == variable.m_type)
6653 const std::string& expected = variable.m_builtin.GetGLSLConstructor(data_ptr);
6654 std::string verification;
6655 size_t verification_position = 0;
6657 verification = "(EXPECTED != NAME)";
6659 Utils::replaceToken("EXPECTED", verification_position, expected.c_str(), verification);
6660 Utils::replaceToken("NAME", verification_position, name.c_str(), verification);
6662 Utils::insertElementOfList(verification.c_str(), logic_op, position, result);
6666 const Utils::Interface* interface = variable.m_interface;
6670 TCU_FAIL("Nullptr");
6673 const GLuint n_members = static_cast<GLuint>(interface->m_members.size());
6675 /* for each member */
6676 for (GLuint member_index = 0; member_index < n_members; ++member_index)
6678 const Utils::Variable::Descriptor& member = interface->m_members[member_index];
6680 /* Get verification of member */
6681 const std::string& verification =
6682 getVariableVerification(name, (GLubyte*)data_ptr + member.m_offset, member, Utils::Variable::BASIC);
6684 Utils::insertElementOfList(verification.c_str(), logic_op, position, result);
6689 Utils::endList("", position, result);
6694 /** Prepare attributes, vertex array object and array buffer
6696 * @param test_case_index Index of test case
6697 * @param program_interface Interface of program
6698 * @param buffer Array buffer
6699 * @param vao Vertex array object
6701 void TextureTestBase::prepareAttributes(GLuint test_case_index, Utils::ProgramInterface& program_interface,
6702 Utils::Buffer& buffer, Utils::VertexArray& vao)
6704 bool use_component_qualifier = useComponentQualifier(test_case_index);
6706 /* Get shader interface */
6707 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
6709 /* Bind vao and buffer */
6713 /* Skip if there are no input variables in vertex shader */
6714 if (0 == si.m_inputs.size())
6719 /* Calculate vertex stride and check */
6720 GLint vertex_stride = 0;
6722 for (GLuint i = 0; i < si.m_inputs.size(); ++i)
6724 Utils::Variable& variable = *si.m_inputs[i];
6726 GLint variable_size = static_cast<GLuint>(variable.m_data_size);
6728 GLint ends_at = variable_size + variable.m_descriptor.m_offset;
6730 vertex_stride = std::max(vertex_stride, ends_at);
6733 /* Prepare buffer data and set up vao */
6734 std::vector<GLubyte> buffer_data;
6735 buffer_data.resize(vertex_stride);
6737 GLubyte* ptr = &buffer_data[0];
6739 for (GLuint i = 0; i < si.m_inputs.size(); ++i)
6741 Utils::Variable& variable = *si.m_inputs[i];
6743 memcpy(ptr + variable.m_descriptor.m_offset, variable.m_data, variable.m_data_size);
6745 if (false == use_component_qualifier)
6747 vao.Attribute(variable.m_descriptor.m_expected_location, variable.m_descriptor.m_builtin,
6748 variable.m_descriptor.m_n_array_elements, variable.m_descriptor.m_normalized,
6749 variable.GetStride(), (GLvoid*)(intptr_t)variable.m_descriptor.m_offset);
6751 else if (0 == variable.m_descriptor.m_expected_component)
6753 /* Components can only be applied to vectors.
6754 Assumption that test use all 4 components */
6755 const Utils::Type& type =
6756 Utils::Type::GetType(variable.m_descriptor.m_builtin.m_basic_type, 1 /* n_columns */, 4 /* n_rows */);
6758 vao.Attribute(variable.m_descriptor.m_expected_location, type, variable.m_descriptor.m_n_array_elements,
6759 variable.m_descriptor.m_normalized, variable.GetStride(),
6760 (GLvoid*)(intptr_t)variable.m_descriptor.m_offset);
6765 buffer.Data(Utils::Buffer::StaticDraw, vertex_stride, ptr);
6768 /** Get locations for all outputs with automatic_location
6770 * @param program Program object
6771 * @param program_interface Interface of program
6773 void TextureTestBase::prepareFragmentDataLoc(Utils::Program& program, Utils::ProgramInterface& program_interface)
6775 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
6776 Utils::Variable::PtrVector& outputs = si.m_outputs;
6778 for (Utils::Variable::PtrVector::iterator it = outputs.begin(); outputs.end() != it; ++it)
6780 /* Test does not specify location, query value and set */
6781 if (Utils::Variable::m_automatic_location == (*it)->m_descriptor.m_expected_location)
6783 GLuint index = program.GetResourceIndex((*it)->m_descriptor.m_name, GL_PROGRAM_OUTPUT);
6786 program.GetResource(GL_PROGRAM_OUTPUT, index, GL_LOCATION, 1 /* size */, &location);
6788 (*it)->m_descriptor.m_expected_location = location;
6793 /** Prepare framebuffer with single texture as color attachment
6795 * @param framebuffer Framebuffer
6796 * @param color_0_texture Texture that will used as color attachment
6798 void TextureTestBase::prepareFramebuffer(Utils::Framebuffer& framebuffer, Utils::Texture& color_0_texture)
6801 std::vector<GLuint> texture_data;
6802 texture_data.resize(m_width * m_height);
6804 for (GLuint i = 0; i < texture_data.size(); ++i)
6806 texture_data[i] = 0x20406080;
6809 /* Prepare texture */
6810 color_0_texture.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT,
6813 /* Prepare framebuffer */
6816 framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0, color_0_texture.m_id, m_width, m_height);
6818 framebuffer.ClearColor(0.0f, 0.0f, 0.0f, 0.0f);
6819 framebuffer.Clear(GL_COLOR_BUFFER_BIT);
6822 /** Prepare iamge unit for compute shader
6824 * @param location Uniform location
6825 * @param image_texture Texture that will used as color attachment
6827 void TextureTestBase::prepareImage(GLint location, Utils::Texture& image_texture) const
6829 static const GLuint image_unit = 0;
6831 std::vector<GLuint> texture_data;
6832 texture_data.resize(m_width * m_height);
6834 for (GLuint i = 0; i < texture_data.size(); ++i)
6836 texture_data[i] = 0x20406080;
6839 image_texture.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT,
6842 const Functions& gl = m_context.getRenderContext().getFunctions();
6844 gl.bindImageTexture(image_unit, image_texture.m_id, 0 /* level */, GL_FALSE /* layered */, 0 /* Layer */,
6845 GL_WRITE_ONLY, GL_R32UI);
6846 GLU_EXPECT_NO_ERROR(gl.getError(), "BindImageTexture");
6848 Utils::Program::Uniform(gl, Utils::Type::_int, 1 /* count */, location, &image_unit);
6851 /** Basic implementation
6854 * @param si Shader interface
6855 * @param program Program
6856 * @param cs_buffer Buffer for ssb blocks
6858 void TextureTestBase::prepareSSBs(GLuint /* test_case_index */, Utils::ShaderInterface& si, Utils::Program& program,
6859 Utils::Buffer& buffer)
6861 /* Skip if there are no input variables in vertex shader */
6862 if (0 == si.m_ssb_blocks.size())
6867 /* Calculate vertex stride */
6868 GLint ssbs_stride = 0;
6870 for (GLuint i = 0; i < si.m_ssb_blocks.size(); ++i)
6872 Utils::Variable& variable = *si.m_ssb_blocks[i];
6874 if (false == variable.IsBlock())
6879 GLint variable_stride = variable.GetStride();
6881 GLint ends_at = variable_stride + variable.m_descriptor.m_offset;
6883 ssbs_stride = std::max(ssbs_stride, ends_at);
6886 /* Set active program */
6891 buffer.Data(Utils::Buffer::StaticDraw, ssbs_stride, 0);
6893 /* Set up uniforms */
6894 for (GLuint i = 0; i < si.m_ssb_blocks.size(); ++i)
6896 Utils::Variable& variable = *si.m_ssb_blocks[i];
6898 /* prepareUnifor should work fine for ssb blocks */
6899 prepareUniform(program, variable, buffer);
6903 /** Basic implementation
6905 * @param test_case_index Test case index
6906 * @param program_interface Program interface
6907 * @param program Program
6908 * @param cs_buffer Buffer for compute shader stage
6910 void TextureTestBase::prepareSSBs(GLuint test_case_index, Utils::ProgramInterface& program_interface,
6911 Utils::Program& program, Utils::Buffer& cs_buffer)
6913 cs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
6915 Utils::ShaderInterface& cs = program_interface.GetShaderInterface(Utils::Shader::COMPUTE);
6917 prepareSSBs(test_case_index, cs, program, cs_buffer);
6919 cs_buffer.BindBase(Utils::Shader::COMPUTE);
6922 /** Basic implementation
6924 * @param test_case_index Test case index
6925 * @param program_interface Program interface
6926 * @param program Program
6927 * @param fs_buffer Buffer for fragment shader stage
6928 * @param gs_buffer Buffer for geometry shader stage
6929 * @param tcs_buffer Buffer for tessellation control shader stage
6930 * @param tes_buffer Buffer for tessellation evaluation shader stage
6931 * @param vs_buffer Buffer for vertex shader stage
6933 void TextureTestBase::prepareSSBs(GLuint test_case_index, Utils::ProgramInterface& program_interface,
6934 Utils::Program& program, Utils::Buffer& fs_buffer, Utils::Buffer& gs_buffer,
6935 Utils::Buffer& tcs_buffer, Utils::Buffer& tes_buffer, Utils::Buffer& vs_buffer)
6937 fs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
6938 gs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
6939 tcs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
6940 tes_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
6941 vs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
6943 Utils::ShaderInterface& fs = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
6944 Utils::ShaderInterface& gs = program_interface.GetShaderInterface(Utils::Shader::GEOMETRY);
6945 Utils::ShaderInterface& tcs = program_interface.GetShaderInterface(Utils::Shader::TESS_CTRL);
6946 Utils::ShaderInterface& tes = program_interface.GetShaderInterface(Utils::Shader::TESS_EVAL);
6947 Utils::ShaderInterface& vs = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
6949 prepareSSBs(test_case_index, fs, program, fs_buffer);
6950 prepareSSBs(test_case_index, gs, program, gs_buffer);
6951 prepareSSBs(test_case_index, tcs, program, tcs_buffer);
6952 prepareSSBs(test_case_index, tes, program, tes_buffer);
6953 prepareSSBs(test_case_index, vs, program, vs_buffer);
6955 fs_buffer.BindBase(Utils::Shader::FRAGMENT);
6956 gs_buffer.BindBase(Utils::Shader::GEOMETRY);
6957 tcs_buffer.BindBase(Utils::Shader::TESS_CTRL);
6958 tes_buffer.BindBase(Utils::Shader::TESS_EVAL);
6959 vs_buffer.BindBase(Utils::Shader::VERTEX);
6962 /** Updates buffer data with variable
6964 * @param program Program object
6965 * @param variable Variable
6966 * @param buffer Buffer
6968 void TextureTestBase::prepareUniform(Utils::Program& program, Utils::Variable& variable, Utils::Buffer& buffer)
6970 const Functions& gl = m_context.getRenderContext().getFunctions();
6972 GLsizei count = variable.m_descriptor.m_n_array_elements;
6978 if (Utils::Variable::BUILTIN == variable.m_descriptor.m_type)
6980 program.Uniform(gl, variable.m_descriptor.m_builtin, count, variable.m_descriptor.m_expected_location,
6985 const bool is_block = variable.IsBlock();
6987 if (false == is_block)
6989 TCU_FAIL("Not implemented");
6993 buffer.SubData(variable.m_descriptor.m_offset, variable.m_descriptor.m_expected_stride_of_element * count,
6999 /** Basic implementation
7002 * @param si Shader interface
7003 * @param program Program
7004 * @param cs_buffer Buffer for uniform blocks
7006 void TextureTestBase::prepareUniforms(GLuint /* test_case_index */, Utils::ShaderInterface& si, Utils::Program& program,
7007 Utils::Buffer& buffer)
7009 /* Skip if there are no input variables in vertex shader */
7010 if (0 == si.m_uniforms.size())
7015 /* Calculate vertex stride */
7016 GLint uniforms_stride = 0;
7018 for (GLuint i = 0; i < si.m_uniforms.size(); ++i)
7020 Utils::Variable& variable = *si.m_uniforms[i];
7022 if (false == variable.IsBlock())
7027 GLint variable_stride = variable.GetStride();
7029 GLint ends_at = variable_stride + variable.m_descriptor.m_offset;
7031 uniforms_stride = std::max(uniforms_stride, ends_at);
7034 /* Set active program */
7039 buffer.Data(Utils::Buffer::StaticDraw, uniforms_stride, 0);
7041 /* Set up uniforms */
7042 for (GLuint i = 0; i < si.m_uniforms.size(); ++i)
7044 Utils::Variable& variable = *si.m_uniforms[i];
7046 prepareUniform(program, variable, buffer);
7050 /** Basic implementation
7052 * @param test_case_index Test case index
7053 * @param program_interface Program interface
7054 * @param program Program
7055 * @param cs_buffer Buffer for compute shader stage
7057 void TextureTestBase::prepareUniforms(GLuint test_case_index, Utils::ProgramInterface& program_interface,
7058 Utils::Program& program, Utils::Buffer& cs_buffer)
7060 cs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7062 Utils::ShaderInterface& cs = program_interface.GetShaderInterface(Utils::Shader::COMPUTE);
7064 prepareUniforms(test_case_index, cs, program, cs_buffer);
7066 cs_buffer.BindBase(Utils::Shader::COMPUTE);
7069 /** Basic implementation
7071 * @param test_case_index Test case index
7072 * @param program_interface Program interface
7073 * @param program Program
7074 * @param fs_buffer Buffer for fragment shader stage
7075 * @param gs_buffer Buffer for geometry shader stage
7076 * @param tcs_buffer Buffer for tessellation control shader stage
7077 * @param tes_buffer Buffer for tessellation evaluation shader stage
7078 * @param vs_buffer Buffer for vertex shader stage
7080 void TextureTestBase::prepareUniforms(GLuint test_case_index, Utils::ProgramInterface& program_interface,
7081 Utils::Program& program, Utils::Buffer& fs_buffer, Utils::Buffer& gs_buffer,
7082 Utils::Buffer& tcs_buffer, Utils::Buffer& tes_buffer, Utils::Buffer& vs_buffer)
7084 fs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7085 gs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7086 tcs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7087 tes_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7088 vs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7090 Utils::ShaderInterface& fs = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
7091 Utils::ShaderInterface& gs = program_interface.GetShaderInterface(Utils::Shader::GEOMETRY);
7092 Utils::ShaderInterface& tcs = program_interface.GetShaderInterface(Utils::Shader::TESS_CTRL);
7093 Utils::ShaderInterface& tes = program_interface.GetShaderInterface(Utils::Shader::TESS_EVAL);
7094 Utils::ShaderInterface& vs = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
7096 prepareUniforms(test_case_index, fs, program, fs_buffer);
7097 prepareUniforms(test_case_index, gs, program, gs_buffer);
7098 prepareUniforms(test_case_index, tcs, program, tcs_buffer);
7099 prepareUniforms(test_case_index, tes, program, tes_buffer);
7100 prepareUniforms(test_case_index, vs, program, vs_buffer);
7102 fs_buffer.BindBase(Utils::Shader::FRAGMENT);
7103 gs_buffer.BindBase(Utils::Shader::GEOMETRY);
7104 tcs_buffer.BindBase(Utils::Shader::TESS_CTRL);
7105 tes_buffer.BindBase(Utils::Shader::TESS_EVAL);
7106 vs_buffer.BindBase(Utils::Shader::VERTEX);
7109 /** Basic implementation
7111 * @param test_case_index Test case index
7112 * @param program_interface Program interface
7113 * @param program Program
7114 * @param fs_buffer Buffer for fragment shader stage
7115 * @param gs_buffer Buffer for geometry shader stage
7116 * @param tcs_buffer Buffer for tessellation control shader stage
7117 * @param tes_buffer Buffer for tessellation evaluation shader stage
7118 * @param vs_buffer Buffer for vertex shader stage
7120 void TextureTestBase::prepareUniforms(GLuint test_case_index, Utils::ProgramInterface& program_interface,
7121 Utils::Program& fs_program, Utils::Program& gs_program,
7122 Utils::Program& tcs_program, Utils::Program& tes_program,
7123 Utils::Program& vs_program, Utils::Buffer& fs_buffer, Utils::Buffer& gs_buffer,
7124 Utils::Buffer& tcs_buffer, Utils::Buffer& tes_buffer, Utils::Buffer& vs_buffer)
7126 fs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7127 gs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7128 tcs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7129 tes_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7130 vs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7132 Utils::ShaderInterface& fs = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
7133 Utils::ShaderInterface& gs = program_interface.GetShaderInterface(Utils::Shader::GEOMETRY);
7134 Utils::ShaderInterface& tcs = program_interface.GetShaderInterface(Utils::Shader::TESS_CTRL);
7135 Utils::ShaderInterface& tes = program_interface.GetShaderInterface(Utils::Shader::TESS_EVAL);
7136 Utils::ShaderInterface& vs = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
7138 prepareUniforms(test_case_index, fs, fs_program, fs_buffer);
7139 fs_buffer.BindBase(Utils::Shader::FRAGMENT);
7141 prepareUniforms(test_case_index, gs, gs_program, gs_buffer);
7142 gs_buffer.BindBase(Utils::Shader::GEOMETRY);
7144 prepareUniforms(test_case_index, tcs, tcs_program, tcs_buffer);
7145 tcs_buffer.BindBase(Utils::Shader::TESS_CTRL);
7147 prepareUniforms(test_case_index, tes, tes_program, tes_buffer);
7148 tes_buffer.BindBase(Utils::Shader::TESS_EVAL);
7150 prepareUniforms(test_case_index, vs, vs_program, vs_buffer);
7151 vs_buffer.BindBase(Utils::Shader::VERTEX);
7154 /** Prepare source for shader
7156 * @param test_case_index Index of test case
7157 * @param program_interface Interface of program
7158 * @param varying_passthrough Collection of connection between in and out variables
7159 * @param stage Shader stage
7161 * @return Source of shader
7163 std::string TextureTestBase::getShaderSource(GLuint test_case_index, Utils::ProgramInterface& program_interface,
7164 Utils::VaryingPassthrough& varying_passthrough,
7165 Utils::Shader::STAGES stage)
7168 const GLchar* shader_template = getShaderTemplate(stage);
7169 const std::string& shader_interface = program_interface.GetInterfaceForStage(stage);
7171 const std::string& verification = getVerificationSnippet(test_case_index, program_interface, stage);
7173 const std::string& passthrough = getPassSnippet(test_case_index, varying_passthrough, stage);
7175 const GLchar* per_vertex = "";
7177 std::string source = shader_template;
7178 size_t position = 0;
7180 /* Replace tokens in template */
7181 if (Utils::Shader::GEOMETRY == stage)
7183 if (false == useMonolithicProgram(test_case_index))
7185 per_vertex = "out gl_PerVertex {\n"
7186 "vec4 gl_Position;\n"
7191 Utils::replaceToken("PERVERTEX", position, per_vertex, source);
7194 Utils::replaceToken("INTERFACE", position, shader_interface.c_str(), source);
7195 Utils::replaceToken("VERIFICATION", position, verification.c_str(), source);
7197 if (false == verification.empty())
7199 Utils::replaceAllTokens("ELSE", " else ", source);
7203 Utils::replaceAllTokens("ELSE", "", source);
7206 Utils::replaceAllTokens("PASSTHROUGH", passthrough.c_str(), source);
7212 /** Returns template of shader for given stage
7214 * @param stage Shade stage
7216 * @return Proper template
7218 const GLchar* TextureTestBase::getShaderTemplate(Utils::Shader::STAGES stage)
7221 static const GLchar* compute_shader_template =
7222 "#version 430 core\n"
7223 "#extension GL_ARB_enhanced_layouts : require\n"
7225 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
7227 "writeonly uniform uimage2D uni_image;\n"
7233 " uint result = 1u;\n"
7237 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), uvec4(result, 0, 0, 0));\n"
7241 static const GLchar* fragment_shader_template = "#version 430 core\n"
7242 "#extension GL_ARB_enhanced_layouts : require\n"
7244 "flat in uint gs_fs_result;\n"
7245 " out uint fs_out_result;\n"
7251 " uint result = 1u;\n"
7253 " if (1u != gs_fs_result)\n"
7255 " result = gs_fs_result;\n"
7259 " fs_out_result = result;\n"
7264 static const GLchar* geometry_shader_template =
7265 "#version 430 core\n"
7266 "#extension GL_ARB_enhanced_layouts : require\n"
7268 "layout(points) in;\n"
7269 "layout(triangle_strip, max_vertices = 4) out;\n"
7271 " in uint tes_gs_result[];\n"
7272 "flat out uint gs_fs_result;\n"
7274 "PERVERTEX" /* Separable programs require explicit declaration of gl_PerVertex */
7279 " uint result = 1u;\n"
7281 " if (1u != tes_gs_result[0])\n"
7283 " result = tes_gs_result[0];\n"
7287 " gs_fs_result = result;\n"
7289 " gl_Position = vec4(-1, -1, 0, 1);\n"
7291 " gs_fs_result = result;\n"
7293 " gl_Position = vec4(-1, 1, 0, 1);\n"
7295 " gs_fs_result = result;\n"
7297 " gl_Position = vec4(1, -1, 0, 1);\n"
7299 " gs_fs_result = result;\n"
7301 " gl_Position = vec4(1, 1, 0, 1);\n"
7306 static const GLchar* tess_ctrl_shader_template = "#version 430 core\n"
7307 "#extension GL_ARB_enhanced_layouts : require\n"
7309 "layout(vertices = 1) out;\n"
7311 "in uint vs_tcs_result[];\n"
7312 "out uint tcs_tes_result[];\n"
7318 " uint result = 1u;\n"
7320 " if (1u != vs_tcs_result[gl_InvocationID])\n"
7322 " result = vs_tcs_result[gl_InvocationID];\n"
7326 " tcs_tes_result[gl_InvocationID] = result;\n"
7330 " gl_TessLevelOuter[0] = 1.0;\n"
7331 " gl_TessLevelOuter[1] = 1.0;\n"
7332 " gl_TessLevelOuter[2] = 1.0;\n"
7333 " gl_TessLevelOuter[3] = 1.0;\n"
7334 " gl_TessLevelInner[0] = 1.0;\n"
7335 " gl_TessLevelInner[1] = 1.0;\n"
7339 static const GLchar* tess_eval_shader_template = "#version 430 core\n"
7340 "#extension GL_ARB_enhanced_layouts : require\n"
7342 "layout(isolines, point_mode) in;\n"
7344 "in uint tcs_tes_result[];\n"
7345 "out uint tes_gs_result;\n"
7351 " uint result = 1u;\n"
7353 " if (1 != tcs_tes_result[0])\n"
7355 " result = tcs_tes_result[0];\n"
7359 " tes_gs_result = result;\n"
7365 static const GLchar* vertex_shader_template = "#version 430 core\n"
7366 "#extension GL_ARB_enhanced_layouts : require\n"
7368 "out uint vs_tcs_result;\n"
7374 " uint result = 1u;\n"
7378 " vs_tcs_result = result;\n"
7384 const GLchar* result = 0;
7388 case Utils::Shader::COMPUTE:
7389 result = compute_shader_template;
7391 case Utils::Shader::FRAGMENT:
7392 result = fragment_shader_template;
7394 case Utils::Shader::GEOMETRY:
7395 result = geometry_shader_template;
7397 case Utils::Shader::TESS_CTRL:
7398 result = tess_ctrl_shader_template;
7400 case Utils::Shader::TESS_EVAL:
7401 result = tess_eval_shader_template;
7403 case Utils::Shader::VERTEX:
7404 result = vertex_shader_template;
7407 TCU_FAIL("Invalid enum");
7415 * @param test_case_index Id of test case
7417 * @return true if test case pass, false otherwise
7419 bool TextureTestBase::testCase(GLuint test_case_index)
7423 if (true == useMonolithicProgram(test_case_index))
7425 return testMonolithic(test_case_index);
7429 return testSeparable(test_case_index);
7432 catch (Utils::Shader::InvalidSourceException& exc)
7435 TCU_FAIL(exc.what());
7437 catch (Utils::Program::BuildException& exc)
7439 TCU_FAIL(exc.what());
7443 /** Runs "draw" test with monolithic program
7445 * @param test_case_index Id of test case
7447 bool TextureTestBase::testMonolithic(GLuint test_case_index)
7449 Utils::ProgramInterface program_interface;
7450 Utils::VaryingPassthrough varying_passthrough;
7453 const std::string& test_name = getTestCaseName(test_case_index);
7456 getProgramInterface(test_case_index, program_interface, varying_passthrough);
7460 if (true == isDrawRelevant(test_case_index))
7462 Utils::Buffer buffer_attr(m_context);
7463 Utils::Buffer buffer_ssb_fs(m_context);
7464 Utils::Buffer buffer_ssb_gs(m_context);
7465 Utils::Buffer buffer_ssb_tcs(m_context);
7466 Utils::Buffer buffer_ssb_tes(m_context);
7467 Utils::Buffer buffer_ssb_vs(m_context);
7468 Utils::Buffer buffer_u_fs(m_context);
7469 Utils::Buffer buffer_u_gs(m_context);
7470 Utils::Buffer buffer_u_tcs(m_context);
7471 Utils::Buffer buffer_u_tes(m_context);
7472 Utils::Buffer buffer_u_vs(m_context);
7473 Utils::Framebuffer framebuffer(m_context);
7474 Utils::Program program(m_context);
7475 Utils::Texture texture_fb(m_context);
7476 Utils::VertexArray vao(m_context);
7479 const std::string& fragment_shader =
7480 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::FRAGMENT);
7481 const std::string& geometry_shader =
7482 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::GEOMETRY);
7483 const std::string& tess_ctrl_shader =
7484 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::TESS_CTRL);
7485 const std::string& tess_eval_shader =
7486 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::TESS_EVAL);
7487 const std::string& vertex_shader =
7488 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::VERTEX);
7490 program.Init("" /* compute_shader */, fragment_shader, geometry_shader, tess_ctrl_shader, tess_eval_shader,
7491 vertex_shader, false /* is_separable */);
7494 prepareAttribLocation(program, program_interface);
7495 prepareFragmentDataLoc(program, program_interface);
7498 std::stringstream stream;
7499 if (false == Utils::checkMonolithicDrawProgramInterface(program, program_interface, stream))
7501 m_context.getTestContext().getLog()
7502 << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7503 << ". Inspection of draw program interface failed:\n"
7504 << stream.str() << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(vertex_shader)
7505 << tcu::TestLog::KernelSource(tess_ctrl_shader) << tcu::TestLog::KernelSource(tess_eval_shader)
7506 << tcu::TestLog::KernelSource(geometry_shader) << tcu::TestLog::KernelSource(fragment_shader);
7515 buffer_attr.Init(Utils::Buffer::Array, Utils::Buffer::StaticDraw, 0, 0);
7517 prepareAttributes(test_case_index, program_interface, buffer_attr, vao);
7520 prepareUniforms(test_case_index, program_interface, program, buffer_u_fs, buffer_u_gs, buffer_u_tcs,
7521 buffer_u_tes, buffer_u_vs);
7523 prepareSSBs(test_case_index, program_interface, program, buffer_ssb_fs, buffer_ssb_gs, buffer_ssb_tcs,
7524 buffer_ssb_tes, buffer_ssb_vs);
7527 prepareFramebuffer(framebuffer, texture_fb);
7530 executeDrawCall(test_case_index);
7533 m_context.getRenderContext().postIterate();
7537 if (false == checkResults(test_case_index, texture_fb))
7539 m_context.getTestContext().getLog()
7540 << tcu::TestLog::Message << "FAILURE. Test case: " << test_name << ". Draw - invalid results."
7541 << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(vertex_shader)
7542 << tcu::TestLog::KernelSource(tess_ctrl_shader) << tcu::TestLog::KernelSource(tess_eval_shader)
7543 << tcu::TestLog::KernelSource(geometry_shader) << tcu::TestLog::KernelSource(fragment_shader);
7550 if (true == isComputeRelevant(test_case_index))
7552 Utils::Buffer buffer_ssb_cs(m_context);
7553 Utils::Buffer buffer_u_cs(m_context);
7554 Utils::Program program(m_context);
7555 Utils::Texture texture_im(m_context);
7556 Utils::VertexArray vao(m_context);
7559 const std::string& compute_shader =
7560 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::COMPUTE);
7562 program.Init(compute_shader, "" /* fragment_shader */, "" /* geometry_shader */, "" /* tess_ctrl_shader */,
7563 "" /* tess_eval_shader */, "" /* vertex_shader */, false /* is_separable */);
7567 std::stringstream stream;
7569 if (false == Utils::checkMonolithicComputeProgramInterface(program, program_interface, stream))
7571 m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7572 << ". Inspection of compute program interface failed:\n"
7573 << stream.str() << tcu::TestLog::EndMessage;
7587 prepareUniforms(test_case_index, program_interface, program, buffer_u_cs);
7589 prepareSSBs(test_case_index, program_interface, program, buffer_ssb_cs);
7592 GLint image_location = program.GetUniformLocation("uni_image");
7593 prepareImage(image_location, texture_im);
7596 executeDispatchCall(test_case_index);
7599 m_context.getRenderContext().postIterate();
7603 if (false == checkResults(test_case_index, texture_im))
7605 m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7606 << ". Compute - invalid results." << tcu::TestLog::EndMessage
7607 << tcu::TestLog::KernelSource(compute_shader);
7616 /** Runs "draw" test with separable program
7618 * @param test_case_index Id of test case
7620 bool TextureTestBase::testSeparable(GLuint test_case_index)
7622 Utils::ProgramInterface program_interface;
7623 Utils::VaryingPassthrough varying_passthrough;
7626 const std::string& test_name = getTestCaseName(test_case_index);
7629 getProgramInterface(test_case_index, program_interface, varying_passthrough);
7633 if (true == isDrawRelevant(test_case_index))
7635 Utils::Buffer buffer_attr(m_context);
7636 Utils::Buffer buffer_u_fs(m_context);
7637 Utils::Buffer buffer_u_gs(m_context);
7638 Utils::Buffer buffer_u_tcs(m_context);
7639 Utils::Buffer buffer_u_tes(m_context);
7640 Utils::Buffer buffer_u_vs(m_context);
7641 Utils::Framebuffer framebuffer(m_context);
7642 Utils::Pipeline pipeline(m_context);
7643 Utils::Program program_fs(m_context);
7644 Utils::Program program_gs(m_context);
7645 Utils::Program program_tcs(m_context);
7646 Utils::Program program_tes(m_context);
7647 Utils::Program program_vs(m_context);
7648 Utils::Texture texture_fb(m_context);
7649 Utils::VertexArray vao(m_context);
7652 const std::string& fs =
7653 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::FRAGMENT);
7654 const std::string& gs =
7655 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::GEOMETRY);
7656 const std::string& tcs =
7657 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::TESS_CTRL);
7658 const std::string& tes =
7659 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::TESS_EVAL);
7660 const std::string& vs =
7661 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::VERTEX);
7663 program_fs.Init("" /*cs*/, fs, "" /*gs*/, "" /*tcs*/, "" /*tes*/, "" /*vs*/, true /* is_separable */);
7664 program_gs.Init("" /*cs*/, "" /*fs*/, gs, "" /*tcs*/, "" /*tes*/, "" /*vs*/, true /* is_separable */);
7665 program_tcs.Init("" /*cs*/, "" /*fs*/, "" /*gs*/, tcs, "" /*tes*/, "" /*vs*/, true /* is_separable */);
7666 program_tes.Init("" /*cs*/, "" /*fs*/, "" /*gs*/, "" /*tcs*/, tes, "" /*vs*/, true /* is_separable */);
7667 program_vs.Init("" /*cs*/, "" /*fs*/, "" /*gs*/, "" /*tcs*/, "" /*tes*/, vs, true /* is_separable */);
7670 prepareAttribLocation(program_vs, program_interface);
7671 prepareFragmentDataLoc(program_vs, program_interface);
7674 std::stringstream stream;
7676 Utils::checkSeparableDrawProgramInterface(program_vs, program_interface, Utils::Shader::VERTEX, stream)) ||
7677 (false == Utils::checkSeparableDrawProgramInterface(program_fs, program_interface, Utils::Shader::FRAGMENT,
7679 (false == Utils::checkSeparableDrawProgramInterface(program_gs, program_interface, Utils::Shader::GEOMETRY,
7681 (false == Utils::checkSeparableDrawProgramInterface(program_tcs, program_interface,
7682 Utils::Shader::TESS_CTRL, stream)) ||
7683 (false == Utils::checkSeparableDrawProgramInterface(program_tes, program_interface,
7684 Utils::Shader::TESS_EVAL, stream)))
7686 m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7687 << ". Inspection of separable draw program interface failed:\n"
7688 << stream.str() << tcu::TestLog::EndMessage
7689 << tcu::TestLog::KernelSource(vs) << tcu::TestLog::KernelSource(tcs)
7690 << tcu::TestLog::KernelSource(tes) << tcu::TestLog::KernelSource(gs)
7691 << tcu::TestLog::KernelSource(fs);
7698 pipeline.UseProgramStages(program_fs.m_id, GL_FRAGMENT_SHADER_BIT);
7699 pipeline.UseProgramStages(program_gs.m_id, GL_GEOMETRY_SHADER_BIT);
7700 pipeline.UseProgramStages(program_tcs.m_id, GL_TESS_CONTROL_SHADER_BIT);
7701 pipeline.UseProgramStages(program_tes.m_id, GL_TESS_EVALUATION_SHADER_BIT);
7702 pipeline.UseProgramStages(program_vs.m_id, GL_VERTEX_SHADER_BIT);
7707 buffer_attr.Init(Utils::Buffer::Array, Utils::Buffer::StaticDraw, 0, 0);
7709 prepareAttributes(test_case_index, program_interface, buffer_attr, vao);
7712 prepareUniforms(test_case_index, program_interface, program_fs, program_gs, program_tcs, program_tes,
7713 program_vs, buffer_u_fs, buffer_u_gs, buffer_u_tcs, buffer_u_tes, buffer_u_vs);
7715 Utils::Program::Use(m_context.getRenderContext().getFunctions(), Utils::Program::m_invalid_id);
7718 prepareFramebuffer(framebuffer, texture_fb);
7721 executeDrawCall(test_case_index);
7724 m_context.getRenderContext().postIterate();
7728 if (false == checkResults(test_case_index, texture_fb))
7730 m_context.getTestContext().getLog()
7731 << tcu::TestLog::Message << "FAILURE. Test case: " << test_name << ". Draw - invalid results."
7732 << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(vs) << tcu::TestLog::KernelSource(tcs)
7733 << tcu::TestLog::KernelSource(tes) << tcu::TestLog::KernelSource(gs) << tcu::TestLog::KernelSource(fs);
7740 if (true == isComputeRelevant(test_case_index))
7742 Utils::Buffer buffer_u_cs(m_context);
7743 Utils::Program program(m_context);
7744 Utils::Texture texture_im(m_context);
7745 Utils::VertexArray vao(m_context);
7748 const std::string& compute_shader =
7749 getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::COMPUTE);
7751 program.Init(compute_shader, "" /* fragment_shader */, "" /* geometry_shader */, "" /* tess_ctrl_shader */,
7752 "" /* tess_eval_shader */, "" /* vertex_shader */, false /* is_separable */);
7756 std::stringstream stream;
7758 if (false == Utils::checkMonolithicComputeProgramInterface(program, program_interface, stream))
7760 m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7761 << ". Inspection of compute program interface failed:\n"
7762 << stream.str() << tcu::TestLog::EndMessage;
7776 prepareUniforms(test_case_index, program_interface, program, buffer_u_cs);
7779 GLint image_location = program.GetUniformLocation("uni_image");
7780 prepareImage(image_location, texture_im);
7783 executeDispatchCall(test_case_index);
7786 m_context.getRenderContext().postIterate();
7790 if (false == checkResults(test_case_index, texture_im))
7792 m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7793 << ". Compute - invalid results." << tcu::TestLog::EndMessage
7794 << tcu::TestLog::KernelSource(compute_shader);
7803 /** Basic implementation
7809 bool TextureTestBase::useComponentQualifier(glw::GLuint /* test_case_index */)
7814 /** Basic implementation
7820 bool TextureTestBase::useMonolithicProgram(GLuint /* test_case_index */)
7827 * @param context Test framework context
7829 APIConstantValuesTest::APIConstantValuesTest(deqp::Context& context)
7830 : TestCase(context, "api_constant_values", "Test verifies values of api constants")
7832 /* Nothing to be done here */
7837 * @return tcu::TestNode::STOP otherwise
7839 tcu::TestNode::IterateResult APIConstantValuesTest::iterate()
7841 static const GLuint expected_comp = 64;
7842 static const GLuint expected_xfb = 4;
7843 static const GLuint expected_sep = 4;
7847 bool test_result = true;
7849 const Functions& gl = m_context.getRenderContext().getFunctions();
7851 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_xfb);
7852 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
7853 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_comp);
7854 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
7855 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, &max_sep);
7856 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
7858 if (expected_xfb > (GLuint)max_xfb)
7860 m_context.getTestContext().getLog() << tcu::TestLog::Message
7861 << "Invalid GL_MAX_TRANSFORM_FEEDBACK_BUFFERS. Got " << max_xfb
7862 << " Expected at least " << expected_xfb << tcu::TestLog::EndMessage;
7864 test_result = false;
7867 if (expected_comp > (GLuint)max_comp)
7869 m_context.getTestContext().getLog()
7870 << tcu::TestLog::Message << "Invalid GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS. Got " << max_comp
7871 << " Expected at least " << expected_comp << tcu::TestLog::EndMessage;
7873 test_result = false;
7876 if (expected_sep > (GLuint)max_sep)
7878 m_context.getTestContext().getLog() << tcu::TestLog::Message
7879 << "Invalid GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS. Got " << max_comp
7880 << " Expected at least " << expected_comp << tcu::TestLog::EndMessage;
7882 test_result = false;
7886 if (true == test_result)
7888 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
7892 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
7896 return tcu::TestNode::STOP;
7901 * @param context Test framework context
7903 APIErrorsTest::APIErrorsTest(deqp::Context& context)
7904 : TestCase(context, "api_errors", "Test verifies errors reeturned by api")
7906 /* Nothing to be done here */
7911 * @return tcu::TestNode::STOP otherwise
7913 tcu::TestNode::IterateResult APIErrorsTest::iterate()
7918 Utils::Program program(m_context);
7919 bool test_result = true;
7921 const Functions& gl = m_context.getRenderContext().getFunctions();
7925 program.Init("" /* cs */, "#version 430 core\n"
7926 "#extension GL_ARB_enhanced_layouts : require\n"
7929 "out vec4 fs_out;\n"
7933 " fs_out = vs_fs;\n"
7936 "" /* gs */, "" /* tcs */, "" /* tes */, "#version 430 core\n"
7937 "#extension GL_ARB_enhanced_layouts : require\n"
7940 "layout (xfb_offset = 16) out vec4 vs_fs;\n"
7947 false /* separable */);
7949 catch (Utils::Shader::InvalidSourceException& exc)
7952 TCU_FAIL(exc.what());
7954 catch (Utils::Program::BuildException& exc)
7956 TCU_FAIL(exc.what());
7960 * - GetProgramInterfaceiv should generate INVALID_OPERATION when
7961 * <programInterface> is TRANSFORM_FEEDBACK_BUFFER and <pname> is one of the
7963 * * MAX_NAME_LENGTH,
7964 * * MAX_NUM_ACTIVE_VARIABLES;
7966 gl.getProgramInterfaceiv(program.m_id, GL_TRANSFORM_FEEDBACK_BUFFER, GL_MAX_NAME_LENGTH, ¶m);
7967 checkError(GL_INVALID_OPERATION, "GetProgramInterfaceiv(GL_TRANSFORM_FEEDBACK_BUFFER, GL_MAX_NAME_LENGTH)",
7971 * - GetProgramResourceIndex should generate INVALID_ENUM when
7972 * <programInterface> is TRANSFORM_FEEDBACK_BUFFER;
7974 gl.getProgramResourceIndex(program.m_id, GL_TRANSFORM_FEEDBACK_BUFFER, "0");
7975 checkError(GL_INVALID_ENUM, "GetProgramResourceIndex(GL_TRANSFORM_FEEDBACK_BUFFER)", test_result);
7977 * - GetProgramResourceName should generate INVALID_ENUM when
7978 * <programInterface> is TRANSFORM_FEEDBACK_BUFFER;
7980 gl.getProgramResourceName(program.m_id, GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, 64 /* bufSize */, &length,
7982 checkError(GL_INVALID_ENUM, "GetProgramResourceName(GL_TRANSFORM_FEEDBACK_BUFFER)", test_result);
7985 if (true == test_result)
7987 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
7991 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
7995 return tcu::TestNode::STOP;
7998 /** Check if error is the expected one.
8000 * @param expected_error Expected error
8001 * @param message Message to log in case of error
8002 * @param test_result Test result, set to false in case of invalid error
8004 void APIErrorsTest::checkError(GLenum expected_error, const GLchar* message, bool& test_result)
8006 const Functions& gl = m_context.getRenderContext().getFunctions();
8008 GLenum error = gl.getError();
8010 if (error != expected_error)
8012 m_context.getTestContext().getLog()
8013 << tcu::TestLog::Message << "Failure. Invalid error. Got " << glu::getErrorStr(error) << " expected "
8014 << glu::getErrorStr(expected_error) << " Msg: " << message << tcu::TestLog::EndMessage;
8016 test_result = false;
8022 * @param context Test framework context
8024 GLSLContantImmutablityTest::GLSLContantImmutablityTest(deqp::Context& context)
8025 : NegativeTestBase(context, "glsl_contant_immutablity", "Test verifies that glsl constants cannot be modified")
8027 /* Nothing to be done here */
8030 /** Source for given test case and stage
8032 * @param test_case_index Index of test case
8033 * @param stage Shader stage
8035 * @return Shader source
8037 std::string GLSLContantImmutablityTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
8039 static const GLchar* cs = "#version 430 core\n"
8040 "#extension GL_ARB_enhanced_layouts : require\n"
8042 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
8044 "writeonly uniform uimage2D uni_image;\n"
8048 " uint result = 1u;\n"
8051 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), uvec4(result, 0, 0, 0));\n"
8054 static const GLchar* fs = "#version 430 core\n"
8055 "#extension GL_ARB_enhanced_layouts : require\n"
8058 "out vec4 fs_out;\n"
8063 " fs_out = gs_fs;\n"
8066 static const GLchar* gs = "#version 430 core\n"
8067 "#extension GL_ARB_enhanced_layouts : require\n"
8069 "layout(points) in;\n"
8070 "layout(triangle_strip, max_vertices = 4) out;\n"
8072 "in vec4 tes_gs[];\n"
8078 " gs_fs = tes_gs[0];\n"
8079 " gl_Position = vec4(-1, -1, 0, 1);\n"
8081 " gs_fs = tes_gs[0];\n"
8082 " gl_Position = vec4(-1, 1, 0, 1);\n"
8084 " gs_fs = tes_gs[0];\n"
8085 " gl_Position = vec4(1, -1, 0, 1);\n"
8087 " gs_fs = tes_gs[0];\n"
8088 " gl_Position = vec4(1, 1, 0, 1);\n"
8092 static const GLchar* tcs = "#version 430 core\n"
8093 "#extension GL_ARB_enhanced_layouts : require\n"
8095 "layout(vertices = 1) out;\n"
8097 "in vec4 vs_tcs[];\n"
8098 "out vec4 tcs_tes[];\n"
8104 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
8106 " gl_TessLevelOuter[0] = 1.0;\n"
8107 " gl_TessLevelOuter[1] = 1.0;\n"
8108 " gl_TessLevelOuter[2] = 1.0;\n"
8109 " gl_TessLevelOuter[3] = 1.0;\n"
8110 " gl_TessLevelInner[0] = 1.0;\n"
8111 " gl_TessLevelInner[1] = 1.0;\n"
8114 static const GLchar* tes = "#version 430 core\n"
8115 "#extension GL_ARB_enhanced_layouts : require\n"
8117 "layout(isolines, point_mode) in;\n"
8119 "in vec4 tcs_tes[];\n"
8120 "out vec4 tes_gs;\n"
8125 " tes_gs = tcs_tes[0];\n"
8128 static const GLchar* vs = "#version 430 core\n"
8129 "#extension GL_ARB_enhanced_layouts : require\n"
8132 "out vec4 vs_tcs;\n"
8137 " vs_tcs = in_vs;\n"
8142 testCase& test_case = m_test_cases[test_case_index];
8144 if (Utils::Shader::COMPUTE == test_case.m_stage)
8146 size_t position = 0;
8150 Utils::replaceToken("CONSTANT", position, getConstantName(test_case.m_constant), source);
8154 std::string assignment = " CONSTANT = 3;\n";
8155 size_t position = 0;
8159 case Utils::Shader::FRAGMENT:
8162 case Utils::Shader::GEOMETRY:
8165 case Utils::Shader::TESS_CTRL:
8168 case Utils::Shader::TESS_EVAL:
8171 case Utils::Shader::VERTEX:
8175 TCU_FAIL("Invalid enum");
8178 if (test_case.m_stage == stage)
8180 Utils::replaceToken("CONSTANT", position, getConstantName(test_case.m_constant), assignment);
8188 Utils::replaceToken("ASSIGNMENT", position, assignment.c_str(), source);
8194 /** Get description of test case
8196 * @param test_case_index Index of test case
8198 * @return Constant name
8200 std::string GLSLContantImmutablityTest::getTestCaseName(GLuint test_case_index)
8202 std::string result = getConstantName(m_test_cases[test_case_index].m_constant);
8207 /** Get number of test cases
8209 * @return Number of test cases
8211 GLuint GLSLContantImmutablityTest::getTestCaseNumber()
8213 return static_cast<GLuint>(m_test_cases.size());
8216 /** Selects if "compute" stage is relevant for test
8218 * @param test_case_index Index of test case
8220 * @return true when tested stage is compute
8222 bool GLSLContantImmutablityTest::isComputeRelevant(GLuint test_case_index)
8224 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
8227 /** Prepare all test cases
8230 void GLSLContantImmutablityTest::testInit()
8232 for (GLuint constant = 0; constant < CONSTANTS_MAX; ++constant)
8234 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
8236 testCase test_case = { (CONSTANTS)constant, (Utils::Shader::STAGES)stage };
8238 m_test_cases.push_back(test_case);
8243 /** Get name of glsl constant
8245 * @param Constant id
8247 * @return Name of constant used in GLSL
8249 const GLchar* GLSLContantImmutablityTest::getConstantName(CONSTANTS constant)
8251 const GLchar* name = "";
8255 case GL_ARB_ENHANCED_LAYOUTS:
8256 name = "GL_ARB_enhanced_layouts";
8259 name = "gl_MaxTransformFeedbackBuffers";
8261 case GL_MAX_XFB_INT_COMP:
8262 name = "gl_MaxTransformFeedbackInterleavedComponents";
8265 TCU_FAIL("Invalid enum");
8273 * @param context Test framework context
8275 GLSLContantValuesTest::GLSLContantValuesTest(deqp::Context& context)
8276 : TextureTestBase(context, "glsl_contant_values", "Test verifies values of constant symbols")
8280 /** Selects if "compute" stage is relevant for test
8286 bool GLSLContantValuesTest::isComputeRelevant(GLuint /* test_case_index */)
8291 /** Prepare code snippet that will verify in and uniform variables
8295 * @param stage Shader stage
8297 * @return Code that verify variables
8299 std::string GLSLContantValuesTest::getVerificationSnippet(GLuint /* test_case_index */,
8300 Utils::ProgramInterface& /* program_interface */,
8301 Utils::Shader::STAGES stage)
8304 const Functions& gl = m_context.getRenderContext().getFunctions();
8306 GLint max_transform_feedback_buffers = 0;
8307 GLint max_transform_feedback_interleaved_components = 0;
8309 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_transform_feedback_buffers);
8310 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8311 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_transform_feedback_interleaved_components);
8312 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8314 std::string verification;
8316 if (Utils::Shader::VERTEX == stage)
8318 verification = "if (1 != GL_ARB_enhanced_layouts)\n"
8322 " else if (MAX_TRANSFORM_FEEDBACK_BUFFERS\n"
8323 " != gl_MaxTransformFeedbackBuffers)\n"
8327 " else if (MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS \n"
8328 " != gl_MaxTransformFeedbackInterleavedComponents)\n"
8333 size_t position = 0;
8336 sprintf(buffer, "%d", max_transform_feedback_buffers);
8337 Utils::replaceToken("MAX_TRANSFORM_FEEDBACK_BUFFERS", position, buffer, verification);
8339 sprintf(buffer, "%d", max_transform_feedback_interleaved_components);
8340 Utils::replaceToken("MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS", position, buffer, verification);
8347 return verification;
8352 * @param context Test framework context
8354 GLSLConstantIntegralExpressionTest::GLSLConstantIntegralExpressionTest(deqp::Context& context)
8355 : TextureTestBase(context, "glsl_constant_integral_expression",
8356 "Test verifies that symbols can be used as constant integral expressions")
8360 /** Get interface of program
8363 * @param program_interface Interface of program
8366 void GLSLConstantIntegralExpressionTest::getProgramInterface(GLuint /* test_case_index */,
8367 Utils::ProgramInterface& program_interface,
8368 Utils::VaryingPassthrough& /* varying_passthrough */)
8371 const Functions& gl = m_context.getRenderContext().getFunctions();
8373 GLint max_transform_feedback_buffers = 0;
8374 GLint max_transform_feedback_interleaved_components = 0;
8376 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_transform_feedback_buffers);
8377 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8378 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_transform_feedback_interleaved_components);
8379 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8381 GLuint gohan_div = std::max(1, max_transform_feedback_buffers / 16);
8382 GLuint goten_div = std::max(1, max_transform_feedback_interleaved_components / 16);
8384 m_gohan_length = max_transform_feedback_buffers / gohan_div;
8385 m_goten_length = max_transform_feedback_interleaved_components / goten_div;
8388 std::string globals = "uniform uint goku [GL_ARB_enhanced_layouts / 1];\n"
8389 "uniform uint gohan[gl_MaxTransformFeedbackBuffers / GOHAN_DIV];\n"
8390 "uniform uint goten[gl_MaxTransformFeedbackInterleavedComponents / GOTEN_DIV];\n";
8392 size_t position = 0;
8395 sprintf(buffer, "%d", gohan_div);
8396 Utils::replaceToken("GOHAN_DIV", position, buffer, globals);
8398 sprintf(buffer, "%d", goten_div);
8399 Utils::replaceToken("GOTEN_DIV", position, buffer, globals);
8401 program_interface.m_vertex.m_globals = globals;
8402 program_interface.m_tess_ctrl.m_globals = globals;
8403 program_interface.m_tess_eval.m_globals = globals;
8404 program_interface.m_geometry.m_globals = globals;
8405 program_interface.m_fragment.m_globals = globals;
8406 program_interface.m_compute.m_globals = globals;
8409 /** Prepare code snippet that will verify in and uniform variables
8415 * @return Code that verify variables
8417 std::string GLSLConstantIntegralExpressionTest::getVerificationSnippet(GLuint /* test_case_index */,
8418 Utils::ProgramInterface& /* program_interface */,
8419 Utils::Shader::STAGES /* stage */)
8421 std::string verification = "{\n"
8422 " uint goku_sum = 0;\n"
8423 " uint gohan_sum = 0;\n"
8424 " uint goten_sum = 0;\n"
8426 " for (uint i = 0u; i < goku.length(); ++i)\n"
8428 " goku_sum += goku[i];\n"
8431 " for (uint i = 0u; i < gohan.length(); ++i)\n"
8433 " gohan_sum += gohan[i];\n"
8436 " for (uint i = 0u; i < goten.length(); ++i)\n"
8438 " goten_sum += goten[i];\n"
8441 " if ( (1u != goku_sum) &&\n"
8442 " (EXPECTED_GOHAN_SUMu != gohan_sum) ||\n"
8443 " (EXPECTED_GOTEN_SUMu != goten_sum) )\n"
8449 size_t position = 0;
8452 sprintf(buffer, "%d", m_gohan_length);
8453 Utils::replaceToken("EXPECTED_GOHAN_SUM", position, buffer, verification);
8455 sprintf(buffer, "%d", m_goten_length);
8456 Utils::replaceToken("EXPECTED_GOTEN_SUM", position, buffer, verification);
8458 return verification;
8461 /** Prepare unifroms
8465 * @param program Program object
8468 void GLSLConstantIntegralExpressionTest::prepareUniforms(GLuint /* test_case_index */,
8469 Utils::ProgramInterface& /* program_interface */,
8470 Utils::Program& program, Utils::Buffer& /* cs_buffer */)
8472 static const GLuint uniform_data[16] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
8474 const Functions& gl = m_context.getRenderContext().getFunctions();
8476 GLint goku_location = program.GetUniformLocation("goku");
8477 GLint gohan_location = program.GetUniformLocation("gohan");
8478 GLint goten_location = program.GetUniformLocation("goten");
8480 program.Uniform(gl, Utils::Type::uint, 1 /* count */, goku_location, uniform_data);
8481 program.Uniform(gl, Utils::Type::uint, m_gohan_length, gohan_location, uniform_data);
8482 program.Uniform(gl, Utils::Type::uint, m_goten_length, goten_location, uniform_data);
8485 /** Prepare unifroms
8487 * @param test_case_index Pass as param to first implemetnation
8488 * @param program_interface Pass as param to first implemetnation
8489 * @param program Pass as param to first implemetnation
8494 * @param vs_buffer Pass as param to first implemetnation
8496 void GLSLConstantIntegralExpressionTest::prepareUniforms(GLuint test_case_index,
8497 Utils::ProgramInterface& program_interface,
8498 Utils::Program& program, Utils::Buffer& /* fs_buffer */,
8499 Utils::Buffer& /* gs_buffer */,
8500 Utils::Buffer& /* tcs_buffer */,
8501 Utils::Buffer& /* tes_buffer */, Utils::Buffer& vs_buffer)
8503 /* Call first implementation */
8504 prepareUniforms(test_case_index, program_interface, program, vs_buffer);
8509 * @param context Test framework context
8511 UniformBlockMemberOffsetAndAlignTest::UniformBlockMemberOffsetAndAlignTest(deqp::Context& context)
8512 : TextureTestBase(context, "uniform_block_member_offset_and_align",
8513 "Test verifies offsets and alignment of uniform buffer members")
8517 /** Get interface of program
8519 * @param test_case_index Test case index
8520 * @param program_interface Interface of program
8521 * @param varying_passthrough Collection of connections between in and out variables
8523 void UniformBlockMemberOffsetAndAlignTest::getProgramInterface(GLuint test_case_index,
8524 Utils::ProgramInterface& program_interface,
8525 Utils::VaryingPassthrough& varying_passthrough)
8527 std::string globals = "const int basic_size = BASIC_SIZE;\n"
8528 "const int type_align = TYPE_ALIGN;\n"
8529 "const int type_size = TYPE_SIZE;\n";
8531 Utils::Type type = getType(test_case_index);
8532 GLuint basic_size = Utils::Type::GetTypeSize(type.m_basic_type);
8533 const GLuint base_align = type.GetBaseAlignment(false);
8534 const GLuint array_align = type.GetBaseAlignment(true);
8535 const GLuint base_stride = Utils::Type::CalculateStd140Stride(base_align, type.m_n_columns, 0);
8536 const GLuint type_align = Utils::roundUpToPowerOf2(base_stride);
8538 /* Calculate offsets */
8539 const GLuint first_offset = 0;
8540 const GLuint second_offset = type.GetActualOffset(base_stride, basic_size / 2);
8542 #if WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST
8544 const GLuint third_offset = type.GetActualOffset(second_offset + base_stride, base_align);
8545 const GLuint fourth_offset = type.GetActualOffset(third_offset + base_stride, base_align);
8546 const GLuint fifth_offset = type.GetActualOffset(fourth_offset + base_stride, base_align);
8547 const GLuint sixth_offset = type.GetActualOffset(fifth_offset + base_stride, array_align);
8548 const GLuint seventh_offset = type.GetActualOffset(sixth_offset + base_stride, array_align);
8549 const GLuint eigth_offset = type.GetActualOffset(seventh_offset + base_stride, array_align);
8551 #else /* WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST */
8553 const GLuint third_offset = type.GetActualOffset(second_offset + base_stride, 2 * type_align);
8554 const GLuint fourth_offset = type.GetActualOffset(3 * type_align + base_stride, base_align);
8555 const GLuint fifth_offset = type.GetActualOffset(fourth_offset + base_stride, base_align);
8556 const GLuint sixth_offset = type.GetActualOffset(fifth_offset + base_stride, array_align);
8557 const GLuint seventh_offset = type.GetActualOffset(sixth_offset + base_stride, array_align);
8558 const GLuint eigth_offset = type.GetActualOffset(seventh_offset + base_stride, 8 * basic_size);
8560 #endif /* WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST */
8563 const std::vector<GLubyte>& first = type.GenerateData();
8564 const std::vector<GLubyte>& second = type.GenerateData();
8565 const std::vector<GLubyte>& third = type.GenerateData();
8566 const std::vector<GLubyte>& fourth = type.GenerateData();
8568 m_data.resize(eigth_offset + base_stride);
8569 GLubyte* ptr = &m_data[0];
8570 memcpy(ptr + first_offset, &first[0], first.size());
8571 memcpy(ptr + second_offset, &second[0], second.size());
8572 memcpy(ptr + third_offset, &third[0], third.size());
8573 memcpy(ptr + fourth_offset, &fourth[0], fourth.size());
8574 memcpy(ptr + fifth_offset, &fourth[0], fourth.size());
8575 memcpy(ptr + sixth_offset, &third[0], third.size());
8576 memcpy(ptr + seventh_offset, &second[0], second.size());
8577 memcpy(ptr + eigth_offset, &first[0], first.size());
8579 /* Prepare globals */
8580 size_t position = 0;
8583 sprintf(buffer, "%d", basic_size);
8584 Utils::replaceToken("BASIC_SIZE", position, buffer, globals);
8586 sprintf(buffer, "%d", type_align);
8587 Utils::replaceToken("TYPE_ALIGN", position, buffer, globals);
8589 sprintf(buffer, "%d", base_stride);
8590 Utils::replaceToken("TYPE_SIZE", position, buffer, globals);
8593 Utils::Interface* vs_uni_block = program_interface.Block("vs_uni_Block");
8595 vs_uni_block->Member("at_first_offset", "layout(offset = 0, align = 8 * basic_size)", 0 /* expected_component */,
8596 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
8599 vs_uni_block->Member("at_second_offset", "layout(offset = type_size, align = basic_size / 2)",
8600 0 /* expected_component */, 0 /* expected_location */, type, false /* normalized */,
8601 0 /* n_array_elements */, base_stride, second_offset);
8603 vs_uni_block->Member("at_third_offset", "layout(align = 2 * type_align)", 0 /* expected_component */,
8604 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
8607 vs_uni_block->Member("at_fourth_offset", "layout(offset = 3 * type_align + type_size)", 0 /* expected_component */,
8608 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
8611 vs_uni_block->Member("at_fifth_offset", "", 0 /* expected_component */, 0 /* expected_location */, type,
8612 false /* normalized */, 0 /* n_array_elements */, base_stride, fifth_offset);
8614 vs_uni_block->Member("at_sixth_offset", "", 0 /* expected_component */, 0 /* expected_location */, type,
8615 false /* normalized */, 2 /* n_array_elements */, array_align * 2, sixth_offset);
8617 vs_uni_block->Member("at_eigth_offset", "layout(align = 8 * basic_size)", 0 /* expected_component */,
8618 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
8621 Utils::ShaderInterface& vs_si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
8624 vs_si.m_globals = globals;
8626 /* Add uniform BLOCK */
8627 vs_si.Uniform("vs_uni_block", "layout (std140, binding = BINDING)", 0, 0, vs_uni_block, 0,
8628 static_cast<glw::GLint>(m_data.size()), 0, &m_data[0], m_data.size());
8631 program_interface.CloneVertexInterface(varying_passthrough);
8636 * @param test_case_index Index of test case
8638 * @return Name of type test in test_case_index
8640 std::string UniformBlockMemberOffsetAndAlignTest::getTestCaseName(glw::GLuint test_case_index)
8642 return getTypeName(test_case_index);
8645 /** Returns number of types to test
8647 * @return Number of types, 34
8649 glw::GLuint UniformBlockMemberOffsetAndAlignTest::getTestCaseNumber()
8651 return getTypesNumber();
8654 /** Prepare code snippet that will verify in and uniform variables
8658 * @param stage Shader stage
8660 * @return Code that verify variables
8662 std::string UniformBlockMemberOffsetAndAlignTest::getVerificationSnippet(
8663 GLuint /* test_case_index */, Utils::ProgramInterface& /* program_interface */, Utils::Shader::STAGES stage)
8665 std::string verification = "if ( (PREFIXblock.at_first_offset != PREFIXblock.at_eigth_offset ) ||\n"
8666 " (PREFIXblock.at_second_offset != PREFIXblock.at_sixth_offset[1]) ||\n"
8667 " (PREFIXblock.at_third_offset != PREFIXblock.at_sixth_offset[0]) ||\n"
8668 " (PREFIXblock.at_fourth_offset != PREFIXblock.at_fifth_offset ) )\n"
8673 const GLchar* prefix = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::UNIFORM);
8675 Utils::replaceAllTokens("PREFIX", prefix, verification);
8677 return verification;
8682 * @param context Test framework context
8684 UniformBlockLayoutQualifierConflictTest::UniformBlockLayoutQualifierConflictTest(deqp::Context& context)
8686 context, "uniform_block_layout_qualifier_conflict",
8687 "Test verifies that std140 is required when offset and/or align qualifiers are used with uniform block")
8689 /* Nothing to be done here */
8692 /** Source for given test case and stage
8694 * @param test_case_index Index of test case
8695 * @param stage Shader stage
8697 * @return Shader source
8699 std::string UniformBlockLayoutQualifierConflictTest::getShaderSource(GLuint test_case_index,
8700 Utils::Shader::STAGES stage)
8702 static const GLchar* cs = "#version 430 core\n"
8703 "#extension GL_ARB_enhanced_layouts : require\n"
8705 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
8707 "LAYOUTuniform Block {\n"
8708 " layout(offset = 16) vec4 boy;\n"
8709 " layout(align = 64) vec4 man;\n"
8712 "writeonly uniform image2D uni_image;\n"
8716 " vec4 result = uni_block.boy + uni_block.man;\n"
8718 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
8721 static const GLchar* fs = "#version 430 core\n"
8722 "#extension GL_ARB_enhanced_layouts : require\n"
8724 "LAYOUTuniform Block {\n"
8725 " layout(offset = 16) vec4 boy;\n"
8726 " layout(align = 64) vec4 man;\n"
8730 "out vec4 fs_out;\n"
8734 " fs_out = gs_fs + uni_block.boy + uni_block.man;\n"
8737 static const GLchar* gs = "#version 430 core\n"
8738 "#extension GL_ARB_enhanced_layouts : require\n"
8740 "layout(points) in;\n"
8741 "layout(triangle_strip, max_vertices = 4) out;\n"
8743 "LAYOUTuniform Block {\n"
8744 " layout(offset = 16) vec4 boy;\n"
8745 " layout(align = 64) vec4 man;\n"
8748 "in vec4 tes_gs[];\n"
8753 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
8754 " gl_Position = vec4(-1, -1, 0, 1);\n"
8756 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
8757 " gl_Position = vec4(-1, 1, 0, 1);\n"
8759 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
8760 " gl_Position = vec4(1, -1, 0, 1);\n"
8762 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
8763 " gl_Position = vec4(1, 1, 0, 1);\n"
8767 static const GLchar* tcs =
8768 "#version 430 core\n"
8769 "#extension GL_ARB_enhanced_layouts : require\n"
8771 "layout(vertices = 1) out;\n"
8773 "LAYOUTuniform Block {\n"
8774 " layout(offset = 16) vec4 boy;\n"
8775 " layout(align = 64) vec4 man;\n"
8778 "in vec4 vs_tcs[];\n"
8779 "out vec4 tcs_tes[];\n"
8784 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID] + uni_block.boy + uni_block.man;\n"
8786 " gl_TessLevelOuter[0] = 1.0;\n"
8787 " gl_TessLevelOuter[1] = 1.0;\n"
8788 " gl_TessLevelOuter[2] = 1.0;\n"
8789 " gl_TessLevelOuter[3] = 1.0;\n"
8790 " gl_TessLevelInner[0] = 1.0;\n"
8791 " gl_TessLevelInner[1] = 1.0;\n"
8794 static const GLchar* tes = "#version 430 core\n"
8795 "#extension GL_ARB_enhanced_layouts : require\n"
8797 "layout(isolines, point_mode) in;\n"
8799 "LAYOUTuniform Block {\n"
8800 " layout(offset = 16) vec4 boy;\n"
8801 " layout(align = 64) vec4 man;\n"
8804 "in vec4 tcs_tes[];\n"
8805 "out vec4 tes_gs;\n"
8809 " tes_gs = tcs_tes[0] + uni_block.boy + uni_block.man;\n"
8812 static const GLchar* vs = "#version 430 core\n"
8813 "#extension GL_ARB_enhanced_layouts : require\n"
8815 "LAYOUTuniform Block {\n"
8816 " layout(offset = 16) vec4 boy;\n"
8817 " layout(align = 64) vec4 man;\n"
8821 "out vec4 vs_tcs;\n"
8825 " vs_tcs = in_vs + uni_block.boy + uni_block.man;\n"
8829 std::string layout = "";
8830 size_t position = 0;
8831 testCase& test_case = m_test_cases[test_case_index];
8832 const GLchar* qualifier = getQualifierName(test_case.m_qualifier);
8835 if (0 != qualifier[0])
8837 size_t layout_position = 0;
8839 layout = "layout (QUALIFIER) ";
8841 Utils::replaceToken("QUALIFIER", layout_position, qualifier, layout);
8846 case Utils::Shader::COMPUTE:
8849 case Utils::Shader::FRAGMENT:
8852 case Utils::Shader::GEOMETRY:
8855 case Utils::Shader::TESS_CTRL:
8858 case Utils::Shader::TESS_EVAL:
8861 case Utils::Shader::VERTEX:
8865 TCU_FAIL("Invalid enum");
8868 if (test_case.m_stage == stage)
8870 Utils::replaceToken("LAYOUT", position, layout.c_str(), source);
8874 Utils::replaceToken("LAYOUT", position, "layout (std140) ", source);
8880 /** Get description of test case
8882 * @param test_case_index Index of test case
8884 * @return Qualifier name
8886 std::string UniformBlockLayoutQualifierConflictTest::getTestCaseName(GLuint test_case_index)
8888 std::string result = getQualifierName(m_test_cases[test_case_index].m_qualifier);
8893 /** Get number of test cases
8895 * @return Number of test cases
8897 GLuint UniformBlockLayoutQualifierConflictTest::getTestCaseNumber()
8899 return static_cast<GLuint>(m_test_cases.size());
8902 /** Selects if "compute" stage is relevant for test
8904 * @param test_case_index Index of test case
8906 * @return true when tested stage is compute
8908 bool UniformBlockLayoutQualifierConflictTest::isComputeRelevant(GLuint test_case_index)
8910 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
8913 /** Selects if compilation failure is expected result
8915 * @param test_case_index Index of test case
8917 * @return false for STD140 cases, true otherwise
8919 bool UniformBlockLayoutQualifierConflictTest::isFailureExpected(GLuint test_case_index)
8921 return (STD140 != m_test_cases[test_case_index].m_qualifier);
8924 /** Prepare all test cases
8927 void UniformBlockLayoutQualifierConflictTest::testInit()
8929 for (GLuint qualifier = 0; qualifier < QUALIFIERS_MAX; ++qualifier)
8931 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
8933 testCase test_case = { (QUALIFIERS)qualifier, (Utils::Shader::STAGES)stage };
8935 m_test_cases.push_back(test_case);
8940 /** Get name of glsl constant
8942 * @param Constant id
8944 * @return Name of constant used in GLSL
8946 const GLchar* UniformBlockLayoutQualifierConflictTest::getQualifierName(QUALIFIERS qualifier)
8948 const GLchar* name = "";
8965 TCU_FAIL("Invalid enum");
8973 * @param context Test framework context
8975 UniformBlockMemberInvalidOffsetAlignmentTest::UniformBlockMemberInvalidOffsetAlignmentTest(deqp::Context& context)
8976 : NegativeTestBase(context, "uniform_block_member_invalid_offset_alignment",
8977 "Test verifies that invalid alignment of offset qualifiers cause compilation failure")
8979 /* Nothing to be done here */
8984 * @param context Test framework context
8985 * @param name Test name
8986 * @param description Test description
8988 UniformBlockMemberInvalidOffsetAlignmentTest::UniformBlockMemberInvalidOffsetAlignmentTest(
8989 deqp::Context& context, const glw::GLchar* name, const glw::GLchar* description)
8990 : NegativeTestBase(context, name, description)
8992 /* Nothing to be done here */
8995 /** Source for given test case and stage
8997 * @param test_case_index Index of test case
8998 * @param stage Shader stage
9000 * @return Shader source
9002 std::string UniformBlockMemberInvalidOffsetAlignmentTest::getShaderSource(GLuint test_case_index,
9003 Utils::Shader::STAGES stage)
9005 static const GLchar* cs = "#version 430 core\n"
9006 "#extension GL_ARB_enhanced_layouts : require\n"
9008 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
9010 "layout (std140) uniform Block {\n"
9011 " layout (offset = OFFSET) TYPE member;\n"
9014 "writeonly uniform image2D uni_image;\n"
9018 " vec4 result = vec4(1, 0, 0.5, 1);\n"
9020 " if (TYPE(1) == block.member)\n"
9022 " result = vec4(1, 1, 1, 1);\n"
9025 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
9028 static const GLchar* fs = "#version 430 core\n"
9029 "#extension GL_ARB_enhanced_layouts : require\n"
9032 "out vec4 fs_out;\n"
9036 " fs_out = gs_fs;\n"
9039 static const GLchar* fs_tested = "#version 430 core\n"
9040 "#extension GL_ARB_enhanced_layouts : require\n"
9042 "layout (std140) uniform Block {\n"
9043 " layout (offset = OFFSET) TYPE member;\n"
9047 "out vec4 fs_out;\n"
9051 " if (TYPE(1) == block.member)\n"
9053 " fs_out = vec4(1, 1, 1, 1);\n"
9056 " fs_out += gs_fs;\n"
9059 static const GLchar* gs = "#version 430 core\n"
9060 "#extension GL_ARB_enhanced_layouts : require\n"
9062 "layout(points) in;\n"
9063 "layout(triangle_strip, max_vertices = 4) out;\n"
9065 "in vec4 tes_gs[];\n"
9070 " gs_fs = tes_gs[0];\n"
9071 " gl_Position = vec4(-1, -1, 0, 1);\n"
9073 " gs_fs = tes_gs[0];\n"
9074 " gl_Position = vec4(-1, 1, 0, 1);\n"
9076 " gs_fs = tes_gs[0];\n"
9077 " gl_Position = vec4(1, -1, 0, 1);\n"
9079 " gs_fs = tes_gs[0];\n"
9080 " gl_Position = vec4(1, 1, 0, 1);\n"
9084 static const GLchar* gs_tested = "#version 430 core\n"
9085 "#extension GL_ARB_enhanced_layouts : require\n"
9087 "layout(points) in;\n"
9088 "layout(triangle_strip, max_vertices = 4) out;\n"
9090 "layout (std140) uniform Block {\n"
9091 " layout (offset = OFFSET) TYPE member;\n"
9094 "in vec4 tes_gs[];\n"
9099 " if (TYPE(1) == block.member)\n"
9101 " gs_fs = vec4(1, 1, 1, 1);\n"
9104 " gs_fs += tes_gs[0];\n"
9105 " gl_Position = vec4(-1, -1, 0, 1);\n"
9107 " gs_fs += tes_gs[0];\n"
9108 " gl_Position = vec4(-1, 1, 0, 1);\n"
9110 " gs_fs += tes_gs[0];\n"
9111 " gl_Position = vec4(1, -1, 0, 1);\n"
9113 " gs_fs += tes_gs[0];\n"
9114 " gl_Position = vec4(1, 1, 0, 1);\n"
9118 static const GLchar* tcs = "#version 430 core\n"
9119 "#extension GL_ARB_enhanced_layouts : require\n"
9121 "layout(vertices = 1) out;\n"
9123 "in vec4 vs_tcs[];\n"
9124 "out vec4 tcs_tes[];\n"
9129 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
9131 " gl_TessLevelOuter[0] = 1.0;\n"
9132 " gl_TessLevelOuter[1] = 1.0;\n"
9133 " gl_TessLevelOuter[2] = 1.0;\n"
9134 " gl_TessLevelOuter[3] = 1.0;\n"
9135 " gl_TessLevelInner[0] = 1.0;\n"
9136 " gl_TessLevelInner[1] = 1.0;\n"
9139 static const GLchar* tcs_tested = "#version 430 core\n"
9140 "#extension GL_ARB_enhanced_layouts : require\n"
9142 "layout(vertices = 1) out;\n"
9144 "layout (std140) uniform Block {\n"
9145 " layout (offset = OFFSET) TYPE member;\n"
9148 "in vec4 vs_tcs[];\n"
9149 "out vec4 tcs_tes[];\n"
9153 " if (TYPE(1) == block.member)\n"
9155 " tcs_tes[gl_InvocationID] = vec4(1, 1, 1, 1);\n"
9159 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
9161 " gl_TessLevelOuter[0] = 1.0;\n"
9162 " gl_TessLevelOuter[1] = 1.0;\n"
9163 " gl_TessLevelOuter[2] = 1.0;\n"
9164 " gl_TessLevelOuter[3] = 1.0;\n"
9165 " gl_TessLevelInner[0] = 1.0;\n"
9166 " gl_TessLevelInner[1] = 1.0;\n"
9169 static const GLchar* tes = "#version 430 core\n"
9170 "#extension GL_ARB_enhanced_layouts : require\n"
9172 "layout(isolines, point_mode) in;\n"
9174 "in vec4 tcs_tes[];\n"
9175 "out vec4 tes_gs;\n"
9179 " tes_gs = tcs_tes[0];\n"
9182 static const GLchar* tes_tested = "#version 430 core\n"
9183 "#extension GL_ARB_enhanced_layouts : require\n"
9185 "layout(isolines, point_mode) in;\n"
9187 "layout (std140) uniform Block {\n"
9188 " layout (offset = OFFSET) TYPE member;\n"
9191 "in vec4 tcs_tes[];\n"
9192 "out vec4 tes_gs;\n"
9196 " if (TYPE(1) == block.member)\n"
9198 " tes_gs = vec4(1, 1, 1, 1);\n"
9201 " tes_gs += tcs_tes[0];\n"
9204 static const GLchar* vs = "#version 430 core\n"
9205 "#extension GL_ARB_enhanced_layouts : require\n"
9208 "out vec4 vs_tcs;\n"
9212 " vs_tcs = in_vs;\n"
9215 static const GLchar* vs_tested = "#version 430 core\n"
9216 "#extension GL_ARB_enhanced_layouts : require\n"
9218 "layout (std140) uniform Block {\n"
9219 " layout (offset = OFFSET) TYPE member;\n"
9223 "out vec4 vs_tcs;\n"
9227 " if (TYPE(1) == block.member)\n"
9229 " vs_tcs = vec4(1, 1, 1, 1);\n"
9232 " vs_tcs += in_vs;\n"
9237 testCase& test_case = m_test_cases[test_case_index];
9239 if (test_case.m_stage == stage)
9242 const GLuint offset = test_case.m_offset;
9243 size_t position = 0;
9244 const Utils::Type& type = test_case.m_type;
9245 const GLchar* type_name = type.GetGLSLTypeName();
9247 sprintf(buffer, "%d", offset);
9251 case Utils::Shader::COMPUTE:
9254 case Utils::Shader::FRAGMENT:
9257 case Utils::Shader::GEOMETRY:
9260 case Utils::Shader::TESS_CTRL:
9261 source = tcs_tested;
9263 case Utils::Shader::TESS_EVAL:
9264 source = tes_tested;
9266 case Utils::Shader::VERTEX:
9270 TCU_FAIL("Invalid enum");
9273 Utils::replaceToken("OFFSET", position, buffer, source);
9274 Utils::replaceToken("TYPE", position, type_name, source);
9275 Utils::replaceToken("TYPE", position, type_name, source);
9281 case Utils::Shader::FRAGMENT:
9284 case Utils::Shader::GEOMETRY:
9287 case Utils::Shader::TESS_CTRL:
9290 case Utils::Shader::TESS_EVAL:
9293 case Utils::Shader::VERTEX:
9297 TCU_FAIL("Invalid enum");
9304 /** Get description of test case
9306 * @param test_case_index Index of test case
9308 * @return Type name and offset
9310 std::string UniformBlockMemberInvalidOffsetAlignmentTest::getTestCaseName(GLuint test_case_index)
9312 std::stringstream stream;
9313 testCase& test_case = m_test_cases[test_case_index];
9315 stream << "Type: " << test_case.m_type.GetGLSLTypeName() << ", offset: " << test_case.m_offset;
9317 return stream.str();
9320 /** Get number of test cases
9322 * @return Number of test cases
9324 GLuint UniformBlockMemberInvalidOffsetAlignmentTest::getTestCaseNumber()
9326 return static_cast<GLuint>(m_test_cases.size());
9329 /** Get the maximum size for an uniform block
9331 * @return The maximum size in basic machine units of a uniform block.
9333 GLint UniformBlockMemberInvalidOffsetAlignmentTest::getMaxBlockSize()
9335 const Functions& gl = m_context.getRenderContext().getFunctions();
9338 gl.getIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &max_size);
9339 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
9344 /** Selects if "compute" stage is relevant for test
9346 * @param test_case_index Index of test case
9348 * @return true when tested stage is compute
9350 bool UniformBlockMemberInvalidOffsetAlignmentTest::isComputeRelevant(GLuint test_case_index)
9352 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
9355 /** Selects if compilation failure is expected result
9357 * @param test_case_index Index of test case
9359 * @return should_fail field from testCase
9361 bool UniformBlockMemberInvalidOffsetAlignmentTest::isFailureExpected(GLuint test_case_index)
9363 return m_test_cases[test_case_index].m_should_fail;
9366 /** Checks if stage is supported
9368 * @param stage ignored
9372 bool UniformBlockMemberInvalidOffsetAlignmentTest::isStageSupported(Utils::Shader::STAGES /* stage */)
9377 /** Prepare all test cases
9380 void UniformBlockMemberInvalidOffsetAlignmentTest::testInit()
9382 const GLuint n_types = getTypesNumber();
9383 bool stage_support[Utils::Shader::STAGE_MAX];
9385 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
9387 stage_support[stage] = isStageSupported((Utils::Shader::STAGES)stage);
9390 for (GLuint i = 0; i < n_types; ++i)
9392 const Utils::Type& type = getType(i);
9393 const GLuint alignment = type.GetBaseAlignment(false);
9394 const GLuint type_size = type.GetSize(true);
9395 const GLuint sec_to_end = getMaxBlockSize() - 2 * type_size;
9397 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
9399 if (false == stage_support[stage])
9404 for (GLuint offset = 0; offset <= type_size; ++offset)
9406 const GLuint modulo = offset % alignment;
9407 const bool is_aligned = (0 == modulo) ? true : false;
9408 const bool should_fail = !is_aligned;
9410 testCase test_case = { offset, should_fail, (Utils::Shader::STAGES)stage, type };
9412 m_test_cases.push_back(test_case);
9415 for (GLuint offset = sec_to_end; offset <= sec_to_end + type_size; ++offset)
9417 const GLuint modulo = offset % alignment;
9418 const bool is_aligned = (0 == modulo) ? true : false;
9419 const bool should_fail = !is_aligned;
9421 testCase test_case = { offset, should_fail, (Utils::Shader::STAGES)stage, type };
9423 m_test_cases.push_back(test_case);
9431 * @param context Test framework context
9433 UniformBlockMemberOverlappingOffsetsTest::UniformBlockMemberOverlappingOffsetsTest(deqp::Context& context)
9434 : NegativeTestBase(context, "uniform_block_member_overlapping_offsets",
9435 "Test verifies that overlapping offsets qualifiers cause compilation failure")
9437 /* Nothing to be done here */
9442 * @param context Test framework context
9443 * @param name Test name
9444 * @param description Test description
9446 UniformBlockMemberOverlappingOffsetsTest::UniformBlockMemberOverlappingOffsetsTest(deqp::Context& context,
9447 const glw::GLchar* name,
9448 const glw::GLchar* description)
9449 : NegativeTestBase(context, name, description)
9451 /* Nothing to be done here */
9454 /** Source for given test case and stage
9456 * @param test_case_index Index of test case
9457 * @param stage Shader stage
9459 * @return Shader source
9461 std::string UniformBlockMemberOverlappingOffsetsTest::getShaderSource(GLuint test_case_index,
9462 Utils::Shader::STAGES stage)
9464 static const GLchar* cs = "#version 430 core\n"
9465 "#extension GL_ARB_enhanced_layouts : require\n"
9467 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
9469 "layout (std140) uniform Block {\n"
9470 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9471 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9474 "writeonly uniform image2D uni_image;\n"
9478 " vec4 result = vec4(1, 0, 0.5, 1);\n"
9480 " if ((BOY_TYPE(1) == block.boy) ||\n"
9481 " (MAN_TYPE(0) == block.man) )\n"
9483 " result = vec4(1, 1, 1, 1);\n"
9486 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
9489 static const GLchar* fs = "#version 430 core\n"
9490 "#extension GL_ARB_enhanced_layouts : require\n"
9493 "out vec4 fs_out;\n"
9497 " fs_out = gs_fs;\n"
9500 static const GLchar* fs_tested = "#version 430 core\n"
9501 "#extension GL_ARB_enhanced_layouts : require\n"
9503 "layout (std140) uniform Block {\n"
9504 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9505 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9509 "out vec4 fs_out;\n"
9513 " if ((BOY_TYPE(1) == block.boy) ||\n"
9514 " (MAN_TYPE(0) == block.man) )\n"
9516 " fs_out = vec4(1, 1, 1, 1);\n"
9519 " fs_out += gs_fs;\n"
9522 static const GLchar* gs = "#version 430 core\n"
9523 "#extension GL_ARB_enhanced_layouts : require\n"
9525 "layout(points) in;\n"
9526 "layout(triangle_strip, max_vertices = 4) out;\n"
9528 "in vec4 tes_gs[];\n"
9533 " gs_fs = tes_gs[0];\n"
9534 " gl_Position = vec4(-1, -1, 0, 1);\n"
9536 " gs_fs = tes_gs[0];\n"
9537 " gl_Position = vec4(-1, 1, 0, 1);\n"
9539 " gs_fs = tes_gs[0];\n"
9540 " gl_Position = vec4(1, -1, 0, 1);\n"
9542 " gs_fs = tes_gs[0];\n"
9543 " gl_Position = vec4(1, 1, 0, 1);\n"
9547 static const GLchar* gs_tested = "#version 430 core\n"
9548 "#extension GL_ARB_enhanced_layouts : require\n"
9550 "layout(points) in;\n"
9551 "layout(triangle_strip, max_vertices = 4) out;\n"
9553 "layout (std140) uniform Block {\n"
9554 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9555 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9558 "in vec4 tes_gs[];\n"
9563 " if ((BOY_TYPE(1) == block.boy) ||\n"
9564 " (MAN_TYPE(0) == block.man) )\n"
9566 " gs_fs = vec4(1, 1, 1, 1);\n"
9569 " gs_fs += tes_gs[0];\n"
9570 " gl_Position = vec4(-1, -1, 0, 1);\n"
9572 " gs_fs += tes_gs[0];\n"
9573 " gl_Position = vec4(-1, 1, 0, 1);\n"
9575 " gs_fs += tes_gs[0];\n"
9576 " gl_Position = vec4(1, -1, 0, 1);\n"
9578 " gs_fs += tes_gs[0];\n"
9579 " gl_Position = vec4(1, 1, 0, 1);\n"
9583 static const GLchar* tcs = "#version 430 core\n"
9584 "#extension GL_ARB_enhanced_layouts : require\n"
9586 "layout(vertices = 1) out;\n"
9588 "in vec4 vs_tcs[];\n"
9589 "out vec4 tcs_tes[];\n"
9594 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
9596 " gl_TessLevelOuter[0] = 1.0;\n"
9597 " gl_TessLevelOuter[1] = 1.0;\n"
9598 " gl_TessLevelOuter[2] = 1.0;\n"
9599 " gl_TessLevelOuter[3] = 1.0;\n"
9600 " gl_TessLevelInner[0] = 1.0;\n"
9601 " gl_TessLevelInner[1] = 1.0;\n"
9604 static const GLchar* tcs_tested = "#version 430 core\n"
9605 "#extension GL_ARB_enhanced_layouts : require\n"
9607 "layout(vertices = 1) out;\n"
9609 "layout (std140) uniform Block {\n"
9610 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9611 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9614 "in vec4 vs_tcs[];\n"
9615 "out vec4 tcs_tes[];\n"
9619 " if ((BOY_TYPE(1) == block.boy) ||\n"
9620 " (MAN_TYPE(0) == block.man) )\n"
9622 " tcs_tes[gl_InvocationID] = vec4(1, 1, 1, 1);\n"
9626 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
9628 " gl_TessLevelOuter[0] = 1.0;\n"
9629 " gl_TessLevelOuter[1] = 1.0;\n"
9630 " gl_TessLevelOuter[2] = 1.0;\n"
9631 " gl_TessLevelOuter[3] = 1.0;\n"
9632 " gl_TessLevelInner[0] = 1.0;\n"
9633 " gl_TessLevelInner[1] = 1.0;\n"
9636 static const GLchar* tes = "#version 430 core\n"
9637 "#extension GL_ARB_enhanced_layouts : require\n"
9639 "layout(isolines, point_mode) in;\n"
9641 "in vec4 tcs_tes[];\n"
9642 "out vec4 tes_gs;\n"
9646 " tes_gs = tcs_tes[0];\n"
9649 static const GLchar* tes_tested = "#version 430 core\n"
9650 "#extension GL_ARB_enhanced_layouts : require\n"
9652 "layout(isolines, point_mode) in;\n"
9654 "layout (std140) uniform Block {\n"
9655 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9656 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9659 "in vec4 tcs_tes[];\n"
9660 "out vec4 tes_gs;\n"
9664 " if ((BOY_TYPE(1) == block.boy) ||\n"
9665 " (MAN_TYPE(0) == block.man) )\n"
9667 " tes_gs = vec4(1, 1, 1, 1);\n"
9670 " tes_gs += tcs_tes[0];\n"
9673 static const GLchar* vs = "#version 430 core\n"
9674 "#extension GL_ARB_enhanced_layouts : require\n"
9677 "out vec4 vs_tcs;\n"
9681 " vs_tcs = in_vs;\n"
9684 static const GLchar* vs_tested = "#version 430 core\n"
9685 "#extension GL_ARB_enhanced_layouts : require\n"
9687 "layout (std140) uniform Block {\n"
9688 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9689 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9693 "out vec4 vs_tcs;\n"
9697 " if ((BOY_TYPE(1) == block.boy) ||\n"
9698 " (MAN_TYPE(0) == block.man) )\n"
9700 " vs_tcs = vec4(1, 1, 1, 1);\n"
9703 " vs_tcs += in_vs;\n"
9708 testCase& test_case = m_test_cases[test_case_index];
9710 if (test_case.m_stage == stage)
9713 const GLuint boy_offset = test_case.m_boy_offset;
9714 const Utils::Type& boy_type = test_case.m_boy_type;
9715 const GLchar* boy_type_name = boy_type.GetGLSLTypeName();
9716 const GLuint man_offset = test_case.m_man_offset;
9717 const Utils::Type& man_type = test_case.m_man_type;
9718 const GLchar* man_type_name = man_type.GetGLSLTypeName();
9719 size_t position = 0;
9723 case Utils::Shader::COMPUTE:
9726 case Utils::Shader::FRAGMENT:
9729 case Utils::Shader::GEOMETRY:
9732 case Utils::Shader::TESS_CTRL:
9733 source = tcs_tested;
9735 case Utils::Shader::TESS_EVAL:
9736 source = tes_tested;
9738 case Utils::Shader::VERTEX:
9742 TCU_FAIL("Invalid enum");
9745 sprintf(buffer, "%d", boy_offset);
9746 Utils::replaceToken("BOY_OFFSET", position, buffer, source);
9747 Utils::replaceToken("BOY_TYPE", position, boy_type_name, source);
9748 sprintf(buffer, "%d", man_offset);
9749 Utils::replaceToken("MAN_OFFSET", position, buffer, source);
9750 Utils::replaceToken("MAN_TYPE", position, man_type_name, source);
9751 Utils::replaceToken("BOY_TYPE", position, boy_type_name, source);
9752 Utils::replaceToken("MAN_TYPE", position, man_type_name, source);
9758 case Utils::Shader::FRAGMENT:
9761 case Utils::Shader::GEOMETRY:
9764 case Utils::Shader::TESS_CTRL:
9767 case Utils::Shader::TESS_EVAL:
9770 case Utils::Shader::VERTEX:
9774 TCU_FAIL("Invalid enum");
9781 /** Get description of test case
9783 * @param test_case_index Index of test case
9785 * @return Type name and offset
9787 std::string UniformBlockMemberOverlappingOffsetsTest::getTestCaseName(GLuint test_case_index)
9789 std::stringstream stream;
9790 testCase& test_case = m_test_cases[test_case_index];
9792 stream << "Type: " << test_case.m_boy_type.GetGLSLTypeName() << ", offset: " << test_case.m_boy_offset
9793 << ". Type: " << test_case.m_man_type.GetGLSLTypeName() << ", offset: " << test_case.m_man_offset;
9795 return stream.str();
9798 /** Get number of test cases
9800 * @return Number of test cases
9802 GLuint UniformBlockMemberOverlappingOffsetsTest::getTestCaseNumber()
9804 return static_cast<GLuint>(m_test_cases.size());
9807 /** Selects if "compute" stage is relevant for test
9809 * @param test_case_index Index of test case
9811 * @return true when tested stage is compute
9813 bool UniformBlockMemberOverlappingOffsetsTest::isComputeRelevant(GLuint test_case_index)
9815 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
9818 /** Checks if stage is supported
9820 * @param stage ignored
9824 bool UniformBlockMemberOverlappingOffsetsTest::isStageSupported(Utils::Shader::STAGES /* stage */)
9829 /** Prepare all test cases
9832 void UniformBlockMemberOverlappingOffsetsTest::testInit()
9834 const GLuint n_types = getTypesNumber();
9835 bool stage_support[Utils::Shader::STAGE_MAX];
9837 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
9839 stage_support[stage] = isStageSupported((Utils::Shader::STAGES)stage);
9842 for (GLuint i = 0; i < n_types; ++i)
9844 const Utils::Type& boy_type = getType(i);
9845 const GLuint boy_size = boy_type.GetActualAlignment(1 /* align */, false /* is_array*/);
9847 for (GLuint j = 0; j < n_types; ++j)
9849 const Utils::Type& man_type = getType(j);
9850 const GLuint man_align = man_type.GetBaseAlignment(false);
9851 const GLuint man_size = man_type.GetActualAlignment(1 /* align */, false /* is_array*/);
9853 const GLuint boy_offset = lcm(boy_size, man_size);
9854 const GLuint man_after_start = boy_offset + 1;
9855 const GLuint man_after_off = man_type.GetActualOffset(man_after_start, man_size);
9856 const GLuint man_before_start = boy_offset - man_align;
9857 const GLuint man_before_off = man_type.GetActualOffset(man_before_start, man_size);
9859 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
9861 if (false == stage_support[stage])
9866 if ((boy_offset > man_before_off) && (boy_offset < man_before_off + man_size))
9868 testCase test_case = { boy_offset, boy_type, man_before_off, man_type,
9869 (Utils::Shader::STAGES)stage };
9871 m_test_cases.push_back(test_case);
9874 if ((boy_offset < man_after_off) && (boy_offset + boy_size > man_after_off))
9876 testCase test_case = { boy_offset, boy_type, man_after_off, man_type,
9877 (Utils::Shader::STAGES)stage };
9879 m_test_cases.push_back(test_case);
9882 /* Boy offset, should be fine for both types */
9883 testCase test_case = { boy_offset, boy_type, boy_offset, man_type, (Utils::Shader::STAGES)stage };
9885 m_test_cases.push_back(test_case);
9891 /** Find greatest common divisor for a and b
9893 * @param a A argument
9894 * @param b B argument
9896 * @return Found gcd value
9898 GLuint UniformBlockMemberOverlappingOffsetsTest::gcd(GLuint a, GLuint b)
9900 if ((0 != a) && (0 == b))
9906 GLuint greater = std::max(a, b);
9907 GLuint lesser = std::min(a, b);
9909 return gcd(lesser, greater % lesser);
9913 /** Find lowest common multiple for a and b
9915 * @param a A argument
9916 * @param b B argument
9918 * @return Found gcd value
9920 GLuint UniformBlockMemberOverlappingOffsetsTest::lcm(GLuint a, GLuint b)
9922 return (a * b) / gcd(a, b);
9927 * @param context Test framework context
9929 UniformBlockMemberAlignNonPowerOf2Test::UniformBlockMemberAlignNonPowerOf2Test(deqp::Context& context)
9930 : NegativeTestBase(context, "uniform_block_member_align_non_power_of_2",
9931 "Test verifies that align qualifier requires value that is a power of 2")
9933 /* Nothing to be done here */
9938 * @param context Test framework context
9939 * @param name Test name
9940 * @param description Test description
9942 UniformBlockMemberAlignNonPowerOf2Test::UniformBlockMemberAlignNonPowerOf2Test(deqp::Context& context,
9943 const glw::GLchar* name,
9944 const glw::GLchar* description)
9945 : NegativeTestBase(context, name, description)
9947 /* Nothing to be done here */
9950 /** Source for given test case and stage
9952 * @param test_case_index Index of test case
9953 * @param stage Shader stage
9955 * @return Shader source
9957 std::string UniformBlockMemberAlignNonPowerOf2Test::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
9959 static const GLchar* cs = "#version 430 core\n"
9960 "#extension GL_ARB_enhanced_layouts : require\n"
9962 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
9964 "layout (std140) uniform Block {\n"
9966 " layout (align = ALIGN) TYPE man;\n"
9969 "writeonly uniform image2D uni_image;\n"
9973 " vec4 result = vec4(1, 0, 0.5, 1);\n"
9975 " if (TYPE(0) == block.man)\n"
9977 " result = vec4(1, 1, 1, 1) - block.boy;\n"
9980 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
9983 static const GLchar* fs = "#version 430 core\n"
9984 "#extension GL_ARB_enhanced_layouts : require\n"
9987 "out vec4 fs_out;\n"
9991 " fs_out = gs_fs;\n"
9994 static const GLchar* fs_tested = "#version 430 core\n"
9995 "#extension GL_ARB_enhanced_layouts : require\n"
9997 "layout (std140) uniform Block {\n"
9999 " layout (align = ALIGN) TYPE man;\n"
10003 "out vec4 fs_out;\n"
10007 " if (TYPE(0) == block.man)\n"
10009 " fs_out = block.boy;\n"
10012 " fs_out += gs_fs;\n"
10015 static const GLchar* gs = "#version 430 core\n"
10016 "#extension GL_ARB_enhanced_layouts : require\n"
10018 "layout(points) in;\n"
10019 "layout(triangle_strip, max_vertices = 4) out;\n"
10021 "in vec4 tes_gs[];\n"
10022 "out vec4 gs_fs;\n"
10026 " gs_fs = tes_gs[0];\n"
10027 " gl_Position = vec4(-1, -1, 0, 1);\n"
10029 " gs_fs = tes_gs[0];\n"
10030 " gl_Position = vec4(-1, 1, 0, 1);\n"
10032 " gs_fs = tes_gs[0];\n"
10033 " gl_Position = vec4(1, -1, 0, 1);\n"
10035 " gs_fs = tes_gs[0];\n"
10036 " gl_Position = vec4(1, 1, 0, 1);\n"
10040 static const GLchar* gs_tested = "#version 430 core\n"
10041 "#extension GL_ARB_enhanced_layouts : require\n"
10043 "layout(points) in;\n"
10044 "layout(triangle_strip, max_vertices = 4) out;\n"
10046 "layout (std140) uniform Block {\n"
10048 " layout (align = ALIGN) TYPE man;\n"
10051 "in vec4 tes_gs[];\n"
10052 "out vec4 gs_fs;\n"
10056 " if (TYPE(0) == block.man)\n"
10058 " gs_fs = block.boy;\n"
10061 " gs_fs += tes_gs[0];\n"
10062 " gl_Position = vec4(-1, -1, 0, 1);\n"
10064 " gs_fs += tes_gs[0];\n"
10065 " gl_Position = vec4(-1, 1, 0, 1);\n"
10067 " gs_fs += tes_gs[0];\n"
10068 " gl_Position = vec4(1, -1, 0, 1);\n"
10070 " gs_fs += tes_gs[0];\n"
10071 " gl_Position = vec4(1, 1, 0, 1);\n"
10075 static const GLchar* tcs = "#version 430 core\n"
10076 "#extension GL_ARB_enhanced_layouts : require\n"
10078 "layout(vertices = 1) out;\n"
10080 "in vec4 vs_tcs[];\n"
10081 "out vec4 tcs_tes[];\n"
10086 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
10088 " gl_TessLevelOuter[0] = 1.0;\n"
10089 " gl_TessLevelOuter[1] = 1.0;\n"
10090 " gl_TessLevelOuter[2] = 1.0;\n"
10091 " gl_TessLevelOuter[3] = 1.0;\n"
10092 " gl_TessLevelInner[0] = 1.0;\n"
10093 " gl_TessLevelInner[1] = 1.0;\n"
10096 static const GLchar* tcs_tested = "#version 430 core\n"
10097 "#extension GL_ARB_enhanced_layouts : require\n"
10099 "layout(vertices = 1) out;\n"
10101 "layout (std140) uniform Block {\n"
10103 " layout (align = ALIGN) TYPE man;\n"
10106 "in vec4 vs_tcs[];\n"
10107 "out vec4 tcs_tes[];\n"
10111 " if (TYPE(0) == block.man)\n"
10113 " tcs_tes[gl_InvocationID] = block.boy;\n"
10117 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
10119 " gl_TessLevelOuter[0] = 1.0;\n"
10120 " gl_TessLevelOuter[1] = 1.0;\n"
10121 " gl_TessLevelOuter[2] = 1.0;\n"
10122 " gl_TessLevelOuter[3] = 1.0;\n"
10123 " gl_TessLevelInner[0] = 1.0;\n"
10124 " gl_TessLevelInner[1] = 1.0;\n"
10127 static const GLchar* tes = "#version 430 core\n"
10128 "#extension GL_ARB_enhanced_layouts : require\n"
10130 "layout(isolines, point_mode) in;\n"
10132 "in vec4 tcs_tes[];\n"
10133 "out vec4 tes_gs;\n"
10137 " tes_gs = tcs_tes[0];\n"
10140 static const GLchar* tes_tested = "#version 430 core\n"
10141 "#extension GL_ARB_enhanced_layouts : require\n"
10143 "layout(isolines, point_mode) in;\n"
10145 "layout (std140) uniform Block {\n"
10147 " layout (align = ALIGN) TYPE man;\n"
10150 "in vec4 tcs_tes[];\n"
10151 "out vec4 tes_gs;\n"
10155 " if (TYPE(0) == block.man)\n"
10157 " tes_gs = block.boy;\n"
10160 " tes_gs += tcs_tes[0];\n"
10163 static const GLchar* vs = "#version 430 core\n"
10164 "#extension GL_ARB_enhanced_layouts : require\n"
10167 "out vec4 vs_tcs;\n"
10171 " vs_tcs = in_vs;\n"
10174 static const GLchar* vs_tested = "#version 430 core\n"
10175 "#extension GL_ARB_enhanced_layouts : require\n"
10177 "layout (std140) uniform Block {\n"
10179 " layout (align = ALIGN) TYPE man;\n"
10183 "out vec4 vs_tcs;\n"
10187 " if (TYPE(0) == block.man)\n"
10189 " vs_tcs = block.boy;\n"
10192 " vs_tcs += in_vs;\n"
10196 std::string source;
10197 testCase& test_case = m_test_cases[test_case_index];
10199 if (test_case.m_stage == stage)
10202 const GLuint alignment = test_case.m_alignment;
10203 const Utils::Type& type = test_case.m_type;
10204 const GLchar* type_name = type.GetGLSLTypeName();
10205 size_t position = 0;
10209 case Utils::Shader::COMPUTE:
10212 case Utils::Shader::FRAGMENT:
10213 source = fs_tested;
10215 case Utils::Shader::GEOMETRY:
10216 source = gs_tested;
10218 case Utils::Shader::TESS_CTRL:
10219 source = tcs_tested;
10221 case Utils::Shader::TESS_EVAL:
10222 source = tes_tested;
10224 case Utils::Shader::VERTEX:
10225 source = vs_tested;
10228 TCU_FAIL("Invalid enum");
10231 sprintf(buffer, "%d", alignment);
10232 Utils::replaceToken("ALIGN", position, buffer, source);
10233 Utils::replaceToken("TYPE", position, type_name, source);
10234 Utils::replaceToken("TYPE", position, type_name, source);
10240 case Utils::Shader::FRAGMENT:
10243 case Utils::Shader::GEOMETRY:
10246 case Utils::Shader::TESS_CTRL:
10249 case Utils::Shader::TESS_EVAL:
10252 case Utils::Shader::VERTEX:
10256 TCU_FAIL("Invalid enum");
10263 /** Get description of test case
10265 * @param test_case_index Index of test case
10267 * @return Type name and offset
10269 std::string UniformBlockMemberAlignNonPowerOf2Test::getTestCaseName(GLuint test_case_index)
10271 std::stringstream stream;
10272 testCase& test_case = m_test_cases[test_case_index];
10274 stream << "Type: " << test_case.m_type.GetGLSLTypeName() << ", align: " << test_case.m_alignment;
10276 return stream.str();
10279 /** Get number of test cases
10281 * @return Number of test cases
10283 GLuint UniformBlockMemberAlignNonPowerOf2Test::getTestCaseNumber()
10285 return static_cast<GLuint>(m_test_cases.size());
10288 /** Selects if "compute" stage is relevant for test
10290 * @param test_case_index Index of test case
10292 * @return true when tested stage is compute
10294 bool UniformBlockMemberAlignNonPowerOf2Test::isComputeRelevant(GLuint test_case_index)
10296 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
10299 /** Checks if stage is supported
10305 bool UniformBlockMemberAlignNonPowerOf2Test::isStageSupported(Utils::Shader::STAGES /* stage */)
10310 /** Selects if compilation failure is expected result
10312 * @param test_case_index Index of test case
10314 * @return should_fail field from testCase
10316 bool UniformBlockMemberAlignNonPowerOf2Test::isFailureExpected(GLuint test_case_index)
10318 return m_test_cases[test_case_index].m_should_fail;
10321 /** Prepare all test cases
10324 void UniformBlockMemberAlignNonPowerOf2Test::testInit()
10326 static const GLuint dmat4_size = 128;
10327 const GLuint n_types = getTypesNumber();
10328 bool stage_support[Utils::Shader::STAGE_MAX];
10330 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
10332 stage_support[stage] = isStageSupported((Utils::Shader::STAGES)stage);
10335 for (GLuint j = 0; j < n_types; ++j)
10337 const Utils::Type& type = getType(j);
10339 for (GLuint align = 0; align <= dmat4_size; ++align)
10342 #if WRKARD_UNIFORMBLOCKMEMBERALIGNNONPOWEROF2TEST
10344 const bool should_fail = (0 == align) ? false : !isPowerOf2(align);
10346 #else /* WRKARD_UNIFORMBLOCKMEMBERALIGNNONPOWEROF2TEST */
10348 const bool should_fail = !isPowerOf2(align);
10350 #endif /* WRKARD_UNIFORMBLOCKMEMBERALIGNNONPOWEROF2TEST */
10352 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
10354 if (false == stage_support[stage])
10359 testCase test_case = { align, type, should_fail, (Utils::Shader::STAGES)stage };
10361 m_test_cases.push_back(test_case);
10367 /** Check if value is power of 2
10369 * @param val Tested value
10371 * @return true if val is power of 2, false otherwise
10373 bool UniformBlockMemberAlignNonPowerOf2Test::isPowerOf2(GLuint val)
10380 return (0 == (val & (val - 1)));
10385 * @param context Test framework context
10387 UniformBlockAlignmentTest::UniformBlockAlignmentTest(deqp::Context& context)
10388 : TextureTestBase(context, "uniform_block_alignment", "Test verifies offset and alignment of uniform buffer")
10392 /** Get interface of program
10395 * @param program_interface Interface of program
10396 * @param varying_passthrough Collection of connections between in and out variables
10398 void UniformBlockAlignmentTest::getProgramInterface(GLuint /* test_case_index */,
10399 Utils::ProgramInterface& program_interface,
10400 Utils::VaryingPassthrough& varying_passthrough)
10402 static const Utils::Type vec4 = Utils::Type::vec4;
10404 #if WRKARD_UNIFORMBLOCKALIGNMENT
10406 static const GLuint block_align = 16;
10408 #else /* WRKARD_UNIFORMBLOCKALIGNMENT */
10410 static const GLuint block_align = 64;
10412 #endif /* WRKARD_UNIFORMBLOCKALIGNMENT */
10414 static const GLuint vec4_stride = 16;
10415 static const GLuint data_stride = vec4_stride * 2; /* one vec4 + one scalar aligned to 16 */
10417 /*Fixed a test issue, the fifth_offset should be calculated by block_align, instead of fifth_align, according to spec, the actual
10418 alignment of a member will be the greater of the specified alignment and the base aligment for the member type
10420 const GLuint first_offset = 0; /* vec4 at 0 */
10421 const GLuint second_offset = Utils::Type::GetActualOffset(first_offset + vec4_stride, block_align); /* Data at 32 */
10422 const GLuint third_offset =
10423 Utils::Type::GetActualOffset(second_offset + data_stride, block_align); /* Data[2] at 64 */
10424 const GLuint fourth_offset =
10425 Utils::Type::GetActualOffset(third_offset + data_stride * 2, block_align); /* vec4[3] at 96 */
10426 const GLuint fifth_offset =
10427 Utils::Type::GetActualOffset(fourth_offset + vec4_stride * 3, block_align); /* vec4[2] at 160 */
10428 const GLuint sixth_offset =
10429 Utils::Type::GetActualOffset(fifth_offset + vec4_stride * 2, block_align); /* Data at 192 */
10431 Utils::Interface* structure = program_interface.Structure("Data");
10433 structure->Member("vector", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::vec4,
10434 false /* normalized */, 0 /* n_array_elements */, Utils::Type::vec4.GetSize(), 0 /* offset */);
10436 structure->Member("scalar", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::_float,
10437 false /* normalized */, 0 /* n_array_elements */, Utils::Type::_float.GetSize(),
10438 Utils::Type::vec4.GetSize() /* offset */);
10440 /* Prepare Block */
10441 Utils::Interface* vs_uni_block = program_interface.Block("vs_uni_Block");
10443 vs_uni_block->Member("first", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::vec4,
10444 false /* normalized */, 0 /* n_array_elements */, vec4_stride, first_offset /* offset */);
10446 vs_uni_block->Member("second", "", 0 /* expected_component */, 0 /* expected_location */, structure,
10447 0 /* n_array_elements */, data_stride, second_offset);
10449 vs_uni_block->Member("third", "", 0 /* expected_component */, 0 /* expected_location */, structure,
10450 2 /* n_array_elements */, data_stride, third_offset);
10452 vs_uni_block->Member("fourth", "", 0 /* expected_component */, 0 /* expected_location */, vec4,
10453 false /* normalized */, 3 /* n_array_elements */, vec4_stride, fourth_offset);
10455 vs_uni_block->Member("fifth", "layout(align = 64)", 0 /* expected_component */, 0 /* expected_location */, vec4,
10456 false /* normalized */, 2 /* n_array_elements */, vec4_stride, fifth_offset);
10458 vs_uni_block->Member("sixth", "", 0 /* expected_component */, 0 /* expected_location */, structure,
10459 0 /* n_array_elements */, data_stride, sixth_offset);
10461 const GLuint stride = calculateStride(*vs_uni_block);
10462 m_data.resize(stride);
10463 generateData(*vs_uni_block, 0, m_data);
10465 Utils::ShaderInterface& vs_si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
10467 /* Add uniform BLOCK */
10468 #if WRKARD_UNIFORMBLOCKALIGNMENT
10469 vs_si.Uniform("vs_uni_block", "layout (std140, binding = BINDING)", 0, 0, vs_uni_block, 0,
10470 static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
10471 #else /* WRKARD_UNIFORMBLOCKALIGNMENT */
10472 vs_si.Uniform("vs_uni_block", "layout (std140, binding = BINDING, align = 64)", 0, 0, vs_uni_block, 0,
10473 static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
10474 #endif /* WRKARD_UNIFORMBLOCKALIGNMENT */
10476 program_interface.CloneVertexInterface(varying_passthrough);
10481 * @param context Test framework context
10483 SSBMemberOffsetAndAlignTest::SSBMemberOffsetAndAlignTest(deqp::Context& context)
10484 : TextureTestBase(context, "ssb_member_offset_and_align",
10485 "Test verifies offsets and alignment of storage buffer members")
10489 /** Get interface of program
10491 * @param test_case_index Test case index
10492 * @param program_interface Interface of program
10493 * @param varying_passthrough Collection of connections between in and out variables
10495 void SSBMemberOffsetAndAlignTest::getProgramInterface(GLuint test_case_index,
10496 Utils::ProgramInterface& program_interface,
10497 Utils::VaryingPassthrough& varying_passthrough)
10499 std::string globals = "const int basic_size = BASIC_SIZE;\n"
10500 "const int type_align = TYPE_ALIGN;\n"
10501 "const int type_size = TYPE_SIZE;\n";
10503 Utils::Type type = getType(test_case_index);
10504 GLuint basic_size = Utils::Type::GetTypeSize(type.m_basic_type);
10505 const GLuint base_align = type.GetBaseAlignment(false);
10506 const GLuint array_align = type.GetBaseAlignment(true);
10507 const GLuint base_stride = Utils::Type::CalculateStd140Stride(base_align, type.m_n_columns, 0);
10508 const GLuint type_align = Utils::roundUpToPowerOf2(base_stride);
10510 /* Calculate offsets */
10511 const GLuint first_offset = 0;
10512 const GLuint second_offset = type.GetActualOffset(base_stride, basic_size / 2);
10514 #if WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST
10516 const GLuint third_offset = type.GetActualOffset(second_offset + base_stride, base_align);
10517 const GLuint fourth_offset = type.GetActualOffset(third_offset + base_stride, base_align);
10518 const GLuint fifth_offset = type.GetActualOffset(fourth_offset + base_stride, base_align);
10519 const GLuint sixth_offset = type.GetActualOffset(fifth_offset + base_stride, array_align);
10520 const GLuint seventh_offset = type.GetActualOffset(sixth_offset + base_stride, array_align);
10521 const GLuint eigth_offset = type.GetActualOffset(seventh_offset + base_stride, array_align);
10523 #else /* WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST */
10525 const GLuint third_offset = type.GetActualOffset(second_offset + base_stride, 2 * type_align);
10526 const GLuint fourth_offset = type.GetActualOffset(3 * type_align + base_stride, base_align);
10527 const GLuint fifth_offset = type.GetActualOffset(fourth_offset + base_stride, base_align);
10528 const GLuint sixth_offset = type.GetActualOffset(fifth_offset + base_stride, array_align);
10529 const GLuint seventh_offset = type.GetActualOffset(sixth_offset + base_stride, array_align);
10530 const GLuint eigth_offset = type.GetActualOffset(seventh_offset + base_stride, 8 * basic_size);
10532 #endif /* WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST */
10535 const std::vector<GLubyte>& first = type.GenerateData();
10536 const std::vector<GLubyte>& second = type.GenerateData();
10537 const std::vector<GLubyte>& third = type.GenerateData();
10538 const std::vector<GLubyte>& fourth = type.GenerateData();
10540 m_data.resize(eigth_offset + base_stride);
10541 GLubyte* ptr = &m_data[0];
10542 memcpy(ptr + first_offset, &first[0], first.size());
10543 memcpy(ptr + second_offset, &second[0], second.size());
10544 memcpy(ptr + third_offset, &third[0], third.size());
10545 memcpy(ptr + fourth_offset, &fourth[0], fourth.size());
10546 memcpy(ptr + fifth_offset, &fourth[0], fourth.size());
10547 memcpy(ptr + sixth_offset, &third[0], third.size());
10548 memcpy(ptr + seventh_offset, &second[0], second.size());
10549 memcpy(ptr + eigth_offset, &first[0], first.size());
10551 /* Prepare globals */
10552 size_t position = 0;
10555 sprintf(buffer, "%d", basic_size);
10556 Utils::replaceToken("BASIC_SIZE", position, buffer, globals);
10558 sprintf(buffer, "%d", type_align);
10559 Utils::replaceToken("TYPE_ALIGN", position, buffer, globals);
10561 sprintf(buffer, "%d", base_stride);
10562 Utils::replaceToken("TYPE_SIZE", position, buffer, globals);
10564 /* Prepare Block */
10565 Utils::Interface* vs_buf_block = program_interface.Block("vs_buf_Block");
10567 vs_buf_block->Member("at_first_offset", "layout(offset = 0, align = 8 * basic_size)", 0 /* expected_component */,
10568 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
10571 vs_buf_block->Member("at_second_offset", "layout(offset = type_size, align = basic_size / 2)",
10572 0 /* expected_component */, 0 /* expected_location */, type, false /* normalized */,
10573 0 /* n_array_elements */, base_stride, second_offset);
10575 vs_buf_block->Member("at_third_offset", "layout(align = 2 * type_align)", 0 /* expected_component */,
10576 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
10579 vs_buf_block->Member("at_fourth_offset", "layout(offset = 3 * type_align + type_size)", 0 /* expected_component */,
10580 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
10583 vs_buf_block->Member("at_fifth_offset", "", 0 /* expected_component */, 0 /* expected_location */, type,
10584 false /* normalized */, 0 /* n_array_elements */, base_stride, fifth_offset);
10586 vs_buf_block->Member("at_sixth_offset", "", 0 /* expected_component */, 0 /* expected_location */, type,
10587 false /* normalized */, 2 /* n_array_elements */, array_align * 2, sixth_offset);
10589 vs_buf_block->Member("at_eigth_offset", "layout(align = 8 * basic_size)", 0 /* expected_component */,
10590 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
10593 Utils::ShaderInterface& vs_si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
10596 vs_si.m_globals = globals;
10598 /* Add uniform BLOCK */
10599 vs_si.SSB("vs_buf_block", "layout (std140, binding = BINDING)", 0, 0, vs_buf_block, 0,
10600 static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
10603 program_interface.CloneVertexInterface(varying_passthrough);
10608 * @param test_case_index Index of test case
10610 * @return Name of type test in test_case_index
10612 std::string SSBMemberOffsetAndAlignTest::getTestCaseName(glw::GLuint test_case_index)
10614 return getTypeName(test_case_index);
10617 /** Returns number of types to test
10619 * @return Number of types, 34
10621 glw::GLuint SSBMemberOffsetAndAlignTest::getTestCaseNumber()
10623 return getTypesNumber();
10626 /** Prepare code snippet that will verify in and uniform variables
10630 * @param stage Shader stage
10632 * @return Code that verify variables
10634 std::string SSBMemberOffsetAndAlignTest::getVerificationSnippet(GLuint /* test_case_index */,
10635 Utils::ProgramInterface& /* program_interface */,
10636 Utils::Shader::STAGES stage)
10638 std::string verification = "if ( (PREFIXblock.at_first_offset != PREFIXblock.at_eigth_offset ) ||\n"
10639 " (PREFIXblock.at_second_offset != PREFIXblock.at_sixth_offset[1]) ||\n"
10640 " (PREFIXblock.at_third_offset != PREFIXblock.at_sixth_offset[0]) ||\n"
10641 " (PREFIXblock.at_fourth_offset != PREFIXblock.at_fifth_offset ) )\n"
10646 const GLchar* prefix = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::SSB);
10648 Utils::replaceAllTokens("PREFIX", prefix, verification);
10650 return verification;
10653 /** Selects if "draw" stages are relevant for test
10657 * @return true if all stages support shader storage buffers, false otherwise
10659 bool SSBMemberOffsetAndAlignTest::isDrawRelevant(GLuint /* test_case_index */)
10661 const Functions& gl = m_context.getRenderContext().getFunctions();
10662 GLint gs_supported_buffers = 0;
10663 GLint tcs_supported_buffers = 0;
10664 GLint tes_supported_buffers = 0;
10665 GLint vs_supported_buffers = 0;
10667 gl.getIntegerv(GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS, &gs_supported_buffers);
10668 gl.getIntegerv(GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS, &tcs_supported_buffers);
10669 gl.getIntegerv(GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS, &tes_supported_buffers);
10670 gl.getIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &vs_supported_buffers);
10672 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
10674 return ((1 <= gs_supported_buffers) && (1 <= tcs_supported_buffers) && (1 <= tes_supported_buffers) &&
10675 (1 <= vs_supported_buffers));
10680 * @param context Test framework context
10682 SSBLayoutQualifierConflictTest::SSBLayoutQualifierConflictTest(deqp::Context& context)
10683 : NegativeTestBase(context, "ssb_layout_qualifier_conflict", "Test verifies that std140 or std430 is required when "
10684 "offset and/or align qualifiers are used with storage "
10687 /* Nothing to be done here */
10690 /** Source for given test case and stage
10692 * @param test_case_index Index of test case
10693 * @param stage Shader stage
10695 * @return Shader source
10697 std::string SSBLayoutQualifierConflictTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
10699 static const GLchar* cs = "#version 430 core\n"
10700 "#extension GL_ARB_enhanced_layouts : require\n"
10702 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
10704 "layout (QUALIFIERbinding = BINDING) buffer cs_Block {\n"
10705 " layout(offset = 16) vec4 boy;\n"
10706 " layout(align = 64) vec4 man;\n"
10709 "writeonly uniform image2D uni_image;\n"
10713 " vec4 result = uni_block.boy + uni_block.man;\n"
10715 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
10718 static const GLchar* fs = "#version 430 core\n"
10719 "#extension GL_ARB_enhanced_layouts : require\n"
10721 "layout (QUALIFIERbinding = BINDING) buffer Block {\n"
10722 " layout(offset = 16) vec4 boy;\n"
10723 " layout(align = 64) vec4 man;\n"
10727 "out vec4 fs_out;\n"
10731 " fs_out = gs_fs + uni_block.boy + uni_block.man;\n"
10734 static const GLchar* gs = "#version 430 core\n"
10735 "#extension GL_ARB_enhanced_layouts : require\n"
10737 "layout(points) in;\n"
10738 "layout(triangle_strip, max_vertices = 4) out;\n"
10740 "layout (QUALIFIERbinding = BINDING) buffer gs_Block {\n"
10741 " layout(offset = 16) vec4 boy;\n"
10742 " layout(align = 64) vec4 man;\n"
10745 "in vec4 tes_gs[];\n"
10746 "out vec4 gs_fs;\n"
10750 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
10751 " gl_Position = vec4(-1, -1, 0, 1);\n"
10753 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
10754 " gl_Position = vec4(-1, 1, 0, 1);\n"
10756 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
10757 " gl_Position = vec4(1, -1, 0, 1);\n"
10759 " gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
10760 " gl_Position = vec4(1, 1, 0, 1);\n"
10764 static const GLchar* tcs =
10765 "#version 430 core\n"
10766 "#extension GL_ARB_enhanced_layouts : require\n"
10768 "layout(vertices = 1) out;\n"
10770 "layout (QUALIFIERbinding = BINDING) buffer tcs_Block {\n"
10771 " layout(offset = 16) vec4 boy;\n"
10772 " layout(align = 64) vec4 man;\n"
10775 "in vec4 vs_tcs[];\n"
10776 "out vec4 tcs_tes[];\n"
10781 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID] + uni_block.boy + uni_block.man;\n"
10783 " gl_TessLevelOuter[0] = 1.0;\n"
10784 " gl_TessLevelOuter[1] = 1.0;\n"
10785 " gl_TessLevelOuter[2] = 1.0;\n"
10786 " gl_TessLevelOuter[3] = 1.0;\n"
10787 " gl_TessLevelInner[0] = 1.0;\n"
10788 " gl_TessLevelInner[1] = 1.0;\n"
10791 static const GLchar* tes = "#version 430 core\n"
10792 "#extension GL_ARB_enhanced_layouts : require\n"
10794 "layout(isolines, point_mode) in;\n"
10796 "layout (QUALIFIERbinding = BINDING) buffer tes_Block {\n"
10797 " layout(offset = 16) vec4 boy;\n"
10798 " layout(align = 64) vec4 man;\n"
10801 "in vec4 tcs_tes[];\n"
10802 "out vec4 tes_gs;\n"
10806 " tes_gs = tcs_tes[0] + uni_block.boy + uni_block.man;\n"
10809 static const GLchar* vs = "#version 430 core\n"
10810 "#extension GL_ARB_enhanced_layouts : require\n"
10812 "layout (QUALIFIERbinding = BINDING) buffer vs_Block {\n"
10813 " layout(offset = 16) vec4 boy;\n"
10814 " layout(align = 64) vec4 man;\n"
10818 "out vec4 vs_tcs;\n"
10822 " vs_tcs = in_vs + uni_block.boy + uni_block.man;\n"
10827 size_t position = 0;
10828 std::string source;
10829 testCase& test_case = m_test_cases[test_case_index];
10830 std::string qualifier = getQualifierName(test_case.m_qualifier);
10832 if (false == qualifier.empty())
10834 qualifier.append(", ");
10837 sprintf(buffer, "%d", stage);
10841 case Utils::Shader::COMPUTE:
10844 case Utils::Shader::FRAGMENT:
10847 case Utils::Shader::GEOMETRY:
10850 case Utils::Shader::TESS_CTRL:
10853 case Utils::Shader::TESS_EVAL:
10856 case Utils::Shader::VERTEX:
10860 TCU_FAIL("Invalid enum");
10863 if (test_case.m_stage == stage)
10865 Utils::replaceToken("QUALIFIER", position, qualifier.c_str(), source);
10869 Utils::replaceToken("QUALIFIER", position, "std140, ", source);
10872 Utils::replaceToken("BINDING", position, buffer, source);
10877 /** Get description of test case
10879 * @param test_case_index Index of test case
10881 * @return Qualifier name
10883 std::string SSBLayoutQualifierConflictTest::getTestCaseName(GLuint test_case_index)
10885 std::string result = getQualifierName(m_test_cases[test_case_index].m_qualifier);
10890 /** Get number of test cases
10892 * @return Number of test cases
10894 GLuint SSBLayoutQualifierConflictTest::getTestCaseNumber()
10896 return static_cast<GLuint>(m_test_cases.size());
10899 /** Selects if "compute" stage is relevant for test
10901 * @param test_case_index Index of test case
10903 * @return true when tested stage is compute
10905 bool SSBLayoutQualifierConflictTest::isComputeRelevant(GLuint test_case_index)
10907 return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
10910 /** Selects if compilation failure is expected result
10912 * @param test_case_index Index of test case
10914 * @return false for STD140 and STD430 cases, true otherwise
10916 bool SSBLayoutQualifierConflictTest::isFailureExpected(GLuint test_case_index)
10918 const QUALIFIERS qualifier = m_test_cases[test_case_index].m_qualifier;
10920 return !((STD140 == qualifier) || (STD430 == qualifier));
10923 /** Checks if stage is supported
10925 * @param stage Shader stage
10927 * @return true if supported, false otherwise
10929 bool SSBLayoutQualifierConflictTest::isStageSupported(Utils::Shader::STAGES stage)
10931 const Functions& gl = m_context.getRenderContext().getFunctions();
10932 GLint max_supported_buffers = 0;
10937 case Utils::Shader::COMPUTE:
10938 pname = GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS;
10940 case Utils::Shader::FRAGMENT:
10941 pname = GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS;
10943 case Utils::Shader::GEOMETRY:
10944 pname = GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS;
10946 case Utils::Shader::TESS_CTRL:
10947 pname = GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS;
10949 case Utils::Shader::TESS_EVAL:
10950 pname = GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS;
10952 case Utils::Shader::VERTEX:
10953 pname = GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS;
10956 TCU_FAIL("Invalid enum");
10959 gl.getIntegerv(pname, &max_supported_buffers);
10960 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
10962 return 1 <= max_supported_buffers;
10965 /** Prepare all test cases
10968 void SSBLayoutQualifierConflictTest::testInit()
10970 bool stage_support[Utils::Shader::STAGE_MAX];
10972 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
10974 stage_support[stage] = isStageSupported((Utils::Shader::STAGES)stage);
10977 for (GLuint qualifier = 0; qualifier < QUALIFIERS_MAX; ++qualifier)
10979 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
10981 if (false == stage_support[stage])
10986 testCase test_case = { (QUALIFIERS)qualifier, (Utils::Shader::STAGES)stage };
10988 m_test_cases.push_back(test_case);
10993 /** Get name of glsl constant
10995 * @param Constant id
10997 * @return Name of constant used in GLSL
10999 const GLchar* SSBLayoutQualifierConflictTest::getQualifierName(QUALIFIERS qualifier)
11001 const GLchar* name = "";
11021 TCU_FAIL("Invalid enum");
11029 * @param context Test framework context
11031 SSBMemberInvalidOffsetAlignmentTest::SSBMemberInvalidOffsetAlignmentTest(deqp::Context& context)
11032 : UniformBlockMemberInvalidOffsetAlignmentTest(
11033 context, "ssb_member_invalid_offset_alignment",
11034 "Test verifies that invalid alignment of offset qualifiers cause compilation failure")
11036 /* Nothing to be done here */
11039 /** Get the maximum size for a shader storage block
11041 * @return The maximum size in basic machine units of a shader storage block.
11043 GLint SSBMemberInvalidOffsetAlignmentTest::getMaxBlockSize()
11045 const Functions& gl = m_context.getRenderContext().getFunctions();
11046 GLint max_size = 0;
11048 gl.getIntegerv(GL_MAX_SHADER_STORAGE_BLOCK_SIZE, &max_size);
11049 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
11054 /** Source for given test case and stage
11056 * @param test_case_index Index of test case
11057 * @param stage Shader stage
11059 * @return Shader source
11061 std::string SSBMemberInvalidOffsetAlignmentTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
11063 static const GLchar* cs = "#version 430 core\n"
11064 "#extension GL_ARB_enhanced_layouts : require\n"
11066 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
11068 "layout (std140) buffer Block {\n"
11069 " layout (offset = OFFSET) TYPE member;\n"
11072 "writeonly uniform image2D uni_image;\n"
11076 " vec4 result = vec4(1, 0, 0.5, 1);\n"
11078 " if (TYPE(1) == block.member)\n"
11080 " result = vec4(1, 1, 1, 1);\n"
11083 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
11086 static const GLchar* fs = "#version 430 core\n"
11087 "#extension GL_ARB_enhanced_layouts : require\n"
11090 "out vec4 fs_out;\n"
11094 " fs_out = gs_fs;\n"
11097 static const GLchar* fs_tested = "#version 430 core\n"
11098 "#extension GL_ARB_enhanced_layouts : require\n"
11100 "layout (std140) buffer Block {\n"
11101 " layout (offset = OFFSET) TYPE member;\n"
11105 "out vec4 fs_out;\n"
11109 " if (TYPE(1) == block.member)\n"
11111 " fs_out = vec4(1, 1, 1, 1);\n"
11114 " fs_out += gs_fs;\n"
11117 static const GLchar* gs = "#version 430 core\n"
11118 "#extension GL_ARB_enhanced_layouts : require\n"
11120 "layout(points) in;\n"
11121 "layout(triangle_strip, max_vertices = 4) out;\n"
11123 "in vec4 tes_gs[];\n"
11124 "out vec4 gs_fs;\n"
11128 " gs_fs = tes_gs[0];\n"
11129 " gl_Position = vec4(-1, -1, 0, 1);\n"
11131 " gs_fs = tes_gs[0];\n"
11132 " gl_Position = vec4(-1, 1, 0, 1);\n"
11134 " gs_fs = tes_gs[0];\n"
11135 " gl_Position = vec4(1, -1, 0, 1);\n"
11137 " gs_fs = tes_gs[0];\n"
11138 " gl_Position = vec4(1, 1, 0, 1);\n"
11142 static const GLchar* gs_tested = "#version 430 core\n"
11143 "#extension GL_ARB_enhanced_layouts : require\n"
11145 "layout(points) in;\n"
11146 "layout(triangle_strip, max_vertices = 4) out;\n"
11148 "layout (std140) buffer Block {\n"
11149 " layout (offset = OFFSET) TYPE member;\n"
11152 "in vec4 tes_gs[];\n"
11153 "out vec4 gs_fs;\n"
11157 " if (TYPE(1) == block.member)\n"
11159 " gs_fs = vec4(1, 1, 1, 1);\n"
11162 " gs_fs += tes_gs[0];\n"
11163 " gl_Position = vec4(-1, -1, 0, 1);\n"
11165 " gs_fs += tes_gs[0];\n"
11166 " gl_Position = vec4(-1, 1, 0, 1);\n"
11168 " gs_fs += tes_gs[0];\n"
11169 " gl_Position = vec4(1, -1, 0, 1);\n"
11171 " gs_fs += tes_gs[0];\n"
11172 " gl_Position = vec4(1, 1, 0, 1);\n"
11176 static const GLchar* tcs = "#version 430 core\n"
11177 "#extension GL_ARB_enhanced_layouts : require\n"
11179 "layout(vertices = 1) out;\n"
11181 "in vec4 vs_tcs[];\n"
11182 "out vec4 tcs_tes[];\n"
11187 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
11189 " gl_TessLevelOuter[0] = 1.0;\n"
11190 " gl_TessLevelOuter[1] = 1.0;\n"
11191 " gl_TessLevelOuter[2] = 1.0;\n"
11192 " gl_TessLevelOuter[3] = 1.0;\n"
11193 " gl_TessLevelInner[0] = 1.0;\n"
11194 " gl_TessLevelInner[1] = 1.0;\n"
11197 static const GLchar* tcs_tested = "#version 430 core\n"
11198 "#extension GL_ARB_enhanced_layouts : require\n"
11200 "layout(vertices = 1) out;\n"
11202 "layout (std140) buffer Block {\n"
11203 " layout (offset = OFFSET) TYPE member;\n"
11206 "in vec4 vs_tcs[];\n"
11207 "out vec4 tcs_tes[];\n"
11211 " if (TYPE(1) == block.member)\n"
11213 " tcs_tes[gl_InvocationID] = vec4(1, 1, 1, 1);\n"
11217 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
11219 " gl_TessLevelOuter[0] = 1.0;\n"
11220 " gl_TessLevelOuter[1] = 1.0;\n"
11221 " gl_TessLevelOuter[2] = 1.0;\n"
11222 " gl_TessLevelOuter[3] = 1.0;\n"
11223 " gl_TessLevelInner[0] = 1.0;\n"
11224 " gl_TessLevelInner[1] = 1.0;\n"
11227 static const GLchar* tes = "#version 430 core\n"
11228 "#extension GL_ARB_enhanced_layouts : require\n"
11230 "layout(isolines, point_mode) in;\n"
11232 "in vec4 tcs_tes[];\n"
11233 "out vec4 tes_gs;\n"
11237 " tes_gs = tcs_tes[0];\n"
11240 static const GLchar* tes_tested = "#version 430 core\n"
11241 "#extension GL_ARB_enhanced_layouts : require\n"
11243 "layout(isolines, point_mode) in;\n"
11245 "layout (std140) buffer Block {\n"
11246 " layout (offset = OFFSET) TYPE member;\n"
11249 "in vec4 tcs_tes[];\n"
11250 "out vec4 tes_gs;\n"
11254 " if (TYPE(1) == block.member)\n"
11256 " tes_gs = vec4(1, 1, 1, 1);\n"
11259 " tes_gs += tcs_tes[0];\n"
11262 static const GLchar* vs = "#version 430 core\n"
11263 "#extension GL_ARB_enhanced_layouts : require\n"
11266 "out vec4 vs_tcs;\n"
11270 " vs_tcs = in_vs;\n"
11273 static const GLchar* vs_tested = "#version 430 core\n"
11274 "#extension GL_ARB_enhanced_layouts : require\n"
11276 "layout (std140) buffer Block {\n"
11277 " layout (offset = OFFSET) TYPE member;\n"
11281 "out vec4 vs_tcs;\n"
11285 " if (TYPE(1) == block.member)\n"
11287 " vs_tcs = vec4(1, 1, 1, 1);\n"
11290 " vs_tcs += in_vs;\n"
11294 std::string source;
11295 testCase& test_case = m_test_cases[test_case_index];
11297 if (test_case.m_stage == stage)
11300 const GLuint offset = test_case.m_offset;
11301 size_t position = 0;
11302 const Utils::Type& type = test_case.m_type;
11303 const GLchar* type_name = type.GetGLSLTypeName();
11305 sprintf(buffer, "%d", offset);
11309 case Utils::Shader::COMPUTE:
11312 case Utils::Shader::FRAGMENT:
11313 source = fs_tested;
11315 case Utils::Shader::GEOMETRY:
11316 source = gs_tested;
11318 case Utils::Shader::TESS_CTRL:
11319 source = tcs_tested;
11321 case Utils::Shader::TESS_EVAL:
11322 source = tes_tested;
11324 case Utils::Shader::VERTEX:
11325 source = vs_tested;
11328 TCU_FAIL("Invalid enum");
11331 Utils::replaceToken("OFFSET", position, buffer, source);
11332 Utils::replaceToken("TYPE", position, type_name, source);
11333 Utils::replaceToken("TYPE", position, type_name, source);
11339 case Utils::Shader::FRAGMENT:
11342 case Utils::Shader::GEOMETRY:
11345 case Utils::Shader::TESS_CTRL:
11348 case Utils::Shader::TESS_EVAL:
11351 case Utils::Shader::VERTEX:
11355 TCU_FAIL("Invalid enum");
11362 /** Checks if stage is supported
11364 * @param stage Shader stage
11366 * @return true if supported, false otherwise
11368 bool SSBMemberInvalidOffsetAlignmentTest::isStageSupported(Utils::Shader::STAGES stage)
11370 const Functions& gl = m_context.getRenderContext().getFunctions();
11371 GLint max_supported_buffers = 0;
11376 case Utils::Shader::COMPUTE:
11377 pname = GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS;
11379 case Utils::Shader::FRAGMENT:
11380 pname = GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS;
11382 case Utils::Shader::GEOMETRY:
11383 pname = GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS;
11385 case Utils::Shader::TESS_CTRL:
11386 pname = GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS;
11388 case Utils::Shader::TESS_EVAL:
11389 pname = GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS;
11391 case Utils::Shader::VERTEX:
11392 pname = GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS;
11395 TCU_FAIL("Invalid enum");
11398 gl.getIntegerv(pname, &max_supported_buffers);
11399 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
11401 return 1 <= max_supported_buffers;
11406 * @param context Test framework context
11408 SSBMemberOverlappingOffsetsTest::SSBMemberOverlappingOffsetsTest(deqp::Context& context)
11409 : UniformBlockMemberOverlappingOffsetsTest(
11410 context, "ssb_member_overlapping_offsets",
11411 "Test verifies that overlapping offsets qualifiers cause compilation failure")
11413 /* Nothing to be done here */
11416 /** Source for given test case and stage
11418 * @param test_case_index Index of test case
11419 * @param stage Shader stage
11421 * @return Shader source
11423 std::string SSBMemberOverlappingOffsetsTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
11425 static const GLchar* cs = "#version 430 core\n"
11426 "#extension GL_ARB_enhanced_layouts : require\n"
11428 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
11430 "layout (std140) buffer Block {\n"
11431 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11432 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11435 "writeonly uniform image2D uni_image;\n"
11439 " vec4 result = vec4(1, 0, 0.5, 1);\n"
11441 " if ((BOY_TYPE(1) == block.boy) ||\n"
11442 " (MAN_TYPE(0) == block.man) )\n"
11444 " result = vec4(1, 1, 1, 1);\n"
11447 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
11450 static const GLchar* fs = "#version 430 core\n"
11451 "#extension GL_ARB_enhanced_layouts : require\n"
11454 "out vec4 fs_out;\n"
11458 " fs_out = gs_fs;\n"
11461 static const GLchar* fs_tested = "#version 430 core\n"
11462 "#extension GL_ARB_enhanced_layouts : require\n"
11464 "layout (std140) buffer Block {\n"
11465 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11466 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11470 "out vec4 fs_out;\n"
11474 " if ((BOY_TYPE(1) == block.boy) ||\n"
11475 " (MAN_TYPE(0) == block.man) )\n"
11477 " fs_out = vec4(1, 1, 1, 1);\n"
11480 " fs_out += gs_fs;\n"
11483 static const GLchar* gs = "#version 430 core\n"
11484 "#extension GL_ARB_enhanced_layouts : require\n"
11486 "layout(points) in;\n"
11487 "layout(triangle_strip, max_vertices = 4) out;\n"
11489 "in vec4 tes_gs[];\n"
11490 "out vec4 gs_fs;\n"
11494 " gs_fs = tes_gs[0];\n"
11495 " gl_Position = vec4(-1, -1, 0, 1);\n"
11497 " gs_fs = tes_gs[0];\n"
11498 " gl_Position = vec4(-1, 1, 0, 1);\n"
11500 " gs_fs = tes_gs[0];\n"
11501 " gl_Position = vec4(1, -1, 0, 1);\n"
11503 " gs_fs = tes_gs[0];\n"
11504 " gl_Position = vec4(1, 1, 0, 1);\n"
11508 static const GLchar* gs_tested = "#version 430 core\n"
11509 "#extension GL_ARB_enhanced_layouts : require\n"
11511 "layout(points) in;\n"
11512 "layout(triangle_strip, max_vertices = 4) out;\n"
11514 "layout (std140) buffer Block {\n"
11515 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11516 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11519 "in vec4 tes_gs[];\n"
11520 "out vec4 gs_fs;\n"
11524 " if ((BOY_TYPE(1) == block.boy) ||\n"
11525 " (MAN_TYPE(0) == block.man) )\n"
11527 " gs_fs = vec4(1, 1, 1, 1);\n"
11530 " gs_fs += tes_gs[0];\n"
11531 " gl_Position = vec4(-1, -1, 0, 1);\n"
11533 " gs_fs += tes_gs[0];\n"
11534 " gl_Position = vec4(-1, 1, 0, 1);\n"
11536 " gs_fs += tes_gs[0];\n"
11537 " gl_Position = vec4(1, -1, 0, 1);\n"
11539 " gs_fs += tes_gs[0];\n"
11540 " gl_Position = vec4(1, 1, 0, 1);\n"
11544 static const GLchar* tcs = "#version 430 core\n"
11545 "#extension GL_ARB_enhanced_layouts : require\n"
11547 "layout(vertices = 1) out;\n"
11549 "in vec4 vs_tcs[];\n"
11550 "out vec4 tcs_tes[];\n"
11555 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
11557 " gl_TessLevelOuter[0] = 1.0;\n"
11558 " gl_TessLevelOuter[1] = 1.0;\n"
11559 " gl_TessLevelOuter[2] = 1.0;\n"
11560 " gl_TessLevelOuter[3] = 1.0;\n"
11561 " gl_TessLevelInner[0] = 1.0;\n"
11562 " gl_TessLevelInner[1] = 1.0;\n"
11565 static const GLchar* tcs_tested = "#version 430 core\n"
11566 "#extension GL_ARB_enhanced_layouts : require\n"
11568 "layout(vertices = 1) out;\n"
11570 "layout (std140) buffer Block {\n"
11571 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11572 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11575 "in vec4 vs_tcs[];\n"
11576 "out vec4 tcs_tes[];\n"
11580 " if ((BOY_TYPE(1) == block.boy) ||\n"
11581 " (MAN_TYPE(0) == block.man) )\n"
11583 " tcs_tes[gl_InvocationID] = vec4(1, 1, 1, 1);\n"
11587 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
11589 " gl_TessLevelOuter[0] = 1.0;\n"
11590 " gl_TessLevelOuter[1] = 1.0;\n"
11591 " gl_TessLevelOuter[2] = 1.0;\n"
11592 " gl_TessLevelOuter[3] = 1.0;\n"
11593 " gl_TessLevelInner[0] = 1.0;\n"
11594 " gl_TessLevelInner[1] = 1.0;\n"
11597 static const GLchar* tes = "#version 430 core\n"
11598 "#extension GL_ARB_enhanced_layouts : require\n"
11600 "layout(isolines, point_mode) in;\n"
11602 "in vec4 tcs_tes[];\n"
11603 "out vec4 tes_gs;\n"
11607 " tes_gs = tcs_tes[0];\n"
11610 static const GLchar* tes_tested = "#version 430 core\n"
11611 "#extension GL_ARB_enhanced_layouts : require\n"
11613 "layout(isolines, point_mode) in;\n"
11615 "layout (std140) buffer Block {\n"
11616 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11617 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11620 "in vec4 tcs_tes[];\n"
11621 "out vec4 tes_gs;\n"
11625 " if ((BOY_TYPE(1) == block.boy) ||\n"
11626 " (MAN_TYPE(0) == block.man) )\n"
11628 " tes_gs = vec4(1, 1, 1, 1);\n"
11631 " tes_gs += tcs_tes[0];\n"
11634 static const GLchar* vs = "#version 430 core\n"
11635 "#extension GL_ARB_enhanced_layouts : require\n"
11638 "out vec4 vs_tcs;\n"
11642 " vs_tcs = in_vs;\n"
11645 static const GLchar* vs_tested = "#version 430 core\n"
11646 "#extension GL_ARB_enhanced_layouts : require\n"
11648 "layout (std140) buffer Block {\n"
11649 " layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11650 " layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11654 "out vec4 vs_tcs;\n"
11658 " if ((BOY_TYPE(1) == block.boy) ||\n"
11659 " (MAN_TYPE(0) == block.man) )\n"
11661 " vs_tcs = vec4(1, 1, 1, 1);\n"
11664 " vs_tcs += in_vs;\n"
11668 std::string source;
11669 testCase& test_case = m_test_cases[test_case_index];
11671 if (test_case.m_stage == stage)
11674 const GLuint boy_offset = test_case.m_boy_offset;
11675 const Utils::Type& boy_type = test_case.m_boy_type;
11676 const GLchar* boy_type_name = boy_type.GetGLSLTypeName();
11677 const GLuint man_offset = test_case.m_man_offset;
11678 const Utils::Type& man_type = test_case.m_man_type;
11679 const GLchar* man_type_name = man_type.GetGLSLTypeName();
11680 size_t position = 0;
11684 case Utils::Shader::COMPUTE:
11687 case Utils::Shader::FRAGMENT:
11688 source = fs_tested;
11690 case Utils::Shader::GEOMETRY:
11691 source = gs_tested;
11693 case Utils::Shader::TESS_CTRL:
11694 source = tcs_tested;
11696 case Utils::Shader::TESS_EVAL:
11697 source = tes_tested;
11699 case Utils::Shader::VERTEX:
11700 source = vs_tested;
11703 TCU_FAIL("Invalid enum");
11706 sprintf(buffer, "%d", boy_offset);
11707 Utils::replaceToken("BOY_OFFSET", position, buffer, source);
11708 Utils::replaceToken("BOY_TYPE", position, boy_type_name, source);
11709 sprintf(buffer, "%d", man_offset);
11710 Utils::replaceToken("MAN_OFFSET", position, buffer, source);
11711 Utils::replaceToken("MAN_TYPE", position, man_type_name, source);
11712 Utils::replaceToken("BOY_TYPE", position, boy_type_name, source);
11713 Utils::replaceToken("MAN_TYPE", position, man_type_name, source);
11719 case Utils::Shader::FRAGMENT:
11722 case Utils::Shader::GEOMETRY:
11725 case Utils::Shader::TESS_CTRL:
11728 case Utils::Shader::TESS_EVAL:
11731 case Utils::Shader::VERTEX:
11735 TCU_FAIL("Invalid enum");
11742 /** Checks if stage is supported
11744 * @param stage Shader stage
11746 * @return true if supported, false otherwise
11748 bool SSBMemberOverlappingOffsetsTest::isStageSupported(Utils::Shader::STAGES stage)
11750 const Functions& gl = m_context.getRenderContext().getFunctions();
11751 GLint max_supported_buffers = 0;
11756 case Utils::Shader::COMPUTE:
11757 pname = GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS;
11759 case Utils::Shader::FRAGMENT:
11760 pname = GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS;
11762 case Utils::Shader::GEOMETRY:
11763 pname = GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS;
11765 case Utils::Shader::TESS_CTRL:
11766 pname = GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS;
11768 case Utils::Shader::TESS_EVAL:
11769 pname = GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS;
11771 case Utils::Shader::VERTEX:
11772 pname = GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS;
11775 TCU_FAIL("Invalid enum");
11778 gl.getIntegerv(pname, &max_supported_buffers);
11779 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
11781 return 1 <= max_supported_buffers;
11786 * @param context Test framework context
11788 SSBMemberAlignNonPowerOf2Test::SSBMemberAlignNonPowerOf2Test(deqp::Context& context)
11789 : UniformBlockMemberAlignNonPowerOf2Test(context, "ssb_member_align_non_power_of_2",
11790 "Test verifies that align qualifier requires value that is a power of 2")
11792 /* Nothing to be done here */
11795 /** Source for given test case and stage
11797 * @param test_case_index Index of test case
11798 * @param stage Shader stage
11800 * @return Shader source
11802 std::string SSBMemberAlignNonPowerOf2Test::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
11804 static const GLchar* cs = "#version 430 core\n"
11805 "#extension GL_ARB_enhanced_layouts : require\n"
11807 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
11809 "layout (std140) buffer Block {\n"
11811 " layout (align = ALIGN) TYPE man;\n"
11814 "writeonly uniform image2D uni_image;\n"
11818 " vec4 result = vec4(1, 0, 0.5, 1);\n"
11820 " if (TYPE(0) == block.man)\n"
11822 " result = vec4(1, 1, 1, 1) - block.boy;\n"
11825 " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
11828 static const GLchar* fs = "#version 430 core\n"
11829 "#extension GL_ARB_enhanced_layouts : require\n"
11832 "out vec4 fs_out;\n"
11836 " fs_out = gs_fs;\n"
11839 static const GLchar* fs_tested = "#version 430 core\n"
11840 "#extension GL_ARB_enhanced_layouts : require\n"
11842 "layout (std140) buffer Block {\n"
11844 " layout (align = ALIGN) TYPE man;\n"
11848 "out vec4 fs_out;\n"
11852 " if (TYPE(0) == block.man)\n"
11854 " fs_out = block.boy;\n"
11857 " fs_out += gs_fs;\n"
11860 static const GLchar* gs = "#version 430 core\n"
11861 "#extension GL_ARB_enhanced_layouts : require\n"
11863 "layout(points) in;\n"
11864 "layout(triangle_strip, max_vertices = 4) out;\n"
11866 "in vec4 tes_gs[];\n"
11867 "out vec4 gs_fs;\n"
11871 " gs_fs = tes_gs[0];\n"
11872 " gl_Position = vec4(-1, -1, 0, 1);\n"
11874 " gs_fs = tes_gs[0];\n"
11875 " gl_Position = vec4(-1, 1, 0, 1);\n"
11877 " gs_fs = tes_gs[0];\n"
11878 " gl_Position = vec4(1, -1, 0, 1);\n"
11880 " gs_fs = tes_gs[0];\n"
11881 " gl_Position = vec4(1, 1, 0, 1);\n"
11885 static const GLchar* gs_tested = "#version 430 core\n"
11886 "#extension GL_ARB_enhanced_layouts : require\n"
11888 "layout(points) in;\n"
11889 "layout(triangle_strip, max_vertices = 4) out;\n"
11891 "layout (std140) buffer Block {\n"
11893 " layout (align = ALIGN) TYPE man;\n"
11896 "in vec4 tes_gs[];\n"
11897 "out vec4 gs_fs;\n"
11901 " if (TYPE(0) == block.man)\n"
11903 " gs_fs = block.boy;\n"
11906 " gs_fs += tes_gs[0];\n"
11907 " gl_Position = vec4(-1, -1, 0, 1);\n"
11909 " gs_fs += tes_gs[0];\n"
11910 " gl_Position = vec4(-1, 1, 0, 1);\n"
11912 " gs_fs += tes_gs[0];\n"
11913 " gl_Position = vec4(1, -1, 0, 1);\n"
11915 " gs_fs += tes_gs[0];\n"
11916 " gl_Position = vec4(1, 1, 0, 1);\n"
11920 static const GLchar* tcs = "#version 430 core\n"
11921 "#extension GL_ARB_enhanced_layouts : require\n"
11923 "layout(vertices = 1) out;\n"
11925 "in vec4 vs_tcs[];\n"
11926 "out vec4 tcs_tes[];\n"
11931 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
11933 " gl_TessLevelOuter[0] = 1.0;\n"
11934 " gl_TessLevelOuter[1] = 1.0;\n"
11935 " gl_TessLevelOuter[2] = 1.0;\n"
11936 " gl_TessLevelOuter[3] = 1.0;\n"
11937 " gl_TessLevelInner[0] = 1.0;\n"
11938 " gl_TessLevelInner[1] = 1.0;\n"
11941 static const GLchar* tcs_tested = "#version 430 core\n"
11942 "#extension GL_ARB_enhanced_layouts : require\n"
11944 "layout(vertices = 1) out;\n"
11946 "layout (std140) buffer Block {\n"
11948 " layout (align = ALIGN) TYPE man;\n"
11951 "in vec4 vs_tcs[];\n"
11952 "out vec4 tcs_tes[];\n"
11956 " if (TYPE(0) == block.man)\n"
11958 " tcs_tes[gl_InvocationID] = block.boy;\n"
11962 " tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
11964 " gl_TessLevelOuter[0] = 1.0;\n"
11965 " gl_TessLevelOuter[1] = 1.0;\n"
11966 " gl_TessLevelOuter[2] = 1.0;\n"
11967 " gl_TessLevelOuter[3] = 1.0;\n"
11968 " gl_TessLevelInner[0] = 1.0;\n"
11969 " gl_TessLevelInner[1] = 1.0;\n"
11972 static const GLchar* tes = "#version 430 core\n"
11973 "#extension GL_ARB_enhanced_layouts : require\n"
11975 "layout(isolines, point_mode) in;\n"
11977 "in vec4 tcs_tes[];\n"
11978 "out vec4 tes_gs;\n"
11982 " tes_gs = tcs_tes[0];\n"
11985 static const GLchar* tes_tested = "#version 430 core\n"
11986 "#extension GL_ARB_enhanced_layouts : require\n"
11988 "layout(isolines, point_mode) in;\n"
11990 "layout (std140) buffer Block {\n"
11992 " layout (align = ALIGN) TYPE man;\n"
11995 "in vec4 tcs_tes[];\n"
11996 "out vec4 tes_gs;\n"
12000 " if (TYPE(0) == block.man)\n"
12002 " tes_gs = block.boy;\n"
12005 " tes_gs += tcs_tes[0];\n"
12008 static const GLchar* vs = "#version 430 core\n"
12009 "#extension GL_ARB_enhanced_layouts : require\n"
12012 "out vec4 vs_tcs;\n"
12016 " vs_tcs = in_vs;\n"
12019 static const GLchar* vs_tested = "#version 430 core\n"
12020 "#extension GL_ARB_enhanced_layouts : require\n"
12022 "layout (std140) buffer Block {\n"
12024 " layout (align = ALIGN) TYPE man;\n"
12028 "out vec4 vs_tcs;\n"
12032 " if (TYPE(0) == block.man)\n"
12034 " vs_tcs = block.boy;\n"
12037 " vs_tcs += in_vs;\n"
12041 std::string source;
12042 testCase& test_case = m_test_cases[test_case_index];
12044 if (test_case.m_stage == stage)
12047 const GLuint alignment = test_case.m_alignment;
12048 const Utils::Type& type = test_case.m_type;
12049 const GLchar* type_name = type.GetGLSLTypeName();
12050 size_t position = 0;
12054 case Utils::Shader::COMPUTE:
12057 case Utils::Shader::FRAGMENT:
12058 source = fs_tested;
12060 case Utils::Shader::GEOMETRY:
12061 source = gs_tested;
12063 case Utils::Shader::TESS_CTRL:
12064 source = tcs_tested;
12066 case Utils::Shader::TESS_EVAL:
12067 source = tes_tested;
12069 case Utils::Shader::VERTEX:
12070 source = vs_tested;
12073 TCU_FAIL("Invalid enum");
12076 sprintf(buffer, "%d", alignment);
12077 Utils::replaceToken("ALIGN", position, buffer, source);
12078 Utils::replaceToken("TYPE", position, type_name, source);
12079 Utils::replaceToken("TYPE", position, type_name, source);
12085 case Utils::Shader::FRAGMENT:
12088 case Utils::Shader::GEOMETRY:
12091 case Utils::Shader::TESS_CTRL:
12094 case Utils::Shader::TESS_EVAL:
12097 case Utils::Shader::VERTEX:
12101 TCU_FAIL("Invalid enum");
12108 /** Checks if stage is supported
12110 * @param stage Shader stage
12112 * @return true if supported, false otherwise
12114 bool SSBMemberAlignNonPowerOf2Test::isStageSupported(Utils::Shader::STAGES stage)
12116 const Functions& gl = m_context.getRenderContext().getFunctions();
12117 GLint max_supported_buffers = 0;
12122 case Utils::Shader::COMPUTE:
12123 pname = GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS;
12125 case Utils::Shader::FRAGMENT:
12126 pname = GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS;
12128 case Utils::Shader::GEOMETRY:
12129 pname = GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS;
12131 case Utils::Shader::TESS_CTRL:
12132 pname = GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS;
12134 case Utils::Shader::TESS_EVAL:
12135 pname = GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS;
12137 case Utils::Shader::VERTEX:
12138 pname = GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS;
12141 TCU_FAIL("Invalid enum");
12144 gl.getIntegerv(pname, &max_supported_buffers);
12145 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
12147 return 1 <= max_supported_buffers;
12152 * @param context Test framework context
12154 SSBAlignmentTest::SSBAlignmentTest(deqp::Context& context)
12155 : TextureTestBase(context, "ssb_alignment", "Test verifies offset and alignment of ssb buffer")
12159 /** Get interface of program
12162 * @param program_interface Interface of program
12163 * @param varying_passthrough Collection of connections between in and out variables
12165 void SSBAlignmentTest::getProgramInterface(GLuint /* test_case_index */, Utils::ProgramInterface& program_interface,
12166 Utils::VaryingPassthrough& varying_passthrough)
12168 static const Utils::Type vec4 = Utils::Type::vec4;
12170 #if WRKARD_UNIFORMBLOCKALIGNMENT
12172 static const GLuint block_align = 16;
12174 #else /* WRKARD_UNIFORMBLOCKALIGNMENT */
12176 static const GLuint block_align = 64;
12178 #endif /* WRKARD_UNIFORMBLOCKALIGNMENT */
12180 static const GLuint fifth_align = 16;
12181 static const GLuint vec4_stride = 16;
12182 static const GLuint data_stride = vec4_stride * 2; /* one vec4 + one scalar aligned to 16 */
12184 const GLuint first_offset = 0; /* vec4 at 0 */
12185 const GLuint second_offset = Utils::Type::GetActualOffset(first_offset + vec4_stride, block_align); /* Data at 32 */
12186 const GLuint third_offset =
12187 Utils::Type::GetActualOffset(second_offset + data_stride, block_align); /* Data[2] at 64 */
12188 const GLuint fourth_offset =
12189 Utils::Type::GetActualOffset(third_offset + data_stride * 2, block_align); /* vec4[3] at 96 */
12190 const GLuint fifth_offset =
12191 Utils::Type::GetActualOffset(fourth_offset + vec4_stride * 3, fifth_align); /* vec4[2] at 160 */
12192 const GLuint sixth_offset =
12193 Utils::Type::GetActualOffset(fifth_offset + vec4_stride * 2, block_align); /* Data at 192 */
12195 Utils::Interface* structure = program_interface.Structure("Data");
12197 structure->Member("vector", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::vec4,
12198 false /* normalized */, 0 /* n_array_elements */, Utils::Type::vec4.GetSize(), 0 /* offset */);
12200 structure->Member("scalar", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::_float,
12201 false /* normalized */, 0 /* n_array_elements */, Utils::Type::_float.GetSize(),
12202 Utils::Type::vec4.GetSize() /* offset */);
12204 /* Prepare Block */
12205 Utils::Interface* vs_buf_Block = program_interface.Block("vs_buf_Block");
12207 vs_buf_Block->Member("first", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::vec4,
12208 false /* normalized */, 0 /* n_array_elements */, vec4_stride, first_offset /* offset */);
12210 vs_buf_Block->Member("second", "", 0 /* expected_component */, 0 /* expected_location */, structure,
12211 0 /* n_array_elements */, data_stride, second_offset);
12213 vs_buf_Block->Member("third", "", 0 /* expected_component */, 0 /* expected_location */, structure,
12214 2 /* n_array_elements */, data_stride, third_offset);
12216 vs_buf_Block->Member("fourth", "", 0 /* expected_component */, 0 /* expected_location */, vec4,
12217 false /* normalized */, 3 /* n_array_elements */, vec4_stride, fourth_offset);
12219 vs_buf_Block->Member("fifth", "layout(align = 16)", 0 /* expected_component */, 0 /* expected_location */, vec4,
12220 false /* normalized */, 2 /* n_array_elements */, vec4_stride, fifth_offset);
12222 vs_buf_Block->Member("sixth", "", 0 /* expected_component */, 0 /* expected_location */, structure,
12223 0 /* n_array_elements */, data_stride, sixth_offset);
12225 const GLuint stride = calculateStride(*vs_buf_Block);
12226 m_data.resize(stride);
12227 generateData(*vs_buf_Block, 0, m_data);
12229 Utils::ShaderInterface& vs_si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
12231 /* Add uniform BLOCK */
12232 #if WRKARD_UNIFORMBLOCKALIGNMENT
12233 vs_si.SSB("vs_buf_block", "layout (std140, binding = BINDING)", 0, 0, vs_buf_Block, 0,
12234 static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
12235 #else /* WRKARD_UNIFORMBLOCKALIGNMENT */
12236 vs_si.SSB("vs_buf_block", "layout (std140, binding = BINDING, align = 64)", 0, 0, vs_buf_Block, 0,
12237 static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
12238 #endif /* WRKARD_UNIFORMBLOCKALIGNMENT */
12240 program_interface.CloneVertexInterface(varying_passthrough);
12243 /** Selects if "draw" stages are relevant for test
12247 * @return true if all stages support shader storage buffers, false otherwise
12249 bool SSBAlignmentTest::isDrawRelevant(GLuint /* test_case_index */)
12251 const Functions& gl = m_context.getRenderContext().getFunctions();
12252 GLint gs_supported_buffers = 0;
12253 GLint tcs_supported_buffers = 0;
12254 GLint tes_supported_buffers = 0;
12255 GLint vs_supported_buffers = 0;
12257 gl.getIntegerv(GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS, &gs_supported_buffers);
12258 gl.getIntegerv(GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS, &tcs_supported_buffers);
12259 gl.getIntegerv(GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS, &tes_supported_buffers);
12260 gl.getIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &vs_supported_buffers);
12262 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
12264 return ((1 <= gs_supported_buffers) && (1 <= tcs_supported_buffers) && (1 <= tes_supported_buffers) &&
12265 (1 <= vs_supported_buffers));
12270 * @param context Test framework context
12272 VaryingLocationsTest::VaryingLocationsTest(deqp::Context& context)
12273 : TextureTestBase(context, "varying_locations", "Test verifies that input and output locations are respected")
12279 * @param context Test context
12280 * @param test_name Name of test
12281 * @param test_description Description of test
12283 VaryingLocationsTest::VaryingLocationsTest(deqp::Context& context, const glw::GLchar* test_name,
12284 const glw::GLchar* test_description)
12285 : TextureTestBase(context, test_name, test_description)
12289 /** Get interface of program
12291 * @param test_case_index Test case
12292 * @param program_interface Interface of program
12293 * @param varying_passthrough Collection of connections between in and out variables
12295 void VaryingLocationsTest::getProgramInterface(GLuint test_case_index, Utils::ProgramInterface& program_interface,
12296 Utils::VaryingPassthrough& varying_passthrough)
12298 const Utils::Type type = getType(test_case_index);
12300 m_first_data = type.GenerateDataPacked();
12301 m_last_data = type.GenerateDataPacked();
12303 prepareShaderStage(Utils::Shader::FRAGMENT, type, program_interface, varying_passthrough);
12304 prepareShaderStage(Utils::Shader::GEOMETRY, type, program_interface, varying_passthrough);
12305 prepareShaderStage(Utils::Shader::TESS_CTRL, type, program_interface, varying_passthrough);
12306 prepareShaderStage(Utils::Shader::TESS_EVAL, type, program_interface, varying_passthrough);
12307 prepareShaderStage(Utils::Shader::VERTEX, type, program_interface, varying_passthrough);
12312 * @param test_case_index Index of test case
12314 * @return Name of type test in test_case_index
12316 std::string VaryingLocationsTest::getTestCaseName(glw::GLuint test_case_index)
12318 return getTypeName(test_case_index);
12321 /** Returns number of types to test
12323 * @return Number of types, 34
12325 glw::GLuint VaryingLocationsTest::getTestCaseNumber()
12327 return getTypesNumber();
12330 /** Selects if "compute" stage is relevant for test
12336 bool VaryingLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
12345 std::string VaryingLocationsTest::prepareGlobals(GLint last_in_loc, GLint last_out_loc)
12348 std::string globals = "const uint first_input_location = 0u;\n"
12349 "const uint first_output_location = 0u;\n"
12350 "const uint last_input_location = LAST_INPUTu;\n"
12351 "const uint last_output_location = LAST_OUTPUTu;\n";
12352 size_t position = 100; /* Skip first part */
12354 sprintf(buffer, "%d", last_in_loc);
12355 Utils::replaceToken("LAST_INPUT", position, buffer, globals);
12357 sprintf(buffer, "%d", last_out_loc);
12358 Utils::replaceToken("LAST_OUTPUT", position, buffer, globals);
12366 void VaryingLocationsTest::prepareShaderStage(Utils::Shader::STAGES stage, const Utils::Type& type,
12367 Utils::ProgramInterface& program_interface,
12368 Utils::VaryingPassthrough& varying_passthrough)
12370 const GLuint array_length = 1;
12371 const GLuint first_in_loc = 0;
12372 const GLuint first_out_loc = 0;
12373 const GLuint last_in_loc = getLastInputLocation(stage, type, array_length);
12374 size_t position = 0;
12376 const GLchar* prefix_in = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::VARYING_INPUT);
12378 const GLchar* prefix_out = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::VARYING_OUTPUT);
12380 const GLchar* qual_first_in = "layout (location = first_input_location)";
12381 const GLchar* qual_first_out = "layout (location = first_output_location)";
12382 const GLchar* qual_last_in = "layout (location = last_input_location)";
12383 const GLchar* qual_last_out = "layout (location = last_output_location)";
12385 Utils::ShaderInterface& si = program_interface.GetShaderInterface(stage);
12386 const GLuint type_size = type.GetSize();
12388 std::string first_in_name = "PREFIXfirst";
12389 std::string first_out_name = "PREFIXfirst";
12390 std::string last_in_name = "PREFIXlast";
12391 std::string last_out_name = "PREFIXlast";
12393 Utils::replaceToken("PREFIX", position, prefix_in, first_in_name);
12395 Utils::replaceToken("PREFIX", position, prefix_out, first_out_name);
12397 Utils::replaceToken("PREFIX", position, prefix_in, last_in_name);
12399 Utils::replaceToken("PREFIX", position, prefix_out, last_out_name);
12401 if (Utils::Shader::FRAGMENT == stage)
12403 qual_first_in = "layout (location = first_input_location) flat";
12404 qual_last_in = "layout (location = last_input_location) flat";
12406 if (Utils::Shader::GEOMETRY == stage)
12408 qual_first_out = "layout (location = first_output_location) flat";
12409 qual_last_out = "layout (location = last_output_location) flat";
12412 Utils::Variable* first_in = si.Input(
12413 first_in_name.c_str(), qual_first_in /* qualifiers */, 0 /* expected_componenet */,
12414 first_in_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */, 0u /* n_array_elements */,
12415 0u /* stride */, 0u /* offset */, (GLvoid*)&m_first_data[0] /* data */, m_first_data.size() /* data_size */);
12417 Utils::Variable* last_in =
12418 si.Input(last_in_name.c_str(), qual_last_in /* qualifiers */, 0 /* expected_componenet */,
12419 last_in_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12420 0u /* n_array_elements */, 0u /* stride */, type_size /* offset */,
12421 (GLvoid*)&m_last_data[0] /* data */, m_last_data.size() /* data_size */);
12423 if (Utils::Shader::FRAGMENT != stage)
12425 const GLuint last_out_loc = getLastOutputLocation(stage, type, array_length);
12427 Utils::Variable* first_out =
12428 si.Output(first_out_name.c_str(), qual_first_out /* qualifiers */, 0 /* expected_componenet */,
12429 first_out_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12430 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)&m_first_data[0] /* data */,
12431 m_first_data.size() /* data_size */);
12433 Utils::Variable* last_out = si.Output(
12434 last_out_name.c_str(), qual_last_out /* qualifiers */, 0 /* expected_componenet */,
12435 last_out_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */, 0u /* n_array_elements */,
12436 0u /* stride */, 0u /* offset */, (GLvoid*)&m_last_data[0] /* data */, m_last_data.size() /* data_size */);
12438 si.m_globals = prepareGlobals(last_in_loc, last_out_loc);
12440 varying_passthrough.Add(stage, first_in, first_out);
12441 varying_passthrough.Add(stage, last_in, last_out);
12445 /* No outputs for fragment shader, so last_output_location can be 0 */
12446 si.m_globals = prepareGlobals(last_in_loc, 0);
12450 /** This test should be run with separable programs
12456 bool VaryingLocationsTest::useMonolithicProgram(GLuint /* test_case_index */)
12461 /* Constants used by VertexAttribLocationsTest */
12462 const GLuint VertexAttribLocationsTest::m_base_vertex = 4;
12463 const GLuint VertexAttribLocationsTest::m_base_instance = 2;
12464 const GLuint VertexAttribLocationsTest::m_loc_vertex = 2;
12465 const GLuint VertexAttribLocationsTest::m_loc_instance = 5;
12466 const GLuint VertexAttribLocationsTest::m_n_instances = 4;
12470 * @param context Test framework context
12472 VertexAttribLocationsTest::VertexAttribLocationsTest(deqp::Context& context)
12473 : TextureTestBase(context, "vertex_attrib_locations",
12474 "Test verifies that attribute locations are respected by drawing operations")
12478 /** Execute proper draw command for test case
12480 * @param test_case_index Index of test case
12482 void VertexAttribLocationsTest::executeDrawCall(GLuint test_case_index)
12484 const Functions& gl = m_context.getRenderContext().getFunctions();
12486 switch (test_case_index)
12489 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
12490 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
12492 case DRAWARRAYSINSTANCED:
12493 gl.drawArraysInstanced(GL_PATCHES, 0 /* first */, 1 /* count */, m_n_instances);
12494 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArraysInstanced");
12497 gl.drawElements(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL);
12498 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElements");
12500 case DRAWELEMENTSBASEVERTEX:
12501 gl.drawElementsBaseVertex(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL, m_base_vertex);
12502 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsBaseVertex");
12504 case DRAWELEMENTSINSTANCED:
12505 gl.drawElementsInstanced(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL, m_n_instances);
12506 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsInstanced");
12508 case DRAWELEMENTSINSTANCEDBASEINSTANCE:
12509 gl.drawElementsInstancedBaseInstance(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL, m_n_instances,
12511 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsInstancedBaseInstance");
12513 case DRAWELEMENTSINSTANCEDBASEVERTEX:
12514 gl.drawElementsInstancedBaseVertex(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL, m_n_instances,
12516 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsInstancedBaseVertex");
12518 case DRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCE:
12519 gl.drawElementsInstancedBaseVertexBaseInstance(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL,
12520 m_n_instances, m_base_vertex, m_base_instance);
12521 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsInstancedBaseVertexBaseInstance");
12524 TCU_FAIL("Invalid enum");
12528 /** Get interface of program
12531 * @param program_interface Interface of program
12534 void VertexAttribLocationsTest::getProgramInterface(GLuint /* test_case_index */,
12535 Utils::ProgramInterface& program_interface,
12536 Utils::VaryingPassthrough& /* varying_passthrough */)
12538 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
12541 si.m_globals = "const uint vertex_index_location = 2;\n"
12542 "const uint instance_index_location = 5;\n";
12545 si.Input("vertex_index" /* name */, "layout (location = vertex_index_location)" /* qualifiers */,
12546 0 /* expected_componenet */, m_loc_vertex /* expected_location */, Utils::Type::uint /* type */,
12547 GL_FALSE /* normalized */, 0u /* n_array_elements */, 16 /* stride */, 0u /* offset */,
12548 (GLvoid*)0 /* data */, 0 /* data_size */);
12549 si.Input("instance_index" /* name */, "layout (location = instance_index_location)" /* qualifiers */,
12550 0 /* expected_componenet */, m_loc_instance /* expected_location */, Utils::Type::uint /* type */,
12551 GL_FALSE /* normalized */, 0u /* n_array_elements */, 16 /* stride */, 16u /* offset */,
12552 (GLvoid*)0 /* data */, 0 /* data_size */);
12555 /** Get name of test case
12557 * @param test_case_index Index of test case
12559 * @return Name of test case
12561 std::string VertexAttribLocationsTest::getTestCaseName(glw::GLuint test_case_index)
12563 std::string result;
12565 switch (test_case_index)
12568 result = "DrawArrays";
12570 case DRAWARRAYSINSTANCED:
12571 result = "DrawArraysInstanced";
12574 result = "DrawElements";
12576 case DRAWELEMENTSBASEVERTEX:
12577 result = "DrawElementsBaseVertex";
12579 case DRAWELEMENTSINSTANCED:
12580 result = "DrawElementsInstanced";
12582 case DRAWELEMENTSINSTANCEDBASEINSTANCE:
12583 result = "DrawElementsInstancedBaseInstance";
12585 case DRAWELEMENTSINSTANCEDBASEVERTEX:
12586 result = "DrawElementsInstancedBaseVertex";
12588 case DRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCE:
12589 result = "DrawElementsInstancedBaseVertexBaseInstance";
12592 TCU_FAIL("Invalid enum");
12598 /** Get number of test cases
12600 * @return Number of test cases
12602 GLuint VertexAttribLocationsTest::getTestCaseNumber()
12604 return TESTCASES_MAX;
12607 /** Prepare code snippet that will verify in and uniform variables
12611 * @param stage Shader stage
12613 * @return Code that verify variables
12615 std::string VertexAttribLocationsTest::getVerificationSnippet(GLuint /* test_case_index */,
12616 Utils::ProgramInterface& /* program_interface */,
12617 Utils::Shader::STAGES stage)
12619 std::string verification;
12621 if (Utils::Shader::VERTEX == stage)
12624 #if DEBUG_VERTEX_ATTRIB_LOCATIONS_TEST_VARIABLE
12626 verification = "if (gl_InstanceID != instance_index)\n"
12630 " else if (gl_VertexID != vertex_index)\n"
12637 verification = "if ((gl_VertexID != vertex_index) ||\n"
12638 " (gl_InstanceID != instance_index) )\n"
12650 return verification;
12653 /** Selects if "compute" stage is relevant for test
12659 bool VertexAttribLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
12664 /** Prepare attributes, vertex array object and array buffer
12667 * @param ignored Interface of program
12668 * @param buffer Array buffer
12669 * @param vao Vertex array object
12671 void VertexAttribLocationsTest::prepareAttributes(GLuint test_case_index /* test_case_index */,
12672 Utils::ProgramInterface& /* program_interface */,
12673 Utils::Buffer& buffer, Utils::VertexArray& vao)
12675 static const GLuint vertex_index_data[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
12676 static const GLuint instance_index_data[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
12678 std::vector<GLuint> buffer_data;
12679 buffer_data.resize(8 + 8); /* vertex_index_data + instance_index_data */
12681 GLubyte* ptr = (GLubyte*)&buffer_data[0];
12684 When case index >=2, the test calls glDrawElement*(), such as glDrawElementsBaseVertex(), glDrawElementsInstanced(), glDrawElementsInstancedBaseInstance() and so on,
12685 So we need to change the buffer type as GL_ELEMENT_ARRAY_BUFFER
12687 if (test_case_index >= 2)
12689 buffer.m_buffer = Utils::Buffer::Element;
12694 vao.Attribute(m_loc_vertex /* vertex_index */, Utils::Type::uint, 0 /* array_elements */, false /* normalized */,
12695 0 /* stride */, 0 /* offset */);
12697 vao.Attribute(m_loc_instance /* instance_index */, Utils::Type::uint, 0 /* array_elements */,
12698 false /* normalized */, 0 /* stride */, (GLvoid*)sizeof(vertex_index_data) /* offset */);
12699 // when test_case_index is 5 or 7, the draw call is glDrawElementsInstancedBaseInstance, glDrawElementsInstancedBaseVertexBaseInstance
12700 // the instancecount is 4, the baseinstance is 2, the divisor should be set 2
12701 bool isBaseInstanced = (test_case_index == DRAWELEMENTSINSTANCEDBASEINSTANCE ||
12702 test_case_index == DRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCE);
12703 vao.Divisor(m_context.getRenderContext().getFunctions() /* gl */, m_loc_instance /* instance_index */,
12704 isBaseInstanced ? 2 : 1 /* divisor. 1 - advance once per instance */);
12706 memcpy(ptr + 0, vertex_index_data, sizeof(vertex_index_data));
12707 memcpy(ptr + sizeof(vertex_index_data), instance_index_data, sizeof(instance_index_data));
12709 buffer.Data(Utils::Buffer::StaticDraw, buffer_data.size() * sizeof(GLuint), ptr);
12712 /** This test should be run with separable programs
12718 bool VertexAttribLocationsTest::useMonolithicProgram(GLuint /* test_case_index */)
12725 * @param context Test framework context
12727 VaryingArrayLocationsTest::VaryingArrayLocationsTest(deqp::Context& context)
12728 : VaryingLocationsTest(context, "varying_array_locations",
12729 "Test verifies that input and output locations are respected for arrays")
12736 void VaryingArrayLocationsTest::prepareShaderStage(Utils::Shader::STAGES stage, const Utils::Type& type,
12737 Utils::ProgramInterface& program_interface,
12738 Utils::VaryingPassthrough& varying_passthrough)
12740 const GLuint array_length = 1u;
12741 const GLuint first_in_loc = 0;
12742 const GLuint first_out_loc = 0;
12743 const GLuint last_in_loc = getLastInputLocation(stage, type, array_length);
12744 size_t position = 0;
12746 const GLchar* prefix_in = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::VARYING_INPUT);
12748 const GLchar* prefix_out = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::VARYING_OUTPUT);
12750 const GLchar* qual_first_in = "layout (location = first_input_location)";
12751 const GLchar* qual_first_out = "layout (location = first_output_location)";
12752 const GLchar* qual_last_in = "layout (location = last_input_location)";
12753 const GLchar* qual_last_out = "layout (location = last_output_location)";
12755 Utils::ShaderInterface& si = program_interface.GetShaderInterface(stage);
12756 const GLuint type_size = type.GetSize();
12758 std::string first_in_name = "PREFIXfirst";
12759 std::string first_out_name = "PREFIXfirst";
12760 std::string last_in_name = "PREFIXlast";
12761 std::string last_out_name = "PREFIXlast";
12763 Utils::replaceToken("PREFIX", position, prefix_in, first_in_name);
12765 Utils::replaceToken("PREFIX", position, prefix_out, first_out_name);
12767 Utils::replaceToken("PREFIX", position, prefix_in, last_in_name);
12769 Utils::replaceToken("PREFIX", position, prefix_out, last_out_name);
12771 if (Utils::Shader::FRAGMENT == stage)
12773 qual_first_in = "layout (location = first_input_location) flat";
12774 qual_last_in = "layout (location = last_input_location) flat";
12776 if (Utils::Shader::GEOMETRY == stage)
12778 qual_first_out = "layout (location = first_output_location) flat";
12779 qual_last_out = "layout (location = last_output_location) flat";
12782 Utils::Variable* first_in =
12783 si.Input(first_in_name.c_str(), qual_first_in /* qualifiers */, 0 /* expected_componenet */,
12784 first_in_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12785 array_length /* n_array_elements */, 0u /* stride */, 0u /* offset */,
12786 (GLvoid*)&m_first_data[0] /* data */, m_first_data.size() /* data_size */);
12788 Utils::Variable* last_in =
12789 si.Input(last_in_name.c_str(), qual_last_in /* qualifiers */, 0 /* expected_componenet */,
12790 last_in_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12791 array_length /* n_array_elements */, 0u /* stride */, type_size /* offset */,
12792 (GLvoid*)&m_last_data[0] /* data */, m_last_data.size() /* data_size */);
12794 if (Utils::Shader::FRAGMENT != stage)
12796 const GLuint last_out_loc = getLastOutputLocation(stage, type, array_length);
12798 Utils::Variable* first_out =
12799 si.Output(first_out_name.c_str(), qual_first_out /* qualifiers */, 0 /* expected_componenet */,
12800 first_out_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12801 array_length /* n_array_elements */, 0u /* stride */, 0u /* offset */,
12802 (GLvoid*)&m_first_data[0] /* data */, m_first_data.size() /* data_size */);
12804 Utils::Variable* last_out =
12805 si.Output(last_out_name.c_str(), qual_last_out /* qualifiers */, 0 /* expected_componenet */,
12806 last_out_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12807 array_length /* n_array_elements */, 0u /* stride */, 0u /* offset */,
12808 (GLvoid*)&m_last_data[0] /* data */, m_last_data.size() /* data_size */);
12810 si.m_globals = prepareGlobals(last_in_loc, last_out_loc);
12812 varying_passthrough.Add(stage, first_in, first_out);
12813 varying_passthrough.Add(stage, last_in, last_out);
12817 /* No outputs for fragment shader, so last_output_location can be 0 */
12818 si.m_globals = prepareGlobals(last_in_loc, 0);
12824 * @param context Test framework context
12826 VaryingStructureLocationsTest::VaryingStructureLocationsTest(deqp::Context& context)
12827 : TextureTestBase(context, "varying_structure_locations",
12828 "Test verifies that locations are respected when structures are used as in and out ")
12832 /** Prepare code snippet that will pass in variables to out variables
12835 * @param varying_passthrough Collection of connections between in and out variables
12836 * @param stage Shader stage
12838 * @return Code that pass in variables to next stage
12840 std::string VaryingStructureLocationsTest::getPassSnippet(GLuint /* test_case_index */,
12841 Utils::VaryingPassthrough& varying_passthrough,
12842 Utils::Shader::STAGES stage)
12844 std::string result;
12846 if (Utils::Shader::VERTEX != stage)
12848 result = TextureTestBase::getPassSnippet(0, varying_passthrough, stage);
12852 result = " vs_tcs_output[0].single = vs_in_single[0];\n"
12853 " vs_tcs_output[0].array[0] = vs_in_array[0];\n";
12859 /** Get interface of program
12861 * @param test_case_index Test case
12862 * @param program_interface Interface of program
12863 * @param varying_passthrough Collection of connections between in and out variables
12865 void VaryingStructureLocationsTest::getProgramInterface(GLuint test_case_index,
12866 Utils::ProgramInterface& program_interface,
12867 Utils::VaryingPassthrough& varying_passthrough)
12869 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
12870 const Utils::Type type = getType(test_case_index);
12873 // We should call GenerateDataPacked() to generate data, which can make sure the data in shader is correct
12874 m_single_data = type.GenerateDataPacked();
12875 m_array_data = type.GenerateDataPacked();
12877 m_data.resize(m_single_data.size() + m_array_data.size());
12878 GLubyte* ptr = (GLubyte*)&m_data[0];
12879 memcpy(ptr, &m_single_data[0], m_single_data.size());
12880 memcpy(ptr + m_single_data.size(), &m_array_data[0], m_array_data.size());
12882 Utils::Interface* structure = program_interface.Structure("Data");
12884 structure->Member("single", "" /* qualifiers */, 0 /* component */, 0 /* location */, type, false /* normalized */,
12885 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */);
12887 // the second struct member 's location should not be 0, it is based on by how many the locations the first struct member consumed.
12888 structure->Member("array", "" /* qualifiers */, 0 /* component */, type.GetLocations() /* location */, type,
12889 false /* normalized */, 1u /* n_array_elements */, 0u /* stride */, type.GetSize() /* offset */);
12891 si.Input("vs_in_single", "layout (location = 0)", 0 /* component */, 0 /* location */, type, false /* normalized */,
12892 1u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)&m_single_data[0] /* data */,
12893 m_single_data.size() /* data_size */);
12895 si.Input("vs_in_array", "layout (location = 8)", 0 /* component */, 8 /* location */, type, false /* normalized */,
12896 1u /* n_array_elements */, 0u /* stride */, type.GetSize() /* offset */,
12897 (GLvoid*)&m_array_data[0] /* data */, m_array_data.size() /* data_size */);
12899 si.Output("vs_tcs_output", "layout (location = 0)", 0 /* component */, 0 /* location */, structure,
12900 1u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)&m_data[0] /* data */,
12901 m_data.size() /* data_size */);
12903 program_interface.CloneVertexInterface(varying_passthrough);
12908 * @param test_case_index Index of test case
12910 * @return Name of type test in test_case_index
12912 std::string VaryingStructureLocationsTest::getTestCaseName(glw::GLuint test_case_index)
12914 return getTypeName(test_case_index);
12917 /** Returns number of types to test
12919 * @return Number of types, 34
12921 glw::GLuint VaryingStructureLocationsTest::getTestCaseNumber()
12923 return getTypesNumber();
12926 /** Selects if "compute" stage is relevant for test
12932 bool VaryingStructureLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
12937 /** This test should be run with separable programs
12943 bool VaryingStructureLocationsTest::useMonolithicProgram(GLuint /* test_case_index */)
12950 * @param context Test context
12951 * @param test_name Name of test
12952 * @param test_description Description of test
12954 VaryingStructureMemberLocationTest::VaryingStructureMemberLocationTest(deqp::Context& context)
12955 : NegativeTestBase(context, "varying_structure_member_location",
12956 "Test verifies that compiler does not allow location qualifier on member of strucure")
12960 /** Source for given test case and stage
12962 * @param test_case_index Index of test case
12963 * @param stage Shader stage
12965 * @return Shader source
12967 std::string VaryingStructureMemberLocationTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
12969 static const GLchar* struct_definition = "struct Data {\n"
12971 " layout (location = 4) vec4 goten;\n"
12973 static const GLchar* input_var = "in Data data;\n";
12974 static const GLchar* output_var = "out Data data;\n";
12975 static const GLchar* input_use = " result += data.gohan + data.goten;\n";
12976 static const GLchar* output_use = " data.gohan = result / 2;\n"
12977 " data.goten = result / 4 - data.gohan;\n";
12978 static const GLchar* fs = "#version 430 core\n"
12979 "#extension GL_ARB_enhanced_layouts : require\n"
12982 "out vec4 fs_out;\n"
12986 " fs_out = gs_fs;\n"
12989 static const GLchar* fs_tested = "#version 430 core\n"
12990 "#extension GL_ARB_enhanced_layouts : require\n"
12992 "STRUCT_DEFINITION"
12994 "VARIABLE_DEFINITION"
12997 "out vec4 fs_out;\n"
13001 " vec4 result = gs_fs;\n"
13005 " fs_out += result;\n"
13008 static const GLchar* gs = "#version 430 core\n"
13009 "#extension GL_ARB_enhanced_layouts : require\n"
13011 "layout(points) in;\n"
13012 "layout(triangle_strip, max_vertices = 4) out;\n"
13014 "in vec4 tes_gs[];\n"
13015 "out vec4 gs_fs;\n"
13019 " gs_fs = tes_gs[0];\n"
13020 " gl_Position = vec4(-1, -1, 0, 1);\n"
13022 " gs_fs = tes_gs[0];\n"
13023 " gl_Position = vec4(-1, 1, 0, 1);\n"
13025 " gs_fs = tes_gs[0];\n"
13026 " gl_Position = vec4(1, -1, 0, 1);\n"
13028 " gs_fs = tes_gs[0];\n"
13029 " gl_Position = vec4(1, 1, 0, 1);\n"
13033 static const GLchar* gs_tested = "#version 430 core\n"
13034 "#extension GL_ARB_enhanced_layouts : require\n"
13036 "layout(points) in;\n"
13037 "layout(triangle_strip, max_vertices = 4) out;\n"
13039 "STRUCT_DEFINITION"
13041 "VARIABLE_DEFINITION"
13043 "in vec4 tes_gs[];\n"
13044 "out vec4 gs_fs;\n"
13048 " vec4 result = tes_gs[0];\n"
13052 " gs_fs = result;\n"
13053 " gl_Position = vec4(-1, -1, 0, 1);\n"
13055 " gs_fs = result;\n"
13056 " gl_Position = vec4(-1, 1, 0, 1);\n"
13058 " gs_fs = result;\n"
13059 " gl_Position = vec4(1, -1, 0, 1);\n"
13061 " gs_fs = result;\n"
13062 " gl_Position = vec4(1, 1, 0, 1);\n"
13066 static const GLchar* tcs = "#version 430 core\n"
13067 "#extension GL_ARB_enhanced_layouts : require\n"
13069 "layout(vertices = 1) out;\n"
13071 "in vec4 vs_tcs[];\n"
13072 "out vec4 tcs_tes[];\n"
13077 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
13079 " gl_TessLevelOuter[0] = 1.0;\n"
13080 " gl_TessLevelOuter[1] = 1.0;\n"
13081 " gl_TessLevelOuter[2] = 1.0;\n"
13082 " gl_TessLevelOuter[3] = 1.0;\n"
13083 " gl_TessLevelInner[0] = 1.0;\n"
13084 " gl_TessLevelInner[1] = 1.0;\n"
13087 static const GLchar* tcs_tested = "#version 430 core\n"
13088 "#extension GL_ARB_enhanced_layouts : require\n"
13090 "layout(vertices = 1) out;\n"
13092 "STRUCT_DEFINITION"
13094 "VARIABLE_DEFINITION"
13096 "in vec4 vs_tcs[];\n"
13097 "out vec4 tcs_tes[];\n"
13101 " vec4 result = vs_tcs[gl_InvocationID];\n"
13105 " tcs_tes[gl_InvocationID] = result;\n"
13107 " gl_TessLevelOuter[0] = 1.0;\n"
13108 " gl_TessLevelOuter[1] = 1.0;\n"
13109 " gl_TessLevelOuter[2] = 1.0;\n"
13110 " gl_TessLevelOuter[3] = 1.0;\n"
13111 " gl_TessLevelInner[0] = 1.0;\n"
13112 " gl_TessLevelInner[1] = 1.0;\n"
13115 static const GLchar* tes = "#version 430 core\n"
13116 "#extension GL_ARB_enhanced_layouts : require\n"
13118 "layout(isolines, point_mode) in;\n"
13120 "in vec4 tcs_tes[];\n"
13121 "out vec4 tes_gs;\n"
13125 " tes_gs = tcs_tes[0];\n"
13128 static const GLchar* tes_tested = "#version 430 core\n"
13129 "#extension GL_ARB_enhanced_layouts : require\n"
13131 "layout(isolines, point_mode) in;\n"
13133 "STRUCT_DEFINITION"
13135 "VARIABLE_DEFINITION"
13137 "in vec4 tcs_tes[];\n"
13138 "out vec4 tes_gs;\n"
13142 " vec4 result = tcs_tes[0];\n"
13146 " tes_gs += result;\n"
13149 static const GLchar* vs = "#version 430 core\n"
13150 "#extension GL_ARB_enhanced_layouts : require\n"
13153 "out vec4 vs_tcs;\n"
13157 " vs_tcs = in_vs;\n"
13160 static const GLchar* vs_tested = "#version 430 core\n"
13161 "#extension GL_ARB_enhanced_layouts : require\n"
13163 "STRUCT_DEFINITION"
13165 "VARIABLE_DEFINITION"
13168 "out vec4 vs_tcs;\n"
13172 " vec4 result = in_vs;\n"
13176 " vs_tcs += result;\n"
13180 std::string source;
13181 testCase& test_case = m_test_cases[test_case_index];
13182 const GLchar* var_definition = 0;
13183 const GLchar* var_use = 0;
13185 if (true == test_case.m_is_input)
13187 var_definition = input_var;
13188 var_use = input_use;
13192 var_definition = output_var;
13193 var_use = output_use;
13196 if (test_case.m_stage == stage)
13198 size_t position = 0;
13202 case Utils::Shader::FRAGMENT:
13203 source = fs_tested;
13205 case Utils::Shader::GEOMETRY:
13206 source = gs_tested;
13208 case Utils::Shader::TESS_CTRL:
13209 source = tcs_tested;
13211 case Utils::Shader::TESS_EVAL:
13212 source = tes_tested;
13214 case Utils::Shader::VERTEX:
13215 source = vs_tested;
13218 TCU_FAIL("Invalid enum");
13221 Utils::replaceToken("STRUCT_DEFINITION", position, struct_definition, source);
13222 Utils::replaceToken("VARIABLE_DEFINITION", position, var_definition, source);
13223 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
13229 case Utils::Shader::FRAGMENT:
13232 case Utils::Shader::GEOMETRY:
13235 case Utils::Shader::TESS_CTRL:
13238 case Utils::Shader::TESS_EVAL:
13241 case Utils::Shader::VERTEX:
13245 TCU_FAIL("Invalid enum");
13252 /** Get description of test case
13254 * @param test_case_index Index of test case
13256 * @return Test case description
13258 std::string VaryingStructureMemberLocationTest::getTestCaseName(GLuint test_case_index)
13260 std::stringstream stream;
13261 testCase& test_case = m_test_cases[test_case_index];
13263 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", direction: ";
13265 if (true == test_case.m_is_input)
13271 stream << "output";
13274 return stream.str();
13277 /** Get number of test cases
13279 * @return Number of test cases
13281 GLuint VaryingStructureMemberLocationTest::getTestCaseNumber()
13283 return static_cast<GLuint>(m_test_cases.size());
13286 /** Selects if "compute" stage is relevant for test
13292 bool VaryingStructureMemberLocationTest::isComputeRelevant(GLuint /* test_case_index */)
13297 /** Prepare all test cases
13300 void VaryingStructureMemberLocationTest::testInit()
13302 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
13304 if (Utils::Shader::COMPUTE == stage)
13309 testCase test_case_in = { true, (Utils::Shader::STAGES)stage };
13310 testCase test_case_out = { false, (Utils::Shader::STAGES)stage };
13312 m_test_cases.push_back(test_case_in);
13314 if (Utils::Shader::FRAGMENT != stage)
13316 m_test_cases.push_back(test_case_out);
13323 * @param context Test framework context
13325 VaryingBlockLocationsTest::VaryingBlockLocationsTest(deqp::Context& context)
13326 : TextureTestBase(context, "varying_block_locations",
13327 "Test verifies that locations are respected when blocks are used as in and out ")
13331 /** Prepare code snippet that will pass in variables to out variables
13334 * @param varying_passthrough Collection of connections between in and out variables
13335 * @param stage Shader stage
13337 * @return Code that pass in variables to next stage
13339 std::string VaryingBlockLocationsTest::getPassSnippet(GLuint /* test_case_index */,
13340 Utils::VaryingPassthrough& varying_passthrough,
13341 Utils::Shader::STAGES stage)
13343 std::string result;
13345 if (Utils::Shader::VERTEX != stage)
13347 result = TextureTestBase::getPassSnippet(0, varying_passthrough, stage);
13351 result = "vs_tcs_block.third = vs_in_third;\n"
13352 " vs_tcs_block.fourth = vs_in_fourth;\n"
13353 " vs_tcs_block.fifth = vs_in_fifth;\n";
13359 /** Get interface of program
13362 * @param program_interface Interface of program
13363 * @param varying_passthrough Collection of connections between in and out variables
13365 void VaryingBlockLocationsTest::getProgramInterface(GLuint /* test_case_index */,
13366 Utils::ProgramInterface& program_interface,
13367 Utils::VaryingPassthrough& varying_passthrough)
13369 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
13370 const Utils::Type vec4 = Utils::Type::vec4;
13373 m_third_data = vec4.GenerateData();
13374 m_fourth_data = vec4.GenerateData();
13375 m_fifth_data = vec4.GenerateData();
13377 /* Memory layout is different from location layout */
13378 const GLuint fifth_offset = 0u;
13379 const GLuint third_offset = static_cast<GLuint>(fifth_offset + m_fifth_data.size());
13380 const GLuint fourth_offset = static_cast<GLuint>(third_offset + m_fourth_data.size());
13382 m_data.resize(fourth_offset + m_fourth_data.size());
13383 GLubyte* ptr = (GLubyte*)&m_data[0];
13384 memcpy(ptr + third_offset, &m_third_data[0], m_third_data.size());
13385 memcpy(ptr + fourth_offset, &m_fourth_data[0], m_fourth_data.size());
13386 memcpy(ptr + fifth_offset, &m_fifth_data[0], m_fifth_data.size());
13388 Utils::Interface* block = program_interface.Block("vs_tcs_Block");
13390 block->Member("fifth", "" /* qualifiers */, 0 /* component */, 4 /* location */, vec4, false /* normalized */,
13391 0u /* n_array_elements */, 0u /* stride */, fifth_offset /* offset */);
13393 block->Member("third", "layout (location = 2)" /* qualifiers */, 0 /* component */, 2 /* location */, vec4,
13394 false /* normalized */, 0u /* n_array_elements */, 0u /* stride */, third_offset /* offset */);
13396 block->Member("fourth", "" /* qualifiers */, 0 /* component */, 3 /* location */, vec4, false /* normalized */,
13397 0u /* n_array_elements */, 0u /* stride */, fourth_offset /* offset */);
13399 si.Output("vs_tcs_block", "layout (location = 4)", 0 /* component */, 4 /* location */, block,
13400 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)&m_data[0] /* data */,
13401 m_data.size() /* data_size */);
13403 si.Input("vs_in_third", "layout (location = 0)", 0 /* component */, 0 /* location */, vec4, false /* normalized */,
13404 0u /* n_array_elements */, 0u /* stride */, third_offset /* offset */,
13405 (GLvoid*)&m_third_data[0] /* data */, m_third_data.size() /* data_size */);
13407 si.Input("vs_in_fourth", "layout (location = 1)", 0 /* component */, 1 /* location */, vec4, false /* normalized */,
13408 0u /* n_array_elements */, 0u /* stride */, fourth_offset /* offset */,
13409 (GLvoid*)&m_fourth_data[0] /* data */, m_fourth_data.size() /* data_size */);
13411 si.Input("vs_in_fifth", "layout (location = 2)", 0 /* component */, 2 /* location */, vec4, false /* normalized */,
13412 0u /* n_array_elements */, 0u /* stride */, fifth_offset /* offset */,
13413 (GLvoid*)&m_fifth_data[0] /* data */, m_fifth_data.size() /* data_size */);
13415 program_interface.CloneVertexInterface(varying_passthrough);
13418 /** Selects if "compute" stage is relevant for test
13424 bool VaryingBlockLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
13429 /** This test should be run with separable programs
13435 bool VaryingBlockLocationsTest::useMonolithicProgram(GLuint /* test_case_index */)
13442 * @param context Test framework context
13444 VaryingBlockMemberLocationsTest::VaryingBlockMemberLocationsTest(deqp::Context& context)
13445 : NegativeTestBase(
13446 context, "varying_block_member_locations",
13447 "Test verifies that compilation error is reported when not all members of block are qualified with location")
13451 /** Source for given test case and stage
13453 * @param test_case_index Index of test case
13454 * @param stage Shader stage
13456 * @return Shader source
13458 std::string VaryingBlockMemberLocationsTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
13460 static const GLchar* block_definition_all = "Goku {\n"
13461 " layout (location = 2) vec4 gohan;\n"
13462 " layout (location = 4) vec4 goten;\n"
13463 " layout (location = 6) vec4 chichi;\n"
13465 static const GLchar* block_definition_default = "Goku {\n"
13470 static const GLchar* block_definition_one = "Goku {\n"
13472 " layout (location = 4) vec4 goten;\n"
13475 static const GLchar* input_use = " result += gokuINDEX.gohan + gokuINDEX.goten + gokuINDEX.chichi;\n";
13476 static const GLchar* output_use = " gokuINDEX.gohan = result / 2;\n"
13477 " gokuINDEX.goten = result / 4 - gokuINDEX.gohan;\n"
13478 " gokuINDEX.chichi = result / 8 - gokuINDEX.goten;\n";
13479 static const GLchar* fs = "#version 430 core\n"
13480 "#extension GL_ARB_enhanced_layouts : require\n"
13483 "out vec4 fs_out;\n"
13487 " fs_out = gs_fs;\n"
13490 static const GLchar* fs_tested = "#version 430 core\n"
13491 "#extension GL_ARB_enhanced_layouts : require\n"
13493 "DIRECTION BLOCK_DEFINITION"
13496 "out vec4 fs_out;\n"
13500 " vec4 result = gs_fs;\n"
13504 " fs_out = result;\n"
13507 static const GLchar* gs = "#version 430 core\n"
13508 "#extension GL_ARB_enhanced_layouts : require\n"
13510 "layout(points) in;\n"
13511 "layout(triangle_strip, max_vertices = 4) out;\n"
13513 "in vec4 tes_gs[];\n"
13514 "out vec4 gs_fs;\n"
13518 " gs_fs = tes_gs[0];\n"
13519 " gl_Position = vec4(-1, -1, 0, 1);\n"
13521 " gs_fs = tes_gs[0];\n"
13522 " gl_Position = vec4(-1, 1, 0, 1);\n"
13524 " gs_fs = tes_gs[0];\n"
13525 " gl_Position = vec4(1, -1, 0, 1);\n"
13527 " gs_fs = tes_gs[0];\n"
13528 " gl_Position = vec4(1, 1, 0, 1);\n"
13532 static const GLchar* gs_tested = "#version 430 core\n"
13533 "#extension GL_ARB_enhanced_layouts : require\n"
13535 "layout(points) in;\n"
13536 "layout(triangle_strip, max_vertices = 4) out;\n"
13538 "DIRECTION BLOCK_DEFINITION"
13540 "in vec4 tes_gs[];\n"
13541 "out vec4 gs_fs;\n"
13545 " vec4 result = tes_gs[0];\n"
13549 " gs_fs = result;\n"
13550 " gl_Position = vec4(-1, -1, 0, 1);\n"
13552 " gs_fs = result;\n"
13553 " gl_Position = vec4(-1, 1, 0, 1);\n"
13555 " gs_fs = result;\n"
13556 " gl_Position = vec4(1, -1, 0, 1);\n"
13558 " gs_fs = result;\n"
13559 " gl_Position = vec4(1, 1, 0, 1);\n"
13563 static const GLchar* tcs = "#version 430 core\n"
13564 "#extension GL_ARB_enhanced_layouts : require\n"
13566 "layout(vertices = 1) out;\n"
13568 "in vec4 vs_tcs[];\n"
13569 "out vec4 tcs_tes[];\n"
13574 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
13576 " gl_TessLevelOuter[0] = 1.0;\n"
13577 " gl_TessLevelOuter[1] = 1.0;\n"
13578 " gl_TessLevelOuter[2] = 1.0;\n"
13579 " gl_TessLevelOuter[3] = 1.0;\n"
13580 " gl_TessLevelInner[0] = 1.0;\n"
13581 " gl_TessLevelInner[1] = 1.0;\n"
13584 static const GLchar* tcs_tested = "#version 430 core\n"
13585 "#extension GL_ARB_enhanced_layouts : require\n"
13587 "layout(vertices = 1) out;\n"
13589 "DIRECTION BLOCK_DEFINITION"
13591 "in vec4 vs_tcs[];\n"
13592 "out vec4 tcs_tes[];\n"
13596 " vec4 result = vs_tcs[gl_InvocationID];\n"
13600 " tcs_tes[gl_InvocationID] = result;\n"
13602 " gl_TessLevelOuter[0] = 1.0;\n"
13603 " gl_TessLevelOuter[1] = 1.0;\n"
13604 " gl_TessLevelOuter[2] = 1.0;\n"
13605 " gl_TessLevelOuter[3] = 1.0;\n"
13606 " gl_TessLevelInner[0] = 1.0;\n"
13607 " gl_TessLevelInner[1] = 1.0;\n"
13610 static const GLchar* tes = "#version 430 core\n"
13611 "#extension GL_ARB_enhanced_layouts : require\n"
13613 "layout(isolines, point_mode) in;\n"
13615 "in vec4 tcs_tes[];\n"
13616 "out vec4 tes_gs;\n"
13620 " tes_gs = tcs_tes[0];\n"
13623 static const GLchar* tes_tested = "#version 430 core\n"
13624 "#extension GL_ARB_enhanced_layouts : require\n"
13626 "layout(isolines, point_mode) in;\n"
13628 "DIRECTION BLOCK_DEFINITION"
13630 "in vec4 tcs_tes[];\n"
13631 "out vec4 tes_gs;\n"
13635 " vec4 result = tcs_tes[0];\n"
13639 " tes_gs = result;\n"
13642 static const GLchar* vs = "#version 430 core\n"
13643 "#extension GL_ARB_enhanced_layouts : require\n"
13646 "out vec4 vs_tcs;\n"
13650 " vs_tcs = in_vs;\n"
13653 static const GLchar* vs_tested = "#version 430 core\n"
13654 "#extension GL_ARB_enhanced_layouts : require\n"
13656 "DIRECTION BLOCK_DEFINITION"
13659 "out vec4 vs_tcs;\n"
13663 " vec4 result = in_vs;\n"
13667 " vs_tcs = result;\n"
13671 static const GLchar* shaders_in[6][6] = { /* cs */ { 0, 0, 0, 0, 0, 0 },
13672 /* vs */ { 0, vs_tested, tcs, tes, gs, fs },
13673 /* tcs */ { 0, vs_tested, tcs_tested, tes, gs, fs },
13674 /* tes */ { 0, vs, tcs_tested, tes_tested, gs, fs },
13675 /* gs */ { 0, vs, tcs, tes_tested, gs_tested, fs },
13676 /* fs */ { 0, vs, tcs, tes, gs_tested, fs_tested } };
13678 static const GLchar* shaders_out[6][6] = { /* cs */ { 0, 0, 0, 0, 0, 0 },
13679 /* vs */ { 0, vs_tested, tcs_tested, tes, gs, fs },
13680 /* tcs */ { 0, vs, tcs_tested, tes_tested, gs, fs },
13681 /* tes */ { 0, vs, tcs, tes_tested, gs_tested, fs },
13682 /* gs */ { 0, vs, tcs, tes, gs_tested, fs_tested },
13683 /* fs */ { 0, 0, 0, 0, 0, 0 } };
13685 static const bool require_modifications_in[6][6] = {
13686 /* cs */ { false, false, false, false, false, false },
13687 /* vs */ { false, true, false, false, false, false },
13688 /* tcs */ { false, true, true, false, false, false },
13689 /* tes */ { false, false, true, true, false, false },
13690 /* gs */ { false, false, false, true, true, false },
13691 /* fs */ { false, false, false, false, true, true }
13694 static const bool require_modifications_out[6][6] = {
13695 /* cs */ { false, false, false, false, false, false },
13696 /* vs */ { false, true, true, false, false, false },
13697 /* tcs */ { false, false, true, true, false, false },
13698 /* tes */ { false, false, false, true, true, false },
13699 /* gs */ { false, false, false, false, true, true },
13700 /* fs */ { false, false, false, false, false, false }
13703 const GLchar* array = "";
13704 const GLchar* direction = "out";
13705 const GLchar* index = "";
13706 bool require_modifications = false;
13707 std::string source;
13708 testCase& test_case = m_test_cases[test_case_index];
13709 const GLchar* var_use = output_use;
13711 if (true == test_case.m_is_input)
13713 require_modifications = require_modifications_in[test_case.m_stage][stage];
13714 source = shaders_in[test_case.m_stage][stage];
13716 if (test_case.m_stage == stage)
13719 var_use = input_use;
13724 require_modifications = require_modifications_out[test_case.m_stage][stage];
13725 source = shaders_out[test_case.m_stage][stage];
13727 if (test_case.m_stage != stage)
13730 var_use = input_use;
13734 const GLchar* definition = test_case.m_qualify_all ? block_definition_all
13735 : block_definition_default;
13737 if (test_case.m_stage == stage)
13739 if (true == test_case.m_qualify_all)
13741 definition = block_definition_all;
13745 definition = block_definition_one;
13749 // Geometry shader inputs, tessellation control shader inputs and outputs, and tessellation evaluation
13750 // inputs all have an additional level of arrayness relative to other shader inputs and outputs.
13753 case Utils::Shader::FRAGMENT:
13755 case Utils::Shader::TESS_CTRL:
13757 index = "[gl_InvocationID]";
13759 // geometry shader's input must have one more dimension than tessellation evaluation shader's output,
13760 // the GS input block is an array, so the DS output can't be declared as an array
13761 case Utils::Shader::GEOMETRY:
13762 case Utils::Shader::TESS_EVAL:
13764 if (std::string(direction) == std::string("in")) // match HS output and DS input
13769 else // match DS output and GS input
13776 case Utils::Shader::VERTEX:
13779 TCU_FAIL("Invalid enum");
13782 if (true == require_modifications)
13784 size_t position = 0;
13787 Utils::replaceToken("DIRECTION", position, direction, source);
13789 Utils::replaceToken("BLOCK_DEFINITION", position, definition, source);
13791 Utils::replaceToken("ARRAY", position, array, source);
13792 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
13794 Utils::replaceAllTokens("INDEX", index, source);
13800 case Utils::Shader::FRAGMENT:
13803 case Utils::Shader::GEOMETRY:
13806 case Utils::Shader::TESS_CTRL:
13809 case Utils::Shader::TESS_EVAL:
13812 case Utils::Shader::VERTEX:
13816 TCU_FAIL("Invalid enum");
13823 /** Get description of test case
13825 * @param test_case_index Index of test case
13827 * @return Test case description
13829 std::string VaryingBlockMemberLocationsTest::getTestCaseName(GLuint test_case_index)
13831 std::stringstream stream;
13832 testCase& test_case = m_test_cases[test_case_index];
13834 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", direction: ";
13836 if (true == test_case.m_is_input)
13842 stream << "output";
13845 if (true == test_case.m_qualify_all)
13847 stream << ", all members qualified";
13851 stream << ", not all members qualified";
13854 return stream.str();
13857 /** Get number of test cases
13859 * @return Number of test cases
13861 GLuint VaryingBlockMemberLocationsTest::getTestCaseNumber()
13863 return static_cast<GLuint>(m_test_cases.size());
13866 /** Selects if "compute" stage is relevant for test
13872 bool VaryingBlockMemberLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
13877 /** Selects if compilation failure is expected result
13879 * @param test_case_index Index of test case
13881 * @return false when all members are qualified, true otherwise
13883 bool VaryingBlockMemberLocationsTest::isFailureExpected(GLuint test_case_index)
13885 return (true != m_test_cases[test_case_index].m_qualify_all);
13888 /** Prepare all test cases
13891 void VaryingBlockMemberLocationsTest::testInit()
13893 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
13895 if (Utils::Shader::COMPUTE == stage)
13900 testCase test_case_in_all = { true, true, (Utils::Shader::STAGES)stage };
13901 testCase test_case_in_one = { true, false, (Utils::Shader::STAGES)stage };
13902 testCase test_case_out_all = { false, true, (Utils::Shader::STAGES)stage };
13903 testCase test_case_out_one = { false, false, (Utils::Shader::STAGES)stage };
13905 if (Utils::Shader::VERTEX != stage)
13907 m_test_cases.push_back(test_case_in_all);
13908 m_test_cases.push_back(test_case_in_one);
13911 if (Utils::Shader::FRAGMENT != stage)
13913 m_test_cases.push_back(test_case_out_all);
13914 m_test_cases.push_back(test_case_out_one);
13921 * @param context Test framework context
13923 VaryingBlockAutomaticMemberLocationsTest::VaryingBlockAutomaticMemberLocationsTest(deqp::Context& context)
13924 : NegativeTestBase(
13925 context, "varying_block_automatic_member_locations",
13926 "Test verifies that compiler assigns subsequent locations to block members, even if this causes errors")
13930 /** Source for given test case and stage
13932 * @param test_case_index Index of test case
13933 * @param stage Shader stage
13935 * @return Shader source
13937 std::string VaryingBlockAutomaticMemberLocationsTest::getShaderSource(GLuint test_case_index,
13938 Utils::Shader::STAGES stage)
13940 static const GLchar* block_definition = "layout (location = 2) DIRECTION DBZ {\n"
13942 " vec4 gohan[4];\n"
13944 " layout (location = 1) vec4 chichi;\n"
13947 static const GLchar* input_use = " result += dbzINDEX.goku + dbzINDEX.gohan[0] + dbzINDEX.gohan[1] + "
13948 "dbzINDEX.gohan[3] + dbzINDEX.gohan[2] + dbzINDEX.goten + dbzINDEX.chichi + "
13950 static const GLchar* output_use = " dbzINDEX.goku = result;\n"
13951 " dbzINDEX.gohan[0] = result / 2;\n"
13952 " dbzINDEX.gohan[1] = result / 2.25;\n"
13953 " dbzINDEX.gohan[2] = result / 2.5;\n"
13954 " dbzINDEX.gohan[3] = result / 2.75;\n"
13955 " dbzINDEX.goten = result / 4 - dbzINDEX.gohan[0] - dbzINDEX.gohan[1] - "
13956 "dbzINDEX.gohan[2] - dbzINDEX.gohan[3];\n"
13957 " dbzINDEX.chichi = result / 8 - dbzINDEX.goten;\n"
13958 " dbzINDEX.pan = result / 16 - dbzINDEX.chichi;\n";
13959 static const GLchar* fs = "#version 430 core\n"
13960 "#extension GL_ARB_enhanced_layouts : require\n"
13963 "out vec4 fs_out;\n"
13967 " fs_out = gs_fs;\n"
13970 static const GLchar* fs_tested = "#version 430 core\n"
13971 "#extension GL_ARB_enhanced_layouts : require\n"
13976 "out vec4 fs_out;\n"
13980 " vec4 result = gs_fs;\n"
13984 " fs_out += result;\n"
13987 static const GLchar* gs = "#version 430 core\n"
13988 "#extension GL_ARB_enhanced_layouts : require\n"
13990 "layout(points) in;\n"
13991 "layout(triangle_strip, max_vertices = 4) out;\n"
13993 "in vec4 tes_gs[];\n"
13994 "out vec4 gs_fs;\n"
13998 " gs_fs = tes_gs[0];\n"
13999 " gl_Position = vec4(-1, -1, 0, 1);\n"
14001 " gs_fs = tes_gs[0];\n"
14002 " gl_Position = vec4(-1, 1, 0, 1);\n"
14004 " gs_fs = tes_gs[0];\n"
14005 " gl_Position = vec4(1, -1, 0, 1);\n"
14007 " gs_fs = tes_gs[0];\n"
14008 " gl_Position = vec4(1, 1, 0, 1);\n"
14012 static const GLchar* gs_tested = "#version 430 core\n"
14013 "#extension GL_ARB_enhanced_layouts : require\n"
14015 "layout(points) in;\n"
14016 "layout(triangle_strip, max_vertices = 4) out;\n"
14020 "in vec4 tes_gs[];\n"
14021 "out vec4 gs_fs;\n"
14025 " vec4 result = tes_gs[0];\n"
14029 " gs_fs = result;\n"
14030 " gl_Position = vec4(-1, -1, 0, 1);\n"
14032 " gs_fs = result;\n"
14033 " gl_Position = vec4(-1, 1, 0, 1);\n"
14035 " gs_fs = result;\n"
14036 " gl_Position = vec4(1, -1, 0, 1);\n"
14038 " gs_fs = result;\n"
14039 " gl_Position = vec4(1, 1, 0, 1);\n"
14043 static const GLchar* tcs = "#version 430 core\n"
14044 "#extension GL_ARB_enhanced_layouts : require\n"
14046 "layout(vertices = 1) out;\n"
14048 "in vec4 vs_tcs[];\n"
14049 "out vec4 tcs_tes[];\n"
14054 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
14056 " gl_TessLevelOuter[0] = 1.0;\n"
14057 " gl_TessLevelOuter[1] = 1.0;\n"
14058 " gl_TessLevelOuter[2] = 1.0;\n"
14059 " gl_TessLevelOuter[3] = 1.0;\n"
14060 " gl_TessLevelInner[0] = 1.0;\n"
14061 " gl_TessLevelInner[1] = 1.0;\n"
14064 static const GLchar* tcs_tested = "#version 430 core\n"
14065 "#extension GL_ARB_enhanced_layouts : require\n"
14067 "layout(vertices = 1) out;\n"
14071 "in vec4 vs_tcs[];\n"
14072 "out vec4 tcs_tes[];\n"
14076 " vec4 result = vs_tcs[gl_InvocationID];\n"
14080 " tcs_tes[gl_InvocationID] = result;\n"
14082 " gl_TessLevelOuter[0] = 1.0;\n"
14083 " gl_TessLevelOuter[1] = 1.0;\n"
14084 " gl_TessLevelOuter[2] = 1.0;\n"
14085 " gl_TessLevelOuter[3] = 1.0;\n"
14086 " gl_TessLevelInner[0] = 1.0;\n"
14087 " gl_TessLevelInner[1] = 1.0;\n"
14090 static const GLchar* tes = "#version 430 core\n"
14091 "#extension GL_ARB_enhanced_layouts : require\n"
14093 "layout(isolines, point_mode) in;\n"
14095 "in vec4 tcs_tes[];\n"
14096 "out vec4 tes_gs;\n"
14100 " tes_gs = tcs_tes[0];\n"
14103 static const GLchar* tes_tested = "#version 430 core\n"
14104 "#extension GL_ARB_enhanced_layouts : require\n"
14106 "layout(isolines, point_mode) in;\n"
14110 "in vec4 tcs_tes[];\n"
14111 "out vec4 tes_gs;\n"
14115 " vec4 result = tcs_tes[0];\n"
14119 " tes_gs += result;\n"
14122 static const GLchar* vs = "#version 430 core\n"
14123 "#extension GL_ARB_enhanced_layouts : require\n"
14126 "out vec4 vs_tcs;\n"
14130 " vs_tcs = in_vs;\n"
14133 static const GLchar* vs_tested = "#version 430 core\n"
14134 "#extension GL_ARB_enhanced_layouts : require\n"
14139 "out vec4 vs_tcs;\n"
14143 " vec4 result = in_vs;\n"
14147 " vs_tcs += result;\n"
14151 const GLchar* array = "";
14152 const GLchar* direction = "out";
14153 const GLchar* index = "";
14154 std::string source;
14155 testCase& test_case = m_test_cases[test_case_index];
14156 const GLchar* var_use = output_use;
14158 if (true == test_case.m_is_input)
14161 var_use = input_use;
14164 if (test_case.m_stage == stage)
14166 size_t position = 0;
14171 case Utils::Shader::FRAGMENT:
14172 source = fs_tested;
14174 case Utils::Shader::GEOMETRY:
14175 source = gs_tested;
14179 case Utils::Shader::TESS_CTRL:
14180 source = tcs_tested;
14182 index = "[gl_InvocationID]";
14184 case Utils::Shader::TESS_EVAL:
14185 source = tes_tested;
14189 case Utils::Shader::VERTEX:
14190 source = vs_tested;
14193 TCU_FAIL("Invalid enum");
14197 Utils::replaceToken("BLOCK_DEFINITION", position, block_definition, source);
14199 Utils::replaceToken("DIRECTION", position, direction, source);
14200 Utils::replaceToken("ARRAY", position, array, source);
14201 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
14203 Utils::replaceAllTokens("INDEX", index, source);
14209 case Utils::Shader::FRAGMENT:
14212 case Utils::Shader::GEOMETRY:
14215 case Utils::Shader::TESS_CTRL:
14218 case Utils::Shader::TESS_EVAL:
14221 case Utils::Shader::VERTEX:
14225 TCU_FAIL("Invalid enum");
14232 /** Get description of test case
14234 * @param test_case_index Index of test case
14236 * @return Test case description
14238 std::string VaryingBlockAutomaticMemberLocationsTest::getTestCaseName(GLuint test_case_index)
14240 std::stringstream stream;
14241 testCase& test_case = m_test_cases[test_case_index];
14243 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", direction: ";
14245 if (true == test_case.m_is_input)
14251 stream << "output";
14254 return stream.str();
14257 /** Get number of test cases
14259 * @return Number of test cases
14261 GLuint VaryingBlockAutomaticMemberLocationsTest::getTestCaseNumber()
14263 return static_cast<GLuint>(m_test_cases.size());
14266 /** Selects if "compute" stage is relevant for test
14272 bool VaryingBlockAutomaticMemberLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
14277 /** Prepare all test cases
14280 void VaryingBlockAutomaticMemberLocationsTest::testInit()
14282 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
14284 if (Utils::Shader::COMPUTE == stage)
14289 testCase test_case_in = { true, (Utils::Shader::STAGES)stage };
14290 testCase test_case_out = { false, (Utils::Shader::STAGES)stage };
14292 if (Utils::Shader::VERTEX != stage)
14294 m_test_cases.push_back(test_case_in);
14297 if (Utils::Shader::FRAGMENT != stage)
14299 m_test_cases.push_back(test_case_out);
14306 * @param context Test framework context
14308 VaryingLocationLimitTest::VaryingLocationLimitTest(deqp::Context& context)
14309 : NegativeTestBase(context, "varying_location_limit",
14310 "Test verifies that compiler reports error when location qualifier exceed limits")
14314 /** Source for given test case and stage
14316 * @param test_case_index Index of test case
14317 * @param stage Shader stage
14319 * @return Shader source
14321 std::string VaryingLocationLimitTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
14323 static const GLchar* var_definition = "layout (location = LAST + 1) FLAT DIRECTION TYPE gokuARRAY;\n";
14324 static const GLchar* input_use = " if (TYPE(0) == gokuINDEX)\n"
14326 " result += vec4(1, 0.5, 0.25, 0.125);\n"
14328 static const GLchar* output_use = " gokuINDEX = TYPE(0);\n"
14329 " if (vec4(0) == result)\n"
14331 " gokuINDEX = TYPE(1);\n"
14333 static const GLchar* fs = "#version 430 core\n"
14334 "#extension GL_ARB_enhanced_layouts : require\n"
14337 "out vec4 fs_out;\n"
14341 " fs_out = gs_fs;\n"
14344 static const GLchar* fs_tested = "#version 430 core\n"
14345 "#extension GL_ARB_enhanced_layouts : require\n"
14350 "out vec4 fs_out;\n"
14354 " vec4 result = gs_fs;\n"
14358 " fs_out += result;\n"
14361 static const GLchar* gs = "#version 430 core\n"
14362 "#extension GL_ARB_enhanced_layouts : require\n"
14364 "layout(points) in;\n"
14365 "layout(triangle_strip, max_vertices = 4) out;\n"
14367 "in vec4 tes_gs[];\n"
14368 "out vec4 gs_fs;\n"
14372 " gs_fs = tes_gs[0];\n"
14373 " gl_Position = vec4(-1, -1, 0, 1);\n"
14375 " gs_fs = tes_gs[0];\n"
14376 " gl_Position = vec4(-1, 1, 0, 1);\n"
14378 " gs_fs = tes_gs[0];\n"
14379 " gl_Position = vec4(1, -1, 0, 1);\n"
14381 " gs_fs = tes_gs[0];\n"
14382 " gl_Position = vec4(1, 1, 0, 1);\n"
14386 static const GLchar* gs_tested = "#version 430 core\n"
14387 "#extension GL_ARB_enhanced_layouts : require\n"
14389 "layout(points) in;\n"
14390 "layout(triangle_strip, max_vertices = 4) out;\n"
14394 "in vec4 tes_gs[];\n"
14395 "out vec4 gs_fs;\n"
14399 " vec4 result = tes_gs[0];\n"
14403 " gs_fs = result;\n"
14404 " gl_Position = vec4(-1, -1, 0, 1);\n"
14406 " gs_fs = result;\n"
14407 " gl_Position = vec4(-1, 1, 0, 1);\n"
14409 " gs_fs = result;\n"
14410 " gl_Position = vec4(1, -1, 0, 1);\n"
14412 " gs_fs = result;\n"
14413 " gl_Position = vec4(1, 1, 0, 1);\n"
14417 static const GLchar* tcs = "#version 430 core\n"
14418 "#extension GL_ARB_enhanced_layouts : require\n"
14420 "layout(vertices = 1) out;\n"
14422 "in vec4 vs_tcs[];\n"
14423 "out vec4 tcs_tes[];\n"
14428 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
14430 " gl_TessLevelOuter[0] = 1.0;\n"
14431 " gl_TessLevelOuter[1] = 1.0;\n"
14432 " gl_TessLevelOuter[2] = 1.0;\n"
14433 " gl_TessLevelOuter[3] = 1.0;\n"
14434 " gl_TessLevelInner[0] = 1.0;\n"
14435 " gl_TessLevelInner[1] = 1.0;\n"
14438 static const GLchar* tcs_tested = "#version 430 core\n"
14439 "#extension GL_ARB_enhanced_layouts : require\n"
14441 "layout(vertices = 1) out;\n"
14445 "in vec4 vs_tcs[];\n"
14446 "out vec4 tcs_tes[];\n"
14450 " vec4 result = vs_tcs[gl_InvocationID];\n"
14454 " tcs_tes[gl_InvocationID] = result;\n"
14456 " gl_TessLevelOuter[0] = 1.0;\n"
14457 " gl_TessLevelOuter[1] = 1.0;\n"
14458 " gl_TessLevelOuter[2] = 1.0;\n"
14459 " gl_TessLevelOuter[3] = 1.0;\n"
14460 " gl_TessLevelInner[0] = 1.0;\n"
14461 " gl_TessLevelInner[1] = 1.0;\n"
14464 static const GLchar* tes = "#version 430 core\n"
14465 "#extension GL_ARB_enhanced_layouts : require\n"
14467 "layout(isolines, point_mode) in;\n"
14469 "in vec4 tcs_tes[];\n"
14470 "out vec4 tes_gs;\n"
14474 " tes_gs = tcs_tes[0];\n"
14477 static const GLchar* tes_tested = "#version 430 core\n"
14478 "#extension GL_ARB_enhanced_layouts : require\n"
14480 "layout(isolines, point_mode) in;\n"
14484 "in vec4 tcs_tes[];\n"
14485 "out vec4 tes_gs;\n"
14489 " vec4 result = tcs_tes[0];\n"
14493 " tes_gs += result;\n"
14496 static const GLchar* vs = "#version 430 core\n"
14497 "#extension GL_ARB_enhanced_layouts : require\n"
14500 "out vec4 vs_tcs;\n"
14504 " vs_tcs = in_vs;\n"
14507 static const GLchar* vs_tested = "#version 430 core\n"
14508 "#extension GL_ARB_enhanced_layouts : require\n"
14513 "out vec4 vs_tcs;\n"
14517 " vec4 result = in_vs;\n"
14521 " vs_tcs += result;\n"
14525 std::string source;
14526 testCase& test_case = m_test_cases[test_case_index];
14528 if (test_case.m_stage == stage)
14530 const GLchar* array = "";
14532 const GLchar* direction = "in ";
14533 const GLchar* flat = "";
14534 const GLchar* index = "";
14535 GLuint last = getLastInputLocation(stage, test_case.m_type, 0);
14536 size_t position = 0;
14538 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
14539 Utils::Variable::STORAGE storage = Utils::Variable::VARYING_INPUT;
14540 const GLchar* var_use = input_use;
14542 if (false == test_case.m_is_input)
14545 last = getLastOutputLocation(stage, test_case.m_type, 0);
14546 storage = Utils::Variable::VARYING_OUTPUT;
14547 var_use = output_use;
14550 if (true == isFlatRequired(stage, test_case.m_type, storage))
14555 sprintf(buffer, "%d", last);
14559 case Utils::Shader::FRAGMENT:
14560 source = fs_tested;
14562 case Utils::Shader::GEOMETRY:
14563 source = gs_tested;
14567 case Utils::Shader::TESS_CTRL:
14568 source = tcs_tested;
14570 index = "[gl_InvocationID]";
14572 case Utils::Shader::TESS_EVAL:
14573 source = tes_tested;
14577 case Utils::Shader::VERTEX:
14578 source = vs_tested;
14581 TCU_FAIL("Invalid enum");
14585 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
14587 Utils::replaceToken("LAST", position, buffer, source);
14588 Utils::replaceToken("FLAT", position, flat, source);
14589 Utils::replaceToken("DIRECTION", position, direction, source);
14590 Utils::replaceToken("ARRAY", position, array, source);
14591 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
14593 Utils::replaceAllTokens("TYPE", type_name, source);
14594 Utils::replaceAllTokens("INDEX", index, source);
14600 case Utils::Shader::FRAGMENT:
14603 case Utils::Shader::GEOMETRY:
14606 case Utils::Shader::TESS_CTRL:
14609 case Utils::Shader::TESS_EVAL:
14612 case Utils::Shader::VERTEX:
14616 TCU_FAIL("Invalid enum");
14623 /** Get description of test case
14625 * @param test_case_index Index of test case
14627 * @return Test case description
14629 std::string VaryingLocationLimitTest::getTestCaseName(GLuint test_case_index)
14631 std::stringstream stream;
14632 testCase& test_case = m_test_cases[test_case_index];
14634 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
14635 << " type: " << test_case.m_type.GetGLSLTypeName() << ", direction: ";
14637 if (true == test_case.m_is_input)
14643 stream << "output";
14646 return stream.str();
14649 /** Get number of test cases
14651 * @return Number of test cases
14653 GLuint VaryingLocationLimitTest::getTestCaseNumber()
14655 return static_cast<GLuint>(m_test_cases.size());
14658 /** Selects if "compute" stage is relevant for test
14664 bool VaryingLocationLimitTest::isComputeRelevant(GLuint /* test_case_index */)
14669 /** Prepare all test cases
14672 void VaryingLocationLimitTest::testInit()
14674 const GLuint n_types = getTypesNumber();
14676 for (GLuint i = 0; i < n_types; ++i)
14678 const Utils::Type& type = getType(i);
14680 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
14682 if (Utils::Shader::COMPUTE == stage)
14687 testCase test_case_in = { true, type, (Utils::Shader::STAGES)stage };
14688 testCase test_case_out = { false, type, (Utils::Shader::STAGES)stage };
14690 m_test_cases.push_back(test_case_in);
14692 if (Utils::Shader::FRAGMENT != stage)
14694 m_test_cases.push_back(test_case_out);
14702 * @param context Test framework context
14704 VaryingComponentsTest::VaryingComponentsTest(deqp::Context& context)
14705 : VaryingLocationsTest(context, "varying_components",
14706 "Test verifies that input and output components are respected")
14712 * @param context Test framework context
14713 * @param test_name Name of test
14714 * @param test_description Description of test
14716 VaryingComponentsTest::VaryingComponentsTest(deqp::Context& context, const glw::GLchar* test_name,
14717 const glw::GLchar* test_description)
14718 : VaryingLocationsTest(context, test_name, test_description)
14722 /** Get interface of program
14724 * @param test_case_index Test case
14725 * @param program_interface Interface of program
14726 * @param varying_passthrough Collection of connections between in and out variables
14728 void VaryingComponentsTest::getProgramInterface(GLuint test_case_index, Utils::ProgramInterface& program_interface,
14729 Utils::VaryingPassthrough& varying_passthrough)
14731 GLuint array_length = getArrayLength();
14732 const testCase& test_case = m_test_cases[test_case_index];
14733 const Utils::Type vector_type = Utils::Type::GetType(test_case.m_type, 1, 4);
14734 Utils::ShaderInterface si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
14736 /* Zero means no array, however we still need at least 1 slot of data */
14737 if (0 == array_length)
14742 /* Generate data */
14743 const std::vector<GLubyte>& data = vector_type.GenerateDataPacked();
14744 const size_t data_size = data.size();
14746 /* Prepare data for variables */
14747 m_data.resize(array_length * data_size);
14749 GLubyte* dst = &m_data[0];
14750 const GLubyte* src = &data[0];
14752 for (GLuint i = 0; i < array_length; ++i)
14754 memcpy(dst + data_size * i, src, data_size);
14757 /* Prepare interface for each stage */
14758 prepareShaderStage(Utils::Shader::FRAGMENT, vector_type, program_interface, test_case, varying_passthrough);
14759 prepareShaderStage(Utils::Shader::GEOMETRY, vector_type, program_interface, test_case, varying_passthrough);
14760 prepareShaderStage(Utils::Shader::TESS_CTRL, vector_type, program_interface, test_case, varying_passthrough);
14761 prepareShaderStage(Utils::Shader::TESS_EVAL, vector_type, program_interface, test_case, varying_passthrough);
14762 prepareShaderStage(Utils::Shader::VERTEX, vector_type, program_interface, test_case, varying_passthrough);
14767 * @param test_case_index Index of test case
14769 * @return Name of type test in test_case_index
14771 std::string VaryingComponentsTest::getTestCaseName(glw::GLuint test_case_index)
14775 const testCase& test_case = m_test_cases[test_case_index];
14779 switch (test_case.m_type)
14781 case Utils::Type::Double:
14782 name.append(Utils::Type::_double.GetGLSLTypeName());
14784 case Utils::Type::Float:
14785 name.append(Utils::Type::_float.GetGLSLTypeName());
14787 case Utils::Type::Int:
14788 name.append(Utils::Type::_int.GetGLSLTypeName());
14790 case Utils::Type::Uint:
14791 name.append(Utils::Type::uint.GetGLSLTypeName());
14795 name.append(", layout: ");
14797 switch (test_case.m_layout)
14800 name.append("GVEC4");
14803 name.append("SCALAR_GVEC3");
14806 name.append("GVEC3_SCALAR");
14809 name.append("GVEC2_GVEC2");
14811 case GVEC2_SCALAR_SCALAR:
14812 name.append("GVEC2_SCALAR_SCALAR");
14814 case SCALAR_GVEC2_SCALAR:
14815 name.append("SCALAR_GVEC2_SCALAR");
14817 case SCALAR_SCALAR_GVEC2:
14818 name.append("SCALAR_SCALAR_GVEC2");
14820 case SCALAR_SCALAR_SCALAR_SCALAR:
14821 name.append("SCALAR_SCALAR_SCALAR_SCALAR");
14828 /** Returns number of types to test
14830 * @return Number of types, 34
14832 glw::GLuint VaryingComponentsTest::getTestCaseNumber()
14834 return static_cast<GLuint>(m_test_cases.size());
14837 /* Prepare test cases */
14838 void VaryingComponentsTest::testInit()
14840 // FIXME: add tests for doubles, which have specific rules
14842 m_test_cases.push_back(testCase(GVEC4, Utils::Type::Float));
14843 m_test_cases.push_back(testCase(SCALAR_GVEC3, Utils::Type::Float));
14844 m_test_cases.push_back(testCase(GVEC3_SCALAR, Utils::Type::Float));
14845 m_test_cases.push_back(testCase(GVEC2_GVEC2, Utils::Type::Float));
14846 m_test_cases.push_back(testCase(GVEC2_SCALAR_SCALAR, Utils::Type::Float));
14847 m_test_cases.push_back(testCase(SCALAR_GVEC2_SCALAR, Utils::Type::Float));
14848 m_test_cases.push_back(testCase(SCALAR_SCALAR_GVEC2, Utils::Type::Float));
14849 m_test_cases.push_back(testCase(SCALAR_SCALAR_SCALAR_SCALAR, Utils::Type::Float));
14851 m_test_cases.push_back(testCase(GVEC4, Utils::Type::Int));
14852 m_test_cases.push_back(testCase(SCALAR_GVEC3, Utils::Type::Int));
14853 m_test_cases.push_back(testCase(GVEC3_SCALAR, Utils::Type::Int));
14854 m_test_cases.push_back(testCase(GVEC2_GVEC2, Utils::Type::Int));
14855 m_test_cases.push_back(testCase(GVEC2_SCALAR_SCALAR, Utils::Type::Int));
14856 m_test_cases.push_back(testCase(SCALAR_GVEC2_SCALAR, Utils::Type::Int));
14857 m_test_cases.push_back(testCase(SCALAR_SCALAR_GVEC2, Utils::Type::Int));
14858 m_test_cases.push_back(testCase(SCALAR_SCALAR_SCALAR_SCALAR, Utils::Type::Int));
14860 m_test_cases.push_back(testCase(GVEC4, Utils::Type::Uint));
14861 m_test_cases.push_back(testCase(SCALAR_GVEC3, Utils::Type::Uint));
14862 m_test_cases.push_back(testCase(GVEC3_SCALAR, Utils::Type::Uint));
14863 m_test_cases.push_back(testCase(GVEC2_GVEC2, Utils::Type::Uint));
14864 m_test_cases.push_back(testCase(GVEC2_SCALAR_SCALAR, Utils::Type::Uint));
14865 m_test_cases.push_back(testCase(SCALAR_GVEC2_SCALAR, Utils::Type::Uint));
14866 m_test_cases.push_back(testCase(SCALAR_SCALAR_GVEC2, Utils::Type::Uint));
14867 m_test_cases.push_back(testCase(SCALAR_SCALAR_SCALAR_SCALAR, Utils::Type::Uint));
14870 /** Inform that test use components
14876 bool VaryingComponentsTest::useComponentQualifier(glw::GLuint /* test_case_index */)
14881 /** Get length of arrays that should be used during test
14883 * @return 0u - no array at all
14885 GLuint VaryingComponentsTest::getArrayLength()
14890 std::string VaryingComponentsTest::prepareGlobals(GLuint last_in_location, GLuint last_out_location)
14892 std::string globals = VaryingLocationsTest::prepareGlobals(last_in_location, last_out_location);
14894 globals.append("const uint comp_x = 0u;\n"
14895 "const uint comp_y = 1u;\n"
14896 "const uint comp_z = 2u;\n"
14897 "const uint comp_w = 3u;\n");
14905 std::string VaryingComponentsTest::prepareName(const glw::GLchar* name, glw::GLint location, glw::GLint component,
14906 Utils::Shader::STAGES stage, Utils::Variable::STORAGE storage)
14909 std::string result = "PREFIXNAME_lLOCATION_cCOMPONENT";
14910 size_t position = 0;
14911 const GLchar* prefix = Utils::ProgramInterface::GetStagePrefix(stage, storage);
14913 Utils::replaceToken("PREFIX", position, prefix, result);
14914 Utils::replaceToken("NAME", position, name, result);
14916 sprintf(buffer, "%d", location);
14917 Utils::replaceToken("LOCATION", position, buffer, result);
14919 sprintf(buffer, "%d", component);
14920 Utils::replaceToken("COMPONENT", position, buffer, result);
14925 std::string VaryingComponentsTest::prepareQualifiers(const glw::GLchar* location, const glw::GLchar* component,
14926 const glw::GLchar* interpolation)
14928 size_t position = 0;
14929 std::string qualifiers = "layout (location = LOCATION, component = COMPONENT) INTERPOLATION";
14931 Utils::replaceToken("LOCATION", position, location, qualifiers);
14932 Utils::replaceToken("COMPONENT", position, component, qualifiers);
14933 Utils::replaceToken("INTERPOLATION", position, interpolation, qualifiers);
14941 void VaryingComponentsTest::prepareShaderStage(Utils::Shader::STAGES stage, const Utils::Type& vector_type,
14942 Utils::ProgramInterface& program_interface, const testCase& test_case,
14943 Utils::VaryingPassthrough& varying_passthrough)
14945 const GLuint array_length = getArrayLength();
14946 const Utils::Type& basic_type = Utils::Type::GetType(vector_type.m_basic_type, 1 /* n_cols */, 1 /* n_rows */);
14947 descriptor desc_in[8];
14948 descriptor desc_out[8];
14949 const GLuint first_in_loc = 0;
14950 const GLuint first_out_loc = 0;
14951 const GLchar* interpolation = "";
14952 const GLuint last_in_loc = getLastInputLocation(stage, vector_type, array_length);
14953 GLuint last_out_loc = 0;
14955 Utils::ShaderInterface& si = program_interface.GetShaderInterface(stage);
14957 /* Select interpolation */
14958 if ((Utils::Shader::FRAGMENT == stage) || (Utils::Shader::GEOMETRY == stage))
14960 interpolation = " flat";
14963 if (Utils::Shader::FRAGMENT != stage)
14965 last_out_loc = getLastOutputLocation(stage, vector_type, array_length);
14968 switch (test_case.m_layout)
14972 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 4, "gvec4");
14973 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 4, "gvec4");
14975 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 4, "gvec4");
14976 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 4, "gvec4");
14980 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "scalar");
14981 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "scalar");
14982 desc_in[2].assign(1, "comp_y", first_in_loc, "first_input_location", 3, "gvec3");
14983 desc_in[3].assign(1, "comp_y", last_in_loc, "last_input_location", 3, "gvec3");
14985 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "scalar");
14986 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "scalar");
14987 desc_out[2].assign(1, "comp_y", first_out_loc, "first_output_location", 3, "gvec3");
14988 desc_out[3].assign(1, "comp_y", last_out_loc, "last_output_location", 3, "gvec3");
14992 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 3, "gvec3");
14993 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 3, "gvec3");
14994 desc_in[2].assign(3, "comp_w", first_in_loc, "first_input_location", 1, "scalar");
14995 desc_in[3].assign(3, "comp_w", last_in_loc, "last_input_location", 1, "scalar");
14997 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 3, "gvec3");
14998 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 3, "gvec3");
14999 desc_out[2].assign(3, "comp_w", first_out_loc, "first_output_location", 1, "scalar");
15000 desc_out[3].assign(3, "comp_w", last_out_loc, "last_output_location", 1, "scalar");
15004 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 2, "gvec2");
15005 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 2, "gvec2");
15006 desc_in[2].assign(2, "comp_z", first_in_loc, "first_input_location", 2, "gvec2");
15007 desc_in[3].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", 2, "gvec2");
15010 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 2, "gvec2");
15011 desc_out[2].assign(2, "comp_z", first_out_loc, "first_output_location", 2, "gvec2");
15012 desc_out[3].assign(2, "comp_z", last_out_loc, "last_output_location", 2, "gvec2");
15014 case GVEC2_SCALAR_SCALAR:
15016 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 2, "gvec2");
15017 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 2, "gvec2");
15018 desc_in[2].assign(2, "comp_z", first_in_loc, "first_input_location", 1, "scalar");
15019 desc_in[3].assign(2, "comp_z", last_in_loc, "last_input_location", 1, "scalar");
15020 desc_in[4].assign(3, "comp_w", first_in_loc, "first_input_location", 1, "scalar");
15021 desc_in[5].assign(3, "comp_w", last_in_loc, "last_input_location", 1, "scalar");
15023 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 2, "gvec2");
15024 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 2, "gvec2");
15025 desc_out[2].assign(2, "comp_z", first_out_loc, "first_output_location", 1, "scalar");
15026 desc_out[3].assign(2, "comp_z", last_out_loc, "last_output_location", 1, "scalar");
15027 desc_out[4].assign(3, "comp_w", first_out_loc, "first_output_location", 1, "scalar");
15028 desc_out[5].assign(3, "comp_w", last_out_loc, "last_output_location", 1, "scalar");
15030 case SCALAR_GVEC2_SCALAR:
15032 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "scalar");
15033 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "scalar");
15034 desc_in[2].assign(1, "comp_y", first_in_loc, "first_input_location", 2, "gvec2");
15035 desc_in[3].assign(1, "comp_y", last_in_loc, "last_input_location", 2, "gvec2");
15036 desc_in[4].assign(3, "comp_w", first_in_loc, "first_input_location", 1, "scalar");
15037 desc_in[5].assign(3, "comp_w", last_in_loc, "last_input_location", 1, "scalar");
15039 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "scalar");
15040 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "scalar");
15041 desc_out[2].assign(1, "comp_y", first_out_loc, "first_output_location", 2, "gvec2");
15042 desc_out[3].assign(1, "comp_y", last_out_loc, "last_output_location", 2, "gvec2");
15043 desc_out[4].assign(3, "comp_w", first_out_loc, "first_output_location", 1, "scalar");
15044 desc_out[5].assign(3, "comp_w", last_out_loc, "last_output_location", 1, "scalar");
15046 case SCALAR_SCALAR_GVEC2:
15048 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "scalar");
15049 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "scalar");
15050 desc_in[2].assign(1, "comp_y", first_in_loc, "first_input_location", 1, "scalar");
15051 desc_in[3].assign(1, "comp_y", last_in_loc, "last_input_location", 1, "scalar");
15052 desc_in[4].assign(2, "comp_z", first_in_loc, "first_input_location", 2, "gvec2");
15053 desc_in[5].assign(2, "comp_z", last_in_loc, "last_input_location", 2, "gvec2");
15055 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "scalar");
15056 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "scalar");
15057 desc_out[2].assign(1, "comp_y", first_out_loc, "first_output_location", 1, "scalar");
15058 desc_out[3].assign(1, "comp_y", last_out_loc, "last_output_location", 1, "scalar");
15059 desc_out[4].assign(2, "comp_z", first_out_loc, "first_output_location", 2, "gvec2");
15060 desc_out[5].assign(2, "comp_z", last_out_loc, "last_output_location", 2, "gvec2");
15062 case SCALAR_SCALAR_SCALAR_SCALAR:
15064 desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "scalar");
15065 desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "scalar");
15066 desc_in[2].assign(1, "comp_y", first_in_loc, "first_input_location", 1, "scalar");
15067 desc_in[3].assign(1, "comp_y", last_in_loc, "last_input_location", 1, "scalar");
15068 desc_in[4].assign(2, "comp_z", first_in_loc, "first_input_location", 1, "scalar");
15069 desc_in[5].assign(2, "comp_z", last_in_loc, "last_input_location", 1, "scalar");
15070 desc_in[6].assign(3, "comp_w", first_in_loc, "first_input_location", 1, "scalar");
15071 desc_in[7].assign(3, "comp_w", last_in_loc, "last_input_location", 1, "scalar");
15073 desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "scalar");
15074 desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "scalar");
15075 desc_out[2].assign(1, "comp_y", first_out_loc, "first_output_location", 1, "scalar");
15076 desc_out[3].assign(1, "comp_y", last_out_loc, "last_output_location", 1, "scalar");
15077 desc_out[4].assign(2, "comp_z", first_out_loc, "first_output_location", 1, "scalar");
15078 desc_out[5].assign(2, "comp_z", last_out_loc, "last_output_location", 1, "scalar");
15079 desc_out[6].assign(3, "comp_w", first_out_loc, "first_output_location", 1, "scalar");
15080 desc_out[7].assign(3, "comp_w", last_out_loc, "last_output_location", 1, "scalar");
15084 for (GLuint i = 0; i < n_desc; ++i)
15086 const descriptor& in_desc = desc_in[i];
15088 Utils::Variable* in =
15089 prepareVarying(basic_type, in_desc, interpolation, si, stage, Utils::Variable::VARYING_INPUT);
15091 if (Utils::Shader::FRAGMENT != stage)
15093 const descriptor& out_desc = desc_out[i];
15095 Utils::Variable* out =
15096 prepareVarying(basic_type, out_desc, interpolation, si, stage, Utils::Variable::VARYING_OUTPUT);
15098 varying_passthrough.Add(stage, in, out);
15102 si.m_globals = prepareGlobals(last_in_loc, last_out_loc);
15108 Utils::Variable* VaryingComponentsTest::prepareVarying(const Utils::Type& basic_type, const descriptor& desc,
15109 const GLchar* interpolation, Utils::ShaderInterface& si,
15110 Utils::Shader::STAGES stage, Utils::Variable::STORAGE storage)
15112 const GLuint array_length = getArrayLength();
15113 const GLuint component_size = basic_type.GetSize();
15114 const std::string& name = prepareName(desc.m_name, desc.m_location, desc.m_component, stage, storage);
15115 const GLuint offset = desc.m_component * component_size;
15116 const std::string& qual = prepareQualifiers(desc.m_location_str, desc.m_component_str, interpolation);
15117 const GLuint size = desc.m_n_rows * component_size;
15118 const Utils::Type& type = Utils::Type::GetType(basic_type.m_basic_type, 1 /* n_columns */, desc.m_n_rows);
15119 Utils::Variable* var = 0;
15121 if (Utils::Variable::VARYING_INPUT == storage)
15123 var = si.Input(name.c_str(), qual.c_str() /* qualifiers */, desc.m_component /* expected_componenet */,
15124 desc.m_location /* expected_location */, type, /* built_in_type */
15125 GL_FALSE /* normalized */, array_length /* n_array_elements */, 0u /* stride */,
15126 offset /* offset */, (GLvoid*)&m_data[offset] /* data */, size /* data_size */);
15130 var = si.Output(name.c_str(), qual.c_str() /* qualifiers */, desc.m_component /* expected_componenet */,
15131 desc.m_location /* expected_location */, type, /* built_in_type */
15132 GL_FALSE /* normalized */, array_length /* n_array_elements */, 0u /* stride */,
15133 offset /* offset */, (GLvoid*)&m_data[offset] /* data */, size /* data_size */);
15139 void VaryingComponentsTest::descriptor::assign(glw::GLint component, const glw::GLchar* component_str,
15140 glw::GLint location, const glw::GLchar* location_str, glw::GLuint n_rows,
15141 const glw::GLchar* name)
15143 m_component = component;
15144 m_component_str = component_str;
15145 m_location = location;
15146 m_location_str = location_str;
15151 VaryingComponentsTest::testCase::testCase(COMPONENTS_LAYOUT layout, Utils::Type::TYPES type)
15152 : m_layout(layout), m_type(type)
15158 * @param context Test framework context
15160 VaryingArrayComponentsTest::VaryingArrayComponentsTest(deqp::Context& context)
15161 : VaryingComponentsTest(context, "varying_array_components",
15162 "Test verifies that input and output components are respected for arrays")
15166 /** Get length of arrays that should be used during test
15170 GLuint VaryingArrayComponentsTest::getArrayLength()
15177 * @param context Test framework context
15179 VaryingExceedingComponentsTest::VaryingExceedingComponentsTest(deqp::Context& context)
15180 : NegativeTestBase(context, "varying_exceeding_components",
15181 "Test verifies that compiler reports error when component qualifier exceed limits")
15185 /** Source for given test case and stage
15187 * @param test_case_index Index of test case
15188 * @param stage Shader stage
15190 * @return Shader source
15192 std::string VaryingExceedingComponentsTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
15194 static const GLchar* var_definition_arr =
15195 "layout (location = 1, component = COMPONENT) flat DIRECTION TYPE gokuARRAY[1];\n";
15196 static const GLchar* var_definition_one =
15197 "layout (location = 1, component = COMPONENT) flat DIRECTION TYPE gokuARRAY;\n";
15198 static const GLchar* input_use_arr = " if (TYPE(0) == gokuINDEX[0])\n"
15200 " result += vec4(1, 0.5, 0.25, 0.125);\n"
15202 static const GLchar* input_use_one = " if (TYPE(0) == gokuINDEX)\n"
15204 " result += vec4(1, 0.5, 0.25, 0.125);\n"
15206 static const GLchar* output_use_arr = " gokuINDEX[0] = TYPE(0);\n"
15207 " if (vec4(0) == result)\n"
15209 " gokuINDEX[0] = TYPE(1);\n"
15211 static const GLchar* output_use_one = " gokuINDEX = TYPE(0);\n"
15212 " if (vec4(0) == result)\n"
15214 " gokuINDEX = TYPE(1);\n"
15216 static const GLchar* fs = "#version 430 core\n"
15217 "#extension GL_ARB_enhanced_layouts : require\n"
15220 "out vec4 fs_out;\n"
15224 " fs_out = gs_fs;\n"
15227 static const GLchar* fs_tested = "#version 430 core\n"
15228 "#extension GL_ARB_enhanced_layouts : require\n"
15233 "out vec4 fs_out;\n"
15237 " vec4 result = gs_fs;\n"
15241 " fs_out += result;\n"
15244 static const GLchar* gs = "#version 430 core\n"
15245 "#extension GL_ARB_enhanced_layouts : require\n"
15247 "layout(points) in;\n"
15248 "layout(triangle_strip, max_vertices = 4) out;\n"
15250 "in vec4 tes_gs[];\n"
15251 "out vec4 gs_fs;\n"
15255 " gs_fs = tes_gs[0];\n"
15256 " gl_Position = vec4(-1, -1, 0, 1);\n"
15258 " gs_fs = tes_gs[0];\n"
15259 " gl_Position = vec4(-1, 1, 0, 1);\n"
15261 " gs_fs = tes_gs[0];\n"
15262 " gl_Position = vec4(1, -1, 0, 1);\n"
15264 " gs_fs = tes_gs[0];\n"
15265 " gl_Position = vec4(1, 1, 0, 1);\n"
15269 static const GLchar* gs_tested = "#version 430 core\n"
15270 "#extension GL_ARB_enhanced_layouts : require\n"
15272 "layout(points) in;\n"
15273 "layout(triangle_strip, max_vertices = 4) out;\n"
15277 "in vec4 tes_gs[];\n"
15278 "out vec4 gs_fs;\n"
15282 " vec4 result = tes_gs[0];\n"
15286 " gs_fs = result;\n"
15287 " gl_Position = vec4(-1, -1, 0, 1);\n"
15289 " gs_fs = result;\n"
15290 " gl_Position = vec4(-1, 1, 0, 1);\n"
15292 " gs_fs = result;\n"
15293 " gl_Position = vec4(1, -1, 0, 1);\n"
15295 " gs_fs = result;\n"
15296 " gl_Position = vec4(1, 1, 0, 1);\n"
15300 static const GLchar* tcs = "#version 430 core\n"
15301 "#extension GL_ARB_enhanced_layouts : require\n"
15303 "layout(vertices = 1) out;\n"
15305 "in vec4 vs_tcs[];\n"
15306 "out vec4 tcs_tes[];\n"
15311 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
15313 " gl_TessLevelOuter[0] = 1.0;\n"
15314 " gl_TessLevelOuter[1] = 1.0;\n"
15315 " gl_TessLevelOuter[2] = 1.0;\n"
15316 " gl_TessLevelOuter[3] = 1.0;\n"
15317 " gl_TessLevelInner[0] = 1.0;\n"
15318 " gl_TessLevelInner[1] = 1.0;\n"
15321 static const GLchar* tcs_tested = "#version 430 core\n"
15322 "#extension GL_ARB_enhanced_layouts : require\n"
15324 "layout(vertices = 1) out;\n"
15328 "in vec4 vs_tcs[];\n"
15329 "out vec4 tcs_tes[];\n"
15333 " vec4 result = vs_tcs[gl_InvocationID];\n"
15337 " tcs_tes[gl_InvocationID] = result;\n"
15339 " gl_TessLevelOuter[0] = 1.0;\n"
15340 " gl_TessLevelOuter[1] = 1.0;\n"
15341 " gl_TessLevelOuter[2] = 1.0;\n"
15342 " gl_TessLevelOuter[3] = 1.0;\n"
15343 " gl_TessLevelInner[0] = 1.0;\n"
15344 " gl_TessLevelInner[1] = 1.0;\n"
15347 static const GLchar* tes = "#version 430 core\n"
15348 "#extension GL_ARB_enhanced_layouts : require\n"
15350 "layout(isolines, point_mode) in;\n"
15352 "in vec4 tcs_tes[];\n"
15353 "out vec4 tes_gs;\n"
15357 " tes_gs = tcs_tes[0];\n"
15360 static const GLchar* tes_tested = "#version 430 core\n"
15361 "#extension GL_ARB_enhanced_layouts : require\n"
15363 "layout(isolines, point_mode) in;\n"
15367 "in vec4 tcs_tes[];\n"
15368 "out vec4 tes_gs;\n"
15372 " vec4 result = tcs_tes[0];\n"
15376 " tes_gs += result;\n"
15379 static const GLchar* vs = "#version 430 core\n"
15380 "#extension GL_ARB_enhanced_layouts : require\n"
15383 "out vec4 vs_tcs;\n"
15387 " vs_tcs = in_vs;\n"
15390 static const GLchar* vs_tested = "#version 430 core\n"
15391 "#extension GL_ARB_enhanced_layouts : require\n"
15396 "out vec4 vs_tcs;\n"
15400 " vec4 result = in_vs;\n"
15404 " vs_tcs += result;\n"
15408 std::string source;
15409 testCase& test_case = m_test_cases[test_case_index];
15411 if (test_case.m_stage == stage)
15413 const GLchar* array = "";
15415 const GLchar* var_definition = 0;
15416 const GLchar* direction = "in ";
15417 const GLchar* index = "";
15418 size_t position = 0;
15420 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
15421 const GLchar* var_use = 0;
15423 if (false == test_case.m_is_input)
15427 if (false == test_case.m_is_array)
15429 var_definition = var_definition_one;
15430 var_use = output_use_one;
15434 var_definition = var_definition_arr;
15435 var_use = output_use_arr;
15440 if (false == test_case.m_is_array)
15442 var_definition = var_definition_one;
15443 var_use = input_use_one;
15447 var_definition = var_definition_arr;
15448 var_use = input_use_arr;
15452 sprintf(buffer, "%d", test_case.m_component);
15456 case Utils::Shader::FRAGMENT:
15457 source = fs_tested;
15459 case Utils::Shader::GEOMETRY:
15460 source = gs_tested;
15464 case Utils::Shader::TESS_CTRL:
15465 source = tcs_tested;
15467 index = "[gl_InvocationID]";
15469 case Utils::Shader::TESS_EVAL:
15470 source = tes_tested;
15474 case Utils::Shader::VERTEX:
15475 source = vs_tested;
15478 TCU_FAIL("Invalid enum");
15482 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
15484 Utils::replaceToken("COMPONENT", position, buffer, source);
15485 Utils::replaceToken("DIRECTION", position, direction, source);
15486 Utils::replaceToken("ARRAY", position, array, source);
15487 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
15489 Utils::replaceAllTokens("TYPE", type_name, source);
15490 Utils::replaceAllTokens("INDEX", index, source);
15496 case Utils::Shader::FRAGMENT:
15499 case Utils::Shader::GEOMETRY:
15502 case Utils::Shader::TESS_CTRL:
15505 case Utils::Shader::TESS_EVAL:
15508 case Utils::Shader::VERTEX:
15512 TCU_FAIL("Invalid enum");
15519 /** Get description of test case
15521 * @param test_case_index Index of test case
15523 * @return Test case description
15525 std::string VaryingExceedingComponentsTest::getTestCaseName(GLuint test_case_index)
15527 std::stringstream stream;
15528 testCase& test_case = m_test_cases[test_case_index];
15530 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
15531 << " type: " << test_case.m_type.GetGLSLTypeName();
15533 if (true == test_case.m_is_array)
15538 stream << ", direction: ";
15540 if (true == test_case.m_is_input)
15546 stream << "output";
15549 stream << ", component: " << test_case.m_component;
15551 return stream.str();
15554 /** Get number of test cases
15556 * @return Number of test cases
15558 GLuint VaryingExceedingComponentsTest::getTestCaseNumber()
15560 return static_cast<GLuint>(m_test_cases.size());
15563 /** Selects if "compute" stage is relevant for test
15569 bool VaryingExceedingComponentsTest::isComputeRelevant(GLuint /* test_case_index */)
15574 /** Prepare all test cases
15577 void VaryingExceedingComponentsTest::testInit()
15579 static const GLuint n_components_per_location = 4;
15580 const GLuint n_types = getTypesNumber();
15582 for (GLuint i = 0; i < n_types; ++i)
15584 const Utils::Type& type = getType(i);
15585 const GLuint n_req_components = type.m_n_rows;
15586 const GLuint valid_component = n_components_per_location - n_req_components;
15587 const GLuint invalid_component = valid_component + 1;
15589 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
15591 if (Utils::Shader::COMPUTE == stage)
15596 /* Component cannot be used for matrices */
15597 if (1 != type.m_n_columns)
15602 testCase test_case_in_arr = { invalid_component, true, true, (Utils::Shader::STAGES)stage, type };
15603 testCase test_case_in_one = { invalid_component, true, false, (Utils::Shader::STAGES)stage, type };
15604 testCase test_case_out_arr = { invalid_component, false, true, (Utils::Shader::STAGES)stage, type };
15605 testCase test_case_out_one = { invalid_component, false, false, (Utils::Shader::STAGES)stage, type };
15607 m_test_cases.push_back(test_case_in_arr);
15608 m_test_cases.push_back(test_case_in_one);
15610 if (Utils::Shader::FRAGMENT != stage)
15612 m_test_cases.push_back(test_case_out_arr);
15613 m_test_cases.push_back(test_case_out_one);
15621 * @param context Test framework context
15623 VaryingComponentWithoutLocationTest::VaryingComponentWithoutLocationTest(deqp::Context& context)
15624 : NegativeTestBase(context, "varying_component_without_location",
15625 "Test verifies that compiler reports error when component qualifier is used without location")
15629 /** Source for given test case and stage
15631 * @param test_case_index Index of test case
15632 * @param stage Shader stage
15634 * @return Shader source
15636 std::string VaryingComponentWithoutLocationTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
15638 static const GLchar* var_definition = "layout (component = COMPONENT) FLAT DIRECTION TYPE gokuARRAY;\n";
15639 static const GLchar* input_use = " if (TYPE(0) == gokuINDEX)\n"
15641 " result += vec4(1, 0.5, 0.25, 0.125);\n"
15643 static const GLchar* output_use = " gokuINDEX = TYPE(0);\n"
15644 " if (vec4(0) == result)\n"
15646 " gokuINDEX = TYPE(1);\n"
15648 static const GLchar* fs = "#version 430 core\n"
15649 "#extension GL_ARB_enhanced_layouts : require\n"
15652 "out vec4 fs_out;\n"
15656 " fs_out = gs_fs;\n"
15659 static const GLchar* fs_tested = "#version 430 core\n"
15660 "#extension GL_ARB_enhanced_layouts : require\n"
15665 "out vec4 fs_out;\n"
15669 " vec4 result = gs_fs;\n"
15673 " fs_out = result;\n"
15676 static const GLchar* gs = "#version 430 core\n"
15677 "#extension GL_ARB_enhanced_layouts : require\n"
15679 "layout(points) in;\n"
15680 "layout(triangle_strip, max_vertices = 4) out;\n"
15682 "in vec4 tes_gs[];\n"
15683 "out vec4 gs_fs;\n"
15687 " gs_fs = tes_gs[0];\n"
15688 " gl_Position = vec4(-1, -1, 0, 1);\n"
15690 " gs_fs = tes_gs[0];\n"
15691 " gl_Position = vec4(-1, 1, 0, 1);\n"
15693 " gs_fs = tes_gs[0];\n"
15694 " gl_Position = vec4(1, -1, 0, 1);\n"
15696 " gs_fs = tes_gs[0];\n"
15697 " gl_Position = vec4(1, 1, 0, 1);\n"
15701 static const GLchar* gs_tested = "#version 430 core\n"
15702 "#extension GL_ARB_enhanced_layouts : require\n"
15704 "layout(points) in;\n"
15705 "layout(triangle_strip, max_vertices = 4) out;\n"
15709 "in vec4 tes_gs[];\n"
15710 "out vec4 gs_fs;\n"
15714 " vec4 result = tes_gs[0];\n"
15718 " gs_fs = result;\n"
15719 " gl_Position = vec4(-1, -1, 0, 1);\n"
15721 " gs_fs = result;\n"
15722 " gl_Position = vec4(-1, 1, 0, 1);\n"
15724 " gs_fs = result;\n"
15725 " gl_Position = vec4(1, -1, 0, 1);\n"
15727 " gs_fs = result;\n"
15728 " gl_Position = vec4(1, 1, 0, 1);\n"
15732 static const GLchar* tcs = "#version 430 core\n"
15733 "#extension GL_ARB_enhanced_layouts : require\n"
15735 "layout(vertices = 1) out;\n"
15737 "in vec4 vs_tcs[];\n"
15738 "out vec4 tcs_tes[];\n"
15743 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
15745 " gl_TessLevelOuter[0] = 1.0;\n"
15746 " gl_TessLevelOuter[1] = 1.0;\n"
15747 " gl_TessLevelOuter[2] = 1.0;\n"
15748 " gl_TessLevelOuter[3] = 1.0;\n"
15749 " gl_TessLevelInner[0] = 1.0;\n"
15750 " gl_TessLevelInner[1] = 1.0;\n"
15753 static const GLchar* tcs_tested = "#version 430 core\n"
15754 "#extension GL_ARB_enhanced_layouts : require\n"
15756 "layout(vertices = 1) out;\n"
15760 "in vec4 vs_tcs[];\n"
15761 "out vec4 tcs_tes[];\n"
15765 " vec4 result = vs_tcs[gl_InvocationID];\n"
15769 " tcs_tes[gl_InvocationID] = result;\n"
15771 " gl_TessLevelOuter[0] = 1.0;\n"
15772 " gl_TessLevelOuter[1] = 1.0;\n"
15773 " gl_TessLevelOuter[2] = 1.0;\n"
15774 " gl_TessLevelOuter[3] = 1.0;\n"
15775 " gl_TessLevelInner[0] = 1.0;\n"
15776 " gl_TessLevelInner[1] = 1.0;\n"
15779 static const GLchar* tes = "#version 430 core\n"
15780 "#extension GL_ARB_enhanced_layouts : require\n"
15782 "layout(isolines, point_mode) in;\n"
15784 "in vec4 tcs_tes[];\n"
15785 "out vec4 tes_gs;\n"
15789 " tes_gs = tcs_tes[0];\n"
15792 static const GLchar* tes_tested = "#version 430 core\n"
15793 "#extension GL_ARB_enhanced_layouts : require\n"
15795 "layout(isolines, point_mode) in;\n"
15799 "in vec4 tcs_tes[];\n"
15800 "out vec4 tes_gs;\n"
15804 " vec4 result = tcs_tes[0];\n"
15808 " tes_gs = result;\n"
15811 static const GLchar* vs = "#version 430 core\n"
15812 "#extension GL_ARB_enhanced_layouts : require\n"
15815 "out vec4 vs_tcs;\n"
15819 " vs_tcs = in_vs;\n"
15822 static const GLchar* vs_tested = "#version 430 core\n"
15823 "#extension GL_ARB_enhanced_layouts : require\n"
15828 "out vec4 vs_tcs;\n"
15832 " vec4 result = in_vs;\n"
15836 " vs_tcs = result;\n"
15840 std::string source;
15841 testCase& test_case = m_test_cases[test_case_index];
15843 if (test_case.m_stage == stage)
15845 const GLchar* array = "";
15847 const GLchar* direction = "in ";
15848 const GLchar* index = "";
15849 size_t position = 0;
15851 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
15852 const GLchar* var_use = input_use;
15853 const GLchar* flat = "flat";
15855 if (false == test_case.m_is_input)
15858 var_use = output_use;
15861 sprintf(buffer, "%d", test_case.m_component);
15865 case Utils::Shader::FRAGMENT:
15866 source = fs_tested;
15868 case Utils::Shader::GEOMETRY:
15869 source = gs_tested;
15873 case Utils::Shader::TESS_CTRL:
15874 source = tcs_tested;
15876 index = "[gl_InvocationID]";
15878 case Utils::Shader::TESS_EVAL:
15879 source = tes_tested;
15883 case Utils::Shader::VERTEX:
15884 source = vs_tested;
15888 TCU_FAIL("Invalid enum");
15892 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
15894 Utils::replaceToken("COMPONENT", position, buffer, source);
15895 Utils::replaceToken("FLAT", position, flat, source);
15896 Utils::replaceToken("DIRECTION", position, direction, source);
15897 Utils::replaceToken("ARRAY", position, array, source);
15898 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
15900 Utils::replaceAllTokens("TYPE", type_name, source);
15901 Utils::replaceAllTokens("INDEX", index, source);
15907 case Utils::Shader::FRAGMENT:
15910 case Utils::Shader::GEOMETRY:
15913 case Utils::Shader::TESS_CTRL:
15916 case Utils::Shader::TESS_EVAL:
15919 case Utils::Shader::VERTEX:
15923 TCU_FAIL("Invalid enum");
15930 /** Get description of test case
15932 * @param test_case_index Index of test case
15934 * @return Test case description
15936 std::string VaryingComponentWithoutLocationTest::getTestCaseName(GLuint test_case_index)
15938 std::stringstream stream;
15939 testCase& test_case = m_test_cases[test_case_index];
15941 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
15942 << " type: " << test_case.m_type.GetGLSLTypeName() << ", direction: ";
15944 if (true == test_case.m_is_input)
15950 stream << "output";
15953 stream << ", component: " << test_case.m_component;
15955 return stream.str();
15958 /** Get number of test cases
15960 * @return Number of test cases
15962 GLuint VaryingComponentWithoutLocationTest::getTestCaseNumber()
15964 return static_cast<GLuint>(m_test_cases.size());
15967 /** Selects if "compute" stage is relevant for test
15973 bool VaryingComponentWithoutLocationTest::isComputeRelevant(GLuint /* test_case_index */)
15978 /** Prepare all test cases
15981 void VaryingComponentWithoutLocationTest::testInit()
15983 static const GLuint n_components_per_location = 4;
15984 const GLuint n_types = getTypesNumber();
15986 for (GLuint i = 0; i < n_types; ++i)
15988 const Utils::Type& type = getType(i);
15989 const GLuint n_req_components = type.m_n_rows;
15990 const GLuint valid_component = n_components_per_location - n_req_components;
15992 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
15994 if (Utils::Shader::COMPUTE == stage)
15999 /* Component cannot be used for matrices */
16000 if (1 != type.m_n_columns)
16005 testCase test_case_in = { valid_component, true, (Utils::Shader::STAGES)stage, type };
16006 testCase test_case_out = { valid_component, false, (Utils::Shader::STAGES)stage, type };
16008 m_test_cases.push_back(test_case_in);
16010 if (Utils::Shader::FRAGMENT != stage)
16012 m_test_cases.push_back(test_case_out);
16020 * @param context Test framework context
16022 VaryingComponentOfInvalidTypeTest::VaryingComponentOfInvalidTypeTest(deqp::Context& context)
16023 : NegativeTestBase(context, "varying_component_of_invalid_type",
16024 "Test verifies that compiler reports error when component qualifier is used for invalid type")
16028 /** Source for given test case and stage
16030 * @param test_case_index Index of test case
16031 * @param stage Shader stage
16033 * @return Shader source
16035 std::string VaryingComponentOfInvalidTypeTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
16037 static const GLchar* block_definition_arr = "layout (location = 1, component = COMPONENT) flat DIRECTION Goku {\n"
16039 "} gokuARRAY[1];\n";
16040 static const GLchar* block_definition_one = "layout (location = 1, component = COMPONENT) flat DIRECTION Goku {\n"
16043 static const GLchar* matrix_definition_arr =
16044 "layout (location = 1, component = COMPONENT) flat DIRECTION TYPE gokuARRAY[1];\n";
16045 static const GLchar* matrix_definition_one =
16046 "layout (location = 1, component = COMPONENT) flat DIRECTION TYPE gokuARRAY;\n";
16047 static const GLchar* struct_definition_arr =
16052 "layout (location = 1, component = COMPONENT) flat DIRECTION Goku gokuARRAY[1];\n";
16053 static const GLchar* struct_definition_one =
16058 "layout (location = 1, component = COMPONENT) flat DIRECTION Goku gokuARRAY;\n";
16059 static const GLchar* matrix_input_use_arr = " if (TYPE(0) == gokuINDEX[0])\n"
16061 " result += vec4(1, 0.5, 0.25, 0.125);\n"
16063 static const GLchar* matrix_input_use_one = " if (TYPE(0) == gokuINDEX)\n"
16065 " result += vec4(1, 0.5, 0.25, 0.125);\n"
16067 static const GLchar* matrix_output_use_arr = " gokuINDEX[0] = TYPE(0);\n"
16068 " if (vec4(0) == result)\n"
16070 " gokuINDEX[0] = TYPE(1);\n"
16072 static const GLchar* matrix_output_use_one = " gokuINDEX = TYPE(0);\n"
16073 " if (vec4(0) == result)\n"
16075 " gokuINDEX = TYPE(1);\n"
16077 static const GLchar* member_input_use_arr = " if (TYPE(0) == gokuINDEX[0].member)\n"
16079 " result += vec4(1, 0.5, 0.25, 0.125);\n"
16081 static const GLchar* member_input_use_one = " if (TYPE(0) == gokuINDEX.member)\n"
16083 " result += vec4(1, 0.5, 0.25, 0.125);\n"
16085 static const GLchar* member_output_use_arr = " gokuINDEX[0].member = TYPE(0);\n"
16086 " if (vec4(0) == result)\n"
16088 " gokuINDEX[0].member = TYPE(1);\n"
16090 static const GLchar* member_output_use_one = " gokuINDEX.member = TYPE(0);\n"
16091 " if (vec4(0) == result)\n"
16093 " gokuINDEX.member = TYPE(1);\n"
16095 static const GLchar* fs = "#version 430 core\n"
16096 "#extension GL_ARB_enhanced_layouts : require\n"
16099 "out vec4 fs_out;\n"
16103 " fs_out = gs_fs;\n"
16106 static const GLchar* fs_tested = "#version 430 core\n"
16107 "#extension GL_ARB_enhanced_layouts : require\n"
16112 "out vec4 fs_out;\n"
16116 " vec4 result = gs_fs;\n"
16120 " fs_out += result;\n"
16123 static const GLchar* gs = "#version 430 core\n"
16124 "#extension GL_ARB_enhanced_layouts : require\n"
16126 "layout(points) in;\n"
16127 "layout(triangle_strip, max_vertices = 4) out;\n"
16129 "in vec4 tes_gs[];\n"
16130 "out vec4 gs_fs;\n"
16134 " gs_fs = tes_gs[0];\n"
16135 " gl_Position = vec4(-1, -1, 0, 1);\n"
16137 " gs_fs = tes_gs[0];\n"
16138 " gl_Position = vec4(-1, 1, 0, 1);\n"
16140 " gs_fs = tes_gs[0];\n"
16141 " gl_Position = vec4(1, -1, 0, 1);\n"
16143 " gs_fs = tes_gs[0];\n"
16144 " gl_Position = vec4(1, 1, 0, 1);\n"
16148 static const GLchar* gs_tested = "#version 430 core\n"
16149 "#extension GL_ARB_enhanced_layouts : require\n"
16151 "layout(points) in;\n"
16152 "layout(triangle_strip, max_vertices = 4) out;\n"
16156 "in vec4 tes_gs[];\n"
16157 "out vec4 gs_fs;\n"
16161 " vec4 result = tes_gs[0];\n"
16165 " gs_fs = result;\n"
16166 " gl_Position = vec4(-1, -1, 0, 1);\n"
16168 " gs_fs = result;\n"
16169 " gl_Position = vec4(-1, 1, 0, 1);\n"
16171 " gs_fs = result;\n"
16172 " gl_Position = vec4(1, -1, 0, 1);\n"
16174 " gs_fs = result;\n"
16175 " gl_Position = vec4(1, 1, 0, 1);\n"
16179 static const GLchar* tcs = "#version 430 core\n"
16180 "#extension GL_ARB_enhanced_layouts : require\n"
16182 "layout(vertices = 1) out;\n"
16184 "in vec4 vs_tcs[];\n"
16185 "out vec4 tcs_tes[];\n"
16190 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
16192 " gl_TessLevelOuter[0] = 1.0;\n"
16193 " gl_TessLevelOuter[1] = 1.0;\n"
16194 " gl_TessLevelOuter[2] = 1.0;\n"
16195 " gl_TessLevelOuter[3] = 1.0;\n"
16196 " gl_TessLevelInner[0] = 1.0;\n"
16197 " gl_TessLevelInner[1] = 1.0;\n"
16200 static const GLchar* tcs_tested = "#version 430 core\n"
16201 "#extension GL_ARB_enhanced_layouts : require\n"
16203 "layout(vertices = 1) out;\n"
16207 "in vec4 vs_tcs[];\n"
16208 "out vec4 tcs_tes[];\n"
16212 " vec4 result = vs_tcs[gl_InvocationID];\n"
16216 " tcs_tes[gl_InvocationID] = result;\n"
16218 " gl_TessLevelOuter[0] = 1.0;\n"
16219 " gl_TessLevelOuter[1] = 1.0;\n"
16220 " gl_TessLevelOuter[2] = 1.0;\n"
16221 " gl_TessLevelOuter[3] = 1.0;\n"
16222 " gl_TessLevelInner[0] = 1.0;\n"
16223 " gl_TessLevelInner[1] = 1.0;\n"
16226 static const GLchar* tes = "#version 430 core\n"
16227 "#extension GL_ARB_enhanced_layouts : require\n"
16229 "layout(isolines, point_mode) in;\n"
16231 "in vec4 tcs_tes[];\n"
16232 "out vec4 tes_gs;\n"
16236 " tes_gs = tcs_tes[0];\n"
16239 static const GLchar* tes_tested = "#version 430 core\n"
16240 "#extension GL_ARB_enhanced_layouts : require\n"
16242 "layout(isolines, point_mode) in;\n"
16246 "in vec4 tcs_tes[];\n"
16247 "out vec4 tes_gs;\n"
16251 " vec4 result = tcs_tes[0];\n"
16255 " tes_gs += result;\n"
16258 static const GLchar* vs = "#version 430 core\n"
16259 "#extension GL_ARB_enhanced_layouts : require\n"
16262 "out vec4 vs_tcs;\n"
16266 " vs_tcs = in_vs;\n"
16269 static const GLchar* vs_tested = "#version 430 core\n"
16270 "#extension GL_ARB_enhanced_layouts : require\n"
16275 "out vec4 vs_tcs;\n"
16279 " vec4 result = in_vs;\n"
16283 " vs_tcs += result;\n"
16287 std::string source;
16288 testCase& test_case = m_test_cases[test_case_index];
16290 if (test_case.m_stage == stage)
16292 const GLchar* array = "";
16294 const GLchar* var_definition = 0;
16295 const GLchar* direction = "in ";
16296 const GLchar* index = "";
16297 size_t position = 0;
16299 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
16300 const GLchar* var_use = 0;
16302 if (false == test_case.m_is_input)
16306 if (false == test_case.m_is_array)
16308 switch (test_case.m_case)
16311 var_definition = block_definition_one;
16312 var_use = member_output_use_one;
16315 var_definition = matrix_definition_one;
16316 var_use = matrix_output_use_one;
16319 var_definition = struct_definition_one;
16320 var_use = member_output_use_one;
16323 TCU_FAIL("Invalid enum");
16328 switch (test_case.m_case)
16331 var_definition = block_definition_arr;
16332 var_use = member_output_use_arr;
16335 var_definition = matrix_definition_arr;
16336 var_use = matrix_output_use_arr;
16339 var_definition = struct_definition_arr;
16340 var_use = member_output_use_arr;
16343 TCU_FAIL("Invalid enum");
16349 if (false == test_case.m_is_array)
16351 switch (test_case.m_case)
16354 var_definition = block_definition_one;
16355 var_use = member_input_use_one;
16358 var_definition = matrix_definition_one;
16359 var_use = matrix_input_use_one;
16362 var_definition = struct_definition_one;
16363 var_use = member_input_use_one;
16366 TCU_FAIL("Invalid enum");
16371 switch (test_case.m_case)
16374 var_definition = block_definition_arr;
16375 var_use = member_input_use_arr;
16378 var_definition = matrix_definition_arr;
16379 var_use = matrix_input_use_arr;
16382 var_definition = struct_definition_arr;
16383 var_use = member_input_use_arr;
16386 TCU_FAIL("Invalid enum");
16391 sprintf(buffer, "%d", test_case.m_component);
16395 case Utils::Shader::FRAGMENT:
16396 source = fs_tested;
16398 case Utils::Shader::GEOMETRY:
16399 source = gs_tested;
16403 case Utils::Shader::TESS_CTRL:
16404 source = tcs_tested;
16406 index = "[gl_InvocationID]";
16408 case Utils::Shader::TESS_EVAL:
16409 source = tes_tested;
16413 case Utils::Shader::VERTEX:
16414 source = vs_tested;
16417 TCU_FAIL("Invalid enum");
16421 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
16423 Utils::replaceToken("COMPONENT", position, buffer, source);
16424 Utils::replaceToken("DIRECTION", position, direction, source);
16425 Utils::replaceToken("ARRAY", position, array, source);
16426 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
16428 Utils::replaceAllTokens("TYPE", type_name, source);
16429 Utils::replaceAllTokens("INDEX", index, source);
16435 case Utils::Shader::FRAGMENT:
16438 case Utils::Shader::GEOMETRY:
16441 case Utils::Shader::TESS_CTRL:
16444 case Utils::Shader::TESS_EVAL:
16447 case Utils::Shader::VERTEX:
16451 TCU_FAIL("Invalid enum");
16458 /** Get description of test case
16460 * @param test_case_index Index of test case
16462 * @return Test case description
16464 std::string VaryingComponentOfInvalidTypeTest::getTestCaseName(GLuint test_case_index)
16466 std::stringstream stream;
16467 testCase& test_case = m_test_cases[test_case_index];
16469 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
16470 << " type: " << test_case.m_type.GetGLSLTypeName();
16472 if (true == test_case.m_is_array)
16477 stream << ", direction: ";
16479 if (true == test_case.m_is_input)
16485 stream << "output";
16488 stream << ", component: " << test_case.m_component;
16490 return stream.str();
16493 /** Get number of test cases
16495 * @return Number of test cases
16497 GLuint VaryingComponentOfInvalidTypeTest::getTestCaseNumber()
16499 return static_cast<GLuint>(m_test_cases.size());
16502 /** Selects if "compute" stage is relevant for test
16508 bool VaryingComponentOfInvalidTypeTest::isComputeRelevant(GLuint /* test_case_index */)
16513 /** Prepare all test cases
16516 void VaryingComponentOfInvalidTypeTest::testInit()
16518 static const GLuint n_components_per_location = 4;
16519 const GLuint n_types = getTypesNumber();
16521 for (GLuint i = 0; i < n_types; ++i)
16523 const Utils::Type& type = getType(i);
16524 const GLuint n_req_components = type.m_n_rows;
16525 const GLuint valid_component = n_components_per_location - n_req_components;
16527 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
16529 if (Utils::Shader::COMPUTE == stage)
16534 /* Use different CASE for matrices */
16535 if (1 != type.m_n_columns)
16537 testCase test_case_in_arr = { MATRIX, valid_component, true, true, (Utils::Shader::STAGES)stage, type };
16538 testCase test_case_in_one = {
16539 MATRIX, valid_component, false, true, (Utils::Shader::STAGES)stage, type
16541 testCase test_case_out_arr = {
16542 MATRIX, valid_component, true, false, (Utils::Shader::STAGES)stage, type
16544 testCase test_case_out_one = {
16545 MATRIX, valid_component, false, false, (Utils::Shader::STAGES)stage, type
16548 m_test_cases.push_back(test_case_in_arr);
16549 m_test_cases.push_back(test_case_in_one);
16551 if (Utils::Shader::FRAGMENT != stage)
16553 m_test_cases.push_back(test_case_out_arr);
16554 m_test_cases.push_back(test_case_out_one);
16559 for (GLuint c = BLOCK; c < MAX_CASES; ++c)
16561 testCase test_case_in_arr = { (CASES)c, valid_component, true, true, (Utils::Shader::STAGES)stage,
16563 testCase test_case_in_one = { (CASES)c, valid_component, false, true, (Utils::Shader::STAGES)stage,
16565 testCase test_case_out_arr = { (CASES)c, valid_component, true, false, (Utils::Shader::STAGES)stage,
16567 testCase test_case_out_one = {
16568 (CASES)c, valid_component, false, false, (Utils::Shader::STAGES)stage, type
16571 if (Utils::Shader::VERTEX != stage)
16573 m_test_cases.push_back(test_case_in_arr);
16574 m_test_cases.push_back(test_case_in_one);
16577 if (Utils::Shader::FRAGMENT != stage)
16579 m_test_cases.push_back(test_case_out_arr);
16580 m_test_cases.push_back(test_case_out_one);
16590 * @param context Test framework context
16592 InputComponentAliasingTest::InputComponentAliasingTest(deqp::Context& context)
16593 : NegativeTestBase(context, "input_component_aliasing",
16594 "Test verifies that compiler reports component aliasing as error")
16598 /** Source for given test case and stage
16600 * @param test_case_index Index of test case
16601 * @param stage Shader stage
16603 * @return Shader source
16605 std::string InputComponentAliasingTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
16607 static const GLchar* var_definition = "layout (location = 1, component = COMPONENT) FLAT in TYPE gohanARRAY;\n"
16608 "layout (location = 1, component = COMPONENT) FLAT in TYPE gotenARRAY;\n";
16609 static const GLchar* test_one = " if (TYPE(0) == gohanINDEX)\n"
16611 " result += vec4(1, 0.5, 0.25, 0.125);\n"
16613 static const GLchar* fs = "#version 430 core\n"
16614 "#extension GL_ARB_enhanced_layouts : require\n"
16617 "out vec4 fs_out;\n"
16621 " fs_out = gs_fs;\n"
16624 static const GLchar* fs_tested = "#version 430 core\n"
16625 "#extension GL_ARB_enhanced_layouts : require\n"
16630 "out vec4 fs_out;\n"
16634 " vec4 result = gs_fs;\n"
16638 " fs_out += result;\n"
16641 static const GLchar* gs = "#version 430 core\n"
16642 "#extension GL_ARB_enhanced_layouts : require\n"
16644 "layout(points) in;\n"
16645 "layout(triangle_strip, max_vertices = 4) out;\n"
16647 "in vec4 tes_gs[];\n"
16648 "out vec4 gs_fs;\n"
16652 " gs_fs = tes_gs[0];\n"
16653 " gl_Position = vec4(-1, -1, 0, 1);\n"
16655 " gs_fs = tes_gs[0];\n"
16656 " gl_Position = vec4(-1, 1, 0, 1);\n"
16658 " gs_fs = tes_gs[0];\n"
16659 " gl_Position = vec4(1, -1, 0, 1);\n"
16661 " gs_fs = tes_gs[0];\n"
16662 " gl_Position = vec4(1, 1, 0, 1);\n"
16666 static const GLchar* gs_tested = "#version 430 core\n"
16667 "#extension GL_ARB_enhanced_layouts : require\n"
16669 "layout(points) in;\n"
16670 "layout(triangle_strip, max_vertices = 4) out;\n"
16674 "in vec4 tes_gs[];\n"
16675 "out vec4 gs_fs;\n"
16679 " vec4 result = tes_gs[0];\n"
16683 " gs_fs = result;\n"
16684 " gl_Position = vec4(-1, -1, 0, 1);\n"
16686 " gs_fs = result;\n"
16687 " gl_Position = vec4(-1, 1, 0, 1);\n"
16689 " gs_fs = result;\n"
16690 " gl_Position = vec4(1, -1, 0, 1);\n"
16692 " gs_fs = result;\n"
16693 " gl_Position = vec4(1, 1, 0, 1);\n"
16697 static const GLchar* tcs = "#version 430 core\n"
16698 "#extension GL_ARB_enhanced_layouts : require\n"
16700 "layout(vertices = 1) out;\n"
16702 "in vec4 vs_tcs[];\n"
16703 "out vec4 tcs_tes[];\n"
16708 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
16710 " gl_TessLevelOuter[0] = 1.0;\n"
16711 " gl_TessLevelOuter[1] = 1.0;\n"
16712 " gl_TessLevelOuter[2] = 1.0;\n"
16713 " gl_TessLevelOuter[3] = 1.0;\n"
16714 " gl_TessLevelInner[0] = 1.0;\n"
16715 " gl_TessLevelInner[1] = 1.0;\n"
16718 static const GLchar* tcs_tested = "#version 430 core\n"
16719 "#extension GL_ARB_enhanced_layouts : require\n"
16721 "layout(vertices = 1) out;\n"
16725 "in vec4 vs_tcs[];\n"
16726 "out vec4 tcs_tes[];\n"
16730 " vec4 result = vs_tcs[gl_InvocationID];\n"
16734 " tcs_tes[gl_InvocationID] = result;\n"
16736 " gl_TessLevelOuter[0] = 1.0;\n"
16737 " gl_TessLevelOuter[1] = 1.0;\n"
16738 " gl_TessLevelOuter[2] = 1.0;\n"
16739 " gl_TessLevelOuter[3] = 1.0;\n"
16740 " gl_TessLevelInner[0] = 1.0;\n"
16741 " gl_TessLevelInner[1] = 1.0;\n"
16744 static const GLchar* tes = "#version 430 core\n"
16745 "#extension GL_ARB_enhanced_layouts : require\n"
16747 "layout(isolines, point_mode) in;\n"
16749 "in vec4 tcs_tes[];\n"
16750 "out vec4 tes_gs;\n"
16754 " tes_gs = tcs_tes[0];\n"
16757 static const GLchar* tes_tested = "#version 430 core\n"
16758 "#extension GL_ARB_enhanced_layouts : require\n"
16760 "layout(isolines, point_mode) in;\n"
16764 "in vec4 tcs_tes[];\n"
16765 "out vec4 tes_gs;\n"
16769 " vec4 result = tcs_tes[0];\n"
16773 " tes_gs += result;\n"
16776 static const GLchar* vs = "#version 430 core\n"
16777 "#extension GL_ARB_enhanced_layouts : require\n"
16780 "out vec4 vs_tcs;\n"
16784 " vs_tcs = in_vs;\n"
16787 static const GLchar* vs_tested = "#version 430 core\n"
16788 "#extension GL_ARB_enhanced_layouts : require\n"
16793 "out vec4 vs_tcs;\n"
16797 " vec4 result = in_vs;\n"
16801 " vs_tcs += result;\n"
16805 std::string source;
16806 testCase& test_case = m_test_cases[test_case_index];
16808 if (test_case.m_stage == stage)
16810 const GLchar* array = "";
16811 GLchar buffer_gohan[16];
16812 GLchar buffer_goten[16];
16813 const GLchar* flat = "";
16814 const GLchar* index = "";
16815 const bool is_flat_req = isFlatRequired(stage, test_case.m_type, Utils::Variable::VARYING_INPUT);
16816 size_t position = 0;
16818 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
16819 const GLchar* var_use = test_one;
16821 if (true == is_flat_req)
16826 sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
16827 sprintf(buffer_goten, "%d", test_case.m_component_goten);
16831 case Utils::Shader::FRAGMENT:
16832 source = fs_tested;
16834 case Utils::Shader::GEOMETRY:
16835 source = gs_tested;
16839 case Utils::Shader::TESS_CTRL:
16840 source = tcs_tested;
16842 index = "[gl_InvocationID]";
16844 case Utils::Shader::TESS_EVAL:
16845 source = tes_tested;
16849 case Utils::Shader::VERTEX:
16850 source = vs_tested;
16853 TCU_FAIL("Invalid enum");
16857 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
16859 Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
16860 Utils::replaceToken("ARRAY", position, array, source);
16861 Utils::replaceToken("COMPONENT", position, buffer_goten, source);
16862 Utils::replaceToken("ARRAY", position, array, source);
16863 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
16865 Utils::replaceAllTokens("FLAT", flat, source);
16866 Utils::replaceAllTokens("TYPE", type_name, source);
16867 Utils::replaceAllTokens("INDEX", index, source);
16873 case Utils::Shader::FRAGMENT:
16876 case Utils::Shader::GEOMETRY:
16879 case Utils::Shader::TESS_CTRL:
16882 case Utils::Shader::TESS_EVAL:
16885 case Utils::Shader::VERTEX:
16889 TCU_FAIL("Invalid enum");
16896 /** Get description of test case
16898 * @param test_case_index Index of test case
16900 * @return Test case description
16902 std::string InputComponentAliasingTest::getTestCaseName(GLuint test_case_index)
16904 std::stringstream stream;
16905 testCase& test_case = m_test_cases[test_case_index];
16907 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
16908 << " type: " << test_case.m_type.GetGLSLTypeName() << ", components: " << test_case.m_component_gohan
16909 << " & " << test_case.m_component_goten;
16911 return stream.str();
16914 /** Get number of test cases
16916 * @return Number of test cases
16918 GLuint InputComponentAliasingTest::getTestCaseNumber()
16920 return static_cast<GLuint>(m_test_cases.size());
16923 /** Selects if "compute" stage is relevant for test
16929 bool InputComponentAliasingTest::isComputeRelevant(GLuint /* test_case_index */)
16934 /** Selects if compilation failure is expected result
16936 * @param test_case_index Index of test case
16938 * @return false for VS that use only single variable, true otherwise
16940 bool InputComponentAliasingTest::isFailureExpected(GLuint test_case_index)
16942 testCase& test_case = m_test_cases[test_case_index];
16944 return (Utils::Shader::VERTEX != test_case.m_stage);
16947 /** Prepare all test cases
16950 void InputComponentAliasingTest::testInit()
16952 const GLuint n_types = getTypesNumber();
16954 for (GLuint i = 0; i < n_types; ++i)
16956 const Utils::Type& type = getType(i);
16957 const bool use_double = (Utils::Type::Double == type.m_basic_type);
16958 const GLuint n_components_per_location = use_double ? 2 : 4;
16959 const GLuint n_req_components = type.m_n_rows;
16960 const GLint valid_component = (GLint)n_components_per_location - (GLint)n_req_components;
16961 const GLuint component_size = use_double ? 2 : 1;
16962 /* Skip matrices */
16963 if (1 != type.m_n_columns)
16967 /* Skip dvec3/dvec4 which doesn't support the component qualifier */
16968 if (valid_component < 0)
16973 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
16975 if (Utils::Shader::COMPUTE == stage)
16980 for (GLuint gohan = 0; gohan <= (GLuint)valid_component; ++gohan)
16982 const GLint first_aliasing = gohan - n_req_components + 1;
16983 const GLint last_aliasing = gohan + n_req_components - 1;
16985 const GLuint goten_start = std::max(0, first_aliasing);
16986 const GLuint goten_stop = std::min(valid_component, last_aliasing);
16988 for (GLuint goten = goten_start; goten <= goten_stop; ++goten)
16990 testCase test_case = { gohan * component_size, goten * component_size, (Utils::Shader::STAGES)stage,
16993 m_test_cases.push_back(test_case);
17002 * @param context Test framework context
17004 OutputComponentAliasingTest::OutputComponentAliasingTest(deqp::Context& context)
17005 : NegativeTestBase(context, "output_component_aliasing",
17006 "Test verifies that compiler reports component aliasing as error")
17010 /** Source for given test case and stage
17012 * @param test_case_index Index of test case
17013 * @param stage Shader stage
17015 * @return Shader source
17017 std::string OutputComponentAliasingTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
17019 static const GLchar* var_definition = "layout (location = 1, component = COMPONENT) flat out TYPE gohanARRAY;\n"
17020 "layout (location = 1, component = COMPONENT) flat out TYPE gotenARRAY;\n";
17021 static const GLchar* l_test = " gohanINDEX = TYPE(1);\n"
17022 " gotenINDEX = TYPE(0);\n";
17023 static const GLchar* fs = "#version 430 core\n"
17024 "#extension GL_ARB_enhanced_layouts : require\n"
17027 "out vec4 fs_out;\n"
17031 " fs_out = gs_fs;\n"
17034 static const GLchar* fs_tested = "#version 430 core\n"
17035 "#extension GL_ARB_enhanced_layouts : require\n"
17040 "out vec4 fs_out;\n"
17044 " vec4 result = gs_fs;\n"
17048 " fs_out += result;\n"
17051 static const GLchar* gs = "#version 430 core\n"
17052 "#extension GL_ARB_enhanced_layouts : require\n"
17054 "layout(points) in;\n"
17055 "layout(triangle_strip, max_vertices = 4) out;\n"
17057 "in vec4 tes_gs[];\n"
17058 "out vec4 gs_fs;\n"
17062 " gs_fs = tes_gs[0];\n"
17063 " gl_Position = vec4(-1, -1, 0, 1);\n"
17065 " gs_fs = tes_gs[0];\n"
17066 " gl_Position = vec4(-1, 1, 0, 1);\n"
17068 " gs_fs = tes_gs[0];\n"
17069 " gl_Position = vec4(1, -1, 0, 1);\n"
17071 " gs_fs = tes_gs[0];\n"
17072 " gl_Position = vec4(1, 1, 0, 1);\n"
17076 static const GLchar* gs_tested = "#version 430 core\n"
17077 "#extension GL_ARB_enhanced_layouts : require\n"
17079 "layout(points) in;\n"
17080 "layout(triangle_strip, max_vertices = 4) out;\n"
17084 "in vec4 tes_gs[];\n"
17085 "out vec4 gs_fs;\n"
17089 " vec4 result = tes_gs[0];\n"
17093 " gs_fs = result;\n"
17094 " gl_Position = vec4(-1, -1, 0, 1);\n"
17096 " gs_fs = result;\n"
17097 " gl_Position = vec4(-1, 1, 0, 1);\n"
17099 " gs_fs = result;\n"
17100 " gl_Position = vec4(1, -1, 0, 1);\n"
17102 " gs_fs = result;\n"
17103 " gl_Position = vec4(1, 1, 0, 1);\n"
17107 static const GLchar* tcs = "#version 430 core\n"
17108 "#extension GL_ARB_enhanced_layouts : require\n"
17110 "layout(vertices = 1) out;\n"
17112 "in vec4 vs_tcs[];\n"
17113 "out vec4 tcs_tes[];\n"
17118 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
17120 " gl_TessLevelOuter[0] = 1.0;\n"
17121 " gl_TessLevelOuter[1] = 1.0;\n"
17122 " gl_TessLevelOuter[2] = 1.0;\n"
17123 " gl_TessLevelOuter[3] = 1.0;\n"
17124 " gl_TessLevelInner[0] = 1.0;\n"
17125 " gl_TessLevelInner[1] = 1.0;\n"
17128 static const GLchar* tcs_tested = "#version 430 core\n"
17129 "#extension GL_ARB_enhanced_layouts : require\n"
17131 "layout(vertices = 1) out;\n"
17135 "in vec4 vs_tcs[];\n"
17136 "out vec4 tcs_tes[];\n"
17140 " vec4 result = vs_tcs[gl_InvocationID];\n"
17144 " tcs_tes[gl_InvocationID] = result;\n"
17146 " gl_TessLevelOuter[0] = 1.0;\n"
17147 " gl_TessLevelOuter[1] = 1.0;\n"
17148 " gl_TessLevelOuter[2] = 1.0;\n"
17149 " gl_TessLevelOuter[3] = 1.0;\n"
17150 " gl_TessLevelInner[0] = 1.0;\n"
17151 " gl_TessLevelInner[1] = 1.0;\n"
17154 static const GLchar* tes = "#version 430 core\n"
17155 "#extension GL_ARB_enhanced_layouts : require\n"
17157 "layout(isolines, point_mode) in;\n"
17159 "in vec4 tcs_tes[];\n"
17160 "out vec4 tes_gs;\n"
17164 " tes_gs = tcs_tes[0];\n"
17167 static const GLchar* tes_tested = "#version 430 core\n"
17168 "#extension GL_ARB_enhanced_layouts : require\n"
17170 "layout(isolines, point_mode) in;\n"
17174 "in vec4 tcs_tes[];\n"
17175 "out vec4 tes_gs;\n"
17179 " vec4 result = tcs_tes[0];\n"
17183 " tes_gs += result;\n"
17186 static const GLchar* vs = "#version 430 core\n"
17187 "#extension GL_ARB_enhanced_layouts : require\n"
17190 "out vec4 vs_tcs;\n"
17194 " vs_tcs = in_vs;\n"
17197 static const GLchar* vs_tested = "#version 430 core\n"
17198 "#extension GL_ARB_enhanced_layouts : require\n"
17203 "out vec4 vs_tcs;\n"
17207 " vec4 result = in_vs;\n"
17211 " vs_tcs += result;\n"
17215 std::string source;
17216 testCase& test_case = m_test_cases[test_case_index];
17218 if (test_case.m_stage == stage)
17220 const GLchar* array = "";
17221 GLchar buffer_gohan[16];
17222 GLchar buffer_goten[16];
17223 const GLchar* index = "";
17224 size_t position = 0;
17226 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
17228 sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
17229 sprintf(buffer_goten, "%d", test_case.m_component_goten);
17233 case Utils::Shader::FRAGMENT:
17234 source = fs_tested;
17236 case Utils::Shader::GEOMETRY:
17237 source = gs_tested;
17241 case Utils::Shader::TESS_CTRL:
17242 source = tcs_tested;
17244 index = "[gl_InvocationID]";
17246 case Utils::Shader::TESS_EVAL:
17247 source = tes_tested;
17251 case Utils::Shader::VERTEX:
17252 source = vs_tested;
17255 TCU_FAIL("Invalid enum");
17259 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
17261 Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
17262 Utils::replaceToken("ARRAY", position, array, source);
17263 Utils::replaceToken("COMPONENT", position, buffer_goten, source);
17264 Utils::replaceToken("ARRAY", position, array, source);
17265 Utils::replaceToken("VARIABLE_USE", position, l_test, source);
17267 Utils::replaceAllTokens("TYPE", type_name, source);
17268 Utils::replaceAllTokens("INDEX", index, source);
17274 case Utils::Shader::FRAGMENT:
17277 case Utils::Shader::GEOMETRY:
17280 case Utils::Shader::TESS_CTRL:
17283 case Utils::Shader::TESS_EVAL:
17286 case Utils::Shader::VERTEX:
17290 TCU_FAIL("Invalid enum");
17297 /** Get description of test case
17299 * @param test_case_index Index of test case
17301 * @return Test case description
17303 std::string OutputComponentAliasingTest::getTestCaseName(GLuint test_case_index)
17305 std::stringstream stream;
17306 testCase& test_case = m_test_cases[test_case_index];
17308 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
17309 << " type: " << test_case.m_type.GetGLSLTypeName() << ", components: " << test_case.m_component_gohan
17310 << " & " << test_case.m_component_goten;
17312 return stream.str();
17315 /** Get number of test cases
17317 * @return Number of test cases
17319 GLuint OutputComponentAliasingTest::getTestCaseNumber()
17321 return static_cast<GLuint>(m_test_cases.size());
17324 /** Selects if "compute" stage is relevant for test
17330 bool OutputComponentAliasingTest::isComputeRelevant(GLuint /* test_case_index */)
17335 /** Prepare all test cases
17338 void OutputComponentAliasingTest::testInit()
17340 static const GLuint n_components_per_location = 4;
17341 const GLuint n_types = getTypesNumber();
17343 for (GLuint i = 0; i < n_types; ++i)
17345 const Utils::Type& type = getType(i);
17346 const GLuint n_req_components = type.m_n_rows;
17347 const GLuint valid_component = n_components_per_location - n_req_components;
17349 /* Skip matrices */
17350 if (1 != type.m_n_columns)
17355 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
17357 if (Utils::Shader::COMPUTE == stage)
17362 if ((Utils::Shader::FRAGMENT == stage) && (Utils::Type::Double == type.m_basic_type))
17367 for (GLuint gohan = 0; gohan <= valid_component; ++gohan)
17369 const GLint first_aliasing = gohan - n_req_components + 1;
17370 const GLint last_aliasing = gohan + n_req_components - 1;
17372 const GLuint goten_start = std::max(0, first_aliasing);
17373 const GLuint goten_stop = std::min((GLint)valid_component, last_aliasing);
17375 for (GLuint goten = goten_start; goten <= goten_stop; ++goten)
17377 testCase test_case = { gohan, goten, (Utils::Shader::STAGES)stage, type };
17379 m_test_cases.push_back(test_case);
17388 * @param context Test framework context
17390 VaryingLocationAliasingWithMixedTypesTest::VaryingLocationAliasingWithMixedTypesTest(deqp::Context& context)
17391 : NegativeTestBase(context, "varying_location_aliasing_with_mixed_types",
17392 "Test verifies that compiler reports error when float/int types are mixed at one location")
17396 /** Source for given test case and stage
17398 * @param test_case_index Index of test case
17399 * @param stage Shader stage
17401 * @return Shader source
17403 std::string VaryingLocationAliasingWithMixedTypesTest::getShaderSource(GLuint test_case_index,
17404 Utils::Shader::STAGES stage)
17406 static const GLchar* var_definition =
17407 "layout (location = 1, component = COMPONENT) FLAT DIRECTION TYPE gohanARRAY;\n"
17408 "layout (location = 1, component = COMPONENT) FLAT DIRECTION TYPE gotenARRAY;\n";
17409 static const GLchar* input_use = " if ((TYPE(0) == gohanINDEX) &&\n"
17410 " (TYPE(1) == gotenINDEX) )\n"
17412 " result += vec4(1, 0.5, 0.25, 0.125);\n"
17414 static const GLchar* output_use = " gohanINDEX = TYPE(0);\n"
17415 " gotenINDEX = TYPE(1);\n"
17416 " if (vec4(0) == result)\n"
17418 " gohanINDEX = TYPE(1);\n"
17419 " gotenINDEX = TYPE(0);\n"
17421 static const GLchar* fs = "#version 430 core\n"
17422 "#extension GL_ARB_enhanced_layouts : require\n"
17425 "out vec4 fs_out;\n"
17429 " fs_out = gs_fs;\n"
17432 static const GLchar* fs_tested = "#version 430 core\n"
17433 "#extension GL_ARB_enhanced_layouts : require\n"
17438 "out vec4 fs_out;\n"
17442 " vec4 result = gs_fs;\n"
17446 " fs_out += result;\n"
17449 static const GLchar* gs = "#version 430 core\n"
17450 "#extension GL_ARB_enhanced_layouts : require\n"
17452 "layout(points) in;\n"
17453 "layout(triangle_strip, max_vertices = 4) out;\n"
17455 "in vec4 tes_gs[];\n"
17456 "out vec4 gs_fs;\n"
17460 " gs_fs = tes_gs[0];\n"
17461 " gl_Position = vec4(-1, -1, 0, 1);\n"
17463 " gs_fs = tes_gs[0];\n"
17464 " gl_Position = vec4(-1, 1, 0, 1);\n"
17466 " gs_fs = tes_gs[0];\n"
17467 " gl_Position = vec4(1, -1, 0, 1);\n"
17469 " gs_fs = tes_gs[0];\n"
17470 " gl_Position = vec4(1, 1, 0, 1);\n"
17474 static const GLchar* gs_tested = "#version 430 core\n"
17475 "#extension GL_ARB_enhanced_layouts : require\n"
17477 "layout(points) in;\n"
17478 "layout(triangle_strip, max_vertices = 4) out;\n"
17482 "in vec4 tes_gs[];\n"
17483 "out vec4 gs_fs;\n"
17487 " vec4 result = tes_gs[0];\n"
17491 " gs_fs = result;\n"
17492 " gl_Position = vec4(-1, -1, 0, 1);\n"
17494 " gs_fs = result;\n"
17495 " gl_Position = vec4(-1, 1, 0, 1);\n"
17497 " gs_fs = result;\n"
17498 " gl_Position = vec4(1, -1, 0, 1);\n"
17500 " gs_fs = result;\n"
17501 " gl_Position = vec4(1, 1, 0, 1);\n"
17505 static const GLchar* tcs = "#version 430 core\n"
17506 "#extension GL_ARB_enhanced_layouts : require\n"
17508 "layout(vertices = 1) out;\n"
17510 "in vec4 vs_tcs[];\n"
17511 "out vec4 tcs_tes[];\n"
17516 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
17518 " gl_TessLevelOuter[0] = 1.0;\n"
17519 " gl_TessLevelOuter[1] = 1.0;\n"
17520 " gl_TessLevelOuter[2] = 1.0;\n"
17521 " gl_TessLevelOuter[3] = 1.0;\n"
17522 " gl_TessLevelInner[0] = 1.0;\n"
17523 " gl_TessLevelInner[1] = 1.0;\n"
17526 static const GLchar* tcs_tested = "#version 430 core\n"
17527 "#extension GL_ARB_enhanced_layouts : require\n"
17529 "layout(vertices = 1) out;\n"
17533 "in vec4 vs_tcs[];\n"
17534 "out vec4 tcs_tes[];\n"
17538 " vec4 result = vs_tcs[gl_InvocationID];\n"
17542 " tcs_tes[gl_InvocationID] = result;\n"
17544 " gl_TessLevelOuter[0] = 1.0;\n"
17545 " gl_TessLevelOuter[1] = 1.0;\n"
17546 " gl_TessLevelOuter[2] = 1.0;\n"
17547 " gl_TessLevelOuter[3] = 1.0;\n"
17548 " gl_TessLevelInner[0] = 1.0;\n"
17549 " gl_TessLevelInner[1] = 1.0;\n"
17552 static const GLchar* tes = "#version 430 core\n"
17553 "#extension GL_ARB_enhanced_layouts : require\n"
17555 "layout(isolines, point_mode) in;\n"
17557 "in vec4 tcs_tes[];\n"
17558 "out vec4 tes_gs;\n"
17562 " tes_gs = tcs_tes[0];\n"
17565 static const GLchar* tes_tested = "#version 430 core\n"
17566 "#extension GL_ARB_enhanced_layouts : require\n"
17568 "layout(isolines, point_mode) in;\n"
17572 "in vec4 tcs_tes[];\n"
17573 "out vec4 tes_gs;\n"
17577 " vec4 result = tcs_tes[0];\n"
17581 " tes_gs += result;\n"
17584 static const GLchar* vs = "#version 430 core\n"
17585 "#extension GL_ARB_enhanced_layouts : require\n"
17588 "out vec4 vs_tcs;\n"
17592 " vs_tcs = in_vs;\n"
17595 static const GLchar* vs_tested = "#version 430 core\n"
17596 "#extension GL_ARB_enhanced_layouts : require\n"
17601 "out vec4 vs_tcs;\n"
17605 " vec4 result = in_vs;\n"
17609 " vs_tcs += result;\n"
17613 std::string source;
17614 testCase& test_case = m_test_cases[test_case_index];
17616 if (test_case.m_stage == stage)
17618 const GLchar* array = "";
17619 GLchar buffer_gohan[16];
17620 GLchar buffer_goten[16];
17621 const GLchar* direction = "in ";
17622 const GLchar* flat_gohan = "";
17623 const GLchar* flat_goten = "";
17624 const GLchar* index = "";
17625 size_t position = 0;
17627 const GLchar* type_gohan_name = test_case.m_type_gohan.GetGLSLTypeName();
17628 const GLchar* type_goten_name = test_case.m_type_goten.GetGLSLTypeName();
17629 Utils::Variable::STORAGE storage = Utils::Variable::VARYING_INPUT;
17630 const GLchar* var_use = input_use;
17632 if (false == test_case.m_is_input)
17635 storage = Utils::Variable::VARYING_OUTPUT;
17636 var_use = output_use;
17639 if (true == isFlatRequired(stage, test_case.m_type_gohan, storage))
17641 flat_gohan = "flat";
17644 if (true == isFlatRequired(stage, test_case.m_type_goten, storage))
17646 flat_goten = "flat";
17649 sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
17650 sprintf(buffer_goten, "%d", test_case.m_component_goten);
17654 case Utils::Shader::FRAGMENT:
17655 source = fs_tested;
17657 case Utils::Shader::GEOMETRY:
17658 source = gs_tested;
17662 case Utils::Shader::TESS_CTRL:
17663 source = tcs_tested;
17665 index = "[gl_InvocationID]";
17667 case Utils::Shader::TESS_EVAL:
17668 source = tes_tested;
17672 case Utils::Shader::VERTEX:
17673 source = vs_tested;
17676 TCU_FAIL("Invalid enum");
17680 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
17682 Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
17683 Utils::replaceToken("FLAT", position, flat_gohan, source);
17684 Utils::replaceToken("DIRECTION", position, direction, source);
17685 Utils::replaceToken("TYPE", position, type_gohan_name, source);
17686 Utils::replaceToken("ARRAY", position, array, source);
17687 Utils::replaceToken("COMPONENT", position, buffer_goten, source);
17688 Utils::replaceToken("FLAT", position, flat_goten, source);
17689 Utils::replaceToken("DIRECTION", position, direction, source);
17690 Utils::replaceToken("TYPE", position, type_goten_name, source);
17691 Utils::replaceToken("ARRAY", position, array, source);
17694 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
17696 if (true == test_case.m_is_input)
17698 Utils::replaceToken("TYPE", position, type_gohan_name, source);
17699 Utils::replaceToken("TYPE", position, type_goten_name, source);
17703 Utils::replaceToken("TYPE", position, type_gohan_name, source);
17704 Utils::replaceToken("TYPE", position, type_goten_name, source);
17705 Utils::replaceToken("TYPE", position, type_gohan_name, source);
17706 Utils::replaceToken("TYPE", position, type_goten_name, source);
17709 Utils::replaceAllTokens("INDEX", index, source);
17715 case Utils::Shader::FRAGMENT:
17718 case Utils::Shader::GEOMETRY:
17721 case Utils::Shader::TESS_CTRL:
17724 case Utils::Shader::TESS_EVAL:
17727 case Utils::Shader::VERTEX:
17731 TCU_FAIL("Invalid enum");
17738 /** Get description of test case
17740 * @param test_case_index Index of test case
17742 * @return Test case description
17744 std::string VaryingLocationAliasingWithMixedTypesTest::getTestCaseName(GLuint test_case_index)
17746 std::stringstream stream;
17747 testCase& test_case = m_test_cases[test_case_index];
17749 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", "
17750 << test_case.m_type_gohan.GetGLSLTypeName() << " at " << test_case.m_component_gohan << ", "
17751 << test_case.m_type_goten.GetGLSLTypeName() << " at " << test_case.m_component_goten << ". Direction: ";
17753 if (true == test_case.m_is_input)
17759 stream << "output";
17762 return stream.str();
17765 /** Get number of test cases
17767 * @return Number of test cases
17769 GLuint VaryingLocationAliasingWithMixedTypesTest::getTestCaseNumber()
17771 return static_cast<GLuint>(m_test_cases.size());
17774 /** Selects if "compute" stage is relevant for test
17780 bool VaryingLocationAliasingWithMixedTypesTest::isComputeRelevant(GLuint /* test_case_index */)
17785 /** Prepare all test cases
17788 void VaryingLocationAliasingWithMixedTypesTest::testInit()
17790 static const GLuint n_components_per_location = 4;
17791 const GLuint n_types = getTypesNumber();
17793 for (GLuint i = 0; i < n_types; ++i)
17795 const Utils::Type& type_gohan = getType(i);
17796 const bool is_float_type_gohan = isFloatType(type_gohan);
17798 /* Skip matrices */
17799 if (1 != type_gohan.m_n_columns)
17804 for (GLuint j = 0; j < n_types; ++j)
17806 const Utils::Type& type_goten = getType(j);
17807 const bool is_float_type_goten = isFloatType(type_goten);
17809 /* Skip matrices */
17810 if (1 != type_goten.m_n_columns)
17815 /* Skip valid combinations */
17816 if (is_float_type_gohan == is_float_type_goten)
17821 const GLuint n_req_components_gohan = type_gohan.m_n_rows;
17822 const GLuint n_req_components_goten = type_goten.m_n_rows;
17823 const GLuint valid_component_gohan = n_components_per_location - n_req_components_gohan;
17824 const GLuint valid_component_goten = n_components_per_location - n_req_components_goten;
17826 /* Skip pairs that cannot fit into one location */
17827 if (n_components_per_location < (n_req_components_gohan + n_req_components_goten))
17832 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
17834 /* Skip compute shader */
17835 if (Utils::Shader::COMPUTE == stage)
17840 for (GLuint gohan = 0; gohan <= valid_component_gohan; ++gohan)
17842 const GLint first_aliasing = gohan - n_req_components_goten + 1;
17843 const GLint last_aliasing = gohan + n_req_components_gohan - 1;
17845 const GLuint goten_lower_limit = std::max(0, first_aliasing);
17846 const GLuint goten_upper_limit = last_aliasing + 1;
17848 /* Compoennets before gohan */
17849 for (GLuint goten = 0; goten < goten_lower_limit; ++goten)
17851 testCase test_case_in = { gohan, goten, true, (Utils::Shader::STAGES)stage,
17852 type_gohan, type_goten };
17853 testCase test_case_out = { gohan, goten, false, (Utils::Shader::STAGES)stage,
17854 type_gohan, type_goten };
17856 m_test_cases.push_back(test_case_in);
17858 /* Skip double outputs in fragment shader */
17859 if ((Utils::Shader::FRAGMENT != stage) || ((Utils::Type::Double != type_gohan.m_basic_type) &&
17860 (Utils::Type::Double != type_goten.m_basic_type)))
17862 m_test_cases.push_back(test_case_out);
17866 /* Components after gohan */
17867 for (GLuint goten = goten_upper_limit; goten <= valid_component_goten; ++goten)
17869 testCase test_case_in = { gohan, goten, true, (Utils::Shader::STAGES)stage,
17870 type_gohan, type_goten };
17871 testCase test_case_out = { gohan, goten, false, (Utils::Shader::STAGES)stage,
17872 type_gohan, type_goten };
17874 m_test_cases.push_back(test_case_in);
17876 /* Skip double outputs in fragment shader */
17877 if ((Utils::Shader::FRAGMENT != stage) || ((Utils::Type::Double != type_gohan.m_basic_type) &&
17878 (Utils::Type::Double != type_goten.m_basic_type)))
17880 m_test_cases.push_back(test_case_out);
17889 /** Check if given type is float
17891 * @param type Type in question
17893 * @return true if tpye is float, false otherwise
17895 bool VaryingLocationAliasingWithMixedTypesTest::isFloatType(const Utils::Type& type)
17897 bool is_float = false;
17899 if ((Utils::Type::Double == type.m_basic_type) || (Utils::Type::Float == type.m_basic_type))
17909 * @param context Test framework context
17911 VaryingLocationAliasingWithMixedInterpolationTest::VaryingLocationAliasingWithMixedInterpolationTest(
17912 deqp::Context& context)
17913 : NegativeTestBase(
17914 context, "varying_location_aliasing_with_mixed_interpolation",
17915 "Test verifies that compiler reports error when interpolation qualifiers are mixed at one location")
17919 /** Source for given test case and stage
17921 * @param test_case_index Index of test case
17922 * @param stage Shader stage
17924 * @return Shader source
17926 std::string VaryingLocationAliasingWithMixedInterpolationTest::getShaderSource(GLuint test_case_index,
17927 Utils::Shader::STAGES stage)
17929 static const GLchar* var_definition =
17930 "layout (location = 1, component = COMPONENT) INTERPOLATION DIRECTION TYPE gohanARRAY;\n"
17931 "layout (location = 1, component = COMPONENT) INTERPOLATION DIRECTION TYPE gotenARRAY;\n";
17932 static const GLchar* input_use = " if ((TYPE(0) == gohanINDEX) &&\n"
17933 " (TYPE(1) == gotenINDEX) )\n"
17935 " result += vec4(1, 0.5, 0.25, 0.125);\n"
17937 static const GLchar* output_use = " gohanINDEX = TYPE(0);\n"
17938 " gotenINDEX = TYPE(1);\n"
17939 " if (vec4(0) == result)\n"
17941 " gohanINDEX = TYPE(1);\n"
17942 " gotenINDEX = TYPE(0);\n"
17944 static const GLchar* fs = "#version 430 core\n"
17945 "#extension GL_ARB_enhanced_layouts : require\n"
17948 "out vec4 fs_out;\n"
17952 " fs_out = gs_fs;\n"
17955 static const GLchar* fs_tested = "#version 430 core\n"
17956 "#extension GL_ARB_enhanced_layouts : require\n"
17961 "out vec4 fs_out;\n"
17965 " vec4 result = gs_fs;\n"
17969 " fs_out = result;\n"
17972 static const GLchar* gs = "#version 430 core\n"
17973 "#extension GL_ARB_enhanced_layouts : require\n"
17975 "layout(points) in;\n"
17976 "layout(triangle_strip, max_vertices = 4) out;\n"
17978 "in vec4 tes_gs[];\n"
17979 "out vec4 gs_fs;\n"
17983 " gs_fs = tes_gs[0];\n"
17984 " gl_Position = vec4(-1, -1, 0, 1);\n"
17986 " gs_fs = tes_gs[0];\n"
17987 " gl_Position = vec4(-1, 1, 0, 1);\n"
17989 " gs_fs = tes_gs[0];\n"
17990 " gl_Position = vec4(1, -1, 0, 1);\n"
17992 " gs_fs = tes_gs[0];\n"
17993 " gl_Position = vec4(1, 1, 0, 1);\n"
17997 static const GLchar* gs_tested = "#version 430 core\n"
17998 "#extension GL_ARB_enhanced_layouts : require\n"
18000 "layout(points) in;\n"
18001 "layout(triangle_strip, max_vertices = 4) out;\n"
18005 "in vec4 tes_gs[];\n"
18006 "out vec4 gs_fs;\n"
18010 " vec4 result = tes_gs[0];\n"
18014 " gs_fs = result;\n"
18015 " gl_Position = vec4(-1, -1, 0, 1);\n"
18017 " gs_fs = result;\n"
18018 " gl_Position = vec4(-1, 1, 0, 1);\n"
18020 " gs_fs = result;\n"
18021 " gl_Position = vec4(1, -1, 0, 1);\n"
18023 " gs_fs = result;\n"
18024 " gl_Position = vec4(1, 1, 0, 1);\n"
18028 static const GLchar* tcs = "#version 430 core\n"
18029 "#extension GL_ARB_enhanced_layouts : require\n"
18031 "layout(vertices = 1) out;\n"
18033 "in vec4 vs_tcs[];\n"
18034 "out vec4 tcs_tes[];\n"
18039 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
18041 " gl_TessLevelOuter[0] = 1.0;\n"
18042 " gl_TessLevelOuter[1] = 1.0;\n"
18043 " gl_TessLevelOuter[2] = 1.0;\n"
18044 " gl_TessLevelOuter[3] = 1.0;\n"
18045 " gl_TessLevelInner[0] = 1.0;\n"
18046 " gl_TessLevelInner[1] = 1.0;\n"
18049 static const GLchar* tcs_tested = "#version 430 core\n"
18050 "#extension GL_ARB_enhanced_layouts : require\n"
18052 "layout(vertices = 1) out;\n"
18056 "in vec4 vs_tcs[];\n"
18057 "out vec4 tcs_tes[];\n"
18061 " vec4 result = vs_tcs[gl_InvocationID];\n"
18065 " tcs_tes[gl_InvocationID] = result;\n"
18067 " gl_TessLevelOuter[0] = 1.0;\n"
18068 " gl_TessLevelOuter[1] = 1.0;\n"
18069 " gl_TessLevelOuter[2] = 1.0;\n"
18070 " gl_TessLevelOuter[3] = 1.0;\n"
18071 " gl_TessLevelInner[0] = 1.0;\n"
18072 " gl_TessLevelInner[1] = 1.0;\n"
18075 static const GLchar* tes = "#version 430 core\n"
18076 "#extension GL_ARB_enhanced_layouts : require\n"
18078 "layout(isolines, point_mode) in;\n"
18080 "in vec4 tcs_tes[];\n"
18081 "out vec4 tes_gs;\n"
18085 " tes_gs = tcs_tes[0];\n"
18088 static const GLchar* tes_tested = "#version 430 core\n"
18089 "#extension GL_ARB_enhanced_layouts : require\n"
18091 "layout(isolines, point_mode) in;\n"
18095 "in vec4 tcs_tes[];\n"
18096 "out vec4 tes_gs;\n"
18100 " vec4 result = tcs_tes[0];\n"
18104 " tes_gs += result;\n"
18107 static const GLchar* vs = "#version 430 core\n"
18108 "#extension GL_ARB_enhanced_layouts : require\n"
18111 "out vec4 vs_tcs;\n"
18115 " vs_tcs = in_vs;\n"
18118 static const GLchar* vs_tested = "#version 430 core\n"
18119 "#extension GL_ARB_enhanced_layouts : require\n"
18124 "out vec4 vs_tcs;\n"
18128 " vec4 result = in_vs;\n"
18132 " vs_tcs += result;\n"
18136 std::string source;
18137 testCase& test_case = m_test_cases[test_case_index];
18139 if (test_case.m_stage == stage)
18141 const GLchar* array = "";
18142 GLchar buffer_gohan[16];
18143 GLchar buffer_goten[16];
18144 const GLchar* direction = "in ";
18145 const GLchar* index = "";
18146 const GLchar* int_gohan = getInterpolationQualifier(test_case.m_interpolation_gohan);
18147 const GLchar* int_goten = getInterpolationQualifier(test_case.m_interpolation_goten);
18148 size_t position = 0;
18150 const GLchar* type_gohan_name = test_case.m_type_gohan.GetGLSLTypeName();
18151 const GLchar* type_goten_name = test_case.m_type_goten.GetGLSLTypeName();
18152 const GLchar* var_use = input_use;
18154 if (false == test_case.m_is_input)
18158 var_use = output_use;
18161 sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
18162 sprintf(buffer_goten, "%d", test_case.m_component_goten);
18166 case Utils::Shader::FRAGMENT:
18167 source = fs_tested;
18169 case Utils::Shader::GEOMETRY:
18170 source = gs_tested;
18174 case Utils::Shader::TESS_CTRL:
18175 source = tcs_tested;
18177 index = "[gl_InvocationID]";
18179 case Utils::Shader::TESS_EVAL:
18180 source = tes_tested;
18184 case Utils::Shader::VERTEX:
18185 source = vs_tested;
18188 TCU_FAIL("Invalid enum");
18192 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
18194 Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
18195 Utils::replaceToken("INTERPOLATION", position, int_gohan, source);
18196 Utils::replaceToken("DIRECTION", position, direction, source);
18197 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18198 Utils::replaceToken("ARRAY", position, array, source);
18199 Utils::replaceToken("COMPONENT", position, buffer_goten, source);
18200 Utils::replaceToken("INTERPOLATION", position, int_goten, source);
18201 Utils::replaceToken("DIRECTION", position, direction, source);
18202 Utils::replaceToken("TYPE", position, type_goten_name, source);
18203 Utils::replaceToken("ARRAY", position, array, source);
18206 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
18208 if (true == test_case.m_is_input)
18210 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18211 Utils::replaceToken("TYPE", position, type_goten_name, source);
18215 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18216 Utils::replaceToken("TYPE", position, type_goten_name, source);
18217 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18218 Utils::replaceToken("TYPE", position, type_goten_name, source);
18221 Utils::replaceAllTokens("INDEX", index, source);
18227 case Utils::Shader::FRAGMENT:
18230 case Utils::Shader::GEOMETRY:
18233 case Utils::Shader::TESS_CTRL:
18236 case Utils::Shader::TESS_EVAL:
18239 case Utils::Shader::VERTEX:
18243 TCU_FAIL("Invalid enum");
18250 /** Get description of test case
18252 * @param test_case_index Index of test case
18254 * @return Test case description
18256 std::string VaryingLocationAliasingWithMixedInterpolationTest::getTestCaseName(GLuint test_case_index)
18258 std::stringstream stream;
18259 testCase& test_case = m_test_cases[test_case_index];
18261 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", "
18262 << getInterpolationQualifier(test_case.m_interpolation_gohan) << " "
18263 << test_case.m_type_gohan.GetGLSLTypeName() << " at " << test_case.m_component_gohan << ", "
18264 << getInterpolationQualifier(test_case.m_interpolation_goten) << " "
18265 << test_case.m_type_goten.GetGLSLTypeName() << " at " << test_case.m_component_goten << ". Direction: ";
18267 if (true == test_case.m_is_input)
18273 stream << "output";
18276 return stream.str();
18279 /** Get number of test cases
18281 * @return Number of test cases
18283 GLuint VaryingLocationAliasingWithMixedInterpolationTest::getTestCaseNumber()
18285 return static_cast<GLuint>(m_test_cases.size());
18288 /** Selects if "compute" stage is relevant for test
18294 bool VaryingLocationAliasingWithMixedInterpolationTest::isComputeRelevant(GLuint /* test_case_index */)
18299 /** Prepare all test cases
18302 void VaryingLocationAliasingWithMixedInterpolationTest::testInit()
18304 static const GLuint n_components_per_location = 4;
18305 const GLuint n_types = getTypesNumber();
18307 for (GLuint i = 0; i < n_types; ++i)
18309 const Utils::Type& type_gohan = getType(i);
18310 const bool is_float_type_gohan = isFloatType(type_gohan);
18312 /* Skip matrices */
18313 if (1 != type_gohan.m_n_columns)
18318 for (GLuint j = 0; j < n_types; ++j)
18320 const Utils::Type& type_goten = getType(j);
18321 const bool is_float_type_goten = isFloatType(type_goten);
18323 /* Skip matrices */
18324 if (1 != type_goten.m_n_columns)
18329 /* Skip invalid combinations */
18330 if (is_float_type_gohan != is_float_type_goten)
18335 const GLuint n_req_components_gohan = type_gohan.m_n_rows;
18336 const GLuint n_req_components_goten = type_goten.m_n_rows;
18338 /* Skip pairs that cannot fit into one location */
18339 if (n_components_per_location < (n_req_components_gohan + n_req_components_goten))
18344 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
18346 /* Skip compute shader */
18347 if (Utils::Shader::COMPUTE == stage)
18352 const GLuint gohan = 0;
18353 const GLuint goten = gohan + n_req_components_gohan;
18355 for (GLuint int_gohan = 0; int_gohan < INTERPOLATION_MAX; ++int_gohan)
18357 for (GLuint int_goten = 0; int_goten < INTERPOLATION_MAX; ++int_goten)
18359 const bool is_gohan_double = (Utils::Type::Double == type_gohan.m_basic_type) ? true : false;
18360 const bool is_goten_double = (Utils::Type::Double == type_goten.m_basic_type) ? true : false;
18361 const bool is_gohan_flat = (FLAT == int_gohan) ? true : false;
18362 const bool is_goten_flat = (FLAT == int_goten) ? true : false;
18363 const bool is_gohan_accepted_as_fs_in =
18364 (is_gohan_double && is_gohan_flat) || (!is_gohan_double);
18365 const bool is_goten_accepted_as_fs_in =
18366 (is_goten_double && is_goten_flat) || (!is_goten_double);
18367 const bool is_comb_accepted_as_fs_in = is_gohan_accepted_as_fs_in && is_goten_accepted_as_fs_in;
18369 /* Skip when both are the same */
18370 if (int_gohan == int_goten)
18375 testCase test_case_in = { gohan,
18377 (INTERPOLATIONS)int_gohan,
18378 (INTERPOLATIONS)int_goten,
18380 (Utils::Shader::STAGES)stage,
18384 testCase test_case_out = { gohan,
18386 (INTERPOLATIONS)int_gohan,
18387 (INTERPOLATIONS)int_goten,
18389 (Utils::Shader::STAGES)stage,
18395 * fragment shader when not flat double is used
18397 if ((Utils::Shader::VERTEX != stage) &&
18398 ((Utils::Shader::FRAGMENT != stage) || (true == is_comb_accepted_as_fs_in)))
18400 m_test_cases.push_back(test_case_in);
18403 /* Skip outputs in fragment shader */
18404 if (Utils::Shader::FRAGMENT != stage)
18406 m_test_cases.push_back(test_case_out);
18415 /** Get interpolation qualifier
18417 * @param interpolation Enumeration
18419 * @return GLSL qualifier
18421 const GLchar* VaryingLocationAliasingWithMixedInterpolationTest::getInterpolationQualifier(INTERPOLATIONS interpolation)
18423 const GLchar* result = 0;
18425 switch (interpolation)
18433 case NO_PERSPECTIVE:
18434 result = "noperspective";
18437 TCU_FAIL("Invalid enum");
18443 /** Check if given type is float
18445 * @param type Type in question
18447 * @return true if tpye is float, false otherwise
18449 bool VaryingLocationAliasingWithMixedInterpolationTest::isFloatType(const Utils::Type& type)
18451 bool is_float = false;
18453 if ((Utils::Type::Double == type.m_basic_type) || (Utils::Type::Float == type.m_basic_type))
18463 * @param context Test framework context
18465 VaryingLocationAliasingWithMixedAuxiliaryStorageTest::VaryingLocationAliasingWithMixedAuxiliaryStorageTest(
18466 deqp::Context& context)
18467 : NegativeTestBase(
18468 context, "varying_location_aliasing_with_mixed_auxiliary_storage",
18469 "Test verifies that compiler reports error when auxiliary storage qualifiers are mixed at one location")
18473 /** Source for given test case and stage
18475 * @param test_case_index Index of test case
18476 * @param stage Shader stage
18478 * @return Shader source
18480 std::string VaryingLocationAliasingWithMixedAuxiliaryStorageTest::getShaderSource(GLuint test_case_index,
18481 Utils::Shader::STAGES stage)
18483 static const GLchar* var_definition =
18484 "layout (location = 1, component = COMPONENT) AUX INTERPOLATION DIRECTION TYPE gohanARRAY;\n"
18485 "layout (location = 1, component = COMPONENT) AUX INTERPOLATION DIRECTION TYPE gotenARRAY;\n";
18486 static const GLchar* input_use = " if ((TYPE(0) == gohanINDEX_GOHAN) &&\n"
18487 " (TYPE(1) == gotenINDEX_GOTEN) )\n"
18489 " result += vec4(1, 0.5, 0.25, 0.125);\n"
18491 static const GLchar* output_use = " gohanINDEX_GOHAN = TYPE(0);\n"
18492 " gotenINDEX_GOTEN = TYPE(1);\n"
18493 " if (vec4(0) == result)\n"
18495 " gohanINDEX_GOHAN = TYPE(1);\n"
18496 " gotenINDEX_GOTEN = TYPE(0);\n"
18498 static const GLchar* fs = "#version 430 core\n"
18499 "#extension GL_ARB_enhanced_layouts : require\n"
18502 "out vec4 fs_out;\n"
18506 " fs_out = gs_fs;\n"
18509 static const GLchar* fs_tested = "#version 430 core\n"
18510 "#extension GL_ARB_enhanced_layouts : require\n"
18515 "out vec4 fs_out;\n"
18519 " vec4 result = gs_fs;\n"
18523 " fs_out = result;\n"
18526 static const GLchar* gs = "#version 430 core\n"
18527 "#extension GL_ARB_enhanced_layouts : require\n"
18529 "layout(points) in;\n"
18530 "layout(triangle_strip, max_vertices = 4) out;\n"
18532 "in vec4 tes_gs[];\n"
18533 "out vec4 gs_fs;\n"
18537 " gs_fs = tes_gs[0];\n"
18538 " gl_Position = vec4(-1, -1, 0, 1);\n"
18540 " gs_fs = tes_gs[0];\n"
18541 " gl_Position = vec4(-1, 1, 0, 1);\n"
18543 " gs_fs = tes_gs[0];\n"
18544 " gl_Position = vec4(1, -1, 0, 1);\n"
18546 " gs_fs = tes_gs[0];\n"
18547 " gl_Position = vec4(1, 1, 0, 1);\n"
18551 static const GLchar* gs_tested = "#version 430 core\n"
18552 "#extension GL_ARB_enhanced_layouts : require\n"
18554 "layout(points) in;\n"
18555 "layout(triangle_strip, max_vertices = 4) out;\n"
18559 "in vec4 tes_gs[];\n"
18560 "out vec4 gs_fs;\n"
18564 " vec4 result = tes_gs[0];\n"
18568 " gs_fs = result;\n"
18569 " gl_Position = vec4(-1, -1, 0, 1);\n"
18571 " gs_fs = result;\n"
18572 " gl_Position = vec4(-1, 1, 0, 1);\n"
18574 " gs_fs = result;\n"
18575 " gl_Position = vec4(1, -1, 0, 1);\n"
18577 " gs_fs = result;\n"
18578 " gl_Position = vec4(1, 1, 0, 1);\n"
18582 static const GLchar* tcs = "#version 430 core\n"
18583 "#extension GL_ARB_enhanced_layouts : require\n"
18585 "layout(vertices = 1) out;\n"
18587 "in vec4 vs_tcs[];\n"
18588 "out vec4 tcs_tes[];\n"
18593 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
18595 " gl_TessLevelOuter[0] = 1.0;\n"
18596 " gl_TessLevelOuter[1] = 1.0;\n"
18597 " gl_TessLevelOuter[2] = 1.0;\n"
18598 " gl_TessLevelOuter[3] = 1.0;\n"
18599 " gl_TessLevelInner[0] = 1.0;\n"
18600 " gl_TessLevelInner[1] = 1.0;\n"
18603 static const GLchar* tcs_tested = "#version 430 core\n"
18604 "#extension GL_ARB_enhanced_layouts : require\n"
18606 "layout(vertices = 1) out;\n"
18610 "in vec4 vs_tcs[];\n"
18611 "out vec4 tcs_tes[];\n"
18615 " vec4 result = vs_tcs[gl_InvocationID];\n"
18619 " tcs_tes[gl_InvocationID] = result;\n"
18621 " gl_TessLevelOuter[0] = 1.0;\n"
18622 " gl_TessLevelOuter[1] = 1.0;\n"
18623 " gl_TessLevelOuter[2] = 1.0;\n"
18624 " gl_TessLevelOuter[3] = 1.0;\n"
18625 " gl_TessLevelInner[0] = 1.0;\n"
18626 " gl_TessLevelInner[1] = 1.0;\n"
18629 static const GLchar* tes = "#version 430 core\n"
18630 "#extension GL_ARB_enhanced_layouts : require\n"
18632 "layout(isolines, point_mode) in;\n"
18634 "in vec4 tcs_tes[];\n"
18635 "out vec4 tes_gs;\n"
18639 " tes_gs = tcs_tes[0];\n"
18642 static const GLchar* tes_tested = "#version 430 core\n"
18643 "#extension GL_ARB_enhanced_layouts : require\n"
18645 "layout(isolines, point_mode) in;\n"
18649 "in vec4 tcs_tes[];\n"
18650 "out vec4 tes_gs;\n"
18654 " vec4 result = tcs_tes[0];\n"
18658 " tes_gs += result;\n"
18661 static const GLchar* vs = "#version 430 core\n"
18662 "#extension GL_ARB_enhanced_layouts : require\n"
18665 "out vec4 vs_tcs;\n"
18669 " vs_tcs = in_vs;\n"
18672 static const GLchar* vs_tested = "#version 430 core\n"
18673 "#extension GL_ARB_enhanced_layouts : require\n"
18678 "out vec4 vs_tcs;\n"
18682 " vec4 result = in_vs;\n"
18686 " vs_tcs += result;\n"
18690 std::string source;
18691 testCase& test_case = m_test_cases[test_case_index];
18693 if (test_case.m_stage == stage)
18695 const GLchar* array_gohan = "";
18696 const GLchar* array_goten = "";
18697 const GLchar* aux_gohan = getAuxiliaryQualifier(test_case.m_aux_gohan);
18698 const GLchar* aux_goten = getAuxiliaryQualifier(test_case.m_aux_goten);
18699 GLchar buffer_gohan[16];
18700 GLchar buffer_goten[16];
18701 const GLchar* direction = "in ";
18702 const GLchar* index_gohan = "";
18703 const GLchar* index_goten = "";
18704 const GLchar* int_gohan = test_case.m_int_gohan;
18705 const GLchar* int_goten = test_case.m_int_goten;
18706 size_t position = 0;
18708 const GLchar* type_gohan_name = test_case.m_type_gohan.GetGLSLTypeName();
18709 const GLchar* type_goten_name = test_case.m_type_goten.GetGLSLTypeName();
18710 const GLchar* var_use = input_use;
18712 if (false == test_case.m_is_input)
18716 var_use = output_use;
18719 sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
18720 sprintf(buffer_goten, "%d", test_case.m_component_goten);
18724 case Utils::Shader::FRAGMENT:
18725 source = fs_tested;
18727 case Utils::Shader::GEOMETRY:
18728 source = gs_tested;
18729 array_gohan = "[]";
18730 index_gohan = "[0]";
18731 array_goten = "[]";
18732 index_goten = "[0]";
18734 case Utils::Shader::TESS_CTRL:
18735 source = tcs_tested;
18736 if (PATCH != test_case.m_aux_gohan)
18738 array_gohan = "[]";
18739 index_gohan = "[gl_InvocationID]";
18741 if (PATCH != test_case.m_aux_goten)
18743 array_goten = "[]";
18744 index_goten = "[gl_InvocationID]";
18747 case Utils::Shader::TESS_EVAL:
18748 source = tes_tested;
18749 array_gohan = "[]";
18750 index_gohan = "[0]";
18751 array_goten = "[]";
18752 index_goten = "[0]";
18754 case Utils::Shader::VERTEX:
18755 source = vs_tested;
18758 TCU_FAIL("Invalid enum");
18762 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
18764 Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
18765 Utils::replaceToken("AUX", position, aux_gohan, source);
18766 Utils::replaceToken("INTERPOLATION", position, int_gohan, source);
18767 Utils::replaceToken("DIRECTION", position, direction, source);
18768 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18769 Utils::replaceToken("ARRAY", position, array_gohan, source);
18770 Utils::replaceToken("COMPONENT", position, buffer_goten, source);
18771 Utils::replaceToken("AUX", position, aux_goten, source);
18772 Utils::replaceToken("INTERPOLATION", position, int_goten, source);
18773 Utils::replaceToken("DIRECTION", position, direction, source);
18774 Utils::replaceToken("TYPE", position, type_goten_name, source);
18775 Utils::replaceToken("ARRAY", position, array_goten, source);
18778 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
18780 if (true == test_case.m_is_input)
18782 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18783 Utils::replaceToken("TYPE", position, type_goten_name, source);
18787 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18788 Utils::replaceToken("TYPE", position, type_goten_name, source);
18789 Utils::replaceToken("TYPE", position, type_gohan_name, source);
18790 Utils::replaceToken("TYPE", position, type_goten_name, source);
18793 Utils::replaceAllTokens("INDEX_GOHAN", index_gohan, source);
18794 Utils::replaceAllTokens("INDEX_GOTEN", index_goten, source);
18800 case Utils::Shader::FRAGMENT:
18803 case Utils::Shader::GEOMETRY:
18806 case Utils::Shader::TESS_CTRL:
18809 case Utils::Shader::TESS_EVAL:
18812 case Utils::Shader::VERTEX:
18816 TCU_FAIL("Invalid enum");
18823 /** Get description of test case
18825 * @param test_case_index Index of test case
18827 * @return Test case description
18829 std::string VaryingLocationAliasingWithMixedAuxiliaryStorageTest::getTestCaseName(GLuint test_case_index)
18831 std::stringstream stream;
18832 testCase& test_case = m_test_cases[test_case_index];
18834 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", "
18835 << getAuxiliaryQualifier(test_case.m_aux_gohan) << " " << test_case.m_type_gohan.GetGLSLTypeName() << " at "
18836 << test_case.m_component_gohan << ", " << getAuxiliaryQualifier(test_case.m_aux_goten) << " "
18837 << test_case.m_type_goten.GetGLSLTypeName() << " at " << test_case.m_component_goten << ". Direction: ";
18839 if (true == test_case.m_is_input)
18845 stream << "output";
18848 return stream.str();
18851 /** Get number of test cases
18853 * @return Number of test cases
18855 GLuint VaryingLocationAliasingWithMixedAuxiliaryStorageTest::getTestCaseNumber()
18857 return static_cast<GLuint>(m_test_cases.size());
18860 /** Selects if "compute" stage is relevant for test
18866 bool VaryingLocationAliasingWithMixedAuxiliaryStorageTest::isComputeRelevant(GLuint /* test_case_index */)
18871 /** Prepare all test cases
18874 void VaryingLocationAliasingWithMixedAuxiliaryStorageTest::testInit()
18876 static const GLuint n_components_per_location = 4;
18877 const GLuint n_types = getTypesNumber();
18879 for (GLuint i = 0; i < n_types; ++i)
18881 const Utils::Type& type_gohan = getType(i);
18882 const bool is_float_type_gohan = isFloatType(type_gohan);
18884 /* Skip matrices */
18885 if (1 != type_gohan.m_n_columns)
18890 for (GLuint j = 0; j < n_types; ++j)
18892 const Utils::Type& type_goten = getType(j);
18893 const bool is_flat_req_gohan = (Utils::Type::Float == type_gohan.m_basic_type) ? false : true;
18894 const bool is_flat_req_goten = (Utils::Type::Float == type_goten.m_basic_type) ? false : true;
18895 const bool is_float_type_goten = isFloatType(type_goten);
18897 /* Skip matrices */
18898 if (1 != type_goten.m_n_columns)
18903 /* Skip invalid combinations */
18904 if (is_float_type_gohan != is_float_type_goten)
18909 const GLuint n_req_components_gohan = type_gohan.m_n_rows;
18910 const GLuint n_req_components_goten = type_goten.m_n_rows;
18912 /* Skip pairs that cannot fit into one location */
18913 if (n_components_per_location < (n_req_components_gohan + n_req_components_goten))
18918 const GLuint gohan = 0;
18919 const GLuint goten = gohan + n_req_components_gohan;
18921 const GLchar* fs_int_gohan = is_flat_req_gohan ? "flat" : "";
18922 const GLchar* fs_int_goten = is_flat_req_goten ? "flat" : "";
18924 testCase test_case_tcs_np = { gohan, goten, NONE, PATCH, "", "", false, Utils::Shader::TESS_CTRL,
18925 type_gohan, type_goten };
18927 testCase test_case_tcs_pn = { gohan, goten, PATCH, NONE, "", "", false, Utils::Shader::TESS_CTRL,
18928 type_gohan, type_goten };
18930 testCase test_case_tes_np = { gohan, goten, NONE, PATCH, "", "", true, Utils::Shader::TESS_EVAL,
18931 type_gohan, type_goten };
18933 testCase test_case_tes_pn = { gohan, goten, PATCH, NONE, "", "", true, Utils::Shader::TESS_EVAL,
18934 type_gohan, type_goten };
18936 testCase test_case_fs_nc = { gohan, goten, NONE, CENTROID,
18937 fs_int_gohan, fs_int_goten, true, Utils::Shader::FRAGMENT,
18938 type_gohan, type_goten };
18940 testCase test_case_fs_cn = { gohan, goten, CENTROID, NONE,
18941 fs_int_gohan, fs_int_goten, true, Utils::Shader::FRAGMENT,
18942 type_gohan, type_goten };
18944 testCase test_case_fs_ns = { gohan, goten, NONE, SAMPLE,
18945 fs_int_gohan, fs_int_goten, true, Utils::Shader::FRAGMENT,
18946 type_gohan, type_goten };
18948 testCase test_case_fs_sn = { gohan, goten, SAMPLE, NONE,
18949 fs_int_gohan, fs_int_goten, true, Utils::Shader::FRAGMENT,
18950 type_gohan, type_goten };
18952 testCase test_case_fs_cs = { gohan, goten, CENTROID, SAMPLE,
18953 fs_int_gohan, fs_int_goten, true, Utils::Shader::FRAGMENT,
18954 type_gohan, type_goten };
18956 testCase test_case_fs_sc = { gohan, goten, SAMPLE, CENTROID,
18957 fs_int_gohan, fs_int_goten, true, Utils::Shader::FRAGMENT,
18958 type_gohan, type_goten };
18960 m_test_cases.push_back(test_case_tcs_np);
18961 m_test_cases.push_back(test_case_tcs_pn);
18962 m_test_cases.push_back(test_case_tes_np);
18963 m_test_cases.push_back(test_case_tes_pn);
18964 m_test_cases.push_back(test_case_fs_nc);
18965 m_test_cases.push_back(test_case_fs_cn);
18966 m_test_cases.push_back(test_case_fs_ns);
18967 m_test_cases.push_back(test_case_fs_sn);
18968 m_test_cases.push_back(test_case_fs_cs);
18969 m_test_cases.push_back(test_case_fs_sc);
18974 /** Get auxiliary storage qualifier
18976 * @param aux Enumeration
18978 * @return GLSL qualifier
18980 const GLchar* VaryingLocationAliasingWithMixedAuxiliaryStorageTest::getAuxiliaryQualifier(AUXILIARIES aux)
18982 const GLchar* result = 0;
18993 result = "centroid";
18999 TCU_FAIL("Invalid enum");
19005 /** Check if given type is float
19007 * @param type Type in question
19009 * @return true if tpye is float, false otherwise
19011 bool VaryingLocationAliasingWithMixedAuxiliaryStorageTest::isFloatType(const Utils::Type& type)
19013 bool is_float = false;
19015 if ((Utils::Type::Double == type.m_basic_type) || (Utils::Type::Float == type.m_basic_type))
19023 /* Constants used by VertexAttribLocationAPITest */
19024 const GLuint VertexAttribLocationAPITest::m_goten_location = 6;
19028 * @param context Test framework context
19030 VertexAttribLocationAPITest::VertexAttribLocationAPITest(deqp::Context& context)
19031 : TextureTestBase(context, "vertex_attrib_location_api",
19032 "Test verifies that attribute locations API works as expected")
19036 /** Does BindAttribLocation for "goten" and relink program
19038 * @param program Program object
19039 * @param program_interface Interface of program
19041 void VertexAttribLocationAPITest::prepareAttribLocation(Utils::Program& program,
19042 Utils::ProgramInterface& program_interface)
19044 const Functions& gl = m_context.getRenderContext().getFunctions();
19046 gl.bindAttribLocation(program.m_id, m_goten_location, "goten");
19047 GLU_EXPECT_NO_ERROR(gl.getError(), "BindAttribLocation");
19049 program.Link(gl, program.m_id);
19051 /* We still need to get locations for gohan and chichi */
19052 TextureTestBase::prepareAttribLocation(program, program_interface);
19055 /** Get interface of program
19058 * @param program_interface Interface of program
19061 void VertexAttribLocationAPITest::getProgramInterface(GLuint /* test_case_index */,
19062 Utils::ProgramInterface& program_interface,
19063 Utils::VaryingPassthrough& /* varying_passthrough */)
19065 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
19066 const Utils::Type& type = Utils::Type::vec4;
19067 const GLuint type_size = type.GetSize();
19070 const GLuint chichi_offset = 0;
19071 const GLuint goten_offset = chichi_offset + type_size;
19072 const GLuint gohan_offset = goten_offset + type_size;
19073 const GLuint goku_offset = gohan_offset + type_size;
19076 const GLuint goku_location = 2;
19077 const GLuint goten_location = m_goten_location;
19079 /* Generate data */
19080 m_goku_data = type.GenerateDataPacked();
19081 m_gohan_data = type.GenerateDataPacked();
19082 m_goten_data = type.GenerateDataPacked();
19083 m_chichi_data = type.GenerateDataPacked();
19086 si.m_globals = "const uint GOKU_LOCATION = 2;\n";
19089 si.Input("goku" /* name */, "layout (location = GOKU_LOCATION)" /* qualifiers */, 0 /* expected_componenet */,
19090 goku_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19091 0u /* n_array_elements */, 0u /* stride */, goku_offset /* offset */, (GLvoid*)&m_goku_data[0] /* data */,
19092 m_goku_data.size() /* data_size */);
19094 si.Input("gohan" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19095 Utils::Variable::m_automatic_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19096 0u /* n_array_elements */, 0u /* stride */, gohan_offset /* offset */,
19097 (GLvoid*)&m_gohan_data[0] /* data */, m_gohan_data.size() /* data_size */);
19099 si.Input("goten" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19100 goten_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19101 0u /* n_array_elements */, 0u /* stride */, goten_offset /* offset */,
19102 (GLvoid*)&m_goten_data[0] /* data */, m_goten_data.size() /* data_size */);
19104 si.Input("chichi" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19105 Utils::Variable::m_automatic_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19106 0u /* n_array_elements */, 0u /* stride */, chichi_offset /* offset */,
19107 (GLvoid*)&m_chichi_data[0] /* data */, m_chichi_data.size() /* data_size */);
19110 /** Selects if "compute" stage is relevant for test
19116 bool VertexAttribLocationAPITest::isComputeRelevant(GLuint /* test_case_index */)
19121 /* Constants used by FragmentDataLocationAPITest */
19122 const GLuint FragmentDataLocationAPITest::m_goten_location = 6;
19126 * @param context Test framework context
19128 FragmentDataLocationAPITest::FragmentDataLocationAPITest(deqp::Context& context)
19129 : TextureTestBase(context, "fragment_data_location_api",
19130 "Test verifies that fragment data locations API works as expected")
19134 , m_chichi(context)
19138 /** Verifies contents of drawn images
19143 * @return true if images are filled with expected values, false otherwise
19145 bool FragmentDataLocationAPITest::checkResults(glw::GLuint /* test_case_index */, Utils::Texture& /* color_0 */)
19147 static const GLuint size = m_width * m_height;
19148 static const GLuint expected_goku = 0xff000000;
19149 static const GLuint expected_gohan = 0xff0000ff;
19150 static const GLuint expected_goten = 0xff00ff00;
19151 static const GLuint expected_chichi = 0xffff0000;
19153 std::vector<GLuint> data;
19156 m_goku.Get(GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
19158 for (GLuint i = 0; i < size; ++i)
19160 const GLuint color = data[i];
19162 if (expected_goku != color)
19164 m_context.getTestContext().getLog() << tcu::TestLog::Message << "RGBA8[" << i << "]:" << color
19165 << tcu::TestLog::EndMessage;
19170 m_gohan.Get(GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
19172 for (GLuint i = 0; i < size; ++i)
19174 const GLuint color = data[i];
19176 if (expected_gohan != color)
19178 m_context.getTestContext().getLog() << tcu::TestLog::Message << "RGBA8[" << i << "]:" << color
19179 << tcu::TestLog::EndMessage;
19184 m_goten.Get(GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
19186 for (GLuint i = 0; i < size; ++i)
19188 const GLuint color = data[i];
19190 if (expected_goten != color)
19192 m_context.getTestContext().getLog() << tcu::TestLog::Message << "RGBA8[" << i << "]:" << color
19193 << tcu::TestLog::EndMessage;
19198 m_chichi.Get(GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
19200 for (GLuint i = 0; i < size; ++i)
19202 const GLuint color = data[i];
19204 if (expected_chichi != color)
19206 m_context.getTestContext().getLog() << tcu::TestLog::Message << "RGBA8[" << i << "]:" << color
19207 << tcu::TestLog::EndMessage;
19215 /** Prepare code snippet that will set out variables
19219 * @param stage Shader stage
19221 * @return Code that pass in variables to next stage
19223 std::string FragmentDataLocationAPITest::getPassSnippet(GLuint /* test_case_index */,
19224 Utils::VaryingPassthrough& /* varying_passthrough */,
19225 Utils::Shader::STAGES stage)
19227 std::string result;
19229 /* Skip for compute shader */
19230 if (Utils::Shader::FRAGMENT != stage)
19236 result = "chichi = vec4(0, 0, 1, 1);\n"
19237 " goku = vec4(0, 0, 0, 1);\n"
19238 " goten = vec4(0, 1, 0, 1);\n"
19239 " gohan = vec4(1, 0, 0, 1);\n";
19245 /** Get interface of program
19248 * @param program_interface Interface of program
19251 void FragmentDataLocationAPITest::getProgramInterface(GLuint /* test_case_index */,
19252 Utils::ProgramInterface& program_interface,
19253 Utils::VaryingPassthrough& /* varying_passthrough */)
19255 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
19256 const Utils::Type& type = Utils::Type::vec4;
19259 m_goku_location = 2;
19262 si.m_globals = "const uint GOKU_LOCATION = 2;\n";
19265 si.Output("goku" /* name */, "layout (location = GOKU_LOCATION)" /* qualifiers */, 0 /* expected_componenet */,
19266 m_goku_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19267 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)0 /* data */, 0u /* data_size */);
19269 si.Output("gohan" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19270 Utils::Variable::m_automatic_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19271 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)0 /* data */, 0u /* data_size */);
19273 si.Output("goten" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19274 m_goten_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19275 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)0 /* data */, 0u /* data_size */);
19277 si.Output("chichi" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19278 Utils::Variable::m_automatic_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19279 0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)0 /* data */, 0u /* data_size */);
19282 /** Selects if "compute" stage is relevant for test
19288 bool FragmentDataLocationAPITest::isComputeRelevant(GLuint /* test_case_index */)
19293 /** Get locations for all outputs with automatic_location
19295 * @param program Program object
19296 * @param program_interface Interface of program
19298 void FragmentDataLocationAPITest::prepareFragmentDataLoc(Utils::Program& program,
19299 Utils::ProgramInterface& program_interface)
19301 /* Bind location of goten */
19302 const Functions& gl = m_context.getRenderContext().getFunctions();
19304 gl.bindFragDataLocation(program.m_id, m_goten_location, "goten");
19305 GLU_EXPECT_NO_ERROR(gl.getError(), "BindFragDataLocation");
19307 program.Link(gl, program.m_id);
19309 /* Prepare locations for gohan and chichi */
19310 TextureTestBase::prepareFragmentDataLoc(program, program_interface);
19312 /* Get all locations */
19313 Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
19315 Utils::Variable::PtrVector& outputs = si.m_outputs;
19317 for (Utils::Variable::PtrVector::iterator it = outputs.begin(); outputs.end() != it; ++it)
19319 const Utils::Variable::Descriptor& desc = (*it)->m_descriptor;
19321 if (0 == desc.m_name.compare("gohan"))
19323 m_gohan_location = desc.m_expected_location;
19325 else if (0 == desc.m_name.compare("chichi"))
19327 m_chichi_location = desc.m_expected_location;
19330 /* Locations of goku and goten are fixed */
19334 /** Prepare framebuffer with single texture as color attachment
19336 * @param framebuffer Framebuffer
19337 * @param color_0_texture Texture that will used as color attachment
19339 void FragmentDataLocationAPITest::prepareFramebuffer(Utils::Framebuffer& framebuffer, Utils::Texture& color_0_texture)
19341 /* Let parent prepare its stuff */
19342 TextureTestBase::prepareFramebuffer(framebuffer, color_0_texture);
19345 std::vector<GLuint> texture_data;
19346 texture_data.resize(m_width * m_height);
19348 for (GLuint i = 0; i < texture_data.size(); ++i)
19350 texture_data[i] = 0x20406080;
19353 /* Prepare textures */
19354 m_goku.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]);
19356 m_gohan.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]);
19358 m_goten.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]);
19360 m_chichi.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]);
19362 /* Attach textures to framebuffer */
19363 framebuffer.Bind();
19364 framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0 + m_goku_location, m_goku.m_id, m_width, m_height);
19365 framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0 + m_gohan_location, m_gohan.m_id, m_width, m_height);
19366 framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0 + m_goten_location, m_goten.m_id, m_width, m_height);
19367 framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0 + m_chichi_location, m_chichi.m_id, m_width, m_height);
19369 /* Set up drawbuffers */
19370 const Functions& gl = m_context.getRenderContext().getFunctions();
19371 // The fragment shader can have more than 4 color outputs, but it only care about 4 (goku, gohan, goten, chichi).
19372 // We will first initialize all draw buffers to NONE and then set the real value for the 4 outputs we care about
19373 GLint maxDrawBuffers = 0;
19374 gl.getIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
19376 std::vector<GLenum> buffers(maxDrawBuffers, GL_NONE);
19377 buffers[m_chichi_location] = GLenum(GL_COLOR_ATTACHMENT0 + m_chichi_location);
19378 buffers[m_goten_location] = GLenum(GL_COLOR_ATTACHMENT0 + m_goten_location);
19379 buffers[m_goku_location] = GLenum(GL_COLOR_ATTACHMENT0 + m_goku_location);
19380 buffers[m_gohan_location] = GLenum(GL_COLOR_ATTACHMENT0 + m_gohan_location);
19382 gl.drawBuffers(maxDrawBuffers, buffers.data());
19383 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawBuffers");
19388 * @param context Test framework context
19390 XFBInputTest::XFBInputTest(deqp::Context& context)
19391 : NegativeTestBase(context, "xfb_input",
19392 "Test verifies that compiler reports error when xfb qualifiers are used with input")
19396 /** Source for given test case and stage
19398 * @param test_case_index Index of test case
19399 * @param stage Shader stage
19401 * @return Shader source
19403 std::string XFBInputTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
19405 static const GLchar* buffer_var_definition = "layout (xfb_buffer = 2) in vec4 gohanARRAY;\n";
19406 static const GLchar* offset_var_definition = "layout (xfb_offset = 16) in vec4 gohanARRAY;\n";
19407 static const GLchar* stride_var_definition = "layout (xfb_stride = 32) in vec4 gohanARRAY;\n";
19408 static const GLchar* input_use = " result += gohanINDEX;\n";
19409 static const GLchar* fs = "#version 430 core\n"
19410 "#extension GL_ARB_enhanced_layouts : require\n"
19413 "out vec4 fs_out;\n"
19417 " fs_out = gs_fs;\n"
19420 static const GLchar* fs_tested = "#version 430 core\n"
19421 "#extension GL_ARB_enhanced_layouts : require\n"
19426 "out vec4 fs_out;\n"
19430 " vec4 result = gs_fs;\n"
19434 " fs_out = result;\n"
19437 static const GLchar* gs = "#version 430 core\n"
19438 "#extension GL_ARB_enhanced_layouts : require\n"
19440 "layout(points) in;\n"
19441 "layout(triangle_strip, max_vertices = 4) out;\n"
19443 "in vec4 tes_gs[];\n"
19444 "out vec4 gs_fs;\n"
19448 " gs_fs = tes_gs[0];\n"
19449 " gl_Position = vec4(-1, -1, 0, 1);\n"
19451 " gs_fs = tes_gs[0];\n"
19452 " gl_Position = vec4(-1, 1, 0, 1);\n"
19454 " gs_fs = tes_gs[0];\n"
19455 " gl_Position = vec4(1, -1, 0, 1);\n"
19457 " gs_fs = tes_gs[0];\n"
19458 " gl_Position = vec4(1, 1, 0, 1);\n"
19462 static const GLchar* gs_tested = "#version 430 core\n"
19463 "#extension GL_ARB_enhanced_layouts : require\n"
19465 "layout(points) in;\n"
19466 "layout(triangle_strip, max_vertices = 4) out;\n"
19470 "in vec4 tes_gs[];\n"
19471 "out vec4 gs_fs;\n"
19475 " vec4 result = tes_gs[0];\n"
19479 " gs_fs = result;\n"
19480 " gl_Position = vec4(-1, -1, 0, 1);\n"
19482 " gs_fs = result;\n"
19483 " gl_Position = vec4(-1, 1, 0, 1);\n"
19485 " gs_fs = result;\n"
19486 " gl_Position = vec4(1, -1, 0, 1);\n"
19488 " gs_fs = result;\n"
19489 " gl_Position = vec4(1, 1, 0, 1);\n"
19493 static const GLchar* tcs = "#version 430 core\n"
19494 "#extension GL_ARB_enhanced_layouts : require\n"
19496 "layout(vertices = 1) out;\n"
19498 "in vec4 vs_tcs[];\n"
19499 "out vec4 tcs_tes[];\n"
19504 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
19506 " gl_TessLevelOuter[0] = 1.0;\n"
19507 " gl_TessLevelOuter[1] = 1.0;\n"
19508 " gl_TessLevelOuter[2] = 1.0;\n"
19509 " gl_TessLevelOuter[3] = 1.0;\n"
19510 " gl_TessLevelInner[0] = 1.0;\n"
19511 " gl_TessLevelInner[1] = 1.0;\n"
19514 static const GLchar* tcs_tested = "#version 430 core\n"
19515 "#extension GL_ARB_enhanced_layouts : require\n"
19517 "layout(vertices = 1) out;\n"
19521 "in vec4 vs_tcs[];\n"
19522 "out vec4 tcs_tes[];\n"
19526 " vec4 result = vs_tcs[gl_InvocationID];\n"
19530 " tcs_tes[gl_InvocationID] = result;\n"
19532 " gl_TessLevelOuter[0] = 1.0;\n"
19533 " gl_TessLevelOuter[1] = 1.0;\n"
19534 " gl_TessLevelOuter[2] = 1.0;\n"
19535 " gl_TessLevelOuter[3] = 1.0;\n"
19536 " gl_TessLevelInner[0] = 1.0;\n"
19537 " gl_TessLevelInner[1] = 1.0;\n"
19540 static const GLchar* tes = "#version 430 core\n"
19541 "#extension GL_ARB_enhanced_layouts : require\n"
19543 "layout(isolines, point_mode) in;\n"
19545 "in vec4 tcs_tes[];\n"
19546 "out vec4 tes_gs;\n"
19550 " tes_gs = tcs_tes[0];\n"
19553 static const GLchar* tes_tested = "#version 430 core\n"
19554 "#extension GL_ARB_enhanced_layouts : require\n"
19556 "layout(isolines, point_mode) in;\n"
19560 "in vec4 tcs_tes[];\n"
19561 "out vec4 tes_gs;\n"
19565 " vec4 result = tcs_tes[0];\n"
19569 " tes_gs += result;\n"
19572 static const GLchar* vs = "#version 430 core\n"
19573 "#extension GL_ARB_enhanced_layouts : require\n"
19576 "out vec4 vs_tcs;\n"
19580 " vs_tcs = in_vs;\n"
19583 static const GLchar* vs_tested = "#version 430 core\n"
19584 "#extension GL_ARB_enhanced_layouts : require\n"
19589 "out vec4 vs_tcs;\n"
19593 " vec4 result = in_vs;\n"
19597 " vs_tcs += result;\n"
19601 std::string source;
19602 testCase& test_case = m_test_cases[test_case_index];
19604 if (test_case.m_stage == stage)
19606 const GLchar* array = "";
19607 const GLchar* index = "";
19608 size_t position = 0;
19610 const GLchar* var_definition = 0;
19611 const GLchar* var_use = input_use;
19613 switch (test_case.m_qualifier)
19616 var_definition = buffer_var_definition;
19619 var_definition = offset_var_definition;
19622 var_definition = stride_var_definition;
19625 TCU_FAIL("Invalid enum");
19630 case Utils::Shader::FRAGMENT:
19631 source = fs_tested;
19633 case Utils::Shader::GEOMETRY:
19634 source = gs_tested;
19638 case Utils::Shader::TESS_CTRL:
19639 source = tcs_tested;
19641 index = "[gl_InvocationID]";
19643 case Utils::Shader::TESS_EVAL:
19644 source = tes_tested;
19648 case Utils::Shader::VERTEX:
19649 source = vs_tested;
19652 TCU_FAIL("Invalid enum");
19656 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
19658 Utils::replaceToken("ARRAY", position, array, source);
19659 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
19661 Utils::replaceAllTokens("INDEX", index, source);
19667 case Utils::Shader::FRAGMENT:
19670 case Utils::Shader::GEOMETRY:
19673 case Utils::Shader::TESS_CTRL:
19676 case Utils::Shader::TESS_EVAL:
19679 case Utils::Shader::VERTEX:
19683 TCU_FAIL("Invalid enum");
19690 /** Get description of test case
19692 * @param test_case_index Index of test case
19694 * @return Test case description
19696 std::string XFBInputTest::getTestCaseName(GLuint test_case_index)
19698 std::stringstream stream;
19699 testCase& test_case = m_test_cases[test_case_index];
19701 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", qualifier: ";
19703 switch (test_case.m_qualifier)
19706 stream << "xfb_buffer";
19709 stream << "xfb_offset";
19712 stream << "xfb_stride";
19715 TCU_FAIL("Invalid enum");
19718 return stream.str();
19721 /** Get number of test cases
19723 * @return Number of test cases
19725 GLuint XFBInputTest::getTestCaseNumber()
19727 return static_cast<GLuint>(m_test_cases.size());
19730 /** Selects if "compute" stage is relevant for test
19736 bool XFBInputTest::isComputeRelevant(GLuint /* test_case_index */)
19741 /** Prepare all test cases
19744 void XFBInputTest::testInit()
19746 for (GLuint qualifier = 0; qualifier < QUALIFIERS_MAX; ++qualifier)
19748 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
19750 if (Utils::Shader::COMPUTE == stage)
19755 testCase test_case = { (QUALIFIERS)qualifier, (Utils::Shader::STAGES)stage };
19757 m_test_cases.push_back(test_case);
19762 /* Constants used by XFBAllStagesTest */
19763 const GLuint XFBAllStagesTest::m_gs_index = 3;
19767 * @param context Test context
19769 XFBAllStagesTest::XFBAllStagesTest(deqp::Context& context)
19770 : BufferTestBase(context, "xfb_all_stages",
19771 "Test verifies that only last stage in vertex processing can output to transform feedback")
19773 /* Nothing to be done here */
19776 /** Get descriptors of buffers necessary for test
19779 * @param out_descriptors Descriptors of buffers used by test
19781 void XFBAllStagesTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
19782 bufferDescriptor::Vector& out_descriptors)
19784 static const GLuint n_stages = 4;
19785 const Utils::Type& vec4 = Utils::Type::vec4;
19790 /* Test uses single uniform and xfb per stage + uniform for fragment shader */
19791 out_descriptors.resize(n_stages * 2 + 1);
19794 for (GLuint i = 0; i < n_stages; ++i)
19796 /* Get references */
19797 bufferDescriptor& uniform = out_descriptors[i + 0];
19798 bufferDescriptor& xfb = out_descriptors[i + n_stages];
19801 uniform.m_index = i;
19805 uniform.m_target = Utils::Buffer::Uniform;
19806 xfb.m_target = Utils::Buffer::Transform_feedback;
19809 const tcu::Vec4 var(Utils::GetRandFloat(), Utils::GetRandFloat(), Utils::GetRandFloat(), Utils::GetRandFloat());
19813 uniform.m_initial_data.resize(vec4.GetSize());
19814 memcpy(&uniform.m_initial_data[0], var.getPtr(), vec4.GetSize());
19816 xfb.m_initial_data = vec4.GenerateDataPacked();
19818 if (m_gs_index != i)
19820 xfb.m_expected_data = xfb.m_initial_data;
19824 xfb.m_expected_data.resize(vec4.GetSize());
19825 memcpy(&xfb.m_expected_data[0], sum.getPtr(), vec4.GetSize());
19831 /* Get reference */
19832 bufferDescriptor& uniform = out_descriptors[n_stages * 2];
19835 uniform.m_index = n_stages;
19838 uniform.m_target = Utils::Buffer::Uniform;
19841 const tcu::Vec4 var(Utils::GetRandFloat(), Utils::GetRandFloat(), Utils::GetRandFloat(), Utils::GetRandFloat());
19843 uniform.m_initial_data.resize(vec4.GetSize());
19844 memcpy(&uniform.m_initial_data[0], var.getPtr(), vec4.GetSize());
19848 /** Get body of main function for given shader stage
19851 * @param stage Shader stage
19852 * @param out_assignments Set to empty
19853 * @param out_calculations Set to empty
19855 void XFBAllStagesTest::getShaderBody(glw::GLuint /* test_case_index */, Utils::Shader::STAGES stage,
19856 std::string& out_assignments, std::string& out_calculations)
19858 out_calculations = "";
19860 static const GLchar* vs = " vs_tcs = uni_vs;\n";
19861 static const GLchar* tcs = " tcs_tes[gl_InvocationID] = uni_tcs + vs_tcs[gl_InvocationID];\n";
19862 static const GLchar* tes = " tes_gs = uni_tes + tcs_tes[0];\n";
19863 static const GLchar* gs = " gs_fs = uni_gs + tes_gs[0];\n";
19864 static const GLchar* fs = " fs_out = uni_fs + gs_fs;\n";
19866 const GLchar* assignments = 0;
19869 case Utils::Shader::FRAGMENT:
19872 case Utils::Shader::GEOMETRY:
19875 case Utils::Shader::TESS_CTRL:
19878 case Utils::Shader::TESS_EVAL:
19881 case Utils::Shader::VERTEX:
19885 TCU_FAIL("Invalid enum");
19888 out_assignments = assignments;
19891 /** Get interface of shader
19894 * @param stage Shader stage
19895 * @param out_interface Set to ""
19897 void XFBAllStagesTest::getShaderInterface(glw::GLuint /* test_case_index */, Utils::Shader::STAGES stage,
19898 std::string& out_interface)
19900 static const GLchar* vs = "layout(xfb_buffer = 0, xfb_offset = 0) out vec4 vs_tcs;\n"
19901 "layout(binding = 0) uniform vs_block {\n"
19904 static const GLchar* tcs = " in vec4 vs_tcs[];\n"
19905 "layout(xfb_buffer = 1, xfb_offset = 0) out vec4 tcs_tes[1];\n"
19906 "layout(binding = 1) uniform tcs_block {\n"
19909 static const GLchar* tes = " in vec4 tcs_tes[];\n"
19910 "layout(xfb_buffer = 2, xfb_offset = 0) out vec4 tes_gs;\n"
19911 "layout(binding = 2) uniform tes_block {\n"
19914 static const GLchar* gs = " in vec4 tes_gs[];\n"
19915 "layout(xfb_buffer = 3, xfb_offset = 0) out vec4 gs_fs;\n"
19916 "layout(binding = 3) uniform gs_block {\n"
19919 static const GLchar* fs = " in vec4 gs_fs;\n"
19920 " out vec4 fs_out;\n"
19921 "layout(binding = 4) uniform fs_block {\n"
19925 const GLchar* interface = 0;
19928 case Utils::Shader::FRAGMENT:
19931 case Utils::Shader::GEOMETRY:
19934 case Utils::Shader::TESS_CTRL:
19937 case Utils::Shader::TESS_EVAL:
19940 case Utils::Shader::VERTEX:
19944 TCU_FAIL("Invalid enum");
19947 out_interface = interface;
19950 /* Constants used by XFBStrideOfEmptyListTest */
19951 const GLuint XFBStrideOfEmptyListTest::m_stride = 64;
19955 * @param context Test context
19957 XFBStrideOfEmptyListTest::XFBStrideOfEmptyListTest(deqp::Context& context)
19958 : BufferTestBase(context, "xfb_stride_of_empty_list",
19959 "Test verifies that xfb_stride qualifier is respected when no xfb_offset is specified")
19961 /* Nothing to be done here */
19964 /** Execute drawArrays for single vertex
19966 * @param test_case_index Index of test case
19968 * @return true if proper error is reported
19970 bool XFBStrideOfEmptyListTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
19972 const Functions& gl = m_context.getRenderContext().getFunctions();
19973 bool result = true;
19976 gl.disable(GL_RASTERIZER_DISCARD);
19977 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
19979 gl.beginTransformFeedback(GL_POINTS);
19980 GLenum error = gl.getError();
19981 switch (test_case_index)
19984 if (GL_NO_ERROR != error)
19986 gl.endTransformFeedback();
19987 GLU_EXPECT_NO_ERROR(error, "BeginTransformFeedback");
19990 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
19991 error = gl.getError();
19993 gl.endTransformFeedback();
19994 GLU_EXPECT_NO_ERROR(error, "DrawArrays");
19995 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
19999 case FIRST_MISSING:
20000 if (GL_NO_ERROR == error)
20002 gl.endTransformFeedback();
20005 if (GL_INVALID_OPERATION != error)
20007 m_context.getTestContext().getLog()
20008 << tcu::TestLog::Message << "XFB at index 0, that is written by GS, is missing. It was expected that "
20009 "INVALID_OPERATION will generated by BeginTransformFeedback. Got: "
20010 << glu::getErrorStr(error) << tcu::TestLog::EndMessage;
20017 case SECOND_MISSING:
20018 if (GL_NO_ERROR == error)
20020 gl.endTransformFeedback();
20023 if (GL_INVALID_OPERATION != error)
20025 m_context.getTestContext().getLog()
20026 << tcu::TestLog::Message << "XFB at index 1, that is declared as empty, is missing. It was expected "
20027 "that INVALID_OPERATION will generated by BeginTransformFeedback. Got: "
20028 << glu::getErrorStr(error) << tcu::TestLog::EndMessage;
20040 /** Get descriptors of buffers necessary for test
20042 * @param test_case_index Index of test case
20043 * @param out_descriptors Descriptors of buffers used by test
20045 void XFBStrideOfEmptyListTest::getBufferDescriptors(glw::GLuint test_case_index,
20046 bufferDescriptor::Vector& out_descriptors)
20048 switch (test_case_index)
20052 /* Test needs single uniform and two xfbs */
20053 out_descriptors.resize(3);
20055 /* Get references */
20056 bufferDescriptor& uniform = out_descriptors[0];
20057 bufferDescriptor& xfb_0 = out_descriptors[1];
20058 bufferDescriptor& xfb_1 = out_descriptors[2];
20061 uniform.m_index = 0;
20066 uniform.m_target = Utils::Buffer::Uniform;
20067 xfb_0.m_target = Utils::Buffer::Transform_feedback;
20068 xfb_1.m_target = Utils::Buffer::Transform_feedback;
20071 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20073 xfb_0.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20074 xfb_0.m_expected_data = uniform.m_initial_data;
20076 /* Data, contents are the same as no modification is expected */
20077 xfb_1.m_initial_data.resize(m_stride);
20078 xfb_1.m_expected_data.resize(m_stride);
20080 for (GLuint i = 0; i < m_stride; ++i)
20082 xfb_1.m_initial_data[0] = (glw::GLubyte)i;
20083 xfb_1.m_expected_data[0] = (glw::GLubyte)i;
20089 case FIRST_MISSING:
20091 /* Test needs single uniform and two xfbs */
20092 out_descriptors.resize(2);
20094 /* Get references */
20095 bufferDescriptor& uniform = out_descriptors[0];
20096 bufferDescriptor& xfb_1 = out_descriptors[1];
20099 uniform.m_index = 0;
20103 uniform.m_target = Utils::Buffer::Uniform;
20104 xfb_1.m_target = Utils::Buffer::Transform_feedback;
20107 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20109 /* Draw call will not be executed, contents does not matter */
20110 xfb_1.m_initial_data.resize(m_stride);
20115 case SECOND_MISSING:
20117 /* Test needs single uniform and two xfbs */
20118 out_descriptors.resize(2);
20120 /* Get references */
20121 bufferDescriptor& uniform = out_descriptors[0];
20122 bufferDescriptor& xfb_0 = out_descriptors[1];
20125 uniform.m_index = 0;
20129 uniform.m_target = Utils::Buffer::Uniform;
20130 xfb_0.m_target = Utils::Buffer::Transform_feedback;
20133 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20135 /* Draw call will not be executed, contents does not matter */
20136 xfb_0.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20143 /** Get body of main function for given shader stage
20146 * @param stage Shader stage
20147 * @param out_assignments Set to empty
20148 * @param out_calculations Set to empty
20150 void XFBStrideOfEmptyListTest::getShaderBody(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
20151 std::string& out_assignments, std::string& out_calculations)
20153 out_calculations = "";
20155 static const GLchar* gs = " gs_fs = uni_gs;\n";
20156 static const GLchar* fs = " fs_out = vec4(gs_fs);\n";
20158 const GLchar* assignments = "";
20161 case Utils::Shader::FRAGMENT:
20164 case Utils::Shader::GEOMETRY:
20171 out_assignments = assignments;
20174 /** Get interface of shader
20177 * @param stage Shader stage
20178 * @param out_interface Set to ""
20180 void XFBStrideOfEmptyListTest::getShaderInterface(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
20181 std::string& out_interface)
20183 static const GLchar* gs = "layout (xfb_buffer = 0, xfb_offset = 0) out vec4 gs_fs;\n"
20184 "layout (xfb_buffer = 1, xfb_stride = 64) out;\n"
20186 "layout (binding = 0) uniform gs_block {\n"
20189 static const GLchar* fs = "in vec4 gs_fs;\n"
20190 "out vec4 fs_out;\n";
20194 case Utils::Shader::FRAGMENT:
20195 out_interface = fs;
20197 case Utils::Shader::GEOMETRY:
20198 out_interface = gs;
20201 out_interface = "";
20206 /** Returns buffer details in human readable form.
20208 * @param test_case_index Index of test case
20210 * @return Case description
20212 std::string XFBStrideOfEmptyListTest::getTestCaseName(GLuint test_case_index)
20214 std::string result;
20216 switch (test_case_index)
20219 result = "Valid case";
20221 case FIRST_MISSING:
20222 result = "Missing xfb at index 0";
20224 case SECOND_MISSING:
20225 result = "Missing xfb at index 1";
20228 TCU_FAIL("Invalid enum");
20234 /** Get number of test cases
20238 GLuint XFBStrideOfEmptyListTest::getTestCaseNumber()
20243 /* Constants used by XFBStrideOfEmptyListTest */
20244 const GLuint XFBStrideOfEmptyListAndAPITest::m_stride = 64;
20248 * @param context Test context
20250 XFBStrideOfEmptyListAndAPITest::XFBStrideOfEmptyListAndAPITest(deqp::Context& context)
20251 : BufferTestBase(context, "xfb_stride_of_empty_list_and_api",
20252 "Test verifies that xfb_stride qualifier is not overriden by API")
20254 /* Nothing to be done here */
20257 /** Execute drawArrays for single vertex
20259 * @param test_case_index Index of test case
20261 * @return true if proper error is reported
20263 bool XFBStrideOfEmptyListAndAPITest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
20265 const Functions& gl = m_context.getRenderContext().getFunctions();
20266 bool result = true;
20269 gl.disable(GL_RASTERIZER_DISCARD);
20270 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
20272 gl.beginTransformFeedback(GL_POINTS);
20273 GLenum error = gl.getError();
20274 switch (test_case_index)
20277 if (GL_NO_ERROR != error)
20279 gl.endTransformFeedback();
20280 GLU_EXPECT_NO_ERROR(error, "BeginTransformFeedback");
20283 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
20284 error = gl.getError();
20286 gl.endTransformFeedback();
20287 GLU_EXPECT_NO_ERROR(error, "DrawArrays");
20288 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
20292 case FIRST_MISSING:
20293 if (GL_NO_ERROR == error)
20295 gl.endTransformFeedback();
20298 if (GL_INVALID_OPERATION != error)
20300 m_context.getTestContext().getLog()
20301 << tcu::TestLog::Message << "XFB at index 0, that is declared as empty, is missing. It was expected "
20302 "that INVALID_OPERATION will generated by BeginTransformFeedback. Got: "
20303 << glu::getErrorStr(error) << tcu::TestLog::EndMessage;
20310 case SECOND_MISSING:
20311 if (GL_NO_ERROR == error)
20313 gl.endTransformFeedback();
20316 if (GL_INVALID_OPERATION != error)
20318 m_context.getTestContext().getLog()
20319 << tcu::TestLog::Message << "XFB at index 1, that is written by GS, is missing. It was expected that "
20320 "INVALID_OPERATION will generated by BeginTransformFeedback. Got: "
20321 << glu::getErrorStr(error) << tcu::TestLog::EndMessage;
20333 /** Get descriptors of buffers necessary for test
20335 * @param test_case_index Index of test case
20336 * @param out_descriptors Descriptors of buffers used by test
20338 void XFBStrideOfEmptyListAndAPITest::getBufferDescriptors(glw::GLuint test_case_index,
20339 bufferDescriptor::Vector& out_descriptors)
20341 switch (test_case_index)
20345 /* Test needs single uniform and two xfbs */
20346 out_descriptors.resize(3);
20348 /* Get references */
20349 bufferDescriptor& uniform = out_descriptors[0];
20350 bufferDescriptor& xfb_0 = out_descriptors[1];
20351 bufferDescriptor& xfb_1 = out_descriptors[2];
20354 uniform.m_index = 0;
20359 uniform.m_target = Utils::Buffer::Uniform;
20360 xfb_0.m_target = Utils::Buffer::Transform_feedback;
20361 xfb_1.m_target = Utils::Buffer::Transform_feedback;
20364 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20366 /* Data, contents are the same as no modification is expected */
20367 xfb_0.m_initial_data.resize(m_stride);
20368 xfb_0.m_expected_data.resize(m_stride);
20370 for (GLuint i = 0; i < m_stride; ++i)
20372 xfb_0.m_initial_data[0] = (glw::GLubyte)i;
20373 xfb_0.m_expected_data[0] = (glw::GLubyte)i;
20376 xfb_1.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20377 xfb_1.m_expected_data = uniform.m_initial_data;
20382 case FIRST_MISSING:
20384 /* Test needs single uniform and two xfbs */
20385 out_descriptors.resize(2);
20387 /* Get references */
20388 bufferDescriptor& uniform = out_descriptors[0];
20389 bufferDescriptor& xfb_1 = out_descriptors[1];
20392 uniform.m_index = 0;
20396 uniform.m_target = Utils::Buffer::Uniform;
20397 xfb_1.m_target = Utils::Buffer::Transform_feedback;
20400 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20402 /* Draw call will not be executed, contents does not matter */
20403 xfb_1.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20408 case SECOND_MISSING:
20410 /* Test needs single uniform and two xfbs */
20411 out_descriptors.resize(2);
20413 /* Get references */
20414 bufferDescriptor& uniform = out_descriptors[0];
20415 bufferDescriptor& xfb_0 = out_descriptors[1];
20418 uniform.m_index = 0;
20422 uniform.m_target = Utils::Buffer::Uniform;
20423 xfb_0.m_target = Utils::Buffer::Transform_feedback;
20426 uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20428 /* Draw call will not be executed, contents does not matter */
20429 xfb_0.m_initial_data.resize(m_stride);
20436 /** Get list of names of varyings that will be registered with TransformFeedbackVaryings
20439 * @param captured_varyings Vector of varying names to be captured
20441 void XFBStrideOfEmptyListAndAPITest::getCapturedVaryings(glw::GLuint /* test_case_index */,
20442 Utils::Program::NameVector& captured_varyings)
20444 captured_varyings.push_back("gs_fs");
20447 /** Get body of main function for given shader stage
20450 * @param stage Shader stage
20451 * @param out_assignments Set to empty
20452 * @param out_calculations Set to empty
20454 void XFBStrideOfEmptyListAndAPITest::getShaderBody(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
20455 std::string& out_assignments, std::string& out_calculations)
20457 out_calculations = "";
20459 static const GLchar* gs = " gs_fs = uni_gs;\n";
20460 static const GLchar* fs = " fs_out = vec4(gs_fs);\n";
20462 const GLchar* assignments = "";
20465 case Utils::Shader::FRAGMENT:
20468 case Utils::Shader::GEOMETRY:
20475 out_assignments = assignments;
20478 /** Get interface of shader
20481 * @param stage Shader stage
20482 * @param out_interface Set to ""
20484 void XFBStrideOfEmptyListAndAPITest::getShaderInterface(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
20485 std::string& out_interface)
20487 static const GLchar* gs = "layout (xfb_buffer = 0, xfb_stride = 64) out;\n"
20488 "layout (xfb_buffer = 1, xfb_offset = 0) out vec4 gs_fs;\n"
20490 "layout(binding = 0) uniform gs_block {\n"
20493 static const GLchar* fs = "in vec4 gs_fs;\n"
20494 "out vec4 fs_out;\n";
20498 case Utils::Shader::FRAGMENT:
20499 out_interface = fs;
20501 case Utils::Shader::GEOMETRY:
20502 out_interface = gs;
20505 out_interface = "";
20510 /** Returns buffer details in human readable form.
20512 * @param test_case_index Index of test case
20514 * @return Case description
20516 std::string XFBStrideOfEmptyListAndAPITest::getTestCaseName(GLuint test_case_index)
20518 std::string result;
20520 switch (test_case_index)
20523 result = "Valid case";
20525 case FIRST_MISSING:
20526 result = "Missing xfb at index 0";
20528 case SECOND_MISSING:
20529 result = "Missing xfb at index 1";
20532 TCU_FAIL("Invalid enum");
20538 /** Get number of test cases
20542 GLuint XFBStrideOfEmptyListAndAPITest::getTestCaseNumber()
20549 * @param context Test framework context
20551 XFBTooSmallStrideTest::XFBTooSmallStrideTest(deqp::Context& context)
20552 : NegativeTestBase(context, "xfb_too_small_stride",
20553 "Test verifies that compiler reports error when xfb_stride sets not enough space")
20557 /** Source for given test case and stage
20559 * @param test_case_index Index of test case
20560 * @param stage Shader stage
20562 * @return Shader source
20564 std::string XFBTooSmallStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
20566 static const GLchar* array_var_definition = "layout (xfb_buffer = 0, xfb_stride = 32) out;\n"
20568 "layout (xfb_offset = 16) out vec4 gohanARRAY[4];\n";
20569 static const GLchar* block_var_definition = "layout (xfb_buffer = 0, xfb_stride = 32) out;\n"
20571 "layout (xfb_offset = 0) out Goku {\n"
20576 static const GLchar* offset_var_definition = "layout (xfb_buffer = 0, xfb_stride = 40) out;\n"
20578 "layout (xfb_offset = 32) out vec4 gohanARRAY;\n";
20579 // 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;"
20580 // To make the shader failed to compile, change xfb_stride to a value that is smaller than 32
20581 static const GLchar* stride_var_definition = "layout (xfb_buffer = 0, xfb_stride = 28) out;\n"
20583 "layout (xfb_offset = 16, xfb_stride = 28) out vec4 gohanARRAY;\n";
20584 static const GLchar* array_use = " gohanINDEX[0] = result / 2;\n"
20585 " gohanINDEX[1] = result / 4;\n"
20586 " gohanINDEX[2] = result / 6;\n"
20587 " gohanINDEX[3] = result / 8;\n";
20588 static const GLchar* block_use = " gokuINDEX.gohan = result / 2;\n"
20589 " gokuINDEX.goten = result / 4;\n"
20590 " gokuINDEX.chichi = result / 6;\n";
20591 static const GLchar* output_use = "gohanINDEX = result / 4;\n";
20592 static const GLchar* fs = "#version 430 core\n"
20593 "#extension GL_ARB_enhanced_layouts : require\n"
20596 "out vec4 fs_out;\n"
20600 " fs_out = gs_fs;\n"
20603 static const GLchar* gs_tested = "#version 430 core\n"
20604 "#extension GL_ARB_enhanced_layouts : require\n"
20606 "layout(points) in;\n"
20607 "layout(triangle_strip, max_vertices = 4) out;\n"
20611 "in vec4 tes_gs[];\n"
20612 "out vec4 gs_fs;\n"
20616 " vec4 result = tes_gs[0];\n"
20620 " gs_fs = result;\n"
20621 " gl_Position = vec4(-1, -1, 0, 1);\n"
20623 " gs_fs = result;\n"
20624 " gl_Position = vec4(-1, 1, 0, 1);\n"
20626 " gs_fs = result;\n"
20627 " gl_Position = vec4(1, -1, 0, 1);\n"
20629 " gs_fs = result;\n"
20630 " gl_Position = vec4(1, 1, 0, 1);\n"
20634 static const GLchar* tcs = "#version 430 core\n"
20635 "#extension GL_ARB_enhanced_layouts : require\n"
20637 "layout(vertices = 1) out;\n"
20639 "in vec4 vs_tcs[];\n"
20640 "out vec4 tcs_tes[];\n"
20645 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
20647 " gl_TessLevelOuter[0] = 1.0;\n"
20648 " gl_TessLevelOuter[1] = 1.0;\n"
20649 " gl_TessLevelOuter[2] = 1.0;\n"
20650 " gl_TessLevelOuter[3] = 1.0;\n"
20651 " gl_TessLevelInner[0] = 1.0;\n"
20652 " gl_TessLevelInner[1] = 1.0;\n"
20655 static const GLchar* tcs_tested = "#version 430 core\n"
20656 "#extension GL_ARB_enhanced_layouts : require\n"
20658 "layout(vertices = 1) out;\n"
20662 "in vec4 vs_tcs[];\n"
20663 "out vec4 tcs_tes[];\n"
20667 " vec4 result = vs_tcs[gl_InvocationID];\n"
20671 " tcs_tes[gl_InvocationID] = result;\n"
20673 " gl_TessLevelOuter[0] = 1.0;\n"
20674 " gl_TessLevelOuter[1] = 1.0;\n"
20675 " gl_TessLevelOuter[2] = 1.0;\n"
20676 " gl_TessLevelOuter[3] = 1.0;\n"
20677 " gl_TessLevelInner[0] = 1.0;\n"
20678 " gl_TessLevelInner[1] = 1.0;\n"
20681 static const GLchar* tes_tested = "#version 430 core\n"
20682 "#extension GL_ARB_enhanced_layouts : require\n"
20684 "layout(isolines, point_mode) in;\n"
20688 "in vec4 tcs_tes[];\n"
20689 "out vec4 tes_gs;\n"
20693 " vec4 result = tcs_tes[0];\n"
20697 " tes_gs += result;\n"
20700 static const GLchar* vs = "#version 430 core\n"
20701 "#extension GL_ARB_enhanced_layouts : require\n"
20704 "out vec4 vs_tcs;\n"
20708 " vs_tcs = in_vs;\n"
20711 static const GLchar* vs_tested = "#version 430 core\n"
20712 "#extension GL_ARB_enhanced_layouts : require\n"
20717 "out vec4 vs_tcs;\n"
20721 " vec4 result = in_vs;\n"
20725 " vs_tcs += result;\n"
20729 std::string source;
20730 testCase& test_case = m_test_cases[test_case_index];
20732 if (test_case.m_stage == stage)
20734 const GLchar* array = "";
20735 const GLchar* index = "";
20736 size_t position = 0;
20738 const GLchar* var_definition = 0;
20739 const GLchar* var_use = 0;
20741 switch (test_case.m_case)
20744 var_definition = offset_var_definition;
20745 var_use = output_use;
20748 var_definition = stride_var_definition;
20749 var_use = output_use;
20752 var_definition = block_var_definition;
20753 var_use = block_use;
20756 var_definition = array_var_definition;
20757 var_use = array_use;
20760 TCU_FAIL("Invalid enum");
20765 case Utils::Shader::GEOMETRY:
20766 source = gs_tested;
20770 case Utils::Shader::TESS_CTRL:
20771 source = tcs_tested;
20773 index = "[gl_InvocationID]";
20775 case Utils::Shader::TESS_EVAL:
20776 source = tes_tested;
20780 case Utils::Shader::VERTEX:
20781 source = vs_tested;
20784 TCU_FAIL("Invalid enum");
20788 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
20790 Utils::replaceToken("ARRAY", position, array, source);
20791 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
20793 Utils::replaceAllTokens("INDEX", index, source);
20797 switch (test_case.m_stage)
20799 case Utils::Shader::GEOMETRY:
20802 case Utils::Shader::FRAGMENT:
20805 case Utils::Shader::VERTEX:
20812 case Utils::Shader::TESS_CTRL:
20815 case Utils::Shader::FRAGMENT:
20818 case Utils::Shader::VERTEX:
20825 case Utils::Shader::TESS_EVAL:
20828 case Utils::Shader::FRAGMENT:
20831 case Utils::Shader::TESS_CTRL:
20834 case Utils::Shader::VERTEX:
20841 case Utils::Shader::VERTEX:
20844 case Utils::Shader::FRAGMENT:
20852 TCU_FAIL("Invalid enum");
20860 /** Get description of test case
20862 * @param test_case_index Index of test case
20864 * @return Test case description
20866 std::string XFBTooSmallStrideTest::getTestCaseName(GLuint test_case_index)
20868 std::stringstream stream;
20869 testCase& test_case = m_test_cases[test_case_index];
20871 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", case: ";
20873 switch (test_case.m_case)
20876 stream << "buffer stride: 40, vec4 offset: 32";
20879 stream << "buffer stride: 32, vec4 off 16 stride: 32";
20882 stream << "buffer stride: 32, block 3xvec4 offset 0";
20885 stream << "buffer stride: 32, vec4[4] offset 16";
20888 TCU_FAIL("Invalid enum");
20891 return stream.str();
20894 /** Get number of test cases
20896 * @return Number of test cases
20898 GLuint XFBTooSmallStrideTest::getTestCaseNumber()
20900 return static_cast<GLuint>(m_test_cases.size());
20903 /** Selects if "compute" stage is relevant for test
20909 bool XFBTooSmallStrideTest::isComputeRelevant(GLuint /* test_case_index */)
20914 /** Prepare all test cases
20917 void XFBTooSmallStrideTest::testInit()
20919 for (GLuint c = 0; c < CASE_MAX; ++c)
20921 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
20924 It is invalid to define transform feedback output in TCS, according to spec:
20925 The data captured in transform feedback mode depends on the active programs on each of the shader stages.
20926 If a program is active for the geometry shader stage, transform feedback captures the vertices of each
20927 primitive emitted by the geometry shader. Otherwise, if a program is active for the tessellation evaluation
20928 shader stage, transform feedback captures each primitive produced by the tessellation primitive generator,
20929 whose vertices are processed by the tessellation evaluation shader. Otherwise, transform feedback captures
20930 each primitive processed by the vertex shader.
20932 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
20933 (Utils::Shader::FRAGMENT == stage))
20938 testCase test_case = { (CASES)c, (Utils::Shader::STAGES)stage };
20940 m_test_cases.push_back(test_case);
20947 * @param context Test framework context
20949 XFBVariableStrideTest::XFBVariableStrideTest(deqp::Context& context)
20950 : NegativeTestBase(context, "xfb_variable_stride", "Test verifies that stride qualifier is respected")
20954 /** Source for given test case and stage
20956 * @param test_case_index Index of test case
20957 * @param stage Shader stage
20959 * @return Shader source
20961 std::string XFBVariableStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
20963 static const GLchar* invalid_var_definition =
20964 "const uint type_size = SIZE;\n"
20966 "layout (xfb_offset = 0, xfb_stride = 2 * type_size) out TYPE gokuARRAY;\n"
20967 "layout (xfb_offset = type_size) out TYPE vegetaARRAY;\n";
20968 static const GLchar* valid_var_definition =
20969 "const uint type_size = SIZE;\n"
20971 "layout (xfb_offset = 0, xfb_stride = 2 * type_size) out TYPE gokuARRAY;\n";
20972 static const GLchar* invalid_use = " gokuINDEX = TYPE(1);\n"
20973 " vegetaINDEX = TYPE(0);\n"
20974 " if (vec4(0) == result)\n"
20976 " gokuINDEX = TYPE(0);\n"
20977 " vegetaINDEX = TYPE(1);\n"
20979 static const GLchar* valid_use = " gokuINDEX = TYPE(1);\n"
20980 " if (vec4(0) == result)\n"
20982 " gokuINDEX = TYPE(0);\n"
20984 static const GLchar* fs = "#version 430 core\n"
20985 "#extension GL_ARB_enhanced_layouts : require\n"
20987 "in vec4 any_fs;\n"
20988 "out vec4 fs_out;\n"
20992 " fs_out = any_fs;\n"
20995 static const GLchar* gs_tested = "#version 430 core\n"
20996 "#extension GL_ARB_enhanced_layouts : require\n"
20998 "layout(points) in;\n"
20999 "layout(triangle_strip, max_vertices = 4) out;\n"
21003 "in vec4 vs_any[];\n"
21004 "out vec4 any_fs;\n"
21008 " vec4 result = vs_any[0];\n"
21012 " any_fs = result;\n"
21013 " gl_Position = vec4(-1, -1, 0, 1);\n"
21015 " any_fs = result;\n"
21016 " gl_Position = vec4(-1, 1, 0, 1);\n"
21018 " any_fs = result;\n"
21019 " gl_Position = vec4(1, -1, 0, 1);\n"
21021 " any_fs = result;\n"
21022 " gl_Position = vec4(1, 1, 0, 1);\n"
21026 static const GLchar* tcs = "#version 430 core\n"
21027 "#extension GL_ARB_enhanced_layouts : require\n"
21029 "layout(vertices = 1) out;\n"
21031 "in vec4 vs_any[];\n"
21032 "out vec4 tcs_tes[];\n"
21037 " tcs_tes[gl_InvocationID] = vs_any[gl_InvocationID];\n"
21039 " gl_TessLevelOuter[0] = 1.0;\n"
21040 " gl_TessLevelOuter[1] = 1.0;\n"
21041 " gl_TessLevelOuter[2] = 1.0;\n"
21042 " gl_TessLevelOuter[3] = 1.0;\n"
21043 " gl_TessLevelInner[0] = 1.0;\n"
21044 " gl_TessLevelInner[1] = 1.0;\n"
21047 static const GLchar* tcs_tested = "#version 430 core\n"
21048 "#extension GL_ARB_enhanced_layouts : require\n"
21050 "layout(vertices = 1) out;\n"
21054 "in vec4 vs_any[];\n"
21055 "out vec4 any_fs[];\n"
21059 " vec4 result = vs_any[gl_InvocationID];\n"
21063 " any_fs[gl_InvocationID] = result;\n"
21065 " gl_TessLevelOuter[0] = 1.0;\n"
21066 " gl_TessLevelOuter[1] = 1.0;\n"
21067 " gl_TessLevelOuter[2] = 1.0;\n"
21068 " gl_TessLevelOuter[3] = 1.0;\n"
21069 " gl_TessLevelInner[0] = 1.0;\n"
21070 " gl_TessLevelInner[1] = 1.0;\n"
21073 static const GLchar* tes_tested = "#version 430 core\n"
21074 "#extension GL_ARB_enhanced_layouts : require\n"
21076 "layout(isolines, point_mode) in;\n"
21080 "in vec4 tcs_tes[];\n"
21081 "out vec4 any_fs;\n"
21085 " vec4 result = tcs_tes[0];\n"
21089 " any_fs = result;\n"
21092 static const GLchar* vs = "#version 430 core\n"
21093 "#extension GL_ARB_enhanced_layouts : require\n"
21096 "out vec4 vs_any;\n"
21100 " vs_any = in_vs;\n"
21103 static const GLchar* vs_tested = "#version 430 core\n"
21104 "#extension GL_ARB_enhanced_layouts : require\n"
21109 "out vec4 any_fs;\n"
21113 " vec4 result = in_vs;\n"
21117 " any_fs = result;\n"
21121 std::string source;
21122 testCase& test_case = m_test_cases[test_case_index];
21124 if (test_case.m_stage == stage)
21126 const GLchar* array = "";
21128 const GLchar* index = "";
21129 size_t position = 0;
21131 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
21132 const GLchar* var_definition = 0;
21133 const GLchar* var_use = 0;
21135 sprintf(buffer, "%d", test_case.m_type.GetSize());
21137 switch (test_case.m_case)
21140 var_definition = valid_var_definition;
21141 var_use = valid_use;
21144 var_definition = invalid_var_definition;
21145 var_use = invalid_use;
21148 TCU_FAIL("Invalid enum");
21153 case Utils::Shader::GEOMETRY:
21154 source = gs_tested;
21158 case Utils::Shader::TESS_CTRL:
21159 source = tcs_tested;
21161 index = "[gl_InvocationID]";
21163 case Utils::Shader::TESS_EVAL:
21164 source = tes_tested;
21168 case Utils::Shader::VERTEX:
21169 source = vs_tested;
21172 TCU_FAIL("Invalid enum");
21176 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
21178 Utils::replaceToken("SIZE", position, buffer, source);
21179 Utils::replaceToken("ARRAY", position, array, source);
21180 if (INVALID == test_case.m_case)
21182 Utils::replaceToken("ARRAY", position, array, source);
21184 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
21186 Utils::replaceAllTokens("TYPE", type_name, source);
21187 Utils::replaceAllTokens("INDEX", index, source);
21191 switch (test_case.m_stage)
21193 case Utils::Shader::GEOMETRY:
21196 case Utils::Shader::FRAGMENT:
21199 case Utils::Shader::VERTEX:
21206 case Utils::Shader::TESS_CTRL:
21209 case Utils::Shader::FRAGMENT:
21212 case Utils::Shader::VERTEX:
21219 case Utils::Shader::TESS_EVAL:
21222 case Utils::Shader::FRAGMENT:
21225 case Utils::Shader::TESS_CTRL:
21228 case Utils::Shader::VERTEX:
21235 case Utils::Shader::VERTEX:
21238 case Utils::Shader::FRAGMENT:
21246 TCU_FAIL("Invalid enum");
21254 /** Get description of test case
21256 * @param test_case_index Index of test case
21258 * @return Test case description
21260 std::string XFBVariableStrideTest::getTestCaseName(GLuint test_case_index)
21262 std::stringstream stream;
21263 testCase& test_case = m_test_cases[test_case_index];
21265 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
21266 << ", type: " << test_case.m_type.GetGLSLTypeName() << ", case: ";
21268 switch (test_case.m_case)
21274 stream << "invalid";
21277 TCU_FAIL("Invalid enum");
21280 return stream.str();
21283 /** Get number of test cases
21285 * @return Number of test cases
21287 GLuint XFBVariableStrideTest::getTestCaseNumber()
21289 return static_cast<GLuint>(m_test_cases.size());
21292 /** Selects if "compute" stage is relevant for test
21298 bool XFBVariableStrideTest::isComputeRelevant(GLuint /* test_case_index */)
21303 /** Selects if compilation failure is expected result
21305 * @param test_case_index Index of test case
21309 bool XFBVariableStrideTest::isFailureExpected(GLuint test_case_index)
21311 testCase& test_case = m_test_cases[test_case_index];
21313 return (INVALID == test_case.m_case);
21316 /** Prepare all test cases
21319 void XFBVariableStrideTest::testInit()
21321 const GLuint n_types = getTypesNumber();
21323 for (GLuint i = 0; i < n_types; ++i)
21325 const Utils::Type& type = getType(i);
21328 Some of the cases are declared as following are considered as invalid,
21329 but accoring to spec, the following declaration is valid: shaders in the
21330 transform feedback capturing mode have an initial global default of layout(xfb_buffer=0) out,
21331 so for the first variable's declaration, the xfb_stride = 16 is applied on buffer 0, for the
21332 second variable, its buffer is also inherited from global buffer 0, and its offset does not overflows
21335 The xfb_stride is the memory width of given buffer, not for variable even though xfb_stride
21336 is declared on the variable. It seems that the writter of this case misunderstand the concept of
21337 xfb_stride, because spec describes that xfb_stride can be declared multiple times for the same buffer,
21338 it is a compile or link-time error to have different values specified for the stride for the same buffer.
21341 layout (xfb_offset = 0, xfb_stride = 2 * type_size) out double goku;
21342 layout (xfb_offset = type_size) out double vegeta;
21344 // all the shaders are valid, so remove the following loop(it contains CASE_MAX is enum of valid and invalid)
21345 // for (GLuint c = 0; c < CASE_MAX; ++c)
21347 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
21349 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
21350 (Utils::Shader::FRAGMENT == stage))
21355 testCase test_case = { (CASES)VALID, (Utils::Shader::STAGES)stage, type };
21357 m_test_cases.push_back(test_case);
21365 * @param context Test framework context
21367 XFBBlockStrideTest::XFBBlockStrideTest(deqp::Context& context)
21368 : TestBase(context, "xfb_block_stride", "Test verifies that stride qualifier is respected for blocks")
21372 /** Source for given test case and stage
21374 * @param test_case_index Index of test case
21375 * @param stage Shader stage
21377 * @return Shader source
21379 std::string XFBBlockStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
21381 static const GLchar* var_definition = "layout (xfb_offset = 0, xfb_stride = 128) out Goku {\n"
21386 static const GLchar* var_use = " gokuINDEX.gohan = vec4(1, 0, 0, 0);\n"
21387 " gokuINDEX.goten = vec4(0, 0, 1, 0);\n"
21388 " gokuINDEX.chichi = vec4(0, 1, 0, 0);\n"
21389 " if (vec4(0) == result)\n"
21391 " gokuINDEX.gohan = vec4(0, 1, 1, 1);\n"
21392 " gokuINDEX.goten = vec4(1, 1, 0, 1);\n"
21393 " gokuINDEX.chichi = vec4(1, 0, 1, 1);\n"
21395 static const GLchar* gs_tested =
21396 "#version 430 core\n"
21397 "#extension GL_ARB_enhanced_layouts : require\n"
21399 "layout(points) in;\n"
21400 "layout(triangle_strip, max_vertices = 4) out;\n"
21404 "out gl_PerVertex \n"
21406 " vec4 gl_Position; \n" // gl_Position must be redeclared in separable program mode
21408 "in vec4 tes_gs[];\n"
21409 "out vec4 gs_fs;\n"
21413 " vec4 result = tes_gs[0];\n"
21417 " gs_fs = result;\n"
21418 " gl_Position = vec4(-1, -1, 0, 1);\n"
21420 " gs_fs = result;\n"
21421 " gl_Position = vec4(-1, 1, 0, 1);\n"
21423 " gs_fs = result;\n"
21424 " gl_Position = vec4(1, -1, 0, 1);\n"
21426 " gs_fs = result;\n"
21427 " gl_Position = vec4(1, 1, 0, 1);\n"
21431 static const GLchar* tcs = "#version 430 core\n"
21432 "#extension GL_ARB_enhanced_layouts : require\n"
21434 "layout(vertices = 1) out;\n"
21436 "in vec4 vs_tcs[];\n"
21437 "out vec4 tcs_tes[];\n"
21442 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
21444 " gl_TessLevelOuter[0] = 1.0;\n"
21445 " gl_TessLevelOuter[1] = 1.0;\n"
21446 " gl_TessLevelOuter[2] = 1.0;\n"
21447 " gl_TessLevelOuter[3] = 1.0;\n"
21448 " gl_TessLevelInner[0] = 1.0;\n"
21449 " gl_TessLevelInner[1] = 1.0;\n"
21453 static const GLchar* tcs_tested =
21454 "#version 430 core\n"
21455 "#extension GL_ARB_enhanced_layouts : require\n"
21457 "layout(vertices = 1) out;\n"
21461 "in vec4 vs_tcs[];\n"
21462 "out vec4 tcs_tes[];\n"
21466 " vec4 result = vs_tcs[gl_InvocationID];\n"
21470 " tcs_tes[gl_InvocationID] = result;\n"
21472 " gl_TessLevelOuter[0] = 1.0;\n"
21473 " gl_TessLevelOuter[1] = 1.0;\n"
21474 " gl_TessLevelOuter[2] = 1.0;\n"
21475 " gl_TessLevelOuter[3] = 1.0;\n"
21476 " gl_TessLevelInner[0] = 1.0;\n"
21477 " gl_TessLevelInner[1] = 1.0;\n"
21481 static const GLchar* tes_tested = "#version 430 core\n"
21482 "#extension GL_ARB_enhanced_layouts : require\n"
21484 "layout(isolines, point_mode) in;\n"
21488 "in vec4 tcs_tes[];\n"
21489 "out vec4 tes_gs;\n"
21493 " vec4 result = tcs_tes[0];\n"
21497 " tes_gs += result;\n"
21500 static const GLchar* vs = "#version 430 core\n"
21501 "#extension GL_ARB_enhanced_layouts : require\n"
21504 "out vec4 vs_tcs;\n"
21508 " vs_tcs = in_vs;\n"
21511 static const GLchar* vs_tested = "#version 430 core\n"
21512 "#extension GL_ARB_enhanced_layouts : require\n"
21517 "out vec4 vs_tcs;\n"
21521 " vec4 result = in_vs;\n"
21525 " vs_tcs += result;\n"
21529 std::string source;
21530 Utils::Shader::STAGES test_case = m_test_cases[test_case_index];
21532 if (test_case == stage)
21534 const GLchar* array = "";
21535 const GLchar* index = "";
21536 size_t position = 0;
21538 // It is a compile time error to apply xfb_offset to the declaration of an unsized array(GLSL4.5 spec: Page73)
21539 // change array = "[]" to "[1]"
21542 case Utils::Shader::GEOMETRY:
21543 source = gs_tested;
21548 It is invalid to define transform feedback output in HS
21551 case Utils::Shader::TESS_CTRL:
21552 source = tcs_tested;
21554 index = "[gl_InvocationID]";
21557 case Utils::Shader::TESS_EVAL:
21558 source = tes_tested;
21562 case Utils::Shader::VERTEX:
21563 source = vs_tested;
21566 TCU_FAIL("Invalid enum");
21570 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
21572 Utils::replaceToken("ARRAY", position, array, source);
21573 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
21575 Utils::replaceAllTokens("INDEX", index, source);
21581 case Utils::Shader::GEOMETRY:
21584 case Utils::Shader::VERTEX:
21591 case Utils::Shader::TESS_CTRL:
21594 case Utils::Shader::VERTEX:
21601 case Utils::Shader::TESS_EVAL:
21604 case Utils::Shader::TESS_CTRL:
21607 case Utils::Shader::VERTEX:
21614 case Utils::Shader::VERTEX:
21618 TCU_FAIL("Invalid enum");
21626 /** Get description of test case
21628 * @param test_case_index Index of test case
21630 * @return Test case description
21632 std::string XFBBlockStrideTest::getTestCaseName(GLuint test_case_index)
21634 std::stringstream stream;
21636 stream << "Stage: " << Utils::Shader::GetStageName(m_test_cases[test_case_index]);
21638 return stream.str();
21641 /** Get number of test cases
21643 * @return Number of test cases
21645 GLuint XFBBlockStrideTest::getTestCaseNumber()
21647 return static_cast<GLuint>(m_test_cases.size());
21650 /** Inspects program for xfb stride
21652 * @param program Program to query
21654 * @return true if query results match expected values, false otherwise
21656 bool XFBBlockStrideTest::inspectProgram(Utils::Program& program)
21660 program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE,
21661 1 /* buf_size */, &stride);
21663 return (128 == stride);
21668 * @param test_case_index Id of test case
21670 * @return true if test case pass, false otherwise
21672 bool XFBBlockStrideTest::testCase(GLuint test_case_index)
21674 const std::string& gs_source = getShaderSource(test_case_index, Utils::Shader::GEOMETRY);
21675 Utils::Program program(m_context);
21676 const std::string& tcs_source = getShaderSource(test_case_index, Utils::Shader::TESS_CTRL);
21677 const std::string& tes_source = getShaderSource(test_case_index, Utils::Shader::TESS_EVAL);
21678 bool test_case_result = true;
21679 const std::string& vs_source = getShaderSource(test_case_index, Utils::Shader::VERTEX);
21681 program.Init("" /* cs */, "", gs_source, tcs_source, tes_source, vs_source, true /* separable */);
21683 test_case_result = inspectProgram(program);
21685 return test_case_result;
21688 /** Prepare all test cases
21691 void XFBBlockStrideTest::testInit()
21693 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
21695 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
21696 (Utils::Shader::FRAGMENT == stage))
21701 m_test_cases.push_back((Utils::Shader::STAGES)stage);
21707 * @param context Test context
21709 XFBBlockMemberStrideTest::XFBBlockMemberStrideTest(deqp::Context& context)
21710 : BufferTestBase(context, "xfb_block_member_stride",
21711 "Test verifies that xfb_stride qualifier is respected for block member")
21713 /* Nothing to be done here */
21716 /** Get descriptors of buffers necessary for test
21719 * @param out_descriptors Descriptors of buffers used by test
21721 void XFBBlockMemberStrideTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
21722 bufferDescriptor::Vector& out_descriptors)
21724 const Utils::Type& vec4 = Utils::Type::vec4;
21726 /* Test needs single uniform and xfb */
21727 out_descriptors.resize(2);
21729 /* Get references */
21730 bufferDescriptor& uniform = out_descriptors[0];
21731 bufferDescriptor& xfb = out_descriptors[1];
21734 uniform.m_index = 0;
21738 uniform.m_target = Utils::Buffer::Uniform;
21739 xfb.m_target = Utils::Buffer::Transform_feedback;
21742 static const GLuint vec4_size = 16;
21743 const std::vector<GLubyte>& gohan_data = vec4.GenerateDataPacked();
21744 const std::vector<GLubyte>& goten_data = vec4.GenerateDataPacked();
21745 const std::vector<GLubyte>& chichi_data = vec4.GenerateDataPacked();
21748 uniform.m_initial_data.resize(3 * vec4_size);
21749 memcpy(&uniform.m_initial_data[0] + 0, &gohan_data[0], vec4_size);
21750 memcpy(&uniform.m_initial_data[0] + vec4_size, &goten_data[0], vec4_size);
21751 memcpy(&uniform.m_initial_data[0] + 2 * vec4_size, &chichi_data[0], vec4_size);
21754 xfb.m_initial_data.resize(4 * vec4_size);
21755 xfb.m_expected_data.resize(4 * vec4_size);
21757 for (GLuint i = 0; i < 4 * vec4_size; ++i)
21759 xfb.m_initial_data[i] = (glw::GLubyte)i;
21760 xfb.m_expected_data[i] = (glw::GLubyte)i;
21763 // the xfb_offset of "chichi" should be 32
21764 memcpy(&xfb.m_expected_data[0] + 0, &gohan_data[0], vec4_size);
21765 memcpy(&xfb.m_expected_data[0] + vec4_size, &goten_data[0], vec4_size);
21766 memcpy(&xfb.m_expected_data[0] + 2 * vec4_size, &chichi_data[0], vec4_size);
21769 /** Get body of main function for given shader stage
21772 * @param stage Shader stage
21773 * @param out_assignments Set to empty
21774 * @param out_calculations Set to empty
21776 void XFBBlockMemberStrideTest::getShaderBody(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
21777 std::string& out_assignments, std::string& out_calculations)
21779 out_calculations = "";
21781 static const GLchar* gs = " gohan = uni_gohan;\n"
21782 " goten = uni_goten;\n"
21783 " chichi = uni_chichi;\n";
21784 static const GLchar* fs = " fs_out = gohan + goten + chichi;\n";
21786 const GLchar* assignments = "";
21789 case Utils::Shader::FRAGMENT:
21792 case Utils::Shader::GEOMETRY:
21799 out_assignments = assignments;
21802 /** Get interface of shader
21805 * @param stage Shader stage
21806 * @param out_interface Set to ""
21808 void XFBBlockMemberStrideTest::getShaderInterface(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
21809 std::string& out_interface)
21811 static const GLchar* gs = "layout (xfb_buffer = 0, xfb_offset = 0) out Goku {\n"
21813 " layout (xfb_stride = 48) vec4 goten;\n"
21816 "layout(binding = 0) uniform gs_block {\n"
21817 " vec4 uni_gohan;\n"
21818 " vec4 uni_goten;\n"
21819 " vec4 uni_chichi;\n"
21821 static const GLchar* fs = "in Goku {\n"
21826 "out vec4 fs_out;\n";
21830 case Utils::Shader::FRAGMENT:
21831 out_interface = fs;
21833 case Utils::Shader::GEOMETRY:
21834 out_interface = gs;
21837 out_interface = "";
21842 /** Inspects program to check if all resources are as expected
21845 * @param program Program instance
21846 * @param out_stream Error message
21848 * @return true if everything is ok, false otherwise
21850 bool XFBBlockMemberStrideTest::inspectProgram(GLuint /* test_case_index*/, Utils::Program& program,
21851 std::stringstream& out_stream)
21853 const GLuint gohan_id = program.GetResourceIndex("gohan", GL_TRANSFORM_FEEDBACK_VARYING);
21854 const GLuint goten_id = program.GetResourceIndex("goten", GL_TRANSFORM_FEEDBACK_VARYING);
21855 const GLuint chichi_id = program.GetResourceIndex("chichi", GL_TRANSFORM_FEEDBACK_VARYING);
21857 GLint gohan_offset = 0;
21858 GLint goten_offset = 0;
21859 GLint chichi_offset = 0;
21861 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, gohan_id, GL_OFFSET, 1, &gohan_offset);
21862 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, goten_id, GL_OFFSET, 1, &goten_offset);
21863 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, chichi_id, GL_OFFSET, 1, &chichi_offset);
21865 // the xfb_offset of "chichi" should be 32
21866 if ((0 != gohan_offset) || (16 != goten_offset) || (32 != chichi_offset))
21868 out_stream << "Got wrong offset: [" << gohan_offset << ", " << goten_offset << ", " << chichi_offset
21869 << "] expected: [0, 16, 32]";
21878 * @param context Test framework context
21880 XFBDuplicatedStrideTest::XFBDuplicatedStrideTest(deqp::Context& context)
21881 : NegativeTestBase(context, "xfb_duplicated_stride",
21882 "Test verifies that compiler reports error when conflicting stride qualifiers are used")
21886 /** Source for given test case and stage
21888 * @param test_case_index Index of test case
21889 * @param stage Shader stage
21891 * @return Shader source
21893 std::string XFBDuplicatedStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
21895 static const GLchar* invalid_var_definition = "const uint valid_stride = 64;\n"
21896 "const uint conflicting_stride = 128;\n"
21898 "layout (xfb_buffer = 0, xfb_stride = valid_stride) out;\n"
21899 "layout (xfb_buffer = 0, xfb_stride = conflicting_stride) out;\n";
21900 static const GLchar* valid_var_definition = "const uint valid_stride = 64;\n"
21902 "layout (xfb_buffer = 0, xfb_stride = valid_stride) out;\n"
21903 "layout (xfb_buffer = 0, xfb_stride = valid_stride) out;\n";
21904 static const GLchar* fs = "#version 430 core\n"
21905 "#extension GL_ARB_enhanced_layouts : require\n"
21907 "in vec4 any_fs;\n"
21908 "out vec4 fs_out;\n"
21912 " fs_out = any_fs;\n"
21915 static const GLchar* gs_tested = "#version 430 core\n"
21916 "#extension GL_ARB_enhanced_layouts : require\n"
21918 "layout(points) in;\n"
21919 "layout(triangle_strip, max_vertices = 4) out;\n"
21923 "in vec4 vs_any[];\n"
21924 "out vec4 any_fs;\n"
21928 " vec4 result = vs_any[0];\n"
21932 " any_fs = result;\n"
21933 " gl_Position = vec4(-1, -1, 0, 1);\n"
21935 " any_fs = result;\n"
21936 " gl_Position = vec4(-1, 1, 0, 1);\n"
21938 " any_fs = result;\n"
21939 " gl_Position = vec4(1, -1, 0, 1);\n"
21941 " any_fs = result;\n"
21942 " gl_Position = vec4(1, 1, 0, 1);\n"
21946 static const GLchar* tcs = "#version 430 core\n"
21947 "#extension GL_ARB_enhanced_layouts : require\n"
21949 "layout(vertices = 1) out;\n"
21951 "in vec4 vs_any[];\n"
21952 "out vec4 tcs_tes[];\n"
21957 " tcs_tes[gl_InvocationID] = vs_any[gl_InvocationID];\n"
21959 " gl_TessLevelOuter[0] = 1.0;\n"
21960 " gl_TessLevelOuter[1] = 1.0;\n"
21961 " gl_TessLevelOuter[2] = 1.0;\n"
21962 " gl_TessLevelOuter[3] = 1.0;\n"
21963 " gl_TessLevelInner[0] = 1.0;\n"
21964 " gl_TessLevelInner[1] = 1.0;\n"
21967 static const GLchar* tcs_tested = "#version 430 core\n"
21968 "#extension GL_ARB_enhanced_layouts : require\n"
21970 "layout(vertices = 1) out;\n"
21974 "in vec4 vs_any[];\n"
21975 "out vec4 any_fs[];\n"
21979 " vec4 result = vs_any[gl_InvocationID];\n"
21983 " any_fs[gl_InvocationID] = result;\n"
21985 " gl_TessLevelOuter[0] = 1.0;\n"
21986 " gl_TessLevelOuter[1] = 1.0;\n"
21987 " gl_TessLevelOuter[2] = 1.0;\n"
21988 " gl_TessLevelOuter[3] = 1.0;\n"
21989 " gl_TessLevelInner[0] = 1.0;\n"
21990 " gl_TessLevelInner[1] = 1.0;\n"
21993 static const GLchar* tes_tested = "#version 430 core\n"
21994 "#extension GL_ARB_enhanced_layouts : require\n"
21996 "layout(isolines, point_mode) in;\n"
22000 "in vec4 tcs_tes[];\n"
22001 "out vec4 any_fs;\n"
22005 " vec4 result = tcs_tes[0];\n"
22009 " any_fs = result;\n"
22012 static const GLchar* vs = "#version 430 core\n"
22013 "#extension GL_ARB_enhanced_layouts : require\n"
22016 "out vec4 vs_any;\n"
22020 " vs_any = in_vs;\n"
22023 static const GLchar* vs_tested = "#version 430 core\n"
22024 "#extension GL_ARB_enhanced_layouts : require\n"
22029 "out vec4 any_fs;\n"
22033 " vec4 result = in_vs;\n"
22037 " any_fs += result;\n"
22041 std::string source;
22042 testCase& test_case = m_test_cases[test_case_index];
22044 if (test_case.m_stage == stage)
22046 size_t position = 0;
22047 const GLchar* var_definition = 0;
22048 const GLchar* var_use = "";
22050 switch (test_case.m_case)
22053 var_definition = valid_var_definition;
22056 var_definition = invalid_var_definition;
22059 TCU_FAIL("Invalid enum");
22064 case Utils::Shader::GEOMETRY:
22065 source = gs_tested;
22067 case Utils::Shader::TESS_CTRL:
22068 source = tcs_tested;
22070 case Utils::Shader::TESS_EVAL:
22071 source = tes_tested;
22073 case Utils::Shader::VERTEX:
22074 source = vs_tested;
22077 TCU_FAIL("Invalid enum");
22080 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
22081 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
22085 switch (test_case.m_stage)
22087 case Utils::Shader::GEOMETRY:
22090 case Utils::Shader::FRAGMENT:
22093 case Utils::Shader::VERTEX:
22100 case Utils::Shader::TESS_CTRL:
22103 case Utils::Shader::FRAGMENT:
22106 case Utils::Shader::VERTEX:
22113 case Utils::Shader::TESS_EVAL:
22116 case Utils::Shader::FRAGMENT:
22119 case Utils::Shader::TESS_CTRL:
22122 case Utils::Shader::VERTEX:
22129 case Utils::Shader::VERTEX:
22132 case Utils::Shader::FRAGMENT:
22140 TCU_FAIL("Invalid enum");
22148 /** Get description of test case
22150 * @param test_case_index Index of test case
22152 * @return Test case description
22154 std::string XFBDuplicatedStrideTest::getTestCaseName(GLuint test_case_index)
22156 std::stringstream stream;
22157 testCase& test_case = m_test_cases[test_case_index];
22159 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", case: ";
22161 switch (test_case.m_case)
22167 stream << "invalid";
22170 TCU_FAIL("Invalid enum");
22173 return stream.str();
22176 /** Get number of test cases
22178 * @return Number of test cases
22180 GLuint XFBDuplicatedStrideTest::getTestCaseNumber()
22182 return static_cast<GLuint>(m_test_cases.size());
22185 /** Selects if "compute" stage is relevant for test
22191 bool XFBDuplicatedStrideTest::isComputeRelevant(GLuint /* test_case_index */)
22196 /** Selects if compilation failure is expected result
22198 * @param test_case_index Index of test case
22202 bool XFBDuplicatedStrideTest::isFailureExpected(GLuint test_case_index)
22204 testCase& test_case = m_test_cases[test_case_index];
22206 return (INVALID == test_case.m_case);
22209 /** Prepare all test cases
22212 void XFBDuplicatedStrideTest::testInit()
22214 for (GLuint c = 0; c < CASE_MAX; ++c)
22216 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
22218 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
22219 (Utils::Shader::FRAGMENT == stage))
22224 testCase test_case = { (CASES)c, (Utils::Shader::STAGES)stage };
22226 m_test_cases.push_back(test_case);
22233 * @param context Test framework context
22235 XFBGetProgramResourceAPITest::XFBGetProgramResourceAPITest(deqp::Context& context)
22236 : TestBase(context, "xfb_get_program_resource_api",
22237 "Test verifies that get program resource reports correct results for XFB")
22241 /** Source for given test case and stage
22243 * @param test_case_index Index of test case
22244 * @param stage Shader stage
22246 * @return Shader source
22248 std::string XFBGetProgramResourceAPITest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
22250 static const GLchar* api_var_definition = "out TYPE b0_v1ARRAY;\n"
22251 "out TYPE b1_v1ARRAY;\n"
22252 "out TYPE b0_v3ARRAY;\n"
22253 "out TYPE b0_v0ARRAY;\n";
22254 static const GLchar* xfb_var_definition =
22255 "const uint type_size = SIZE;\n"
22257 "layout (xfb_buffer = 1, xfb_stride = 4 * type_size) out;\n"
22259 "layout (xfb_buffer = 0, xfb_offset = 1 * type_size) out TYPE b0_v1ARRAY;\n"
22260 "layout (xfb_buffer = 1, xfb_offset = 1 * type_size) out TYPE b1_v1ARRAY;\n"
22261 "layout (xfb_buffer = 0, xfb_offset = 3 * type_size) out TYPE b0_v3ARRAY;\n"
22262 "layout (xfb_buffer = 0, xfb_offset = 0 * type_size) out TYPE b0_v0ARRAY;\n";
22263 static const GLchar* var_use = " b0_v1INDEX = TYPE(0);\n"
22264 " b1_v1INDEX = TYPE(1);\n"
22265 " b0_v3INDEX = TYPE(0);\n"
22266 " b0_v0INDEX = TYPE(1);\n"
22267 " if (vec4(0) == result)\n"
22269 " b0_v1INDEX = TYPE(1);\n"
22270 " b1_v1INDEX = TYPE(0);\n"
22271 " b0_v3INDEX = TYPE(1);\n"
22272 " b0_v0INDEX = TYPE(0);\n"
22274 static const GLchar* gs_tested =
22275 "#version 430 core\n"
22276 "#extension GL_ARB_enhanced_layouts : require\n"
22278 "layout(points) in;\n"
22279 "layout(triangle_strip, max_vertices = 4) out;\n"
22283 "out gl_PerVertex \n"
22285 " vec4 gl_Position; \n" // gl_Position must be redeclared in separable program mode
22287 "in vec4 tes_gs[];\n"
22288 "out vec4 gs_fs;\n"
22292 " vec4 result = tes_gs[0];\n"
22296 " gs_fs = result;\n"
22297 " gl_Position = vec4(-1, -1, 0, 1);\n"
22299 " gs_fs = result;\n"
22300 " gl_Position = vec4(-1, 1, 0, 1);\n"
22302 " gs_fs = result;\n"
22303 " gl_Position = vec4(1, -1, 0, 1);\n"
22305 " gs_fs = result;\n"
22306 " gl_Position = vec4(1, 1, 0, 1);\n"
22311 static const GLchar* tcs_tested =
22312 "#version 430 core\n"
22313 "#extension GL_ARB_enhanced_layouts : require\n"
22315 "layout(vertices = 1) out;\n"
22319 "in vec4 vs_tcs[];\n"
22320 "out vec4 tcs_tes[];\n"
22324 " vec4 result = vs_tcs[gl_InvocationID];\n"
22328 " tcs_tes[gl_InvocationID] = result;\n"
22330 " gl_TessLevelOuter[0] = 1.0;\n"
22331 " gl_TessLevelOuter[1] = 1.0;\n"
22332 " gl_TessLevelOuter[2] = 1.0;\n"
22333 " gl_TessLevelOuter[3] = 1.0;\n"
22334 " gl_TessLevelInner[0] = 1.0;\n"
22335 " gl_TessLevelInner[1] = 1.0;\n"
22339 static const GLchar* tes_tested = "#version 430 core\n"
22340 "#extension GL_ARB_enhanced_layouts : require\n"
22342 "layout(isolines, point_mode) in;\n"
22346 "in vec4 tcs_tes[];\n"
22347 "out vec4 tes_gs;\n"
22351 " vec4 result = tcs_tes[0];\n"
22355 " tes_gs = result;\n"
22358 static const GLchar* vs_tested = "#version 430 core\n"
22359 "#extension GL_ARB_enhanced_layouts : require\n"
22364 "out vec4 vs_tcs;\n"
22368 " vec4 result = in_vs;\n"
22372 " vs_tcs = result;\n"
22376 std::string source;
22377 const test_Case& test_case = m_test_cases[test_case_index];
22379 if (test_case.m_stage == stage)
22381 const GLchar* array = "";
22383 const GLchar* index = "";
22384 size_t position = 0;
22386 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
22387 const GLchar* var_definition = 0;
22389 sprintf(buffer, "%d", test_case.m_type.GetSize());
22391 if (XFB == test_case.m_case)
22393 var_definition = xfb_var_definition;
22397 var_definition = api_var_definition;
22400 // It is a compile time error to apply xfb_offset to the declaration of an unsized array(GLSL4.5 spec: Page73)
22401 // change array = "[]" to "[1]"
22404 case Utils::Shader::GEOMETRY:
22405 source = gs_tested;
22409 // It is invalid to output transform feedback varyings in tessellation control shader
22411 case Utils::Shader::TESS_CTRL:
22412 source = tcs_tested;
22414 index = "[gl_InvocationID]";
22417 case Utils::Shader::TESS_EVAL:
22418 source = tes_tested;
22422 case Utils::Shader::VERTEX:
22423 source = vs_tested;
22426 TCU_FAIL("Invalid enum");
22430 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
22431 if (XFB == test_case.m_case)
22434 Utils::replaceToken("SIZE", position, buffer, source);
22436 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
22438 Utils::replaceAllTokens("ARRAY", array, source);
22439 Utils::replaceAllTokens("INDEX", index, source);
22440 Utils::replaceAllTokens("TYPE", type_name, source);
22450 /** Get description of test case
22452 * @param test_case_index Index of test case
22454 * @return Test case description
22456 std::string XFBGetProgramResourceAPITest::getTestCaseName(GLuint test_case_index)
22458 std::stringstream stream;
22459 const test_Case& test_case = m_test_cases[test_case_index];
22461 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
22462 << ", type: " << test_case.m_type.GetGLSLTypeName() << ", case: ";
22464 switch (test_case.m_case)
22467 stream << "interleaved";
22470 stream << "separated";
22476 TCU_FAIL("Invalid enum");
22479 return stream.str();
22482 /** Get number of test cases
22484 * @return Number of test cases
22486 GLuint XFBGetProgramResourceAPITest::getTestCaseNumber()
22488 return static_cast<GLuint>(m_test_cases.size());
22491 /** Inspects program for offset, buffer index, buffer stride and type
22493 * @param test_case_index Index of test case
22494 * @param program Program to query
22496 * @return true if query results match expected values, false otherwise
22498 bool XFBGetProgramResourceAPITest::inspectProgram(glw::GLuint test_case_index, Utils::Program& program)
22500 GLint b0_stride = 0;
22501 GLint b1_stride = 0;
22502 GLint b0_v0_buf = 0;
22503 GLint b0_v0_offset = 0;
22504 GLint b0_v0_type = 0;
22505 GLint b0_v1_buf = 0;
22506 GLint b0_v1_offset = 0;
22507 GLint b0_v1_type = 0;
22508 GLint b0_v3_buf = 0;
22509 GLint b0_v3_offset = 0;
22510 GLint b0_v3_type = 0;
22511 GLint b1_v1_buf = 0;
22512 GLint b1_v1_offset = 0;
22513 GLint b1_v1_type = 0;
22514 const test_Case& test_case = m_test_cases[test_case_index];
22515 const GLenum type_enum = test_case.m_type.GetTypeGLenum();
22516 const GLint type_size = test_case.m_type.GetSize();
22518 GLuint b0_v0_index = program.GetResourceIndex("b0_v0", GL_TRANSFORM_FEEDBACK_VARYING);
22519 GLuint b0_v1_index = program.GetResourceIndex("b0_v1", GL_TRANSFORM_FEEDBACK_VARYING);
22520 GLuint b0_v3_index = program.GetResourceIndex("b0_v3", GL_TRANSFORM_FEEDBACK_VARYING);
22521 GLuint b1_v1_index = program.GetResourceIndex("b1_v1", GL_TRANSFORM_FEEDBACK_VARYING);
22523 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v0_index, GL_OFFSET, 1 /* buf_size */, &b0_v0_offset);
22524 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v1_index, GL_OFFSET, 1 /* buf_size */, &b0_v1_offset);
22525 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v3_index, GL_OFFSET, 1 /* buf_size */, &b0_v3_offset);
22526 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b1_v1_index, GL_OFFSET, 1 /* buf_size */, &b1_v1_offset);
22528 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v0_index, GL_TYPE, 1 /* buf_size */, &b0_v0_type);
22529 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v1_index, GL_TYPE, 1 /* buf_size */, &b0_v1_type);
22530 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v3_index, GL_TYPE, 1 /* buf_size */, &b0_v3_type);
22531 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b1_v1_index, GL_TYPE, 1 /* buf_size */, &b1_v1_type);
22533 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v0_index, GL_TRANSFORM_FEEDBACK_BUFFER_INDEX,
22534 1 /* buf_size */, &b0_v0_buf);
22535 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v1_index, GL_TRANSFORM_FEEDBACK_BUFFER_INDEX,
22536 1 /* buf_size */, &b0_v1_buf);
22537 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v3_index, GL_TRANSFORM_FEEDBACK_BUFFER_INDEX,
22538 1 /* buf_size */, &b0_v3_buf);
22539 program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b1_v1_index, GL_TRANSFORM_FEEDBACK_BUFFER_INDEX,
22540 1 /* buf_size */, &b1_v1_buf);
22542 program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, b0_v0_buf, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE, 1 /* buf_size */,
22544 program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, b1_v1_buf, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE, 1 /* buf_size */,
22547 if (SEPARATED != test_case.m_case)
22549 return (((GLint)(4 * type_size) == b0_stride) && ((GLint)(4 * type_size) == b1_stride) &&
22550 ((GLint)(0) == b0_v0_buf) && ((GLint)(0 * type_size) == b0_v0_offset) &&
22551 ((GLint)(type_enum) == b0_v0_type) && ((GLint)(0) == b0_v1_buf) &&
22552 ((GLint)(1 * type_size) == b0_v1_offset) && ((GLint)(type_enum) == b0_v1_type) &&
22553 ((GLint)(0) == b0_v3_buf) && ((GLint)(3 * type_size) == b0_v3_offset) &&
22554 ((GLint)(type_enum) == b0_v3_type) && ((GLint)(1) == b1_v1_buf) &&
22555 ((GLint)(1 * type_size) == b1_v1_offset) && ((GLint)(type_enum) == b1_v1_type));
22559 return (((GLint)(1 * type_size) == b0_stride) && ((GLint)(1 * type_size) == b1_stride) &&
22560 ((GLint)(0) == b0_v0_buf) && ((GLint)(0) == b0_v0_offset) && ((GLint)(type_enum) == b0_v0_type) &&
22561 ((GLint)(1) == b0_v1_buf) && ((GLint)(0) == b0_v1_offset) && ((GLint)(type_enum) == b0_v1_type) &&
22562 ((GLint)(2) == b0_v3_buf) && ((GLint)(0) == b0_v3_offset) && ((GLint)(type_enum) == b0_v3_type) &&
22563 ((GLint)(3) == b1_v1_buf) && ((GLint)(0) == b1_v1_offset) && ((GLint)(type_enum) == b1_v1_type));
22567 /** Insert gl_SkipComponents
22569 * @param num_components How many gl_SkipComponents1 need to be inserted
22570 * @param varyings The transform feedback varyings string vector
22573 void XFBGetProgramResourceAPITest::insertSkipComponents(int num_components, Utils::Program::NameVector& varyings)
22575 int num_component_4 = num_components / 4;
22576 int num_component_1 = num_components % 4;
22577 for (int i = 0; i < num_component_4; i++)
22579 varyings.push_back("gl_SkipComponents4");
22581 switch (num_component_1)
22584 varyings.push_back("gl_SkipComponents1");
22587 varyings.push_back("gl_SkipComponents2");
22590 varyings.push_back("gl_SkipComponents3");
22599 * @param test_case_index Id of test case
22601 * @return true if test case pass, false otherwise
22603 bool XFBGetProgramResourceAPITest::testCase(GLuint test_case_index)
22605 const std::string& gs_source = getShaderSource(test_case_index, Utils::Shader::GEOMETRY);
22606 Utils::Program program(m_context);
22607 const std::string& tcs_source = getShaderSource(test_case_index, Utils::Shader::TESS_CTRL);
22608 const std::string& tes_source = getShaderSource(test_case_index, Utils::Shader::TESS_EVAL);
22609 const test_Case& test_case = m_test_cases[test_case_index];
22610 bool test_case_result = true;
22611 const std::string& vs_source = getShaderSource(test_case_index, Utils::Shader::VERTEX);
22613 // According to spec: gl_SkipComponents1 ~ gl_SkipComponents4 is treated as specifying a one- to four-component floating point output variables with undefined values.
22614 // 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.
22616 if (INTERLEAVED == test_case.m_case)
22619 layout (xfb_buffer = 0, xfb_offset = 1 * type_size) out type b0_v1;
22620 layout (xfb_buffer = 1, xfb_offset = 1 * type_size) out type b1_v1;
22621 layout (xfb_buffer = 0, xfb_offset = 3 * type_size) out type b0_v3;
22622 layout (xfb_buffer = 0, xfb_offset = 0 * type_size) out type b0_v0;
22624 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,
22625 we need to calculate how many "gl_SkipComponents" need to be inserted.
22627 Utils::Program::NameVector captured_varyings;
22628 captured_varyings.push_back("b0_v0");
22629 captured_varyings.push_back("b0_v1");
22630 // Compute how many gl_SkipComponents to be inserted
22631 int numComponents = test_case.m_type.GetSize() / 4;
22632 insertSkipComponents(numComponents, captured_varyings);
22633 captured_varyings.push_back("b0_v3");
22634 captured_varyings.push_back("gl_NextBuffer");
22635 insertSkipComponents(numComponents, captured_varyings);
22636 captured_varyings.push_back("b1_v1");
22637 insertSkipComponents(numComponents * 2, captured_varyings);
22639 program.Init("" /* cs */, "", gs_source, tcs_source, tes_source, vs_source, captured_varyings, true,
22640 true /* separable */);
22642 else if (SEPARATED == test_case.m_case)
22644 Utils::Program::NameVector captured_varyings;
22646 captured_varyings.push_back("b0_v0");
22647 captured_varyings.push_back("b0_v1");
22648 captured_varyings.push_back("b0_v3");
22649 captured_varyings.push_back("b1_v1");
22651 program.Init("" /* cs */, "", gs_source, tcs_source, tes_source, vs_source, captured_varyings, false,
22652 true /* separable */);
22657 program.Init("" /* cs */, "", gs_source, tcs_source, tes_source, vs_source, true /* separable */);
22660 test_case_result = inspectProgram(test_case_index, program);
22662 return test_case_result;
22665 /** Prepare all test cases
22668 void XFBGetProgramResourceAPITest::testInit()
22670 const Functions& gl = m_context.getRenderContext().getFunctions();
22671 const GLuint n_types = getTypesNumber();
22675 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_xfb_int);
22676 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
22678 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, &max_xfb_sep);
22679 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
22681 GLint max_varyings;
22682 gl.getIntegerv(GL_MAX_VARYING_COMPONENTS, &max_varyings);
22684 for (GLuint i = 0; i < n_types; ++i)
22686 // 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,
22687 // 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
22688 // shader valid, we can either skip the dmat4, dmat4x3 or query the implementation-dependent value MAX_VARYING_COMPONENTS before generating the shader
22689 // to guarantee the number of varying not exceeded.
22691 layout (xfb_buffer = 1, xfb_stride = 4 * type_size) out;
22692 layout (xfb_buffer = 0, xfb_offset = 1 * type_size) out type b0_v1;
22693 layout (xfb_buffer = 1, xfb_offset = 1 * type_size) out type b1_v1;
22694 layout (xfb_buffer = 0, xfb_offset = 3 * type_size) out type b0_v3;
22695 layout (xfb_buffer = 0, xfb_offset = 0 * type_size) out type b0_v0;
22699 if (i == 7 || i == 9)
22701 const Utils::Type& type = getType(i);
22702 if (4 * type.GetNumComponents() + 4 > (GLuint)max_varyings)
22706 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
22709 It is invalid to define transform feedback output in HS
22711 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
22712 (Utils::Shader::FRAGMENT == stage))
22717 test_Case test_case_int = { INTERLEAVED, (Utils::Shader::STAGES)stage, type };
22718 test_Case test_case_sep = { SEPARATED, (Utils::Shader::STAGES)stage, type };
22719 test_Case test_case_xfb = { XFB, (Utils::Shader::STAGES)stage, type };
22721 if ((int)type.GetSize() <= max_xfb_int)
22723 m_test_cases.push_back(test_case_xfb);
22724 m_test_cases.push_back(test_case_int);
22727 if ((int)type.GetSize() <= max_xfb_sep)
22729 m_test_cases.push_back(test_case_sep);
22737 * @param context Test context
22739 XFBOverrideQualifiersWithAPITest::XFBOverrideQualifiersWithAPITest(deqp::Context& context)
22740 : BufferTestBase(context, "xfb_override_qualifiers_with_api",
22741 "Test verifies that xfb_offset qualifier is not overriden with API")
22743 /* Nothing to be done here */
22746 /** Get descriptors of buffers necessary for test
22748 * @param test_case_index Index of test case
22749 * @param out_descriptors Descriptors of buffers used by test
22751 void XFBOverrideQualifiersWithAPITest::getBufferDescriptors(glw::GLuint test_case_index,
22752 bufferDescriptor::Vector& out_descriptors)
22754 const Utils::Type& type = getType(test_case_index);
22756 /* Test needs single uniform and xfb */
22757 out_descriptors.resize(2);
22759 /* Get references */
22760 bufferDescriptor& uniform = out_descriptors[0];
22761 bufferDescriptor& xfb = out_descriptors[1];
22764 uniform.m_index = 0;
22768 uniform.m_target = Utils::Buffer::Uniform;
22769 xfb.m_target = Utils::Buffer::Transform_feedback;
22772 const GLuint gen_start = Utils::s_rand;
22773 const std::vector<GLubyte>& vegeta_data = type.GenerateData();
22774 const std::vector<GLubyte>& trunks_data = type.GenerateData();
22775 const std::vector<GLubyte>& goku_data = type.GenerateData();
22777 Utils::s_rand = gen_start;
22778 const std::vector<GLubyte>& vegeta_data_pck = type.GenerateDataPacked();
22779 type.GenerateDataPacked(); // generate the data for trunks
22780 const std::vector<GLubyte>& goku_data_pck = type.GenerateDataPacked();
22782 const GLuint type_size = static_cast<GLuint>(vegeta_data.size());
22783 const GLuint type_size_pck = static_cast<GLuint>(vegeta_data_pck.size());
22786 uniform.m_initial_data.resize(3 * type_size);
22787 memcpy(&uniform.m_initial_data[0] + 0, &vegeta_data[0], type_size);
22788 memcpy(&uniform.m_initial_data[0] + type_size, &trunks_data[0], type_size);
22789 memcpy(&uniform.m_initial_data[0] + 2 * type_size, &goku_data[0], type_size);
22792 xfb.m_initial_data.resize(3 * type_size_pck);
22793 xfb.m_expected_data.resize(3 * type_size_pck);
22795 for (GLuint i = 0; i < 3 * type_size_pck; ++i)
22797 xfb.m_initial_data[i] = (glw::GLubyte)i;
22798 xfb.m_expected_data[i] = (glw::GLubyte)i;
22801 memcpy(&xfb.m_expected_data[0] + 0, &goku_data_pck[0], type_size_pck);
22802 memcpy(&xfb.m_expected_data[0] + 2 * type_size_pck, &vegeta_data_pck[0], type_size_pck);
22805 /** Get list of names of varyings that will be registered with TransformFeedbackVaryings
22808 * @param captured_varyings List of names
22810 void XFBOverrideQualifiersWithAPITest::getCapturedVaryings(glw::GLuint /* test_case_index */,
22811 Utils::Program::NameVector& captured_varyings)
22813 captured_varyings.resize(1);
22815 captured_varyings[0] = "trunks";
22818 /** Get body of main function for given shader stage
22820 * @param test_case_index Index of test case
22821 * @param stage Shader stage
22822 * @param out_assignments Set to empty
22823 * @param out_calculations Set to empty
22825 void XFBOverrideQualifiersWithAPITest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
22826 std::string& out_assignments, std::string& out_calculations)
22828 out_calculations = "";
22830 static const GLchar* gs = " vegeta = uni_vegeta;\n"
22831 " trunks = uni_trunks;\n"
22832 " goku = uni_goku;\n";
22833 static const GLchar* fs = " fs_out = vec4(0);\n"
22834 " if (TYPE(1) == goku + trunks + vegeta)\n"
22836 " fs_out = vec4(1);\n"
22839 const GLchar* assignments = "";
22842 case Utils::Shader::FRAGMENT:
22845 case Utils::Shader::GEOMETRY:
22852 out_assignments = assignments;
22854 if (Utils::Shader::FRAGMENT == stage)
22856 const Utils::Type& type = getType(test_case_index);
22858 Utils::replaceAllTokens("TYPE", type.GetGLSLTypeName(), out_assignments);
22862 /** Get interface of shader
22864 * @param test_case_index Index of test case
22865 * @param stage Shader stage
22866 * @param out_interface Set to ""
22868 void XFBOverrideQualifiersWithAPITest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
22869 std::string& out_interface)
22871 static const GLchar* gs = "const uint sizeof_type = SIZE;\n"
22873 "layout (xfb_offset = 2 * sizeof_type) flat out TYPE vegeta;\n"
22874 " flat out TYPE trunks;\n"
22875 "layout (xfb_offset = 0) flat out TYPE goku;\n"
22878 There is no packing qualifier for uniform block gs_block, according to spec, it should be "shared" by default,
22879 the definition equals to "layout(binding=0, shared)", if the block is declared as shared, each block member will
22880 not be packed, and each block member's layout in memory is implementation dependent, so we can't use the API
22881 glBufferData() to update the UBO directly, we need to query each block member's offset first, then upload the
22882 data to the corresponding offset, otherwise we can't get the correct data from UBO; to make the test passed,
22883 we need to add the qualifier std140, and change the declaration as layout(binding=0, std140), which can make
22884 sure all the block members are packed and the application can upload the data by glBufferData() directly.
22886 "layout(binding = 0, std140) uniform gs_block {\n"
22887 " TYPE uni_vegeta;\n"
22888 " TYPE uni_trunks;\n"
22889 " TYPE uni_goku;\n"
22891 static const GLchar* fs = "flat in TYPE vegeta;\n"
22892 "flat in TYPE trunks;\n"
22893 "flat in TYPE goku;\n"
22895 "out vec4 fs_out;\n";
22897 const Utils::Type& type = getType(test_case_index);
22901 case Utils::Shader::FRAGMENT:
22902 out_interface = fs;
22904 case Utils::Shader::GEOMETRY:
22905 out_interface = gs;
22908 out_interface = "";
22912 if (Utils::Shader::GEOMETRY == stage)
22915 size_t position = 0;
22916 const GLuint type_size = type.GetSize();
22918 sprintf(buffer, "%d", type_size);
22920 Utils::replaceToken("SIZE", position, buffer, out_interface);
22923 Utils::replaceAllTokens("TYPE", type.GetGLSLTypeName(), out_interface);
22928 * @param test_case_index Index of test case
22930 * @return Name of type test in test_case_index
22932 std::string XFBOverrideQualifiersWithAPITest::getTestCaseName(glw::GLuint test_case_index)
22934 return getTypeName(test_case_index);
22937 /** Returns number of types to test
22939 * @return Number of types, 34
22941 glw::GLuint XFBOverrideQualifiersWithAPITest::getTestCaseNumber()
22943 return getTypesNumber();
22946 /** Inspects program to check if all resources are as expected
22948 * @param test_case_index Index of test case
22949 * @param program Program instance
22950 * @param out_stream Error message
22952 * @return true if everything is ok, false otherwise
22954 bool XFBOverrideQualifiersWithAPITest::inspectProgram(GLuint test_case_index, Utils::Program& program,
22955 std::stringstream& out_stream)
22958 const Utils::Type& type = getType(test_case_index);
22959 const GLuint type_size = type.GetSize(false);
22961 program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE,
22962 1 /* buf_size */, &stride);
22964 if ((GLint)(3 * type_size) != stride)
22966 out_stream << "Stride is: " << stride << " expected: " << (3 * type_size);
22976 * @param context Test context
22978 XFBVertexStreamsTest::XFBVertexStreamsTest(deqp::Context& context)
22979 : BufferTestBase(context, "xfb_vertex_streams",
22980 "Test verifies that xfb qualifier works with multiple output streams")
22982 /* Nothing to be done here */
22985 /** Get descriptors of buffers necessary for test
22988 * @param out_descriptors Descriptors of buffers used by test
22990 void XFBVertexStreamsTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
22991 bufferDescriptor::Vector& out_descriptors)
22993 const Utils::Type& type = Utils::Type::vec4;
22995 /* Test needs single uniform and three xfbs */
22996 out_descriptors.resize(4);
22998 /* Get references */
22999 bufferDescriptor& uniform = out_descriptors[0];
23000 bufferDescriptor& xfb_1 = out_descriptors[1];
23001 bufferDescriptor& xfb_2 = out_descriptors[2];
23002 bufferDescriptor& xfb_3 = out_descriptors[3];
23005 uniform.m_index = 0;
23011 uniform.m_target = Utils::Buffer::Uniform;
23012 xfb_1.m_target = Utils::Buffer::Transform_feedback;
23013 xfb_2.m_target = Utils::Buffer::Transform_feedback;
23014 xfb_3.m_target = Utils::Buffer::Transform_feedback;
23017 const std::vector<GLubyte>& goku_data = type.GenerateData();
23018 const std::vector<GLubyte>& gohan_data = type.GenerateData();
23019 const std::vector<GLubyte>& goten_data = type.GenerateData();
23020 const std::vector<GLubyte>& picolo_data = type.GenerateData();
23021 const std::vector<GLubyte>& vegeta_data = type.GenerateData();
23022 const std::vector<GLubyte>& bulma_data = type.GenerateData();
23024 const GLuint type_size = static_cast<GLuint>(vegeta_data.size());
23027 uniform.m_initial_data.resize(6 * type_size);
23028 memcpy(&uniform.m_initial_data[0] + 0, &goku_data[0], type_size);
23029 memcpy(&uniform.m_initial_data[0] + type_size, &gohan_data[0], type_size);
23030 memcpy(&uniform.m_initial_data[0] + 2 * type_size, &goten_data[0], type_size);
23031 memcpy(&uniform.m_initial_data[0] + 3 * type_size, &picolo_data[0], type_size);
23032 memcpy(&uniform.m_initial_data[0] + 4 * type_size, &vegeta_data[0], type_size);
23033 memcpy(&uniform.m_initial_data[0] + 5 * type_size, &bulma_data[0], type_size);
23036 static const GLuint xfb_stride = 64;
23037 xfb_1.m_initial_data.resize(xfb_stride);
23038 xfb_1.m_expected_data.resize(xfb_stride);
23039 xfb_2.m_initial_data.resize(xfb_stride);
23040 xfb_2.m_expected_data.resize(xfb_stride);
23041 xfb_3.m_initial_data.resize(xfb_stride);
23042 xfb_3.m_expected_data.resize(xfb_stride);
23044 for (GLuint i = 0; i < xfb_stride; ++i)
23046 xfb_1.m_initial_data[i] = (glw::GLubyte)i;
23047 xfb_1.m_expected_data[i] = (glw::GLubyte)i;
23048 xfb_2.m_initial_data[i] = (glw::GLubyte)i;
23049 xfb_2.m_expected_data[i] = (glw::GLubyte)i;
23050 xfb_3.m_initial_data[i] = (glw::GLubyte)i;
23051 xfb_3.m_expected_data[i] = (glw::GLubyte)i;
23054 memcpy(&xfb_1.m_expected_data[0] + 48, &goku_data[0], type_size);
23055 memcpy(&xfb_1.m_expected_data[0] + 32, &gohan_data[0], type_size);
23056 memcpy(&xfb_1.m_expected_data[0] + 16, &goten_data[0], type_size);
23057 memcpy(&xfb_3.m_expected_data[0] + 48, &picolo_data[0], type_size);
23058 memcpy(&xfb_3.m_expected_data[0] + 32, &vegeta_data[0], type_size);
23059 memcpy(&xfb_2.m_expected_data[0] + 32, &bulma_data[0], type_size);
23062 /** Get body of main function for given shader stage
23065 * @param stage Shader stage
23066 * @param out_assignments Set to empty
23067 * @param out_calculations Set to empty
23069 void XFBVertexStreamsTest::getShaderBody(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
23070 std::string& out_assignments, std::string& out_calculations)
23072 out_calculations = "";
23074 // the shader declares the output variables with different "stream" qualifier, to make the data can export to
23075 // each stream, we must call the function EmitStreamVertex() and EndStreamPrimitive() to make each vertex emitted
23076 // by the GS is assigned to specific stream.
23077 static const GLchar* gs = " goku = uni_goku;\n"
23078 " gohan = uni_gohan;\n"
23079 " goten = uni_goten;\n"
23080 " EmitStreamVertex(0);\n"
23081 " EndStreamPrimitive(0);\n"
23082 " picolo = uni_picolo;\n"
23083 " vegeta = uni_vegeta;\n"
23084 " EmitStreamVertex(1);\n"
23085 " EndStreamPrimitive(1);\n"
23086 " bulma = uni_bulma;\n"
23087 " EmitStreamVertex(2);\n"
23088 " EndStreamPrimitive(2);\n";
23090 static const GLchar* fs = " fs_out = gohan + goku + goten;\n";
23092 const GLchar* assignments = "";
23095 case Utils::Shader::FRAGMENT:
23098 case Utils::Shader::GEOMETRY:
23105 out_assignments = assignments;
23108 /** Get interface of shader
23111 * @param stage Shader stage
23112 * @param out_interface Set to ""
23114 void XFBVertexStreamsTest::getShaderInterface(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
23115 std::string& out_interface)
23117 static const GLchar* gs = "layout (xfb_buffer = 1, xfb_stride = 64) out;\n"
23118 "layout (xfb_buffer = 2, xfb_stride = 64) out;\n"
23119 "layout (xfb_buffer = 3, xfb_stride = 64) out;\n"
23121 "layout (stream = 0, xfb_buffer = 1, xfb_offset = 48) out vec4 goku;\n"
23122 "layout (stream = 0, xfb_buffer = 1, xfb_offset = 32) out vec4 gohan;\n"
23123 "layout (stream = 0, xfb_buffer = 1, xfb_offset = 16) out vec4 goten;\n"
23124 "layout (stream = 1, xfb_buffer = 3, xfb_offset = 48) out vec4 picolo;\n"
23125 "layout (stream = 1, xfb_buffer = 3, xfb_offset = 32) out vec4 vegeta;\n"
23126 "layout (stream = 2, xfb_buffer = 2, xfb_offset = 32) out vec4 bulma;\n"
23128 "layout(binding = 0) uniform gs_block {\n"
23129 " vec4 uni_goku;\n"
23130 " vec4 uni_gohan;\n"
23131 " vec4 uni_goten;\n"
23132 " vec4 uni_picolo;\n"
23133 " vec4 uni_vegeta;\n"
23134 " vec4 uni_bulma;\n"
23137 Fixed incorrect usage of in/out qualifier, the following variable should be input symbols for fragment shader
23139 static const GLchar* fs = "in vec4 goku;\n"
23143 "out vec4 fs_out;\n";
23147 case Utils::Shader::FRAGMENT:
23148 out_interface = fs;
23150 case Utils::Shader::GEOMETRY:
23151 out_interface = gs;
23154 out_interface = "";
23161 * @param context Test framework context
23163 XFBMultipleVertexStreamsTest::XFBMultipleVertexStreamsTest(deqp::Context& context)
23164 : NegativeTestBase(
23165 context, "xfb_multiple_vertex_streams",
23166 "Test verifies that compiler reports error when multiple streams are captured with same xfb_buffer")
23170 /** Source for given test case and stage
23173 * @param stage Shader stage
23175 * @return Shader source
23177 std::string XFBMultipleVertexStreamsTest::getShaderSource(GLuint /* test_case_index */, Utils::Shader::STAGES stage)
23179 static const GLchar* var_definition = "const uint valid_stride = 64;\n"
23181 "layout (xfb_buffer = 1, xfb_stride = valid_stride) out;\n"
23182 "layout (xfb_buffer = 3, xfb_stride = valid_stride) out;\n"
23185 "layout (stream = 0, xfb_buffer = 1, xfb_offset = 48) out vec4 goku;\n"
23186 "layout (stream = 1, xfb_buffer = 1, xfb_offset = 32) out vec4 gohan;\n"
23187 "layout (stream = 2, xfb_buffer = 1, xfb_offset = 16) out vec4 goten;\n";
23188 static const GLchar* var_use = " goku = result / 2;\n"
23189 " gohan = result / 4;\n"
23190 " goten = result / 6;\n";
23191 static const GLchar* fs = "#version 430 core\n"
23192 "#extension GL_ARB_enhanced_layouts : require\n"
23196 "out vec4 fs_out;\n"
23200 " fs_out = gs_fs + goku;\n"
23203 static const GLchar* gs = "#version 430 core\n"
23204 "#extension GL_ARB_enhanced_layouts : require\n"
23206 "layout(points) in;\n"
23207 "layout(triangle_strip, max_vertices = 4) out;\n"
23211 "in vec4 tes_gs[];\n"
23212 "out vec4 gs_fs;\n"
23216 " vec4 result = tes_gs[0];\n"
23220 " gs_fs = result;\n"
23221 " gl_Position = vec4(-1, -1, 0, 1);\n"
23223 " gs_fs = result;\n"
23224 " gl_Position = vec4(-1, 1, 0, 1);\n"
23226 " gs_fs = result;\n"
23227 " gl_Position = vec4(1, -1, 0, 1);\n"
23229 " gs_fs = result;\n"
23230 " gl_Position = vec4(1, 1, 0, 1);\n"
23234 static const GLchar* vs = "#version 430 core\n"
23235 "#extension GL_ARB_enhanced_layouts : require\n"
23238 "out vec4 vs_tcs;\n"
23242 " vs_tcs = in_vs;\n"
23246 std::string source;
23248 if (Utils::Shader::GEOMETRY == stage)
23250 size_t position = 0;
23254 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
23255 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
23261 case Utils::Shader::FRAGMENT:
23264 case Utils::Shader::VERTEX:
23275 /** Selects if "compute" stage is relevant for test
23281 bool XFBMultipleVertexStreamsTest::isComputeRelevant(GLuint /* test_case_index */)
23288 * @param context Test framework context
23290 XFBExceedBufferLimitTest::XFBExceedBufferLimitTest(deqp::Context& context)
23291 : NegativeTestBase(context, "xfb_exceed_buffer_limit",
23292 "Test verifies that compiler reports error when xfb_buffer qualifier exceeds limit")
23296 /** Source for given test case and stage
23298 * @param test_case_index Index of test case
23299 * @param stage Shader stage
23301 * @return Shader source
23303 std::string XFBExceedBufferLimitTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
23305 static const GLchar* block_var_definition = "const uint buffer_index = BUFFER;\n"
23307 "layout (xfb_buffer = buffer_index, xfb_offset = 0) out Goku {\n"
23310 static const GLchar* global_var_definition = "const uint buffer_index = BUFFER;\n"
23312 "layout (xfb_buffer = buffer_index) out;\n";
23313 static const GLchar* vector_var_definition = "const uint buffer_index = BUFFER;\n"
23315 "layout (xfb_buffer = buffer_index) out vec4 gokuARRAY;\n";
23316 static const GLchar* block_use = " gokuINDEX.member = result / 2;\n";
23317 static const GLchar* global_use = "";
23318 static const GLchar* vector_use = " gokuINDEX = result / 2;\n";
23319 static const GLchar* fs = "#version 430 core\n"
23320 "#extension GL_ARB_enhanced_layouts : require\n"
23323 "out vec4 fs_out;\n"
23327 " fs_out = gs_fs;\n"
23330 static const GLchar* gs_tested = "#version 430 core\n"
23331 "#extension GL_ARB_enhanced_layouts : require\n"
23333 "layout(points) in;\n"
23334 "layout(triangle_strip, max_vertices = 4) out;\n"
23338 "in vec4 tes_gs[];\n"
23339 "out vec4 gs_fs;\n"
23343 " vec4 result = tes_gs[0];\n"
23347 " gs_fs = result;\n"
23348 " gl_Position = vec4(-1, -1, 0, 1);\n"
23350 " gs_fs = result;\n"
23351 " gl_Position = vec4(-1, 1, 0, 1);\n"
23353 " gs_fs = result;\n"
23354 " gl_Position = vec4(1, -1, 0, 1);\n"
23356 " gs_fs = result;\n"
23357 " gl_Position = vec4(1, 1, 0, 1);\n"
23361 static const GLchar* tcs = "#version 430 core\n"
23362 "#extension GL_ARB_enhanced_layouts : require\n"
23364 "layout(vertices = 1) out;\n"
23366 "in vec4 vs_tcs[];\n"
23367 "out vec4 tcs_tes[];\n"
23372 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\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* tcs_tested = "#version 430 core\n"
23383 "#extension GL_ARB_enhanced_layouts : require\n"
23385 "layout(vertices = 1) out;\n"
23389 "in vec4 vs_tcs[];\n"
23390 "out vec4 tcs_tes[];\n"
23394 " vec4 result = vs_tcs[gl_InvocationID];\n"
23398 " tcs_tes[gl_InvocationID] = result;\n"
23400 " gl_TessLevelOuter[0] = 1.0;\n"
23401 " gl_TessLevelOuter[1] = 1.0;\n"
23402 " gl_TessLevelOuter[2] = 1.0;\n"
23403 " gl_TessLevelOuter[3] = 1.0;\n"
23404 " gl_TessLevelInner[0] = 1.0;\n"
23405 " gl_TessLevelInner[1] = 1.0;\n"
23408 static const GLchar* tes_tested = "#version 430 core\n"
23409 "#extension GL_ARB_enhanced_layouts : require\n"
23411 "layout(isolines, point_mode) in;\n"
23415 "in vec4 tcs_tes[];\n"
23416 "out vec4 tes_gs;\n"
23420 " vec4 result = tcs_tes[0];\n"
23424 " tes_gs += result;\n"
23427 static const GLchar* vs = "#version 430 core\n"
23428 "#extension GL_ARB_enhanced_layouts : require\n"
23431 "out vec4 vs_tcs;\n"
23435 " vs_tcs = in_vs;\n"
23438 static const GLchar* vs_tested = "#version 430 core\n"
23439 "#extension GL_ARB_enhanced_layouts : require\n"
23444 "out vec4 vs_tcs;\n"
23448 " vec4 result = in_vs;\n"
23452 " vs_tcs = result;\n"
23456 std::string source;
23457 testCase& test_case = m_test_cases[test_case_index];
23459 if (test_case.m_stage == stage)
23461 const GLchar* array = "";
23463 const Functions& gl = m_context.getRenderContext().getFunctions();
23464 const GLchar* index = "";
23465 GLint max_n_xfb = 0;
23466 size_t position = 0;
23468 const GLchar* var_definition = 0;
23469 const GLchar* var_use = 0;
23471 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_n_xfb);
23472 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
23474 sprintf(buffer, "%d", max_n_xfb);
23476 switch (test_case.m_case)
23479 var_definition = block_var_definition;
23480 var_use = block_use;
23483 var_definition = global_var_definition;
23484 var_use = global_use;
23487 var_definition = vector_var_definition;
23488 var_use = vector_use;
23491 TCU_FAIL("Invalid enum");
23496 case Utils::Shader::GEOMETRY:
23497 source = gs_tested;
23501 case Utils::Shader::TESS_CTRL:
23502 source = tcs_tested;
23504 index = "[gl_InvocationID]";
23506 case Utils::Shader::TESS_EVAL:
23507 source = tes_tested;
23511 case Utils::Shader::VERTEX:
23512 source = vs_tested;
23515 TCU_FAIL("Invalid enum");
23519 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
23521 Utils::replaceToken("BUFFER", position, buffer, source);
23522 if (GLOBAL != test_case.m_case)
23524 Utils::replaceToken("ARRAY", position, array, source);
23526 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
23528 Utils::replaceAllTokens("INDEX", index, source);
23532 switch (test_case.m_stage)
23534 case Utils::Shader::GEOMETRY:
23537 case Utils::Shader::FRAGMENT:
23540 case Utils::Shader::VERTEX:
23547 case Utils::Shader::TESS_CTRL:
23550 case Utils::Shader::FRAGMENT:
23553 case Utils::Shader::VERTEX:
23560 case Utils::Shader::TESS_EVAL:
23563 case Utils::Shader::FRAGMENT:
23566 case Utils::Shader::TESS_CTRL:
23569 case Utils::Shader::VERTEX:
23576 case Utils::Shader::VERTEX:
23579 case Utils::Shader::FRAGMENT:
23587 TCU_FAIL("Invalid enum");
23595 /** Get description of test case
23597 * @param test_case_index Index of test case
23599 * @return Test case description
23601 std::string XFBExceedBufferLimitTest::getTestCaseName(GLuint test_case_index)
23603 std::stringstream stream;
23604 testCase& test_case = m_test_cases[test_case_index];
23606 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", case: ";
23608 switch (test_case.m_case)
23614 stream << "GLOBAL";
23617 stream << "VECTOR";
23620 TCU_FAIL("Invalid enum");
23623 return stream.str();
23626 /** Get number of test cases
23628 * @return Number of test cases
23630 GLuint XFBExceedBufferLimitTest::getTestCaseNumber()
23632 return static_cast<GLuint>(m_test_cases.size());
23635 /** Selects if "compute" stage is relevant for test
23641 bool XFBExceedBufferLimitTest::isComputeRelevant(GLuint /* test_case_index */)
23646 /** Prepare all test cases
23649 void XFBExceedBufferLimitTest::testInit()
23651 for (GLuint c = 0; c < CASE_MAX; ++c)
23653 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
23655 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
23656 (Utils::Shader::FRAGMENT == stage))
23661 testCase test_case = { (CASES)c, (Utils::Shader::STAGES)stage };
23663 m_test_cases.push_back(test_case);
23670 * @param context Test framework context
23672 XFBExceedOffsetLimitTest::XFBExceedOffsetLimitTest(deqp::Context& context)
23673 : NegativeTestBase(context, "xfb_exceed_offset_limit",
23674 "Test verifies that compiler reports error when xfb_offset qualifier exceeds limit")
23678 /** Source for given test case and stage
23680 * @param test_case_index Index of test case
23681 * @param stage Shader stage
23683 * @return Shader source
23685 std::string XFBExceedOffsetLimitTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
23687 static const GLchar* block_var_definition = "const uint max_size = SIZE;\n"
23689 "layout (xfb_buffer = 0, xfb_offset = max_size + 16) out Goku {\n"
23692 static const GLchar* global_var_definition = "const uint max_size = SIZE;\n"
23694 "layout (xfb_buffer = 0, xfb_stride = max_size + 16) out;\n";
23695 static const GLchar* vector_var_definition =
23696 "const uint max_size = SIZE;\n"
23698 "layout (xfb_buffer = 0, xfb_offset = max_size + 16) out vec4 gokuARRAY;\n";
23699 static const GLchar* block_use = " gokuINDEX.member = result / 2;\n";
23700 static const GLchar* global_use = "";
23701 static const GLchar* vector_use = " gokuINDEX = result / 2;\n";
23702 static const GLchar* fs = "#version 430 core\n"
23703 "#extension GL_ARB_enhanced_layouts : require\n"
23706 "out vec4 fs_out;\n"
23710 " fs_out = gs_fs;\n"
23713 static const GLchar* gs_tested = "#version 430 core\n"
23714 "#extension GL_ARB_enhanced_layouts : require\n"
23716 "layout(points) in;\n"
23717 "layout(triangle_strip, max_vertices = 4) out;\n"
23721 "in vec4 tes_gs[];\n"
23722 "out vec4 gs_fs;\n"
23726 " vec4 result = tes_gs[0];\n"
23730 " gs_fs = result;\n"
23731 " gl_Position = vec4(-1, -1, 0, 1);\n"
23733 " gs_fs = result;\n"
23734 " gl_Position = vec4(-1, 1, 0, 1);\n"
23736 " gs_fs = result;\n"
23737 " gl_Position = vec4(1, -1, 0, 1);\n"
23739 " gs_fs = result;\n"
23740 " gl_Position = vec4(1, 1, 0, 1);\n"
23744 static const GLchar* tcs = "#version 430 core\n"
23745 "#extension GL_ARB_enhanced_layouts : require\n"
23747 "layout(vertices = 1) out;\n"
23749 "in vec4 vs_tcs[];\n"
23750 "out vec4 tcs_tes[];\n"
23755 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\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* tcs_tested = "#version 430 core\n"
23766 "#extension GL_ARB_enhanced_layouts : require\n"
23768 "layout(vertices = 1) out;\n"
23772 "in vec4 vs_tcs[];\n"
23773 "out vec4 tcs_tes[];\n"
23777 " vec4 result = vs_tcs[gl_InvocationID];\n"
23781 " tcs_tes[gl_InvocationID] = result;\n"
23783 " gl_TessLevelOuter[0] = 1.0;\n"
23784 " gl_TessLevelOuter[1] = 1.0;\n"
23785 " gl_TessLevelOuter[2] = 1.0;\n"
23786 " gl_TessLevelOuter[3] = 1.0;\n"
23787 " gl_TessLevelInner[0] = 1.0;\n"
23788 " gl_TessLevelInner[1] = 1.0;\n"
23791 static const GLchar* tes_tested = "#version 430 core\n"
23792 "#extension GL_ARB_enhanced_layouts : require\n"
23794 "layout(isolines, point_mode) in;\n"
23798 "in vec4 tcs_tes[];\n"
23799 "out vec4 tes_gs;\n"
23803 " vec4 result = tcs_tes[0];\n"
23807 " tes_gs += result;\n"
23810 static const GLchar* vs = "#version 430 core\n"
23811 "#extension GL_ARB_enhanced_layouts : require\n"
23814 "out vec4 vs_tcs;\n"
23818 " vs_tcs = in_vs;\n"
23821 static const GLchar* vs_tested = "#version 430 core\n"
23822 "#extension GL_ARB_enhanced_layouts : require\n"
23827 "out vec4 vs_tcs;\n"
23831 " vec4 result = in_vs;\n"
23835 " vs_tcs = result;\n"
23839 std::string source;
23840 testCase& test_case = m_test_cases[test_case_index];
23842 if (test_case.m_stage == stage)
23844 const GLchar* array = "";
23846 const Functions& gl = m_context.getRenderContext().getFunctions();
23847 const GLchar* index = "";
23848 GLint max_n_xfb_comp = 0;
23849 GLint max_n_xfb_bytes = 0;
23850 size_t position = 0;
23852 const GLchar* var_definition = 0;
23853 const GLchar* var_use = 0;
23855 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_n_xfb_comp);
23856 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
23858 max_n_xfb_bytes = max_n_xfb_comp * 4;
23860 sprintf(buffer, "%d", max_n_xfb_bytes);
23862 switch (test_case.m_case)
23865 var_definition = block_var_definition;
23866 var_use = block_use;
23869 var_definition = global_var_definition;
23870 var_use = global_use;
23873 var_definition = vector_var_definition;
23874 var_use = vector_use;
23877 TCU_FAIL("Invalid enum");
23879 // It is a compile time error to apply xfb_offset to the declaration of an unsized array(GLSL4.5 spec: Page73)
23880 // change array = "[]" to "[1]"
23883 case Utils::Shader::GEOMETRY:
23884 source = gs_tested;
23888 case Utils::Shader::TESS_CTRL:
23889 source = tcs_tested;
23891 index = "[gl_InvocationID]";
23893 case Utils::Shader::TESS_EVAL:
23894 source = tes_tested;
23898 case Utils::Shader::VERTEX:
23899 source = vs_tested;
23902 TCU_FAIL("Invalid enum");
23906 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
23908 Utils::replaceToken("SIZE", position, buffer, source);
23909 if (GLOBAL != test_case.m_case)
23911 Utils::replaceToken("ARRAY", position, array, source);
23913 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
23915 Utils::replaceAllTokens("INDEX", index, source);
23919 switch (test_case.m_stage)
23921 case Utils::Shader::GEOMETRY:
23924 case Utils::Shader::FRAGMENT:
23927 case Utils::Shader::VERTEX:
23934 case Utils::Shader::TESS_CTRL:
23937 case Utils::Shader::FRAGMENT:
23940 case Utils::Shader::VERTEX:
23947 case Utils::Shader::TESS_EVAL:
23950 case Utils::Shader::FRAGMENT:
23953 case Utils::Shader::TESS_CTRL:
23956 case Utils::Shader::VERTEX:
23963 case Utils::Shader::VERTEX:
23966 case Utils::Shader::FRAGMENT:
23974 TCU_FAIL("Invalid enum");
23982 /** Get description of test case
23984 * @param test_case_index Index of test case
23986 * @return Test case description
23988 std::string XFBExceedOffsetLimitTest::getTestCaseName(GLuint test_case_index)
23990 std::stringstream stream;
23991 testCase& test_case = m_test_cases[test_case_index];
23993 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", case: ";
23995 switch (test_case.m_case)
24001 stream << "GLOBAL";
24004 stream << "VECTOR";
24007 TCU_FAIL("Invalid enum");
24010 return stream.str();
24013 /** Get number of test cases
24015 * @return Number of test cases
24017 GLuint XFBExceedOffsetLimitTest::getTestCaseNumber()
24019 return static_cast<GLuint>(m_test_cases.size());
24022 /** Selects if "compute" stage is relevant for test
24028 bool XFBExceedOffsetLimitTest::isComputeRelevant(GLuint /* test_case_index */)
24033 /** Prepare all test cases
24036 void XFBExceedOffsetLimitTest::testInit()
24038 for (GLuint c = 0; c < CASE_MAX; ++c)
24040 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
24042 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
24043 (Utils::Shader::FRAGMENT == stage))
24048 testCase test_case = { (CASES)c, (Utils::Shader::STAGES)stage };
24050 m_test_cases.push_back(test_case);
24057 * @param context Test context
24059 XFBGlobalBufferTest::XFBGlobalBufferTest(deqp::Context& context)
24060 : BufferTestBase(context, "xfb_global_buffer", "Test verifies that global xfb_buffer qualifier is respected")
24062 /* Nothing to be done here */
24065 /** Get descriptors of buffers necessary for test
24067 * @param test_case_index Index of test case
24068 * @param out_descriptors Descriptors of buffers used by test
24070 void XFBGlobalBufferTest::getBufferDescriptors(glw::GLuint test_case_index, bufferDescriptor::Vector& out_descriptors)
24072 // the function "getType(test_case_index)" can't return correct data type, so change code as following:
24073 const Utils::Type& type = m_test_cases[test_case_index].m_type;
24075 /* Test needs single uniform and two xfbs */
24076 out_descriptors.resize(3);
24078 /* Get references */
24079 bufferDescriptor& uniform = out_descriptors[0];
24080 bufferDescriptor& xfb_1 = out_descriptors[1];
24081 bufferDescriptor& xfb_3 = out_descriptors[2];
24084 uniform.m_index = 0;
24089 uniform.m_target = Utils::Buffer::Uniform;
24090 xfb_1.m_target = Utils::Buffer::Transform_feedback;
24091 xfb_3.m_target = Utils::Buffer::Transform_feedback;
24094 const GLuint gen_start = Utils::s_rand;
24095 const std::vector<GLubyte>& chichi_data = type.GenerateData();
24096 const std::vector<GLubyte>& bulma_data = type.GenerateData();
24097 const std::vector<GLubyte>& trunks_data = type.GenerateData();
24098 const std::vector<GLubyte>& bra_data = type.GenerateData();
24099 const std::vector<GLubyte>& gohan_data = type.GenerateData();
24100 const std::vector<GLubyte>& goten_data = type.GenerateData();
24102 Utils::s_rand = gen_start;
24103 const std::vector<GLubyte>& chichi_data_pck = type.GenerateDataPacked();
24104 const std::vector<GLubyte>& bulma_data_pck = type.GenerateDataPacked();
24105 const std::vector<GLubyte>& trunks_data_pck = type.GenerateDataPacked();
24106 const std::vector<GLubyte>& bra_data_pck = type.GenerateDataPacked();
24107 const std::vector<GLubyte>& gohan_data_pck = type.GenerateDataPacked();
24108 const std::vector<GLubyte>& goten_data_pck = type.GenerateDataPacked();
24110 const GLuint type_size = static_cast<GLuint>(chichi_data.size());
24111 const GLuint type_size_pck = static_cast<GLuint>(chichi_data_pck.size());
24114 uniform.m_initial_data.resize(6 * type_size);
24115 memcpy(&uniform.m_initial_data[0] + 0, &chichi_data[0], type_size);
24116 memcpy(&uniform.m_initial_data[0] + type_size, &bulma_data[0], type_size);
24117 memcpy(&uniform.m_initial_data[0] + 2 * type_size, &trunks_data[0], type_size);
24118 memcpy(&uniform.m_initial_data[0] + 3 * type_size, &bra_data[0], type_size);
24119 memcpy(&uniform.m_initial_data[0] + 4 * type_size, &gohan_data[0], type_size);
24120 memcpy(&uniform.m_initial_data[0] + 5 * type_size, &goten_data[0], type_size);
24123 xfb_1.m_initial_data.resize(3 * type_size_pck);
24124 xfb_1.m_expected_data.resize(3 * type_size_pck);
24125 xfb_3.m_initial_data.resize(3 * type_size_pck);
24126 xfb_3.m_expected_data.resize(3 * type_size_pck);
24128 for (GLuint i = 0; i < 3 * type_size_pck; ++i)
24130 xfb_1.m_initial_data[i] = (glw::GLubyte)i;
24131 xfb_1.m_expected_data[i] = (glw::GLubyte)i;
24132 xfb_3.m_initial_data[i] = (glw::GLubyte)i;
24133 xfb_3.m_expected_data[i] = (glw::GLubyte)i;
24136 memcpy(&xfb_3.m_expected_data[0] + 2 * type_size_pck, &chichi_data_pck[0], type_size_pck);
24137 memcpy(&xfb_1.m_expected_data[0] + 0 * type_size_pck, &bulma_data_pck[0], type_size_pck);
24138 memcpy(&xfb_1.m_expected_data[0] + 1 * type_size_pck, &trunks_data_pck[0], type_size_pck);
24139 memcpy(&xfb_1.m_expected_data[0] + 2 * type_size_pck, &bra_data_pck[0], type_size_pck);
24140 memcpy(&xfb_3.m_expected_data[0] + 0 * type_size_pck, &gohan_data_pck[0], type_size_pck);
24141 memcpy(&xfb_3.m_expected_data[0] + 1 * type_size_pck, &goten_data_pck[0], type_size_pck);
24144 /** Source for given test case and stage
24146 * @param test_case_index Index of test case
24147 * @param stage Shader stage
24149 * @return Shader source
24151 std::string XFBGlobalBufferTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
24153 static const GLchar* fs =
24154 "#version 430 core\n"
24155 "#extension GL_ARB_enhanced_layouts : require\n"
24157 "flat in TYPE chichi;\n"
24158 "flat in TYPE bulma;\n"
24160 " flat TYPE trunk;\n"
24161 " flat TYPE bra;\n"
24164 " flat TYPE gohan;\n"
24165 " flat TYPE goten;\n"
24168 "out vec4 fs_out;\n"
24172 " fs_out = vec4(1);\n"
24173 " if (TYPE(1) != chichi + bulma + vegeta.trunk + vegeta.bra + goku.gohan + goku.goten)\n"
24175 " fs_out = vec4(0);\n"
24180 static const GLchar* gs = "#version 430 core\n"
24181 "#extension GL_ARB_enhanced_layouts : require\n"
24183 "layout(points) in;\n"
24184 "layout(points, max_vertices = 1) out;\n"
24195 static const GLchar* tcs = "#version 430 core\n"
24196 "#extension GL_ARB_enhanced_layouts : require\n"
24198 "layout(vertices = 1) out;\n"
24203 " gl_TessLevelOuter[0] = 1.0;\n"
24204 " gl_TessLevelOuter[1] = 1.0;\n"
24205 " gl_TessLevelOuter[2] = 1.0;\n"
24206 " gl_TessLevelOuter[3] = 1.0;\n"
24207 " gl_TessLevelInner[0] = 1.0;\n"
24208 " gl_TessLevelInner[1] = 1.0;\n"
24212 static const GLchar* tes = "#version 430 core\n"
24213 "#extension GL_ARB_enhanced_layouts : require\n"
24215 "layout(isolines, point_mode) in;\n"
24225 static const GLchar* vs = "#version 430 core\n"
24226 "#extension GL_ARB_enhanced_layouts : require\n"
24233 static const GLchar* vs_tested = "#version 430 core\n"
24234 "#extension GL_ARB_enhanced_layouts : require\n"
24244 std::string source;
24245 const _testCase& test_case = m_test_cases[test_case_index];
24246 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
24248 if (test_case.m_stage == stage)
24250 std::string assignments = " chichi = uni_chichi;\n"
24251 " bulma = uni_bulma;\n"
24252 " vegeta.trunk = uni_trunk;\n"
24253 " vegeta.bra = uni_bra;\n"
24254 " goku.gohan = uni_gohan;\n"
24255 " goku.goten = uni_goten;\n";
24257 std::string interface = "layout (xfb_buffer = 3) out;\n"
24259 "const uint type_size = SIZE;\n"
24261 "layout ( xfb_offset = 2 * type_size) flat out TYPE chichi;\n"
24262 "layout (xfb_buffer = 1, xfb_offset = 0) flat out TYPE bulma;\n"
24263 "layout (xfb_buffer = 1, xfb_offset = 1 * type_size) out Vegeta {\n"
24264 " flat TYPE trunk;\n"
24265 " flat TYPE bra;\n"
24267 "layout ( xfb_offset = 0) out Goku {\n"
24268 " flat TYPE gohan;\n"
24269 " flat TYPE goten;\n"
24272 // Uniform block must be declared with std140, otherwise each block member is not packed
24273 "layout(binding = 0, std140) uniform block {\n"
24274 " TYPE uni_chichi;\n"
24275 " TYPE uni_bulma;\n"
24276 " TYPE uni_trunk;\n"
24278 " TYPE uni_gohan;\n"
24279 " TYPE uni_goten;\n"
24282 /* Prepare interface string */
24285 size_t position = 0;
24286 const GLuint type_size = test_case.m_type.GetSize();
24288 sprintf(buffer, "%d", type_size);
24290 Utils::replaceToken("SIZE", position, buffer, interface);
24291 Utils::replaceAllTokens("TYPE", type_name, interface);
24296 case Utils::Shader::GEOMETRY:
24299 case Utils::Shader::TESS_EVAL:
24302 case Utils::Shader::VERTEX:
24303 source = vs_tested;
24306 TCU_FAIL("Invalid enum");
24309 /* Replace tokens */
24311 size_t position = 0;
24313 Utils::replaceToken("INTERFACE", position, interface.c_str(), source);
24314 Utils::replaceToken("ASSIGNMENTS", position, assignments.c_str(), source);
24319 switch (test_case.m_stage)
24321 case Utils::Shader::GEOMETRY:
24324 case Utils::Shader::FRAGMENT:
24326 Utils::replaceAllTokens("TYPE", type_name, source);
24328 case Utils::Shader::VERTEX:
24335 case Utils::Shader::TESS_EVAL:
24338 case Utils::Shader::FRAGMENT:
24340 Utils::replaceAllTokens("TYPE", type_name, source);
24342 case Utils::Shader::TESS_CTRL:
24345 case Utils::Shader::VERTEX:
24352 case Utils::Shader::VERTEX:
24355 case Utils::Shader::FRAGMENT:
24357 Utils::replaceAllTokens("TYPE", type_name, source);
24364 TCU_FAIL("Invalid enum");
24372 /** Get name of test case
24374 * @param test_case_index Index of test case
24376 * @return Name of case
24378 std::string XFBGlobalBufferTest::getTestCaseName(GLuint test_case_index)
24381 const _testCase& test_case = m_test_cases[test_case_index];
24383 name = "Tested stage: ";
24384 name.append(Utils::Shader::GetStageName(test_case.m_stage));
24385 name.append(". Tested type: ");
24386 name.append(test_case.m_type.GetGLSLTypeName());
24391 /** Get number of cases
24393 * @return Number of test cases
24395 GLuint XFBGlobalBufferTest::getTestCaseNumber()
24397 return static_cast<GLuint>(m_test_cases.size());
24400 /** Prepare set of test cases
24403 void XFBGlobalBufferTest::testInit()
24405 GLuint n_types = getTypesNumber();
24407 for (GLuint i = 0; i < n_types; ++i)
24409 const Utils::Type& type = getType(i);
24411 When the tfx varying is the following type, the number of output exceeds the gl_MaxVaryingComponents, which will
24412 cause a link time error.
24414 if (strcmp(type.GetGLSLTypeName(), "dmat3") == 0 || strcmp(type.GetGLSLTypeName(), "dmat4") == 0 ||
24415 strcmp(type.GetGLSLTypeName(), "dmat3x4") == 0 || strcmp(type.GetGLSLTypeName(), "dmat4x3") == 0)
24419 const _testCase test_cases[] = { { Utils::Shader::VERTEX, type },
24420 { Utils::Shader::GEOMETRY, type },
24421 { Utils::Shader::TESS_EVAL, type } };
24423 m_test_cases.push_back(test_cases[0]);
24424 m_test_cases.push_back(test_cases[1]);
24425 m_test_cases.push_back(test_cases[2]);
24431 * @param context Test context
24433 XFBStrideTest::XFBStrideTest(deqp::Context& context)
24434 : BufferTestBase(context, "xfb_stride", "Test verifies that correct stride is used for all types")
24436 /* Nothing to be done here */
24439 /** Execute drawArrays for single vertex
24441 * @param test_case_index
24445 bool XFBStrideTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
24447 const Functions& gl = m_context.getRenderContext().getFunctions();
24448 GLenum primitive_type = GL_PATCHES;
24449 const testCase& test_case = m_test_cases[test_case_index];
24451 if (Utils::Shader::VERTEX == test_case.m_stage)
24453 primitive_type = GL_POINTS;
24456 gl.disable(GL_RASTERIZER_DISCARD);
24457 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
24459 gl.beginTransformFeedback(GL_POINTS);
24460 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
24462 gl.drawArrays(primitive_type, 0 /* first */, 2 /* count */);
24463 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
24465 gl.endTransformFeedback();
24466 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
24471 /** Get descriptors of buffers necessary for test
24473 * @param test_case_index Index of test case
24474 * @param out_descriptors Descriptors of buffers used by test
24476 void XFBStrideTest::getBufferDescriptors(GLuint test_case_index, bufferDescriptor::Vector& out_descriptors)
24478 const testCase& test_case = m_test_cases[test_case_index];
24479 const Utils::Type& type = test_case.m_type;
24481 /* Test needs single uniform and xfb */
24482 out_descriptors.resize(2);
24484 /* Get references */
24485 bufferDescriptor& uniform = out_descriptors[0];
24486 bufferDescriptor& xfb = out_descriptors[1];
24489 uniform.m_index = 0;
24493 uniform.m_target = Utils::Buffer::Uniform;
24494 xfb.m_target = Utils::Buffer::Transform_feedback;
24497 const GLuint rand_start = Utils::s_rand;
24498 const std::vector<GLubyte>& uniform_data = type.GenerateData();
24500 Utils::s_rand = rand_start;
24501 const std::vector<GLubyte>& xfb_data = type.GenerateDataPacked();
24503 const GLuint uni_type_size = static_cast<GLuint>(uniform_data.size());
24504 const GLuint xfb_type_size = static_cast<GLuint>(xfb_data.size());
24506 Note: If xfb varying output from vertex shader, the variable "goku" will only output once to transform feedback buffer,
24507 if xfb varying output from TES or GS, because the input primitive type in TES is defined as "layout(isolines, point_mode) in;",
24508 the primitive type is line which make the variable "goku" will output twice to transform feedback buffer, so for vertex shader
24509 only one valid data should be initialized in xfb.m_expected_data
24511 const GLuint xfb_data_size = (test_case.m_stage == Utils::Shader::VERTEX) ? xfb_type_size : xfb_type_size * 2;
24513 uniform.m_initial_data.resize(uni_type_size);
24514 memcpy(&uniform.m_initial_data[0] + 0 * uni_type_size, &uniform_data[0], uni_type_size);
24517 xfb.m_initial_data.resize(xfb_data_size);
24518 xfb.m_expected_data.resize(xfb_data_size);
24520 for (GLuint i = 0; i < xfb_data_size; ++i)
24522 xfb.m_initial_data[i] = (glw::GLubyte)i;
24523 xfb.m_expected_data[i] = (glw::GLubyte)i;
24526 if (test_case.m_stage == Utils::Shader::VERTEX)
24528 memcpy(&xfb.m_expected_data[0] + 0 * xfb_type_size, &xfb_data[0], xfb_type_size);
24532 memcpy(&xfb.m_expected_data[0] + 0 * xfb_type_size, &xfb_data[0], xfb_type_size);
24533 memcpy(&xfb.m_expected_data[0] + 1 * xfb_type_size, &xfb_data[0], xfb_type_size);
24537 /** Get body of main function for given shader stage
24539 * @param test_case_index Index of test case
24540 * @param stage Shader stage
24541 * @param out_assignments Set to empty
24542 * @param out_calculations Set to empty
24544 void XFBStrideTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage, std::string& out_assignments,
24545 std::string& out_calculations)
24547 const testCase& test_case = m_test_cases[test_case_index];
24549 out_calculations = "";
24551 static const GLchar* vs_tes_gs = " goku = uni_goku;\n";
24552 static const GLchar* fs = " fs_out = vec4(1, 0.25, 0.5, 0.75);\n"
24553 " if (TYPE(0) == goku)\n"
24555 " fs_out = vec4(1, 0.75, 0.5, 0.5);\n"
24558 const GLchar* assignments = "";
24560 if (test_case.m_stage == stage)
24564 case Utils::Shader::GEOMETRY:
24565 assignments = vs_tes_gs;
24567 case Utils::Shader::TESS_EVAL:
24568 assignments = vs_tes_gs;
24570 case Utils::Shader::VERTEX:
24571 assignments = vs_tes_gs;
24574 TCU_FAIL("Invalid enum");
24581 case Utils::Shader::FRAGMENT:
24584 case Utils::Shader::GEOMETRY:
24585 case Utils::Shader::TESS_CTRL:
24586 case Utils::Shader::TESS_EVAL:
24587 case Utils::Shader::VERTEX:
24590 TCU_FAIL("Invalid enum");
24594 out_assignments = assignments;
24596 if (Utils::Shader::FRAGMENT == stage)
24598 Utils::replaceAllTokens("TYPE", test_case.m_type.GetGLSLTypeName(), out_assignments);
24602 /** Get interface of shader
24604 * @param test_case_index Index of test case
24605 * @param stage Shader stage
24606 * @param out_interface Set to ""
24608 void XFBStrideTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage, std::string& out_interface)
24610 static const GLchar* vs_tes_gs = "layout (xfb_offset = 0) FLAT out TYPE goku;\n"
24612 "layout(std140, binding = 0) uniform Goku {\n"
24613 " TYPE uni_goku;\n"
24615 static const GLchar* fs = "FLAT in TYPE goku;\n"
24617 "out vec4 fs_out;\n";
24619 const testCase& test_case = m_test_cases[test_case_index];
24620 const GLchar* interface = "";
24621 const GLchar* flat = "";
24623 if (test_case.m_stage == stage)
24627 case Utils::Shader::GEOMETRY:
24628 interface = vs_tes_gs;
24630 case Utils::Shader::TESS_EVAL:
24631 interface = vs_tes_gs;
24633 case Utils::Shader::VERTEX:
24634 interface = vs_tes_gs;
24637 TCU_FAIL("Invalid enum");
24644 case Utils::Shader::FRAGMENT:
24647 case Utils::Shader::GEOMETRY:
24648 case Utils::Shader::TESS_CTRL:
24649 case Utils::Shader::TESS_EVAL:
24650 case Utils::Shader::VERTEX:
24653 TCU_FAIL("Invalid enum");
24657 out_interface = interface;
24659 if (Utils::Type::Float != test_case.m_type.m_basic_type)
24664 Utils::replaceAllTokens("FLAT", flat, out_interface);
24665 Utils::replaceAllTokens("TYPE", test_case.m_type.GetGLSLTypeName(), out_interface);
24668 /** Get source code of shader
24670 * @param test_case_index Index of test case
24671 * @param stage Shader stage
24675 std::string XFBStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
24677 std::string source;
24678 const testCase& test_case = m_test_cases[test_case_index];
24680 switch (test_case.m_stage)
24682 case Utils::Shader::VERTEX:
24685 case Utils::Shader::FRAGMENT:
24686 case Utils::Shader::VERTEX:
24687 source = BufferTestBase::getShaderSource(test_case_index, stage);
24694 case Utils::Shader::TESS_EVAL:
24697 case Utils::Shader::FRAGMENT:
24698 case Utils::Shader::TESS_CTRL:
24699 case Utils::Shader::TESS_EVAL:
24700 case Utils::Shader::VERTEX:
24701 source = BufferTestBase::getShaderSource(test_case_index, stage);
24708 case Utils::Shader::GEOMETRY:
24709 source = BufferTestBase::getShaderSource(test_case_index, stage);
24713 TCU_FAIL("Invalid enum");
24721 /** Get name of test case
24723 * @param test_case_index Index of test case
24725 * @return Name of tested stage
24727 std::string XFBStrideTest::getTestCaseName(glw::GLuint test_case_index)
24729 std::stringstream stream;
24730 const testCase& test_case = m_test_cases[test_case_index];
24732 stream << "Type: " << test_case.m_type.GetGLSLTypeName()
24733 << ", stage: " << Utils::Shader::GetStageName(test_case.m_stage);
24735 return stream.str();
24738 /** Returns number of test cases
24742 glw::GLuint XFBStrideTest::getTestCaseNumber()
24744 return static_cast<GLuint>(m_test_cases.size());
24747 /** Prepare all test cases
24750 void XFBStrideTest::testInit()
24752 const GLuint n_types = getTypesNumber();
24754 for (GLuint i = 0; i < n_types; ++i)
24756 const Utils::Type& type = getType(i);
24758 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
24760 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::FRAGMENT == stage) ||
24761 (Utils::Shader::TESS_CTRL == stage))
24766 testCase test_case = { (Utils::Shader::STAGES)stage, type };
24768 m_test_cases.push_back(test_case);
24775 * @param context Test framework context
24777 XFBBlockMemberBufferTest::XFBBlockMemberBufferTest(deqp::Context& context)
24778 : NegativeTestBase(
24779 context, "xfb_block_member_buffer",
24780 "Test verifies that compiler reports error when block member has different xfb_buffer qualifier than buffer")
24784 /** Source for given test case and stage
24786 * @param test_case_index Index of test case
24787 * @param stage Shader stage
24789 * @return Shader source
24791 std::string XFBBlockMemberBufferTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
24793 static const GLchar* var_definition = "layout (xfb_offset = 0) out Goku {\n"
24795 " layout (xfb_buffer = 1) vec4 goten;\n"
24797 static const GLchar* var_use = " gokuINDEX.gohan = result / 2;\n"
24798 " gokuINDEX.goten = result / 4;\n";
24799 static const GLchar* fs = "#version 430 core\n"
24800 "#extension GL_ARB_enhanced_layouts : require\n"
24803 "out vec4 fs_out;\n"
24807 " fs_out = gs_fs;\n"
24810 static const GLchar* gs_tested = "#version 430 core\n"
24811 "#extension GL_ARB_enhanced_layouts : require\n"
24813 "layout(points) in;\n"
24814 "layout(triangle_strip, max_vertices = 4) out;\n"
24818 "in vec4 tes_gs[];\n"
24819 "out vec4 gs_fs;\n"
24823 " vec4 result = tes_gs[0];\n"
24827 " gs_fs = result;\n"
24828 " gl_Position = vec4(-1, -1, 0, 1);\n"
24830 " gs_fs = result;\n"
24831 " gl_Position = vec4(-1, 1, 0, 1);\n"
24833 " gs_fs = result;\n"
24834 " gl_Position = vec4(1, -1, 0, 1);\n"
24836 " gs_fs = result;\n"
24837 " gl_Position = vec4(1, 1, 0, 1);\n"
24841 static const GLchar* tcs = "#version 430 core\n"
24842 "#extension GL_ARB_enhanced_layouts : require\n"
24844 "layout(vertices = 1) out;\n"
24846 "in vec4 vs_tcs[];\n"
24847 "out vec4 tcs_tes[];\n"
24852 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\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* tcs_tested = "#version 430 core\n"
24863 "#extension GL_ARB_enhanced_layouts : require\n"
24865 "layout(vertices = 1) out;\n"
24869 "in vec4 vs_tcs[];\n"
24870 "out vec4 tcs_tes[];\n"
24874 " vec4 result = vs_tcs[gl_InvocationID];\n"
24878 " tcs_tes[gl_InvocationID] = result;\n"
24880 " gl_TessLevelOuter[0] = 1.0;\n"
24881 " gl_TessLevelOuter[1] = 1.0;\n"
24882 " gl_TessLevelOuter[2] = 1.0;\n"
24883 " gl_TessLevelOuter[3] = 1.0;\n"
24884 " gl_TessLevelInner[0] = 1.0;\n"
24885 " gl_TessLevelInner[1] = 1.0;\n"
24888 static const GLchar* tes_tested = "#version 430 core\n"
24889 "#extension GL_ARB_enhanced_layouts : require\n"
24891 "layout(isolines, point_mode) in;\n"
24895 "in vec4 tcs_tes[];\n"
24896 "out vec4 tes_gs;\n"
24900 " vec4 result = tcs_tes[0];\n"
24904 " tes_gs += result;\n"
24907 static const GLchar* vs = "#version 430 core\n"
24908 "#extension GL_ARB_enhanced_layouts : require\n"
24911 "out vec4 vs_tcs;\n"
24915 " vs_tcs = in_vs;\n"
24918 static const GLchar* vs_tested = "#version 430 core\n"
24919 "#extension GL_ARB_enhanced_layouts : require\n"
24924 "out vec4 vs_tcs;\n"
24928 " vec4 result = in_vs;\n"
24932 " vs_tcs = result;\n"
24936 std::string source;
24937 testCase& test_case = m_test_cases[test_case_index];
24939 if (test_case.m_stage == stage)
24941 const GLchar* array = "";
24942 const GLchar* index = "";
24943 size_t position = 0;
24947 case Utils::Shader::GEOMETRY:
24948 source = gs_tested;
24952 case Utils::Shader::TESS_CTRL:
24953 source = tcs_tested;
24955 index = "[gl_InvocationID]";
24957 case Utils::Shader::TESS_EVAL:
24958 source = tes_tested;
24962 case Utils::Shader::VERTEX:
24963 source = vs_tested;
24966 TCU_FAIL("Invalid enum");
24969 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
24971 Utils::replaceToken("ARRAY", position, array, source);
24972 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
24974 Utils::replaceAllTokens("INDEX", index, source);
24978 switch (test_case.m_stage)
24980 case Utils::Shader::GEOMETRY:
24983 case Utils::Shader::FRAGMENT:
24986 case Utils::Shader::VERTEX:
24993 case Utils::Shader::TESS_CTRL:
24996 case Utils::Shader::FRAGMENT:
24999 case Utils::Shader::VERTEX:
25006 case Utils::Shader::TESS_EVAL:
25009 case Utils::Shader::FRAGMENT:
25012 case Utils::Shader::TESS_CTRL:
25015 case Utils::Shader::VERTEX:
25022 case Utils::Shader::VERTEX:
25025 case Utils::Shader::FRAGMENT:
25033 TCU_FAIL("Invalid enum");
25041 /** Get description of test case
25043 * @param test_case_index Index of test case
25045 * @return Test case description
25047 std::string XFBBlockMemberBufferTest::getTestCaseName(GLuint test_case_index)
25049 std::stringstream stream;
25050 testCase& test_case = m_test_cases[test_case_index];
25052 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage);
25054 return stream.str();
25057 /** Get number of test cases
25059 * @return Number of test cases
25061 GLuint XFBBlockMemberBufferTest::getTestCaseNumber()
25063 return static_cast<GLuint>(m_test_cases.size());
25066 /** Selects if "compute" stage is relevant for test
25072 bool XFBBlockMemberBufferTest::isComputeRelevant(GLuint /* test_case_index */)
25077 /** Prepare all test cases
25080 void XFBBlockMemberBufferTest::testInit()
25082 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
25084 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
25085 (Utils::Shader::FRAGMENT == stage))
25090 testCase test_case = { (Utils::Shader::STAGES)stage };
25092 m_test_cases.push_back(test_case);
25098 * @param context Test framework context
25100 XFBOutputOverlappingTest::XFBOutputOverlappingTest(deqp::Context& context)
25101 : NegativeTestBase(context, "xfb_output_overlapping",
25102 "Test verifies that compiler reports error when two xfb qualified outputs overlap")
25106 /** Source for given test case and stage
25108 * @param test_case_index Index of test case
25109 * @param stage Shader stage
25111 * @return Shader source
25113 std::string XFBOutputOverlappingTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
25115 static const GLchar* var_definition = "layout (xfb_offset = OFFSET) out TYPE gohanARRAY;\n"
25116 "layout (xfb_offset = OFFSET) out TYPE gotenARRAY;\n";
25117 static const GLchar* var_use = " gohanINDEX = TYPE(0);\n"
25118 " gotenINDEX = TYPE(1);\n"
25119 " if (vec4(0) == result)\n"
25121 " gohanINDEX = TYPE(1);\n"
25122 " gotenINDEX = TYPE(0);\n"
25124 static const GLchar* fs = "#version 430 core\n"
25125 "#extension GL_ARB_enhanced_layouts : require\n"
25128 "out vec4 fs_out;\n"
25132 " fs_out = gs_fs;\n"
25135 static const GLchar* gs_tested = "#version 430 core\n"
25136 "#extension GL_ARB_enhanced_layouts : require\n"
25138 "layout(points) in;\n"
25139 "layout(triangle_strip, max_vertices = 4) out;\n"
25143 "in vec4 tes_gs[];\n"
25144 "out vec4 gs_fs;\n"
25148 " vec4 result = tes_gs[0];\n"
25152 " gs_fs = result;\n"
25153 " gl_Position = vec4(-1, -1, 0, 1);\n"
25155 " gs_fs = result;\n"
25156 " gl_Position = vec4(-1, 1, 0, 1);\n"
25158 " gs_fs = result;\n"
25159 " gl_Position = vec4(1, -1, 0, 1);\n"
25161 " gs_fs = result;\n"
25162 " gl_Position = vec4(1, 1, 0, 1);\n"
25166 static const GLchar* tcs = "#version 430 core\n"
25167 "#extension GL_ARB_enhanced_layouts : require\n"
25169 "layout(vertices = 1) out;\n"
25171 "in vec4 vs_tcs[];\n"
25172 "out vec4 tcs_tes[];\n"
25177 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\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* tcs_tested = "#version 430 core\n"
25188 "#extension GL_ARB_enhanced_layouts : require\n"
25190 "layout(vertices = 1) out;\n"
25194 "in vec4 vs_tcs[];\n"
25195 "out vec4 tcs_tes[];\n"
25199 " vec4 result = vs_tcs[gl_InvocationID];\n"
25203 " tcs_tes[gl_InvocationID] = result;\n"
25205 " gl_TessLevelOuter[0] = 1.0;\n"
25206 " gl_TessLevelOuter[1] = 1.0;\n"
25207 " gl_TessLevelOuter[2] = 1.0;\n"
25208 " gl_TessLevelOuter[3] = 1.0;\n"
25209 " gl_TessLevelInner[0] = 1.0;\n"
25210 " gl_TessLevelInner[1] = 1.0;\n"
25213 static const GLchar* tes_tested = "#version 430 core\n"
25214 "#extension GL_ARB_enhanced_layouts : require\n"
25216 "layout(isolines, point_mode) in;\n"
25220 "in vec4 tcs_tes[];\n"
25221 "out vec4 tes_gs;\n"
25225 " vec4 result = tcs_tes[0];\n"
25229 " tes_gs += result;\n"
25232 static const GLchar* vs = "#version 430 core\n"
25233 "#extension GL_ARB_enhanced_layouts : require\n"
25236 "out vec4 vs_tcs;\n"
25240 " vs_tcs = in_vs;\n"
25243 static const GLchar* vs_tested = "#version 430 core\n"
25244 "#extension GL_ARB_enhanced_layouts : require\n"
25249 "out vec4 vs_tcs;\n"
25253 " vec4 result = in_vs;\n"
25257 " vs_tcs = result;\n"
25261 std::string source;
25262 testCase& test_case = m_test_cases[test_case_index];
25264 if (test_case.m_stage == stage)
25266 const GLchar* array = "";
25267 GLchar buffer_gohan[16];
25268 GLchar buffer_goten[16];
25269 const GLchar* index = "";
25270 size_t position = 0;
25271 size_t position_start = 0;
25272 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
25274 sprintf(buffer_gohan, "%d", test_case.m_offset_gohan);
25275 sprintf(buffer_goten, "%d", test_case.m_offset_goten);
25279 case Utils::Shader::GEOMETRY:
25280 source = gs_tested;
25284 case Utils::Shader::TESS_CTRL:
25285 source = tcs_tested;
25287 index = "[gl_InvocationID]";
25289 case Utils::Shader::TESS_EVAL:
25290 source = tes_tested;
25294 case Utils::Shader::VERTEX:
25295 source = vs_tested;
25298 TCU_FAIL("Invalid enum");
25301 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
25303 Utils::replaceToken("OFFSET", position, buffer_gohan, source);
25304 Utils::replaceToken("TYPE", position, type_name, source);
25305 Utils::replaceToken("ARRAY", position, array, source);
25306 Utils::replaceToken("OFFSET", position, buffer_goten, source);
25307 Utils::replaceToken("TYPE", position, type_name, source);
25308 Utils::replaceToken("ARRAY", position, array, source);
25309 position_start = position;
25310 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
25311 position = position_start;
25312 Utils::replaceToken("INDEX", position, index, source);
25313 Utils::replaceToken("TYPE", position, type_name, source);
25314 Utils::replaceToken("INDEX", position, index, source);
25315 Utils::replaceToken("TYPE", position, type_name, source);
25316 Utils::replaceToken("INDEX", position, index, source);
25317 Utils::replaceToken("TYPE", position, type_name, source);
25318 Utils::replaceToken("INDEX", position, index, source);
25319 Utils::replaceToken("TYPE", position, type_name, source);
25323 switch (test_case.m_stage)
25325 case Utils::Shader::GEOMETRY:
25328 case Utils::Shader::FRAGMENT:
25331 case Utils::Shader::VERTEX:
25338 case Utils::Shader::TESS_CTRL:
25341 case Utils::Shader::FRAGMENT:
25344 case Utils::Shader::VERTEX:
25351 case Utils::Shader::TESS_EVAL:
25354 case Utils::Shader::FRAGMENT:
25357 case Utils::Shader::TESS_CTRL:
25360 case Utils::Shader::VERTEX:
25367 case Utils::Shader::VERTEX:
25370 case Utils::Shader::FRAGMENT:
25378 TCU_FAIL("Invalid enum");
25386 /** Get description of test case
25388 * @param test_case_index Index of test case
25390 * @return Test case description
25392 std::string XFBOutputOverlappingTest::getTestCaseName(GLuint test_case_index)
25394 std::stringstream stream;
25395 testCase& test_case = m_test_cases[test_case_index];
25397 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
25398 << ", type: " << test_case.m_type.GetGLSLTypeName() << ", offsets: " << test_case.m_offset_gohan << " & "
25399 << test_case.m_offset_goten;
25401 return stream.str();
25404 /** Get number of test cases
25406 * @return Number of test cases
25408 GLuint XFBOutputOverlappingTest::getTestCaseNumber()
25410 return static_cast<GLuint>(m_test_cases.size());
25413 /** Selects if "compute" stage is relevant for test
25419 bool XFBOutputOverlappingTest::isComputeRelevant(GLuint /* test_case_index */)
25424 /** Prepare all test cases
25427 void XFBOutputOverlappingTest::testInit()
25429 const GLuint n_types = getTypesNumber();
25431 for (GLuint i = 0; i < n_types; ++i)
25433 const Utils::Type& type = getType(i);
25434 const GLuint base_alingment = Utils::Type::GetTypeSize(type.m_basic_type);
25436 /* Skip scalars, not applicable as:
25438 * The offset must be a multiple of the size of the first component of the first
25439 * qualified variable or block member, or a compile-time error results.
25441 if ((1 == type.m_n_columns) && (1 == type.m_n_rows))
25446 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
25448 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
25449 (Utils::Shader::FRAGMENT == stage))
25454 testCase test_case = { 0 /* gohan offset */, base_alingment /* goten_offset */,
25455 (Utils::Shader::STAGES)stage, type };
25457 m_test_cases.push_back(test_case);
25464 * @param context Test framework context
25466 XFBInvalidOffsetAlignmentTest::XFBInvalidOffsetAlignmentTest(deqp::Context& context)
25467 : NegativeTestBase(context, "xfb_invalid_offset_alignment",
25468 "Test verifies that compiler reports error when xfb_offset has invalid alignment")
25472 /** Source for given test case and stage
25474 * @param test_case_index Index of test case
25475 * @param stage Shader stage
25477 * @return Shader source
25479 std::string XFBInvalidOffsetAlignmentTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
25481 static const GLchar* var_definition = "layout (xfb_offset = OFFSET) out TYPE gohanARRAY;\n";
25482 static const GLchar* var_use = " gohanINDEX = TYPE(0);\n"
25483 " if (vec4(0) == result)\n"
25485 " gohanINDEX = TYPE(1);\n"
25487 static const GLchar* fs = "#version 430 core\n"
25488 "#extension GL_ARB_enhanced_layouts : require\n"
25491 "out vec4 fs_out;\n"
25495 " fs_out = gs_fs;\n"
25498 static const GLchar* gs_tested = "#version 430 core\n"
25499 "#extension GL_ARB_enhanced_layouts : require\n"
25501 "layout(points) in;\n"
25502 "layout(triangle_strip, max_vertices = 4) out;\n"
25506 "in vec4 tes_gs[];\n"
25507 "out vec4 gs_fs;\n"
25511 " vec4 result = tes_gs[0];\n"
25515 " gs_fs = result;\n"
25516 " gl_Position = vec4(-1, -1, 0, 1);\n"
25518 " gs_fs = result;\n"
25519 " gl_Position = vec4(-1, 1, 0, 1);\n"
25521 " gs_fs = result;\n"
25522 " gl_Position = vec4(1, -1, 0, 1);\n"
25524 " gs_fs = result;\n"
25525 " gl_Position = vec4(1, 1, 0, 1);\n"
25529 static const GLchar* tcs = "#version 430 core\n"
25530 "#extension GL_ARB_enhanced_layouts : require\n"
25532 "layout(vertices = 1) out;\n"
25534 "in vec4 vs_tcs[];\n"
25535 "out vec4 tcs_tes[];\n"
25540 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\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* tcs_tested = "#version 430 core\n"
25551 "#extension GL_ARB_enhanced_layouts : require\n"
25553 "layout(vertices = 1) out;\n"
25557 "in vec4 vs_tcs[];\n"
25558 "out vec4 tcs_tes[];\n"
25562 " vec4 result = vs_tcs[gl_InvocationID];\n"
25566 " tcs_tes[gl_InvocationID] = result;\n"
25568 " gl_TessLevelOuter[0] = 1.0;\n"
25569 " gl_TessLevelOuter[1] = 1.0;\n"
25570 " gl_TessLevelOuter[2] = 1.0;\n"
25571 " gl_TessLevelOuter[3] = 1.0;\n"
25572 " gl_TessLevelInner[0] = 1.0;\n"
25573 " gl_TessLevelInner[1] = 1.0;\n"
25576 static const GLchar* tes_tested = "#version 430 core\n"
25577 "#extension GL_ARB_enhanced_layouts : require\n"
25579 "layout(isolines, point_mode) in;\n"
25583 "in vec4 tcs_tes[];\n"
25584 "out vec4 tes_gs;\n"
25588 " vec4 result = tcs_tes[0];\n"
25592 " tes_gs += result;\n"
25595 static const GLchar* vs = "#version 430 core\n"
25596 "#extension GL_ARB_enhanced_layouts : require\n"
25599 "out vec4 vs_tcs;\n"
25603 " vs_tcs = in_vs;\n"
25606 static const GLchar* vs_tested = "#version 430 core\n"
25607 "#extension GL_ARB_enhanced_layouts : require\n"
25612 "out vec4 vs_tcs;\n"
25616 " vec4 result = in_vs;\n"
25620 " vs_tcs = result;\n"
25624 std::string source;
25625 testCase& test_case = m_test_cases[test_case_index];
25627 if (test_case.m_stage == stage)
25629 const GLchar* array = "";
25631 const GLchar* index = "";
25632 size_t position = 0;
25633 size_t position_start = 0;
25634 const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
25636 sprintf(buffer, "%d", test_case.m_offset);
25640 case Utils::Shader::GEOMETRY:
25641 source = gs_tested;
25645 case Utils::Shader::TESS_CTRL:
25646 source = tcs_tested;
25648 index = "[gl_InvocationID]";
25650 case Utils::Shader::TESS_EVAL:
25651 source = tes_tested;
25655 case Utils::Shader::VERTEX:
25656 source = vs_tested;
25659 TCU_FAIL("Invalid enum");
25662 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
25664 Utils::replaceToken("OFFSET", position, buffer, source);
25665 Utils::replaceToken("TYPE", position, type_name, source);
25666 Utils::replaceToken("ARRAY", position, array, source);
25667 position_start = position;
25668 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
25669 position = position_start;
25670 Utils::replaceToken("INDEX", position, index, source);
25671 Utils::replaceToken("TYPE", position, type_name, source);
25672 Utils::replaceToken("INDEX", position, index, source);
25673 Utils::replaceToken("TYPE", position, type_name, source);
25677 switch (test_case.m_stage)
25679 case Utils::Shader::GEOMETRY:
25682 case Utils::Shader::FRAGMENT:
25685 case Utils::Shader::VERTEX:
25692 case Utils::Shader::TESS_CTRL:
25695 case Utils::Shader::FRAGMENT:
25698 case Utils::Shader::VERTEX:
25705 case Utils::Shader::TESS_EVAL:
25708 case Utils::Shader::FRAGMENT:
25711 case Utils::Shader::TESS_CTRL:
25714 case Utils::Shader::VERTEX:
25721 case Utils::Shader::VERTEX:
25724 case Utils::Shader::FRAGMENT:
25732 TCU_FAIL("Invalid enum");
25740 /** Get description of test case
25742 * @param test_case_index Index of test case
25744 * @return Test case description
25746 std::string XFBInvalidOffsetAlignmentTest::getTestCaseName(GLuint test_case_index)
25748 std::stringstream stream;
25749 testCase& test_case = m_test_cases[test_case_index];
25751 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
25752 << ", type: " << test_case.m_type.GetGLSLTypeName() << ", offset: " << test_case.m_offset;
25754 return stream.str();
25757 /** Get number of test cases
25759 * @return Number of test cases
25761 GLuint XFBInvalidOffsetAlignmentTest::getTestCaseNumber()
25763 return static_cast<GLuint>(m_test_cases.size());
25766 /** Selects if "compute" stage is relevant for test
25772 bool XFBInvalidOffsetAlignmentTest::isComputeRelevant(GLuint /* test_case_index */)
25777 /** Prepare all test cases
25780 void XFBInvalidOffsetAlignmentTest::testInit()
25782 const GLuint n_types = getTypesNumber();
25784 for (GLuint i = 0; i < n_types; ++i)
25786 const Utils::Type& type = getType(i);
25787 const GLuint base_alingment = Utils::Type::GetTypeSize(type.m_basic_type);
25789 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
25791 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
25792 (Utils::Shader::FRAGMENT == stage))
25797 for (GLuint offset = base_alingment + 1; offset < 2 * base_alingment; ++offset)
25799 testCase test_case = { offset, (Utils::Shader::STAGES)stage, type };
25801 m_test_cases.push_back(test_case);
25809 * @param context Test context
25811 XFBCaptureInactiveOutputVariableTest::XFBCaptureInactiveOutputVariableTest(deqp::Context& context)
25812 : BufferTestBase(context, "xfb_capture_inactive_output_variable",
25813 "Test verifies that inactive variables are captured")
25815 /* Nothing to be done here */
25818 /** Execute drawArrays for single vertex
25820 * @param test_case_index
25824 bool XFBCaptureInactiveOutputVariableTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
25826 const Functions& gl = m_context.getRenderContext().getFunctions();
25827 GLenum primitive_type = GL_PATCHES;
25829 if (TEST_VS == test_case_index)
25831 primitive_type = GL_POINTS;
25834 gl.disable(GL_RASTERIZER_DISCARD);
25835 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
25837 gl.beginTransformFeedback(GL_POINTS);
25838 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
25840 gl.drawArrays(primitive_type, 0 /* first */, 1 /* count */);
25841 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
25843 gl.endTransformFeedback();
25844 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
25849 /** Get descriptors of buffers necessary for test
25852 * @param out_descriptors Descriptors of buffers used by test
25854 void XFBCaptureInactiveOutputVariableTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
25855 bufferDescriptor::Vector& out_descriptors)
25857 const Utils::Type& type = Utils::Type::vec4;
25859 /* Test needs single uniform and xfb */
25860 out_descriptors.resize(2);
25862 /* Get references */
25863 bufferDescriptor& uniform = out_descriptors[0];
25864 bufferDescriptor& xfb = out_descriptors[1];
25867 uniform.m_index = 0;
25871 uniform.m_target = Utils::Buffer::Uniform;
25872 xfb.m_target = Utils::Buffer::Transform_feedback;
25875 const std::vector<GLubyte>& gohan_data = type.GenerateData();
25876 const std::vector<GLubyte>& goten_data = type.GenerateData();
25878 const GLuint type_size = static_cast<GLuint>(gohan_data.size());
25881 uniform.m_initial_data.resize(2 * type_size);
25882 memcpy(&uniform.m_initial_data[0] + 0, &gohan_data[0], type_size);
25883 memcpy(&uniform.m_initial_data[0] + type_size, &goten_data[0], type_size);
25886 xfb.m_initial_data.resize(3 * type_size);
25887 xfb.m_expected_data.resize(3 * type_size);
25889 for (GLuint i = 0; i < 3 * type_size; ++i)
25891 xfb.m_initial_data[i] = (glw::GLubyte)i;
25892 xfb.m_expected_data[i] = (glw::GLubyte)i;
25895 memcpy(&xfb.m_expected_data[0] + 2 * type_size, &gohan_data[0], type_size);
25896 memcpy(&xfb.m_expected_data[0] + 0 * type_size, &goten_data[0], type_size);
25899 /** Get body of main function for given shader stage
25901 * @param test_case_index Index of test case
25902 * @param stage Shader stage
25903 * @param out_assignments Set to empty
25904 * @param out_calculations Set to empty
25906 void XFBCaptureInactiveOutputVariableTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
25907 std::string& out_assignments, std::string& out_calculations)
25909 out_calculations = "";
25911 static const GLchar* vs_tes_gs = " goten = uni_goten;\n"
25912 " gohan = uni_gohan;\n";
25913 static const GLchar* fs = " fs_out = goku + gohan + goten;\n";
25915 const GLchar* assignments = "";
25919 case Utils::Shader::FRAGMENT:
25923 case Utils::Shader::GEOMETRY:
25924 if (TEST_GS == test_case_index)
25926 assignments = vs_tes_gs;
25930 case Utils::Shader::TESS_CTRL:
25933 case Utils::Shader::TESS_EVAL:
25934 if (TEST_TES == test_case_index)
25936 assignments = vs_tes_gs;
25940 case Utils::Shader::VERTEX:
25941 if (TEST_VS == test_case_index)
25943 assignments = vs_tes_gs;
25948 TCU_FAIL("Invalid enum");
25951 out_assignments = assignments;
25954 /** Get interface of shader
25956 * @param test_case_index Index of test case
25957 * @param stage Shader stage
25958 * @param out_interface Set to ""
25960 void XFBCaptureInactiveOutputVariableTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
25961 std::string& out_interface)
25963 static const GLchar* vs_tes_gs = "const uint sizeof_type = 16;\n"
25965 "layout (xfb_offset = 1 * sizeof_type) out vec4 goku;\n"
25966 "layout (xfb_offset = 2 * sizeof_type) out vec4 gohan;\n"
25967 "layout (xfb_offset = 0 * sizeof_type) out vec4 goten;\n"
25969 "layout(binding = 0) uniform block {\n"
25970 " vec4 uni_gohan;\n"
25971 " vec4 uni_goten;\n"
25973 static const GLchar* fs = "in vec4 goku;\n"
25976 "out vec4 fs_out;\n";
25978 const GLchar* interface = "";
25982 case Utils::Shader::FRAGMENT:
25986 case Utils::Shader::GEOMETRY:
25987 if (TEST_GS == test_case_index)
25989 interface = vs_tes_gs;
25993 case Utils::Shader::TESS_CTRL:
25996 case Utils::Shader::TESS_EVAL:
25997 if (TEST_TES == test_case_index)
25999 interface = vs_tes_gs;
26003 case Utils::Shader::VERTEX:
26004 if (TEST_VS == test_case_index)
26006 interface = vs_tes_gs;
26011 TCU_FAIL("Invalid enum");
26014 out_interface = interface;
26017 /** Get source code of shader
26019 * @param test_case_index Index of test case
26020 * @param stage Shader stage
26024 std::string XFBCaptureInactiveOutputVariableTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
26026 std::string source;
26028 switch (test_case_index)
26033 case Utils::Shader::FRAGMENT:
26034 case Utils::Shader::VERTEX:
26035 source = BufferTestBase::getShaderSource(test_case_index, stage);
26045 case Utils::Shader::FRAGMENT:
26046 case Utils::Shader::TESS_CTRL:
26047 case Utils::Shader::TESS_EVAL:
26048 case Utils::Shader::VERTEX:
26049 source = BufferTestBase::getShaderSource(test_case_index, stage);
26057 source = BufferTestBase::getShaderSource(test_case_index, stage);
26061 TCU_FAIL("Invalid enum");
26069 /** Get name of test case
26071 * @param test_case_index Index of test case
26073 * @return Name of tested stage
26075 std::string XFBCaptureInactiveOutputVariableTest::getTestCaseName(glw::GLuint test_case_index)
26077 const GLchar* name = 0;
26079 switch (test_case_index)
26085 name = "tessellation evaluation";
26091 TCU_FAIL("Invalid enum");
26097 /** Returns number of test cases
26101 glw::GLuint XFBCaptureInactiveOutputVariableTest::getTestCaseNumber()
26106 /** Inspects program to check if all resources are as expected
26109 * @param program Program instance
26110 * @param out_stream Error message
26112 * @return true if everything is ok, false otherwise
26114 bool XFBCaptureInactiveOutputVariableTest::inspectProgram(GLuint /* test_case_index */, Utils::Program& program,
26115 std::stringstream& out_stream)
26118 const Utils::Type& type = Utils::Type::vec4;
26119 const GLuint type_size = type.GetSize();
26121 program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE,
26122 1 /* buf_size */, &stride);
26124 if ((GLint)(3 * type_size) != stride)
26126 out_stream << "Stride is: " << stride << " expected: " << (3 * type_size);
26134 /** Verify contents of buffers
26136 * @param buffers Collection of buffers to be verified
26138 * @return true if everything is as expected, false otherwise
26140 bool XFBCaptureInactiveOutputVariableTest::verifyBuffers(bufferCollection& buffers)
26142 bool result = true;
26144 bufferCollection::pair& pair = buffers.m_vector[1] /* xfb */;
26145 Utils::Buffer* buffer = pair.m_buffer;
26146 bufferDescriptor* descriptor = pair.m_descriptor;
26148 /* Get pointer to contents of buffer */
26150 GLubyte* buffer_data = (GLubyte*)buffer->Map(Utils::Buffer::ReadOnly);
26152 /* Get pointer to expected data */
26153 GLubyte* expected_data = (GLubyte*)&descriptor->m_expected_data[0];
26156 static const GLuint vec4_size = 16;
26158 int res_gohan = memcmp(buffer_data + 2 * vec4_size, expected_data + 2 * vec4_size, vec4_size);
26159 int res_goten = memcmp(buffer_data + 0 * vec4_size, expected_data + 0 * vec4_size, vec4_size);
26161 if ((0 != res_gohan) || (0 != res_goten))
26163 m_context.getTestContext().getLog()
26164 << tcu::TestLog::Message << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
26165 << ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
26170 /* Release buffer mapping */
26178 * @param context Test context
26180 XFBCaptureInactiveOutputComponentTest::XFBCaptureInactiveOutputComponentTest(deqp::Context& context)
26181 : BufferTestBase(context, "xfb_capture_inactive_output_component",
26182 "Test verifies that inactive components are not modified")
26184 /* Nothing to be done here */
26187 /** Execute drawArrays for single vertex
26189 * @param test_case_index
26193 bool XFBCaptureInactiveOutputComponentTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
26195 const Functions& gl = m_context.getRenderContext().getFunctions();
26196 GLenum primitive_type = GL_PATCHES;
26198 if (TEST_VS == test_case_index)
26200 primitive_type = GL_POINTS;
26203 gl.disable(GL_RASTERIZER_DISCARD);
26204 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
26206 gl.beginTransformFeedback(GL_POINTS);
26207 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
26209 gl.drawArrays(primitive_type, 0 /* first */, 1 /* count */);
26210 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
26212 gl.endTransformFeedback();
26213 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
26218 /** Get descriptors of buffers necessary for test
26221 * @param out_descriptors Descriptors of buffers used by test
26223 void XFBCaptureInactiveOutputComponentTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
26224 bufferDescriptor::Vector& out_descriptors)
26226 const Utils::Type& type = Utils::Type::vec4;
26228 /* Test needs single uniform and xfb */
26229 out_descriptors.resize(2);
26231 /* Get references */
26232 bufferDescriptor& uniform = out_descriptors[0];
26233 bufferDescriptor& xfb = out_descriptors[1];
26236 uniform.m_index = 0;
26240 uniform.m_target = Utils::Buffer::Uniform;
26241 xfb.m_target = Utils::Buffer::Transform_feedback;
26244 const std::vector<GLubyte>& goku_data = type.GenerateData();
26245 const std::vector<GLubyte>& gohan_data = type.GenerateData();
26246 const std::vector<GLubyte>& goten_data = type.GenerateData();
26247 const std::vector<GLubyte>& chichi_data = type.GenerateData();
26248 const std::vector<GLubyte>& vegeta_data = type.GenerateData();
26249 const std::vector<GLubyte>& trunks_data = type.GenerateData();
26250 const std::vector<GLubyte>& bra_data = type.GenerateData();
26251 const std::vector<GLubyte>& bulma_data = type.GenerateData();
26253 const GLuint comp_size = Utils::Type::GetTypeSize(type.m_basic_type);
26254 const GLuint type_size = static_cast<GLuint>(gohan_data.size());
26257 uniform.m_initial_data.resize(8 * type_size);
26258 memcpy(&uniform.m_initial_data[0] + 0 * type_size, &goku_data[0], type_size);
26259 memcpy(&uniform.m_initial_data[0] + 1 * type_size, &gohan_data[0], type_size);
26260 memcpy(&uniform.m_initial_data[0] + 2 * type_size, &goten_data[0], type_size);
26261 memcpy(&uniform.m_initial_data[0] + 3 * type_size, &chichi_data[0], type_size);
26262 memcpy(&uniform.m_initial_data[0] + 4 * type_size, &vegeta_data[0], type_size);
26263 memcpy(&uniform.m_initial_data[0] + 5 * type_size, &trunks_data[0], type_size);
26264 memcpy(&uniform.m_initial_data[0] + 6 * type_size, &bra_data[0], type_size);
26265 memcpy(&uniform.m_initial_data[0] + 7 * type_size, &bulma_data[0], type_size);
26268 xfb.m_initial_data.resize(8 * type_size);
26269 xfb.m_expected_data.resize(8 * type_size);
26271 for (GLuint i = 0; i < 8 * type_size; ++i)
26273 xfb.m_initial_data[i] = (glw::GLubyte)i;
26274 xfb.m_expected_data[i] = (glw::GLubyte)i;
26277 /* goku - x, z - 32 */
26278 memcpy(&xfb.m_expected_data[0] + 2 * type_size + 0 * comp_size, &goku_data[0] + 0 * comp_size, comp_size);
26279 memcpy(&xfb.m_expected_data[0] + 2 * type_size + 2 * comp_size, &goku_data[0] + 2 * comp_size, comp_size);
26281 /* gohan - y, w - 0 */
26282 memcpy(&xfb.m_expected_data[0] + 0 * type_size + 1 * comp_size, &gohan_data[0] + 1 * comp_size, comp_size);
26283 memcpy(&xfb.m_expected_data[0] + 0 * type_size + 3 * comp_size, &gohan_data[0] + 3 * comp_size, comp_size);
26285 /* goten - x, y - 16 */
26286 memcpy(&xfb.m_expected_data[0] + 1 * type_size + 0 * comp_size, &goten_data[0] + 0 * comp_size, comp_size);
26287 memcpy(&xfb.m_expected_data[0] + 1 * type_size + 1 * comp_size, &goten_data[0] + 1 * comp_size, comp_size);
26289 /* chichi - z, w - 48 */
26290 memcpy(&xfb.m_expected_data[0] + 3 * type_size + 2 * comp_size, &chichi_data[0] + 2 * comp_size, comp_size);
26291 memcpy(&xfb.m_expected_data[0] + 3 * type_size + 3 * comp_size, &chichi_data[0] + 3 * comp_size, comp_size);
26293 /* vegeta - x - 112 */
26294 memcpy(&xfb.m_expected_data[0] + 7 * type_size + 0 * comp_size, &vegeta_data[0] + 0 * comp_size, comp_size);
26296 /* trunks - y - 96 */
26297 memcpy(&xfb.m_expected_data[0] + 6 * type_size + 1 * comp_size, &trunks_data[0] + 1 * comp_size, comp_size);
26300 memcpy(&xfb.m_expected_data[0] + 5 * type_size + 2 * comp_size, &bra_data[0] + 2 * comp_size, comp_size);
26302 /* bulma - w - 64 */
26303 memcpy(&xfb.m_expected_data[0] + 4 * type_size + 3 * comp_size, &bulma_data[0] + 3 * comp_size, comp_size);
26306 /** Get body of main function for given shader stage
26308 * @param test_case_index Index of test case
26309 * @param stage Shader stage
26310 * @param out_assignments Set to empty
26311 * @param out_calculations Set to empty
26313 void XFBCaptureInactiveOutputComponentTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
26314 std::string& out_assignments, std::string& out_calculations)
26316 out_calculations = "";
26318 static const GLchar* vs_tes_gs = " goku.x = uni_goku.x ;\n"
26319 " goku.z = uni_goku.z ;\n"
26320 " gohan.y = uni_gohan.y ;\n"
26321 " gohan.w = uni_gohan.w ;\n"
26322 " goten.x = uni_goten.x ;\n"
26323 " goten.y = uni_goten.y ;\n"
26324 " chichi.z = uni_chichi.z ;\n"
26325 " chichi.w = uni_chichi.w ;\n"
26326 " vegeta.x = uni_vegeta.x ;\n"
26327 " trunks.y = uni_trunks.y ;\n"
26328 " bra.z = uni_bra.z ;\n"
26329 " bulma.w = uni_bulma.w ;\n";
26330 static const GLchar* fs = " fs_out = goku + gohan + goten + chichi + vegeta + trunks + bra + bulma;\n";
26332 const GLchar* assignments = "";
26336 case Utils::Shader::FRAGMENT:
26340 case Utils::Shader::GEOMETRY:
26341 if (TEST_GS == test_case_index)
26343 assignments = vs_tes_gs;
26347 case Utils::Shader::TESS_CTRL:
26350 case Utils::Shader::TESS_EVAL:
26351 if (TEST_TES == test_case_index)
26353 assignments = vs_tes_gs;
26357 case Utils::Shader::VERTEX:
26358 if (TEST_VS == test_case_index)
26360 assignments = vs_tes_gs;
26365 TCU_FAIL("Invalid enum");
26368 out_assignments = assignments;
26371 /** Get interface of shader
26373 * @param test_case_index Index of test case
26374 * @param stage Shader stage
26375 * @param out_interface Set to ""
26377 void XFBCaptureInactiveOutputComponentTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
26378 std::string& out_interface)
26380 static const GLchar* vs_tes_gs = "const uint sizeof_type = 16;\n"
26382 "layout (xfb_offset = 2 * sizeof_type) out vec4 goku;\n"
26383 "layout (xfb_offset = 0 * sizeof_type) out vec4 gohan;\n"
26384 "layout (xfb_offset = 1 * sizeof_type) out vec4 goten;\n"
26385 "layout (xfb_offset = 3 * sizeof_type) out vec4 chichi;\n"
26386 "layout (xfb_offset = 7 * sizeof_type) out vec4 vegeta;\n"
26387 "layout (xfb_offset = 6 * sizeof_type) out vec4 trunks;\n"
26388 "layout (xfb_offset = 5 * sizeof_type) out vec4 bra;\n"
26389 "layout (xfb_offset = 4 * sizeof_type) out vec4 bulma;\n"
26391 "layout(binding = 0) uniform block {\n"
26392 " vec4 uni_goku;\n"
26393 " vec4 uni_gohan;\n"
26394 " vec4 uni_goten;\n"
26395 " vec4 uni_chichi;\n"
26396 " vec4 uni_vegeta;\n"
26397 " vec4 uni_trunks;\n"
26399 " vec4 uni_bulma;\n"
26401 static const GLchar* fs = "in vec4 vegeta;\n"
26402 "in vec4 trunks;\n"
26408 "in vec4 chichi;\n"
26410 "out vec4 fs_out;\n";
26412 const GLchar* interface = "";
26416 case Utils::Shader::FRAGMENT:
26420 case Utils::Shader::GEOMETRY:
26421 if (TEST_GS == test_case_index)
26423 interface = vs_tes_gs;
26427 case Utils::Shader::TESS_CTRL:
26430 case Utils::Shader::TESS_EVAL:
26431 if (TEST_TES == test_case_index)
26433 interface = vs_tes_gs;
26437 case Utils::Shader::VERTEX:
26438 if (TEST_VS == test_case_index)
26440 interface = vs_tes_gs;
26445 TCU_FAIL("Invalid enum");
26448 out_interface = interface;
26451 /** Get source code of shader
26453 * @param test_case_index Index of test case
26454 * @param stage Shader stage
26458 std::string XFBCaptureInactiveOutputComponentTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
26460 std::string source;
26462 switch (test_case_index)
26467 case Utils::Shader::FRAGMENT:
26468 case Utils::Shader::VERTEX:
26469 source = BufferTestBase::getShaderSource(test_case_index, stage);
26479 case Utils::Shader::FRAGMENT:
26480 case Utils::Shader::TESS_CTRL:
26481 case Utils::Shader::TESS_EVAL:
26482 case Utils::Shader::VERTEX:
26483 source = BufferTestBase::getShaderSource(test_case_index, stage);
26491 source = BufferTestBase::getShaderSource(test_case_index, stage);
26495 TCU_FAIL("Invalid enum");
26503 /** Get name of test case
26505 * @param test_case_index Index of test case
26507 * @return Name of tested stage
26509 std::string XFBCaptureInactiveOutputComponentTest::getTestCaseName(glw::GLuint test_case_index)
26511 const GLchar* name = 0;
26513 switch (test_case_index)
26519 name = "tessellation evaluation";
26525 TCU_FAIL("Invalid enum");
26531 /** Returns number of test cases
26535 glw::GLuint XFBCaptureInactiveOutputComponentTest::getTestCaseNumber()
26540 /** Verify contents of buffers
26542 * @param buffers Collection of buffers to be verified
26544 * @return true if everything is as expected, false otherwise
26546 bool XFBCaptureInactiveOutputComponentTest::verifyBuffers(bufferCollection& buffers)
26548 bool result = true;
26550 bufferCollection::pair& pair = buffers.m_vector[1] /* xfb */;
26551 Utils::Buffer* buffer = pair.m_buffer;
26552 bufferDescriptor* descriptor = pair.m_descriptor;
26554 /* Get pointer to contents of buffer */
26556 GLubyte* buffer_data = (GLubyte*)buffer->Map(Utils::Buffer::ReadOnly);
26558 /* Get pointer to expected data */
26559 GLubyte* expected_data = (GLubyte*)&descriptor->m_expected_data[0];
26562 static const GLuint comp_size = 4;
26563 static const GLuint vec4_size = 16;
26566 memcmp(buffer_data + 2 * vec4_size + 0 * comp_size, expected_data + 2 * vec4_size + 0 * comp_size, comp_size);
26568 memcmp(buffer_data + 2 * vec4_size + 2 * comp_size, expected_data + 2 * vec4_size + 2 * comp_size, comp_size);
26571 memcmp(buffer_data + 0 * vec4_size + 1 * comp_size, expected_data + 0 * vec4_size + 1 * comp_size, comp_size);
26573 memcmp(buffer_data + 0 * vec4_size + 3 * comp_size, expected_data + 0 * vec4_size + 3 * comp_size, comp_size);
26576 memcmp(buffer_data + 1 * vec4_size + 0 * comp_size, expected_data + 1 * vec4_size + 0 * comp_size, comp_size);
26578 memcmp(buffer_data + 1 * vec4_size + 1 * comp_size, expected_data + 1 * vec4_size + 1 * comp_size, comp_size);
26581 memcmp(buffer_data + 3 * vec4_size + 2 * comp_size, expected_data + 3 * vec4_size + 2 * comp_size, comp_size);
26583 memcmp(buffer_data + 3 * vec4_size + 3 * comp_size, expected_data + 3 * vec4_size + 3 * comp_size, comp_size);
26586 memcmp(buffer_data + 7 * vec4_size + 0 * comp_size, expected_data + 7 * vec4_size + 0 * comp_size, comp_size);
26589 memcmp(buffer_data + 6 * vec4_size + 1 * comp_size, expected_data + 6 * vec4_size + 1 * comp_size, comp_size);
26592 memcmp(buffer_data + 5 * vec4_size + 2 * comp_size, expected_data + 5 * vec4_size + 2 * comp_size, comp_size);
26595 memcmp(buffer_data + 4 * vec4_size + 3 * comp_size, expected_data + 4 * vec4_size + 3 * comp_size, comp_size);
26597 if ((0 != res_goku_x) || (0 != res_goku_z) || (0 != res_gohan_y) || (0 != res_gohan_w) || (0 != res_goten_x) ||
26598 (0 != res_goten_y) || (0 != res_chichi_z) || (0 != res_chichi_w) || (0 != res_vegeta_x) ||
26599 (0 != res_trunks_y) || (0 != res_bra_z) || (0 != res_bulma_w))
26601 m_context.getTestContext().getLog()
26602 << tcu::TestLog::Message << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
26603 << ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
26608 /* Release buffer mapping */
26616 * @param context Test context
26618 XFBCaptureInactiveOutputBlockMemberTest::XFBCaptureInactiveOutputBlockMemberTest(deqp::Context& context)
26619 : BufferTestBase(context, "xfb_capture_inactive_output_block_member",
26620 "Test verifies that inactive block members are captured")
26622 /* Nothing to be done here */
26625 /** Execute drawArrays for single vertex
26627 * @param test_case_index
26631 bool XFBCaptureInactiveOutputBlockMemberTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
26633 const Functions& gl = m_context.getRenderContext().getFunctions();
26634 GLenum primitive_type = GL_PATCHES;
26636 if (TEST_VS == test_case_index)
26638 primitive_type = GL_POINTS;
26641 gl.disable(GL_RASTERIZER_DISCARD);
26642 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
26644 gl.beginTransformFeedback(GL_POINTS);
26645 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
26647 gl.drawArrays(primitive_type, 0 /* first */, 1 /* count */);
26648 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
26650 gl.endTransformFeedback();
26651 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
26656 /** Get descriptors of buffers necessary for test
26659 * @param out_descriptors Descriptors of buffers used by test
26661 void XFBCaptureInactiveOutputBlockMemberTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
26662 bufferDescriptor::Vector& out_descriptors)
26664 const Utils::Type& type = Utils::Type::vec4;
26666 /* Test needs single uniform and xfb */
26667 out_descriptors.resize(2);
26669 /* Get references */
26670 bufferDescriptor& uniform = out_descriptors[0];
26671 bufferDescriptor& xfb = out_descriptors[1];
26674 uniform.m_index = 0;
26678 uniform.m_target = Utils::Buffer::Uniform;
26679 xfb.m_target = Utils::Buffer::Transform_feedback;
26682 const std::vector<GLubyte>& gohan_data = type.GenerateData();
26683 const std::vector<GLubyte>& chichi_data = type.GenerateData();
26685 const GLuint type_size = static_cast<GLuint>(gohan_data.size());
26688 uniform.m_initial_data.resize(2 * type_size);
26689 memcpy(&uniform.m_initial_data[0] + 0, &gohan_data[0], type_size);
26690 memcpy(&uniform.m_initial_data[0] + type_size, &chichi_data[0], type_size);
26693 xfb.m_initial_data.resize(4 * type_size);
26694 xfb.m_expected_data.resize(4 * type_size);
26696 for (GLuint i = 0; i < 4 * type_size; ++i)
26698 xfb.m_initial_data[i] = (glw::GLubyte)i;
26699 xfb.m_expected_data[i] = (glw::GLubyte)i;
26702 memcpy(&xfb.m_expected_data[0] + 1 * type_size, &gohan_data[0], type_size);
26703 memcpy(&xfb.m_expected_data[0] + 3 * type_size, &chichi_data[0], type_size);
26706 /** Get body of main function for given shader stage
26708 * @param test_case_index Index of test case
26709 * @param stage Shader stage
26710 * @param out_assignments Set to empty
26711 * @param out_calculations Set to empty
26713 void XFBCaptureInactiveOutputBlockMemberTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
26714 std::string& out_assignments, std::string& out_calculations)
26716 out_calculations = "";
26718 static const GLchar* vs_tes_gs = " chichi = uni_chichi;\n"
26719 " gohan = uni_gohan;\n";
26720 static const GLchar* fs = " fs_out = goten + gohan + chichi;\n";
26722 const GLchar* assignments = "";
26726 case Utils::Shader::FRAGMENT:
26730 case Utils::Shader::GEOMETRY:
26731 if (TEST_GS == test_case_index)
26733 assignments = vs_tes_gs;
26737 case Utils::Shader::TESS_CTRL:
26740 case Utils::Shader::TESS_EVAL:
26741 if (TEST_TES == test_case_index)
26743 assignments = vs_tes_gs;
26747 case Utils::Shader::VERTEX:
26748 if (TEST_VS == test_case_index)
26750 assignments = vs_tes_gs;
26755 TCU_FAIL("Invalid enum");
26758 out_assignments = assignments;
26761 /** Get interface of shader
26763 * @param test_case_index Index of test case
26764 * @param stage Shader stage
26765 * @param out_interface Set to ""
26767 void XFBCaptureInactiveOutputBlockMemberTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
26768 std::string& out_interface)
26770 static const GLchar* vs_tes_gs = "const uint sizeof_type = 16;\n"
26772 "layout (xfb_offset = 1 * sizeof_type) out Goku {\n"
26778 "layout(binding = 0) uniform block {\n"
26779 " vec4 uni_gohan;\n"
26780 " vec4 uni_chichi;\n"
26782 static const GLchar* fs = "in Goku {\n"
26787 "out vec4 fs_out;\n";
26789 const GLchar* interface = "";
26793 case Utils::Shader::FRAGMENT:
26797 case Utils::Shader::GEOMETRY:
26798 if (TEST_GS == test_case_index)
26800 interface = vs_tes_gs;
26804 case Utils::Shader::TESS_CTRL:
26807 case Utils::Shader::TESS_EVAL:
26808 if (TEST_TES == test_case_index)
26810 interface = vs_tes_gs;
26814 case Utils::Shader::VERTEX:
26815 if (TEST_VS == test_case_index)
26817 interface = vs_tes_gs;
26822 TCU_FAIL("Invalid enum");
26825 out_interface = interface;
26828 /** Get source code of shader
26830 * @param test_case_index Index of test case
26831 * @param stage Shader stage
26835 std::string XFBCaptureInactiveOutputBlockMemberTest::getShaderSource(GLuint test_case_index,
26836 Utils::Shader::STAGES stage)
26838 std::string source;
26840 switch (test_case_index)
26845 case Utils::Shader::FRAGMENT:
26846 case Utils::Shader::VERTEX:
26847 source = BufferTestBase::getShaderSource(test_case_index, stage);
26857 case Utils::Shader::FRAGMENT:
26858 case Utils::Shader::TESS_CTRL:
26859 case Utils::Shader::TESS_EVAL:
26860 case Utils::Shader::VERTEX:
26861 source = BufferTestBase::getShaderSource(test_case_index, stage);
26869 source = BufferTestBase::getShaderSource(test_case_index, stage);
26873 TCU_FAIL("Invalid enum");
26881 /** Get name of test case
26883 * @param test_case_index Index of test case
26885 * @return Name of tested stage
26887 std::string XFBCaptureInactiveOutputBlockMemberTest::getTestCaseName(glw::GLuint test_case_index)
26889 const GLchar* name = 0;
26891 switch (test_case_index)
26897 name = "tessellation evaluation";
26903 TCU_FAIL("Invalid enum");
26909 /** Returns number of test cases
26913 glw::GLuint XFBCaptureInactiveOutputBlockMemberTest::getTestCaseNumber()
26918 /** Verify contents of buffers
26920 * @param buffers Collection of buffers to be verified
26922 * @return true if everything is as expected, false otherwise
26924 bool XFBCaptureInactiveOutputBlockMemberTest::verifyBuffers(bufferCollection& buffers)
26926 bool result = true;
26928 bufferCollection::pair& pair = buffers.m_vector[1] /* xfb */;
26929 Utils::Buffer* buffer = pair.m_buffer;
26930 bufferDescriptor* descriptor = pair.m_descriptor;
26932 /* Get pointer to contents of buffer */
26934 GLubyte* buffer_data = (GLubyte*)buffer->Map(Utils::Buffer::ReadOnly);
26936 /* Get pointer to expected data */
26937 GLubyte* expected_data = (GLubyte*)&descriptor->m_expected_data[0];
26940 static const GLuint vec4_size = 16;
26942 int res_before = memcmp(buffer_data, expected_data, vec4_size);
26943 int res_gohan = memcmp(buffer_data + 1 * vec4_size, expected_data + 1 * vec4_size, vec4_size);
26944 int res_chichi = memcmp(buffer_data + 3 * vec4_size, expected_data + 3 * vec4_size, vec4_size);
26946 if ((0 != res_before) || (0 != res_gohan) || (0 != res_chichi))
26948 m_context.getTestContext().getLog()
26949 << tcu::TestLog::Message << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
26950 << ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
26955 /* Release buffer mapping */
26963 * @param context Test context
26965 XFBCaptureStructTest::XFBCaptureStructTest(deqp::Context& context)
26966 : BufferTestBase(context, "xfb_capture_struct", "Test verifies that inactive structure members are captured")
26968 /* Nothing to be done here */
26971 /** Execute drawArrays for single vertex
26973 * @param test_case_index
26977 bool XFBCaptureStructTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
26979 const Functions& gl = m_context.getRenderContext().getFunctions();
26980 GLenum primitive_type = GL_PATCHES;
26982 if (TEST_VS == test_case_index)
26984 primitive_type = GL_POINTS;
26987 gl.disable(GL_RASTERIZER_DISCARD);
26988 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
26990 gl.beginTransformFeedback(GL_POINTS);
26991 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
26993 gl.drawArrays(primitive_type, 0 /* first */, 1 /* count */);
26994 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
26996 gl.endTransformFeedback();
26997 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
27002 /** Get descriptors of buffers necessary for test
27005 * @param out_descriptors Descriptors of buffers used by test
27007 void XFBCaptureStructTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
27008 bufferDescriptor::Vector& out_descriptors)
27010 const Utils::Type& type = Utils::Type::vec4;
27012 /* Test needs single uniform and xfb */
27013 out_descriptors.resize(2);
27015 /* Get references */
27016 bufferDescriptor& uniform = out_descriptors[0];
27017 bufferDescriptor& xfb = out_descriptors[1];
27020 uniform.m_index = 0;
27024 uniform.m_target = Utils::Buffer::Uniform;
27025 xfb.m_target = Utils::Buffer::Transform_feedback;
27028 const std::vector<GLubyte>& gohan_data = type.GenerateData();
27029 const std::vector<GLubyte>& chichi_data = type.GenerateData();
27031 const GLuint type_size = static_cast<GLuint>(gohan_data.size());
27034 uniform.m_initial_data.resize(2 * type_size);
27035 memcpy(&uniform.m_initial_data[0] + 0, &gohan_data[0], type_size);
27036 memcpy(&uniform.m_initial_data[0] + type_size, &chichi_data[0], type_size);
27039 xfb.m_initial_data.resize(4 * type_size);
27040 xfb.m_expected_data.resize(4 * type_size);
27042 for (GLuint i = 0; i < 4 * type_size; ++i)
27044 xfb.m_initial_data[i] = (glw::GLubyte)i;
27045 xfb.m_expected_data[i] = (glw::GLubyte)i;
27048 memcpy(&xfb.m_expected_data[0] + 1 * type_size, &gohan_data[0], type_size);
27049 memcpy(&xfb.m_expected_data[0] + 3 * type_size, &chichi_data[0], type_size);
27052 /** Get body of main function for given shader stage
27054 * @param test_case_index Index of test case
27055 * @param stage Shader stage
27056 * @param out_assignments Set to empty
27057 * @param out_calculations Set to empty
27059 void XFBCaptureStructTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
27060 std::string& out_assignments, std::string& out_calculations)
27062 out_calculations = "";
27064 static const GLchar* vs_tes_gs = " goku.chichi = uni_chichi;\n"
27065 " goku.gohan = uni_gohan;\n";
27066 static const GLchar* fs = " fs_out = goku.goten + goku.gohan + goku.chichi;\n";
27068 const GLchar* assignments = "";
27072 case Utils::Shader::FRAGMENT:
27076 case Utils::Shader::GEOMETRY:
27077 if (TEST_GS == test_case_index)
27079 assignments = vs_tes_gs;
27083 case Utils::Shader::TESS_CTRL:
27086 case Utils::Shader::TESS_EVAL:
27087 if (TEST_TES == test_case_index)
27089 assignments = vs_tes_gs;
27093 case Utils::Shader::VERTEX:
27094 if (TEST_VS == test_case_index)
27096 assignments = vs_tes_gs;
27101 TCU_FAIL("Invalid enum");
27104 out_assignments = assignments;
27107 /** Get interface of shader
27109 * @param test_case_index Index of test case
27110 * @param stage Shader stage
27111 * @param out_interface Set to ""
27113 void XFBCaptureStructTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
27114 std::string& out_interface)
27116 static const GLchar* vs_tes_gs = "const uint sizeof_type = 16;\n"
27124 "layout (xfb_offset = sizeof_type) out Goku goku;\n"
27126 "layout(binding = 0, std140) uniform block {\n"
27127 " vec4 uni_gohan;\n"
27128 " vec4 uni_chichi;\n"
27130 static const GLchar* fs = "struct Goku {\n"
27138 "out vec4 fs_out;\n";
27140 const GLchar* interface = "";
27144 case Utils::Shader::FRAGMENT:
27148 case Utils::Shader::GEOMETRY:
27149 if (TEST_GS == test_case_index)
27151 interface = vs_tes_gs;
27155 case Utils::Shader::TESS_CTRL:
27158 case Utils::Shader::TESS_EVAL:
27159 if (TEST_TES == test_case_index)
27161 interface = vs_tes_gs;
27165 case Utils::Shader::VERTEX:
27166 if (TEST_VS == test_case_index)
27168 interface = vs_tes_gs;
27173 TCU_FAIL("Invalid enum");
27176 out_interface = interface;
27179 /** Get source code of shader
27181 * @param test_case_index Index of test case
27182 * @param stage Shader stage
27186 std::string XFBCaptureStructTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
27188 std::string source;
27190 switch (test_case_index)
27195 case Utils::Shader::FRAGMENT:
27196 case Utils::Shader::VERTEX:
27197 source = BufferTestBase::getShaderSource(test_case_index, stage);
27207 case Utils::Shader::FRAGMENT:
27208 case Utils::Shader::TESS_CTRL:
27209 case Utils::Shader::TESS_EVAL:
27210 case Utils::Shader::VERTEX:
27211 source = BufferTestBase::getShaderSource(test_case_index, stage);
27219 source = BufferTestBase::getShaderSource(test_case_index, stage);
27223 TCU_FAIL("Invalid enum");
27231 /** Get name of test case
27233 * @param test_case_index Index of test case
27235 * @return Name of tested stage
27237 std::string XFBCaptureStructTest::getTestCaseName(glw::GLuint test_case_index)
27239 const GLchar* name = 0;
27241 switch (test_case_index)
27247 name = "tessellation evaluation";
27253 TCU_FAIL("Invalid enum");
27259 /** Returns number of test cases
27263 glw::GLuint XFBCaptureStructTest::getTestCaseNumber()
27268 /** Verify contents of buffers
27270 * @param buffers Collection of buffers to be verified
27272 * @return true if everything is as expected, false otherwise
27274 bool XFBCaptureStructTest::verifyBuffers(bufferCollection& buffers)
27276 bool result = true;
27278 bufferCollection::pair& pair = buffers.m_vector[1] /* xfb */;
27279 Utils::Buffer* buffer = pair.m_buffer;
27280 bufferDescriptor* descriptor = pair.m_descriptor;
27282 /* Get pointer to contents of buffer */
27284 GLubyte* buffer_data = (GLubyte*)buffer->Map(Utils::Buffer::ReadOnly);
27286 /* Get pointer to expected data */
27287 GLubyte* expected_data = (GLubyte*)&descriptor->m_expected_data[0];
27290 static const GLuint vec4_size = 16;
27292 int res_before = memcmp(buffer_data, expected_data, vec4_size);
27293 int res_gohan = memcmp(buffer_data + 1 * vec4_size, expected_data + 1 * vec4_size, vec4_size);
27294 int res_chichi = memcmp(buffer_data + 3 * vec4_size, expected_data + 3 * vec4_size, vec4_size);
27296 if ((0 != res_before) || (0 != res_gohan) || (0 != res_chichi))
27298 m_context.getTestContext().getLog()
27299 << tcu::TestLog::Message << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
27300 << ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
27305 /* Release buffer mapping */
27313 * @param context Test framework context
27315 XFBCaptureUnsizedArrayTest::XFBCaptureUnsizedArrayTest(deqp::Context& context)
27316 : NegativeTestBase(context, "xfb_capture_unsized_array",
27317 "Test verifies that compiler reports error when unsized array is qualified with xfb_offset")
27321 /** Source for given test case and stage
27323 * @param test_case_index Index of test case
27324 * @param stage Shader stage
27326 * @return Shader source
27328 std::string XFBCaptureUnsizedArrayTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
27330 static const GLchar* var_definition = "layout (xfb_offset = 0) out vec4 gokuARRAY[];\n";
27331 static const GLchar* var_use = " gokuINDEX[0] = result / 2;\n";
27332 static const GLchar* fs = "#version 430 core\n"
27333 "#extension GL_ARB_enhanced_layouts : require\n"
27336 "out vec4 fs_out;\n"
27340 " fs_out = gs_fs;\n"
27343 static const GLchar* gs_tested = "#version 430 core\n"
27344 "#extension GL_ARB_enhanced_layouts : require\n"
27346 "layout(points) in;\n"
27347 "layout(triangle_strip, max_vertices = 4) out;\n"
27351 "in vec4 tes_gs[];\n"
27352 "out vec4 gs_fs;\n"
27356 " vec4 result = tes_gs[0];\n"
27360 " gs_fs = result;\n"
27361 " gl_Position = vec4(-1, -1, 0, 1);\n"
27363 " gs_fs = result;\n"
27364 " gl_Position = vec4(-1, 1, 0, 1);\n"
27366 " gs_fs = result;\n"
27367 " gl_Position = vec4(1, -1, 0, 1);\n"
27369 " gs_fs = result;\n"
27370 " gl_Position = vec4(1, 1, 0, 1);\n"
27374 static const GLchar* tcs = "#version 430 core\n"
27375 "#extension GL_ARB_enhanced_layouts : require\n"
27377 "layout(vertices = 1) out;\n"
27379 "in vec4 vs_tcs[];\n"
27380 "out vec4 tcs_tes[];\n"
27385 " tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\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* tcs_tested = "#version 430 core\n"
27396 "#extension GL_ARB_enhanced_layouts : require\n"
27398 "layout(vertices = 1) out;\n"
27402 "in vec4 vs_tcs[];\n"
27403 "out vec4 tcs_tes[];\n"
27407 " vec4 result = vs_tcs[gl_InvocationID];\n"
27411 " tcs_tes[gl_InvocationID] = result;\n"
27413 " gl_TessLevelOuter[0] = 1.0;\n"
27414 " gl_TessLevelOuter[1] = 1.0;\n"
27415 " gl_TessLevelOuter[2] = 1.0;\n"
27416 " gl_TessLevelOuter[3] = 1.0;\n"
27417 " gl_TessLevelInner[0] = 1.0;\n"
27418 " gl_TessLevelInner[1] = 1.0;\n"
27421 static const GLchar* tes_tested = "#version 430 core\n"
27422 "#extension GL_ARB_enhanced_layouts : require\n"
27424 "layout(isolines, point_mode) in;\n"
27428 "in vec4 tcs_tes[];\n"
27429 "out vec4 tes_gs;\n"
27433 " vec4 result = tcs_tes[0];\n"
27437 " tes_gs += result;\n"
27440 static const GLchar* vs = "#version 430 core\n"
27441 "#extension GL_ARB_enhanced_layouts : require\n"
27444 "out vec4 vs_tcs;\n"
27448 " vs_tcs = in_vs;\n"
27451 static const GLchar* vs_tested = "#version 430 core\n"
27452 "#extension GL_ARB_enhanced_layouts : require\n"
27457 "out vec4 vs_tcs;\n"
27461 " vec4 result = in_vs;\n"
27465 " vs_tcs = result;\n"
27469 std::string source;
27470 testCase& test_case = m_test_cases[test_case_index];
27472 if (test_case.m_stage == stage)
27474 const GLchar* array = "";
27475 const GLchar* index = "";
27476 size_t position = 0;
27480 case Utils::Shader::GEOMETRY:
27481 source = gs_tested;
27485 case Utils::Shader::TESS_CTRL:
27486 source = tcs_tested;
27488 index = "[gl_InvocationID]";
27490 case Utils::Shader::TESS_EVAL:
27491 source = tes_tested;
27495 case Utils::Shader::VERTEX:
27496 source = vs_tested;
27499 TCU_FAIL("Invalid enum");
27502 Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
27504 Utils::replaceToken("ARRAY", position, array, source);
27505 Utils::replaceToken("VARIABLE_USE", position, var_use, source);
27507 Utils::replaceAllTokens("INDEX", index, source);
27511 switch (test_case.m_stage)
27513 case Utils::Shader::GEOMETRY:
27516 case Utils::Shader::FRAGMENT:
27519 case Utils::Shader::VERTEX:
27526 case Utils::Shader::TESS_CTRL:
27529 case Utils::Shader::FRAGMENT:
27532 case Utils::Shader::VERTEX:
27539 case Utils::Shader::TESS_EVAL:
27542 case Utils::Shader::FRAGMENT:
27545 case Utils::Shader::TESS_CTRL:
27548 case Utils::Shader::VERTEX:
27555 case Utils::Shader::VERTEX:
27558 case Utils::Shader::FRAGMENT:
27566 TCU_FAIL("Invalid enum");
27574 /** Get description of test case
27576 * @param test_case_index Index of test case
27578 * @return Test case description
27580 std::string XFBCaptureUnsizedArrayTest::getTestCaseName(GLuint test_case_index)
27582 std::stringstream stream;
27583 testCase& test_case = m_test_cases[test_case_index];
27585 stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage);
27587 return stream.str();
27590 /** Get number of test cases
27592 * @return Number of test cases
27594 GLuint XFBCaptureUnsizedArrayTest::getTestCaseNumber()
27596 return static_cast<GLuint>(m_test_cases.size());
27599 /** Selects if "compute" stage is relevant for test
27605 bool XFBCaptureUnsizedArrayTest::isComputeRelevant(GLuint /* test_case_index */)
27610 /** Prepare all test cases
27613 void XFBCaptureUnsizedArrayTest::testInit()
27615 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
27617 /* Not aplicable for */
27618 if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::FRAGMENT == stage) ||
27619 (Utils::Shader::GEOMETRY == stage) || (Utils::Shader::TESS_EVAL == stage))
27624 testCase test_case = { (Utils::Shader::STAGES)stage };
27626 m_test_cases.push_back(test_case);
27629 } /* EnhancedLayouts namespace */
27633 * @param context Rendering context.
27635 EnhancedLayoutsTests::EnhancedLayoutsTests(deqp::Context& context)
27636 : TestCaseGroup(context, "enhanced_layouts", "Verifies \"enhanced layouts\" functionality")
27638 /* Left blank on purpose */
27641 /** Initializes a texture_storage_multisample test group.
27644 void EnhancedLayoutsTests::init(void)
27646 addChild(new EnhancedLayouts::APIConstantValuesTest(m_context));
27647 addChild(new EnhancedLayouts::APIErrorsTest(m_context));
27648 addChild(new EnhancedLayouts::GLSLContantValuesTest(m_context));
27649 addChild(new EnhancedLayouts::GLSLContantImmutablityTest(m_context));
27650 addChild(new EnhancedLayouts::GLSLConstantIntegralExpressionTest(m_context));
27651 addChild(new EnhancedLayouts::UniformBlockLayoutQualifierConflictTest(m_context));
27652 addChild(new EnhancedLayouts::SSBMemberInvalidOffsetAlignmentTest(m_context));
27653 addChild(new EnhancedLayouts::SSBMemberOverlappingOffsetsTest(m_context));
27654 addChild(new EnhancedLayouts::VaryingExceedingComponentsTest(m_context));
27655 addChild(new EnhancedLayouts::VaryingComponentOfInvalidTypeTest(m_context));
27656 addChild(new EnhancedLayouts::OutputComponentAliasingTest(m_context));
27657 addChild(new EnhancedLayouts::VertexAttribLocationAPITest(m_context));
27658 addChild(new EnhancedLayouts::XFBInputTest(m_context));
27659 addChild(new EnhancedLayouts::XFBAllStagesTest(m_context));
27660 addChild(new EnhancedLayouts::XFBCaptureInactiveOutputVariableTest(m_context));
27661 addChild(new EnhancedLayouts::XFBCaptureInactiveOutputComponentTest(m_context));
27662 addChild(new EnhancedLayouts::XFBCaptureInactiveOutputBlockMemberTest(m_context));
27663 addChild(new EnhancedLayouts::XFBStrideTest(m_context));
27665 addChild(new EnhancedLayouts::UniformBlockMemberOffsetAndAlignTest(m_context));
27666 addChild(new EnhancedLayouts::UniformBlockMemberInvalidOffsetAlignmentTest(m_context));
27667 addChild(new EnhancedLayouts::UniformBlockMemberOverlappingOffsetsTest(m_context));
27668 addChild(new EnhancedLayouts::UniformBlockMemberAlignNonPowerOf2Test(m_context));
27669 addChild(new EnhancedLayouts::SSBLayoutQualifierConflictTest(m_context));
27670 addChild(new EnhancedLayouts::SSBMemberAlignNonPowerOf2Test(m_context));
27671 addChild(new EnhancedLayouts::SSBAlignmentTest(m_context));
27672 addChild(new EnhancedLayouts::VaryingStructureMemberLocationTest(m_context));
27673 addChild(new EnhancedLayouts::VaryingBlockAutomaticMemberLocationsTest(m_context));
27674 addChild(new EnhancedLayouts::VaryingComponentWithoutLocationTest(m_context));
27675 addChild(new EnhancedLayouts::InputComponentAliasingTest(m_context));
27676 addChild(new EnhancedLayouts::VaryingLocationAliasingWithMixedTypesTest(m_context));
27677 addChild(new EnhancedLayouts::VaryingLocationAliasingWithMixedInterpolationTest(m_context));
27678 addChild(new EnhancedLayouts::VaryingLocationAliasingWithMixedAuxiliaryStorageTest(m_context));
27679 addChild(new EnhancedLayouts::XFBStrideOfEmptyListTest(m_context));
27680 addChild(new EnhancedLayouts::XFBStrideOfEmptyListAndAPITest(m_context));
27681 addChild(new EnhancedLayouts::XFBTooSmallStrideTest(m_context));
27682 addChild(new EnhancedLayouts::XFBBlockMemberStrideTest(m_context));
27683 addChild(new EnhancedLayouts::XFBDuplicatedStrideTest(m_context));
27684 addChild(new EnhancedLayouts::XFBGetProgramResourceAPITest(m_context));
27685 addChild(new EnhancedLayouts::XFBMultipleVertexStreamsTest(m_context));
27686 addChild(new EnhancedLayouts::XFBExceedBufferLimitTest(m_context));
27687 addChild(new EnhancedLayouts::XFBExceedOffsetLimitTest(m_context));
27688 addChild(new EnhancedLayouts::XFBBlockMemberBufferTest(m_context));
27689 addChild(new EnhancedLayouts::XFBOutputOverlappingTest(m_context));
27690 addChild(new EnhancedLayouts::XFBInvalidOffsetAlignmentTest(m_context));
27691 addChild(new EnhancedLayouts::XFBCaptureStructTest(m_context));
27692 addChild(new EnhancedLayouts::XFBCaptureUnsizedArrayTest(m_context));
27693 addChild(new EnhancedLayouts::UniformBlockAlignmentTest(m_context));
27694 addChild(new EnhancedLayouts::SSBMemberOffsetAndAlignTest(m_context));
27695 addChild(new EnhancedLayouts::VertexAttribLocationsTest(m_context));
27696 addChild(new EnhancedLayouts::VaryingLocationsTest(m_context));
27697 addChild(new EnhancedLayouts::VaryingArrayLocationsTest(m_context));
27698 addChild(new EnhancedLayouts::VaryingStructureLocationsTest(m_context));
27699 addChild(new EnhancedLayouts::VaryingBlockLocationsTest(m_context));
27700 addChild(new EnhancedLayouts::VaryingBlockMemberLocationsTest(m_context));
27701 addChild(new EnhancedLayouts::XFBVariableStrideTest(m_context));
27702 addChild(new EnhancedLayouts::XFBBlockStrideTest(m_context));
27703 addChild(new EnhancedLayouts::XFBOverrideQualifiersWithAPITest(m_context));
27704 addChild(new EnhancedLayouts::XFBVertexStreamsTest(m_context));
27705 addChild(new EnhancedLayouts::XFBGlobalBufferTest(m_context));
27706 addChild(new EnhancedLayouts::FragmentDataLocationAPITest(m_context));
27707 addChild(new EnhancedLayouts::VaryingLocationLimitTest(m_context));
27708 addChild(new EnhancedLayouts::VaryingComponentsTest(m_context));
27709 addChild(new EnhancedLayouts::VaryingArrayComponentsTest(m_context));
27712 } /* gl4cts namespace */