xref: /aosp_15_r20/external/deqp/external/openglcts/modules/gl/gl4cEnhancedLayoutsTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 /*-------------------------------------------------------------------------
2  * OpenGL Conformance Test Suite
3  * -----------------------------
4  *
5  * Copyright (c) 2015-2016 The Khronos Group Inc.
6  *
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
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
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.
18  *
19  */ /*!
20  * \file
21  * \brief
22  */ /*-------------------------------------------------------------------*/
23 
24 /**
25  * \file  gl4cEnhancedLayoutsTests.cpp
26  * \brief Implements conformance tests for "Enhanced Layouts" functionality.
27  */ /*-------------------------------------------------------------------*/
28 
29 #include "gl4cEnhancedLayoutsTests.hpp"
30 
31 #include "gluContextInfo.hpp"
32 #include "gluDefs.hpp"
33 #include "gluShaderUtil.hpp"
34 #include "gluStrUtil.hpp"
35 #include "glwEnums.hpp"
36 #include "glwFunctions.hpp"
37 #include "tcuTestLog.hpp"
38 
39 #include <algorithm>
40 #include <iomanip>
41 #include <string>
42 #include <vector>
43 
44 /* DEBUG */
45 #define USE_NSIGHT 0
46 #define DEBUG_ENBALE_MESSAGE_CALLBACK 0
47 #define DEBUG_NEG_LOG_ERROR 0
48 #define DEBUG_NEG_REMOVE_ERROR 0
49 #define DEBUG_REPLACE_TOKEN 0
50 #define DEBUG_REPEAT_TEST_CASE 0
51 #define DEBUG_REPEATED_TEST_CASE 0
52 
53 /* Texture test base */
54 #define DEBUG_TTB_VERIFICATION_SNIPPET_STAGE 0
55 #define DEBUG_TTB_VERIFICATION_SNIPPET_VARIABLE 0
56 
57 /* Tests */
58 #define DEBUG_VERTEX_ATTRIB_LOCATIONS_TEST_VARIABLE 0
59 
60 /* WORKAROUNDS */
61 #define WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST 0
62 #define WRKARD_UNIFORMBLOCKMEMBERALIGNNONPOWEROF2TEST 0
63 #define WRKARD_UNIFORMBLOCKALIGNMENT 0
64 #define WRKARD_VARYINGLOCATIONSTEST 0
65 
66 using namespace glw;
67 
68 namespace gl4cts
69 {
70 namespace EnhancedLayouts
71 {
72 namespace Utils
73 {
74 /** Constants used by "random" generators **/
75 static const GLuint s_rand_start    = 3;
76 static const GLuint s_rand_max      = 16;
77 static const GLuint s_rand_max_half = s_rand_max / 2;
78 
79 /** Seed used by "random" generators **/
80 static GLuint s_rand = s_rand_start;
81 
82 /** Get "random" unsigned int value
83  *
84  * @return Value
85  **/
GetRandUint()86 static GLuint GetRandUint()
87 {
88     const GLuint rand = s_rand++;
89 
90     if (s_rand_max <= s_rand)
91     {
92         s_rand = s_rand_start;
93     }
94 
95     return rand;
96 }
97 
98 /** Get "random" int value
99  *
100  * @return Value
101  **/
GetRandInt()102 GLint GetRandInt()
103 {
104     const GLint rand = GetRandUint() - s_rand_max_half;
105 
106     return rand;
107 }
108 
109 /** Get "random" double value
110  *
111  * @return Value
112  **/
GetRandDouble()113 GLdouble GetRandDouble()
114 {
115     const GLint rand = GetRandInt();
116 
117     GLdouble result = (GLfloat)rand / (GLdouble)s_rand_max_half;
118 
119     return result;
120 }
121 
122 /** Get "random" float value
123  *
124  * @return Value
125  **/
GetRandFloat()126 GLfloat GetRandFloat()
127 {
128     const GLint rand = GetRandInt();
129 
130     GLfloat result = (GLfloat)rand / (GLfloat)s_rand_max_half;
131 
132     return result;
133 }
134 
135 /** String used by list routines **/
136 static const GLchar *const g_list = "LIST";
137 
138 /** Type constants **/
139 const Type Type::_double = Type::GetType(Type::Double, 1, 1);
140 const Type Type::dmat2   = Type::GetType(Type::Double, 2, 2);
141 const Type Type::dmat2x3 = Type::GetType(Type::Double, 2, 3);
142 const Type Type::dmat2x4 = Type::GetType(Type::Double, 2, 4);
143 const Type Type::dmat3x2 = Type::GetType(Type::Double, 3, 2);
144 const Type Type::dmat3   = Type::GetType(Type::Double, 3, 3);
145 const Type Type::dmat3x4 = Type::GetType(Type::Double, 3, 4);
146 const Type Type::dmat4x2 = Type::GetType(Type::Double, 4, 2);
147 const Type Type::dmat4x3 = Type::GetType(Type::Double, 4, 3);
148 const Type Type::dmat4   = Type::GetType(Type::Double, 4, 4);
149 const Type Type::dvec2   = Type::GetType(Type::Double, 1, 2);
150 const Type Type::dvec3   = Type::GetType(Type::Double, 1, 3);
151 const Type Type::dvec4   = Type::GetType(Type::Double, 1, 4);
152 const Type Type::_int    = Type::GetType(Type::Int, 1, 1);
153 const Type Type::ivec2   = Type::GetType(Type::Int, 1, 2);
154 const Type Type::ivec3   = Type::GetType(Type::Int, 1, 3);
155 const Type Type::ivec4   = Type::GetType(Type::Int, 1, 4);
156 const Type Type::_float  = Type::GetType(Type::Float, 1, 1);
157 const Type Type::mat2    = Type::GetType(Type::Float, 2, 2);
158 const Type Type::mat2x3  = Type::GetType(Type::Float, 2, 3);
159 const Type Type::mat2x4  = Type::GetType(Type::Float, 2, 4);
160 const Type Type::mat3x2  = Type::GetType(Type::Float, 3, 2);
161 const Type Type::mat3    = Type::GetType(Type::Float, 3, 3);
162 const Type Type::mat3x4  = Type::GetType(Type::Float, 3, 4);
163 const Type Type::mat4x2  = Type::GetType(Type::Float, 4, 2);
164 const Type Type::mat4x3  = Type::GetType(Type::Float, 4, 3);
165 const Type Type::mat4    = Type::GetType(Type::Float, 4, 4);
166 const Type Type::vec2    = Type::GetType(Type::Float, 1, 2);
167 const Type Type::vec3    = Type::GetType(Type::Float, 1, 3);
168 const Type Type::vec4    = Type::GetType(Type::Float, 1, 4);
169 const Type Type::uint    = Type::GetType(Type::Uint, 1, 1);
170 const Type Type::uvec2   = Type::GetType(Type::Uint, 1, 2);
171 const Type Type::uvec3   = Type::GetType(Type::Uint, 1, 3);
172 const Type Type::uvec4   = Type::GetType(Type::Uint, 1, 4);
173 
174 /** Generate data for type. This routine follows STD140 rules
175  *
176  * @return Vector of bytes filled with data
177  **/
GenerateData() const178 std::vector<GLubyte> Type::GenerateData() const
179 {
180     const GLuint alignment = GetActualAlignment(0, false);
181     const GLuint padding   = alignment - GetTypeSize(m_basic_type) * m_n_rows;
182     const GLuint data_size = alignment * m_n_columns - padding;
183 
184     std::vector<GLubyte> data;
185     data.resize(data_size);
186 
187     for (GLuint column = 0; column < m_n_columns; ++column)
188     {
189         GLvoid *ptr = (GLvoid *)&data[column * alignment];
190 
191         switch (m_basic_type)
192         {
193         case Double:
194         {
195             GLdouble *d_ptr = (GLdouble *)ptr;
196 
197             for (GLuint i = 0; i < m_n_rows; ++i)
198             {
199                 d_ptr[i] = GetRandDouble();
200             }
201         }
202         break;
203         case Float:
204         {
205             GLfloat *f_ptr = (GLfloat *)ptr;
206 
207             for (GLuint i = 0; i < m_n_rows; ++i)
208             {
209                 f_ptr[i] = GetRandFloat();
210             }
211         }
212         break;
213         case Int:
214         {
215             GLint *i_ptr = (GLint *)ptr;
216 
217             for (GLuint i = 0; i < m_n_rows; ++i)
218             {
219                 i_ptr[i] = GetRandInt();
220             }
221         }
222         break;
223         case Uint:
224         {
225             GLuint *ui_ptr = (GLuint *)ptr;
226 
227             for (GLuint i = 0; i < m_n_rows; ++i)
228             {
229                 ui_ptr[i] = GetRandUint();
230             }
231         }
232         break;
233         }
234     }
235 
236     return data;
237 }
238 
239 /** Generate data for type. This routine packs data tightly.
240  *
241  * @return Vector of bytes filled with data
242  **/
GenerateDataPacked() const243 std::vector<GLubyte> Type::GenerateDataPacked() const
244 {
245     const GLuint basic_size = GetTypeSize(m_basic_type);
246     const GLuint n_elements = m_n_columns * m_n_rows;
247     const GLuint size       = basic_size * n_elements;
248 
249     std::vector<GLubyte> data;
250     data.resize(size);
251 
252     GLvoid *ptr = (GLvoid *)&data[0];
253 
254     switch (m_basic_type)
255     {
256     case Double:
257     {
258         GLdouble *d_ptr = (GLdouble *)ptr;
259 
260         for (GLuint i = 0; i < n_elements; ++i)
261         {
262             d_ptr[i] = GetRandDouble();
263         }
264     }
265     break;
266     case Float:
267     {
268         GLfloat *f_ptr = (GLfloat *)ptr;
269 
270         for (GLuint i = 0; i < n_elements; ++i)
271         {
272             f_ptr[i] = GetRandFloat();
273         }
274     }
275     break;
276     case Int:
277     {
278         GLint *i_ptr = (GLint *)ptr;
279 
280         for (GLuint i = 0; i < n_elements; ++i)
281         {
282             i_ptr[i] = GetRandInt();
283         }
284     }
285     break;
286     case Uint:
287     {
288         GLuint *ui_ptr = (GLuint *)ptr;
289 
290         for (GLuint i = 0; i < n_elements; ++i)
291         {
292             ui_ptr[i] = GetRandUint();
293         }
294     }
295     break;
296     }
297 
298     return data;
299 }
300 
301 /** Calculate "actual alignment". It work under assumption that align value is valid
302  *
303  * @param align    Requested alignment, eg with "align" qualifier
304  * @param is_array Selects if an array of type or single instance should be considered
305  *
306  * @return Calculated value
307  **/
GetActualAlignment(GLuint align,bool is_array) const308 GLuint Type::GetActualAlignment(GLuint align, bool is_array) const
309 {
310     const GLuint base_alignment = GetBaseAlignment(is_array);
311 
312     return std::max(align, base_alignment);
313 }
314 
315 /** Align given ofset with specified alignment
316  *
317  * @param offset    Offset
318  * @param alignment Alignment
319  *
320  * @return Calculated value
321  **/
align(GLuint offset,GLuint alignment)322 GLuint align(GLuint offset, GLuint alignment)
323 {
324     const GLuint rest = offset % alignment;
325 
326     if (0 != rest)
327     {
328         GLuint missing = alignment - rest;
329         offset += missing;
330     }
331 
332     return offset;
333 }
334 
335 /** Calculate "actual offset"
336  *
337  * @param start_offset     Requested offset
338  * @param actual_alignment Actual alignemnt
339  *
340  * @return Calculated value
341  **/
GetActualOffset(GLuint start_offset,GLuint actual_alignment)342 GLuint Type::GetActualOffset(GLuint start_offset, GLuint actual_alignment)
343 {
344     GLuint offset = align(start_offset, actual_alignment);
345 
346     return offset;
347 }
348 
349 /** Calculate "base alignment" for given type
350  *
351  * @param is_array Select if array or single instance should be considered
352  *
353  * @return Calculated value
354  **/
GetBaseAlignment(bool is_array) const355 GLuint Type::GetBaseAlignment(bool is_array) const
356 {
357     GLuint elements = 1;
358 
359     switch (m_n_rows)
360     {
361     case 2:
362         elements = 2;
363         break;
364     case 3:
365     case 4:
366         elements = 4;
367         break;
368     default:
369         break;
370     }
371 
372     GLuint N         = GetTypeSize(m_basic_type);
373     GLuint alignment = N * elements;
374 
375     if ((true == is_array) || (1 != m_n_columns))
376     {
377         alignment = align(alignment, 16 /* vec4 alignment */);
378     }
379 
380     return alignment;
381 }
382 
383 /** Returns string representing GLSL constructor of type with arguments provided in data
384  *
385  * @param data Array of values that will be used as construcotr arguments.
386  *             It is interpreted as tightly packed array of type matching this type.
387  *
388  * @return String in form "Type(args)"
389  **/
GetGLSLConstructor(const GLvoid * data) const390 std::string Type::GetGLSLConstructor(const GLvoid *data) const
391 {
392     const GLchar *type = GetGLSLTypeName();
393 
394     std::stringstream stream;
395 
396     stream << type << "(";
397 
398     /* Scalar or vector */
399     if (1 == m_n_columns)
400     {
401         for (GLuint row = 0; row < m_n_rows; ++row)
402         {
403             switch (m_basic_type)
404             {
405             case Double:
406                 stream << ((GLdouble *)data)[row];
407                 break;
408             case Float:
409                 stream << ((GLfloat *)data)[row];
410                 break;
411             case Int:
412                 stream << ((GLint *)data)[row];
413                 break;
414             case Uint:
415                 stream << ((GLuint *)data)[row];
416                 break;
417             }
418 
419             if (row + 1 != m_n_rows)
420             {
421                 stream << ", ";
422             }
423         }
424     }
425     else /* Matrix: mat(vec(), vec() .. ) */
426     {
427         const GLuint basic_size = GetTypeSize(m_basic_type);
428         // 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)
429         const GLuint column_stride = m_n_rows * basic_size;
430         const Type column_type     = GetType(m_basic_type, 1, m_n_rows);
431 
432         for (GLuint column = 0; column < m_n_columns; ++column)
433         {
434             const GLuint column_offset = column * column_stride;
435             const GLvoid *column_data  = (GLubyte *)data + column_offset;
436 
437             stream << column_type.GetGLSLConstructor(column_data);
438 
439             if (column + 1 != m_n_columns)
440             {
441                 stream << ", ";
442             }
443         }
444     }
445 
446     stream << ")";
447 
448     return stream.str();
449 }
450 
451 /** Get glsl name of the type
452  *
453  * @return Name of glsl type
454  **/
GetGLSLTypeName() const455 const glw::GLchar *Type::GetGLSLTypeName() const
456 {
457     static const GLchar *float_lut[4][4] = {
458         {"float", "vec2", "vec3", "vec4"},
459         {0, "mat2", "mat2x3", "mat2x4"},
460         {0, "mat3x2", "mat3", "mat3x4"},
461         {0, "mat4x2", "mat4x3", "mat4"},
462     };
463 
464     static const GLchar *double_lut[4][4] = {
465         {"double", "dvec2", "dvec3", "dvec4"},
466         {0, "dmat2", "dmat2x3", "dmat2x4"},
467         {0, "dmat3x2", "dmat3", "dmat3x4"},
468         {0, "dmat4x2", "dmat4x3", "dmat4"},
469     };
470 
471     static const GLchar *int_lut[4] = {"int", "ivec2", "ivec3", "ivec4"};
472 
473     static const GLchar *uint_lut[4] = {"uint", "uvec2", "uvec3", "uvec4"};
474 
475     const GLchar *result = 0;
476 
477     if ((1 > m_n_columns) || (1 > m_n_rows) || (4 < m_n_columns) || (4 < m_n_rows))
478     {
479         return 0;
480     }
481 
482     switch (m_basic_type)
483     {
484     case Float:
485         result = float_lut[m_n_columns - 1][m_n_rows - 1];
486         break;
487     case Double:
488         result = double_lut[m_n_columns - 1][m_n_rows - 1];
489         break;
490     case Int:
491         result = int_lut[m_n_rows - 1];
492         break;
493     case Uint:
494         result = uint_lut[m_n_rows - 1];
495         break;
496     default:
497         TCU_FAIL("Invalid enum");
498     }
499 
500     return result;
501 }
502 
503 /** Get number of locations required for the type
504  *
505  * @return Number of columns times:
506  *          - 2 when type is double with 3 or 4 rows,
507  *          - 1 otherwise or if it's a vertex shader input.
508  **/
GetLocations(bool is_vs_input) const509 GLuint Type::GetLocations(bool is_vs_input) const
510 {
511     GLuint n_loc_per_column;
512 
513     /* 1 or 2 doubles any for rest */
514     if ((2 >= m_n_rows) || (Double != m_basic_type) || is_vs_input)
515     {
516         n_loc_per_column = 1;
517     }
518     else
519     {
520         /* 3 and 4 doubles */
521         n_loc_per_column = 2;
522     }
523 
524     return n_loc_per_column * m_n_columns;
525 }
526 
527 /** Get size of the type in bytes.
528  * Note that this routine doesn't consider arrays and assumes
529  * column_major matrices.
530  *
531  * @return Formula:
532  *          - If std140 packaging and matrix; number of columns * base alignment
533  *          - Otherwise; number of elements * sizeof(base_type)
534  **/
GetSize(const bool is_std140) const535 GLuint Type::GetSize(const bool is_std140) const
536 {
537     const GLuint basic_type_size = GetTypeSize(m_basic_type);
538     const GLuint n_elements      = m_n_columns * m_n_rows;
539 
540     if (is_std140 && m_n_columns > 1)
541     {
542         return m_n_columns * GetBaseAlignment(false);
543     }
544 
545     return basic_type_size * n_elements;
546 }
547 
548 /** Get GLenum representing the type
549  *
550  * @return GLenum
551  **/
GetTypeGLenum() const552 GLenum Type::GetTypeGLenum() const
553 {
554     static const GLenum float_lut[4][4] = {
555         {GL_FLOAT, GL_FLOAT_VEC2, GL_FLOAT_VEC3, GL_FLOAT_VEC4},
556         {0, GL_FLOAT_MAT2, GL_FLOAT_MAT2x3, GL_FLOAT_MAT2x4},
557         {0, GL_FLOAT_MAT3x2, GL_FLOAT_MAT3, GL_FLOAT_MAT3x4},
558         {0, GL_FLOAT_MAT4x2, GL_FLOAT_MAT4x3, GL_FLOAT_MAT4},
559     };
560 
561     static const GLenum double_lut[4][4] = {
562         {GL_DOUBLE, GL_DOUBLE_VEC2, GL_DOUBLE_VEC3, GL_DOUBLE_VEC4},
563         {0, GL_DOUBLE_MAT2, GL_DOUBLE_MAT2x3, GL_DOUBLE_MAT2x4},
564         {0, GL_DOUBLE_MAT3x2, GL_DOUBLE_MAT3, GL_DOUBLE_MAT3x4},
565         {0, GL_DOUBLE_MAT4x2, GL_DOUBLE_MAT4x3, GL_DOUBLE_MAT4},
566     };
567 
568     static const GLenum int_lut[4] = {GL_INT, GL_INT_VEC2, GL_INT_VEC3, GL_INT_VEC4};
569 
570     static const GLenum uint_lut[4] = {GL_UNSIGNED_INT, GL_UNSIGNED_INT_VEC2, GL_UNSIGNED_INT_VEC3,
571                                        GL_UNSIGNED_INT_VEC4};
572 
573     GLenum result = 0;
574 
575     if ((1 > m_n_columns) || (1 > m_n_rows) || (4 < m_n_columns) || (4 < m_n_rows))
576     {
577         return 0;
578     }
579 
580     switch (m_basic_type)
581     {
582     case Float:
583         result = float_lut[m_n_columns - 1][m_n_rows - 1];
584         break;
585     case Double:
586         result = double_lut[m_n_columns - 1][m_n_rows - 1];
587         break;
588     case Int:
589         result = int_lut[m_n_rows - 1];
590         break;
591     case Uint:
592         result = uint_lut[m_n_rows - 1];
593         break;
594     default:
595         TCU_FAIL("Invalid enum");
596     }
597 
598     return result;
599 }
600 
601 /** Calculate the number of components consumed by a type
602  *   according to 11.1.2.1 Output Variables
603  *
604  * @return Calculated number of components for the type
605  **/
GetNumComponents() const606 GLuint Type::GetNumComponents() const
607 {
608     // Rule 3 of Section 7.6.2.2
609     // If the member is a three-component vector with components consuming N
610     // basic machine units, the base alignment is 4N.
611     GLuint num_components = (m_n_rows == 3 ? 4 : m_n_rows) * m_n_columns;
612 
613     if (m_basic_type == Double)
614     {
615         num_components *= 2;
616     }
617 
618     return num_components;
619 }
620 
621 /** Calculate the valid values to use with the component qualifier
622  *
623  * @return Vector with the valid values, in growing order, or empty if
624  *         the component qualifier is not allowed
625  **/
GetValidComponents() const626 std::vector<GLuint> Type::GetValidComponents() const
627 {
628     const GLuint component_size            = Utils::Type::Double == m_basic_type ? 2 : 1;
629     const GLuint n_components_per_location = Utils::Type::Double == m_basic_type ? 2 : 4;
630     const GLuint n_req_components          = m_n_rows;
631     const GLint max_valid_component        = (GLint)n_components_per_location - (GLint)n_req_components;
632     std::vector<GLuint> data;
633 
634     /* The component qualifier cannot be used for matrices */
635     if (1 != m_n_columns)
636     {
637         return data;
638     }
639 
640     /* The component qualifier cannot be used for dvec3/dvec4 */
641     if (max_valid_component < 0)
642     {
643         return data;
644     }
645 
646     for (GLuint i = 0; i <= (GLuint)max_valid_component; ++i)
647     {
648         data.push_back(i * component_size);
649     }
650 
651     return data;
652 }
653 
654 /** Calculate stride for the type according to std140 rules
655  *
656  * @param alignment        Alignment of type
657  * @param n_columns        Number of columns
658  * @param n_array_elements Number of elements in array
659  *
660  * @return Calculated value
661  **/
CalculateStd140Stride(GLuint alignment,GLuint n_columns,GLuint n_array_elements)662 GLuint Type::CalculateStd140Stride(GLuint alignment, GLuint n_columns, GLuint n_array_elements)
663 {
664     GLuint stride = alignment * n_columns;
665     if (0 != n_array_elements)
666     {
667         stride *= n_array_elements;
668     }
669 
670     return stride;
671 }
672 
673 /** Check if glsl support matrices for specific basic type
674  *
675  * @param type Basic type
676  *
677  * @return true if matrices of <type> are supported, false otherwise
678  **/
DoesTypeSupportMatrix(TYPES type)679 bool Type::DoesTypeSupportMatrix(TYPES type)
680 {
681     bool result = false;
682 
683     switch (type)
684     {
685     case Float:
686     case Double:
687         result = true;
688         break;
689     case Int:
690     case Uint:
691         result = false;
692         break;
693     default:
694         TCU_FAIL("Invalid enum");
695     }
696 
697     return result;
698 }
699 
700 /** Creates instance of Type
701  *
702  * @param basic_type Select basic type of instance
703  * @param n_columns  Number of columns
704  * @param n_rows     Number of rows
705  *
706  * @return Type instance
707  **/
GetType(TYPES basic_type,glw::GLuint n_columns,glw::GLuint n_rows)708 Type Type::GetType(TYPES basic_type, glw::GLuint n_columns, glw::GLuint n_rows)
709 {
710     Type type = {basic_type, n_columns, n_rows};
711 
712     return type;
713 }
714 
715 /** Get Size of given type in bytes
716  *
717  * @param type
718  *
719  * @return Size of type
720  **/
GetTypeSize(TYPES type)721 GLuint Type::GetTypeSize(TYPES type)
722 {
723     GLuint result = 0;
724 
725     switch (type)
726     {
727     case Float:
728         result = sizeof(GLfloat);
729         break;
730     case Double:
731         result = sizeof(GLdouble);
732         break;
733     case Int:
734         result = sizeof(GLint);
735         break;
736     case Uint:
737         result = sizeof(GLuint);
738         break;
739     default:
740         TCU_FAIL("Invalid enum");
741     }
742 
743     return result;
744 }
745 
746 /** Get GLenum representing given type
747  *
748  * @param type
749  *
750  * @return GLenum value
751  **/
GetTypeGLenum(TYPES type)752 GLenum Type::GetTypeGLenum(TYPES type)
753 {
754     GLenum result = 0;
755 
756     switch (type)
757     {
758     case Float:
759         result = GL_FLOAT;
760         break;
761     case Double:
762         result = GL_DOUBLE;
763         break;
764     case Int:
765         result = GL_INT;
766         break;
767     case Uint:
768         result = GL_UNSIGNED_INT;
769         break;
770     default:
771         TCU_FAIL("Invalid enum");
772     }
773 
774     return result;
775 }
776 
777 /** Check if two types can share the same location, based on the underlying numerical type and bit width
778  *
779  * @param first   First type to compare
780  * @param second  Second type to compare
781  *
782  * @return true if the types can share the same location
783  **/
CanTypesShareLocation(TYPES first,TYPES second)784 bool Type::CanTypesShareLocation(TYPES first, TYPES second)
785 {
786     if (first == second)
787     {
788         return true;
789     }
790 
791     if (Float == first || Float == second || Double == first || Double == second)
792     {
793         return false;
794     }
795 
796     return true;
797 }
798 
799 /** Get proper glUniformNdv routine for vectors with specified number of rows
800  *
801  * @param gl     GL functions
802  * @param n_rows Number of rows
803  *
804  * @return Function address
805  **/
getUniformNdv(const glw::Functions & gl,glw::GLuint n_rows)806 uniformNdv getUniformNdv(const glw::Functions &gl, glw::GLuint n_rows)
807 {
808     uniformNdv result = 0;
809 
810     switch (n_rows)
811     {
812     case 1:
813         result = gl.uniform1dv;
814         break;
815     case 2:
816         result = gl.uniform2dv;
817         break;
818     case 3:
819         result = gl.uniform3dv;
820         break;
821     case 4:
822         result = gl.uniform4dv;
823         break;
824     default:
825         TCU_FAIL("Invalid number of rows");
826     }
827 
828     return result;
829 }
830 
831 /** Get proper glUniformNfv routine for vectors with specified number of rows
832  *
833  * @param gl     GL functions
834  * @param n_rows Number of rows
835  *
836  * @return Function address
837  **/
getUniformNfv(const glw::Functions & gl,glw::GLuint n_rows)838 uniformNfv getUniformNfv(const glw::Functions &gl, glw::GLuint n_rows)
839 {
840     uniformNfv result = 0;
841 
842     switch (n_rows)
843     {
844     case 1:
845         result = gl.uniform1fv;
846         break;
847     case 2:
848         result = gl.uniform2fv;
849         break;
850     case 3:
851         result = gl.uniform3fv;
852         break;
853     case 4:
854         result = gl.uniform4fv;
855         break;
856     default:
857         TCU_FAIL("Invalid number of rows");
858     }
859 
860     return result;
861 }
862 
863 /** Get proper glUniformNiv routine for vectors with specified number of rows
864  *
865  * @param gl     GL functions
866  * @param n_rows Number of rows
867  *
868  * @return Function address
869  **/
getUniformNiv(const glw::Functions & gl,glw::GLuint n_rows)870 uniformNiv getUniformNiv(const glw::Functions &gl, glw::GLuint n_rows)
871 {
872     uniformNiv result = 0;
873 
874     switch (n_rows)
875     {
876     case 1:
877         result = gl.uniform1iv;
878         break;
879     case 2:
880         result = gl.uniform2iv;
881         break;
882     case 3:
883         result = gl.uniform3iv;
884         break;
885     case 4:
886         result = gl.uniform4iv;
887         break;
888     default:
889         TCU_FAIL("Invalid number of rows");
890     }
891 
892     return result;
893 }
894 
895 /** Get proper glUniformNuiv routine for vectors with specified number of rows
896  *
897  * @param gl     GL functions
898  * @param n_rows Number of rows
899  *
900  * @return Function address
901  **/
getUniformNuiv(const glw::Functions & gl,glw::GLuint n_rows)902 uniformNuiv getUniformNuiv(const glw::Functions &gl, glw::GLuint n_rows)
903 {
904     uniformNuiv result = 0;
905 
906     switch (n_rows)
907     {
908     case 1:
909         result = gl.uniform1uiv;
910         break;
911     case 2:
912         result = gl.uniform2uiv;
913         break;
914     case 3:
915         result = gl.uniform3uiv;
916         break;
917     case 4:
918         result = gl.uniform4uiv;
919         break;
920     default:
921         TCU_FAIL("Invalid number of rows");
922     }
923 
924     return result;
925 }
926 
927 /** Get proper glUniformMatrixNdv routine for matrix with specified number of columns and rows
928  *
929  * @param gl     GL functions
930  * @param n_rows Number of rows
931  *
932  * @return Function address
933  **/
getUniformMatrixNdv(const glw::Functions & gl,glw::GLuint n_columns,glw::GLuint n_rows)934 uniformMatrixNdv getUniformMatrixNdv(const glw::Functions &gl, glw::GLuint n_columns, glw::GLuint n_rows)
935 {
936     uniformMatrixNdv result = 0;
937 
938     switch (n_columns)
939     {
940     case 2:
941         switch (n_rows)
942         {
943         case 2:
944             result = gl.uniformMatrix2dv;
945             break;
946         case 3:
947             result = gl.uniformMatrix2x3dv;
948             break;
949         case 4:
950             result = gl.uniformMatrix2x4dv;
951             break;
952         default:
953             TCU_FAIL("Invalid number of rows");
954         }
955         break;
956     case 3:
957         switch (n_rows)
958         {
959         case 2:
960             result = gl.uniformMatrix3x2dv;
961             break;
962         case 3:
963             result = gl.uniformMatrix3dv;
964             break;
965         case 4:
966             result = gl.uniformMatrix3x4dv;
967             break;
968         default:
969             TCU_FAIL("Invalid number of rows");
970         }
971         break;
972     case 4:
973         switch (n_rows)
974         {
975         case 2:
976             result = gl.uniformMatrix4x2dv;
977             break;
978         case 3:
979             result = gl.uniformMatrix4x3dv;
980             break;
981         case 4:
982             result = gl.uniformMatrix4dv;
983             break;
984         default:
985             TCU_FAIL("Invalid number of rows");
986         }
987         break;
988     default:
989         TCU_FAIL("Invalid number of columns");
990     }
991 
992     return result;
993 }
994 
995 /** Get proper glUniformMatrixNfv routine for vectors with specified number of columns and rows
996  *
997  * @param gl     GL functions
998  * @param n_rows Number of rows
999  *
1000  * @return Function address
1001  **/
getUniformMatrixNfv(const glw::Functions & gl,glw::GLuint n_columns,glw::GLuint n_rows)1002 uniformMatrixNfv getUniformMatrixNfv(const glw::Functions &gl, glw::GLuint n_columns, glw::GLuint n_rows)
1003 {
1004     uniformMatrixNfv result = 0;
1005 
1006     switch (n_columns)
1007     {
1008     case 2:
1009         switch (n_rows)
1010         {
1011         case 2:
1012             result = gl.uniformMatrix2fv;
1013             break;
1014         case 3:
1015             result = gl.uniformMatrix2x3fv;
1016             break;
1017         case 4:
1018             result = gl.uniformMatrix2x4fv;
1019             break;
1020         default:
1021             TCU_FAIL("Invalid number of rows");
1022         }
1023         break;
1024     case 3:
1025         switch (n_rows)
1026         {
1027         case 2:
1028             result = gl.uniformMatrix3x2fv;
1029             break;
1030         case 3:
1031             result = gl.uniformMatrix3fv;
1032             break;
1033         case 4:
1034             result = gl.uniformMatrix3x4fv;
1035             break;
1036         default:
1037             TCU_FAIL("Invalid number of rows");
1038         }
1039         break;
1040     case 4:
1041         switch (n_rows)
1042         {
1043         case 2:
1044             result = gl.uniformMatrix4x2fv;
1045             break;
1046         case 3:
1047             result = gl.uniformMatrix4x3fv;
1048             break;
1049         case 4:
1050             result = gl.uniformMatrix4fv;
1051             break;
1052         default:
1053             TCU_FAIL("Invalid number of rows");
1054         }
1055         break;
1056     default:
1057         TCU_FAIL("Invalid number of columns");
1058     }
1059 
1060     return result;
1061 }
1062 
verifyVarying(Program & program,const std::string & parent_name,const Variable::Descriptor & desc,std::stringstream & stream,bool is_input)1063 bool verifyVarying(Program &program, const std::string &parent_name, const Variable::Descriptor &desc,
1064                    std::stringstream &stream, bool is_input)
1065 {
1066     GLint component  = 0;
1067     GLuint index     = 0;
1068     GLenum interface = GL_PROGRAM_INPUT;
1069     GLint location   = 0;
1070 
1071     if (false == is_input)
1072     {
1073         interface = GL_PROGRAM_OUTPUT;
1074     }
1075 
1076     const std::string &name = Utils::Variable::GetReference(parent_name, desc, Utils::Variable::BASIC, 0);
1077 
1078     try
1079     {
1080         index = program.GetResourceIndex(name, interface);
1081 
1082         program.GetResource(interface, index, GL_LOCATION, 1 /* size */, &location);
1083         program.GetResource(interface, index, GL_LOCATION_COMPONENT, 1 /* size */, &component);
1084     }
1085     catch (std::exception &exc)
1086     {
1087         stream << "Failed to query program for varying: " << desc.m_name << ". Reason: " << exc.what() << "\n";
1088 
1089         return false;
1090     }
1091 
1092     bool result = true;
1093 
1094     if (location != desc.m_expected_location)
1095     {
1096         stream << "Attribute: " << desc.m_name << " - invalid location: " << location
1097                << " expected: " << desc.m_expected_location << std::endl;
1098         result = false;
1099     }
1100     if (component != desc.m_expected_component)
1101     {
1102         stream << "Attribute: " << desc.m_name << " - invalid component: " << component
1103                << " expected: " << desc.m_expected_component << std::endl;
1104         result = false;
1105     }
1106 
1107     return result;
1108 }
1109 
1110 /** Query program resource for given variable and verify that everything is as expected
1111  *
1112  * @param program  Program object
1113  * @param variable Variable object
1114  * @param stream   Stream that will be used to log any error
1115  * @param is_input Selects if varying is input or output
1116  *
1117  * @return true if verification is positive, false otherwise
1118  **/
checkVarying(Program & program,Shader::STAGES stage,const Variable & variable,std::stringstream & stream,bool is_input)1119 bool checkVarying(Program &program, Shader::STAGES stage, const Variable &variable, std::stringstream &stream,
1120                   bool is_input)
1121 {
1122     bool result = true;
1123 
1124     if (variable.IsBlock())
1125     {
1126         Utils::Interface *interface = variable.m_descriptor.m_interface;
1127         const size_t n_members      = interface->m_members.size();
1128 
1129         for (size_t i = 0; i < n_members; ++i)
1130         {
1131             const Variable::Descriptor &member = interface->m_members[i];
1132             bool member_result                 = verifyVarying(program, interface->m_name, member, stream, is_input);
1133 
1134             if (false == member_result)
1135             {
1136                 result = false;
1137             }
1138         }
1139     }
1140     /*
1141      To query the the location of struct member by glGetProgramResource, we need pass the variable name "gs_fs_output[0].single",
1142      but in original implementation, the test pass the name "Data.single", which can't get any valid result.
1143      struct Data {
1144      dmat2 single;
1145      dmat2 array[1];
1146      };
1147      layout (location = 0) in Data gs_fs_output[1];
1148      */
1149     else if (variable.IsStruct())
1150     {
1151         Utils::Interface *interface = variable.m_descriptor.m_interface;
1152         const size_t n_members      = interface->m_members.size();
1153         std::string structVariable  = variable.m_descriptor.m_name;
1154 
1155         switch (Variable::GetFlavour(stage, is_input ? Variable::INPUT : Variable::OUTPUT))
1156         {
1157         case Variable::ARRAY:
1158         case Variable::INDEXED_BY_INVOCATION_ID:
1159             structVariable.append("[0]");
1160             break;
1161         default:
1162             break;
1163         }
1164 
1165         // If struct variable is an array
1166         if (0 != variable.m_descriptor.m_n_array_elements)
1167         {
1168             for (GLuint i = 0; i < variable.m_descriptor.m_n_array_elements; i++)
1169             {
1170                 GLchar buffer[16];
1171                 sprintf(buffer, "%d", i);
1172                 structVariable.append("[");
1173                 structVariable.append(buffer);
1174                 structVariable.append("]");
1175                 for (size_t j = 0; j < n_members; ++j)
1176                 {
1177                     const Variable::Descriptor &member = interface->m_members[j];
1178                     bool member_result = verifyVarying(program, structVariable, member, stream, is_input);
1179 
1180                     if (false == member_result)
1181                     {
1182                         result = false;
1183                     }
1184                 }
1185             }
1186         }
1187         else
1188         {
1189             for (GLuint i = 0; i < n_members; ++i)
1190             {
1191                 const Variable::Descriptor &member = interface->m_members[i];
1192                 bool member_result                 = verifyVarying(program, structVariable, member, stream, is_input);
1193 
1194                 if (false == member_result)
1195                 {
1196                     result = false;
1197                 }
1198             }
1199         }
1200     }
1201     else
1202     {
1203         result = verifyVarying(program, "", variable.m_descriptor, stream, is_input);
1204     }
1205     return result;
1206 }
1207 
1208 /** Query program resource for given variable and verify that everything is as expected
1209  *
1210  * @param program  Program object
1211  * @param variable Variable object
1212  * @param stream   Stream that will be used to log any error
1213  *
1214  * @return true if verification is positive, false otherwise
1215  **/
checkUniform(Program & program,const Utils::Variable & variable,std::stringstream & stream)1216 bool checkUniform(Program &program, const Utils::Variable &variable, std::stringstream &stream)
1217 {
1218     bool result = true;
1219 
1220     if (false == variable.IsBlock())
1221     {
1222         TCU_FAIL("Not implemented");
1223     }
1224     else
1225     {
1226         Utils::Interface *interface = variable.m_descriptor.m_interface;
1227 
1228         size_t size = interface->m_members.size();
1229 
1230         std::vector<GLuint> indices;
1231         std::vector<const char *> names;
1232         std::vector<std::string> names_str;
1233         std::vector<GLint> offsets;
1234 
1235         indices.resize(size);
1236         names.resize(size);
1237         names_str.resize(size);
1238         offsets.resize(size);
1239 
1240         for (size_t i = 0; i < size; ++i)
1241         {
1242             indices[i] = 0;
1243             offsets[i] = 0;
1244 
1245             const std::string &name =
1246                 Utils::Variable::GetReference(interface->m_name, interface->m_members[i], Utils::Variable::BASIC, 0);
1247 
1248             if (Utils::Variable::INTERFACE == interface->m_members[i].m_type)
1249             {
1250                 const std::string &member_name = Utils::Variable::GetReference(
1251                     name, interface->m_members[i].m_interface->m_members[0], Utils::Variable::BASIC, 0);
1252 
1253                 names_str[i] = member_name;
1254             }
1255             else
1256             {
1257                 names_str[i] = name;
1258             }
1259 
1260             names[i] = names_str[i].c_str();
1261         }
1262 
1263         try
1264         {
1265             program.GetUniformIndices(static_cast<glw::GLsizei>(size), &names[0], &indices[0]);
1266             program.GetActiveUniformsiv(static_cast<glw::GLsizei>(size), &indices[0], GL_UNIFORM_OFFSET, &offsets[0]);
1267         }
1268         catch (std::exception &exc)
1269         {
1270             stream << "Failed to query program for uniforms in block: " << variable.m_descriptor.m_name
1271                    << ". Reason: " << exc.what() << "\n";
1272 
1273             return false;
1274         }
1275 
1276         for (size_t i = 0; i < size; ++i)
1277         {
1278             Utils::Variable::Descriptor &desc = interface->m_members[i];
1279 
1280             if (offsets[i] != (GLint)desc.m_offset)
1281             {
1282                 stream << "Uniform: " << desc.m_name << " - invalid offset: " << offsets[i]
1283                        << " expected: " << desc.m_offset << std::endl;
1284                 result = false;
1285             }
1286         }
1287     }
1288 
1289     return result;
1290 }
1291 
1292 /** Query program resource for given variable and verify that everything is as expected
1293  *
1294  * @param program  Program object
1295  * @param variable Variable object
1296  * @param stream   Stream that will be used to log any error
1297  *
1298  * @return true if verification is positive, false otherwise
1299  **/
checkSSB(Program & program,const Utils::Variable & variable,std::stringstream & stream)1300 bool checkSSB(Program &program, const Utils::Variable &variable, std::stringstream &stream)
1301 {
1302     bool result = true;
1303 
1304     if (false == variable.IsBlock())
1305     {
1306         TCU_FAIL("Not implemented");
1307     }
1308     else
1309     {
1310         Utils::Interface *interface = variable.m_descriptor.m_interface;
1311 
1312         size_t size = interface->m_members.size();
1313 
1314         for (size_t i = 0; i < size; ++i)
1315         {
1316             GLuint index         = 0;
1317             std::string name_str = "";
1318             GLint offset         = 0;
1319 
1320             const std::string &name =
1321                 Utils::Variable::GetReference(interface->m_name, interface->m_members[i], Utils::Variable::BASIC, 0);
1322 
1323             if (Utils::Variable::INTERFACE == interface->m_members[i].m_type)
1324             {
1325                 const std::string &member_name = Utils::Variable::GetReference(
1326                     name, interface->m_members[i].m_interface->m_members[0], Utils::Variable::BASIC, 0);
1327 
1328                 name_str = member_name;
1329             }
1330             else
1331             {
1332                 name_str = name;
1333             }
1334 
1335             try
1336             {
1337                 index = program.GetResourceIndex(name_str, GL_BUFFER_VARIABLE);
1338 
1339                 program.GetResource(GL_BUFFER_VARIABLE, index, GL_OFFSET, 1, &offset);
1340             }
1341             catch (std::exception &exc)
1342             {
1343                 stream << "Failed to query program for buffer variable: " << variable.m_descriptor.m_name
1344                        << ". Reason: " << exc.what() << "\n";
1345 
1346                 return false;
1347             }
1348 
1349             Utils::Variable::Descriptor &desc = interface->m_members[i];
1350 
1351             if (offset != (GLint)desc.m_offset)
1352             {
1353                 stream << "Uniform: " << desc.m_name << " - invalid offset: " << offset
1354                        << " expected: " << desc.m_offset << std::endl;
1355                 result = false;
1356             }
1357         }
1358     }
1359 
1360     return result;
1361 }
1362 
1363 /** Query program resources at given stage and verifies results
1364  *
1365  * @param program           Program object
1366  * @param program_interface Definition of program interface
1367  * @param stage             Stage to be verified
1368  * @param check_inputs      Select if inputs should be verified
1369  * @param check_outputs     Select if output should be verified
1370  * @param check_uniforms    Select if uniforms should be verified
1371  * @param check_ssbs        Select if buffers should be verified
1372  * @param stream            Stream that will be used to log any error
1373  *
1374  * @return true if verification is positive, false otherwise
1375  **/
checkProgramStage(Program & program,const ProgramInterface & program_interface,Utils::Shader::STAGES stage,bool check_inputs,bool check_outputs,bool check_uniforms,bool check_ssbs,std::stringstream & stream)1376 bool checkProgramStage(Program &program, const ProgramInterface &program_interface, Utils::Shader::STAGES stage,
1377                        bool check_inputs, bool check_outputs, bool check_uniforms, bool check_ssbs,
1378                        std::stringstream &stream)
1379 {
1380     typedef Variable::PtrVector::const_iterator const_iterator;
1381 
1382     const ShaderInterface &interface = program_interface.GetShaderInterface(stage);
1383 
1384     bool result = true;
1385 
1386     /* Inputs */
1387     if (true == check_inputs)
1388     {
1389         const Variable::PtrVector &inputs = interface.m_inputs;
1390 
1391         for (const_iterator it = inputs.begin(); it != inputs.end(); ++it)
1392         {
1393             if (false == checkVarying(program, stage, **it, stream, true))
1394             {
1395                 result = false;
1396             }
1397         }
1398     }
1399 
1400     /* Outputs */
1401     if (true == check_outputs)
1402     {
1403         const Variable::PtrVector &outputs = interface.m_outputs;
1404 
1405         for (const_iterator it = outputs.begin(); it != outputs.end(); ++it)
1406         {
1407             if (false == checkVarying(program, stage, **it, stream, false))
1408             {
1409                 result = false;
1410             }
1411         }
1412     }
1413 
1414     /* Uniforms */
1415     if (true == check_uniforms)
1416     {
1417         const Variable::PtrVector &uniforms = interface.m_uniforms;
1418 
1419         for (const_iterator it = uniforms.begin(); it != uniforms.end(); ++it)
1420         {
1421             if (false == checkUniform(program, **it, stream))
1422             {
1423                 result = false;
1424             }
1425         }
1426     }
1427 
1428     /* SSBs */
1429     if (true == check_ssbs)
1430     {
1431         const Variable::PtrVector &ssbs = interface.m_ssb_blocks;
1432 
1433         for (const_iterator it = ssbs.begin(); it != ssbs.end(); ++it)
1434         {
1435             if (false == checkSSB(program, **it, stream))
1436             {
1437                 result = false;
1438             }
1439         }
1440     }
1441 
1442     return result;
1443 }
1444 
1445 /** Query resources of monolithic compute program and verifies results
1446  *
1447  * @param program           Program object
1448  * @param program_interface Definition of program interface
1449  * @param stream            Stream that will be used to log any error
1450  *
1451  * @return true if verification is positive, false otherwise
1452  **/
checkMonolithicComputeProgramInterface(Program & program,const ProgramInterface & program_interface,std::stringstream & stream)1453 bool checkMonolithicComputeProgramInterface(Program &program, const ProgramInterface &program_interface,
1454                                             std::stringstream &stream)
1455 {
1456     bool result = true;
1457 
1458     if (false == checkProgramStage(program, program_interface, Shader::COMPUTE, false, false, true, true, stream))
1459     {
1460         result = false;
1461     }
1462 
1463     /* Done */
1464     return result;
1465 }
1466 
1467 /** Query resources of monolithic draw program and verifies results
1468  *
1469  * @param program           Program object
1470  * @param program_interface Definition of program interface
1471  * @param stream            Stream that will be used to log any error
1472  *
1473  * @return true if verification is positive, false otherwise
1474  **/
checkMonolithicDrawProgramInterface(Program & program,const ProgramInterface & program_interface,std::stringstream & stream)1475 bool checkMonolithicDrawProgramInterface(Program &program, const ProgramInterface &program_interface,
1476                                          std::stringstream &stream)
1477 {
1478     bool result = true;
1479 
1480     if (false == checkProgramStage(program, program_interface, Shader::VERTEX, true, false, true, true, stream))
1481     {
1482         result = false;
1483     }
1484 
1485     /* Done */
1486     return result;
1487 }
1488 
1489 /** Query resources of separable draw program and verifies results
1490  *
1491  * @param program           Program object
1492  * @param program_interface Definition of program interface
1493  * @param stream            Stream that will be used to log any error
1494  *
1495  * @return true if verification is positive, false otherwise
1496  **/
checkSeparableDrawProgramInterface(Program & program,const ProgramInterface & program_interface,Utils::Shader::STAGES stage,std::stringstream & stream)1497 bool checkSeparableDrawProgramInterface(Program &program, const ProgramInterface &program_interface,
1498                                         Utils::Shader::STAGES stage, std::stringstream &stream)
1499 {
1500     bool result = true;
1501 
1502     if (false == checkProgramStage(program, program_interface, stage, true, true, true, true, stream))
1503     {
1504         result = false;
1505     }
1506 
1507     /* Done */
1508     return result;
1509 }
1510 
1511 /** Check if extension is supported
1512  *
1513  * @param context        Test context
1514  * @param extension_name Name of extension
1515  *
1516  * @return true if extension is supported, false otherwise
1517  **/
isExtensionSupported(deqp::Context & context,const GLchar * extension_name)1518 bool isExtensionSupported(deqp::Context &context, const GLchar *extension_name)
1519 {
1520     const std::vector<std::string> &extensions = context.getContextInfo().getExtensions();
1521 
1522     if (std::find(extensions.begin(), extensions.end(), extension_name) == extensions.end())
1523     {
1524         return false;
1525     }
1526 
1527     return true;
1528 }
1529 
1530 /** Check if GL context meets version requirements
1531  *
1532  * @param gl             Functions
1533  * @param required_major Minimum required MAJOR_VERSION
1534  * @param required_minor Minimum required MINOR_VERSION
1535  *
1536  * @return true if GL context version is at least as requested, false otherwise
1537  **/
isGLVersionAtLeast(const Functions & gl,GLint required_major,GLint required_minor)1538 bool isGLVersionAtLeast(const Functions &gl, GLint required_major, GLint required_minor)
1539 {
1540     glw::GLint major = 0;
1541     glw::GLint minor = 0;
1542 
1543     gl.getIntegerv(GL_MAJOR_VERSION, &major);
1544     gl.getIntegerv(GL_MINOR_VERSION, &minor);
1545 
1546     GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
1547 
1548     if (major > required_major)
1549     {
1550         /* Major is higher than required one */
1551         return true;
1552     }
1553     else if (major == required_major)
1554     {
1555         if (minor >= required_minor)
1556         {
1557             /* Major is equal to required one */
1558             /* Minor is higher than or equal to required one */
1559             return true;
1560         }
1561         else
1562         {
1563             /* Major is equal to required one */
1564             /* Minor is lower than required one */
1565             return false;
1566         }
1567     }
1568     else
1569     {
1570         /* Major is lower than required one */
1571         return false;
1572     }
1573 }
1574 
1575 /** Replace first occurance of <token> with <text> in <string> starting at <search_posistion>
1576  *
1577  * @param token           Token string
1578  * @param search_position Position at which find will start, it is updated to position at which replaced text ends
1579  * @param text            String that will be used as replacement for <token>
1580  * @param string          String to work on
1581  **/
replaceToken(const GLchar * token,size_t & search_position,const GLchar * text,std::string & string)1582 void replaceToken(const GLchar *token, size_t &search_position, const GLchar *text, std::string &string)
1583 {
1584     const size_t text_length    = strlen(text);
1585     const size_t token_length   = strlen(token);
1586     const size_t token_position = string.find(token, search_position);
1587 
1588 #if DEBUG_REPLACE_TOKEN
1589     if (std::string::npos == token_position)
1590     {
1591         string.append("\n\nInvalid token: ");
1592         string.append(token);
1593 
1594         TCU_FAIL(string.c_str());
1595     }
1596 #endif /* DEBUG_REPLACE_TOKEN */
1597 
1598     string.replace(token_position, token_length, text, text_length);
1599 
1600     search_position = token_position + text_length;
1601 }
1602 
1603 /** Replace all occurances of <token> with <text> in <string>
1604  *
1605  * @param token           Token string
1606  * @param text            String that will be used as replacement for <token>
1607  * @param string          String to work on
1608  **/
replaceAllTokens(const GLchar * token,const GLchar * text,std::string & string)1609 void replaceAllTokens(const GLchar *token, const GLchar *text, std::string &string)
1610 {
1611     const size_t text_length  = strlen(text);
1612     const size_t token_length = strlen(token);
1613 
1614     size_t search_position = 0;
1615 
1616     while (1)
1617     {
1618         const size_t token_position = string.find(token, search_position);
1619 
1620         if (std::string::npos == token_position)
1621         {
1622             break;
1623         }
1624 
1625         search_position = token_position + text_length;
1626 
1627         string.replace(token_position, token_length, text, text_length);
1628     }
1629 }
1630 
1631 /** Rounds up the value to the next power of 2.
1632  * This routine does not work for 0, see the url for explanations.
1633  *
1634  * @param value Starting point
1635  *
1636  * @return Calculated value
1637  **/
roundUpToPowerOf2(glw::GLuint value)1638 glw::GLuint roundUpToPowerOf2(glw::GLuint value)
1639 {
1640     /* Taken from: graphics.stanford.edu/~seander/bithacks.html */
1641     --value;
1642 
1643     value |= value >> 1;
1644     value |= value >> 2;
1645     value |= value >> 4;
1646     value |= value >> 8;
1647     value |= value >> 16;
1648 
1649     ++value;
1650 
1651     return value;
1652 }
1653 
1654 /** Insert elements of list into string.
1655  * List in string is represented either by token "LIST" or "SEPARATORLIST".
1656  * If SEPARATORLIST is available, than SEPARATOR is replaced with <separator>.
1657  * LIST is replaced with <element>SEPARATORLIST
1658  *
1659  * @param element         Element to be inserted
1660  * @param separator       Separator inserted between elements
1661  * @param search_position Position in string, where search for list should start
1662  * @param string          String
1663  **/
insertElementOfList(const GLchar * element,const GLchar * separator,size_t & search_position,std::string & string)1664 void insertElementOfList(const GLchar *element, const GLchar *separator, size_t &search_position, std::string &string)
1665 {
1666     static const char *list     = g_list;
1667     static const char *sep_list = "SEPARATORLIST";
1668 
1669     /* Try to get "list" positions */
1670     const size_t list_position     = string.find(list, search_position);
1671     const size_t sep_list_position = string.find(sep_list, search_position);
1672 
1673     /* There is no list in string */
1674     if (std::string::npos == list_position)
1675     {
1676         return;
1677     }
1678 
1679     if (9 /* strlen(SEPARATOR) */ == list_position - sep_list_position)
1680     {
1681         replaceToken("SEPARATOR", search_position, separator, string);
1682     }
1683 
1684     /* Save search_position */
1685     const size_t start_position = search_position;
1686 
1687     /* Prepare new element */
1688     replaceToken("LIST", search_position, "ELEMENTSEPARATORLIST", string);
1689 
1690     /* Restore search_position */
1691     search_position = start_position;
1692 
1693     /* Replace element and separator */
1694     replaceToken("ELEMENT", search_position, element, string);
1695 }
1696 
1697 /** Close list in string.
1698  * If SEPARATORLIST is available, than SEPARATOR is replaced with <separator>
1699  * LIST is replaced with ""
1700  *
1701  * @param separator       Separator inserted between elements
1702  * @param search_position Position in string, where search for list should start
1703  * @param string          String
1704  **/
endList(const glw::GLchar * separator,size_t & search_position,std::string & string)1705 void endList(const glw::GLchar *separator, size_t &search_position, std::string &string)
1706 {
1707     const size_t sep_position = string.find("SEPARATOR", search_position);
1708     if (std::string::npos != sep_position)
1709     {
1710         replaceToken("SEPARATOR", search_position, separator, string);
1711     }
1712 
1713     replaceToken("LIST", search_position, "", string);
1714 }
1715 
1716 /* Buffer constants */
1717 const GLuint Buffer::m_invalid_id = -1;
1718 
1719 /** Constructor.
1720  *
1721  * @param context CTS context.
1722  **/
Buffer(deqp::Context & context)1723 Buffer::Buffer(deqp::Context &context) : m_id(m_invalid_id), m_buffer(Array), m_context(context)
1724 {
1725 }
1726 
1727 /** Destructor
1728  *
1729  **/
~Buffer()1730 Buffer::~Buffer()
1731 {
1732     Release();
1733 }
1734 
1735 /** Initialize buffer instance
1736  *
1737  * @param buffer Buffer type
1738  * @param usage  Buffer usage enum
1739  * @param size   <size> parameter
1740  * @param data   <data> parameter
1741  **/
Init(BUFFERS buffer,USAGE usage,GLsizeiptr size,GLvoid * data)1742 void Buffer::Init(BUFFERS buffer, USAGE usage, GLsizeiptr size, GLvoid *data)
1743 {
1744     /* Delete previous buffer instance */
1745     Release();
1746 
1747     m_buffer = buffer;
1748 
1749     const Functions &gl = m_context.getRenderContext().getFunctions();
1750 
1751     Generate(gl, m_id);
1752     Bind(gl, m_id, m_buffer);
1753     Data(gl, m_buffer, usage, size, data);
1754 }
1755 
1756 /** Release buffer instance
1757  *
1758  **/
Release()1759 void Buffer::Release()
1760 {
1761     if (m_invalid_id != m_id)
1762     {
1763         const Functions &gl = m_context.getRenderContext().getFunctions();
1764 
1765         gl.deleteBuffers(1, &m_id);
1766         m_id = m_invalid_id;
1767     }
1768 }
1769 
1770 /** Binds buffer to its target
1771  *
1772  **/
Bind() const1773 void Buffer::Bind() const
1774 {
1775     const Functions &gl = m_context.getRenderContext().getFunctions();
1776 
1777     Bind(gl, m_id, m_buffer);
1778 }
1779 
1780 /** Binds indexed buffer
1781  *
1782  * @param index <index> parameter
1783  **/
BindBase(GLuint index) const1784 void Buffer::BindBase(GLuint index) const
1785 {
1786     const Functions &gl = m_context.getRenderContext().getFunctions();
1787 
1788     BindBase(gl, m_id, m_buffer, index);
1789 }
1790 
1791 /** Binds range of buffer
1792  *
1793  * @param index  <index> parameter
1794  * @param offset <offset> parameter
1795  * @param size   <size> parameter
1796  **/
BindRange(GLuint index,GLintptr offset,GLsizeiptr size) const1797 void Buffer::BindRange(GLuint index, GLintptr offset, GLsizeiptr size) const
1798 {
1799     const Functions &gl = m_context.getRenderContext().getFunctions();
1800 
1801     BindRange(gl, m_id, m_buffer, index, offset, size);
1802 }
1803 
1804 /** Allocate memory for buffer and sends initial content
1805  *
1806  * @param usage  Buffer usage enum
1807  * @param size   <size> parameter
1808  * @param data   <data> parameter
1809  **/
Data(USAGE usage,glw::GLsizeiptr size,glw::GLvoid * data)1810 void Buffer::Data(USAGE usage, glw::GLsizeiptr size, glw::GLvoid *data)
1811 {
1812     const Functions &gl = m_context.getRenderContext().getFunctions();
1813 
1814     Data(gl, m_buffer, usage, size, data);
1815 }
1816 
1817 /** Maps contents of buffer into CPU space
1818  *
1819  * @param access Requested access
1820  *
1821  * @return Pointer to memory region available for CPU
1822  **/
Map(ACCESS access)1823 GLvoid *Buffer::Map(ACCESS access)
1824 {
1825     const Functions &gl = m_context.getRenderContext().getFunctions();
1826 
1827     return Map(gl, m_buffer, access);
1828 }
1829 
1830 /** Allocate memory for buffer and sends initial content
1831  *
1832  * @param offset Offset in buffer
1833  * @param size   <size> parameter
1834  * @param data   <data> parameter
1835  **/
SubData(glw::GLintptr offset,glw::GLsizeiptr size,glw::GLvoid * data)1836 void Buffer::SubData(glw::GLintptr offset, glw::GLsizeiptr size, glw::GLvoid *data)
1837 {
1838     const Functions &gl = m_context.getRenderContext().getFunctions();
1839 
1840     SubData(gl, m_buffer, offset, size, data);
1841 }
1842 
1843 /** Maps contents of buffer into CPU space
1844  **/
UnMap()1845 void Buffer::UnMap()
1846 {
1847     const Functions &gl = m_context.getRenderContext().getFunctions();
1848 
1849     return UnMap(gl, m_buffer);
1850 }
1851 
1852 /** Bind buffer to given target
1853  *
1854  * @param gl     GL functions
1855  * @param id     Id of buffer
1856  * @param buffer Buffer enum
1857  **/
Bind(const Functions & gl,GLuint id,BUFFERS buffer)1858 void Buffer::Bind(const Functions &gl, GLuint id, BUFFERS buffer)
1859 {
1860     GLenum target = GetBufferGLenum(buffer);
1861 
1862     gl.bindBuffer(target, id);
1863     GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffer");
1864 }
1865 
1866 /** Binds indexed buffer
1867  *
1868  * @param gl     GL functions
1869  * @param id     Id of buffer
1870  * @param buffer Buffer enum
1871  * @param index  <index> parameter
1872  **/
BindBase(const Functions & gl,GLuint id,BUFFERS buffer,GLuint index)1873 void Buffer::BindBase(const Functions &gl, GLuint id, BUFFERS buffer, GLuint index)
1874 {
1875     GLenum target = GetBufferGLenum(buffer);
1876 
1877     gl.bindBufferBase(target, index, id);
1878     GLU_EXPECT_NO_ERROR(gl.getError(), "BindBufferBase");
1879 }
1880 
1881 /** Binds buffer range
1882  *
1883  * @param gl     GL functions
1884  * @param id     Id of buffer
1885  * @param buffer Buffer enum
1886  * @param index  <index> parameter
1887  * @param offset <offset> parameter
1888  * @param size   <size> parameter
1889  **/
BindRange(const Functions & gl,GLuint id,BUFFERS buffer,GLuint index,GLintptr offset,GLsizeiptr size)1890 void Buffer::BindRange(const Functions &gl, GLuint id, BUFFERS buffer, GLuint index, GLintptr offset, GLsizeiptr size)
1891 {
1892     GLenum target = GetBufferGLenum(buffer);
1893 
1894     gl.bindBufferRange(target, index, id, offset, size);
1895     GLU_EXPECT_NO_ERROR(gl.getError(), "BindBufferRange");
1896 }
1897 
1898 /** Allocate memory for buffer and sends initial content
1899  *
1900  * @param gl     GL functions
1901  * @param buffer Buffer enum
1902  * @param usage  Buffer usage enum
1903  * @param size   <size> parameter
1904  * @param data   <data> parameter
1905  **/
Data(const glw::Functions & gl,BUFFERS buffer,USAGE usage,glw::GLsizeiptr size,glw::GLvoid * data)1906 void Buffer::Data(const glw::Functions &gl, BUFFERS buffer, USAGE usage, glw::GLsizeiptr size, glw::GLvoid *data)
1907 {
1908     GLenum target   = GetBufferGLenum(buffer);
1909     GLenum gl_usage = GetUsageGLenum(usage);
1910 
1911     gl.bufferData(target, size, data, gl_usage);
1912     GLU_EXPECT_NO_ERROR(gl.getError(), "BufferData");
1913 }
1914 
1915 /** Allocate memory for buffer and sends initial content
1916  *
1917  * @param gl     GL functions
1918  * @param buffer Buffer enum
1919  * @param offset Offset in buffer
1920  * @param size   <size> parameter
1921  * @param data   <data> parameter
1922  **/
SubData(const glw::Functions & gl,BUFFERS buffer,glw::GLintptr offset,glw::GLsizeiptr size,glw::GLvoid * data)1923 void Buffer::SubData(const glw::Functions &gl, BUFFERS buffer, glw::GLintptr offset, glw::GLsizeiptr size,
1924                      glw::GLvoid *data)
1925 {
1926     GLenum target = GetBufferGLenum(buffer);
1927 
1928     gl.bufferSubData(target, offset, size, data);
1929     GLU_EXPECT_NO_ERROR(gl.getError(), "BufferSubData");
1930 }
1931 
1932 /** Generate buffer
1933  *
1934  * @param gl     GL functions
1935  * @param out_id Id of buffer
1936  **/
Generate(const Functions & gl,GLuint & out_id)1937 void Buffer::Generate(const Functions &gl, GLuint &out_id)
1938 {
1939     GLuint id = m_invalid_id;
1940 
1941     gl.genBuffers(1, &id);
1942     GLU_EXPECT_NO_ERROR(gl.getError(), "GenBuffers");
1943 
1944     if (m_invalid_id == id)
1945     {
1946         TCU_FAIL("Got invalid id");
1947     }
1948 
1949     out_id = id;
1950 }
1951 
1952 /** Maps buffer content
1953  *
1954  * @param gl     GL functions
1955  * @param buffer Buffer enum
1956  * @param access Access rights for mapped region
1957  *
1958  * @return Mapped memory
1959  **/
Map(const Functions & gl,BUFFERS buffer,ACCESS access)1960 void *Buffer::Map(const Functions &gl, BUFFERS buffer, ACCESS access)
1961 {
1962     GLenum target    = GetBufferGLenum(buffer);
1963     GLenum gl_access = GetAccessGLenum(access);
1964 
1965     void *result = gl.mapBuffer(target, gl_access);
1966     GLU_EXPECT_NO_ERROR(gl.getError(), "MapBuffer");
1967 
1968     return result;
1969 }
1970 
1971 /** Unmaps buffer
1972  *
1973  **/
UnMap(const Functions & gl,BUFFERS buffer)1974 void Buffer::UnMap(const Functions &gl, BUFFERS buffer)
1975 {
1976     GLenum target = GetBufferGLenum(buffer);
1977 
1978     gl.unmapBuffer(target);
1979     GLU_EXPECT_NO_ERROR(gl.getError(), "UnmapBuffer");
1980 }
1981 
1982 /** Return GLenum representation of requested access
1983  *
1984  * @param access Requested access
1985  *
1986  * @return GLenum value
1987  **/
GetAccessGLenum(ACCESS access)1988 GLenum Buffer::GetAccessGLenum(ACCESS access)
1989 {
1990     GLenum result = 0;
1991 
1992     switch (access)
1993     {
1994     case ReadOnly:
1995         result = GL_READ_ONLY;
1996         break;
1997     case WriteOnly:
1998         result = GL_WRITE_ONLY;
1999         break;
2000     case ReadWrite:
2001         result = GL_READ_WRITE;
2002         break;
2003     default:
2004         TCU_FAIL("Invalid enum");
2005     }
2006 
2007     return result;
2008 }
2009 
2010 /** Return GLenum representation of requested buffer type
2011  *
2012  * @param buffer Requested buffer type
2013  *
2014  * @return GLenum value
2015  **/
GetBufferGLenum(BUFFERS buffer)2016 GLenum Buffer::GetBufferGLenum(BUFFERS buffer)
2017 {
2018     GLenum result = 0;
2019 
2020     switch (buffer)
2021     {
2022     case Array:
2023         result = GL_ARRAY_BUFFER;
2024         break;
2025     case Element:
2026         result = GL_ELEMENT_ARRAY_BUFFER;
2027         break;
2028     case Shader_Storage:
2029         result = GL_SHADER_STORAGE_BUFFER;
2030         break;
2031     case Texture:
2032         result = GL_TEXTURE_BUFFER;
2033         break;
2034     case Transform_feedback:
2035         result = GL_TRANSFORM_FEEDBACK_BUFFER;
2036         break;
2037     case Uniform:
2038         result = GL_UNIFORM_BUFFER;
2039         break;
2040     default:
2041         TCU_FAIL("Invalid enum");
2042     }
2043 
2044     return result;
2045 }
2046 
2047 /** Return GLenum representation of requested usage
2048  *
2049  * @param usage Requested usage
2050  *
2051  * @return GLenum value
2052  **/
GetUsageGLenum(USAGE usage)2053 GLenum Buffer::GetUsageGLenum(USAGE usage)
2054 {
2055     GLenum result = 0;
2056 
2057     switch (usage)
2058     {
2059     case DynamicCopy:
2060         result = GL_DYNAMIC_COPY;
2061         break;
2062     case DynamicDraw:
2063         result = GL_DYNAMIC_DRAW;
2064         break;
2065     case DynamicRead:
2066         result = GL_DYNAMIC_READ;
2067         break;
2068     case StaticCopy:
2069         result = GL_STATIC_COPY;
2070         break;
2071     case StaticDraw:
2072         result = GL_STATIC_DRAW;
2073         break;
2074     case StaticRead:
2075         result = GL_STATIC_READ;
2076         break;
2077     case StreamCopy:
2078         result = GL_STREAM_COPY;
2079         break;
2080     case StreamDraw:
2081         result = GL_STREAM_DRAW;
2082         break;
2083     case StreamRead:
2084         result = GL_STREAM_READ;
2085         break;
2086     default:
2087         TCU_FAIL("Invalid enum");
2088     }
2089 
2090     return result;
2091 }
2092 
2093 /** Returns name of buffer target
2094  *
2095  * @param buffer Target enum
2096  *
2097  * @return Name of target
2098  **/
GetBufferName(BUFFERS buffer)2099 const GLchar *Buffer::GetBufferName(BUFFERS buffer)
2100 {
2101     const GLchar *name = 0;
2102 
2103     switch (buffer)
2104     {
2105     case Array:
2106         name = "Array";
2107         break;
2108     case Element:
2109         name = "Element";
2110         break;
2111     case Shader_Storage:
2112         name = "Shader_Storage";
2113         break;
2114     case Texture:
2115         name = "Texture";
2116         break;
2117     case Transform_feedback:
2118         name = "Transform_feedback";
2119         break;
2120     case Uniform:
2121         name = "Uniform";
2122         break;
2123     default:
2124         TCU_FAIL("Invalid enum");
2125     }
2126 
2127     return name;
2128 }
2129 
2130 /* Framebuffer constants */
2131 const GLuint Framebuffer::m_invalid_id = -1;
2132 
2133 /** Constructor
2134  *
2135  * @param context CTS context
2136  **/
Framebuffer(deqp::Context & context)2137 Framebuffer::Framebuffer(deqp::Context &context) : m_id(m_invalid_id), m_context(context)
2138 {
2139     /* Nothing to be done here */
2140 }
2141 
2142 /** Destructor
2143  *
2144  **/
~Framebuffer()2145 Framebuffer::~Framebuffer()
2146 {
2147     Release();
2148 }
2149 
2150 /** Initialize framebuffer instance
2151  *
2152  **/
Init()2153 void Framebuffer::Init()
2154 {
2155     /* Delete previous instance */
2156     Release();
2157 
2158     const Functions &gl = m_context.getRenderContext().getFunctions();
2159 
2160     Generate(gl, m_id);
2161 }
2162 
2163 /** Release framebuffer instance
2164  *
2165  **/
Release()2166 void Framebuffer::Release()
2167 {
2168     if (m_invalid_id != m_id)
2169     {
2170         const Functions &gl = m_context.getRenderContext().getFunctions();
2171 
2172         gl.deleteFramebuffers(1, &m_id);
2173         m_id = m_invalid_id;
2174     }
2175 }
2176 
2177 /** Attach texture to specified attachment
2178  *
2179  * @param attachment Attachment
2180  * @param texture_id Texture id
2181  * @param width      Texture width
2182  * @param height     Texture height
2183  **/
AttachTexture(GLenum attachment,GLuint texture_id,GLuint width,GLuint height)2184 void Framebuffer::AttachTexture(GLenum attachment, GLuint texture_id, GLuint width, GLuint height)
2185 {
2186     const Functions &gl = m_context.getRenderContext().getFunctions();
2187 
2188     AttachTexture(gl, attachment, texture_id, width, height);
2189 }
2190 
2191 /** Binds framebuffer to DRAW_FRAMEBUFFER
2192  *
2193  **/
Bind()2194 void Framebuffer::Bind()
2195 {
2196     const Functions &gl = m_context.getRenderContext().getFunctions();
2197 
2198     Bind(gl, m_id);
2199 }
2200 
2201 /** Clear framebuffer
2202  *
2203  * @param mask <mask> parameter of glClear. Decides which shall be cleared
2204  **/
Clear(GLenum mask)2205 void Framebuffer::Clear(GLenum mask)
2206 {
2207     const Functions &gl = m_context.getRenderContext().getFunctions();
2208 
2209     Clear(gl, mask);
2210 }
2211 
2212 /** Specifies clear color
2213  *
2214  * @param red   Red channel
2215  * @param green Green channel
2216  * @param blue  Blue channel
2217  * @param alpha Alpha channel
2218  **/
ClearColor(GLfloat red,GLfloat green,GLfloat blue,GLfloat alpha)2219 void Framebuffer::ClearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
2220 {
2221     const Functions &gl = m_context.getRenderContext().getFunctions();
2222 
2223     ClearColor(gl, red, green, blue, alpha);
2224 }
2225 
2226 /** Attach texture to specified attachment
2227  *
2228  * @param gl         GL functions
2229  * @param attachment Attachment
2230  * @param texture_id Texture id
2231  * @param width      Texture width
2232  * @param height     Texture height
2233  **/
AttachTexture(const Functions & gl,GLenum attachment,GLuint texture_id,GLuint width,GLuint height)2234 void Framebuffer::AttachTexture(const Functions &gl, GLenum attachment, GLuint texture_id, GLuint width, GLuint height)
2235 {
2236     gl.framebufferTexture(GL_DRAW_FRAMEBUFFER, attachment, texture_id, 0 /* level */);
2237     GLU_EXPECT_NO_ERROR(gl.getError(), "FramebufferTexture");
2238 
2239     gl.viewport(0 /* x */, 0 /* y */, width, height);
2240     GLU_EXPECT_NO_ERROR(gl.getError(), "Viewport");
2241 }
2242 
2243 /** Binds framebuffer to DRAW_FRAMEBUFFER
2244  *
2245  * @param gl GL functions
2246  * @param id ID of framebuffer
2247  **/
Bind(const Functions & gl,GLuint id)2248 void Framebuffer::Bind(const Functions &gl, GLuint id)
2249 {
2250     gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, id);
2251     GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer");
2252 }
2253 
2254 /** Clear framebuffer
2255  *
2256  * @param gl   GL functions
2257  * @param mask <mask> parameter of glClear. Decides which shall be cleared
2258  **/
Clear(const Functions & gl,GLenum mask)2259 void Framebuffer::Clear(const Functions &gl, GLenum mask)
2260 {
2261     gl.clear(mask);
2262     GLU_EXPECT_NO_ERROR(gl.getError(), "Clear");
2263 }
2264 
2265 /** Specifies clear color
2266  *
2267  * @param gl    GL functions
2268  * @param red   Red channel
2269  * @param green Green channel
2270  * @param blue  Blue channel
2271  * @param alpha Alpha channel
2272  **/
ClearColor(const Functions & gl,GLfloat red,GLfloat green,GLfloat blue,GLfloat alpha)2273 void Framebuffer::ClearColor(const Functions &gl, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
2274 {
2275     gl.clearColor(red, green, blue, alpha);
2276     GLU_EXPECT_NO_ERROR(gl.getError(), "ClearColor");
2277 }
2278 
2279 /** Generate framebuffer
2280  *
2281  **/
Generate(const Functions & gl,GLuint & out_id)2282 void Framebuffer::Generate(const Functions &gl, GLuint &out_id)
2283 {
2284     GLuint id = m_invalid_id;
2285 
2286     gl.genFramebuffers(1, &id);
2287     GLU_EXPECT_NO_ERROR(gl.getError(), "GenFramebuffers");
2288 
2289     if (m_invalid_id == id)
2290     {
2291         TCU_FAIL("Invalid id");
2292     }
2293 
2294     out_id = id;
2295 }
2296 
2297 /* Shader's constants */
2298 const GLuint Shader::m_invalid_id = 0;
2299 
2300 /** Constructor.
2301  *
2302  * @param context CTS context.
2303  **/
Shader(deqp::Context & context)2304 Shader::Shader(deqp::Context &context) : m_id(m_invalid_id), m_context(context)
2305 {
2306     /* Nothing to be done here */
2307 }
2308 
2309 /** Destructor
2310  *
2311  **/
~Shader()2312 Shader::~Shader()
2313 {
2314     Release();
2315 }
2316 
2317 /** Initialize shader instance
2318  *
2319  * @param stage  Shader stage
2320  * @param source Source code
2321  **/
Init(STAGES stage,const std::string & source)2322 void Shader::Init(STAGES stage, const std::string &source)
2323 {
2324     if (true == source.empty())
2325     {
2326         /* No source == no shader */
2327         return;
2328     }
2329 
2330     /* Delete any previous shader */
2331     Release();
2332 
2333     /* Create, set source and compile */
2334     const Functions &gl = m_context.getRenderContext().getFunctions();
2335 
2336     Create(gl, stage, m_id);
2337     Source(gl, m_id, source);
2338 
2339     try
2340     {
2341         Compile(gl, m_id);
2342     }
2343     catch (const CompilationException &exc)
2344     {
2345         throw InvalidSourceException(exc.what(), source, stage);
2346     }
2347 }
2348 
2349 /** Release shader instance
2350  *
2351  **/
Release()2352 void Shader::Release()
2353 {
2354     if (m_invalid_id != m_id)
2355     {
2356         const Functions &gl = m_context.getRenderContext().getFunctions();
2357 
2358         gl.deleteShader(m_id);
2359         m_id = m_invalid_id;
2360     }
2361 }
2362 
2363 /** Compile shader
2364  *
2365  * @param gl GL functions
2366  * @param id Shader id
2367  **/
Compile(const Functions & gl,GLuint id)2368 void Shader::Compile(const Functions &gl, GLuint id)
2369 {
2370     GLint status = GL_FALSE;
2371 
2372     /* Compile */
2373     gl.compileShader(id);
2374     GLU_EXPECT_NO_ERROR(gl.getError(), "CompileShader");
2375 
2376     /* Get compilation status */
2377     gl.getShaderiv(id, GL_COMPILE_STATUS, &status);
2378     GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");
2379 
2380     /* Log compilation error */
2381     if (GL_TRUE != status)
2382     {
2383         glw::GLint length = 0;
2384         std::string message;
2385 
2386         /* Error log length */
2387         gl.getShaderiv(id, GL_INFO_LOG_LENGTH, &length);
2388         GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");
2389 
2390         /* Prepare storage */
2391         message.resize(length, 0);
2392 
2393         /* Get error log */
2394         gl.getShaderInfoLog(id, length, 0, &message[0]);
2395         GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderInfoLog");
2396 
2397         throw CompilationException(message.c_str());
2398     }
2399 }
2400 
2401 /** Create shader
2402  *
2403  * @param gl     GL functions
2404  * @param stage  Shader stage
2405  * @param out_id Shader id
2406  **/
Create(const Functions & gl,STAGES stage,GLuint & out_id)2407 void Shader::Create(const Functions &gl, STAGES stage, GLuint &out_id)
2408 {
2409     const GLenum shaderType = GetShaderStageGLenum(stage);
2410     const GLuint id         = gl.createShader(shaderType);
2411     GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
2412 
2413     if (m_invalid_id == id)
2414     {
2415         TCU_FAIL("Failed to create shader");
2416     }
2417 
2418     out_id = id;
2419 }
2420 
2421 /** Set shader's source code
2422  *
2423  * @param gl     GL functions
2424  * @param id     Shader id
2425  * @param source Shader source code
2426  **/
Source(const Functions & gl,GLuint id,const std::string & source)2427 void Shader::Source(const Functions &gl, GLuint id, const std::string &source)
2428 {
2429     const GLchar *code = source.c_str();
2430 
2431     gl.shaderSource(id, 1 /* count */, &code, 0 /* lengths */);
2432     GLU_EXPECT_NO_ERROR(gl.getError(), "ShaderSource");
2433 }
2434 
2435 /** Get GLenum repesenting shader stage
2436  *
2437  * @param stage Shader stage
2438  *
2439  * @return GLenum
2440  **/
GetShaderStageGLenum(STAGES stage)2441 GLenum Shader::GetShaderStageGLenum(STAGES stage)
2442 {
2443     GLenum result = 0;
2444 
2445     switch (stage)
2446     {
2447     case COMPUTE:
2448         result = GL_COMPUTE_SHADER;
2449         break;
2450     case FRAGMENT:
2451         result = GL_FRAGMENT_SHADER;
2452         break;
2453     case GEOMETRY:
2454         result = GL_GEOMETRY_SHADER;
2455         break;
2456     case TESS_CTRL:
2457         result = GL_TESS_CONTROL_SHADER;
2458         break;
2459     case TESS_EVAL:
2460         result = GL_TESS_EVALUATION_SHADER;
2461         break;
2462     case VERTEX:
2463         result = GL_VERTEX_SHADER;
2464         break;
2465     default:
2466         TCU_FAIL("Invalid enum");
2467     }
2468 
2469     return result;
2470 }
2471 
2472 /** Get string representing name of shader stage
2473  *
2474  * @param stage Shader stage
2475  *
2476  * @return String with name of shader stage
2477  **/
GetStageName(STAGES stage)2478 const glw::GLchar *Shader::GetStageName(STAGES stage)
2479 {
2480     const GLchar *result = 0;
2481 
2482     switch (stage)
2483     {
2484     case COMPUTE:
2485         result = "compute";
2486         break;
2487     case VERTEX:
2488         result = "vertex";
2489         break;
2490     case TESS_CTRL:
2491         result = "tessellation control";
2492         break;
2493     case TESS_EVAL:
2494         result = "tessellation evaluation";
2495         break;
2496     case GEOMETRY:
2497         result = "geometry";
2498         break;
2499     case FRAGMENT:
2500         result = "fragment";
2501         break;
2502     default:
2503         TCU_FAIL("Invalid enum");
2504     }
2505 
2506     return result;
2507 }
2508 
2509 /** Logs shader source
2510  *
2511  * @param context CTS context
2512  * @param source  Source of shader
2513  * @param stage   Shader stage
2514  **/
LogSource(deqp::Context & context,const std::string & source,STAGES stage)2515 void Shader::LogSource(deqp::Context &context, const std::string &source, STAGES stage)
2516 {
2517     /* Skip empty shaders */
2518     if (true == source.empty())
2519     {
2520         return;
2521     }
2522 
2523     context.getTestContext().getLog() << tcu::TestLog::Message
2524                                       << "Shader source. Stage: " << Shader::GetStageName(stage)
2525                                       << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(source);
2526 }
2527 
2528 /** Constructor
2529  *
2530  * @param message Compilation error message
2531  **/
CompilationException(const GLchar * message)2532 Shader::CompilationException::CompilationException(const GLchar *message)
2533 {
2534     m_message = message;
2535 }
2536 
2537 /** Returns error messages
2538  *
2539  * @return Compilation error message
2540  **/
what() const2541 const char *Shader::CompilationException::what() const throw()
2542 {
2543     return m_message.c_str();
2544 }
2545 
2546 /** Constructor
2547  *
2548  * @param message Compilation error message
2549  **/
InvalidSourceException(const GLchar * error_message,const std::string & source,STAGES stage)2550 Shader::InvalidSourceException::InvalidSourceException(const GLchar *error_message, const std::string &source,
2551                                                        STAGES stage)
2552     : m_message(error_message)
2553     , m_source(source)
2554     , m_stage(stage)
2555 {
2556 }
2557 
2558 /** Returns error messages
2559  *
2560  * @return Compilation error message
2561  **/
what() const2562 const char *Shader::InvalidSourceException::what() const throw()
2563 {
2564     return "Compilation error";
2565 }
2566 
2567 /** Logs error message and shader sources **/
log(deqp::Context & context) const2568 void Shader::InvalidSourceException::log(deqp::Context &context) const
2569 {
2570     context.getTestContext().getLog() << tcu::TestLog::Message << "Failed to compile shader: " << m_message.c_str()
2571                                       << tcu::TestLog::EndMessage;
2572 
2573     LogSource(context, m_source, m_stage);
2574 }
2575 
2576 /* Program constants */
2577 const GLuint Pipeline::m_invalid_id = 0;
2578 
2579 /** Constructor.
2580  *
2581  * @param context CTS context.
2582  **/
Pipeline(deqp::Context & context)2583 Pipeline::Pipeline(deqp::Context &context) : m_id(m_invalid_id), m_context(context)
2584 {
2585     /* Nothing to be done here */
2586 }
2587 
2588 /** Destructor
2589  *
2590  **/
~Pipeline()2591 Pipeline::~Pipeline()
2592 {
2593     Release();
2594 }
2595 
2596 /** Initialize pipline object
2597  *
2598  **/
Init()2599 void Pipeline::Init()
2600 {
2601     Release();
2602 
2603     const Functions &gl = m_context.getRenderContext().getFunctions();
2604 
2605     /* Generate */
2606     gl.genProgramPipelines(1, &m_id);
2607     GLU_EXPECT_NO_ERROR(gl.getError(), "GenProgramPipelines");
2608 }
2609 
2610 /** Release pipeline object
2611  *
2612  **/
Release()2613 void Pipeline::Release()
2614 {
2615     if (m_invalid_id != m_id)
2616     {
2617         const Functions &gl = m_context.getRenderContext().getFunctions();
2618 
2619         /* Generate */
2620         gl.deleteProgramPipelines(1, &m_id);
2621         GLU_EXPECT_NO_ERROR(gl.getError(), "DeleteProgramPipelines");
2622 
2623         m_id = m_invalid_id;
2624     }
2625 }
2626 
2627 /** Bind pipeline
2628  *
2629  **/
Bind()2630 void Pipeline::Bind()
2631 {
2632     const Functions &gl = m_context.getRenderContext().getFunctions();
2633 
2634     Bind(gl, m_id);
2635 }
2636 
2637 /** Set which stages should be active
2638  *
2639  * @param program_id Id of program
2640  * @param stages     Logical combination of enums representing stages
2641  **/
UseProgramStages(GLuint program_id,GLenum stages)2642 void Pipeline::UseProgramStages(GLuint program_id, GLenum stages)
2643 {
2644     const Functions &gl = m_context.getRenderContext().getFunctions();
2645 
2646     UseProgramStages(gl, m_id, program_id, stages);
2647 }
2648 
2649 /** Bind pipeline
2650  *
2651  * @param gl Functiions
2652  * @param id Pipeline id
2653  **/
Bind(const Functions & gl,GLuint id)2654 void Pipeline::Bind(const Functions &gl, GLuint id)
2655 {
2656     gl.bindProgramPipeline(id);
2657     GLU_EXPECT_NO_ERROR(gl.getError(), "BindProgramPipeline");
2658 }
2659 
2660 /** Set which stages should be active
2661  *
2662  * @param gl         Functiions
2663  * @param id         Pipeline id
2664  * @param program_id Id of program
2665  * @param stages     Logical combination of enums representing stages
2666  **/
UseProgramStages(const Functions & gl,GLuint id,GLuint program_id,GLenum stages)2667 void Pipeline::UseProgramStages(const Functions &gl, GLuint id, GLuint program_id, GLenum stages)
2668 {
2669     gl.useProgramStages(id, stages, program_id);
2670     GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgramStages");
2671 }
2672 
2673 /* Program constants */
2674 const GLuint Program::m_invalid_id = 0;
2675 
2676 /** Constructor.
2677  *
2678  * @param context CTS context.
2679  **/
Program(deqp::Context & context)2680 Program::Program(deqp::Context &context)
2681     : m_id(m_invalid_id)
2682     , m_compute(context)
2683     , m_fragment(context)
2684     , m_geometry(context)
2685     , m_tess_ctrl(context)
2686     , m_tess_eval(context)
2687     , m_vertex(context)
2688     , m_context(context)
2689 {
2690     /* Nothing to be done here */
2691 }
2692 
2693 /** Destructor
2694  *
2695  **/
~Program()2696 Program::~Program()
2697 {
2698     Release();
2699 }
2700 
2701 /** Initialize program instance
2702  *
2703  * @param compute_shader                    Compute shader source code
2704  * @param fragment_shader                   Fragment shader source code
2705  * @param geometry_shader                   Geometry shader source code
2706  * @param tessellation_control_shader       Tessellation control shader source code
2707  * @param tessellation_evaluation_shader    Tessellation evaluation shader source code
2708  * @param vertex_shader                     Vertex shader source code
2709  * @param captured_varyings                 Vector of variables to be captured with transfrom feedback
2710  * @param capture_interleaved               Select mode of transform feedback (separate or interleaved)
2711  * @param is_separable                      Selects if monolithic or separable program should be built. Defaults to false
2712  **/
Init(const std::string & compute_shader,const std::string & fragment_shader,const std::string & geometry_shader,const std::string & tessellation_control_shader,const std::string & tessellation_evaluation_shader,const std::string & vertex_shader,const NameVector & captured_varyings,bool capture_interleaved,bool is_separable)2713 void Program::Init(const std::string &compute_shader, const std::string &fragment_shader,
2714                    const std::string &geometry_shader, const std::string &tessellation_control_shader,
2715                    const std::string &tessellation_evaluation_shader, const std::string &vertex_shader,
2716                    const NameVector &captured_varyings, bool capture_interleaved, bool is_separable)
2717 {
2718     /* Delete previous program */
2719     Release();
2720 
2721     /* GL entry points */
2722     const Functions &gl = m_context.getRenderContext().getFunctions();
2723 
2724     /* Initialize shaders */
2725     m_compute.Init(Shader::COMPUTE, compute_shader);
2726     m_fragment.Init(Shader::FRAGMENT, fragment_shader);
2727     m_geometry.Init(Shader::GEOMETRY, geometry_shader);
2728     m_tess_ctrl.Init(Shader::TESS_CTRL, tessellation_control_shader);
2729     m_tess_eval.Init(Shader::TESS_EVAL, tessellation_evaluation_shader);
2730     m_vertex.Init(Shader::VERTEX, vertex_shader);
2731 
2732     /* Create program, set up transform feedback and attach shaders */
2733     Create(gl, m_id);
2734     Capture(gl, m_id, captured_varyings, capture_interleaved);
2735     Attach(gl, m_id, m_compute.m_id);
2736     Attach(gl, m_id, m_fragment.m_id);
2737     Attach(gl, m_id, m_geometry.m_id);
2738     Attach(gl, m_id, m_tess_ctrl.m_id);
2739     Attach(gl, m_id, m_tess_eval.m_id);
2740     Attach(gl, m_id, m_vertex.m_id);
2741 
2742     /* Set separable parameter */
2743     if (true == is_separable)
2744     {
2745         gl.programParameteri(m_id, GL_PROGRAM_SEPARABLE, GL_TRUE);
2746         GLU_EXPECT_NO_ERROR(gl.getError(), "ProgramParameteri");
2747     }
2748 
2749     try
2750     {
2751         /* Link program */
2752         Link(gl, m_id);
2753     }
2754     catch (const LinkageException &exc)
2755     {
2756         throw BuildException(exc.what(), compute_shader, fragment_shader, geometry_shader, tessellation_control_shader,
2757                              tessellation_evaluation_shader, vertex_shader);
2758     }
2759 }
2760 
2761 /** Initialize program instance
2762  *
2763  * @param compute_shader                    Compute shader source code
2764  * @param fragment_shader                   Fragment shader source code
2765  * @param geometry_shader                   Geometry shader source code
2766  * @param tessellation_control_shader       Tessellation control shader source code
2767  * @param tessellation_evaluation_shader    Tessellation evaluation shader source code
2768  * @param vertex_shader                     Vertex shader source code
2769  * @param is_separable                      Selects if monolithic or separable program should be built. Defaults to false
2770  **/
Init(const std::string & compute_shader,const std::string & fragment_shader,const std::string & geometry_shader,const std::string & tessellation_control_shader,const std::string & tessellation_evaluation_shader,const std::string & vertex_shader,bool is_separable)2771 void Program::Init(const std::string &compute_shader, const std::string &fragment_shader,
2772                    const std::string &geometry_shader, const std::string &tessellation_control_shader,
2773                    const std::string &tessellation_evaluation_shader, const std::string &vertex_shader,
2774                    bool is_separable)
2775 {
2776     NameVector captured_varying;
2777 
2778     Init(compute_shader, fragment_shader, geometry_shader, tessellation_control_shader, tessellation_evaluation_shader,
2779          vertex_shader, captured_varying, true, is_separable);
2780 }
2781 
2782 /** Release program instance
2783  *
2784  **/
Release()2785 void Program::Release()
2786 {
2787     const Functions &gl = m_context.getRenderContext().getFunctions();
2788 
2789     if (m_invalid_id != m_id)
2790     {
2791         Use(gl, m_invalid_id);
2792 
2793         gl.deleteProgram(m_id);
2794         m_id = m_invalid_id;
2795     }
2796 
2797     m_compute.Release();
2798     m_fragment.Release();
2799     m_geometry.Release();
2800     m_tess_ctrl.Release();
2801     m_tess_eval.Release();
2802     m_vertex.Release();
2803 }
2804 
2805 /** Get <pname> for a set of active uniforms
2806  *
2807  * @param count   Number of indices
2808  * @param indices Indices of uniforms
2809  * @param pname   Queired pname
2810  * @param params  Array that will be filled with values of parameters
2811  **/
GetActiveUniformsiv(GLsizei count,const GLuint * indices,GLenum pname,GLint * params) const2812 void Program::GetActiveUniformsiv(GLsizei count, const GLuint *indices, GLenum pname, GLint *params) const
2813 {
2814     const Functions &gl = m_context.getRenderContext().getFunctions();
2815 
2816     GetActiveUniformsiv(gl, m_id, count, indices, pname, params);
2817 }
2818 
2819 /** Get location of attribute
2820  *
2821  * @param name Name of attribute
2822  *
2823  * @return Result of query
2824  **/
GetAttribLocation(const std::string & name) const2825 glw::GLint Program::GetAttribLocation(const std::string &name) const
2826 {
2827     const Functions &gl = m_context.getRenderContext().getFunctions();
2828 
2829     return GetAttribLocation(gl, m_id, name);
2830 }
2831 
2832 /** Query resource
2833  *
2834  * @param interface Interface to be queried
2835  * @param index     Index of resource
2836  * @param property  Property to be queried
2837  * @param buf_size  Size of <params> buffer
2838  * @param params    Results of query
2839  **/
GetResource(GLenum interface,GLuint index,GLenum property,GLsizei buf_size,GLint * params) const2840 void Program::GetResource(GLenum interface, GLuint index, GLenum property, GLsizei buf_size, GLint *params) const
2841 {
2842     const Functions &gl = m_context.getRenderContext().getFunctions();
2843 
2844     GetResource(gl, m_id, interface, index, property, buf_size, params);
2845 }
2846 
2847 /** Query for index of resource
2848  *
2849  * @param name      Name of resource
2850  * @param interface Interface to be queried
2851  *
2852  * @return Result of query
2853  **/
GetResourceIndex(const std::string & name,GLenum interface) const2854 glw::GLuint Program::GetResourceIndex(const std::string &name, GLenum interface) const
2855 {
2856     const Functions &gl = m_context.getRenderContext().getFunctions();
2857 
2858     return GetResourceIndex(gl, m_id, name, interface);
2859 }
2860 
2861 /** Get indices for a set of uniforms
2862  *
2863  * @param count   Count number of uniforms
2864  * @param names   Names of uniforms
2865  * @param indices Buffer that will be filled with indices
2866  **/
GetUniformIndices(GLsizei count,const GLchar ** names,GLuint * indices) const2867 void Program::GetUniformIndices(GLsizei count, const GLchar **names, GLuint *indices) const
2868 {
2869     const Functions &gl = m_context.getRenderContext().getFunctions();
2870 
2871     GetUniformIndices(gl, m_id, count, names, indices);
2872 }
2873 
2874 /** Get uniform location
2875  *
2876  * @param name Name of uniform
2877  *
2878  * @return Results of query
2879  **/
GetUniformLocation(const std::string & name) const2880 glw::GLint Program::GetUniformLocation(const std::string &name) const
2881 {
2882     const Functions &gl = m_context.getRenderContext().getFunctions();
2883 
2884     return GetUniformLocation(gl, m_id, name);
2885 }
2886 
2887 /** Set program as active
2888  *
2889  **/
Use() const2890 void Program::Use() const
2891 {
2892     const Functions &gl = m_context.getRenderContext().getFunctions();
2893 
2894     Use(gl, m_id);
2895 }
2896 
2897 /** Attach shader to program
2898  *
2899  * @param gl         GL functions
2900  * @param program_id Id of program
2901  * @param shader_id  Id of shader
2902  **/
Attach(const Functions & gl,GLuint program_id,GLuint shader_id)2903 void Program::Attach(const Functions &gl, GLuint program_id, GLuint shader_id)
2904 {
2905     /* Quick checks */
2906     if ((m_invalid_id == program_id) || (Shader::m_invalid_id == shader_id))
2907     {
2908         return;
2909     }
2910 
2911     gl.attachShader(program_id, shader_id);
2912     GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
2913 }
2914 
2915 /** Set up captured varyings
2916  *
2917  * @param gl                  GL functions
2918  * @param id                  Id of program
2919  * @param captured_varyings   Vector of varyings
2920  * @param capture_interleaved Selects if interleaved or separate mode should be used
2921  **/
Capture(const Functions & gl,GLuint id,const NameVector & captured_varyings,bool capture_interleaved)2922 void Program::Capture(const Functions &gl, GLuint id, const NameVector &captured_varyings, bool capture_interleaved)
2923 {
2924     const size_t n_varyings = captured_varyings.size();
2925 
2926     if (0 == n_varyings)
2927     {
2928         /* empty list, skip */
2929         return;
2930     }
2931 
2932     std::vector<const GLchar *> varying_names;
2933     varying_names.resize(n_varyings);
2934 
2935     for (size_t i = 0; i < n_varyings; ++i)
2936     {
2937         varying_names[i] = captured_varyings[i].c_str();
2938     }
2939 
2940     GLenum mode = 0;
2941     if (true == capture_interleaved)
2942     {
2943         mode = GL_INTERLEAVED_ATTRIBS;
2944     }
2945     else
2946     {
2947         mode = GL_SEPARATE_ATTRIBS;
2948     }
2949 
2950     gl.transformFeedbackVaryings(id, static_cast<GLsizei>(n_varyings), &varying_names[0], mode);
2951     GLU_EXPECT_NO_ERROR(gl.getError(), "TransformFeedbackVaryings");
2952 }
2953 
2954 /** Create program instance
2955  *
2956  * @param gl     GL functions
2957  * @param out_id Id of program
2958  **/
Create(const Functions & gl,GLuint & out_id)2959 void Program::Create(const Functions &gl, GLuint &out_id)
2960 {
2961     const GLuint id = gl.createProgram();
2962     GLU_EXPECT_NO_ERROR(gl.getError(), "CreateProgram");
2963 
2964     if (m_invalid_id == id)
2965     {
2966         TCU_FAIL("Failed to create program");
2967     }
2968 
2969     out_id = id;
2970 }
2971 
2972 /** Get <pname> for a set of active uniforms
2973  *
2974  * @param gl         Functions
2975  * @param program_id Id of program
2976  * @param count      Number of indices
2977  * @param indices    Indices of uniforms
2978  * @param pname      Queired pname
2979  * @param params     Array that will be filled with values of parameters
2980  **/
GetActiveUniformsiv(const Functions & gl,GLuint program_id,GLsizei count,const GLuint * indices,GLenum pname,GLint * params)2981 void Program::GetActiveUniformsiv(const Functions &gl, GLuint program_id, GLsizei count, const GLuint *indices,
2982                                   GLenum pname, GLint *params)
2983 {
2984     gl.getActiveUniformsiv(program_id, count, indices, pname, params);
2985     GLU_EXPECT_NO_ERROR(gl.getError(), "GetActiveUniformsiv");
2986 }
2987 
2988 /** Get indices for a set of uniforms
2989  *
2990  * @param gl         Functions
2991  * @param program_id Id of program
2992  * @param count      Count number of uniforms
2993  * @param names      Names of uniforms
2994  * @param indices    Buffer that will be filled with indices
2995  **/
GetUniformIndices(const Functions & gl,GLuint program_id,GLsizei count,const GLchar ** names,GLuint * indices)2996 void Program::GetUniformIndices(const Functions &gl, GLuint program_id, GLsizei count, const GLchar **names,
2997                                 GLuint *indices)
2998 {
2999     gl.getUniformIndices(program_id, count, names, indices);
3000     GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformIndices");
3001 }
3002 
3003 /** Link program
3004  *
3005  * @param gl GL functions
3006  * @param id Id of program
3007  **/
Link(const Functions & gl,GLuint id)3008 void Program::Link(const Functions &gl, GLuint id)
3009 {
3010     GLint status = GL_FALSE;
3011 
3012     gl.linkProgram(id);
3013     GLU_EXPECT_NO_ERROR(gl.getError(), "LinkProgram");
3014 
3015     /* Get link status */
3016     gl.getProgramiv(id, GL_LINK_STATUS, &status);
3017     GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");
3018 
3019     /* Log link error */
3020     if (GL_TRUE != status)
3021     {
3022         glw::GLint length = 0;
3023         std::string message;
3024 
3025         /* Get error log length */
3026         gl.getProgramiv(id, GL_INFO_LOG_LENGTH, &length);
3027         GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");
3028 
3029         message.resize(length, 0);
3030 
3031         /* Get error log */
3032         gl.getProgramInfoLog(id, length, 0, &message[0]);
3033         GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramInfoLog");
3034 
3035         throw LinkageException(message.c_str());
3036     }
3037 }
3038 
3039 /** Set generic uniform
3040  *
3041  * @param gl       Functions
3042  * @param type     Type of uniform
3043  * @param count    Length of array
3044  * @param location Location of uniform
3045  * @param data     Data that will be used
3046  **/
Uniform(const Functions & gl,const Type & type,GLsizei count,GLint location,const GLvoid * data)3047 void Program::Uniform(const Functions &gl, const Type &type, GLsizei count, GLint location, const GLvoid *data)
3048 {
3049     if (-1 == location)
3050     {
3051         TCU_FAIL("Uniform is inactive");
3052     }
3053 
3054     switch (type.m_basic_type)
3055     {
3056     case Type::Double:
3057         if (1 == type.m_n_columns)
3058         {
3059             getUniformNdv(gl, type.m_n_rows)(location, count, (const GLdouble *)data);
3060             GLU_EXPECT_NO_ERROR(gl.getError(), "UniformNdv");
3061         }
3062         else
3063         {
3064             getUniformMatrixNdv(gl, type.m_n_columns, type.m_n_rows)(location, count, false, (const GLdouble *)data);
3065             GLU_EXPECT_NO_ERROR(gl.getError(), "UniformMatrixNdv");
3066         }
3067         break;
3068     case Type::Float:
3069         if (1 == type.m_n_columns)
3070         {
3071             getUniformNfv(gl, type.m_n_rows)(location, count, (const GLfloat *)data);
3072             GLU_EXPECT_NO_ERROR(gl.getError(), "UniformNfv");
3073         }
3074         else
3075         {
3076             getUniformMatrixNfv(gl, type.m_n_columns, type.m_n_rows)(location, count, false, (const GLfloat *)data);
3077             GLU_EXPECT_NO_ERROR(gl.getError(), "UniformMatrixNfv");
3078         }
3079         break;
3080     case Type::Int:
3081         getUniformNiv(gl, type.m_n_rows)(location, count, (const GLint *)data);
3082         GLU_EXPECT_NO_ERROR(gl.getError(), "UniformNiv");
3083         break;
3084     case Type::Uint:
3085         getUniformNuiv(gl, type.m_n_rows)(location, count, (const GLuint *)data);
3086         GLU_EXPECT_NO_ERROR(gl.getError(), "UniformNuiv");
3087         break;
3088     default:
3089         TCU_FAIL("Invalid enum");
3090     }
3091 }
3092 
3093 /** Use program
3094  *
3095  * @param gl GL functions
3096  * @param id Id of program
3097  **/
Use(const Functions & gl,GLuint id)3098 void Program::Use(const Functions &gl, GLuint id)
3099 {
3100     gl.useProgram(id);
3101     GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram");
3102 }
3103 
3104 /** Get location of attribute
3105  *
3106  * @param gl   GL functions
3107  * @param id   Id of program
3108  * @param name Name of attribute
3109  *
3110  * @return Location of attribute
3111  **/
GetAttribLocation(const Functions & gl,GLuint id,const std::string & name)3112 GLint Program::GetAttribLocation(const Functions &gl, GLuint id, const std::string &name)
3113 {
3114     GLint location = gl.getAttribLocation(id, name.c_str());
3115     GLU_EXPECT_NO_ERROR(gl.getError(), "GetAttribLocation");
3116 
3117     return location;
3118 }
3119 
3120 /** Query resource
3121  *
3122  * @param gl        GL functions
3123  * @param id        Id of program
3124  * @param interface Interface to be queried
3125  * @param index     Index of resource
3126  * @param property  Property to be queried
3127  * @param buf_size  Size of <params> buffer
3128  * @param params    Results of query
3129  **/
GetResource(const Functions & gl,GLuint id,GLenum interface,GLuint index,GLenum property,GLsizei buf_size,GLint * params)3130 void Program::GetResource(const Functions &gl, GLuint id, GLenum interface, GLuint index, GLenum property,
3131                           GLsizei buf_size, GLint *params)
3132 {
3133     gl.getProgramResourceiv(id, interface, index, 1 /* propCount */, &property, buf_size /* bufSize */, 0 /* length */,
3134                             params);
3135     GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramResourceiv");
3136 }
3137 
3138 /** Get index of resource
3139  *
3140  * @param gl        GL functions
3141  * @param id        Id of program
3142  * @param name      Name of resource
3143  * @param interface Program interface to queried
3144  *
3145  * @return Location of attribute
3146  **/
GetResourceIndex(const Functions & gl,GLuint id,const std::string & name,GLenum interface)3147 GLuint Program::GetResourceIndex(const Functions &gl, GLuint id, const std::string &name, GLenum interface)
3148 {
3149     GLuint index = gl.getProgramResourceIndex(id, interface, name.c_str());
3150     GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramResourceIndex");
3151 
3152     return index;
3153 }
3154 
3155 /** Get location of attribute
3156  *
3157  * @param gl   GL functions
3158  * @param id   Id of program
3159  * @param name Name of attribute
3160  *
3161  * @return Location of uniform
3162  **/
GetUniformLocation(const Functions & gl,GLuint id,const std::string & name)3163 GLint Program::GetUniformLocation(const Functions &gl, GLuint id, const std::string &name)
3164 {
3165     GLint location = gl.getUniformLocation(id, name.c_str());
3166     GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformLocation");
3167 
3168     return location;
3169 }
3170 
3171 /** Constructor
3172  *
3173  * @param error_message    Error message
3174  * @param compute_shader   Source code for compute stage
3175  * @param fragment_shader  Source code for fragment stage
3176  * @param geometry_shader  Source code for geometry stage
3177  * @param tess_ctrl_shader Source code for tessellation control stage
3178  * @param tess_eval_shader Source code for tessellation evaluation stage
3179  * @param vertex_shader    Source code for vertex stage
3180  **/
BuildException(const glw::GLchar * error_message,const std::string compute_shader,const std::string fragment_shader,const std::string geometry_shader,const std::string tess_ctrl_shader,const std::string tess_eval_shader,const std::string vertex_shader)3181 Program::BuildException::BuildException(const glw::GLchar *error_message, const std::string compute_shader,
3182                                         const std::string fragment_shader, const std::string geometry_shader,
3183                                         const std::string tess_ctrl_shader, const std::string tess_eval_shader,
3184                                         const std::string vertex_shader)
3185     : m_error_message(error_message)
3186     , m_compute_shader(compute_shader)
3187     , m_fragment_shader(fragment_shader)
3188     , m_geometry_shader(geometry_shader)
3189     , m_tess_ctrl_shader(tess_ctrl_shader)
3190     , m_tess_eval_shader(tess_eval_shader)
3191     , m_vertex_shader(vertex_shader)
3192 {
3193 }
3194 
3195 /** Overwrites std::exception::what method
3196  *
3197  * @return Message compossed from error message and shader sources
3198  **/
what() const3199 const char *Program::BuildException::what() const throw()
3200 {
3201     return "Failed to link program";
3202 }
3203 
3204 /** Logs error message and shader sources **/
log(deqp::Context & context) const3205 void Program::BuildException::log(deqp::Context &context) const
3206 {
3207     context.getTestContext().getLog() << tcu::TestLog::Message << "Link failure: " << m_error_message
3208                                       << tcu::TestLog::EndMessage;
3209 
3210     Shader::LogSource(context, m_vertex_shader, Shader::VERTEX);
3211     Shader::LogSource(context, m_tess_ctrl_shader, Shader::TESS_CTRL);
3212     Shader::LogSource(context, m_tess_eval_shader, Shader::TESS_EVAL);
3213     Shader::LogSource(context, m_geometry_shader, Shader::GEOMETRY);
3214     Shader::LogSource(context, m_fragment_shader, Shader::FRAGMENT);
3215     Shader::LogSource(context, m_compute_shader, Shader::COMPUTE);
3216 }
3217 
3218 /** Constructor
3219  *
3220  * @param message Linking error message
3221  **/
LinkageException(const glw::GLchar * message)3222 Program::LinkageException::LinkageException(const glw::GLchar *message) : m_error_message(message)
3223 {
3224     /* Nothing to be done */
3225 }
3226 
3227 /** Returns error messages
3228  *
3229  * @return Linking error message
3230  **/
what() const3231 const char *Program::LinkageException::what() const throw()
3232 {
3233     return m_error_message.c_str();
3234 }
3235 
3236 /* Texture constants */
3237 const GLuint Texture::m_invalid_id = -1;
3238 
3239 /** Constructor.
3240  *
3241  * @param context CTS context.
3242  **/
Texture(deqp::Context & context)3243 Texture::Texture(deqp::Context &context) : m_id(m_invalid_id), m_context(context), m_type(TEX_2D)
3244 {
3245     /* Nothing to done here */
3246 }
3247 
3248 /** Destructor
3249  *
3250  **/
~Texture()3251 Texture::~Texture()
3252 {
3253     Release();
3254 }
3255 
3256 /** Initialize texture instance
3257  *
3258  * @param tex_type        Type of texture
3259  * @param width           Width of texture
3260  * @param height          Height of texture
3261  * @param depth           Depth of texture
3262  * @param internal_format Internal format of texture
3263  * @param format          Format of texture data
3264  * @param type            Type of texture data
3265  * @param data            Texture data
3266  **/
Init(TYPES tex_type,GLuint width,GLuint height,GLuint depth,GLenum internal_format,GLenum format,GLenum type,GLvoid * data)3267 void Texture::Init(TYPES tex_type, GLuint width, GLuint height, GLuint depth, GLenum internal_format, GLenum format,
3268                    GLenum type, GLvoid *data)
3269 {
3270     const Functions &gl = m_context.getRenderContext().getFunctions();
3271 
3272     /* Delete previous texture */
3273     Release();
3274 
3275     m_type = tex_type;
3276 
3277     /* Generate, bind, allocate storage and upload data */
3278     Generate(gl, m_id);
3279     Bind(gl, m_id, tex_type);
3280     Storage(gl, tex_type, width, height, depth, internal_format);
3281     Update(gl, tex_type, width, height, depth, format, type, data);
3282 }
3283 
3284 /** Initialize buffer texture
3285  *
3286  * @param internal_format Internal format of texture
3287  * @param buffer_id       Id of buffer that will be used as data source
3288  **/
Init(GLenum internal_format,GLuint buffer_id)3289 void Texture::Init(GLenum internal_format, GLuint buffer_id)
3290 {
3291     const Functions &gl = m_context.getRenderContext().getFunctions();
3292 
3293     /* Delete previous texture */
3294     Release();
3295 
3296     m_type = TEX_BUFFER;
3297 
3298     /* Generate, bind and attach buffer */
3299     Generate(gl, m_id);
3300     Bind(gl, m_id, TEX_BUFFER);
3301     TexBuffer(gl, buffer_id, internal_format);
3302 }
3303 
3304 /** Release texture instance
3305  *
3306  **/
Release()3307 void Texture::Release()
3308 {
3309     if (m_invalid_id != m_id)
3310     {
3311         const Functions &gl = m_context.getRenderContext().getFunctions();
3312 
3313         gl.deleteTextures(1, &m_id);
3314         m_id = m_invalid_id;
3315     }
3316 }
3317 
3318 /** Bind texture to its target
3319  *
3320  **/
Bind() const3321 void Texture::Bind() const
3322 {
3323     const Functions &gl = m_context.getRenderContext().getFunctions();
3324 
3325     Bind(gl, m_id, m_type);
3326 }
3327 
3328 /** Get texture data
3329  *
3330  * @param format   Format of data
3331  * @param type     Type of data
3332  * @param out_data Buffer for data
3333  **/
Get(GLenum format,GLenum type,GLvoid * out_data) const3334 void Texture::Get(GLenum format, GLenum type, GLvoid *out_data) const
3335 {
3336     const Functions &gl = m_context.getRenderContext().getFunctions();
3337 
3338     Bind(gl, m_id, m_type);
3339     Get(gl, m_type, format, type, out_data);
3340 }
3341 
3342 /** Bind texture to target
3343  *
3344  * @param gl       GL functions
3345  * @param id       Id of texture
3346  * @param tex_type Type of texture
3347  **/
Bind(const Functions & gl,GLuint id,TYPES tex_type)3348 void Texture::Bind(const Functions &gl, GLuint id, TYPES tex_type)
3349 {
3350     GLenum target = GetTargetGLenum(tex_type);
3351 
3352     gl.bindTexture(target, id);
3353     GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
3354 }
3355 
3356 /** Generate texture instance
3357  *
3358  * @param gl     GL functions
3359  * @param out_id Id of texture
3360  **/
Generate(const Functions & gl,GLuint & out_id)3361 void Texture::Generate(const Functions &gl, GLuint &out_id)
3362 {
3363     GLuint id = m_invalid_id;
3364 
3365     gl.genTextures(1, &id);
3366     GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures");
3367 
3368     if (m_invalid_id == id)
3369     {
3370         TCU_FAIL("Invalid id");
3371     }
3372 
3373     out_id = id;
3374 }
3375 
3376 /** Get texture data
3377  *
3378  * @param gl       GL functions
3379  * @param format   Format of data
3380  * @param type     Type of data
3381  * @param out_data Buffer for data
3382  **/
Get(const Functions & gl,TYPES tex_type,GLenum format,GLenum type,GLvoid * out_data)3383 void Texture::Get(const Functions &gl, TYPES tex_type, GLenum format, GLenum type, GLvoid *out_data)
3384 {
3385     GLenum target = GetTargetGLenum(tex_type);
3386 
3387     if (TEX_CUBE != tex_type)
3388     {
3389         gl.getTexImage(target, 0 /* level */, format, type, out_data);
3390         GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexImage");
3391     }
3392     else
3393     {
3394         GLint width;
3395         GLint height;
3396 
3397         if ((GL_RGBA != format) && (GL_UNSIGNED_BYTE != type))
3398         {
3399             TCU_FAIL("Not implemented");
3400         }
3401 
3402         GLuint texel_size = 4;
3403 
3404         gl.getTexLevelParameteriv(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0 /* level */, GL_TEXTURE_WIDTH, &width);
3405         GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv");
3406 
3407         gl.getTexLevelParameteriv(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0 /* level */, GL_TEXTURE_HEIGHT, &height);
3408         GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv");
3409 
3410         const GLuint image_size = width * height * texel_size;
3411 
3412         gl.getTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0 /* level */, format, type,
3413                        (GLvoid *)((GLchar *)out_data + (image_size * 0)));
3414         gl.getTexImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0 /* level */, format, type,
3415                        (GLvoid *)((GLchar *)out_data + (image_size * 1)));
3416         gl.getTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0 /* level */, format, type,
3417                        (GLvoid *)((GLchar *)out_data + (image_size * 2)));
3418         gl.getTexImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0 /* level */, format, type,
3419                        (GLvoid *)((GLchar *)out_data + (image_size * 3)));
3420         gl.getTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0 /* level */, format, type,
3421                        (GLvoid *)((GLchar *)out_data + (image_size * 4)));
3422         gl.getTexImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0 /* level */, format, type,
3423                        (GLvoid *)((GLchar *)out_data + (image_size * 5)));
3424         GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexImage");
3425     }
3426 }
3427 
3428 /** Allocate storage for texture
3429  *
3430  * @param gl              GL functions
3431  * @param tex_type        Type of texture
3432  * @param width           Width of texture
3433  * @param height          Height of texture
3434  * @param depth           Depth of texture
3435  * @param internal_format Internal format of texture
3436  **/
Storage(const Functions & gl,TYPES tex_type,GLuint width,GLuint height,GLuint depth,GLenum internal_format)3437 void Texture::Storage(const Functions &gl, TYPES tex_type, GLuint width, GLuint height, GLuint depth,
3438                       GLenum internal_format)
3439 {
3440     static const GLuint levels = 1;
3441 
3442     GLenum target = GetTargetGLenum(tex_type);
3443 
3444     switch (tex_type)
3445     {
3446     case TEX_1D:
3447         gl.texStorage1D(target, levels, internal_format, width);
3448         GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage1D");
3449         break;
3450     case TEX_2D:
3451     case TEX_1D_ARRAY:
3452     case TEX_2D_RECT:
3453     case TEX_CUBE:
3454         gl.texStorage2D(target, levels, internal_format, width, height);
3455         GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2D");
3456         break;
3457     case TEX_3D:
3458     case TEX_2D_ARRAY:
3459         gl.texStorage3D(target, levels, internal_format, width, height, depth);
3460         GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage3D");
3461         break;
3462     default:
3463         TCU_FAIL("Invalid enum");
3464     }
3465 }
3466 
3467 /** Attach buffer as source of texture buffer data
3468  *
3469  * @param gl              GL functions
3470  * @param internal_format Internal format of texture
3471  * @param buffer_id       Id of buffer that will be used as data source
3472  **/
TexBuffer(const Functions & gl,GLenum internal_format,GLuint & buffer_id)3473 void Texture::TexBuffer(const Functions &gl, GLenum internal_format, GLuint &buffer_id)
3474 {
3475     gl.texBuffer(GL_TEXTURE_BUFFER, internal_format, buffer_id);
3476     GLU_EXPECT_NO_ERROR(gl.getError(), "TexBuffer");
3477 }
3478 
3479 /** Update contents of texture
3480  *
3481  * @param gl       GL functions
3482  * @param tex_type Type of texture
3483  * @param width    Width of texture
3484  * @param height   Height of texture
3485  * @param format   Format of data
3486  * @param type     Type of data
3487  * @param data     Buffer with image data
3488  **/
Update(const Functions & gl,TYPES tex_type,GLuint width,GLuint height,GLuint depth,GLenum format,GLenum type,GLvoid * data)3489 void Texture::Update(const Functions &gl, TYPES tex_type, GLuint width, GLuint height, GLuint depth, GLenum format,
3490                      GLenum type, GLvoid *data)
3491 {
3492     static const GLuint level = 0;
3493 
3494     GLenum target = GetTargetGLenum(tex_type);
3495 
3496     switch (tex_type)
3497     {
3498     case TEX_1D:
3499         gl.texSubImage1D(target, level, 0 /* x */, width, format, type, data);
3500         GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage1D");
3501         break;
3502     case TEX_2D:
3503     case TEX_1D_ARRAY:
3504     case TEX_2D_RECT:
3505         gl.texSubImage2D(target, level, 0 /* x */, 0 /* y */, width, height, format, type, data);
3506         GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2D");
3507         break;
3508     case TEX_CUBE:
3509         gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, level, 0 /* x */, 0 /* y */, width, height, format, type,
3510                          data);
3511         gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, level, 0 /* x */, 0 /* y */, width, height, format, type,
3512                          data);
3513         gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, level, 0 /* x */, 0 /* y */, width, height, format, type,
3514                          data);
3515         gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, level, 0 /* x */, 0 /* y */, width, height, format, type,
3516                          data);
3517         gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, level, 0 /* x */, 0 /* y */, width, height, format, type,
3518                          data);
3519         gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, level, 0 /* x */, 0 /* y */, width, height, format, type,
3520                          data);
3521         GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2D");
3522         break;
3523     case TEX_3D:
3524     case TEX_2D_ARRAY:
3525         gl.texSubImage3D(target, level, 0 /* x */, 0 /* y */, 0 /* z */, width, height, depth, format, type, data);
3526         GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage3D");
3527         break;
3528     default:
3529         TCU_FAIL("Invalid enum");
3530     }
3531 }
3532 
3533 /** Get target for given texture type
3534  *
3535  * @param type Type of texture
3536  *
3537  * @return Target
3538  **/
GetTargetGLenum(TYPES type)3539 GLenum Texture::GetTargetGLenum(TYPES type)
3540 {
3541     GLenum result = 0;
3542 
3543     switch (type)
3544     {
3545     case TEX_BUFFER:
3546         result = GL_TEXTURE_BUFFER;
3547         break;
3548     case TEX_2D:
3549         result = GL_TEXTURE_2D;
3550         break;
3551     case TEX_2D_RECT:
3552         result = GL_TEXTURE_RECTANGLE;
3553         break;
3554     case TEX_2D_ARRAY:
3555         result = GL_TEXTURE_2D_ARRAY;
3556         break;
3557     case TEX_3D:
3558         result = GL_TEXTURE_3D;
3559         break;
3560     case TEX_CUBE:
3561         result = GL_TEXTURE_CUBE_MAP;
3562         break;
3563     case TEX_1D:
3564         result = GL_TEXTURE_1D;
3565         break;
3566     case TEX_1D_ARRAY:
3567         result = GL_TEXTURE_1D_ARRAY;
3568         break;
3569     }
3570 
3571     return result;
3572 }
3573 
3574 /* VertexArray constants */
3575 const GLuint VertexArray::m_invalid_id = -1;
3576 
3577 /** Constructor.
3578  *
3579  * @param context CTS context.
3580  **/
VertexArray(deqp::Context & context)3581 VertexArray::VertexArray(deqp::Context &context) : m_id(m_invalid_id), m_context(context)
3582 {
3583 }
3584 
3585 /** Destructor
3586  *
3587  **/
~VertexArray()3588 VertexArray::~VertexArray()
3589 {
3590     Release();
3591 }
3592 
3593 /** Initialize vertex array instance
3594  *
3595  **/
Init()3596 void VertexArray::Init()
3597 {
3598     /* Delete previous instance */
3599     Release();
3600 
3601     const Functions &gl = m_context.getRenderContext().getFunctions();
3602 
3603     Generate(gl, m_id);
3604 }
3605 
3606 /** Release vertex array object instance
3607  *
3608  **/
Release()3609 void VertexArray::Release()
3610 {
3611     if (m_invalid_id != m_id)
3612     {
3613         const Functions &gl = m_context.getRenderContext().getFunctions();
3614 
3615         gl.deleteVertexArrays(1, &m_id);
3616 
3617         m_id = m_invalid_id;
3618     }
3619 }
3620 
3621 /** Set attribute in VAO
3622  *
3623  * @param index            Index of attribute
3624  * @param type             Type of attribute
3625  * @param n_array_elements Arary length
3626  * @param normalized       Selects if values should be normalized
3627  * @param stride           Stride
3628  * @param pointer          Pointer to data, or offset in buffer
3629  **/
Attribute(GLuint index,const Type & type,GLuint n_array_elements,GLboolean normalized,GLsizei stride,const GLvoid * pointer)3630 void VertexArray::Attribute(GLuint index, const Type &type, GLuint n_array_elements, GLboolean normalized,
3631                             GLsizei stride, const GLvoid *pointer)
3632 {
3633     const Functions &gl = m_context.getRenderContext().getFunctions();
3634 
3635     AttribPointer(gl, index, type, n_array_elements, normalized, stride, pointer);
3636     Enable(gl, index, type, n_array_elements);
3637 }
3638 
3639 /** Binds Vertex array object
3640  *
3641  **/
Bind()3642 void VertexArray::Bind()
3643 {
3644     const Functions &gl = m_context.getRenderContext().getFunctions();
3645 
3646     Bind(gl, m_id);
3647 }
3648 
3649 /** Set attribute in VAO
3650  *
3651  * @param gl               Functions
3652  * @param index            Index of attribute
3653  * @param type             Type of attribute
3654  * @param n_array_elements Arary length
3655  * @param normalized       Selects if values should be normalized
3656  * @param stride           Stride
3657  * @param pointer          Pointer to data, or offset in buffer
3658  **/
AttribPointer(const Functions & gl,GLuint index,const Type & type,GLuint n_array_elements,GLboolean normalized,GLsizei stride,const GLvoid * pointer)3659 void VertexArray::AttribPointer(const Functions &gl, GLuint index, const Type &type, GLuint n_array_elements,
3660                                 GLboolean normalized, GLsizei stride, const GLvoid *pointer)
3661 {
3662     const GLuint basic_type_size = Type::GetTypeSize(type.m_basic_type);
3663     const GLint size             = (GLint)type.m_n_rows;
3664     const GLuint column_size     = (GLuint)size * basic_type_size;
3665     const GLenum gl_type         = Type::GetTypeGLenum(type.m_basic_type);
3666 
3667     GLuint offset = 0;
3668 
3669     /* If attribute is not an array */
3670     if (0 == n_array_elements)
3671     {
3672         n_array_elements = 1;
3673     }
3674 
3675     /* For each element in array */
3676     for (GLuint element = 0; element < n_array_elements; ++element)
3677     {
3678         /* For each column in matrix */
3679         for (GLuint column = 1; column <= type.m_n_columns; ++column)
3680         {
3681             /* Calculate offset */
3682             const GLvoid *ptr = (GLubyte *)pointer + offset;
3683 
3684             /* Set up attribute */
3685             switch (type.m_basic_type)
3686             {
3687             case Type::Float:
3688                 gl.vertexAttribPointer(index, size, gl_type, normalized, stride, ptr);
3689                 GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttribPointer");
3690                 break;
3691             case Type::Int:
3692             case Type::Uint:
3693                 gl.vertexAttribIPointer(index, size, gl_type, stride, ptr);
3694                 GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttribIPointer");
3695                 break;
3696             case Type::Double:
3697                 gl.vertexAttribLPointer(index, size, gl_type, stride, ptr);
3698                 GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttribLPointer");
3699                 break;
3700             default:
3701                 TCU_FAIL("Invalid enum");
3702             }
3703 
3704             /* Next location */
3705             offset += column_size;
3706             index += 1;
3707         }
3708     }
3709 }
3710 
3711 /** Binds Vertex array object
3712  *
3713  * @param gl GL functions
3714  * @param id ID of vertex array object
3715  **/
Bind(const glw::Functions & gl,glw::GLuint id)3716 void VertexArray::Bind(const glw::Functions &gl, glw::GLuint id)
3717 {
3718     gl.bindVertexArray(id);
3719     GLU_EXPECT_NO_ERROR(gl.getError(), "BindVertexArray");
3720 }
3721 
3722 /** Disable attribute in VAO
3723  *
3724  * @param gl               Functions
3725  * @param index            Index of attribute
3726  * @param type             Type of attribute
3727  * @param n_array_elements Arary length
3728  **/
Disable(const Functions & gl,GLuint index,const Type & type,GLuint n_array_elements)3729 void VertexArray::Disable(const Functions &gl, GLuint index, const Type &type, GLuint n_array_elements)
3730 {
3731     /* If attribute is not an array */
3732     if (0 == n_array_elements)
3733     {
3734         n_array_elements = 1;
3735     }
3736 
3737     /* For each element in array */
3738     for (GLuint element = 0; element < n_array_elements; ++element)
3739     {
3740         /* For each column in matrix */
3741         for (GLuint column = 1; column <= type.m_n_columns; ++column)
3742         {
3743             /* Enable attribute array */
3744             gl.disableVertexAttribArray(index);
3745             GLU_EXPECT_NO_ERROR(gl.getError(), "DisableVertexAttribArray");
3746 
3747             /* Next location */
3748             index += 1;
3749         }
3750     }
3751 }
3752 
3753 /** Set divisor for attribute
3754  *
3755  * @param gl               Functions
3756  * @param index            Index of attribute
3757  * @param divisor          New divisor value
3758  **/
Divisor(const Functions & gl,GLuint index,GLuint divisor)3759 void VertexArray::Divisor(const Functions &gl, GLuint index, GLuint divisor)
3760 {
3761     gl.vertexAttribDivisor(index, divisor);
3762     GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttribDivisor");
3763 }
3764 
3765 /** Enables attribute in VAO
3766  *
3767  * @param gl               Functions
3768  * @param index            Index of attribute
3769  * @param type             Type of attribute
3770  * @param n_array_elements Arary length
3771  **/
Enable(const Functions & gl,GLuint index,const Type & type,GLuint n_array_elements)3772 void VertexArray::Enable(const Functions &gl, GLuint index, const Type &type, GLuint n_array_elements)
3773 {
3774     /* If attribute is not an array */
3775     if (0 == n_array_elements)
3776     {
3777         n_array_elements = 1;
3778     }
3779 
3780     /* For each element in array */
3781     for (GLuint element = 0; element < n_array_elements; ++element)
3782     {
3783         /* For each column in matrix */
3784         for (GLuint column = 1; column <= type.m_n_columns; ++column)
3785         {
3786             /* Enable attribute array */
3787             gl.enableVertexAttribArray(index);
3788             GLU_EXPECT_NO_ERROR(gl.getError(), "EnableVertexAttribArray");
3789 
3790             /* Next location */
3791             index += 1;
3792         }
3793     }
3794 }
3795 
3796 /** Generates Vertex array object
3797  *
3798  * @param gl     GL functions
3799  * @param out_id ID of vertex array object
3800  **/
Generate(const glw::Functions & gl,glw::GLuint & out_id)3801 void VertexArray::Generate(const glw::Functions &gl, glw::GLuint &out_id)
3802 {
3803     GLuint id = m_invalid_id;
3804 
3805     gl.genVertexArrays(1, &id);
3806     GLU_EXPECT_NO_ERROR(gl.getError(), "GenVertexArrays");
3807 
3808     if (m_invalid_id == id)
3809     {
3810         TCU_FAIL("Invalid id");
3811     }
3812 
3813     out_id = id;
3814 }
3815 
3816 /* Constatns used by Variable */
3817 const GLint Variable::m_automatic_location = -1;
3818 
3819 /** Copy constructor
3820  *
3821  **/
Variable(const Variable & var)3822 Variable::Variable(const Variable &var)
3823     : m_data(var.m_data)
3824     , m_data_size(var.m_data_size)
3825     , m_descriptor(var.m_descriptor.m_name.c_str(), var.m_descriptor.m_qualifiers.c_str(),
3826                    var.m_descriptor.m_expected_component, var.m_descriptor.m_expected_location,
3827                    var.m_descriptor.m_builtin, var.m_descriptor.m_normalized, var.m_descriptor.m_n_array_elements,
3828                    var.m_descriptor.m_expected_stride_of_element, var.m_descriptor.m_offset)
3829     , m_storage(var.m_storage)
3830 {
3831     m_descriptor.m_type = var.m_descriptor.m_type;
3832 
3833     if (BUILTIN != var.m_descriptor.m_type)
3834     {
3835         m_descriptor.m_interface = var.m_descriptor.m_interface;
3836     }
3837 }
3838 
3839 /** Get code that defines variable
3840  *
3841  * @param flavour Provides info if variable is array or not
3842  *
3843  * @return String with code
3844  **/
GetDefinition(FLAVOUR flavour) const3845 std::string Variable::GetDefinition(FLAVOUR flavour) const
3846 {
3847     return m_descriptor.GetDefinition(flavour, m_storage);
3848 }
3849 
3850 /** Calcualtes stride of variable
3851  *
3852  * @return Calculated value
3853  **/
GetStride() const3854 GLuint Variable::GetStride() const
3855 {
3856     GLint variable_stride = 0;
3857 
3858     if (0 == m_descriptor.m_n_array_elements)
3859     {
3860         variable_stride = m_descriptor.m_expected_stride_of_element;
3861     }
3862     else
3863     {
3864         variable_stride = m_descriptor.m_expected_stride_of_element * m_descriptor.m_n_array_elements;
3865     }
3866 
3867     return variable_stride;
3868 }
3869 
3870 /** Check if variable is block
3871  *
3872  * @return true if variable type is block, false otherwise
3873  **/
IsBlock() const3874 bool Variable::IsBlock() const
3875 {
3876     if (BUILTIN == m_descriptor.m_type)
3877     {
3878         return false;
3879     }
3880 
3881     const Interface *interface = m_descriptor.m_interface;
3882     if (0 == interface)
3883     {
3884         TCU_FAIL("Nullptr");
3885     }
3886 
3887     return (Interface::BLOCK == interface->m_type);
3888 }
3889 
3890 /** Check if variable is struct
3891  *
3892  * @return true if variable type is struct, false otherwise
3893  **/
IsStruct() const3894 bool Variable::IsStruct() const
3895 {
3896     if (BUILTIN == m_descriptor.m_type)
3897     {
3898         return false;
3899     }
3900 
3901     const Interface *interface = m_descriptor.m_interface;
3902     if (0 == interface)
3903     {
3904         TCU_FAIL("Nullptr");
3905     }
3906 
3907     return (Interface::STRUCT == interface->m_type);
3908 }
3909 /** Get code that reference variable
3910  *
3911  * @param parent_name Name of parent
3912  * @param variable    Descriptor of variable
3913  * @param flavour     Provides info about how variable should be referenced
3914  * @param array_index Index of array, ignored when variable is not array
3915  *
3916  * @return String with code
3917  **/
GetReference(const std::string & parent_name,const Descriptor & variable,FLAVOUR flavour,GLuint array_index)3918 std::string Variable::GetReference(const std::string &parent_name, const Descriptor &variable, FLAVOUR flavour,
3919                                    GLuint array_index)
3920 {
3921     std::string name;
3922 
3923     /* Prepare name */
3924     if (false == parent_name.empty())
3925     {
3926         name = parent_name;
3927         name.append(".");
3928         name.append(variable.m_name);
3929     }
3930     else
3931     {
3932         name = variable.m_name;
3933     }
3934 
3935     /* */
3936     switch (flavour)
3937     {
3938     case Utils::Variable::BASIC:
3939         break;
3940 
3941     case Utils::Variable::ARRAY:
3942         name.append("[0]");
3943         break;
3944 
3945     case Utils::Variable::INDEXED_BY_INVOCATION_ID:
3946         name.append("[gl_InvocationID]");
3947         break;
3948     }
3949 
3950     /* Assumption that both variables have same lengths */
3951     if (0 != variable.m_n_array_elements)
3952     {
3953         GLchar buffer[16];
3954         sprintf(buffer, "%d", array_index);
3955         name.append("[");
3956         name.append(buffer);
3957         name.append("]");
3958     }
3959 
3960     return name;
3961 }
3962 
3963 /** Get "flavour" of varying
3964  *
3965  * @param stage     Stage of shader
3966  * @param direction Selects if varying is in or out
3967  *
3968  * @return Flavour
3969  **/
GetFlavour(Shader::STAGES stage,VARYING_DIRECTION direction)3970 Variable::FLAVOUR Variable::GetFlavour(Shader::STAGES stage, VARYING_DIRECTION direction)
3971 {
3972     FLAVOUR result = BASIC;
3973 
3974     switch (stage)
3975     {
3976     case Shader::GEOMETRY:
3977     case Shader::TESS_EVAL:
3978         if (INPUT == direction)
3979         {
3980             result = ARRAY;
3981         }
3982         break;
3983     case Shader::TESS_CTRL:
3984         result = INDEXED_BY_INVOCATION_ID;
3985         break;
3986     default:
3987         break;
3988     }
3989 
3990     return result;
3991 }
3992 
3993 /** Constructor, for built-in types
3994  *
3995  * @param name                       Name
3996  * @param qualifiers                 Qualifiers
3997  * @param expected_component         Expected component of variable
3998  * @param expected_location          Expected location
3999  * @param type                       Type
4000  * @param normalized                 Selects if data should be normalized
4001  * @param n_array_elements           Length of array
4002  * @param expected_stride_of_element Expected stride of element
4003  * @param offset                     Offset
4004  **/
Descriptor(const GLchar * name,const GLchar * qualifiers,GLint expected_component,GLint expected_location,const Type & type,GLboolean normalized,GLuint n_array_elements,GLint expected_stride_of_element,GLuint offset)4005 Variable::Descriptor::Descriptor(const GLchar *name, const GLchar *qualifiers, GLint expected_component,
4006                                  GLint expected_location, const Type &type, GLboolean normalized,
4007                                  GLuint n_array_elements, GLint expected_stride_of_element, GLuint offset)
4008     : m_expected_component(expected_component)
4009     , m_expected_location(expected_location)
4010     , m_expected_stride_of_element(expected_stride_of_element)
4011     , m_n_array_elements(n_array_elements)
4012     , m_name(name)
4013     , m_normalized(normalized)
4014     , m_offset(offset)
4015     , m_qualifiers(qualifiers)
4016     , m_type(BUILTIN)
4017     , m_builtin(type)
4018 {
4019 }
4020 
4021 /** Constructor, for interface types
4022  *
4023  * @param name                       Name
4024  * @param qualifiers                 Qualifiers
4025  * @param expected_component         Expected component of variable
4026  * @param expected_location          Expected location
4027  * @param interface                  Interface of variable
4028  * @param n_array_elements           Length of array
4029  * @param expected_stride_of_element Expected stride of element
4030  * @param offset                     Offset
4031  **/
Descriptor(const GLchar * name,const GLchar * qualifiers,GLint expected_componenet,GLint expected_location,Interface * interface,GLuint n_array_elements,GLint expected_stride_of_element,GLuint offset)4032 Variable::Descriptor::Descriptor(const GLchar *name, const GLchar *qualifiers, GLint expected_componenet,
4033                                  GLint expected_location, Interface *interface, GLuint n_array_elements,
4034                                  GLint expected_stride_of_element, GLuint offset)
4035     : m_expected_component(expected_componenet)
4036     , m_expected_location(expected_location)
4037     , m_expected_stride_of_element(expected_stride_of_element)
4038     , m_n_array_elements(n_array_elements)
4039     , m_name(name)
4040     , m_normalized(GL_FALSE)
4041     , m_offset(offset)
4042     , m_qualifiers(qualifiers)
4043     , m_type(INTERFACE)
4044     , m_interface(interface)
4045 {
4046 }
4047 
4048 /** Get definition of variable
4049  *
4050  * @param flavour Flavour of variable
4051  * @param storage Storage used for variable
4052  *
4053  * @return code with defintion
4054  **/
GetDefinition(FLAVOUR flavour,STORAGE storage) const4055 std::string Variable::Descriptor::GetDefinition(FLAVOUR flavour, STORAGE storage) const
4056 {
4057     static const GLchar *basic_template = "QUALIFIERS STORAGETYPE NAMEARRAY;";
4058     static const GLchar *array_template = "QUALIFIERS STORAGETYPE NAME[]ARRAY;";
4059     const GLchar *storage_str           = 0;
4060 
4061     std::string definition;
4062     size_t position = 0;
4063 
4064     /* Select definition template */
4065     switch (flavour)
4066     {
4067     case BASIC:
4068         definition = basic_template;
4069         break;
4070     case ARRAY:
4071     case INDEXED_BY_INVOCATION_ID:
4072         definition = array_template;
4073         break;
4074     default:
4075         TCU_FAIL("Invalid enum");
4076     }
4077 
4078     if (BUILTIN != m_type)
4079     {
4080         if (0 == m_interface)
4081         {
4082             TCU_FAIL("Nullptr");
4083         }
4084     }
4085 
4086     /* Qualifiers */
4087     if (true == m_qualifiers.empty())
4088     {
4089         replaceToken("QUALIFIERS ", position, "", definition);
4090     }
4091     else
4092     {
4093         replaceToken("QUALIFIERS", position, m_qualifiers.c_str(), definition);
4094     }
4095 
4096     // According to spec: int, uint, and double type must always be declared with flat qualifier
4097     bool flat_qualifier = false;
4098     if (m_type != BUILTIN && m_interface != NULL)
4099     {
4100         if (m_interface->m_members[0].m_builtin.m_basic_type == Utils::Type::Int ||
4101             m_interface->m_members[0].m_builtin.m_basic_type == Utils::Type::Uint ||
4102             m_interface->m_members[0].m_builtin.m_basic_type == Utils::Type::Double)
4103         {
4104             flat_qualifier = true;
4105         }
4106     }
4107     /* Storage */
4108     switch (storage)
4109     {
4110     case VARYING_INPUT:
4111         storage_str = flat_qualifier ? "flat in " : "in ";
4112         break;
4113     case VARYING_OUTPUT:
4114         storage_str = "out ";
4115         break;
4116     case UNIFORM:
4117         storage_str = "uniform ";
4118         break;
4119     case SSB:
4120         storage_str = "buffer ";
4121         break;
4122     case MEMBER:
4123         storage_str = "";
4124         break;
4125     default:
4126         TCU_FAIL("Invalid enum");
4127     }
4128 
4129     replaceToken("STORAGE", position, storage_str, definition);
4130 
4131     /* Type */
4132     if (BUILTIN == m_type)
4133     {
4134         replaceToken("TYPE", position, m_builtin.GetGLSLTypeName(), definition);
4135     }
4136     else
4137     {
4138         if (Interface::STRUCT == m_interface->m_type)
4139         {
4140             replaceToken("TYPE", position, m_interface->m_name.c_str(), definition);
4141         }
4142         else
4143         {
4144             const std::string &block_definition = m_interface->GetDefinition();
4145 
4146             replaceToken("TYPE", position, block_definition.c_str(), definition);
4147         }
4148     }
4149 
4150     /* Name */
4151     replaceToken("NAME", position, m_name.c_str(), definition);
4152 
4153     /* Array size */
4154     if (0 == m_n_array_elements)
4155     {
4156         replaceToken("ARRAY", position, "", definition);
4157     }
4158     else
4159     {
4160         char buffer[16];
4161         sprintf(buffer, "[%d]", m_n_array_elements);
4162 
4163         replaceToken("ARRAY", position, buffer, definition);
4164     }
4165 
4166     /* Done */
4167     return definition;
4168 }
4169 
4170 /** Get definitions for variables collected in vector
4171  *
4172  * @param vector  Collection of variables
4173  * @param flavour Flavour of variables
4174  *
4175  * @return Code with definitions
4176  **/
GetDefinitions(const Variable::PtrVector & vector,Variable::FLAVOUR flavour)4177 std::string GetDefinitions(const Variable::PtrVector &vector, Variable::FLAVOUR flavour)
4178 {
4179     std::string list = Utils::g_list;
4180     size_t position  = 0;
4181 
4182     for (GLuint i = 0; i < vector.size(); ++i)
4183     {
4184         Utils::insertElementOfList(vector[i]->GetDefinition(flavour).c_str(), "\n", position, list);
4185     }
4186 
4187     Utils::endList("", position, list);
4188 
4189     return list;
4190 }
4191 
4192 /** Get definitions for interfaces collected in vector
4193  *
4194  * @param vector Collection of interfaces
4195  *
4196  * @return Code with definitions
4197  **/
GetDefinitions(const Interface::PtrVector & vector)4198 std::string GetDefinitions(const Interface::PtrVector &vector)
4199 {
4200     std::string list = Utils::g_list;
4201     size_t position  = 0;
4202 
4203     for (GLuint i = 0; i < vector.size(); ++i)
4204     {
4205         Utils::insertElementOfList(vector[i]->GetDefinition().c_str(), "\n", position, list);
4206     }
4207 
4208     Utils::endList("", position, list);
4209 
4210     return list;
4211 }
4212 
4213 /** Constructor
4214  *
4215  * @param name Name
4216  * @param type Type of interface
4217  **/
Interface(const GLchar * name,Interface::TYPE type)4218 Interface::Interface(const GLchar *name, Interface::TYPE type) : m_name(name), m_type(type)
4219 {
4220 }
4221 
4222 /** Adds member to interface
4223  *
4224  * @param member Descriptor of new member
4225  *
4226  * @return Pointer to just created member
4227  **/
AddMember(const Variable::Descriptor & member)4228 Variable::Descriptor *Interface::AddMember(const Variable::Descriptor &member)
4229 {
4230     m_members.push_back(member);
4231 
4232     return &m_members.back();
4233 }
4234 
4235 /** Get definition of interface
4236  *
4237  * @param Code with definition
4238  **/
GetDefinition() const4239 std::string Interface::GetDefinition() const
4240 {
4241     std::string definition;
4242     size_t position = 0;
4243 
4244     const GLchar *member_list = "    MEMBER_DEFINITION\nMEMBER_LIST";
4245 
4246     if (STRUCT == m_type)
4247     {
4248         definition = "struct NAME {\nMEMBER_LIST};";
4249     }
4250     else
4251     {
4252         definition = "NAME {\nMEMBER_LIST}";
4253     }
4254 
4255     /* Name */
4256     replaceToken("NAME", position, m_name.c_str(), definition);
4257 
4258     /* Member list */
4259     for (GLuint i = 0; i < m_members.size(); ++i)
4260     {
4261         const size_t start_position          = position;
4262         const std::string &member_definition = m_members[i].GetDefinition(Variable::BASIC, Variable::MEMBER);
4263 
4264         /* Member list */
4265         replaceToken("MEMBER_LIST", position, member_list, definition);
4266 
4267         /* Move back position */
4268         position = start_position;
4269 
4270         /* Member definition */
4271         replaceToken("MEMBER_DEFINITION", position, member_definition.c_str(), definition);
4272     }
4273 
4274     /* Remove last member list */
4275     replaceToken("MEMBER_LIST", position, "", definition);
4276 
4277     /* Done */
4278     return definition;
4279 }
4280 
4281 /** Adds member of built-in type to interface
4282  *
4283  * @param name                       Name
4284  * @param qualifiers                 Qualifiers
4285  * @param expected_component         Expected component of variable
4286  * @param expected_location          Expected location
4287  * @param type                       Type
4288  * @param normalized                 Selects if data should be normalized
4289  * @param n_array_elements           Length of array
4290  * @param expected_stride_of_element Expected stride of element
4291  * @param offset                     Offset
4292  *
4293  * @return Pointer to just created member
4294  **/
Member(const GLchar * name,const GLchar * qualifiers,GLint expected_component,GLint expected_location,const Type & type,GLboolean normalized,GLuint n_array_elements,GLint expected_stride_of_element,GLuint offset)4295 Variable::Descriptor *Interface::Member(const GLchar *name, const GLchar *qualifiers, GLint expected_component,
4296                                         GLint expected_location, const Type &type, GLboolean normalized,
4297                                         GLuint n_array_elements, GLint expected_stride_of_element, GLuint offset)
4298 {
4299     return AddMember(Variable::Descriptor(name, qualifiers, expected_component, expected_location, type, normalized,
4300                                           n_array_elements, expected_stride_of_element, offset));
4301 }
4302 
4303 /** Adds member of interface type to interface
4304  *
4305  * @param name                       Name
4306  * @param qualifiers                 Qualifiers
4307  * @param expected_component         Expected component of variable
4308  * @param expected_location          Expected location
4309  * @param type                       Type
4310  * @param normalized                 Selects if data should be normalized
4311  * @param n_array_elements           Length of array
4312  * @param expected_stride_of_element Expected stride of element
4313  * @param offset                     Offset
4314  *
4315  * @return Pointer to just created member
4316  **/
Member(const GLchar * name,const GLchar * qualifiers,GLint expected_component,GLint expected_location,Interface * nterface,GLuint n_array_elements,GLint expected_stride_of_element,GLuint offset)4317 Variable::Descriptor *Interface::Member(const GLchar *name, const GLchar *qualifiers, GLint expected_component,
4318                                         GLint expected_location, Interface *nterface, GLuint n_array_elements,
4319                                         GLint expected_stride_of_element, GLuint offset)
4320 {
4321     return AddMember(Variable::Descriptor(name, qualifiers, expected_component, expected_location, nterface,
4322                                           n_array_elements, expected_stride_of_element, offset));
4323 }
4324 
4325 /** Clears contents of vector of pointers
4326  *
4327  * @tparam T Type of elements
4328  *
4329  * @param vector Collection to be cleared
4330  **/
4331 template <typename T>
clearPtrVector(std::vector<T * > & vector)4332 void clearPtrVector(std::vector<T *> &vector)
4333 {
4334     for (size_t i = 0; i < vector.size(); ++i)
4335     {
4336         T *t = vector[i];
4337 
4338         vector[i] = 0;
4339 
4340         if (0 != t)
4341         {
4342             delete t;
4343         }
4344     }
4345 
4346     vector.clear();
4347 }
4348 
4349 /** Constructor
4350  *
4351  * @param stage Stage described by that interface
4352  **/
ShaderInterface(Shader::STAGES stage)4353 ShaderInterface::ShaderInterface(Shader::STAGES stage) : m_stage(stage)
4354 {
4355     /* Nothing to be done */
4356 }
4357 
4358 /** Get definitions of globals
4359  *
4360  * @return Code with definitions
4361  **/
GetDefinitionsGlobals() const4362 std::string ShaderInterface::GetDefinitionsGlobals() const
4363 {
4364     return m_globals;
4365 }
4366 
4367 /** Get definitions of inputs
4368  *
4369  * @return Code with definitions
4370  **/
GetDefinitionsInputs() const4371 std::string ShaderInterface::GetDefinitionsInputs() const
4372 {
4373     Variable::FLAVOUR flavour = Variable::GetFlavour(m_stage, Variable::INPUT);
4374 
4375     return GetDefinitions(m_inputs, flavour);
4376 }
4377 
4378 /** Get definitions of outputs
4379  *
4380  * @return Code with definitions
4381  **/
GetDefinitionsOutputs() const4382 std::string ShaderInterface::GetDefinitionsOutputs() const
4383 {
4384     Variable::FLAVOUR flavour = Variable::GetFlavour(m_stage, Variable::OUTPUT);
4385 
4386     return GetDefinitions(m_outputs, flavour);
4387 }
4388 
4389 /** Get definitions of buffers
4390  *
4391  * @return Code with definitions
4392  **/
GetDefinitionsSSBs() const4393 std::string ShaderInterface::GetDefinitionsSSBs() const
4394 {
4395     return GetDefinitions(m_ssb_blocks, Variable::BASIC);
4396 }
4397 
4398 /** Get definitions of uniforms
4399  *
4400  * @return Code with definitions
4401  **/
GetDefinitionsUniforms() const4402 std::string ShaderInterface::GetDefinitionsUniforms() const
4403 {
4404     return GetDefinitions(m_uniforms, Variable::BASIC);
4405 }
4406 
4407 /** Constructor
4408  *
4409  * @param in  Input variable
4410  * @param out Output variable
4411  **/
VaryingConnection(Variable * in,Variable * out)4412 VaryingConnection::VaryingConnection(Variable *in, Variable *out) : m_in(in), m_out(out)
4413 {
4414     /* NBothing to be done here */
4415 }
4416 
4417 /** Adds new varying connection to given stage
4418  *
4419  * @param stage Shader stage
4420  * @param in    In varying
4421  * @param out   Out varying
4422  **/
Add(Shader::STAGES stage,Variable * in,Variable * out)4423 void VaryingPassthrough::Add(Shader::STAGES stage, Variable *in, Variable *out)
4424 {
4425     VaryingConnection::Vector &vector = Get(stage);
4426 
4427     vector.push_back(VaryingConnection(in, out));
4428 }
4429 
4430 /** Get all passthrough connections for given stage
4431  *
4432  * @param stage Shader stage
4433  *
4434  * @return Vector of connections
4435  **/
Get(Shader::STAGES stage)4436 VaryingConnection::Vector &VaryingPassthrough::Get(Shader::STAGES stage)
4437 {
4438     VaryingConnection::Vector *result = 0;
4439 
4440     switch (stage)
4441     {
4442     case Shader::FRAGMENT:
4443         result = &m_fragment;
4444         break;
4445     case Shader::GEOMETRY:
4446         result = &m_geometry;
4447         break;
4448     case Shader::TESS_CTRL:
4449         result = &m_tess_ctrl;
4450         break;
4451     case Shader::TESS_EVAL:
4452         result = &m_tess_eval;
4453         break;
4454     case Shader::VERTEX:
4455         result = &m_vertex;
4456         break;
4457     default:
4458         TCU_FAIL("Invalid enum");
4459     }
4460 
4461     return *result;
4462 }
4463 
4464 /** Constructor
4465  *
4466  **/
ProgramInterface()4467 ProgramInterface::ProgramInterface()
4468     : m_compute(Shader::COMPUTE)
4469     , m_vertex(Shader::VERTEX)
4470     , m_tess_ctrl(Shader::TESS_CTRL)
4471     , m_tess_eval(Shader::TESS_EVAL)
4472     , m_geometry(Shader::GEOMETRY)
4473     , m_fragment(Shader::FRAGMENT)
4474 {
4475 }
4476 
4477 /** Destructor
4478  *
4479  **/
~ProgramInterface()4480 ProgramInterface::~ProgramInterface()
4481 {
4482     clearPtrVector(m_blocks);
4483     clearPtrVector(m_structures);
4484 }
4485 
4486 /** Adds new interface
4487  *
4488  * @param name
4489  * @param type
4490  *
4491  * @return Pointer to created interface
4492  **/
AddInterface(const GLchar * name,Interface::TYPE type)4493 Interface *ProgramInterface::AddInterface(const GLchar *name, Interface::TYPE type)
4494 {
4495     Interface *interface = 0;
4496 
4497     if (Interface::STRUCT == type)
4498     {
4499         interface = new Interface(name, type);
4500 
4501         m_structures.push_back(interface);
4502     }
4503     else
4504     {
4505         interface = new Interface(name, type);
4506 
4507         m_blocks.push_back(interface);
4508     }
4509 
4510     return interface;
4511 }
4512 
4513 /** Adds new block interface
4514  *
4515  * @param name
4516  *
4517  * @return Pointer to created interface
4518  **/
Block(const GLchar * name)4519 Interface *ProgramInterface::Block(const GLchar *name)
4520 {
4521     return AddInterface(name, Interface::BLOCK);
4522 }
4523 
4524 /** Get interface of given shader stage
4525  *
4526  * @param stage Shader stage
4527  *
4528  * @return Reference to stage interface
4529  **/
GetShaderInterface(Shader::STAGES stage)4530 ShaderInterface &ProgramInterface::GetShaderInterface(Shader::STAGES stage)
4531 {
4532     ShaderInterface *interface = 0;
4533 
4534     switch (stage)
4535     {
4536     case Shader::COMPUTE:
4537         interface = &m_compute;
4538         break;
4539     case Shader::FRAGMENT:
4540         interface = &m_fragment;
4541         break;
4542     case Shader::GEOMETRY:
4543         interface = &m_geometry;
4544         break;
4545     case Shader::TESS_CTRL:
4546         interface = &m_tess_ctrl;
4547         break;
4548     case Shader::TESS_EVAL:
4549         interface = &m_tess_eval;
4550         break;
4551     case Shader::VERTEX:
4552         interface = &m_vertex;
4553         break;
4554     default:
4555         TCU_FAIL("Invalid enum");
4556     }
4557 
4558     return *interface;
4559 }
4560 
4561 /** Get interface of given shader stage
4562  *
4563  * @param stage Shader stage
4564  *
4565  * @return Reference to stage interface
4566  **/
GetShaderInterface(Shader::STAGES stage) const4567 const ShaderInterface &ProgramInterface::GetShaderInterface(Shader::STAGES stage) const
4568 {
4569     const ShaderInterface *interface = 0;
4570 
4571     switch (stage)
4572     {
4573     case Shader::COMPUTE:
4574         interface = &m_compute;
4575         break;
4576     case Shader::FRAGMENT:
4577         interface = &m_fragment;
4578         break;
4579     case Shader::GEOMETRY:
4580         interface = &m_geometry;
4581         break;
4582     case Shader::TESS_CTRL:
4583         interface = &m_tess_ctrl;
4584         break;
4585     case Shader::TESS_EVAL:
4586         interface = &m_tess_eval;
4587         break;
4588     case Shader::VERTEX:
4589         interface = &m_vertex;
4590         break;
4591     default:
4592         TCU_FAIL("Invalid enum");
4593     }
4594 
4595     return *interface;
4596 }
4597 
4598 /** Clone interface of Vertex shader stage to other stages
4599  * It creates matching inputs, outputs, uniforms and buffers in other stages.
4600  * There are no additional outputs for FRAGMENT shader generated.
4601  *
4602  * @param varying_passthrough Collection of varyings connections
4603  **/
CloneVertexInterface(VaryingPassthrough & varying_passthrough)4604 void ProgramInterface::CloneVertexInterface(VaryingPassthrough &varying_passthrough)
4605 {
4606     /* VS outputs >> TCS inputs >> TCS outputs >> ..  >> FS inputs */
4607     for (size_t i = 0; i < m_vertex.m_outputs.size(); ++i)
4608     {
4609         const Variable &vs_var = *m_vertex.m_outputs[i];
4610         const GLchar *prefix   = GetStagePrefix(Shader::VERTEX, vs_var.m_storage);
4611 
4612         cloneVariableForStage(vs_var, Shader::TESS_CTRL, prefix, varying_passthrough);
4613         cloneVariableForStage(vs_var, Shader::TESS_EVAL, prefix, varying_passthrough);
4614         cloneVariableForStage(vs_var, Shader::GEOMETRY, prefix, varying_passthrough);
4615         cloneVariableForStage(vs_var, Shader::FRAGMENT, prefix, varying_passthrough);
4616     }
4617 
4618     /* Copy uniforms from VS to other stages */
4619     for (size_t i = 0; i < m_vertex.m_uniforms.size(); ++i)
4620     {
4621         Variable &vs_var     = *m_vertex.m_uniforms[i];
4622         const GLchar *prefix = GetStagePrefix(Shader::VERTEX, vs_var.m_storage);
4623 
4624         cloneVariableForStage(vs_var, Shader::COMPUTE, prefix, varying_passthrough);
4625         cloneVariableForStage(vs_var, Shader::TESS_CTRL, prefix, varying_passthrough);
4626         cloneVariableForStage(vs_var, Shader::TESS_EVAL, prefix, varying_passthrough);
4627         cloneVariableForStage(vs_var, Shader::GEOMETRY, prefix, varying_passthrough);
4628         cloneVariableForStage(vs_var, Shader::FRAGMENT, prefix, varying_passthrough);
4629 
4630         /* Uniform blocks needs unique binding */
4631         if (true == vs_var.IsBlock())
4632         {
4633             replaceBinding(vs_var, Shader::VERTEX);
4634         }
4635     }
4636 
4637     /* Copy SSBs from VS to other stages */
4638     for (size_t i = 0; i < m_vertex.m_ssb_blocks.size(); ++i)
4639     {
4640         Variable &vs_var     = *m_vertex.m_ssb_blocks[i];
4641         const GLchar *prefix = GetStagePrefix(Shader::VERTEX, vs_var.m_storage);
4642 
4643         cloneVariableForStage(vs_var, Shader::COMPUTE, prefix, varying_passthrough);
4644         cloneVariableForStage(vs_var, Shader::TESS_CTRL, prefix, varying_passthrough);
4645         cloneVariableForStage(vs_var, Shader::TESS_EVAL, prefix, varying_passthrough);
4646         cloneVariableForStage(vs_var, Shader::GEOMETRY, prefix, varying_passthrough);
4647         cloneVariableForStage(vs_var, Shader::FRAGMENT, prefix, varying_passthrough);
4648 
4649         /* SSBs blocks needs unique binding */
4650         if (true == vs_var.IsBlock())
4651         {
4652             replaceBinding(vs_var, Shader::VERTEX);
4653         }
4654     }
4655 
4656     m_compute.m_globals   = m_vertex.m_globals;
4657     m_fragment.m_globals  = m_vertex.m_globals;
4658     m_geometry.m_globals  = m_vertex.m_globals;
4659     m_tess_ctrl.m_globals = m_vertex.m_globals;
4660     m_tess_eval.m_globals = m_vertex.m_globals;
4661 }
4662 
4663 /** Clone variable for specific stage
4664  *
4665  * @param variable            Variable
4666  * @param stage               Requested stage
4667  * @param prefix              Prefix used in variable name that is specific for original stage
4668  * @param varying_passthrough Collection of varyings connections
4669  **/
cloneVariableForStage(const Variable & variable,Shader::STAGES stage,const GLchar * prefix,VaryingPassthrough & varying_passthrough)4670 void ProgramInterface::cloneVariableForStage(const Variable &variable, Shader::STAGES stage, const GLchar *prefix,
4671                                              VaryingPassthrough &varying_passthrough)
4672 {
4673     switch (variable.m_storage)
4674     {
4675     case Variable::VARYING_OUTPUT:
4676     {
4677         Variable *in = cloneVariableForStage(variable, stage, Variable::VARYING_INPUT, prefix);
4678 
4679         if (Shader::FRAGMENT != stage)
4680         {
4681             Variable *out = cloneVariableForStage(variable, stage, Variable::VARYING_OUTPUT, prefix);
4682             varying_passthrough.Add(stage, in, out);
4683         }
4684     }
4685     break;
4686     case Variable::UNIFORM:
4687     case Variable::SSB:
4688         cloneVariableForStage(variable, stage, variable.m_storage, prefix);
4689         break;
4690     default:
4691         TCU_FAIL("Invalid enum");
4692     }
4693 }
4694 
4695 /** Clone variable for specific stage
4696  *
4697  * @param variable Variable
4698  * @param stage    Requested stage
4699  * @param storage  Storage used by variable
4700  * @param prefix   Prefix used in variable name that is specific for original stage
4701  *
4702  * @return New variable
4703  **/
cloneVariableForStage(const Variable & variable,Shader::STAGES stage,Variable::STORAGE storage,const GLchar * prefix)4704 Variable *ProgramInterface::cloneVariableForStage(const Variable &variable, Shader::STAGES stage,
4705                                                   Variable::STORAGE storage, const GLchar *prefix)
4706 {
4707     /* Initialize with original variable */
4708     Variable *var = new Variable(variable);
4709     if (0 == var)
4710     {
4711         TCU_FAIL("Memory allocation");
4712     }
4713 
4714     /* Set up storage */
4715     var->m_storage = storage;
4716 
4717     /* Get name */
4718     std::string name = variable.m_descriptor.m_name;
4719 
4720     /* Prefix name with stage ID, empty means default block */
4721     if (false == name.empty())
4722     {
4723         size_t position            = 0;
4724         const GLchar *stage_prefix = GetStagePrefix(stage, storage);
4725         Utils::replaceToken(prefix, position, stage_prefix, name);
4726     }
4727     var->m_descriptor.m_name = name;
4728 
4729     /* Clone block */
4730     const bool is_block = variable.IsBlock();
4731     if (true == is_block)
4732     {
4733         const Interface *interface = variable.m_descriptor.m_interface;
4734 
4735         Interface *block = CloneBlockForStage(*interface, stage, storage, prefix);
4736 
4737         var->m_descriptor.m_interface = block;
4738     }
4739 
4740     /* Store variable */
4741     ShaderInterface &si = GetShaderInterface(stage);
4742     Variable *result    = 0;
4743 
4744     switch (storage)
4745     {
4746     case Variable::VARYING_INPUT:
4747         si.m_inputs.push_back(var);
4748         result = si.m_inputs.back();
4749         break;
4750     case Variable::VARYING_OUTPUT:
4751         si.m_outputs.push_back(var);
4752         result = si.m_outputs.back();
4753         break;
4754     case Variable::UNIFORM:
4755         /* Uniform blocks needs unique binding */
4756         if (true == is_block)
4757         {
4758             replaceBinding(*var, stage);
4759         }
4760 
4761         si.m_uniforms.push_back(var);
4762         result = si.m_uniforms.back();
4763         break;
4764     case Variable::SSB:
4765         /* SSBs needs unique binding */
4766         if (true == is_block)
4767         {
4768             replaceBinding(*var, stage);
4769         }
4770 
4771         si.m_ssb_blocks.push_back(var);
4772         result = si.m_ssb_blocks.back();
4773         break;
4774     default:
4775         TCU_FAIL("Invalid enum");
4776     }
4777 
4778     return result;
4779 }
4780 
4781 /** clone block to specific stage
4782  *
4783  * @param block   Block to be copied
4784  * @param stage   Specific stage
4785  * @param storage Storage used by block
4786  * @param prefix  Prefix used in block name
4787  *
4788  * @return New interface
4789  **/
CloneBlockForStage(const Interface & block,Shader::STAGES stage,Variable::STORAGE storage,const GLchar * prefix)4790 Interface *ProgramInterface::CloneBlockForStage(const Interface &block, Shader::STAGES stage, Variable::STORAGE storage,
4791                                                 const GLchar *prefix)
4792 {
4793     /* Get name */
4794     std::string name = block.m_name;
4795 
4796     /* Prefix name with stage ID */
4797     size_t position            = 0;
4798     const GLchar *stage_prefix = GetStagePrefix(stage, storage);
4799     Utils::replaceToken(prefix, position, stage_prefix, name);
4800 
4801     Interface *ptr = GetBlock(name.c_str());
4802 
4803     if (0 == ptr)
4804     {
4805         ptr = AddInterface(name.c_str(), Interface::BLOCK);
4806     }
4807 
4808     ptr->m_members = block.m_members;
4809 
4810     return ptr;
4811 }
4812 
4813 /** Get stage specific prefix used in names
4814  *
4815  * @param stage   Stage
4816  * @param storage Storage class
4817  *
4818  * @return String
4819  **/
GetStagePrefix(Shader::STAGES stage,Variable::STORAGE storage)4820 const GLchar *ProgramInterface::GetStagePrefix(Shader::STAGES stage, Variable::STORAGE storage)
4821 {
4822     static const GLchar *lut[Shader::STAGE_MAX][Variable::STORAGE_MAX] = {
4823         /*          IN          OUT         UNIFORM     SSB        MEMBER    */
4824         /* CS  */ {0, 0, "cs_uni_", "cs_buf_", ""},
4825         /* VS  */ {"in_vs_", "vs_tcs_", "vs_uni_", "vs_buf_", ""},
4826         /* TCS */ {"vs_tcs_", "tcs_tes_", "tcs_uni_", "tcs_buf_", ""},
4827         /* TES */ {"tcs_tes_", "tes_gs_", "tes_uni_", "tes_buf_", ""},
4828         /* GS  */ {"tes_gs_", "gs_fs_", "gs_uni_", "gs_buf_", ""},
4829         /* FS  */ {"gs_fs_", "fs_out_", "fs_uni_", "fs_buf_", ""},
4830     };
4831 
4832     const GLchar *result = 0;
4833 
4834     result = lut[stage][storage];
4835 
4836     return result;
4837 }
4838 
4839 /** Get definitions of all structures used in program interface
4840  *
4841  * @return String with code
4842  **/
GetDefinitionsStructures() const4843 std::string ProgramInterface::GetDefinitionsStructures() const
4844 {
4845     return GetDefinitions(m_structures);
4846 }
4847 
4848 /** Get interface code for stage
4849  *
4850  * @param stage Specific stage
4851  *
4852  * @return String with code
4853  **/
GetInterfaceForStage(Shader::STAGES stage) const4854 std::string ProgramInterface::GetInterfaceForStage(Shader::STAGES stage) const
4855 {
4856     size_t position       = 0;
4857     std::string interface = "/* Globals */\n"
4858                             "GLOBALS\n"
4859                             "\n"
4860                             "/* Structures */\n"
4861                             "STRUCTURES\n"
4862                             "\n"
4863                             "/* Uniforms */\n"
4864                             "UNIFORMS\n"
4865                             "\n"
4866                             "/* Inputs */\n"
4867                             "INPUTS\n"
4868                             "\n"
4869                             "/* Outputs */\n"
4870                             "OUTPUTS\n"
4871                             "\n"
4872                             "/* Storage */\n"
4873                             "STORAGE\n";
4874 
4875     const ShaderInterface &si = GetShaderInterface(stage);
4876 
4877     const std::string &structures = GetDefinitionsStructures();
4878 
4879     const std::string &globals  = si.GetDefinitionsGlobals();
4880     const std::string &inputs   = si.GetDefinitionsInputs();
4881     const std::string &outputs  = si.GetDefinitionsOutputs();
4882     const std::string &uniforms = si.GetDefinitionsUniforms();
4883     const std::string &ssbs     = si.GetDefinitionsSSBs();
4884 
4885     replaceToken("GLOBALS", position, globals.c_str(), interface);
4886     replaceToken("STRUCTURES", position, structures.c_str(), interface);
4887     replaceToken("UNIFORMS", position, uniforms.c_str(), interface);
4888     replaceToken("INPUTS", position, inputs.c_str(), interface);
4889     replaceToken("OUTPUTS", position, outputs.c_str(), interface);
4890     replaceToken("STORAGE", position, ssbs.c_str(), interface);
4891 
4892     return interface;
4893 }
4894 
4895 /** Functional object used in find_if algorithm, in search for interface of given name
4896  *
4897  **/
4898 struct matchInterfaceName
4899 {
matchInterfaceNamegl4cts::EnhancedLayouts::Utils::matchInterfaceName4900     matchInterfaceName(const GLchar *name) : m_name(name)
4901     {
4902     }
4903 
operator ()gl4cts::EnhancedLayouts::Utils::matchInterfaceName4904     bool operator()(const Interface *interface)
4905     {
4906         return 0 == interface->m_name.compare(m_name);
4907     }
4908 
4909     const GLchar *m_name;
4910 };
4911 
4912 /** Finds interface of given name in given vector of interfaces
4913  *
4914  * @param vector Collection of interfaces
4915  * @param name   Requested name
4916  *
4917  * @return Pointer to interface if available, 0 otherwise
4918  **/
findInterfaceByName(Interface::PtrVector & vector,const GLchar * name)4919 static Interface *findInterfaceByName(Interface::PtrVector &vector, const GLchar *name)
4920 {
4921     Interface::PtrVector::iterator it = std::find_if(vector.begin(), vector.end(), matchInterfaceName(name));
4922 
4923     if (vector.end() != it)
4924     {
4925         return *it;
4926     }
4927     else
4928     {
4929         return 0;
4930     }
4931 }
4932 
4933 /** Search for block of given name
4934  *
4935  * @param name Name of block
4936  *
4937  * @return Pointer to block or 0
4938  **/
GetBlock(const GLchar * name)4939 Interface *ProgramInterface::GetBlock(const GLchar *name)
4940 {
4941     return findInterfaceByName(m_blocks, name);
4942 }
4943 
4944 /** Search for structure of given name
4945  *
4946  * @param name Name of structure
4947  *
4948  * @return Pointer to structure or 0
4949  **/
GetStructure(const GLchar * name)4950 Interface *ProgramInterface::GetStructure(const GLchar *name)
4951 {
4952     return findInterfaceByName(m_structures, name);
4953 }
4954 
4955 /** Adds new sturcture to interface
4956  *
4957  * @param name Name of structure
4958  *
4959  * @return Created structure
4960  **/
Structure(const GLchar * name)4961 Interface *ProgramInterface::Structure(const GLchar *name)
4962 {
4963     return AddInterface(name, Interface::STRUCT);
4964 }
4965 
4966 /** Replace "BINDING" token in qualifiers string to value specific for given stage
4967  *
4968  * @param variable Variable to modify
4969  * @param stage    Requested stage
4970  **/
replaceBinding(Variable & variable,Shader::STAGES stage)4971 void ProgramInterface::replaceBinding(Variable &variable, Shader::STAGES stage)
4972 {
4973     GLchar binding[16];
4974     sprintf(binding, "%d", stage);
4975     replaceAllTokens("BINDING", binding, variable.m_descriptor.m_qualifiers);
4976 }
4977 } // namespace Utils
4978 
4979 /** Debuging procedure. Logs parameters.
4980  *
4981  * @param source   As specified in GL spec.
4982  * @param type     As specified in GL spec.
4983  * @param id       As specified in GL spec.
4984  * @param severity As specified in GL spec.
4985  * @param ignored
4986  * @param message  As specified in GL spec.
4987  * @param info     Pointer to instance of Context used by test.
4988  */
debug_proc(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei,const GLchar * message,void * info)4989 void GLW_APIENTRY debug_proc(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei /* length */,
4990                              const GLchar *message, void *info)
4991 {
4992     deqp::Context *ctx = (deqp::Context *)info;
4993 
4994     const GLchar *source_str   = "Unknown";
4995     const GLchar *type_str     = "Unknown";
4996     const GLchar *severity_str = "Unknown";
4997 
4998     switch (source)
4999     {
5000     case GL_DEBUG_SOURCE_API:
5001         source_str = "API";
5002         break;
5003     case GL_DEBUG_SOURCE_APPLICATION:
5004         source_str = "APP";
5005         break;
5006     case GL_DEBUG_SOURCE_OTHER:
5007         source_str = "OTR";
5008         break;
5009     case GL_DEBUG_SOURCE_SHADER_COMPILER:
5010         source_str = "COM";
5011         break;
5012     case GL_DEBUG_SOURCE_THIRD_PARTY:
5013         source_str = "3RD";
5014         break;
5015     case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
5016         source_str = "WS";
5017         break;
5018     default:
5019         break;
5020     }
5021 
5022     switch (type)
5023     {
5024     case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
5025         type_str = "DEPRECATED_BEHAVIOR";
5026         break;
5027     case GL_DEBUG_TYPE_ERROR:
5028         type_str = "ERROR";
5029         break;
5030     case GL_DEBUG_TYPE_MARKER:
5031         type_str = "MARKER";
5032         break;
5033     case GL_DEBUG_TYPE_OTHER:
5034         type_str = "OTHER";
5035         break;
5036     case GL_DEBUG_TYPE_PERFORMANCE:
5037         type_str = "PERFORMANCE";
5038         break;
5039     case GL_DEBUG_TYPE_POP_GROUP:
5040         type_str = "POP_GROUP";
5041         break;
5042     case GL_DEBUG_TYPE_PORTABILITY:
5043         type_str = "PORTABILITY";
5044         break;
5045     case GL_DEBUG_TYPE_PUSH_GROUP:
5046         type_str = "PUSH_GROUP";
5047         break;
5048     case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
5049         type_str = "UNDEFINED_BEHAVIOR";
5050         break;
5051     default:
5052         break;
5053     }
5054 
5055     switch (severity)
5056     {
5057     case GL_DEBUG_SEVERITY_HIGH:
5058         severity_str = "H";
5059         break;
5060     case GL_DEBUG_SEVERITY_LOW:
5061         severity_str = "L";
5062         break;
5063     case GL_DEBUG_SEVERITY_MEDIUM:
5064         severity_str = "M";
5065         break;
5066     case GL_DEBUG_SEVERITY_NOTIFICATION:
5067         severity_str = "N";
5068         break;
5069     default:
5070         break;
5071     }
5072 
5073     ctx->getTestContext().getLog() << tcu::TestLog::Message << "DEBUG_INFO: " << std::setw(3) << source_str << "|"
5074                                    << severity_str << "|" << std::setw(18) << type_str << "|" << std::setw(12) << id
5075                                    << ": " << message << tcu::TestLog::EndMessage;
5076 }
5077 
5078 /** Constructor
5079  *
5080  * @param context          Test context
5081  * @param test_name        Test name
5082  * @param test_description Test description
5083  **/
TestBase(deqp::Context & context,const GLchar * test_name,const GLchar * test_description)5084 TestBase::TestBase(deqp::Context &context, const GLchar *test_name, const GLchar *test_description)
5085     : TestCase(context, test_name, test_description)
5086 {
5087     /* Nothing to be done here */
5088 }
5089 
5090 /** Execute test
5091  *
5092  * @return tcu::TestNode::STOP otherwise
5093  **/
iterate()5094 tcu::TestNode::IterateResult TestBase::iterate()
5095 {
5096     bool test_result;
5097 
5098 #if DEBUG_ENBALE_MESSAGE_CALLBACK
5099     const Functions &gl = m_context.getRenderContext().getFunctions();
5100 
5101     gl.debugMessageCallback(debug_proc, &m_context);
5102     GLU_EXPECT_NO_ERROR(gl.getError(), "DebugMessageCallback");
5103 #endif /* DEBUG_ENBALE_MESSAGE_CALLBACK */
5104 
5105     try
5106     {
5107         /* Execute test */
5108         test_result = test();
5109     }
5110     catch (std::exception &exc)
5111     {
5112         TCU_FAIL(exc.what());
5113     }
5114 
5115     /* Set result */
5116     if (true == test_result)
5117     {
5118         m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
5119     }
5120     else
5121     {
5122         m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
5123     }
5124 
5125     /* Done */
5126     return tcu::TestNode::STOP;
5127 }
5128 
5129 /** Get last input location available for given type at specific stage
5130  *
5131  * @param stage        Shader stage
5132  * @param type         Input type
5133  * @param array_length Length of input array
5134  *
5135  * @return Last location index
5136  **/
getLastInputLocation(Utils::Shader::STAGES stage,const Utils::Type & type,GLuint array_length,bool ignore_prev_stage)5137 GLint TestBase::getLastInputLocation(Utils::Shader::STAGES stage, const Utils::Type &type, GLuint array_length,
5138                                      bool ignore_prev_stage)
5139 {
5140     GLint divide     = 4; /* 4 components per location */
5141     GLint param      = 0;
5142     GLenum pname     = 0;
5143     GLint paramPrev  = 0;
5144     GLenum pnamePrev = 0;
5145 
5146     /* Select pnmae */
5147     switch (stage)
5148     {
5149     case Utils::Shader::FRAGMENT:
5150         pname     = GL_MAX_FRAGMENT_INPUT_COMPONENTS;
5151         pnamePrev = GL_MAX_GEOMETRY_OUTPUT_COMPONENTS;
5152         break;
5153     case Utils::Shader::GEOMETRY:
5154         pname     = GL_MAX_GEOMETRY_INPUT_COMPONENTS;
5155         pnamePrev = GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS;
5156         break;
5157     case Utils::Shader::TESS_CTRL:
5158         pname     = GL_MAX_TESS_CONTROL_INPUT_COMPONENTS;
5159         pnamePrev = GL_MAX_VERTEX_OUTPUT_COMPONENTS;
5160         break;
5161     case Utils::Shader::TESS_EVAL:
5162         pname     = GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS;
5163         pnamePrev = GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS;
5164         break;
5165     case Utils::Shader::VERTEX:
5166         pname  = GL_MAX_VERTEX_ATTRIBS;
5167         divide = 1;
5168         break;
5169     default:
5170         TCU_FAIL("Invalid enum");
5171     }
5172 
5173     /* Zero means no array, but 1 slot is required */
5174     if (0 == array_length)
5175     {
5176         array_length += 1;
5177     }
5178 
5179     /* Get MAX */
5180     const Functions &gl = m_context.getRenderContext().getFunctions();
5181 
5182     gl.getIntegerv(pname, &param);
5183     GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
5184 
5185     if (pnamePrev && !ignore_prev_stage)
5186     {
5187         gl.getIntegerv(pnamePrev, &paramPrev);
5188         GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
5189 
5190         /* Don't read from a location that doesn't exist in the previous stage */
5191         param = de::min(param, paramPrev);
5192     }
5193 
5194 /* Calculate */
5195 #if WRKARD_VARYINGLOCATIONSTEST
5196 
5197     const GLint n_avl_locations = 16;
5198 
5199 #else
5200 
5201     const GLint n_avl_locations = param / divide;
5202 
5203 #endif
5204 
5205     const GLuint n_req_location = type.GetLocations(stage == Utils::Shader::VERTEX) * array_length;
5206 
5207     return n_avl_locations - n_req_location; /* last is max - 1 */
5208 }
5209 
5210 /** Get last output location available for given type at specific stage
5211  *
5212  * @param stage        Shader stage
5213  * @param type         Input type
5214  * @param array_length Length of input array
5215  *
5216  * @return Last location index
5217  **/
getLastOutputLocation(Utils::Shader::STAGES stage,const Utils::Type & type,GLuint array_length,bool ignore_next_stage)5218 GLint TestBase::getLastOutputLocation(Utils::Shader::STAGES stage, const Utils::Type &type, GLuint array_length,
5219                                       bool ignore_next_stage)
5220 {
5221     GLint param      = 0;
5222     GLenum pname     = 0;
5223     GLint paramNext  = 0;
5224     GLenum pnameNext = 0;
5225 
5226     /* Select pname */
5227     switch (stage)
5228     {
5229     case Utils::Shader::GEOMETRY:
5230         pname     = GL_MAX_GEOMETRY_OUTPUT_COMPONENTS;
5231         pnameNext = GL_MAX_FRAGMENT_INPUT_COMPONENTS;
5232         break;
5233     case Utils::Shader::TESS_CTRL:
5234         pname     = GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS;
5235         pnameNext = GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS;
5236         break;
5237     case Utils::Shader::TESS_EVAL:
5238         pname     = GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS;
5239         pnameNext = GL_MAX_GEOMETRY_INPUT_COMPONENTS;
5240         break;
5241     case Utils::Shader::VERTEX:
5242         pname     = GL_MAX_VERTEX_OUTPUT_COMPONENTS;
5243         pnameNext = GL_MAX_TESS_CONTROL_INPUT_COMPONENTS;
5244         break;
5245     default:
5246         TCU_FAIL("Invalid enum");
5247     }
5248 
5249     /* Zero means no array, but 1 slot is required */
5250     if (0 == array_length)
5251     {
5252         array_length += 1;
5253     }
5254 
5255     /* Get MAX */
5256     const Functions &gl = m_context.getRenderContext().getFunctions();
5257 
5258     gl.getIntegerv(pname, &param);
5259     GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
5260 
5261 /* Calculate */
5262 #if WRKARD_VARYINGLOCATIONSTEST
5263 
5264     const GLint n_avl_locations = 16;
5265 
5266 #else
5267 
5268     /* Don't write to a location that doesn't exist in the next stage */
5269     if (!ignore_next_stage)
5270     {
5271         gl.getIntegerv(pnameNext, &paramNext);
5272         GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
5273 
5274         param = de::min(param, paramNext);
5275     }
5276 
5277     const GLint n_avl_locations = param / 4; /* 4 components per location */
5278 
5279 #endif
5280 
5281     const GLuint n_req_location = type.GetLocations() * array_length;
5282 
5283     return n_avl_locations - n_req_location; /* last is max - 1 */
5284 }
5285 
5286 /** Basic implementation
5287  *
5288  * @param ignored
5289  *
5290  * @return Empty string
5291  **/
getTestCaseName(GLuint)5292 std::string TestBase::getTestCaseName(GLuint /* test_case_index */)
5293 {
5294     std::string result;
5295 
5296     return result;
5297 }
5298 
5299 /** Basic implementation
5300  *
5301  * @return 1
5302  **/
getTestCaseNumber()5303 GLuint TestBase::getTestCaseNumber()
5304 {
5305     return 1;
5306 }
5307 
5308 /** Check if flat qualifier is required for given type, stage and storage
5309  *
5310  * @param stage        Shader stage
5311  * @param type         Input type
5312  * @param storage      Storage of variable
5313  *
5314  * @return Last location index
5315  **/
isFlatRequired(Utils::Shader::STAGES stage,const Utils::Type & type,Utils::Variable::STORAGE storage,const bool coherent) const5316 bool TestBase::isFlatRequired(Utils::Shader::STAGES stage, const Utils::Type &type, Utils::Variable::STORAGE storage,
5317                               const bool coherent) const
5318 {
5319     /* Float types do not need flat at all */
5320     if (Utils::Type::Float == type.m_basic_type)
5321     {
5322         return false;
5323     }
5324 
5325     /* Inputs to fragment shader */
5326     if ((Utils::Shader::FRAGMENT == stage) && (Utils::Variable::VARYING_INPUT == storage))
5327     {
5328         return true;
5329     }
5330 
5331     /* Outputs from geometry shader
5332      *
5333      * This is not strictly needed since fragment shader input
5334      * interpolation qualifiers will override whatever comes from the
5335      * previous stage. However, if we want to have a coherent
5336      * interface, let's better do it.
5337      */
5338     if ((Utils::Shader::GEOMETRY == stage) && (Utils::Variable::VARYING_OUTPUT == storage) && coherent)
5339     {
5340         return true;
5341     }
5342 
5343     return false;
5344 }
5345 
5346 /** Basic implementation of testInit method
5347  *
5348  **/
testInit()5349 void TestBase::testInit()
5350 {
5351 }
5352 
5353 /** Calculate stride for interface
5354  *
5355  * @param interface Interface
5356  *
5357  * @return Calculated value
5358  **/
calculateStride(const Utils::Interface & interface) const5359 GLuint TestBase::calculateStride(const Utils::Interface &interface) const
5360 {
5361     const size_t n_members = interface.m_members.size();
5362 
5363     GLuint stride = 0;
5364 
5365     for (size_t i = 0; i < n_members; ++i)
5366     {
5367         const Utils::Variable::Descriptor &member = interface.m_members[i];
5368         const GLuint member_offset                = member.m_offset;
5369         const GLuint member_stride                = member.m_expected_stride_of_element;
5370         const GLuint member_ends_at               = member_offset + member_stride;
5371 
5372         stride = std::max(stride, member_ends_at);
5373     }
5374 
5375     return stride;
5376 }
5377 
5378 /** Generate data for interface. This routine is recursive
5379  *
5380  * @param interface Interface
5381  * @param offset    Offset in out_data
5382  * @param out_data  Buffer to be filled
5383  **/
generateData(const Utils::Interface & interface,GLuint offset,std::vector<GLubyte> & out_data) const5384 void TestBase::generateData(const Utils::Interface &interface, GLuint offset, std::vector<GLubyte> &out_data) const
5385 {
5386     const size_t n_members = interface.m_members.size();
5387     GLubyte *ptr           = &out_data[offset];
5388 
5389     for (size_t i = 0; i < n_members; ++i)
5390     {
5391         const Utils::Variable::Descriptor &member = interface.m_members[i];
5392         const GLuint member_offset                = member.m_offset;
5393         const GLuint n_elements                   = (0 == member.m_n_array_elements) ? 1 : member.m_n_array_elements;
5394 
5395         for (GLuint element = 0; element < n_elements; ++element)
5396         {
5397             const GLuint element_offset = element * member.m_expected_stride_of_element;
5398             const GLuint data_offfset   = member_offset + element_offset;
5399 
5400             if (Utils::Variable::BUILTIN == member.m_type)
5401             {
5402                 const std::vector<GLubyte> &data = member.m_builtin.GenerateData();
5403 
5404                 memcpy(ptr + data_offfset, &data[0], data.size());
5405             }
5406             else
5407             {
5408                 generateData(*member.m_interface, offset + data_offfset, out_data);
5409             }
5410         }
5411     }
5412 }
5413 
5414 /** Get type at index
5415  *
5416  * @param index Index of requested type
5417  *
5418  * @return Type
5419  **/
getType(GLuint index) const5420 Utils::Type TestBase::getType(GLuint index) const
5421 {
5422     Utils::Type type;
5423 
5424     switch (index)
5425     {
5426     case 0:
5427         type = Utils::Type::_double;
5428         break;
5429     case 1:
5430         type = Utils::Type::dmat2;
5431         break;
5432     case 2:
5433         type = Utils::Type::dmat2x3;
5434         break;
5435     case 3:
5436         type = Utils::Type::dmat2x4;
5437         break;
5438     case 4:
5439         type = Utils::Type::dmat3;
5440         break;
5441     case 5:
5442         type = Utils::Type::dmat3x2;
5443         break;
5444     case 6:
5445         type = Utils::Type::dmat3x4;
5446         break;
5447     case 7:
5448         type = Utils::Type::dmat4;
5449         break;
5450     case 8:
5451         type = Utils::Type::dmat4x2;
5452         break;
5453     case 9:
5454         type = Utils::Type::dmat4x3;
5455         break;
5456     case 10:
5457         type = Utils::Type::dvec2;
5458         break;
5459     case 11:
5460         type = Utils::Type::dvec3;
5461         break;
5462     case 12:
5463         type = Utils::Type::dvec4;
5464         break;
5465     case 13:
5466         type = Utils::Type::_float;
5467         break;
5468     case 14:
5469         type = Utils::Type::mat2;
5470         break;
5471     case 15:
5472         type = Utils::Type::mat2x3;
5473         break;
5474     case 16:
5475         type = Utils::Type::mat2x4;
5476         break;
5477     case 17:
5478         type = Utils::Type::mat3;
5479         break;
5480     case 18:
5481         type = Utils::Type::mat3x2;
5482         break;
5483     case 19:
5484         type = Utils::Type::mat3x4;
5485         break;
5486     case 20:
5487         type = Utils::Type::mat4;
5488         break;
5489     case 21:
5490         type = Utils::Type::mat4x2;
5491         break;
5492     case 22:
5493         type = Utils::Type::mat4x3;
5494         break;
5495     case 23:
5496         type = Utils::Type::vec2;
5497         break;
5498     case 24:
5499         type = Utils::Type::vec3;
5500         break;
5501     case 25:
5502         type = Utils::Type::vec4;
5503         break;
5504     case 26:
5505         type = Utils::Type::_int;
5506         break;
5507     case 27:
5508         type = Utils::Type::ivec2;
5509         break;
5510     case 28:
5511         type = Utils::Type::ivec3;
5512         break;
5513     case 29:
5514         type = Utils::Type::ivec4;
5515         break;
5516     case 30:
5517         type = Utils::Type::uint;
5518         break;
5519     case 31:
5520         type = Utils::Type::uvec2;
5521         break;
5522     case 32:
5523         type = Utils::Type::uvec3;
5524         break;
5525     case 33:
5526         type = Utils::Type::uvec4;
5527         break;
5528     default:
5529         TCU_FAIL("invalid enum");
5530     }
5531 
5532     return type;
5533 }
5534 
5535 /** Get name of type at index
5536  *
5537  * @param index Index of type
5538  *
5539  * @return Name
5540  **/
getTypeName(GLuint index) const5541 std::string TestBase::getTypeName(GLuint index) const
5542 {
5543     std::string name = getType(index).GetGLSLTypeName();
5544 
5545     return name;
5546 }
5547 
5548 /** Get number of types
5549  *
5550  * @return 34
5551  **/
getTypesNumber() const5552 glw::GLuint TestBase::getTypesNumber() const
5553 {
5554     return 34;
5555 }
5556 
5557 /** Execute test
5558  *
5559  * @return true if test pass, false otherwise
5560  **/
test()5561 bool TestBase::test()
5562 {
5563     bool result         = true;
5564     GLuint n_test_cases = 0;
5565 
5566     /* Prepare test */
5567     testInit();
5568 
5569     /* GL entry points */
5570     const Functions &gl = m_context.getRenderContext().getFunctions();
5571 
5572     /* Tessellation patch set up */
5573     gl.patchParameteri(GL_PATCH_VERTICES, 1);
5574     GLU_EXPECT_NO_ERROR(gl.getError(), "PatchParameteri");
5575 
5576     /* Get number of test cases */
5577     n_test_cases = getTestCaseNumber();
5578 
5579 #if DEBUG_REPEAT_TEST_CASE
5580 
5581     while (1)
5582     {
5583         GLuint test_case = DEBUG_REPEATED_TEST_CASE;
5584 
5585 #else  /* DEBUG_REPEAT_TEST_CASE */
5586 
5587     for (GLuint test_case = 0; test_case < n_test_cases; ++test_case)
5588     {
5589 #endif /* DEBUG_REPEAT_TEST_CASE */
5590 
5591         /* Execute case */
5592         if (!testCase(test_case))
5593         {
5594             const std::string &test_case_name = getTestCaseName(test_case);
5595 
5596             if (false == test_case_name.empty())
5597             {
5598                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Test case (" << test_case_name
5599                                                     << ") failed." << tcu::TestLog::EndMessage;
5600             }
5601             else
5602             {
5603                 m_context.getTestContext().getLog()
5604                     << tcu::TestLog::Message << "Test case (" << test_case << ") failed." << tcu::TestLog::EndMessage;
5605             }
5606 
5607             result = false;
5608         }
5609     }
5610 
5611     /* Done */
5612     return result;
5613 }
5614 
5615 /* Constants used by BufferTestBase */
5616 const GLuint BufferTestBase::bufferDescriptor::m_non_indexed = -1;
5617 
5618 /** Constructor
5619  *
5620  * @param context          Test context
5621  * @param test_name        Name of test
5622  * @param test_description Description of test
5623  **/
5624 BufferTestBase::BufferTestBase(deqp::Context &context, const GLchar *test_name, const GLchar *test_description)
5625     : TestBase(context, test_name, test_description)
5626 {
5627 }
5628 
5629 /** Execute drawArrays for single vertex
5630  *
5631  * @param ignored
5632  *
5633  * @return true
5634  **/
5635 bool BufferTestBase::executeDrawCall(bool tesEnabled, GLuint /* test_case_index */)
5636 {
5637     const Functions &gl = m_context.getRenderContext().getFunctions();
5638 
5639     gl.disable(GL_RASTERIZER_DISCARD);
5640     GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
5641 
5642     gl.beginTransformFeedback(GL_POINTS);
5643     GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
5644 
5645     // Only TES is existed, glDrawArray can use the parameter GL_PATCHES
5646     if (tesEnabled == false)
5647     {
5648         gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */);
5649     }
5650     else
5651     {
5652         gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
5653     }
5654 
5655     GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
5656 
5657     gl.endTransformFeedback();
5658     GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
5659 
5660     return true;
5661 }
5662 
5663 /** Get descriptors of buffers necessary for test
5664  *
5665  * @param ignored
5666  * @param ignored
5667  **/
5668 void BufferTestBase::getBufferDescriptors(glw::GLuint /* test_case_index */,
5669                                           bufferDescriptor::Vector & /* out_descriptors */)
5670 {
5671     /* Nothhing to be done */
5672 }
5673 
5674 /** Get list of names of varyings that will be registered with TransformFeedbackVaryings
5675  *
5676  * @param ignored
5677  * @param ignored
5678  **/
5679 void BufferTestBase::getCapturedVaryings(glw::GLuint /* test_case_index */,
5680                                          Utils::Program::NameVector & /* captured_varyings */,
5681                                          GLint * /* xfb_components */)
5682 {
5683     /* Nothing to be done */
5684 }
5685 
5686 /** Get body of main function for given shader stage
5687  *
5688  * @param ignored
5689  * @param ignored
5690  * @param out_assignments  Set to empty
5691  * @param out_calculations Set to empty
5692  **/
5693 void BufferTestBase::getShaderBody(glw::GLuint /* test_case_index */, Utils::Shader::STAGES /* stage */,
5694                                    std::string &out_assignments, std::string &out_calculations)
5695 {
5696     out_assignments  = "";
5697     out_calculations = "";
5698 }
5699 
5700 /** Get interface of shader
5701  *
5702  * @param ignored
5703  * @param ignored
5704  * @param out_interface Set to ""
5705  **/
5706 void BufferTestBase::getShaderInterface(glw::GLuint /* test_case_index */, Utils::Shader::STAGES /* stage */,
5707                                         std::string &out_interface)
5708 {
5709     out_interface = "";
5710 }
5711 
5712 /** Get source code of shader
5713  *
5714  * @param test_case_index Index of test case
5715  * @param stage           Shader stage
5716  *
5717  * @return Source
5718  **/
5719 std::string BufferTestBase::getShaderSource(glw::GLuint test_case_index, Utils::Shader::STAGES stage)
5720 {
5721     std::string assignments;
5722     std::string calculations;
5723     std::string interface;
5724 
5725     /* */
5726     getShaderBody(test_case_index, stage, assignments, calculations);
5727     getShaderInterface(test_case_index, stage, interface);
5728 
5729     /* */
5730     std::string source = getShaderTemplate(stage);
5731 
5732     /* */
5733     size_t position = 0;
5734     Utils::replaceToken("INTERFACE", position, interface.c_str(), source);
5735     Utils::replaceToken("CALCULATIONS", position, calculations.c_str(), source);
5736     Utils::replaceToken("ASSIGNMENTS", position, assignments.c_str(), source);
5737 
5738     /* */
5739     return source;
5740 }
5741 
5742 /** Inspects program to check if all resources are as expected
5743  *
5744  * @param ignored
5745  * @param ignored
5746  * @param ignored
5747  *
5748  * @return true
5749  **/
5750 bool BufferTestBase::inspectProgram(GLuint /* test_case_index */, Utils::Program & /* program */,
5751                                     std::stringstream & /* out_stream */)
5752 {
5753     return true;
5754 }
5755 
5756 /** Runs test case
5757  *
5758  * @param test_case_index Id of test case
5759  *
5760  * @return true if test case pass, false otherwise
5761  **/
5762 bool BufferTestBase::testCase(GLuint test_case_index)
5763 {
5764     try
5765     {
5766         bufferCollection buffers;
5767         Utils::Program::NameVector captured_varyings;
5768         bufferDescriptor::Vector descriptors;
5769         Utils::Program program(m_context);
5770         Utils::VertexArray vao(m_context);
5771 
5772         /* Get captured varyings */
5773         GLint xfb_components;
5774         getCapturedVaryings(test_case_index, captured_varyings, &xfb_components);
5775 
5776         /* Don't generate shaders that try to capture more XFB components than the implementation's limit */
5777         if (captured_varyings.size() > 0)
5778         {
5779             const Functions &gl = m_context.getRenderContext().getFunctions();
5780 
5781             GLint max_xfb_components;
5782             gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_xfb_components);
5783             GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
5784 
5785             if (xfb_components > max_xfb_components)
5786                 return true;
5787         }
5788 
5789         /* Get shader sources */
5790         const std::string &fragment_shader  = getShaderSource(test_case_index, Utils::Shader::FRAGMENT);
5791         const std::string &geometry_shader  = getShaderSource(test_case_index, Utils::Shader::GEOMETRY);
5792         const std::string &tess_ctrl_shader = getShaderSource(test_case_index, Utils::Shader::TESS_CTRL);
5793         const std::string &tess_eval_shader = getShaderSource(test_case_index, Utils::Shader::TESS_EVAL);
5794         const std::string &vertex_shader    = getShaderSource(test_case_index, Utils::Shader::VERTEX);
5795 
5796         /* Set up program */
5797         program.Init("" /* compute_shader */, fragment_shader, geometry_shader, tess_ctrl_shader, tess_eval_shader,
5798                      vertex_shader, captured_varyings, true, false /* is_separable */);
5799 
5800         /* Inspection */
5801         {
5802             std::stringstream stream;
5803             if (false == inspectProgram(test_case_index, program, stream))
5804             {
5805                 m_context.getTestContext().getLog()
5806                     << tcu::TestLog::Message
5807                     << "Program inspection failed. Test case: " << getTestCaseName(test_case_index)
5808                     << ". Reason: " << stream.str() << tcu::TestLog::EndMessage
5809                     << tcu::TestLog::KernelSource(vertex_shader) << tcu::TestLog::KernelSource(tess_ctrl_shader)
5810                     << tcu::TestLog::KernelSource(tess_eval_shader) << tcu::TestLog::KernelSource(geometry_shader)
5811                     << tcu::TestLog::KernelSource(fragment_shader);
5812 
5813                 return false;
5814             }
5815         }
5816 
5817         program.Use();
5818 
5819         /* Set up buffers */
5820         getBufferDescriptors(test_case_index, descriptors);
5821         cleanBuffers();
5822         prepareBuffers(descriptors, buffers);
5823 
5824         /* Set up vao */
5825         vao.Init();
5826         vao.Bind();
5827 
5828         /* Draw */
5829         bool result = executeDrawCall((program.m_tess_eval.m_id != 0), test_case_index);
5830 
5831 #if USE_NSIGHT
5832         m_context.getRenderContext().postIterate();
5833 #endif
5834 
5835         if (false == result)
5836         {
5837             m_context.getTestContext().getLog()
5838                 << tcu::TestLog::KernelSource(vertex_shader) << tcu::TestLog::KernelSource(tess_ctrl_shader)
5839                 << tcu::TestLog::KernelSource(tess_eval_shader) << tcu::TestLog::KernelSource(geometry_shader)
5840                 << tcu::TestLog::KernelSource(fragment_shader);
5841 
5842             return false;
5843         }
5844 
5845         /* Verify result */
5846         if (false == verifyBuffers(buffers))
5847         {
5848             m_context.getTestContext().getLog()
5849                 << tcu::TestLog::KernelSource(vertex_shader) << tcu::TestLog::KernelSource(tess_ctrl_shader)
5850                 << tcu::TestLog::KernelSource(tess_eval_shader) << tcu::TestLog::KernelSource(geometry_shader)
5851                 << tcu::TestLog::KernelSource(fragment_shader);
5852 
5853             return false;
5854         }
5855     }
5856     catch (Utils::Shader::InvalidSourceException &exc)
5857     {
5858         exc.log(m_context);
5859         TCU_FAIL(exc.what());
5860     }
5861     catch (Utils::Program::BuildException &exc)
5862     {
5863         exc.log(m_context);
5864         TCU_FAIL(exc.what());
5865     }
5866 
5867     /* Done */
5868     return true;
5869 }
5870 
5871 /** Verify contents of buffers
5872  *
5873  * @param buffers Collection of buffers to be verified
5874  *
5875  * @return true if everything is as expected, false otherwise
5876  **/
5877 bool BufferTestBase::verifyBuffers(bufferCollection &buffers)
5878 {
5879     bool result = true;
5880 
5881     for (bufferCollection::Vector::iterator it = buffers.m_vector.begin(), end = buffers.m_vector.end(); end != it;
5882          ++it)
5883     {
5884         bufferCollection::pair &pair = *it;
5885         Utils::Buffer *buffer        = pair.m_buffer;
5886         bufferDescriptor *descriptor = pair.m_descriptor;
5887         size_t size                  = descriptor->m_expected_data.size();
5888 
5889         /* Skip buffers that have no expected data */
5890         if (0 == size)
5891         {
5892             continue;
5893         }
5894 
5895         /* Get pointer to contents of buffer */
5896         buffer->Bind();
5897         GLvoid *buffer_data = buffer->Map(Utils::Buffer::ReadOnly);
5898 
5899         /* Get pointer to expected data */
5900         GLvoid *expected_data = &descriptor->m_expected_data[0];
5901 
5902         /* Compare */
5903         int res = memcmp(buffer_data, expected_data, size);
5904 
5905         if (0 != res)
5906         {
5907             m_context.getTestContext().getLog()
5908                 << tcu::TestLog::Message
5909                 << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
5910                 << ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
5911 
5912             result = false;
5913         }
5914 
5915         /* Release buffer mapping */
5916         buffer->UnMap();
5917     }
5918 
5919     return result;
5920 }
5921 
5922 /** Unbinds all uniforms and xfb
5923  *
5924  **/
5925 void BufferTestBase::cleanBuffers()
5926 {
5927     const Functions &gl = m_context.getRenderContext().getFunctions();
5928 
5929     GLint max_uni = 0;
5930     GLint max_xfb = 0;
5931 
5932     gl.getIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &max_uni);
5933     gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_xfb);
5934     GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
5935 
5936     for (GLint i = 0; i < max_uni; ++i)
5937     {
5938         Utils::Buffer::BindBase(gl, 0, Utils::Buffer::Uniform, i);
5939     }
5940 
5941     for (GLint i = 0; i < max_xfb; ++i)
5942     {
5943         Utils::Buffer::BindBase(gl, 0, Utils::Buffer::Transform_feedback, i);
5944     }
5945 }
5946 
5947 /** Get template of shader for given stage
5948  *
5949  * @param stage Stage
5950  *
5951  * @return Template of shader source
5952  **/
5953 std::string BufferTestBase::getShaderTemplate(Utils::Shader::STAGES stage)
5954 {
5955     static const GLchar *compute_shader_template = "#version 430 core\n"
5956                                                    "#extension GL_ARB_enhanced_layouts : require\n"
5957                                                    "\n"
5958                                                    "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
5959                                                    "\n"
5960                                                    "writeonly uniform uimage2D uni_image;\n"
5961                                                    "\n"
5962                                                    "INTERFACE"
5963                                                    "\n"
5964                                                    "void main()\n"
5965                                                    "{\n"
5966                                                    "CALCULATIONS"
5967                                                    "\n"
5968                                                    "ASSIGNMENTS"
5969                                                    "}\n"
5970                                                    "\n";
5971 
5972     static const GLchar *fragment_shader_template = "#version 430 core\n"
5973                                                     "#extension GL_ARB_enhanced_layouts : require\n"
5974                                                     "\n"
5975                                                     "INTERFACE"
5976                                                     "\n"
5977                                                     "void main()\n"
5978                                                     "{\n"
5979                                                     "CALCULATIONS"
5980                                                     "\n"
5981                                                     "ASSIGNMENTS"
5982                                                     "}\n"
5983                                                     "\n";
5984 
5985     // max_vertices is set to 3 for the test case "xfb_vertex_streams" declares 3 streams in geometry shader,
5986     // according to spec, max_vertices should be no less than 3 if there are 3 streams in GS.
5987     static const GLchar *geometry_shader_template = "#version 430 core\n"
5988                                                     "#extension GL_ARB_enhanced_layouts : require\n"
5989                                                     "\n"
5990                                                     "layout(points)                   in;\n"
5991                                                     "layout(points, max_vertices = 3) out;\n"
5992                                                     "\n"
5993                                                     "INTERFACE"
5994                                                     "\n"
5995                                                     "void main()\n"
5996                                                     "{\n"
5997                                                     "CALCULATIONS"
5998                                                     "\n"
5999                                                     "\n"
6000                                                     "ASSIGNMENTS"
6001                                                     "    gl_Position  = vec4(0, 0, 0, 1);\n"
6002                                                     "    EmitVertex();\n"
6003                                                     "}\n"
6004                                                     "\n";
6005 
6006     static const GLchar *tess_ctrl_shader_template = "#version 430 core\n"
6007                                                      "#extension GL_ARB_enhanced_layouts : require\n"
6008                                                      "\n"
6009                                                      "layout(vertices = 1) out;\n"
6010                                                      "\n"
6011                                                      "INTERFACE"
6012                                                      "\n"
6013                                                      "void main()\n"
6014                                                      "{\n"
6015                                                      "CALCULATIONS"
6016                                                      "\n"
6017                                                      "ASSIGNMENTS"
6018                                                      "\n"
6019                                                      "    gl_TessLevelOuter[0] = 1.0;\n"
6020                                                      "    gl_TessLevelOuter[1] = 1.0;\n"
6021                                                      "    gl_TessLevelOuter[2] = 1.0;\n"
6022                                                      "    gl_TessLevelOuter[3] = 1.0;\n"
6023                                                      "    gl_TessLevelInner[0] = 1.0;\n"
6024                                                      "    gl_TessLevelInner[1] = 1.0;\n"
6025                                                      "}\n"
6026                                                      "\n";
6027 
6028     static const GLchar *tess_eval_shader_template = "#version 430 core\n"
6029                                                      "#extension GL_ARB_enhanced_layouts : require\n"
6030                                                      "\n"
6031                                                      "layout(isolines, point_mode) in;\n"
6032                                                      "\n"
6033                                                      "INTERFACE"
6034                                                      "\n"
6035                                                      "void main()\n"
6036                                                      "{\n"
6037                                                      "CALCULATIONS"
6038                                                      "\n"
6039                                                      "ASSIGNMENTS"
6040                                                      "}\n"
6041                                                      "\n";
6042 
6043     static const GLchar *vertex_shader_template = "#version 430 core\n"
6044                                                   "#extension GL_ARB_enhanced_layouts : require\n"
6045                                                   "\n"
6046                                                   "INTERFACE"
6047                                                   "\n"
6048                                                   "void main()\n"
6049                                                   "{\n"
6050                                                   "CALCULATIONS"
6051                                                   "\n"
6052                                                   "ASSIGNMENTS"
6053                                                   "}\n"
6054                                                   "\n";
6055 
6056     const GLchar *result = 0;
6057 
6058     switch (stage)
6059     {
6060     case Utils::Shader::COMPUTE:
6061         result = compute_shader_template;
6062         break;
6063     case Utils::Shader::FRAGMENT:
6064         result = fragment_shader_template;
6065         break;
6066     case Utils::Shader::GEOMETRY:
6067         result = geometry_shader_template;
6068         break;
6069     case Utils::Shader::TESS_CTRL:
6070         result = tess_ctrl_shader_template;
6071         break;
6072     case Utils::Shader::TESS_EVAL:
6073         result = tess_eval_shader_template;
6074         break;
6075     case Utils::Shader::VERTEX:
6076         result = vertex_shader_template;
6077         break;
6078     default:
6079         TCU_FAIL("Invalid enum");
6080     }
6081 
6082     return result;
6083 }
6084 
6085 /** Prepare buffer according to descriptor
6086  *
6087  * @param buffer Buffer to prepare
6088  * @param desc   Descriptor
6089  **/
6090 void BufferTestBase::prepareBuffer(Utils::Buffer &buffer, bufferDescriptor &desc)
6091 {
6092     GLsizeiptr size = 0;
6093     GLvoid *data    = 0;
6094 
6095     if (false == desc.m_initial_data.empty())
6096     {
6097         size = desc.m_initial_data.size();
6098         data = &desc.m_initial_data[0];
6099     }
6100     else if (false == desc.m_expected_data.empty())
6101     {
6102         size = desc.m_expected_data.size();
6103     }
6104 
6105     buffer.Init(desc.m_target, Utils::Buffer::StaticDraw, size, data);
6106 
6107     if (bufferDescriptor::m_non_indexed != desc.m_index)
6108     {
6109         buffer.BindBase(desc.m_index);
6110     }
6111     else
6112     {
6113         buffer.Bind();
6114     }
6115 }
6116 
6117 /** Prepare collection of buffer
6118  *
6119  * @param descriptors Collection of descriptors
6120  * @param out_buffers Collection of buffers
6121  **/
6122 void BufferTestBase::prepareBuffers(bufferDescriptor::Vector &descriptors, bufferCollection &out_buffers)
6123 {
6124     for (bufferDescriptor::Vector::iterator it = descriptors.begin(), end = descriptors.end(); end != it; ++it)
6125     {
6126         bufferCollection::pair pair;
6127 
6128         pair.m_buffer = new Utils::Buffer(m_context);
6129         if (0 == pair.m_buffer)
6130         {
6131             TCU_FAIL("Memory allocation failed");
6132         }
6133 
6134         pair.m_descriptor = &(*it);
6135 
6136         prepareBuffer(*pair.m_buffer, *pair.m_descriptor);
6137 
6138         out_buffers.m_vector.push_back(pair);
6139     }
6140 }
6141 
6142 /** Destructor
6143  *
6144  **/
6145 BufferTestBase::bufferCollection::~bufferCollection()
6146 {
6147     for (Vector::iterator it = m_vector.begin(), end = m_vector.end(); end != it; ++it)
6148     {
6149         if (0 != it->m_buffer)
6150         {
6151             delete it->m_buffer;
6152             it->m_buffer = 0;
6153         }
6154     }
6155 }
6156 
6157 /** Constructor
6158  *
6159  * @param context          Test context
6160  * @param test_name        Name of test
6161  * @param test_description Description of test
6162  **/
6163 NegativeTestBase::NegativeTestBase(deqp::Context &context, const GLchar *test_name, const GLchar *test_description)
6164     : TestBase(context, test_name, test_description)
6165 {
6166 }
6167 
6168 /** Selects if "compute" stage is relevant for test
6169  *
6170  * @param ignored
6171  *
6172  * @return true
6173  **/
6174 bool NegativeTestBase::isComputeRelevant(GLuint /* test_case_index */)
6175 {
6176     return true;
6177 }
6178 
6179 /** Selects if compilation failure is expected result
6180  *
6181  * @param ignored
6182  *
6183  * @return true
6184  **/
6185 bool NegativeTestBase::isFailureExpected(GLuint /* test_case_index */)
6186 {
6187     return true;
6188 }
6189 
6190 /** Selects if the test case should use a separable program
6191  *
6192  * @param ignored
6193  *
6194  * @return false
6195  **/
6196 bool NegativeTestBase::isSeparable(const GLuint /* test_case_index */)
6197 {
6198     return false;
6199 }
6200 
6201 /** Runs test case
6202  *
6203  * @param test_case_index Id of test case
6204  *
6205  * @return true if test case pass, false otherwise
6206  **/
6207 bool NegativeTestBase::testCase(GLuint test_case_index)
6208 {
6209     bool test_case_result = true;
6210 
6211     /* Compute */
6212     if (true == isComputeRelevant(test_case_index))
6213     {
6214         const std::string &cs_source   = getShaderSource(test_case_index, Utils::Shader::COMPUTE);
6215         bool is_build_error            = false;
6216         const bool is_failure_expected = isFailureExpected(test_case_index);
6217         Utils::Program program(m_context);
6218 
6219         try
6220         {
6221             program.Init(cs_source, "" /* fs */, "" /* gs */, "" /* tcs */, "" /* tes */, "" /* vs */,
6222                          false /* separable */);
6223         }
6224         catch (Utils::Shader::InvalidSourceException &exc)
6225         {
6226             if (false == is_failure_expected)
6227             {
6228                 m_context.getTestContext().getLog()
6229                     << tcu::TestLog::Message << "Unexpected error in shader compilation: " << tcu::TestLog::EndMessage;
6230                 exc.log(m_context);
6231             }
6232 
6233 #if DEBUG_NEG_LOG_ERROR
6234 
6235             else
6236             {
6237                 m_context.getTestContext().getLog()
6238                     << tcu::TestLog::Message << "Error in shader compilation was expected, logged for verification: "
6239                     << tcu::TestLog::EndMessage;
6240                 exc.log(m_context);
6241             }
6242 
6243 #endif /* DEBUG_NEG_LOG_ERROR */
6244 
6245             is_build_error = true;
6246         }
6247         catch (Utils::Program::BuildException &exc)
6248         {
6249             if (false == is_failure_expected)
6250             {
6251                 m_context.getTestContext().getLog()
6252                     << tcu::TestLog::Message << "Unexpected error in program linking: " << tcu::TestLog::EndMessage;
6253                 exc.log(m_context);
6254             }
6255 
6256 #if DEBUG_NEG_LOG_ERROR
6257 
6258             else
6259             {
6260                 m_context.getTestContext().getLog()
6261                     << tcu::TestLog::Message
6262                     << "Error in program linking was expected, logged for verification: " << tcu::TestLog::EndMessage;
6263                 exc.log(m_context);
6264             }
6265 
6266 #endif /* DEBUG_NEG_LOG_ERROR */
6267 
6268             is_build_error = true;
6269         }
6270 
6271         if (is_build_error != is_failure_expected)
6272         {
6273             if (!is_build_error)
6274             {
6275                 m_context.getTestContext().getLog()
6276                     << tcu::TestLog::Message << "Unexpected success: " << tcu::TestLog::EndMessage;
6277                 Utils::Shader::LogSource(m_context, cs_source, Utils::Shader::COMPUTE);
6278             }
6279             test_case_result = false;
6280         }
6281     }
6282     else /* Draw */
6283     {
6284         const std::string &fs_source   = getShaderSource(test_case_index, Utils::Shader::FRAGMENT);
6285         const std::string &gs_source   = getShaderSource(test_case_index, Utils::Shader::GEOMETRY);
6286         bool is_build_error            = false;
6287         const bool is_failure_expected = isFailureExpected(test_case_index);
6288         Utils::Program program(m_context);
6289         const std::string &tcs_source = getShaderSource(test_case_index, Utils::Shader::TESS_CTRL);
6290         const std::string &tes_source = getShaderSource(test_case_index, Utils::Shader::TESS_EVAL);
6291         const std::string &vs_source  = getShaderSource(test_case_index, Utils::Shader::VERTEX);
6292 
6293         try
6294         {
6295             if (isSeparable(test_case_index))
6296             {
6297                 program.Init("" /*cs*/, fs_source, "" /*gs_source*/, "" /*tcs_source*/, "" /*tes_source*/,
6298                              "" /*vs_source*/, true /* separable */);
6299                 program.Init("" /*cs*/, "" /*fs_source*/, gs_source, "" /*tcs_source*/, "" /*tes_source*/,
6300                              "" /*vs_source*/, true /* separable */);
6301                 program.Init("" /*cs*/, "" /*fs_source*/, "" /*gs_source*/, tcs_source, "" /*tes_source*/,
6302                              "" /*vs_source*/, true /* separable */);
6303                 program.Init("" /*cs*/, "" /*fs_source*/, "" /*gs_source*/, "" /*tcs_source*/, tes_source,
6304                              "" /*vs_source*/, true /* separable */);
6305                 program.Init("" /*cs*/, "" /*fs_source*/, "" /*gs_source*/, "" /*tcs_source*/, "" /*tes_source*/,
6306                              vs_source, true /* separable */);
6307             }
6308             else
6309             {
6310                 program.Init("" /* cs */, fs_source, gs_source, tcs_source, tes_source, vs_source,
6311                              false /* separable */);
6312             }
6313         }
6314         catch (Utils::Shader::InvalidSourceException &exc)
6315         {
6316             if (false == is_failure_expected)
6317             {
6318                 m_context.getTestContext().getLog()
6319                     << tcu::TestLog::Message << "Unexpected error in shader compilation: " << tcu::TestLog::EndMessage;
6320                 exc.log(m_context);
6321             }
6322 
6323 #if DEBUG_NEG_LOG_ERROR
6324 
6325             else
6326             {
6327                 m_context.getTestContext().getLog()
6328                     << tcu::TestLog::Message << "Error in shader compilation was expected, logged for verification: "
6329                     << tcu::TestLog::EndMessage;
6330                 exc.log(m_context);
6331             }
6332 
6333 #endif /* DEBUG_NEG_LOG_ERROR */
6334 
6335             is_build_error = true;
6336         }
6337         catch (Utils::Program::BuildException &exc)
6338         {
6339             if (false == is_failure_expected)
6340             {
6341                 m_context.getTestContext().getLog()
6342                     << tcu::TestLog::Message << "Unexpected error in program linking: " << tcu::TestLog::EndMessage;
6343                 exc.log(m_context);
6344             }
6345 
6346 #if DEBUG_NEG_LOG_ERROR
6347 
6348             else
6349             {
6350                 m_context.getTestContext().getLog()
6351                     << tcu::TestLog::Message
6352                     << "Error in program linking was expected, logged for verification: " << tcu::TestLog::EndMessage;
6353                 exc.log(m_context);
6354             }
6355 
6356 #endif /* DEBUG_NEG_LOG_ERROR */
6357 
6358             is_build_error = true;
6359         }
6360 
6361         if (is_build_error != is_failure_expected)
6362         {
6363             if (!is_build_error)
6364             {
6365                 m_context.getTestContext().getLog()
6366                     << tcu::TestLog::Message << "Unexpected success: " << tcu::TestLog::EndMessage;
6367                 Utils::Shader::LogSource(m_context, vs_source, Utils::Shader::VERTEX);
6368                 Utils::Shader::LogSource(m_context, tcs_source, Utils::Shader::TESS_CTRL);
6369                 Utils::Shader::LogSource(m_context, tes_source, Utils::Shader::TESS_EVAL);
6370                 Utils::Shader::LogSource(m_context, gs_source, Utils::Shader::GEOMETRY);
6371                 Utils::Shader::LogSource(m_context, fs_source, Utils::Shader::FRAGMENT);
6372             }
6373             test_case_result = false;
6374         }
6375     }
6376 
6377     return test_case_result;
6378 }
6379 
6380 /* Constants used by TextureTestBase */
6381 const glw::GLuint TextureTestBase::m_width  = 16;
6382 const glw::GLuint TextureTestBase::m_height = 16;
6383 
6384 /** Constructor
6385  *
6386  * @param context          Test context
6387  * @param test_name        Name of test
6388  * @param test_description Description of test
6389  **/
6390 TextureTestBase::TextureTestBase(deqp::Context &context, const GLchar *test_name, const GLchar *test_description)
6391     : TestBase(context, test_name, test_description)
6392 {
6393 }
6394 
6395 /** Get locations for all inputs with automatic_location
6396  *
6397  * @param program           Program object
6398  * @param program_interface Interface of program
6399  **/
6400 void TextureTestBase::prepareAttribLocation(Utils::Program &program, Utils::ProgramInterface &program_interface)
6401 {
6402     Utils::ShaderInterface &si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
6403 
6404     Utils::Variable::PtrVector &inputs = si.m_inputs;
6405 
6406     for (Utils::Variable::PtrVector::iterator it = inputs.begin(); inputs.end() != it; ++it)
6407     {
6408         /* Test does not specify location, query value and set */
6409         if (Utils::Variable::m_automatic_location == (*it)->m_descriptor.m_expected_location)
6410         {
6411             GLuint index   = program.GetResourceIndex((*it)->m_descriptor.m_name, GL_PROGRAM_INPUT);
6412             GLint location = 0;
6413 
6414             program.GetResource(GL_PROGRAM_INPUT, index, GL_LOCATION, 1 /* size */, &location);
6415 
6416             (*it)->m_descriptor.m_expected_location = location;
6417         }
6418     }
6419 }
6420 
6421 /** Verifies contents of drawn image
6422  *
6423  * @param ignored
6424  * @param color_0 Verified image
6425  *
6426  * @return true if image is filled with 1, false otherwise
6427  **/
6428 bool TextureTestBase::checkResults(glw::GLuint /* test_case_index */, Utils::Texture &color_0)
6429 {
6430     static const GLuint size           = m_width * m_height;
6431     static const GLuint expected_color = 1;
6432 
6433     std::vector<GLuint> data;
6434     data.resize(size);
6435 
6436     color_0.Get(GL_RED_INTEGER, GL_UNSIGNED_INT, &data[0]);
6437 
6438     for (GLuint i = 0; i < size; ++i)
6439     {
6440         const GLuint color = data[i];
6441 
6442         if (expected_color != color)
6443         {
6444             m_context.getTestContext().getLog()
6445                 << tcu::TestLog::Message << "R32UI[" << i << "]:" << color << tcu::TestLog::EndMessage;
6446             return false;
6447         }
6448     }
6449 
6450     return true;
6451 }
6452 
6453 /** Execute dispatch compute for 16x16x1
6454  *
6455  * @param ignored
6456  **/
6457 void TextureTestBase::executeDispatchCall(GLuint /* test_case_index */)
6458 {
6459     const Functions &gl = m_context.getRenderContext().getFunctions();
6460 
6461     gl.dispatchCompute(16 /* x */, 16 /* y */, 1 /* z */);
6462     GLU_EXPECT_NO_ERROR(gl.getError(), "DispatchCompute");
6463 }
6464 
6465 /** Execute drawArrays for single vertex
6466  *
6467  * @param ignored
6468  **/
6469 void TextureTestBase::executeDrawCall(GLuint /* test_case_index */)
6470 {
6471     const Functions &gl = m_context.getRenderContext().getFunctions();
6472 
6473     gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
6474     GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
6475 }
6476 
6477 /** Prepare code snippet that will pass in variables to out variables
6478  *
6479  * @param ignored
6480  * @param varying_passthrough Collection of connections between in and out variables
6481  * @param stage               Shader stage
6482  *
6483  * @return Code that pass in variables to next stage
6484  **/
6485 std::string TextureTestBase::getPassSnippet(GLuint /* test_case_index */,
6486                                             Utils::VaryingPassthrough &varying_passthrough, Utils::Shader::STAGES stage)
6487 {
6488     static const GLchar *separator = "\n    ";
6489 
6490     /* Skip for compute shader */
6491     if (Utils::Shader::COMPUTE == stage)
6492     {
6493         return "";
6494     }
6495 
6496     Utils::VaryingConnection::Vector &vector = varying_passthrough.Get(stage);
6497 
6498     std::string result = Utils::g_list;
6499     size_t position    = 0;
6500 
6501     for (GLuint i = 0; i < vector.size(); ++i)
6502     {
6503 
6504         Utils::VaryingConnection &connection = vector[i];
6505 
6506         Utils::Variable *in  = connection.m_in;
6507         Utils::Variable *out = connection.m_out;
6508 
6509         Utils::Variable::FLAVOUR in_flavour  = Utils::Variable::GetFlavour(stage, Utils::Variable::INPUT);
6510         Utils::Variable::FLAVOUR out_flavour = Utils::Variable::GetFlavour(stage, Utils::Variable::OUTPUT);
6511 
6512         const std::string passthrough =
6513             getVariablePassthrough("", in->m_descriptor, in_flavour, "", out->m_descriptor, out_flavour);
6514 
6515         Utils::insertElementOfList(passthrough.c_str(), separator, position, result);
6516     }
6517 
6518     Utils::endList("", position, result);
6519 
6520     return result;
6521 }
6522 
6523 /** Basic implementation of method getProgramInterface
6524  *
6525  * @param ignored
6526  * @param ignored
6527  * @param ignored
6528  **/
6529 void TextureTestBase::getProgramInterface(GLuint /* test_case_index */,
6530                                           Utils::ProgramInterface & /* program_interface */,
6531                                           Utils::VaryingPassthrough & /* varying_passthrough */)
6532 {
6533 }
6534 
6535 /** Prepare code snippet that will verify in and uniform variables
6536  *
6537  * @param ignored
6538  * @param program_interface Interface of program
6539  * @param stage             Shader stage
6540  *
6541  * @return Code that verify variables
6542  **/
6543 std::string TextureTestBase::getVerificationSnippet(GLuint /* test_case_index */,
6544                                                     Utils::ProgramInterface &program_interface,
6545                                                     Utils::Shader::STAGES stage)
6546 {
6547     static const GLchar *separator = " ||\n        ";
6548 
6549     std::string verification = "if (LIST)\n"
6550                                "    {\n"
6551                                "        result = 0u;\n"
6552                                "    }\n";
6553 
6554     /* Get flavour of in and out variables */
6555     Utils::Variable::FLAVOUR in_flavour = Utils::Variable::GetFlavour(stage, Utils::Variable::INPUT);
6556 
6557     /* Get interface for shader stage */
6558     Utils::ShaderInterface &si = program_interface.GetShaderInterface(stage);
6559 
6560     /* There are no varialbes to verify */
6561     if ((0 == si.m_inputs.size()) && (0 == si.m_uniforms.size()) && (0 == si.m_ssb_blocks.size()))
6562     {
6563         return "";
6564     }
6565 
6566     /* For each in variable insert verification code */
6567     size_t position = 0;
6568 
6569     for (GLuint i = 0; i < si.m_inputs.size(); ++i)
6570     {
6571         const Utils::Variable &var          = *si.m_inputs[i];
6572         const std::string &var_verification = getVariableVerification("", var.m_data, var.m_descriptor, in_flavour);
6573 
6574         Utils::insertElementOfList(var_verification.c_str(), separator, position, verification);
6575     }
6576 
6577     /* For each unifrom variable insert verification code */
6578     for (GLuint i = 0; i < si.m_uniforms.size(); ++i)
6579     {
6580         const Utils::Variable &var = *si.m_uniforms[i];
6581         const std::string &var_verification =
6582             getVariableVerification("", var.m_data, var.m_descriptor, Utils::Variable::BASIC);
6583 
6584         Utils::insertElementOfList(var_verification.c_str(), separator, position, verification);
6585     }
6586 
6587     /* For each ssb variable insert verification code */
6588     for (GLuint i = 0; i < si.m_ssb_blocks.size(); ++i)
6589     {
6590         const Utils::Variable &var = *si.m_ssb_blocks[i];
6591         const std::string &var_verification =
6592             getVariableVerification("", var.m_data, var.m_descriptor, Utils::Variable::BASIC);
6593 
6594         Utils::insertElementOfList(var_verification.c_str(), separator, position, verification);
6595     }
6596 
6597     Utils::endList("", position, verification);
6598 
6599 #if DEBUG_TTB_VERIFICATION_SNIPPET_STAGE
6600 
6601     {
6602         GLchar buffer[16];
6603         sprintf(buffer, "%d", stage + 10);
6604         Utils::replaceToken("0u", position, buffer, verification);
6605     }
6606 
6607 #elif DEBUG_TTB_VERIFICATION_SNIPPET_VARIABLE
6608 
6609     if (Utils::Shader::VERTEX == stage)
6610     {
6611         Utils::replaceToken("0u", position, "in_vs_first.x", verification);
6612     }
6613     else
6614     {
6615         Utils::replaceToken("0u", position, "31u", verification);
6616     }
6617 
6618 #endif
6619 
6620     /* Done */
6621     return verification;
6622 }
6623 
6624 /** Selects if "compute" stage is relevant for test
6625  *
6626  * @param ignored
6627  *
6628  * @return true
6629  **/
6630 bool TextureTestBase::isComputeRelevant(GLuint /* test_case_index */)
6631 {
6632     return true;
6633 }
6634 
6635 /** Selects if "draw" stages are relevant for test
6636  *
6637  * @param ignored
6638  *
6639  * @return true
6640  **/
6641 bool TextureTestBase::isDrawRelevant(GLuint /* test_case_index */)
6642 {
6643     return true;
6644 }
6645 
6646 /** Prepare code that will do assignment of single in to single out
6647  *
6648  * @param in_parent_name  Name of parent in variable
6649  * @param in_variable     Descriptor of in variable
6650  * @param in_flavour      Flavoud of in variable
6651  * @param out_parent_name Name of parent out variable
6652  * @param out_variable    Descriptor of out variable
6653  * @param out_flavour     Flavoud of out variable
6654  *
6655  * @return Code that does OUT = IN
6656  **/
6657 std::string TextureTestBase::getVariablePassthrough(const std::string &in_parent_name,
6658                                                     const Utils::Variable::Descriptor &in_variable,
6659                                                     Utils::Variable::FLAVOUR in_flavour,
6660                                                     const std::string &out_parent_name,
6661                                                     const Utils::Variable::Descriptor &out_variable,
6662                                                     Utils::Variable::FLAVOUR out_flavour)
6663 {
6664     bool done                      = false;
6665     GLuint index                   = 0;
6666     GLuint member_index            = 0;
6667     size_t position                = 0;
6668     std::string result             = Utils::g_list;
6669     static const GLchar *separator = ";\n    ";
6670 
6671     /* For each member of each array element */
6672     do
6673     {
6674         const std::string in_name  = Utils::Variable::GetReference(in_parent_name, in_variable, in_flavour, index);
6675         const std::string out_name = Utils::Variable::GetReference(out_parent_name, out_variable, out_flavour, index);
6676         std::string passthrough;
6677 
6678         /* Prepare verification */
6679         if (Utils::Variable::BUILTIN == in_variable.m_type)
6680         {
6681             size_t pass_position = 0;
6682 
6683             passthrough = "OUT = IN;";
6684 
6685             Utils::replaceToken("OUT", pass_position, out_name.c_str(), passthrough);
6686             Utils::replaceToken("IN", pass_position, in_name.c_str(), passthrough);
6687 
6688             /* Increment index */
6689             ++index;
6690         }
6691         else
6692         {
6693             const Utils::Interface *in_interface  = in_variable.m_interface;
6694             const Utils::Interface *out_interface = out_variable.m_interface;
6695 
6696             if ((0 == in_interface) || (0 == out_interface))
6697             {
6698                 TCU_FAIL("Nullptr");
6699             }
6700 
6701             const Utils::Variable::Descriptor &in_member  = in_interface->m_members[member_index];
6702             const Utils::Variable::Descriptor &out_member = out_interface->m_members[member_index];
6703 
6704             passthrough = getVariablePassthrough(in_name, in_member, Utils::Variable::BASIC, out_name, out_member,
6705                                                  Utils::Variable::BASIC);
6706 
6707             /* Increment member_index */
6708             ++member_index;
6709 
6710             /* Increment index and reset member_index if all members were processed */
6711             if (in_interface->m_members.size() == member_index)
6712             {
6713                 ++index;
6714                 member_index = 0;
6715             }
6716         }
6717 
6718         /* Check if loop should end */
6719         if ((index >= in_variable.m_n_array_elements) && (0 == member_index))
6720         {
6721             done = true;
6722         }
6723 
6724         Utils::insertElementOfList(passthrough.c_str(), separator, position, result);
6725 
6726     } while (true != done);
6727 
6728     Utils::endList("", position, result);
6729 
6730     /* Done */
6731     return result;
6732 }
6733 
6734 /** Get verification of single variable
6735  *
6736  * @param parent_name Name of parent variable
6737  * @param data        Data that should be used as EXPECTED
6738  * @param variable    Descriptor of variable
6739  * @param flavour     Flavour of variable
6740  *
6741  * @return Code that does (EXPECTED != VALUE) ||
6742  **/
6743 std::string TextureTestBase::getVariableVerification(const std::string &parent_name, const GLvoid *data,
6744                                                      const Utils::Variable::Descriptor &variable,
6745                                                      Utils::Variable::FLAVOUR flavour)
6746 {
6747     static const GLchar *logic_op = " ||\n        ";
6748     const GLuint n_elements       = (0 == variable.m_n_array_elements) ? 1 : variable.m_n_array_elements;
6749     size_t position               = 0;
6750     std::string result            = Utils::g_list;
6751     GLint stride                  = variable.m_expected_stride_of_element;
6752 
6753     /* For each each array element */
6754     for (GLuint element = 0; element < n_elements; ++element)
6755     {
6756         const std::string name = Utils::Variable::GetReference(parent_name, variable, flavour, element);
6757 
6758         /* Calculate data pointer */
6759         GLvoid *data_ptr = (GLvoid *)((GLubyte *)data + element * stride);
6760 
6761         /* Prepare verification */
6762         if (Utils::Variable::BUILTIN == variable.m_type)
6763         {
6764             const std::string &expected = variable.m_builtin.GetGLSLConstructor(data_ptr);
6765             std::string verification;
6766             size_t verification_position = 0;
6767 
6768             verification = "(EXPECTED != NAME)";
6769 
6770             Utils::replaceToken("EXPECTED", verification_position, expected.c_str(), verification);
6771             Utils::replaceToken("NAME", verification_position, name.c_str(), verification);
6772 
6773             Utils::insertElementOfList(verification.c_str(), logic_op, position, result);
6774         }
6775         else
6776         {
6777             const Utils::Interface *interface = variable.m_interface;
6778 
6779             if (0 == interface)
6780             {
6781                 TCU_FAIL("Nullptr");
6782             }
6783 
6784             const GLuint n_members = static_cast<GLuint>(interface->m_members.size());
6785 
6786             /* for each member */
6787             for (GLuint member_index = 0; member_index < n_members; ++member_index)
6788             {
6789                 const Utils::Variable::Descriptor &member = interface->m_members[member_index];
6790 
6791                 /* Get verification of member */
6792                 const std::string &verification = getVariableVerification(name, (GLubyte *)data_ptr + member.m_offset,
6793                                                                           member, Utils::Variable::BASIC);
6794 
6795                 Utils::insertElementOfList(verification.c_str(), logic_op, position, result);
6796             }
6797         }
6798     }
6799 
6800     Utils::endList("", position, result);
6801 
6802     return result;
6803 }
6804 
6805 /** Prepare attributes, vertex array object and array buffer
6806  *
6807  * @param test_case_index   Index of test case
6808  * @param program_interface Interface of program
6809  * @param buffer            Array buffer
6810  * @param vao               Vertex array object
6811  **/
6812 void TextureTestBase::prepareAttributes(GLuint test_case_index, Utils::ProgramInterface &program_interface,
6813                                         Utils::Buffer &buffer, Utils::VertexArray &vao)
6814 {
6815     const bool use_component_qualifier = useComponentQualifier(test_case_index);
6816 
6817     /* Get shader interface */
6818     const Utils::ShaderInterface &si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
6819 
6820     /* Bind vao and buffer */
6821     vao.Bind();
6822     buffer.Bind();
6823 
6824     /* Skip if there are no input variables in vertex shader */
6825     if (0 == si.m_inputs.size())
6826     {
6827         return;
6828     }
6829 
6830     const Functions &gl = m_context.getRenderContext().getFunctions();
6831 
6832     /* Calculate vertex stride and check */
6833     GLint max_inputs;
6834     gl.getIntegerv(GL_MAX_VERTEX_ATTRIBS, &max_inputs);
6835     GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
6836 
6837     /* dvec3/4 vertex inputs use a single location but require 2x16B slots */
6838     const GLuint max_slots = max_inputs * 2;
6839 
6840     /* Compute used slots */
6841     std::vector<GLuint> slot_sizes(max_slots, 0);
6842     for (GLuint i = 0; i < si.m_inputs.size(); ++i)
6843     {
6844         const Utils::Variable &variable = *si.m_inputs[i];
6845 
6846         const GLuint variable_size = static_cast<GLuint>(variable.m_data_size);
6847 
6848         const GLuint base_slot = variable.m_descriptor.m_expected_location + variable.m_descriptor.m_offset / 16;
6849         const GLuint ends_at   = variable.m_descriptor.m_offset % 16 + variable_size;
6850 
6851         const GLuint array_length = std::max(1u, variable.m_descriptor.m_n_array_elements);
6852         for (GLuint loc = 0; loc < array_length; loc++)
6853         {
6854             const GLuint slot = base_slot + loc;
6855             slot_sizes[slot]  = std::max(slot_sizes[slot], ends_at);
6856         }
6857     }
6858 
6859     /* Compute the offsets where we need to put vertex buffer data for each slot */
6860     std::vector<GLint> slot_offsets(max_slots, -1);
6861     GLuint buffer_size = 0;
6862     for (GLuint i = 0; i < max_slots; i++)
6863     {
6864         if (slot_sizes[i] == 0)
6865             continue;
6866         slot_offsets[i] = buffer_size;
6867         buffer_size += slot_sizes[i];
6868     }
6869 
6870     /* Prepare buffer data and set up vao */
6871     std::vector<GLubyte> buffer_data(buffer_size);
6872 
6873     GLubyte *ptr = &buffer_data[0];
6874 
6875     for (GLuint i = 0; i < si.m_inputs.size(); ++i)
6876     {
6877         const Utils::Variable &variable = *si.m_inputs[i];
6878 
6879         const GLuint base_slot       = variable.m_descriptor.m_expected_location + variable.m_descriptor.m_offset / 16;
6880         const GLuint variable_offset = variable.m_descriptor.m_offset % 16;
6881         const GLuint array_length    = std::max(1u, variable.m_descriptor.m_n_array_elements);
6882         for (GLuint loc = 0; loc < array_length; loc++)
6883         {
6884             const GLuint slot = base_slot + loc;
6885             memcpy(ptr + slot_offsets[slot] + variable_offset, variable.m_data, variable.m_data_size);
6886         }
6887 
6888         if (!use_component_qualifier)
6889         {
6890             vao.Attribute(variable.m_descriptor.m_expected_location, variable.m_descriptor.m_builtin,
6891                           variable.m_descriptor.m_n_array_elements, variable.m_descriptor.m_normalized,
6892                           variable.GetStride(), (GLvoid *)(intptr_t)(slot_offsets[base_slot] + variable_offset));
6893         }
6894         else if (0 == variable.m_descriptor.m_expected_component)
6895         {
6896             /* Components can only be applied to types not surpassing
6897              * the bounds of a single slot. Therefore, we calculate
6898              * the amount of used components in the varying based on
6899              * the calculated slot sizes.
6900              */
6901             const GLuint n_component_size = Utils::Type::Double == variable.m_descriptor.m_builtin.m_basic_type ? 8 : 4;
6902             const GLuint n_rows           = slot_sizes[base_slot] / n_component_size;
6903 
6904             const Utils::Type &type = Utils::Type::GetType(variable.m_descriptor.m_builtin.m_basic_type,
6905                                                            1 /* n_columns */, n_rows /* n_rows */);
6906 
6907             vao.Attribute(variable.m_descriptor.m_expected_location, type, variable.m_descriptor.m_n_array_elements,
6908                           variable.m_descriptor.m_normalized, variable.GetStride(),
6909                           (GLvoid *)(intptr_t)(slot_offsets[base_slot] + variable_offset));
6910         }
6911     }
6912 
6913     /* Update buffer */
6914     buffer.Data(Utils::Buffer::StaticDraw, buffer_size, ptr);
6915 }
6916 
6917 /** Get locations for all outputs with automatic_location
6918  *
6919  * @param program           Program object
6920  * @param program_interface Interface of program
6921  **/
6922 void TextureTestBase::prepareFragmentDataLoc(Utils::Program &program, Utils::ProgramInterface &program_interface)
6923 {
6924     Utils::ShaderInterface &si          = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
6925     Utils::Variable::PtrVector &outputs = si.m_outputs;
6926 
6927     for (Utils::Variable::PtrVector::iterator it = outputs.begin(); outputs.end() != it; ++it)
6928     {
6929         /* Test does not specify location, query value and set */
6930         if (Utils::Variable::m_automatic_location == (*it)->m_descriptor.m_expected_location)
6931         {
6932             GLuint index   = program.GetResourceIndex((*it)->m_descriptor.m_name, GL_PROGRAM_OUTPUT);
6933             GLint location = 0;
6934 
6935             program.GetResource(GL_PROGRAM_OUTPUT, index, GL_LOCATION, 1 /* size */, &location);
6936 
6937             (*it)->m_descriptor.m_expected_location = location;
6938         }
6939     }
6940 }
6941 
6942 /** Prepare framebuffer with single texture as color attachment
6943  *
6944  * @param framebuffer     Framebuffer
6945  * @param color_0_texture Texture that will used as color attachment
6946  **/
6947 void TextureTestBase::prepareFramebuffer(Utils::Framebuffer &framebuffer, Utils::Texture &color_0_texture)
6948 {
6949     /* Prepare data */
6950     std::vector<GLuint> texture_data;
6951     texture_data.resize(m_width * m_height);
6952 
6953     for (GLuint i = 0; i < texture_data.size(); ++i)
6954     {
6955         texture_data[i] = 0x20406080;
6956     }
6957 
6958     /* Prepare texture */
6959     color_0_texture.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT,
6960                          &texture_data[0]);
6961 
6962     /* Prepare framebuffer */
6963     framebuffer.Init();
6964     framebuffer.Bind();
6965     framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0, color_0_texture.m_id, m_width, m_height);
6966 
6967     framebuffer.ClearColor(0.0f, 0.0f, 0.0f, 0.0f);
6968     framebuffer.Clear(GL_COLOR_BUFFER_BIT);
6969 }
6970 
6971 /** Prepare iamge unit for compute shader
6972  *
6973  * @param location      Uniform location
6974  * @param image_texture Texture that will used as color attachment
6975  **/
6976 void TextureTestBase::prepareImage(GLint location, Utils::Texture &image_texture) const
6977 {
6978     static const GLuint image_unit = 0;
6979 
6980     std::vector<GLuint> texture_data;
6981     texture_data.resize(m_width * m_height);
6982 
6983     for (GLuint i = 0; i < texture_data.size(); ++i)
6984     {
6985         texture_data[i] = 0x20406080;
6986     }
6987 
6988     image_texture.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT,
6989                        &texture_data[0]);
6990 
6991     const Functions &gl = m_context.getRenderContext().getFunctions();
6992 
6993     gl.bindImageTexture(image_unit, image_texture.m_id, 0 /* level */, GL_FALSE /* layered */, 0 /* Layer */,
6994                         GL_WRITE_ONLY, GL_R32UI);
6995     GLU_EXPECT_NO_ERROR(gl.getError(), "BindImageTexture");
6996 
6997     Utils::Program::Uniform(gl, Utils::Type::_int, 1 /* count */, location, &image_unit);
6998 }
6999 
7000 /** Basic implementation
7001  *
7002  * @param ignored
7003  * @param si        Shader interface
7004  * @param program   Program
7005  * @param cs_buffer Buffer for ssb blocks
7006  **/
7007 void TextureTestBase::prepareSSBs(GLuint /* test_case_index */, Utils::ShaderInterface &si, Utils::Program &program,
7008                                   Utils::Buffer &buffer)
7009 {
7010     /* Skip if there are no input variables in vertex shader */
7011     if (0 == si.m_ssb_blocks.size())
7012     {
7013         return;
7014     }
7015 
7016     /* Calculate vertex stride */
7017     GLint ssbs_stride = 0;
7018 
7019     for (GLuint i = 0; i < si.m_ssb_blocks.size(); ++i)
7020     {
7021         Utils::Variable &variable = *si.m_ssb_blocks[i];
7022 
7023         if (false == variable.IsBlock())
7024         {
7025             continue;
7026         }
7027 
7028         GLint variable_stride = variable.GetStride();
7029 
7030         GLint ends_at = variable_stride + variable.m_descriptor.m_offset;
7031 
7032         ssbs_stride = std::max(ssbs_stride, ends_at);
7033     }
7034 
7035     /* Set active program */
7036     program.Use();
7037 
7038     /* Allocate */
7039     buffer.Bind();
7040     buffer.Data(Utils::Buffer::StaticDraw, ssbs_stride, 0);
7041 
7042     /* Set up uniforms */
7043     for (GLuint i = 0; i < si.m_ssb_blocks.size(); ++i)
7044     {
7045         Utils::Variable &variable = *si.m_ssb_blocks[i];
7046 
7047         /* prepareUnifor should work fine for ssb blocks */
7048         prepareUniform(program, variable, buffer);
7049     }
7050 }
7051 
7052 /** Basic implementation
7053  *
7054  * @param test_case_index   Test case index
7055  * @param program_interface Program interface
7056  * @param program           Program
7057  * @param cs_buffer         Buffer for compute shader stage
7058  **/
7059 void TextureTestBase::prepareSSBs(GLuint test_case_index, Utils::ProgramInterface &program_interface,
7060                                   Utils::Program &program, Utils::Buffer &cs_buffer)
7061 {
7062     cs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
7063 
7064     Utils::ShaderInterface &cs = program_interface.GetShaderInterface(Utils::Shader::COMPUTE);
7065 
7066     prepareSSBs(test_case_index, cs, program, cs_buffer);
7067 
7068     cs_buffer.BindBase(Utils::Shader::COMPUTE);
7069 }
7070 
7071 /** Basic implementation
7072  *
7073  * @param test_case_index   Test case index
7074  * @param program_interface Program interface
7075  * @param program           Program
7076  * @param fs_buffer         Buffer for fragment shader stage
7077  * @param gs_buffer         Buffer for geometry shader stage
7078  * @param tcs_buffer        Buffer for tessellation control shader stage
7079  * @param tes_buffer        Buffer for tessellation evaluation shader stage
7080  * @param vs_buffer         Buffer for vertex shader stage
7081  **/
7082 void TextureTestBase::prepareSSBs(GLuint test_case_index, Utils::ProgramInterface &program_interface,
7083                                   Utils::Program &program, Utils::Buffer &fs_buffer, Utils::Buffer &gs_buffer,
7084                                   Utils::Buffer &tcs_buffer, Utils::Buffer &tes_buffer, Utils::Buffer &vs_buffer)
7085 {
7086     fs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
7087     gs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
7088     tcs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
7089     tes_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
7090     vs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
7091 
7092     Utils::ShaderInterface &fs  = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
7093     Utils::ShaderInterface &gs  = program_interface.GetShaderInterface(Utils::Shader::GEOMETRY);
7094     Utils::ShaderInterface &tcs = program_interface.GetShaderInterface(Utils::Shader::TESS_CTRL);
7095     Utils::ShaderInterface &tes = program_interface.GetShaderInterface(Utils::Shader::TESS_EVAL);
7096     Utils::ShaderInterface &vs  = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
7097 
7098     prepareSSBs(test_case_index, fs, program, fs_buffer);
7099     prepareSSBs(test_case_index, gs, program, gs_buffer);
7100     prepareSSBs(test_case_index, tcs, program, tcs_buffer);
7101     prepareSSBs(test_case_index, tes, program, tes_buffer);
7102     prepareSSBs(test_case_index, vs, program, vs_buffer);
7103 
7104     fs_buffer.BindBase(Utils::Shader::FRAGMENT);
7105     gs_buffer.BindBase(Utils::Shader::GEOMETRY);
7106     tcs_buffer.BindBase(Utils::Shader::TESS_CTRL);
7107     tes_buffer.BindBase(Utils::Shader::TESS_EVAL);
7108     vs_buffer.BindBase(Utils::Shader::VERTEX);
7109 }
7110 
7111 /** Updates buffer data with variable
7112  *
7113  * @param program  Program object
7114  * @param variable Variable
7115  * @param buffer   Buffer
7116  **/
7117 void TextureTestBase::prepareUniform(Utils::Program &program, Utils::Variable &variable, Utils::Buffer &buffer)
7118 {
7119     const Functions &gl = m_context.getRenderContext().getFunctions();
7120 
7121     GLsizei count = variable.m_descriptor.m_n_array_elements;
7122     if (0 == count)
7123     {
7124         count = 1;
7125     }
7126 
7127     if (Utils::Variable::BUILTIN == variable.m_descriptor.m_type)
7128     {
7129         program.Uniform(gl, variable.m_descriptor.m_builtin, count, variable.m_descriptor.m_expected_location,
7130                         variable.m_data);
7131     }
7132     else
7133     {
7134         const bool is_block = variable.IsBlock();
7135 
7136         if (false == is_block)
7137         {
7138             TCU_FAIL("Not implemented");
7139         }
7140         else
7141         {
7142             buffer.SubData(variable.m_descriptor.m_offset, variable.m_descriptor.m_expected_stride_of_element * count,
7143                            variable.m_data);
7144         }
7145     }
7146 }
7147 
7148 /** Basic implementation
7149  *
7150  * @param ignored
7151  * @param si        Shader interface
7152  * @param program   Program
7153  * @param cs_buffer Buffer for uniform blocks
7154  **/
7155 void TextureTestBase::prepareUniforms(GLuint /* test_case_index */, Utils::ShaderInterface &si, Utils::Program &program,
7156                                       Utils::Buffer &buffer)
7157 {
7158     /* Skip if there are no input variables in vertex shader */
7159     if (0 == si.m_uniforms.size())
7160     {
7161         return;
7162     }
7163 
7164     /* Calculate vertex stride */
7165     GLint uniforms_stride = 0;
7166 
7167     for (GLuint i = 0; i < si.m_uniforms.size(); ++i)
7168     {
7169         Utils::Variable &variable = *si.m_uniforms[i];
7170 
7171         if (false == variable.IsBlock())
7172         {
7173             continue;
7174         }
7175 
7176         GLint variable_stride = variable.GetStride();
7177 
7178         GLint ends_at = variable_stride + variable.m_descriptor.m_offset;
7179 
7180         uniforms_stride = std::max(uniforms_stride, ends_at);
7181     }
7182 
7183     /* Set active program */
7184     program.Use();
7185 
7186     /* Allocate */
7187     buffer.Bind();
7188     buffer.Data(Utils::Buffer::StaticDraw, uniforms_stride, 0);
7189 
7190     /* Set up uniforms */
7191     for (GLuint i = 0; i < si.m_uniforms.size(); ++i)
7192     {
7193         Utils::Variable &variable = *si.m_uniforms[i];
7194 
7195         prepareUniform(program, variable, buffer);
7196     }
7197 }
7198 
7199 /** Basic implementation
7200  *
7201  * @param test_case_index   Test case index
7202  * @param program_interface Program interface
7203  * @param program           Program
7204  * @param cs_buffer         Buffer for compute shader stage
7205  **/
7206 void TextureTestBase::prepareUniforms(GLuint test_case_index, Utils::ProgramInterface &program_interface,
7207                                       Utils::Program &program, Utils::Buffer &cs_buffer)
7208 {
7209     cs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7210 
7211     Utils::ShaderInterface &cs = program_interface.GetShaderInterface(Utils::Shader::COMPUTE);
7212 
7213     prepareUniforms(test_case_index, cs, program, cs_buffer);
7214 
7215     cs_buffer.BindBase(Utils::Shader::COMPUTE);
7216 }
7217 
7218 /** Basic implementation
7219  *
7220  * @param test_case_index   Test case index
7221  * @param program_interface Program interface
7222  * @param program           Program
7223  * @param fs_buffer         Buffer for fragment shader stage
7224  * @param gs_buffer         Buffer for geometry shader stage
7225  * @param tcs_buffer        Buffer for tessellation control shader stage
7226  * @param tes_buffer        Buffer for tessellation evaluation shader stage
7227  * @param vs_buffer         Buffer for vertex shader stage
7228  **/
7229 void TextureTestBase::prepareUniforms(GLuint test_case_index, Utils::ProgramInterface &program_interface,
7230                                       Utils::Program &program, Utils::Buffer &fs_buffer, Utils::Buffer &gs_buffer,
7231                                       Utils::Buffer &tcs_buffer, Utils::Buffer &tes_buffer, Utils::Buffer &vs_buffer)
7232 {
7233     fs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7234     gs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7235     tcs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7236     tes_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7237     vs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7238 
7239     Utils::ShaderInterface &fs  = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
7240     Utils::ShaderInterface &gs  = program_interface.GetShaderInterface(Utils::Shader::GEOMETRY);
7241     Utils::ShaderInterface &tcs = program_interface.GetShaderInterface(Utils::Shader::TESS_CTRL);
7242     Utils::ShaderInterface &tes = program_interface.GetShaderInterface(Utils::Shader::TESS_EVAL);
7243     Utils::ShaderInterface &vs  = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
7244 
7245     prepareUniforms(test_case_index, fs, program, fs_buffer);
7246     prepareUniforms(test_case_index, gs, program, gs_buffer);
7247     prepareUniforms(test_case_index, tcs, program, tcs_buffer);
7248     prepareUniforms(test_case_index, tes, program, tes_buffer);
7249     prepareUniforms(test_case_index, vs, program, vs_buffer);
7250 
7251     fs_buffer.BindBase(Utils::Shader::FRAGMENT);
7252     gs_buffer.BindBase(Utils::Shader::GEOMETRY);
7253     tcs_buffer.BindBase(Utils::Shader::TESS_CTRL);
7254     tes_buffer.BindBase(Utils::Shader::TESS_EVAL);
7255     vs_buffer.BindBase(Utils::Shader::VERTEX);
7256 }
7257 
7258 /** Basic implementation
7259  *
7260  * @param test_case_index   Test case index
7261  * @param program_interface Program interface
7262  * @param program           Program
7263  * @param fs_buffer         Buffer for fragment shader stage
7264  * @param gs_buffer         Buffer for geometry shader stage
7265  * @param tcs_buffer        Buffer for tessellation control shader stage
7266  * @param tes_buffer        Buffer for tessellation evaluation shader stage
7267  * @param vs_buffer         Buffer for vertex shader stage
7268  **/
7269 void TextureTestBase::prepareUniforms(GLuint test_case_index, Utils::ProgramInterface &program_interface,
7270                                       Utils::Program &fs_program, Utils::Program &gs_program,
7271                                       Utils::Program &tcs_program, Utils::Program &tes_program,
7272                                       Utils::Program &vs_program, Utils::Buffer &fs_buffer, Utils::Buffer &gs_buffer,
7273                                       Utils::Buffer &tcs_buffer, Utils::Buffer &tes_buffer, Utils::Buffer &vs_buffer)
7274 {
7275     fs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7276     gs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7277     tcs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7278     tes_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7279     vs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7280 
7281     Utils::ShaderInterface &fs  = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
7282     Utils::ShaderInterface &gs  = program_interface.GetShaderInterface(Utils::Shader::GEOMETRY);
7283     Utils::ShaderInterface &tcs = program_interface.GetShaderInterface(Utils::Shader::TESS_CTRL);
7284     Utils::ShaderInterface &tes = program_interface.GetShaderInterface(Utils::Shader::TESS_EVAL);
7285     Utils::ShaderInterface &vs  = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
7286 
7287     prepareUniforms(test_case_index, fs, fs_program, fs_buffer);
7288     fs_buffer.BindBase(Utils::Shader::FRAGMENT);
7289 
7290     prepareUniforms(test_case_index, gs, gs_program, gs_buffer);
7291     gs_buffer.BindBase(Utils::Shader::GEOMETRY);
7292 
7293     prepareUniforms(test_case_index, tcs, tcs_program, tcs_buffer);
7294     tcs_buffer.BindBase(Utils::Shader::TESS_CTRL);
7295 
7296     prepareUniforms(test_case_index, tes, tes_program, tes_buffer);
7297     tes_buffer.BindBase(Utils::Shader::TESS_EVAL);
7298 
7299     prepareUniforms(test_case_index, vs, vs_program, vs_buffer);
7300     vs_buffer.BindBase(Utils::Shader::VERTEX);
7301 }
7302 
7303 /** Prepare source for shader
7304  *
7305  * @param test_case_index     Index of test case
7306  * @param program_interface   Interface of program
7307  * @param varying_passthrough Collection of connection between in and out variables
7308  * @param stage               Shader stage
7309  *
7310  * @return Source of shader
7311  **/
7312 std::string TextureTestBase::getShaderSource(GLuint test_case_index, Utils::ProgramInterface &program_interface,
7313                                              Utils::VaryingPassthrough &varying_passthrough,
7314                                              Utils::Shader::STAGES stage)
7315 {
7316     /* Get strings */
7317     const GLchar *shader_template       = getShaderTemplate(stage);
7318     glu::GLSLVersion glslVersion        = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
7319     const char *shader_version          = glu::getGLSLVersionDeclaration(glslVersion);
7320     const std::string &shader_interface = program_interface.GetInterfaceForStage(stage);
7321     const std::string &verification     = getVerificationSnippet(test_case_index, program_interface, stage);
7322     const std::string &passthrough      = getPassSnippet(test_case_index, varying_passthrough, stage);
7323 
7324     const GLchar *per_vertex = "";
7325 
7326     std::string source = shader_template;
7327     size_t position    = 0;
7328 
7329     Utils::replaceToken("VERSION", position, shader_version, source);
7330 
7331     /* Replace tokens in template */
7332     if (Utils::Shader::GEOMETRY == stage)
7333     {
7334         if (false == useMonolithicProgram(test_case_index))
7335         {
7336             per_vertex = "out gl_PerVertex {\n"
7337                          "vec4 gl_Position;\n"
7338                          "};\n"
7339                          "\n";
7340         }
7341 
7342         Utils::replaceToken("PERVERTEX", position, per_vertex, source);
7343     }
7344 
7345     Utils::replaceToken("INTERFACE", position, shader_interface.c_str(), source);
7346     Utils::replaceToken("VERIFICATION", position, verification.c_str(), source);
7347 
7348     if (false == verification.empty())
7349     {
7350         Utils::replaceAllTokens("ELSE", "    else ", source);
7351     }
7352     else
7353     {
7354         Utils::replaceAllTokens("ELSE", "", source);
7355     }
7356 
7357     Utils::replaceAllTokens("PASSTHROUGH", passthrough.c_str(), source);
7358 
7359     /* Done */
7360     return source;
7361 }
7362 
7363 /** Returns template of shader for given stage
7364  *
7365  * @param stage Shade stage
7366  *
7367  * @return Proper template
7368  **/
7369 const GLchar *TextureTestBase::getShaderTemplate(Utils::Shader::STAGES stage)
7370 {
7371 
7372     static const GLchar *compute_shader_template =
7373         "VERSION\n"
7374         "#extension GL_ARB_enhanced_layouts : require\n"
7375         "\n"
7376         "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
7377         "\n"
7378         "writeonly uniform uimage2D uni_image;\n"
7379         "\n"
7380         "INTERFACE"
7381         "\n"
7382         "void main()\n"
7383         "{\n"
7384         "    uint result = 1u;\n"
7385         "\n"
7386         "    VERIFICATION"
7387         "\n"
7388         "    imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), uvec4(result, 0, 0, 0));\n"
7389         "}\n"
7390         "\n";
7391 
7392     static const GLchar *fragment_shader_template = "VERSION\n"
7393                                                     "#extension GL_ARB_enhanced_layouts : require\n"
7394                                                     "\n"
7395                                                     "flat in  uint gs_fs_result;\n"
7396                                                     "     out uint fs_out_result;\n"
7397                                                     "\n"
7398                                                     "INTERFACE"
7399                                                     "\n"
7400                                                     "void main()\n"
7401                                                     "{\n"
7402                                                     "    uint result = 1u;\n"
7403                                                     "\n"
7404                                                     "    if (1u != gs_fs_result)\n"
7405                                                     "    {\n"
7406                                                     "         result = gs_fs_result;\n"
7407                                                     "    }\n"
7408                                                     "ELSEVERIFICATION"
7409                                                     "\n"
7410                                                     "    fs_out_result = result;\n"
7411                                                     "    PASSTHROUGH\n"
7412                                                     "}\n"
7413                                                     "\n";
7414 
7415     static const GLchar *geometry_shader_template =
7416         "VERSION\n"
7417         "#extension GL_ARB_enhanced_layouts : require\n"
7418         "\n"
7419         "layout(points)                           in;\n"
7420         "layout(triangle_strip, max_vertices = 4) out;\n"
7421         "\n"
7422         "     in  uint tes_gs_result[];\n"
7423         "     flat out uint gs_fs_result;\n"
7424         "\n"
7425         "PERVERTEX" /* Separable programs require explicit declaration of gl_PerVertex */
7426         "INTERFACE"
7427         "\n"
7428         "void main()\n"
7429         "{\n"
7430         "    uint result = 1u;\n"
7431         "\n"
7432         "    if (1u != tes_gs_result[0])\n"
7433         "    {\n"
7434         "         result = tes_gs_result[0];\n"
7435         "    }\n"
7436         "ELSEVERIFICATION"
7437         "\n"
7438         "    gs_fs_result = result;\n"
7439         "    PASSTHROUGH\n"
7440         "    gl_Position  = vec4(-1, -1, 0, 1);\n"
7441         "    EmitVertex();\n"
7442         "    gs_fs_result = result;\n"
7443         "    PASSTHROUGH\n"
7444         "    gl_Position  = vec4(-1, 1, 0, 1);\n"
7445         "    EmitVertex();\n"
7446         "    gs_fs_result = result;\n"
7447         "    PASSTHROUGH\n"
7448         "    gl_Position  = vec4(1, -1, 0, 1);\n"
7449         "    EmitVertex();\n"
7450         "    gs_fs_result = result;\n"
7451         "    PASSTHROUGH\n"
7452         "    gl_Position  = vec4(1, 1, 0, 1);\n"
7453         "    EmitVertex();\n"
7454         "}\n"
7455         "\n";
7456 
7457     static const GLchar *tess_ctrl_shader_template = "VERSION\n"
7458                                                      "#extension GL_ARB_enhanced_layouts : require\n"
7459                                                      "\n"
7460                                                      "layout(vertices = 1) out;\n"
7461                                                      "\n"
7462                                                      "in  uint vs_tcs_result[];\n"
7463                                                      "out uint tcs_tes_result[];\n"
7464                                                      "\n"
7465                                                      "INTERFACE"
7466                                                      "\n"
7467                                                      "void main()\n"
7468                                                      "{\n"
7469                                                      "    uint result = 1u;\n"
7470                                                      "\n"
7471                                                      "    if (1u != vs_tcs_result[gl_InvocationID])\n"
7472                                                      "    {\n"
7473                                                      "         result = vs_tcs_result[gl_InvocationID];\n"
7474                                                      "    }\n"
7475                                                      "ELSEVERIFICATION"
7476                                                      "\n"
7477                                                      "    tcs_tes_result[gl_InvocationID] = result;\n"
7478                                                      "\n"
7479                                                      "    PASSTHROUGH\n"
7480                                                      "\n"
7481                                                      "    gl_TessLevelOuter[0] = 1.0;\n"
7482                                                      "    gl_TessLevelOuter[1] = 1.0;\n"
7483                                                      "    gl_TessLevelOuter[2] = 1.0;\n"
7484                                                      "    gl_TessLevelOuter[3] = 1.0;\n"
7485                                                      "    gl_TessLevelInner[0] = 1.0;\n"
7486                                                      "    gl_TessLevelInner[1] = 1.0;\n"
7487                                                      "}\n"
7488                                                      "\n";
7489 
7490     static const GLchar *tess_eval_shader_template = "VERSION\n"
7491                                                      "#extension GL_ARB_enhanced_layouts : require\n"
7492                                                      "\n"
7493                                                      "layout(isolines, point_mode) in;\n"
7494                                                      "\n"
7495                                                      "in  uint tcs_tes_result[];\n"
7496                                                      "out uint tes_gs_result;\n"
7497                                                      "\n"
7498                                                      "INTERFACE"
7499                                                      "\n"
7500                                                      "void main()\n"
7501                                                      "{\n"
7502                                                      "    uint result = 1u;\n"
7503                                                      "\n"
7504                                                      "    if (1u != tcs_tes_result[0])\n"
7505                                                      "    {\n"
7506                                                      "         result = tcs_tes_result[0];\n"
7507                                                      "    }\n"
7508                                                      "ELSEVERIFICATION"
7509                                                      "\n"
7510                                                      "    tes_gs_result = result;\n"
7511                                                      "\n"
7512                                                      "    PASSTHROUGH\n"
7513                                                      "}\n"
7514                                                      "\n";
7515 
7516     static const GLchar *vertex_shader_template = "VERSION\n"
7517                                                   "#extension GL_ARB_enhanced_layouts : require\n"
7518                                                   "\n"
7519                                                   "out uint vs_tcs_result;\n"
7520                                                   "\n"
7521                                                   "INTERFACE"
7522                                                   "\n"
7523                                                   "void main()\n"
7524                                                   "{\n"
7525                                                   "    uint result = 1u;\n"
7526                                                   "\n"
7527                                                   "    VERIFICATION\n"
7528                                                   "\n"
7529                                                   "    vs_tcs_result = result;\n"
7530                                                   "\n"
7531                                                   "    PASSTHROUGH\n"
7532                                                   "}\n"
7533                                                   "\n";
7534 
7535     const GLchar *result = 0;
7536 
7537     switch (stage)
7538     {
7539     case Utils::Shader::COMPUTE:
7540         result = compute_shader_template;
7541         break;
7542     case Utils::Shader::FRAGMENT:
7543         result = fragment_shader_template;
7544         break;
7545     case Utils::Shader::GEOMETRY:
7546         result = geometry_shader_template;
7547         break;
7548     case Utils::Shader::TESS_CTRL:
7549         result = tess_ctrl_shader_template;
7550         break;
7551     case Utils::Shader::TESS_EVAL:
7552         result = tess_eval_shader_template;
7553         break;
7554     case Utils::Shader::VERTEX:
7555         result = vertex_shader_template;
7556         break;
7557     default:
7558         TCU_FAIL("Invalid enum");
7559     }
7560 
7561     return result;
7562 }
7563 
7564 /** Runs test case
7565  *
7566  * @param test_case_index Id of test case
7567  *
7568  * @return true if test case pass, false otherwise
7569  **/
7570 bool TextureTestBase::testCase(GLuint test_case_index)
7571 {
7572     try
7573     {
7574         if (true == useMonolithicProgram(test_case_index))
7575         {
7576             return testMonolithic(test_case_index);
7577         }
7578         else
7579         {
7580             return testSeparable(test_case_index);
7581         }
7582     }
7583     catch (Utils::Shader::InvalidSourceException &exc)
7584     {
7585         exc.log(m_context);
7586         TCU_FAIL(exc.what());
7587     }
7588     catch (Utils::Program::BuildException &exc)
7589     {
7590         exc.log(m_context);
7591         TCU_FAIL(exc.what());
7592     }
7593 }
7594 
7595 /** Runs "draw" test with monolithic program
7596  *
7597  * @param test_case_index Id of test case
7598  **/
7599 bool TextureTestBase::testMonolithic(GLuint test_case_index)
7600 {
7601     Utils::ProgramInterface program_interface;
7602     Utils::VaryingPassthrough varying_passthrough;
7603 
7604     /* */
7605     const std::string &test_name = getTestCaseName(test_case_index);
7606 
7607     /* */
7608     getProgramInterface(test_case_index, program_interface, varying_passthrough);
7609 
7610     bool result = true;
7611     /* Draw */
7612     if (true == isDrawRelevant(test_case_index))
7613     {
7614         Utils::Buffer buffer_attr(m_context);
7615         Utils::Buffer buffer_ssb_fs(m_context);
7616         Utils::Buffer buffer_ssb_gs(m_context);
7617         Utils::Buffer buffer_ssb_tcs(m_context);
7618         Utils::Buffer buffer_ssb_tes(m_context);
7619         Utils::Buffer buffer_ssb_vs(m_context);
7620         Utils::Buffer buffer_u_fs(m_context);
7621         Utils::Buffer buffer_u_gs(m_context);
7622         Utils::Buffer buffer_u_tcs(m_context);
7623         Utils::Buffer buffer_u_tes(m_context);
7624         Utils::Buffer buffer_u_vs(m_context);
7625         Utils::Framebuffer framebuffer(m_context);
7626         Utils::Program program(m_context);
7627         Utils::Texture texture_fb(m_context);
7628         Utils::VertexArray vao(m_context);
7629 
7630         /* */
7631         const std::string &fragment_shader =
7632             getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::FRAGMENT);
7633         const std::string &geometry_shader =
7634             getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::GEOMETRY);
7635         const std::string &tess_ctrl_shader =
7636             getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::TESS_CTRL);
7637         const std::string &tess_eval_shader =
7638             getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::TESS_EVAL);
7639         const std::string &vertex_shader =
7640             getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::VERTEX);
7641 
7642         program.Init("" /* compute_shader */, fragment_shader, geometry_shader, tess_ctrl_shader, tess_eval_shader,
7643                      vertex_shader, false /* is_separable */);
7644 
7645         /* */
7646         prepareAttribLocation(program, program_interface);
7647         prepareFragmentDataLoc(program, program_interface);
7648 
7649         /* */
7650         std::stringstream stream;
7651         if (false == Utils::checkMonolithicDrawProgramInterface(program, program_interface, stream))
7652         {
7653             m_context.getTestContext().getLog()
7654                 << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7655                 << ". Inspection of draw program interface failed:\n"
7656                 << stream.str() << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(vertex_shader)
7657                 << tcu::TestLog::KernelSource(tess_ctrl_shader) << tcu::TestLog::KernelSource(tess_eval_shader)
7658                 << tcu::TestLog::KernelSource(geometry_shader) << tcu::TestLog::KernelSource(fragment_shader);
7659 
7660             return false;
7661         }
7662 
7663         /* */
7664         program.Use();
7665 
7666         /* */
7667         buffer_attr.Init(Utils::Buffer::Array, Utils::Buffer::StaticDraw, 0, 0);
7668         vao.Init();
7669         prepareAttributes(test_case_index, program_interface, buffer_attr, vao);
7670 
7671         /* */
7672         prepareUniforms(test_case_index, program_interface, program, buffer_u_fs, buffer_u_gs, buffer_u_tcs,
7673                         buffer_u_tes, buffer_u_vs);
7674 
7675         prepareSSBs(test_case_index, program_interface, program, buffer_ssb_fs, buffer_ssb_gs, buffer_ssb_tcs,
7676                     buffer_ssb_tes, buffer_ssb_vs);
7677 
7678         /* */
7679         prepareFramebuffer(framebuffer, texture_fb);
7680 
7681         /* Draw */
7682         executeDrawCall(test_case_index);
7683 
7684 #if USE_NSIGHT
7685         m_context.getRenderContext().postIterate();
7686 #endif
7687 
7688         /* Check results */
7689         if (false == checkResults(test_case_index, texture_fb))
7690         {
7691             m_context.getTestContext().getLog()
7692                 << tcu::TestLog::Message << "FAILURE. Test case: " << test_name << ". Draw - invalid results."
7693                 << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(vertex_shader)
7694                 << tcu::TestLog::KernelSource(tess_ctrl_shader) << tcu::TestLog::KernelSource(tess_eval_shader)
7695                 << tcu::TestLog::KernelSource(geometry_shader) << tcu::TestLog::KernelSource(fragment_shader);
7696 
7697             result = false;
7698         }
7699     }
7700 
7701     /* Compute */
7702     if (true == isComputeRelevant(test_case_index))
7703     {
7704         Utils::Buffer buffer_ssb_cs(m_context);
7705         Utils::Buffer buffer_u_cs(m_context);
7706         Utils::Program program(m_context);
7707         Utils::Texture texture_im(m_context);
7708         Utils::VertexArray vao(m_context);
7709 
7710         /* */
7711         const std::string &compute_shader =
7712             getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::COMPUTE);
7713 
7714         program.Init(compute_shader, "" /* fragment_shader */, "" /* geometry_shader */, "" /* tess_ctrl_shader */,
7715                      "" /* tess_eval_shader */, "" /* vertex_shader */, false /* is_separable */);
7716 
7717         /* */
7718         {
7719             std::stringstream stream;
7720 
7721             if (false == Utils::checkMonolithicComputeProgramInterface(program, program_interface, stream))
7722             {
7723                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7724                                                     << ". Inspection of compute program interface failed:\n"
7725                                                     << stream.str() << tcu::TestLog::EndMessage;
7726 
7727                 return false;
7728             }
7729         }
7730 
7731         /* */
7732         program.Use();
7733 
7734         /* */
7735         vao.Init();
7736         vao.Bind();
7737 
7738         /* */
7739         prepareUniforms(test_case_index, program_interface, program, buffer_u_cs);
7740 
7741         prepareSSBs(test_case_index, program_interface, program, buffer_ssb_cs);
7742 
7743         /* */
7744         GLint image_location = program.GetUniformLocation("uni_image");
7745         prepareImage(image_location, texture_im);
7746 
7747         /* Draw */
7748         executeDispatchCall(test_case_index);
7749 
7750 #if USE_NSIGHT
7751         m_context.getRenderContext().postIterate();
7752 #endif
7753 
7754         /* Check results */
7755         if (false == checkResults(test_case_index, texture_im))
7756         {
7757             m_context.getTestContext().getLog()
7758                 << tcu::TestLog::Message << "FAILURE. Test case: " << test_name << ". Compute - invalid results."
7759                 << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(compute_shader);
7760 
7761             result = false;
7762         }
7763     }
7764 
7765     return result;
7766 }
7767 
7768 /** Runs "draw" test with separable program
7769  *
7770  * @param test_case_index Id of test case
7771  **/
7772 bool TextureTestBase::testSeparable(GLuint test_case_index)
7773 {
7774     Utils::ProgramInterface program_interface;
7775     Utils::VaryingPassthrough varying_passthrough;
7776 
7777     /* */
7778     const std::string &test_name = getTestCaseName(test_case_index);
7779 
7780     /* */
7781     getProgramInterface(test_case_index, program_interface, varying_passthrough);
7782 
7783     bool result = true;
7784     /* Draw */
7785     if (true == isDrawRelevant(test_case_index))
7786     {
7787         Utils::Buffer buffer_attr(m_context);
7788         Utils::Buffer buffer_u_fs(m_context);
7789         Utils::Buffer buffer_u_gs(m_context);
7790         Utils::Buffer buffer_u_tcs(m_context);
7791         Utils::Buffer buffer_u_tes(m_context);
7792         Utils::Buffer buffer_u_vs(m_context);
7793         Utils::Framebuffer framebuffer(m_context);
7794         Utils::Pipeline pipeline(m_context);
7795         Utils::Program program_fs(m_context);
7796         Utils::Program program_gs(m_context);
7797         Utils::Program program_tcs(m_context);
7798         Utils::Program program_tes(m_context);
7799         Utils::Program program_vs(m_context);
7800         Utils::Texture texture_fb(m_context);
7801         Utils::VertexArray vao(m_context);
7802 
7803         /* */
7804         const std::string &fs =
7805             getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::FRAGMENT);
7806         const std::string &gs =
7807             getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::GEOMETRY);
7808         const std::string &tcs =
7809             getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::TESS_CTRL);
7810         const std::string &tes =
7811             getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::TESS_EVAL);
7812         const std::string &vs =
7813             getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::VERTEX);
7814 
7815         program_fs.Init("" /*cs*/, fs, "" /*gs*/, "" /*tcs*/, "" /*tes*/, "" /*vs*/, true /* is_separable */);
7816         program_gs.Init("" /*cs*/, "" /*fs*/, gs, "" /*tcs*/, "" /*tes*/, "" /*vs*/, true /* is_separable */);
7817         program_tcs.Init("" /*cs*/, "" /*fs*/, "" /*gs*/, tcs, "" /*tes*/, "" /*vs*/, true /* is_separable */);
7818         program_tes.Init("" /*cs*/, "" /*fs*/, "" /*gs*/, "" /*tcs*/, tes, "" /*vs*/, true /* is_separable */);
7819         program_vs.Init("" /*cs*/, "" /*fs*/, "" /*gs*/, "" /*tcs*/, "" /*tes*/, vs, true /* is_separable */);
7820 
7821         /* */
7822         prepareAttribLocation(program_vs, program_interface);
7823         prepareFragmentDataLoc(program_vs, program_interface);
7824 
7825         /* */
7826         std::stringstream stream;
7827         if ((false ==
7828              Utils::checkSeparableDrawProgramInterface(program_vs, program_interface, Utils::Shader::VERTEX, stream)) ||
7829             (false == Utils::checkSeparableDrawProgramInterface(program_fs, program_interface, Utils::Shader::FRAGMENT,
7830                                                                 stream)) ||
7831             (false == Utils::checkSeparableDrawProgramInterface(program_gs, program_interface, Utils::Shader::GEOMETRY,
7832                                                                 stream)) ||
7833             (false == Utils::checkSeparableDrawProgramInterface(program_tcs, program_interface,
7834                                                                 Utils::Shader::TESS_CTRL, stream)) ||
7835             (false == Utils::checkSeparableDrawProgramInterface(program_tes, program_interface,
7836                                                                 Utils::Shader::TESS_EVAL, stream)))
7837         {
7838             m_context.getTestContext().getLog()
7839                 << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7840                 << ". Inspection of separable draw program interface failed:\n"
7841                 << stream.str() << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(vs)
7842                 << tcu::TestLog::KernelSource(tcs) << tcu::TestLog::KernelSource(tes) << tcu::TestLog::KernelSource(gs)
7843                 << tcu::TestLog::KernelSource(fs);
7844 
7845             return false;
7846         }
7847 
7848         /* */
7849         pipeline.Init();
7850         pipeline.UseProgramStages(program_fs.m_id, GL_FRAGMENT_SHADER_BIT);
7851         pipeline.UseProgramStages(program_gs.m_id, GL_GEOMETRY_SHADER_BIT);
7852         pipeline.UseProgramStages(program_tcs.m_id, GL_TESS_CONTROL_SHADER_BIT);
7853         pipeline.UseProgramStages(program_tes.m_id, GL_TESS_EVALUATION_SHADER_BIT);
7854         pipeline.UseProgramStages(program_vs.m_id, GL_VERTEX_SHADER_BIT);
7855         pipeline.Bind();
7856 
7857         /* */
7858 
7859         buffer_attr.Init(Utils::Buffer::Array, Utils::Buffer::StaticDraw, 0, 0);
7860         vao.Init();
7861         prepareAttributes(test_case_index, program_interface, buffer_attr, vao);
7862 
7863         /* */
7864         prepareUniforms(test_case_index, program_interface, program_fs, program_gs, program_tcs, program_tes,
7865                         program_vs, buffer_u_fs, buffer_u_gs, buffer_u_tcs, buffer_u_tes, buffer_u_vs);
7866 
7867         Utils::Program::Use(m_context.getRenderContext().getFunctions(), Utils::Program::m_invalid_id);
7868 
7869         /* */
7870         prepareFramebuffer(framebuffer, texture_fb);
7871 
7872         /* Draw */
7873         executeDrawCall(test_case_index);
7874 
7875 #if USE_NSIGHT
7876         m_context.getRenderContext().postIterate();
7877 #endif
7878 
7879         /* Check results */
7880         if (false == checkResults(test_case_index, texture_fb))
7881         {
7882             m_context.getTestContext().getLog()
7883                 << tcu::TestLog::Message << "FAILURE. Test case: " << test_name << ". Draw - invalid results."
7884                 << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(vs) << tcu::TestLog::KernelSource(tcs)
7885                 << tcu::TestLog::KernelSource(tes) << tcu::TestLog::KernelSource(gs) << tcu::TestLog::KernelSource(fs);
7886 
7887             result = false;
7888         }
7889         else
7890         {
7891             m_context.getTestContext().getLog()
7892                 << tcu::TestLog::Message << "Success." << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(vs)
7893                 << tcu::TestLog::KernelSource(tcs) << tcu::TestLog::KernelSource(tes) << tcu::TestLog::KernelSource(gs)
7894                 << tcu::TestLog::KernelSource(fs);
7895         }
7896     }
7897 
7898     /* Compute */
7899     if (true == isComputeRelevant(test_case_index))
7900     {
7901         Utils::Buffer buffer_u_cs(m_context);
7902         Utils::Program program(m_context);
7903         Utils::Texture texture_im(m_context);
7904         Utils::VertexArray vao(m_context);
7905 
7906         /* */
7907         const std::string &compute_shader =
7908             getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::COMPUTE);
7909 
7910         program.Init(compute_shader, "" /* fragment_shader */, "" /* geometry_shader */, "" /* tess_ctrl_shader */,
7911                      "" /* tess_eval_shader */, "" /* vertex_shader */, false /* is_separable */);
7912 
7913         /* */
7914         {
7915             std::stringstream stream;
7916 
7917             if (false == Utils::checkMonolithicComputeProgramInterface(program, program_interface, stream))
7918             {
7919                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7920                                                     << ". Inspection of compute program interface failed:\n"
7921                                                     << stream.str() << tcu::TestLog::EndMessage;
7922 
7923                 return false;
7924             }
7925         }
7926 
7927         /* */
7928         program.Use();
7929 
7930         /* */
7931         vao.Init();
7932         vao.Bind();
7933 
7934         /* */
7935         prepareUniforms(test_case_index, program_interface, program, buffer_u_cs);
7936 
7937         /* */
7938         GLint image_location = program.GetUniformLocation("uni_image");
7939         prepareImage(image_location, texture_im);
7940 
7941         /* Draw */
7942         executeDispatchCall(test_case_index);
7943 
7944 #if USE_NSIGHT
7945         m_context.getRenderContext().postIterate();
7946 #endif
7947 
7948         /* Check results */
7949         if (false == checkResults(test_case_index, texture_im))
7950         {
7951             m_context.getTestContext().getLog()
7952                 << tcu::TestLog::Message << "FAILURE. Test case: " << test_name << ". Compute - invalid results."
7953                 << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(compute_shader);
7954 
7955             result = false;
7956         }
7957     }
7958 
7959     return result;
7960 }
7961 
7962 /** Basic implementation
7963  *
7964  * @param ignored
7965  *
7966  * @return false
7967  **/
7968 bool TextureTestBase::useComponentQualifier(glw::GLuint /* test_case_index */)
7969 {
7970     return false;
7971 }
7972 
7973 /** Basic implementation
7974  *
7975  * @param ignored
7976  *
7977  * @return true
7978  **/
7979 bool TextureTestBase::useMonolithicProgram(GLuint /* test_case_index */)
7980 {
7981     return true;
7982 }
7983 
7984 /** Constructor
7985  *
7986  * @param context Test framework context
7987  **/
7988 APIConstantValuesTest::APIConstantValuesTest(deqp::Context &context)
7989     : TestCase(context, "api_constant_values", "Test verifies values of api constants")
7990 {
7991     /* Nothing to be done here */
7992 }
7993 
7994 /** Execute test
7995  *
7996  * @return tcu::TestNode::STOP otherwise
7997  **/
7998 tcu::TestNode::IterateResult APIConstantValuesTest::iterate()
7999 {
8000     static const GLuint expected_comp = 64;
8001     static const GLuint expected_xfb  = 4;
8002     static const GLuint expected_sep  = 4;
8003     GLint max_comp                    = 0;
8004     GLint max_xfb                     = 0;
8005     GLint max_sep                     = 0;
8006     bool test_result                  = true;
8007 
8008     const Functions &gl = m_context.getRenderContext().getFunctions();
8009 
8010     gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_xfb);
8011     GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8012     gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_comp);
8013     GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8014     gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, &max_sep);
8015     GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8016 
8017     if (expected_xfb > (GLuint)max_xfb)
8018     {
8019         m_context.getTestContext().getLog()
8020             << tcu::TestLog::Message << "Invalid GL_MAX_TRANSFORM_FEEDBACK_BUFFERS. Got " << max_xfb
8021             << " Expected at least " << expected_xfb << tcu::TestLog::EndMessage;
8022 
8023         test_result = false;
8024     }
8025 
8026     if (expected_comp > (GLuint)max_comp)
8027     {
8028         m_context.getTestContext().getLog()
8029             << tcu::TestLog::Message << "Invalid GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS. Got " << max_comp
8030             << " Expected at least " << expected_comp << tcu::TestLog::EndMessage;
8031 
8032         test_result = false;
8033     }
8034 
8035     if (expected_sep > (GLuint)max_sep)
8036     {
8037         m_context.getTestContext().getLog()
8038             << tcu::TestLog::Message << "Invalid GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS. Got " << max_comp
8039             << " Expected at least " << expected_comp << tcu::TestLog::EndMessage;
8040 
8041         test_result = false;
8042     }
8043 
8044     /* Set result */
8045     if (true == test_result)
8046     {
8047         m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
8048     }
8049     else
8050     {
8051         m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
8052     }
8053 
8054     /* Done */
8055     return tcu::TestNode::STOP;
8056 }
8057 
8058 /** Constructor
8059  *
8060  * @param context Test framework context
8061  **/
8062 APIErrorsTest::APIErrorsTest(deqp::Context &context)
8063     : TestCase(context, "api_errors", "Test verifies errors reeturned by api")
8064 {
8065     /* Nothing to be done here */
8066 }
8067 
8068 /** Execute test
8069  *
8070  * @return tcu::TestNode::STOP otherwise
8071  **/
8072 tcu::TestNode::IterateResult APIErrorsTest::iterate()
8073 {
8074     GLint length = 0;
8075     GLchar name[64];
8076     GLint param = 0;
8077     Utils::Program program(m_context);
8078     bool test_result = true;
8079 
8080     const Functions &gl = m_context.getRenderContext().getFunctions();
8081 
8082     try
8083     {
8084         program.Init("" /* cs */,
8085                      "#version 430 core\n"
8086                      "#extension GL_ARB_enhanced_layouts : require\n"
8087                      "\n"
8088                      "in  vec4 vs_fs;\n"
8089                      "out vec4 fs_out;\n"
8090                      "\n"
8091                      "void main()\n"
8092                      "{\n"
8093                      "    fs_out = vs_fs;\n"
8094                      "}\n"
8095                      "\n" /* fs */,
8096                      "" /* gs */, "" /* tcs */, "" /* tes */,
8097                      "#version 430 core\n"
8098                      "#extension GL_ARB_enhanced_layouts : require\n"
8099                      "\n"
8100                      "in  vec4 in_vs;\n"
8101                      "layout (xfb_offset = 16) out vec4 vs_fs;\n"
8102                      "\n"
8103                      "void main()\n"
8104                      "{\n"
8105                      "    vs_fs = in_vs;\n"
8106                      "}\n"
8107                      "\n" /* vs */,
8108                      false /* separable */);
8109     }
8110     catch (Utils::Shader::InvalidSourceException &exc)
8111     {
8112         exc.log(m_context);
8113         TCU_FAIL(exc.what());
8114     }
8115     catch (Utils::Program::BuildException &exc)
8116     {
8117         TCU_FAIL(exc.what());
8118     }
8119 
8120     /*
8121      * - GetProgramInterfaceiv should generate INVALID_OPERATION when
8122      * <programInterface> is TRANSFORM_FEEDBACK_BUFFER and <pname> is one of the
8123      * following:
8124      *   * MAX_NAME_LENGTH,
8125      *   * MAX_NUM_ACTIVE_VARIABLES;
8126      */
8127     gl.getProgramInterfaceiv(program.m_id, GL_TRANSFORM_FEEDBACK_BUFFER, GL_MAX_NAME_LENGTH, &param);
8128     checkError(GL_INVALID_OPERATION, "GetProgramInterfaceiv(GL_TRANSFORM_FEEDBACK_BUFFER, GL_MAX_NAME_LENGTH)",
8129                test_result);
8130 
8131     /*
8132      * - GetProgramResourceIndex should generate INVALID_ENUM when
8133      * <programInterface> is TRANSFORM_FEEDBACK_BUFFER;
8134      */
8135     gl.getProgramResourceIndex(program.m_id, GL_TRANSFORM_FEEDBACK_BUFFER, "0");
8136     checkError(GL_INVALID_ENUM, "GetProgramResourceIndex(GL_TRANSFORM_FEEDBACK_BUFFER)", test_result);
8137     /*
8138      * - GetProgramResourceName should generate INVALID_ENUM when
8139      * <programInterface> is TRANSFORM_FEEDBACK_BUFFER;
8140      */
8141     gl.getProgramResourceName(program.m_id, GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, 64 /* bufSize */, &length,
8142                               name);
8143     checkError(GL_INVALID_ENUM, "GetProgramResourceName(GL_TRANSFORM_FEEDBACK_BUFFER)", test_result);
8144 
8145     /* Set result */
8146     if (true == test_result)
8147     {
8148         m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
8149     }
8150     else
8151     {
8152         m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
8153     }
8154 
8155     /* Done */
8156     return tcu::TestNode::STOP;
8157 }
8158 
8159 /** Check if error is the expected one.
8160  *
8161  * @param expected_error Expected error
8162  * @param message        Message to log in case of error
8163  * @param test_result    Test result, set to false in case of invalid error
8164  **/
8165 void APIErrorsTest::checkError(GLenum expected_error, const GLchar *message, bool &test_result)
8166 {
8167     const Functions &gl = m_context.getRenderContext().getFunctions();
8168 
8169     GLenum error = gl.getError();
8170 
8171     if (error != expected_error)
8172     {
8173         m_context.getTestContext().getLog()
8174             << tcu::TestLog::Message << "Failure. Invalid error. Got " << glu::getErrorStr(error) << " expected "
8175             << glu::getErrorStr(expected_error) << " Msg: " << message << tcu::TestLog::EndMessage;
8176 
8177         test_result = false;
8178     }
8179 }
8180 
8181 /** Constructor
8182  *
8183  * @param context Test framework context
8184  **/
8185 GLSLContantImmutablityTest::GLSLContantImmutablityTest(deqp::Context &context)
8186     : NegativeTestBase(context, "glsl_contant_immutablity", "Test verifies that glsl constants cannot be modified")
8187 {
8188     /* Nothing to be done here */
8189 }
8190 
8191 /** Source for given test case and stage
8192  *
8193  * @param test_case_index Index of test case
8194  * @param stage           Shader stage
8195  *
8196  * @return Shader source
8197  **/
8198 std::string GLSLContantImmutablityTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
8199 {
8200     static const GLchar *cs  = "#version 430 core\n"
8201                                "#extension GL_ARB_enhanced_layouts : require\n"
8202                                "\n"
8203                                "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
8204                                "\n"
8205                                "writeonly uniform uimage2D uni_image;\n"
8206                                "\n"
8207                                "void main()\n"
8208                                "{\n"
8209                                "    uint result = 1u;\n"
8210                                "    CONSTANT = 3;\n"
8211                                "\n"
8212                                "    imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), uvec4(result, 0, 0, 0));\n"
8213                                "}\n"
8214                                "\n";
8215     static const GLchar *fs  = "#version 430 core\n"
8216                                "#extension GL_ARB_enhanced_layouts : require\n"
8217                                "\n"
8218                                "in  vec4 gs_fs;\n"
8219                                "out vec4 fs_out;\n"
8220                                "\n"
8221                                "void main()\n"
8222                                "{\n"
8223                                "ASSIGNMENT"
8224                                "    fs_out = gs_fs;\n"
8225                                "}\n"
8226                                "\n";
8227     static const GLchar *gs  = "#version 430 core\n"
8228                                "#extension GL_ARB_enhanced_layouts : require\n"
8229                                "\n"
8230                                "layout(points)                           in;\n"
8231                                "layout(triangle_strip, max_vertices = 4) out;\n"
8232                                "\n"
8233                                "in  vec4 tes_gs[];\n"
8234                                "out vec4 gs_fs;\n"
8235                                "\n"
8236                                "void main()\n"
8237                                "{\n"
8238                                "ASSIGNMENT"
8239                                "    gs_fs = tes_gs[0];\n"
8240                                "    gl_Position  = vec4(-1, -1, 0, 1);\n"
8241                                "    EmitVertex();\n"
8242                                "    gs_fs = tes_gs[0];\n"
8243                                "    gl_Position  = vec4(-1, 1, 0, 1);\n"
8244                                "    EmitVertex();\n"
8245                                "    gs_fs = tes_gs[0];\n"
8246                                "    gl_Position  = vec4(1, -1, 0, 1);\n"
8247                                "    EmitVertex();\n"
8248                                "    gs_fs = tes_gs[0];\n"
8249                                "    gl_Position  = vec4(1, 1, 0, 1);\n"
8250                                "    EmitVertex();\n"
8251                                "}\n"
8252                                "\n";
8253     static const GLchar *tcs = "#version 430 core\n"
8254                                "#extension GL_ARB_enhanced_layouts : require\n"
8255                                "\n"
8256                                "layout(vertices = 1) out;\n"
8257                                "\n"
8258                                "in  vec4 vs_tcs[];\n"
8259                                "out vec4 tcs_tes[];\n"
8260                                "\n"
8261                                "void main()\n"
8262                                "{\n"
8263                                "\n"
8264                                "ASSIGNMENT"
8265                                "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
8266                                "\n"
8267                                "    gl_TessLevelOuter[0] = 1.0;\n"
8268                                "    gl_TessLevelOuter[1] = 1.0;\n"
8269                                "    gl_TessLevelOuter[2] = 1.0;\n"
8270                                "    gl_TessLevelOuter[3] = 1.0;\n"
8271                                "    gl_TessLevelInner[0] = 1.0;\n"
8272                                "    gl_TessLevelInner[1] = 1.0;\n"
8273                                "}\n"
8274                                "\n";
8275     static const GLchar *tes = "#version 430 core\n"
8276                                "#extension GL_ARB_enhanced_layouts : require\n"
8277                                "\n"
8278                                "layout(isolines, point_mode) in;\n"
8279                                "\n"
8280                                "in  vec4 tcs_tes[];\n"
8281                                "out vec4 tes_gs;\n"
8282                                "\n"
8283                                "void main()\n"
8284                                "{\n"
8285                                "ASSIGNMENT"
8286                                "    tes_gs = tcs_tes[0];\n"
8287                                "}\n"
8288                                "\n";
8289     static const GLchar *vs  = "#version 430 core\n"
8290                                "#extension GL_ARB_enhanced_layouts : require\n"
8291                                "\n"
8292                                "in  vec4 in_vs;\n"
8293                                "out vec4 vs_tcs;\n"
8294                                "\n"
8295                                "void main()\n"
8296                                "{\n"
8297                                "ASSIGNMENT"
8298                                "    vs_tcs = in_vs;\n"
8299                                "}\n"
8300                                "\n";
8301 
8302     std::string source;
8303     testCase &test_case = m_test_cases[test_case_index];
8304 
8305     if (Utils::Shader::COMPUTE == test_case.m_stage)
8306     {
8307         size_t position = 0;
8308 
8309         source = cs;
8310 
8311         Utils::replaceToken("CONSTANT", position, getConstantName(test_case.m_constant), source);
8312     }
8313     else
8314     {
8315         std::string assignment = "    CONSTANT = 3;\n";
8316         size_t position        = 0;
8317 
8318         switch (stage)
8319         {
8320         case Utils::Shader::FRAGMENT:
8321             source = fs;
8322             break;
8323         case Utils::Shader::GEOMETRY:
8324             source = gs;
8325             break;
8326         case Utils::Shader::TESS_CTRL:
8327             source = tcs;
8328             break;
8329         case Utils::Shader::TESS_EVAL:
8330             source = tes;
8331             break;
8332         case Utils::Shader::VERTEX:
8333             source = vs;
8334             break;
8335         default:
8336             TCU_FAIL("Invalid enum");
8337         }
8338 
8339         if (test_case.m_stage == stage)
8340         {
8341             Utils::replaceToken("CONSTANT", position, getConstantName(test_case.m_constant), assignment);
8342         }
8343         else
8344         {
8345             assignment = "";
8346         }
8347 
8348         position = 0;
8349         Utils::replaceToken("ASSIGNMENT", position, assignment.c_str(), source);
8350     }
8351 
8352     return source;
8353 }
8354 
8355 /** Get description of test case
8356  *
8357  * @param test_case_index Index of test case
8358  *
8359  * @return Constant name
8360  **/
8361 std::string GLSLContantImmutablityTest::getTestCaseName(GLuint test_case_index)
8362 {
8363     std::string result = getConstantName(m_test_cases[test_case_index].m_constant);
8364 
8365     return result;
8366 }
8367 
8368 /** Get number of test cases
8369  *
8370  * @return Number of test cases
8371  **/
8372 GLuint GLSLContantImmutablityTest::getTestCaseNumber()
8373 {
8374     return static_cast<GLuint>(m_test_cases.size());
8375 }
8376 
8377 /** Selects if "compute" stage is relevant for test
8378  *
8379  * @param test_case_index Index of test case
8380  *
8381  * @return true when tested stage is compute
8382  **/
8383 bool GLSLContantImmutablityTest::isComputeRelevant(GLuint test_case_index)
8384 {
8385     return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
8386 }
8387 
8388 /** Prepare all test cases
8389  *
8390  **/
8391 void GLSLContantImmutablityTest::testInit()
8392 {
8393     for (GLuint constant = 0; constant < CONSTANTS_MAX; ++constant)
8394     {
8395         for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
8396         {
8397             testCase test_case = {(CONSTANTS)constant, (Utils::Shader::STAGES)stage};
8398 
8399             m_test_cases.push_back(test_case);
8400         }
8401     }
8402 }
8403 
8404 /** Get name of glsl constant
8405  *
8406  * @param Constant id
8407  *
8408  * @return Name of constant used in GLSL
8409  **/
8410 const GLchar *GLSLContantImmutablityTest::getConstantName(CONSTANTS constant)
8411 {
8412     const GLchar *name = "";
8413 
8414     switch (constant)
8415     {
8416     case GL_ARB_ENHANCED_LAYOUTS:
8417         name = "GL_ARB_enhanced_layouts";
8418         break;
8419     case GL_MAX_XFB:
8420         name = "gl_MaxTransformFeedbackBuffers";
8421         break;
8422     case GL_MAX_XFB_INT_COMP:
8423         name = "gl_MaxTransformFeedbackInterleavedComponents";
8424         break;
8425     default:
8426         TCU_FAIL("Invalid enum");
8427     }
8428 
8429     return name;
8430 }
8431 
8432 /** Constructor
8433  *
8434  * @param context Test framework context
8435  **/
8436 GLSLContantValuesTest::GLSLContantValuesTest(deqp::Context &context)
8437     : TextureTestBase(context, "glsl_contant_values", "Test verifies values of constant symbols")
8438 {
8439 }
8440 
8441 /** Selects if "compute" stage is relevant for test
8442  *
8443  * @param ignored
8444  *
8445  * @return false
8446  **/
8447 bool GLSLContantValuesTest::isComputeRelevant(GLuint /* test_case_index */)
8448 {
8449     return false;
8450 }
8451 
8452 /** Prepare code snippet that will verify in and uniform variables
8453  *
8454  * @param ignored
8455  * @param ignored
8456  * @param stage   Shader stage
8457  *
8458  * @return Code that verify variables
8459  **/
8460 std::string GLSLContantValuesTest::getVerificationSnippet(GLuint /* test_case_index */,
8461                                                           Utils::ProgramInterface & /* program_interface */,
8462                                                           Utils::Shader::STAGES stage)
8463 {
8464     /* Get constants */
8465     const Functions &gl = m_context.getRenderContext().getFunctions();
8466 
8467     GLint max_transform_feedback_buffers                = 0;
8468     GLint max_transform_feedback_interleaved_components = 0;
8469 
8470     gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_transform_feedback_buffers);
8471     GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8472     gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_transform_feedback_interleaved_components);
8473     GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8474 
8475     std::string verification;
8476 
8477     if (Utils::Shader::VERTEX == stage)
8478     {
8479         verification = "if (1 != GL_ARB_enhanced_layouts)\n"
8480                        "    {\n"
8481                        "        result = 0;\n"
8482                        "    }\n"
8483                        "    else if (MAX_TRANSFORM_FEEDBACK_BUFFERS\n"
8484                        "        != gl_MaxTransformFeedbackBuffers)\n"
8485                        "    {\n"
8486                        "        result = 0;\n"
8487                        "    }\n"
8488                        "    else if (MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS \n"
8489                        "        != gl_MaxTransformFeedbackInterleavedComponents)\n"
8490                        "    {\n"
8491                        "        result = 0;\n"
8492                        "    }\n";
8493 
8494         size_t position = 0;
8495         GLchar buffer[16];
8496 
8497         sprintf(buffer, "%d", max_transform_feedback_buffers);
8498         Utils::replaceToken("MAX_TRANSFORM_FEEDBACK_BUFFERS", position, buffer, verification);
8499 
8500         sprintf(buffer, "%d", max_transform_feedback_interleaved_components);
8501         Utils::replaceToken("MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS", position, buffer, verification);
8502     }
8503     else
8504     {
8505         verification = "";
8506     }
8507 
8508     return verification;
8509 }
8510 
8511 /** Constructor
8512  *
8513  * @param context Test framework context
8514  **/
8515 GLSLConstantIntegralExpressionTest::GLSLConstantIntegralExpressionTest(deqp::Context &context)
8516     : TextureTestBase(context, "glsl_constant_integral_expression",
8517                       "Test verifies that symbols can be used as constant integral expressions")
8518 {
8519 }
8520 
8521 /** Get interface of program
8522  *
8523  * @param ignored
8524  * @param program_interface Interface of program
8525  * @param ignored
8526  **/
8527 void GLSLConstantIntegralExpressionTest::getProgramInterface(GLuint /* test_case_index */,
8528                                                              Utils::ProgramInterface &program_interface,
8529                                                              Utils::VaryingPassthrough & /* varying_passthrough */)
8530 {
8531     /* Get constants */
8532     const Functions &gl = m_context.getRenderContext().getFunctions();
8533 
8534     GLint max_transform_feedback_buffers                = 0;
8535     GLint max_transform_feedback_interleaved_components = 0;
8536 
8537     gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_transform_feedback_buffers);
8538     GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8539     gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_transform_feedback_interleaved_components);
8540     GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8541 
8542     GLuint gohan_div = std::max(1, max_transform_feedback_buffers / 16);
8543     GLuint goten_div = std::max(1, max_transform_feedback_interleaved_components / 16);
8544 
8545     m_gohan_length = max_transform_feedback_buffers / gohan_div;
8546     m_goten_length = max_transform_feedback_interleaved_components / goten_div;
8547 
8548     /* Globals */
8549     std::string globals = "uniform uint goku [GL_ARB_enhanced_layouts / 1];\n"
8550                           "uniform uint gohan[gl_MaxTransformFeedbackBuffers / GOHAN_DIV];\n"
8551                           "uniform uint goten[gl_MaxTransformFeedbackInterleavedComponents / GOTEN_DIV];\n";
8552 
8553     size_t position = 0;
8554     GLchar buffer[16];
8555 
8556     sprintf(buffer, "%d", gohan_div);
8557     Utils::replaceToken("GOHAN_DIV", position, buffer, globals);
8558 
8559     sprintf(buffer, "%d", goten_div);
8560     Utils::replaceToken("GOTEN_DIV", position, buffer, globals);
8561 
8562     program_interface.m_vertex.m_globals    = globals;
8563     program_interface.m_tess_ctrl.m_globals = globals;
8564     program_interface.m_tess_eval.m_globals = globals;
8565     program_interface.m_geometry.m_globals  = globals;
8566     program_interface.m_fragment.m_globals  = globals;
8567     program_interface.m_compute.m_globals   = globals;
8568 }
8569 
8570 /** Prepare code snippet that will verify in and uniform variables
8571  *
8572  * @param ignored
8573  * @param ignored
8574  * @param ignored
8575  *
8576  * @return Code that verify variables
8577  **/
8578 std::string GLSLConstantIntegralExpressionTest::getVerificationSnippet(
8579     GLuint /* test_case_index */, Utils::ProgramInterface & /* program_interface */, Utils::Shader::STAGES /* stage */)
8580 {
8581     std::string verification = "{\n"
8582                                "        uint goku_sum = 0;\n"
8583                                "        uint gohan_sum = 0;\n"
8584                                "        uint goten_sum = 0;\n"
8585                                "\n"
8586                                "        for (uint i = 0u; i < goku.length(); ++i)\n"
8587                                "        {\n"
8588                                "            goku_sum += goku[i];\n"
8589                                "        }\n"
8590                                "\n"
8591                                "        for (uint i = 0u; i < gohan.length(); ++i)\n"
8592                                "        {\n"
8593                                "            gohan_sum += gohan[i];\n"
8594                                "        }\n"
8595                                "\n"
8596                                "        for (uint i = 0u; i < goten.length(); ++i)\n"
8597                                "        {\n"
8598                                "            goten_sum += goten[i];\n"
8599                                "        }\n"
8600                                "\n"
8601                                "        if ( (1u != goku_sum)  &&\n"
8602                                "             (EXPECTED_GOHAN_SUMu != gohan_sum) ||\n"
8603                                "             (EXPECTED_GOTEN_SUMu != goten_sum) )\n"
8604                                "        {\n"
8605                                "            result = 0u;\n"
8606                                "        }\n"
8607                                "    }\n";
8608 
8609     size_t position = 0;
8610     GLchar buffer[16];
8611 
8612     sprintf(buffer, "%d", m_gohan_length);
8613     Utils::replaceToken("EXPECTED_GOHAN_SUM", position, buffer, verification);
8614 
8615     sprintf(buffer, "%d", m_goten_length);
8616     Utils::replaceToken("EXPECTED_GOTEN_SUM", position, buffer, verification);
8617 
8618     return verification;
8619 }
8620 
8621 /** Prepare unifroms
8622  *
8623  * @param ignored
8624  * @param ignored
8625  * @param program Program object
8626  * @param ignored
8627  **/
8628 void GLSLConstantIntegralExpressionTest::prepareUniforms(GLuint /* test_case_index */,
8629                                                          Utils::ProgramInterface & /* program_interface */,
8630                                                          Utils::Program &program, Utils::Buffer & /* cs_buffer */)
8631 {
8632     static const GLuint uniform_data[16] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
8633 
8634     const Functions &gl = m_context.getRenderContext().getFunctions();
8635 
8636     GLint goku_location  = program.GetUniformLocation("goku");
8637     GLint gohan_location = program.GetUniformLocation("gohan");
8638     GLint goten_location = program.GetUniformLocation("goten");
8639 
8640     program.Uniform(gl, Utils::Type::uint, 1 /* count */, goku_location, uniform_data);
8641     program.Uniform(gl, Utils::Type::uint, m_gohan_length, gohan_location, uniform_data);
8642     program.Uniform(gl, Utils::Type::uint, m_goten_length, goten_location, uniform_data);
8643 }
8644 
8645 /** Prepare unifroms
8646  *
8647  * @param test_case_index   Pass as param to first implemetnation
8648  * @param program_interface Pass as param to first implemetnation
8649  * @param program           Pass as param to first implemetnation
8650  * @param ignored
8651  * @param ignored
8652  * @param ignored
8653  * @param ignored
8654  * @param vs_buffer         Pass as param to first implemetnation
8655  **/
8656 void GLSLConstantIntegralExpressionTest::prepareUniforms(GLuint test_case_index,
8657                                                          Utils::ProgramInterface &program_interface,
8658                                                          Utils::Program &program, Utils::Buffer & /* fs_buffer */,
8659                                                          Utils::Buffer & /* gs_buffer */,
8660                                                          Utils::Buffer & /* tcs_buffer */,
8661                                                          Utils::Buffer & /* tes_buffer */, Utils::Buffer &vs_buffer)
8662 {
8663     /* Call first implementation */
8664     prepareUniforms(test_case_index, program_interface, program, vs_buffer);
8665 }
8666 
8667 /** Constructor
8668  *
8669  * @param context Test framework context
8670  **/
8671 UniformBlockMemberOffsetAndAlignTest::UniformBlockMemberOffsetAndAlignTest(deqp::Context &context)
8672     : TextureTestBase(context, "uniform_block_member_offset_and_align",
8673                       "Test verifies offsets and alignment of uniform buffer members")
8674 {
8675 }
8676 
8677 /** Get interface of program
8678  *
8679  * @param test_case_index     Test case index
8680  * @param program_interface   Interface of program
8681  * @param varying_passthrough Collection of connections between in and out variables
8682  **/
8683 void UniformBlockMemberOffsetAndAlignTest::getProgramInterface(GLuint test_case_index,
8684                                                                Utils::ProgramInterface &program_interface,
8685                                                                Utils::VaryingPassthrough &varying_passthrough)
8686 {
8687     std::string globals = "const int basic_size = BASIC_SIZE;\n"
8688                           "const int type_align = TYPE_ALIGN;\n"
8689                           "const int type_size  = TYPE_SIZE;\n";
8690 
8691     Utils::Type type         = getType(test_case_index);
8692     GLuint basic_size        = Utils::Type::GetTypeSize(type.m_basic_type);
8693     const GLuint base_align  = type.GetBaseAlignment(false);
8694     const GLuint array_align = type.GetBaseAlignment(true);
8695     const GLuint base_stride = Utils::Type::CalculateStd140Stride(base_align, type.m_n_columns, 0);
8696     const GLuint type_align  = Utils::roundUpToPowerOf2(base_stride);
8697 
8698     /* Calculate offsets */
8699     const GLuint first_offset  = 0;
8700     const GLuint second_offset = type.GetActualOffset(base_stride, basic_size / 2);
8701 
8702 #if WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST
8703 
8704     const GLuint third_offset   = type.GetActualOffset(second_offset + base_stride, base_align);
8705     const GLuint fourth_offset  = type.GetActualOffset(third_offset + base_stride, base_align);
8706     const GLuint fifth_offset   = type.GetActualOffset(fourth_offset + base_stride, base_align);
8707     const GLuint sixth_offset   = type.GetActualOffset(fifth_offset + base_stride, array_align);
8708     const GLuint seventh_offset = type.GetActualOffset(sixth_offset + base_stride, array_align);
8709     const GLuint eigth_offset   = type.GetActualOffset(seventh_offset + base_stride, array_align);
8710 
8711 #else /* WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST */
8712 
8713     const GLuint third_offset   = type.GetActualOffset(second_offset + base_stride, 2 * type_align);
8714     const GLuint fourth_offset  = type.GetActualOffset(3 * type_align + base_stride, base_align);
8715     const GLuint fifth_offset   = type.GetActualOffset(fourth_offset + base_stride, base_align);
8716     const GLuint sixth_offset   = type.GetActualOffset(fifth_offset + base_stride, array_align);
8717     const GLuint seventh_offset = type.GetActualOffset(sixth_offset + base_stride, array_align);
8718     const GLuint eigth_offset   = type.GetActualOffset(seventh_offset + base_stride, 8 * basic_size);
8719 
8720 #endif /* WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST */
8721 
8722     /* Prepare data */
8723     const std::vector<GLubyte> &first  = type.GenerateData();
8724     const std::vector<GLubyte> &second = type.GenerateData();
8725     const std::vector<GLubyte> &third  = type.GenerateData();
8726     const std::vector<GLubyte> &fourth = type.GenerateData();
8727 
8728     m_data.resize(eigth_offset + base_stride);
8729     GLubyte *ptr = &m_data[0];
8730     memcpy(ptr + first_offset, &first[0], first.size());
8731     memcpy(ptr + second_offset, &second[0], second.size());
8732     memcpy(ptr + third_offset, &third[0], third.size());
8733     memcpy(ptr + fourth_offset, &fourth[0], fourth.size());
8734     memcpy(ptr + fifth_offset, &fourth[0], fourth.size());
8735     memcpy(ptr + sixth_offset, &third[0], third.size());
8736     memcpy(ptr + seventh_offset, &second[0], second.size());
8737     memcpy(ptr + eigth_offset, &first[0], first.size());
8738 
8739     /* Prepare globals */
8740     size_t position = 0;
8741     GLchar buffer[16];
8742 
8743     sprintf(buffer, "%d", basic_size);
8744     Utils::replaceToken("BASIC_SIZE", position, buffer, globals);
8745 
8746     sprintf(buffer, "%d", type_align);
8747     Utils::replaceToken("TYPE_ALIGN", position, buffer, globals);
8748 
8749     sprintf(buffer, "%d", base_stride);
8750     Utils::replaceToken("TYPE_SIZE", position, buffer, globals);
8751 
8752     /* Prepare Block */
8753     Utils::Interface *vs_uni_block = program_interface.Block("vs_uni_Block");
8754 
8755     vs_uni_block->Member("at_first_offset", "layout(offset = 0, align = 8 * basic_size)", 0 /* expected_component */,
8756                          0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
8757                          first_offset);
8758 
8759     vs_uni_block->Member("at_second_offset", "layout(offset = type_size, align = basic_size / 2)",
8760                          0 /* expected_component */, 0 /* expected_location */, type, false /* normalized */,
8761                          0 /* n_array_elements */, base_stride, second_offset);
8762 
8763     vs_uni_block->Member("at_third_offset", "layout(align = 2 * type_align)", 0 /* expected_component */,
8764                          0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
8765                          third_offset);
8766 
8767     vs_uni_block->Member("at_fourth_offset", "layout(offset = 3 * type_align + type_size)", 0 /* expected_component */,
8768                          0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
8769                          fourth_offset);
8770 
8771     vs_uni_block->Member("at_fifth_offset", "", 0 /* expected_component */, 0 /* expected_location */, type,
8772                          false /* normalized */, 0 /* n_array_elements */, base_stride, fifth_offset);
8773 
8774     vs_uni_block->Member("at_sixth_offset", "", 0 /* expected_component */, 0 /* expected_location */, type,
8775                          false /* normalized */, 2 /* n_array_elements */, array_align * 2, sixth_offset);
8776 
8777     vs_uni_block->Member("at_eigth_offset", "layout(align = 8 * basic_size)", 0 /* expected_component */,
8778                          0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
8779                          eigth_offset);
8780 
8781     Utils::ShaderInterface &vs_si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
8782 
8783     /* Add globals */
8784     vs_si.m_globals = globals;
8785 
8786     /* Add uniform BLOCK */
8787     vs_si.Uniform("vs_uni_block", "layout (std140, binding = BINDING)", 0, 0, vs_uni_block, 0,
8788                   static_cast<glw::GLint>(m_data.size()), 0, &m_data[0], m_data.size());
8789 
8790     /* */
8791     program_interface.CloneVertexInterface(varying_passthrough);
8792 }
8793 
8794 /** Get type name
8795  *
8796  * @param test_case_index Index of test case
8797  *
8798  * @return Name of type test in test_case_index
8799  **/
8800 std::string UniformBlockMemberOffsetAndAlignTest::getTestCaseName(glw::GLuint test_case_index)
8801 {
8802     return getTypeName(test_case_index);
8803 }
8804 
8805 /** Returns number of types to test
8806  *
8807  * @return Number of types, 34
8808  **/
8809 glw::GLuint UniformBlockMemberOffsetAndAlignTest::getTestCaseNumber()
8810 {
8811     return getTypesNumber();
8812 }
8813 
8814 /** Prepare code snippet that will verify in and uniform variables
8815  *
8816  * @param ignored
8817  * @param ignored
8818  * @param stage   Shader stage
8819  *
8820  * @return Code that verify variables
8821  **/
8822 std::string UniformBlockMemberOffsetAndAlignTest::getVerificationSnippet(
8823     GLuint /* test_case_index */, Utils::ProgramInterface & /* program_interface */, Utils::Shader::STAGES stage)
8824 {
8825     std::string verification = "if ( (PREFIXblock.at_first_offset  != PREFIXblock.at_eigth_offset   ) ||\n"
8826                                "         (PREFIXblock.at_second_offset != PREFIXblock.at_sixth_offset[1]) ||\n"
8827                                "         (PREFIXblock.at_third_offset  != PREFIXblock.at_sixth_offset[0]) ||\n"
8828                                "         (PREFIXblock.at_fourth_offset != PREFIXblock.at_fifth_offset   )  )\n"
8829                                "    {\n"
8830                                "        result = 0;\n"
8831                                "    }";
8832 
8833     const GLchar *prefix = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::UNIFORM);
8834 
8835     Utils::replaceAllTokens("PREFIX", prefix, verification);
8836 
8837     return verification;
8838 }
8839 
8840 /** Constructor
8841  *
8842  * @param context Test framework context
8843  **/
8844 UniformBlockLayoutQualifierConflictTest::UniformBlockLayoutQualifierConflictTest(deqp::Context &context)
8845     : NegativeTestBase(
8846           context, "uniform_block_layout_qualifier_conflict",
8847           "Test verifies that std140 is required when offset and/or align qualifiers are used with uniform block")
8848 {
8849     /* Nothing to be done here */
8850 }
8851 
8852 /** Source for given test case and stage
8853  *
8854  * @param test_case_index Index of test case
8855  * @param stage           Shader stage
8856  *
8857  * @return Shader source
8858  **/
8859 std::string UniformBlockLayoutQualifierConflictTest::getShaderSource(GLuint test_case_index,
8860                                                                      Utils::Shader::STAGES stage)
8861 {
8862     static const GLchar *cs  = "#version 430 core\n"
8863                                "#extension GL_ARB_enhanced_layouts : require\n"
8864                                "\n"
8865                                "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
8866                                "\n"
8867                                "LAYOUTuniform Block {\n"
8868                                "    layout(offset = 16) vec4 b;\n"
8869                                "    layout(align  = 64) vec4 a;\n"
8870                                "} uni_block;\n"
8871                                "\n"
8872                                "writeonly uniform image2D uni_image;\n"
8873                                "\n"
8874                                "void main()\n"
8875                                "{\n"
8876                                "    vec4 result = uni_block.b + uni_block.a;\n"
8877                                "\n"
8878                                "    imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
8879                                "}\n"
8880                                "\n";
8881     static const GLchar *fs  = "#version 430 core\n"
8882                                "#extension GL_ARB_enhanced_layouts : require\n"
8883                                "\n"
8884                                "LAYOUTuniform Block {\n"
8885                                "    layout(offset = 16) vec4 b;\n"
8886                                "    layout(align  = 64) vec4 a;\n"
8887                                "} uni_block;\n"
8888                                "\n"
8889                                "in  vec4 gs_fs;\n"
8890                                "out vec4 fs_out;\n"
8891                                "\n"
8892                                "void main()\n"
8893                                "{\n"
8894                                "    fs_out = gs_fs + uni_block.b + uni_block.a;\n"
8895                                "}\n"
8896                                "\n";
8897     static const GLchar *gs  = "#version 430 core\n"
8898                                "#extension GL_ARB_enhanced_layouts : require\n"
8899                                "\n"
8900                                "layout(points)                           in;\n"
8901                                "layout(triangle_strip, max_vertices = 4) out;\n"
8902                                "\n"
8903                                "LAYOUTuniform Block {\n"
8904                                "    layout(offset = 16) vec4 b;\n"
8905                                "    layout(align  = 64) vec4 a;\n"
8906                                "} uni_block;\n"
8907                                "\n"
8908                                "in  vec4 tes_gs[];\n"
8909                                "out vec4 gs_fs;\n"
8910                                "\n"
8911                                "void main()\n"
8912                                "{\n"
8913                                "    gs_fs = tes_gs[0] + uni_block.b + uni_block.a;\n"
8914                                "    gl_Position  = vec4(-1, -1, 0, 1);\n"
8915                                "    EmitVertex();\n"
8916                                "    gs_fs = tes_gs[0] + uni_block.b + uni_block.a;\n"
8917                                "    gl_Position  = vec4(-1, 1, 0, 1);\n"
8918                                "    EmitVertex();\n"
8919                                "    gs_fs = tes_gs[0] + uni_block.b + uni_block.a;\n"
8920                                "    gl_Position  = vec4(1, -1, 0, 1);\n"
8921                                "    EmitVertex();\n"
8922                                "    gs_fs = tes_gs[0] + uni_block.b + uni_block.a;\n"
8923                                "    gl_Position  = vec4(1, 1, 0, 1);\n"
8924                                "    EmitVertex();\n"
8925                                "}\n"
8926                                "\n";
8927     static const GLchar *tcs = "#version 430 core\n"
8928                                "#extension GL_ARB_enhanced_layouts : require\n"
8929                                "\n"
8930                                "layout(vertices = 1) out;\n"
8931                                "\n"
8932                                "LAYOUTuniform Block {\n"
8933                                "    layout(offset = 16) vec4 b;\n"
8934                                "    layout(align  = 64) vec4 a;\n"
8935                                "} uni_block;\n"
8936                                "\n"
8937                                "in  vec4 vs_tcs[];\n"
8938                                "out vec4 tcs_tes[];\n"
8939                                "\n"
8940                                "void main()\n"
8941                                "{\n"
8942                                "\n"
8943                                "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID] + uni_block.b + uni_block.a;\n"
8944                                "\n"
8945                                "    gl_TessLevelOuter[0] = 1.0;\n"
8946                                "    gl_TessLevelOuter[1] = 1.0;\n"
8947                                "    gl_TessLevelOuter[2] = 1.0;\n"
8948                                "    gl_TessLevelOuter[3] = 1.0;\n"
8949                                "    gl_TessLevelInner[0] = 1.0;\n"
8950                                "    gl_TessLevelInner[1] = 1.0;\n"
8951                                "}\n"
8952                                "\n";
8953     static const GLchar *tes = "#version 430 core\n"
8954                                "#extension GL_ARB_enhanced_layouts : require\n"
8955                                "\n"
8956                                "layout(isolines, point_mode) in;\n"
8957                                "\n"
8958                                "LAYOUTuniform Block {\n"
8959                                "    layout(offset = 16) vec4 b;\n"
8960                                "    layout(align  = 64) vec4 a;\n"
8961                                "} uni_block;\n"
8962                                "\n"
8963                                "in  vec4 tcs_tes[];\n"
8964                                "out vec4 tes_gs;\n"
8965                                "\n"
8966                                "void main()\n"
8967                                "{\n"
8968                                "    tes_gs = tcs_tes[0] + uni_block.b + uni_block.a;\n"
8969                                "}\n"
8970                                "\n";
8971     static const GLchar *vs  = "#version 430 core\n"
8972                                "#extension GL_ARB_enhanced_layouts : require\n"
8973                                "\n"
8974                                "LAYOUTuniform Block {\n"
8975                                "    layout(offset = 16) vec4 b;\n"
8976                                "    layout(align  = 64) vec4 a;\n"
8977                                "} uni_block;\n"
8978                                "\n"
8979                                "in  vec4 in_vs;\n"
8980                                "out vec4 vs_tcs;\n"
8981                                "\n"
8982                                "void main()\n"
8983                                "{\n"
8984                                "    vs_tcs = in_vs + uni_block.b + uni_block.a;\n"
8985                                "}\n"
8986                                "\n";
8987 
8988     std::string layout      = "";
8989     size_t position         = 0;
8990     testCase &test_case     = m_test_cases[test_case_index];
8991     const GLchar *qualifier = getQualifierName(test_case.m_qualifier);
8992     std::string source;
8993 
8994     if (0 != qualifier[0])
8995     {
8996         size_t layout_position = 0;
8997 
8998         layout = "layout (QUALIFIER) ";
8999 
9000         Utils::replaceToken("QUALIFIER", layout_position, qualifier, layout);
9001     }
9002 
9003     switch (stage)
9004     {
9005     case Utils::Shader::COMPUTE:
9006         source = cs;
9007         break;
9008     case Utils::Shader::FRAGMENT:
9009         source = fs;
9010         break;
9011     case Utils::Shader::GEOMETRY:
9012         source = gs;
9013         break;
9014     case Utils::Shader::TESS_CTRL:
9015         source = tcs;
9016         break;
9017     case Utils::Shader::TESS_EVAL:
9018         source = tes;
9019         break;
9020     case Utils::Shader::VERTEX:
9021         source = vs;
9022         break;
9023     default:
9024         TCU_FAIL("Invalid enum");
9025     }
9026 
9027     if (test_case.m_stage == stage)
9028     {
9029         Utils::replaceToken("LAYOUT", position, layout.c_str(), source);
9030     }
9031     else
9032     {
9033         Utils::replaceToken("LAYOUT", position, "layout (std140) ", source);
9034     }
9035 
9036     return source;
9037 }
9038 
9039 /** Get description of test case
9040  *
9041  * @param test_case_index Index of test case
9042  *
9043  * @return Qualifier name
9044  **/
9045 std::string UniformBlockLayoutQualifierConflictTest::getTestCaseName(GLuint test_case_index)
9046 {
9047     std::string result = getQualifierName(m_test_cases[test_case_index].m_qualifier);
9048 
9049     return result;
9050 }
9051 
9052 /** Get number of test cases
9053  *
9054  * @return Number of test cases
9055  **/
9056 GLuint UniformBlockLayoutQualifierConflictTest::getTestCaseNumber()
9057 {
9058     return static_cast<GLuint>(m_test_cases.size());
9059 }
9060 
9061 /** Selects if "compute" stage is relevant for test
9062  *
9063  * @param test_case_index Index of test case
9064  *
9065  * @return true when tested stage is compute
9066  **/
9067 bool UniformBlockLayoutQualifierConflictTest::isComputeRelevant(GLuint test_case_index)
9068 {
9069     return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
9070 }
9071 
9072 /** Selects if compilation failure is expected result
9073  *
9074  * @param test_case_index Index of test case
9075  *
9076  * @return false for STD140 cases, true otherwise
9077  **/
9078 bool UniformBlockLayoutQualifierConflictTest::isFailureExpected(GLuint test_case_index)
9079 {
9080     return (STD140 != m_test_cases[test_case_index].m_qualifier);
9081 }
9082 
9083 /** Prepare all test cases
9084  *
9085  **/
9086 void UniformBlockLayoutQualifierConflictTest::testInit()
9087 {
9088     for (GLuint qualifier = 0; qualifier < QUALIFIERS_MAX; ++qualifier)
9089     {
9090         for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
9091         {
9092             testCase test_case = {(QUALIFIERS)qualifier, (Utils::Shader::STAGES)stage};
9093 
9094             m_test_cases.push_back(test_case);
9095         }
9096     }
9097 }
9098 
9099 /** Get name of glsl constant
9100  *
9101  * @param Constant id
9102  *
9103  * @return Name of constant used in GLSL
9104  **/
9105 const GLchar *UniformBlockLayoutQualifierConflictTest::getQualifierName(QUALIFIERS qualifier)
9106 {
9107     const GLchar *name = "";
9108 
9109     switch (qualifier)
9110     {
9111     case DEFAULT:
9112         name = "";
9113         break;
9114     case STD140:
9115         name = "std140";
9116         break;
9117     case SHARED:
9118         name = "shared";
9119         break;
9120     case PACKED:
9121         name = "packed";
9122         break;
9123     default:
9124         TCU_FAIL("Invalid enum");
9125     }
9126 
9127     return name;
9128 }
9129 
9130 /** Constructor
9131  *
9132  * @param context Test framework context
9133  **/
9134 UniformBlockMemberInvalidOffsetAlignmentTest::UniformBlockMemberInvalidOffsetAlignmentTest(deqp::Context &context)
9135     : NegativeTestBase(context, "uniform_block_member_invalid_offset_alignment",
9136                        "Test verifies that invalid alignment of offset qualifiers cause compilation failure")
9137 {
9138     /* Nothing to be done here */
9139 }
9140 
9141 /** Constructor
9142  *
9143  * @param context     Test framework context
9144  * @param name        Test name
9145  * @param description Test description
9146  **/
9147 UniformBlockMemberInvalidOffsetAlignmentTest::UniformBlockMemberInvalidOffsetAlignmentTest(
9148     deqp::Context &context, const glw::GLchar *name, const glw::GLchar *description)
9149     : NegativeTestBase(context, name, description)
9150 {
9151     /* Nothing to be done here */
9152 }
9153 
9154 /** Source for given test case and stage
9155  *
9156  * @param test_case_index Index of test case
9157  * @param stage           Shader stage
9158  *
9159  * @return Shader source
9160  **/
9161 std::string UniformBlockMemberInvalidOffsetAlignmentTest::getShaderSource(GLuint test_case_index,
9162                                                                           Utils::Shader::STAGES stage)
9163 {
9164     static const GLchar *cs         = "#version 430 core\n"
9165                                       "#extension GL_ARB_enhanced_layouts : require\n"
9166                                       "\n"
9167                                       "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
9168                                       "\n"
9169                                       "layout (std140) uniform Block {\n"
9170                                       "    layout (offset = OFFSET) TYPE member;\n"
9171                                       "} block;\n"
9172                                       "\n"
9173                                       "writeonly uniform image2D uni_image;\n"
9174                                       "\n"
9175                                       "void main()\n"
9176                                       "{\n"
9177                                       "    vec4 result = vec4(1, 0, 0.5, 1);\n"
9178                                       "\n"
9179                                       "    if (TYPE(1) == block.member)\n"
9180                                       "    {\n"
9181                                       "        result = vec4(1, 1, 1, 1);\n"
9182                                       "    }\n"
9183                                       "\n"
9184                                       "    imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
9185                                       "}\n"
9186                                       "\n";
9187     static const GLchar *fs         = "#version 430 core\n"
9188                                       "#extension GL_ARB_enhanced_layouts : require\n"
9189                                       "\n"
9190                                       "in  vec4 gs_fs;\n"
9191                                       "out vec4 fs_out;\n"
9192                                       "\n"
9193                                       "void main()\n"
9194                                       "{\n"
9195                                       "    fs_out = gs_fs;\n"
9196                                       "}\n"
9197                                       "\n";
9198     static const GLchar *fs_tested  = "#version 430 core\n"
9199                                       "#extension GL_ARB_enhanced_layouts : require\n"
9200                                       "\n"
9201                                       "layout (std140) uniform Block {\n"
9202                                       "    layout (offset = OFFSET) TYPE member;\n"
9203                                       "} block;\n"
9204                                       "\n"
9205                                       "in  vec4 gs_fs;\n"
9206                                       "out vec4 fs_out;\n"
9207                                       "\n"
9208                                       "void main()\n"
9209                                       "{\n"
9210                                       "    if (TYPE(1) == block.member)\n"
9211                                       "    {\n"
9212                                       "        fs_out = vec4(1, 1, 1, 1);\n"
9213                                       "    }\n"
9214                                       "\n"
9215                                       "    fs_out += gs_fs;\n"
9216                                       "}\n"
9217                                       "\n";
9218     static const GLchar *gs         = "#version 430 core\n"
9219                                       "#extension GL_ARB_enhanced_layouts : require\n"
9220                                       "\n"
9221                                       "layout(points)                           in;\n"
9222                                       "layout(triangle_strip, max_vertices = 4) out;\n"
9223                                       "\n"
9224                                       "in  vec4 tes_gs[];\n"
9225                                       "out vec4 gs_fs;\n"
9226                                       "\n"
9227                                       "void main()\n"
9228                                       "{\n"
9229                                       "    gs_fs = tes_gs[0];\n"
9230                                       "    gl_Position  = vec4(-1, -1, 0, 1);\n"
9231                                       "    EmitVertex();\n"
9232                                       "    gs_fs = tes_gs[0];\n"
9233                                       "    gl_Position  = vec4(-1, 1, 0, 1);\n"
9234                                       "    EmitVertex();\n"
9235                                       "    gs_fs = tes_gs[0];\n"
9236                                       "    gl_Position  = vec4(1, -1, 0, 1);\n"
9237                                       "    EmitVertex();\n"
9238                                       "    gs_fs = tes_gs[0];\n"
9239                                       "    gl_Position  = vec4(1, 1, 0, 1);\n"
9240                                       "    EmitVertex();\n"
9241                                       "}\n"
9242                                       "\n";
9243     static const GLchar *gs_tested  = "#version 430 core\n"
9244                                       "#extension GL_ARB_enhanced_layouts : require\n"
9245                                       "\n"
9246                                       "layout(points)                           in;\n"
9247                                       "layout(triangle_strip, max_vertices = 4) out;\n"
9248                                       "\n"
9249                                       "layout (std140) uniform Block {\n"
9250                                       "    layout (offset = OFFSET) TYPE member;\n"
9251                                       "} block;\n"
9252                                       "\n"
9253                                       "in  vec4 tes_gs[];\n"
9254                                       "out vec4 gs_fs;\n"
9255                                       "\n"
9256                                       "void main()\n"
9257                                       "{\n"
9258                                       "    if (TYPE(1) == block.member)\n"
9259                                       "    {\n"
9260                                       "        gs_fs = vec4(1, 1, 1, 1);\n"
9261                                       "    }\n"
9262                                       "\n"
9263                                       "    gs_fs += tes_gs[0];\n"
9264                                       "    gl_Position  = vec4(-1, -1, 0, 1);\n"
9265                                       "    EmitVertex();\n"
9266                                       "    gs_fs += tes_gs[0];\n"
9267                                       "    gl_Position  = vec4(-1, 1, 0, 1);\n"
9268                                       "    EmitVertex();\n"
9269                                       "    gs_fs += tes_gs[0];\n"
9270                                       "    gl_Position  = vec4(1, -1, 0, 1);\n"
9271                                       "    EmitVertex();\n"
9272                                       "    gs_fs += tes_gs[0];\n"
9273                                       "    gl_Position  = vec4(1, 1, 0, 1);\n"
9274                                       "    EmitVertex();\n"
9275                                       "}\n"
9276                                       "\n";
9277     static const GLchar *tcs        = "#version 430 core\n"
9278                                       "#extension GL_ARB_enhanced_layouts : require\n"
9279                                       "\n"
9280                                       "layout(vertices = 1) out;\n"
9281                                       "\n"
9282                                       "in  vec4 vs_tcs[];\n"
9283                                       "out vec4 tcs_tes[];\n"
9284                                       "\n"
9285                                       "void main()\n"
9286                                       "{\n"
9287                                       "\n"
9288                                       "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
9289                                       "\n"
9290                                       "    gl_TessLevelOuter[0] = 1.0;\n"
9291                                       "    gl_TessLevelOuter[1] = 1.0;\n"
9292                                       "    gl_TessLevelOuter[2] = 1.0;\n"
9293                                       "    gl_TessLevelOuter[3] = 1.0;\n"
9294                                       "    gl_TessLevelInner[0] = 1.0;\n"
9295                                       "    gl_TessLevelInner[1] = 1.0;\n"
9296                                       "}\n"
9297                                       "\n";
9298     static const GLchar *tcs_tested = "#version 430 core\n"
9299                                       "#extension GL_ARB_enhanced_layouts : require\n"
9300                                       "\n"
9301                                       "layout(vertices = 1) out;\n"
9302                                       "\n"
9303                                       "layout (std140) uniform Block {\n"
9304                                       "    layout (offset = OFFSET) TYPE member;\n"
9305                                       "} block;\n"
9306                                       "\n"
9307                                       "in  vec4 vs_tcs[];\n"
9308                                       "out vec4 tcs_tes[];\n"
9309                                       "\n"
9310                                       "void main()\n"
9311                                       "{\n"
9312                                       "    if (TYPE(1) == block.member)\n"
9313                                       "    {\n"
9314                                       "        tcs_tes[gl_InvocationID] = vec4(1, 1, 1, 1);\n"
9315                                       "    }\n"
9316                                       "\n"
9317                                       "\n"
9318                                       "    tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
9319                                       "\n"
9320                                       "    gl_TessLevelOuter[0] = 1.0;\n"
9321                                       "    gl_TessLevelOuter[1] = 1.0;\n"
9322                                       "    gl_TessLevelOuter[2] = 1.0;\n"
9323                                       "    gl_TessLevelOuter[3] = 1.0;\n"
9324                                       "    gl_TessLevelInner[0] = 1.0;\n"
9325                                       "    gl_TessLevelInner[1] = 1.0;\n"
9326                                       "}\n"
9327                                       "\n";
9328     static const GLchar *tes        = "#version 430 core\n"
9329                                       "#extension GL_ARB_enhanced_layouts : require\n"
9330                                       "\n"
9331                                       "layout(isolines, point_mode) in;\n"
9332                                       "\n"
9333                                       "in  vec4 tcs_tes[];\n"
9334                                       "out vec4 tes_gs;\n"
9335                                       "\n"
9336                                       "void main()\n"
9337                                       "{\n"
9338                                       "    tes_gs = tcs_tes[0];\n"
9339                                       "}\n"
9340                                       "\n";
9341     static const GLchar *tes_tested = "#version 430 core\n"
9342                                       "#extension GL_ARB_enhanced_layouts : require\n"
9343                                       "\n"
9344                                       "layout(isolines, point_mode) in;\n"
9345                                       "\n"
9346                                       "layout (std140) uniform Block {\n"
9347                                       "    layout (offset = OFFSET) TYPE member;\n"
9348                                       "} block;\n"
9349                                       "\n"
9350                                       "in  vec4 tcs_tes[];\n"
9351                                       "out vec4 tes_gs;\n"
9352                                       "\n"
9353                                       "void main()\n"
9354                                       "{\n"
9355                                       "    if (TYPE(1) == block.member)\n"
9356                                       "    {\n"
9357                                       "        tes_gs = vec4(1, 1, 1, 1);\n"
9358                                       "    }\n"
9359                                       "\n"
9360                                       "    tes_gs += tcs_tes[0];\n"
9361                                       "}\n"
9362                                       "\n";
9363     static const GLchar *vs         = "#version 430 core\n"
9364                                       "#extension GL_ARB_enhanced_layouts : require\n"
9365                                       "\n"
9366                                       "in  vec4 in_vs;\n"
9367                                       "out vec4 vs_tcs;\n"
9368                                       "\n"
9369                                       "void main()\n"
9370                                       "{\n"
9371                                       "    vs_tcs = in_vs;\n"
9372                                       "}\n"
9373                                       "\n";
9374     static const GLchar *vs_tested  = "#version 430 core\n"
9375                                       "#extension GL_ARB_enhanced_layouts : require\n"
9376                                       "\n"
9377                                       "layout (std140) uniform Block {\n"
9378                                       "    layout (offset = OFFSET) TYPE member;\n"
9379                                       "} block;\n"
9380                                       "\n"
9381                                       "in  vec4 in_vs;\n"
9382                                       "out vec4 vs_tcs;\n"
9383                                       "\n"
9384                                       "void main()\n"
9385                                       "{\n"
9386                                       "    if (TYPE(1) == block.member)\n"
9387                                       "    {\n"
9388                                       "        vs_tcs = vec4(1, 1, 1, 1);\n"
9389                                       "    }\n"
9390                                       "\n"
9391                                       "    vs_tcs += in_vs;\n"
9392                                       "}\n"
9393                                       "\n";
9394 
9395     std::string source;
9396     testCase &test_case = m_test_cases[test_case_index];
9397 
9398     if (test_case.m_stage == stage)
9399     {
9400         GLchar buffer[16];
9401         const GLuint offset     = test_case.m_offset;
9402         size_t position         = 0;
9403         const Utils::Type &type = test_case.m_type;
9404         const GLchar *type_name = type.GetGLSLTypeName();
9405 
9406         sprintf(buffer, "%d", offset);
9407 
9408         switch (stage)
9409         {
9410         case Utils::Shader::COMPUTE:
9411             source = cs;
9412             break;
9413         case Utils::Shader::FRAGMENT:
9414             source = fs_tested;
9415             break;
9416         case Utils::Shader::GEOMETRY:
9417             source = gs_tested;
9418             break;
9419         case Utils::Shader::TESS_CTRL:
9420             source = tcs_tested;
9421             break;
9422         case Utils::Shader::TESS_EVAL:
9423             source = tes_tested;
9424             break;
9425         case Utils::Shader::VERTEX:
9426             source = vs_tested;
9427             break;
9428         default:
9429             TCU_FAIL("Invalid enum");
9430         }
9431 
9432         Utils::replaceToken("OFFSET", position, buffer, source);
9433         Utils::replaceToken("TYPE", position, type_name, source);
9434         Utils::replaceToken("TYPE", position, type_name, source);
9435     }
9436     else
9437     {
9438         switch (stage)
9439         {
9440         case Utils::Shader::FRAGMENT:
9441             source = fs;
9442             break;
9443         case Utils::Shader::GEOMETRY:
9444             source = gs;
9445             break;
9446         case Utils::Shader::TESS_CTRL:
9447             source = tcs;
9448             break;
9449         case Utils::Shader::TESS_EVAL:
9450             source = tes;
9451             break;
9452         case Utils::Shader::VERTEX:
9453             source = vs;
9454             break;
9455         default:
9456             TCU_FAIL("Invalid enum");
9457         }
9458     }
9459 
9460     return source;
9461 }
9462 
9463 /** Get description of test case
9464  *
9465  * @param test_case_index Index of test case
9466  *
9467  * @return Type name and offset
9468  **/
9469 std::string UniformBlockMemberInvalidOffsetAlignmentTest::getTestCaseName(GLuint test_case_index)
9470 {
9471     std::stringstream stream;
9472     testCase &test_case = m_test_cases[test_case_index];
9473 
9474     stream << "Type: " << test_case.m_type.GetGLSLTypeName() << ", offset: " << test_case.m_offset;
9475 
9476     return stream.str();
9477 }
9478 
9479 /** Get number of test cases
9480  *
9481  * @return Number of test cases
9482  **/
9483 GLuint UniformBlockMemberInvalidOffsetAlignmentTest::getTestCaseNumber()
9484 {
9485     return static_cast<GLuint>(m_test_cases.size());
9486 }
9487 
9488 /** Get the maximum size for an uniform block
9489  *
9490  * @return The maximum size in basic machine units of a uniform block.
9491  **/
9492 GLint UniformBlockMemberInvalidOffsetAlignmentTest::getMaxBlockSize()
9493 {
9494     const Functions &gl = m_context.getRenderContext().getFunctions();
9495     GLint max_size      = 0;
9496 
9497     gl.getIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &max_size);
9498     GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
9499 
9500     return max_size;
9501 }
9502 
9503 /** Selects if "compute" stage is relevant for test
9504  *
9505  * @param test_case_index Index of test case
9506  *
9507  * @return true when tested stage is compute
9508  **/
9509 bool UniformBlockMemberInvalidOffsetAlignmentTest::isComputeRelevant(GLuint test_case_index)
9510 {
9511     return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
9512 }
9513 
9514 /** Selects if compilation failure is expected result
9515  *
9516  * @param test_case_index Index of test case
9517  *
9518  * @return should_fail field from testCase
9519  **/
9520 bool UniformBlockMemberInvalidOffsetAlignmentTest::isFailureExpected(GLuint test_case_index)
9521 {
9522     return m_test_cases[test_case_index].m_should_fail;
9523 }
9524 
9525 /** Checks if stage is supported
9526  *
9527  * @param stage ignored
9528  *
9529  * @return true
9530  **/
9531 bool UniformBlockMemberInvalidOffsetAlignmentTest::isStageSupported(Utils::Shader::STAGES /* stage */)
9532 {
9533     return true;
9534 }
9535 
9536 /** Prepare all test cases
9537  *
9538  **/
9539 void UniformBlockMemberInvalidOffsetAlignmentTest::testInit()
9540 {
9541     const GLuint n_types = getTypesNumber();
9542     bool stage_support[Utils::Shader::STAGE_MAX];
9543 
9544     for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
9545     {
9546         stage_support[stage] = isStageSupported((Utils::Shader::STAGES)stage);
9547     }
9548 
9549     for (GLuint i = 0; i < n_types; ++i)
9550     {
9551         const Utils::Type &type = getType(i);
9552         const GLuint alignment  = type.GetBaseAlignment(false);
9553         const GLuint type_size  = type.GetSize(true);
9554         const GLuint sec_to_end = getMaxBlockSize() - 2 * type_size;
9555 
9556         for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
9557         {
9558             if (false == stage_support[stage])
9559             {
9560                 continue;
9561             }
9562 
9563             for (GLuint offset = 0; offset <= type_size; ++offset)
9564             {
9565                 const GLuint modulo    = offset % alignment;
9566                 const bool is_aligned  = (0 == modulo) ? true : false;
9567                 const bool should_fail = !is_aligned;
9568 
9569                 testCase test_case = {offset, should_fail, (Utils::Shader::STAGES)stage, type};
9570 
9571                 m_test_cases.push_back(test_case);
9572             }
9573 
9574             for (GLuint offset = sec_to_end; offset <= sec_to_end + type_size; ++offset)
9575             {
9576                 const GLuint modulo    = offset % alignment;
9577                 const bool is_aligned  = (0 == modulo) ? true : false;
9578                 const bool should_fail = !is_aligned;
9579 
9580                 testCase test_case = {offset, should_fail, (Utils::Shader::STAGES)stage, type};
9581 
9582                 m_test_cases.push_back(test_case);
9583             }
9584         }
9585     }
9586 }
9587 
9588 /** Constructor
9589  *
9590  * @param context Test framework context
9591  **/
9592 UniformBlockMemberOverlappingOffsetsTest::UniformBlockMemberOverlappingOffsetsTest(deqp::Context &context)
9593     : NegativeTestBase(context, "uniform_block_member_overlapping_offsets",
9594                        "Test verifies that overlapping offsets qualifiers cause compilation failure")
9595 {
9596     /* Nothing to be done here */
9597 }
9598 
9599 /** Constructor
9600  *
9601  * @param context Test framework context
9602  * @param name        Test name
9603  * @param description Test description
9604  **/
9605 UniformBlockMemberOverlappingOffsetsTest::UniformBlockMemberOverlappingOffsetsTest(deqp::Context &context,
9606                                                                                    const glw::GLchar *name,
9607                                                                                    const glw::GLchar *description)
9608     : NegativeTestBase(context, name, description)
9609 {
9610     /* Nothing to be done here */
9611 }
9612 
9613 /** Source for given test case and stage
9614  *
9615  * @param test_case_index Index of test case
9616  * @param stage           Shader stage
9617  *
9618  * @return Shader source
9619  **/
9620 std::string UniformBlockMemberOverlappingOffsetsTest::getShaderSource(GLuint test_case_index,
9621                                                                       Utils::Shader::STAGES stage)
9622 {
9623     static const GLchar *cs         = "#version 430 core\n"
9624                                       "#extension GL_ARB_enhanced_layouts : require\n"
9625                                       "\n"
9626                                       "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
9627                                       "\n"
9628                                       "layout (std140) uniform Block {\n"
9629                                       "    layout (offset = B_OFFSET) B_TYPE b;\n"
9630                                       "    layout (offset = A_OFFSET) A_TYPE a;\n"
9631                                       "} block;\n"
9632                                       "\n"
9633                                       "writeonly uniform image2D uni_image;\n"
9634                                       "\n"
9635                                       "void main()\n"
9636                                       "{\n"
9637                                       "    vec4 result = vec4(1, 0, 0.5, 1);\n"
9638                                       "\n"
9639                                       "    if ((B_TYPE(1) == block.b) ||\n"
9640                                       "        (A_TYPE(0) == block.a) )\n"
9641                                       "    {\n"
9642                                       "        result = vec4(1, 1, 1, 1);\n"
9643                                       "    }\n"
9644                                       "\n"
9645                                       "    imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
9646                                       "}\n"
9647                                       "\n";
9648     static const GLchar *fs         = "#version 430 core\n"
9649                                       "#extension GL_ARB_enhanced_layouts : require\n"
9650                                       "\n"
9651                                       "in  vec4 gs_fs;\n"
9652                                       "out vec4 fs_out;\n"
9653                                       "\n"
9654                                       "void main()\n"
9655                                       "{\n"
9656                                       "    fs_out = gs_fs;\n"
9657                                       "}\n"
9658                                       "\n";
9659     static const GLchar *fs_tested  = "#version 430 core\n"
9660                                       "#extension GL_ARB_enhanced_layouts : require\n"
9661                                       "\n"
9662                                       "layout (std140) uniform Block {\n"
9663                                       "    layout (offset = B_OFFSET) B_TYPE b;\n"
9664                                       "    layout (offset = A_OFFSET) A_TYPE a;\n"
9665                                       "} block;\n"
9666                                       "\n"
9667                                       "in  vec4 gs_fs;\n"
9668                                       "out vec4 fs_out;\n"
9669                                       "\n"
9670                                       "void main()\n"
9671                                       "{\n"
9672                                       "    if ((B_TYPE(1) == block.b) ||\n"
9673                                       "        (A_TYPE(0) == block.a) )\n"
9674                                       "    {\n"
9675                                       "        fs_out = vec4(1, 1, 1, 1);\n"
9676                                       "    }\n"
9677                                       "\n"
9678                                       "    fs_out += gs_fs;\n"
9679                                       "}\n"
9680                                       "\n";
9681     static const GLchar *gs         = "#version 430 core\n"
9682                                       "#extension GL_ARB_enhanced_layouts : require\n"
9683                                       "\n"
9684                                       "layout(points)                           in;\n"
9685                                       "layout(triangle_strip, max_vertices = 4) out;\n"
9686                                       "\n"
9687                                       "in  vec4 tes_gs[];\n"
9688                                       "out vec4 gs_fs;\n"
9689                                       "\n"
9690                                       "void main()\n"
9691                                       "{\n"
9692                                       "    gs_fs = tes_gs[0];\n"
9693                                       "    gl_Position  = vec4(-1, -1, 0, 1);\n"
9694                                       "    EmitVertex();\n"
9695                                       "    gs_fs = tes_gs[0];\n"
9696                                       "    gl_Position  = vec4(-1, 1, 0, 1);\n"
9697                                       "    EmitVertex();\n"
9698                                       "    gs_fs = tes_gs[0];\n"
9699                                       "    gl_Position  = vec4(1, -1, 0, 1);\n"
9700                                       "    EmitVertex();\n"
9701                                       "    gs_fs = tes_gs[0];\n"
9702                                       "    gl_Position  = vec4(1, 1, 0, 1);\n"
9703                                       "    EmitVertex();\n"
9704                                       "}\n"
9705                                       "\n";
9706     static const GLchar *gs_tested  = "#version 430 core\n"
9707                                       "#extension GL_ARB_enhanced_layouts : require\n"
9708                                       "\n"
9709                                       "layout(points)                           in;\n"
9710                                       "layout(triangle_strip, max_vertices = 4) out;\n"
9711                                       "\n"
9712                                       "layout (std140) uniform Block {\n"
9713                                       "    layout (offset = B_OFFSET) B_TYPE b;\n"
9714                                       "    layout (offset = A_OFFSET) A_TYPE a;\n"
9715                                       "} block;\n"
9716                                       "\n"
9717                                       "in  vec4 tes_gs[];\n"
9718                                       "out vec4 gs_fs;\n"
9719                                       "\n"
9720                                       "void main()\n"
9721                                       "{\n"
9722                                       "    if ((B_TYPE(1) == block.b) ||\n"
9723                                       "        (A_TYPE(0) == block.a) )\n"
9724                                       "    {\n"
9725                                       "        gs_fs = vec4(1, 1, 1, 1);\n"
9726                                       "    }\n"
9727                                       "\n"
9728                                       "    gs_fs += tes_gs[0];\n"
9729                                       "    gl_Position  = vec4(-1, -1, 0, 1);\n"
9730                                       "    EmitVertex();\n"
9731                                       "    gs_fs += tes_gs[0];\n"
9732                                       "    gl_Position  = vec4(-1, 1, 0, 1);\n"
9733                                       "    EmitVertex();\n"
9734                                       "    gs_fs += tes_gs[0];\n"
9735                                       "    gl_Position  = vec4(1, -1, 0, 1);\n"
9736                                       "    EmitVertex();\n"
9737                                       "    gs_fs += tes_gs[0];\n"
9738                                       "    gl_Position  = vec4(1, 1, 0, 1);\n"
9739                                       "    EmitVertex();\n"
9740                                       "}\n"
9741                                       "\n";
9742     static const GLchar *tcs        = "#version 430 core\n"
9743                                       "#extension GL_ARB_enhanced_layouts : require\n"
9744                                       "\n"
9745                                       "layout(vertices = 1) out;\n"
9746                                       "\n"
9747                                       "in  vec4 vs_tcs[];\n"
9748                                       "out vec4 tcs_tes[];\n"
9749                                       "\n"
9750                                       "void main()\n"
9751                                       "{\n"
9752                                       "\n"
9753                                       "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
9754                                       "\n"
9755                                       "    gl_TessLevelOuter[0] = 1.0;\n"
9756                                       "    gl_TessLevelOuter[1] = 1.0;\n"
9757                                       "    gl_TessLevelOuter[2] = 1.0;\n"
9758                                       "    gl_TessLevelOuter[3] = 1.0;\n"
9759                                       "    gl_TessLevelInner[0] = 1.0;\n"
9760                                       "    gl_TessLevelInner[1] = 1.0;\n"
9761                                       "}\n"
9762                                       "\n";
9763     static const GLchar *tcs_tested = "#version 430 core\n"
9764                                       "#extension GL_ARB_enhanced_layouts : require\n"
9765                                       "\n"
9766                                       "layout(vertices = 1) out;\n"
9767                                       "\n"
9768                                       "layout (std140) uniform Block {\n"
9769                                       "    layout (offset = B_OFFSET) B_TYPE b;\n"
9770                                       "    layout (offset = A_OFFSET) A_TYPE a;\n"
9771                                       "} block;\n"
9772                                       "\n"
9773                                       "in  vec4 vs_tcs[];\n"
9774                                       "out vec4 tcs_tes[];\n"
9775                                       "\n"
9776                                       "void main()\n"
9777                                       "{\n"
9778                                       "    if ((B_TYPE(1) == block.b) ||\n"
9779                                       "        (A_TYPE(0) == block.a) )\n"
9780                                       "    {\n"
9781                                       "        tcs_tes[gl_InvocationID] = vec4(1, 1, 1, 1);\n"
9782                                       "    }\n"
9783                                       "\n"
9784                                       "\n"
9785                                       "    tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
9786                                       "\n"
9787                                       "    gl_TessLevelOuter[0] = 1.0;\n"
9788                                       "    gl_TessLevelOuter[1] = 1.0;\n"
9789                                       "    gl_TessLevelOuter[2] = 1.0;\n"
9790                                       "    gl_TessLevelOuter[3] = 1.0;\n"
9791                                       "    gl_TessLevelInner[0] = 1.0;\n"
9792                                       "    gl_TessLevelInner[1] = 1.0;\n"
9793                                       "}\n"
9794                                       "\n";
9795     static const GLchar *tes        = "#version 430 core\n"
9796                                       "#extension GL_ARB_enhanced_layouts : require\n"
9797                                       "\n"
9798                                       "layout(isolines, point_mode) in;\n"
9799                                       "\n"
9800                                       "in  vec4 tcs_tes[];\n"
9801                                       "out vec4 tes_gs;\n"
9802                                       "\n"
9803                                       "void main()\n"
9804                                       "{\n"
9805                                       "    tes_gs = tcs_tes[0];\n"
9806                                       "}\n"
9807                                       "\n";
9808     static const GLchar *tes_tested = "#version 430 core\n"
9809                                       "#extension GL_ARB_enhanced_layouts : require\n"
9810                                       "\n"
9811                                       "layout(isolines, point_mode) in;\n"
9812                                       "\n"
9813                                       "layout (std140) uniform Block {\n"
9814                                       "    layout (offset = B_OFFSET) B_TYPE b;\n"
9815                                       "    layout (offset = A_OFFSET) A_TYPE a;\n"
9816                                       "} block;\n"
9817                                       "\n"
9818                                       "in  vec4 tcs_tes[];\n"
9819                                       "out vec4 tes_gs;\n"
9820                                       "\n"
9821                                       "void main()\n"
9822                                       "{\n"
9823                                       "    if ((B_TYPE(1) == block.b) ||\n"
9824                                       "        (A_TYPE(0) == block.a) )\n"
9825                                       "    {\n"
9826                                       "        tes_gs = vec4(1, 1, 1, 1);\n"
9827                                       "    }\n"
9828                                       "\n"
9829                                       "    tes_gs += tcs_tes[0];\n"
9830                                       "}\n"
9831                                       "\n";
9832     static const GLchar *vs         = "#version 430 core\n"
9833                                       "#extension GL_ARB_enhanced_layouts : require\n"
9834                                       "\n"
9835                                       "in  vec4 in_vs;\n"
9836                                       "out vec4 vs_tcs;\n"
9837                                       "\n"
9838                                       "void main()\n"
9839                                       "{\n"
9840                                       "    vs_tcs = in_vs;\n"
9841                                       "}\n"
9842                                       "\n";
9843     static const GLchar *vs_tested  = "#version 430 core\n"
9844                                       "#extension GL_ARB_enhanced_layouts : require\n"
9845                                       "\n"
9846                                       "layout (std140) uniform Block {\n"
9847                                       "    layout (offset = B_OFFSET) B_TYPE b;\n"
9848                                       "    layout (offset = A_OFFSET) A_TYPE a;\n"
9849                                       "} block;\n"
9850                                       "\n"
9851                                       "in  vec4 in_vs;\n"
9852                                       "out vec4 vs_tcs;\n"
9853                                       "\n"
9854                                       "void main()\n"
9855                                       "{\n"
9856                                       "    if ((B_TYPE(1) == block.b) ||\n"
9857                                       "        (A_TYPE(0) == block.a) )\n"
9858                                       "    {\n"
9859                                       "        vs_tcs = vec4(1, 1, 1, 1);\n"
9860                                       "    }\n"
9861                                       "\n"
9862                                       "    vs_tcs += in_vs;\n"
9863                                       "}\n"
9864                                       "\n";
9865 
9866     std::string source;
9867     testCase &test_case = m_test_cases[test_case_index];
9868 
9869     if (test_case.m_stage == stage)
9870     {
9871         GLchar buffer[16];
9872         const GLuint b_offset     = test_case.m_b_offset;
9873         const Utils::Type &b_type = test_case.m_b_type;
9874         const GLchar *b_type_name = b_type.GetGLSLTypeName();
9875         const GLuint a_offset     = test_case.m_a_offset;
9876         const Utils::Type &a_type = test_case.m_a_type;
9877         const GLchar *a_type_name = a_type.GetGLSLTypeName();
9878         size_t position           = 0;
9879 
9880         switch (stage)
9881         {
9882         case Utils::Shader::COMPUTE:
9883             source = cs;
9884             break;
9885         case Utils::Shader::FRAGMENT:
9886             source = fs_tested;
9887             break;
9888         case Utils::Shader::GEOMETRY:
9889             source = gs_tested;
9890             break;
9891         case Utils::Shader::TESS_CTRL:
9892             source = tcs_tested;
9893             break;
9894         case Utils::Shader::TESS_EVAL:
9895             source = tes_tested;
9896             break;
9897         case Utils::Shader::VERTEX:
9898             source = vs_tested;
9899             break;
9900         default:
9901             TCU_FAIL("Invalid enum");
9902         }
9903 
9904         sprintf(buffer, "%d", b_offset);
9905         Utils::replaceToken("B_OFFSET", position, buffer, source);
9906         Utils::replaceToken("B_TYPE", position, b_type_name, source);
9907         sprintf(buffer, "%d", a_offset);
9908         Utils::replaceToken("A_OFFSET", position, buffer, source);
9909         Utils::replaceToken("A_TYPE", position, a_type_name, source);
9910         Utils::replaceToken("B_TYPE", position, b_type_name, source);
9911         Utils::replaceToken("A_TYPE", position, a_type_name, source);
9912     }
9913     else
9914     {
9915         switch (stage)
9916         {
9917         case Utils::Shader::FRAGMENT:
9918             source = fs;
9919             break;
9920         case Utils::Shader::GEOMETRY:
9921             source = gs;
9922             break;
9923         case Utils::Shader::TESS_CTRL:
9924             source = tcs;
9925             break;
9926         case Utils::Shader::TESS_EVAL:
9927             source = tes;
9928             break;
9929         case Utils::Shader::VERTEX:
9930             source = vs;
9931             break;
9932         default:
9933             TCU_FAIL("Invalid enum");
9934         }
9935     }
9936 
9937     return source;
9938 }
9939 
9940 /** Get description of test case
9941  *
9942  * @param test_case_index Index of test case
9943  *
9944  * @return Type name and offset
9945  **/
9946 std::string UniformBlockMemberOverlappingOffsetsTest::getTestCaseName(GLuint test_case_index)
9947 {
9948     std::stringstream stream;
9949     testCase &test_case = m_test_cases[test_case_index];
9950 
9951     stream << "Type: " << test_case.m_b_type.GetGLSLTypeName() << ", offset: " << test_case.m_b_offset
9952            << ". Type: " << test_case.m_a_type.GetGLSLTypeName() << ", offset: " << test_case.m_a_offset;
9953 
9954     return stream.str();
9955 }
9956 
9957 /** Get number of test cases
9958  *
9959  * @return Number of test cases
9960  **/
9961 GLuint UniformBlockMemberOverlappingOffsetsTest::getTestCaseNumber()
9962 {
9963     return static_cast<GLuint>(m_test_cases.size());
9964 }
9965 
9966 /** Selects if "compute" stage is relevant for test
9967  *
9968  * @param test_case_index Index of test case
9969  *
9970  * @return true when tested stage is compute
9971  **/
9972 bool UniformBlockMemberOverlappingOffsetsTest::isComputeRelevant(GLuint test_case_index)
9973 {
9974     return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
9975 }
9976 
9977 /** Checks if stage is supported
9978  *
9979  * @param stage ignored
9980  *
9981  * @return true
9982  **/
9983 bool UniformBlockMemberOverlappingOffsetsTest::isStageSupported(Utils::Shader::STAGES /* stage */)
9984 {
9985     return true;
9986 }
9987 
9988 /** Prepare all test cases
9989  *
9990  **/
9991 void UniformBlockMemberOverlappingOffsetsTest::testInit()
9992 {
9993     const GLuint n_types = getTypesNumber();
9994     bool stage_support[Utils::Shader::STAGE_MAX];
9995 
9996     for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
9997     {
9998         stage_support[stage] = isStageSupported((Utils::Shader::STAGES)stage);
9999     }
10000 
10001     for (GLuint i = 0; i < n_types; ++i)
10002     {
10003         const Utils::Type &b_type = getType(i);
10004         const GLuint b_size       = b_type.GetActualAlignment(1 /* align */, false /* is_array*/);
10005 
10006         for (GLuint j = 0; j < n_types; ++j)
10007         {
10008             const Utils::Type &a_type = getType(j);
10009             const GLuint a_align      = a_type.GetBaseAlignment(false);
10010             const GLuint a_size       = a_type.GetActualAlignment(1 /* align */, false /* is_array*/);
10011 
10012             const GLuint b_offset       = lcm(b_size, a_size);
10013             const GLuint a_after_start  = b_offset + 1;
10014             const GLuint a_after_off    = a_type.GetActualOffset(a_after_start, a_size);
10015             const GLuint a_before_start = b_offset - a_align;
10016             const GLuint a_before_off   = a_type.GetActualOffset(a_before_start, a_size);
10017 
10018             for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
10019             {
10020                 if (false == stage_support[stage])
10021                 {
10022                     continue;
10023                 }
10024 
10025                 if ((b_offset > a_before_off) && (b_offset < a_before_off + a_size))
10026                 {
10027                     testCase test_case = {b_offset, b_type, a_before_off, a_type, (Utils::Shader::STAGES)stage};
10028 
10029                     m_test_cases.push_back(test_case);
10030                 }
10031 
10032                 if ((b_offset < a_after_off) && (b_offset + b_size > a_after_off))
10033                 {
10034                     testCase test_case = {b_offset, b_type, a_after_off, a_type, (Utils::Shader::STAGES)stage};
10035 
10036                     m_test_cases.push_back(test_case);
10037                 }
10038 
10039                 /* b offset, should be fine for both types */
10040                 testCase test_case = {b_offset, b_type, b_offset, a_type, (Utils::Shader::STAGES)stage};
10041 
10042                 m_test_cases.push_back(test_case);
10043             }
10044         }
10045     }
10046 }
10047 
10048 /** Find greatest common divisor for a and b
10049  *
10050  * @param a A argument
10051  * @param b B argument
10052  *
10053  * @return Found gcd value
10054  **/
10055 GLuint UniformBlockMemberOverlappingOffsetsTest::gcd(GLuint a, GLuint b)
10056 {
10057     if ((0 != a) && (0 == b))
10058     {
10059         return a;
10060     }
10061     else
10062     {
10063         GLuint greater = std::max(a, b);
10064         GLuint lesser  = std::min(a, b);
10065 
10066         return gcd(lesser, greater % lesser);
10067     }
10068 }
10069 
10070 /** Find lowest common multiple for a and b
10071  *
10072  * @param a A argument
10073  * @param b B argument
10074  *
10075  * @return Found gcd value
10076  **/
10077 GLuint UniformBlockMemberOverlappingOffsetsTest::lcm(GLuint a, GLuint b)
10078 {
10079     return (a * b) / gcd(a, b);
10080 }
10081 
10082 /** Constructor
10083  *
10084  * @param context Test framework context
10085  **/
10086 UniformBlockMemberAlignNonPowerOf2Test::UniformBlockMemberAlignNonPowerOf2Test(deqp::Context &context)
10087     : NegativeTestBase(context, "uniform_block_member_align_non_power_of_2",
10088                        "Test verifies that align qualifier requires value that is a power of 2")
10089 {
10090     /* Nothing to be done here */
10091 }
10092 
10093 /** Constructor
10094  *
10095  * @param context Test framework context
10096  * @param name        Test name
10097  * @param description Test description
10098  **/
10099 UniformBlockMemberAlignNonPowerOf2Test::UniformBlockMemberAlignNonPowerOf2Test(deqp::Context &context,
10100                                                                                const glw::GLchar *name,
10101                                                                                const glw::GLchar *description)
10102     : NegativeTestBase(context, name, description)
10103 {
10104     /* Nothing to be done here */
10105 }
10106 
10107 /** Source for given test case and stage
10108  *
10109  * @param test_case_index Index of test case
10110  * @param stage           Shader stage
10111  *
10112  * @return Shader source
10113  **/
10114 std::string UniformBlockMemberAlignNonPowerOf2Test::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
10115 {
10116     static const GLchar *cs         = "#version 430 core\n"
10117                                       "#extension GL_ARB_enhanced_layouts : require\n"
10118                                       "\n"
10119                                       "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
10120                                       "\n"
10121                                       "layout (std140) uniform Block {\n"
10122                                       "    vec4 b;\n"
10123                                       "    layout (align = ALIGN) TYPE a;\n"
10124                                       "} block;\n"
10125                                       "\n"
10126                                       "writeonly uniform image2D uni_image;\n"
10127                                       "\n"
10128                                       "void main()\n"
10129                                       "{\n"
10130                                       "    vec4 result = vec4(1, 0, 0.5, 1);\n"
10131                                       "\n"
10132                                       "    if (TYPE(0) == block.a)\n"
10133                                       "    {\n"
10134                                       "        result = vec4(1, 1, 1, 1) - block.b;\n"
10135                                       "    }\n"
10136                                       "\n"
10137                                       "    imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
10138                                       "}\n"
10139                                       "\n";
10140     static const GLchar *fs         = "#version 430 core\n"
10141                                       "#extension GL_ARB_enhanced_layouts : require\n"
10142                                       "\n"
10143                                       "in  vec4 gs_fs;\n"
10144                                       "out vec4 fs_out;\n"
10145                                       "\n"
10146                                       "void main()\n"
10147                                       "{\n"
10148                                       "    fs_out = gs_fs;\n"
10149                                       "}\n"
10150                                       "\n";
10151     static const GLchar *fs_tested  = "#version 430 core\n"
10152                                       "#extension GL_ARB_enhanced_layouts : require\n"
10153                                       "\n"
10154                                       "layout (std140) uniform Block {\n"
10155                                       "    vec4 b;\n"
10156                                       "    layout (align = ALIGN) TYPE a;\n"
10157                                       "} block;\n"
10158                                       "\n"
10159                                       "in  vec4 gs_fs;\n"
10160                                       "out vec4 fs_out;\n"
10161                                       "\n"
10162                                       "void main()\n"
10163                                       "{\n"
10164                                       "    if (TYPE(0) == block.a)\n"
10165                                       "    {\n"
10166                                       "        fs_out = block.b;\n"
10167                                       "    }\n"
10168                                       "\n"
10169                                       "    fs_out += gs_fs;\n"
10170                                       "}\n"
10171                                       "\n";
10172     static const GLchar *gs         = "#version 430 core\n"
10173                                       "#extension GL_ARB_enhanced_layouts : require\n"
10174                                       "\n"
10175                                       "layout(points)                           in;\n"
10176                                       "layout(triangle_strip, max_vertices = 4) out;\n"
10177                                       "\n"
10178                                       "in  vec4 tes_gs[];\n"
10179                                       "out vec4 gs_fs;\n"
10180                                       "\n"
10181                                       "void main()\n"
10182                                       "{\n"
10183                                       "    gs_fs = tes_gs[0];\n"
10184                                       "    gl_Position  = vec4(-1, -1, 0, 1);\n"
10185                                       "    EmitVertex();\n"
10186                                       "    gs_fs = tes_gs[0];\n"
10187                                       "    gl_Position  = vec4(-1, 1, 0, 1);\n"
10188                                       "    EmitVertex();\n"
10189                                       "    gs_fs = tes_gs[0];\n"
10190                                       "    gl_Position  = vec4(1, -1, 0, 1);\n"
10191                                       "    EmitVertex();\n"
10192                                       "    gs_fs = tes_gs[0];\n"
10193                                       "    gl_Position  = vec4(1, 1, 0, 1);\n"
10194                                       "    EmitVertex();\n"
10195                                       "}\n"
10196                                       "\n";
10197     static const GLchar *gs_tested  = "#version 430 core\n"
10198                                       "#extension GL_ARB_enhanced_layouts : require\n"
10199                                       "\n"
10200                                       "layout(points)                           in;\n"
10201                                       "layout(triangle_strip, max_vertices = 4) out;\n"
10202                                       "\n"
10203                                       "layout (std140) uniform Block {\n"
10204                                       "    vec4 b;\n"
10205                                       "    layout (align = ALIGN) TYPE a;\n"
10206                                       "} block;\n"
10207                                       "\n"
10208                                       "in  vec4 tes_gs[];\n"
10209                                       "out vec4 gs_fs;\n"
10210                                       "\n"
10211                                       "void main()\n"
10212                                       "{\n"
10213                                       "    if (TYPE(0) == block.a)\n"
10214                                       "    {\n"
10215                                       "        gs_fs = block.b;\n"
10216                                       "    }\n"
10217                                       "\n"
10218                                       "    gs_fs += tes_gs[0];\n"
10219                                       "    gl_Position  = vec4(-1, -1, 0, 1);\n"
10220                                       "    EmitVertex();\n"
10221                                       "    gs_fs += tes_gs[0];\n"
10222                                       "    gl_Position  = vec4(-1, 1, 0, 1);\n"
10223                                       "    EmitVertex();\n"
10224                                       "    gs_fs += tes_gs[0];\n"
10225                                       "    gl_Position  = vec4(1, -1, 0, 1);\n"
10226                                       "    EmitVertex();\n"
10227                                       "    gs_fs += tes_gs[0];\n"
10228                                       "    gl_Position  = vec4(1, 1, 0, 1);\n"
10229                                       "    EmitVertex();\n"
10230                                       "}\n"
10231                                       "\n";
10232     static const GLchar *tcs        = "#version 430 core\n"
10233                                       "#extension GL_ARB_enhanced_layouts : require\n"
10234                                       "\n"
10235                                       "layout(vertices = 1) out;\n"
10236                                       "\n"
10237                                       "in  vec4 vs_tcs[];\n"
10238                                       "out vec4 tcs_tes[];\n"
10239                                       "\n"
10240                                       "void main()\n"
10241                                       "{\n"
10242                                       "\n"
10243                                       "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
10244                                       "\n"
10245                                       "    gl_TessLevelOuter[0] = 1.0;\n"
10246                                       "    gl_TessLevelOuter[1] = 1.0;\n"
10247                                       "    gl_TessLevelOuter[2] = 1.0;\n"
10248                                       "    gl_TessLevelOuter[3] = 1.0;\n"
10249                                       "    gl_TessLevelInner[0] = 1.0;\n"
10250                                       "    gl_TessLevelInner[1] = 1.0;\n"
10251                                       "}\n"
10252                                       "\n";
10253     static const GLchar *tcs_tested = "#version 430 core\n"
10254                                       "#extension GL_ARB_enhanced_layouts : require\n"
10255                                       "\n"
10256                                       "layout(vertices = 1) out;\n"
10257                                       "\n"
10258                                       "layout (std140) uniform Block {\n"
10259                                       "    vec4 b;\n"
10260                                       "    layout (align = ALIGN) TYPE a;\n"
10261                                       "} block;\n"
10262                                       "\n"
10263                                       "in  vec4 vs_tcs[];\n"
10264                                       "out vec4 tcs_tes[];\n"
10265                                       "\n"
10266                                       "void main()\n"
10267                                       "{\n"
10268                                       "    if (TYPE(0) == block.a)\n"
10269                                       "    {\n"
10270                                       "        tcs_tes[gl_InvocationID] = block.b;\n"
10271                                       "    }\n"
10272                                       "\n"
10273                                       "\n"
10274                                       "    tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
10275                                       "\n"
10276                                       "    gl_TessLevelOuter[0] = 1.0;\n"
10277                                       "    gl_TessLevelOuter[1] = 1.0;\n"
10278                                       "    gl_TessLevelOuter[2] = 1.0;\n"
10279                                       "    gl_TessLevelOuter[3] = 1.0;\n"
10280                                       "    gl_TessLevelInner[0] = 1.0;\n"
10281                                       "    gl_TessLevelInner[1] = 1.0;\n"
10282                                       "}\n"
10283                                       "\n";
10284     static const GLchar *tes        = "#version 430 core\n"
10285                                       "#extension GL_ARB_enhanced_layouts : require\n"
10286                                       "\n"
10287                                       "layout(isolines, point_mode) in;\n"
10288                                       "\n"
10289                                       "in  vec4 tcs_tes[];\n"
10290                                       "out vec4 tes_gs;\n"
10291                                       "\n"
10292                                       "void main()\n"
10293                                       "{\n"
10294                                       "    tes_gs = tcs_tes[0];\n"
10295                                       "}\n"
10296                                       "\n";
10297     static const GLchar *tes_tested = "#version 430 core\n"
10298                                       "#extension GL_ARB_enhanced_layouts : require\n"
10299                                       "\n"
10300                                       "layout(isolines, point_mode) in;\n"
10301                                       "\n"
10302                                       "layout (std140) uniform Block {\n"
10303                                       "    vec4 b;\n"
10304                                       "    layout (align = ALIGN) TYPE a;\n"
10305                                       "} block;\n"
10306                                       "\n"
10307                                       "in  vec4 tcs_tes[];\n"
10308                                       "out vec4 tes_gs;\n"
10309                                       "\n"
10310                                       "void main()\n"
10311                                       "{\n"
10312                                       "    if (TYPE(0) == block.a)\n"
10313                                       "    {\n"
10314                                       "        tes_gs = block.b;\n"
10315                                       "    }\n"
10316                                       "\n"
10317                                       "    tes_gs += tcs_tes[0];\n"
10318                                       "}\n"
10319                                       "\n";
10320     static const GLchar *vs         = "#version 430 core\n"
10321                                       "#extension GL_ARB_enhanced_layouts : require\n"
10322                                       "\n"
10323                                       "in  vec4 in_vs;\n"
10324                                       "out vec4 vs_tcs;\n"
10325                                       "\n"
10326                                       "void main()\n"
10327                                       "{\n"
10328                                       "    vs_tcs = in_vs;\n"
10329                                       "}\n"
10330                                       "\n";
10331     static const GLchar *vs_tested  = "#version 430 core\n"
10332                                       "#extension GL_ARB_enhanced_layouts : require\n"
10333                                       "\n"
10334                                       "layout (std140) uniform Block {\n"
10335                                       "    vec4 b;\n"
10336                                       "    layout (align = ALIGN) TYPE a;\n"
10337                                       "} block;\n"
10338                                       "\n"
10339                                       "in  vec4 in_vs;\n"
10340                                       "out vec4 vs_tcs;\n"
10341                                       "\n"
10342                                       "void main()\n"
10343                                       "{\n"
10344                                       "    if (TYPE(0) == block.a)\n"
10345                                       "    {\n"
10346                                       "        vs_tcs = block.b;\n"
10347                                       "    }\n"
10348                                       "\n"
10349                                       "    vs_tcs += in_vs;\n"
10350                                       "}\n"
10351                                       "\n";
10352 
10353     std::string source;
10354     testCase &test_case = m_test_cases[test_case_index];
10355 
10356     if (test_case.m_stage == stage)
10357     {
10358         GLchar buffer[16];
10359         const GLuint alignment  = test_case.m_alignment;
10360         const Utils::Type &type = test_case.m_type;
10361         const GLchar *type_name = type.GetGLSLTypeName();
10362         size_t position         = 0;
10363 
10364         switch (stage)
10365         {
10366         case Utils::Shader::COMPUTE:
10367             source = cs;
10368             break;
10369         case Utils::Shader::FRAGMENT:
10370             source = fs_tested;
10371             break;
10372         case Utils::Shader::GEOMETRY:
10373             source = gs_tested;
10374             break;
10375         case Utils::Shader::TESS_CTRL:
10376             source = tcs_tested;
10377             break;
10378         case Utils::Shader::TESS_EVAL:
10379             source = tes_tested;
10380             break;
10381         case Utils::Shader::VERTEX:
10382             source = vs_tested;
10383             break;
10384         default:
10385             TCU_FAIL("Invalid enum");
10386         }
10387 
10388         sprintf(buffer, "%d", alignment);
10389         Utils::replaceToken("ALIGN", position, buffer, source);
10390         Utils::replaceToken("TYPE", position, type_name, source);
10391         Utils::replaceToken("TYPE", position, type_name, source);
10392     }
10393     else
10394     {
10395         switch (stage)
10396         {
10397         case Utils::Shader::FRAGMENT:
10398             source = fs;
10399             break;
10400         case Utils::Shader::GEOMETRY:
10401             source = gs;
10402             break;
10403         case Utils::Shader::TESS_CTRL:
10404             source = tcs;
10405             break;
10406         case Utils::Shader::TESS_EVAL:
10407             source = tes;
10408             break;
10409         case Utils::Shader::VERTEX:
10410             source = vs;
10411             break;
10412         default:
10413             TCU_FAIL("Invalid enum");
10414         }
10415     }
10416 
10417     return source;
10418 }
10419 
10420 /** Get description of test case
10421  *
10422  * @param test_case_index Index of test case
10423  *
10424  * @return Type name and offset
10425  **/
10426 std::string UniformBlockMemberAlignNonPowerOf2Test::getTestCaseName(GLuint test_case_index)
10427 {
10428     std::stringstream stream;
10429     testCase &test_case = m_test_cases[test_case_index];
10430 
10431     stream << "Type: " << test_case.m_type.GetGLSLTypeName() << ", align: " << test_case.m_alignment;
10432 
10433     return stream.str();
10434 }
10435 
10436 /** Get number of test cases
10437  *
10438  * @return Number of test cases
10439  **/
10440 GLuint UniformBlockMemberAlignNonPowerOf2Test::getTestCaseNumber()
10441 {
10442     return static_cast<GLuint>(m_test_cases.size());
10443 }
10444 
10445 /** Selects if "compute" stage is relevant for test
10446  *
10447  * @param test_case_index Index of test case
10448  *
10449  * @return true when tested stage is compute
10450  **/
10451 bool UniformBlockMemberAlignNonPowerOf2Test::isComputeRelevant(GLuint test_case_index)
10452 {
10453     return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
10454 }
10455 
10456 /** Checks if stage is supported
10457  *
10458  * @param ignored
10459  *
10460  * @return true
10461  **/
10462 bool UniformBlockMemberAlignNonPowerOf2Test::isStageSupported(Utils::Shader::STAGES /* stage */)
10463 {
10464     return true;
10465 }
10466 
10467 /** Selects if compilation failure is expected result
10468  *
10469  * @param test_case_index Index of test case
10470  *
10471  * @return should_fail field from testCase
10472  **/
10473 bool UniformBlockMemberAlignNonPowerOf2Test::isFailureExpected(GLuint test_case_index)
10474 {
10475     return m_test_cases[test_case_index].m_should_fail;
10476 }
10477 
10478 /** Prepare all test cases
10479  *
10480  **/
10481 void UniformBlockMemberAlignNonPowerOf2Test::testInit()
10482 {
10483     static const GLuint dmat4_size = 128;
10484     const GLuint n_types           = getTypesNumber();
10485     bool stage_support[Utils::Shader::STAGE_MAX];
10486 
10487     for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
10488     {
10489         stage_support[stage] = isStageSupported((Utils::Shader::STAGES)stage);
10490     }
10491 
10492     for (GLuint j = 0; j < n_types; ++j)
10493     {
10494         const Utils::Type &type = getType(j);
10495 
10496         for (GLuint align = 0; align <= dmat4_size; ++align)
10497         {
10498 
10499 #if WRKARD_UNIFORMBLOCKMEMBERALIGNNONPOWEROF2TEST
10500 
10501             const bool should_fail = (0 == align) ? false : !isPowerOf2(align);
10502 
10503 #else /* WRKARD_UNIFORMBLOCKMEMBERALIGNNONPOWEROF2TEST */
10504 
10505             const bool should_fail = !isPowerOf2(align);
10506 
10507 #endif /* WRKARD_UNIFORMBLOCKMEMBERALIGNNONPOWEROF2TEST */
10508 
10509             for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
10510             {
10511                 if (false == stage_support[stage])
10512                 {
10513                     continue;
10514                 }
10515 
10516                 testCase test_case = {align, type, should_fail, (Utils::Shader::STAGES)stage};
10517 
10518                 m_test_cases.push_back(test_case);
10519             }
10520         }
10521     }
10522 }
10523 
10524 /** Check if value is power of 2
10525  *
10526  * @param val Tested value
10527  *
10528  * @return true if val is power of 2, false otherwise
10529  **/
10530 bool UniformBlockMemberAlignNonPowerOf2Test::isPowerOf2(GLuint val)
10531 {
10532     if (0 == val)
10533     {
10534         return false;
10535     }
10536 
10537     return (0 == (val & (val - 1)));
10538 }
10539 
10540 /** Constructor
10541  *
10542  * @param context Test framework context
10543  **/
10544 UniformBlockAlignmentTest::UniformBlockAlignmentTest(deqp::Context &context)
10545     : TextureTestBase(context, "uniform_block_alignment", "Test verifies offset and alignment of uniform buffer")
10546 {
10547 }
10548 
10549 /** Get interface of program
10550  *
10551  * @param ignored
10552  * @param program_interface Interface of program
10553  * @param varying_passthrough Collection of connections between in and out variables
10554  **/
10555 void UniformBlockAlignmentTest::getProgramInterface(GLuint /* test_case_index */,
10556                                                     Utils::ProgramInterface &program_interface,
10557                                                     Utils::VaryingPassthrough &varying_passthrough)
10558 {
10559     static const Utils::Type vec4 = Utils::Type::vec4;
10560 
10561 #if WRKARD_UNIFORMBLOCKALIGNMENT
10562 
10563     static const GLuint block_align = 16;
10564 
10565 #else /* WRKARD_UNIFORMBLOCKALIGNMENT */
10566 
10567     static const GLuint block_align = 64;
10568 
10569 #endif /* WRKARD_UNIFORMBLOCKALIGNMENT */
10570 
10571     static const GLuint vec4_stride = 16;
10572     static const GLuint data_stride = vec4_stride * 2; /* one vec4 + one scalar aligned to 16 */
10573 
10574     /*Fixed a test issue, the fifth_offset should be calculated by block_align, instead of fifth_align, according to spec, the actual
10575      alignment of a member will be the greater of the specified alignment and the base aligment for the member type
10576      */
10577     const GLuint first_offset  = 0;                                                                     /* vec4 at 0 */
10578     const GLuint second_offset = Utils::Type::GetActualOffset(first_offset + vec4_stride, block_align); /* Data at 32 */
10579     const GLuint third_offset =
10580         Utils::Type::GetActualOffset(second_offset + data_stride, block_align); /* Data[2] at 64 */
10581     const GLuint fourth_offset =
10582         Utils::Type::GetActualOffset(third_offset + data_stride * 2, block_align); /* vec4[3] at 96 */
10583     const GLuint fifth_offset =
10584         Utils::Type::GetActualOffset(fourth_offset + vec4_stride * 3, block_align); /* vec4[2] at 160 */
10585     const GLuint sixth_offset =
10586         Utils::Type::GetActualOffset(fifth_offset + vec4_stride * 2, block_align); /* Data at 192 */
10587 
10588     Utils::Interface *structure = program_interface.Structure("Data");
10589 
10590     structure->Member("vector", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::vec4,
10591                       false /* normalized */, 0 /* n_array_elements */, Utils::Type::vec4.GetSize(), 0 /* offset */);
10592 
10593     structure->Member("scalar", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::_float,
10594                       false /* normalized */, 0 /* n_array_elements */, Utils::Type::_float.GetSize(),
10595                       Utils::Type::vec4.GetSize() /* offset */);
10596 
10597     /* Prepare Block */
10598     Utils::Interface *vs_uni_block = program_interface.Block("vs_uni_Block");
10599 
10600     vs_uni_block->Member("first", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::vec4,
10601                          false /* normalized */, 0 /* n_array_elements */, vec4_stride, first_offset /* offset */);
10602 
10603     vs_uni_block->Member("second", "", 0 /* expected_component */, 0 /* expected_location */, structure,
10604                          0 /* n_array_elements */, data_stride, second_offset);
10605 
10606     vs_uni_block->Member("third", "", 0 /* expected_component */, 0 /* expected_location */, structure,
10607                          2 /* n_array_elements */, data_stride, third_offset);
10608 
10609     vs_uni_block->Member("fourth", "", 0 /* expected_component */, 0 /* expected_location */, vec4,
10610                          false /* normalized */, 3 /* n_array_elements */, vec4_stride, fourth_offset);
10611 
10612     vs_uni_block->Member("fifth", "layout(align = 64)", 0 /* expected_component */, 0 /* expected_location */, vec4,
10613                          false /* normalized */, 2 /* n_array_elements */, vec4_stride, fifth_offset);
10614 
10615     vs_uni_block->Member("sixth", "", 0 /* expected_component */, 0 /* expected_location */, structure,
10616                          0 /* n_array_elements */, data_stride, sixth_offset);
10617 
10618     const GLuint stride = calculateStride(*vs_uni_block);
10619     m_data.resize(stride);
10620     generateData(*vs_uni_block, 0, m_data);
10621 
10622     Utils::ShaderInterface &vs_si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
10623 
10624 /* Add uniform BLOCK */
10625 #if WRKARD_UNIFORMBLOCKALIGNMENT
10626     vs_si.Uniform("vs_uni_block", "layout (std140, binding = BINDING)", 0, 0, vs_uni_block, 0,
10627                   static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
10628 #else  /* WRKARD_UNIFORMBLOCKALIGNMENT */
10629     vs_si.Uniform("vs_uni_block", "layout (std140, binding = BINDING, align = 64)", 0, 0, vs_uni_block, 0,
10630                   static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
10631 #endif /* WRKARD_UNIFORMBLOCKALIGNMENT */
10632 
10633     program_interface.CloneVertexInterface(varying_passthrough);
10634 }
10635 
10636 /** Constructor
10637  *
10638  * @param context Test framework context
10639  **/
10640 SSBMemberOffsetAndAlignTest::SSBMemberOffsetAndAlignTest(deqp::Context &context)
10641     : TextureTestBase(context, "ssb_member_offset_and_align",
10642                       "Test verifies offsets and alignment of storage buffer members")
10643 {
10644 }
10645 
10646 /** Get interface of program
10647  *
10648  * @param test_case_index     Test case index
10649  * @param program_interface   Interface of program
10650  * @param varying_passthrough Collection of connections between in and out variables
10651  **/
10652 void SSBMemberOffsetAndAlignTest::getProgramInterface(GLuint test_case_index,
10653                                                       Utils::ProgramInterface &program_interface,
10654                                                       Utils::VaryingPassthrough &varying_passthrough)
10655 {
10656     std::string globals = "const int basic_size = BASIC_SIZE;\n"
10657                           "const int type_align = TYPE_ALIGN;\n"
10658                           "const int type_size  = TYPE_SIZE;\n";
10659 
10660     Utils::Type type         = getType(test_case_index);
10661     GLuint basic_size        = Utils::Type::GetTypeSize(type.m_basic_type);
10662     const GLuint base_align  = type.GetBaseAlignment(false);
10663     const GLuint array_align = type.GetBaseAlignment(true);
10664     const GLuint base_stride = Utils::Type::CalculateStd140Stride(base_align, type.m_n_columns, 0);
10665     const GLuint type_align  = Utils::roundUpToPowerOf2(base_stride);
10666 
10667     /* Calculate offsets */
10668     const GLuint first_offset  = 0;
10669     const GLuint second_offset = type.GetActualOffset(base_stride, basic_size / 2);
10670 
10671 #if WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST
10672 
10673     const GLuint third_offset   = type.GetActualOffset(second_offset + base_stride, base_align);
10674     const GLuint fourth_offset  = type.GetActualOffset(third_offset + base_stride, base_align);
10675     const GLuint fifth_offset   = type.GetActualOffset(fourth_offset + base_stride, base_align);
10676     const GLuint sixth_offset   = type.GetActualOffset(fifth_offset + base_stride, array_align);
10677     const GLuint seventh_offset = type.GetActualOffset(sixth_offset + base_stride, array_align);
10678     const GLuint eigth_offset   = type.GetActualOffset(seventh_offset + base_stride, array_align);
10679 
10680 #else /* WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST */
10681 
10682     const GLuint third_offset   = type.GetActualOffset(second_offset + base_stride, 2 * type_align);
10683     const GLuint fourth_offset  = type.GetActualOffset(3 * type_align + base_stride, base_align);
10684     const GLuint fifth_offset   = type.GetActualOffset(fourth_offset + base_stride, base_align);
10685     const GLuint sixth_offset   = type.GetActualOffset(fifth_offset + base_stride, array_align);
10686     const GLuint seventh_offset = type.GetActualOffset(sixth_offset + base_stride, array_align);
10687     const GLuint eigth_offset   = type.GetActualOffset(seventh_offset + base_stride, 8 * basic_size);
10688 
10689 #endif /* WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST */
10690 
10691     /* Prepare data */
10692     const std::vector<GLubyte> &first  = type.GenerateData();
10693     const std::vector<GLubyte> &second = type.GenerateData();
10694     const std::vector<GLubyte> &third  = type.GenerateData();
10695     const std::vector<GLubyte> &fourth = type.GenerateData();
10696 
10697     m_data.resize(eigth_offset + base_stride);
10698     GLubyte *ptr = &m_data[0];
10699     memcpy(ptr + first_offset, &first[0], first.size());
10700     memcpy(ptr + second_offset, &second[0], second.size());
10701     memcpy(ptr + third_offset, &third[0], third.size());
10702     memcpy(ptr + fourth_offset, &fourth[0], fourth.size());
10703     memcpy(ptr + fifth_offset, &fourth[0], fourth.size());
10704     memcpy(ptr + sixth_offset, &third[0], third.size());
10705     memcpy(ptr + seventh_offset, &second[0], second.size());
10706     memcpy(ptr + eigth_offset, &first[0], first.size());
10707 
10708     /* Prepare globals */
10709     size_t position = 0;
10710     GLchar buffer[16];
10711 
10712     sprintf(buffer, "%d", basic_size);
10713     Utils::replaceToken("BASIC_SIZE", position, buffer, globals);
10714 
10715     sprintf(buffer, "%d", type_align);
10716     Utils::replaceToken("TYPE_ALIGN", position, buffer, globals);
10717 
10718     sprintf(buffer, "%d", base_stride);
10719     Utils::replaceToken("TYPE_SIZE", position, buffer, globals);
10720 
10721     /* Prepare Block */
10722     Utils::Interface *vs_buf_block = program_interface.Block("vs_buf_Block");
10723 
10724     vs_buf_block->Member("at_first_offset", "layout(offset = 0, align = 8 * basic_size)", 0 /* expected_component */,
10725                          0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
10726                          first_offset);
10727 
10728     vs_buf_block->Member("at_second_offset", "layout(offset = type_size, align = basic_size / 2)",
10729                          0 /* expected_component */, 0 /* expected_location */, type, false /* normalized */,
10730                          0 /* n_array_elements */, base_stride, second_offset);
10731 
10732     vs_buf_block->Member("at_third_offset", "layout(align = 2 * type_align)", 0 /* expected_component */,
10733                          0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
10734                          third_offset);
10735 
10736     vs_buf_block->Member("at_fourth_offset", "layout(offset = 3 * type_align + type_size)", 0 /* expected_component */,
10737                          0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
10738                          fourth_offset);
10739 
10740     vs_buf_block->Member("at_fifth_offset", "", 0 /* expected_component */, 0 /* expected_location */, type,
10741                          false /* normalized */, 0 /* n_array_elements */, base_stride, fifth_offset);
10742 
10743     vs_buf_block->Member("at_sixth_offset", "", 0 /* expected_component */, 0 /* expected_location */, type,
10744                          false /* normalized */, 2 /* n_array_elements */, array_align * 2, sixth_offset);
10745 
10746     vs_buf_block->Member("at_eigth_offset", "layout(align = 8 * basic_size)", 0 /* expected_component */,
10747                          0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
10748                          eigth_offset);
10749 
10750     Utils::ShaderInterface &vs_si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
10751 
10752     /* Add globals */
10753     vs_si.m_globals = globals;
10754 
10755     /* Add uniform BLOCK */
10756     vs_si.SSB("vs_buf_block", "layout (std140, binding = BINDING)", 0, 0, vs_buf_block, 0,
10757               static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
10758 
10759     /* */
10760     program_interface.CloneVertexInterface(varying_passthrough);
10761 }
10762 
10763 /** Get type name
10764  *
10765  * @param test_case_index Index of test case
10766  *
10767  * @return Name of type test in test_case_index
10768  **/
10769 std::string SSBMemberOffsetAndAlignTest::getTestCaseName(glw::GLuint test_case_index)
10770 {
10771     return getTypeName(test_case_index);
10772 }
10773 
10774 /** Returns number of types to test
10775  *
10776  * @return Number of types, 34
10777  **/
10778 glw::GLuint SSBMemberOffsetAndAlignTest::getTestCaseNumber()
10779 {
10780     return getTypesNumber();
10781 }
10782 
10783 /** Prepare code snippet that will verify in and uniform variables
10784  *
10785  * @param ignored
10786  * @param ignored
10787  * @param stage   Shader stage
10788  *
10789  * @return Code that verify variables
10790  **/
10791 std::string SSBMemberOffsetAndAlignTest::getVerificationSnippet(GLuint /* test_case_index */,
10792                                                                 Utils::ProgramInterface & /* program_interface */,
10793                                                                 Utils::Shader::STAGES stage)
10794 {
10795     std::string verification = "if ( (PREFIXblock.at_first_offset  != PREFIXblock.at_eigth_offset   ) ||\n"
10796                                "         (PREFIXblock.at_second_offset != PREFIXblock.at_sixth_offset[1]) ||\n"
10797                                "         (PREFIXblock.at_third_offset  != PREFIXblock.at_sixth_offset[0]) ||\n"
10798                                "         (PREFIXblock.at_fourth_offset != PREFIXblock.at_fifth_offset   )  )\n"
10799                                "    {\n"
10800                                "        result = 0;\n"
10801                                "    }";
10802 
10803     const GLchar *prefix = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::SSB);
10804 
10805     Utils::replaceAllTokens("PREFIX", prefix, verification);
10806 
10807     return verification;
10808 }
10809 
10810 /** Selects if "draw" stages are relevant for test
10811  *
10812  * @param ignored
10813  *
10814  * @return true if all stages support shader storage buffers, false otherwise
10815  **/
10816 bool SSBMemberOffsetAndAlignTest::isDrawRelevant(GLuint /* test_case_index */)
10817 {
10818     const Functions &gl         = m_context.getRenderContext().getFunctions();
10819     GLint gs_supported_buffers  = 0;
10820     GLint tcs_supported_buffers = 0;
10821     GLint tes_supported_buffers = 0;
10822     GLint vs_supported_buffers  = 0;
10823 
10824     gl.getIntegerv(GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS, &gs_supported_buffers);
10825     gl.getIntegerv(GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS, &tcs_supported_buffers);
10826     gl.getIntegerv(GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS, &tes_supported_buffers);
10827     gl.getIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &vs_supported_buffers);
10828 
10829     GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
10830 
10831     return ((1 <= gs_supported_buffers) && (1 <= tcs_supported_buffers) && (1 <= tes_supported_buffers) &&
10832             (1 <= vs_supported_buffers));
10833 }
10834 
10835 /** Constructor
10836  *
10837  * @param context Test framework context
10838  **/
10839 SSBLayoutQualifierConflictTest::SSBLayoutQualifierConflictTest(deqp::Context &context)
10840     : NegativeTestBase(context, "ssb_layout_qualifier_conflict",
10841                        "Test verifies that std140 or std430 is required when "
10842                        "offset and/or align qualifiers are used with storage "
10843                        "block")
10844 {
10845     /* Nothing to be done here */
10846 }
10847 
10848 /** Source for given test case and stage
10849  *
10850  * @param test_case_index Index of test case
10851  * @param stage           Shader stage
10852  *
10853  * @return Shader source
10854  **/
10855 std::string SSBLayoutQualifierConflictTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
10856 {
10857     static const GLchar *cs  = "#version 430 core\n"
10858                                "#extension GL_ARB_enhanced_layouts : require\n"
10859                                "\n"
10860                                "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
10861                                "\n"
10862                                "layout (QUALIFIERbinding = BINDING) buffer cs_Block {\n"
10863                                "    layout(offset = 16) vec4 b;\n"
10864                                "    layout(align  = 64) vec4 a;\n"
10865                                "} uni_block;\n"
10866                                "\n"
10867                                "writeonly uniform image2D uni_image;\n"
10868                                "\n"
10869                                "void main()\n"
10870                                "{\n"
10871                                "    vec4 result = uni_block.b + uni_block.a;\n"
10872                                "\n"
10873                                "    imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
10874                                "}\n"
10875                                "\n";
10876     static const GLchar *fs  = "#version 430 core\n"
10877                                "#extension GL_ARB_enhanced_layouts : require\n"
10878                                "\n"
10879                                "layout (QUALIFIERbinding = BINDING) buffer Block {\n"
10880                                "    layout(offset = 16) vec4 b;\n"
10881                                "    layout(align  = 64) vec4 a;\n"
10882                                "} uni_block;\n"
10883                                "\n"
10884                                "in  vec4 gs_fs;\n"
10885                                "out vec4 fs_out;\n"
10886                                "\n"
10887                                "void main()\n"
10888                                "{\n"
10889                                "    fs_out = gs_fs + uni_block.b + uni_block.a;\n"
10890                                "}\n"
10891                                "\n";
10892     static const GLchar *gs  = "#version 430 core\n"
10893                                "#extension GL_ARB_enhanced_layouts : require\n"
10894                                "\n"
10895                                "layout(points)                           in;\n"
10896                                "layout(triangle_strip, max_vertices = 4) out;\n"
10897                                "\n"
10898                                "layout (QUALIFIERbinding = BINDING) buffer gs_Block {\n"
10899                                "    layout(offset = 16) vec4 b;\n"
10900                                "    layout(align  = 64) vec4 a;\n"
10901                                "} uni_block;\n"
10902                                "\n"
10903                                "in  vec4 tes_gs[];\n"
10904                                "out vec4 gs_fs;\n"
10905                                "\n"
10906                                "void main()\n"
10907                                "{\n"
10908                                "    gs_fs = tes_gs[0] + uni_block.b + uni_block.a;\n"
10909                                "    gl_Position  = vec4(-1, -1, 0, 1);\n"
10910                                "    EmitVertex();\n"
10911                                "    gs_fs = tes_gs[0] + uni_block.b + uni_block.a;\n"
10912                                "    gl_Position  = vec4(-1, 1, 0, 1);\n"
10913                                "    EmitVertex();\n"
10914                                "    gs_fs = tes_gs[0] + uni_block.b + uni_block.a;\n"
10915                                "    gl_Position  = vec4(1, -1, 0, 1);\n"
10916                                "    EmitVertex();\n"
10917                                "    gs_fs = tes_gs[0] + uni_block.b + uni_block.a;\n"
10918                                "    gl_Position  = vec4(1, 1, 0, 1);\n"
10919                                "    EmitVertex();\n"
10920                                "}\n"
10921                                "\n";
10922     static const GLchar *tcs = "#version 430 core\n"
10923                                "#extension GL_ARB_enhanced_layouts : require\n"
10924                                "\n"
10925                                "layout(vertices = 1) out;\n"
10926                                "\n"
10927                                "layout (QUALIFIERbinding = BINDING) buffer tcs_Block {\n"
10928                                "    layout(offset = 16) vec4 b;\n"
10929                                "    layout(align  = 64) vec4 a;\n"
10930                                "} uni_block;\n"
10931                                "\n"
10932                                "in  vec4 vs_tcs[];\n"
10933                                "out vec4 tcs_tes[];\n"
10934                                "\n"
10935                                "void main()\n"
10936                                "{\n"
10937                                "\n"
10938                                "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID] + uni_block.b + uni_block.a;\n"
10939                                "\n"
10940                                "    gl_TessLevelOuter[0] = 1.0;\n"
10941                                "    gl_TessLevelOuter[1] = 1.0;\n"
10942                                "    gl_TessLevelOuter[2] = 1.0;\n"
10943                                "    gl_TessLevelOuter[3] = 1.0;\n"
10944                                "    gl_TessLevelInner[0] = 1.0;\n"
10945                                "    gl_TessLevelInner[1] = 1.0;\n"
10946                                "}\n"
10947                                "\n";
10948     static const GLchar *tes = "#version 430 core\n"
10949                                "#extension GL_ARB_enhanced_layouts : require\n"
10950                                "\n"
10951                                "layout(isolines, point_mode) in;\n"
10952                                "\n"
10953                                "layout (QUALIFIERbinding = BINDING) buffer tes_Block {\n"
10954                                "    layout(offset = 16) vec4 b;\n"
10955                                "    layout(align  = 64) vec4 a;\n"
10956                                "} uni_block;\n"
10957                                "\n"
10958                                "in  vec4 tcs_tes[];\n"
10959                                "out vec4 tes_gs;\n"
10960                                "\n"
10961                                "void main()\n"
10962                                "{\n"
10963                                "    tes_gs = tcs_tes[0] + uni_block.b + uni_block.a;\n"
10964                                "}\n"
10965                                "\n";
10966     static const GLchar *vs  = "#version 430 core\n"
10967                                "#extension GL_ARB_enhanced_layouts : require\n"
10968                                "\n"
10969                                "layout (QUALIFIERbinding = BINDING) buffer vs_Block {\n"
10970                                "    layout(offset = 16) vec4 b;\n"
10971                                "    layout(align  = 64) vec4 a;\n"
10972                                "} uni_block;\n"
10973                                "\n"
10974                                "in  vec4 in_vs;\n"
10975                                "out vec4 vs_tcs;\n"
10976                                "\n"
10977                                "void main()\n"
10978                                "{\n"
10979                                "    vs_tcs = in_vs + uni_block.b + uni_block.a;\n"
10980                                "}\n"
10981                                "\n";
10982 
10983     GLchar buffer[16];
10984     size_t position = 0;
10985     std::string source;
10986     testCase &test_case   = m_test_cases[test_case_index];
10987     std::string qualifier = getQualifierName(test_case.m_qualifier);
10988 
10989     if (false == qualifier.empty())
10990     {
10991         qualifier.append(", ");
10992     }
10993 
10994     sprintf(buffer, "%d", stage);
10995 
10996     switch (stage)
10997     {
10998     case Utils::Shader::COMPUTE:
10999         source = cs;
11000         break;
11001     case Utils::Shader::FRAGMENT:
11002         source = fs;
11003         break;
11004     case Utils::Shader::GEOMETRY:
11005         source = gs;
11006         break;
11007     case Utils::Shader::TESS_CTRL:
11008         source = tcs;
11009         break;
11010     case Utils::Shader::TESS_EVAL:
11011         source = tes;
11012         break;
11013     case Utils::Shader::VERTEX:
11014         source = vs;
11015         break;
11016     default:
11017         TCU_FAIL("Invalid enum");
11018     }
11019 
11020     if (test_case.m_stage == stage)
11021     {
11022         Utils::replaceToken("QUALIFIER", position, qualifier.c_str(), source);
11023     }
11024     else
11025     {
11026         Utils::replaceToken("QUALIFIER", position, "std140, ", source);
11027     }
11028 
11029     Utils::replaceToken("BINDING", position, buffer, source);
11030 
11031     return source;
11032 }
11033 
11034 /** Get description of test case
11035  *
11036  * @param test_case_index Index of test case
11037  *
11038  * @return Qualifier name
11039  **/
11040 std::string SSBLayoutQualifierConflictTest::getTestCaseName(GLuint test_case_index)
11041 {
11042     std::string result = getQualifierName(m_test_cases[test_case_index].m_qualifier);
11043 
11044     return result;
11045 }
11046 
11047 /** Get number of test cases
11048  *
11049  * @return Number of test cases
11050  **/
11051 GLuint SSBLayoutQualifierConflictTest::getTestCaseNumber()
11052 {
11053     return static_cast<GLuint>(m_test_cases.size());
11054 }
11055 
11056 /** Selects if "compute" stage is relevant for test
11057  *
11058  * @param test_case_index Index of test case
11059  *
11060  * @return true when tested stage is compute
11061  **/
11062 bool SSBLayoutQualifierConflictTest::isComputeRelevant(GLuint test_case_index)
11063 {
11064     return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
11065 }
11066 
11067 /** Selects if compilation failure is expected result
11068  *
11069  * @param test_case_index Index of test case
11070  *
11071  * @return false for STD140 and STD430 cases, true otherwise
11072  **/
11073 bool SSBLayoutQualifierConflictTest::isFailureExpected(GLuint test_case_index)
11074 {
11075     const QUALIFIERS qualifier = m_test_cases[test_case_index].m_qualifier;
11076 
11077     return !((STD140 == qualifier) || (STD430 == qualifier));
11078 }
11079 
11080 /** Checks if stage is supported
11081  *
11082  * @param stage Shader stage
11083  *
11084  * @return true if supported, false otherwise
11085  **/
11086 bool SSBLayoutQualifierConflictTest::isStageSupported(Utils::Shader::STAGES stage)
11087 {
11088     const Functions &gl         = m_context.getRenderContext().getFunctions();
11089     GLint max_supported_buffers = 0;
11090     GLenum pname                = 0;
11091 
11092     switch (stage)
11093     {
11094     case Utils::Shader::COMPUTE:
11095         pname = GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS;
11096         break;
11097     case Utils::Shader::FRAGMENT:
11098         pname = GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS;
11099         break;
11100     case Utils::Shader::GEOMETRY:
11101         pname = GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS;
11102         break;
11103     case Utils::Shader::TESS_CTRL:
11104         pname = GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS;
11105         break;
11106     case Utils::Shader::TESS_EVAL:
11107         pname = GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS;
11108         break;
11109     case Utils::Shader::VERTEX:
11110         pname = GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS;
11111         break;
11112     default:
11113         TCU_FAIL("Invalid enum");
11114     }
11115 
11116     gl.getIntegerv(pname, &max_supported_buffers);
11117     GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
11118 
11119     return 1 <= max_supported_buffers;
11120 }
11121 
11122 /** Prepare all test cases
11123  *
11124  **/
11125 void SSBLayoutQualifierConflictTest::testInit()
11126 {
11127     bool stage_support[Utils::Shader::STAGE_MAX];
11128 
11129     for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
11130     {
11131         stage_support[stage] = isStageSupported((Utils::Shader::STAGES)stage);
11132     }
11133 
11134     for (GLuint qualifier = 0; qualifier < QUALIFIERS_MAX; ++qualifier)
11135     {
11136         for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
11137         {
11138             if (false == stage_support[stage])
11139             {
11140                 continue;
11141             }
11142 
11143             testCase test_case = {(QUALIFIERS)qualifier, (Utils::Shader::STAGES)stage};
11144 
11145             m_test_cases.push_back(test_case);
11146         }
11147     }
11148 }
11149 
11150 /** Get name of glsl constant
11151  *
11152  * @param Constant id
11153  *
11154  * @return Name of constant used in GLSL
11155  **/
11156 const GLchar *SSBLayoutQualifierConflictTest::getQualifierName(QUALIFIERS qualifier)
11157 {
11158     const GLchar *name = "";
11159 
11160     switch (qualifier)
11161     {
11162     case DEFAULT:
11163         name = "";
11164         break;
11165     case STD140:
11166         name = "std140";
11167         break;
11168     case STD430:
11169         name = "std430";
11170         break;
11171     case SHARED:
11172         name = "shared";
11173         break;
11174     case PACKED:
11175         name = "packed";
11176         break;
11177     default:
11178         TCU_FAIL("Invalid enum");
11179     }
11180 
11181     return name;
11182 }
11183 
11184 /** Constructor
11185  *
11186  * @param context Test framework context
11187  **/
11188 SSBMemberInvalidOffsetAlignmentTest::SSBMemberInvalidOffsetAlignmentTest(deqp::Context &context)
11189     : UniformBlockMemberInvalidOffsetAlignmentTest(
11190           context, "ssb_member_invalid_offset_alignment",
11191           "Test verifies that invalid alignment of offset qualifiers cause compilation failure")
11192 {
11193     /* Nothing to be done here */
11194 }
11195 
11196 /** Get the maximum size for a shader storage block
11197  *
11198  * @return The maximum size in basic machine units of a shader storage block.
11199  **/
11200 GLint SSBMemberInvalidOffsetAlignmentTest::getMaxBlockSize()
11201 {
11202     const Functions &gl = m_context.getRenderContext().getFunctions();
11203     GLint max_size      = 0;
11204 
11205     gl.getIntegerv(GL_MAX_SHADER_STORAGE_BLOCK_SIZE, &max_size);
11206     GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
11207 
11208     return max_size;
11209 }
11210 
11211 /** Source for given test case and stage
11212  *
11213  * @param test_case_index Index of test case
11214  * @param stage           Shader stage
11215  *
11216  * @return Shader source
11217  **/
11218 std::string SSBMemberInvalidOffsetAlignmentTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
11219 {
11220     static const GLchar *cs         = "#version 430 core\n"
11221                                       "#extension GL_ARB_enhanced_layouts : require\n"
11222                                       "\n"
11223                                       "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
11224                                       "\n"
11225                                       "layout (std140) buffer Block {\n"
11226                                       "    layout (offset = OFFSET) TYPE member;\n"
11227                                       "} block;\n"
11228                                       "\n"
11229                                       "writeonly uniform image2D uni_image;\n"
11230                                       "\n"
11231                                       "void main()\n"
11232                                       "{\n"
11233                                       "    vec4 result = vec4(1, 0, 0.5, 1);\n"
11234                                       "\n"
11235                                       "    if (TYPE(1) == block.member)\n"
11236                                       "    {\n"
11237                                       "        result = vec4(1, 1, 1, 1);\n"
11238                                       "    }\n"
11239                                       "\n"
11240                                       "    imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
11241                                       "}\n"
11242                                       "\n";
11243     static const GLchar *fs         = "#version 430 core\n"
11244                                       "#extension GL_ARB_enhanced_layouts : require\n"
11245                                       "\n"
11246                                       "in  vec4 gs_fs;\n"
11247                                       "out vec4 fs_out;\n"
11248                                       "\n"
11249                                       "void main()\n"
11250                                       "{\n"
11251                                       "    fs_out = gs_fs;\n"
11252                                       "}\n"
11253                                       "\n";
11254     static const GLchar *fs_tested  = "#version 430 core\n"
11255                                       "#extension GL_ARB_enhanced_layouts : require\n"
11256                                       "\n"
11257                                       "layout (std140) buffer Block {\n"
11258                                       "    layout (offset = OFFSET) TYPE member;\n"
11259                                       "} block;\n"
11260                                       "\n"
11261                                       "in  vec4 gs_fs;\n"
11262                                       "out vec4 fs_out;\n"
11263                                       "\n"
11264                                       "void main()\n"
11265                                       "{\n"
11266                                       "    if (TYPE(1) == block.member)\n"
11267                                       "    {\n"
11268                                       "        fs_out = vec4(1, 1, 1, 1);\n"
11269                                       "    }\n"
11270                                       "\n"
11271                                       "    fs_out += gs_fs;\n"
11272                                       "}\n"
11273                                       "\n";
11274     static const GLchar *gs         = "#version 430 core\n"
11275                                       "#extension GL_ARB_enhanced_layouts : require\n"
11276                                       "\n"
11277                                       "layout(points)                           in;\n"
11278                                       "layout(triangle_strip, max_vertices = 4) out;\n"
11279                                       "\n"
11280                                       "in  vec4 tes_gs[];\n"
11281                                       "out vec4 gs_fs;\n"
11282                                       "\n"
11283                                       "void main()\n"
11284                                       "{\n"
11285                                       "    gs_fs = tes_gs[0];\n"
11286                                       "    gl_Position  = vec4(-1, -1, 0, 1);\n"
11287                                       "    EmitVertex();\n"
11288                                       "    gs_fs = tes_gs[0];\n"
11289                                       "    gl_Position  = vec4(-1, 1, 0, 1);\n"
11290                                       "    EmitVertex();\n"
11291                                       "    gs_fs = tes_gs[0];\n"
11292                                       "    gl_Position  = vec4(1, -1, 0, 1);\n"
11293                                       "    EmitVertex();\n"
11294                                       "    gs_fs = tes_gs[0];\n"
11295                                       "    gl_Position  = vec4(1, 1, 0, 1);\n"
11296                                       "    EmitVertex();\n"
11297                                       "}\n"
11298                                       "\n";
11299     static const GLchar *gs_tested  = "#version 430 core\n"
11300                                       "#extension GL_ARB_enhanced_layouts : require\n"
11301                                       "\n"
11302                                       "layout(points)                           in;\n"
11303                                       "layout(triangle_strip, max_vertices = 4) out;\n"
11304                                       "\n"
11305                                       "layout (std140) buffer Block {\n"
11306                                       "    layout (offset = OFFSET) TYPE member;\n"
11307                                       "} block;\n"
11308                                       "\n"
11309                                       "in  vec4 tes_gs[];\n"
11310                                       "out vec4 gs_fs;\n"
11311                                       "\n"
11312                                       "void main()\n"
11313                                       "{\n"
11314                                       "    if (TYPE(1) == block.member)\n"
11315                                       "    {\n"
11316                                       "        gs_fs = vec4(1, 1, 1, 1);\n"
11317                                       "    }\n"
11318                                       "\n"
11319                                       "    gs_fs += tes_gs[0];\n"
11320                                       "    gl_Position  = vec4(-1, -1, 0, 1);\n"
11321                                       "    EmitVertex();\n"
11322                                       "    gs_fs += tes_gs[0];\n"
11323                                       "    gl_Position  = vec4(-1, 1, 0, 1);\n"
11324                                       "    EmitVertex();\n"
11325                                       "    gs_fs += tes_gs[0];\n"
11326                                       "    gl_Position  = vec4(1, -1, 0, 1);\n"
11327                                       "    EmitVertex();\n"
11328                                       "    gs_fs += tes_gs[0];\n"
11329                                       "    gl_Position  = vec4(1, 1, 0, 1);\n"
11330                                       "    EmitVertex();\n"
11331                                       "}\n"
11332                                       "\n";
11333     static const GLchar *tcs        = "#version 430 core\n"
11334                                       "#extension GL_ARB_enhanced_layouts : require\n"
11335                                       "\n"
11336                                       "layout(vertices = 1) out;\n"
11337                                       "\n"
11338                                       "in  vec4 vs_tcs[];\n"
11339                                       "out vec4 tcs_tes[];\n"
11340                                       "\n"
11341                                       "void main()\n"
11342                                       "{\n"
11343                                       "\n"
11344                                       "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
11345                                       "\n"
11346                                       "    gl_TessLevelOuter[0] = 1.0;\n"
11347                                       "    gl_TessLevelOuter[1] = 1.0;\n"
11348                                       "    gl_TessLevelOuter[2] = 1.0;\n"
11349                                       "    gl_TessLevelOuter[3] = 1.0;\n"
11350                                       "    gl_TessLevelInner[0] = 1.0;\n"
11351                                       "    gl_TessLevelInner[1] = 1.0;\n"
11352                                       "}\n"
11353                                       "\n";
11354     static const GLchar *tcs_tested = "#version 430 core\n"
11355                                       "#extension GL_ARB_enhanced_layouts : require\n"
11356                                       "\n"
11357                                       "layout(vertices = 1) out;\n"
11358                                       "\n"
11359                                       "layout (std140) buffer Block {\n"
11360                                       "    layout (offset = OFFSET) TYPE member;\n"
11361                                       "} block;\n"
11362                                       "\n"
11363                                       "in  vec4 vs_tcs[];\n"
11364                                       "out vec4 tcs_tes[];\n"
11365                                       "\n"
11366                                       "void main()\n"
11367                                       "{\n"
11368                                       "    if (TYPE(1) == block.member)\n"
11369                                       "    {\n"
11370                                       "        tcs_tes[gl_InvocationID] = vec4(1, 1, 1, 1);\n"
11371                                       "    }\n"
11372                                       "\n"
11373                                       "\n"
11374                                       "    tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
11375                                       "\n"
11376                                       "    gl_TessLevelOuter[0] = 1.0;\n"
11377                                       "    gl_TessLevelOuter[1] = 1.0;\n"
11378                                       "    gl_TessLevelOuter[2] = 1.0;\n"
11379                                       "    gl_TessLevelOuter[3] = 1.0;\n"
11380                                       "    gl_TessLevelInner[0] = 1.0;\n"
11381                                       "    gl_TessLevelInner[1] = 1.0;\n"
11382                                       "}\n"
11383                                       "\n";
11384     static const GLchar *tes        = "#version 430 core\n"
11385                                       "#extension GL_ARB_enhanced_layouts : require\n"
11386                                       "\n"
11387                                       "layout(isolines, point_mode) in;\n"
11388                                       "\n"
11389                                       "in  vec4 tcs_tes[];\n"
11390                                       "out vec4 tes_gs;\n"
11391                                       "\n"
11392                                       "void main()\n"
11393                                       "{\n"
11394                                       "    tes_gs = tcs_tes[0];\n"
11395                                       "}\n"
11396                                       "\n";
11397     static const GLchar *tes_tested = "#version 430 core\n"
11398                                       "#extension GL_ARB_enhanced_layouts : require\n"
11399                                       "\n"
11400                                       "layout(isolines, point_mode) in;\n"
11401                                       "\n"
11402                                       "layout (std140) buffer Block {\n"
11403                                       "    layout (offset = OFFSET) TYPE member;\n"
11404                                       "} block;\n"
11405                                       "\n"
11406                                       "in  vec4 tcs_tes[];\n"
11407                                       "out vec4 tes_gs;\n"
11408                                       "\n"
11409                                       "void main()\n"
11410                                       "{\n"
11411                                       "    if (TYPE(1) == block.member)\n"
11412                                       "    {\n"
11413                                       "        tes_gs = vec4(1, 1, 1, 1);\n"
11414                                       "    }\n"
11415                                       "\n"
11416                                       "    tes_gs += tcs_tes[0];\n"
11417                                       "}\n"
11418                                       "\n";
11419     static const GLchar *vs         = "#version 430 core\n"
11420                                       "#extension GL_ARB_enhanced_layouts : require\n"
11421                                       "\n"
11422                                       "in  vec4 in_vs;\n"
11423                                       "out vec4 vs_tcs;\n"
11424                                       "\n"
11425                                       "void main()\n"
11426                                       "{\n"
11427                                       "    vs_tcs = in_vs;\n"
11428                                       "}\n"
11429                                       "\n";
11430     static const GLchar *vs_tested  = "#version 430 core\n"
11431                                       "#extension GL_ARB_enhanced_layouts : require\n"
11432                                       "\n"
11433                                       "layout (std140) buffer Block {\n"
11434                                       "    layout (offset = OFFSET) TYPE member;\n"
11435                                       "} block;\n"
11436                                       "\n"
11437                                       "in  vec4 in_vs;\n"
11438                                       "out vec4 vs_tcs;\n"
11439                                       "\n"
11440                                       "void main()\n"
11441                                       "{\n"
11442                                       "    if (TYPE(1) == block.member)\n"
11443                                       "    {\n"
11444                                       "        vs_tcs = vec4(1, 1, 1, 1);\n"
11445                                       "    }\n"
11446                                       "\n"
11447                                       "    vs_tcs += in_vs;\n"
11448                                       "}\n"
11449                                       "\n";
11450 
11451     std::string source;
11452     testCase &test_case = m_test_cases[test_case_index];
11453 
11454     if (test_case.m_stage == stage)
11455     {
11456         GLchar buffer[16];
11457         const GLuint offset     = test_case.m_offset;
11458         size_t position         = 0;
11459         const Utils::Type &type = test_case.m_type;
11460         const GLchar *type_name = type.GetGLSLTypeName();
11461 
11462         sprintf(buffer, "%d", offset);
11463 
11464         switch (stage)
11465         {
11466         case Utils::Shader::COMPUTE:
11467             source = cs;
11468             break;
11469         case Utils::Shader::FRAGMENT:
11470             source = fs_tested;
11471             break;
11472         case Utils::Shader::GEOMETRY:
11473             source = gs_tested;
11474             break;
11475         case Utils::Shader::TESS_CTRL:
11476             source = tcs_tested;
11477             break;
11478         case Utils::Shader::TESS_EVAL:
11479             source = tes_tested;
11480             break;
11481         case Utils::Shader::VERTEX:
11482             source = vs_tested;
11483             break;
11484         default:
11485             TCU_FAIL("Invalid enum");
11486         }
11487 
11488         Utils::replaceToken("OFFSET", position, buffer, source);
11489         Utils::replaceToken("TYPE", position, type_name, source);
11490         Utils::replaceToken("TYPE", position, type_name, source);
11491     }
11492     else
11493     {
11494         switch (stage)
11495         {
11496         case Utils::Shader::FRAGMENT:
11497             source = fs;
11498             break;
11499         case Utils::Shader::GEOMETRY:
11500             source = gs;
11501             break;
11502         case Utils::Shader::TESS_CTRL:
11503             source = tcs;
11504             break;
11505         case Utils::Shader::TESS_EVAL:
11506             source = tes;
11507             break;
11508         case Utils::Shader::VERTEX:
11509             source = vs;
11510             break;
11511         default:
11512             TCU_FAIL("Invalid enum");
11513         }
11514     }
11515 
11516     return source;
11517 }
11518 
11519 /** Checks if stage is supported
11520  *
11521  * @param stage Shader stage
11522  *
11523  * @return true if supported, false otherwise
11524  **/
11525 bool SSBMemberInvalidOffsetAlignmentTest::isStageSupported(Utils::Shader::STAGES stage)
11526 {
11527     const Functions &gl         = m_context.getRenderContext().getFunctions();
11528     GLint max_supported_buffers = 0;
11529     GLenum pname                = 0;
11530 
11531     switch (stage)
11532     {
11533     case Utils::Shader::COMPUTE:
11534         pname = GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS;
11535         break;
11536     case Utils::Shader::FRAGMENT:
11537         pname = GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS;
11538         break;
11539     case Utils::Shader::GEOMETRY:
11540         pname = GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS;
11541         break;
11542     case Utils::Shader::TESS_CTRL:
11543         pname = GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS;
11544         break;
11545     case Utils::Shader::TESS_EVAL:
11546         pname = GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS;
11547         break;
11548     case Utils::Shader::VERTEX:
11549         pname = GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS;
11550         break;
11551     default:
11552         TCU_FAIL("Invalid enum");
11553     }
11554 
11555     gl.getIntegerv(pname, &max_supported_buffers);
11556     GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
11557 
11558     return 1 <= max_supported_buffers;
11559 }
11560 
11561 /** Constructor
11562  *
11563  * @param context Test framework context
11564  **/
11565 SSBMemberOverlappingOffsetsTest::SSBMemberOverlappingOffsetsTest(deqp::Context &context)
11566     : UniformBlockMemberOverlappingOffsetsTest(
11567           context, "ssb_member_overlapping_offsets",
11568           "Test verifies that overlapping offsets qualifiers cause compilation failure")
11569 {
11570     /* Nothing to be done here */
11571 }
11572 
11573 /** Source for given test case and stage
11574  *
11575  * @param test_case_index Index of test case
11576  * @param stage           Shader stage
11577  *
11578  * @return Shader source
11579  **/
11580 std::string SSBMemberOverlappingOffsetsTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
11581 {
11582     static const GLchar *cs         = "#version 430 core\n"
11583                                       "#extension GL_ARB_enhanced_layouts : require\n"
11584                                       "\n"
11585                                       "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
11586                                       "\n"
11587                                       "layout (std140) buffer Block {\n"
11588                                       "    layout (offset = B_OFFSET) B_TYPE b;\n"
11589                                       "    layout (offset = A_OFFSET) A_TYPE a;\n"
11590                                       "} block;\n"
11591                                       "\n"
11592                                       "writeonly uniform image2D uni_image;\n"
11593                                       "\n"
11594                                       "void main()\n"
11595                                       "{\n"
11596                                       "    vec4 result = vec4(1, 0, 0.5, 1);\n"
11597                                       "\n"
11598                                       "    if ((B_TYPE(1) == block.b) ||\n"
11599                                       "        (A_TYPE(0) == block.a) )\n"
11600                                       "    {\n"
11601                                       "        result = vec4(1, 1, 1, 1);\n"
11602                                       "    }\n"
11603                                       "\n"
11604                                       "    imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
11605                                       "}\n"
11606                                       "\n";
11607     static const GLchar *fs         = "#version 430 core\n"
11608                                       "#extension GL_ARB_enhanced_layouts : require\n"
11609                                       "\n"
11610                                       "in  vec4 gs_fs;\n"
11611                                       "out vec4 fs_out;\n"
11612                                       "\n"
11613                                       "void main()\n"
11614                                       "{\n"
11615                                       "    fs_out = gs_fs;\n"
11616                                       "}\n"
11617                                       "\n";
11618     static const GLchar *fs_tested  = "#version 430 core\n"
11619                                       "#extension GL_ARB_enhanced_layouts : require\n"
11620                                       "\n"
11621                                       "layout (std140) buffer Block {\n"
11622                                       "    layout (offset = B_OFFSET) B_TYPE b;\n"
11623                                       "    layout (offset = A_OFFSET) A_TYPE a;\n"
11624                                       "} block;\n"
11625                                       "\n"
11626                                       "in  vec4 gs_fs;\n"
11627                                       "out vec4 fs_out;\n"
11628                                       "\n"
11629                                       "void main()\n"
11630                                       "{\n"
11631                                       "    if ((B_TYPE(1) == block.b) ||\n"
11632                                       "        (A_TYPE(0) == block.a) )\n"
11633                                       "    {\n"
11634                                       "        fs_out = vec4(1, 1, 1, 1);\n"
11635                                       "    }\n"
11636                                       "\n"
11637                                       "    fs_out += gs_fs;\n"
11638                                       "}\n"
11639                                       "\n";
11640     static const GLchar *gs         = "#version 430 core\n"
11641                                       "#extension GL_ARB_enhanced_layouts : require\n"
11642                                       "\n"
11643                                       "layout(points)                           in;\n"
11644                                       "layout(triangle_strip, max_vertices = 4) out;\n"
11645                                       "\n"
11646                                       "in  vec4 tes_gs[];\n"
11647                                       "out vec4 gs_fs;\n"
11648                                       "\n"
11649                                       "void main()\n"
11650                                       "{\n"
11651                                       "    gs_fs = tes_gs[0];\n"
11652                                       "    gl_Position  = vec4(-1, -1, 0, 1);\n"
11653                                       "    EmitVertex();\n"
11654                                       "    gs_fs = tes_gs[0];\n"
11655                                       "    gl_Position  = vec4(-1, 1, 0, 1);\n"
11656                                       "    EmitVertex();\n"
11657                                       "    gs_fs = tes_gs[0];\n"
11658                                       "    gl_Position  = vec4(1, -1, 0, 1);\n"
11659                                       "    EmitVertex();\n"
11660                                       "    gs_fs = tes_gs[0];\n"
11661                                       "    gl_Position  = vec4(1, 1, 0, 1);\n"
11662                                       "    EmitVertex();\n"
11663                                       "}\n"
11664                                       "\n";
11665     static const GLchar *gs_tested  = "#version 430 core\n"
11666                                       "#extension GL_ARB_enhanced_layouts : require\n"
11667                                       "\n"
11668                                       "layout(points)                           in;\n"
11669                                       "layout(triangle_strip, max_vertices = 4) out;\n"
11670                                       "\n"
11671                                       "layout (std140) buffer Block {\n"
11672                                       "    layout (offset = B_OFFSET) B_TYPE b;\n"
11673                                       "    layout (offset = A_OFFSET) A_TYPE a;\n"
11674                                       "} block;\n"
11675                                       "\n"
11676                                       "in  vec4 tes_gs[];\n"
11677                                       "out vec4 gs_fs;\n"
11678                                       "\n"
11679                                       "void main()\n"
11680                                       "{\n"
11681                                       "    if ((B_TYPE(1) == block.b) ||\n"
11682                                       "        (A_TYPE(0) == block.a) )\n"
11683                                       "    {\n"
11684                                       "        gs_fs = vec4(1, 1, 1, 1);\n"
11685                                       "    }\n"
11686                                       "\n"
11687                                       "    gs_fs += tes_gs[0];\n"
11688                                       "    gl_Position  = vec4(-1, -1, 0, 1);\n"
11689                                       "    EmitVertex();\n"
11690                                       "    gs_fs += tes_gs[0];\n"
11691                                       "    gl_Position  = vec4(-1, 1, 0, 1);\n"
11692                                       "    EmitVertex();\n"
11693                                       "    gs_fs += tes_gs[0];\n"
11694                                       "    gl_Position  = vec4(1, -1, 0, 1);\n"
11695                                       "    EmitVertex();\n"
11696                                       "    gs_fs += tes_gs[0];\n"
11697                                       "    gl_Position  = vec4(1, 1, 0, 1);\n"
11698                                       "    EmitVertex();\n"
11699                                       "}\n"
11700                                       "\n";
11701     static const GLchar *tcs        = "#version 430 core\n"
11702                                       "#extension GL_ARB_enhanced_layouts : require\n"
11703                                       "\n"
11704                                       "layout(vertices = 1) out;\n"
11705                                       "\n"
11706                                       "in  vec4 vs_tcs[];\n"
11707                                       "out vec4 tcs_tes[];\n"
11708                                       "\n"
11709                                       "void main()\n"
11710                                       "{\n"
11711                                       "\n"
11712                                       "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
11713                                       "\n"
11714                                       "    gl_TessLevelOuter[0] = 1.0;\n"
11715                                       "    gl_TessLevelOuter[1] = 1.0;\n"
11716                                       "    gl_TessLevelOuter[2] = 1.0;\n"
11717                                       "    gl_TessLevelOuter[3] = 1.0;\n"
11718                                       "    gl_TessLevelInner[0] = 1.0;\n"
11719                                       "    gl_TessLevelInner[1] = 1.0;\n"
11720                                       "}\n"
11721                                       "\n";
11722     static const GLchar *tcs_tested = "#version 430 core\n"
11723                                       "#extension GL_ARB_enhanced_layouts : require\n"
11724                                       "\n"
11725                                       "layout(vertices = 1) out;\n"
11726                                       "\n"
11727                                       "layout (std140) buffer Block {\n"
11728                                       "    layout (offset = B_OFFSET) B_TYPE b;\n"
11729                                       "    layout (offset = A_OFFSET) A_TYPE a;\n"
11730                                       "} block;\n"
11731                                       "\n"
11732                                       "in  vec4 vs_tcs[];\n"
11733                                       "out vec4 tcs_tes[];\n"
11734                                       "\n"
11735                                       "void main()\n"
11736                                       "{\n"
11737                                       "    if ((B_TYPE(1) == block.b) ||\n"
11738                                       "        (A_TYPE(0) == block.a) )\n"
11739                                       "    {\n"
11740                                       "        tcs_tes[gl_InvocationID] = vec4(1, 1, 1, 1);\n"
11741                                       "    }\n"
11742                                       "\n"
11743                                       "\n"
11744                                       "    tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
11745                                       "\n"
11746                                       "    gl_TessLevelOuter[0] = 1.0;\n"
11747                                       "    gl_TessLevelOuter[1] = 1.0;\n"
11748                                       "    gl_TessLevelOuter[2] = 1.0;\n"
11749                                       "    gl_TessLevelOuter[3] = 1.0;\n"
11750                                       "    gl_TessLevelInner[0] = 1.0;\n"
11751                                       "    gl_TessLevelInner[1] = 1.0;\n"
11752                                       "}\n"
11753                                       "\n";
11754     static const GLchar *tes        = "#version 430 core\n"
11755                                       "#extension GL_ARB_enhanced_layouts : require\n"
11756                                       "\n"
11757                                       "layout(isolines, point_mode) in;\n"
11758                                       "\n"
11759                                       "in  vec4 tcs_tes[];\n"
11760                                       "out vec4 tes_gs;\n"
11761                                       "\n"
11762                                       "void main()\n"
11763                                       "{\n"
11764                                       "    tes_gs = tcs_tes[0];\n"
11765                                       "}\n"
11766                                       "\n";
11767     static const GLchar *tes_tested = "#version 430 core\n"
11768                                       "#extension GL_ARB_enhanced_layouts : require\n"
11769                                       "\n"
11770                                       "layout(isolines, point_mode) in;\n"
11771                                       "\n"
11772                                       "layout (std140) buffer Block {\n"
11773                                       "    layout (offset = B_OFFSET) B_TYPE b;\n"
11774                                       "    layout (offset = A_OFFSET) A_TYPE a;\n"
11775                                       "} block;\n"
11776                                       "\n"
11777                                       "in  vec4 tcs_tes[];\n"
11778                                       "out vec4 tes_gs;\n"
11779                                       "\n"
11780                                       "void main()\n"
11781                                       "{\n"
11782                                       "    if ((B_TYPE(1) == block.b) ||\n"
11783                                       "        (A_TYPE(0) == block.a) )\n"
11784                                       "    {\n"
11785                                       "        tes_gs = vec4(1, 1, 1, 1);\n"
11786                                       "    }\n"
11787                                       "\n"
11788                                       "    tes_gs += tcs_tes[0];\n"
11789                                       "}\n"
11790                                       "\n";
11791     static const GLchar *vs         = "#version 430 core\n"
11792                                       "#extension GL_ARB_enhanced_layouts : require\n"
11793                                       "\n"
11794                                       "in  vec4 in_vs;\n"
11795                                       "out vec4 vs_tcs;\n"
11796                                       "\n"
11797                                       "void main()\n"
11798                                       "{\n"
11799                                       "    vs_tcs = in_vs;\n"
11800                                       "}\n"
11801                                       "\n";
11802     static const GLchar *vs_tested  = "#version 430 core\n"
11803                                       "#extension GL_ARB_enhanced_layouts : require\n"
11804                                       "\n"
11805                                       "layout (std140) buffer Block {\n"
11806                                       "    layout (offset = B_OFFSET) B_TYPE b;\n"
11807                                       "    layout (offset = A_OFFSET) A_TYPE a;\n"
11808                                       "} block;\n"
11809                                       "\n"
11810                                       "in  vec4 in_vs;\n"
11811                                       "out vec4 vs_tcs;\n"
11812                                       "\n"
11813                                       "void main()\n"
11814                                       "{\n"
11815                                       "    if ((B_TYPE(1) == block.b) ||\n"
11816                                       "        (A_TYPE(0) == block.a) )\n"
11817                                       "    {\n"
11818                                       "        vs_tcs = vec4(1, 1, 1, 1);\n"
11819                                       "    }\n"
11820                                       "\n"
11821                                       "    vs_tcs += in_vs;\n"
11822                                       "}\n"
11823                                       "\n";
11824 
11825     std::string source;
11826     testCase &test_case = m_test_cases[test_case_index];
11827 
11828     if (test_case.m_stage == stage)
11829     {
11830         GLchar buffer[16];
11831         const GLuint b_offset     = test_case.m_b_offset;
11832         const Utils::Type &b_type = test_case.m_b_type;
11833         const GLchar *b_type_name = b_type.GetGLSLTypeName();
11834         const GLuint a_offset     = test_case.m_a_offset;
11835         const Utils::Type &a_type = test_case.m_a_type;
11836         const GLchar *a_type_name = a_type.GetGLSLTypeName();
11837         size_t position           = 0;
11838 
11839         switch (stage)
11840         {
11841         case Utils::Shader::COMPUTE:
11842             source = cs;
11843             break;
11844         case Utils::Shader::FRAGMENT:
11845             source = fs_tested;
11846             break;
11847         case Utils::Shader::GEOMETRY:
11848             source = gs_tested;
11849             break;
11850         case Utils::Shader::TESS_CTRL:
11851             source = tcs_tested;
11852             break;
11853         case Utils::Shader::TESS_EVAL:
11854             source = tes_tested;
11855             break;
11856         case Utils::Shader::VERTEX:
11857             source = vs_tested;
11858             break;
11859         default:
11860             TCU_FAIL("Invalid enum");
11861         }
11862 
11863         sprintf(buffer, "%d", b_offset);
11864         Utils::replaceToken("B_OFFSET", position, buffer, source);
11865         Utils::replaceToken("B_TYPE", position, b_type_name, source);
11866         sprintf(buffer, "%d", a_offset);
11867         Utils::replaceToken("A_OFFSET", position, buffer, source);
11868         Utils::replaceToken("A_TYPE", position, a_type_name, source);
11869         Utils::replaceToken("B_TYPE", position, b_type_name, source);
11870         Utils::replaceToken("A_TYPE", position, a_type_name, source);
11871     }
11872     else
11873     {
11874         switch (stage)
11875         {
11876         case Utils::Shader::FRAGMENT:
11877             source = fs;
11878             break;
11879         case Utils::Shader::GEOMETRY:
11880             source = gs;
11881             break;
11882         case Utils::Shader::TESS_CTRL:
11883             source = tcs;
11884             break;
11885         case Utils::Shader::TESS_EVAL:
11886             source = tes;
11887             break;
11888         case Utils::Shader::VERTEX:
11889             source = vs;
11890             break;
11891         default:
11892             TCU_FAIL("Invalid enum");
11893         }
11894     }
11895 
11896     return source;
11897 }
11898 
11899 /** Checks if stage is supported
11900  *
11901  * @param stage Shader stage
11902  *
11903  * @return true if supported, false otherwise
11904  **/
11905 bool SSBMemberOverlappingOffsetsTest::isStageSupported(Utils::Shader::STAGES stage)
11906 {
11907     const Functions &gl         = m_context.getRenderContext().getFunctions();
11908     GLint max_supported_buffers = 0;
11909     GLenum pname                = 0;
11910 
11911     switch (stage)
11912     {
11913     case Utils::Shader::COMPUTE:
11914         pname = GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS;
11915         break;
11916     case Utils::Shader::FRAGMENT:
11917         pname = GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS;
11918         break;
11919     case Utils::Shader::GEOMETRY:
11920         pname = GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS;
11921         break;
11922     case Utils::Shader::TESS_CTRL:
11923         pname = GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS;
11924         break;
11925     case Utils::Shader::TESS_EVAL:
11926         pname = GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS;
11927         break;
11928     case Utils::Shader::VERTEX:
11929         pname = GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS;
11930         break;
11931     default:
11932         TCU_FAIL("Invalid enum");
11933     }
11934 
11935     gl.getIntegerv(pname, &max_supported_buffers);
11936     GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
11937 
11938     return 1 <= max_supported_buffers;
11939 }
11940 
11941 /** Constructor
11942  *
11943  * @param context Test framework context
11944  **/
11945 SSBMemberAlignNonPowerOf2Test::SSBMemberAlignNonPowerOf2Test(deqp::Context &context)
11946     : UniformBlockMemberAlignNonPowerOf2Test(context, "ssb_member_align_non_power_of_2",
11947                                              "Test verifies that align qualifier requires value that is a power of 2")
11948 {
11949     /* Nothing to be done here */
11950 }
11951 
11952 /** Source for given test case and stage
11953  *
11954  * @param test_case_index Index of test case
11955  * @param stage           Shader stage
11956  *
11957  * @return Shader source
11958  **/
11959 std::string SSBMemberAlignNonPowerOf2Test::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
11960 {
11961     static const GLchar *cs         = "#version 430 core\n"
11962                                       "#extension GL_ARB_enhanced_layouts : require\n"
11963                                       "\n"
11964                                       "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
11965                                       "\n"
11966                                       "layout (std140) buffer Block {\n"
11967                                       "    vec4 b;\n"
11968                                       "    layout (align = ALIGN) TYPE a;\n"
11969                                       "} block;\n"
11970                                       "\n"
11971                                       "writeonly uniform image2D uni_image;\n"
11972                                       "\n"
11973                                       "void main()\n"
11974                                       "{\n"
11975                                       "    vec4 result = vec4(1, 0, 0.5, 1);\n"
11976                                       "\n"
11977                                       "    if (TYPE(0) == block.a)\n"
11978                                       "    {\n"
11979                                       "        result = vec4(1, 1, 1, 1) - block.b;\n"
11980                                       "    }\n"
11981                                       "\n"
11982                                       "    imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
11983                                       "}\n"
11984                                       "\n";
11985     static const GLchar *fs         = "#version 430 core\n"
11986                                       "#extension GL_ARB_enhanced_layouts : require\n"
11987                                       "\n"
11988                                       "in  vec4 gs_fs;\n"
11989                                       "out vec4 fs_out;\n"
11990                                       "\n"
11991                                       "void main()\n"
11992                                       "{\n"
11993                                       "    fs_out = gs_fs;\n"
11994                                       "}\n"
11995                                       "\n";
11996     static const GLchar *fs_tested  = "#version 430 core\n"
11997                                       "#extension GL_ARB_enhanced_layouts : require\n"
11998                                       "\n"
11999                                       "layout (std140) buffer Block {\n"
12000                                       "    vec4 b;\n"
12001                                       "    layout (align = ALIGN) TYPE a;\n"
12002                                       "} block;\n"
12003                                       "\n"
12004                                       "in  vec4 gs_fs;\n"
12005                                       "out vec4 fs_out;\n"
12006                                       "\n"
12007                                       "void main()\n"
12008                                       "{\n"
12009                                       "    if (TYPE(0) == block.a)\n"
12010                                       "    {\n"
12011                                       "        fs_out = block.b;\n"
12012                                       "    }\n"
12013                                       "\n"
12014                                       "    fs_out += gs_fs;\n"
12015                                       "}\n"
12016                                       "\n";
12017     static const GLchar *gs         = "#version 430 core\n"
12018                                       "#extension GL_ARB_enhanced_layouts : require\n"
12019                                       "\n"
12020                                       "layout(points)                           in;\n"
12021                                       "layout(triangle_strip, max_vertices = 4) out;\n"
12022                                       "\n"
12023                                       "in  vec4 tes_gs[];\n"
12024                                       "out vec4 gs_fs;\n"
12025                                       "\n"
12026                                       "void main()\n"
12027                                       "{\n"
12028                                       "    gs_fs = tes_gs[0];\n"
12029                                       "    gl_Position  = vec4(-1, -1, 0, 1);\n"
12030                                       "    EmitVertex();\n"
12031                                       "    gs_fs = tes_gs[0];\n"
12032                                       "    gl_Position  = vec4(-1, 1, 0, 1);\n"
12033                                       "    EmitVertex();\n"
12034                                       "    gs_fs = tes_gs[0];\n"
12035                                       "    gl_Position  = vec4(1, -1, 0, 1);\n"
12036                                       "    EmitVertex();\n"
12037                                       "    gs_fs = tes_gs[0];\n"
12038                                       "    gl_Position  = vec4(1, 1, 0, 1);\n"
12039                                       "    EmitVertex();\n"
12040                                       "}\n"
12041                                       "\n";
12042     static const GLchar *gs_tested  = "#version 430 core\n"
12043                                       "#extension GL_ARB_enhanced_layouts : require\n"
12044                                       "\n"
12045                                       "layout(points)                           in;\n"
12046                                       "layout(triangle_strip, max_vertices = 4) out;\n"
12047                                       "\n"
12048                                       "layout (std140) buffer Block {\n"
12049                                       "    vec4 b;\n"
12050                                       "    layout (align = ALIGN) TYPE a;\n"
12051                                       "} block;\n"
12052                                       "\n"
12053                                       "in  vec4 tes_gs[];\n"
12054                                       "out vec4 gs_fs;\n"
12055                                       "\n"
12056                                       "void main()\n"
12057                                       "{\n"
12058                                       "    if (TYPE(0) == block.a)\n"
12059                                       "    {\n"
12060                                       "        gs_fs = block.b;\n"
12061                                       "    }\n"
12062                                       "\n"
12063                                       "    gs_fs += tes_gs[0];\n"
12064                                       "    gl_Position  = vec4(-1, -1, 0, 1);\n"
12065                                       "    EmitVertex();\n"
12066                                       "    gs_fs += tes_gs[0];\n"
12067                                       "    gl_Position  = vec4(-1, 1, 0, 1);\n"
12068                                       "    EmitVertex();\n"
12069                                       "    gs_fs += tes_gs[0];\n"
12070                                       "    gl_Position  = vec4(1, -1, 0, 1);\n"
12071                                       "    EmitVertex();\n"
12072                                       "    gs_fs += tes_gs[0];\n"
12073                                       "    gl_Position  = vec4(1, 1, 0, 1);\n"
12074                                       "    EmitVertex();\n"
12075                                       "}\n"
12076                                       "\n";
12077     static const GLchar *tcs        = "#version 430 core\n"
12078                                       "#extension GL_ARB_enhanced_layouts : require\n"
12079                                       "\n"
12080                                       "layout(vertices = 1) out;\n"
12081                                       "\n"
12082                                       "in  vec4 vs_tcs[];\n"
12083                                       "out vec4 tcs_tes[];\n"
12084                                       "\n"
12085                                       "void main()\n"
12086                                       "{\n"
12087                                       "\n"
12088                                       "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
12089                                       "\n"
12090                                       "    gl_TessLevelOuter[0] = 1.0;\n"
12091                                       "    gl_TessLevelOuter[1] = 1.0;\n"
12092                                       "    gl_TessLevelOuter[2] = 1.0;\n"
12093                                       "    gl_TessLevelOuter[3] = 1.0;\n"
12094                                       "    gl_TessLevelInner[0] = 1.0;\n"
12095                                       "    gl_TessLevelInner[1] = 1.0;\n"
12096                                       "}\n"
12097                                       "\n";
12098     static const GLchar *tcs_tested = "#version 430 core\n"
12099                                       "#extension GL_ARB_enhanced_layouts : require\n"
12100                                       "\n"
12101                                       "layout(vertices = 1) out;\n"
12102                                       "\n"
12103                                       "layout (std140) buffer Block {\n"
12104                                       "    vec4 b;\n"
12105                                       "    layout (align = ALIGN) TYPE a;\n"
12106                                       "} block;\n"
12107                                       "\n"
12108                                       "in  vec4 vs_tcs[];\n"
12109                                       "out vec4 tcs_tes[];\n"
12110                                       "\n"
12111                                       "void main()\n"
12112                                       "{\n"
12113                                       "    if (TYPE(0) == block.a)\n"
12114                                       "    {\n"
12115                                       "        tcs_tes[gl_InvocationID] = block.b;\n"
12116                                       "    }\n"
12117                                       "\n"
12118                                       "\n"
12119                                       "    tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
12120                                       "\n"
12121                                       "    gl_TessLevelOuter[0] = 1.0;\n"
12122                                       "    gl_TessLevelOuter[1] = 1.0;\n"
12123                                       "    gl_TessLevelOuter[2] = 1.0;\n"
12124                                       "    gl_TessLevelOuter[3] = 1.0;\n"
12125                                       "    gl_TessLevelInner[0] = 1.0;\n"
12126                                       "    gl_TessLevelInner[1] = 1.0;\n"
12127                                       "}\n"
12128                                       "\n";
12129     static const GLchar *tes        = "#version 430 core\n"
12130                                       "#extension GL_ARB_enhanced_layouts : require\n"
12131                                       "\n"
12132                                       "layout(isolines, point_mode) in;\n"
12133                                       "\n"
12134                                       "in  vec4 tcs_tes[];\n"
12135                                       "out vec4 tes_gs;\n"
12136                                       "\n"
12137                                       "void main()\n"
12138                                       "{\n"
12139                                       "    tes_gs = tcs_tes[0];\n"
12140                                       "}\n"
12141                                       "\n";
12142     static const GLchar *tes_tested = "#version 430 core\n"
12143                                       "#extension GL_ARB_enhanced_layouts : require\n"
12144                                       "\n"
12145                                       "layout(isolines, point_mode) in;\n"
12146                                       "\n"
12147                                       "layout (std140) buffer Block {\n"
12148                                       "    vec4 b;\n"
12149                                       "    layout (align = ALIGN) TYPE a;\n"
12150                                       "} block;\n"
12151                                       "\n"
12152                                       "in  vec4 tcs_tes[];\n"
12153                                       "out vec4 tes_gs;\n"
12154                                       "\n"
12155                                       "void main()\n"
12156                                       "{\n"
12157                                       "    if (TYPE(0) == block.a)\n"
12158                                       "    {\n"
12159                                       "        tes_gs = block.b;\n"
12160                                       "    }\n"
12161                                       "\n"
12162                                       "    tes_gs += tcs_tes[0];\n"
12163                                       "}\n"
12164                                       "\n";
12165     static const GLchar *vs         = "#version 430 core\n"
12166                                       "#extension GL_ARB_enhanced_layouts : require\n"
12167                                       "\n"
12168                                       "in  vec4 in_vs;\n"
12169                                       "out vec4 vs_tcs;\n"
12170                                       "\n"
12171                                       "void main()\n"
12172                                       "{\n"
12173                                       "    vs_tcs = in_vs;\n"
12174                                       "}\n"
12175                                       "\n";
12176     static const GLchar *vs_tested  = "#version 430 core\n"
12177                                       "#extension GL_ARB_enhanced_layouts : require\n"
12178                                       "\n"
12179                                       "layout (std140) buffer Block {\n"
12180                                       "    vec4 b;\n"
12181                                       "    layout (align = ALIGN) TYPE a;\n"
12182                                       "} block;\n"
12183                                       "\n"
12184                                       "in  vec4 in_vs;\n"
12185                                       "out vec4 vs_tcs;\n"
12186                                       "\n"
12187                                       "void main()\n"
12188                                       "{\n"
12189                                       "    if (TYPE(0) == block.a)\n"
12190                                       "    {\n"
12191                                       "        vs_tcs = block.b;\n"
12192                                       "    }\n"
12193                                       "\n"
12194                                       "    vs_tcs += in_vs;\n"
12195                                       "}\n"
12196                                       "\n";
12197 
12198     std::string source;
12199     testCase &test_case = m_test_cases[test_case_index];
12200 
12201     if (test_case.m_stage == stage)
12202     {
12203         GLchar buffer[16];
12204         const GLuint alignment  = test_case.m_alignment;
12205         const Utils::Type &type = test_case.m_type;
12206         const GLchar *type_name = type.GetGLSLTypeName();
12207         size_t position         = 0;
12208 
12209         switch (stage)
12210         {
12211         case Utils::Shader::COMPUTE:
12212             source = cs;
12213             break;
12214         case Utils::Shader::FRAGMENT:
12215             source = fs_tested;
12216             break;
12217         case Utils::Shader::GEOMETRY:
12218             source = gs_tested;
12219             break;
12220         case Utils::Shader::TESS_CTRL:
12221             source = tcs_tested;
12222             break;
12223         case Utils::Shader::TESS_EVAL:
12224             source = tes_tested;
12225             break;
12226         case Utils::Shader::VERTEX:
12227             source = vs_tested;
12228             break;
12229         default:
12230             TCU_FAIL("Invalid enum");
12231         }
12232 
12233         sprintf(buffer, "%d", alignment);
12234         Utils::replaceToken("ALIGN", position, buffer, source);
12235         Utils::replaceToken("TYPE", position, type_name, source);
12236         Utils::replaceToken("TYPE", position, type_name, source);
12237     }
12238     else
12239     {
12240         switch (stage)
12241         {
12242         case Utils::Shader::FRAGMENT:
12243             source = fs;
12244             break;
12245         case Utils::Shader::GEOMETRY:
12246             source = gs;
12247             break;
12248         case Utils::Shader::TESS_CTRL:
12249             source = tcs;
12250             break;
12251         case Utils::Shader::TESS_EVAL:
12252             source = tes;
12253             break;
12254         case Utils::Shader::VERTEX:
12255             source = vs;
12256             break;
12257         default:
12258             TCU_FAIL("Invalid enum");
12259         }
12260     }
12261 
12262     return source;
12263 }
12264 
12265 /** Checks if stage is supported
12266  *
12267  * @param stage Shader stage
12268  *
12269  * @return true if supported, false otherwise
12270  **/
12271 bool SSBMemberAlignNonPowerOf2Test::isStageSupported(Utils::Shader::STAGES stage)
12272 {
12273     const Functions &gl         = m_context.getRenderContext().getFunctions();
12274     GLint max_supported_buffers = 0;
12275     GLenum pname                = 0;
12276 
12277     switch (stage)
12278     {
12279     case Utils::Shader::COMPUTE:
12280         pname = GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS;
12281         break;
12282     case Utils::Shader::FRAGMENT:
12283         pname = GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS;
12284         break;
12285     case Utils::Shader::GEOMETRY:
12286         pname = GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS;
12287         break;
12288     case Utils::Shader::TESS_CTRL:
12289         pname = GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS;
12290         break;
12291     case Utils::Shader::TESS_EVAL:
12292         pname = GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS;
12293         break;
12294     case Utils::Shader::VERTEX:
12295         pname = GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS;
12296         break;
12297     default:
12298         TCU_FAIL("Invalid enum");
12299     }
12300 
12301     gl.getIntegerv(pname, &max_supported_buffers);
12302     GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
12303 
12304     return 1 <= max_supported_buffers;
12305 }
12306 
12307 /** Constructor
12308  *
12309  * @param context Test framework context
12310  **/
12311 SSBAlignmentTest::SSBAlignmentTest(deqp::Context &context)
12312     : TextureTestBase(context, "ssb_alignment", "Test verifies offset and alignment of ssb buffer")
12313 {
12314 }
12315 
12316 /** Get interface of program
12317  *
12318  * @param ignored
12319  * @param program_interface Interface of program
12320  * @param varying_passthrough Collection of connections between in and out variables
12321  **/
12322 void SSBAlignmentTest::getProgramInterface(GLuint /* test_case_index */, Utils::ProgramInterface &program_interface,
12323                                            Utils::VaryingPassthrough &varying_passthrough)
12324 {
12325     static const Utils::Type vec4 = Utils::Type::vec4;
12326 
12327 #if WRKARD_UNIFORMBLOCKALIGNMENT
12328 
12329     static const GLuint block_align = 16;
12330 
12331 #else /* WRKARD_UNIFORMBLOCKALIGNMENT */
12332 
12333     static const GLuint block_align = 64;
12334 
12335 #endif /* WRKARD_UNIFORMBLOCKALIGNMENT */
12336 
12337     static const GLuint fifth_align = 16;
12338     static const GLuint vec4_stride = 16;
12339     static const GLuint data_stride = vec4_stride * 2; /* one vec4 + one scalar aligned to 16 */
12340 
12341     const GLuint first_offset  = 0;                                                                     /* vec4 at 0 */
12342     const GLuint second_offset = Utils::Type::GetActualOffset(first_offset + vec4_stride, block_align); /* Data at 32 */
12343     const GLuint third_offset =
12344         Utils::Type::GetActualOffset(second_offset + data_stride, block_align); /* Data[2] at 64 */
12345     const GLuint fourth_offset =
12346         Utils::Type::GetActualOffset(third_offset + data_stride * 2, block_align); /* vec4[3] at 96 */
12347     const GLuint fifth_offset =
12348         Utils::Type::GetActualOffset(fourth_offset + vec4_stride * 3, fifth_align); /* vec4[2] at 160 */
12349     const GLuint sixth_offset =
12350         Utils::Type::GetActualOffset(fifth_offset + vec4_stride * 2, block_align); /* Data at 192 */
12351 
12352     Utils::Interface *structure = program_interface.Structure("Data");
12353 
12354     structure->Member("vector", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::vec4,
12355                       false /* normalized */, 0 /* n_array_elements */, Utils::Type::vec4.GetSize(), 0 /* offset */);
12356 
12357     structure->Member("scalar", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::_float,
12358                       false /* normalized */, 0 /* n_array_elements */, Utils::Type::_float.GetSize(),
12359                       Utils::Type::vec4.GetSize() /* offset */);
12360 
12361     /* Prepare Block */
12362     Utils::Interface *vs_buf_Block = program_interface.Block("vs_buf_Block");
12363 
12364     vs_buf_Block->Member("first", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::vec4,
12365                          false /* normalized */, 0 /* n_array_elements */, vec4_stride, first_offset /* offset */);
12366 
12367     vs_buf_Block->Member("second", "", 0 /* expected_component */, 0 /* expected_location */, structure,
12368                          0 /* n_array_elements */, data_stride, second_offset);
12369 
12370     vs_buf_Block->Member("third", "", 0 /* expected_component */, 0 /* expected_location */, structure,
12371                          2 /* n_array_elements */, data_stride, third_offset);
12372 
12373     vs_buf_Block->Member("fourth", "", 0 /* expected_component */, 0 /* expected_location */, vec4,
12374                          false /* normalized */, 3 /* n_array_elements */, vec4_stride, fourth_offset);
12375 
12376     vs_buf_Block->Member("fifth", "layout(align = 16)", 0 /* expected_component */, 0 /* expected_location */, vec4,
12377                          false /* normalized */, 2 /* n_array_elements */, vec4_stride, fifth_offset);
12378 
12379     vs_buf_Block->Member("sixth", "", 0 /* expected_component */, 0 /* expected_location */, structure,
12380                          0 /* n_array_elements */, data_stride, sixth_offset);
12381 
12382     const GLuint stride = calculateStride(*vs_buf_Block);
12383     m_data.resize(stride);
12384     generateData(*vs_buf_Block, 0, m_data);
12385 
12386     Utils::ShaderInterface &vs_si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
12387 
12388 /* Add uniform BLOCK */
12389 #if WRKARD_UNIFORMBLOCKALIGNMENT
12390     vs_si.SSB("vs_buf_block", "layout (std140, binding = BINDING)", 0, 0, vs_buf_Block, 0,
12391               static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
12392 #else  /* WRKARD_UNIFORMBLOCKALIGNMENT */
12393     vs_si.SSB("vs_buf_block", "layout (std140, binding = BINDING, align = 64)", 0, 0, vs_buf_Block, 0,
12394               static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
12395 #endif /* WRKARD_UNIFORMBLOCKALIGNMENT */
12396 
12397     program_interface.CloneVertexInterface(varying_passthrough);
12398 }
12399 
12400 /** Selects if "draw" stages are relevant for test
12401  *
12402  * @param ignored
12403  *
12404  * @return true if all stages support shader storage buffers, false otherwise
12405  **/
12406 bool SSBAlignmentTest::isDrawRelevant(GLuint /* test_case_index */)
12407 {
12408     const Functions &gl         = m_context.getRenderContext().getFunctions();
12409     GLint gs_supported_buffers  = 0;
12410     GLint tcs_supported_buffers = 0;
12411     GLint tes_supported_buffers = 0;
12412     GLint vs_supported_buffers  = 0;
12413 
12414     gl.getIntegerv(GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS, &gs_supported_buffers);
12415     gl.getIntegerv(GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS, &tcs_supported_buffers);
12416     gl.getIntegerv(GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS, &tes_supported_buffers);
12417     gl.getIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &vs_supported_buffers);
12418 
12419     GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
12420 
12421     return ((1 <= gs_supported_buffers) && (1 <= tcs_supported_buffers) && (1 <= tes_supported_buffers) &&
12422             (1 <= vs_supported_buffers));
12423 }
12424 
12425 /** Constructor
12426  *
12427  * @param context Test framework context
12428  **/
12429 VaryingLocationsTest::VaryingLocationsTest(deqp::Context &context)
12430     : TextureTestBase(context, "varying_locations", "Test verifies that input and output locations are respected")
12431 {
12432 }
12433 
12434 /** Constructor
12435  *
12436  * @param context          Test context
12437  * @param test_name        Name of test
12438  * @param test_description Description of test
12439  **/
12440 VaryingLocationsTest::VaryingLocationsTest(deqp::Context &context, const glw::GLchar *test_name,
12441                                            const glw::GLchar *test_description)
12442     : TextureTestBase(context, test_name, test_description)
12443 {
12444 }
12445 
12446 /** Get interface of program
12447  *
12448  * @param test_case_index     Test case
12449  * @param program_interface   Interface of program
12450  * @param varying_passthrough Collection of connections between in and out variables
12451  **/
12452 void VaryingLocationsTest::getProgramInterface(GLuint test_case_index, Utils::ProgramInterface &program_interface,
12453                                                Utils::VaryingPassthrough &varying_passthrough)
12454 {
12455     const Utils::Type type = getType(test_case_index);
12456 
12457     m_first_data = type.GenerateDataPacked();
12458     m_last_data  = type.GenerateDataPacked();
12459 
12460     prepareShaderStage(Utils::Shader::FRAGMENT, type, program_interface, varying_passthrough);
12461     prepareShaderStage(Utils::Shader::GEOMETRY, type, program_interface, varying_passthrough);
12462     prepareShaderStage(Utils::Shader::TESS_CTRL, type, program_interface, varying_passthrough);
12463     prepareShaderStage(Utils::Shader::TESS_EVAL, type, program_interface, varying_passthrough);
12464     prepareShaderStage(Utils::Shader::VERTEX, type, program_interface, varying_passthrough);
12465 }
12466 
12467 /** Get type name
12468  *
12469  * @param test_case_index Index of test case
12470  *
12471  * @return Name of type test in test_case_index
12472  **/
12473 std::string VaryingLocationsTest::getTestCaseName(glw::GLuint test_case_index)
12474 {
12475     return getTypeName(test_case_index);
12476 }
12477 
12478 /** Returns number of types to test
12479  *
12480  * @return Number of types, 34
12481  **/
12482 glw::GLuint VaryingLocationsTest::getTestCaseNumber()
12483 {
12484     return getTypesNumber();
12485 }
12486 
12487 /** Selects if "compute" stage is relevant for test
12488  *
12489  * @param ignored
12490  *
12491  * @return false
12492  **/
12493 bool VaryingLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
12494 {
12495     return false;
12496 }
12497 
12498 /**
12499  *
12500  *
12501  **/
12502 std::string VaryingLocationsTest::prepareGlobals(GLint last_in_loc, GLint last_out_loc)
12503 {
12504     GLchar buffer[16];
12505     std::string globals = "const uint first_input_location  = 0u;\n"
12506                           "const uint first_output_location = 0u;\n"
12507                           "const uint last_input_location   = LAST_INPUTu;\n"
12508                           "const uint last_output_location  = LAST_OUTPUTu;\n";
12509     size_t position     = 100; /* Skip first part */
12510 
12511     sprintf(buffer, "%d", last_in_loc);
12512     Utils::replaceToken("LAST_INPUT", position, buffer, globals);
12513 
12514     sprintf(buffer, "%d", last_out_loc);
12515     Utils::replaceToken("LAST_OUTPUT", position, buffer, globals);
12516 
12517     return globals;
12518 }
12519 
12520 /**
12521  *
12522  **/
12523 void VaryingLocationsTest::prepareShaderStage(Utils::Shader::STAGES stage, const Utils::Type &type,
12524                                               Utils::ProgramInterface &program_interface,
12525                                               Utils::VaryingPassthrough &varying_passthrough)
12526 {
12527     const GLuint array_length  = 1;
12528     const GLuint first_in_loc  = 0;
12529     const GLuint first_out_loc = 0;
12530     const GLuint last_in_loc   = getLastInputLocation(stage, type, array_length, false);
12531     size_t position            = 0;
12532 
12533     const GLchar *prefix_in = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::VARYING_INPUT);
12534 
12535     const GLchar *prefix_out = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::VARYING_OUTPUT);
12536 
12537     const GLchar *qual_first_in  = "layout (location = first_input_location)";
12538     const GLchar *qual_first_out = "layout (location = first_output_location)";
12539     const GLchar *qual_last_in   = "layout (location = last_input_location)";
12540     const GLchar *qual_last_out  = "layout (location = last_output_location)";
12541 
12542     Utils::ShaderInterface &si = program_interface.GetShaderInterface(stage);
12543     const GLuint type_size     = type.GetSize();
12544 
12545     std::string first_in_name  = "PREFIXfirst";
12546     std::string first_out_name = "PREFIXfirst";
12547     std::string last_in_name   = "PREFIXlast";
12548     std::string last_out_name  = "PREFIXlast";
12549 
12550     Utils::replaceToken("PREFIX", position, prefix_in, first_in_name);
12551     position = 0;
12552     Utils::replaceToken("PREFIX", position, prefix_out, first_out_name);
12553     position = 0;
12554     Utils::replaceToken("PREFIX", position, prefix_in, last_in_name);
12555     position = 0;
12556     Utils::replaceToken("PREFIX", position, prefix_out, last_out_name);
12557 
12558     if (Utils::Shader::FRAGMENT == stage)
12559     {
12560         qual_first_in = "layout (location = first_input_location) flat";
12561         qual_last_in  = "layout (location = last_input_location)  flat";
12562     }
12563     if (Utils::Shader::GEOMETRY == stage)
12564     {
12565         qual_first_out = "layout (location = first_output_location) flat";
12566         qual_last_out  = "layout (location = last_output_location)  flat";
12567     }
12568 
12569     Utils::Variable *first_in = si.Input(
12570         first_in_name.c_str(), qual_first_in /* qualifiers */, 0 /* expected_componenet */,
12571         first_in_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */, 0u /* n_array_elements */,
12572         0u /* stride */, 0u /* offset */, (GLvoid *)&m_first_data[0] /* data */, m_first_data.size() /* data_size */);
12573 
12574     Utils::Variable *last_in =
12575         si.Input(last_in_name.c_str(), qual_last_in /* qualifiers */, 0 /* expected_componenet */,
12576                  last_in_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12577                  0u /* n_array_elements */, 0u /* stride */, type_size /* offset */,
12578                  (GLvoid *)&m_last_data[0] /* data */, m_last_data.size() /* data_size */);
12579 
12580     if (Utils::Shader::FRAGMENT != stage)
12581     {
12582         const GLuint last_out_loc = getLastOutputLocation(stage, type, array_length, false);
12583 
12584         Utils::Variable *first_out =
12585             si.Output(first_out_name.c_str(), qual_first_out /* qualifiers */, 0 /* expected_componenet */,
12586                       first_out_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12587                       0u /* n_array_elements */, 0u /* stride */, 0u /* offset */,
12588                       (GLvoid *)&m_first_data[0] /* data */, m_first_data.size() /* data_size */);
12589 
12590         Utils::Variable *last_out = si.Output(
12591             last_out_name.c_str(), qual_last_out /* qualifiers */, 0 /* expected_componenet */,
12592             last_out_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */, 0u /* n_array_elements */,
12593             0u /* stride */, 0u /* offset */, (GLvoid *)&m_last_data[0] /* data */, m_last_data.size() /* data_size */);
12594 
12595         si.m_globals = prepareGlobals(last_in_loc, last_out_loc);
12596 
12597         varying_passthrough.Add(stage, first_in, first_out);
12598         varying_passthrough.Add(stage, last_in, last_out);
12599     }
12600     else
12601     {
12602         /* No outputs for fragment shader, so last_output_location can be 0 */
12603         si.m_globals = prepareGlobals(last_in_loc, 0);
12604     }
12605 }
12606 
12607 /** This test should be run with separable programs
12608  *
12609  * @param ignored
12610  *
12611  * @return true
12612  **/
12613 bool VaryingLocationsTest::useMonolithicProgram(GLuint /* test_case_index */)
12614 {
12615     return false;
12616 }
12617 
12618 /* Constants used by VertexAttribLocationsTest */
12619 const GLuint VertexAttribLocationsTest::m_base_vertex   = 4;
12620 const GLuint VertexAttribLocationsTest::m_base_instance = 2;
12621 const GLuint VertexAttribLocationsTest::m_loc_vertex    = 2;
12622 const GLuint VertexAttribLocationsTest::m_loc_instance  = 5;
12623 const GLuint VertexAttribLocationsTest::m_n_instances   = 4;
12624 
12625 /** Constructor
12626  *
12627  * @param context Test framework context
12628  **/
12629 VertexAttribLocationsTest::VertexAttribLocationsTest(deqp::Context &context)
12630     : TextureTestBase(context, "vertex_attrib_locations",
12631                       "Test verifies that attribute locations are respected by drawing operations")
12632 {
12633 }
12634 
12635 /** Execute proper draw command for test case
12636  *
12637  * @param test_case_index Index of test case
12638  **/
12639 void VertexAttribLocationsTest::executeDrawCall(GLuint test_case_index)
12640 {
12641     const Functions &gl = m_context.getRenderContext().getFunctions();
12642 
12643     switch (test_case_index)
12644     {
12645     case DRAWARRAYS:
12646         gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
12647         GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
12648         break;
12649     case DRAWARRAYSINSTANCED:
12650         gl.drawArraysInstanced(GL_PATCHES, 0 /* first */, 1 /* count */, m_n_instances);
12651         GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArraysInstanced");
12652         break;
12653     case DRAWELEMENTS:
12654         gl.drawElements(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL);
12655         GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElements");
12656         break;
12657     case DRAWELEMENTSBASEVERTEX:
12658         gl.drawElementsBaseVertex(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL, m_base_vertex);
12659         GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsBaseVertex");
12660         break;
12661     case DRAWELEMENTSINSTANCED:
12662         gl.drawElementsInstanced(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL, m_n_instances);
12663         GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsInstanced");
12664         break;
12665     case DRAWELEMENTSINSTANCEDBASEINSTANCE:
12666         gl.drawElementsInstancedBaseInstance(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL, m_n_instances,
12667                                              m_base_instance);
12668         GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsInstancedBaseInstance");
12669         break;
12670     case DRAWELEMENTSINSTANCEDBASEVERTEX:
12671         gl.drawElementsInstancedBaseVertex(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL, m_n_instances,
12672                                            m_base_vertex);
12673         GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsInstancedBaseVertex");
12674         break;
12675     case DRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCE:
12676         gl.drawElementsInstancedBaseVertexBaseInstance(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL,
12677                                                        m_n_instances, m_base_vertex, m_base_instance);
12678         GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsInstancedBaseVertexBaseInstance");
12679         break;
12680     default:
12681         TCU_FAIL("Invalid enum");
12682     }
12683 }
12684 
12685 /** Get interface of program
12686  *
12687  * @param ignored
12688  * @param program_interface   Interface of program
12689  * @param ignored
12690  **/
12691 void VertexAttribLocationsTest::getProgramInterface(GLuint /* test_case_index */,
12692                                                     Utils::ProgramInterface &program_interface,
12693                                                     Utils::VaryingPassthrough & /* varying_passthrough */)
12694 {
12695     Utils::ShaderInterface &si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
12696 
12697     /* Globals */
12698     si.m_globals = "const uint vertex_index_location   = 2;\n"
12699                    "const uint instance_index_location = 5;\n";
12700 
12701     /* Attributes */
12702     si.Input("vertex_index" /* name */, "layout (location = vertex_index_location)" /* qualifiers */,
12703              0 /* expected_componenet */, m_loc_vertex /* expected_location */, Utils::Type::uint /* type */,
12704              GL_FALSE /* normalized */, 0u /* n_array_elements */, 16 /* stride */, 0u /* offset */,
12705              (GLvoid *)0 /* data */, 0 /* data_size */);
12706     si.Input("instance_index" /* name */, "layout (location = instance_index_location)" /* qualifiers */,
12707              0 /* expected_componenet */, m_loc_instance /* expected_location */, Utils::Type::uint /* type */,
12708              GL_FALSE /* normalized */, 0u /* n_array_elements */, 16 /* stride */, 16u /* offset */,
12709              (GLvoid *)0 /* data */, 0 /* data_size */);
12710 }
12711 
12712 /** Get name of test case
12713  *
12714  * @param test_case_index Index of test case
12715  *
12716  * @return Name of test case
12717  **/
12718 std::string VertexAttribLocationsTest::getTestCaseName(glw::GLuint test_case_index)
12719 {
12720     std::string result;
12721 
12722     switch (test_case_index)
12723     {
12724     case DRAWARRAYS:
12725         result = "DrawArrays";
12726         break;
12727     case DRAWARRAYSINSTANCED:
12728         result = "DrawArraysInstanced";
12729         break;
12730     case DRAWELEMENTS:
12731         result = "DrawElements";
12732         break;
12733     case DRAWELEMENTSBASEVERTEX:
12734         result = "DrawElementsBaseVertex";
12735         break;
12736     case DRAWELEMENTSINSTANCED:
12737         result = "DrawElementsInstanced";
12738         break;
12739     case DRAWELEMENTSINSTANCEDBASEINSTANCE:
12740         result = "DrawElementsInstancedBaseInstance";
12741         break;
12742     case DRAWELEMENTSINSTANCEDBASEVERTEX:
12743         result = "DrawElementsInstancedBaseVertex";
12744         break;
12745     case DRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCE:
12746         result = "DrawElementsInstancedBaseVertexBaseInstance";
12747         break;
12748     default:
12749         TCU_FAIL("Invalid enum");
12750     }
12751 
12752     return result;
12753 }
12754 
12755 /** Get number of test cases
12756  *
12757  * @return Number of test cases
12758  **/
12759 GLuint VertexAttribLocationsTest::getTestCaseNumber()
12760 {
12761     return TESTCASES_MAX;
12762 }
12763 
12764 /** Prepare code snippet that will verify in and uniform variables
12765  *
12766  * @param ignored
12767  * @param ignored
12768  * @param stage   Shader stage
12769  *
12770  * @return Code that verify variables
12771  **/
12772 std::string VertexAttribLocationsTest::getVerificationSnippet(GLuint /* test_case_index */,
12773                                                               Utils::ProgramInterface & /* program_interface */,
12774                                                               Utils::Shader::STAGES stage)
12775 {
12776     std::string verification;
12777 
12778     if (Utils::Shader::VERTEX == stage)
12779     {
12780 
12781 #if DEBUG_VERTEX_ATTRIB_LOCATIONS_TEST_VARIABLE
12782 
12783         verification = "if (gl_InstanceID != instance_index)\n"
12784                        "    {\n"
12785                        "        result = 12u;\n"
12786                        "    }\n"
12787                        "    else if (gl_VertexID != vertex_index)\n"
12788                        "    {\n"
12789                        "        result = 11u;\n"
12790                        "    }\n";
12791 
12792 #else
12793 
12794         verification = "if ((gl_VertexID   != vertex_index)  ||\n"
12795                        "        (gl_InstanceID != instance_index) )\n"
12796                        "    {\n"
12797                        "        result = 0u;\n"
12798                        "    }\n";
12799 
12800 #endif
12801     }
12802     else
12803     {
12804         verification = "";
12805     }
12806 
12807     return verification;
12808 }
12809 
12810 /** Selects if "compute" stage is relevant for test
12811  *
12812  * @param ignored
12813  *
12814  * @return false
12815  **/
12816 bool VertexAttribLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
12817 {
12818     return false;
12819 }
12820 
12821 /** Prepare attributes, vertex array object and array buffer
12822  *
12823  * @param ignored
12824  * @param ignored Interface of program
12825  * @param buffer  Array buffer
12826  * @param vao     Vertex array object
12827  **/
12828 void VertexAttribLocationsTest::prepareAttributes(GLuint test_case_index /* test_case_index */,
12829                                                   Utils::ProgramInterface & /* program_interface */,
12830                                                   Utils::Buffer &buffer, Utils::VertexArray &vao)
12831 {
12832     static const GLuint vertex_index_data[8]   = {0, 1, 2, 3, 4, 5, 6, 7};
12833     static const GLuint instance_index_data[8] = {0, 1, 2, 3, 4, 5, 6, 7};
12834 
12835     std::vector<GLuint> buffer_data;
12836     buffer_data.resize(8 + 8); /* vertex_index_data + instance_index_data */
12837 
12838     GLubyte *ptr = (GLubyte *)&buffer_data[0];
12839 
12840     /*
12841      When case index >=2, the test calls glDrawElement*(), such as glDrawElementsBaseVertex(), glDrawElementsInstanced(), glDrawElementsInstancedBaseInstance() and so on,
12842      So we need to change the buffer type as GL_ELEMENT_ARRAY_BUFFER
12843      */
12844     if (test_case_index >= 2)
12845     {
12846         buffer.m_buffer = Utils::Buffer::Element;
12847     }
12848     vao.Bind();
12849     buffer.Bind();
12850 
12851     vao.Attribute(m_loc_vertex /* vertex_index */, Utils::Type::uint, 0 /* array_elements */, false /* normalized */,
12852                   0 /* stride */, 0 /* offset */);
12853 
12854     vao.Attribute(m_loc_instance /* instance_index */, Utils::Type::uint, 0 /* array_elements */,
12855                   false /* normalized */, 0 /* stride */, (GLvoid *)sizeof(vertex_index_data) /* offset */);
12856     // when test_case_index is 5 or 7, the draw call is glDrawElementsInstancedBaseInstance, glDrawElementsInstancedBaseVertexBaseInstance
12857     // the instancecount is 4, the baseinstance is 2, the divisor should be set 2
12858     bool isBaseInstanced = (test_case_index == DRAWELEMENTSINSTANCEDBASEINSTANCE ||
12859                             test_case_index == DRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCE);
12860     vao.Divisor(m_context.getRenderContext().getFunctions() /* gl */, m_loc_instance /* instance_index */,
12861                 isBaseInstanced ? 2 : 1 /* divisor. 1 - advance once per instance */);
12862 
12863     memcpy(ptr + 0, vertex_index_data, sizeof(vertex_index_data));
12864     memcpy(ptr + sizeof(vertex_index_data), instance_index_data, sizeof(instance_index_data));
12865 
12866     buffer.Data(Utils::Buffer::StaticDraw, buffer_data.size() * sizeof(GLuint), ptr);
12867 }
12868 
12869 /** This test should be run with separable programs
12870  *
12871  * @param ignored
12872  *
12873  * @return true
12874  **/
12875 bool VertexAttribLocationsTest::useMonolithicProgram(GLuint /* test_case_index */)
12876 {
12877     return false;
12878 }
12879 
12880 /** Constructor
12881  *
12882  * @param context Test framework context
12883  **/
12884 VaryingArrayLocationsTest::VaryingArrayLocationsTest(deqp::Context &context)
12885     : VaryingLocationsTest(context, "varying_array_locations",
12886                            "Test verifies that input and output locations are respected for arrays")
12887 {
12888 }
12889 
12890 /**
12891  *
12892  **/
12893 void VaryingArrayLocationsTest::prepareShaderStage(Utils::Shader::STAGES stage, const Utils::Type &type,
12894                                                    Utils::ProgramInterface &program_interface,
12895                                                    Utils::VaryingPassthrough &varying_passthrough)
12896 {
12897     const GLuint array_length  = 1u;
12898     const GLuint first_in_loc  = 0;
12899     const GLuint first_out_loc = 0;
12900     const GLuint last_in_loc   = getLastInputLocation(stage, type, array_length, false);
12901     size_t position            = 0;
12902 
12903     const GLchar *prefix_in = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::VARYING_INPUT);
12904 
12905     const GLchar *prefix_out = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::VARYING_OUTPUT);
12906 
12907     const GLchar *qual_first_in  = "layout (location = first_input_location)";
12908     const GLchar *qual_first_out = "layout (location = first_output_location)";
12909     const GLchar *qual_last_in   = "layout (location = last_input_location)";
12910     const GLchar *qual_last_out  = "layout (location = last_output_location)";
12911 
12912     Utils::ShaderInterface &si = program_interface.GetShaderInterface(stage);
12913     const GLuint type_size     = type.GetSize();
12914 
12915     std::string first_in_name  = "PREFIXfirst";
12916     std::string first_out_name = "PREFIXfirst";
12917     std::string last_in_name   = "PREFIXlast";
12918     std::string last_out_name  = "PREFIXlast";
12919 
12920     Utils::replaceToken("PREFIX", position, prefix_in, first_in_name);
12921     position = 0;
12922     Utils::replaceToken("PREFIX", position, prefix_out, first_out_name);
12923     position = 0;
12924     Utils::replaceToken("PREFIX", position, prefix_in, last_in_name);
12925     position = 0;
12926     Utils::replaceToken("PREFIX", position, prefix_out, last_out_name);
12927 
12928     if (Utils::Shader::FRAGMENT == stage)
12929     {
12930         qual_first_in = "layout (location = first_input_location) flat";
12931         qual_last_in  = "layout (location = last_input_location)  flat";
12932     }
12933     if (Utils::Shader::GEOMETRY == stage)
12934     {
12935         qual_first_out = "layout (location = first_output_location) flat";
12936         qual_last_out  = "layout (location = last_output_location)  flat";
12937     }
12938 
12939     Utils::Variable *first_in =
12940         si.Input(first_in_name.c_str(), qual_first_in /* qualifiers */, 0 /* expected_componenet */,
12941                  first_in_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12942                  array_length /* n_array_elements */, 0u /* stride */, 0u /* offset */,
12943                  (GLvoid *)&m_first_data[0] /* data */, m_first_data.size() /* data_size */);
12944 
12945     Utils::Variable *last_in =
12946         si.Input(last_in_name.c_str(), qual_last_in /* qualifiers */, 0 /* expected_componenet */,
12947                  last_in_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12948                  array_length /* n_array_elements */, 0u /* stride */, type_size /* offset */,
12949                  (GLvoid *)&m_last_data[0] /* data */, m_last_data.size() /* data_size */);
12950 
12951     if (Utils::Shader::FRAGMENT != stage)
12952     {
12953         const GLuint last_out_loc = getLastOutputLocation(stage, type, array_length, false);
12954 
12955         Utils::Variable *first_out =
12956             si.Output(first_out_name.c_str(), qual_first_out /* qualifiers */, 0 /* expected_componenet */,
12957                       first_out_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12958                       array_length /* n_array_elements */, 0u /* stride */, 0u /* offset */,
12959                       (GLvoid *)&m_first_data[0] /* data */, m_first_data.size() /* data_size */);
12960 
12961         Utils::Variable *last_out =
12962             si.Output(last_out_name.c_str(), qual_last_out /* qualifiers */, 0 /* expected_componenet */,
12963                       last_out_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12964                       array_length /* n_array_elements */, 0u /* stride */, 0u /* offset */,
12965                       (GLvoid *)&m_last_data[0] /* data */, m_last_data.size() /* data_size */);
12966 
12967         si.m_globals = prepareGlobals(last_in_loc, last_out_loc);
12968 
12969         varying_passthrough.Add(stage, first_in, first_out);
12970         varying_passthrough.Add(stage, last_in, last_out);
12971     }
12972     else
12973     {
12974         /* No outputs for fragment shader, so last_output_location can be 0 */
12975         si.m_globals = prepareGlobals(last_in_loc, 0);
12976     }
12977 }
12978 
12979 /** Constructor
12980  *
12981  * @param context Test framework context
12982  **/
12983 VaryingStructureLocationsTest::VaryingStructureLocationsTest(deqp::Context &context)
12984     : TextureTestBase(context, "varying_structure_locations",
12985                       "Test verifies that locations are respected when structures are used as in and out ")
12986 {
12987 }
12988 
12989 /** Prepare code snippet that will pass in variables to out variables
12990  *
12991  * @param ignored
12992  * @param varying_passthrough Collection of connections between in and out variables
12993  * @param stage               Shader stage
12994  *
12995  * @return Code that pass in variables to next stage
12996  **/
12997 std::string VaryingStructureLocationsTest::getPassSnippet(GLuint /* test_case_index */,
12998                                                           Utils::VaryingPassthrough &varying_passthrough,
12999                                                           Utils::Shader::STAGES stage)
13000 {
13001     std::string result;
13002 
13003     if (Utils::Shader::VERTEX != stage)
13004     {
13005         result = TextureTestBase::getPassSnippet(0, varying_passthrough, stage);
13006     }
13007     else
13008     {
13009         result = "    vs_tcs_output[0].single   = vs_in_single[0];\n"
13010                  "    vs_tcs_output[0].array[0] = vs_in_array[0];\n";
13011     }
13012 
13013     return result;
13014 }
13015 
13016 /** Get interface of program
13017  *
13018  * @param test_case_index     Test case
13019  * @param program_interface   Interface of program
13020  * @param varying_passthrough Collection of connections between in and out variables
13021  **/
13022 void VaryingStructureLocationsTest::getProgramInterface(GLuint test_case_index,
13023                                                         Utils::ProgramInterface &program_interface,
13024                                                         Utils::VaryingPassthrough &varying_passthrough)
13025 {
13026     Utils::ShaderInterface &si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
13027     const Utils::Type type     = getType(test_case_index);
13028 
13029     /* Prepare data */
13030     // We should call GenerateDataPacked() to generate data, which can make sure the data in shader is correct
13031     m_single_data = type.GenerateDataPacked();
13032     m_array_data  = type.GenerateDataPacked();
13033 
13034     m_data.resize(m_single_data.size() + m_array_data.size());
13035     GLubyte *ptr = (GLubyte *)&m_data[0];
13036     memcpy(ptr, &m_single_data[0], m_single_data.size());
13037     memcpy(ptr + m_single_data.size(), &m_array_data[0], m_array_data.size());
13038 
13039     Utils::Interface *structure = program_interface.Structure("Data");
13040 
13041     structure->Member("single", "" /* qualifiers */, 0 /* component */, 0 /* location */, type, false /* normalized */,
13042                       0u /* n_array_elements */, 0u /* stride */, 0u /* offset */);
13043 
13044     // the second struct member 's location should not be 0, it is based on by how many the locations the first struct member consumed.
13045     structure->Member("array", "" /* qualifiers */, 0 /* component */, type.GetLocations() /* location */, type,
13046                       false /* normalized */, 1u /* n_array_elements */, 0u /* stride */, type.GetSize() /* offset */);
13047 
13048     si.Input("vs_in_single", "layout (location = 0)", 0 /* component */, 0 /* location */, type, false /* normalized */,
13049              1u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid *)&m_single_data[0] /* data */,
13050              m_single_data.size() /* data_size */);
13051 
13052     si.Input("vs_in_array", "layout (location = 8)", 0 /* component */, 8 /* location */, type, false /* normalized */,
13053              1u /* n_array_elements */, 0u /* stride */, type.GetSize() /* offset */,
13054              (GLvoid *)&m_array_data[0] /* data */, m_array_data.size() /* data_size */);
13055 
13056     si.Output("vs_tcs_output", "layout (location = 0)", 0 /* component */, 0 /* location */, structure,
13057               1u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid *)&m_data[0] /* data */,
13058               m_data.size() /* data_size */);
13059 
13060     program_interface.CloneVertexInterface(varying_passthrough);
13061 }
13062 
13063 /** Get type name
13064  *
13065  * @param test_case_index Index of test case
13066  *
13067  * @return Name of type test in test_case_index
13068  **/
13069 std::string VaryingStructureLocationsTest::getTestCaseName(glw::GLuint test_case_index)
13070 {
13071     return getTypeName(test_case_index);
13072 }
13073 
13074 /** Returns number of types to test
13075  *
13076  * @return Number of types, 34
13077  **/
13078 glw::GLuint VaryingStructureLocationsTest::getTestCaseNumber()
13079 {
13080     return getTypesNumber();
13081 }
13082 
13083 /** Selects if "compute" stage is relevant for test
13084  *
13085  * @param ignored
13086  *
13087  * @return false
13088  **/
13089 bool VaryingStructureLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
13090 {
13091     return false;
13092 }
13093 
13094 /** This test should be run with separable programs
13095  *
13096  * @param ignored
13097  *
13098  * @return true
13099  **/
13100 bool VaryingStructureLocationsTest::useMonolithicProgram(GLuint /* test_case_index */)
13101 {
13102     return false;
13103 }
13104 
13105 /** Constructor
13106  *
13107  * @param context          Test context
13108  * @param test_name        Name of test
13109  * @param test_description Description of test
13110  **/
13111 VaryingStructureMemberLocationTest::VaryingStructureMemberLocationTest(deqp::Context &context)
13112     : NegativeTestBase(context, "varying_structure_member_location",
13113                        "Test verifies that compiler does not allow location qualifier on member of structure")
13114 {
13115 }
13116 
13117 /** Source for given test case and stage
13118  *
13119  * @param test_case_index Index of test case
13120  * @param stage           Shader stage
13121  *
13122  * @return Shader source
13123  **/
13124 std::string VaryingStructureMemberLocationTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
13125 {
13126     static const GLchar *struct_definition = "struct Data {\n"
13127                                              "    vec4 gohan;\n"
13128 #if DEBUG_NEG_REMOVE_ERROR
13129                                              "    /* layout (location = 4) */ vec4 goten;\n"
13130 #else
13131                                              "    layout (location = 4) vec4 goten;\n"
13132 #endif /* DEBUG_NEG_REMOVE_ERROR */
13133                                              "};\n";
13134     static const GLchar *input_use  = "    result += data.gohan + data.goten;\n";
13135     static const GLchar *input_var  = "in Data dataARRAY;\n";
13136     static const GLchar *output_var = "out Data dataARRAY;\n";
13137     static const GLchar *output_use = "    dataINDEX.gohan = result / 2;\n"
13138                                       "    dataINDEX.goten = result / 4 - dataINDEX.gohan;\n";
13139     static const GLchar *fs         = "#version 430 core\n"
13140                                       "#extension GL_ARB_enhanced_layouts : require\n"
13141                                       "\n"
13142                                       "in  vec4 gs_fs;\n"
13143                                       "out vec4 fs_out;\n"
13144                                       "\n"
13145                                       "void main()\n"
13146                                       "{\n"
13147                                       "    fs_out = gs_fs;\n"
13148                                       "}\n"
13149                                       "\n";
13150     static const GLchar *fs_tested  = "#version 430 core\n"
13151                                       "#extension GL_ARB_enhanced_layouts : require\n"
13152                                       "\n"
13153                                       "STRUCT_DEFINITION"
13154                                       "\n"
13155                                       "VARIABLE_DEFINITION"
13156                                       "\n"
13157                                       "in  vec4 gs_fs;\n"
13158                                       "out vec4 fs_out;\n"
13159                                       "\n"
13160                                       "void main()\n"
13161                                       "{\n"
13162                                       "    vec4 result = gs_fs;\n"
13163                                       "\n"
13164                                       "VARIABLE_USE"
13165                                       "\n"
13166                                       "    fs_out += result;\n"
13167                                       "}\n"
13168                                       "\n";
13169     static const GLchar *gs         = "#version 430 core\n"
13170                                       "#extension GL_ARB_enhanced_layouts : require\n"
13171                                       "\n"
13172                                       "layout(points)                           in;\n"
13173                                       "layout(triangle_strip, max_vertices = 4) out;\n"
13174                                       "\n"
13175                                       "in  vec4 tes_gs[];\n"
13176                                       "out vec4 gs_fs;\n"
13177                                       "\n"
13178                                       "void main()\n"
13179                                       "{\n"
13180                                       "    gs_fs = tes_gs[0];\n"
13181                                       "    gl_Position  = vec4(-1, -1, 0, 1);\n"
13182                                       "    EmitVertex();\n"
13183                                       "    gs_fs = tes_gs[0];\n"
13184                                       "    gl_Position  = vec4(-1, 1, 0, 1);\n"
13185                                       "    EmitVertex();\n"
13186                                       "    gs_fs = tes_gs[0];\n"
13187                                       "    gl_Position  = vec4(1, -1, 0, 1);\n"
13188                                       "    EmitVertex();\n"
13189                                       "    gs_fs = tes_gs[0];\n"
13190                                       "    gl_Position  = vec4(1, 1, 0, 1);\n"
13191                                       "    EmitVertex();\n"
13192                                       "}\n"
13193                                       "\n";
13194     static const GLchar *gs_tested  = "#version 430 core\n"
13195                                       "#extension GL_ARB_enhanced_layouts : require\n"
13196                                       "\n"
13197                                       "layout(points)                           in;\n"
13198                                       "layout(triangle_strip, max_vertices = 4) out;\n"
13199                                       "\n"
13200                                       "STRUCT_DEFINITION"
13201                                       "\n"
13202                                       "VARIABLE_DEFINITION"
13203                                       "\n"
13204                                       "in  vec4 tes_gs[];\n"
13205                                       "out vec4 gs_fs;\n"
13206                                       "\n"
13207                                       "void main()\n"
13208                                       "{\n"
13209                                       "    vec4 result = tes_gs[0];\n"
13210                                       "\n"
13211                                       "VARIABLE_USE"
13212                                       "\n"
13213                                       "    gs_fs = result;\n"
13214                                       "    gl_Position  = vec4(-1, -1, 0, 1);\n"
13215                                       "    EmitVertex();\n"
13216                                       "    gs_fs = result;\n"
13217                                       "    gl_Position  = vec4(-1, 1, 0, 1);\n"
13218                                       "    EmitVertex();\n"
13219                                       "    gs_fs = result;\n"
13220                                       "    gl_Position  = vec4(1, -1, 0, 1);\n"
13221                                       "    EmitVertex();\n"
13222                                       "    gs_fs = result;\n"
13223                                       "    gl_Position  = vec4(1, 1, 0, 1);\n"
13224                                       "    EmitVertex();\n"
13225                                       "}\n"
13226                                       "\n";
13227     static const GLchar *tcs        = "#version 430 core\n"
13228                                       "#extension GL_ARB_enhanced_layouts : require\n"
13229                                       "\n"
13230                                       "layout(vertices = 1) out;\n"
13231                                       "\n"
13232                                       "in  vec4 vs_tcs[];\n"
13233                                       "out vec4 tcs_tes[];\n"
13234                                       "\n"
13235                                       "void main()\n"
13236                                       "{\n"
13237                                       "\n"
13238                                       "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
13239                                       "\n"
13240                                       "    gl_TessLevelOuter[0] = 1.0;\n"
13241                                       "    gl_TessLevelOuter[1] = 1.0;\n"
13242                                       "    gl_TessLevelOuter[2] = 1.0;\n"
13243                                       "    gl_TessLevelOuter[3] = 1.0;\n"
13244                                       "    gl_TessLevelInner[0] = 1.0;\n"
13245                                       "    gl_TessLevelInner[1] = 1.0;\n"
13246                                       "}\n"
13247                                       "\n";
13248     static const GLchar *tcs_tested = "#version 430 core\n"
13249                                       "#extension GL_ARB_enhanced_layouts : require\n"
13250                                       "\n"
13251                                       "layout(vertices = 1) out;\n"
13252                                       "\n"
13253                                       "STRUCT_DEFINITION"
13254                                       "\n"
13255                                       "VARIABLE_DEFINITION"
13256                                       "\n"
13257                                       "in  vec4 vs_tcs[];\n"
13258                                       "out vec4 tcs_tes[];\n"
13259                                       "\n"
13260                                       "void main()\n"
13261                                       "{\n"
13262                                       "    vec4 result = vs_tcs[gl_InvocationID];\n"
13263                                       "\n"
13264                                       "VARIABLE_USE"
13265                                       "\n"
13266                                       "    tcs_tes[gl_InvocationID] = result;\n"
13267                                       "\n"
13268                                       "    gl_TessLevelOuter[0] = 1.0;\n"
13269                                       "    gl_TessLevelOuter[1] = 1.0;\n"
13270                                       "    gl_TessLevelOuter[2] = 1.0;\n"
13271                                       "    gl_TessLevelOuter[3] = 1.0;\n"
13272                                       "    gl_TessLevelInner[0] = 1.0;\n"
13273                                       "    gl_TessLevelInner[1] = 1.0;\n"
13274                                       "}\n"
13275                                       "\n";
13276     static const GLchar *tes        = "#version 430 core\n"
13277                                       "#extension GL_ARB_enhanced_layouts : require\n"
13278                                       "\n"
13279                                       "layout(isolines, point_mode) in;\n"
13280                                       "\n"
13281                                       "in  vec4 tcs_tes[];\n"
13282                                       "out vec4 tes_gs;\n"
13283                                       "\n"
13284                                       "void main()\n"
13285                                       "{\n"
13286                                       "    tes_gs = tcs_tes[0];\n"
13287                                       "}\n"
13288                                       "\n";
13289     static const GLchar *tes_tested = "#version 430 core\n"
13290                                       "#extension GL_ARB_enhanced_layouts : require\n"
13291                                       "\n"
13292                                       "layout(isolines, point_mode) in;\n"
13293                                       "\n"
13294                                       "STRUCT_DEFINITION"
13295                                       "\n"
13296                                       "VARIABLE_DEFINITION"
13297                                       "\n"
13298                                       "in  vec4 tcs_tes[];\n"
13299                                       "out vec4 tes_gs;\n"
13300                                       "\n"
13301                                       "void main()\n"
13302                                       "{\n"
13303                                       "    vec4 result = tcs_tes[0];\n"
13304                                       "\n"
13305                                       "VARIABLE_USE"
13306                                       "\n"
13307                                       "    tes_gs += result;\n"
13308                                       "}\n"
13309                                       "\n";
13310     static const GLchar *vs         = "#version 430 core\n"
13311                                       "#extension GL_ARB_enhanced_layouts : require\n"
13312                                       "\n"
13313                                       "in  vec4 in_vs;\n"
13314                                       "out vec4 vs_tcs;\n"
13315                                       "\n"
13316                                       "void main()\n"
13317                                       "{\n"
13318                                       "    vs_tcs = in_vs;\n"
13319                                       "}\n"
13320                                       "\n";
13321     static const GLchar *vs_tested  = "#version 430 core\n"
13322                                       "#extension GL_ARB_enhanced_layouts : require\n"
13323                                       "\n"
13324                                       "STRUCT_DEFINITION"
13325                                       "\n"
13326                                       "VARIABLE_DEFINITION"
13327                                       "\n"
13328                                       "in  vec4 in_vs;\n"
13329                                       "out vec4 vs_tcs;\n"
13330                                       "\n"
13331                                       "void main()\n"
13332                                       "{\n"
13333                                       "    vec4 result = in_vs;\n"
13334                                       "\n"
13335                                       "VARIABLE_USE"
13336                                       "\n"
13337                                       "    vs_tcs += result;\n"
13338                                       "}\n"
13339                                       "\n";
13340 
13341     std::string source;
13342     testCase &test_case          = m_test_cases[test_case_index];
13343     const GLchar *var_definition = input_var;
13344     const GLchar *var_use        = Utils::Shader::VERTEX == test_case.m_stage ? input_use : "\n";
13345     const GLchar *array          = "";
13346     const GLchar *index          = "";
13347 
13348     if (!test_case.m_is_input)
13349     {
13350         var_definition = output_var;
13351         var_use        = output_use;
13352     }
13353 
13354     if (test_case.m_stage == stage)
13355     {
13356         size_t position = 0;
13357         size_t temp     = 0;
13358 
13359         switch (stage)
13360         {
13361         case Utils::Shader::FRAGMENT:
13362             source = fs_tested;
13363             break;
13364         case Utils::Shader::GEOMETRY:
13365             source = gs_tested;
13366             array  = test_case.m_is_input ? "[]" : "";
13367             index  = test_case.m_is_input ? "[0]" : "";
13368             break;
13369         case Utils::Shader::TESS_CTRL:
13370             source = tcs_tested;
13371             array  = "[]";
13372             index  = "[gl_InvocationID]";
13373             break;
13374         case Utils::Shader::TESS_EVAL:
13375             source = tes_tested;
13376             array  = test_case.m_is_input ? "[]" : "";
13377             index  = test_case.m_is_input ? "[0]" : "";
13378             break;
13379         case Utils::Shader::VERTEX:
13380             source = vs_tested;
13381             break;
13382         default:
13383             TCU_FAIL("Invalid enum");
13384         }
13385 
13386         Utils::replaceToken("STRUCT_DEFINITION", position, struct_definition, source);
13387         temp = position;
13388         Utils::replaceToken("VARIABLE_DEFINITION", position, var_definition, source);
13389         position = temp;
13390         Utils::replaceToken("ARRAY", position, array, source);
13391         Utils::replaceToken("VARIABLE_USE", position, var_use, source);
13392 
13393         Utils::replaceAllTokens("INDEX", index, source);
13394     }
13395     else
13396     {
13397         switch (stage)
13398         {
13399         case Utils::Shader::FRAGMENT:
13400             source = fs;
13401             break;
13402         case Utils::Shader::GEOMETRY:
13403             source = gs;
13404             break;
13405         case Utils::Shader::TESS_CTRL:
13406             source = tcs;
13407             break;
13408         case Utils::Shader::TESS_EVAL:
13409             source = tes;
13410             break;
13411         case Utils::Shader::VERTEX:
13412             source = vs;
13413             break;
13414         default:
13415             TCU_FAIL("Invalid enum");
13416         }
13417     }
13418 
13419     return source;
13420 }
13421 
13422 /** Get description of test case
13423  *
13424  * @param test_case_index Index of test case
13425  *
13426  * @return Test case description
13427  **/
13428 std::string VaryingStructureMemberLocationTest::getTestCaseName(GLuint test_case_index)
13429 {
13430     std::stringstream stream;
13431     testCase &test_case = m_test_cases[test_case_index];
13432 
13433     stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", direction: ";
13434 
13435     if (true == test_case.m_is_input)
13436     {
13437         stream << "input";
13438     }
13439     else
13440     {
13441         stream << "output";
13442     }
13443 
13444     return stream.str();
13445 }
13446 
13447 /** Get number of test cases
13448  *
13449  * @return Number of test cases
13450  **/
13451 GLuint VaryingStructureMemberLocationTest::getTestCaseNumber()
13452 {
13453     return static_cast<GLuint>(m_test_cases.size());
13454 }
13455 
13456 /** Selects if "compute" stage is relevant for test
13457  *
13458  * @param ignored
13459  *
13460  * @return false
13461  **/
13462 bool VaryingStructureMemberLocationTest::isComputeRelevant(GLuint /* test_case_index */)
13463 {
13464     return false;
13465 }
13466 
13467 /** Prepare all test cases
13468  *
13469  **/
13470 void VaryingStructureMemberLocationTest::testInit()
13471 {
13472     for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
13473     {
13474         if (Utils::Shader::COMPUTE == stage)
13475         {
13476             continue;
13477         }
13478 
13479         testCase test_case_in  = {true, (Utils::Shader::STAGES)stage};
13480         testCase test_case_out = {false, (Utils::Shader::STAGES)stage};
13481 
13482         /* It is a compile-time error to declare a struct as a VS input */
13483         if (Utils::Shader::VERTEX != stage)
13484         {
13485             m_test_cases.push_back(test_case_in);
13486         }
13487 
13488         if (Utils::Shader::FRAGMENT != stage)
13489         {
13490             m_test_cases.push_back(test_case_out);
13491         }
13492     }
13493 }
13494 
13495 /** Constructor
13496  *
13497  * @param context Test framework context
13498  **/
13499 VaryingBlockLocationsTest::VaryingBlockLocationsTest(deqp::Context &context)
13500     : TextureTestBase(context, "varying_block_locations",
13501                       "Test verifies that locations are respected when blocks are used as in and out ")
13502 {
13503 }
13504 
13505 /** Prepare code snippet that will pass in variables to out variables
13506  *
13507  * @param ignored
13508  * @param varying_passthrough Collection of connections between in and out variables
13509  * @param stage               Shader stage
13510  *
13511  * @return Code that pass in variables to next stage
13512  **/
13513 std::string VaryingBlockLocationsTest::getPassSnippet(GLuint /* test_case_index */,
13514                                                       Utils::VaryingPassthrough &varying_passthrough,
13515                                                       Utils::Shader::STAGES stage)
13516 {
13517     std::string result;
13518 
13519     if (Utils::Shader::VERTEX != stage)
13520     {
13521         result = TextureTestBase::getPassSnippet(0, varying_passthrough, stage);
13522     }
13523     else
13524     {
13525         result = "vs_tcs_block.third  = vs_in_third;\n"
13526                  "    vs_tcs_block.fourth = vs_in_fourth;\n"
13527                  "    vs_tcs_block.fifth  = vs_in_fifth;\n";
13528     }
13529 
13530     return result;
13531 }
13532 
13533 /** Get interface of program
13534  *
13535  * @param ignored
13536  * @param program_interface   Interface of program
13537  * @param varying_passthrough Collection of connections between in and out variables
13538  **/
13539 void VaryingBlockLocationsTest::getProgramInterface(GLuint /* test_case_index */,
13540                                                     Utils::ProgramInterface &program_interface,
13541                                                     Utils::VaryingPassthrough &varying_passthrough)
13542 {
13543     Utils::ShaderInterface &si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
13544     const Utils::Type vec4     = Utils::Type::vec4;
13545 
13546     /* Prepare data */
13547     m_third_data  = vec4.GenerateData();
13548     m_fourth_data = vec4.GenerateData();
13549     m_fifth_data  = vec4.GenerateData();
13550 
13551     /* Memory layout is different from location layout */
13552     const GLuint fifth_offset  = 0u;
13553     const GLuint third_offset  = static_cast<GLuint>(fifth_offset + m_fifth_data.size());
13554     const GLuint fourth_offset = static_cast<GLuint>(third_offset + m_fourth_data.size());
13555 
13556     m_data.resize(fourth_offset + m_fourth_data.size());
13557     GLubyte *ptr = (GLubyte *)&m_data[0];
13558     memcpy(ptr + third_offset, &m_third_data[0], m_third_data.size());
13559     memcpy(ptr + fourth_offset, &m_fourth_data[0], m_fourth_data.size());
13560     memcpy(ptr + fifth_offset, &m_fifth_data[0], m_fifth_data.size());
13561 
13562     Utils::Interface *block = program_interface.Block("vs_tcs_Block");
13563 
13564     block->Member("fifth", "" /* qualifiers */, 0 /* component */, 4 /* location */, vec4, false /* normalized */,
13565                   0u /* n_array_elements */, 0u /* stride */, fifth_offset /* offset */);
13566 
13567     block->Member("third", "layout (location = 2)" /* qualifiers */, 0 /* component */, 2 /* location */, vec4,
13568                   false /* normalized */, 0u /* n_array_elements */, 0u /* stride */, third_offset /* offset */);
13569 
13570     block->Member("fourth", "" /* qualifiers */, 0 /* component */, 3 /* location */, vec4, false /* normalized */,
13571                   0u /* n_array_elements */, 0u /* stride */, fourth_offset /* offset */);
13572 
13573     si.Output("vs_tcs_block", "layout (location = 4)", 0 /* component */, 4 /* location */, block,
13574               0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid *)&m_data[0] /* data */,
13575               m_data.size() /* data_size */);
13576 
13577     si.Input("vs_in_third", "layout (location = 0)", 0 /* component */, 0 /* location */, vec4, false /* normalized */,
13578              0u /* n_array_elements */, 0u /* stride */, third_offset /* offset */,
13579              (GLvoid *)&m_third_data[0] /* data */, m_third_data.size() /* data_size */);
13580 
13581     si.Input("vs_in_fourth", "layout (location = 1)", 0 /* component */, 1 /* location */, vec4, false /* normalized */,
13582              0u /* n_array_elements */, 0u /* stride */, fourth_offset /* offset */,
13583              (GLvoid *)&m_fourth_data[0] /* data */, m_fourth_data.size() /* data_size */);
13584 
13585     si.Input("vs_in_fifth", "layout (location = 2)", 0 /* component */, 2 /* location */, vec4, false /* normalized */,
13586              0u /* n_array_elements */, 0u /* stride */, fifth_offset /* offset */,
13587              (GLvoid *)&m_fifth_data[0] /* data */, m_fifth_data.size() /* data_size */);
13588 
13589     program_interface.CloneVertexInterface(varying_passthrough);
13590 }
13591 
13592 /** Selects if "compute" stage is relevant for test
13593  *
13594  * @param ignored
13595  *
13596  * @return false
13597  **/
13598 bool VaryingBlockLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
13599 {
13600     return false;
13601 }
13602 
13603 /** This test should be run with separable programs
13604  *
13605  * @param ignored
13606  *
13607  * @return true
13608  **/
13609 bool VaryingBlockLocationsTest::useMonolithicProgram(GLuint /* test_case_index */)
13610 {
13611     return false;
13612 }
13613 
13614 /** Constructor
13615  *
13616  * @param context Test framework context
13617  **/
13618 VaryingBlockMemberLocationsTest::VaryingBlockMemberLocationsTest(deqp::Context &context)
13619     : NegativeTestBase(
13620           context, "varying_block_member_locations",
13621           "Test verifies that compilation error is reported when not all members of block are qualified with location")
13622 {
13623 }
13624 
13625 /** Source for given test case and stage
13626  *
13627  * @param test_case_index Index of test case
13628  * @param stage           Shader stage
13629  *
13630  * @return Shader source
13631  **/
13632 std::string VaryingBlockMemberLocationsTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
13633 {
13634     static const GLchar *block_definition_all = "Goku {\n"
13635                                                 "    layout (location = 2) vec4 gohan;\n"
13636                                                 "    layout (location = 4) vec4 goten;\n"
13637                                                 "    layout (location = 6) vec4 chichi;\n"
13638                                                 "} gokuARRAY;\n";
13639     static const GLchar *block_definition_one = "Goku {\n"
13640                                                 "    vec4 gohan;\n"
13641 #if DEBUG_NEG_REMOVE_ERROR
13642                                                 "    /* layout (location = 4) */ vec4 goten;\n"
13643 #else
13644                                                 "    layout (location = 4) vec4 goten;\n"
13645 #endif /* DEBUG_NEG_REMOVE_ERROR */
13646                                                 "    vec4 chichi;\n"
13647                                                 "} gokuARRAY;\n";
13648     static const GLchar *input_use  = "    result += gokuINDEX.gohan + gokuINDEX.goten + gokuINDEX.chichi;\n";
13649     static const GLchar *output_use = "    gokuINDEX.gohan  = result / 2;\n"
13650                                       "    gokuINDEX.goten  = result / 4 - gokuINDEX.gohan;\n"
13651                                       "    gokuINDEX.chichi = result / 8 - gokuINDEX.goten;\n";
13652     static const GLchar *fs         = "#version 430 core\n"
13653                                       "#extension GL_ARB_enhanced_layouts : require\n"
13654                                       "\n"
13655                                       "in  vec4 gs_fs;\n"
13656                                       "out vec4 fs_out;\n"
13657                                       "\n"
13658                                       "void main()\n"
13659                                       "{\n"
13660                                       "    fs_out = gs_fs;\n"
13661                                       "}\n"
13662                                       "\n";
13663     static const GLchar *fs_tested  = "#version 430 core\n"
13664                                       "#extension GL_ARB_enhanced_layouts : require\n"
13665                                       "\n"
13666                                       "DIRECTION BLOCK_DEFINITION"
13667                                       "\n"
13668                                       "in  vec4 gs_fs;\n"
13669                                       "out vec4 fs_out;\n"
13670                                       "\n"
13671                                       "void main()\n"
13672                                       "{\n"
13673                                       "    vec4 result = gs_fs;\n"
13674                                       "\n"
13675                                       "VARIABLE_USE"
13676                                       "\n"
13677                                       "    fs_out = result;\n"
13678                                       "}\n"
13679                                       "\n";
13680     static const GLchar *gs         = "#version 430 core\n"
13681                                       "#extension GL_ARB_enhanced_layouts : require\n"
13682                                       "\n"
13683                                       "layout(points)                           in;\n"
13684                                       "layout(triangle_strip, max_vertices = 4) out;\n"
13685                                       "\n"
13686                                       "in  vec4 tes_gs[];\n"
13687                                       "out vec4 gs_fs;\n"
13688                                       "\n"
13689                                       "void main()\n"
13690                                       "{\n"
13691                                       "    gs_fs = tes_gs[0];\n"
13692                                       "    gl_Position  = vec4(-1, -1, 0, 1);\n"
13693                                       "    EmitVertex();\n"
13694                                       "    gs_fs = tes_gs[0];\n"
13695                                       "    gl_Position  = vec4(-1, 1, 0, 1);\n"
13696                                       "    EmitVertex();\n"
13697                                       "    gs_fs = tes_gs[0];\n"
13698                                       "    gl_Position  = vec4(1, -1, 0, 1);\n"
13699                                       "    EmitVertex();\n"
13700                                       "    gs_fs = tes_gs[0];\n"
13701                                       "    gl_Position  = vec4(1, 1, 0, 1);\n"
13702                                       "    EmitVertex();\n"
13703                                       "}\n"
13704                                       "\n";
13705     static const GLchar *gs_tested  = "#version 430 core\n"
13706                                       "#extension GL_ARB_enhanced_layouts : require\n"
13707                                       "\n"
13708                                       "layout(points)                           in;\n"
13709                                       "layout(triangle_strip, max_vertices = 4) out;\n"
13710                                       "\n"
13711                                       "DIRECTION BLOCK_DEFINITION"
13712                                       "\n"
13713                                       "in  vec4 tes_gs[];\n"
13714                                       "out vec4 gs_fs;\n"
13715                                       "\n"
13716                                       "void main()\n"
13717                                       "{\n"
13718                                       "    vec4 result = tes_gs[0];\n"
13719                                       "\n"
13720                                       "VARIABLE_USE"
13721                                       "\n"
13722                                       "    gs_fs = result;\n"
13723                                       "    gl_Position  = vec4(-1, -1, 0, 1);\n"
13724                                       "    EmitVertex();\n"
13725                                       "    gs_fs = result;\n"
13726                                       "    gl_Position  = vec4(-1, 1, 0, 1);\n"
13727                                       "    EmitVertex();\n"
13728                                       "    gs_fs = result;\n"
13729                                       "    gl_Position  = vec4(1, -1, 0, 1);\n"
13730                                       "    EmitVertex();\n"
13731                                       "    gs_fs = result;\n"
13732                                       "    gl_Position  = vec4(1, 1, 0, 1);\n"
13733                                       "    EmitVertex();\n"
13734                                       "}\n"
13735                                       "\n";
13736     static const GLchar *tcs        = "#version 430 core\n"
13737                                       "#extension GL_ARB_enhanced_layouts : require\n"
13738                                       "\n"
13739                                       "layout(vertices = 1) out;\n"
13740                                       "\n"
13741                                       "in  vec4 vs_tcs[];\n"
13742                                       "out vec4 tcs_tes[];\n"
13743                                       "\n"
13744                                       "void main()\n"
13745                                       "{\n"
13746                                       "\n"
13747                                       "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
13748                                       "\n"
13749                                       "    gl_TessLevelOuter[0] = 1.0;\n"
13750                                       "    gl_TessLevelOuter[1] = 1.0;\n"
13751                                       "    gl_TessLevelOuter[2] = 1.0;\n"
13752                                       "    gl_TessLevelOuter[3] = 1.0;\n"
13753                                       "    gl_TessLevelInner[0] = 1.0;\n"
13754                                       "    gl_TessLevelInner[1] = 1.0;\n"
13755                                       "}\n"
13756                                       "\n";
13757     static const GLchar *tcs_tested = "#version 430 core\n"
13758                                       "#extension GL_ARB_enhanced_layouts : require\n"
13759                                       "\n"
13760                                       "layout(vertices = 1) out;\n"
13761                                       "\n"
13762                                       "DIRECTION BLOCK_DEFINITION"
13763                                       "\n"
13764                                       "in  vec4 vs_tcs[];\n"
13765                                       "out vec4 tcs_tes[];\n"
13766                                       "\n"
13767                                       "void main()\n"
13768                                       "{\n"
13769                                       "    vec4 result = vs_tcs[gl_InvocationID];\n"
13770                                       "\n"
13771                                       "VARIABLE_USE"
13772                                       "\n"
13773                                       "    tcs_tes[gl_InvocationID] = result;\n"
13774                                       "\n"
13775                                       "    gl_TessLevelOuter[0] = 1.0;\n"
13776                                       "    gl_TessLevelOuter[1] = 1.0;\n"
13777                                       "    gl_TessLevelOuter[2] = 1.0;\n"
13778                                       "    gl_TessLevelOuter[3] = 1.0;\n"
13779                                       "    gl_TessLevelInner[0] = 1.0;\n"
13780                                       "    gl_TessLevelInner[1] = 1.0;\n"
13781                                       "}\n"
13782                                       "\n";
13783     static const GLchar *tes        = "#version 430 core\n"
13784                                       "#extension GL_ARB_enhanced_layouts : require\n"
13785                                       "\n"
13786                                       "layout(isolines, point_mode) in;\n"
13787                                       "\n"
13788                                       "in  vec4 tcs_tes[];\n"
13789                                       "out vec4 tes_gs;\n"
13790                                       "\n"
13791                                       "void main()\n"
13792                                       "{\n"
13793                                       "    tes_gs = tcs_tes[0];\n"
13794                                       "}\n"
13795                                       "\n";
13796     static const GLchar *tes_tested = "#version 430 core\n"
13797                                       "#extension GL_ARB_enhanced_layouts : require\n"
13798                                       "\n"
13799                                       "layout(isolines, point_mode) in;\n"
13800                                       "\n"
13801                                       "DIRECTION BLOCK_DEFINITION"
13802                                       "\n"
13803                                       "in  vec4 tcs_tes[];\n"
13804                                       "out vec4 tes_gs;\n"
13805                                       "\n"
13806                                       "void main()\n"
13807                                       "{\n"
13808                                       "    vec4 result = tcs_tes[0];\n"
13809                                       "\n"
13810                                       "VARIABLE_USE"
13811                                       "\n"
13812                                       "    tes_gs = result;\n"
13813                                       "}\n"
13814                                       "\n";
13815     static const GLchar *vs         = "#version 430 core\n"
13816                                       "#extension GL_ARB_enhanced_layouts : require\n"
13817                                       "\n"
13818                                       "in  vec4 in_vs;\n"
13819                                       "out vec4 vs_tcs;\n"
13820                                       "\n"
13821                                       "void main()\n"
13822                                       "{\n"
13823                                       "    vs_tcs = in_vs;\n"
13824                                       "}\n"
13825                                       "\n";
13826     static const GLchar *vs_tested  = "#version 430 core\n"
13827                                       "#extension GL_ARB_enhanced_layouts : require\n"
13828                                       "\n"
13829                                       "DIRECTION BLOCK_DEFINITION"
13830                                       "\n"
13831                                       "in  vec4 in_vs;\n"
13832                                       "out vec4 vs_tcs;\n"
13833                                       "\n"
13834                                       "void main()\n"
13835                                       "{\n"
13836                                       "    vec4 result = in_vs;\n"
13837                                       "\n"
13838                                       "VARIABLE_USE"
13839                                       "\n"
13840                                       "    vs_tcs = result;\n"
13841                                       "}\n"
13842                                       "\n";
13843 
13844     const GLchar *array     = "";
13845     const GLchar *direction = "in";
13846     const GLchar *index     = "";
13847     std::string source;
13848     testCase &test_case      = m_test_cases[test_case_index];
13849     const GLchar *var_use    = Utils::Shader::VERTEX == test_case.m_stage ? input_use : "\n";
13850     const GLchar *definition = test_case.m_qualify_all ? block_definition_all : block_definition_one;
13851 
13852     if (!test_case.m_is_input)
13853     {
13854         direction = "out";
13855         var_use   = output_use;
13856     }
13857 
13858     if (test_case.m_stage == stage)
13859     {
13860         size_t position = 0;
13861         size_t temp     = 0;
13862 
13863         switch (stage)
13864         {
13865         case Utils::Shader::FRAGMENT:
13866             source = fs_tested;
13867             break;
13868         case Utils::Shader::GEOMETRY:
13869             source = gs_tested;
13870             array  = test_case.m_is_input ? "[]" : "";
13871             index  = test_case.m_is_input ? "[0]" : "";
13872             break;
13873         case Utils::Shader::TESS_CTRL:
13874             source = tcs_tested;
13875             array  = "[]";
13876             index  = "[gl_InvocationID]";
13877             break;
13878         case Utils::Shader::TESS_EVAL:
13879             source = tes_tested;
13880             array  = test_case.m_is_input ? "[]" : "";
13881             index  = test_case.m_is_input ? "[0]" : "";
13882             break;
13883         case Utils::Shader::VERTEX:
13884             source = vs_tested;
13885             break;
13886         default:
13887             TCU_FAIL("Invalid enum");
13888         }
13889 
13890         Utils::replaceToken("DIRECTION", position, direction, source);
13891         temp = position;
13892         Utils::replaceToken("BLOCK_DEFINITION", position, definition, source);
13893         position = temp;
13894         Utils::replaceToken("ARRAY", position, array, source);
13895         Utils::replaceToken("VARIABLE_USE", position, var_use, source);
13896 
13897         Utils::replaceAllTokens("INDEX", index, source);
13898     }
13899     else
13900     {
13901         switch (stage)
13902         {
13903         case Utils::Shader::FRAGMENT:
13904             source = fs;
13905             break;
13906         case Utils::Shader::GEOMETRY:
13907             source = gs;
13908             break;
13909         case Utils::Shader::TESS_CTRL:
13910             source = tcs;
13911             break;
13912         case Utils::Shader::TESS_EVAL:
13913             source = tes;
13914             break;
13915         case Utils::Shader::VERTEX:
13916             source = vs;
13917             break;
13918         default:
13919             TCU_FAIL("Invalid enum");
13920         }
13921     }
13922 
13923     return source;
13924 }
13925 
13926 /** Get description of test case
13927  *
13928  * @param test_case_index Index of test case
13929  *
13930  * @return Test case description
13931  **/
13932 std::string VaryingBlockMemberLocationsTest::getTestCaseName(GLuint test_case_index)
13933 {
13934     std::stringstream stream;
13935     testCase &test_case = m_test_cases[test_case_index];
13936 
13937     stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", direction: ";
13938 
13939     if (true == test_case.m_is_input)
13940     {
13941         stream << "input";
13942     }
13943     else
13944     {
13945         stream << "output";
13946     }
13947 
13948     if (true == test_case.m_qualify_all)
13949     {
13950         stream << ", all members qualified";
13951     }
13952     else
13953     {
13954         stream << ", not all members qualified";
13955     }
13956 
13957     return stream.str();
13958 }
13959 
13960 /** Get number of test cases
13961  *
13962  * @return Number of test cases
13963  **/
13964 GLuint VaryingBlockMemberLocationsTest::getTestCaseNumber()
13965 {
13966     return static_cast<GLuint>(m_test_cases.size());
13967 }
13968 
13969 /** Selects if "compute" stage is relevant for test
13970  *
13971  * @param ignored
13972  *
13973  * @return false
13974  **/
13975 bool VaryingBlockMemberLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
13976 {
13977     return false;
13978 }
13979 
13980 /** Selects if compilation failure is expected result
13981  *
13982  * @param test_case_index Index of test case
13983  *
13984  * @return false when all members are qualified, true otherwise
13985  **/
13986 bool VaryingBlockMemberLocationsTest::isFailureExpected(GLuint test_case_index)
13987 {
13988     return (true != m_test_cases[test_case_index].m_qualify_all);
13989 }
13990 
13991 /** Prepare all test cases
13992  *
13993  **/
13994 void VaryingBlockMemberLocationsTest::testInit()
13995 {
13996     for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
13997     {
13998         if (Utils::Shader::COMPUTE == stage)
13999         {
14000             continue;
14001         }
14002 
14003         testCase test_case_in_all  = {true, true, (Utils::Shader::STAGES)stage};
14004         testCase test_case_in_one  = {true, false, (Utils::Shader::STAGES)stage};
14005         testCase test_case_out_all = {false, true, (Utils::Shader::STAGES)stage};
14006         testCase test_case_out_one = {false, false, (Utils::Shader::STAGES)stage};
14007 
14008         if (Utils::Shader::VERTEX != stage)
14009         {
14010             m_test_cases.push_back(test_case_in_all);
14011             m_test_cases.push_back(test_case_in_one);
14012         }
14013 
14014         if (Utils::Shader::FRAGMENT != stage)
14015         {
14016             m_test_cases.push_back(test_case_out_all);
14017             m_test_cases.push_back(test_case_out_one);
14018         }
14019     }
14020 }
14021 
14022 /** Constructor
14023  *
14024  * @param context Test framework context
14025  **/
14026 VaryingBlockAutomaticMemberLocationsTest::VaryingBlockAutomaticMemberLocationsTest(deqp::Context &context)
14027     : NegativeTestBase(
14028           context, "varying_block_automatic_member_locations",
14029           "Test verifies that compiler assigns subsequent locations to block members, even if this causes errors")
14030 {
14031 }
14032 
14033 /** Source for given test case and stage
14034  *
14035  * @param test_case_index Index of test case
14036  * @param stage           Shader stage
14037  *
14038  * @return Shader source
14039  **/
14040 std::string VaryingBlockAutomaticMemberLocationsTest::getShaderSource(GLuint test_case_index,
14041                                                                       Utils::Shader::STAGES stage)
14042 {
14043     static const GLchar *block_definition = "layout (location = 2) DIRECTION DBZ {\n"
14044                                             "    vec4 goku;\n"
14045                                             "    vec4 gohan[4];\n"
14046                                             "    vec4 goten;\n"
14047 #if DEBUG_NEG_REMOVE_ERROR
14048                                             "    /* layout (location = 1) */ vec4 chichi;\n"
14049 #else
14050                                             "    layout (location = 1) vec4 chichi;\n"
14051 #endif /* DEBUG_NEG_REMOVE_ERROR */
14052                                             "    vec4 pan;\n"
14053                                             "} dbzARRAY;\n";
14054     static const GLchar *input_use  = "    result += dbzINDEX.goku + dbzINDEX.gohan[0] + dbzINDEX.gohan[1] + "
14055                                       "dbzINDEX.gohan[3] + dbzINDEX.gohan[2] + dbzINDEX.goten + dbzINDEX.chichi + "
14056                                       "dbzINDEX.pan;\n";
14057     static const GLchar *output_use = "    dbzINDEX.goku     = result;\n"
14058                                       "    dbzINDEX.gohan[0] = result / 2;\n"
14059                                       "    dbzINDEX.gohan[1] = result / 2.25;\n"
14060                                       "    dbzINDEX.gohan[2] = result / 2.5;\n"
14061                                       "    dbzINDEX.gohan[3] = result / 2.75;\n"
14062                                       "    dbzINDEX.goten    = result / 4  - dbzINDEX.gohan[0] - dbzINDEX.gohan[1] - "
14063                                       "dbzINDEX.gohan[2] - dbzINDEX.gohan[3];\n"
14064                                       "    dbzINDEX.chichi   = result / 8  - dbzINDEX.goten;\n"
14065                                       "    dbzINDEX.pan      = result / 16 - dbzINDEX.chichi;\n";
14066     static const GLchar *fs         = "#version 430 core\n"
14067                                       "#extension GL_ARB_enhanced_layouts : require\n"
14068                                       "\n"
14069                                       "in  vec4 gs_fs;\n"
14070                                       "out vec4 fs_out;\n"
14071                                       "\n"
14072                                       "void main()\n"
14073                                       "{\n"
14074                                       "    fs_out = gs_fs;\n"
14075                                       "}\n"
14076                                       "\n";
14077     static const GLchar *fs_tested  = "#version 430 core\n"
14078                                       "#extension GL_ARB_enhanced_layouts : require\n"
14079                                       "\n"
14080                                       "BLOCK_DEFINITION"
14081                                       "\n"
14082                                       "in  vec4 gs_fs;\n"
14083                                       "out vec4 fs_out;\n"
14084                                       "\n"
14085                                       "void main()\n"
14086                                       "{\n"
14087                                       "    vec4 result = gs_fs;\n"
14088                                       "\n"
14089                                       "VARIABLE_USE"
14090                                       "\n"
14091                                       "    fs_out += result;\n"
14092                                       "}\n"
14093                                       "\n";
14094     static const GLchar *gs         = "#version 430 core\n"
14095                                       "#extension GL_ARB_enhanced_layouts : require\n"
14096                                       "\n"
14097                                       "layout(points)                           in;\n"
14098                                       "layout(triangle_strip, max_vertices = 4) out;\n"
14099                                       "\n"
14100                                       "in  vec4 tes_gs[];\n"
14101                                       "out vec4 gs_fs;\n"
14102                                       "\n"
14103                                       "void main()\n"
14104                                       "{\n"
14105                                       "    gs_fs = tes_gs[0];\n"
14106                                       "    gl_Position  = vec4(-1, -1, 0, 1);\n"
14107                                       "    EmitVertex();\n"
14108                                       "    gs_fs = tes_gs[0];\n"
14109                                       "    gl_Position  = vec4(-1, 1, 0, 1);\n"
14110                                       "    EmitVertex();\n"
14111                                       "    gs_fs = tes_gs[0];\n"
14112                                       "    gl_Position  = vec4(1, -1, 0, 1);\n"
14113                                       "    EmitVertex();\n"
14114                                       "    gs_fs = tes_gs[0];\n"
14115                                       "    gl_Position  = vec4(1, 1, 0, 1);\n"
14116                                       "    EmitVertex();\n"
14117                                       "}\n"
14118                                       "\n";
14119     static const GLchar *gs_tested  = "#version 430 core\n"
14120                                       "#extension GL_ARB_enhanced_layouts : require\n"
14121                                       "\n"
14122                                       "layout(points)                           in;\n"
14123                                       "layout(triangle_strip, max_vertices = 4) out;\n"
14124                                       "\n"
14125                                       "BLOCK_DEFINITION"
14126                                       "\n"
14127                                       "in  vec4 tes_gs[];\n"
14128                                       "out vec4 gs_fs;\n"
14129                                       "\n"
14130                                       "void main()\n"
14131                                       "{\n"
14132                                       "    vec4 result = tes_gs[0];\n"
14133                                       "\n"
14134                                       "VARIABLE_USE"
14135                                       "\n"
14136                                       "    gs_fs = result;\n"
14137                                       "    gl_Position  = vec4(-1, -1, 0, 1);\n"
14138                                       "    EmitVertex();\n"
14139                                       "    gs_fs = result;\n"
14140                                       "    gl_Position  = vec4(-1, 1, 0, 1);\n"
14141                                       "    EmitVertex();\n"
14142                                       "    gs_fs = result;\n"
14143                                       "    gl_Position  = vec4(1, -1, 0, 1);\n"
14144                                       "    EmitVertex();\n"
14145                                       "    gs_fs = result;\n"
14146                                       "    gl_Position  = vec4(1, 1, 0, 1);\n"
14147                                       "    EmitVertex();\n"
14148                                       "}\n"
14149                                       "\n";
14150     static const GLchar *tcs        = "#version 430 core\n"
14151                                       "#extension GL_ARB_enhanced_layouts : require\n"
14152                                       "\n"
14153                                       "layout(vertices = 1) out;\n"
14154                                       "\n"
14155                                       "in  vec4 vs_tcs[];\n"
14156                                       "out vec4 tcs_tes[];\n"
14157                                       "\n"
14158                                       "void main()\n"
14159                                       "{\n"
14160                                       "\n"
14161                                       "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
14162                                       "\n"
14163                                       "    gl_TessLevelOuter[0] = 1.0;\n"
14164                                       "    gl_TessLevelOuter[1] = 1.0;\n"
14165                                       "    gl_TessLevelOuter[2] = 1.0;\n"
14166                                       "    gl_TessLevelOuter[3] = 1.0;\n"
14167                                       "    gl_TessLevelInner[0] = 1.0;\n"
14168                                       "    gl_TessLevelInner[1] = 1.0;\n"
14169                                       "}\n"
14170                                       "\n";
14171     static const GLchar *tcs_tested = "#version 430 core\n"
14172                                       "#extension GL_ARB_enhanced_layouts : require\n"
14173                                       "\n"
14174                                       "layout(vertices = 1) out;\n"
14175                                       "\n"
14176                                       "BLOCK_DEFINITION"
14177                                       "\n"
14178                                       "in  vec4 vs_tcs[];\n"
14179                                       "out vec4 tcs_tes[];\n"
14180                                       "\n"
14181                                       "void main()\n"
14182                                       "{\n"
14183                                       "    vec4 result = vs_tcs[gl_InvocationID];\n"
14184                                       "\n"
14185                                       "VARIABLE_USE"
14186                                       "\n"
14187                                       "    tcs_tes[gl_InvocationID] = result;\n"
14188                                       "\n"
14189                                       "    gl_TessLevelOuter[0] = 1.0;\n"
14190                                       "    gl_TessLevelOuter[1] = 1.0;\n"
14191                                       "    gl_TessLevelOuter[2] = 1.0;\n"
14192                                       "    gl_TessLevelOuter[3] = 1.0;\n"
14193                                       "    gl_TessLevelInner[0] = 1.0;\n"
14194                                       "    gl_TessLevelInner[1] = 1.0;\n"
14195                                       "}\n"
14196                                       "\n";
14197     static const GLchar *tes        = "#version 430 core\n"
14198                                       "#extension GL_ARB_enhanced_layouts : require\n"
14199                                       "\n"
14200                                       "layout(isolines, point_mode) in;\n"
14201                                       "\n"
14202                                       "in  vec4 tcs_tes[];\n"
14203                                       "out vec4 tes_gs;\n"
14204                                       "\n"
14205                                       "void main()\n"
14206                                       "{\n"
14207                                       "    tes_gs = tcs_tes[0];\n"
14208                                       "}\n"
14209                                       "\n";
14210     static const GLchar *tes_tested = "#version 430 core\n"
14211                                       "#extension GL_ARB_enhanced_layouts : require\n"
14212                                       "\n"
14213                                       "layout(isolines, point_mode) in;\n"
14214                                       "\n"
14215                                       "BLOCK_DEFINITION"
14216                                       "\n"
14217                                       "in  vec4 tcs_tes[];\n"
14218                                       "out vec4 tes_gs;\n"
14219                                       "\n"
14220                                       "void main()\n"
14221                                       "{\n"
14222                                       "    vec4 result = tcs_tes[0];\n"
14223                                       "\n"
14224                                       "VARIABLE_USE"
14225                                       "\n"
14226                                       "    tes_gs += result;\n"
14227                                       "}\n"
14228                                       "\n";
14229     static const GLchar *vs         = "#version 430 core\n"
14230                                       "#extension GL_ARB_enhanced_layouts : require\n"
14231                                       "\n"
14232                                       "in  vec4 in_vs;\n"
14233                                       "out vec4 vs_tcs;\n"
14234                                       "\n"
14235                                       "void main()\n"
14236                                       "{\n"
14237                                       "    vs_tcs = in_vs;\n"
14238                                       "}\n"
14239                                       "\n";
14240     static const GLchar *vs_tested  = "#version 430 core\n"
14241                                       "#extension GL_ARB_enhanced_layouts : require\n"
14242                                       "\n"
14243                                       "BLOCK_DEFINITION"
14244                                       "\n"
14245                                       "in  vec4 in_vs;\n"
14246                                       "out vec4 vs_tcs;\n"
14247                                       "\n"
14248                                       "void main()\n"
14249                                       "{\n"
14250                                       "    vec4 result = in_vs;\n"
14251                                       "\n"
14252                                       "VARIABLE_USE"
14253                                       "\n"
14254                                       "    vs_tcs += result;\n"
14255                                       "}\n"
14256                                       "\n";
14257 
14258     const GLchar *array     = "";
14259     const GLchar *direction = "in";
14260     const GLchar *index     = "";
14261     std::string source;
14262     testCase &test_case   = m_test_cases[test_case_index];
14263     const GLchar *var_use = Utils::Shader::VERTEX == test_case.m_stage ? input_use : "\n";
14264 
14265     if (!test_case.m_is_input)
14266     {
14267         direction = "out";
14268         var_use   = output_use;
14269     }
14270 
14271     if (test_case.m_stage == stage)
14272     {
14273         size_t position = 0;
14274 
14275         switch (stage)
14276         {
14277         case Utils::Shader::FRAGMENT:
14278             source = fs_tested;
14279             break;
14280         case Utils::Shader::GEOMETRY:
14281             source = gs_tested;
14282             array  = test_case.m_is_input ? "[]" : "";
14283             index  = test_case.m_is_input ? "[0]" : "";
14284             break;
14285         case Utils::Shader::TESS_CTRL:
14286             source = tcs_tested;
14287             array  = "[]";
14288             index  = "[gl_InvocationID]";
14289             break;
14290         case Utils::Shader::TESS_EVAL:
14291             source = tes_tested;
14292             array  = test_case.m_is_input ? "[]" : "";
14293             index  = test_case.m_is_input ? "[0]" : "";
14294             break;
14295         case Utils::Shader::VERTEX:
14296             source = vs_tested;
14297             break;
14298         default:
14299             TCU_FAIL("Invalid enum");
14300         }
14301 
14302         Utils::replaceToken("BLOCK_DEFINITION", position, block_definition, source);
14303         position = 0;
14304         Utils::replaceToken("DIRECTION", position, direction, source);
14305         Utils::replaceToken("ARRAY", position, array, source);
14306         Utils::replaceToken("VARIABLE_USE", position, var_use, source);
14307 
14308         Utils::replaceAllTokens("INDEX", index, source);
14309     }
14310     else
14311     {
14312         switch (stage)
14313         {
14314         case Utils::Shader::FRAGMENT:
14315             source = fs;
14316             break;
14317         case Utils::Shader::GEOMETRY:
14318             source = gs;
14319             break;
14320         case Utils::Shader::TESS_CTRL:
14321             source = tcs;
14322             break;
14323         case Utils::Shader::TESS_EVAL:
14324             source = tes;
14325             break;
14326         case Utils::Shader::VERTEX:
14327             source = vs;
14328             break;
14329         default:
14330             TCU_FAIL("Invalid enum");
14331         }
14332     }
14333 
14334     return source;
14335 }
14336 
14337 /** Get description of test case
14338  *
14339  * @param test_case_index Index of test case
14340  *
14341  * @return Test case description
14342  **/
14343 std::string VaryingBlockAutomaticMemberLocationsTest::getTestCaseName(GLuint test_case_index)
14344 {
14345     std::stringstream stream;
14346     testCase &test_case = m_test_cases[test_case_index];
14347 
14348     stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", direction: ";
14349 
14350     if (true == test_case.m_is_input)
14351     {
14352         stream << "input";
14353     }
14354     else
14355     {
14356         stream << "output";
14357     }
14358 
14359     return stream.str();
14360 }
14361 
14362 /** Get number of test cases
14363  *
14364  * @return Number of test cases
14365  **/
14366 GLuint VaryingBlockAutomaticMemberLocationsTest::getTestCaseNumber()
14367 {
14368     return static_cast<GLuint>(m_test_cases.size());
14369 }
14370 
14371 /** Selects if "compute" stage is relevant for test
14372  *
14373  * @param ignored
14374  *
14375  * @return false
14376  **/
14377 bool VaryingBlockAutomaticMemberLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
14378 {
14379     return false;
14380 }
14381 
14382 /** Prepare all test cases
14383  *
14384  **/
14385 void VaryingBlockAutomaticMemberLocationsTest::testInit()
14386 {
14387     for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
14388     {
14389         if (Utils::Shader::COMPUTE == stage)
14390         {
14391             continue;
14392         }
14393 
14394         testCase test_case_in  = {true, (Utils::Shader::STAGES)stage};
14395         testCase test_case_out = {false, (Utils::Shader::STAGES)stage};
14396 
14397         if (Utils::Shader::VERTEX != stage)
14398         {
14399             m_test_cases.push_back(test_case_in);
14400         }
14401 
14402         if (Utils::Shader::FRAGMENT != stage)
14403         {
14404             m_test_cases.push_back(test_case_out);
14405         }
14406     }
14407 }
14408 
14409 /** Constructor
14410  *
14411  * @param context Test framework context
14412  **/
14413 VaryingLocationLimitTest::VaryingLocationLimitTest(deqp::Context &context)
14414     : NegativeTestBase(context, "varying_location_limit",
14415                        "Test verifies that compiler reports error when location qualifier exceeds limits")
14416 {
14417 }
14418 
14419 /** Source for given test case and stage
14420  *
14421  * @param test_case_index Index of test case
14422  * @param stage           Shader stage
14423  *
14424  * @return Shader source
14425  **/
14426 std::string VaryingLocationLimitTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
14427 {
14428 #if DEBUG_NEG_REMOVE_ERROR
14429     static const GLchar *var_definition = "layout (location = LAST /* + 1 */) FLAT DIRECTION TYPE gokuARRAY;\n";
14430 #else
14431     static const GLchar *var_definition = "layout (location = LAST + 1) FLAT DIRECTION TYPE gokuARRAY;\n";
14432 #endif /* DEBUG_NEG_REMOVE_ERROR */
14433     static const GLchar *input_use  = "    if (TYPE(0) == gokuINDEX)\n"
14434                                       "    {\n"
14435                                       "        result += vec4(1, 0.5, 0.25, 0.125);\n"
14436                                       "    }\n";
14437     static const GLchar *output_use = "    gokuINDEX = TYPE(0);\n"
14438                                       "    if (vec4(0) == result)\n"
14439                                       "    {\n"
14440                                       "        gokuINDEX = TYPE(1);\n"
14441                                       "    }\n";
14442     static const GLchar *fs         = "#version 430 core\n"
14443                                       "#extension GL_ARB_enhanced_layouts : require\n"
14444                                       "\n"
14445                                       "in  vec4 gs_fs;\n"
14446                                       "out vec4 fs_out;\n"
14447                                       "\n"
14448                                       "void main()\n"
14449                                       "{\n"
14450                                       "    fs_out = gs_fs;\n"
14451                                       "}\n"
14452                                       "\n";
14453     static const GLchar *fs_tested  = "#version 430 core\n"
14454                                       "#extension GL_ARB_enhanced_layouts : require\n"
14455                                       "\n"
14456                                       "VAR_DEFINITION"
14457                                       "\n"
14458                                       "in  vec4 gs_fs;\n"
14459                                       "out vec4 fs_out;\n"
14460                                       "\n"
14461                                       "void main()\n"
14462                                       "{\n"
14463                                       "    vec4 result = gs_fs;\n"
14464                                       "\n"
14465                                       "VARIABLE_USE"
14466                                       "\n"
14467                                       "    fs_out += result;\n"
14468                                       "}\n"
14469                                       "\n";
14470     static const GLchar *gs         = "#version 430 core\n"
14471                                       "#extension GL_ARB_enhanced_layouts : require\n"
14472                                       "\n"
14473                                       "layout(points)                           in;\n"
14474                                       "layout(triangle_strip, max_vertices = 4) out;\n"
14475                                       "\n"
14476                                       "PERVERTEX" /* Separable programs require explicit declaration of gl_PerVertex */
14477                               "in  vec4 tes_gs[];\n"
14478                               "out vec4 gs_fs;\n"
14479                               "\n"
14480                               "void main()\n"
14481                               "{\n"
14482                               "    gs_fs = tes_gs[0];\n"
14483                               "    gl_Position  = vec4(-1, -1, 0, 1);\n"
14484                               "    EmitVertex();\n"
14485                               "    gs_fs = tes_gs[0];\n"
14486                               "    gl_Position  = vec4(-1, 1, 0, 1);\n"
14487                               "    EmitVertex();\n"
14488                               "    gs_fs = tes_gs[0];\n"
14489                               "    gl_Position  = vec4(1, -1, 0, 1);\n"
14490                               "    EmitVertex();\n"
14491                               "    gs_fs = tes_gs[0];\n"
14492                               "    gl_Position  = vec4(1, 1, 0, 1);\n"
14493                               "    EmitVertex();\n"
14494                               "}\n"
14495                               "\n";
14496     static const GLchar *gs_tested = "#version 430 core\n"
14497                                      "#extension GL_ARB_enhanced_layouts : require\n"
14498                                      "\n"
14499                                      "layout(points)                           in;\n"
14500                                      "layout(triangle_strip, max_vertices = 4) out;\n"
14501                                      "\n"
14502                                      "PERVERTEX" /* Separable programs require explicit declaration of gl_PerVertex */
14503                                      "VAR_DEFINITION"
14504                                      "\n"
14505                                      "in  vec4 tes_gs[];\n"
14506                                      "out vec4 gs_fs;\n"
14507                                      "\n"
14508                                      "void main()\n"
14509                                      "{\n"
14510                                      "    vec4 result = tes_gs[0];\n"
14511                                      "\n"
14512                                      "VARIABLE_USE"
14513                                      "\n"
14514                                      "    gs_fs = result;\n"
14515                                      "    gl_Position  = vec4(-1, -1, 0, 1);\n"
14516                                      "    EmitVertex();\n"
14517                                      "    gs_fs = result;\n"
14518                                      "    gl_Position  = vec4(-1, 1, 0, 1);\n"
14519                                      "    EmitVertex();\n"
14520                                      "    gs_fs = result;\n"
14521                                      "    gl_Position  = vec4(1, -1, 0, 1);\n"
14522                                      "    EmitVertex();\n"
14523                                      "    gs_fs = result;\n"
14524                                      "    gl_Position  = vec4(1, 1, 0, 1);\n"
14525                                      "    EmitVertex();\n"
14526                                      "}\n"
14527                                      "\n";
14528     static const GLchar *tcs        = "#version 430 core\n"
14529                                       "#extension GL_ARB_enhanced_layouts : require\n"
14530                                       "\n"
14531                                       "layout(vertices = 1) out;\n"
14532                                       "\n"
14533                                       "in  vec4 vs_tcs[];\n"
14534                                       "out vec4 tcs_tes[];\n"
14535                                       "\n"
14536                                       "void main()\n"
14537                                       "{\n"
14538                                       "\n"
14539                                       "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
14540                                       "\n"
14541                                       "    gl_TessLevelOuter[0] = 1.0;\n"
14542                                       "    gl_TessLevelOuter[1] = 1.0;\n"
14543                                       "    gl_TessLevelOuter[2] = 1.0;\n"
14544                                       "    gl_TessLevelOuter[3] = 1.0;\n"
14545                                       "    gl_TessLevelInner[0] = 1.0;\n"
14546                                       "    gl_TessLevelInner[1] = 1.0;\n"
14547                                       "}\n"
14548                                       "\n";
14549     static const GLchar *tcs_tested = "#version 430 core\n"
14550                                       "#extension GL_ARB_enhanced_layouts : require\n"
14551                                       "\n"
14552                                       "layout(vertices = 1) out;\n"
14553                                       "\n"
14554                                       "VAR_DEFINITION"
14555                                       "\n"
14556                                       "in  vec4 vs_tcs[];\n"
14557                                       "out vec4 tcs_tes[];\n"
14558                                       "\n"
14559                                       "void main()\n"
14560                                       "{\n"
14561                                       "    vec4 result = vs_tcs[gl_InvocationID];\n"
14562                                       "\n"
14563                                       "VARIABLE_USE"
14564                                       "\n"
14565                                       "    tcs_tes[gl_InvocationID] = result;\n"
14566                                       "\n"
14567                                       "    gl_TessLevelOuter[0] = 1.0;\n"
14568                                       "    gl_TessLevelOuter[1] = 1.0;\n"
14569                                       "    gl_TessLevelOuter[2] = 1.0;\n"
14570                                       "    gl_TessLevelOuter[3] = 1.0;\n"
14571                                       "    gl_TessLevelInner[0] = 1.0;\n"
14572                                       "    gl_TessLevelInner[1] = 1.0;\n"
14573                                       "}\n"
14574                                       "\n";
14575     static const GLchar *tes        = "#version 430 core\n"
14576                                       "#extension GL_ARB_enhanced_layouts : require\n"
14577                                       "\n"
14578                                       "layout(isolines, point_mode) in;\n"
14579                                       "\n"
14580                                       "in  vec4 tcs_tes[];\n"
14581                                       "out vec4 tes_gs;\n"
14582                                       "\n"
14583                                       "void main()\n"
14584                                       "{\n"
14585                                       "    tes_gs = tcs_tes[0];\n"
14586                                       "}\n"
14587                                       "\n";
14588     static const GLchar *tes_tested = "#version 430 core\n"
14589                                       "#extension GL_ARB_enhanced_layouts : require\n"
14590                                       "\n"
14591                                       "layout(isolines, point_mode) in;\n"
14592                                       "\n"
14593                                       "VAR_DEFINITION"
14594                                       "\n"
14595                                       "in  vec4 tcs_tes[];\n"
14596                                       "out vec4 tes_gs;\n"
14597                                       "\n"
14598                                       "void main()\n"
14599                                       "{\n"
14600                                       "    vec4 result = tcs_tes[0];\n"
14601                                       "\n"
14602                                       "VARIABLE_USE"
14603                                       "\n"
14604                                       "    tes_gs += result;\n"
14605                                       "}\n"
14606                                       "\n";
14607     static const GLchar *vs         = "#version 430 core\n"
14608                                       "#extension GL_ARB_enhanced_layouts : require\n"
14609                                       "\n"
14610                                       "in  vec4 in_vs;\n"
14611                                       "out vec4 vs_tcs;\n"
14612                                       "\n"
14613                                       "void main()\n"
14614                                       "{\n"
14615                                       "    vs_tcs = in_vs;\n"
14616                                       "}\n"
14617                                       "\n";
14618     static const GLchar *vs_tested  = "#version 430 core\n"
14619                                       "#extension GL_ARB_enhanced_layouts : require\n"
14620                                       "\n"
14621                                       "VAR_DEFINITION"
14622                                       "\n"
14623                                       "in  vec4 in_vs;\n"
14624                                       "out vec4 vs_tcs;\n"
14625                                       "\n"
14626                                       "void main()\n"
14627                                       "{\n"
14628                                       "    vec4 result = in_vs;\n"
14629                                       "\n"
14630                                       "VARIABLE_USE"
14631                                       "\n"
14632                                       "    vs_tcs += result;\n"
14633                                       "}\n"
14634                                       "\n";
14635 
14636     std::string source;
14637     testCase &test_case      = m_test_cases[test_case_index];
14638     size_t position          = 0;
14639     const GLchar *per_vertex = !isSeparable(test_case_index) ? "" :
14640                                                                "out gl_PerVertex {\n"
14641                                                                "vec4 gl_Position;\n"
14642                                                                "};\n"
14643                                                                "\n";
14644 
14645     if (test_case.m_stage == stage)
14646     {
14647         const GLchar *array = "";
14648         GLchar buffer[16];
14649         const GLchar *direction          = "in ";
14650         const GLchar *flat               = "";
14651         const GLchar *index              = "";
14652         GLuint last                      = getLastInputLocation(stage, test_case.m_type, 0, true);
14653         const GLchar *type_name          = test_case.m_type.GetGLSLTypeName();
14654         Utils::Variable::STORAGE storage = Utils::Variable::VARYING_INPUT;
14655         const GLchar *var_use            = input_use;
14656 
14657         if (false == test_case.m_is_input)
14658         {
14659             direction = "out";
14660             last      = getLastOutputLocation(stage, test_case.m_type, 0, true);
14661             storage   = Utils::Variable::VARYING_OUTPUT;
14662             var_use   = output_use;
14663         }
14664 
14665         if (isFlatRequired(stage, test_case.m_type, storage))
14666         {
14667             flat = "flat";
14668         }
14669 
14670         sprintf(buffer, "%d", last);
14671 
14672         switch (stage)
14673         {
14674         case Utils::Shader::FRAGMENT:
14675             source = fs_tested;
14676             break;
14677         case Utils::Shader::GEOMETRY:
14678             source = gs_tested;
14679             array  = test_case.m_is_input ? "[]" : "";
14680             index  = test_case.m_is_input ? "[0]" : "";
14681             Utils::replaceToken("PERVERTEX", position, per_vertex, source);
14682             break;
14683         case Utils::Shader::TESS_CTRL:
14684             source = tcs_tested;
14685             array  = "[]";
14686             index  = "[gl_InvocationID]";
14687             break;
14688         case Utils::Shader::TESS_EVAL:
14689             source = tes_tested;
14690             array  = test_case.m_is_input ? "[]" : "";
14691             index  = test_case.m_is_input ? "[0]" : "";
14692             break;
14693         case Utils::Shader::VERTEX:
14694             source = vs_tested;
14695             break;
14696         default:
14697             TCU_FAIL("Invalid enum");
14698         }
14699 
14700         Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
14701         position = 0;
14702         Utils::replaceToken("LAST", position, buffer, source);
14703         Utils::replaceToken("FLAT", position, flat, source);
14704         Utils::replaceToken("DIRECTION", position, direction, source);
14705         Utils::replaceToken("ARRAY", position, array, source);
14706         Utils::replaceToken("VARIABLE_USE", position, var_use, source);
14707 
14708         Utils::replaceAllTokens("TYPE", type_name, source);
14709         Utils::replaceAllTokens("INDEX", index, source);
14710     }
14711     else
14712     {
14713         switch (stage)
14714         {
14715         case Utils::Shader::FRAGMENT:
14716             source = fs;
14717             break;
14718         case Utils::Shader::GEOMETRY:
14719             source = gs;
14720             Utils::replaceToken("PERVERTEX", position, per_vertex, source);
14721             break;
14722         case Utils::Shader::TESS_CTRL:
14723             source = tcs;
14724             break;
14725         case Utils::Shader::TESS_EVAL:
14726             source = tes;
14727             break;
14728         case Utils::Shader::VERTEX:
14729             source = vs;
14730             break;
14731         default:
14732             TCU_FAIL("Invalid enum");
14733         }
14734     }
14735 
14736     return source;
14737 }
14738 
14739 /** Get description of test case
14740  *
14741  * @param test_case_index Index of test case
14742  *
14743  * @return Test case description
14744  **/
14745 std::string VaryingLocationLimitTest::getTestCaseName(GLuint test_case_index)
14746 {
14747     std::stringstream stream;
14748     testCase &test_case = m_test_cases[test_case_index];
14749 
14750     stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
14751            << " type: " << test_case.m_type.GetGLSLTypeName() << ", direction: ";
14752 
14753     if (true == test_case.m_is_input)
14754     {
14755         stream << "input";
14756     }
14757     else
14758     {
14759         stream << "output";
14760     }
14761 
14762     return stream.str();
14763 }
14764 
14765 /** Get number of test cases
14766  *
14767  * @return Number of test cases
14768  **/
14769 GLuint VaryingLocationLimitTest::getTestCaseNumber()
14770 {
14771     return static_cast<GLuint>(m_test_cases.size());
14772 }
14773 
14774 /** Selects if "compute" stage is relevant for test
14775  *
14776  * @param ignored
14777  *
14778  * @return false
14779  **/
14780 bool VaryingLocationLimitTest::isComputeRelevant(GLuint /* test_case_index */)
14781 {
14782     return false;
14783 }
14784 
14785 /** Selects if the test case should use a separable program
14786  *
14787  * @param test_case_index Id of test case
14788  *
14789  * @return whether the test should use separable programs or not
14790  **/
14791 bool VaryingLocationLimitTest::isSeparable(const GLuint test_case_index)
14792 {
14793     const testCase &test_case = m_test_cases[test_case_index];
14794 
14795     return test_case.m_is_input && test_case.m_stage != Utils::Shader::VERTEX;
14796 }
14797 
14798 /** Prepare all test cases
14799  *
14800  **/
14801 void VaryingLocationLimitTest::testInit()
14802 {
14803     const GLuint n_types = getTypesNumber();
14804 
14805     for (GLuint i = 0; i < n_types; ++i)
14806     {
14807         const Utils::Type &type = getType(i);
14808 
14809         for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
14810         {
14811             if (Utils::Shader::COMPUTE == stage)
14812             {
14813                 continue;
14814             }
14815 
14816             testCase test_case_in  = {true, type, (Utils::Shader::STAGES)stage};
14817             testCase test_case_out = {false, type, (Utils::Shader::STAGES)stage};
14818 
14819             m_test_cases.push_back(test_case_in);
14820 
14821             if (Utils::Shader::FRAGMENT != stage)
14822             {
14823                 m_test_cases.push_back(test_case_out);
14824             }
14825         }
14826     }
14827 }
14828 
14829 /** Constructor
14830  *
14831  * @param context Test framework context
14832  **/
14833 VaryingComponentsTest::VaryingComponentsTest(deqp::Context &context)
14834     : VaryingLocationsTest(context, "varying_components",
14835                            "Test verifies that input and output components are respected")
14836 {
14837 }
14838 
14839 /** Constructor
14840  *
14841  * @param context          Test framework context
14842  * @param test_name        Name of test
14843  * @param test_description Description of test
14844  **/
14845 VaryingComponentsTest::VaryingComponentsTest(deqp::Context &context, const glw::GLchar *test_name,
14846                                              const glw::GLchar *test_description)
14847     : VaryingLocationsTest(context, test_name, test_description)
14848 {
14849 }
14850 
14851 /** Get interface of program
14852  *
14853  * @param test_case_index     Test case
14854  * @param program_interface   Interface of program
14855  * @param varying_passthrough Collection of connections between in and out variables
14856  **/
14857 void VaryingComponentsTest::getProgramInterface(GLuint test_case_index, Utils::ProgramInterface &program_interface,
14858                                                 Utils::VaryingPassthrough &varying_passthrough)
14859 {
14860     GLuint array_length           = getArrayLength();
14861     const testCase &test_case     = m_test_cases[test_case_index];
14862     const Utils::Type vector_type = Utils::Type::GetType(test_case.m_type, 1, 4);
14863     Utils::ShaderInterface si     = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
14864 
14865     /* Zero means no array, however we still need at least 1 slot of data */
14866     if (0 == array_length)
14867     {
14868         array_length += 1;
14869     }
14870 
14871     /* Generate data */
14872     const std::vector<GLubyte> &data = vector_type.GenerateDataPacked();
14873     const size_t data_size           = data.size();
14874 
14875     /* Prepare data for variables */
14876     m_data.resize(array_length * data_size);
14877 
14878     GLubyte *dst       = &m_data[0];
14879     const GLubyte *src = &data[0];
14880 
14881     for (GLuint i = 0; i < array_length; ++i)
14882     {
14883         memcpy(dst + data_size * i, src, data_size);
14884     }
14885 
14886     /* Prepare interface for each stage */
14887     prepareShaderStage(Utils::Shader::FRAGMENT, vector_type, program_interface, test_case, varying_passthrough);
14888     prepareShaderStage(Utils::Shader::GEOMETRY, vector_type, program_interface, test_case, varying_passthrough);
14889     prepareShaderStage(Utils::Shader::TESS_CTRL, vector_type, program_interface, test_case, varying_passthrough);
14890     prepareShaderStage(Utils::Shader::TESS_EVAL, vector_type, program_interface, test_case, varying_passthrough);
14891     prepareShaderStage(Utils::Shader::VERTEX, vector_type, program_interface, test_case, varying_passthrough);
14892 }
14893 
14894 /** Get type name
14895  *
14896  * @param test_case_index Index of test case
14897  *
14898  * @return Name of type test in test_case_index
14899  **/
14900 std::string VaryingComponentsTest::getTestCaseName(glw::GLuint test_case_index)
14901 {
14902     std::string name;
14903 
14904     const testCase &test_case = m_test_cases[test_case_index];
14905 
14906     name = "Type: ";
14907 
14908     switch (test_case.m_type)
14909     {
14910     case Utils::Type::Double:
14911         name.append(Utils::Type::_double.GetGLSLTypeName());
14912         break;
14913     case Utils::Type::Float:
14914         name.append(Utils::Type::_float.GetGLSLTypeName());
14915         break;
14916     case Utils::Type::Int:
14917         name.append(Utils::Type::_int.GetGLSLTypeName());
14918         break;
14919     case Utils::Type::Uint:
14920         name.append(Utils::Type::uint.GetGLSLTypeName());
14921         break;
14922     }
14923 
14924     name.append(", layout: ");
14925 
14926     switch (test_case.m_layout)
14927     {
14928     case G64VEC2:
14929         name.append("G64VEC2");
14930         break;
14931     case G64SCALAR_G64SCALAR:
14932         name.append("G64SCALAR_G64SCALAR");
14933         break;
14934     case GVEC4:
14935         name.append("GVEC4");
14936         break;
14937     case SCALAR_GVEC3:
14938         name.append("SCALAR_GVEC3");
14939         break;
14940     case GVEC3_SCALAR:
14941         name.append("GVEC3_SCALAR");
14942         break;
14943     case GVEC2_GVEC2:
14944         name.append("GVEC2_GVEC2");
14945         break;
14946     case GVEC2_SCALAR_SCALAR:
14947         name.append("GVEC2_SCALAR_SCALAR");
14948         break;
14949     case SCALAR_GVEC2_SCALAR:
14950         name.append("SCALAR_GVEC2_SCALAR");
14951         break;
14952     case SCALAR_SCALAR_GVEC2:
14953         name.append("SCALAR_SCALAR_GVEC2");
14954         break;
14955     case SCALAR_SCALAR_SCALAR_SCALAR:
14956         name.append("SCALAR_SCALAR_SCALAR_SCALAR");
14957         break;
14958     }
14959 
14960     return name;
14961 }
14962 
14963 /** Returns number of types to test
14964  *
14965  * @return Number of types
14966  **/
14967 glw::GLuint VaryingComponentsTest::getTestCaseNumber()
14968 {
14969     return static_cast<GLuint>(m_test_cases.size());
14970 }
14971 
14972 /* Prepare test cases */
14973 void VaryingComponentsTest::testInit()
14974 {
14975     m_test_cases.push_back(testCase(G64VEC2, Utils::Type::Double));
14976     m_test_cases.push_back(testCase(G64SCALAR_G64SCALAR, Utils::Type::Double));
14977 
14978     m_test_cases.push_back(testCase(GVEC4, Utils::Type::Float));
14979     m_test_cases.push_back(testCase(SCALAR_GVEC3, Utils::Type::Float));
14980     m_test_cases.push_back(testCase(GVEC3_SCALAR, Utils::Type::Float));
14981     m_test_cases.push_back(testCase(GVEC2_GVEC2, Utils::Type::Float));
14982     m_test_cases.push_back(testCase(GVEC2_SCALAR_SCALAR, Utils::Type::Float));
14983     m_test_cases.push_back(testCase(SCALAR_GVEC2_SCALAR, Utils::Type::Float));
14984     m_test_cases.push_back(testCase(SCALAR_SCALAR_GVEC2, Utils::Type::Float));
14985     m_test_cases.push_back(testCase(SCALAR_SCALAR_SCALAR_SCALAR, Utils::Type::Float));
14986 
14987     m_test_cases.push_back(testCase(GVEC4, Utils::Type::Int));
14988     m_test_cases.push_back(testCase(SCALAR_GVEC3, Utils::Type::Int));
14989     m_test_cases.push_back(testCase(GVEC3_SCALAR, Utils::Type::Int));
14990     m_test_cases.push_back(testCase(GVEC2_GVEC2, Utils::Type::Int));
14991     m_test_cases.push_back(testCase(GVEC2_SCALAR_SCALAR, Utils::Type::Int));
14992     m_test_cases.push_back(testCase(SCALAR_GVEC2_SCALAR, Utils::Type::Int));
14993     m_test_cases.push_back(testCase(SCALAR_SCALAR_GVEC2, Utils::Type::Int));
14994     m_test_cases.push_back(testCase(SCALAR_SCALAR_SCALAR_SCALAR, Utils::Type::Int));
14995 
14996     m_test_cases.push_back(testCase(GVEC4, Utils::Type::Uint));
14997     m_test_cases.push_back(testCase(SCALAR_GVEC3, Utils::Type::Uint));
14998     m_test_cases.push_back(testCase(GVEC3_SCALAR, Utils::Type::Uint));
14999     m_test_cases.push_back(testCase(GVEC2_GVEC2, Utils::Type::Uint));
15000     m_test_cases.push_back(testCase(GVEC2_SCALAR_SCALAR, Utils::Type::Uint));
15001     m_test_cases.push_back(testCase(SCALAR_GVEC2_SCALAR, Utils::Type::Uint));
15002     m_test_cases.push_back(testCase(SCALAR_SCALAR_GVEC2, Utils::Type::Uint));
15003     m_test_cases.push_back(testCase(SCALAR_SCALAR_SCALAR_SCALAR, Utils::Type::Uint));
15004 }
15005 
15006 /** Inform that test use components
15007  *
15008  * @param ignored
15009  *
15010  * @return true
15011  **/
15012 bool VaryingComponentsTest::useComponentQualifier(glw::GLuint /* test_case_index */)
15013 {
15014     return true;
15015 }
15016 
15017 /** Get length of arrays that should be used during test
15018  *
15019  * @return 0u - no array at all
15020  **/
15021 GLuint VaryingComponentsTest::getArrayLength()
15022 {
15023     return 0;
15024 }
15025 
15026 std::string VaryingComponentsTest::prepareGlobals(GLuint last_in_location, GLuint last_out_location)
15027 {
15028     std::string globals = VaryingLocationsTest::prepareGlobals(last_in_location, last_out_location);
15029 
15030     globals.append("const uint comp_x = 0u;\n"
15031                    "const uint comp_y = 1u;\n"
15032                    "const uint comp_z = 2u;\n"
15033                    "const uint comp_w = 3u;\n");
15034 
15035     return globals;
15036 }
15037 
15038 /**
15039  *
15040  **/
15041 std::string VaryingComponentsTest::prepareName(const glw::GLchar *name, glw::GLint location, glw::GLint component,
15042                                                Utils::Shader::STAGES stage, Utils::Variable::STORAGE storage)
15043 {
15044     GLchar buffer[16];
15045     std::string result   = "PREFIXNAME_lLOCATION_cCOMPONENT";
15046     size_t position      = 0;
15047     const GLchar *prefix = Utils::ProgramInterface::GetStagePrefix(stage, storage);
15048 
15049     Utils::replaceToken("PREFIX", position, prefix, result);
15050     Utils::replaceToken("NAME", position, name, result);
15051 
15052     sprintf(buffer, "%d", location);
15053     Utils::replaceToken("LOCATION", position, buffer, result);
15054 
15055     sprintf(buffer, "%d", component);
15056     Utils::replaceToken("COMPONENT", position, buffer, result);
15057 
15058     return result;
15059 }
15060 
15061 std::string VaryingComponentsTest::prepareQualifiers(const glw::GLchar *location, const glw::GLchar *component,
15062                                                      const glw::GLchar *interpolation)
15063 {
15064     size_t position        = 0;
15065     std::string qualifiers = "layout (location = LOCATION, component = COMPONENT) INTERPOLATION";
15066 
15067     Utils::replaceToken("LOCATION", position, location, qualifiers);
15068     Utils::replaceToken("COMPONENT", position, component, qualifiers);
15069     Utils::replaceToken("INTERPOLATION", position, interpolation, qualifiers);
15070 
15071     return qualifiers;
15072 }
15073 
15074 /**
15075  *
15076  **/
15077 void VaryingComponentsTest::prepareShaderStage(Utils::Shader::STAGES stage, const Utils::Type &vector_type,
15078                                                Utils::ProgramInterface &program_interface, const testCase &test_case,
15079                                                Utils::VaryingPassthrough &varying_passthrough)
15080 {
15081     const GLuint array_length     = getArrayLength();
15082     const Utils::Type &basic_type = Utils::Type::GetType(vector_type.m_basic_type, 1 /* n_cols */, 1 /* n_rows */);
15083     descriptor desc_in[8];
15084     descriptor desc_out[8];
15085     const GLuint first_in_loc   = 0;
15086     const GLuint first_out_loc  = 0;
15087     const GLchar *interpolation = "";
15088     const GLuint last_in_loc    = getLastInputLocation(stage, vector_type, array_length, false);
15089     GLuint last_out_loc         = 0;
15090     GLuint n_desc               = 0;
15091     Utils::ShaderInterface &si  = program_interface.GetShaderInterface(stage);
15092 
15093     /* Select interpolation */
15094     if ((Utils::Shader::FRAGMENT == stage) || (Utils::Shader::GEOMETRY == stage))
15095     {
15096         interpolation = " flat";
15097     }
15098 
15099     if (Utils::Shader::FRAGMENT != stage)
15100     {
15101         last_out_loc = getLastOutputLocation(stage, vector_type, array_length, false);
15102     }
15103 
15104     switch (test_case.m_layout)
15105     {
15106     case G64VEC2:
15107         n_desc = 2;
15108         desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 2, "g64vec2");
15109         desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 2, "g64vec2");
15110 
15111         desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 2, "g64vec2");
15112         desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 2, "g64vec2");
15113         break;
15114 
15115     case G64SCALAR_G64SCALAR:
15116         n_desc = 4;
15117         desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "g64scalar");
15118         desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "g64scalar");
15119         desc_in[2].assign(2, "comp_z", first_in_loc, "first_input_location", 1, "g64scalar");
15120         desc_in[3].assign(2, "comp_z", last_in_loc, "last_input_location", 1, "g64scalar");
15121 
15122         desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "g64scalar");
15123         desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "g64scalar");
15124         desc_out[2].assign(2, "comp_z", first_out_loc, "first_output_location", 1, "g64scalar");
15125         desc_out[3].assign(2, "comp_z", last_out_loc, "last_output_location", 1, "g64scalar");
15126         break;
15127     case GVEC4:
15128         n_desc = 2;
15129         desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 4, "gvec4");
15130         desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 4, "gvec4");
15131 
15132         desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 4, "gvec4");
15133         desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 4, "gvec4");
15134         break;
15135     case SCALAR_GVEC3:
15136         n_desc = 4;
15137         desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "scalar");
15138         desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "scalar");
15139         desc_in[2].assign(1, "comp_y", first_in_loc, "first_input_location", 3, "gvec3");
15140         desc_in[3].assign(1, "comp_y", last_in_loc, "last_input_location", 3, "gvec3");
15141 
15142         desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "scalar");
15143         desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "scalar");
15144         desc_out[2].assign(1, "comp_y", first_out_loc, "first_output_location", 3, "gvec3");
15145         desc_out[3].assign(1, "comp_y", last_out_loc, "last_output_location", 3, "gvec3");
15146         break;
15147     case GVEC3_SCALAR:
15148         n_desc = 4;
15149         desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 3, "gvec3");
15150         desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 3, "gvec3");
15151         desc_in[2].assign(3, "comp_w", first_in_loc, "first_input_location", 1, "scalar");
15152         desc_in[3].assign(3, "comp_w", last_in_loc, "last_input_location", 1, "scalar");
15153 
15154         desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 3, "gvec3");
15155         desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 3, "gvec3");
15156         desc_out[2].assign(3, "comp_w", first_out_loc, "first_output_location", 1, "scalar");
15157         desc_out[3].assign(3, "comp_w", last_out_loc, "last_output_location", 1, "scalar");
15158         break;
15159     case GVEC2_GVEC2:
15160         n_desc = 4;
15161         desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 2, "gvec2");
15162         desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 2, "gvec2");
15163         desc_in[2].assign(2, "comp_z", first_in_loc, "first_input_location", 2, "gvec2");
15164         desc_in[3].assign(2, "comp_z", last_in_loc, "last_input_location", 2, "gvec2");
15165 
15166         desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 2, "gvec2");
15167         desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 2, "gvec2");
15168         desc_out[2].assign(2, "comp_z", first_out_loc, "first_output_location", 2, "gvec2");
15169         desc_out[3].assign(2, "comp_z", last_out_loc, "last_output_location", 2, "gvec2");
15170         break;
15171     case GVEC2_SCALAR_SCALAR:
15172         n_desc = 6;
15173         desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 2, "gvec2");
15174         desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 2, "gvec2");
15175         desc_in[2].assign(2, "comp_z", first_in_loc, "first_input_location", 1, "scalar");
15176         desc_in[3].assign(2, "comp_z", last_in_loc, "last_input_location", 1, "scalar");
15177         desc_in[4].assign(3, "comp_w", first_in_loc, "first_input_location", 1, "scalar");
15178         desc_in[5].assign(3, "comp_w", last_in_loc, "last_input_location", 1, "scalar");
15179 
15180         desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 2, "gvec2");
15181         desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 2, "gvec2");
15182         desc_out[2].assign(2, "comp_z", first_out_loc, "first_output_location", 1, "scalar");
15183         desc_out[3].assign(2, "comp_z", last_out_loc, "last_output_location", 1, "scalar");
15184         desc_out[4].assign(3, "comp_w", first_out_loc, "first_output_location", 1, "scalar");
15185         desc_out[5].assign(3, "comp_w", last_out_loc, "last_output_location", 1, "scalar");
15186         break;
15187     case SCALAR_GVEC2_SCALAR:
15188         n_desc = 6;
15189         desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "scalar");
15190         desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "scalar");
15191         desc_in[2].assign(1, "comp_y", first_in_loc, "first_input_location", 2, "gvec2");
15192         desc_in[3].assign(1, "comp_y", last_in_loc, "last_input_location", 2, "gvec2");
15193         desc_in[4].assign(3, "comp_w", first_in_loc, "first_input_location", 1, "scalar");
15194         desc_in[5].assign(3, "comp_w", last_in_loc, "last_input_location", 1, "scalar");
15195 
15196         desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "scalar");
15197         desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "scalar");
15198         desc_out[2].assign(1, "comp_y", first_out_loc, "first_output_location", 2, "gvec2");
15199         desc_out[3].assign(1, "comp_y", last_out_loc, "last_output_location", 2, "gvec2");
15200         desc_out[4].assign(3, "comp_w", first_out_loc, "first_output_location", 1, "scalar");
15201         desc_out[5].assign(3, "comp_w", last_out_loc, "last_output_location", 1, "scalar");
15202         break;
15203     case SCALAR_SCALAR_GVEC2:
15204         n_desc = 6;
15205         desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "scalar");
15206         desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "scalar");
15207         desc_in[2].assign(1, "comp_y", first_in_loc, "first_input_location", 1, "scalar");
15208         desc_in[3].assign(1, "comp_y", last_in_loc, "last_input_location", 1, "scalar");
15209         desc_in[4].assign(2, "comp_z", first_in_loc, "first_input_location", 2, "gvec2");
15210         desc_in[5].assign(2, "comp_z", last_in_loc, "last_input_location", 2, "gvec2");
15211 
15212         desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "scalar");
15213         desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "scalar");
15214         desc_out[2].assign(1, "comp_y", first_out_loc, "first_output_location", 1, "scalar");
15215         desc_out[3].assign(1, "comp_y", last_out_loc, "last_output_location", 1, "scalar");
15216         desc_out[4].assign(2, "comp_z", first_out_loc, "first_output_location", 2, "gvec2");
15217         desc_out[5].assign(2, "comp_z", last_out_loc, "last_output_location", 2, "gvec2");
15218         break;
15219     case SCALAR_SCALAR_SCALAR_SCALAR:
15220         n_desc = 8;
15221         desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "scalar");
15222         desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "scalar");
15223         desc_in[2].assign(1, "comp_y", first_in_loc, "first_input_location", 1, "scalar");
15224         desc_in[3].assign(1, "comp_y", last_in_loc, "last_input_location", 1, "scalar");
15225         desc_in[4].assign(2, "comp_z", first_in_loc, "first_input_location", 1, "scalar");
15226         desc_in[5].assign(2, "comp_z", last_in_loc, "last_input_location", 1, "scalar");
15227         desc_in[6].assign(3, "comp_w", first_in_loc, "first_input_location", 1, "scalar");
15228         desc_in[7].assign(3, "comp_w", last_in_loc, "last_input_location", 1, "scalar");
15229 
15230         desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "scalar");
15231         desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "scalar");
15232         desc_out[2].assign(1, "comp_y", first_out_loc, "first_output_location", 1, "scalar");
15233         desc_out[3].assign(1, "comp_y", last_out_loc, "last_output_location", 1, "scalar");
15234         desc_out[4].assign(2, "comp_z", first_out_loc, "first_output_location", 1, "scalar");
15235         desc_out[5].assign(2, "comp_z", last_out_loc, "last_output_location", 1, "scalar");
15236         desc_out[6].assign(3, "comp_w", first_out_loc, "first_output_location", 1, "scalar");
15237         desc_out[7].assign(3, "comp_w", last_out_loc, "last_output_location", 1, "scalar");
15238         break;
15239     }
15240 
15241     for (GLuint i = 0; i < n_desc; ++i)
15242     {
15243         const descriptor &in_desc = desc_in[i];
15244 
15245         Utils::Variable *in =
15246             prepareVarying(basic_type, in_desc, interpolation, si, stage, Utils::Variable::VARYING_INPUT);
15247 
15248         if (Utils::Shader::FRAGMENT != stage)
15249         {
15250             const descriptor &out_desc = desc_out[i];
15251 
15252             Utils::Variable *out =
15253                 prepareVarying(basic_type, out_desc, interpolation, si, stage, Utils::Variable::VARYING_OUTPUT);
15254 
15255             varying_passthrough.Add(stage, in, out);
15256         }
15257     }
15258 
15259     si.m_globals = prepareGlobals(last_in_loc, last_out_loc);
15260 }
15261 
15262 /**
15263  *
15264  **/
15265 Utils::Variable *VaryingComponentsTest::prepareVarying(const Utils::Type &basic_type, const descriptor &desc,
15266                                                        const GLchar *interpolation, Utils::ShaderInterface &si,
15267                                                        Utils::Shader::STAGES stage, Utils::Variable::STORAGE storage)
15268 {
15269     const GLuint array_length   = getArrayLength();
15270     const GLuint component_size = Utils::Type::_float.GetSize();
15271     const std::string &name     = prepareName(desc.m_name, desc.m_location, desc.m_component, stage, storage);
15272     const GLuint offset         = desc.m_component * component_size;
15273     const std::string &qual     = prepareQualifiers(desc.m_location_str, desc.m_component_str, interpolation);
15274     const GLuint size           = desc.m_n_rows * basic_type.GetSize();
15275     const Utils::Type &type     = Utils::Type::GetType(basic_type.m_basic_type, 1 /* n_columns */, desc.m_n_rows);
15276     Utils::Variable *var        = 0;
15277 
15278     if (Utils::Variable::VARYING_INPUT == storage)
15279     {
15280         var = si.Input(name.c_str(), qual.c_str() /* qualifiers */, desc.m_component /* expected_componenet */,
15281                        desc.m_location /* expected_location */, type, /* built_in_type */
15282                        GL_FALSE /* normalized */, array_length /* n_array_elements */, 0u /* stride */,
15283                        offset /* offset */, (GLvoid *)&m_data[offset] /* data */, size /* data_size */);
15284     }
15285     else
15286     {
15287         var = si.Output(name.c_str(), qual.c_str() /* qualifiers */, desc.m_component /* expected_componenet */,
15288                         desc.m_location /* expected_location */, type, /* built_in_type */
15289                         GL_FALSE /* normalized */, array_length /* n_array_elements */, 0u /* stride */,
15290                         offset /* offset */, (GLvoid *)&m_data[offset] /* data */, size /* data_size */);
15291     }
15292 
15293     return var;
15294 }
15295 
15296 void VaryingComponentsTest::descriptor::assign(glw::GLint component, const glw::GLchar *component_str,
15297                                                glw::GLint location, const glw::GLchar *location_str, glw::GLuint n_rows,
15298                                                const glw::GLchar *name)
15299 {
15300     m_component     = component;
15301     m_component_str = component_str;
15302     m_location      = location;
15303     m_location_str  = location_str;
15304     m_n_rows        = n_rows;
15305     m_name          = name;
15306 }
15307 
15308 VaryingComponentsTest::testCase::testCase(COMPONENTS_LAYOUT layout, Utils::Type::TYPES type)
15309     : m_layout(layout)
15310     , m_type(type)
15311 {
15312 }
15313 
15314 /** Constructor
15315  *
15316  * @param context Test framework context
15317  **/
15318 VaryingArrayComponentsTest::VaryingArrayComponentsTest(deqp::Context &context)
15319     : VaryingComponentsTest(context, "varying_array_components",
15320                             "Test verifies that input and output components are respected for arrays")
15321 {
15322 }
15323 
15324 /** Get length of arrays that should be used during test
15325  *
15326  * @return 4u
15327  **/
15328 GLuint VaryingArrayComponentsTest::getArrayLength()
15329 {
15330     return 4u;
15331 }
15332 
15333 /** Constructor
15334  *
15335  * @param context Test framework context
15336  **/
15337 VaryingInvalidValueComponentTest::VaryingInvalidValueComponentTest(deqp::Context &context)
15338     : NegativeTestBase(context, "varying_invalid_value_component",
15339                        "Test verifies that compiler reports error when "
15340                        "using an invalid value in the component "
15341                        "qualification for a specific type")
15342 {
15343 }
15344 
15345 /** Source for given test case and stage
15346  *
15347  * @param test_case_index Index of test case
15348  * @param stage           Shader stage
15349  *
15350  * @return Shader source
15351  **/
15352 std::string VaryingInvalidValueComponentTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
15353 {
15354 #if DEBUG_NEG_REMOVE_ERROR
15355     static const GLchar *var_definition_arr =
15356         "layout (location = 1 /*, component = COMPONENT */) FLAT DIRECTION TYPE gokuARRAY[1];\n";
15357     static const GLchar *var_definition_one =
15358         "layout (location = 1 /*, component = COMPONENT */) FLAT DIRECTION TYPE gokuARRAY;\n";
15359 #else
15360     static const GLchar *var_definition_arr =
15361         "layout (location = 1, component = COMPONENT) FLAT DIRECTION TYPE gokuARRAY[1];\n";
15362     static const GLchar *var_definition_one =
15363         "layout (location = 1, component = COMPONENT) FLAT DIRECTION TYPE gokuARRAY;\n";
15364 #endif /* DEBUG_NEG_REMOVE_ERROR */
15365     static const GLchar *input_use_arr  = "    if (TYPE(0) == gokuINDEX[0])\n"
15366                                           "    {\n"
15367                                           "        result += vec4(1, 0.5, 0.25, 0.125);\n"
15368                                           "    }\n";
15369     static const GLchar *input_use_one  = "    if (TYPE(0) == gokuINDEX)\n"
15370                                           "    {\n"
15371                                           "        result += vec4(1, 0.5, 0.25, 0.125);\n"
15372                                           "    }\n";
15373     static const GLchar *output_use_arr = "    gokuINDEX[0] = TYPE(0);\n"
15374                                           "    if (vec4(0) == result)\n"
15375                                           "    {\n"
15376                                           "        gokuINDEX[0] = TYPE(1);\n"
15377                                           "    }\n";
15378     static const GLchar *output_use_one = "    gokuINDEX = TYPE(0);\n"
15379                                           "    if (vec4(0) == result)\n"
15380                                           "    {\n"
15381                                           "        gokuINDEX = TYPE(1);\n"
15382                                           "    }\n";
15383     static const GLchar *fs             = "#version 430 core\n"
15384                                           "#extension GL_ARB_enhanced_layouts : require\n"
15385                                           "\n"
15386                                           "in  vec4 gs_fs;\n"
15387                                           "out vec4 fs_out;\n"
15388                                           "\n"
15389                                           "void main()\n"
15390                                           "{\n"
15391                                           "    fs_out = gs_fs;\n"
15392                                           "}\n"
15393                                           "\n";
15394     static const GLchar *fs_tested      = "#version 430 core\n"
15395                                           "#extension GL_ARB_enhanced_layouts : require\n"
15396                                           "\n"
15397                                           "VAR_DEFINITION"
15398                                           "\n"
15399                                           "in  vec4 gs_fs;\n"
15400                                           "out vec4 fs_out;\n"
15401                                           "\n"
15402                                           "void main()\n"
15403                                           "{\n"
15404                                           "    vec4 result = gs_fs;\n"
15405                                           "\n"
15406                                           "VARIABLE_USE"
15407                                           "\n"
15408                                           "    fs_out += result;\n"
15409                                           "}\n"
15410                                           "\n";
15411     static const GLchar *gs             = "#version 430 core\n"
15412                                           "#extension GL_ARB_enhanced_layouts : require\n"
15413                                           "\n"
15414                                           "layout(points)                           in;\n"
15415                                           "layout(triangle_strip, max_vertices = 4) out;\n"
15416                                           "\n"
15417                                           "in  vec4 tes_gs[];\n"
15418                                           "out vec4 gs_fs;\n"
15419                                           "\n"
15420                                           "void main()\n"
15421                                           "{\n"
15422                                           "    gs_fs = tes_gs[0];\n"
15423                                           "    gl_Position  = vec4(-1, -1, 0, 1);\n"
15424                                           "    EmitVertex();\n"
15425                                           "    gs_fs = tes_gs[0];\n"
15426                                           "    gl_Position  = vec4(-1, 1, 0, 1);\n"
15427                                           "    EmitVertex();\n"
15428                                           "    gs_fs = tes_gs[0];\n"
15429                                           "    gl_Position  = vec4(1, -1, 0, 1);\n"
15430                                           "    EmitVertex();\n"
15431                                           "    gs_fs = tes_gs[0];\n"
15432                                           "    gl_Position  = vec4(1, 1, 0, 1);\n"
15433                                           "    EmitVertex();\n"
15434                                           "}\n"
15435                                           "\n";
15436     static const GLchar *gs_tested      = "#version 430 core\n"
15437                                           "#extension GL_ARB_enhanced_layouts : require\n"
15438                                           "\n"
15439                                           "layout(points)                           in;\n"
15440                                           "layout(triangle_strip, max_vertices = 4) out;\n"
15441                                           "\n"
15442                                           "VAR_DEFINITION"
15443                                           "\n"
15444                                           "in  vec4 tes_gs[];\n"
15445                                           "out vec4 gs_fs;\n"
15446                                           "\n"
15447                                           "void main()\n"
15448                                           "{\n"
15449                                           "    vec4 result = tes_gs[0];\n"
15450                                           "\n"
15451                                           "VARIABLE_USE"
15452                                           "\n"
15453                                           "    gs_fs = result;\n"
15454                                           "    gl_Position  = vec4(-1, -1, 0, 1);\n"
15455                                           "    EmitVertex();\n"
15456                                           "    gs_fs = result;\n"
15457                                           "    gl_Position  = vec4(-1, 1, 0, 1);\n"
15458                                           "    EmitVertex();\n"
15459                                           "    gs_fs = result;\n"
15460                                           "    gl_Position  = vec4(1, -1, 0, 1);\n"
15461                                           "    EmitVertex();\n"
15462                                           "    gs_fs = result;\n"
15463                                           "    gl_Position  = vec4(1, 1, 0, 1);\n"
15464                                           "    EmitVertex();\n"
15465                                           "}\n"
15466                                           "\n";
15467     static const GLchar *tcs            = "#version 430 core\n"
15468                                           "#extension GL_ARB_enhanced_layouts : require\n"
15469                                           "\n"
15470                                           "layout(vertices = 1) out;\n"
15471                                           "\n"
15472                                           "in  vec4 vs_tcs[];\n"
15473                                           "out vec4 tcs_tes[];\n"
15474                                           "\n"
15475                                           "void main()\n"
15476                                           "{\n"
15477                                           "\n"
15478                                           "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
15479                                           "\n"
15480                                           "    gl_TessLevelOuter[0] = 1.0;\n"
15481                                           "    gl_TessLevelOuter[1] = 1.0;\n"
15482                                           "    gl_TessLevelOuter[2] = 1.0;\n"
15483                                           "    gl_TessLevelOuter[3] = 1.0;\n"
15484                                           "    gl_TessLevelInner[0] = 1.0;\n"
15485                                           "    gl_TessLevelInner[1] = 1.0;\n"
15486                                           "}\n"
15487                                           "\n";
15488     static const GLchar *tcs_tested     = "#version 430 core\n"
15489                                           "#extension GL_ARB_enhanced_layouts : require\n"
15490                                           "\n"
15491                                           "layout(vertices = 1) out;\n"
15492                                           "\n"
15493                                           "VAR_DEFINITION"
15494                                           "\n"
15495                                           "in  vec4 vs_tcs[];\n"
15496                                           "out vec4 tcs_tes[];\n"
15497                                           "\n"
15498                                           "void main()\n"
15499                                           "{\n"
15500                                           "    vec4 result = vs_tcs[gl_InvocationID];\n"
15501                                           "\n"
15502                                           "VARIABLE_USE"
15503                                           "\n"
15504                                           "    tcs_tes[gl_InvocationID] = result;\n"
15505                                           "\n"
15506                                           "    gl_TessLevelOuter[0] = 1.0;\n"
15507                                           "    gl_TessLevelOuter[1] = 1.0;\n"
15508                                           "    gl_TessLevelOuter[2] = 1.0;\n"
15509                                           "    gl_TessLevelOuter[3] = 1.0;\n"
15510                                           "    gl_TessLevelInner[0] = 1.0;\n"
15511                                           "    gl_TessLevelInner[1] = 1.0;\n"
15512                                           "}\n"
15513                                           "\n";
15514     static const GLchar *tes            = "#version 430 core\n"
15515                                           "#extension GL_ARB_enhanced_layouts : require\n"
15516                                           "\n"
15517                                           "layout(isolines, point_mode) in;\n"
15518                                           "\n"
15519                                           "in  vec4 tcs_tes[];\n"
15520                                           "out vec4 tes_gs;\n"
15521                                           "\n"
15522                                           "void main()\n"
15523                                           "{\n"
15524                                           "    tes_gs = tcs_tes[0];\n"
15525                                           "}\n"
15526                                           "\n";
15527     static const GLchar *tes_tested     = "#version 430 core\n"
15528                                           "#extension GL_ARB_enhanced_layouts : require\n"
15529                                           "\n"
15530                                           "layout(isolines, point_mode) in;\n"
15531                                           "\n"
15532                                           "VAR_DEFINITION"
15533                                           "\n"
15534                                           "in  vec4 tcs_tes[];\n"
15535                                           "out vec4 tes_gs;\n"
15536                                           "\n"
15537                                           "void main()\n"
15538                                           "{\n"
15539                                           "    vec4 result = tcs_tes[0];\n"
15540                                           "\n"
15541                                           "VARIABLE_USE"
15542                                           "\n"
15543                                           "    tes_gs += result;\n"
15544                                           "}\n"
15545                                           "\n";
15546     static const GLchar *vs             = "#version 430 core\n"
15547                                           "#extension GL_ARB_enhanced_layouts : require\n"
15548                                           "\n"
15549                                           "in  vec4 in_vs;\n"
15550                                           "out vec4 vs_tcs;\n"
15551                                           "\n"
15552                                           "void main()\n"
15553                                           "{\n"
15554                                           "    vs_tcs = in_vs;\n"
15555                                           "}\n"
15556                                           "\n";
15557     static const GLchar *vs_tested      = "#version 430 core\n"
15558                                           "#extension GL_ARB_enhanced_layouts : require\n"
15559                                           "\n"
15560                                           "VAR_DEFINITION"
15561                                           "\n"
15562                                           "in  vec4 in_vs;\n"
15563                                           "out vec4 vs_tcs;\n"
15564                                           "\n"
15565                                           "void main()\n"
15566                                           "{\n"
15567                                           "    vec4 result = in_vs;\n"
15568                                           "\n"
15569                                           "VARIABLE_USE"
15570                                           "\n"
15571                                           "    vs_tcs += result;\n"
15572                                           "}\n"
15573                                           "\n";
15574 
15575     std::string source;
15576     testCase &test_case = m_test_cases[test_case_index];
15577 
15578     if (test_case.m_stage == stage)
15579     {
15580         const GLchar *array = "";
15581         GLchar buffer[16];
15582         const GLchar *var_definition     = 0;
15583         const GLchar *direction          = "in";
15584         const GLchar *index              = "";
15585         size_t position                  = 0;
15586         const GLchar *type_name          = test_case.m_type.GetGLSLTypeName();
15587         const GLchar *var_use            = 0;
15588         Utils::Variable::STORAGE storage = Utils::Variable::VARYING_INPUT;
15589         const GLchar *flat               = "";
15590 
15591         if (false == test_case.m_is_input)
15592         {
15593             direction = "out";
15594             storage   = Utils::Variable::VARYING_OUTPUT;
15595 
15596             if (false == test_case.m_is_array)
15597             {
15598                 var_definition = var_definition_one;
15599                 var_use        = output_use_one;
15600             }
15601             else
15602             {
15603                 var_definition = var_definition_arr;
15604                 var_use        = output_use_arr;
15605             }
15606         }
15607         else
15608         {
15609             if (false == test_case.m_is_array)
15610             {
15611                 var_definition = var_definition_one;
15612                 var_use        = Utils::Shader::VERTEX == stage ? input_use_one : "\n";
15613             }
15614             else
15615             {
15616                 var_definition = var_definition_arr;
15617                 var_use        = Utils::Shader::VERTEX == stage ? input_use_arr : "\n";
15618             }
15619         }
15620 
15621         if (isFlatRequired(stage, test_case.m_type, storage, true))
15622         {
15623             flat = "flat";
15624         }
15625 
15626         sprintf(buffer, "%d", test_case.m_component);
15627 
15628         switch (stage)
15629         {
15630         case Utils::Shader::FRAGMENT:
15631             source = fs_tested;
15632             break;
15633         case Utils::Shader::GEOMETRY:
15634             source = gs_tested;
15635             array  = test_case.m_is_input ? "[]" : "";
15636             index  = test_case.m_is_input ? "[0]" : "";
15637             break;
15638         case Utils::Shader::TESS_CTRL:
15639             source = tcs_tested;
15640             array  = "[]";
15641             index  = "[gl_InvocationID]";
15642             break;
15643         case Utils::Shader::TESS_EVAL:
15644             source = tes_tested;
15645             array  = test_case.m_is_input ? "[]" : "";
15646             index  = test_case.m_is_input ? "[0]" : "";
15647             break;
15648         case Utils::Shader::VERTEX:
15649             source = vs_tested;
15650             break;
15651         default:
15652             TCU_FAIL("Invalid enum");
15653         }
15654 
15655         Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
15656         position = 0;
15657         Utils::replaceToken("COMPONENT", position, buffer, source);
15658         Utils::replaceToken("FLAT", position, flat, source);
15659         Utils::replaceToken("DIRECTION", position, direction, source);
15660         Utils::replaceToken("ARRAY", position, array, source);
15661         Utils::replaceToken("VARIABLE_USE", position, var_use, source);
15662 
15663         Utils::replaceAllTokens("TYPE", type_name, source);
15664         Utils::replaceAllTokens("INDEX", index, source);
15665     }
15666     else
15667     {
15668         switch (stage)
15669         {
15670         case Utils::Shader::FRAGMENT:
15671             source = fs;
15672             break;
15673         case Utils::Shader::GEOMETRY:
15674             source = gs;
15675             break;
15676         case Utils::Shader::TESS_CTRL:
15677             source = tcs;
15678             break;
15679         case Utils::Shader::TESS_EVAL:
15680             source = tes;
15681             break;
15682         case Utils::Shader::VERTEX:
15683             source = vs;
15684             break;
15685         default:
15686             TCU_FAIL("Invalid enum");
15687         }
15688     }
15689 
15690     return source;
15691 }
15692 
15693 /** Get description of test case
15694  *
15695  * @param test_case_index Index of test case
15696  *
15697  * @return Test case description
15698  **/
15699 std::string VaryingInvalidValueComponentTest::getTestCaseName(GLuint test_case_index)
15700 {
15701     std::stringstream stream;
15702     testCase &test_case = m_test_cases[test_case_index];
15703 
15704     stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
15705            << " type: " << test_case.m_type.GetGLSLTypeName();
15706 
15707     if (true == test_case.m_is_array)
15708     {
15709         stream << "[1]";
15710     }
15711 
15712     stream << ", direction: ";
15713 
15714     if (true == test_case.m_is_input)
15715     {
15716         stream << "input";
15717     }
15718     else
15719     {
15720         stream << "output";
15721     }
15722 
15723     stream << ", component: " << test_case.m_component;
15724 
15725     return stream.str();
15726 }
15727 
15728 /** Get number of test cases
15729  *
15730  * @return Number of test cases
15731  **/
15732 GLuint VaryingInvalidValueComponentTest::getTestCaseNumber()
15733 {
15734     return static_cast<GLuint>(m_test_cases.size());
15735 }
15736 
15737 /** Selects if "compute" stage is relevant for test
15738  *
15739  * @param ignored
15740  *
15741  * @return false
15742  **/
15743 bool VaryingInvalidValueComponentTest::isComputeRelevant(GLuint /* test_case_index */)
15744 {
15745     return false;
15746 }
15747 
15748 /** Prepare all test cases
15749  *
15750  **/
15751 void VaryingInvalidValueComponentTest::testInit()
15752 {
15753     const GLuint n_types = getTypesNumber();
15754 
15755     for (GLuint i = 0; i < n_types; ++i)
15756     {
15757         const Utils::Type &type                     = getType(i);
15758         const std::vector<GLuint> &valid_components = type.GetValidComponents();
15759 
15760         if (valid_components.empty())
15761         {
15762             continue;
15763         }
15764 
15765         std::vector<GLuint> every_component(4, 0);
15766         every_component[1] = 1;
15767         every_component[2] = 2;
15768         every_component[3] = 3;
15769         std::vector<GLuint> invalid_components;
15770 
15771         std::set_symmetric_difference(every_component.begin(), every_component.end(), valid_components.begin(),
15772                                       valid_components.end(), back_inserter(invalid_components));
15773 
15774         for (std::vector<GLuint>::const_iterator it_invalid_components = invalid_components.begin();
15775              it_invalid_components != invalid_components.end(); ++it_invalid_components)
15776         {
15777             for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
15778             {
15779                 if (Utils::Shader::COMPUTE == stage)
15780                 {
15781                     continue;
15782                 }
15783 
15784                 testCase test_case_in_arr  = {*it_invalid_components, true, true, (Utils::Shader::STAGES)stage, type};
15785                 testCase test_case_in_one  = {*it_invalid_components, true, false, (Utils::Shader::STAGES)stage, type};
15786                 testCase test_case_out_arr = {*it_invalid_components, false, true, (Utils::Shader::STAGES)stage, type};
15787                 testCase test_case_out_one = {*it_invalid_components, false, false, (Utils::Shader::STAGES)stage, type};
15788 
15789                 m_test_cases.push_back(test_case_in_arr);
15790                 m_test_cases.push_back(test_case_in_one);
15791 
15792                 if (Utils::Shader::FRAGMENT != stage)
15793                 {
15794                     m_test_cases.push_back(test_case_out_arr);
15795                     m_test_cases.push_back(test_case_out_one);
15796                 }
15797             }
15798         }
15799     }
15800 }
15801 
15802 /** Constructor
15803  *
15804  * @param context Test framework context
15805  **/
15806 VaryingExceedingComponentsTest::VaryingExceedingComponentsTest(deqp::Context &context)
15807     : NegativeTestBase(context, "varying_exceeding_components",
15808                        "Test verifies that compiler reports error when component qualifier exceeds limits")
15809 {
15810 }
15811 
15812 /** Source for given test case and stage
15813  *
15814  * @param test_case_index Index of test case
15815  * @param stage           Shader stage
15816  *
15817  * @return Shader source
15818  **/
15819 std::string VaryingExceedingComponentsTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
15820 {
15821 #if DEBUG_NEG_REMOVE_ERROR
15822     static const GLchar *var_definition_arr =
15823         "layout (location = 1 /*, component = 4 */) FLAT DIRECTION TYPE gokuARRAY[1];\n";
15824     static const GLchar *var_definition_one =
15825         "layout (location = 1 /*, component = 4 */) FLAT DIRECTION TYPE gokuARRAY;\n";
15826 #else
15827     static const GLchar *var_definition_arr =
15828         "layout (location = 1, component = 4) FLAT DIRECTION TYPE gokuARRAY[1];\n";
15829     static const GLchar *var_definition_one = "layout (location = 1, component = 4) FLAT DIRECTION TYPE gokuARRAY;\n";
15830 #endif /* DEBUG_NEG_REMOVE_ERROR */
15831     static const GLchar *input_use_arr  = "    if (TYPE(0) == gokuINDEX[0])\n"
15832                                           "    {\n"
15833                                           "        result += vec4(1, 0.5, 0.25, 0.125);\n"
15834                                           "    }\n";
15835     static const GLchar *input_use_one  = "    if (TYPE(0) == gokuINDEX)\n"
15836                                           "    {\n"
15837                                           "        result += vec4(1, 0.5, 0.25, 0.125);\n"
15838                                           "    }\n";
15839     static const GLchar *output_use_arr = "    gokuINDEX[0] = TYPE(0);\n"
15840                                           "    if (vec4(0) == result)\n"
15841                                           "    {\n"
15842                                           "        gokuINDEX[0] = TYPE(1);\n"
15843                                           "    }\n";
15844     static const GLchar *output_use_one = "    gokuINDEX = TYPE(0);\n"
15845                                           "    if (vec4(0) == result)\n"
15846                                           "    {\n"
15847                                           "        gokuINDEX = TYPE(1);\n"
15848                                           "    }\n";
15849     static const GLchar *fs             = "#version 430 core\n"
15850                                           "#extension GL_ARB_enhanced_layouts : require\n"
15851                                           "\n"
15852                                           "in  vec4 gs_fs;\n"
15853                                           "out vec4 fs_out;\n"
15854                                           "\n"
15855                                           "void main()\n"
15856                                           "{\n"
15857                                           "    fs_out = gs_fs;\n"
15858                                           "}\n"
15859                                           "\n";
15860     static const GLchar *fs_tested      = "#version 430 core\n"
15861                                           "#extension GL_ARB_enhanced_layouts : require\n"
15862                                           "\n"
15863                                           "VAR_DEFINITION"
15864                                           "\n"
15865                                           "in  vec4 gs_fs;\n"
15866                                           "out vec4 fs_out;\n"
15867                                           "\n"
15868                                           "void main()\n"
15869                                           "{\n"
15870                                           "    vec4 result = gs_fs;\n"
15871                                           "\n"
15872                                           "VARIABLE_USE"
15873                                           "\n"
15874                                           "    fs_out += result;\n"
15875                                           "}\n"
15876                                           "\n";
15877     static const GLchar *gs             = "#version 430 core\n"
15878                                           "#extension GL_ARB_enhanced_layouts : require\n"
15879                                           "\n"
15880                                           "layout(points)                           in;\n"
15881                                           "layout(triangle_strip, max_vertices = 4) out;\n"
15882                                           "\n"
15883                                           "in  vec4 tes_gs[];\n"
15884                                           "out vec4 gs_fs;\n"
15885                                           "\n"
15886                                           "void main()\n"
15887                                           "{\n"
15888                                           "    gs_fs = tes_gs[0];\n"
15889                                           "    gl_Position  = vec4(-1, -1, 0, 1);\n"
15890                                           "    EmitVertex();\n"
15891                                           "    gs_fs = tes_gs[0];\n"
15892                                           "    gl_Position  = vec4(-1, 1, 0, 1);\n"
15893                                           "    EmitVertex();\n"
15894                                           "    gs_fs = tes_gs[0];\n"
15895                                           "    gl_Position  = vec4(1, -1, 0, 1);\n"
15896                                           "    EmitVertex();\n"
15897                                           "    gs_fs = tes_gs[0];\n"
15898                                           "    gl_Position  = vec4(1, 1, 0, 1);\n"
15899                                           "    EmitVertex();\n"
15900                                           "}\n"
15901                                           "\n";
15902     static const GLchar *gs_tested      = "#version 430 core\n"
15903                                           "#extension GL_ARB_enhanced_layouts : require\n"
15904                                           "\n"
15905                                           "layout(points)                           in;\n"
15906                                           "layout(triangle_strip, max_vertices = 4) out;\n"
15907                                           "\n"
15908                                           "VAR_DEFINITION"
15909                                           "\n"
15910                                           "in  vec4 tes_gs[];\n"
15911                                           "out vec4 gs_fs;\n"
15912                                           "\n"
15913                                           "void main()\n"
15914                                           "{\n"
15915                                           "    vec4 result = tes_gs[0];\n"
15916                                           "\n"
15917                                           "VARIABLE_USE"
15918                                           "\n"
15919                                           "    gs_fs = result;\n"
15920                                           "    gl_Position  = vec4(-1, -1, 0, 1);\n"
15921                                           "    EmitVertex();\n"
15922                                           "    gs_fs = result;\n"
15923                                           "    gl_Position  = vec4(-1, 1, 0, 1);\n"
15924                                           "    EmitVertex();\n"
15925                                           "    gs_fs = result;\n"
15926                                           "    gl_Position  = vec4(1, -1, 0, 1);\n"
15927                                           "    EmitVertex();\n"
15928                                           "    gs_fs = result;\n"
15929                                           "    gl_Position  = vec4(1, 1, 0, 1);\n"
15930                                           "    EmitVertex();\n"
15931                                           "}\n"
15932                                           "\n";
15933     static const GLchar *tcs            = "#version 430 core\n"
15934                                           "#extension GL_ARB_enhanced_layouts : require\n"
15935                                           "\n"
15936                                           "layout(vertices = 1) out;\n"
15937                                           "\n"
15938                                           "in  vec4 vs_tcs[];\n"
15939                                           "out vec4 tcs_tes[];\n"
15940                                           "\n"
15941                                           "void main()\n"
15942                                           "{\n"
15943                                           "\n"
15944                                           "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
15945                                           "\n"
15946                                           "    gl_TessLevelOuter[0] = 1.0;\n"
15947                                           "    gl_TessLevelOuter[1] = 1.0;\n"
15948                                           "    gl_TessLevelOuter[2] = 1.0;\n"
15949                                           "    gl_TessLevelOuter[3] = 1.0;\n"
15950                                           "    gl_TessLevelInner[0] = 1.0;\n"
15951                                           "    gl_TessLevelInner[1] = 1.0;\n"
15952                                           "}\n"
15953                                           "\n";
15954     static const GLchar *tcs_tested     = "#version 430 core\n"
15955                                           "#extension GL_ARB_enhanced_layouts : require\n"
15956                                           "\n"
15957                                           "layout(vertices = 1) out;\n"
15958                                           "\n"
15959                                           "VAR_DEFINITION"
15960                                           "\n"
15961                                           "in  vec4 vs_tcs[];\n"
15962                                           "out vec4 tcs_tes[];\n"
15963                                           "\n"
15964                                           "void main()\n"
15965                                           "{\n"
15966                                           "    vec4 result = vs_tcs[gl_InvocationID];\n"
15967                                           "\n"
15968                                           "VARIABLE_USE"
15969                                           "\n"
15970                                           "    tcs_tes[gl_InvocationID] = result;\n"
15971                                           "\n"
15972                                           "    gl_TessLevelOuter[0] = 1.0;\n"
15973                                           "    gl_TessLevelOuter[1] = 1.0;\n"
15974                                           "    gl_TessLevelOuter[2] = 1.0;\n"
15975                                           "    gl_TessLevelOuter[3] = 1.0;\n"
15976                                           "    gl_TessLevelInner[0] = 1.0;\n"
15977                                           "    gl_TessLevelInner[1] = 1.0;\n"
15978                                           "}\n"
15979                                           "\n";
15980     static const GLchar *tes            = "#version 430 core\n"
15981                                           "#extension GL_ARB_enhanced_layouts : require\n"
15982                                           "\n"
15983                                           "layout(isolines, point_mode) in;\n"
15984                                           "\n"
15985                                           "in  vec4 tcs_tes[];\n"
15986                                           "out vec4 tes_gs;\n"
15987                                           "\n"
15988                                           "void main()\n"
15989                                           "{\n"
15990                                           "    tes_gs = tcs_tes[0];\n"
15991                                           "}\n"
15992                                           "\n";
15993     static const GLchar *tes_tested     = "#version 430 core\n"
15994                                           "#extension GL_ARB_enhanced_layouts : require\n"
15995                                           "\n"
15996                                           "layout(isolines, point_mode) in;\n"
15997                                           "\n"
15998                                           "VAR_DEFINITION"
15999                                           "\n"
16000                                           "in  vec4 tcs_tes[];\n"
16001                                           "out vec4 tes_gs;\n"
16002                                           "\n"
16003                                           "void main()\n"
16004                                           "{\n"
16005                                           "    vec4 result = tcs_tes[0];\n"
16006                                           "\n"
16007                                           "VARIABLE_USE"
16008                                           "\n"
16009                                           "    tes_gs += result;\n"
16010                                           "}\n"
16011                                           "\n";
16012     static const GLchar *vs             = "#version 430 core\n"
16013                                           "#extension GL_ARB_enhanced_layouts : require\n"
16014                                           "\n"
16015                                           "in  vec4 in_vs;\n"
16016                                           "out vec4 vs_tcs;\n"
16017                                           "\n"
16018                                           "void main()\n"
16019                                           "{\n"
16020                                           "    vs_tcs = in_vs;\n"
16021                                           "}\n"
16022                                           "\n";
16023     static const GLchar *vs_tested      = "#version 430 core\n"
16024                                           "#extension GL_ARB_enhanced_layouts : require\n"
16025                                           "\n"
16026                                           "VAR_DEFINITION"
16027                                           "\n"
16028                                           "in  vec4 in_vs;\n"
16029                                           "out vec4 vs_tcs;\n"
16030                                           "\n"
16031                                           "void main()\n"
16032                                           "{\n"
16033                                           "    vec4 result = in_vs;\n"
16034                                           "\n"
16035                                           "VARIABLE_USE"
16036                                           "\n"
16037                                           "    vs_tcs += result;\n"
16038                                           "}\n"
16039                                           "\n";
16040 
16041     std::string source;
16042     testCase &test_case = m_test_cases[test_case_index];
16043 
16044     if (test_case.m_stage == stage)
16045     {
16046         const GLchar *array              = "";
16047         const GLchar *var_definition     = 0;
16048         const GLchar *direction          = "in";
16049         const GLchar *index              = "";
16050         size_t position                  = 0;
16051         const GLchar *type_name          = test_case.m_type.GetGLSLTypeName();
16052         const GLchar *var_use            = 0;
16053         Utils::Variable::STORAGE storage = Utils::Variable::VARYING_INPUT;
16054         const GLchar *flat               = "";
16055 
16056         if (false == test_case.m_is_input)
16057         {
16058             direction = "out";
16059             storage   = Utils::Variable::VARYING_OUTPUT;
16060 
16061             if (false == test_case.m_is_array)
16062             {
16063                 var_definition = var_definition_one;
16064                 var_use        = output_use_one;
16065             }
16066             else
16067             {
16068                 var_definition = var_definition_arr;
16069                 var_use        = output_use_arr;
16070             }
16071         }
16072         else
16073         {
16074             if (false == test_case.m_is_array)
16075             {
16076                 var_definition = var_definition_one;
16077                 var_use        = Utils::Shader::VERTEX == stage ? input_use_one : "\n";
16078             }
16079             else
16080             {
16081                 var_definition = var_definition_arr;
16082                 var_use        = Utils::Shader::VERTEX == stage ? input_use_arr : "\n";
16083             }
16084         }
16085 
16086         if (isFlatRequired(stage, test_case.m_type, storage, true))
16087         {
16088             flat = "flat";
16089         }
16090 
16091         switch (stage)
16092         {
16093         case Utils::Shader::FRAGMENT:
16094             source = fs_tested;
16095             break;
16096         case Utils::Shader::GEOMETRY:
16097             source = gs_tested;
16098             array  = test_case.m_is_input ? "[]" : "";
16099             index  = test_case.m_is_input ? "[0]" : "";
16100             break;
16101         case Utils::Shader::TESS_CTRL:
16102             source = tcs_tested;
16103             array  = "[]";
16104             index  = "[gl_InvocationID]";
16105             break;
16106         case Utils::Shader::TESS_EVAL:
16107             source = tes_tested;
16108             array  = test_case.m_is_input ? "[]" : "";
16109             index  = test_case.m_is_input ? "[0]" : "";
16110             break;
16111         case Utils::Shader::VERTEX:
16112             source = vs_tested;
16113             break;
16114         default:
16115             TCU_FAIL("Invalid enum");
16116         }
16117 
16118         Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
16119         position = 0;
16120         Utils::replaceToken("FLAT", position, flat, source);
16121         Utils::replaceToken("DIRECTION", position, direction, source);
16122         Utils::replaceToken("ARRAY", position, array, source);
16123         Utils::replaceToken("VARIABLE_USE", position, var_use, source);
16124 
16125         Utils::replaceAllTokens("TYPE", type_name, source);
16126         Utils::replaceAllTokens("INDEX", index, source);
16127     }
16128     else
16129     {
16130         switch (stage)
16131         {
16132         case Utils::Shader::FRAGMENT:
16133             source = fs;
16134             break;
16135         case Utils::Shader::GEOMETRY:
16136             source = gs;
16137             break;
16138         case Utils::Shader::TESS_CTRL:
16139             source = tcs;
16140             break;
16141         case Utils::Shader::TESS_EVAL:
16142             source = tes;
16143             break;
16144         case Utils::Shader::VERTEX:
16145             source = vs;
16146             break;
16147         default:
16148             TCU_FAIL("Invalid enum");
16149         }
16150     }
16151 
16152     return source;
16153 }
16154 
16155 /** Get description of test case
16156  *
16157  * @param test_case_index Index of test case
16158  *
16159  * @return Test case description
16160  **/
16161 std::string VaryingExceedingComponentsTest::getTestCaseName(GLuint test_case_index)
16162 {
16163     std::stringstream stream;
16164     testCase &test_case = m_test_cases[test_case_index];
16165 
16166     stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
16167            << " type: " << test_case.m_type.GetGLSLTypeName();
16168 
16169     if (true == test_case.m_is_array)
16170     {
16171         stream << "[1]";
16172     }
16173 
16174     stream << ", direction: ";
16175 
16176     if (true == test_case.m_is_input)
16177     {
16178         stream << "input";
16179     }
16180     else
16181     {
16182         stream << "output";
16183     }
16184 
16185     return stream.str();
16186 }
16187 
16188 /** Get number of test cases
16189  *
16190  * @return Number of test cases
16191  **/
16192 GLuint VaryingExceedingComponentsTest::getTestCaseNumber()
16193 {
16194     return static_cast<GLuint>(m_test_cases.size());
16195 }
16196 
16197 /** Selects if "compute" stage is relevant for test
16198  *
16199  * @param ignored
16200  *
16201  * @return false
16202  **/
16203 bool VaryingExceedingComponentsTest::isComputeRelevant(GLuint /* test_case_index */)
16204 {
16205     return false;
16206 }
16207 
16208 /** Prepare all test cases
16209  *
16210  **/
16211 void VaryingExceedingComponentsTest::testInit()
16212 {
16213     const GLuint n_types = getTypesNumber();
16214 
16215     for (GLuint i = 0; i < n_types; ++i)
16216     {
16217         const Utils::Type &type                     = getType(i);
16218         const std::vector<GLuint> &valid_components = type.GetValidComponents();
16219 
16220         if (valid_components.empty())
16221         {
16222             continue;
16223         }
16224 
16225         for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
16226         {
16227             if (Utils::Shader::COMPUTE == stage)
16228             {
16229                 continue;
16230             }
16231 
16232             testCase test_case_in_arr  = {true, true, (Utils::Shader::STAGES)stage, type};
16233             testCase test_case_in_one  = {true, false, (Utils::Shader::STAGES)stage, type};
16234             testCase test_case_out_arr = {false, true, (Utils::Shader::STAGES)stage, type};
16235             testCase test_case_out_one = {false, false, (Utils::Shader::STAGES)stage, type};
16236 
16237             m_test_cases.push_back(test_case_in_arr);
16238             m_test_cases.push_back(test_case_in_one);
16239 
16240             if (Utils::Shader::FRAGMENT != stage)
16241             {
16242                 m_test_cases.push_back(test_case_out_arr);
16243                 m_test_cases.push_back(test_case_out_one);
16244             }
16245         }
16246     }
16247 }
16248 
16249 /** Constructor
16250  *
16251  * @param context Test framework context
16252  **/
16253 VaryingComponentWithoutLocationTest::VaryingComponentWithoutLocationTest(deqp::Context &context)
16254     : NegativeTestBase(context, "varying_component_without_location",
16255                        "Test verifies that compiler reports error when component qualifier is used without location")
16256 {
16257 }
16258 
16259 /** Source for given test case and stage
16260  *
16261  * @param test_case_index Index of test case
16262  * @param stage           Shader stage
16263  *
16264  * @return Shader source
16265  **/
16266 std::string VaryingComponentWithoutLocationTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
16267 {
16268 #if DEBUG_NEG_REMOVE_ERROR
16269     static const GLchar *var_definition = "/* layout (component = COMPONENT) */ FLAT DIRECTION TYPE gokuARRAY;\n";
16270 #else
16271     static const GLchar *var_definition     = "layout (component = COMPONENT) FLAT DIRECTION TYPE gokuARRAY;\n";
16272 #endif /* DEBUG_NEG_REMOVE_ERROR */
16273     static const GLchar *input_use  = "    if (TYPE(0) == gokuINDEX)\n"
16274                                       "    {\n"
16275                                       "        result += vec4(1, 0.5, 0.25, 0.125);\n"
16276                                       "    }\n";
16277     static const GLchar *output_use = "    gokuINDEX = TYPE(0);\n"
16278                                       "    if (vec4(0) == result)\n"
16279                                       "    {\n"
16280                                       "        gokuINDEX = TYPE(1);\n"
16281                                       "    }\n";
16282     static const GLchar *fs         = "#version 430 core\n"
16283                                       "#extension GL_ARB_enhanced_layouts : require\n"
16284                                       "\n"
16285                                       "in  vec4 gs_fs;\n"
16286                                       "out vec4 fs_out;\n"
16287                                       "\n"
16288                                       "void main()\n"
16289                                       "{\n"
16290                                       "    fs_out = gs_fs;\n"
16291                                       "}\n"
16292                                       "\n";
16293     static const GLchar *fs_tested  = "#version 430 core\n"
16294                                       "#extension GL_ARB_enhanced_layouts : require\n"
16295                                       "\n"
16296                                       "VAR_DEFINITION"
16297                                       "\n"
16298                                       "in  vec4 gs_fs;\n"
16299                                       "out vec4 fs_out;\n"
16300                                       "\n"
16301                                       "void main()\n"
16302                                       "{\n"
16303                                       "    vec4 result = gs_fs;\n"
16304                                       "\n"
16305                                       "VARIABLE_USE"
16306                                       "\n"
16307                                       "    fs_out = result;\n"
16308                                       "}\n"
16309                                       "\n";
16310     static const GLchar *gs         = "#version 430 core\n"
16311                                       "#extension GL_ARB_enhanced_layouts : require\n"
16312                                       "\n"
16313                                       "layout(points)                           in;\n"
16314                                       "layout(triangle_strip, max_vertices = 4) out;\n"
16315                                       "\n"
16316                                       "in  vec4 tes_gs[];\n"
16317                                       "out vec4 gs_fs;\n"
16318                                       "\n"
16319                                       "void main()\n"
16320                                       "{\n"
16321                                       "    gs_fs = tes_gs[0];\n"
16322                                       "    gl_Position  = vec4(-1, -1, 0, 1);\n"
16323                                       "    EmitVertex();\n"
16324                                       "    gs_fs = tes_gs[0];\n"
16325                                       "    gl_Position  = vec4(-1, 1, 0, 1);\n"
16326                                       "    EmitVertex();\n"
16327                                       "    gs_fs = tes_gs[0];\n"
16328                                       "    gl_Position  = vec4(1, -1, 0, 1);\n"
16329                                       "    EmitVertex();\n"
16330                                       "    gs_fs = tes_gs[0];\n"
16331                                       "    gl_Position  = vec4(1, 1, 0, 1);\n"
16332                                       "    EmitVertex();\n"
16333                                       "}\n"
16334                                       "\n";
16335     static const GLchar *gs_tested  = "#version 430 core\n"
16336                                       "#extension GL_ARB_enhanced_layouts : require\n"
16337                                       "\n"
16338                                       "layout(points)                           in;\n"
16339                                       "layout(triangle_strip, max_vertices = 4) out;\n"
16340                                       "\n"
16341                                       "VAR_DEFINITION"
16342                                       "\n"
16343                                       "in  vec4 tes_gs[];\n"
16344                                       "out vec4 gs_fs;\n"
16345                                       "\n"
16346                                       "void main()\n"
16347                                       "{\n"
16348                                       "    vec4 result = tes_gs[0];\n"
16349                                       "\n"
16350                                       "VARIABLE_USE"
16351                                       "\n"
16352                                       "    gs_fs = result;\n"
16353                                       "    gl_Position  = vec4(-1, -1, 0, 1);\n"
16354                                       "    EmitVertex();\n"
16355                                       "    gs_fs = result;\n"
16356                                       "    gl_Position  = vec4(-1, 1, 0, 1);\n"
16357                                       "    EmitVertex();\n"
16358                                       "    gs_fs = result;\n"
16359                                       "    gl_Position  = vec4(1, -1, 0, 1);\n"
16360                                       "    EmitVertex();\n"
16361                                       "    gs_fs = result;\n"
16362                                       "    gl_Position  = vec4(1, 1, 0, 1);\n"
16363                                       "    EmitVertex();\n"
16364                                       "}\n"
16365                                       "\n";
16366     static const GLchar *tcs        = "#version 430 core\n"
16367                                       "#extension GL_ARB_enhanced_layouts : require\n"
16368                                       "\n"
16369                                       "layout(vertices = 1) out;\n"
16370                                       "\n"
16371                                       "in  vec4 vs_tcs[];\n"
16372                                       "out vec4 tcs_tes[];\n"
16373                                       "\n"
16374                                       "void main()\n"
16375                                       "{\n"
16376                                       "\n"
16377                                       "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
16378                                       "\n"
16379                                       "    gl_TessLevelOuter[0] = 1.0;\n"
16380                                       "    gl_TessLevelOuter[1] = 1.0;\n"
16381                                       "    gl_TessLevelOuter[2] = 1.0;\n"
16382                                       "    gl_TessLevelOuter[3] = 1.0;\n"
16383                                       "    gl_TessLevelInner[0] = 1.0;\n"
16384                                       "    gl_TessLevelInner[1] = 1.0;\n"
16385                                       "}\n"
16386                                       "\n";
16387     static const GLchar *tcs_tested = "#version 430 core\n"
16388                                       "#extension GL_ARB_enhanced_layouts : require\n"
16389                                       "\n"
16390                                       "layout(vertices = 1) out;\n"
16391                                       "\n"
16392                                       "VAR_DEFINITION"
16393                                       "\n"
16394                                       "in  vec4 vs_tcs[];\n"
16395                                       "out vec4 tcs_tes[];\n"
16396                                       "\n"
16397                                       "void main()\n"
16398                                       "{\n"
16399                                       "    vec4 result = vs_tcs[gl_InvocationID];\n"
16400                                       "\n"
16401                                       "VARIABLE_USE"
16402                                       "\n"
16403                                       "    tcs_tes[gl_InvocationID] = result;\n"
16404                                       "\n"
16405                                       "    gl_TessLevelOuter[0] = 1.0;\n"
16406                                       "    gl_TessLevelOuter[1] = 1.0;\n"
16407                                       "    gl_TessLevelOuter[2] = 1.0;\n"
16408                                       "    gl_TessLevelOuter[3] = 1.0;\n"
16409                                       "    gl_TessLevelInner[0] = 1.0;\n"
16410                                       "    gl_TessLevelInner[1] = 1.0;\n"
16411                                       "}\n"
16412                                       "\n";
16413     static const GLchar *tes        = "#version 430 core\n"
16414                                       "#extension GL_ARB_enhanced_layouts : require\n"
16415                                       "\n"
16416                                       "layout(isolines, point_mode) in;\n"
16417                                       "\n"
16418                                       "in  vec4 tcs_tes[];\n"
16419                                       "out vec4 tes_gs;\n"
16420                                       "\n"
16421                                       "void main()\n"
16422                                       "{\n"
16423                                       "    tes_gs = tcs_tes[0];\n"
16424                                       "}\n"
16425                                       "\n";
16426     static const GLchar *tes_tested = "#version 430 core\n"
16427                                       "#extension GL_ARB_enhanced_layouts : require\n"
16428                                       "\n"
16429                                       "layout(isolines, point_mode) in;\n"
16430                                       "\n"
16431                                       "VAR_DEFINITION"
16432                                       "\n"
16433                                       "in  vec4 tcs_tes[];\n"
16434                                       "out vec4 tes_gs;\n"
16435                                       "\n"
16436                                       "void main()\n"
16437                                       "{\n"
16438                                       "    vec4 result = tcs_tes[0];\n"
16439                                       "\n"
16440                                       "VARIABLE_USE"
16441                                       "\n"
16442                                       "    tes_gs = result;\n"
16443                                       "}\n"
16444                                       "\n";
16445     static const GLchar *vs         = "#version 430 core\n"
16446                                       "#extension GL_ARB_enhanced_layouts : require\n"
16447                                       "\n"
16448                                       "in  vec4 in_vs;\n"
16449                                       "out vec4 vs_tcs;\n"
16450                                       "\n"
16451                                       "void main()\n"
16452                                       "{\n"
16453                                       "    vs_tcs = in_vs;\n"
16454                                       "}\n"
16455                                       "\n";
16456     static const GLchar *vs_tested  = "#version 430 core\n"
16457                                       "#extension GL_ARB_enhanced_layouts : require\n"
16458                                       "\n"
16459                                       "VAR_DEFINITION"
16460                                       "\n"
16461                                       "in  vec4 in_vs;\n"
16462                                       "out vec4 vs_tcs;\n"
16463                                       "\n"
16464                                       "void main()\n"
16465                                       "{\n"
16466                                       "    vec4 result = in_vs;\n"
16467                                       "\n"
16468                                       "VARIABLE_USE"
16469                                       "\n"
16470                                       "    vs_tcs = result;\n"
16471                                       "}\n"
16472                                       "\n";
16473 
16474     std::string source;
16475     testCase &test_case = m_test_cases[test_case_index];
16476 
16477     if (test_case.m_stage == stage)
16478     {
16479         const GLchar *array = "";
16480         GLchar buffer[16];
16481         const GLchar *direction          = "in";
16482         const GLchar *index              = "";
16483         size_t position                  = 0;
16484         const GLchar *type_name          = test_case.m_type.GetGLSLTypeName();
16485         const GLchar *var_use            = Utils::Shader::VERTEX == stage ? input_use : "\n";
16486         Utils::Variable::STORAGE storage = Utils::Variable::VARYING_INPUT;
16487         const GLchar *flat               = "";
16488 
16489         if (false == test_case.m_is_input)
16490         {
16491             direction = "out";
16492             storage   = Utils::Variable::VARYING_OUTPUT;
16493             var_use   = output_use;
16494         }
16495 
16496         if (isFlatRequired(stage, test_case.m_type, storage, true))
16497         {
16498             flat = "flat";
16499         }
16500 
16501         sprintf(buffer, "%d", test_case.m_component);
16502 
16503         switch (stage)
16504         {
16505         case Utils::Shader::FRAGMENT:
16506             source = fs_tested;
16507             break;
16508         case Utils::Shader::GEOMETRY:
16509             source = gs_tested;
16510             array  = test_case.m_is_input ? "[]" : "";
16511             index  = test_case.m_is_input ? "[0]" : "";
16512             break;
16513         case Utils::Shader::TESS_CTRL:
16514             source = tcs_tested;
16515             array  = "[]";
16516             index  = "[gl_InvocationID]";
16517             break;
16518         case Utils::Shader::TESS_EVAL:
16519             source = tes_tested;
16520             array  = test_case.m_is_input ? "[]" : "";
16521             index  = test_case.m_is_input ? "[0]" : "";
16522             break;
16523         case Utils::Shader::VERTEX:
16524             source = vs_tested;
16525             break;
16526         default:
16527             TCU_FAIL("Invalid enum");
16528         }
16529 
16530         Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
16531         position = 0;
16532         Utils::replaceToken("COMPONENT", position, buffer, source);
16533         Utils::replaceToken("FLAT", position, flat, source);
16534         Utils::replaceToken("DIRECTION", position, direction, source);
16535         Utils::replaceToken("ARRAY", position, array, source);
16536         Utils::replaceToken("VARIABLE_USE", position, var_use, source);
16537 
16538         Utils::replaceAllTokens("TYPE", type_name, source);
16539         Utils::replaceAllTokens("INDEX", index, source);
16540     }
16541     else
16542     {
16543         switch (stage)
16544         {
16545         case Utils::Shader::FRAGMENT:
16546             source = fs;
16547             break;
16548         case Utils::Shader::GEOMETRY:
16549             source = gs;
16550             break;
16551         case Utils::Shader::TESS_CTRL:
16552             source = tcs;
16553             break;
16554         case Utils::Shader::TESS_EVAL:
16555             source = tes;
16556             break;
16557         case Utils::Shader::VERTEX:
16558             source = vs;
16559             break;
16560         default:
16561             TCU_FAIL("Invalid enum");
16562         }
16563     }
16564 
16565     return source;
16566 }
16567 
16568 /** Get description of test case
16569  *
16570  * @param test_case_index Index of test case
16571  *
16572  * @return Test case description
16573  **/
16574 std::string VaryingComponentWithoutLocationTest::getTestCaseName(GLuint test_case_index)
16575 {
16576     std::stringstream stream;
16577     testCase &test_case = m_test_cases[test_case_index];
16578 
16579     stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
16580            << " type: " << test_case.m_type.GetGLSLTypeName() << ", direction: ";
16581 
16582     if (true == test_case.m_is_input)
16583     {
16584         stream << "input";
16585     }
16586     else
16587     {
16588         stream << "output";
16589     }
16590 
16591     stream << ", component: " << test_case.m_component;
16592 
16593     return stream.str();
16594 }
16595 
16596 /** Get number of test cases
16597  *
16598  * @return Number of test cases
16599  **/
16600 GLuint VaryingComponentWithoutLocationTest::getTestCaseNumber()
16601 {
16602     return static_cast<GLuint>(m_test_cases.size());
16603 }
16604 
16605 /** Selects if "compute" stage is relevant for test
16606  *
16607  * @param ignored
16608  *
16609  * @return false
16610  **/
16611 bool VaryingComponentWithoutLocationTest::isComputeRelevant(GLuint /* test_case_index */)
16612 {
16613     return false;
16614 }
16615 
16616 /** Prepare all test cases
16617  *
16618  **/
16619 void VaryingComponentWithoutLocationTest::testInit()
16620 {
16621     const GLuint n_types = getTypesNumber();
16622 
16623     for (GLuint i = 0; i < n_types; ++i)
16624     {
16625         const Utils::Type &type                     = getType(i);
16626         const std::vector<GLuint> &valid_components = type.GetValidComponents();
16627 
16628         if (valid_components.empty())
16629         {
16630             continue;
16631         }
16632 
16633         for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
16634         {
16635             if (Utils::Shader::COMPUTE == stage)
16636             {
16637                 continue;
16638             }
16639 
16640             testCase test_case_in  = {valid_components.back(), true, (Utils::Shader::STAGES)stage, type};
16641             testCase test_case_out = {valid_components.back(), false, (Utils::Shader::STAGES)stage, type};
16642 
16643             m_test_cases.push_back(test_case_in);
16644 
16645             if (Utils::Shader::FRAGMENT != stage)
16646             {
16647                 m_test_cases.push_back(test_case_out);
16648             }
16649         }
16650     }
16651 }
16652 
16653 /** Constructor
16654  *
16655  * @param context Test framework context
16656  **/
16657 VaryingComponentOfInvalidTypeTest::VaryingComponentOfInvalidTypeTest(deqp::Context &context)
16658     : NegativeTestBase(context, "varying_component_of_invalid_type",
16659                        "Test verifies that compiler reports error when component qualifier is used for invalid type")
16660 {
16661 }
16662 
16663 /** Source for given test case and stage
16664  *
16665  * @param test_case_index Index of test case
16666  * @param stage           Shader stage
16667  *
16668  * @return Shader source
16669  **/
16670 std::string VaryingComponentOfInvalidTypeTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
16671 {
16672     static const GLchar *block_definition_arr = "layout (location = 1COMPONENT) DIRECTION Goku {\n"
16673                                                 "    FLAT TYPE member;\n"
16674                                                 "} gokuARRAY[1];\n";
16675     static const GLchar *block_definition_one = "layout (location = 1COMPONENT) DIRECTION Goku {\n"
16676                                                 "    FLAT TYPE member;\n"
16677                                                 "} gokuARRAY;\n";
16678     static const GLchar *matrix_dvec3_dvec4_definition_arr =
16679         "layout (location = 1COMPONENT) FLAT DIRECTION TYPE gokuARRAY[1];\n";
16680     static const GLchar *matrix_dvec3_dvec4_definition_one =
16681         "layout (location = 1COMPONENT) FLAT DIRECTION TYPE gokuARRAY;\n";
16682     static const GLchar *struct_definition_arr             = "struct Goku {\n"
16683                                                              "    TYPE member;\n"
16684                                                              "};\n"
16685                                                              "\n"
16686                                                              "layout (location = 1COMPONENT) FLAT DIRECTION Goku gokuARRAY[1];\n";
16687     static const GLchar *struct_definition_one             = "struct Goku {\n"
16688                                                              "    TYPE member;\n"
16689                                                              "};\n"
16690                                                              "\n"
16691                                                              "layout (location = 1COMPONENT) FLAT DIRECTION Goku gokuARRAY;\n";
16692     static const GLchar *matrix_dvec3_dvec4_input_use_arr  = "    if (TYPE(0) == gokuINDEX[0])\n"
16693                                                              "    {\n"
16694                                                              "        result += vec4(1, 0.5, 0.25, 0.125);\n"
16695                                                              "    }\n";
16696     static const GLchar *matrix_dvec3_dvec4_input_use_one  = "    if (TYPE(0) == gokuINDEX)\n"
16697                                                              "    {\n"
16698                                                              "        result += vec4(1, 0.5, 0.25, 0.125);\n"
16699                                                              "    }\n";
16700     static const GLchar *matrix_dvec3_dvec4_output_use_arr = "    gokuINDEX[0] = TYPE(0);\n"
16701                                                              "    if (vec4(0) == result)\n"
16702                                                              "    {\n"
16703                                                              "        gokuINDEX[0] = TYPE(1);\n"
16704                                                              "    }\n";
16705     static const GLchar *matrix_dvec3_dvec4_output_use_one = "    gokuINDEX = TYPE(0);\n"
16706                                                              "    if (vec4(0) == result)\n"
16707                                                              "    {\n"
16708                                                              "        gokuINDEX = TYPE(1);\n"
16709                                                              "    }\n";
16710     static const GLchar *member_input_use_arr              = "    if (TYPE(0) == gokuINDEX[0].member)\n"
16711                                                              "    {\n"
16712                                                              "        result += vec4(1, 0.5, 0.25, 0.125);\n"
16713                                                              "    }\n";
16714     static const GLchar *member_input_use_one              = "    if (TYPE(0) == gokuINDEX.member)\n"
16715                                                              "    {\n"
16716                                                              "        result += vec4(1, 0.5, 0.25, 0.125);\n"
16717                                                              "    }\n";
16718     static const GLchar *member_output_use_arr             = "    gokuINDEX[0].member = TYPE(0);\n"
16719                                                              "    if (vec4(0) == result)\n"
16720                                                              "    {\n"
16721                                                              "        gokuINDEX[0].member = TYPE(1);\n"
16722                                                              "    }\n";
16723     static const GLchar *member_output_use_one             = "    gokuINDEX.member = TYPE(0);\n"
16724                                                              "    if (vec4(0) == result)\n"
16725                                                              "    {\n"
16726                                                              "        gokuINDEX.member = TYPE(1);\n"
16727                                                              "    }\n";
16728     static const GLchar *fs                                = "#version 430 core\n"
16729                                                              "#extension GL_ARB_enhanced_layouts : require\n"
16730                                                              "\n"
16731                                                              "in  vec4 gs_fs;\n"
16732                                                              "out vec4 fs_out;\n"
16733                                                              "\n"
16734                                                              "void main()\n"
16735                                                              "{\n"
16736                                                              "    fs_out = gs_fs;\n"
16737                                                              "}\n"
16738                                                              "\n";
16739     static const GLchar *fs_tested                         = "#version 430 core\n"
16740                                                              "#extension GL_ARB_enhanced_layouts : require\n"
16741                                                              "\n"
16742                                                              "VAR_DEFINITION"
16743                                                              "\n"
16744                                                              "in  vec4 gs_fs;\n"
16745                                                              "out vec4 fs_out;\n"
16746                                                              "\n"
16747                                                              "void main()\n"
16748                                                              "{\n"
16749                                                              "    vec4 result = gs_fs;\n"
16750                                                              "\n"
16751                                                              "VARIABLE_USE"
16752                                                              "\n"
16753                                                              "    fs_out += result;\n"
16754                                                              "}\n"
16755                                                              "\n";
16756     static const GLchar *gs                                = "#version 430 core\n"
16757                                                              "#extension GL_ARB_enhanced_layouts : require\n"
16758                                                              "\n"
16759                                                              "layout(points)                           in;\n"
16760                                                              "layout(triangle_strip, max_vertices = 4) out;\n"
16761                                                              "\n"
16762                                                              "in  vec4 tes_gs[];\n"
16763                                                              "out vec4 gs_fs;\n"
16764                                                              "\n"
16765                                                              "void main()\n"
16766                                                              "{\n"
16767                                                              "    gs_fs = tes_gs[0];\n"
16768                                                              "    gl_Position  = vec4(-1, -1, 0, 1);\n"
16769                                                              "    EmitVertex();\n"
16770                                                              "    gs_fs = tes_gs[0];\n"
16771                                                              "    gl_Position  = vec4(-1, 1, 0, 1);\n"
16772                                                              "    EmitVertex();\n"
16773                                                              "    gs_fs = tes_gs[0];\n"
16774                                                              "    gl_Position  = vec4(1, -1, 0, 1);\n"
16775                                                              "    EmitVertex();\n"
16776                                                              "    gs_fs = tes_gs[0];\n"
16777                                                              "    gl_Position  = vec4(1, 1, 0, 1);\n"
16778                                                              "    EmitVertex();\n"
16779                                                              "}\n"
16780                                                              "\n";
16781     static const GLchar *gs_tested                         = "#version 430 core\n"
16782                                                              "#extension GL_ARB_enhanced_layouts : require\n"
16783                                                              "\n"
16784                                                              "layout(points)                           in;\n"
16785                                                              "layout(triangle_strip, max_vertices = 4) out;\n"
16786                                                              "\n"
16787                                                              "VAR_DEFINITION"
16788                                                              "\n"
16789                                                              "in  vec4 tes_gs[];\n"
16790                                                              "out vec4 gs_fs;\n"
16791                                                              "\n"
16792                                                              "void main()\n"
16793                                                              "{\n"
16794                                                              "    vec4 result = tes_gs[0];\n"
16795                                                              "\n"
16796                                                              "VARIABLE_USE"
16797                                                              "\n"
16798                                                              "    gs_fs = result;\n"
16799                                                              "    gl_Position  = vec4(-1, -1, 0, 1);\n"
16800                                                              "    EmitVertex();\n"
16801                                                              "    gs_fs = result;\n"
16802                                                              "    gl_Position  = vec4(-1, 1, 0, 1);\n"
16803                                                              "    EmitVertex();\n"
16804                                                              "    gs_fs = result;\n"
16805                                                              "    gl_Position  = vec4(1, -1, 0, 1);\n"
16806                                                              "    EmitVertex();\n"
16807                                                              "    gs_fs = result;\n"
16808                                                              "    gl_Position  = vec4(1, 1, 0, 1);\n"
16809                                                              "    EmitVertex();\n"
16810                                                              "}\n"
16811                                                              "\n";
16812     static const GLchar *tcs                               = "#version 430 core\n"
16813                                                              "#extension GL_ARB_enhanced_layouts : require\n"
16814                                                              "\n"
16815                                                              "layout(vertices = 1) out;\n"
16816                                                              "\n"
16817                                                              "in  vec4 vs_tcs[];\n"
16818                                                              "out vec4 tcs_tes[];\n"
16819                                                              "\n"
16820                                                              "void main()\n"
16821                                                              "{\n"
16822                                                              "\n"
16823                                                              "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
16824                                                              "\n"
16825                                                              "    gl_TessLevelOuter[0] = 1.0;\n"
16826                                                              "    gl_TessLevelOuter[1] = 1.0;\n"
16827                                                              "    gl_TessLevelOuter[2] = 1.0;\n"
16828                                                              "    gl_TessLevelOuter[3] = 1.0;\n"
16829                                                              "    gl_TessLevelInner[0] = 1.0;\n"
16830                                                              "    gl_TessLevelInner[1] = 1.0;\n"
16831                                                              "}\n"
16832                                                              "\n";
16833     static const GLchar *tcs_tested                        = "#version 430 core\n"
16834                                                              "#extension GL_ARB_enhanced_layouts : require\n"
16835                                                              "\n"
16836                                                              "layout(vertices = 1) out;\n"
16837                                                              "\n"
16838                                                              "VAR_DEFINITION"
16839                                                              "\n"
16840                                                              "in  vec4 vs_tcs[];\n"
16841                                                              "out vec4 tcs_tes[];\n"
16842                                                              "\n"
16843                                                              "void main()\n"
16844                                                              "{\n"
16845                                                              "    vec4 result = vs_tcs[gl_InvocationID];\n"
16846                                                              "\n"
16847                                                              "VARIABLE_USE"
16848                                                              "\n"
16849                                                              "    tcs_tes[gl_InvocationID] = result;\n"
16850                                                              "\n"
16851                                                              "    gl_TessLevelOuter[0] = 1.0;\n"
16852                                                              "    gl_TessLevelOuter[1] = 1.0;\n"
16853                                                              "    gl_TessLevelOuter[2] = 1.0;\n"
16854                                                              "    gl_TessLevelOuter[3] = 1.0;\n"
16855                                                              "    gl_TessLevelInner[0] = 1.0;\n"
16856                                                              "    gl_TessLevelInner[1] = 1.0;\n"
16857                                                              "}\n"
16858                                                              "\n";
16859     static const GLchar *tes                               = "#version 430 core\n"
16860                                                              "#extension GL_ARB_enhanced_layouts : require\n"
16861                                                              "\n"
16862                                                              "layout(isolines, point_mode) in;\n"
16863                                                              "\n"
16864                                                              "in  vec4 tcs_tes[];\n"
16865                                                              "out vec4 tes_gs;\n"
16866                                                              "\n"
16867                                                              "void main()\n"
16868                                                              "{\n"
16869                                                              "    tes_gs = tcs_tes[0];\n"
16870                                                              "}\n"
16871                                                              "\n";
16872     static const GLchar *tes_tested                        = "#version 430 core\n"
16873                                                              "#extension GL_ARB_enhanced_layouts : require\n"
16874                                                              "\n"
16875                                                              "layout(isolines, point_mode) in;\n"
16876                                                              "\n"
16877                                                              "VAR_DEFINITION"
16878                                                              "\n"
16879                                                              "in  vec4 tcs_tes[];\n"
16880                                                              "out vec4 tes_gs;\n"
16881                                                              "\n"
16882                                                              "void main()\n"
16883                                                              "{\n"
16884                                                              "    vec4 result = tcs_tes[0];\n"
16885                                                              "\n"
16886                                                              "VARIABLE_USE"
16887                                                              "\n"
16888                                                              "    tes_gs += result;\n"
16889                                                              "}\n"
16890                                                              "\n";
16891     static const GLchar *vs                                = "#version 430 core\n"
16892                                                              "#extension GL_ARB_enhanced_layouts : require\n"
16893                                                              "\n"
16894                                                              "in  vec4 in_vs;\n"
16895                                                              "out vec4 vs_tcs;\n"
16896                                                              "\n"
16897                                                              "void main()\n"
16898                                                              "{\n"
16899                                                              "    vs_tcs = in_vs;\n"
16900                                                              "}\n"
16901                                                              "\n";
16902     static const GLchar *vs_tested                         = "#version 430 core\n"
16903                                                              "#extension GL_ARB_enhanced_layouts : require\n"
16904                                                              "\n"
16905                                                              "VAR_DEFINITION"
16906                                                              "\n"
16907                                                              "in  vec4 in_vs;\n"
16908                                                              "out vec4 vs_tcs;\n"
16909                                                              "\n"
16910                                                              "void main()\n"
16911                                                              "{\n"
16912                                                              "    vec4 result = in_vs;\n"
16913                                                              "\n"
16914                                                              "VARIABLE_USE"
16915                                                              "\n"
16916                                                              "    vs_tcs += result;\n"
16917                                                              "}\n"
16918                                                              "\n";
16919 
16920     std::string source;
16921     testCase &test_case = m_test_cases[test_case_index];
16922 
16923     if (test_case.m_stage == stage)
16924     {
16925         const GLchar *array = "";
16926         GLchar buffer[32];
16927         const GLchar *var_definition     = 0;
16928         const GLchar *direction          = "in ";
16929         const GLchar *index              = "";
16930         size_t position                  = 0;
16931         const GLchar *type_name          = test_case.m_type.GetGLSLTypeName();
16932         const GLchar *var_use            = 0;
16933         Utils::Variable::STORAGE storage = Utils::Variable::VARYING_INPUT;
16934         const GLchar *flat               = "";
16935 
16936         if (false == test_case.m_is_input)
16937         {
16938             direction = "out";
16939             storage   = Utils::Variable::VARYING_OUTPUT;
16940 
16941             if (false == test_case.m_is_array)
16942             {
16943                 switch (test_case.m_case)
16944                 {
16945                 case BLOCK:
16946                     var_definition = block_definition_one;
16947                     var_use        = member_output_use_one;
16948                     break;
16949                 case MATRIX:
16950                 case DVEC3_DVEC4:
16951                     var_definition = matrix_dvec3_dvec4_definition_one;
16952                     var_use        = matrix_dvec3_dvec4_output_use_one;
16953                     break;
16954                 case STRUCT:
16955                     var_definition = struct_definition_one;
16956                     var_use        = member_output_use_one;
16957                     break;
16958                 default:
16959                     TCU_FAIL("Invalid enum");
16960                 }
16961             }
16962             else
16963             {
16964                 switch (test_case.m_case)
16965                 {
16966                 case BLOCK:
16967                     var_definition = block_definition_arr;
16968                     var_use        = member_output_use_arr;
16969                     break;
16970                 case MATRIX:
16971                 case DVEC3_DVEC4:
16972                     var_definition = matrix_dvec3_dvec4_definition_arr;
16973                     var_use        = matrix_dvec3_dvec4_output_use_arr;
16974                     break;
16975                 case STRUCT:
16976                     var_definition = struct_definition_arr;
16977                     var_use        = member_output_use_arr;
16978                     break;
16979                 default:
16980                     TCU_FAIL("Invalid enum");
16981                 }
16982             }
16983         }
16984         else
16985         {
16986             if (false == test_case.m_is_array)
16987             {
16988                 switch (test_case.m_case)
16989                 {
16990                 case BLOCK:
16991                     var_definition = block_definition_one;
16992                     var_use        = Utils::Shader::VERTEX == stage ? member_input_use_one : "\n";
16993                     break;
16994                 case MATRIX:
16995                 case DVEC3_DVEC4:
16996                     var_definition = matrix_dvec3_dvec4_definition_one;
16997                     var_use        = Utils::Shader::VERTEX == stage ? matrix_dvec3_dvec4_input_use_one : "\n";
16998                     break;
16999                 case STRUCT:
17000                     var_definition = struct_definition_one;
17001                     var_use        = Utils::Shader::VERTEX == stage ? member_input_use_one : "\n";
17002                     break;
17003                 default:
17004                     TCU_FAIL("Invalid enum");
17005                 }
17006             }
17007             else
17008             {
17009                 switch (test_case.m_case)
17010                 {
17011                 case BLOCK:
17012                     var_definition = block_definition_arr;
17013                     var_use        = Utils::Shader::VERTEX == stage ? member_input_use_arr : "\n";
17014                     break;
17015                 case MATRIX:
17016                 case DVEC3_DVEC4:
17017                     var_definition = matrix_dvec3_dvec4_definition_arr;
17018                     var_use        = Utils::Shader::VERTEX == stage ? matrix_dvec3_dvec4_input_use_arr : "\n";
17019                     break;
17020                 case STRUCT:
17021                     var_definition = struct_definition_arr;
17022                     var_use        = Utils::Shader::VERTEX == stage ? member_input_use_arr : "\n";
17023                     break;
17024                 default:
17025                     TCU_FAIL("Invalid enum");
17026                 }
17027             }
17028         }
17029 
17030         if (isFlatRequired(stage, test_case.m_type, storage))
17031         {
17032             flat = "flat";
17033         }
17034 
17035 #if DEBUG_NEG_REMOVE_ERROR
17036         sprintf(buffer, " /* , component = %d */", test_case.m_component);
17037 #else
17038         sprintf(buffer, ", component = %d", test_case.m_component);
17039 #endif /* DEBUG_NEG_REMOVE_ERROR */
17040 
17041         switch (stage)
17042         {
17043         case Utils::Shader::FRAGMENT:
17044             source = fs_tested;
17045             break;
17046         case Utils::Shader::GEOMETRY:
17047             source = gs_tested;
17048             array  = test_case.m_is_input ? "[]" : "";
17049             index  = test_case.m_is_input ? "[0]" : "";
17050             break;
17051         case Utils::Shader::TESS_CTRL:
17052             source = tcs_tested;
17053             array  = "[]";
17054             index  = "[gl_InvocationID]";
17055             break;
17056         case Utils::Shader::TESS_EVAL:
17057             source = tes_tested;
17058             array  = test_case.m_is_input ? "[]" : "";
17059             index  = test_case.m_is_input ? "[0]" : "";
17060             break;
17061         case Utils::Shader::VERTEX:
17062             source = vs_tested;
17063             break;
17064         default:
17065             TCU_FAIL("Invalid enum");
17066         }
17067 
17068         Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
17069         position = 0;
17070         Utils::replaceToken("COMPONENT", position, buffer, source);
17071         Utils::replaceToken("DIRECTION", position, direction, source);
17072         Utils::replaceToken("ARRAY", position, array, source);
17073         Utils::replaceToken("VARIABLE_USE", position, var_use, source);
17074 
17075         Utils::replaceAllTokens("FLAT", flat, source);
17076         Utils::replaceAllTokens("TYPE", type_name, source);
17077         Utils::replaceAllTokens("INDEX", index, source);
17078     }
17079     else
17080     {
17081         switch (stage)
17082         {
17083         case Utils::Shader::FRAGMENT:
17084             source = fs;
17085             break;
17086         case Utils::Shader::GEOMETRY:
17087             source = gs;
17088             break;
17089         case Utils::Shader::TESS_CTRL:
17090             source = tcs;
17091             break;
17092         case Utils::Shader::TESS_EVAL:
17093             source = tes;
17094             break;
17095         case Utils::Shader::VERTEX:
17096             source = vs;
17097             break;
17098         default:
17099             TCU_FAIL("Invalid enum");
17100         }
17101     }
17102 
17103     return source;
17104 }
17105 
17106 /** Get description of test case
17107  *
17108  * @param test_case_index Index of test case
17109  *
17110  * @return Test case description
17111  **/
17112 std::string VaryingComponentOfInvalidTypeTest::getTestCaseName(GLuint test_case_index)
17113 {
17114     std::stringstream stream;
17115     testCase &test_case = m_test_cases[test_case_index];
17116 
17117     stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
17118            << " type: " << test_case.m_type.GetGLSLTypeName();
17119 
17120     if (true == test_case.m_is_array)
17121     {
17122         stream << "[1]";
17123     }
17124 
17125     stream << ", direction: ";
17126 
17127     if (true == test_case.m_is_input)
17128     {
17129         stream << "input";
17130     }
17131     else
17132     {
17133         stream << "output";
17134     }
17135 
17136     stream << ", component: " << test_case.m_component;
17137 
17138     return stream.str();
17139 }
17140 
17141 /** Get number of test cases
17142  *
17143  * @return Number of test cases
17144  **/
17145 GLuint VaryingComponentOfInvalidTypeTest::getTestCaseNumber()
17146 {
17147     return static_cast<GLuint>(m_test_cases.size());
17148 }
17149 
17150 /** Selects if "compute" stage is relevant for test
17151  *
17152  * @param ignored
17153  *
17154  * @return false
17155  **/
17156 bool VaryingComponentOfInvalidTypeTest::isComputeRelevant(GLuint /* test_case_index */)
17157 {
17158     return false;
17159 }
17160 
17161 /** Prepare all test cases
17162  *
17163  **/
17164 void VaryingComponentOfInvalidTypeTest::testInit()
17165 {
17166     const GLuint n_types = getTypesNumber();
17167 
17168     for (GLuint i = 0; i < n_types; ++i)
17169     {
17170         const Utils::Type &type                     = getType(i);
17171         const std::vector<GLuint> &valid_components = type.GetValidComponents();
17172 
17173         for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
17174         {
17175             if (Utils::Shader::COMPUTE == stage)
17176             {
17177                 continue;
17178             }
17179 
17180             /* matrices */
17181             if (1 != type.m_n_columns)
17182             {
17183                 testCase test_case_in_arr  = {MATRIX, 0, true, true, (Utils::Shader::STAGES)stage, type};
17184                 testCase test_case_in_one  = {MATRIX, 0, false, true, (Utils::Shader::STAGES)stage, type};
17185                 testCase test_case_out_arr = {MATRIX, 0, true, false, (Utils::Shader::STAGES)stage, type};
17186                 testCase test_case_out_one = {MATRIX, 0, false, false, (Utils::Shader::STAGES)stage, type};
17187 
17188                 m_test_cases.push_back(test_case_in_arr);
17189                 m_test_cases.push_back(test_case_in_one);
17190 
17191                 if (Utils::Shader::FRAGMENT != stage)
17192                 {
17193                     m_test_cases.push_back(test_case_out_arr);
17194                     m_test_cases.push_back(test_case_out_one);
17195                 }
17196             }
17197             else if (Utils::Type::Double == type.m_basic_type && 2 < type.m_n_rows) /* dvec3 and dvec4 */
17198             {
17199                 testCase test_case_in_arr  = {DVEC3_DVEC4, 0, true, true, (Utils::Shader::STAGES)stage, type};
17200                 testCase test_case_in_one  = {DVEC3_DVEC4, 0, false, true, (Utils::Shader::STAGES)stage, type};
17201                 testCase test_case_out_arr = {DVEC3_DVEC4, 0, true, false, (Utils::Shader::STAGES)stage, type};
17202                 testCase test_case_out_one = {DVEC3_DVEC4, 0, false, false, (Utils::Shader::STAGES)stage, type};
17203 
17204                 m_test_cases.push_back(test_case_in_arr);
17205                 m_test_cases.push_back(test_case_in_one);
17206 
17207                 if (Utils::Shader::FRAGMENT != stage)
17208                 {
17209                     m_test_cases.push_back(test_case_out_arr);
17210                     m_test_cases.push_back(test_case_out_one);
17211                 }
17212             }
17213             else
17214             {
17215                 if (valid_components.empty())
17216                 {
17217                     TCU_FAIL("Unhandled type");
17218                 }
17219 
17220                 for (GLuint c = BLOCK; c < MAX_CASES; ++c)
17221                 {
17222                     testCase test_case_in_arr  = {(CASES)c, valid_components.back(),      true,
17223                                                   true,     (Utils::Shader::STAGES)stage, type};
17224                     testCase test_case_in_one  = {(CASES)c, valid_components.back(),      false,
17225                                                   true,     (Utils::Shader::STAGES)stage, type};
17226                     testCase test_case_out_arr = {(CASES)c, valid_components.back(),      true,
17227                                                   false,    (Utils::Shader::STAGES)stage, type};
17228                     testCase test_case_out_one = {(CASES)c, valid_components.back(),      false,
17229                                                   false,    (Utils::Shader::STAGES)stage, type};
17230 
17231                     if (Utils::Shader::VERTEX != stage)
17232                     {
17233                         m_test_cases.push_back(test_case_in_arr);
17234                         m_test_cases.push_back(test_case_in_one);
17235                     }
17236 
17237                     if (Utils::Shader::FRAGMENT != stage)
17238                     {
17239                         m_test_cases.push_back(test_case_out_arr);
17240                         m_test_cases.push_back(test_case_out_one);
17241                     }
17242                 }
17243             }
17244         }
17245     }
17246 }
17247 
17248 /** Constructor
17249  *
17250  * @param context Test framework context
17251  **/
17252 InputComponentAliasingTest::InputComponentAliasingTest(deqp::Context &context)
17253     : NegativeTestBase(context, "input_component_aliasing",
17254                        "Test verifies that compiler reports component aliasing as error")
17255 {
17256 }
17257 
17258 /** Source for given test case and stage
17259  *
17260  * @param test_case_index Index of test case
17261  * @param stage           Shader stage
17262  *
17263  * @return Shader source
17264  **/
17265 std::string InputComponentAliasingTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
17266 {
17267     static const GLchar *var_definition =
17268         "layout (location = 1, component = COMPONENT) FLAT in TYPE gohanARRAY;\n"
17269 #if DEBUG_NEG_REMOVE_ERROR
17270         "/* layout (location = 1, component = COMPONENT) */ FLAT in TYPE gotenARRAY;\n";
17271 #else
17272         "layout (location = 1, component = COMPONENT) FLAT in TYPE gotenARRAY;\n";
17273 #endif /* DEBUG_NEG_REMOVE_ERROR */
17274     static const GLchar *test_one   = "    if (TYPE(0) == gohanINDEX)\n"
17275                                       "    {\n"
17276                                       "        result += vec4(1, 0.5, 0.25, 0.125);\n"
17277                                       "    }\n";
17278     static const GLchar *fs         = "#version 430 core\n"
17279                                       "#extension GL_ARB_enhanced_layouts : require\n"
17280                                       "\n"
17281                                       "in  vec4 gs_fs;\n"
17282                                       "out vec4 fs_out;\n"
17283                                       "\n"
17284                                       "void main()\n"
17285                                       "{\n"
17286                                       "    fs_out = gs_fs;\n"
17287                                       "}\n"
17288                                       "\n";
17289     static const GLchar *fs_tested  = "#version 430 core\n"
17290                                       "#extension GL_ARB_enhanced_layouts : require\n"
17291                                       "\n"
17292                                       "VAR_DEFINITION"
17293                                       "\n"
17294                                       "in  vec4 gs_fs;\n"
17295                                       "out vec4 fs_out;\n"
17296                                       "\n"
17297                                       "void main()\n"
17298                                       "{\n"
17299                                       "    vec4 result = gs_fs;\n"
17300                                       "\n"
17301                                       "VARIABLE_USE"
17302                                       "\n"
17303                                       "    fs_out += result;\n"
17304                                       "}\n"
17305                                       "\n";
17306     static const GLchar *gs         = "#version 430 core\n"
17307                                       "#extension GL_ARB_enhanced_layouts : require\n"
17308                                       "\n"
17309                                       "layout(points)                           in;\n"
17310                                       "layout(triangle_strip, max_vertices = 4) out;\n"
17311                                       "\n"
17312                                       "layout (location = 1, component = COMPONENT) FLAT out TYPE gohan;\n"
17313                                       "\n"
17314                                       "in  vec4 tes_gs[];\n"
17315                                       "out vec4 gs_fs;\n"
17316                                       "\n"
17317                                       "void main()\n"
17318                                       "{\n"
17319                                       "    gohan = TYPE(1);\n"
17320                                       "\n"
17321                                       "    gs_fs = tes_gs[0];\n"
17322                                       "    gl_Position  = vec4(-1, -1, 0, 1);\n"
17323                                       "    EmitVertex();\n"
17324                                       "    gs_fs = tes_gs[0];\n"
17325                                       "    gl_Position  = vec4(-1, 1, 0, 1);\n"
17326                                       "    EmitVertex();\n"
17327                                       "    gs_fs = tes_gs[0];\n"
17328                                       "    gl_Position  = vec4(1, -1, 0, 1);\n"
17329                                       "    EmitVertex();\n"
17330                                       "    gs_fs = tes_gs[0];\n"
17331                                       "    gl_Position  = vec4(1, 1, 0, 1);\n"
17332                                       "    EmitVertex();\n"
17333                                       "}\n"
17334                                       "\n";
17335     static const GLchar *gs_tested  = "#version 430 core\n"
17336                                       "#extension GL_ARB_enhanced_layouts : require\n"
17337                                       "\n"
17338                                       "layout(points)                           in;\n"
17339                                       "layout(triangle_strip, max_vertices = 4) out;\n"
17340                                       "\n"
17341                                       "VAR_DEFINITION"
17342                                       "\n"
17343                                       "in  vec4 tes_gs[];\n"
17344                                       "out vec4 gs_fs;\n"
17345                                       "\n"
17346                                       "void main()\n"
17347                                       "{\n"
17348                                       "    vec4 result = tes_gs[0];\n"
17349                                       "\n"
17350                                       "VARIABLE_USE"
17351                                       "\n"
17352                                       "    gs_fs = result;\n"
17353                                       "    gl_Position  = vec4(-1, -1, 0, 1);\n"
17354                                       "    EmitVertex();\n"
17355                                       "    gs_fs = result;\n"
17356                                       "    gl_Position  = vec4(-1, 1, 0, 1);\n"
17357                                       "    EmitVertex();\n"
17358                                       "    gs_fs = result;\n"
17359                                       "    gl_Position  = vec4(1, -1, 0, 1);\n"
17360                                       "    EmitVertex();\n"
17361                                       "    gs_fs = result;\n"
17362                                       "    gl_Position  = vec4(1, 1, 0, 1);\n"
17363                                       "    EmitVertex();\n"
17364                                       "}\n"
17365                                       "\n";
17366     static const GLchar *tcs        = "#version 430 core\n"
17367                                       "#extension GL_ARB_enhanced_layouts : require\n"
17368                                       "\n"
17369                                       "layout(vertices = 1) out;\n"
17370                                       "\n"
17371                                       "layout (location = 1, component = COMPONENT) FLAT out TYPE gohan[];\n"
17372                                       "\n"
17373                                       "in  vec4 vs_tcs[];\n"
17374                                       "out vec4 tcs_tes[];\n"
17375                                       "\n"
17376                                       "void main()\n"
17377                                       "{\n"
17378                                       "    gohan[gl_InvocationID] = TYPE(1);\n"
17379                                       "\n"
17380                                       "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
17381                                       "\n"
17382                                       "    gl_TessLevelOuter[0] = 1.0;\n"
17383                                       "    gl_TessLevelOuter[1] = 1.0;\n"
17384                                       "    gl_TessLevelOuter[2] = 1.0;\n"
17385                                       "    gl_TessLevelOuter[3] = 1.0;\n"
17386                                       "    gl_TessLevelInner[0] = 1.0;\n"
17387                                       "    gl_TessLevelInner[1] = 1.0;\n"
17388                                       "}\n"
17389                                       "\n";
17390     static const GLchar *tcs_tested = "#version 430 core\n"
17391                                       "#extension GL_ARB_enhanced_layouts : require\n"
17392                                       "\n"
17393                                       "layout(vertices = 1) out;\n"
17394                                       "\n"
17395                                       "VAR_DEFINITION"
17396                                       "\n"
17397                                       "in  vec4 vs_tcs[];\n"
17398                                       "out vec4 tcs_tes[];\n"
17399                                       "\n"
17400                                       "void main()\n"
17401                                       "{\n"
17402                                       "    vec4 result = vs_tcs[gl_InvocationID];\n"
17403                                       "\n"
17404                                       "VARIABLE_USE"
17405                                       "\n"
17406                                       "    tcs_tes[gl_InvocationID] = result;\n"
17407                                       "\n"
17408                                       "    gl_TessLevelOuter[0] = 1.0;\n"
17409                                       "    gl_TessLevelOuter[1] = 1.0;\n"
17410                                       "    gl_TessLevelOuter[2] = 1.0;\n"
17411                                       "    gl_TessLevelOuter[3] = 1.0;\n"
17412                                       "    gl_TessLevelInner[0] = 1.0;\n"
17413                                       "    gl_TessLevelInner[1] = 1.0;\n"
17414                                       "}\n"
17415                                       "\n";
17416     static const GLchar *tes        = "#version 430 core\n"
17417                                       "#extension GL_ARB_enhanced_layouts : require\n"
17418                                       "\n"
17419                                       "layout(isolines, point_mode) in;\n"
17420                                       "\n"
17421                                       "layout (location = 1, component = COMPONENT) FLAT out TYPE gohan;\n"
17422                                       "\n"
17423                                       "in  vec4 tcs_tes[];\n"
17424                                       "out vec4 tes_gs;\n"
17425                                       "\n"
17426                                       "void main()\n"
17427                                       "{\n"
17428                                       "    gohan = TYPE(1);\n"
17429                                       "\n"
17430                                       "    tes_gs = tcs_tes[0];\n"
17431                                       "}\n"
17432                                       "\n";
17433     static const GLchar *tes_tested = "#version 430 core\n"
17434                                       "#extension GL_ARB_enhanced_layouts : require\n"
17435                                       "\n"
17436                                       "layout(isolines, point_mode) in;\n"
17437                                       "\n"
17438                                       "VAR_DEFINITION"
17439                                       "\n"
17440                                       "in  vec4 tcs_tes[];\n"
17441                                       "out vec4 tes_gs;\n"
17442                                       "\n"
17443                                       "void main()\n"
17444                                       "{\n"
17445                                       "    vec4 result = tcs_tes[0];\n"
17446                                       "\n"
17447                                       "VARIABLE_USE"
17448                                       "\n"
17449                                       "    tes_gs += result;\n"
17450                                       "}\n"
17451                                       "\n";
17452     static const GLchar *vs         = "#version 430 core\n"
17453                                       "#extension GL_ARB_enhanced_layouts : require\n"
17454                                       "\n"
17455                                       "layout (location = 1, component = COMPONENT) FLAT out TYPE gohan;\n"
17456                                       "\n"
17457                                       "in  vec4 in_vs;\n"
17458                                       "out vec4 vs_tcs;\n"
17459                                       "\n"
17460                                       "void main()\n"
17461                                       "{\n"
17462                                       "    gohan = TYPE(1);\n"
17463                                       "\n"
17464                                       "    vs_tcs = in_vs;\n"
17465                                       "}\n"
17466                                       "\n";
17467     static const GLchar *vs_tested  = "#version 430 core\n"
17468                                       "#extension GL_ARB_enhanced_layouts : require\n"
17469                                       "\n"
17470                                       "VAR_DEFINITION"
17471                                       "\n"
17472                                       "in  vec4 in_vs;\n"
17473                                       "out vec4 vs_tcs;\n"
17474                                       "\n"
17475                                       "void main()\n"
17476                                       "{\n"
17477                                       "    vec4 result = in_vs;\n"
17478                                       "\n"
17479                                       "VARIABLE_USE"
17480                                       "\n"
17481                                       "    vs_tcs += result;\n"
17482                                       "}\n"
17483                                       "\n";
17484 
17485     std::string source;
17486     testCase &test_case = m_test_cases[test_case_index];
17487     GLchar buffer_gohan[16];
17488     const GLchar *type_name = test_case.m_type.GetGLSLTypeName();
17489 
17490     sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
17491 
17492     if (test_case.m_stage == stage)
17493     {
17494         const GLchar *array = "";
17495         GLchar buffer_goten[16];
17496         const GLchar *flat    = "";
17497         const GLchar *index   = "";
17498         size_t position       = 0;
17499         const GLchar *var_use = test_one;
17500 
17501         if (isFlatRequired(stage, test_case.m_type, Utils::Variable::VARYING_INPUT, true))
17502         {
17503             flat = "flat";
17504         }
17505 
17506         sprintf(buffer_goten, "%d", test_case.m_component_goten);
17507 
17508         switch (stage)
17509         {
17510         case Utils::Shader::FRAGMENT:
17511             source = fs_tested;
17512             break;
17513         case Utils::Shader::GEOMETRY:
17514             source = gs_tested;
17515             array  = "[]";
17516             index  = "[0]";
17517             break;
17518         case Utils::Shader::TESS_CTRL:
17519             source = tcs_tested;
17520             array  = "[]";
17521             index  = "[gl_InvocationID]";
17522             break;
17523         case Utils::Shader::TESS_EVAL:
17524             source = tes_tested;
17525             array  = "[]";
17526             index  = "[0]";
17527             break;
17528         case Utils::Shader::VERTEX:
17529             source = vs_tested;
17530             break;
17531         default:
17532             TCU_FAIL("Invalid enum");
17533         }
17534 
17535         Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
17536         position = 0;
17537         Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
17538         Utils::replaceToken("ARRAY", position, array, source);
17539         Utils::replaceToken("COMPONENT", position, buffer_goten, source);
17540         Utils::replaceToken("ARRAY", position, array, source);
17541         Utils::replaceToken("VARIABLE_USE", position, var_use, source);
17542 
17543         Utils::replaceAllTokens("FLAT", flat, source);
17544         Utils::replaceAllTokens("TYPE", type_name, source);
17545         Utils::replaceAllTokens("INDEX", index, source);
17546     }
17547     else
17548     {
17549         const GLchar *flat = "";
17550 
17551         if (isFlatRequired(stage, test_case.m_type, Utils::Variable::VARYING_OUTPUT, true))
17552         {
17553             flat = "flat";
17554         }
17555 
17556         switch (stage)
17557         {
17558         case Utils::Shader::FRAGMENT:
17559             source = fs;
17560             break;
17561         case Utils::Shader::GEOMETRY:
17562             source = gs;
17563             break;
17564         case Utils::Shader::TESS_CTRL:
17565             source = tcs;
17566             break;
17567         case Utils::Shader::TESS_EVAL:
17568             source = tes;
17569             break;
17570         case Utils::Shader::VERTEX:
17571             source = vs;
17572             break;
17573         default:
17574             TCU_FAIL("Invalid enum");
17575         }
17576 
17577         Utils::replaceAllTokens("FLAT", flat, source);
17578         Utils::replaceAllTokens("COMPONENT", buffer_gohan, source);
17579         Utils::replaceAllTokens("TYPE", type_name, source);
17580     }
17581 
17582     return source;
17583 }
17584 
17585 /** Get description of test case
17586  *
17587  * @param test_case_index Index of test case
17588  *
17589  * @return Test case description
17590  **/
17591 std::string InputComponentAliasingTest::getTestCaseName(GLuint test_case_index)
17592 {
17593     std::stringstream stream;
17594     testCase &test_case = m_test_cases[test_case_index];
17595 
17596     stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
17597            << " type: " << test_case.m_type.GetGLSLTypeName() << ", components: " << test_case.m_component_gohan
17598            << " & " << test_case.m_component_goten;
17599 
17600     return stream.str();
17601 }
17602 
17603 /** Get number of test cases
17604  *
17605  * @return Number of test cases
17606  **/
17607 GLuint InputComponentAliasingTest::getTestCaseNumber()
17608 {
17609     return static_cast<GLuint>(m_test_cases.size());
17610 }
17611 
17612 /** Selects if "compute" stage is relevant for test
17613  *
17614  * @param ignored
17615  *
17616  * @return false
17617  **/
17618 bool InputComponentAliasingTest::isComputeRelevant(GLuint /* test_case_index */)
17619 {
17620     return false;
17621 }
17622 
17623 /** Selects if compilation failure is expected result
17624  *
17625  * @param test_case_index Index of test case
17626  *
17627  * @return false for VS that use only single variable, true otherwise
17628  **/
17629 bool InputComponentAliasingTest::isFailureExpected(GLuint test_case_index)
17630 {
17631     testCase &test_case = m_test_cases[test_case_index];
17632 
17633     return (Utils::Shader::VERTEX != test_case.m_stage);
17634 }
17635 
17636 /** Prepare all test cases
17637  *
17638  **/
17639 void InputComponentAliasingTest::testInit()
17640 {
17641     const GLuint n_types = getTypesNumber();
17642 
17643     for (GLuint i = 0; i < n_types; ++i)
17644     {
17645         const Utils::Type &type                     = getType(i);
17646         const std::vector<GLuint> &valid_components = type.GetValidComponents();
17647 
17648         if (valid_components.empty())
17649         {
17650             continue;
17651         }
17652 
17653         for (std::vector<GLuint>::const_iterator it_gohan = valid_components.begin();
17654              it_gohan != valid_components.end(); ++it_gohan)
17655         {
17656             const GLuint max_component = *it_gohan + type.GetNumComponents();
17657             for (std::vector<GLuint>::const_iterator it_goten = it_gohan;
17658                  it_goten != valid_components.end() && max_component > *it_goten; ++it_goten)
17659             {
17660                 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
17661                 {
17662                     /* Skip compute shader */
17663                     if (Utils::Shader::COMPUTE == stage)
17664                     {
17665                         continue;
17666                     }
17667 
17668                     testCase test_case = {*it_gohan, *it_goten, (Utils::Shader::STAGES)stage, type};
17669 
17670                     m_test_cases.push_back(test_case);
17671                 }
17672             }
17673         }
17674     }
17675 }
17676 
17677 /** Constructor
17678  *
17679  * @param context Test framework context
17680  **/
17681 OutputComponentAliasingTest::OutputComponentAliasingTest(deqp::Context &context)
17682     : NegativeTestBase(context, "output_component_aliasing",
17683                        "Test verifies that compiler reports component aliasing as error")
17684 {
17685 }
17686 
17687 /** Source for given test case and stage
17688  *
17689  * @param test_case_index Index of test case
17690  * @param stage           Shader stage
17691  *
17692  * @return Shader source
17693  **/
17694 std::string OutputComponentAliasingTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
17695 {
17696     static const GLchar *var_definition =
17697         "layout (location = 1, component = COMPONENT) FLAT out TYPE gohanARRAY;\n"
17698 #if DEBUG_NEG_REMOVE_ERROR
17699         "/* layout (location = 1, component = COMPONENT) */ FLAT out TYPE gotenARRAY;\n";
17700 #else
17701         "layout (location = 1, component = COMPONENT) FLAT out TYPE gotenARRAY;\n";
17702 #endif /* DEBUG_NEG_REMOVE_ERROR */
17703     static const GLchar *l_test     = "    gohanINDEX = TYPE(1);\n"
17704                                       "    gotenINDEX = TYPE(0);\n";
17705     static const GLchar *fs         = "#version 430 core\n"
17706                                       "#extension GL_ARB_enhanced_layouts : require\n"
17707                                       "\n"
17708                                       "in  vec4 gs_fs;\n"
17709                                       "out vec4 fs_out;\n"
17710                                       "\n"
17711                                       "void main()\n"
17712                                       "{\n"
17713                                       "    fs_out = gs_fs;\n"
17714                                       "}\n"
17715                                       "\n";
17716     static const GLchar *fs_tested  = "#version 430 core\n"
17717                                       "#extension GL_ARB_enhanced_layouts : require\n"
17718                                       "\n"
17719                                       "VAR_DEFINITION"
17720                                       "\n"
17721                                       "in  vec4 gs_fs;\n"
17722                                       "out vec4 fs_out;\n"
17723                                       "\n"
17724                                       "void main()\n"
17725                                       "{\n"
17726                                       "    vec4 result = gs_fs;\n"
17727                                       "\n"
17728                                       "VARIABLE_USE"
17729                                       "\n"
17730                                       "    fs_out += result;\n"
17731                                       "}\n"
17732                                       "\n";
17733     static const GLchar *gs         = "#version 430 core\n"
17734                                       "#extension GL_ARB_enhanced_layouts : require\n"
17735                                       "\n"
17736                                       "layout(points)                           in;\n"
17737                                       "layout(triangle_strip, max_vertices = 4) out;\n"
17738                                       "\n"
17739                                       "in  vec4 tes_gs[];\n"
17740                                       "out vec4 gs_fs;\n"
17741                                       "\n"
17742                                       "void main()\n"
17743                                       "{\n"
17744                                       "    gs_fs = tes_gs[0];\n"
17745                                       "    gl_Position  = vec4(-1, -1, 0, 1);\n"
17746                                       "    EmitVertex();\n"
17747                                       "    gs_fs = tes_gs[0];\n"
17748                                       "    gl_Position  = vec4(-1, 1, 0, 1);\n"
17749                                       "    EmitVertex();\n"
17750                                       "    gs_fs = tes_gs[0];\n"
17751                                       "    gl_Position  = vec4(1, -1, 0, 1);\n"
17752                                       "    EmitVertex();\n"
17753                                       "    gs_fs = tes_gs[0];\n"
17754                                       "    gl_Position  = vec4(1, 1, 0, 1);\n"
17755                                       "    EmitVertex();\n"
17756                                       "}\n"
17757                                       "\n";
17758     static const GLchar *gs_tested  = "#version 430 core\n"
17759                                       "#extension GL_ARB_enhanced_layouts : require\n"
17760                                       "\n"
17761                                       "layout(points)                           in;\n"
17762                                       "layout(triangle_strip, max_vertices = 4) out;\n"
17763                                       "\n"
17764                                       "VAR_DEFINITION"
17765                                       "\n"
17766                                       "in  vec4 tes_gs[];\n"
17767                                       "out vec4 gs_fs;\n"
17768                                       "\n"
17769                                       "void main()\n"
17770                                       "{\n"
17771                                       "    vec4 result = tes_gs[0];\n"
17772                                       "\n"
17773                                       "VARIABLE_USE"
17774                                       "\n"
17775                                       "    gs_fs = result;\n"
17776                                       "    gl_Position  = vec4(-1, -1, 0, 1);\n"
17777                                       "    EmitVertex();\n"
17778                                       "    gs_fs = result;\n"
17779                                       "    gl_Position  = vec4(-1, 1, 0, 1);\n"
17780                                       "    EmitVertex();\n"
17781                                       "    gs_fs = result;\n"
17782                                       "    gl_Position  = vec4(1, -1, 0, 1);\n"
17783                                       "    EmitVertex();\n"
17784                                       "    gs_fs = result;\n"
17785                                       "    gl_Position  = vec4(1, 1, 0, 1);\n"
17786                                       "    EmitVertex();\n"
17787                                       "}\n"
17788                                       "\n";
17789     static const GLchar *tcs        = "#version 430 core\n"
17790                                       "#extension GL_ARB_enhanced_layouts : require\n"
17791                                       "\n"
17792                                       "layout(vertices = 1) out;\n"
17793                                       "\n"
17794                                       "in  vec4 vs_tcs[];\n"
17795                                       "out vec4 tcs_tes[];\n"
17796                                       "\n"
17797                                       "void main()\n"
17798                                       "{\n"
17799                                       "\n"
17800                                       "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
17801                                       "\n"
17802                                       "    gl_TessLevelOuter[0] = 1.0;\n"
17803                                       "    gl_TessLevelOuter[1] = 1.0;\n"
17804                                       "    gl_TessLevelOuter[2] = 1.0;\n"
17805                                       "    gl_TessLevelOuter[3] = 1.0;\n"
17806                                       "    gl_TessLevelInner[0] = 1.0;\n"
17807                                       "    gl_TessLevelInner[1] = 1.0;\n"
17808                                       "}\n"
17809                                       "\n";
17810     static const GLchar *tcs_tested = "#version 430 core\n"
17811                                       "#extension GL_ARB_enhanced_layouts : require\n"
17812                                       "\n"
17813                                       "layout(vertices = 1) out;\n"
17814                                       "\n"
17815                                       "VAR_DEFINITION"
17816                                       "\n"
17817                                       "in  vec4 vs_tcs[];\n"
17818                                       "out vec4 tcs_tes[];\n"
17819                                       "\n"
17820                                       "void main()\n"
17821                                       "{\n"
17822                                       "    vec4 result = vs_tcs[gl_InvocationID];\n"
17823                                       "\n"
17824                                       "VARIABLE_USE"
17825                                       "\n"
17826                                       "    tcs_tes[gl_InvocationID] = result;\n"
17827                                       "\n"
17828                                       "    gl_TessLevelOuter[0] = 1.0;\n"
17829                                       "    gl_TessLevelOuter[1] = 1.0;\n"
17830                                       "    gl_TessLevelOuter[2] = 1.0;\n"
17831                                       "    gl_TessLevelOuter[3] = 1.0;\n"
17832                                       "    gl_TessLevelInner[0] = 1.0;\n"
17833                                       "    gl_TessLevelInner[1] = 1.0;\n"
17834                                       "}\n"
17835                                       "\n";
17836     static const GLchar *tes        = "#version 430 core\n"
17837                                       "#extension GL_ARB_enhanced_layouts : require\n"
17838                                       "\n"
17839                                       "layout(isolines, point_mode) in;\n"
17840                                       "\n"
17841                                       "in  vec4 tcs_tes[];\n"
17842                                       "out vec4 tes_gs;\n"
17843                                       "\n"
17844                                       "void main()\n"
17845                                       "{\n"
17846                                       "    tes_gs = tcs_tes[0];\n"
17847                                       "}\n"
17848                                       "\n";
17849     static const GLchar *tes_tested = "#version 430 core\n"
17850                                       "#extension GL_ARB_enhanced_layouts : require\n"
17851                                       "\n"
17852                                       "layout(isolines, point_mode) in;\n"
17853                                       "\n"
17854                                       "VAR_DEFINITION"
17855                                       "\n"
17856                                       "in  vec4 tcs_tes[];\n"
17857                                       "out vec4 tes_gs;\n"
17858                                       "\n"
17859                                       "void main()\n"
17860                                       "{\n"
17861                                       "    vec4 result = tcs_tes[0];\n"
17862                                       "\n"
17863                                       "VARIABLE_USE"
17864                                       "\n"
17865                                       "    tes_gs += result;\n"
17866                                       "}\n"
17867                                       "\n";
17868     static const GLchar *vs         = "#version 430 core\n"
17869                                       "#extension GL_ARB_enhanced_layouts : require\n"
17870                                       "\n"
17871                                       "in  vec4 in_vs;\n"
17872                                       "out vec4 vs_tcs;\n"
17873                                       "\n"
17874                                       "void main()\n"
17875                                       "{\n"
17876                                       "    vs_tcs = in_vs;\n"
17877                                       "}\n"
17878                                       "\n";
17879     static const GLchar *vs_tested  = "#version 430 core\n"
17880                                       "#extension GL_ARB_enhanced_layouts : require\n"
17881                                       "\n"
17882                                       "VAR_DEFINITION"
17883                                       "\n"
17884                                       "in  vec4 in_vs;\n"
17885                                       "out vec4 vs_tcs;\n"
17886                                       "\n"
17887                                       "void main()\n"
17888                                       "{\n"
17889                                       "    vec4 result = in_vs;\n"
17890                                       "\n"
17891                                       "VARIABLE_USE"
17892                                       "\n"
17893                                       "    vs_tcs += result;\n"
17894                                       "}\n"
17895                                       "\n";
17896 
17897     std::string source;
17898     testCase &test_case = m_test_cases[test_case_index];
17899 
17900     if (test_case.m_stage == stage)
17901     {
17902         const GLchar *array = "";
17903         GLchar buffer_gohan[16];
17904         GLchar buffer_goten[16];
17905         const GLchar *flat      = "";
17906         const GLchar *index     = "";
17907         size_t position         = 0;
17908         const GLchar *type_name = test_case.m_type.GetGLSLTypeName();
17909 
17910         if (isFlatRequired(stage, test_case.m_type, Utils::Variable::VARYING_OUTPUT))
17911         {
17912             flat = "flat";
17913         }
17914 
17915         sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
17916         sprintf(buffer_goten, "%d", test_case.m_component_goten);
17917 
17918         switch (stage)
17919         {
17920         case Utils::Shader::FRAGMENT:
17921             source = fs_tested;
17922             break;
17923         case Utils::Shader::GEOMETRY:
17924             source = gs_tested;
17925             break;
17926         case Utils::Shader::TESS_CTRL:
17927             source = tcs_tested;
17928             array  = "[]";
17929             index  = "[gl_InvocationID]";
17930             break;
17931         case Utils::Shader::TESS_EVAL:
17932             source = tes_tested;
17933             break;
17934         case Utils::Shader::VERTEX:
17935             source = vs_tested;
17936             break;
17937         default:
17938             TCU_FAIL("Invalid enum");
17939         }
17940 
17941         Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
17942         position = 0;
17943         Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
17944         Utils::replaceToken("FLAT", position, flat, source);
17945         Utils::replaceToken("ARRAY", position, array, source);
17946         Utils::replaceToken("COMPONENT", position, buffer_goten, source);
17947         Utils::replaceToken("FLAT", position, flat, source);
17948         Utils::replaceToken("ARRAY", position, array, source);
17949         Utils::replaceToken("VARIABLE_USE", position, l_test, source);
17950 
17951         Utils::replaceAllTokens("TYPE", type_name, source);
17952         Utils::replaceAllTokens("INDEX", index, source);
17953     }
17954     else
17955     {
17956         switch (stage)
17957         {
17958         case Utils::Shader::FRAGMENT:
17959             source = fs;
17960             break;
17961         case Utils::Shader::GEOMETRY:
17962             source = gs;
17963             break;
17964         case Utils::Shader::TESS_CTRL:
17965             source = tcs;
17966             break;
17967         case Utils::Shader::TESS_EVAL:
17968             source = tes;
17969             break;
17970         case Utils::Shader::VERTEX:
17971             source = vs;
17972             break;
17973         default:
17974             TCU_FAIL("Invalid enum");
17975         }
17976     }
17977 
17978     return source;
17979 }
17980 
17981 /** Get description of test case
17982  *
17983  * @param test_case_index Index of test case
17984  *
17985  * @return Test case description
17986  **/
17987 std::string OutputComponentAliasingTest::getTestCaseName(GLuint test_case_index)
17988 {
17989     std::stringstream stream;
17990     testCase &test_case = m_test_cases[test_case_index];
17991 
17992     stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
17993            << " type: " << test_case.m_type.GetGLSLTypeName() << ", components: " << test_case.m_component_gohan
17994            << " & " << test_case.m_component_goten;
17995 
17996     return stream.str();
17997 }
17998 
17999 /** Get number of test cases
18000  *
18001  * @return Number of test cases
18002  **/
18003 GLuint OutputComponentAliasingTest::getTestCaseNumber()
18004 {
18005     return static_cast<GLuint>(m_test_cases.size());
18006 }
18007 
18008 /** Selects if "compute" stage is relevant for test
18009  *
18010  * @param ignored
18011  *
18012  * @return false
18013  **/
18014 bool OutputComponentAliasingTest::isComputeRelevant(GLuint /* test_case_index */)
18015 {
18016     return false;
18017 }
18018 
18019 /** Prepare all test cases
18020  *
18021  **/
18022 void OutputComponentAliasingTest::testInit()
18023 {
18024     const GLuint n_types = getTypesNumber();
18025 
18026     for (GLuint i = 0; i < n_types; ++i)
18027     {
18028         const Utils::Type &type                     = getType(i);
18029         const std::vector<GLuint> &valid_components = type.GetValidComponents();
18030 
18031         if (valid_components.empty())
18032         {
18033             continue;
18034         }
18035 
18036         for (std::vector<GLuint>::const_iterator it_gohan = valid_components.begin();
18037              it_gohan != valid_components.end(); ++it_gohan)
18038         {
18039             const GLuint max_component = *it_gohan + type.GetNumComponents();
18040             for (std::vector<GLuint>::const_iterator it_goten = it_gohan;
18041                  it_goten != valid_components.end() && max_component > *it_goten; ++it_goten)
18042             {
18043                 for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
18044                 {
18045                     /* Skip compute shader */
18046                     if (Utils::Shader::COMPUTE == stage)
18047                     {
18048                         continue;
18049                     }
18050 
18051                     if ((Utils::Shader::FRAGMENT == stage) && (Utils::Type::Double == type.m_basic_type))
18052                     {
18053                         continue;
18054                     }
18055 
18056                     testCase test_case = {*it_gohan, *it_goten, (Utils::Shader::STAGES)stage, type};
18057 
18058                     m_test_cases.push_back(test_case);
18059                 }
18060             }
18061         }
18062     }
18063 }
18064 
18065 /** Constructor
18066  *
18067  * @param context Test framework context
18068  **/
18069 VaryingLocationAliasingWithMixedTypesTest::VaryingLocationAliasingWithMixedTypesTest(deqp::Context &context)
18070     : NegativeTestBase(context, "varying_location_aliasing_with_mixed_types",
18071                        "Test verifies that compiler reports error when float/int types are mixed at one location")
18072 {
18073 }
18074 
18075 /** Source for given test case and stage
18076  *
18077  * @param test_case_index Index of test case
18078  * @param stage           Shader stage
18079  *
18080  * @return Shader source
18081  **/
18082 std::string VaryingLocationAliasingWithMixedTypesTest::getShaderSource(GLuint test_case_index,
18083                                                                        Utils::Shader::STAGES stage)
18084 {
18085     static const GLchar *var_definition =
18086         "layout (location = 1, component = COMPONENT) FLAT DIRECTION TYPE gohanARRAY;\n"
18087         "layout (location = 1, component = COMPONENT) FLAT DIRECTION TYPE gotenARRAY;\n";
18088     static const GLchar *input_use  = "    if ((TYPE(0) == gohanINDEX) &&\n"
18089                                       "        (TYPE(1) == gotenINDEX) )\n"
18090                                       "    {\n"
18091                                       "        result += vec4(1, 0.5, 0.25, 0.125);\n"
18092                                       "    }\n";
18093     static const GLchar *output_use = "    gohanINDEX = TYPE(0);\n"
18094                                       "    gotenINDEX = TYPE(1);\n"
18095                                       "    if (vec4(0) == result)\n"
18096                                       "    {\n"
18097                                       "        gohanINDEX = TYPE(1);\n"
18098                                       "        gotenINDEX = TYPE(0);\n"
18099                                       "    }\n";
18100     static const GLchar *fs         = "#version 430 core\n"
18101                                       "#extension GL_ARB_enhanced_layouts : require\n"
18102                                       "\n"
18103                                       "in  vec4 gs_fs;\n"
18104                                       "out vec4 fs_out;\n"
18105                                       "\n"
18106                                       "void main()\n"
18107                                       "{\n"
18108                                       "    fs_out = gs_fs;\n"
18109                                       "}\n"
18110                                       "\n";
18111     static const GLchar *fs_tested  = "#version 430 core\n"
18112                                       "#extension GL_ARB_enhanced_layouts : require\n"
18113                                       "\n"
18114                                       "VAR_DEFINITION"
18115                                       "\n"
18116                                       "in  vec4 gs_fs;\n"
18117                                       "out vec4 fs_out;\n"
18118                                       "\n"
18119                                       "void main()\n"
18120                                       "{\n"
18121                                       "    vec4 result = gs_fs;\n"
18122                                       "\n"
18123                                       "VARIABLE_USE"
18124                                       "\n"
18125                                       "    fs_out += result;\n"
18126                                       "}\n"
18127                                       "\n";
18128     static const GLchar *gs         = "#version 430 core\n"
18129                                       "#extension GL_ARB_enhanced_layouts : require\n"
18130                                       "\n"
18131                                       "layout(points)                           in;\n"
18132                                       "layout(triangle_strip, max_vertices = 4) out;\n"
18133                                       "\n"
18134                                       "in  vec4 tes_gs[];\n"
18135                                       "out vec4 gs_fs;\n"
18136                                       "\n"
18137                                       "void main()\n"
18138                                       "{\n"
18139                                       "    gs_fs = tes_gs[0];\n"
18140                                       "    gl_Position  = vec4(-1, -1, 0, 1);\n"
18141                                       "    EmitVertex();\n"
18142                                       "    gs_fs = tes_gs[0];\n"
18143                                       "    gl_Position  = vec4(-1, 1, 0, 1);\n"
18144                                       "    EmitVertex();\n"
18145                                       "    gs_fs = tes_gs[0];\n"
18146                                       "    gl_Position  = vec4(1, -1, 0, 1);\n"
18147                                       "    EmitVertex();\n"
18148                                       "    gs_fs = tes_gs[0];\n"
18149                                       "    gl_Position  = vec4(1, 1, 0, 1);\n"
18150                                       "    EmitVertex();\n"
18151                                       "}\n"
18152                                       "\n";
18153     static const GLchar *gs_tested  = "#version 430 core\n"
18154                                       "#extension GL_ARB_enhanced_layouts : require\n"
18155                                       "\n"
18156                                       "layout(points)                           in;\n"
18157                                       "layout(triangle_strip, max_vertices = 4) out;\n"
18158                                       "\n"
18159                                       "VAR_DEFINITION"
18160                                       "\n"
18161                                       "in  vec4 tes_gs[];\n"
18162                                       "out vec4 gs_fs;\n"
18163                                       "\n"
18164                                       "void main()\n"
18165                                       "{\n"
18166                                       "    vec4 result = tes_gs[0];\n"
18167                                       "\n"
18168                                       "VARIABLE_USE"
18169                                       "\n"
18170                                       "    gs_fs = result;\n"
18171                                       "    gl_Position  = vec4(-1, -1, 0, 1);\n"
18172                                       "    EmitVertex();\n"
18173                                       "    gs_fs = result;\n"
18174                                       "    gl_Position  = vec4(-1, 1, 0, 1);\n"
18175                                       "    EmitVertex();\n"
18176                                       "    gs_fs = result;\n"
18177                                       "    gl_Position  = vec4(1, -1, 0, 1);\n"
18178                                       "    EmitVertex();\n"
18179                                       "    gs_fs = result;\n"
18180                                       "    gl_Position  = vec4(1, 1, 0, 1);\n"
18181                                       "    EmitVertex();\n"
18182                                       "}\n"
18183                                       "\n";
18184     static const GLchar *tcs        = "#version 430 core\n"
18185                                       "#extension GL_ARB_enhanced_layouts : require\n"
18186                                       "\n"
18187                                       "layout(vertices = 1) out;\n"
18188                                       "\n"
18189                                       "in  vec4 vs_tcs[];\n"
18190                                       "out vec4 tcs_tes[];\n"
18191                                       "\n"
18192                                       "void main()\n"
18193                                       "{\n"
18194                                       "\n"
18195                                       "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
18196                                       "\n"
18197                                       "    gl_TessLevelOuter[0] = 1.0;\n"
18198                                       "    gl_TessLevelOuter[1] = 1.0;\n"
18199                                       "    gl_TessLevelOuter[2] = 1.0;\n"
18200                                       "    gl_TessLevelOuter[3] = 1.0;\n"
18201                                       "    gl_TessLevelInner[0] = 1.0;\n"
18202                                       "    gl_TessLevelInner[1] = 1.0;\n"
18203                                       "}\n"
18204                                       "\n";
18205     static const GLchar *tcs_tested = "#version 430 core\n"
18206                                       "#extension GL_ARB_enhanced_layouts : require\n"
18207                                       "\n"
18208                                       "layout(vertices = 1) out;\n"
18209                                       "\n"
18210                                       "VAR_DEFINITION"
18211                                       "\n"
18212                                       "in  vec4 vs_tcs[];\n"
18213                                       "out vec4 tcs_tes[];\n"
18214                                       "\n"
18215                                       "void main()\n"
18216                                       "{\n"
18217                                       "    vec4 result = vs_tcs[gl_InvocationID];\n"
18218                                       "\n"
18219                                       "VARIABLE_USE"
18220                                       "\n"
18221                                       "    tcs_tes[gl_InvocationID] = result;\n"
18222                                       "\n"
18223                                       "    gl_TessLevelOuter[0] = 1.0;\n"
18224                                       "    gl_TessLevelOuter[1] = 1.0;\n"
18225                                       "    gl_TessLevelOuter[2] = 1.0;\n"
18226                                       "    gl_TessLevelOuter[3] = 1.0;\n"
18227                                       "    gl_TessLevelInner[0] = 1.0;\n"
18228                                       "    gl_TessLevelInner[1] = 1.0;\n"
18229                                       "}\n"
18230                                       "\n";
18231     static const GLchar *tes        = "#version 430 core\n"
18232                                       "#extension GL_ARB_enhanced_layouts : require\n"
18233                                       "\n"
18234                                       "layout(isolines, point_mode) in;\n"
18235                                       "\n"
18236                                       "in  vec4 tcs_tes[];\n"
18237                                       "out vec4 tes_gs;\n"
18238                                       "\n"
18239                                       "void main()\n"
18240                                       "{\n"
18241                                       "    tes_gs = tcs_tes[0];\n"
18242                                       "}\n"
18243                                       "\n";
18244     static const GLchar *tes_tested = "#version 430 core\n"
18245                                       "#extension GL_ARB_enhanced_layouts : require\n"
18246                                       "\n"
18247                                       "layout(isolines, point_mode) in;\n"
18248                                       "\n"
18249                                       "VAR_DEFINITION"
18250                                       "\n"
18251                                       "in  vec4 tcs_tes[];\n"
18252                                       "out vec4 tes_gs;\n"
18253                                       "\n"
18254                                       "void main()\n"
18255                                       "{\n"
18256                                       "    vec4 result = tcs_tes[0];\n"
18257                                       "\n"
18258                                       "VARIABLE_USE"
18259                                       "\n"
18260                                       "    tes_gs += result;\n"
18261                                       "}\n"
18262                                       "\n";
18263     static const GLchar *vs         = "#version 430 core\n"
18264                                       "#extension GL_ARB_enhanced_layouts : require\n"
18265                                       "\n"
18266                                       "in  vec4 in_vs;\n"
18267                                       "out vec4 vs_tcs;\n"
18268                                       "\n"
18269                                       "void main()\n"
18270                                       "{\n"
18271                                       "    vs_tcs = in_vs;\n"
18272                                       "}\n"
18273                                       "\n";
18274     static const GLchar *vs_tested  = "#version 430 core\n"
18275                                       "#extension GL_ARB_enhanced_layouts : require\n"
18276                                       "\n"
18277                                       "VAR_DEFINITION"
18278                                       "\n"
18279                                       "in  vec4 in_vs;\n"
18280                                       "out vec4 vs_tcs;\n"
18281                                       "\n"
18282                                       "void main()\n"
18283                                       "{\n"
18284                                       "    vec4 result = in_vs;\n"
18285                                       "\n"
18286                                       "VARIABLE_USE"
18287                                       "\n"
18288                                       "    vs_tcs += result;\n"
18289                                       "}\n"
18290                                       "\n";
18291 
18292     std::string source;
18293     testCase &test_case = m_test_cases[test_case_index];
18294 
18295     if (test_case.m_stage == stage)
18296     {
18297         const GLchar *array = "";
18298         GLchar buffer_gohan[16];
18299         GLchar buffer_goten[16];
18300         const GLchar *direction  = "in ";
18301         const GLchar *flat_gohan = "";
18302         const GLchar *flat_goten = "";
18303         const GLchar *index      = "";
18304         size_t position          = 0;
18305         size_t temp;
18306         const GLchar *type_gohan_name    = test_case.m_type_gohan.GetGLSLTypeName();
18307         const GLchar *type_goten_name    = test_case.m_type_goten.GetGLSLTypeName();
18308         Utils::Variable::STORAGE storage = Utils::Variable::VARYING_INPUT;
18309         const GLchar *var_use            = Utils::Shader::VERTEX == stage ? input_use : "\n";
18310 
18311         if (false == test_case.m_is_input)
18312         {
18313             direction = "out";
18314             storage   = Utils::Variable::VARYING_OUTPUT;
18315             var_use   = output_use;
18316         }
18317 
18318         /* If the interpolation qualifier would be different, the test
18319          * would fail and we are testing here mixed types, not mixed
18320          * interpolation qualifiers.
18321          */
18322         if (isFlatRequired(stage, test_case.m_type_gohan, storage) ||
18323             isFlatRequired(stage, test_case.m_type_goten, storage))
18324         {
18325             flat_gohan = "flat";
18326             flat_goten = "flat";
18327         }
18328 
18329         sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
18330         sprintf(buffer_goten, "%d", test_case.m_component_goten);
18331 
18332 #if DEBUG_NEG_REMOVE_ERROR
18333         type_goten_name = Utils::Type::GetType(test_case.m_type_gohan.m_basic_type, 1, 1).GetGLSLTypeName();
18334         if (Utils::Type::Double == test_case.m_type_gohan.m_basic_type)
18335         {
18336             sprintf(buffer_goten, "%d", 0 == test_case.m_component_gohan ? 2 : 0);
18337         }
18338 #endif /* DEBUG_NEG_REMOVE_ERROR */
18339 
18340         switch (stage)
18341         {
18342         case Utils::Shader::FRAGMENT:
18343             source = fs_tested;
18344             break;
18345         case Utils::Shader::GEOMETRY:
18346             source = gs_tested;
18347             array  = test_case.m_is_input ? "[]" : "";
18348             index  = test_case.m_is_input ? "[0]" : "";
18349             break;
18350         case Utils::Shader::TESS_CTRL:
18351             source = tcs_tested;
18352             array  = "[]";
18353             index  = "[gl_InvocationID]";
18354             break;
18355         case Utils::Shader::TESS_EVAL:
18356             source = tes_tested;
18357             array  = test_case.m_is_input ? "[]" : "";
18358             index  = test_case.m_is_input ? "[0]" : "";
18359             break;
18360         case Utils::Shader::VERTEX:
18361             source = vs_tested;
18362             break;
18363         default:
18364             TCU_FAIL("Invalid enum");
18365         }
18366 
18367         Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
18368         position = 0;
18369         Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
18370         Utils::replaceToken("FLAT", position, flat_gohan, source);
18371         Utils::replaceToken("DIRECTION", position, direction, source);
18372         Utils::replaceToken("TYPE", position, type_gohan_name, source);
18373         Utils::replaceToken("ARRAY", position, array, source);
18374         Utils::replaceToken("COMPONENT", position, buffer_goten, source);
18375         Utils::replaceToken("FLAT", position, flat_goten, source);
18376         Utils::replaceToken("DIRECTION", position, direction, source);
18377         Utils::replaceToken("TYPE", position, type_goten_name, source);
18378         Utils::replaceToken("ARRAY", position, array, source);
18379 
18380         temp = position;
18381         Utils::replaceToken("VARIABLE_USE", position, var_use, source);
18382         position = temp;
18383         if (!test_case.m_is_input)
18384         {
18385             Utils::replaceToken("TYPE", position, type_gohan_name, source);
18386             Utils::replaceToken("TYPE", position, type_goten_name, source);
18387             Utils::replaceToken("TYPE", position, type_gohan_name, source);
18388             Utils::replaceToken("TYPE", position, type_goten_name, source);
18389         }
18390         else if (Utils::Shader::VERTEX == stage)
18391         {
18392             Utils::replaceToken("TYPE", position, type_gohan_name, source);
18393             Utils::replaceToken("TYPE", position, type_goten_name, source);
18394         }
18395 
18396         Utils::replaceAllTokens("INDEX", index, source);
18397     }
18398     else
18399     {
18400         switch (stage)
18401         {
18402         case Utils::Shader::FRAGMENT:
18403             source = fs;
18404             break;
18405         case Utils::Shader::GEOMETRY:
18406             source = gs;
18407             break;
18408         case Utils::Shader::TESS_CTRL:
18409             source = tcs;
18410             break;
18411         case Utils::Shader::TESS_EVAL:
18412             source = tes;
18413             break;
18414         case Utils::Shader::VERTEX:
18415             source = vs;
18416             break;
18417         default:
18418             TCU_FAIL("Invalid enum");
18419         }
18420     }
18421 
18422     return source;
18423 }
18424 
18425 /** Get description of test case
18426  *
18427  * @param test_case_index Index of test case
18428  *
18429  * @return Test case description
18430  **/
18431 std::string VaryingLocationAliasingWithMixedTypesTest::getTestCaseName(GLuint test_case_index)
18432 {
18433     std::stringstream stream;
18434     testCase &test_case = m_test_cases[test_case_index];
18435 
18436     stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", "
18437            << test_case.m_type_gohan.GetGLSLTypeName() << " at " << test_case.m_component_gohan << ", "
18438            << test_case.m_type_goten.GetGLSLTypeName() << " at " << test_case.m_component_goten << ". Direction: ";
18439 
18440     if (true == test_case.m_is_input)
18441     {
18442         stream << "input";
18443     }
18444     else
18445     {
18446         stream << "output";
18447     }
18448 
18449     return stream.str();
18450 }
18451 
18452 /** Get number of test cases
18453  *
18454  * @return Number of test cases
18455  **/
18456 GLuint VaryingLocationAliasingWithMixedTypesTest::getTestCaseNumber()
18457 {
18458     return static_cast<GLuint>(m_test_cases.size());
18459 }
18460 
18461 /** Selects if "compute" stage is relevant for test
18462  *
18463  * @param ignored
18464  *
18465  * @return false
18466  **/
18467 bool VaryingLocationAliasingWithMixedTypesTest::isComputeRelevant(GLuint /* test_case_index */)
18468 {
18469     return false;
18470 }
18471 
18472 /** Prepare all test cases
18473  *
18474  **/
18475 void VaryingLocationAliasingWithMixedTypesTest::testInit()
18476 {
18477     const GLuint n_types = getTypesNumber();
18478 
18479     for (GLuint i = 0; i < n_types; ++i)
18480     {
18481         const Utils::Type &type_gohan                     = getType(i);
18482         const std::vector<GLuint> &valid_components_gohan = type_gohan.GetValidComponents();
18483 
18484         if (valid_components_gohan.empty())
18485         {
18486             continue;
18487         }
18488 
18489         for (GLuint j = 0; j < n_types; ++j)
18490         {
18491             const Utils::Type &type_goten                     = getType(j);
18492             const std::vector<GLuint> &valid_components_goten = type_goten.GetValidComponents();
18493 
18494             if (valid_components_goten.empty())
18495             {
18496                 continue;
18497             }
18498 
18499             /* Skip valid combinations */
18500             if (Utils::Type::CanTypesShareLocation(type_gohan.m_basic_type, type_goten.m_basic_type))
18501             {
18502                 continue;
18503             }
18504 
18505             for (std::vector<GLuint>::const_iterator it_gohan = valid_components_gohan.begin();
18506                  it_gohan != valid_components_gohan.end(); ++it_gohan)
18507             {
18508                 const GLuint min_component = *it_gohan + type_gohan.GetNumComponents();
18509                 for (std::vector<GLuint>::const_iterator it_goten = valid_components_goten.begin();
18510                      it_goten != valid_components_goten.end(); ++it_goten)
18511                 {
18512 
18513                     if (min_component > *it_goten)
18514                     {
18515                         continue;
18516                     }
18517 
18518                     for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
18519                     {
18520                         /* Skip compute shader */
18521                         if (Utils::Shader::COMPUTE == stage)
18522                         {
18523                             continue;
18524                         }
18525 
18526                         if (Utils::Shader::VERTEX != stage)
18527                         {
18528                             testCase test_case_in = {*it_gohan,  *it_goten, true, (Utils::Shader::STAGES)stage,
18529                                                      type_gohan, type_goten};
18530 
18531                             m_test_cases.push_back(test_case_in);
18532                         }
18533 
18534                         /* Skip double outputs in fragment shader */
18535                         if ((Utils::Shader::FRAGMENT != stage) || ((Utils::Type::Double != type_gohan.m_basic_type) &&
18536                                                                    (Utils::Type::Double != type_goten.m_basic_type)))
18537                         {
18538                             testCase test_case_out = {*it_gohan,  *it_goten, false, (Utils::Shader::STAGES)stage,
18539                                                       type_gohan, type_goten};
18540 
18541                             m_test_cases.push_back(test_case_out);
18542                         }
18543                     }
18544                 }
18545             }
18546         }
18547     }
18548 }
18549 
18550 /** Constructor
18551  *
18552  * @param context Test framework context
18553  **/
18554 VaryingLocationAliasingWithMixedInterpolationTest::VaryingLocationAliasingWithMixedInterpolationTest(
18555     deqp::Context &context)
18556     : NegativeTestBase(
18557           context, "varying_location_aliasing_with_mixed_interpolation",
18558           "Test verifies that compiler reports error when interpolation qualifiers are mixed at one location")
18559 {
18560 }
18561 
18562 /** Source for given test case and stage
18563  *
18564  * @param test_case_index Index of test case
18565  * @param stage           Shader stage
18566  *
18567  * @return Shader source
18568  **/
18569 std::string VaryingLocationAliasingWithMixedInterpolationTest::getShaderSource(GLuint test_case_index,
18570                                                                                Utils::Shader::STAGES stage)
18571 {
18572     static const GLchar *var_definition =
18573         "layout (location = 1, component = COMPONENT) INTERPOLATION DIRECTION TYPE gohanARRAY;\n"
18574         "layout (location = 1, component = COMPONENT) INTERPOLATION DIRECTION TYPE gotenARRAY;\n";
18575     static const GLchar *input_use  = "    if ((TYPE(0) == gohanINDEX) &&\n"
18576                                       "        (TYPE(1) == gotenINDEX) )\n"
18577                                       "    {\n"
18578                                       "        result += vec4(1, 0.5, 0.25, 0.125);\n"
18579                                       "    }\n";
18580     static const GLchar *output_use = "    gohanINDEX = TYPE(0);\n"
18581                                       "    gotenINDEX = TYPE(1);\n"
18582                                       "    if (vec4(0) == result)\n"
18583                                       "    {\n"
18584                                       "        gohanINDEX = TYPE(1);\n"
18585                                       "        gotenINDEX = TYPE(0);\n"
18586                                       "    }\n";
18587     static const GLchar *fs         = "#version 430 core\n"
18588                                       "#extension GL_ARB_enhanced_layouts : require\n"
18589                                       "\n"
18590                                       "in  vec4 gs_fs;\n"
18591                                       "out vec4 fs_out;\n"
18592                                       "\n"
18593                                       "void main()\n"
18594                                       "{\n"
18595                                       "    fs_out = gs_fs;\n"
18596                                       "}\n"
18597                                       "\n";
18598     static const GLchar *fs_tested  = "#version 430 core\n"
18599                                       "#extension GL_ARB_enhanced_layouts : require\n"
18600                                       "\n"
18601                                       "VAR_DEFINITION"
18602                                       "\n"
18603                                       "in  vec4 gs_fs;\n"
18604                                       "out vec4 fs_out;\n"
18605                                       "\n"
18606                                       "void main()\n"
18607                                       "{\n"
18608                                       "    vec4 result = gs_fs;\n"
18609                                       "\n"
18610                                       "VARIABLE_USE"
18611                                       "\n"
18612                                       "    fs_out = result;\n"
18613                                       "}\n"
18614                                       "\n";
18615     static const GLchar *gs         = "#version 430 core\n"
18616                                       "#extension GL_ARB_enhanced_layouts : require\n"
18617                                       "\n"
18618                                       "layout(points)                           in;\n"
18619                                       "layout(triangle_strip, max_vertices = 4) out;\n"
18620                                       "\n"
18621                                       "in  vec4 tes_gs[];\n"
18622                                       "out vec4 gs_fs;\n"
18623                                       "\n"
18624                                       "void main()\n"
18625                                       "{\n"
18626                                       "    gs_fs = tes_gs[0];\n"
18627                                       "    gl_Position  = vec4(-1, -1, 0, 1);\n"
18628                                       "    EmitVertex();\n"
18629                                       "    gs_fs = tes_gs[0];\n"
18630                                       "    gl_Position  = vec4(-1, 1, 0, 1);\n"
18631                                       "    EmitVertex();\n"
18632                                       "    gs_fs = tes_gs[0];\n"
18633                                       "    gl_Position  = vec4(1, -1, 0, 1);\n"
18634                                       "    EmitVertex();\n"
18635                                       "    gs_fs = tes_gs[0];\n"
18636                                       "    gl_Position  = vec4(1, 1, 0, 1);\n"
18637                                       "    EmitVertex();\n"
18638                                       "}\n"
18639                                       "\n";
18640     static const GLchar *gs_tested  = "#version 430 core\n"
18641                                       "#extension GL_ARB_enhanced_layouts : require\n"
18642                                       "\n"
18643                                       "layout(points)                           in;\n"
18644                                       "layout(triangle_strip, max_vertices = 4) out;\n"
18645                                       "\n"
18646                                       "VAR_DEFINITION"
18647                                       "\n"
18648                                       "in  vec4 tes_gs[];\n"
18649                                       "out vec4 gs_fs;\n"
18650                                       "\n"
18651                                       "void main()\n"
18652                                       "{\n"
18653                                       "    vec4 result = tes_gs[0];\n"
18654                                       "\n"
18655                                       "VARIABLE_USE"
18656                                       "\n"
18657                                       "    gs_fs = result;\n"
18658                                       "    gl_Position  = vec4(-1, -1, 0, 1);\n"
18659                                       "    EmitVertex();\n"
18660                                       "    gs_fs = result;\n"
18661                                       "    gl_Position  = vec4(-1, 1, 0, 1);\n"
18662                                       "    EmitVertex();\n"
18663                                       "    gs_fs = result;\n"
18664                                       "    gl_Position  = vec4(1, -1, 0, 1);\n"
18665                                       "    EmitVertex();\n"
18666                                       "    gs_fs = result;\n"
18667                                       "    gl_Position  = vec4(1, 1, 0, 1);\n"
18668                                       "    EmitVertex();\n"
18669                                       "}\n"
18670                                       "\n";
18671     static const GLchar *tcs        = "#version 430 core\n"
18672                                       "#extension GL_ARB_enhanced_layouts : require\n"
18673                                       "\n"
18674                                       "layout(vertices = 1) out;\n"
18675                                       "\n"
18676                                       "in  vec4 vs_tcs[];\n"
18677                                       "out vec4 tcs_tes[];\n"
18678                                       "\n"
18679                                       "void main()\n"
18680                                       "{\n"
18681                                       "\n"
18682                                       "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
18683                                       "\n"
18684                                       "    gl_TessLevelOuter[0] = 1.0;\n"
18685                                       "    gl_TessLevelOuter[1] = 1.0;\n"
18686                                       "    gl_TessLevelOuter[2] = 1.0;\n"
18687                                       "    gl_TessLevelOuter[3] = 1.0;\n"
18688                                       "    gl_TessLevelInner[0] = 1.0;\n"
18689                                       "    gl_TessLevelInner[1] = 1.0;\n"
18690                                       "}\n"
18691                                       "\n";
18692     static const GLchar *tcs_tested = "#version 430 core\n"
18693                                       "#extension GL_ARB_enhanced_layouts : require\n"
18694                                       "\n"
18695                                       "layout(vertices = 1) out;\n"
18696                                       "\n"
18697                                       "VAR_DEFINITION"
18698                                       "\n"
18699                                       "in  vec4 vs_tcs[];\n"
18700                                       "out vec4 tcs_tes[];\n"
18701                                       "\n"
18702                                       "void main()\n"
18703                                       "{\n"
18704                                       "    vec4 result = vs_tcs[gl_InvocationID];\n"
18705                                       "\n"
18706                                       "VARIABLE_USE"
18707                                       "\n"
18708                                       "    tcs_tes[gl_InvocationID] = result;\n"
18709                                       "\n"
18710                                       "    gl_TessLevelOuter[0] = 1.0;\n"
18711                                       "    gl_TessLevelOuter[1] = 1.0;\n"
18712                                       "    gl_TessLevelOuter[2] = 1.0;\n"
18713                                       "    gl_TessLevelOuter[3] = 1.0;\n"
18714                                       "    gl_TessLevelInner[0] = 1.0;\n"
18715                                       "    gl_TessLevelInner[1] = 1.0;\n"
18716                                       "}\n"
18717                                       "\n";
18718     static const GLchar *tes        = "#version 430 core\n"
18719                                       "#extension GL_ARB_enhanced_layouts : require\n"
18720                                       "\n"
18721                                       "layout(isolines, point_mode) in;\n"
18722                                       "\n"
18723                                       "in  vec4 tcs_tes[];\n"
18724                                       "out vec4 tes_gs;\n"
18725                                       "\n"
18726                                       "void main()\n"
18727                                       "{\n"
18728                                       "    tes_gs = tcs_tes[0];\n"
18729                                       "}\n"
18730                                       "\n";
18731     static const GLchar *tes_tested = "#version 430 core\n"
18732                                       "#extension GL_ARB_enhanced_layouts : require\n"
18733                                       "\n"
18734                                       "layout(isolines, point_mode) in;\n"
18735                                       "\n"
18736                                       "VAR_DEFINITION"
18737                                       "\n"
18738                                       "in  vec4 tcs_tes[];\n"
18739                                       "out vec4 tes_gs;\n"
18740                                       "\n"
18741                                       "void main()\n"
18742                                       "{\n"
18743                                       "    vec4 result = tcs_tes[0];\n"
18744                                       "\n"
18745                                       "VARIABLE_USE"
18746                                       "\n"
18747                                       "    tes_gs += result;\n"
18748                                       "}\n"
18749                                       "\n";
18750     static const GLchar *vs         = "#version 430 core\n"
18751                                       "#extension GL_ARB_enhanced_layouts : require\n"
18752                                       "\n"
18753                                       "in  vec4 in_vs;\n"
18754                                       "out vec4 vs_tcs;\n"
18755                                       "\n"
18756                                       "void main()\n"
18757                                       "{\n"
18758                                       "    vs_tcs = in_vs;\n"
18759                                       "}\n"
18760                                       "\n";
18761     static const GLchar *vs_tested  = "#version 430 core\n"
18762                                       "#extension GL_ARB_enhanced_layouts : require\n"
18763                                       "\n"
18764                                       "VAR_DEFINITION"
18765                                       "\n"
18766                                       "in  vec4 in_vs;\n"
18767                                       "out vec4 vs_tcs;\n"
18768                                       "\n"
18769                                       "void main()\n"
18770                                       "{\n"
18771                                       "    vec4 result = in_vs;\n"
18772                                       "\n"
18773                                       "VARIABLE_USE"
18774                                       "\n"
18775                                       "    vs_tcs += result;\n"
18776                                       "}\n"
18777                                       "\n";
18778 
18779     std::string source;
18780     testCase &test_case = m_test_cases[test_case_index];
18781 
18782     if (test_case.m_stage == stage)
18783     {
18784         const GLchar *array = "";
18785         GLchar buffer_gohan[16];
18786         GLchar buffer_goten[16];
18787         const GLchar *direction = "in ";
18788         const GLchar *index     = "";
18789         const GLchar *int_gohan = getInterpolationQualifier(test_case.m_interpolation_gohan);
18790         const GLchar *int_goten = getInterpolationQualifier(test_case.m_interpolation_goten);
18791 #if DEBUG_NEG_REMOVE_ERROR
18792         if (FLAT == test_case.m_interpolation_goten)
18793         {
18794             int_gohan = int_goten;
18795         }
18796         else
18797         {
18798             int_goten = int_gohan;
18799         }
18800 #endif /* DEBUG_NEG_REMOVE_ERROR */
18801         size_t position = 0;
18802         size_t temp;
18803         const GLchar *type_gohan_name = test_case.m_type_gohan.GetGLSLTypeName();
18804         const GLchar *type_goten_name = test_case.m_type_goten.GetGLSLTypeName();
18805         const GLchar *var_use         = Utils::Shader::VERTEX == stage ? input_use : "\n";
18806 
18807         if (false == test_case.m_is_input)
18808         {
18809             direction = "out";
18810 
18811             var_use = output_use;
18812         }
18813 
18814         sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
18815         sprintf(buffer_goten, "%d", test_case.m_component_goten);
18816 
18817         switch (stage)
18818         {
18819         case Utils::Shader::FRAGMENT:
18820             source = fs_tested;
18821             break;
18822         case Utils::Shader::GEOMETRY:
18823             source = gs_tested;
18824             array  = test_case.m_is_input ? "[]" : "";
18825             index  = test_case.m_is_input ? "[0]" : "";
18826             break;
18827         case Utils::Shader::TESS_CTRL:
18828             source = tcs_tested;
18829             array  = "[]";
18830             index  = "[gl_InvocationID]";
18831             break;
18832         case Utils::Shader::TESS_EVAL:
18833             source = tes_tested;
18834             array  = test_case.m_is_input ? "[]" : "";
18835             index  = test_case.m_is_input ? "[0]" : "";
18836             break;
18837         case Utils::Shader::VERTEX:
18838             source = vs_tested;
18839             break;
18840         default:
18841             TCU_FAIL("Invalid enum");
18842         }
18843 
18844         Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
18845         position = 0;
18846         Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
18847         Utils::replaceToken("INTERPOLATION", position, int_gohan, source);
18848         Utils::replaceToken("DIRECTION", position, direction, source);
18849         Utils::replaceToken("TYPE", position, type_gohan_name, source);
18850         Utils::replaceToken("ARRAY", position, array, source);
18851         Utils::replaceToken("COMPONENT", position, buffer_goten, source);
18852         Utils::replaceToken("INTERPOLATION", position, int_goten, source);
18853         Utils::replaceToken("DIRECTION", position, direction, source);
18854         Utils::replaceToken("TYPE", position, type_goten_name, source);
18855         Utils::replaceToken("ARRAY", position, array, source);
18856 
18857         temp = position;
18858         Utils::replaceToken("VARIABLE_USE", position, var_use, source);
18859         position = temp;
18860         if (!test_case.m_is_input)
18861         {
18862             Utils::replaceToken("TYPE", position, type_gohan_name, source);
18863             Utils::replaceToken("TYPE", position, type_goten_name, source);
18864             Utils::replaceToken("TYPE", position, type_gohan_name, source);
18865             Utils::replaceToken("TYPE", position, type_goten_name, source);
18866         }
18867         else if (Utils::Shader::VERTEX == stage)
18868         {
18869             Utils::replaceToken("TYPE", position, type_gohan_name, source);
18870             Utils::replaceToken("TYPE", position, type_goten_name, source);
18871         }
18872 
18873         Utils::replaceAllTokens("INDEX", index, source);
18874     }
18875     else
18876     {
18877         switch (stage)
18878         {
18879         case Utils::Shader::FRAGMENT:
18880             source = fs;
18881             break;
18882         case Utils::Shader::GEOMETRY:
18883             source = gs;
18884             break;
18885         case Utils::Shader::TESS_CTRL:
18886             source = tcs;
18887             break;
18888         case Utils::Shader::TESS_EVAL:
18889             source = tes;
18890             break;
18891         case Utils::Shader::VERTEX:
18892             source = vs;
18893             break;
18894         default:
18895             TCU_FAIL("Invalid enum");
18896         }
18897     }
18898 
18899     return source;
18900 }
18901 
18902 /** Get description of test case
18903  *
18904  * @param test_case_index Index of test case
18905  *
18906  * @return Test case description
18907  **/
18908 std::string VaryingLocationAliasingWithMixedInterpolationTest::getTestCaseName(GLuint test_case_index)
18909 {
18910     std::stringstream stream;
18911     testCase &test_case = m_test_cases[test_case_index];
18912 
18913     stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", "
18914            << getInterpolationQualifier(test_case.m_interpolation_gohan) << " "
18915            << test_case.m_type_gohan.GetGLSLTypeName() << " at " << test_case.m_component_gohan << ", "
18916            << getInterpolationQualifier(test_case.m_interpolation_goten) << " "
18917            << test_case.m_type_goten.GetGLSLTypeName() << " at " << test_case.m_component_goten << ". Direction: ";
18918 
18919     if (true == test_case.m_is_input)
18920     {
18921         stream << "input";
18922     }
18923     else
18924     {
18925         stream << "output";
18926     }
18927 
18928     return stream.str();
18929 }
18930 
18931 /** Get number of test cases
18932  *
18933  * @return Number of test cases
18934  **/
18935 GLuint VaryingLocationAliasingWithMixedInterpolationTest::getTestCaseNumber()
18936 {
18937     return static_cast<GLuint>(m_test_cases.size());
18938 }
18939 
18940 /** Selects if "compute" stage is relevant for test
18941  *
18942  * @param ignored
18943  *
18944  * @return false
18945  **/
18946 bool VaryingLocationAliasingWithMixedInterpolationTest::isComputeRelevant(GLuint /* test_case_index */)
18947 {
18948     return false;
18949 }
18950 
18951 /** Prepare all test cases
18952  *
18953  **/
18954 void VaryingLocationAliasingWithMixedInterpolationTest::testInit()
18955 {
18956     const GLuint n_types = getTypesNumber();
18957 
18958     for (GLuint i = 0; i < n_types; ++i)
18959     {
18960         const Utils::Type &type_gohan                     = getType(i);
18961         const std::vector<GLuint> &valid_components_gohan = type_gohan.GetValidComponents();
18962 
18963         if (valid_components_gohan.empty())
18964         {
18965             continue;
18966         }
18967 
18968         const GLuint gohan = valid_components_gohan.front();
18969 
18970         for (GLuint j = 0; j < n_types; ++j)
18971         {
18972             const Utils::Type &type_goten                     = getType(j);
18973             const std::vector<GLuint> &valid_components_goten = type_goten.GetValidComponents();
18974 
18975             if (valid_components_goten.empty())
18976             {
18977                 continue;
18978             }
18979 
18980             /* Just get the highest valid component for goten and
18981              * check if we can use it.
18982              */
18983             const GLuint min_component = gohan + type_gohan.GetNumComponents();
18984             const GLuint goten         = valid_components_goten.back();
18985 
18986             if (min_component > goten)
18987             {
18988                 continue;
18989             }
18990 
18991             /* Skip invalid combinations */
18992             if (!Utils::Type::CanTypesShareLocation(type_gohan.m_basic_type, type_goten.m_basic_type))
18993             {
18994                 continue;
18995             }
18996 
18997             for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
18998             {
18999                 /* Skip compute shader */
19000                 if (Utils::Shader::COMPUTE == stage)
19001                 {
19002                     continue;
19003                 }
19004 
19005                 for (GLuint int_gohan = 0; int_gohan < INTERPOLATION_MAX; ++int_gohan)
19006                 {
19007                     for (GLuint int_goten = 0; int_goten < INTERPOLATION_MAX; ++int_goten)
19008                     {
19009                         /* Skip when both are the same */
19010                         if (int_gohan == int_goten)
19011                         {
19012                             continue;
19013                         }
19014 
19015                         /* Skip inputs in: vertex shader and whenever
19016                          * flat is mandatory and is not the chosen
19017                          * one.
19018                          */
19019                         bool skip_inputs = Utils::Shader::VERTEX == stage;
19020                         skip_inputs |=
19021                             (FLAT != int_gohan && isFlatRequired(static_cast<Utils::Shader::STAGES>(stage), type_gohan,
19022                                                                  Utils::Variable::VARYING_INPUT));
19023                         skip_inputs |=
19024                             (FLAT != int_goten && isFlatRequired(static_cast<Utils::Shader::STAGES>(stage), type_goten,
19025                                                                  Utils::Variable::VARYING_INPUT));
19026 
19027                         if (!skip_inputs)
19028                         {
19029                             testCase test_case_in = {gohan,
19030                                                      goten,
19031                                                      static_cast<INTERPOLATIONS>(int_gohan),
19032                                                      static_cast<INTERPOLATIONS>(int_goten),
19033                                                      true,
19034                                                      static_cast<Utils::Shader::STAGES>(stage),
19035                                                      type_gohan,
19036                                                      type_goten};
19037                             m_test_cases.push_back(test_case_in);
19038                         }
19039 
19040                         /* Skip outputs in fragment shader and
19041                          * whenever flat is mandatory and is not the
19042                          * chosen one.
19043                          */
19044                         bool skip_outputs = Utils::Shader::FRAGMENT == stage;
19045                         skip_outputs |=
19046                             (FLAT != int_gohan && isFlatRequired(static_cast<Utils::Shader::STAGES>(stage), type_gohan,
19047                                                                  Utils::Variable::VARYING_OUTPUT));
19048                         skip_outputs |=
19049                             (FLAT != int_goten && isFlatRequired(static_cast<Utils::Shader::STAGES>(stage), type_goten,
19050                                                                  Utils::Variable::VARYING_OUTPUT));
19051 
19052                         if (!skip_outputs)
19053                         {
19054                             testCase test_case_out = {gohan,
19055                                                       goten,
19056                                                       static_cast<INTERPOLATIONS>(int_gohan),
19057                                                       static_cast<INTERPOLATIONS>(int_goten),
19058                                                       false,
19059                                                       static_cast<Utils::Shader::STAGES>(stage),
19060                                                       type_gohan,
19061                                                       type_goten};
19062                             m_test_cases.push_back(test_case_out);
19063                         }
19064                     }
19065                 }
19066             }
19067         }
19068     }
19069 }
19070 
19071 /** Get interpolation qualifier
19072  *
19073  * @param interpolation Enumeration
19074  *
19075  * @return GLSL qualifier
19076  **/
19077 const GLchar *VaryingLocationAliasingWithMixedInterpolationTest::getInterpolationQualifier(INTERPOLATIONS interpolation)
19078 {
19079     const GLchar *result = 0;
19080 
19081     switch (interpolation)
19082     {
19083     case SMOOTH:
19084         result = "smooth";
19085         break;
19086     case FLAT:
19087         result = "flat";
19088         break;
19089     case NO_PERSPECTIVE:
19090         result = "noperspective";
19091         break;
19092     default:
19093         TCU_FAIL("Invalid enum");
19094     }
19095 
19096     return result;
19097 }
19098 
19099 /** Constructor
19100  *
19101  * @param context Test framework context
19102  **/
19103 VaryingLocationAliasingWithMixedAuxiliaryStorageTest::VaryingLocationAliasingWithMixedAuxiliaryStorageTest(
19104     deqp::Context &context)
19105     : NegativeTestBase(
19106           context, "varying_location_aliasing_with_mixed_auxiliary_storage",
19107           "Test verifies that compiler reports error when auxiliary storage qualifiers are mixed at one location")
19108 {
19109 }
19110 
19111 /** Source for given test case and stage
19112  *
19113  * @param test_case_index Index of test case
19114  * @param stage           Shader stage
19115  *
19116  * @return Shader source
19117  **/
19118 std::string VaryingLocationAliasingWithMixedAuxiliaryStorageTest::getShaderSource(GLuint test_case_index,
19119                                                                                   Utils::Shader::STAGES stage)
19120 {
19121     static const GLchar *var_definition =
19122         "layout (location = 1, component = COMPONENT) AUX INTERPOLATION DIRECTION TYPE gohanARRAY;\n"
19123         "layout (location = 1, component = COMPONENT) AUX INTERPOLATION DIRECTION TYPE gotenARRAY;\n";
19124     static const GLchar *input_use  = "    if ((TYPE(0) == gohanINDEX_GOHAN) &&\n"
19125                                       "        (TYPE(1) == gotenINDEX_GOTEN) )\n"
19126                                       "    {\n"
19127                                       "        result += vec4(1, 0.5, 0.25, 0.125);\n"
19128                                       "    }\n";
19129     static const GLchar *output_use = "    gohanINDEX_GOHAN = TYPE(0);\n"
19130                                       "    gotenINDEX_GOTEN = TYPE(1);\n"
19131                                       "    if (vec4(0) == result)\n"
19132                                       "    {\n"
19133                                       "        gohanINDEX_GOHAN = TYPE(1);\n"
19134                                       "        gotenINDEX_GOTEN = TYPE(0);\n"
19135                                       "    }\n";
19136     static const GLchar *fs         = "#version 430 core\n"
19137                                       "#extension GL_ARB_enhanced_layouts : require\n"
19138                                       "\n"
19139                                       "in  vec4 gs_fs;\n"
19140                                       "out vec4 fs_out;\n"
19141                                       "\n"
19142                                       "void main()\n"
19143                                       "{\n"
19144                                       "    fs_out = gs_fs;\n"
19145                                       "}\n"
19146                                       "\n";
19147     static const GLchar *fs_tested  = "#version 430 core\n"
19148                                       "#extension GL_ARB_enhanced_layouts : require\n"
19149                                       "\n"
19150                                       "VAR_DEFINITION"
19151                                       "\n"
19152                                       "in  vec4 gs_fs;\n"
19153                                       "out vec4 fs_out;\n"
19154                                       "\n"
19155                                       "void main()\n"
19156                                       "{\n"
19157                                       "    vec4 result = gs_fs;\n"
19158                                       "\n"
19159                                       "VARIABLE_USE"
19160                                       "\n"
19161                                       "    fs_out = result;\n"
19162                                       "}\n"
19163                                       "\n";
19164     static const GLchar *gs         = "#version 430 core\n"
19165                                       "#extension GL_ARB_enhanced_layouts : require\n"
19166                                       "\n"
19167                                       "layout(points)                           in;\n"
19168                                       "layout(triangle_strip, max_vertices = 4) out;\n"
19169                                       "\n"
19170                                       "in  vec4 tes_gs[];\n"
19171                                       "out vec4 gs_fs;\n"
19172                                       "\n"
19173                                       "void main()\n"
19174                                       "{\n"
19175                                       "    gs_fs = tes_gs[0];\n"
19176                                       "    gl_Position  = vec4(-1, -1, 0, 1);\n"
19177                                       "    EmitVertex();\n"
19178                                       "    gs_fs = tes_gs[0];\n"
19179                                       "    gl_Position  = vec4(-1, 1, 0, 1);\n"
19180                                       "    EmitVertex();\n"
19181                                       "    gs_fs = tes_gs[0];\n"
19182                                       "    gl_Position  = vec4(1, -1, 0, 1);\n"
19183                                       "    EmitVertex();\n"
19184                                       "    gs_fs = tes_gs[0];\n"
19185                                       "    gl_Position  = vec4(1, 1, 0, 1);\n"
19186                                       "    EmitVertex();\n"
19187                                       "}\n"
19188                                       "\n";
19189     static const GLchar *gs_tested  = "#version 430 core\n"
19190                                       "#extension GL_ARB_enhanced_layouts : require\n"
19191                                       "\n"
19192                                       "layout(points)                           in;\n"
19193                                       "layout(triangle_strip, max_vertices = 4) out;\n"
19194                                       "\n"
19195                                       "VAR_DEFINITION"
19196                                       "\n"
19197                                       "in  vec4 tes_gs[];\n"
19198                                       "out vec4 gs_fs;\n"
19199                                       "\n"
19200                                       "void main()\n"
19201                                       "{\n"
19202                                       "    vec4 result = tes_gs[0];\n"
19203                                       "\n"
19204                                       "VARIABLE_USE"
19205                                       "\n"
19206                                       "    gs_fs = result;\n"
19207                                       "    gl_Position  = vec4(-1, -1, 0, 1);\n"
19208                                       "    EmitVertex();\n"
19209                                       "    gs_fs = result;\n"
19210                                       "    gl_Position  = vec4(-1, 1, 0, 1);\n"
19211                                       "    EmitVertex();\n"
19212                                       "    gs_fs = result;\n"
19213                                       "    gl_Position  = vec4(1, -1, 0, 1);\n"
19214                                       "    EmitVertex();\n"
19215                                       "    gs_fs = result;\n"
19216                                       "    gl_Position  = vec4(1, 1, 0, 1);\n"
19217                                       "    EmitVertex();\n"
19218                                       "}\n"
19219                                       "\n";
19220     static const GLchar *tcs        = "#version 430 core\n"
19221                                       "#extension GL_ARB_enhanced_layouts : require\n"
19222                                       "\n"
19223                                       "layout(vertices = 1) out;\n"
19224                                       "\n"
19225                                       "in  vec4 vs_tcs[];\n"
19226                                       "out vec4 tcs_tes[];\n"
19227                                       "\n"
19228                                       "void main()\n"
19229                                       "{\n"
19230                                       "\n"
19231                                       "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
19232                                       "\n"
19233                                       "    gl_TessLevelOuter[0] = 1.0;\n"
19234                                       "    gl_TessLevelOuter[1] = 1.0;\n"
19235                                       "    gl_TessLevelOuter[2] = 1.0;\n"
19236                                       "    gl_TessLevelOuter[3] = 1.0;\n"
19237                                       "    gl_TessLevelInner[0] = 1.0;\n"
19238                                       "    gl_TessLevelInner[1] = 1.0;\n"
19239                                       "}\n"
19240                                       "\n";
19241     static const GLchar *tcs_tested = "#version 430 core\n"
19242                                       "#extension GL_ARB_enhanced_layouts : require\n"
19243                                       "\n"
19244                                       "layout(vertices = 1) out;\n"
19245                                       "\n"
19246                                       "VAR_DEFINITION"
19247                                       "\n"
19248                                       "in  vec4 vs_tcs[];\n"
19249                                       "out vec4 tcs_tes[];\n"
19250                                       "\n"
19251                                       "void main()\n"
19252                                       "{\n"
19253                                       "    vec4 result = vs_tcs[gl_InvocationID];\n"
19254                                       "\n"
19255                                       "VARIABLE_USE"
19256                                       "\n"
19257                                       "    tcs_tes[gl_InvocationID] = result;\n"
19258                                       "\n"
19259                                       "    gl_TessLevelOuter[0] = 1.0;\n"
19260                                       "    gl_TessLevelOuter[1] = 1.0;\n"
19261                                       "    gl_TessLevelOuter[2] = 1.0;\n"
19262                                       "    gl_TessLevelOuter[3] = 1.0;\n"
19263                                       "    gl_TessLevelInner[0] = 1.0;\n"
19264                                       "    gl_TessLevelInner[1] = 1.0;\n"
19265                                       "}\n"
19266                                       "\n";
19267     static const GLchar *tes        = "#version 430 core\n"
19268                                       "#extension GL_ARB_enhanced_layouts : require\n"
19269                                       "\n"
19270                                       "layout(isolines, point_mode) in;\n"
19271                                       "\n"
19272                                       "in  vec4 tcs_tes[];\n"
19273                                       "out vec4 tes_gs;\n"
19274                                       "\n"
19275                                       "void main()\n"
19276                                       "{\n"
19277                                       "    tes_gs = tcs_tes[0];\n"
19278                                       "}\n"
19279                                       "\n";
19280     static const GLchar *tes_tested = "#version 430 core\n"
19281                                       "#extension GL_ARB_enhanced_layouts : require\n"
19282                                       "\n"
19283                                       "layout(isolines, point_mode) in;\n"
19284                                       "\n"
19285                                       "VAR_DEFINITION"
19286                                       "\n"
19287                                       "in  vec4 tcs_tes[];\n"
19288                                       "out vec4 tes_gs;\n"
19289                                       "\n"
19290                                       "void main()\n"
19291                                       "{\n"
19292                                       "    vec4 result = tcs_tes[0];\n"
19293                                       "\n"
19294                                       "VARIABLE_USE"
19295                                       "\n"
19296                                       "    tes_gs += result;\n"
19297                                       "}\n"
19298                                       "\n";
19299     static const GLchar *vs         = "#version 430 core\n"
19300                                       "#extension GL_ARB_enhanced_layouts : require\n"
19301                                       "\n"
19302                                       "in  vec4 in_vs;\n"
19303                                       "out vec4 vs_tcs;\n"
19304                                       "\n"
19305                                       "void main()\n"
19306                                       "{\n"
19307                                       "    vs_tcs = in_vs;\n"
19308                                       "}\n"
19309                                       "\n";
19310     static const GLchar *vs_tested  = "#version 430 core\n"
19311                                       "#extension GL_ARB_enhanced_layouts : require\n"
19312                                       "\n"
19313                                       "VAR_DEFINITION"
19314                                       "\n"
19315                                       "in  vec4 in_vs;\n"
19316                                       "out vec4 vs_tcs;\n"
19317                                       "\n"
19318                                       "void main()\n"
19319                                       "{\n"
19320                                       "    vec4 result = in_vs;\n"
19321                                       "\n"
19322                                       "VARIABLE_USE"
19323                                       "\n"
19324                                       "    vs_tcs += result;\n"
19325                                       "}\n"
19326                                       "\n";
19327 
19328     std::string source;
19329     testCase &test_case = m_test_cases[test_case_index];
19330 
19331     if (test_case.m_stage == stage)
19332     {
19333         const GLchar *array_gohan = "";
19334         const GLchar *array_goten = "";
19335         const GLchar *aux_gohan   = getAuxiliaryQualifier(test_case.m_aux_gohan);
19336 #if DEBUG_NEG_REMOVE_ERROR
19337         const GLchar *aux_goten = aux_gohan;
19338 #else
19339         const GLchar *aux_goten = getAuxiliaryQualifier(test_case.m_aux_goten);
19340 #endif /* DEBUG_NEG_REMOVE_ERROR */
19341         GLchar buffer_gohan[16];
19342         GLchar buffer_goten[16];
19343         const GLchar *direction          = "in";
19344         const GLchar *index_gohan        = "";
19345         const GLchar *index_goten        = "";
19346         Utils::Variable::STORAGE storage = Utils::Variable::VARYING_INPUT;
19347         const GLchar *interpolation      = "";
19348         size_t position                  = 0;
19349         size_t temp;
19350         const GLchar *type_gohan_name = test_case.m_type_gohan.GetGLSLTypeName();
19351         const GLchar *type_goten_name = test_case.m_type_goten.GetGLSLTypeName();
19352         const GLchar *var_use         = Utils::Shader::VERTEX == stage ? input_use : "\n";
19353 
19354         if (false == test_case.m_is_input)
19355         {
19356             direction = "out";
19357             storage   = Utils::Variable::VARYING_OUTPUT;
19358             var_use   = output_use;
19359         }
19360 
19361         if (isFlatRequired(stage, test_case.m_type_gohan, storage) ||
19362             isFlatRequired(stage, test_case.m_type_goten, storage))
19363         {
19364             interpolation = "flat";
19365         }
19366 
19367         sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
19368         sprintf(buffer_goten, "%d", test_case.m_component_goten);
19369 
19370         switch (stage)
19371         {
19372         case Utils::Shader::FRAGMENT:
19373             source = fs_tested;
19374             break;
19375         case Utils::Shader::GEOMETRY:
19376             source      = gs_tested;
19377             array_gohan = test_case.m_is_input ? "[]" : "";
19378             index_gohan = test_case.m_is_input ? "[0]" : "";
19379             array_goten = test_case.m_is_input ? "[]" : "";
19380             index_goten = test_case.m_is_input ? "[0]" : "";
19381             break;
19382         case Utils::Shader::TESS_CTRL:
19383             source = tcs_tested;
19384             if (PATCH != test_case.m_aux_gohan)
19385             {
19386                 array_gohan = "[]";
19387                 index_gohan = "[gl_InvocationID]";
19388             }
19389 #if DEBUG_NEG_REMOVE_ERROR
19390             array_goten = array_gohan;
19391             index_goten = index_gohan;
19392 #else
19393             if (PATCH != test_case.m_aux_goten)
19394             {
19395                 array_goten = "[]";
19396                 index_goten = "[gl_InvocationID]";
19397             }
19398 #endif /* DEBUG_NEG_REMOVE_ERROR */
19399             break;
19400         case Utils::Shader::TESS_EVAL:
19401             source = tes_tested;
19402             if (PATCH != test_case.m_aux_gohan)
19403             {
19404                 array_gohan = test_case.m_is_input ? "[]" : "";
19405                 index_gohan = test_case.m_is_input ? "[0]" : "";
19406             }
19407 #if DEBUG_NEG_REMOVE_ERROR
19408             array_goten = array_gohan;
19409             index_goten = index_gohan;
19410 #else
19411             if (PATCH != test_case.m_aux_goten)
19412             {
19413                 array_goten = test_case.m_is_input ? "[]" : "";
19414                 index_goten = test_case.m_is_input ? "[0]" : "";
19415             }
19416 #endif /* DEBUG_NEG_REMOVE_ERROR */
19417             break;
19418         case Utils::Shader::VERTEX:
19419             source = vs_tested;
19420             break;
19421         default:
19422             TCU_FAIL("Invalid enum");
19423         }
19424 
19425         Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
19426         position = 0;
19427         Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
19428         Utils::replaceToken("AUX", position, aux_gohan, source);
19429         Utils::replaceToken("INTERPOLATION", position, interpolation, source);
19430         Utils::replaceToken("DIRECTION", position, direction, source);
19431         Utils::replaceToken("TYPE", position, type_gohan_name, source);
19432         Utils::replaceToken("ARRAY", position, array_gohan, source);
19433         Utils::replaceToken("COMPONENT", position, buffer_goten, source);
19434         Utils::replaceToken("AUX", position, aux_goten, source);
19435         Utils::replaceToken("INTERPOLATION", position, interpolation, source);
19436         Utils::replaceToken("DIRECTION", position, direction, source);
19437         Utils::replaceToken("TYPE", position, type_goten_name, source);
19438         Utils::replaceToken("ARRAY", position, array_goten, source);
19439 
19440         temp = position;
19441         Utils::replaceToken("VARIABLE_USE", position, var_use, source);
19442         position = temp;
19443         if (!test_case.m_is_input)
19444         {
19445             Utils::replaceToken("TYPE", position, type_gohan_name, source);
19446             Utils::replaceToken("TYPE", position, type_goten_name, source);
19447             Utils::replaceToken("TYPE", position, type_gohan_name, source);
19448             Utils::replaceToken("TYPE", position, type_goten_name, source);
19449         }
19450         else if (Utils::Shader::VERTEX == stage)
19451         {
19452             Utils::replaceToken("TYPE", position, type_gohan_name, source);
19453             Utils::replaceToken("TYPE", position, type_goten_name, source);
19454         }
19455 
19456         Utils::replaceAllTokens("INDEX_GOHAN", index_gohan, source);
19457         Utils::replaceAllTokens("INDEX_GOTEN", index_goten, source);
19458     }
19459     else
19460     {
19461         switch (stage)
19462         {
19463         case Utils::Shader::FRAGMENT:
19464             source = fs;
19465             break;
19466         case Utils::Shader::GEOMETRY:
19467             source = gs;
19468             break;
19469         case Utils::Shader::TESS_CTRL:
19470             source = tcs;
19471             break;
19472         case Utils::Shader::TESS_EVAL:
19473             source = tes;
19474             break;
19475         case Utils::Shader::VERTEX:
19476             source = vs;
19477             break;
19478         default:
19479             TCU_FAIL("Invalid enum");
19480         }
19481     }
19482 
19483     return source;
19484 }
19485 
19486 /** Get description of test case
19487  *
19488  * @param test_case_index Index of test case
19489  *
19490  * @return Test case description
19491  **/
19492 std::string VaryingLocationAliasingWithMixedAuxiliaryStorageTest::getTestCaseName(GLuint test_case_index)
19493 {
19494     std::stringstream stream;
19495     testCase &test_case = m_test_cases[test_case_index];
19496 
19497     stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", "
19498            << getAuxiliaryQualifier(test_case.m_aux_gohan) << " " << test_case.m_type_gohan.GetGLSLTypeName() << " at "
19499            << test_case.m_component_gohan << ", " << getAuxiliaryQualifier(test_case.m_aux_goten) << " "
19500            << test_case.m_type_goten.GetGLSLTypeName() << " at " << test_case.m_component_goten << ". Direction: ";
19501 
19502     if (true == test_case.m_is_input)
19503     {
19504         stream << "input";
19505     }
19506     else
19507     {
19508         stream << "output";
19509     }
19510 
19511     return stream.str();
19512 }
19513 
19514 /** Get number of test cases
19515  *
19516  * @return Number of test cases
19517  **/
19518 GLuint VaryingLocationAliasingWithMixedAuxiliaryStorageTest::getTestCaseNumber()
19519 {
19520     return static_cast<GLuint>(m_test_cases.size());
19521 }
19522 
19523 /** Selects if "compute" stage is relevant for test
19524  *
19525  * @param ignored
19526  *
19527  * @return false
19528  **/
19529 bool VaryingLocationAliasingWithMixedAuxiliaryStorageTest::isComputeRelevant(GLuint /* test_case_index */)
19530 {
19531     return false;
19532 }
19533 
19534 /** Prepare all test cases
19535  *
19536  **/
19537 void VaryingLocationAliasingWithMixedAuxiliaryStorageTest::testInit()
19538 {
19539     const GLuint n_types = getTypesNumber();
19540 
19541     for (GLuint i = 0; i < n_types; ++i)
19542     {
19543         const Utils::Type &type_gohan                     = getType(i);
19544         const std::vector<GLuint> &valid_components_gohan = type_gohan.GetValidComponents();
19545 
19546         if (valid_components_gohan.empty())
19547         {
19548             continue;
19549         }
19550 
19551         const GLuint gohan = valid_components_gohan.front();
19552 
19553         for (GLuint j = 0; j < n_types; ++j)
19554         {
19555             const Utils::Type &type_goten                     = getType(j);
19556             const std::vector<GLuint> &valid_components_goten = type_goten.GetValidComponents();
19557 
19558             if (valid_components_goten.empty())
19559             {
19560                 continue;
19561             }
19562 
19563             /* Just get the highest valid component for goten and
19564              * check if we can use it.
19565              */
19566             const GLuint min_component = gohan + type_gohan.GetNumComponents();
19567             const GLuint goten         = valid_components_goten.back();
19568 
19569             if (min_component > goten)
19570             {
19571                 continue;
19572             }
19573 
19574             /* Skip invalid combinations */
19575             if (!Utils::Type::CanTypesShareLocation(type_gohan.m_basic_type, type_goten.m_basic_type))
19576             {
19577                 continue;
19578             }
19579 
19580             for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
19581             {
19582                 /* Skip compute shader */
19583                 if (Utils::Shader::COMPUTE == stage)
19584                 {
19585                     continue;
19586                 }
19587 
19588                 for (GLuint aux = 0; aux < AUXILIARY_MAX; ++aux)
19589                 {
19590                     Utils::Shader::STAGES const shader_stage = static_cast<Utils::Shader::STAGES>(stage);
19591                     AUXILIARIES const auxiliary              = static_cast<AUXILIARIES>(aux);
19592 
19593                     if (PATCH == auxiliary)
19594                     {
19595                         if (Utils::Shader::TESS_CTRL == shader_stage || Utils::Shader::TESS_EVAL == shader_stage)
19596                         {
19597                             bool direction                 = Utils::Shader::TESS_EVAL == shader_stage;
19598                             testCase test_case_patch_gohan = {gohan,     goten,        auxiliary,  NONE,
19599                                                               direction, shader_stage, type_gohan, type_goten};
19600                             testCase test_case_patch_goten = {gohan,     goten,        NONE,       auxiliary,
19601                                                               direction, shader_stage, type_gohan, type_goten};
19602 
19603                             m_test_cases.push_back(test_case_patch_gohan);
19604                             m_test_cases.push_back(test_case_patch_goten);
19605                         }
19606                         continue;
19607                     }
19608 
19609                     for (GLuint second_aux = 0; second_aux < AUXILIARY_MAX; ++second_aux)
19610                     {
19611                         AUXILIARIES const second_auxiliary = static_cast<AUXILIARIES>(second_aux);
19612 
19613                         if (PATCH == second_auxiliary || auxiliary == second_auxiliary)
19614                         {
19615                             continue;
19616                         }
19617 
19618                         if (Utils::Shader::FRAGMENT != shader_stage)
19619                         {
19620                             testCase test_case_out = {gohan, goten,        auxiliary,  second_auxiliary,
19621                                                       false, shader_stage, type_gohan, type_goten};
19622 
19623                             m_test_cases.push_back(test_case_out);
19624                         }
19625 
19626                         if (Utils::Shader::VERTEX != shader_stage)
19627                         {
19628                             testCase test_case_in = {gohan, goten,        auxiliary,  second_auxiliary,
19629                                                      true,  shader_stage, type_gohan, type_goten};
19630 
19631                             m_test_cases.push_back(test_case_in);
19632                         }
19633                     }
19634                 }
19635             }
19636         }
19637     }
19638 }
19639 
19640 /** Get auxiliary storage qualifier
19641  *
19642  * @param aux Enumeration
19643  *
19644  * @return GLSL qualifier
19645  **/
19646 const GLchar *VaryingLocationAliasingWithMixedAuxiliaryStorageTest::getAuxiliaryQualifier(AUXILIARIES aux)
19647 {
19648     const GLchar *result = 0;
19649 
19650     switch (aux)
19651     {
19652     case NONE:
19653         result = "";
19654         break;
19655     case PATCH:
19656         result = "patch";
19657         break;
19658     case CENTROID:
19659         result = "centroid";
19660         break;
19661     case SAMPLE:
19662         result = "sample";
19663         break;
19664     default:
19665         TCU_FAIL("Invalid enum");
19666     }
19667 
19668     return result;
19669 }
19670 
19671 /* Constants used by VertexAttribLocationAPITest */
19672 const GLuint VertexAttribLocationAPITest::m_goten_location = 6;
19673 
19674 /** Constructor
19675  *
19676  * @param context Test framework context
19677  **/
19678 VertexAttribLocationAPITest::VertexAttribLocationAPITest(deqp::Context &context)
19679     : TextureTestBase(context, "vertex_attrib_location_api",
19680                       "Test verifies that attribute locations API works as expected")
19681 {
19682 }
19683 
19684 /** Does BindAttribLocation for "goten" and relink program
19685  *
19686  * @param program           Program object
19687  * @param program_interface Interface of program
19688  **/
19689 void VertexAttribLocationAPITest::prepareAttribLocation(Utils::Program &program,
19690                                                         Utils::ProgramInterface &program_interface)
19691 {
19692     const Functions &gl = m_context.getRenderContext().getFunctions();
19693 
19694     gl.bindAttribLocation(program.m_id, m_goten_location, "goten");
19695     GLU_EXPECT_NO_ERROR(gl.getError(), "BindAttribLocation");
19696 
19697     program.Link(gl, program.m_id);
19698 
19699     /* We still need to get locations for gohan and chichi */
19700     TextureTestBase::prepareAttribLocation(program, program_interface);
19701 }
19702 
19703 /** Get interface of program
19704  *
19705  * @param ignored
19706  * @param program_interface   Interface of program
19707  * @param ignored
19708  **/
19709 void VertexAttribLocationAPITest::getProgramInterface(GLuint /* test_case_index */,
19710                                                       Utils::ProgramInterface &program_interface,
19711                                                       Utils::VaryingPassthrough & /* varying_passthrough */)
19712 {
19713     Utils::ShaderInterface &si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
19714     const Utils::Type &type    = Utils::Type::vec4;
19715     const GLuint type_size     = type.GetSize();
19716 
19717     /* Offsets */
19718     const GLuint chichi_offset = 0;
19719     const GLuint goten_offset  = chichi_offset + type_size;
19720     const GLuint gohan_offset  = goten_offset + type_size;
19721     const GLuint goku_offset   = gohan_offset + type_size;
19722 
19723     /* Locations */
19724     const GLuint goku_location  = 2;
19725     const GLuint goten_location = m_goten_location;
19726 
19727     /* Generate data */
19728     m_goku_data   = type.GenerateDataPacked();
19729     m_gohan_data  = type.GenerateDataPacked();
19730     m_goten_data  = type.GenerateDataPacked();
19731     m_chichi_data = type.GenerateDataPacked();
19732 
19733     /* Globals */
19734     si.m_globals = "const uint GOKU_LOCATION = 2;\n";
19735 
19736     /* Attributes */
19737     si.Input("goku" /* name */, "layout (location = GOKU_LOCATION)" /* qualifiers */, 0 /* expected_componenet */,
19738              goku_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19739              0u /* n_array_elements */, 0u /* stride */, goku_offset /* offset */, (GLvoid *)&m_goku_data[0] /* data */,
19740              m_goku_data.size() /* data_size */);
19741 
19742     si.Input("gohan" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19743              Utils::Variable::m_automatic_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19744              0u /* n_array_elements */, 0u /* stride */, gohan_offset /* offset */,
19745              (GLvoid *)&m_gohan_data[0] /* data */, m_gohan_data.size() /* data_size */);
19746 
19747     si.Input("goten" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19748              goten_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19749              0u /* n_array_elements */, 0u /* stride */, goten_offset /* offset */,
19750              (GLvoid *)&m_goten_data[0] /* data */, m_goten_data.size() /* data_size */);
19751 
19752     si.Input("chichi" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19753              Utils::Variable::m_automatic_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19754              0u /* n_array_elements */, 0u /* stride */, chichi_offset /* offset */,
19755              (GLvoid *)&m_chichi_data[0] /* data */, m_chichi_data.size() /* data_size */);
19756 }
19757 
19758 /** Selects if "compute" stage is relevant for test
19759  *
19760  * @param ignored
19761  *
19762  * @return false
19763  **/
19764 bool VertexAttribLocationAPITest::isComputeRelevant(GLuint /* test_case_index */)
19765 {
19766     return false;
19767 }
19768 
19769 /* Constants used by FragmentDataLocationAPITest */
19770 const GLuint FragmentDataLocationAPITest::m_goten_location = 6;
19771 
19772 /** Constructor
19773  *
19774  * @param context Test framework context
19775  **/
19776 FragmentDataLocationAPITest::FragmentDataLocationAPITest(deqp::Context &context)
19777     : TextureTestBase(context, "fragment_data_location_api",
19778                       "Test verifies that fragment data locations API works as expected")
19779     , m_goku(context)
19780     , m_gohan(context)
19781     , m_goten(context)
19782     , m_chichi(context)
19783     , m_goku_location(0)
19784     , m_gohan_location(0)
19785     , m_chichi_location(0)
19786 {
19787 }
19788 
19789 /** Verifies contents of drawn images
19790  *
19791  * @param ignored
19792  * @param ignored
19793  *
19794  * @return true if images are filled with expected values, false otherwise
19795  **/
19796 bool FragmentDataLocationAPITest::checkResults(glw::GLuint /* test_case_index */, Utils::Texture & /* color_0 */)
19797 {
19798     static const GLuint size            = m_width * m_height;
19799     static const GLuint expected_goku   = 0xff000000;
19800     static const GLuint expected_gohan  = 0xff0000ff;
19801     static const GLuint expected_goten  = 0xff00ff00;
19802     static const GLuint expected_chichi = 0xffff0000;
19803 
19804     std::vector<GLuint> data;
19805     data.resize(size);
19806 
19807     m_goku.Get(GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
19808 
19809     for (GLuint i = 0; i < size; ++i)
19810     {
19811         const GLuint color = data[i];
19812 
19813         if (expected_goku != color)
19814         {
19815             m_context.getTestContext().getLog()
19816                 << tcu::TestLog::Message << "RGBA8[" << i << "]:" << color << tcu::TestLog::EndMessage;
19817             return false;
19818         }
19819     }
19820 
19821     m_gohan.Get(GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
19822 
19823     for (GLuint i = 0; i < size; ++i)
19824     {
19825         const GLuint color = data[i];
19826 
19827         if (expected_gohan != color)
19828         {
19829             m_context.getTestContext().getLog()
19830                 << tcu::TestLog::Message << "RGBA8[" << i << "]:" << color << tcu::TestLog::EndMessage;
19831             return false;
19832         }
19833     }
19834 
19835     m_goten.Get(GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
19836 
19837     for (GLuint i = 0; i < size; ++i)
19838     {
19839         const GLuint color = data[i];
19840 
19841         if (expected_goten != color)
19842         {
19843             m_context.getTestContext().getLog()
19844                 << tcu::TestLog::Message << "RGBA8[" << i << "]:" << color << tcu::TestLog::EndMessage;
19845             return false;
19846         }
19847     }
19848 
19849     m_chichi.Get(GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
19850 
19851     for (GLuint i = 0; i < size; ++i)
19852     {
19853         const GLuint color = data[i];
19854 
19855         if (expected_chichi != color)
19856         {
19857             m_context.getTestContext().getLog()
19858                 << tcu::TestLog::Message << "RGBA8[" << i << "]:" << color << tcu::TestLog::EndMessage;
19859             return false;
19860         }
19861     }
19862 
19863     return true;
19864 }
19865 
19866 /** Prepare code snippet that will set out variables
19867  *
19868  * @param ignored
19869  * @param ignored
19870  * @param stage               Shader stage
19871  *
19872  * @return Code that pass in variables to next stage
19873  **/
19874 std::string FragmentDataLocationAPITest::getPassSnippet(GLuint /* test_case_index */,
19875                                                         Utils::VaryingPassthrough & /* varying_passthrough */,
19876                                                         Utils::Shader::STAGES stage)
19877 {
19878     std::string result;
19879 
19880     /* Skip for compute shader */
19881     if (Utils::Shader::FRAGMENT != stage)
19882     {
19883         result = "";
19884     }
19885     else
19886     {
19887         result = "chichi = vec4(0, 0, 1, 1);\n"
19888                  "    goku   = vec4(0, 0, 0, 1);\n"
19889                  "    goten  = vec4(0, 1, 0, 1);\n"
19890                  "    gohan  = vec4(1, 0, 0, 1);\n";
19891     }
19892 
19893     return result;
19894 }
19895 
19896 /** Get interface of program
19897  *
19898  * @param ignored
19899  * @param program_interface Interface of program
19900  * @param ignored
19901  **/
19902 void FragmentDataLocationAPITest::getProgramInterface(GLuint /* test_case_index */,
19903                                                       Utils::ProgramInterface &program_interface,
19904                                                       Utils::VaryingPassthrough & /* varying_passthrough */)
19905 {
19906     Utils::ShaderInterface &si = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
19907     const Utils::Type &type    = Utils::Type::vec4;
19908 
19909     /* Locations */
19910     m_goku_location = 2;
19911 
19912     /* Globals */
19913     si.m_globals = "const uint GOKU_LOCATION = 2;\n";
19914 
19915     /* Attributes */
19916     si.Output("goku" /* name */, "layout (location = GOKU_LOCATION)" /* qualifiers */, 0 /* expected_componenet */,
19917               m_goku_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19918               0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid *)0 /* data */, 0u /* data_size */);
19919 
19920     si.Output("gohan" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19921               Utils::Variable::m_automatic_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19922               0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid *)0 /* data */, 0u /* data_size */);
19923 
19924     si.Output("goten" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19925               m_goten_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19926               0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid *)0 /* data */, 0u /* data_size */);
19927 
19928     si.Output("chichi" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19929               Utils::Variable::m_automatic_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19930               0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid *)0 /* data */, 0u /* data_size */);
19931 }
19932 
19933 /** Selects if "compute" stage is relevant for test
19934  *
19935  * @param ignored
19936  *
19937  * @return false
19938  **/
19939 bool FragmentDataLocationAPITest::isComputeRelevant(GLuint /* test_case_index */)
19940 {
19941     return false;
19942 }
19943 
19944 /** Get locations for all outputs with automatic_location
19945  *
19946  * @param program           Program object
19947  * @param program_interface Interface of program
19948  **/
19949 void FragmentDataLocationAPITest::prepareFragmentDataLoc(Utils::Program &program,
19950                                                          Utils::ProgramInterface &program_interface)
19951 {
19952     /* Bind location of goten */
19953     const Functions &gl = m_context.getRenderContext().getFunctions();
19954 
19955     gl.bindFragDataLocation(program.m_id, m_goten_location, "goten");
19956     GLU_EXPECT_NO_ERROR(gl.getError(), "BindFragDataLocation");
19957 
19958     program.Link(gl, program.m_id);
19959 
19960     /* Prepare locations for gohan and chichi */
19961     TextureTestBase::prepareFragmentDataLoc(program, program_interface);
19962 
19963     /* Get all locations */
19964     Utils::ShaderInterface &si = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
19965 
19966     Utils::Variable::PtrVector &outputs = si.m_outputs;
19967 
19968     for (Utils::Variable::PtrVector::iterator it = outputs.begin(); outputs.end() != it; ++it)
19969     {
19970         const Utils::Variable::Descriptor &desc = (*it)->m_descriptor;
19971 
19972         if (0 == desc.m_name.compare("gohan"))
19973         {
19974             m_gohan_location = desc.m_expected_location;
19975         }
19976         else if (0 == desc.m_name.compare("chichi"))
19977         {
19978             m_chichi_location = desc.m_expected_location;
19979         }
19980 
19981         /* Locations of goku and goten are fixed */
19982     }
19983 }
19984 
19985 /** Prepare framebuffer with single texture as color attachment
19986  *
19987  * @param framebuffer     Framebuffer
19988  * @param color_0_texture Texture that will used as color attachment
19989  **/
19990 void FragmentDataLocationAPITest::prepareFramebuffer(Utils::Framebuffer &framebuffer, Utils::Texture &color_0_texture)
19991 {
19992     /* Let parent prepare its stuff */
19993     TextureTestBase::prepareFramebuffer(framebuffer, color_0_texture);
19994 
19995     /* Prepare data */
19996     std::vector<GLuint> texture_data;
19997     texture_data.resize(m_width * m_height);
19998 
19999     for (GLuint i = 0; i < texture_data.size(); ++i)
20000     {
20001         texture_data[i] = 0x20406080;
20002     }
20003 
20004     /* Prepare textures */
20005     m_goku.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]);
20006 
20007     m_gohan.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]);
20008 
20009     m_goten.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]);
20010 
20011     m_chichi.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]);
20012 
20013     /* Attach textures to framebuffer */
20014     framebuffer.Bind();
20015     framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0 + m_goku_location, m_goku.m_id, m_width, m_height);
20016     framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0 + m_gohan_location, m_gohan.m_id, m_width, m_height);
20017     framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0 + m_goten_location, m_goten.m_id, m_width, m_height);
20018     framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0 + m_chichi_location, m_chichi.m_id, m_width, m_height);
20019 
20020     /* Set up drawbuffers */
20021     const Functions &gl = m_context.getRenderContext().getFunctions();
20022     // The fragment shader can have more than 4 color outputs, but it only care about 4 (goku, gohan, goten, chichi).
20023     // We will first initialize all draw buffers to NONE and then set the real value for the 4 outputs we care about
20024     GLint maxDrawBuffers = 0;
20025     gl.getIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
20026 
20027     std::vector<GLenum> buffers(maxDrawBuffers, GL_NONE);
20028     buffers[m_chichi_location] = GLenum(GL_COLOR_ATTACHMENT0 + m_chichi_location);
20029     buffers[m_goten_location]  = GLenum(GL_COLOR_ATTACHMENT0 + m_goten_location);
20030     buffers[m_goku_location]   = GLenum(GL_COLOR_ATTACHMENT0 + m_goku_location);
20031     buffers[m_gohan_location]  = GLenum(GL_COLOR_ATTACHMENT0 + m_gohan_location);
20032 
20033     gl.drawBuffers(maxDrawBuffers, buffers.data());
20034     GLU_EXPECT_NO_ERROR(gl.getError(), "DrawBuffers");
20035 }
20036 
20037 /** Constructor
20038  *
20039  * @param context Test framework context
20040  **/
20041 XFBInputTest::XFBInputTest(deqp::Context &context)
20042     : NegativeTestBase(context, "xfb_input",
20043                        "Test verifies that compiler reports error when xfb qualifiers are used with input")
20044 {
20045 }
20046 
20047 /** Source for given test case and stage
20048  *
20049  * @param test_case_index Index of test case
20050  * @param stage           Shader stage
20051  *
20052  * @return Shader source
20053  **/
20054 std::string XFBInputTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
20055 {
20056 #if DEBUG_NEG_REMOVE_ERROR
20057     static const GLchar *buffer_var_definition = "/* layout (xfb_buffer = 2) */ in vec4 gohanARRAY;\n";
20058     static const GLchar *offset_var_definition = "/* layout (xfb_offset = 16) */ in vec4 gohanARRAY;\n";
20059     static const GLchar *stride_var_definition = "/* layout (xfb_stride = 32) */ in vec4 gohanARRAY;\n";
20060 #else
20061     static const GLchar *buffer_var_definition = "layout (xfb_buffer = 2) in vec4 gohanARRAY;\n";
20062     static const GLchar *offset_var_definition = "layout (xfb_offset = 16) in vec4 gohanARRAY;\n";
20063     static const GLchar *stride_var_definition = "layout (xfb_stride = 32) in vec4 gohanARRAY;\n";
20064 #endif /* DEBUG_NEG_REMOVE_ERROR */
20065     static const GLchar *fs         = "#version 430 core\n"
20066                                       "#extension GL_ARB_enhanced_layouts : require\n"
20067                                       "\n"
20068                                       "in  vec4 gs_fs;\n"
20069                                       "out vec4 fs_out;\n"
20070                                       "\n"
20071                                       "void main()\n"
20072                                       "{\n"
20073                                       "    fs_out = gs_fs;\n"
20074                                       "}\n"
20075                                       "\n";
20076     static const GLchar *fs_tested  = "#version 430 core\n"
20077                                       "#extension GL_ARB_enhanced_layouts : require\n"
20078                                       "\n"
20079                                       "VAR_DEFINITION"
20080                                       "\n"
20081                                       "in  vec4 gs_fs;\n"
20082                                       "out vec4 fs_out;\n"
20083                                       "\n"
20084                                       "void main()\n"
20085                                       "{\n"
20086                                       "    vec4 result = gs_fs;\n"
20087                                       "\n"
20088                                       "    fs_out = result;\n"
20089                                       "}\n"
20090                                       "\n";
20091     static const GLchar *gs         = "#version 430 core\n"
20092                                       "#extension GL_ARB_enhanced_layouts : require\n"
20093                                       "\n"
20094                                       "layout(points)                           in;\n"
20095                                       "layout(triangle_strip, max_vertices = 4) out;\n"
20096                                       "\n"
20097                                       "in  vec4 tes_gs[];\n"
20098                                       "out vec4 gs_fs;\n"
20099                                       "\n"
20100                                       "void main()\n"
20101                                       "{\n"
20102                                       "    gs_fs = tes_gs[0];\n"
20103                                       "    gl_Position  = vec4(-1, -1, 0, 1);\n"
20104                                       "    EmitVertex();\n"
20105                                       "    gs_fs = tes_gs[0];\n"
20106                                       "    gl_Position  = vec4(-1, 1, 0, 1);\n"
20107                                       "    EmitVertex();\n"
20108                                       "    gs_fs = tes_gs[0];\n"
20109                                       "    gl_Position  = vec4(1, -1, 0, 1);\n"
20110                                       "    EmitVertex();\n"
20111                                       "    gs_fs = tes_gs[0];\n"
20112                                       "    gl_Position  = vec4(1, 1, 0, 1);\n"
20113                                       "    EmitVertex();\n"
20114                                       "}\n"
20115                                       "\n";
20116     static const GLchar *gs_tested  = "#version 430 core\n"
20117                                       "#extension GL_ARB_enhanced_layouts : require\n"
20118                                       "\n"
20119                                       "layout(points)                           in;\n"
20120                                       "layout(triangle_strip, max_vertices = 4) out;\n"
20121                                       "\n"
20122                                       "VAR_DEFINITION"
20123                                       "\n"
20124                                       "in  vec4 tes_gs[];\n"
20125                                       "out vec4 gs_fs;\n"
20126                                       "\n"
20127                                       "void main()\n"
20128                                       "{\n"
20129                                       "    vec4 result = tes_gs[0];\n"
20130                                       "\n"
20131                                       "    gs_fs = result;\n"
20132                                       "    gl_Position  = vec4(-1, -1, 0, 1);\n"
20133                                       "    EmitVertex();\n"
20134                                       "    gs_fs = result;\n"
20135                                       "    gl_Position  = vec4(-1, 1, 0, 1);\n"
20136                                       "    EmitVertex();\n"
20137                                       "    gs_fs = result;\n"
20138                                       "    gl_Position  = vec4(1, -1, 0, 1);\n"
20139                                       "    EmitVertex();\n"
20140                                       "    gs_fs = result;\n"
20141                                       "    gl_Position  = vec4(1, 1, 0, 1);\n"
20142                                       "    EmitVertex();\n"
20143                                       "}\n"
20144                                       "\n";
20145     static const GLchar *tcs        = "#version 430 core\n"
20146                                       "#extension GL_ARB_enhanced_layouts : require\n"
20147                                       "\n"
20148                                       "layout(vertices = 1) out;\n"
20149                                       "\n"
20150                                       "in  vec4 vs_tcs[];\n"
20151                                       "out vec4 tcs_tes[];\n"
20152                                       "\n"
20153                                       "void main()\n"
20154                                       "{\n"
20155                                       "\n"
20156                                       "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
20157                                       "\n"
20158                                       "    gl_TessLevelOuter[0] = 1.0;\n"
20159                                       "    gl_TessLevelOuter[1] = 1.0;\n"
20160                                       "    gl_TessLevelOuter[2] = 1.0;\n"
20161                                       "    gl_TessLevelOuter[3] = 1.0;\n"
20162                                       "    gl_TessLevelInner[0] = 1.0;\n"
20163                                       "    gl_TessLevelInner[1] = 1.0;\n"
20164                                       "}\n"
20165                                       "\n";
20166     static const GLchar *tcs_tested = "#version 430 core\n"
20167                                       "#extension GL_ARB_enhanced_layouts : require\n"
20168                                       "\n"
20169                                       "layout(vertices = 1) out;\n"
20170                                       "\n"
20171                                       "VAR_DEFINITION"
20172                                       "\n"
20173                                       "in  vec4 vs_tcs[];\n"
20174                                       "out vec4 tcs_tes[];\n"
20175                                       "\n"
20176                                       "void main()\n"
20177                                       "{\n"
20178                                       "    vec4 result = vs_tcs[gl_InvocationID];\n"
20179                                       "\n"
20180                                       "    tcs_tes[gl_InvocationID] = result;\n"
20181                                       "\n"
20182                                       "    gl_TessLevelOuter[0] = 1.0;\n"
20183                                       "    gl_TessLevelOuter[1] = 1.0;\n"
20184                                       "    gl_TessLevelOuter[2] = 1.0;\n"
20185                                       "    gl_TessLevelOuter[3] = 1.0;\n"
20186                                       "    gl_TessLevelInner[0] = 1.0;\n"
20187                                       "    gl_TessLevelInner[1] = 1.0;\n"
20188                                       "}\n"
20189                                       "\n";
20190     static const GLchar *tes        = "#version 430 core\n"
20191                                       "#extension GL_ARB_enhanced_layouts : require\n"
20192                                       "\n"
20193                                       "layout(isolines, point_mode) in;\n"
20194                                       "\n"
20195                                       "in  vec4 tcs_tes[];\n"
20196                                       "out vec4 tes_gs;\n"
20197                                       "\n"
20198                                       "void main()\n"
20199                                       "{\n"
20200                                       "    tes_gs = tcs_tes[0];\n"
20201                                       "}\n"
20202                                       "\n";
20203     static const GLchar *tes_tested = "#version 430 core\n"
20204                                       "#extension GL_ARB_enhanced_layouts : require\n"
20205                                       "\n"
20206                                       "layout(isolines, point_mode) in;\n"
20207                                       "\n"
20208                                       "VAR_DEFINITION"
20209                                       "\n"
20210                                       "in  vec4 tcs_tes[];\n"
20211                                       "out vec4 tes_gs;\n"
20212                                       "\n"
20213                                       "void main()\n"
20214                                       "{\n"
20215                                       "    vec4 result = tcs_tes[0];\n"
20216                                       "\n"
20217                                       "    tes_gs += result;\n"
20218                                       "}\n"
20219                                       "\n";
20220     static const GLchar *vs         = "#version 430 core\n"
20221                                       "#extension GL_ARB_enhanced_layouts : require\n"
20222                                       "\n"
20223                                       "in  vec4 in_vs;\n"
20224                                       "out vec4 vs_tcs;\n"
20225                                       "\n"
20226                                       "void main()\n"
20227                                       "{\n"
20228                                       "    vs_tcs = in_vs;\n"
20229                                       "}\n"
20230                                       "\n";
20231     static const GLchar *vs_tested  = "#version 430 core\n"
20232                                       "#extension GL_ARB_enhanced_layouts : require\n"
20233                                       "\n"
20234                                       "VAR_DEFINITION"
20235                                       "\n"
20236                                       "in  vec4 in_vs;\n"
20237                                       "out vec4 vs_tcs;\n"
20238                                       "\n"
20239                                       "void main()\n"
20240                                       "{\n"
20241                                       "    vec4 result = in_vs;\n"
20242                                       "\n"
20243                                       "    vs_tcs += result;\n"
20244                                       "}\n"
20245                                       "\n";
20246 
20247     std::string source;
20248     testCase &test_case = m_test_cases[test_case_index];
20249 
20250     if (test_case.m_stage == stage)
20251     {
20252         const GLchar *array          = "";
20253         size_t position              = 0;
20254         const GLchar *var_definition = 0;
20255 
20256         switch (test_case.m_qualifier)
20257         {
20258         case BUFFER:
20259             var_definition = buffer_var_definition;
20260             break;
20261         case OFFSET:
20262             var_definition = offset_var_definition;
20263             break;
20264         case STRIDE:
20265             var_definition = stride_var_definition;
20266             break;
20267         default:
20268             TCU_FAIL("Invalid enum");
20269         }
20270 
20271         switch (stage)
20272         {
20273         case Utils::Shader::FRAGMENT:
20274             source = fs_tested;
20275             break;
20276         case Utils::Shader::GEOMETRY:
20277             source = gs_tested;
20278             array  = "[]";
20279             break;
20280         case Utils::Shader::TESS_CTRL:
20281             source = tcs_tested;
20282             array  = "[]";
20283             break;
20284         case Utils::Shader::TESS_EVAL:
20285             source = tes_tested;
20286             array  = "[]";
20287             break;
20288         case Utils::Shader::VERTEX:
20289             source = vs_tested;
20290             break;
20291         default:
20292             TCU_FAIL("Invalid enum");
20293         }
20294 
20295         Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
20296         position = 0;
20297         Utils::replaceToken("ARRAY", position, array, source);
20298     }
20299     else
20300     {
20301         switch (stage)
20302         {
20303         case Utils::Shader::FRAGMENT:
20304             source = fs;
20305             break;
20306         case Utils::Shader::GEOMETRY:
20307             source = gs;
20308             break;
20309         case Utils::Shader::TESS_CTRL:
20310             source = tcs;
20311             break;
20312         case Utils::Shader::TESS_EVAL:
20313             source = tes;
20314             break;
20315         case Utils::Shader::VERTEX:
20316             source = vs;
20317             break;
20318         default:
20319             TCU_FAIL("Invalid enum");
20320         }
20321     }
20322 
20323     return source;
20324 }
20325 
20326 /** Get description of test case
20327  *
20328  * @param test_case_index Index of test case
20329  *
20330  * @return Test case description
20331  **/
20332 std::string XFBInputTest::getTestCaseName(GLuint test_case_index)
20333 {
20334     std::stringstream stream;
20335     testCase &test_case = m_test_cases[test_case_index];
20336 
20337     stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", qualifier: ";
20338 
20339     switch (test_case.m_qualifier)
20340     {
20341     case BUFFER:
20342         stream << "xfb_buffer";
20343         break;
20344     case OFFSET:
20345         stream << "xfb_offset";
20346         break;
20347     case STRIDE:
20348         stream << "xfb_stride";
20349         break;
20350     default:
20351         TCU_FAIL("Invalid enum");
20352     }
20353 
20354     return stream.str();
20355 }
20356 
20357 /** Get number of test cases
20358  *
20359  * @return Number of test cases
20360  **/
20361 GLuint XFBInputTest::getTestCaseNumber()
20362 {
20363     return static_cast<GLuint>(m_test_cases.size());
20364 }
20365 
20366 /** Selects if "compute" stage is relevant for test
20367  *
20368  * @param ignored
20369  *
20370  * @return false
20371  **/
20372 bool XFBInputTest::isComputeRelevant(GLuint /* test_case_index */)
20373 {
20374     return false;
20375 }
20376 
20377 /** Prepare all test cases
20378  *
20379  **/
20380 void XFBInputTest::testInit()
20381 {
20382     for (GLuint qualifier = 0; qualifier < QUALIFIERS_MAX; ++qualifier)
20383     {
20384         for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
20385         {
20386             if (Utils::Shader::COMPUTE == stage)
20387             {
20388                 continue;
20389             }
20390 
20391             testCase test_case = {(QUALIFIERS)qualifier, (Utils::Shader::STAGES)stage};
20392 
20393             m_test_cases.push_back(test_case);
20394         }
20395     }
20396 }
20397 
20398 /* Constants used by XFBAllStagesTest */
20399 const GLuint XFBAllStagesTest::m_gs_index = 3;
20400 
20401 /** Constructor
20402  *
20403  * @param context Test context
20404  **/
20405 XFBAllStagesTest::XFBAllStagesTest(deqp::Context &context)
20406     : BufferTestBase(context, "xfb_all_stages",
20407                      "Test verifies that only last stage in vertex processing can output to transform feedback")
20408 {
20409     /* Nothing to be done here */
20410 }
20411 
20412 /** Get descriptors of buffers necessary for test
20413  *
20414  * @param ignored
20415  * @param out_descriptors Descriptors of buffers used by test
20416  **/
20417 void XFBAllStagesTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
20418                                             bufferDescriptor::Vector &out_descriptors)
20419 {
20420     static const GLuint n_stages = 4;
20421     const Utils::Type &vec4      = Utils::Type::vec4;
20422 
20423     /* Data */
20424     tcu::Vec4 sum;
20425 
20426     /* Test uses single uniform and xfb per stage + uniform for fragment shader */
20427     out_descriptors.resize(n_stages * 2 + 1);
20428 
20429     /* */
20430     for (GLuint i = 0; i < n_stages; ++i)
20431     {
20432         /* Get references */
20433         bufferDescriptor &uniform = out_descriptors[i + 0];
20434         bufferDescriptor &xfb     = out_descriptors[i + n_stages];
20435 
20436         /* Index */
20437         uniform.m_index = i;
20438         xfb.m_index     = i;
20439 
20440         /* Target */
20441         uniform.m_target = Utils::Buffer::Uniform;
20442         xfb.m_target     = Utils::Buffer::Transform_feedback;
20443 
20444         /* Data */
20445         const tcu::Vec4 var(Utils::GetRandFloat(), Utils::GetRandFloat(), Utils::GetRandFloat(), Utils::GetRandFloat());
20446 
20447         sum += var;
20448 
20449         uniform.m_initial_data.resize(vec4.GetSize());
20450         memcpy(&uniform.m_initial_data[0], var.getPtr(), vec4.GetSize());
20451 
20452         xfb.m_initial_data = vec4.GenerateDataPacked();
20453 
20454         if (m_gs_index != i)
20455         {
20456             xfb.m_expected_data = xfb.m_initial_data;
20457         }
20458         else
20459         {
20460             xfb.m_expected_data.resize(vec4.GetSize());
20461             memcpy(&xfb.m_expected_data[0], sum.getPtr(), vec4.GetSize());
20462         }
20463     }
20464 
20465     /* FS */
20466     {
20467         /* Get reference */
20468         bufferDescriptor &uniform = out_descriptors[n_stages * 2];
20469 
20470         /* Index */
20471         uniform.m_index = n_stages;
20472 
20473         /* Target */
20474         uniform.m_target = Utils::Buffer::Uniform;
20475 
20476         /* Data */
20477         const tcu::Vec4 var(Utils::GetRandFloat(), Utils::GetRandFloat(), Utils::GetRandFloat(), Utils::GetRandFloat());
20478 
20479         uniform.m_initial_data.resize(vec4.GetSize());
20480         memcpy(&uniform.m_initial_data[0], var.getPtr(), vec4.GetSize());
20481     }
20482 }
20483 
20484 /** Get body of main function for given shader stage
20485  *
20486  * @param ignored
20487  * @param stage            Shader stage
20488  * @param out_assignments  Set to empty
20489  * @param out_calculations Set to empty
20490  **/
20491 void XFBAllStagesTest::getShaderBody(glw::GLuint /* test_case_index */, Utils::Shader::STAGES stage,
20492                                      std::string &out_assignments, std::string &out_calculations)
20493 {
20494     out_calculations = "";
20495 
20496     static const GLchar *vs  = "    vs_tcs  = uni_vs;\n";
20497     static const GLchar *tcs = "    tcs_tes[gl_InvocationID] = uni_tcs + vs_tcs[gl_InvocationID];\n";
20498     static const GLchar *tes = "    tes_gs  = uni_tes + tcs_tes[0];\n";
20499     static const GLchar *gs  = "    gs_fs   = uni_gs  + tes_gs[0];\n";
20500     static const GLchar *fs  = "    fs_out  = uni_fs  + gs_fs;\n";
20501 
20502     const GLchar *assignments = 0;
20503     switch (stage)
20504     {
20505     case Utils::Shader::FRAGMENT:
20506         assignments = fs;
20507         break;
20508     case Utils::Shader::GEOMETRY:
20509         assignments = gs;
20510         break;
20511     case Utils::Shader::TESS_CTRL:
20512         assignments = tcs;
20513         break;
20514     case Utils::Shader::TESS_EVAL:
20515         assignments = tes;
20516         break;
20517     case Utils::Shader::VERTEX:
20518         assignments = vs;
20519         break;
20520     default:
20521         TCU_FAIL("Invalid enum");
20522     }
20523 
20524     out_assignments = assignments;
20525 }
20526 
20527 /** Get interface of shader
20528  *
20529  * @param ignored
20530  * @param stage         Shader stage
20531  * @param out_interface Set to ""
20532  **/
20533 void XFBAllStagesTest::getShaderInterface(glw::GLuint /* test_case_index */, Utils::Shader::STAGES stage,
20534                                           std::string &out_interface)
20535 {
20536     static const GLchar *vs  = "layout(xfb_buffer = 0, xfb_offset = 0) out     vec4 vs_tcs;\n"
20537                                "layout(binding    = 0)                 uniform vs_block {\n"
20538                                "    vec4 uni_vs;\n"
20539                                "};\n";
20540     static const GLchar *tcs = "                                       in      vec4 vs_tcs[];\n"
20541                                "layout(xfb_buffer = 1, xfb_offset = 0) out     vec4 tcs_tes[1];\n"
20542                                "layout(binding    = 1)                 uniform tcs_block {\n"
20543                                "    vec4 uni_tcs;\n"
20544                                "};\n";
20545     static const GLchar *tes = "                                       in      vec4 tcs_tes[];\n"
20546                                "layout(xfb_buffer = 2, xfb_offset = 0) out     vec4 tes_gs;\n"
20547                                "layout(binding    = 2)                 uniform tes_block {\n"
20548                                "    vec4 uni_tes;\n"
20549                                "};\n";
20550     static const GLchar *gs  = "                                       in      vec4 tes_gs[];\n"
20551                                "layout(xfb_buffer = 3, xfb_offset = 0) out     vec4 gs_fs;\n"
20552                                "layout(binding    = 3)                 uniform gs_block {\n"
20553                                "    vec4 uni_gs;\n"
20554                                "};\n";
20555     static const GLchar *fs  = "                       in      vec4 gs_fs;\n"
20556                                "                       out     vec4 fs_out;\n"
20557                                "layout(binding    = 4) uniform fs_block {\n"
20558                                "    vec4 uni_fs;\n"
20559                                "};\n";
20560 
20561     const GLchar *interface = 0;
20562     switch (stage)
20563     {
20564     case Utils::Shader::FRAGMENT:
20565         interface = fs;
20566         break;
20567     case Utils::Shader::GEOMETRY:
20568         interface = gs;
20569         break;
20570     case Utils::Shader::TESS_CTRL:
20571         interface = tcs;
20572         break;
20573     case Utils::Shader::TESS_EVAL:
20574         interface = tes;
20575         break;
20576     case Utils::Shader::VERTEX:
20577         interface = vs;
20578         break;
20579     default:
20580         TCU_FAIL("Invalid enum");
20581     }
20582 
20583     out_interface = interface;
20584 }
20585 
20586 /* Constants used by XFBStrideOfEmptyListTest */
20587 const GLuint XFBStrideOfEmptyListTest::m_stride = 64;
20588 
20589 /** Constructor
20590  *
20591  * @param context Test context
20592  **/
20593 XFBStrideOfEmptyListTest::XFBStrideOfEmptyListTest(deqp::Context &context)
20594     : BufferTestBase(
20595           context, "xfb_stride_of_empty_list",
20596           "Test verifies correct behavior when xfb_stride qualifier is specified but no xfb_offset is specified")
20597 {
20598     /* Nothing to be done here */
20599 }
20600 
20601 /** Execute drawArrays for single vertex
20602  *
20603  * @param test_case_index Index of test case
20604  *
20605  * @return true if proper error is reported
20606  **/
20607 bool XFBStrideOfEmptyListTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
20608 {
20609     const Functions &gl = m_context.getRenderContext().getFunctions();
20610     bool result         = true;
20611 
20612     /* Draw */
20613     gl.disable(GL_RASTERIZER_DISCARD);
20614     GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
20615 
20616     gl.beginTransformFeedback(GL_POINTS);
20617     GLenum error = gl.getError();
20618     switch (test_case_index)
20619     {
20620     case VALID:
20621         if (GL_NO_ERROR != error)
20622         {
20623             gl.endTransformFeedback();
20624             GLU_EXPECT_NO_ERROR(error, "BeginTransformFeedback");
20625         }
20626 
20627         gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
20628         error = gl.getError();
20629 
20630         gl.endTransformFeedback();
20631         GLU_EXPECT_NO_ERROR(error, "DrawArrays");
20632         GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
20633 
20634         break;
20635 
20636     case FIRST_MISSING:
20637         if (GL_NO_ERROR == error)
20638         {
20639             gl.endTransformFeedback();
20640         }
20641 
20642         if (GL_INVALID_OPERATION != error)
20643         {
20644             m_context.getTestContext().getLog()
20645                 << tcu::TestLog::Message
20646                 << "XFB at index 0, that is written by GS, is missing. It was expected that "
20647                    "INVALID_OPERATION will generated by BeginTransformFeedback. Got: "
20648                 << glu::getErrorStr(error) << tcu::TestLog::EndMessage;
20649 
20650             result = false;
20651         }
20652 
20653         break;
20654 
20655     case SECOND_MISSING:
20656         if (GL_NO_ERROR != error)
20657         {
20658             gl.endTransformFeedback();
20659             GLU_EXPECT_NO_ERROR(error, "BeginTransformFeedback");
20660         }
20661 
20662         gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
20663         error = gl.getError();
20664 
20665         gl.endTransformFeedback();
20666         GLU_EXPECT_NO_ERROR(error, "DrawArrays");
20667         GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
20668 
20669         break;
20670     }
20671 
20672     /* Done */
20673     return result;
20674 }
20675 
20676 /** Get descriptors of buffers necessary for test
20677  *
20678  * @param test_case_index Index of test case
20679  * @param out_descriptors Descriptors of buffers used by test
20680  **/
20681 void XFBStrideOfEmptyListTest::getBufferDescriptors(glw::GLuint test_case_index,
20682                                                     bufferDescriptor::Vector &out_descriptors)
20683 {
20684     switch (test_case_index)
20685     {
20686     case VALID:
20687     {
20688         /* Test needs single uniform and two xfbs */
20689         out_descriptors.resize(3);
20690 
20691         /* Get references */
20692         bufferDescriptor &uniform = out_descriptors[0];
20693         bufferDescriptor &xfb_0   = out_descriptors[1];
20694         bufferDescriptor &xfb_1   = out_descriptors[2];
20695 
20696         /* Index */
20697         uniform.m_index = 0;
20698         xfb_0.m_index   = 0;
20699         xfb_1.m_index   = 1;
20700 
20701         /* Target */
20702         uniform.m_target = Utils::Buffer::Uniform;
20703         xfb_0.m_target   = Utils::Buffer::Transform_feedback;
20704         xfb_1.m_target   = Utils::Buffer::Transform_feedback;
20705 
20706         /* Data */
20707         uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20708 
20709         xfb_0.m_initial_data  = Utils::Type::vec4.GenerateDataPacked();
20710         xfb_0.m_expected_data = uniform.m_initial_data;
20711 
20712         /* Data, contents are the same as no modification is expected */
20713         xfb_1.m_initial_data.resize(m_stride);
20714         xfb_1.m_expected_data.resize(m_stride);
20715 
20716         for (GLuint i = 0; i < m_stride; ++i)
20717         {
20718             xfb_1.m_initial_data[0]  = (glw::GLubyte)i;
20719             xfb_1.m_expected_data[0] = (glw::GLubyte)i;
20720         }
20721     }
20722 
20723     break;
20724 
20725     case FIRST_MISSING:
20726     {
20727         /* Test needs single uniform and two xfbs */
20728         out_descriptors.resize(2);
20729 
20730         /* Get references */
20731         bufferDescriptor &uniform = out_descriptors[0];
20732         bufferDescriptor &xfb_1   = out_descriptors[1];
20733 
20734         /* Index */
20735         uniform.m_index = 0;
20736         xfb_1.m_index   = 1;
20737 
20738         /* Target */
20739         uniform.m_target = Utils::Buffer::Uniform;
20740         xfb_1.m_target   = Utils::Buffer::Transform_feedback;
20741 
20742         /* Data */
20743         uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20744 
20745         /* Draw call will not be executed, contents does not matter */
20746         xfb_1.m_initial_data.resize(m_stride);
20747     }
20748 
20749     break;
20750 
20751     case SECOND_MISSING:
20752     {
20753         /* Test needs single uniform and two xfbs */
20754         out_descriptors.resize(2);
20755 
20756         /* Get references */
20757         bufferDescriptor &uniform = out_descriptors[0];
20758         bufferDescriptor &xfb_0   = out_descriptors[1];
20759 
20760         /* Index */
20761         uniform.m_index = 0;
20762         xfb_0.m_index   = 0;
20763 
20764         /* Target */
20765         uniform.m_target = Utils::Buffer::Uniform;
20766         xfb_0.m_target   = Utils::Buffer::Transform_feedback;
20767 
20768         /* Data */
20769         uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20770 
20771         xfb_0.m_initial_data  = Utils::Type::vec4.GenerateDataPacked();
20772         xfb_0.m_expected_data = uniform.m_initial_data;
20773     }
20774 
20775     break;
20776     }
20777 }
20778 
20779 /** Get body of main function for given shader stage
20780  *
20781  * @param ignored
20782  * @param stage            Shader stage
20783  * @param out_assignments  Set to empty
20784  * @param out_calculations Set to empty
20785  **/
20786 void XFBStrideOfEmptyListTest::getShaderBody(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
20787                                              std::string &out_assignments, std::string &out_calculations)
20788 {
20789     out_calculations = "";
20790 
20791     static const GLchar *gs = "    gs_fs  = uni_gs;\n";
20792     static const GLchar *fs = "    fs_out = vec4(gs_fs);\n";
20793 
20794     const GLchar *assignments = "";
20795     switch (stage)
20796     {
20797     case Utils::Shader::FRAGMENT:
20798         assignments = fs;
20799         break;
20800     case Utils::Shader::GEOMETRY:
20801         assignments = gs;
20802         break;
20803     default:
20804         break;
20805     }
20806 
20807     out_assignments = assignments;
20808 }
20809 
20810 /** Get interface of shader
20811  *
20812  * @param ignored
20813  * @param stage            Shader stage
20814  * @param out_interface    Set to ""
20815  **/
20816 void XFBStrideOfEmptyListTest::getShaderInterface(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
20817                                                   std::string &out_interface)
20818 {
20819     static const GLchar *gs = "layout (xfb_buffer = 0, xfb_offset = 0)  out     vec4 gs_fs;\n"
20820                               "layout (xfb_buffer = 1, xfb_stride = 64) out;\n"
20821                               "\n"
20822                               "layout (binding    = 0)                  uniform gs_block {\n"
20823                               "    vec4 uni_gs;\n"
20824                               "};\n";
20825     static const GLchar *fs = "in  vec4 gs_fs;\n"
20826                               "out vec4 fs_out;\n";
20827 
20828     switch (stage)
20829     {
20830     case Utils::Shader::FRAGMENT:
20831         out_interface = fs;
20832         break;
20833     case Utils::Shader::GEOMETRY:
20834         out_interface = gs;
20835         break;
20836     default:
20837         out_interface = "";
20838         return;
20839     }
20840 }
20841 
20842 /** Returns buffer details in human readable form.
20843  *
20844  * @param test_case_index Index of test case
20845  *
20846  * @return Case description
20847  **/
20848 std::string XFBStrideOfEmptyListTest::getTestCaseName(GLuint test_case_index)
20849 {
20850     std::string result;
20851 
20852     switch (test_case_index)
20853     {
20854     case VALID:
20855         result = "Valid case";
20856         break;
20857     case FIRST_MISSING:
20858         result = "Missing xfb at index 0";
20859         break;
20860     case SECOND_MISSING:
20861         result = "Missing xfb at index 1";
20862         break;
20863     default:
20864         TCU_FAIL("Invalid enum");
20865     }
20866 
20867     return result;
20868 }
20869 
20870 /** Get number of test cases
20871  *
20872  * @return 3
20873  **/
20874 GLuint XFBStrideOfEmptyListTest::getTestCaseNumber()
20875 {
20876     return 3;
20877 }
20878 
20879 /* Constants used by XFBStrideOfEmptyListTest */
20880 const GLuint XFBStrideOfEmptyListAndAPITest::m_stride = 64;
20881 
20882 /** Constructor
20883  *
20884  * @param context Test context
20885  **/
20886 XFBStrideOfEmptyListAndAPITest::XFBStrideOfEmptyListAndAPITest(deqp::Context &context)
20887     : BufferTestBase(context, "xfb_stride_of_empty_list_and_api",
20888                      "Test verifies that xfb_stride qualifier is not overriden by API")
20889 {
20890     /* Nothing to be done here */
20891 }
20892 
20893 /** Execute drawArrays for single vertex
20894  *
20895  * @param test_case_index Index of test case
20896  *
20897  * @return true if proper error is reported
20898  **/
20899 bool XFBStrideOfEmptyListAndAPITest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
20900 {
20901     const Functions &gl = m_context.getRenderContext().getFunctions();
20902     bool result         = true;
20903 
20904     /* Draw */
20905     gl.disable(GL_RASTERIZER_DISCARD);
20906     GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
20907 
20908     gl.beginTransformFeedback(GL_POINTS);
20909     GLenum error = gl.getError();
20910     switch (test_case_index)
20911     {
20912     case VALID:
20913         if (GL_NO_ERROR != error)
20914         {
20915             gl.endTransformFeedback();
20916             GLU_EXPECT_NO_ERROR(error, "BeginTransformFeedback");
20917         }
20918 
20919         gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
20920         error = gl.getError();
20921 
20922         gl.endTransformFeedback();
20923         GLU_EXPECT_NO_ERROR(error, "DrawArrays");
20924         GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
20925 
20926         break;
20927 
20928     case FIRST_MISSING:
20929         if (GL_NO_ERROR != error)
20930         {
20931             gl.endTransformFeedback();
20932             GLU_EXPECT_NO_ERROR(error, "BeginTransformFeedback");
20933         }
20934 
20935         gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
20936         error = gl.getError();
20937 
20938         gl.endTransformFeedback();
20939         GLU_EXPECT_NO_ERROR(error, "DrawArrays");
20940         GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
20941 
20942         break;
20943 
20944     case SECOND_MISSING:
20945         if (GL_NO_ERROR == error)
20946         {
20947             gl.endTransformFeedback();
20948         }
20949 
20950         if (GL_INVALID_OPERATION != error)
20951         {
20952             m_context.getTestContext().getLog()
20953                 << tcu::TestLog::Message
20954                 << "XFB at index 1, that is declared as empty, is missing. It was expected "
20955                    "that INVALID_OPERATION will generated by BeginTransformFeedback. Got: "
20956                 << glu::getErrorStr(error) << tcu::TestLog::EndMessage;
20957 
20958             result = false;
20959         }
20960 
20961         break;
20962     }
20963 
20964     /* Done */
20965     return result;
20966 }
20967 
20968 /** Get descriptors of buffers necessary for test
20969  *
20970  * @param test_case_index Index of test case
20971  * @param out_descriptors Descriptors of buffers used by test
20972  **/
20973 void XFBStrideOfEmptyListAndAPITest::getBufferDescriptors(glw::GLuint test_case_index,
20974                                                           bufferDescriptor::Vector &out_descriptors)
20975 {
20976     switch (test_case_index)
20977     {
20978     case VALID:
20979     {
20980         /* Test needs single uniform and two xfbs */
20981         out_descriptors.resize(3);
20982 
20983         /* Get references */
20984         bufferDescriptor &uniform = out_descriptors[0];
20985         bufferDescriptor &xfb_0   = out_descriptors[1];
20986         bufferDescriptor &xfb_1   = out_descriptors[2];
20987 
20988         /* Index */
20989         uniform.m_index = 0;
20990         xfb_0.m_index   = 0;
20991         xfb_1.m_index   = 1;
20992 
20993         /* Target */
20994         uniform.m_target = Utils::Buffer::Uniform;
20995         xfb_0.m_target   = Utils::Buffer::Transform_feedback;
20996         xfb_1.m_target   = Utils::Buffer::Transform_feedback;
20997 
20998         /* Data */
20999         uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
21000 
21001         /* Data, contents are the same as no modification is expected */
21002         xfb_0.m_initial_data.resize(m_stride);
21003         xfb_0.m_expected_data.resize(m_stride);
21004 
21005         for (GLuint i = 0; i < m_stride; ++i)
21006         {
21007             xfb_0.m_initial_data[0]  = (glw::GLubyte)i;
21008             xfb_0.m_expected_data[0] = (glw::GLubyte)i;
21009         }
21010 
21011         xfb_1.m_initial_data  = Utils::Type::vec4.GenerateDataPacked();
21012         xfb_1.m_expected_data = uniform.m_initial_data;
21013     }
21014 
21015     break;
21016 
21017     case FIRST_MISSING:
21018     {
21019         /* Test needs single uniform and two xfbs */
21020         out_descriptors.resize(2);
21021 
21022         /* Get references */
21023         bufferDescriptor &uniform = out_descriptors[0];
21024         bufferDescriptor &xfb_1   = out_descriptors[1];
21025 
21026         /* Index */
21027         uniform.m_index = 0;
21028         xfb_1.m_index   = 1;
21029 
21030         /* Target */
21031         uniform.m_target = Utils::Buffer::Uniform;
21032         xfb_1.m_target   = Utils::Buffer::Transform_feedback;
21033 
21034         /* Data */
21035         uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
21036 
21037         /* Data, contents are the same as no modification is expected */
21038         xfb_1.m_initial_data  = Utils::Type::vec4.GenerateDataPacked();
21039         xfb_1.m_expected_data = uniform.m_initial_data;
21040     }
21041 
21042     break;
21043 
21044     case SECOND_MISSING:
21045     {
21046         /* Test needs single uniform and two xfbs */
21047         out_descriptors.resize(2);
21048 
21049         /* Get references */
21050         bufferDescriptor &uniform = out_descriptors[0];
21051         bufferDescriptor &xfb_0   = out_descriptors[1];
21052 
21053         /* Index */
21054         uniform.m_index = 0;
21055         xfb_0.m_index   = 0;
21056 
21057         /* Target */
21058         uniform.m_target = Utils::Buffer::Uniform;
21059         xfb_0.m_target   = Utils::Buffer::Transform_feedback;
21060 
21061         /* Data */
21062         uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
21063 
21064         /* Draw call will not be executed, contents does not matter */
21065         xfb_0.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
21066     }
21067 
21068     break;
21069     }
21070 }
21071 
21072 /** Get list of names of varyings that will be registered with TransformFeedbackVaryings
21073  *
21074  * @param ignored
21075  * @param captured_varyings Vector of varying names to be captured
21076  **/
21077 void XFBStrideOfEmptyListAndAPITest::getCapturedVaryings(glw::GLuint /* test_case_index */,
21078                                                          Utils::Program::NameVector &captured_varyings,
21079                                                          GLint *xfb_components)
21080 {
21081     captured_varyings.push_back("gs_fs1");
21082     captured_varyings.push_back("gs_fs2");
21083     *xfb_components = 4;
21084 }
21085 
21086 /** Get body of main function for given shader stage
21087  *
21088  * @param ignored
21089  * @param stage            Shader stage
21090  * @param out_assignments  Set to empty
21091  * @param out_calculations Set to empty
21092  **/
21093 void XFBStrideOfEmptyListAndAPITest::getShaderBody(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
21094                                                    std::string &out_assignments, std::string &out_calculations)
21095 {
21096     out_calculations = "";
21097 
21098     static const GLchar *gs = "    gs_fs1 = -uni_gs;\n"
21099                               "    gs_fs2 = uni_gs;\n";
21100     static const GLchar *fs = "    fs_out = vec4(gs_fs2);\n";
21101 
21102     const GLchar *assignments = "";
21103     switch (stage)
21104     {
21105     case Utils::Shader::FRAGMENT:
21106         assignments = fs;
21107         break;
21108     case Utils::Shader::GEOMETRY:
21109         assignments = gs;
21110         break;
21111     default:
21112         break;
21113     }
21114 
21115     out_assignments = assignments;
21116 }
21117 
21118 /** Get interface of shader
21119  *
21120  * @param ignored
21121  * @param stage            Shader stage
21122  * @param out_interface    Set to ""
21123  **/
21124 void XFBStrideOfEmptyListAndAPITest::getShaderInterface(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
21125                                                         std::string &out_interface)
21126 {
21127     static const GLchar *gs = "layout (xfb_buffer = 0, xfb_stride = 64) out vec4 gs_fs1;\n"
21128                               "layout (xfb_buffer = 1, xfb_offset = 0)  out vec4 gs_fs2;\n"
21129                               "\n"
21130                               "layout(binding    = 0) uniform gs_block {\n"
21131                               "    vec4 uni_gs;\n"
21132                               "};\n";
21133     static const GLchar *fs = "in  vec4 gs_fs2;\n"
21134                               "out vec4 fs_out;\n";
21135 
21136     switch (stage)
21137     {
21138     case Utils::Shader::FRAGMENT:
21139         out_interface = fs;
21140         break;
21141     case Utils::Shader::GEOMETRY:
21142         out_interface = gs;
21143         break;
21144     default:
21145         out_interface = "";
21146         return;
21147     }
21148 }
21149 
21150 /** Returns buffer details in human readable form.
21151  *
21152  * @param test_case_index Index of test case
21153  *
21154  * @return Case description
21155  **/
21156 std::string XFBStrideOfEmptyListAndAPITest::getTestCaseName(GLuint test_case_index)
21157 {
21158     std::string result;
21159 
21160     switch (test_case_index)
21161     {
21162     case VALID:
21163         result = "Valid case";
21164         break;
21165     case FIRST_MISSING:
21166         result = "Missing xfb at index 0";
21167         break;
21168     case SECOND_MISSING:
21169         result = "Missing xfb at index 1";
21170         break;
21171     default:
21172         TCU_FAIL("Invalid enum");
21173     }
21174 
21175     return result;
21176 }
21177 
21178 /** Get number of test cases
21179  *
21180  * @return 2
21181  **/
21182 GLuint XFBStrideOfEmptyListAndAPITest::getTestCaseNumber()
21183 {
21184     return 3;
21185 }
21186 
21187 /** Constructor
21188  *
21189  * @param context Test framework context
21190  **/
21191 XFBTooSmallStrideTest::XFBTooSmallStrideTest(deqp::Context &context)
21192     : NegativeTestBase(context, "xfb_too_small_stride",
21193                        "Test verifies that compiler reports error when xfb_stride sets not enough space")
21194 {
21195 }
21196 
21197 /** Source for given test case and stage
21198  *
21199  * @param test_case_index Index of test case
21200  * @param stage           Shader stage
21201  *
21202  * @return Shader source
21203  **/
21204 std::string XFBTooSmallStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
21205 {
21206 #if DEBUG_NEG_REMOVE_ERROR
21207     static const GLchar *array_var_definition = "layout (xfb_buffer = 0 /*, xfb_stride = 32 */ ) out;\n"
21208 #else
21209     static const GLchar *array_var_definition  = "layout (xfb_buffer = 0, xfb_stride = 32) out;\n"
21210 #endif /* DEBUG_NEG_REMOVE_ERROR */
21211                                                 "\n"
21212                                                 "layout (xfb_offset = 16) out vec4 gohan[4];\n";
21213 #if DEBUG_NEG_REMOVE_ERROR
21214     static const GLchar *block_var_definition = "layout (xfb_buffer = 0 /*, xfb_stride = 32 */ ) out;\n"
21215 #else
21216     static const GLchar *block_var_definition  = "layout (xfb_buffer = 0, xfb_stride = 32) out;\n"
21217 #endif /* DEBUG_NEG_REMOVE_ERROR */
21218                                                 "\n"
21219                                                 "layout (xfb_offset = 0) out Goku {\n"
21220                                                 "    vec4 gohan;\n"
21221                                                 "    vec4 goten;\n"
21222                                                 "    vec4 chichi;\n"
21223                                                 "} goku;\n";
21224 #if DEBUG_NEG_REMOVE_ERROR
21225     static const GLchar *offset_var_definition = "layout (xfb_buffer = 0 /*, xfb_stride = 40 */ ) out;\n"
21226 #else
21227     static const GLchar *offset_var_definition = "layout (xfb_buffer = 0, xfb_stride = 40) out;\n"
21228 #endif /* DEBUG_NEG_REMOVE_ERROR */
21229                                                  "\n"
21230                                                  "layout (xfb_offset = 32) out vec4 gohan;\n";
21231 // 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;"
21232 // To make the shader failed to compile, change xfb_stride to a value that is smaller than 32
21233 #if DEBUG_NEG_REMOVE_ERROR
21234     static const GLchar *stride_var_definition = "layout (xfb_buffer = 0 /*, xfb_stride = 28 */ ) out;\n"
21235                                                  "\n"
21236                                                  "layout (xfb_offset = 16 /*, xfb_stride = 28 */ ) out vec4 gohan;\n";
21237 #else
21238     static const GLchar *stride_var_definition = "layout (xfb_buffer = 0, xfb_stride = 28) out;\n"
21239                                                  "\n"
21240                                                  "layout (xfb_offset = 16, xfb_stride = 28) out vec4 gohan;\n";
21241 #endif /* DEBUG_NEG_REMOVE_ERROR */
21242     static const GLchar *array_use  = "    gohan[0] = result / 2;\n"
21243                                       "    gohan[1] = result / 4;\n"
21244                                       "    gohan[2] = result / 6;\n"
21245                                       "    gohan[3] = result / 8;\n";
21246     static const GLchar *block_use  = "    goku.gohan  = result / 2;\n"
21247                                       "    goku.goten  = result / 4;\n"
21248                                       "    goku.chichi = result / 6;\n";
21249     static const GLchar *output_use = "gohan = result / 4;\n";
21250     static const GLchar *fs         = "#version 430 core\n"
21251                                       "#extension GL_ARB_enhanced_layouts : require\n"
21252                                       "\n"
21253                                       "in  vec4 any_fs;\n"
21254                                       "out vec4 fs_out;\n"
21255                                       "\n"
21256                                       "void main()\n"
21257                                       "{\n"
21258                                       "    fs_out = any_fs;\n"
21259                                       "}\n"
21260                                       "\n";
21261     static const GLchar *gs_tested  = "#version 430 core\n"
21262                                       "#extension GL_ARB_enhanced_layouts : require\n"
21263                                       "\n"
21264                                       "layout(points)                           in;\n"
21265                                       "layout(triangle_strip, max_vertices = 4) out;\n"
21266                                       "\n"
21267                                       "VAR_DEFINITION"
21268                                       "\n"
21269                                       "in  vec4 vs_any[];\n"
21270                                       "out vec4 any_fs;\n"
21271                                       "\n"
21272                                       "void main()\n"
21273                                       "{\n"
21274                                       "    vec4 result = vs_any[0];\n"
21275                                       "\n"
21276                                       "VARIABLE_USE"
21277                                       "\n"
21278                                       "    any_fs = result;\n"
21279                                       "    gl_Position  = vec4(-1, -1, 0, 1);\n"
21280                                       "    EmitVertex();\n"
21281                                       "    any_fs = result;\n"
21282                                       "    gl_Position  = vec4(-1, 1, 0, 1);\n"
21283                                       "    EmitVertex();\n"
21284                                       "    any_fs = result;\n"
21285                                       "    gl_Position  = vec4(1, -1, 0, 1);\n"
21286                                       "    EmitVertex();\n"
21287                                       "    any_fs = result;\n"
21288                                       "    gl_Position  = vec4(1, 1, 0, 1);\n"
21289                                       "    EmitVertex();\n"
21290                                       "}\n"
21291                                       "\n";
21292     static const GLchar *tcs        = "#version 430 core\n"
21293                                       "#extension GL_ARB_enhanced_layouts : require\n"
21294                                       "\n"
21295                                       "layout(vertices = 1) out;\n"
21296                                       "\n"
21297                                       "in  vec4 vs_any[];\n"
21298                                       "out vec4 tcs_tes[];\n"
21299                                       "\n"
21300                                       "void main()\n"
21301                                       "{\n"
21302                                       "\n"
21303                                       "    tcs_tes[gl_InvocationID] = vs_any[gl_InvocationID];\n"
21304                                       "\n"
21305                                       "    gl_TessLevelOuter[0] = 1.0;\n"
21306                                       "    gl_TessLevelOuter[1] = 1.0;\n"
21307                                       "    gl_TessLevelOuter[2] = 1.0;\n"
21308                                       "    gl_TessLevelOuter[3] = 1.0;\n"
21309                                       "    gl_TessLevelInner[0] = 1.0;\n"
21310                                       "    gl_TessLevelInner[1] = 1.0;\n"
21311                                       "}\n"
21312                                       "\n";
21313     static const GLchar *tes_tested = "#version 430 core\n"
21314                                       "#extension GL_ARB_enhanced_layouts : require\n"
21315                                       "\n"
21316                                       "layout(isolines, point_mode) in;\n"
21317                                       "\n"
21318                                       "VAR_DEFINITION"
21319                                       "\n"
21320                                       "in  vec4 tcs_tes[];\n"
21321                                       "out vec4 any_fs;\n"
21322                                       "\n"
21323                                       "void main()\n"
21324                                       "{\n"
21325                                       "    vec4 result = tcs_tes[0];\n"
21326                                       "\n"
21327                                       "VARIABLE_USE"
21328                                       "\n"
21329                                       "    any_fs += result;\n"
21330                                       "}\n"
21331                                       "\n";
21332     static const GLchar *vs         = "#version 430 core\n"
21333                                       "#extension GL_ARB_enhanced_layouts : require\n"
21334                                       "\n"
21335                                       "in  vec4 in_vs;\n"
21336                                       "out vec4 vs_any;\n"
21337                                       "\n"
21338                                       "void main()\n"
21339                                       "{\n"
21340                                       "    vs_any = in_vs;\n"
21341                                       "}\n"
21342                                       "\n";
21343     static const GLchar *vs_tested  = "#version 430 core\n"
21344                                       "#extension GL_ARB_enhanced_layouts : require\n"
21345                                       "\n"
21346                                       "VAR_DEFINITION"
21347                                       "\n"
21348                                       "in  vec4 in_vs;\n"
21349                                       "out vec4 any_fs;\n"
21350                                       "\n"
21351                                       "void main()\n"
21352                                       "{\n"
21353                                       "    vec4 result = in_vs;\n"
21354                                       "\n"
21355                                       "VARIABLE_USE"
21356                                       "\n"
21357                                       "    any_fs += result;\n"
21358                                       "}\n"
21359                                       "\n";
21360 
21361     std::string source;
21362     testCase &test_case = m_test_cases[test_case_index];
21363 
21364     if (test_case.m_stage == stage)
21365     {
21366         size_t position              = 0;
21367         const GLchar *var_definition = 0;
21368         const GLchar *var_use        = 0;
21369 
21370         switch (test_case.m_case)
21371         {
21372         case OFFSET:
21373             var_definition = offset_var_definition;
21374             var_use        = output_use;
21375             break;
21376         case STRIDE:
21377             var_definition = stride_var_definition;
21378             var_use        = output_use;
21379             break;
21380         case BLOCK:
21381             var_definition = block_var_definition;
21382             var_use        = block_use;
21383             break;
21384         case ARRAY:
21385             var_definition = array_var_definition;
21386             var_use        = array_use;
21387             break;
21388         default:
21389             TCU_FAIL("Invalid enum");
21390         }
21391 
21392         switch (stage)
21393         {
21394         case Utils::Shader::GEOMETRY:
21395             source = gs_tested;
21396             break;
21397         case Utils::Shader::TESS_EVAL:
21398             source = tes_tested;
21399             break;
21400         case Utils::Shader::VERTEX:
21401             source = vs_tested;
21402             break;
21403         default:
21404             TCU_FAIL("Invalid enum");
21405         }
21406 
21407         Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
21408         position = 0;
21409         Utils::replaceToken("VARIABLE_USE", position, var_use, source);
21410     }
21411     else
21412     {
21413         switch (test_case.m_stage)
21414         {
21415         case Utils::Shader::GEOMETRY:
21416             switch (stage)
21417             {
21418             case Utils::Shader::FRAGMENT:
21419                 source = fs;
21420                 break;
21421             case Utils::Shader::VERTEX:
21422                 source = vs;
21423                 break;
21424             default:
21425                 source = "";
21426             }
21427             break;
21428         case Utils::Shader::TESS_EVAL:
21429             switch (stage)
21430             {
21431             case Utils::Shader::FRAGMENT:
21432                 source = fs;
21433                 break;
21434             case Utils::Shader::TESS_CTRL:
21435                 source = tcs;
21436                 break;
21437             case Utils::Shader::VERTEX:
21438                 source = vs;
21439                 break;
21440             default:
21441                 source = "";
21442             }
21443             break;
21444         case Utils::Shader::VERTEX:
21445             switch (stage)
21446             {
21447             case Utils::Shader::FRAGMENT:
21448                 source = fs;
21449                 break;
21450             default:
21451                 source = "";
21452             }
21453             break;
21454         default:
21455             TCU_FAIL("Invalid enum");
21456         }
21457     }
21458 
21459     return source;
21460 }
21461 
21462 /** Get description of test case
21463  *
21464  * @param test_case_index Index of test case
21465  *
21466  * @return Test case description
21467  **/
21468 std::string XFBTooSmallStrideTest::getTestCaseName(GLuint test_case_index)
21469 {
21470     std::stringstream stream;
21471     testCase &test_case = m_test_cases[test_case_index];
21472 
21473     stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", case: ";
21474 
21475     switch (test_case.m_case)
21476     {
21477     case OFFSET:
21478         stream << "buffer stride: 40, vec4 offset: 32";
21479         break;
21480     case STRIDE:
21481         stream << "buffer stride: 32, vec4 off 16 stride: 32";
21482         break;
21483     case BLOCK:
21484         stream << "buffer stride: 32, block 3xvec4 offset 0";
21485         break;
21486     case ARRAY:
21487         stream << "buffer stride: 32, vec4[4] offset 16";
21488         break;
21489     default:
21490         TCU_FAIL("Invalid enum");
21491     }
21492 
21493     return stream.str();
21494 }
21495 
21496 /** Get number of test cases
21497  *
21498  * @return Number of test cases
21499  **/
21500 GLuint XFBTooSmallStrideTest::getTestCaseNumber()
21501 {
21502     return static_cast<GLuint>(m_test_cases.size());
21503 }
21504 
21505 /** Selects if "compute" stage is relevant for test
21506  *
21507  * @param ignored
21508  *
21509  * @return false
21510  **/
21511 bool XFBTooSmallStrideTest::isComputeRelevant(GLuint /* test_case_index */)
21512 {
21513     return false;
21514 }
21515 
21516 /** Prepare all test cases
21517  *
21518  **/
21519 void XFBTooSmallStrideTest::testInit()
21520 {
21521     for (GLuint c = 0; c < CASE_MAX; ++c)
21522     {
21523         for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
21524         {
21525             /*
21526              It is invalid to define transform feedback output in TCS, according to spec:
21527              The data captured in transform feedback mode depends on the active programs on each of the shader stages.
21528              If a program is active for the geometry shader stage, transform feedback captures the vertices of each
21529              primitive emitted by the geometry shader. Otherwise, if a program is active for the tessellation evaluation
21530              shader stage, transform feedback captures each primitive produced by the tessellation primitive generator,
21531              whose vertices are processed by the tessellation evaluation shader. Otherwise, transform feedback captures
21532              each primitive processed by the vertex shader.
21533              */
21534             if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
21535                 (Utils::Shader::FRAGMENT == stage))
21536             {
21537                 continue;
21538             }
21539 
21540             testCase test_case = {(CASES)c, (Utils::Shader::STAGES)stage};
21541 
21542             m_test_cases.push_back(test_case);
21543         }
21544     }
21545 }
21546 
21547 /** Constructor
21548  *
21549  * @param context Test framework context
21550  **/
21551 XFBVariableStrideTest::XFBVariableStrideTest(deqp::Context &context)
21552     : NegativeTestBase(context, "xfb_variable_stride", "Test verifies that stride qualifier is respected")
21553 {
21554 }
21555 
21556 /** Source for given test case and stage
21557  *
21558  * @param test_case_index Index of test case
21559  * @param stage           Shader stage
21560  *
21561  * @return Shader source
21562  **/
21563 std::string XFBVariableStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
21564 {
21565     static const GLchar *invalid_var_definition = "const uint type_size = SIZE;\n"
21566                                                   "\n"
21567 #if DEBUG_NEG_REMOVE_ERROR
21568                                                   "layout (xfb_stride = 2 * type_size) out;\n"
21569 #else
21570                                                   "layout (xfb_stride = type_size) out;\n"
21571 #endif /* DEBUG_NEG_REMOVE_ERROR */
21572                                                   "\n"
21573                                                   "layout (xfb_offset = 0)         out TYPE goku;\n"
21574                                                   "layout (xfb_offset = type_size) out TYPE vegeta;\n";
21575     static const GLchar *valid_var_definition = "const uint type_size = SIZE;\n"
21576                                                 "\n"
21577                                                 "layout (xfb_stride = type_size) out;\n"
21578                                                 "\n"
21579                                                 "layout (xfb_offset = 0) out TYPE goku;\n";
21580     static const GLchar *invalid_use          = "    goku   = TYPE(1);\n"
21581                                                 "    vegeta = TYPE(0);\n"
21582                                                 "    if (vec4(0) == result)\n"
21583                                                 "    {\n"
21584                                                 "        goku   = TYPE(0);\n"
21585                                                 "        vegeta = TYPE(1);\n"
21586                                                 "    }\n";
21587     static const GLchar *valid_use            = "    goku   = TYPE(1);\n"
21588                                                 "    if (vec4(0) == result)\n"
21589                                                 "    {\n"
21590                                                 "        goku   = TYPE(0);\n"
21591                                                 "    }\n";
21592     static const GLchar *fs                   = "#version 430 core\n"
21593                                                 "#extension GL_ARB_enhanced_layouts : require\n"
21594                                                 "\n"
21595                                                 "in  vec4 any_fs;\n"
21596                                                 "out vec4 fs_out;\n"
21597                                                 "\n"
21598                                                 "void main()\n"
21599                                                 "{\n"
21600                                                 "    fs_out = any_fs;\n"
21601                                                 "}\n"
21602                                                 "\n";
21603     static const GLchar *gs_tested            = "#version 430 core\n"
21604                                                 "#extension GL_ARB_enhanced_layouts : require\n"
21605                                                 "\n"
21606                                                 "layout(points)                           in;\n"
21607                                                 "layout(triangle_strip, max_vertices = 4) out;\n"
21608                                                 "\n"
21609                                                 "VAR_DEFINITION"
21610                                                 "\n"
21611                                                 "in  vec4 vs_any[];\n"
21612                                                 "out vec4 any_fs;\n"
21613                                                 "\n"
21614                                                 "void main()\n"
21615                                                 "{\n"
21616                                                 "    vec4 result = vs_any[0];\n"
21617                                                 "\n"
21618                                                 "VARIABLE_USE"
21619                                                 "\n"
21620                                                 "    any_fs = result;\n"
21621                                                 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
21622                                                 "    EmitVertex();\n"
21623                                                 "    any_fs = result;\n"
21624                                                 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
21625                                                 "    EmitVertex();\n"
21626                                                 "    any_fs = result;\n"
21627                                                 "    gl_Position  = vec4(1, -1, 0, 1);\n"
21628                                                 "    EmitVertex();\n"
21629                                                 "    any_fs = result;\n"
21630                                                 "    gl_Position  = vec4(1, 1, 0, 1);\n"
21631                                                 "    EmitVertex();\n"
21632                                                 "}\n"
21633                                                 "\n";
21634     static const GLchar *tcs                  = "#version 430 core\n"
21635                                                 "#extension GL_ARB_enhanced_layouts : require\n"
21636                                                 "\n"
21637                                                 "layout(vertices = 1) out;\n"
21638                                                 "\n"
21639                                                 "in  vec4 vs_any[];\n"
21640                                                 "out vec4 tcs_tes[];\n"
21641                                                 "\n"
21642                                                 "void main()\n"
21643                                                 "{\n"
21644                                                 "\n"
21645                                                 "    tcs_tes[gl_InvocationID] = vs_any[gl_InvocationID];\n"
21646                                                 "\n"
21647                                                 "    gl_TessLevelOuter[0] = 1.0;\n"
21648                                                 "    gl_TessLevelOuter[1] = 1.0;\n"
21649                                                 "    gl_TessLevelOuter[2] = 1.0;\n"
21650                                                 "    gl_TessLevelOuter[3] = 1.0;\n"
21651                                                 "    gl_TessLevelInner[0] = 1.0;\n"
21652                                                 "    gl_TessLevelInner[1] = 1.0;\n"
21653                                                 "}\n"
21654                                                 "\n";
21655     static const GLchar *tes_tested           = "#version 430 core\n"
21656                                                 "#extension GL_ARB_enhanced_layouts : require\n"
21657                                                 "\n"
21658                                                 "layout(isolines, point_mode) in;\n"
21659                                                 "\n"
21660                                                 "VAR_DEFINITION"
21661                                                 "\n"
21662                                                 "in  vec4 tcs_tes[];\n"
21663                                                 "out vec4 any_fs;\n"
21664                                                 "\n"
21665                                                 "void main()\n"
21666                                                 "{\n"
21667                                                 "    vec4 result = tcs_tes[0];\n"
21668                                                 "\n"
21669                                                 "VARIABLE_USE"
21670                                                 "\n"
21671                                                 "    any_fs = result;\n"
21672                                                 "}\n"
21673                                                 "\n";
21674     static const GLchar *vs                   = "#version 430 core\n"
21675                                                 "#extension GL_ARB_enhanced_layouts : require\n"
21676                                                 "\n"
21677                                                 "in  vec4 in_vs;\n"
21678                                                 "out vec4 vs_any;\n"
21679                                                 "\n"
21680                                                 "void main()\n"
21681                                                 "{\n"
21682                                                 "    vs_any = in_vs;\n"
21683                                                 "}\n"
21684                                                 "\n";
21685     static const GLchar *vs_tested            = "#version 430 core\n"
21686                                                 "#extension GL_ARB_enhanced_layouts : require\n"
21687                                                 "\n"
21688                                                 "VAR_DEFINITION"
21689                                                 "\n"
21690                                                 "in  vec4 in_vs;\n"
21691                                                 "out vec4 any_fs;\n"
21692                                                 "\n"
21693                                                 "void main()\n"
21694                                                 "{\n"
21695                                                 "    vec4 result = in_vs;\n"
21696                                                 "\n"
21697                                                 "VARIABLE_USE"
21698                                                 "\n"
21699                                                 "    any_fs = result;\n"
21700                                                 "}\n"
21701                                                 "\n";
21702 
21703     std::string source;
21704     testCase &test_case = m_test_cases[test_case_index];
21705 
21706     if (test_case.m_stage == stage)
21707     {
21708         GLchar buffer[16];
21709         size_t position              = 0;
21710         const GLchar *type_name      = test_case.m_type.GetGLSLTypeName();
21711         const GLchar *var_definition = 0;
21712         const GLchar *var_use        = 0;
21713 
21714         sprintf(buffer, "%d", test_case.m_type.GetSize());
21715 
21716         switch (test_case.m_case)
21717         {
21718         case VALID:
21719             var_definition = valid_var_definition;
21720             var_use        = valid_use;
21721             break;
21722         case INVALID:
21723             var_definition = invalid_var_definition;
21724             var_use        = invalid_use;
21725             break;
21726         default:
21727             TCU_FAIL("Invalid enum");
21728         }
21729 
21730         switch (stage)
21731         {
21732         case Utils::Shader::GEOMETRY:
21733             source = gs_tested;
21734             break;
21735         case Utils::Shader::TESS_EVAL:
21736             source = tes_tested;
21737             break;
21738         case Utils::Shader::VERTEX:
21739             source = vs_tested;
21740             break;
21741         default:
21742             TCU_FAIL("Invalid enum");
21743         }
21744 
21745         Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
21746         position = 0;
21747         Utils::replaceToken("SIZE", position, buffer, source);
21748         Utils::replaceToken("VARIABLE_USE", position, var_use, source);
21749 
21750         Utils::replaceAllTokens("TYPE", type_name, source);
21751     }
21752     else
21753     {
21754         switch (test_case.m_stage)
21755         {
21756         case Utils::Shader::GEOMETRY:
21757             switch (stage)
21758             {
21759             case Utils::Shader::FRAGMENT:
21760                 source = fs;
21761                 break;
21762             case Utils::Shader::VERTEX:
21763                 source = vs;
21764                 break;
21765             default:
21766                 source = "";
21767             }
21768             break;
21769         case Utils::Shader::TESS_EVAL:
21770             switch (stage)
21771             {
21772             case Utils::Shader::FRAGMENT:
21773                 source = fs;
21774                 break;
21775             case Utils::Shader::TESS_CTRL:
21776                 source = tcs;
21777                 break;
21778             case Utils::Shader::VERTEX:
21779                 source = vs;
21780                 break;
21781             default:
21782                 source = "";
21783             }
21784             break;
21785         case Utils::Shader::VERTEX:
21786             switch (stage)
21787             {
21788             case Utils::Shader::FRAGMENT:
21789                 source = fs;
21790                 break;
21791             default:
21792                 source = "";
21793             }
21794             break;
21795         default:
21796             TCU_FAIL("Invalid enum");
21797         }
21798     }
21799 
21800     return source;
21801 }
21802 
21803 /** Get description of test case
21804  *
21805  * @param test_case_index Index of test case
21806  *
21807  * @return Test case description
21808  **/
21809 std::string XFBVariableStrideTest::getTestCaseName(GLuint test_case_index)
21810 {
21811     std::stringstream stream;
21812     testCase &test_case = m_test_cases[test_case_index];
21813 
21814     stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
21815            << ", type: " << test_case.m_type.GetGLSLTypeName() << ", case: ";
21816 
21817     switch (test_case.m_case)
21818     {
21819     case VALID:
21820         stream << "valid";
21821         break;
21822     case INVALID:
21823         stream << "invalid";
21824         break;
21825     default:
21826         TCU_FAIL("Invalid enum");
21827     }
21828 
21829     return stream.str();
21830 }
21831 
21832 /** Get number of test cases
21833  *
21834  * @return Number of test cases
21835  **/
21836 GLuint XFBVariableStrideTest::getTestCaseNumber()
21837 {
21838     return static_cast<GLuint>(m_test_cases.size());
21839 }
21840 
21841 /** Selects if "compute" stage is relevant for test
21842  *
21843  * @param ignored
21844  *
21845  * @return false
21846  **/
21847 bool XFBVariableStrideTest::isComputeRelevant(GLuint /* test_case_index */)
21848 {
21849     return false;
21850 }
21851 
21852 /** Selects if compilation failure is expected result
21853  *
21854  * @param test_case_index Index of test case
21855  *
21856  * @return true
21857  **/
21858 bool XFBVariableStrideTest::isFailureExpected(GLuint test_case_index)
21859 {
21860     testCase &test_case = m_test_cases[test_case_index];
21861 
21862     return (INVALID == test_case.m_case);
21863 }
21864 
21865 /** Prepare all test cases
21866  *
21867  **/
21868 void XFBVariableStrideTest::testInit()
21869 {
21870     const GLuint n_types = getTypesNumber();
21871 
21872     for (GLuint i = 0; i < n_types; ++i)
21873     {
21874         for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
21875         {
21876             if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
21877                 (Utils::Shader::FRAGMENT == stage))
21878             {
21879                 continue;
21880             }
21881 
21882             const Utils::Type &type = getType(i);
21883             for (GLuint c = 0; c < CASE_MAX; ++c)
21884             {
21885                 testCase test_case = {static_cast<CASES>(c), static_cast<Utils::Shader::STAGES>(stage), type};
21886 
21887                 m_test_cases.push_back(test_case);
21888             }
21889         }
21890     }
21891 }
21892 
21893 /** Constructor
21894  *
21895  * @param context Test framework context
21896  **/
21897 XFBBlockStrideTest::XFBBlockStrideTest(deqp::Context &context)
21898     : TestBase(context, "xfb_block_stride", "Test verifies that stride qualifier is respected for blocks")
21899 {
21900 }
21901 
21902 /** Source for given test case and stage
21903  *
21904  * @param test_case_index Index of test case
21905  * @param stage           Shader stage
21906  *
21907  * @return Shader source
21908  **/
21909 std::string XFBBlockStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
21910 {
21911     static const GLchar *var_definition = "layout (xfb_offset = 0, xfb_stride = 128) out Goku {\n"
21912                                           "    vec4 gohan;\n"
21913                                           "    vec4 goten;\n"
21914                                           "    vec4 chichi;\n"
21915                                           "} gokuARRAY;\n";
21916     static const GLchar *var_use        = "    gokuINDEX.gohan  = vec4(1, 0, 0, 0);\n"
21917                                           "    gokuINDEX.goten  = vec4(0, 0, 1, 0);\n"
21918                                           "    gokuINDEX.chichi = vec4(0, 1, 0, 0);\n"
21919                                           "    if (vec4(0) == result)\n"
21920                                           "    {\n"
21921                                           "        gokuINDEX.gohan  = vec4(0, 1, 1, 1);\n"
21922                                           "        gokuINDEX.goten  = vec4(1, 1, 0, 1);\n"
21923                                           "        gokuINDEX.chichi = vec4(1, 0, 1, 1);\n"
21924                                           "    }\n";
21925     static const GLchar *gs_tested =
21926         "#version 430 core\n"
21927         "#extension GL_ARB_enhanced_layouts : require\n"
21928         "\n"
21929         "layout(points)                           in;\n"
21930         "layout(triangle_strip, max_vertices = 4) out;\n"
21931         "\n"
21932         "VAR_DEFINITION"
21933         "\n"
21934         "out gl_PerVertex \n"
21935         "{ \n"
21936         "   vec4  gl_Position; \n" // gl_Position must be redeclared in separable program mode
21937         "}; \n"
21938         "in  vec4 tes_gs[];\n"
21939         "out vec4 gs_fs;\n"
21940         "\n"
21941         "void main()\n"
21942         "{\n"
21943         "    vec4 result = tes_gs[0];\n"
21944         "\n"
21945         "VARIABLE_USE"
21946         "\n"
21947         "    gs_fs = result;\n"
21948         "    gl_Position  = vec4(-1, -1, 0, 1);\n"
21949         "    EmitVertex();\n"
21950         "    gs_fs = result;\n"
21951         "    gl_Position  = vec4(-1, 1, 0, 1);\n"
21952         "    EmitVertex();\n"
21953         "    gs_fs = result;\n"
21954         "    gl_Position  = vec4(1, -1, 0, 1);\n"
21955         "    EmitVertex();\n"
21956         "    gs_fs = result;\n"
21957         "    gl_Position  = vec4(1, 1, 0, 1);\n"
21958         "    EmitVertex();\n"
21959         "}\n"
21960         "\n";
21961     static const GLchar *tcs = "#version 430 core\n"
21962                                "#extension GL_ARB_enhanced_layouts : require\n"
21963                                "\n"
21964                                "layout(vertices = 1) out;\n"
21965                                "\n"
21966                                "in  vec4 vs_tcs[];\n"
21967                                "out vec4 tcs_tes[];\n"
21968                                "\n"
21969                                "void main()\n"
21970                                "{\n"
21971                                "\n"
21972                                "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
21973                                "\n"
21974                                "    gl_TessLevelOuter[0] = 1.0;\n"
21975                                "    gl_TessLevelOuter[1] = 1.0;\n"
21976                                "    gl_TessLevelOuter[2] = 1.0;\n"
21977                                "    gl_TessLevelOuter[3] = 1.0;\n"
21978                                "    gl_TessLevelInner[0] = 1.0;\n"
21979                                "    gl_TessLevelInner[1] = 1.0;\n"
21980                                "}\n"
21981                                "\n";
21982 #if 0
21983     static const GLchar* tcs_tested =
21984         "#version 430 core\n"
21985         "#extension GL_ARB_enhanced_layouts : require\n"
21986         "\n"
21987         "layout(vertices = 1) out;\n"
21988         "\n"
21989         "VAR_DEFINITION"
21990         "\n"
21991         "in  vec4 vs_tcs[];\n"
21992         "out vec4 tcs_tes[];\n"
21993         "\n"
21994         "void main()\n"
21995         "{\n"
21996         "    vec4 result = vs_tcs[gl_InvocationID];\n"
21997         "\n"
21998         "VARIABLE_USE"
21999         "\n"
22000         "    tcs_tes[gl_InvocationID] = result;\n"
22001         "\n"
22002         "    gl_TessLevelOuter[0] = 1.0;\n"
22003         "    gl_TessLevelOuter[1] = 1.0;\n"
22004         "    gl_TessLevelOuter[2] = 1.0;\n"
22005         "    gl_TessLevelOuter[3] = 1.0;\n"
22006         "    gl_TessLevelInner[0] = 1.0;\n"
22007         "    gl_TessLevelInner[1] = 1.0;\n"
22008         "}\n"
22009         "\n";
22010 #endif
22011     static const GLchar *tes_tested = "#version 430 core\n"
22012                                       "#extension GL_ARB_enhanced_layouts : require\n"
22013                                       "\n"
22014                                       "layout(isolines, point_mode) in;\n"
22015                                       "\n"
22016                                       "VAR_DEFINITION"
22017                                       "\n"
22018                                       "in  vec4 tcs_tes[];\n"
22019                                       "out vec4 tes_gs;\n"
22020                                       "\n"
22021                                       "void main()\n"
22022                                       "{\n"
22023                                       "    vec4 result = tcs_tes[0];\n"
22024                                       "\n"
22025                                       "VARIABLE_USE"
22026                                       "\n"
22027                                       "    tes_gs += result;\n"
22028                                       "}\n"
22029                                       "\n";
22030     static const GLchar *vs         = "#version 430 core\n"
22031                                       "#extension GL_ARB_enhanced_layouts : require\n"
22032                                       "\n"
22033                                       "in  vec4 in_vs;\n"
22034                                       "out vec4 vs_tcs;\n"
22035                                       "out vec4 tes_gs;\n"
22036                                       "\n"
22037                                       "void main()\n"
22038                                       "{\n"
22039                                       "    vs_tcs = tes_gs = in_vs;\n"
22040                                       "}\n"
22041                                       "\n";
22042     static const GLchar *vs_tested  = "#version 430 core\n"
22043                                       "#extension GL_ARB_enhanced_layouts : require\n"
22044                                       "\n"
22045                                       "VAR_DEFINITION"
22046                                       "\n"
22047                                       "in  vec4 in_vs;\n"
22048                                       "out vec4 vs_tcs;\n"
22049                                       "\n"
22050                                       "void main()\n"
22051                                       "{\n"
22052                                       "    vec4 result = in_vs;\n"
22053                                       "\n"
22054                                       "VARIABLE_USE"
22055                                       "\n"
22056                                       "    vs_tcs += result;\n"
22057                                       "}\n"
22058                                       "\n";
22059 
22060     std::string source;
22061     Utils::Shader::STAGES test_case = m_test_cases[test_case_index];
22062 
22063     if (test_case == stage)
22064     {
22065         const GLchar *array = "";
22066         const GLchar *index = "";
22067         size_t position     = 0;
22068         size_t temp;
22069         // It is a compile time error to apply xfb_offset to the declaration of an unsized array(GLSL4.5 spec: Page73)
22070         // change array = "[]" to "[1]"
22071         switch (stage)
22072         {
22073         case Utils::Shader::GEOMETRY:
22074             source = gs_tested;
22075             array  = "[1]";
22076             index  = "[0]";
22077             break;
22078 /*
22079              It is invalid to define transform feedback output in HS
22080              */
22081 #if 0
22082             case Utils::Shader::TESS_CTRL:
22083             source = tcs_tested;
22084             array = "[]";
22085             index = "[gl_InvocationID]";
22086             break;
22087 #endif
22088         case Utils::Shader::TESS_EVAL:
22089             source = tes_tested;
22090             array  = "[1]";
22091             index  = "[0]";
22092             break;
22093         case Utils::Shader::VERTEX:
22094             source = vs_tested;
22095             break;
22096         default:
22097             TCU_FAIL("Invalid enum");
22098         }
22099 
22100         temp = position;
22101         Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
22102         position = temp;
22103         Utils::replaceToken("ARRAY", position, array, source);
22104         Utils::replaceToken("VARIABLE_USE", position, var_use, source);
22105 
22106         Utils::replaceAllTokens("INDEX", index, source);
22107     }
22108     else
22109     {
22110         switch (test_case)
22111         {
22112         case Utils::Shader::GEOMETRY:
22113             switch (stage)
22114             {
22115             case Utils::Shader::VERTEX:
22116                 source = vs;
22117                 break;
22118             default:
22119                 source = "";
22120             }
22121             break;
22122         case Utils::Shader::TESS_CTRL:
22123             switch (stage)
22124             {
22125             case Utils::Shader::VERTEX:
22126                 source = vs;
22127                 break;
22128             default:
22129                 source = "";
22130             }
22131             break;
22132         case Utils::Shader::TESS_EVAL:
22133             switch (stage)
22134             {
22135             case Utils::Shader::TESS_CTRL:
22136                 source = tcs;
22137                 break;
22138             case Utils::Shader::VERTEX:
22139                 source = vs;
22140                 break;
22141             default:
22142                 source = "";
22143             }
22144             break;
22145         case Utils::Shader::VERTEX:
22146             source = "";
22147             break;
22148         default:
22149             TCU_FAIL("Invalid enum");
22150         }
22151     }
22152 
22153     return source;
22154 }
22155 
22156 /** Get description of test case
22157  *
22158  * @param test_case_index Index of test case
22159  *
22160  * @return Test case description
22161  **/
22162 std::string XFBBlockStrideTest::getTestCaseName(GLuint test_case_index)
22163 {
22164     std::stringstream stream;
22165 
22166     stream << "Stage: " << Utils::Shader::GetStageName(m_test_cases[test_case_index]);
22167 
22168     return stream.str();
22169 }
22170 
22171 /** Get number of test cases
22172  *
22173  * @return Number of test cases
22174  **/
22175 GLuint XFBBlockStrideTest::getTestCaseNumber()
22176 {
22177     return static_cast<GLuint>(m_test_cases.size());
22178 }
22179 
22180 /** Inspects program for xfb stride
22181  *
22182  * @param program Program to query
22183  *
22184  * @return true if query results match expected values, false otherwise
22185  **/
22186 bool XFBBlockStrideTest::inspectProgram(Utils::Program &program)
22187 {
22188     GLint stride = 0;
22189 
22190     program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE,
22191                         1 /* buf_size */, &stride);
22192 
22193     return (128 == stride);
22194 }
22195 
22196 /** Runs test case
22197  *
22198  * @param test_case_index Id of test case
22199  *
22200  * @return true if test case pass, false otherwise
22201  **/
22202 bool XFBBlockStrideTest::testCase(GLuint test_case_index)
22203 {
22204     const std::string &gs_source = getShaderSource(test_case_index, Utils::Shader::GEOMETRY);
22205     Utils::Program program(m_context);
22206     const std::string &tcs_source = getShaderSource(test_case_index, Utils::Shader::TESS_CTRL);
22207     const std::string &tes_source = getShaderSource(test_case_index, Utils::Shader::TESS_EVAL);
22208     bool test_case_result         = true;
22209     const std::string &vs_source  = getShaderSource(test_case_index, Utils::Shader::VERTEX);
22210 
22211     program.Init("" /* cs */, "", gs_source, tcs_source, tes_source, vs_source, true /* separable */);
22212 
22213     test_case_result = inspectProgram(program);
22214 
22215     return test_case_result;
22216 }
22217 
22218 /** Prepare all test cases
22219  *
22220  **/
22221 void XFBBlockStrideTest::testInit()
22222 {
22223     for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
22224     {
22225         if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
22226             (Utils::Shader::FRAGMENT == stage))
22227         {
22228             continue;
22229         }
22230 
22231         m_test_cases.push_back((Utils::Shader::STAGES)stage);
22232     }
22233 }
22234 
22235 /** Constructor
22236  *
22237  * @param context Test context
22238  **/
22239 XFBBlockMemberStrideTest::XFBBlockMemberStrideTest(deqp::Context &context)
22240     : BufferTestBase(context, "xfb_block_member_stride",
22241                      "Test verifies that xfb_stride qualifier is respected for block member")
22242 {
22243     /* Nothing to be done here */
22244 }
22245 
22246 /** Get descriptors of buffers necessary for test
22247  *
22248  * @param ignored
22249  * @param out_descriptors Descriptors of buffers used by test
22250  **/
22251 void XFBBlockMemberStrideTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
22252                                                     bufferDescriptor::Vector &out_descriptors)
22253 {
22254     const Utils::Type &vec4 = Utils::Type::vec4;
22255 
22256     /* Test needs single uniform and xfb */
22257     out_descriptors.resize(2);
22258 
22259     /* Get references */
22260     bufferDescriptor &uniform = out_descriptors[0];
22261     bufferDescriptor &xfb     = out_descriptors[1];
22262 
22263     /* Index */
22264     uniform.m_index = 0;
22265     xfb.m_index     = 0;
22266 
22267     /* Target */
22268     uniform.m_target = Utils::Buffer::Uniform;
22269     xfb.m_target     = Utils::Buffer::Transform_feedback;
22270 
22271     /* Data */
22272     static const GLuint vec4_size           = 16;
22273     const std::vector<GLubyte> &gohan_data  = vec4.GenerateDataPacked();
22274     const std::vector<GLubyte> &goten_data  = vec4.GenerateDataPacked();
22275     const std::vector<GLubyte> &chichi_data = vec4.GenerateDataPacked();
22276 
22277     /* Uniform data */
22278     uniform.m_initial_data.resize(3 * vec4_size);
22279     memcpy(&uniform.m_initial_data[0] + 0, &gohan_data[0], vec4_size);
22280     memcpy(&uniform.m_initial_data[0] + vec4_size, &goten_data[0], vec4_size);
22281     memcpy(&uniform.m_initial_data[0] + 2 * vec4_size, &chichi_data[0], vec4_size);
22282 
22283     /* XFB data */
22284     xfb.m_initial_data.resize(4 * vec4_size);
22285     xfb.m_expected_data.resize(4 * vec4_size);
22286 
22287     for (GLuint i = 0; i < 4 * vec4_size; ++i)
22288     {
22289         xfb.m_initial_data[i]  = (glw::GLubyte)i;
22290         xfb.m_expected_data[i] = (glw::GLubyte)i;
22291     }
22292 
22293     // the xfb_offset of "chichi" should be 32
22294     memcpy(&xfb.m_expected_data[0] + 0, &gohan_data[0], vec4_size);
22295     memcpy(&xfb.m_expected_data[0] + vec4_size, &goten_data[0], vec4_size);
22296     memcpy(&xfb.m_expected_data[0] + 2 * vec4_size, &chichi_data[0], vec4_size);
22297 }
22298 
22299 /** Get body of main function for given shader stage
22300  *
22301  * @param ignored
22302  * @param stage            Shader stage
22303  * @param out_assignments  Set to empty
22304  * @param out_calculations Set to empty
22305  **/
22306 void XFBBlockMemberStrideTest::getShaderBody(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
22307                                              std::string &out_assignments, std::string &out_calculations)
22308 {
22309     out_calculations = "";
22310 
22311     static const GLchar *gs = "    gohan  = uni_gohan;\n"
22312                               "    goten  = uni_goten;\n"
22313                               "    chichi = uni_chichi;\n";
22314     static const GLchar *fs = "    fs_out = gohan + goten + chichi;\n";
22315 
22316     const GLchar *assignments = "";
22317     switch (stage)
22318     {
22319     case Utils::Shader::FRAGMENT:
22320         assignments = fs;
22321         break;
22322     case Utils::Shader::GEOMETRY:
22323         assignments = gs;
22324         break;
22325     default:
22326         break;
22327     }
22328 
22329     out_assignments = assignments;
22330 }
22331 
22332 /** Get interface of shader
22333  *
22334  * @param ignored
22335  * @param stage            Shader stage
22336  * @param out_interface    Set to ""
22337  **/
22338 void XFBBlockMemberStrideTest::getShaderInterface(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
22339                                                   std::string &out_interface)
22340 {
22341     static const GLchar *gs = "layout (xfb_buffer = 0, xfb_offset = 0) out Goku {\n"
22342                               "                             vec4 gohan;\n"
22343                               "    layout (xfb_stride = 48) vec4 goten;\n"
22344                               "                             vec4 chichi;\n"
22345                               "};\n"
22346                               "layout(binding = 0) uniform gs_block {\n"
22347                               "    vec4 uni_gohan;\n"
22348                               "    vec4 uni_goten;\n"
22349                               "    vec4 uni_chichi;\n"
22350                               "};\n";
22351     static const GLchar *fs = "in Goku {\n"
22352                               "    vec4 gohan;\n"
22353                               "    vec4 goten;\n"
22354                               "    vec4 chichi;\n"
22355                               "};\n"
22356                               "out vec4 fs_out;\n";
22357 
22358     switch (stage)
22359     {
22360     case Utils::Shader::FRAGMENT:
22361         out_interface = fs;
22362         break;
22363     case Utils::Shader::GEOMETRY:
22364         out_interface = gs;
22365         break;
22366     default:
22367         out_interface = "";
22368         return;
22369     }
22370 }
22371 
22372 /** Inspects program to check if all resources are as expected
22373  *
22374  * @param ignored
22375  * @param program    Program instance
22376  * @param out_stream Error message
22377  *
22378  * @return true if everything is ok, false otherwise
22379  **/
22380 bool XFBBlockMemberStrideTest::inspectProgram(GLuint /* test_case_index*/, Utils::Program &program,
22381                                               std::stringstream &out_stream)
22382 {
22383     const GLuint gohan_id  = program.GetResourceIndex("gohan", GL_TRANSFORM_FEEDBACK_VARYING);
22384     const GLuint goten_id  = program.GetResourceIndex("goten", GL_TRANSFORM_FEEDBACK_VARYING);
22385     const GLuint chichi_id = program.GetResourceIndex("chichi", GL_TRANSFORM_FEEDBACK_VARYING);
22386 
22387     GLint gohan_offset  = 0;
22388     GLint goten_offset  = 0;
22389     GLint chichi_offset = 0;
22390 
22391     program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, gohan_id, GL_OFFSET, 1, &gohan_offset);
22392     program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, goten_id, GL_OFFSET, 1, &goten_offset);
22393     program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, chichi_id, GL_OFFSET, 1, &chichi_offset);
22394 
22395     // the xfb_offset of "chichi" should be 32
22396     if ((0 != gohan_offset) || (16 != goten_offset) || (32 != chichi_offset))
22397     {
22398         out_stream << "Got wrong offset: [" << gohan_offset << ", " << goten_offset << ", " << chichi_offset
22399                    << "] expected: [0, 16, 32]";
22400         return false;
22401     }
22402 
22403     return true;
22404 }
22405 
22406 /** Constructor
22407  *
22408  * @param context Test framework context
22409  **/
22410 XFBDuplicatedStrideTest::XFBDuplicatedStrideTest(deqp::Context &context)
22411     : NegativeTestBase(context, "xfb_duplicated_stride",
22412                        "Test verifies that compiler reports error when conflicting stride qualifiers are used")
22413 {
22414 }
22415 
22416 /** Source for given test case and stage
22417  *
22418  * @param test_case_index Index of test case
22419  * @param stage           Shader stage
22420  *
22421  * @return Shader source
22422  **/
22423 std::string XFBDuplicatedStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
22424 {
22425     static const GLchar *invalid_var_definition = "const uint valid_stride = 64;\n"
22426 #if DEBUG_NEG_REMOVE_ERROR
22427                                                   "const uint conflicting_stride = 64;\n"
22428 #else
22429                                                   "const uint conflicting_stride = 128;\n"
22430 #endif /* DEBUG_NEG_REMOVE_ERROR */
22431                                                   "\n"
22432                                                   "layout (xfb_buffer = 0, xfb_stride = valid_stride)       out;\n"
22433                                                   "layout (xfb_buffer = 0, xfb_stride = conflicting_stride) out;\n";
22434     static const GLchar *valid_var_definition = "const uint valid_stride = 64;\n"
22435                                                 "\n"
22436                                                 "layout (xfb_buffer = 0, xfb_stride = valid_stride) out;\n"
22437                                                 "layout (xfb_buffer = 0, xfb_stride = valid_stride) out;\n";
22438     static const GLchar *fs                   = "#version 430 core\n"
22439                                                 "#extension GL_ARB_enhanced_layouts : require\n"
22440                                                 "\n"
22441                                                 "in  vec4 any_fs;\n"
22442                                                 "out vec4 fs_out;\n"
22443                                                 "\n"
22444                                                 "void main()\n"
22445                                                 "{\n"
22446                                                 "    fs_out = any_fs;\n"
22447                                                 "}\n"
22448                                                 "\n";
22449     static const GLchar *gs_tested            = "#version 430 core\n"
22450                                                 "#extension GL_ARB_enhanced_layouts : require\n"
22451                                                 "\n"
22452                                                 "layout(points)                           in;\n"
22453                                                 "layout(triangle_strip, max_vertices = 4) out;\n"
22454                                                 "\n"
22455                                                 "VAR_DEFINITION"
22456                                                 "\n"
22457                                                 "in  vec4 vs_any[];\n"
22458                                                 "out vec4 any_fs;\n"
22459                                                 "\n"
22460                                                 "void main()\n"
22461                                                 "{\n"
22462                                                 "    vec4 result = vs_any[0];\n"
22463                                                 "\n"
22464                                                 "    any_fs = result;\n"
22465                                                 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
22466                                                 "    EmitVertex();\n"
22467                                                 "    any_fs = result;\n"
22468                                                 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
22469                                                 "    EmitVertex();\n"
22470                                                 "    any_fs = result;\n"
22471                                                 "    gl_Position  = vec4(1, -1, 0, 1);\n"
22472                                                 "    EmitVertex();\n"
22473                                                 "    any_fs = result;\n"
22474                                                 "    gl_Position  = vec4(1, 1, 0, 1);\n"
22475                                                 "    EmitVertex();\n"
22476                                                 "}\n"
22477                                                 "\n";
22478     static const GLchar *tcs                  = "#version 430 core\n"
22479                                                 "#extension GL_ARB_enhanced_layouts : require\n"
22480                                                 "\n"
22481                                                 "layout(vertices = 1) out;\n"
22482                                                 "\n"
22483                                                 "in  vec4 vs_any[];\n"
22484                                                 "out vec4 tcs_tes[];\n"
22485                                                 "\n"
22486                                                 "void main()\n"
22487                                                 "{\n"
22488                                                 "\n"
22489                                                 "    tcs_tes[gl_InvocationID] = vs_any[gl_InvocationID];\n"
22490                                                 "\n"
22491                                                 "    gl_TessLevelOuter[0] = 1.0;\n"
22492                                                 "    gl_TessLevelOuter[1] = 1.0;\n"
22493                                                 "    gl_TessLevelOuter[2] = 1.0;\n"
22494                                                 "    gl_TessLevelOuter[3] = 1.0;\n"
22495                                                 "    gl_TessLevelInner[0] = 1.0;\n"
22496                                                 "    gl_TessLevelInner[1] = 1.0;\n"
22497                                                 "}\n"
22498                                                 "\n";
22499     static const GLchar *tes_tested           = "#version 430 core\n"
22500                                                 "#extension GL_ARB_enhanced_layouts : require\n"
22501                                                 "\n"
22502                                                 "layout(isolines, point_mode) in;\n"
22503                                                 "\n"
22504                                                 "VAR_DEFINITION"
22505                                                 "\n"
22506                                                 "in  vec4 tcs_tes[];\n"
22507                                                 "out vec4 any_fs;\n"
22508                                                 "\n"
22509                                                 "void main()\n"
22510                                                 "{\n"
22511                                                 "    vec4 result = tcs_tes[0];\n"
22512                                                 "\n"
22513                                                 "    any_fs = result;\n"
22514                                                 "}\n"
22515                                                 "\n";
22516     static const GLchar *vs                   = "#version 430 core\n"
22517                                                 "#extension GL_ARB_enhanced_layouts : require\n"
22518                                                 "\n"
22519                                                 "in  vec4 in_vs;\n"
22520                                                 "out vec4 vs_any;\n"
22521                                                 "\n"
22522                                                 "void main()\n"
22523                                                 "{\n"
22524                                                 "    vs_any = in_vs;\n"
22525                                                 "}\n"
22526                                                 "\n";
22527     static const GLchar *vs_tested            = "#version 430 core\n"
22528                                                 "#extension GL_ARB_enhanced_layouts : require\n"
22529                                                 "\n"
22530                                                 "VAR_DEFINITION"
22531                                                 "\n"
22532                                                 "in  vec4 in_vs;\n"
22533                                                 "out vec4 any_fs;\n"
22534                                                 "\n"
22535                                                 "void main()\n"
22536                                                 "{\n"
22537                                                 "    vec4 result = in_vs;\n"
22538                                                 "\n"
22539                                                 "    any_fs += result;\n"
22540                                                 "}\n"
22541                                                 "\n";
22542 
22543     std::string source;
22544     testCase &test_case = m_test_cases[test_case_index];
22545 
22546     if (test_case.m_stage == stage)
22547     {
22548         size_t position              = 0;
22549         const GLchar *var_definition = 0;
22550 
22551         switch (test_case.m_case)
22552         {
22553         case VALID:
22554             var_definition = valid_var_definition;
22555             break;
22556         case INVALID:
22557             var_definition = invalid_var_definition;
22558             break;
22559         default:
22560             TCU_FAIL("Invalid enum");
22561         }
22562 
22563         switch (stage)
22564         {
22565         case Utils::Shader::GEOMETRY:
22566             source = gs_tested;
22567             break;
22568         case Utils::Shader::TESS_EVAL:
22569             source = tes_tested;
22570             break;
22571         case Utils::Shader::VERTEX:
22572             source = vs_tested;
22573             break;
22574         default:
22575             TCU_FAIL("Invalid enum");
22576         }
22577 
22578         Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
22579     }
22580     else
22581     {
22582         switch (test_case.m_stage)
22583         {
22584         case Utils::Shader::GEOMETRY:
22585             switch (stage)
22586             {
22587             case Utils::Shader::FRAGMENT:
22588                 source = fs;
22589                 break;
22590             case Utils::Shader::VERTEX:
22591                 source = vs;
22592                 break;
22593             default:
22594                 source = "";
22595             }
22596             break;
22597         case Utils::Shader::TESS_EVAL:
22598             switch (stage)
22599             {
22600             case Utils::Shader::FRAGMENT:
22601                 source = fs;
22602                 break;
22603             case Utils::Shader::TESS_CTRL:
22604                 source = tcs;
22605                 break;
22606             case Utils::Shader::VERTEX:
22607                 source = vs;
22608                 break;
22609             default:
22610                 source = "";
22611             }
22612             break;
22613         case Utils::Shader::VERTEX:
22614             switch (stage)
22615             {
22616             case Utils::Shader::FRAGMENT:
22617                 source = fs;
22618                 break;
22619             default:
22620                 source = "";
22621             }
22622             break;
22623         default:
22624             TCU_FAIL("Invalid enum");
22625         }
22626     }
22627 
22628     return source;
22629 }
22630 
22631 /** Get description of test case
22632  *
22633  * @param test_case_index Index of test case
22634  *
22635  * @return Test case description
22636  **/
22637 std::string XFBDuplicatedStrideTest::getTestCaseName(GLuint test_case_index)
22638 {
22639     std::stringstream stream;
22640     testCase &test_case = m_test_cases[test_case_index];
22641 
22642     stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", case: ";
22643 
22644     switch (test_case.m_case)
22645     {
22646     case VALID:
22647         stream << "valid";
22648         break;
22649     case INVALID:
22650         stream << "invalid";
22651         break;
22652     default:
22653         TCU_FAIL("Invalid enum");
22654     }
22655 
22656     return stream.str();
22657 }
22658 
22659 /** Get number of test cases
22660  *
22661  * @return Number of test cases
22662  **/
22663 GLuint XFBDuplicatedStrideTest::getTestCaseNumber()
22664 {
22665     return static_cast<GLuint>(m_test_cases.size());
22666 }
22667 
22668 /** Selects if "compute" stage is relevant for test
22669  *
22670  * @param ignored
22671  *
22672  * @return false
22673  **/
22674 bool XFBDuplicatedStrideTest::isComputeRelevant(GLuint /* test_case_index */)
22675 {
22676     return false;
22677 }
22678 
22679 /** Selects if compilation failure is expected result
22680  *
22681  * @param test_case_index Index of test case
22682  *
22683  * @return true
22684  **/
22685 bool XFBDuplicatedStrideTest::isFailureExpected(GLuint test_case_index)
22686 {
22687     testCase &test_case = m_test_cases[test_case_index];
22688 
22689     return (INVALID == test_case.m_case);
22690 }
22691 
22692 /** Prepare all test cases
22693  *
22694  **/
22695 void XFBDuplicatedStrideTest::testInit()
22696 {
22697     for (GLuint c = 0; c < CASE_MAX; ++c)
22698     {
22699         for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
22700         {
22701             if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
22702                 (Utils::Shader::FRAGMENT == stage))
22703             {
22704                 continue;
22705             }
22706 
22707             testCase test_case = {(CASES)c, (Utils::Shader::STAGES)stage};
22708 
22709             m_test_cases.push_back(test_case);
22710         }
22711     }
22712 }
22713 
22714 /** Constructor
22715  *
22716  * @param context Test framework context
22717  **/
22718 XFBGetProgramResourceAPITest::XFBGetProgramResourceAPITest(deqp::Context &context)
22719     : TestBase(context, "xfb_get_program_resource_api",
22720                "Test verifies that get program resource reports correct results for XFB")
22721 {
22722 }
22723 
22724 /** Source for given test case and stage
22725  *
22726  * @param test_case_index Index of test case
22727  * @param stage           Shader stage
22728  *
22729  * @return Shader source
22730  **/
22731 std::string XFBGetProgramResourceAPITest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
22732 {
22733     static const GLchar *api_var_definition = "out TYPE b0_v1ARRAY;\n"
22734                                               "out TYPE b1_v1ARRAY;\n"
22735                                               "out TYPE b0_v3ARRAY;\n"
22736                                               "out TYPE b0_v0ARRAY;\n";
22737     static const GLchar *xfb_var_definition =
22738         "const uint type_size = SIZE;\n"
22739         "\n"
22740         "layout (xfb_buffer = 1, xfb_stride = 4 * type_size) out;\n"
22741         "\n"
22742         "layout (xfb_buffer = 0, xfb_offset = 1 * type_size) out TYPE b0_v1ARRAY;\n"
22743         "layout (xfb_buffer = 1, xfb_offset = 1 * type_size) out TYPE b1_v1ARRAY;\n"
22744         "layout (xfb_buffer = 0, xfb_offset = 3 * type_size) out TYPE b0_v3ARRAY;\n"
22745         "layout (xfb_buffer = 0, xfb_offset = 0 * type_size) out TYPE b0_v0ARRAY;\n";
22746     static const GLchar *var_use = "    b0_v1INDEX = TYPE(0);\n"
22747                                    "    b1_v1INDEX = TYPE(1);\n"
22748                                    "    b0_v3INDEX = TYPE(0);\n"
22749                                    "    b0_v0INDEX = TYPE(1);\n"
22750                                    "    if (vec4(0) == result)\n"
22751                                    "    {\n"
22752                                    "        b0_v1INDEX = TYPE(1);\n"
22753                                    "        b1_v1INDEX = TYPE(0);\n"
22754                                    "        b0_v3INDEX = TYPE(1);\n"
22755                                    "        b0_v0INDEX = TYPE(0);\n"
22756                                    "    }\n";
22757     static const GLchar *gs_tested =
22758         "#version 430 core\n"
22759         "#extension GL_ARB_enhanced_layouts : require\n"
22760         "\n"
22761         "layout(points)                           in;\n"
22762         "layout(triangle_strip, max_vertices = 4) out;\n"
22763         "\n"
22764         "VAR_DEFINITION"
22765         "\n"
22766         "out gl_PerVertex \n"
22767         "{ \n"
22768         "   vec4  gl_Position; \n" // gl_Position must be redeclared in separable program mode
22769         "}; \n"
22770         "in  vec4 tes_gs[];\n"
22771         "out vec4 gs_fs;\n"
22772         "\n"
22773         "void main()\n"
22774         "{\n"
22775         "    vec4 result = tes_gs[0];\n"
22776         "\n"
22777         "VARIABLE_USE"
22778         "\n"
22779         "    gs_fs = result;\n"
22780         "    gl_Position  = vec4(-1, -1, 0, 1);\n"
22781         "    EmitVertex();\n"
22782         "    gs_fs = result;\n"
22783         "    gl_Position  = vec4(-1, 1, 0, 1);\n"
22784         "    EmitVertex();\n"
22785         "    gs_fs = result;\n"
22786         "    gl_Position  = vec4(1, -1, 0, 1);\n"
22787         "    EmitVertex();\n"
22788         "    gs_fs = result;\n"
22789         "    gl_Position  = vec4(1, 1, 0, 1);\n"
22790         "    EmitVertex();\n"
22791         "}\n"
22792         "\n";
22793 #if 0
22794     static const GLchar* tcs_tested =
22795         "#version 430 core\n"
22796         "#extension GL_ARB_enhanced_layouts : require\n"
22797         "\n"
22798         "layout(vertices = 1) out;\n"
22799         "\n"
22800         "VAR_DEFINITION"
22801         "\n"
22802         "in  vec4 vs_tcs[];\n"
22803         "out vec4 tcs_tes[];\n"
22804         "\n"
22805         "void main()\n"
22806         "{\n"
22807         "    vec4 result = vs_tcs[gl_InvocationID];\n"
22808         "\n"
22809         "VARIABLE_USE"
22810         "\n"
22811         "    tcs_tes[gl_InvocationID] = result;\n"
22812         "\n"
22813         "    gl_TessLevelOuter[0] = 1.0;\n"
22814         "    gl_TessLevelOuter[1] = 1.0;\n"
22815         "    gl_TessLevelOuter[2] = 1.0;\n"
22816         "    gl_TessLevelOuter[3] = 1.0;\n"
22817         "    gl_TessLevelInner[0] = 1.0;\n"
22818         "    gl_TessLevelInner[1] = 1.0;\n"
22819         "}\n"
22820         "\n";
22821 #endif
22822     static const GLchar *tes_tested = "#version 430 core\n"
22823                                       "#extension GL_ARB_enhanced_layouts : require\n"
22824                                       "\n"
22825                                       "layout(isolines, point_mode) in;\n"
22826                                       "\n"
22827                                       "VAR_DEFINITION"
22828                                       "\n"
22829                                       "in  vec4 tcs_tes[];\n"
22830                                       "out vec4 tes_gs;\n"
22831                                       "\n"
22832                                       "void main()\n"
22833                                       "{\n"
22834                                       "    vec4 result = tcs_tes[0];\n"
22835                                       "\n"
22836                                       "VARIABLE_USE"
22837                                       "\n"
22838                                       "    tes_gs = result;\n"
22839                                       "}\n"
22840                                       "\n";
22841     static const GLchar *vs_tested  = "#version 430 core\n"
22842                                       "#extension GL_ARB_enhanced_layouts : require\n"
22843                                       "\n"
22844                                       "VAR_DEFINITION"
22845                                       "\n"
22846                                       "in  vec4 in_vs;\n"
22847                                       "out vec4 vs_tcs;\n"
22848                                       "\n"
22849                                       "void main()\n"
22850                                       "{\n"
22851                                       "    vec4 result = in_vs;\n"
22852                                       "\n"
22853                                       "VARIABLE_USE"
22854                                       "\n"
22855                                       "    vs_tcs = result;\n"
22856                                       "}\n"
22857                                       "\n";
22858 
22859     std::string source;
22860     const test_Case &test_case = m_test_cases[test_case_index];
22861 
22862     if (test_case.m_stage == stage)
22863     {
22864         const GLchar *array = "";
22865         GLchar buffer[16];
22866         const GLchar *index = "";
22867         size_t position     = 0;
22868         size_t temp;
22869         const GLchar *type_name      = test_case.m_type.GetGLSLTypeName();
22870         const GLchar *var_definition = 0;
22871 
22872         sprintf(buffer, "%d", test_case.m_type.GetSize());
22873 
22874         if (XFB == test_case.m_case)
22875         {
22876             var_definition = xfb_var_definition;
22877         }
22878         else
22879         {
22880             var_definition = api_var_definition;
22881         }
22882 
22883         // It is a compile time error to apply xfb_offset to the declaration of an unsized array(GLSL4.5 spec: Page73)
22884         // change array = "[]" to "[1]"
22885         switch (stage)
22886         {
22887         case Utils::Shader::GEOMETRY:
22888             source = gs_tested;
22889             array  = "[1]";
22890             index  = "[0]";
22891             break;
22892 // It is invalid to output transform feedback varyings in tessellation control shader
22893 #if 0
22894         case Utils::Shader::TESS_CTRL:
22895             source = tcs_tested;
22896             array = "[]";
22897             index = "[gl_InvocationID]";
22898             break;
22899 #endif
22900         case Utils::Shader::TESS_EVAL:
22901             source = tes_tested;
22902             array  = "[1]";
22903             index  = "[0]";
22904             break;
22905         case Utils::Shader::VERTEX:
22906             source = vs_tested;
22907             break;
22908         default:
22909             TCU_FAIL("Invalid enum");
22910         }
22911 
22912         temp = position;
22913         Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
22914         if (XFB == test_case.m_case)
22915         {
22916             position = temp;
22917             Utils::replaceToken("SIZE", position, buffer, source);
22918         }
22919         Utils::replaceToken("VARIABLE_USE", position, var_use, source);
22920 
22921         Utils::replaceAllTokens("ARRAY", array, source);
22922         Utils::replaceAllTokens("INDEX", index, source);
22923         Utils::replaceAllTokens("TYPE", type_name, source);
22924     }
22925     else
22926     {
22927         source = "";
22928     }
22929 
22930     return source;
22931 }
22932 
22933 /** Get description of test case
22934  *
22935  * @param test_case_index Index of test case
22936  *
22937  * @return Test case description
22938  **/
22939 std::string XFBGetProgramResourceAPITest::getTestCaseName(GLuint test_case_index)
22940 {
22941     std::stringstream stream;
22942     const test_Case &test_case = m_test_cases[test_case_index];
22943 
22944     stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
22945            << ", type: " << test_case.m_type.GetGLSLTypeName() << ", case: ";
22946 
22947     switch (test_case.m_case)
22948     {
22949     case INTERLEAVED:
22950         stream << "interleaved";
22951         break;
22952     case SEPARATED:
22953         stream << "separated";
22954         break;
22955     case XFB:
22956         stream << "xfb";
22957         break;
22958     default:
22959         TCU_FAIL("Invalid enum");
22960     }
22961 
22962     return stream.str();
22963 }
22964 
22965 /** Get number of test cases
22966  *
22967  * @return Number of test cases
22968  **/
22969 GLuint XFBGetProgramResourceAPITest::getTestCaseNumber()
22970 {
22971     return static_cast<GLuint>(m_test_cases.size());
22972 }
22973 
22974 /** Inspects program for offset, buffer index, buffer stride and type
22975  *
22976  * @param test_case_index Index of test case
22977  * @param program         Program to query
22978  *
22979  * @return true if query results match expected values, false otherwise
22980  **/
22981 bool XFBGetProgramResourceAPITest::inspectProgram(glw::GLuint test_case_index, Utils::Program &program)
22982 {
22983     GLint b0_stride            = 0;
22984     GLint b1_stride            = 0;
22985     GLint b0_v0_buf            = 0;
22986     GLint b0_v0_offset         = 0;
22987     GLint b0_v0_type           = 0;
22988     GLint b0_v1_buf            = 0;
22989     GLint b0_v1_offset         = 0;
22990     GLint b0_v1_type           = 0;
22991     GLint b0_v3_buf            = 0;
22992     GLint b0_v3_offset         = 0;
22993     GLint b0_v3_type           = 0;
22994     GLint b1_v1_buf            = 0;
22995     GLint b1_v1_offset         = 0;
22996     GLint b1_v1_type           = 0;
22997     const test_Case &test_case = m_test_cases[test_case_index];
22998     const GLenum type_enum     = test_case.m_type.GetTypeGLenum();
22999     const GLint type_size      = test_case.m_type.GetSize();
23000 
23001     GLuint b0_v0_index = program.GetResourceIndex("b0_v0", GL_TRANSFORM_FEEDBACK_VARYING);
23002     GLuint b0_v1_index = program.GetResourceIndex("b0_v1", GL_TRANSFORM_FEEDBACK_VARYING);
23003     GLuint b0_v3_index = program.GetResourceIndex("b0_v3", GL_TRANSFORM_FEEDBACK_VARYING);
23004     GLuint b1_v1_index = program.GetResourceIndex("b1_v1", GL_TRANSFORM_FEEDBACK_VARYING);
23005 
23006     program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v0_index, GL_OFFSET, 1 /* buf_size */, &b0_v0_offset);
23007     program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v1_index, GL_OFFSET, 1 /* buf_size */, &b0_v1_offset);
23008     program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v3_index, GL_OFFSET, 1 /* buf_size */, &b0_v3_offset);
23009     program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b1_v1_index, GL_OFFSET, 1 /* buf_size */, &b1_v1_offset);
23010 
23011     program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v0_index, GL_TYPE, 1 /* buf_size */, &b0_v0_type);
23012     program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v1_index, GL_TYPE, 1 /* buf_size */, &b0_v1_type);
23013     program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v3_index, GL_TYPE, 1 /* buf_size */, &b0_v3_type);
23014     program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b1_v1_index, GL_TYPE, 1 /* buf_size */, &b1_v1_type);
23015 
23016     program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v0_index, GL_TRANSFORM_FEEDBACK_BUFFER_INDEX,
23017                         1 /* buf_size */, &b0_v0_buf);
23018     program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v1_index, GL_TRANSFORM_FEEDBACK_BUFFER_INDEX,
23019                         1 /* buf_size */, &b0_v1_buf);
23020     program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v3_index, GL_TRANSFORM_FEEDBACK_BUFFER_INDEX,
23021                         1 /* buf_size */, &b0_v3_buf);
23022     program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b1_v1_index, GL_TRANSFORM_FEEDBACK_BUFFER_INDEX,
23023                         1 /* buf_size */, &b1_v1_buf);
23024 
23025     program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, b0_v0_buf, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE, 1 /* buf_size */,
23026                         &b0_stride);
23027     program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, b1_v1_buf, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE, 1 /* buf_size */,
23028                         &b1_stride);
23029 
23030     if (SEPARATED != test_case.m_case)
23031     {
23032         return (((GLint)(4 * type_size) == b0_stride) && ((GLint)(4 * type_size) == b1_stride) &&
23033                 ((GLint)(0) == b0_v0_buf) && ((GLint)(0 * type_size) == b0_v0_offset) &&
23034                 ((GLint)(type_enum) == b0_v0_type) && ((GLint)(0) == b0_v1_buf) &&
23035                 ((GLint)(1 * type_size) == b0_v1_offset) && ((GLint)(type_enum) == b0_v1_type) &&
23036                 ((GLint)(0) == b0_v3_buf) && ((GLint)(3 * type_size) == b0_v3_offset) &&
23037                 ((GLint)(type_enum) == b0_v3_type) && ((GLint)(1) == b1_v1_buf) &&
23038                 ((GLint)(1 * type_size) == b1_v1_offset) && ((GLint)(type_enum) == b1_v1_type));
23039     }
23040     else
23041     {
23042         return (((GLint)(1 * type_size) == b0_stride) && ((GLint)(1 * type_size) == b1_stride) &&
23043                 ((GLint)(0) == b0_v0_buf) && ((GLint)(0) == b0_v0_offset) && ((GLint)(type_enum) == b0_v0_type) &&
23044                 ((GLint)(1) == b0_v1_buf) && ((GLint)(0) == b0_v1_offset) && ((GLint)(type_enum) == b0_v1_type) &&
23045                 ((GLint)(2) == b0_v3_buf) && ((GLint)(0) == b0_v3_offset) && ((GLint)(type_enum) == b0_v3_type) &&
23046                 ((GLint)(3) == b1_v1_buf) && ((GLint)(0) == b1_v1_offset) && ((GLint)(type_enum) == b1_v1_type));
23047     }
23048 }
23049 
23050 /** Insert gl_SkipComponents
23051  *
23052  * @param num_components How many gl_SkipComponents1 need to be inserted
23053  * @param varyings The transform feedback varyings string vector
23054  *
23055  **/
23056 void XFBGetProgramResourceAPITest::insertSkipComponents(int num_components, Utils::Program::NameVector &varyings)
23057 {
23058     int num_component_4 = num_components / 4;
23059     int num_component_1 = num_components % 4;
23060     for (int i = 0; i < num_component_4; i++)
23061     {
23062         varyings.push_back("gl_SkipComponents4");
23063     }
23064     switch (num_component_1)
23065     {
23066     case 1:
23067         varyings.push_back("gl_SkipComponents1");
23068         break;
23069     case 2:
23070         varyings.push_back("gl_SkipComponents2");
23071         break;
23072     case 3:
23073         varyings.push_back("gl_SkipComponents3");
23074         break;
23075     default:
23076         break;
23077     }
23078 }
23079 
23080 /** Runs test case
23081  *
23082  * @param test_case_index Id of test case
23083  *
23084  * @return true if test case pass, false otherwise
23085  **/
23086 bool XFBGetProgramResourceAPITest::testCase(GLuint test_case_index)
23087 {
23088     const std::string &gs_source = getShaderSource(test_case_index, Utils::Shader::GEOMETRY);
23089     Utils::Program program(m_context);
23090     const std::string &tcs_source = getShaderSource(test_case_index, Utils::Shader::TESS_CTRL);
23091     const std::string &tes_source = getShaderSource(test_case_index, Utils::Shader::TESS_EVAL);
23092     const test_Case &test_case    = m_test_cases[test_case_index];
23093     bool test_case_result         = true;
23094     const std::string &vs_source  = getShaderSource(test_case_index, Utils::Shader::VERTEX);
23095 
23096     // According to spec: gl_SkipComponents1 ~ gl_SkipComponents4 is treated as specifying a one- to four-component floating point output variables with undefined values.
23097     // 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.
23098 
23099     if (INTERLEAVED == test_case.m_case)
23100     {
23101         /*
23102          layout (xfb_buffer = 0, xfb_offset = 1 * type_size) out type b0_v1;
23103          layout (xfb_buffer = 1, xfb_offset = 1 * type_size) out type b1_v1;
23104          layout (xfb_buffer = 0, xfb_offset = 3 * type_size) out type b0_v3;
23105          layout (xfb_buffer = 0, xfb_offset = 0 * type_size) out type b0_v0;
23106 
23107          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,
23108          we need to calculate how many "gl_SkipComponents" need to be inserted.
23109          */
23110         Utils::Program::NameVector captured_varyings;
23111         captured_varyings.push_back("b0_v0");
23112         captured_varyings.push_back("b0_v1");
23113         // Compute how many gl_SkipComponents to be inserted
23114         int numComponents = test_case.m_type.GetSize() / 4;
23115         insertSkipComponents(numComponents, captured_varyings);
23116         captured_varyings.push_back("b0_v3");
23117         captured_varyings.push_back("gl_NextBuffer");
23118         insertSkipComponents(numComponents, captured_varyings);
23119         captured_varyings.push_back("b1_v1");
23120         insertSkipComponents(numComponents * 2, captured_varyings);
23121 
23122         program.Init("" /* cs */, "", gs_source, tcs_source, tes_source, vs_source, captured_varyings, true,
23123                      true /* separable */);
23124     }
23125     else if (SEPARATED == test_case.m_case)
23126     {
23127         Utils::Program::NameVector captured_varyings;
23128 
23129         captured_varyings.push_back("b0_v0");
23130         captured_varyings.push_back("b0_v1");
23131         captured_varyings.push_back("b0_v3");
23132         captured_varyings.push_back("b1_v1");
23133 
23134         program.Init("" /* cs */, "", gs_source, tcs_source, tes_source, vs_source, captured_varyings, false,
23135                      true /* separable */);
23136     }
23137     else
23138     {
23139 
23140         program.Init("" /* cs */, "", gs_source, tcs_source, tes_source, vs_source, true /* separable */);
23141     }
23142 
23143     test_case_result = inspectProgram(test_case_index, program);
23144 
23145     return test_case_result;
23146 }
23147 
23148 /** Prepare all test cases
23149  *
23150  **/
23151 void XFBGetProgramResourceAPITest::testInit()
23152 {
23153     const Functions &gl  = m_context.getRenderContext().getFunctions();
23154     const GLuint n_types = getTypesNumber();
23155     GLint max_xfb_int;
23156     GLint max_xfb_sep;
23157 
23158     gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_xfb_int);
23159     GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
23160 
23161     gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, &max_xfb_sep);
23162     GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
23163 
23164     GLint max_varyings;
23165     gl.getIntegerv(GL_MAX_VARYING_COMPONENTS, &max_varyings);
23166 
23167     for (GLuint i = 0; i < n_types; ++i)
23168     {
23169         // 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,
23170         // 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
23171         // shader valid, we can either skip the dmat4, dmat4x3 or query the implementation-dependent value MAX_VARYING_COMPONENTS before generating the shader
23172         // to guarantee the number of varying not exceeded.
23173         /*
23174          layout (xfb_buffer = 1, xfb_stride = 4 * type_size) out;
23175          layout (xfb_buffer = 0, xfb_offset = 1 * type_size) out type b0_v1;
23176          layout (xfb_buffer = 1, xfb_offset = 1 * type_size) out type b1_v1;
23177          layout (xfb_buffer = 0, xfb_offset = 3 * type_size) out type b0_v3;
23178          layout (xfb_buffer = 0, xfb_offset = 0 * type_size) out type b0_v0;
23179          in  vec4 in_vs;
23180          out vec4 vs_tcs;
23181          */
23182         if (i == 7 || i == 9)
23183             continue;
23184         const Utils::Type &type = getType(i);
23185         if (4 * type.GetNumComponents() + 4 > (GLuint)max_varyings)
23186         {
23187             continue;
23188         }
23189         for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
23190         {
23191             /*
23192              It is invalid to define transform feedback output in HS
23193              */
23194             if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
23195                 (Utils::Shader::FRAGMENT == stage))
23196             {
23197                 continue;
23198             }
23199 
23200             test_Case test_case_int = {INTERLEAVED, (Utils::Shader::STAGES)stage, type};
23201             test_Case test_case_sep = {SEPARATED, (Utils::Shader::STAGES)stage, type};
23202             test_Case test_case_xfb = {XFB, (Utils::Shader::STAGES)stage, type};
23203 
23204             if ((int)type.GetSize() <= max_xfb_int)
23205             {
23206                 m_test_cases.push_back(test_case_xfb);
23207                 m_test_cases.push_back(test_case_int);
23208             }
23209 
23210             if ((int)type.GetSize() <= max_xfb_sep)
23211             {
23212                 m_test_cases.push_back(test_case_sep);
23213             }
23214         }
23215     }
23216 }
23217 
23218 /** Constructor
23219  *
23220  * @param context Test context
23221  **/
23222 XFBOverrideQualifiersWithAPITest::XFBOverrideQualifiersWithAPITest(deqp::Context &context)
23223     : BufferTestBase(context, "xfb_override_qualifiers_with_api",
23224                      "Test verifies that xfb_offset qualifier is not overriden with API")
23225 {
23226     /* Nothing to be done here */
23227 }
23228 
23229 /** Get descriptors of buffers necessary for test
23230  *
23231  * @param test_case_index Index of test case
23232  * @param out_descriptors Descriptors of buffers used by test
23233  **/
23234 void XFBOverrideQualifiersWithAPITest::getBufferDescriptors(glw::GLuint test_case_index,
23235                                                             bufferDescriptor::Vector &out_descriptors)
23236 {
23237     const Utils::Type &type = getType(test_case_index);
23238 
23239     /* Test needs single uniform and xfb */
23240     out_descriptors.resize(2);
23241 
23242     /* Get references */
23243     bufferDescriptor &uniform = out_descriptors[0];
23244     bufferDescriptor &xfb     = out_descriptors[1];
23245 
23246     /* Index */
23247     uniform.m_index = 0;
23248     xfb.m_index     = 0;
23249 
23250     /* Target */
23251     uniform.m_target = Utils::Buffer::Uniform;
23252     xfb.m_target     = Utils::Buffer::Transform_feedback;
23253 
23254     /* Data */
23255     const GLuint gen_start                  = Utils::s_rand;
23256     const std::vector<GLubyte> &vegeta_data = type.GenerateData();
23257     const std::vector<GLubyte> &trunks_data = type.GenerateData();
23258     const std::vector<GLubyte> &goku_data   = type.GenerateData();
23259 
23260     Utils::s_rand                               = gen_start;
23261     const std::vector<GLubyte> &vegeta_data_pck = type.GenerateDataPacked();
23262     type.GenerateDataPacked(); // generate the data for trunks
23263     const std::vector<GLubyte> &goku_data_pck = type.GenerateDataPacked();
23264 
23265     const GLuint type_size        = static_cast<GLuint>(vegeta_data.size());
23266     const GLuint padded_type_size = type.GetBaseAlignment(false) * type.m_n_columns;
23267     const GLuint type_size_pck    = static_cast<GLuint>(vegeta_data_pck.size());
23268 
23269     /* Uniform data */
23270     uniform.m_initial_data.resize(3 * padded_type_size);
23271     memcpy(&uniform.m_initial_data[0] + 0, &vegeta_data[0], type_size);
23272     memcpy(&uniform.m_initial_data[0] + padded_type_size, &trunks_data[0], type_size);
23273     memcpy(&uniform.m_initial_data[0] + 2 * padded_type_size, &goku_data[0], type_size);
23274 
23275     /* XFB data */
23276     xfb.m_initial_data.resize(3 * type_size_pck);
23277     xfb.m_expected_data.resize(3 * type_size_pck);
23278 
23279     for (GLuint i = 0; i < 3 * type_size_pck; ++i)
23280     {
23281         xfb.m_initial_data[i]  = (glw::GLubyte)i;
23282         xfb.m_expected_data[i] = (glw::GLubyte)i;
23283     }
23284 
23285     memcpy(&xfb.m_expected_data[0] + 0, &goku_data_pck[0], type_size_pck);
23286     memcpy(&xfb.m_expected_data[0] + 2 * type_size_pck, &vegeta_data_pck[0], type_size_pck);
23287 }
23288 
23289 /** Get list of names of varyings that will be registered with TransformFeedbackVaryings
23290  *
23291  * @param ignored
23292  * @param captured_varyings List of names
23293  **/
23294 void XFBOverrideQualifiersWithAPITest::getCapturedVaryings(glw::GLuint test_case_index,
23295                                                            Utils::Program::NameVector &captured_varyings,
23296                                                            GLint *xfb_components)
23297 {
23298     captured_varyings.resize(1);
23299 
23300     captured_varyings[0] = "trunks";
23301 
23302     /* The test captures 3 varyings of type 'type' */
23303     Utils::Type type = getType(test_case_index);
23304     GLint type_size  = type.GetSize(false);
23305     *xfb_components  = 3 * type_size / 4;
23306 }
23307 
23308 /** Get body of main function for given shader stage
23309  *
23310  * @param test_case_index  Index of test case
23311  * @param stage            Shader stage
23312  * @param out_assignments  Set to empty
23313  * @param out_calculations Set to empty
23314  **/
23315 void XFBOverrideQualifiersWithAPITest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
23316                                                      std::string &out_assignments, std::string &out_calculations)
23317 {
23318     out_calculations = "";
23319 
23320     static const GLchar *gs = "    vegeta = uni_vegeta;\n"
23321                               "    trunks = uni_trunks;\n"
23322                               "    goku   = uni_goku;\n";
23323     static const GLchar *fs = "    fs_out = vec4(0);\n"
23324                               "    if (TYPE(1) == goku + trunks + vegeta)\n"
23325                               "    {\n"
23326                               "        fs_out = vec4(1);\n"
23327                               "    }\n";
23328 
23329     const GLchar *assignments = "";
23330     switch (stage)
23331     {
23332     case Utils::Shader::FRAGMENT:
23333         assignments = fs;
23334         break;
23335     case Utils::Shader::GEOMETRY:
23336         assignments = gs;
23337         break;
23338     default:
23339         break;
23340     }
23341 
23342     out_assignments = assignments;
23343 
23344     if (Utils::Shader::FRAGMENT == stage)
23345     {
23346         const Utils::Type &type = getType(test_case_index);
23347 
23348         Utils::replaceAllTokens("TYPE", type.GetGLSLTypeName(), out_assignments);
23349     }
23350 }
23351 
23352 /** Get interface of shader
23353  *
23354  * @param test_case_index  Index of test case
23355  * @param stage            Shader stage
23356  * @param out_interface    Set to ""
23357  **/
23358 void XFBOverrideQualifiersWithAPITest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
23359                                                           std::string &out_interface)
23360 {
23361     static const GLchar *gs =
23362         "const uint sizeof_type = SIZE;\n"
23363         "\n"
23364         "layout (xfb_offset = 2 * sizeof_type) flat out TYPE vegeta;\n"
23365         "                                      flat out TYPE trunks;\n"
23366         "layout (xfb_offset = 0)               flat out TYPE goku;\n"
23367         "\n"
23368         /*
23369 There is no packing qualifier for uniform block gs_block, according to spec, it should be "shared" by default,
23370 the definition equals to "layout(binding=0, shared)", if the block is declared as shared, each block member will
23371 not be packed, and each block member's layout in memory is implementation dependent, so we can't use the API
23372 glBufferData() to update the UBO directly, we need to query each block member's offset first, then upload the
23373 data to the corresponding offset, otherwise we can't get the correct data from UBO; to make the test passed,
23374 we need to add the qualifier std140,  and change the declaration as layout(binding=0, std140), which can make
23375 sure all the block members are packed and the application can upload the data by glBufferData() directly.
23376 */
23377         "layout(binding = 0, std140) uniform gs_block {\n"
23378         "    TYPE uni_vegeta;\n"
23379         "    TYPE uni_trunks;\n"
23380         "    TYPE uni_goku;\n"
23381         "};\n";
23382     static const GLchar *fs = "flat in TYPE vegeta;\n"
23383                               "flat in TYPE trunks;\n"
23384                               "flat in TYPE goku;\n"
23385                               "\n"
23386                               "out vec4 fs_out;\n";
23387 
23388     const Utils::Type &type = getType(test_case_index);
23389 
23390     switch (stage)
23391     {
23392     case Utils::Shader::FRAGMENT:
23393         out_interface = fs;
23394         break;
23395     case Utils::Shader::GEOMETRY:
23396         out_interface = gs;
23397         break;
23398     default:
23399         out_interface = "";
23400         return;
23401     }
23402 
23403     if (Utils::Shader::GEOMETRY == stage)
23404     {
23405         GLchar buffer[16];
23406         size_t position        = 0;
23407         const GLuint type_size = type.GetSize();
23408 
23409         sprintf(buffer, "%d", type_size);
23410 
23411         Utils::replaceToken("SIZE", position, buffer, out_interface);
23412     }
23413 
23414     Utils::replaceAllTokens("TYPE", type.GetGLSLTypeName(), out_interface);
23415 }
23416 
23417 /** Get type name
23418  *
23419  * @param test_case_index Index of test case
23420  *
23421  * @return Name of type test in test_case_index
23422  **/
23423 std::string XFBOverrideQualifiersWithAPITest::getTestCaseName(glw::GLuint test_case_index)
23424 {
23425     return getTypeName(test_case_index);
23426 }
23427 
23428 /** Returns number of types to test
23429  *
23430  * @return Number of types, 34
23431  **/
23432 glw::GLuint XFBOverrideQualifiersWithAPITest::getTestCaseNumber()
23433 {
23434     return getTypesNumber();
23435 }
23436 
23437 /** Inspects program to check if all resources are as expected
23438  *
23439  * @param test_case_index Index of test case
23440  * @param program         Program instance
23441  * @param out_stream      Error message
23442  *
23443  * @return true if everything is ok, false otherwise
23444  **/
23445 bool XFBOverrideQualifiersWithAPITest::inspectProgram(GLuint test_case_index, Utils::Program &program,
23446                                                       std::stringstream &out_stream)
23447 {
23448     GLint stride            = 0;
23449     const Utils::Type &type = getType(test_case_index);
23450     const GLuint type_size  = type.GetSize(false);
23451 
23452     program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE,
23453                         1 /* buf_size */, &stride);
23454 
23455     if ((GLint)(3 * type_size) != stride)
23456     {
23457         out_stream << "Stride is: " << stride << " expected: " << (3 * type_size);
23458 
23459         return false;
23460     }
23461 
23462     return true;
23463 }
23464 
23465 /** Constructor
23466  *
23467  * @param context Test context
23468  **/
23469 XFBVertexStreamsTest::XFBVertexStreamsTest(deqp::Context &context)
23470     : BufferTestBase(context, "xfb_vertex_streams",
23471                      "Test verifies that xfb qualifier works with multiple output streams")
23472 {
23473     /* Nothing to be done here */
23474 }
23475 
23476 /** Get descriptors of buffers necessary for test
23477  *
23478  * @param ignored
23479  * @param out_descriptors Descriptors of buffers used by test
23480  **/
23481 void XFBVertexStreamsTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
23482                                                 bufferDescriptor::Vector &out_descriptors)
23483 {
23484     const Utils::Type &type = Utils::Type::vec4;
23485 
23486     /* Test needs single uniform and three xfbs */
23487     out_descriptors.resize(4);
23488 
23489     /* Get references */
23490     bufferDescriptor &uniform = out_descriptors[0];
23491     bufferDescriptor &xfb_1   = out_descriptors[1];
23492     bufferDescriptor &xfb_2   = out_descriptors[2];
23493     bufferDescriptor &xfb_3   = out_descriptors[3];
23494 
23495     /* Index */
23496     uniform.m_index = 0;
23497     xfb_1.m_index   = 1;
23498     xfb_2.m_index   = 2;
23499     xfb_3.m_index   = 3;
23500 
23501     /* Target */
23502     uniform.m_target = Utils::Buffer::Uniform;
23503     xfb_1.m_target   = Utils::Buffer::Transform_feedback;
23504     xfb_2.m_target   = Utils::Buffer::Transform_feedback;
23505     xfb_3.m_target   = Utils::Buffer::Transform_feedback;
23506 
23507     /* Data */
23508     const std::vector<GLubyte> &goku_data   = type.GenerateData();
23509     const std::vector<GLubyte> &gohan_data  = type.GenerateData();
23510     const std::vector<GLubyte> &goten_data  = type.GenerateData();
23511     const std::vector<GLubyte> &picolo_data = type.GenerateData();
23512     const std::vector<GLubyte> &vegeta_data = type.GenerateData();
23513     const std::vector<GLubyte> &bulma_data  = type.GenerateData();
23514 
23515     const GLuint type_size = static_cast<GLuint>(vegeta_data.size());
23516 
23517     /* Uniform data */
23518     uniform.m_initial_data.resize(6 * type_size);
23519     memcpy(&uniform.m_initial_data[0] + 0, &goku_data[0], type_size);
23520     memcpy(&uniform.m_initial_data[0] + type_size, &gohan_data[0], type_size);
23521     memcpy(&uniform.m_initial_data[0] + 2 * type_size, &goten_data[0], type_size);
23522     memcpy(&uniform.m_initial_data[0] + 3 * type_size, &picolo_data[0], type_size);
23523     memcpy(&uniform.m_initial_data[0] + 4 * type_size, &vegeta_data[0], type_size);
23524     memcpy(&uniform.m_initial_data[0] + 5 * type_size, &bulma_data[0], type_size);
23525 
23526     /* XFB data */
23527     static const GLuint xfb_stride = 64;
23528     xfb_1.m_initial_data.resize(xfb_stride);
23529     xfb_1.m_expected_data.resize(xfb_stride);
23530     xfb_2.m_initial_data.resize(xfb_stride);
23531     xfb_2.m_expected_data.resize(xfb_stride);
23532     xfb_3.m_initial_data.resize(xfb_stride);
23533     xfb_3.m_expected_data.resize(xfb_stride);
23534 
23535     for (GLuint i = 0; i < xfb_stride; ++i)
23536     {
23537         xfb_1.m_initial_data[i]  = (glw::GLubyte)i;
23538         xfb_1.m_expected_data[i] = (glw::GLubyte)i;
23539         xfb_2.m_initial_data[i]  = (glw::GLubyte)i;
23540         xfb_2.m_expected_data[i] = (glw::GLubyte)i;
23541         xfb_3.m_initial_data[i]  = (glw::GLubyte)i;
23542         xfb_3.m_expected_data[i] = (glw::GLubyte)i;
23543     }
23544 
23545     memcpy(&xfb_1.m_expected_data[0] + 48, &goku_data[0], type_size);
23546     memcpy(&xfb_1.m_expected_data[0] + 32, &gohan_data[0], type_size);
23547     memcpy(&xfb_1.m_expected_data[0] + 16, &goten_data[0], type_size);
23548     memcpy(&xfb_3.m_expected_data[0] + 48, &picolo_data[0], type_size);
23549     memcpy(&xfb_3.m_expected_data[0] + 32, &vegeta_data[0], type_size);
23550     memcpy(&xfb_2.m_expected_data[0] + 32, &bulma_data[0], type_size);
23551 }
23552 
23553 /** Get body of main function for given shader stage
23554  *
23555  * @param ignored
23556  * @param stage            Shader stage
23557  * @param out_assignments  Set to empty
23558  * @param out_calculations Set to empty
23559  **/
23560 void XFBVertexStreamsTest::getShaderBody(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
23561                                          std::string &out_assignments, std::string &out_calculations)
23562 {
23563     out_calculations = "";
23564 
23565     // the shader declares the output variables with different "stream" qualifier, to make the data can export to
23566     // each stream, we must call the function EmitStreamVertex() and EndStreamPrimitive() to make each vertex emitted
23567     // by the GS is assigned to specific stream.
23568     static const GLchar *gs = "    goku   = uni_goku;\n"
23569                               "    gohan  = uni_gohan;\n"
23570                               "    goten  = uni_goten;\n"
23571                               "    EmitStreamVertex(0);\n"
23572                               "    EndStreamPrimitive(0);\n"
23573                               "    picolo = uni_picolo;\n"
23574                               "    vegeta = uni_vegeta;\n"
23575                               "    EmitStreamVertex(1);\n"
23576                               "    EndStreamPrimitive(1);\n"
23577                               "    bulma  = uni_bulma;\n"
23578                               "    EmitStreamVertex(2);\n"
23579                               "    EndStreamPrimitive(2);\n";
23580 
23581     static const GLchar *fs = "    fs_out = gohan + goku + goten;\n";
23582 
23583     const GLchar *assignments = "";
23584     switch (stage)
23585     {
23586     case Utils::Shader::FRAGMENT:
23587         assignments = fs;
23588         break;
23589     case Utils::Shader::GEOMETRY:
23590         assignments = gs;
23591         break;
23592     default:
23593         break;
23594     }
23595 
23596     out_assignments = assignments;
23597 }
23598 
23599 /** Get interface of shader
23600  *
23601  * @param ignored
23602  * @param stage            Shader stage
23603  * @param out_interface    Set to ""
23604  **/
23605 void XFBVertexStreamsTest::getShaderInterface(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
23606                                               std::string &out_interface)
23607 {
23608     static const GLchar *gs = "layout (xfb_buffer = 1, xfb_stride = 64) out;\n"
23609                               "layout (xfb_buffer = 2, xfb_stride = 64) out;\n"
23610                               "layout (xfb_buffer = 3, xfb_stride = 64) out;\n"
23611                               "\n"
23612                               "layout (stream = 0, xfb_buffer = 1, xfb_offset = 48) out vec4 goku;\n"
23613                               "layout (stream = 0, xfb_buffer = 1, xfb_offset = 32) out vec4 gohan;\n"
23614                               "layout (stream = 0, xfb_buffer = 1, xfb_offset = 16) out vec4 goten;\n"
23615                               "layout (stream = 1, xfb_buffer = 3, xfb_offset = 48) out vec4 picolo;\n"
23616                               "layout (stream = 1, xfb_buffer = 3, xfb_offset = 32) out vec4 vegeta;\n"
23617                               "layout (stream = 2, xfb_buffer = 2, xfb_offset = 32) out vec4 bulma;\n"
23618                               "\n"
23619                               "layout(binding = 0) uniform gs_block {\n"
23620                               "    vec4 uni_goku;\n"
23621                               "    vec4 uni_gohan;\n"
23622                               "    vec4 uni_goten;\n"
23623                               "    vec4 uni_picolo;\n"
23624                               "    vec4 uni_vegeta;\n"
23625                               "    vec4 uni_bulma;\n"
23626                               "};\n";
23627     /*
23628      Fixed incorrect usage of in/out qualifier, the following variable should be input symbols for fragment shader
23629      */
23630     static const GLchar *fs = "in vec4 goku;\n"
23631                               "in vec4 gohan;\n"
23632                               "in vec4 goten;\n"
23633                               "\n"
23634                               "out vec4 fs_out;\n";
23635 
23636     switch (stage)
23637     {
23638     case Utils::Shader::FRAGMENT:
23639         out_interface = fs;
23640         break;
23641     case Utils::Shader::GEOMETRY:
23642         out_interface = gs;
23643         break;
23644     default:
23645         out_interface = "";
23646         return;
23647     }
23648 }
23649 
23650 /** Constructor
23651  *
23652  * @param context Test framework context
23653  **/
23654 XFBMultipleVertexStreamsTest::XFBMultipleVertexStreamsTest(deqp::Context &context)
23655     : NegativeTestBase(
23656           context, "xfb_multiple_vertex_streams",
23657           "Test verifies that compiler reports error when multiple streams are captured with same xfb_buffer")
23658 {
23659 }
23660 
23661 /** Source for given test case and stage
23662  *
23663  * @param ignored
23664  * @param stage           Shader stage
23665  *
23666  * @return Shader source
23667  **/
23668 std::string XFBMultipleVertexStreamsTest::getShaderSource(GLuint /* test_case_index */, Utils::Shader::STAGES stage)
23669 {
23670     static const GLchar *var_definition = "const uint valid_stride = 64;\n"
23671                                           "\n"
23672                                           "layout (xfb_buffer = 1, xfb_stride = valid_stride) out;\n"
23673                                           "layout (xfb_buffer = 3, xfb_stride = valid_stride) out;\n"
23674                                           "\n"
23675                                           "\n"
23676 #if DEBUG_NEG_REMOVE_ERROR
23677                                           "layout (stream = 0, xfb_buffer = 1, xfb_offset = 48) out vec4 goku;\n"
23678                                           "layout (stream = 1, xfb_buffer = 3, xfb_offset = 32) out vec4 gohan;\n"
23679                                           "layout (stream = 2, xfb_buffer = 2, xfb_offset = 16) out vec4 goten;\n";
23680 #else
23681                                           "layout (stream = 0, xfb_buffer = 1, xfb_offset = 48) out vec4 goku;\n"
23682                                           "layout (stream = 1, xfb_buffer = 1, xfb_offset = 32) out vec4 gohan;\n"
23683                                           "layout (stream = 2, xfb_buffer = 1, xfb_offset = 16) out vec4 goten;\n";
23684 #endif /* DEBUG_NEG_REMOVE_ERROR */
23685     static const GLchar *var_use = "    goku  = result / 2;\n"
23686                                    "    gohan = result / 4;\n"
23687                                    "    goten = result / 6;\n";
23688     static const GLchar *fs      = "#version 430 core\n"
23689                                    "#extension GL_ARB_enhanced_layouts : require\n"
23690                                    "\n"
23691                                    "in  vec4 gs_fs;\n"
23692                                    "in  vec4 goku;\n"
23693                                    "out vec4 fs_out;\n"
23694                                    "\n"
23695                                    "void main()\n"
23696                                    "{\n"
23697                                    "    fs_out = gs_fs + goku;\n"
23698                                    "}\n"
23699                                    "\n";
23700     static const GLchar *gs      = "#version 430 core\n"
23701                                    "#extension GL_ARB_enhanced_layouts : require\n"
23702                                    "\n"
23703                                    "layout(points)                           in;\n"
23704                                    "layout(triangle_strip, max_vertices = 4) out;\n"
23705                                    "\n"
23706                                    "VAR_DEFINITION"
23707                                    "\n"
23708                                    "in  vec4 vs_gs[];\n"
23709                                    "out vec4 gs_fs;\n"
23710                                    "\n"
23711                                    "void main()\n"
23712                                    "{\n"
23713                                    "    vec4 result = vs_gs[0];\n"
23714                                    "\n"
23715                                    "VARIABLE_USE"
23716                                    "\n"
23717                                    "    gs_fs = result;\n"
23718                                    "    gl_Position  = vec4(-1, -1, 0, 1);\n"
23719                                    "    EmitVertex();\n"
23720                                    "    gs_fs = result;\n"
23721                                    "    gl_Position  = vec4(-1, 1, 0, 1);\n"
23722                                    "    EmitVertex();\n"
23723                                    "    gs_fs = result;\n"
23724                                    "    gl_Position  = vec4(1, -1, 0, 1);\n"
23725                                    "    EmitVertex();\n"
23726                                    "    gs_fs = result;\n"
23727                                    "    gl_Position  = vec4(1, 1, 0, 1);\n"
23728                                    "    EmitVertex();\n"
23729                                    "}\n"
23730                                    "\n";
23731     static const GLchar *vs      = "#version 430 core\n"
23732                                    "#extension GL_ARB_enhanced_layouts : require\n"
23733                                    "\n"
23734                                    "in  vec4 in_vs;\n"
23735                                    "out vec4 vs_gs;\n"
23736                                    "\n"
23737                                    "void main()\n"
23738                                    "{\n"
23739                                    "    vs_gs = in_vs;\n"
23740                                    "}\n"
23741                                    "\n";
23742 
23743     std::string source;
23744 
23745     if (Utils::Shader::GEOMETRY == stage)
23746     {
23747         size_t position = 0;
23748 
23749         source = gs;
23750 
23751         Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
23752         Utils::replaceToken("VARIABLE_USE", position, var_use, source);
23753     }
23754     else
23755     {
23756         switch (stage)
23757         {
23758         case Utils::Shader::FRAGMENT:
23759             source = fs;
23760             break;
23761         case Utils::Shader::VERTEX:
23762             source = vs;
23763             break;
23764         default:
23765             source = "";
23766         }
23767     }
23768 
23769     return source;
23770 }
23771 
23772 /** Selects if "compute" stage is relevant for test
23773  *
23774  * @param ignored
23775  *
23776  * @return false
23777  **/
23778 bool XFBMultipleVertexStreamsTest::isComputeRelevant(GLuint /* test_case_index */)
23779 {
23780     return false;
23781 }
23782 
23783 /** Constructor
23784  *
23785  * @param context Test framework context
23786  **/
23787 XFBExceedBufferLimitTest::XFBExceedBufferLimitTest(deqp::Context &context)
23788     : NegativeTestBase(context, "xfb_exceed_buffer_limit",
23789                        "Test verifies that compiler reports error when xfb_buffer qualifier exceeds limit")
23790 {
23791 }
23792 
23793 /** Source for given test case and stage
23794  *
23795  * @param test_case_index Index of test case
23796  * @param stage           Shader stage
23797  *
23798  * @return Shader source
23799  **/
23800 std::string XFBExceedBufferLimitTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
23801 {
23802     static const GLchar *block_var_definition = "const uint buffer_index = MAX_BUFFER;\n"
23803                                                 "\n"
23804 #if DEBUG_NEG_REMOVE_ERROR
23805                                                 "layout (xfb_buffer = 0, xfb_offset = 0) out Goku {\n"
23806 #else
23807                                                 "layout (xfb_buffer = buffer_index, xfb_offset = 0) out Goku {\n"
23808 #endif /* DEBUG_NEG_REMOVE_ERROR */
23809                                                 "    vec4 member;\n"
23810                                                 "} goku;\n";
23811     static const GLchar *global_var_definition = "const uint buffer_index = MAX_BUFFER;\n"
23812                                                  "\n"
23813 #if DEBUG_NEG_REMOVE_ERROR
23814                                                  "layout (xfb_buffer = 0) out;\n";
23815 #else
23816                                                  "layout (xfb_buffer = buffer_index) out;\n";
23817 #endif /* DEBUG_NEG_REMOVE_ERROR */
23818     static const GLchar *vector_var_definition = "const uint buffer_index = MAX_BUFFER;\n"
23819                                                  "\n"
23820 #if DEBUG_NEG_REMOVE_ERROR
23821                                                  "layout (xfb_buffer = 0) out vec4 goku;\n";
23822 #else
23823                                                  "layout (xfb_buffer = buffer_index) out vec4 goku;\n";
23824 #endif /* DEBUG_NEG_REMOVE_ERROR */
23825     static const GLchar *block_use  = "    goku.member = result / 2;\n";
23826     static const GLchar *global_use = "";
23827     static const GLchar *vector_use = "    goku = result / 2;\n";
23828     static const GLchar *fs         = "#version 430 core\n"
23829                                       "#extension GL_ARB_enhanced_layouts : require\n"
23830                                       "\n"
23831                                       "in  vec4 any_fs;\n"
23832                                       "out vec4 fs_out;\n"
23833                                       "\n"
23834                                       "void main()\n"
23835                                       "{\n"
23836                                       "    fs_out = any_fs;\n"
23837                                       "}\n"
23838                                       "\n";
23839     static const GLchar *gs_tested  = "#version 430 core\n"
23840                                       "#extension GL_ARB_enhanced_layouts : require\n"
23841                                       "\n"
23842                                       "layout(points)                           in;\n"
23843                                       "layout(triangle_strip, max_vertices = 4) out;\n"
23844                                       "\n"
23845                                       "VAR_DEFINITION"
23846                                       "\n"
23847                                       "in  vec4 vs_any[];\n"
23848                                       "out vec4 any_fs;\n"
23849                                       "\n"
23850                                       "void main()\n"
23851                                       "{\n"
23852                                       "    vec4 result = vs_any[0];\n"
23853                                       "\n"
23854                                       "VARIABLE_USE"
23855                                       "\n"
23856                                       "    any_fs = result;\n"
23857                                       "    gl_Position  = vec4(-1, -1, 0, 1);\n"
23858                                       "    EmitVertex();\n"
23859                                       "    any_fs = result;\n"
23860                                       "    gl_Position  = vec4(-1, 1, 0, 1);\n"
23861                                       "    EmitVertex();\n"
23862                                       "    any_fs = result;\n"
23863                                       "    gl_Position  = vec4(1, -1, 0, 1);\n"
23864                                       "    EmitVertex();\n"
23865                                       "    any_fs = result;\n"
23866                                       "    gl_Position  = vec4(1, 1, 0, 1);\n"
23867                                       "    EmitVertex();\n"
23868                                       "}\n"
23869                                       "\n";
23870     static const GLchar *tcs        = "#version 430 core\n"
23871                                       "#extension GL_ARB_enhanced_layouts : require\n"
23872                                       "\n"
23873                                       "layout(vertices = 1) out;\n"
23874                                       "\n"
23875                                       "in  vec4 vs_any[];\n"
23876                                       "out vec4 tcs_tes[];\n"
23877                                       "\n"
23878                                       "void main()\n"
23879                                       "{\n"
23880                                       "\n"
23881                                       "    tcs_tes[gl_InvocationID] = vs_any[gl_InvocationID];\n"
23882                                       "\n"
23883                                       "    gl_TessLevelOuter[0] = 1.0;\n"
23884                                       "    gl_TessLevelOuter[1] = 1.0;\n"
23885                                       "    gl_TessLevelOuter[2] = 1.0;\n"
23886                                       "    gl_TessLevelOuter[3] = 1.0;\n"
23887                                       "    gl_TessLevelInner[0] = 1.0;\n"
23888                                       "    gl_TessLevelInner[1] = 1.0;\n"
23889                                       "}\n"
23890                                       "\n";
23891     static const GLchar *tes_tested = "#version 430 core\n"
23892                                       "#extension GL_ARB_enhanced_layouts : require\n"
23893                                       "\n"
23894                                       "layout(isolines, point_mode) in;\n"
23895                                       "\n"
23896                                       "VAR_DEFINITION"
23897                                       "\n"
23898                                       "in  vec4 tcs_tes[];\n"
23899                                       "out vec4 any_fs;\n"
23900                                       "\n"
23901                                       "void main()\n"
23902                                       "{\n"
23903                                       "    vec4 result = tcs_tes[0];\n"
23904                                       "\n"
23905                                       "VARIABLE_USE"
23906                                       "\n"
23907                                       "    any_fs += result;\n"
23908                                       "}\n"
23909                                       "\n";
23910     static const GLchar *vs         = "#version 430 core\n"
23911                                       "#extension GL_ARB_enhanced_layouts : require\n"
23912                                       "\n"
23913                                       "in  vec4 in_vs;\n"
23914                                       "out vec4 vs_any;\n"
23915                                       "\n"
23916                                       "void main()\n"
23917                                       "{\n"
23918                                       "    vs_any = in_vs;\n"
23919                                       "}\n"
23920                                       "\n";
23921     static const GLchar *vs_tested  = "#version 430 core\n"
23922                                       "#extension GL_ARB_enhanced_layouts : require\n"
23923                                       "\n"
23924                                       "VAR_DEFINITION"
23925                                       "\n"
23926                                       "in  vec4 in_vs;\n"
23927                                       "out vec4 any_fs;\n"
23928                                       "\n"
23929                                       "void main()\n"
23930                                       "{\n"
23931                                       "    vec4 result = in_vs;\n"
23932                                       "\n"
23933                                       "VARIABLE_USE"
23934                                       "\n"
23935                                       "    any_fs = result;\n"
23936                                       "}\n"
23937                                       "\n";
23938 
23939     std::string source;
23940     testCase &test_case = m_test_cases[test_case_index];
23941 
23942     if (test_case.m_stage == stage)
23943     {
23944         GLchar buffer[16];
23945         const Functions &gl          = m_context.getRenderContext().getFunctions();
23946         GLint max_n_xfb              = 0;
23947         size_t position              = 0;
23948         const GLchar *var_definition = 0;
23949         const GLchar *var_use        = 0;
23950 
23951         gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_n_xfb);
23952         GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
23953 
23954         sprintf(buffer, "%d", max_n_xfb);
23955 
23956         switch (test_case.m_case)
23957         {
23958         case BLOCK:
23959             var_definition = block_var_definition;
23960             var_use        = block_use;
23961             break;
23962         case GLOBAL:
23963             var_definition = global_var_definition;
23964             var_use        = global_use;
23965             break;
23966         case VECTOR:
23967             var_definition = vector_var_definition;
23968             var_use        = vector_use;
23969             break;
23970         default:
23971             TCU_FAIL("Invalid enum");
23972         }
23973 
23974         switch (stage)
23975         {
23976         case Utils::Shader::GEOMETRY:
23977             source = gs_tested;
23978             break;
23979         case Utils::Shader::TESS_EVAL:
23980             source = tes_tested;
23981             break;
23982         case Utils::Shader::VERTEX:
23983             source = vs_tested;
23984             break;
23985         default:
23986             TCU_FAIL("Invalid enum");
23987         }
23988 
23989         Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
23990         position = 0;
23991         Utils::replaceToken("MAX_BUFFER", position, buffer, source);
23992         Utils::replaceToken("VARIABLE_USE", position, var_use, source);
23993     }
23994     else
23995     {
23996         switch (test_case.m_stage)
23997         {
23998         case Utils::Shader::GEOMETRY:
23999             switch (stage)
24000             {
24001             case Utils::Shader::FRAGMENT:
24002                 source = fs;
24003                 break;
24004             case Utils::Shader::VERTEX:
24005                 source = vs;
24006                 break;
24007             default:
24008                 source = "";
24009             }
24010             break;
24011         case Utils::Shader::TESS_EVAL:
24012             switch (stage)
24013             {
24014             case Utils::Shader::FRAGMENT:
24015                 source = fs;
24016                 break;
24017             case Utils::Shader::TESS_CTRL:
24018                 source = tcs;
24019                 break;
24020             case Utils::Shader::VERTEX:
24021                 source = vs;
24022                 break;
24023             default:
24024                 source = "";
24025             }
24026             break;
24027         case Utils::Shader::VERTEX:
24028             switch (stage)
24029             {
24030             case Utils::Shader::FRAGMENT:
24031                 source = fs;
24032                 break;
24033             default:
24034                 source = "";
24035             }
24036             break;
24037         default:
24038             TCU_FAIL("Invalid enum");
24039         }
24040     }
24041 
24042     return source;
24043 }
24044 
24045 /** Get description of test case
24046  *
24047  * @param test_case_index Index of test case
24048  *
24049  * @return Test case description
24050  **/
24051 std::string XFBExceedBufferLimitTest::getTestCaseName(GLuint test_case_index)
24052 {
24053     std::stringstream stream;
24054     testCase &test_case = m_test_cases[test_case_index];
24055 
24056     stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", case: ";
24057 
24058     switch (test_case.m_case)
24059     {
24060     case BLOCK:
24061         stream << "BLOCK";
24062         break;
24063     case GLOBAL:
24064         stream << "GLOBAL";
24065         break;
24066     case VECTOR:
24067         stream << "VECTOR";
24068         break;
24069     default:
24070         TCU_FAIL("Invalid enum");
24071     }
24072 
24073     return stream.str();
24074 }
24075 
24076 /** Get number of test cases
24077  *
24078  * @return Number of test cases
24079  **/
24080 GLuint XFBExceedBufferLimitTest::getTestCaseNumber()
24081 {
24082     return static_cast<GLuint>(m_test_cases.size());
24083 }
24084 
24085 /** Selects if "compute" stage is relevant for test
24086  *
24087  * @param ignored
24088  *
24089  * @return false
24090  **/
24091 bool XFBExceedBufferLimitTest::isComputeRelevant(GLuint /* test_case_index */)
24092 {
24093     return false;
24094 }
24095 
24096 /** Prepare all test cases
24097  *
24098  **/
24099 void XFBExceedBufferLimitTest::testInit()
24100 {
24101     for (GLuint c = 0; c < CASE_MAX; ++c)
24102     {
24103         for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
24104         {
24105             if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
24106                 (Utils::Shader::FRAGMENT == stage))
24107             {
24108                 continue;
24109             }
24110 
24111             testCase test_case = {(CASES)c, (Utils::Shader::STAGES)stage};
24112 
24113             m_test_cases.push_back(test_case);
24114         }
24115     }
24116 }
24117 
24118 /** Constructor
24119  *
24120  * @param context Test framework context
24121  **/
24122 XFBExceedOffsetLimitTest::XFBExceedOffsetLimitTest(deqp::Context &context)
24123     : NegativeTestBase(context, "xfb_exceed_offset_limit",
24124                        "Test verifies that compiler reports error when xfb_offset qualifier exceeds limit")
24125 {
24126 }
24127 
24128 /** Source for given test case and stage
24129  *
24130  * @param test_case_index Index of test case
24131  * @param stage           Shader stage
24132  *
24133  * @return Shader source
24134  **/
24135 std::string XFBExceedOffsetLimitTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
24136 {
24137     static const GLchar *block_var_definition = "const uint overflow_offset = MAX_SIZE + 16;\n"
24138                                                 "\n"
24139 #if DEBUG_NEG_REMOVE_ERROR
24140                                                 "layout (xfb_buffer = 0, xfb_offset = 0) out Goku {\n"
24141 #else
24142                                                 "layout (xfb_buffer = 0, xfb_offset = overflow_offset + 16) out Goku "
24143                                                 "{\n"
24144 #endif /* DEBUG_NEG_REMOVE_ERROR */
24145                                                 "    vec4 member;\n"
24146                                                 "} goku;\n";
24147     static const GLchar *global_var_definition = "const uint overflow_offset = MAX_SIZE + 16;\n"
24148                                                  "\n"
24149 #if DEBUG_NEG_REMOVE_ERROR
24150                                                  "layout (xfb_buffer = 0, xfb_stride = 0) out;\n";
24151 #else
24152                                                  "layout (xfb_buffer = 0, xfb_stride = overflow_offset) out;\n";
24153 #endif /* DEBUG_NEG_REMOVE_ERROR */
24154     static const GLchar *vector_var_definition = "const uint overflow_offset = MAX_SIZE + 16;\n"
24155                                                  "\n"
24156 #if DEBUG_NEG_REMOVE_ERROR
24157                                                  "layout (xfb_buffer = 0, xfb_offset = 0) out vec4 goku;\n";
24158 #else
24159                                                  "layout (xfb_buffer = 0, xfb_offset = overflow_offset) out vec4 "
24160                                                  "goku;\n";
24161 #endif /* DEBUG_NEG_REMOVE_ERROR */
24162     static const GLchar *block_use  = "    goku.member = result / 2;\n";
24163     static const GLchar *global_use = "";
24164     static const GLchar *vector_use = "    goku = result / 2;\n";
24165     static const GLchar *fs         = "#version 430 core\n"
24166                                       "#extension GL_ARB_enhanced_layouts : require\n"
24167                                       "\n"
24168                                       "in  vec4 any_fs;\n"
24169                                       "out vec4 fs_out;\n"
24170                                       "\n"
24171                                       "void main()\n"
24172                                       "{\n"
24173                                       "    fs_out = any_fs;\n"
24174                                       "}\n"
24175                                       "\n";
24176     static const GLchar *gs_tested  = "#version 430 core\n"
24177                                       "#extension GL_ARB_enhanced_layouts : require\n"
24178                                       "\n"
24179                                       "layout(points)                           in;\n"
24180                                       "layout(triangle_strip, max_vertices = 4) out;\n"
24181                                       "\n"
24182                                       "VAR_DEFINITION"
24183                                       "\n"
24184                                       "in  vec4 vs_any[];\n"
24185                                       "out vec4 any_fs;\n"
24186                                       "\n"
24187                                       "void main()\n"
24188                                       "{\n"
24189                                       "    vec4 result = vs_any[0];\n"
24190                                       "\n"
24191                                       "VARIABLE_USE"
24192                                       "\n"
24193                                       "    any_fs = result;\n"
24194                                       "    gl_Position  = vec4(-1, -1, 0, 1);\n"
24195                                       "    EmitVertex();\n"
24196                                       "    any_fs = result;\n"
24197                                       "    gl_Position  = vec4(-1, 1, 0, 1);\n"
24198                                       "    EmitVertex();\n"
24199                                       "    any_fs = result;\n"
24200                                       "    gl_Position  = vec4(1, -1, 0, 1);\n"
24201                                       "    EmitVertex();\n"
24202                                       "    any_fs = result;\n"
24203                                       "    gl_Position  = vec4(1, 1, 0, 1);\n"
24204                                       "    EmitVertex();\n"
24205                                       "}\n"
24206                                       "\n";
24207     static const GLchar *tcs        = "#version 430 core\n"
24208                                       "#extension GL_ARB_enhanced_layouts : require\n"
24209                                       "\n"
24210                                       "layout(vertices = 1) out;\n"
24211                                       "\n"
24212                                       "in  vec4 vs_any[];\n"
24213                                       "out vec4 tcs_tes[];\n"
24214                                       "\n"
24215                                       "void main()\n"
24216                                       "{\n"
24217                                       "\n"
24218                                       "    tcs_tes[gl_InvocationID] = vs_any[gl_InvocationID];\n"
24219                                       "\n"
24220                                       "    gl_TessLevelOuter[0] = 1.0;\n"
24221                                       "    gl_TessLevelOuter[1] = 1.0;\n"
24222                                       "    gl_TessLevelOuter[2] = 1.0;\n"
24223                                       "    gl_TessLevelOuter[3] = 1.0;\n"
24224                                       "    gl_TessLevelInner[0] = 1.0;\n"
24225                                       "    gl_TessLevelInner[1] = 1.0;\n"
24226                                       "}\n"
24227                                       "\n";
24228     static const GLchar *tes_tested = "#version 430 core\n"
24229                                       "#extension GL_ARB_enhanced_layouts : require\n"
24230                                       "\n"
24231                                       "layout(isolines, point_mode) in;\n"
24232                                       "\n"
24233                                       "VAR_DEFINITION"
24234                                       "\n"
24235                                       "in  vec4 tcs_tes[];\n"
24236                                       "out vec4 any_fs;\n"
24237                                       "\n"
24238                                       "void main()\n"
24239                                       "{\n"
24240                                       "    vec4 result = tcs_tes[0];\n"
24241                                       "\n"
24242                                       "VARIABLE_USE"
24243                                       "\n"
24244                                       "    any_fs += result;\n"
24245                                       "}\n"
24246                                       "\n";
24247     static const GLchar *vs         = "#version 430 core\n"
24248                                       "#extension GL_ARB_enhanced_layouts : require\n"
24249                                       "\n"
24250                                       "in  vec4 in_vs;\n"
24251                                       "out vec4 vs_any;\n"
24252                                       "\n"
24253                                       "void main()\n"
24254                                       "{\n"
24255                                       "    vs_any = in_vs;\n"
24256                                       "}\n"
24257                                       "\n";
24258     static const GLchar *vs_tested  = "#version 430 core\n"
24259                                       "#extension GL_ARB_enhanced_layouts : require\n"
24260                                       "\n"
24261                                       "VAR_DEFINITION"
24262                                       "\n"
24263                                       "in  vec4 in_vs;\n"
24264                                       "out vec4 any_fs;\n"
24265                                       "\n"
24266                                       "void main()\n"
24267                                       "{\n"
24268                                       "    vec4 result = in_vs;\n"
24269                                       "\n"
24270                                       "VARIABLE_USE"
24271                                       "\n"
24272                                       "    any_fs = result;\n"
24273                                       "}\n"
24274                                       "\n";
24275 
24276     std::string source;
24277     testCase &test_case = m_test_cases[test_case_index];
24278 
24279     if (test_case.m_stage == stage)
24280     {
24281         GLchar buffer[16];
24282         const Functions &gl          = m_context.getRenderContext().getFunctions();
24283         GLint max_n_xfb_comp         = 0;
24284         GLint max_n_xfb_bytes        = 0;
24285         size_t position              = 0;
24286         const GLchar *var_definition = 0;
24287         const GLchar *var_use        = 0;
24288 
24289         gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_n_xfb_comp);
24290         GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
24291 
24292         max_n_xfb_bytes = max_n_xfb_comp * 4;
24293 
24294         sprintf(buffer, "%d", max_n_xfb_bytes);
24295 
24296         switch (test_case.m_case)
24297         {
24298         case BLOCK:
24299             var_definition = block_var_definition;
24300             var_use        = block_use;
24301             break;
24302         case GLOBAL:
24303             var_definition = global_var_definition;
24304             var_use        = global_use;
24305             break;
24306         case VECTOR:
24307             var_definition = vector_var_definition;
24308             var_use        = vector_use;
24309             break;
24310         default:
24311             TCU_FAIL("Invalid enum");
24312         }
24313 
24314         switch (stage)
24315         {
24316         case Utils::Shader::GEOMETRY:
24317             source = gs_tested;
24318             break;
24319         case Utils::Shader::TESS_EVAL:
24320             source = tes_tested;
24321             break;
24322         case Utils::Shader::VERTEX:
24323             source = vs_tested;
24324             break;
24325         default:
24326             TCU_FAIL("Invalid enum");
24327         }
24328 
24329         Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
24330         position = 0;
24331         Utils::replaceToken("MAX_SIZE", position, buffer, source);
24332         Utils::replaceToken("VARIABLE_USE", position, var_use, source);
24333     }
24334     else
24335     {
24336         switch (test_case.m_stage)
24337         {
24338         case Utils::Shader::GEOMETRY:
24339             switch (stage)
24340             {
24341             case Utils::Shader::FRAGMENT:
24342                 source = fs;
24343                 break;
24344             case Utils::Shader::VERTEX:
24345                 source = vs;
24346                 break;
24347             default:
24348                 source = "";
24349             }
24350             break;
24351         case Utils::Shader::TESS_EVAL:
24352             switch (stage)
24353             {
24354             case Utils::Shader::FRAGMENT:
24355                 source = fs;
24356                 break;
24357             case Utils::Shader::TESS_CTRL:
24358                 source = tcs;
24359                 break;
24360             case Utils::Shader::VERTEX:
24361                 source = vs;
24362                 break;
24363             default:
24364                 source = "";
24365             }
24366             break;
24367         case Utils::Shader::VERTEX:
24368             switch (stage)
24369             {
24370             case Utils::Shader::FRAGMENT:
24371                 source = fs;
24372                 break;
24373             default:
24374                 source = "";
24375             }
24376             break;
24377         default:
24378             TCU_FAIL("Invalid enum");
24379         }
24380     }
24381 
24382     return source;
24383 }
24384 
24385 /** Get description of test case
24386  *
24387  * @param test_case_index Index of test case
24388  *
24389  * @return Test case description
24390  **/
24391 std::string XFBExceedOffsetLimitTest::getTestCaseName(GLuint test_case_index)
24392 {
24393     std::stringstream stream;
24394     testCase &test_case = m_test_cases[test_case_index];
24395 
24396     stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", case: ";
24397 
24398     switch (test_case.m_case)
24399     {
24400     case BLOCK:
24401         stream << "BLOCK";
24402         break;
24403     case GLOBAL:
24404         stream << "GLOBAL";
24405         break;
24406     case VECTOR:
24407         stream << "VECTOR";
24408         break;
24409     default:
24410         TCU_FAIL("Invalid enum");
24411     }
24412 
24413     return stream.str();
24414 }
24415 
24416 /** Get number of test cases
24417  *
24418  * @return Number of test cases
24419  **/
24420 GLuint XFBExceedOffsetLimitTest::getTestCaseNumber()
24421 {
24422     return static_cast<GLuint>(m_test_cases.size());
24423 }
24424 
24425 /** Selects if "compute" stage is relevant for test
24426  *
24427  * @param ignored
24428  *
24429  * @return false
24430  **/
24431 bool XFBExceedOffsetLimitTest::isComputeRelevant(GLuint /* test_case_index */)
24432 {
24433     return false;
24434 }
24435 
24436 /** Prepare all test cases
24437  *
24438  **/
24439 void XFBExceedOffsetLimitTest::testInit()
24440 {
24441     for (GLuint c = 0; c < CASE_MAX; ++c)
24442     {
24443         for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
24444         {
24445             if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
24446                 (Utils::Shader::FRAGMENT == stage))
24447             {
24448                 continue;
24449             }
24450 
24451             testCase test_case = {(CASES)c, (Utils::Shader::STAGES)stage};
24452 
24453             m_test_cases.push_back(test_case);
24454         }
24455     }
24456 }
24457 
24458 /** Constructor
24459  *
24460  * @param context Test context
24461  **/
24462 XFBGlobalBufferTest::XFBGlobalBufferTest(deqp::Context &context)
24463     : BufferTestBase(context, "xfb_global_buffer", "Test verifies that global xfb_buffer qualifier is respected")
24464 {
24465     /* Nothing to be done here */
24466 }
24467 
24468 /** Get descriptors of buffers necessary for test
24469  *
24470  * @param test_case_index Index of test case
24471  * @param out_descriptors Descriptors of buffers used by test
24472  **/
24473 void XFBGlobalBufferTest::getBufferDescriptors(glw::GLuint test_case_index, bufferDescriptor::Vector &out_descriptors)
24474 {
24475     // the function "getType(test_case_index)" can't return correct data type, so change code as following:
24476     const Utils::Type &type = m_test_cases[test_case_index].m_type;
24477 
24478     /* Test needs single uniform and two xfbs */
24479     out_descriptors.resize(3);
24480 
24481     /* Get references */
24482     bufferDescriptor &uniform = out_descriptors[0];
24483     bufferDescriptor &xfb_1   = out_descriptors[1];
24484     bufferDescriptor &xfb_3   = out_descriptors[2];
24485 
24486     /* Index */
24487     uniform.m_index = 0;
24488     xfb_1.m_index   = 1;
24489     xfb_3.m_index   = 3;
24490 
24491     /* Target */
24492     uniform.m_target = Utils::Buffer::Uniform;
24493     xfb_1.m_target   = Utils::Buffer::Transform_feedback;
24494     xfb_3.m_target   = Utils::Buffer::Transform_feedback;
24495 
24496     /* Data */
24497     const GLuint gen_start                  = Utils::s_rand;
24498     const std::vector<GLubyte> &chichi_data = type.GenerateData();
24499     const std::vector<GLubyte> &bulma_data  = type.GenerateData();
24500     const std::vector<GLubyte> &trunks_data = type.GenerateData();
24501     const std::vector<GLubyte> &bra_data    = type.GenerateData();
24502     const std::vector<GLubyte> &gohan_data  = type.GenerateData();
24503     const std::vector<GLubyte> &goten_data  = type.GenerateData();
24504 
24505     Utils::s_rand                               = gen_start;
24506     const std::vector<GLubyte> &chichi_data_pck = type.GenerateDataPacked();
24507     const std::vector<GLubyte> &bulma_data_pck  = type.GenerateDataPacked();
24508     const std::vector<GLubyte> &trunks_data_pck = type.GenerateDataPacked();
24509     const std::vector<GLubyte> &bra_data_pck    = type.GenerateDataPacked();
24510     const std::vector<GLubyte> &gohan_data_pck  = type.GenerateDataPacked();
24511     const std::vector<GLubyte> &goten_data_pck  = type.GenerateDataPacked();
24512 
24513     const GLuint type_size        = static_cast<GLuint>(chichi_data.size());
24514     const GLuint padded_type_size = type.GetBaseAlignment(false) * type.m_n_columns;
24515     const GLuint type_size_pck    = static_cast<GLuint>(chichi_data_pck.size());
24516 
24517     /* Uniform data */
24518     uniform.m_initial_data.resize(6 * padded_type_size);
24519     memcpy(&uniform.m_initial_data[0] + 0, &chichi_data[0], type_size);
24520     memcpy(&uniform.m_initial_data[0] + padded_type_size, &bulma_data[0], type_size);
24521     memcpy(&uniform.m_initial_data[0] + 2 * padded_type_size, &trunks_data[0], type_size);
24522     memcpy(&uniform.m_initial_data[0] + 3 * padded_type_size, &bra_data[0], type_size);
24523     memcpy(&uniform.m_initial_data[0] + 4 * padded_type_size, &gohan_data[0], type_size);
24524     memcpy(&uniform.m_initial_data[0] + 5 * padded_type_size, &goten_data[0], type_size);
24525 
24526     /* XFB data */
24527     xfb_1.m_initial_data.resize(3 * type_size_pck);
24528     xfb_1.m_expected_data.resize(3 * type_size_pck);
24529     xfb_3.m_initial_data.resize(3 * type_size_pck);
24530     xfb_3.m_expected_data.resize(3 * type_size_pck);
24531 
24532     for (GLuint i = 0; i < 3 * type_size_pck; ++i)
24533     {
24534         xfb_1.m_initial_data[i]  = (glw::GLubyte)i;
24535         xfb_1.m_expected_data[i] = (glw::GLubyte)i;
24536         xfb_3.m_initial_data[i]  = (glw::GLubyte)i;
24537         xfb_3.m_expected_data[i] = (glw::GLubyte)i;
24538     }
24539 
24540     memcpy(&xfb_3.m_expected_data[0] + 2 * type_size_pck, &chichi_data_pck[0], type_size_pck);
24541     memcpy(&xfb_1.m_expected_data[0] + 0 * type_size_pck, &bulma_data_pck[0], type_size_pck);
24542     memcpy(&xfb_1.m_expected_data[0] + 1 * type_size_pck, &trunks_data_pck[0], type_size_pck);
24543     memcpy(&xfb_1.m_expected_data[0] + 2 * type_size_pck, &bra_data_pck[0], type_size_pck);
24544     memcpy(&xfb_3.m_expected_data[0] + 0 * type_size_pck, &gohan_data_pck[0], type_size_pck);
24545     memcpy(&xfb_3.m_expected_data[0] + 1 * type_size_pck, &goten_data_pck[0], type_size_pck);
24546 }
24547 
24548 /** Source for given test case and stage
24549  *
24550  * @param test_case_index Index of test case
24551  * @param stage           Shader stage
24552  *
24553  * @return Shader source
24554  **/
24555 std::string XFBGlobalBufferTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
24556 {
24557     static const GLchar *fs =
24558         "#version 430 core\n"
24559         "#extension GL_ARB_enhanced_layouts : require\n"
24560         "\n"
24561         "flat in TYPE chichi;\n"
24562         "flat in TYPE bulma;\n"
24563         "in Vegeta {\n"
24564         "    flat TYPE trunk;\n"
24565         "    flat TYPE bra;\n"
24566         "} vegeta;\n"
24567         "in Goku {\n"
24568         "    flat TYPE gohan;\n"
24569         "    flat TYPE goten;\n"
24570         "} goku;\n"
24571         "\n"
24572         "out vec4 fs_out;\n"
24573         "\n"
24574         "void main()\n"
24575         "{\n"
24576         "    fs_out = vec4(1);\n"
24577         "    if (TYPE(1) != chichi + bulma + vegeta.trunk + vegeta.bra + goku.gohan + goku.goten)\n"
24578         "    {\n"
24579         "        fs_out = vec4(0);\n"
24580         "    }\n"
24581         "}\n"
24582         "\n";
24583 
24584     static const GLchar *gs = "#version 430 core\n"
24585                               "#extension GL_ARB_enhanced_layouts : require\n"
24586                               "\n"
24587                               "layout(points)                   in;\n"
24588                               "layout(points, max_vertices = 1) out;\n"
24589                               "\n"
24590                               "INTERFACE"
24591                               "\n"
24592                               "void main()\n"
24593                               "{\n"
24594                               "ASSIGNMENTS"
24595                               "    EmitVertex();\n"
24596                               "}\n"
24597                               "\n";
24598 
24599     static const GLchar *tcs = "#version 430 core\n"
24600                                "#extension GL_ARB_enhanced_layouts : require\n"
24601                                "\n"
24602                                "layout(vertices = 1) out;\n"
24603                                "\n"
24604                                "\n"
24605                                "void main()\n"
24606                                "{\n"
24607                                "    gl_TessLevelOuter[0] = 1.0;\n"
24608                                "    gl_TessLevelOuter[1] = 1.0;\n"
24609                                "    gl_TessLevelOuter[2] = 1.0;\n"
24610                                "    gl_TessLevelOuter[3] = 1.0;\n"
24611                                "    gl_TessLevelInner[0] = 1.0;\n"
24612                                "    gl_TessLevelInner[1] = 1.0;\n"
24613                                "}\n"
24614                                "\n";
24615 
24616     static const GLchar *tes = "#version 430 core\n"
24617                                "#extension GL_ARB_enhanced_layouts : require\n"
24618                                "\n"
24619                                "layout(isolines, point_mode) in;\n"
24620                                "\n"
24621                                "INTERFACE"
24622                                "\n"
24623                                "void main()\n"
24624                                "{\n"
24625                                "ASSIGNMENTS"
24626                                "}\n"
24627                                "\n";
24628 
24629     static const GLchar *vs = "#version 430 core\n"
24630                               "#extension GL_ARB_enhanced_layouts : require\n"
24631                               "\n"
24632                               "void main()\n"
24633                               "{\n"
24634                               "}\n"
24635                               "\n";
24636 
24637     static const GLchar *vs_tested = "#version 430 core\n"
24638                                      "#extension GL_ARB_enhanced_layouts : require\n"
24639                                      "\n"
24640                                      "INTERFACE"
24641                                      "\n"
24642                                      "void main()\n"
24643                                      "{\n"
24644                                      "ASSIGNMENTS"
24645                                      "}\n"
24646                                      "\n";
24647 
24648     std::string source;
24649     const _testCase &test_case = m_test_cases[test_case_index];
24650     const GLchar *type_name    = test_case.m_type.GetGLSLTypeName();
24651 
24652     if (test_case.m_stage == stage)
24653     {
24654         std::string assignments = "    chichi       = uni_chichi;\n"
24655                                   "    bulma        = uni_bulma;\n"
24656                                   "    vegeta.trunk = uni_trunk;\n"
24657                                   "    vegeta.bra   = uni_bra;\n"
24658                                   "    goku.gohan   = uni_gohan;\n"
24659                                   "    goku.goten   = uni_goten;\n";
24660 
24661         std::string interface = "layout (xfb_buffer = 3) out;\n"
24662                                 "\n"
24663                                 "const uint type_size = SIZE;\n"
24664                                 "\n"
24665                                 "layout (                xfb_offset = 2 * type_size) flat out TYPE chichi;\n"
24666                                 "layout (xfb_buffer = 1, xfb_offset = 0)             flat out TYPE bulma;\n"
24667                                 "layout (xfb_buffer = 1, xfb_offset = 1 * type_size) out Vegeta {\n"
24668                                 "    flat TYPE trunk;\n"
24669                                 "    flat TYPE bra;\n"
24670                                 "} vegeta;\n"
24671                                 "layout (                xfb_offset = 0)             out Goku {\n"
24672                                 "    flat TYPE gohan;\n"
24673                                 "    flat TYPE goten;\n"
24674                                 "} goku;\n"
24675                                 "\n"
24676                                 // Uniform block must be declared with std140, otherwise each block member is not packed
24677                                 "layout(binding = 0, std140) uniform block {\n"
24678                                 "    TYPE uni_chichi;\n"
24679                                 "    TYPE uni_bulma;\n"
24680                                 "    TYPE uni_trunk;\n"
24681                                 "    TYPE uni_bra;\n"
24682                                 "    TYPE uni_gohan;\n"
24683                                 "    TYPE uni_goten;\n"
24684                                 "};\n";
24685 
24686         /* Prepare interface string */
24687         {
24688             GLchar buffer[16];
24689             size_t position        = 0;
24690             const GLuint type_size = test_case.m_type.GetSize();
24691 
24692             sprintf(buffer, "%d", type_size);
24693 
24694             Utils::replaceToken("SIZE", position, buffer, interface);
24695             Utils::replaceAllTokens("TYPE", type_name, interface);
24696         }
24697 
24698         switch (stage)
24699         {
24700         case Utils::Shader::GEOMETRY:
24701             source = gs;
24702             break;
24703         case Utils::Shader::TESS_EVAL:
24704             source = tes;
24705             break;
24706         case Utils::Shader::VERTEX:
24707             source = vs_tested;
24708             break;
24709         default:
24710             TCU_FAIL("Invalid enum");
24711         }
24712 
24713         /* Replace tokens */
24714         {
24715             size_t position = 0;
24716 
24717             Utils::replaceToken("INTERFACE", position, interface.c_str(), source);
24718             Utils::replaceToken("ASSIGNMENTS", position, assignments.c_str(), source);
24719         }
24720     }
24721     else
24722     {
24723         switch (test_case.m_stage)
24724         {
24725         case Utils::Shader::GEOMETRY:
24726             switch (stage)
24727             {
24728             case Utils::Shader::FRAGMENT:
24729                 source = fs;
24730                 Utils::replaceAllTokens("TYPE", type_name, source);
24731                 break;
24732             case Utils::Shader::VERTEX:
24733                 source = vs;
24734                 break;
24735             default:
24736                 source = "";
24737             }
24738             break;
24739         case Utils::Shader::TESS_EVAL:
24740             switch (stage)
24741             {
24742             case Utils::Shader::FRAGMENT:
24743                 source = fs;
24744                 Utils::replaceAllTokens("TYPE", type_name, source);
24745                 break;
24746             case Utils::Shader::TESS_CTRL:
24747                 source = tcs;
24748                 break;
24749             case Utils::Shader::VERTEX:
24750                 source = vs;
24751                 break;
24752             default:
24753                 source = "";
24754             }
24755             break;
24756         case Utils::Shader::VERTEX:
24757             switch (stage)
24758             {
24759             case Utils::Shader::FRAGMENT:
24760                 source = fs;
24761                 Utils::replaceAllTokens("TYPE", type_name, source);
24762                 break;
24763             default:
24764                 source = "";
24765             }
24766             break;
24767         default:
24768             TCU_FAIL("Invalid enum");
24769         }
24770     }
24771 
24772     return source;
24773 }
24774 
24775 /** Get name of test case
24776  *
24777  * @param test_case_index Index of test case
24778  *
24779  * @return Name of case
24780  **/
24781 std::string XFBGlobalBufferTest::getTestCaseName(GLuint test_case_index)
24782 {
24783     std::string name;
24784     const _testCase &test_case = m_test_cases[test_case_index];
24785 
24786     name = "Tested stage: ";
24787     name.append(Utils::Shader::GetStageName(test_case.m_stage));
24788     name.append(". Tested type: ");
24789     name.append(test_case.m_type.GetGLSLTypeName());
24790 
24791     return name;
24792 }
24793 
24794 /** Get number of cases
24795  *
24796  * @return Number of test cases
24797  **/
24798 GLuint XFBGlobalBufferTest::getTestCaseNumber()
24799 {
24800     return static_cast<GLuint>(m_test_cases.size());
24801 }
24802 
24803 /** Prepare set of test cases
24804  *
24805  **/
24806 void XFBGlobalBufferTest::testInit()
24807 {
24808     GLuint n_types = getTypesNumber();
24809 
24810     for (GLuint i = 0; i < n_types; ++i)
24811     {
24812         const Utils::Type &type = getType(i);
24813         /*
24814          When the tfx varying is the following type, the number of output exceeds the gl_MaxVaryingComponents, which will
24815          cause a link time error.
24816          */
24817         if (strcmp(type.GetGLSLTypeName(), "dmat3") == 0 || strcmp(type.GetGLSLTypeName(), "dmat4") == 0 ||
24818             strcmp(type.GetGLSLTypeName(), "dmat3x4") == 0 || strcmp(type.GetGLSLTypeName(), "dmat4x3") == 0)
24819         {
24820             continue;
24821         }
24822         const _testCase test_cases[] = {
24823             {Utils::Shader::VERTEX, type}, {Utils::Shader::GEOMETRY, type}, {Utils::Shader::TESS_EVAL, type}};
24824 
24825         m_test_cases.push_back(test_cases[0]);
24826         m_test_cases.push_back(test_cases[1]);
24827         m_test_cases.push_back(test_cases[2]);
24828     }
24829 }
24830 
24831 /** Constructor
24832  *
24833  * @param context Test context
24834  **/
24835 XFBStrideTest::XFBStrideTest(deqp::Context &context)
24836     : BufferTestBase(context, "xfb_stride", "Test verifies that correct stride is used for all types")
24837 {
24838     /* Nothing to be done here */
24839 }
24840 
24841 /** Execute drawArrays for single vertex
24842  *
24843  * @param test_case_index
24844  *
24845  * @return true
24846  **/
24847 bool XFBStrideTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
24848 {
24849     const Functions &gl       = m_context.getRenderContext().getFunctions();
24850     GLenum primitive_type     = GL_PATCHES;
24851     const testCase &test_case = m_test_cases[test_case_index];
24852 
24853     if (Utils::Shader::VERTEX == test_case.m_stage)
24854     {
24855         primitive_type = GL_POINTS;
24856     }
24857 
24858     gl.disable(GL_RASTERIZER_DISCARD);
24859     GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
24860 
24861     gl.beginTransformFeedback(GL_POINTS);
24862     GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
24863 
24864     gl.drawArrays(primitive_type, 0 /* first */, 2 /* count */);
24865     GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
24866 
24867     gl.endTransformFeedback();
24868     GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
24869 
24870     return true;
24871 }
24872 
24873 /** Get descriptors of buffers necessary for test
24874  *
24875  * @param test_case_index Index of test case
24876  * @param out_descriptors Descriptors of buffers used by test
24877  **/
24878 void XFBStrideTest::getBufferDescriptors(GLuint test_case_index, bufferDescriptor::Vector &out_descriptors)
24879 {
24880     const testCase &test_case = m_test_cases[test_case_index];
24881     const Utils::Type &type   = test_case.m_type;
24882 
24883     /* Test needs single uniform and xfb */
24884     out_descriptors.resize(2);
24885 
24886     /* Get references */
24887     bufferDescriptor &uniform = out_descriptors[0];
24888     bufferDescriptor &xfb     = out_descriptors[1];
24889 
24890     /* Index */
24891     uniform.m_index = 0;
24892     xfb.m_index     = 0;
24893 
24894     /* Target */
24895     uniform.m_target = Utils::Buffer::Uniform;
24896     xfb.m_target     = Utils::Buffer::Transform_feedback;
24897 
24898     /* Data */
24899     const GLuint rand_start                  = Utils::s_rand;
24900     const std::vector<GLubyte> &uniform_data = type.GenerateData();
24901 
24902     Utils::s_rand                        = rand_start;
24903     const std::vector<GLubyte> &xfb_data = type.GenerateDataPacked();
24904 
24905     const GLuint uni_type_size = static_cast<GLuint>(uniform_data.size());
24906     const GLuint xfb_type_size = static_cast<GLuint>(xfb_data.size());
24907     /*
24908      Note: If xfb varying output from vertex shader, the variable "goku" will only output once to transform feedback buffer,
24909      if xfb varying output from TES or GS, because the input primitive type in TES is defined as "layout(isolines, point_mode) in;",
24910      the primitive type is line which make the variable "goku" will output twice to transform feedback buffer, so for vertex shader
24911      only one valid data should be initialized in xfb.m_expected_data
24912      */
24913     const GLuint xfb_data_size = (test_case.m_stage == Utils::Shader::VERTEX) ? xfb_type_size : xfb_type_size * 2;
24914     /* Uniform data */
24915     uniform.m_initial_data.resize(uni_type_size);
24916     memcpy(&uniform.m_initial_data[0] + 0 * uni_type_size, &uniform_data[0], uni_type_size);
24917 
24918     /* XFB data */
24919     xfb.m_initial_data.resize(xfb_data_size);
24920     xfb.m_expected_data.resize(xfb_data_size);
24921 
24922     for (GLuint i = 0; i < xfb_data_size; ++i)
24923     {
24924         xfb.m_initial_data[i]  = (glw::GLubyte)i;
24925         xfb.m_expected_data[i] = (glw::GLubyte)i;
24926     }
24927 
24928     if (test_case.m_stage == Utils::Shader::VERTEX)
24929     {
24930         memcpy(&xfb.m_expected_data[0] + 0 * xfb_type_size, &xfb_data[0], xfb_type_size);
24931     }
24932     else
24933     {
24934         memcpy(&xfb.m_expected_data[0] + 0 * xfb_type_size, &xfb_data[0], xfb_type_size);
24935         memcpy(&xfb.m_expected_data[0] + 1 * xfb_type_size, &xfb_data[0], xfb_type_size);
24936     }
24937 }
24938 
24939 /** Get body of main function for given shader stage
24940  *
24941  * @param test_case_index  Index of test case
24942  * @param stage            Shader stage
24943  * @param out_assignments  Set to empty
24944  * @param out_calculations Set to empty
24945  **/
24946 void XFBStrideTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage, std::string &out_assignments,
24947                                   std::string &out_calculations)
24948 {
24949     const testCase &test_case = m_test_cases[test_case_index];
24950 
24951     out_calculations = "";
24952 
24953     static const GLchar *vs_tes_gs = "    goku = uni_goku;\n";
24954     static const GLchar *fs        = "    fs_out = vec4(1, 0.25, 0.5, 0.75);\n"
24955                                      "    if (TYPE(0) == goku)\n"
24956                                      "    {\n"
24957                                      "         fs_out = vec4(1, 0.75, 0.5, 0.5);\n"
24958                                      "    }\n";
24959 
24960     const GLchar *assignments = "";
24961 
24962     if (test_case.m_stage == stage)
24963     {
24964         switch (stage)
24965         {
24966         case Utils::Shader::GEOMETRY:
24967             assignments = vs_tes_gs;
24968             break;
24969         case Utils::Shader::TESS_EVAL:
24970             assignments = vs_tes_gs;
24971             break;
24972         case Utils::Shader::VERTEX:
24973             assignments = vs_tes_gs;
24974             break;
24975         default:
24976             TCU_FAIL("Invalid enum");
24977         }
24978     }
24979     else
24980     {
24981         switch (stage)
24982         {
24983         case Utils::Shader::FRAGMENT:
24984             assignments = fs;
24985             break;
24986         case Utils::Shader::GEOMETRY:
24987         case Utils::Shader::TESS_CTRL:
24988         case Utils::Shader::TESS_EVAL:
24989         case Utils::Shader::VERTEX:
24990             break;
24991         default:
24992             TCU_FAIL("Invalid enum");
24993         }
24994     }
24995 
24996     out_assignments = assignments;
24997 
24998     if (Utils::Shader::FRAGMENT == stage)
24999     {
25000         Utils::replaceAllTokens("TYPE", test_case.m_type.GetGLSLTypeName(), out_assignments);
25001     }
25002 }
25003 
25004 /** Get interface of shader
25005  *
25006  * @param test_case_index  Index of test case
25007  * @param stage            Shader stage
25008  * @param out_interface    Set to ""
25009  **/
25010 void XFBStrideTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage, std::string &out_interface)
25011 {
25012     static const GLchar *vs_tes_gs = "layout (xfb_offset = 0) FLAT out TYPE goku;\n"
25013                                      "\n"
25014                                      "layout(std140, binding = 0) uniform Goku {\n"
25015                                      "    TYPE uni_goku;\n"
25016                                      "};\n";
25017     static const GLchar *fs        = "FLAT in TYPE goku;\n"
25018                                      "\n"
25019                                      "out vec4 fs_out;\n";
25020 
25021     const testCase &test_case = m_test_cases[test_case_index];
25022     const GLchar *interface   = "";
25023     const GLchar *flat        = "";
25024 
25025     if (test_case.m_stage == stage)
25026     {
25027         switch (stage)
25028         {
25029         case Utils::Shader::GEOMETRY:
25030             interface = vs_tes_gs;
25031             break;
25032         case Utils::Shader::TESS_EVAL:
25033             interface = vs_tes_gs;
25034             break;
25035         case Utils::Shader::VERTEX:
25036             interface = vs_tes_gs;
25037             break;
25038         default:
25039             TCU_FAIL("Invalid enum");
25040         }
25041     }
25042     else
25043     {
25044         switch (stage)
25045         {
25046         case Utils::Shader::FRAGMENT:
25047             interface = fs;
25048             break;
25049         case Utils::Shader::GEOMETRY:
25050         case Utils::Shader::TESS_CTRL:
25051         case Utils::Shader::TESS_EVAL:
25052         case Utils::Shader::VERTEX:
25053             break;
25054         default:
25055             TCU_FAIL("Invalid enum");
25056         }
25057     }
25058 
25059     out_interface = interface;
25060 
25061     if (Utils::Type::Float != test_case.m_type.m_basic_type)
25062     {
25063         flat = "flat";
25064     }
25065 
25066     Utils::replaceAllTokens("FLAT", flat, out_interface);
25067     Utils::replaceAllTokens("TYPE", test_case.m_type.GetGLSLTypeName(), out_interface);
25068 }
25069 
25070 /** Get source code of shader
25071  *
25072  * @param test_case_index Index of test case
25073  * @param stage           Shader stage
25074  *
25075  * @return Source
25076  **/
25077 std::string XFBStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
25078 {
25079     std::string source;
25080     const testCase &test_case = m_test_cases[test_case_index];
25081 
25082     switch (test_case.m_stage)
25083     {
25084     case Utils::Shader::VERTEX:
25085         switch (stage)
25086         {
25087         case Utils::Shader::FRAGMENT:
25088         case Utils::Shader::VERTEX:
25089             source = BufferTestBase::getShaderSource(test_case_index, stage);
25090             break;
25091         default:
25092             break;
25093         }
25094         break;
25095 
25096     case Utils::Shader::TESS_EVAL:
25097         switch (stage)
25098         {
25099         case Utils::Shader::FRAGMENT:
25100         case Utils::Shader::TESS_CTRL:
25101         case Utils::Shader::TESS_EVAL:
25102         case Utils::Shader::VERTEX:
25103             source = BufferTestBase::getShaderSource(test_case_index, stage);
25104             break;
25105         default:
25106             break;
25107         }
25108         break;
25109 
25110     case Utils::Shader::GEOMETRY:
25111         source = BufferTestBase::getShaderSource(test_case_index, stage);
25112         break;
25113 
25114     default:
25115         TCU_FAIL("Invalid enum");
25116     }
25117 
25118     /* */
25119     return source;
25120 }
25121 
25122 /** Get name of test case
25123  *
25124  * @param test_case_index Index of test case
25125  *
25126  * @return Name of tested stage
25127  **/
25128 std::string XFBStrideTest::getTestCaseName(glw::GLuint test_case_index)
25129 {
25130     std::stringstream stream;
25131     const testCase &test_case = m_test_cases[test_case_index];
25132 
25133     stream << "Type: " << test_case.m_type.GetGLSLTypeName()
25134            << ", stage: " << Utils::Shader::GetStageName(test_case.m_stage);
25135 
25136     return stream.str();
25137 }
25138 
25139 /** Returns number of test cases
25140  *
25141  * @return TEST_MAX
25142  **/
25143 glw::GLuint XFBStrideTest::getTestCaseNumber()
25144 {
25145     return static_cast<GLuint>(m_test_cases.size());
25146 }
25147 
25148 /** Prepare all test cases
25149  *
25150  **/
25151 void XFBStrideTest::testInit()
25152 {
25153     const GLuint n_types = getTypesNumber();
25154 
25155     for (GLuint i = 0; i < n_types; ++i)
25156     {
25157         const Utils::Type &type = getType(i);
25158 
25159         for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
25160         {
25161             if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::FRAGMENT == stage) ||
25162                 (Utils::Shader::TESS_CTRL == stage))
25163             {
25164                 continue;
25165             }
25166 
25167             testCase test_case = {(Utils::Shader::STAGES)stage, type};
25168 
25169             m_test_cases.push_back(test_case);
25170         }
25171     }
25172 }
25173 
25174 /** Constructor
25175  *
25176  * @param context Test framework context
25177  **/
25178 XFBBlockMemberBufferTest::XFBBlockMemberBufferTest(deqp::Context &context)
25179     : NegativeTestBase(
25180           context, "xfb_block_member_buffer",
25181           "Test verifies that compiler reports error when block member has different xfb_buffer qualifier than buffer")
25182 {
25183 }
25184 
25185 /** Source for given test case and stage
25186  *
25187  * @param test_case_index Index of test case
25188  * @param stage           Shader stage
25189  *
25190  * @return Shader source
25191  **/
25192 std::string XFBBlockMemberBufferTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
25193 {
25194     static const GLchar *var_definition = "layout (xfb_offset = 0) out Goku {\n"
25195                                           "                            vec4 gohan;\n"
25196 #if DEBUG_NEG_REMOVE_ERROR
25197                                           "    /* layout (xfb_buffer = 1) */ vec4 goten;\n"
25198 #else
25199                                           "    layout (xfb_buffer = 1) vec4 goten;\n"
25200 #endif /* DEBUG_NEG_REMOVE_ERROR */
25201                                           "} goku;\n";
25202     static const GLchar *var_use    = "    goku.gohan = result / 2;\n"
25203                                       "    goku.goten = result / 4;\n";
25204     static const GLchar *fs         = "#version 430 core\n"
25205                                       "#extension GL_ARB_enhanced_layouts : require\n"
25206                                       "\n"
25207                                       "in  vec4 any_fs;\n"
25208                                       "out vec4 fs_out;\n"
25209                                       "\n"
25210                                       "void main()\n"
25211                                       "{\n"
25212                                       "    fs_out = any_fs;\n"
25213                                       "}\n"
25214                                       "\n";
25215     static const GLchar *gs_tested  = "#version 430 core\n"
25216                                       "#extension GL_ARB_enhanced_layouts : require\n"
25217                                       "\n"
25218                                       "layout(points)                           in;\n"
25219                                       "layout(triangle_strip, max_vertices = 4) out;\n"
25220                                       "\n"
25221                                       "VAR_DEFINITION"
25222                                       "\n"
25223                                       "in  vec4 vs_any[];\n"
25224                                       "out vec4 any_fs;\n"
25225                                       "\n"
25226                                       "void main()\n"
25227                                       "{\n"
25228                                       "    vec4 result = vs_any[0];\n"
25229                                       "\n"
25230                                       "VARIABLE_USE"
25231                                       "\n"
25232                                       "    any_fs = result;\n"
25233                                       "    gl_Position  = vec4(-1, -1, 0, 1);\n"
25234                                       "    EmitVertex();\n"
25235                                       "    any_fs = result;\n"
25236                                       "    gl_Position  = vec4(-1, 1, 0, 1);\n"
25237                                       "    EmitVertex();\n"
25238                                       "    any_fs = result;\n"
25239                                       "    gl_Position  = vec4(1, -1, 0, 1);\n"
25240                                       "    EmitVertex();\n"
25241                                       "    any_fs = result;\n"
25242                                       "    gl_Position  = vec4(1, 1, 0, 1);\n"
25243                                       "    EmitVertex();\n"
25244                                       "}\n"
25245                                       "\n";
25246     static const GLchar *tcs        = "#version 430 core\n"
25247                                       "#extension GL_ARB_enhanced_layouts : require\n"
25248                                       "\n"
25249                                       "layout(vertices = 1) out;\n"
25250                                       "\n"
25251                                       "in  vec4 vs_any[];\n"
25252                                       "out vec4 tcs_tes[];\n"
25253                                       "\n"
25254                                       "void main()\n"
25255                                       "{\n"
25256                                       "\n"
25257                                       "    tcs_tes[gl_InvocationID] = vs_any[gl_InvocationID];\n"
25258                                       "\n"
25259                                       "    gl_TessLevelOuter[0] = 1.0;\n"
25260                                       "    gl_TessLevelOuter[1] = 1.0;\n"
25261                                       "    gl_TessLevelOuter[2] = 1.0;\n"
25262                                       "    gl_TessLevelOuter[3] = 1.0;\n"
25263                                       "    gl_TessLevelInner[0] = 1.0;\n"
25264                                       "    gl_TessLevelInner[1] = 1.0;\n"
25265                                       "}\n"
25266                                       "\n";
25267     static const GLchar *tes_tested = "#version 430 core\n"
25268                                       "#extension GL_ARB_enhanced_layouts : require\n"
25269                                       "\n"
25270                                       "layout(isolines, point_mode) in;\n"
25271                                       "\n"
25272                                       "VAR_DEFINITION"
25273                                       "\n"
25274                                       "in  vec4 tcs_tes[];\n"
25275                                       "out vec4 any_fs;\n"
25276                                       "\n"
25277                                       "void main()\n"
25278                                       "{\n"
25279                                       "    vec4 result = tcs_tes[0];\n"
25280                                       "\n"
25281                                       "VARIABLE_USE"
25282                                       "\n"
25283                                       "    any_fs += result;\n"
25284                                       "}\n"
25285                                       "\n";
25286     static const GLchar *vs         = "#version 430 core\n"
25287                                       "#extension GL_ARB_enhanced_layouts : require\n"
25288                                       "\n"
25289                                       "in  vec4 in_vs;\n"
25290                                       "out vec4 vs_any;\n"
25291                                       "\n"
25292                                       "void main()\n"
25293                                       "{\n"
25294                                       "    vs_any = in_vs;\n"
25295                                       "}\n"
25296                                       "\n";
25297     static const GLchar *vs_tested  = "#version 430 core\n"
25298                                       "#extension GL_ARB_enhanced_layouts : require\n"
25299                                       "\n"
25300                                       "VAR_DEFINITION"
25301                                       "\n"
25302                                       "in  vec4 in_vs;\n"
25303                                       "out vec4 any_fs;\n"
25304                                       "\n"
25305                                       "void main()\n"
25306                                       "{\n"
25307                                       "    vec4 result = in_vs;\n"
25308                                       "\n"
25309                                       "VARIABLE_USE"
25310                                       "\n"
25311                                       "    any_fs = result;\n"
25312                                       "}\n"
25313                                       "\n";
25314 
25315     std::string source;
25316     testCase &test_case = m_test_cases[test_case_index];
25317 
25318     if (test_case.m_stage == stage)
25319     {
25320         size_t position = 0;
25321 
25322         switch (stage)
25323         {
25324         case Utils::Shader::GEOMETRY:
25325             source = gs_tested;
25326             break;
25327         case Utils::Shader::TESS_EVAL:
25328             source = tes_tested;
25329             break;
25330         case Utils::Shader::VERTEX:
25331             source = vs_tested;
25332             break;
25333         default:
25334             TCU_FAIL("Invalid enum");
25335         }
25336 
25337         Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
25338         position = 0;
25339         Utils::replaceToken("VARIABLE_USE", position, var_use, source);
25340     }
25341     else
25342     {
25343         switch (test_case.m_stage)
25344         {
25345         case Utils::Shader::GEOMETRY:
25346             switch (stage)
25347             {
25348             case Utils::Shader::FRAGMENT:
25349                 source = fs;
25350                 break;
25351             case Utils::Shader::VERTEX:
25352                 source = vs;
25353                 break;
25354             default:
25355                 source = "";
25356             }
25357             break;
25358         case Utils::Shader::TESS_EVAL:
25359             switch (stage)
25360             {
25361             case Utils::Shader::FRAGMENT:
25362                 source = fs;
25363                 break;
25364             case Utils::Shader::TESS_CTRL:
25365                 source = tcs;
25366                 break;
25367             case Utils::Shader::VERTEX:
25368                 source = vs;
25369                 break;
25370             default:
25371                 source = "";
25372             }
25373             break;
25374         case Utils::Shader::VERTEX:
25375             switch (stage)
25376             {
25377             case Utils::Shader::FRAGMENT:
25378                 source = fs;
25379                 break;
25380             default:
25381                 source = "";
25382             }
25383             break;
25384         default:
25385             TCU_FAIL("Invalid enum");
25386         }
25387     }
25388 
25389     return source;
25390 }
25391 
25392 /** Get description of test case
25393  *
25394  * @param test_case_index Index of test case
25395  *
25396  * @return Test case description
25397  **/
25398 std::string XFBBlockMemberBufferTest::getTestCaseName(GLuint test_case_index)
25399 {
25400     std::stringstream stream;
25401     testCase &test_case = m_test_cases[test_case_index];
25402 
25403     stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage);
25404 
25405     return stream.str();
25406 }
25407 
25408 /** Get number of test cases
25409  *
25410  * @return Number of test cases
25411  **/
25412 GLuint XFBBlockMemberBufferTest::getTestCaseNumber()
25413 {
25414     return static_cast<GLuint>(m_test_cases.size());
25415 }
25416 
25417 /** Selects if "compute" stage is relevant for test
25418  *
25419  * @param ignored
25420  *
25421  * @return false
25422  **/
25423 bool XFBBlockMemberBufferTest::isComputeRelevant(GLuint /* test_case_index */)
25424 {
25425     return false;
25426 }
25427 
25428 /** Prepare all test cases
25429  *
25430  **/
25431 void XFBBlockMemberBufferTest::testInit()
25432 {
25433     for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
25434     {
25435         if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
25436             (Utils::Shader::FRAGMENT == stage))
25437         {
25438             continue;
25439         }
25440 
25441         testCase test_case = {(Utils::Shader::STAGES)stage};
25442 
25443         m_test_cases.push_back(test_case);
25444     }
25445 }
25446 
25447 /** Constructor
25448  *
25449  * @param context Test framework context
25450  **/
25451 XFBOutputOverlappingTest::XFBOutputOverlappingTest(deqp::Context &context)
25452     : NegativeTestBase(context, "xfb_output_overlapping",
25453                        "Test verifies that compiler reports error when two xfb qualified outputs overlap")
25454 {
25455 }
25456 
25457 /** Source for given test case and stage
25458  *
25459  * @param test_case_index Index of test case
25460  * @param stage           Shader stage
25461  *
25462  * @return Shader source
25463  **/
25464 std::string XFBOutputOverlappingTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
25465 {
25466     static const GLchar *var_definition = "layout (xfb_offset = 0) out TYPE gohan;\n"
25467 #if DEBUG_NEG_REMOVE_ERROR
25468                                           "/* layout (xfb_offset = OFFSET) */ out TYPE goten;\n";
25469 #else
25470                                           "layout (xfb_offset = OFFSET) out TYPE goten;\n";
25471 #endif /* DEBUG_NEG_REMOVE_ERROR */
25472     static const GLchar *var_use    = "    gohan = TYPE(0);\n"
25473                                       "    goten = TYPE(1);\n"
25474                                       "    if (vec4(0) == result)\n"
25475                                       "    {\n"
25476                                       "        gohan = TYPE(1);\n"
25477                                       "        goten = TYPE(0);\n"
25478                                       "    }\n";
25479     static const GLchar *fs         = "#version 430 core\n"
25480                                       "#extension GL_ARB_enhanced_layouts : require\n"
25481                                       "\n"
25482                                       "in  vec4 any_fs;\n"
25483                                       "out vec4 fs_out;\n"
25484                                       "\n"
25485                                       "void main()\n"
25486                                       "{\n"
25487                                       "    fs_out = any_fs;\n"
25488                                       "}\n"
25489                                       "\n";
25490     static const GLchar *gs_tested  = "#version 430 core\n"
25491                                       "#extension GL_ARB_enhanced_layouts : require\n"
25492                                       "\n"
25493                                       "layout(points)                           in;\n"
25494                                       "layout(triangle_strip, max_vertices = 4) out;\n"
25495                                       "\n"
25496                                       "VAR_DEFINITION"
25497                                       "\n"
25498                                       "in  vec4 vs_any[];\n"
25499                                       "out vec4 any_fs;\n"
25500                                       "\n"
25501                                       "void main()\n"
25502                                       "{\n"
25503                                       "    vec4 result = vs_any[0];\n"
25504                                       "\n"
25505                                       "VARIABLE_USE"
25506                                       "\n"
25507                                       "    any_fs = result;\n"
25508                                       "    gl_Position  = vec4(-1, -1, 0, 1);\n"
25509                                       "    EmitVertex();\n"
25510                                       "    any_fs = result;\n"
25511                                       "    gl_Position  = vec4(-1, 1, 0, 1);\n"
25512                                       "    EmitVertex();\n"
25513                                       "    any_fs = result;\n"
25514                                       "    gl_Position  = vec4(1, -1, 0, 1);\n"
25515                                       "    EmitVertex();\n"
25516                                       "    any_fs = result;\n"
25517                                       "    gl_Position  = vec4(1, 1, 0, 1);\n"
25518                                       "    EmitVertex();\n"
25519                                       "}\n"
25520                                       "\n";
25521     static const GLchar *tcs        = "#version 430 core\n"
25522                                       "#extension GL_ARB_enhanced_layouts : require\n"
25523                                       "\n"
25524                                       "layout(vertices = 1) out;\n"
25525                                       "\n"
25526                                       "in  vec4 vs_any[];\n"
25527                                       "out vec4 tcs_tes[];\n"
25528                                       "\n"
25529                                       "void main()\n"
25530                                       "{\n"
25531                                       "\n"
25532                                       "    tcs_tes[gl_InvocationID] = vs_any[gl_InvocationID];\n"
25533                                       "\n"
25534                                       "    gl_TessLevelOuter[0] = 1.0;\n"
25535                                       "    gl_TessLevelOuter[1] = 1.0;\n"
25536                                       "    gl_TessLevelOuter[2] = 1.0;\n"
25537                                       "    gl_TessLevelOuter[3] = 1.0;\n"
25538                                       "    gl_TessLevelInner[0] = 1.0;\n"
25539                                       "    gl_TessLevelInner[1] = 1.0;\n"
25540                                       "}\n"
25541                                       "\n";
25542     static const GLchar *tes_tested = "#version 430 core\n"
25543                                       "#extension GL_ARB_enhanced_layouts : require\n"
25544                                       "\n"
25545                                       "layout(isolines, point_mode) in;\n"
25546                                       "\n"
25547                                       "VAR_DEFINITION"
25548                                       "\n"
25549                                       "in  vec4 tcs_tes[];\n"
25550                                       "out vec4 any_fs;\n"
25551                                       "\n"
25552                                       "void main()\n"
25553                                       "{\n"
25554                                       "    vec4 result = tcs_tes[0];\n"
25555                                       "\n"
25556                                       "VARIABLE_USE"
25557                                       "\n"
25558                                       "    any_fs += result;\n"
25559                                       "}\n"
25560                                       "\n";
25561     static const GLchar *vs         = "#version 430 core\n"
25562                                       "#extension GL_ARB_enhanced_layouts : require\n"
25563                                       "\n"
25564                                       "in  vec4 in_vs;\n"
25565                                       "out vec4 vs_any;\n"
25566                                       "\n"
25567                                       "void main()\n"
25568                                       "{\n"
25569                                       "    vs_any = in_vs;\n"
25570                                       "}\n"
25571                                       "\n";
25572     static const GLchar *vs_tested  = "#version 430 core\n"
25573                                       "#extension GL_ARB_enhanced_layouts : require\n"
25574                                       "\n"
25575                                       "VAR_DEFINITION"
25576                                       "\n"
25577                                       "in  vec4 in_vs;\n"
25578                                       "out vec4 any_fs;\n"
25579                                       "\n"
25580                                       "void main()\n"
25581                                       "{\n"
25582                                       "    vec4 result = in_vs;\n"
25583                                       "\n"
25584                                       "VARIABLE_USE"
25585                                       "\n"
25586                                       "    any_fs = result;\n"
25587                                       "}\n"
25588                                       "\n";
25589 
25590     std::string source;
25591     testCase &test_case = m_test_cases[test_case_index];
25592 
25593     if (test_case.m_stage == stage)
25594     {
25595         GLchar offset[16];
25596         size_t position         = 0;
25597         const GLchar *type_name = test_case.m_type.GetGLSLTypeName();
25598 
25599         sprintf(offset, "%d", test_case.m_offset);
25600 
25601         switch (stage)
25602         {
25603         case Utils::Shader::GEOMETRY:
25604             source = gs_tested;
25605             break;
25606         case Utils::Shader::TESS_EVAL:
25607             source = tes_tested;
25608             break;
25609         case Utils::Shader::VERTEX:
25610             source = vs_tested;
25611             break;
25612         default:
25613             TCU_FAIL("Invalid enum");
25614         }
25615 
25616         Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
25617         position = 0;
25618         Utils::replaceToken("OFFSET", position, offset, source);
25619         Utils::replaceToken("VARIABLE_USE", position, var_use, source);
25620 
25621         Utils::replaceAllTokens("TYPE", type_name, source);
25622     }
25623     else
25624     {
25625         switch (test_case.m_stage)
25626         {
25627         case Utils::Shader::GEOMETRY:
25628             switch (stage)
25629             {
25630             case Utils::Shader::FRAGMENT:
25631                 source = fs;
25632                 break;
25633             case Utils::Shader::VERTEX:
25634                 source = vs;
25635                 break;
25636             default:
25637                 source = "";
25638             }
25639             break;
25640         case Utils::Shader::TESS_EVAL:
25641             switch (stage)
25642             {
25643             case Utils::Shader::FRAGMENT:
25644                 source = fs;
25645                 break;
25646             case Utils::Shader::TESS_CTRL:
25647                 source = tcs;
25648                 break;
25649             case Utils::Shader::VERTEX:
25650                 source = vs;
25651                 break;
25652             default:
25653                 source = "";
25654             }
25655             break;
25656         case Utils::Shader::VERTEX:
25657             switch (stage)
25658             {
25659             case Utils::Shader::FRAGMENT:
25660                 source = fs;
25661                 break;
25662             default:
25663                 source = "";
25664             }
25665             break;
25666         default:
25667             TCU_FAIL("Invalid enum");
25668         }
25669     }
25670 
25671     return source;
25672 }
25673 
25674 /** Get description of test case
25675  *
25676  * @param test_case_index Index of test case
25677  *
25678  * @return Test case description
25679  **/
25680 std::string XFBOutputOverlappingTest::getTestCaseName(GLuint test_case_index)
25681 {
25682     std::stringstream stream;
25683     testCase &test_case = m_test_cases[test_case_index];
25684 
25685     stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
25686            << ", type: " << test_case.m_type.GetGLSLTypeName() << ", offset: " << test_case.m_offset;
25687 
25688     return stream.str();
25689 }
25690 
25691 /** Get number of test cases
25692  *
25693  * @return Number of test cases
25694  **/
25695 GLuint XFBOutputOverlappingTest::getTestCaseNumber()
25696 {
25697     return static_cast<GLuint>(m_test_cases.size());
25698 }
25699 
25700 /** Selects if "compute" stage is relevant for test
25701  *
25702  * @param ignored
25703  *
25704  * @return false
25705  **/
25706 bool XFBOutputOverlappingTest::isComputeRelevant(GLuint /* test_case_index */)
25707 {
25708     return false;
25709 }
25710 
25711 /** Prepare all test cases
25712  *
25713  **/
25714 void XFBOutputOverlappingTest::testInit()
25715 {
25716     const GLuint n_types = getTypesNumber();
25717 
25718     for (GLuint i = 0; i < n_types; ++i)
25719     {
25720         const Utils::Type &type      = getType(i);
25721         const GLuint basic_type_size = Utils::Type::GetTypeSize(type.m_basic_type);
25722 
25723         /* Skip scalars, not applicable as:
25724          *
25725          *     The offset must be a multiple of the size of the first component of the first
25726          *     qualified variable or block member, or a compile-time error results.
25727          */
25728         if ((1 == type.m_n_columns) && (1 == type.m_n_rows))
25729         {
25730             continue;
25731         }
25732 
25733         for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
25734         {
25735             if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
25736                 (Utils::Shader::FRAGMENT == stage))
25737             {
25738                 continue;
25739             }
25740 
25741             testCase test_case = {basic_type_size /* offset */, (Utils::Shader::STAGES)stage, type};
25742 
25743             m_test_cases.push_back(test_case);
25744         }
25745     }
25746 }
25747 
25748 /** Constructor
25749  *
25750  * @param context Test framework context
25751  **/
25752 XFBInvalidOffsetAlignmentTest::XFBInvalidOffsetAlignmentTest(deqp::Context &context)
25753     : NegativeTestBase(context, "xfb_invalid_offset_alignment",
25754                        "Test verifies that compiler reports error when xfb_offset has invalid alignment")
25755 {
25756 }
25757 
25758 /** Source for given test case and stage
25759  *
25760  * @param test_case_index Index of test case
25761  * @param stage           Shader stage
25762  *
25763  * @return Shader source
25764  **/
25765 std::string XFBInvalidOffsetAlignmentTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
25766 {
25767 #if DEBUG_NEG_REMOVE_ERROR
25768     static const GLchar *var_definition = "/* layout (xfb_offset = OFFSET) */ out TYPE gohan;\n";
25769 #else
25770     static const GLchar *var_definition = "layout (xfb_offset = OFFSET) out TYPE gohan;\n";
25771 #endif /* DEBUG_NEG_REMOVE_ERROR */
25772     static const GLchar *var_use    = "    gohan = TYPE(0);\n"
25773                                       "    if (vec4(0) == result)\n"
25774                                       "    {\n"
25775                                       "        gohan = TYPE(1);\n"
25776                                       "    }\n";
25777     static const GLchar *fs         = "#version 430 core\n"
25778                                       "#extension GL_ARB_enhanced_layouts : require\n"
25779                                       "\n"
25780                                       "in  vec4 any_fs;\n"
25781                                       "out vec4 fs_out;\n"
25782                                       "\n"
25783                                       "void main()\n"
25784                                       "{\n"
25785                                       "    fs_out = any_fs;\n"
25786                                       "}\n"
25787                                       "\n";
25788     static const GLchar *gs_tested  = "#version 430 core\n"
25789                                       "#extension GL_ARB_enhanced_layouts : require\n"
25790                                       "\n"
25791                                       "layout(points)                           in;\n"
25792                                       "layout(triangle_strip, max_vertices = 4) out;\n"
25793                                       "\n"
25794                                       "VAR_DEFINITION"
25795                                       "\n"
25796                                       "in  vec4 vs_any[];\n"
25797                                       "out vec4 any_fs;\n"
25798                                       "\n"
25799                                       "void main()\n"
25800                                       "{\n"
25801                                       "    vec4 result = vs_any[0];\n"
25802                                       "\n"
25803                                       "VARIABLE_USE"
25804                                       "\n"
25805                                       "    any_fs = result;\n"
25806                                       "    gl_Position  = vec4(-1, -1, 0, 1);\n"
25807                                       "    EmitVertex();\n"
25808                                       "    any_fs = result;\n"
25809                                       "    gl_Position  = vec4(-1, 1, 0, 1);\n"
25810                                       "    EmitVertex();\n"
25811                                       "    any_fs = result;\n"
25812                                       "    gl_Position  = vec4(1, -1, 0, 1);\n"
25813                                       "    EmitVertex();\n"
25814                                       "    any_fs = result;\n"
25815                                       "    gl_Position  = vec4(1, 1, 0, 1);\n"
25816                                       "    EmitVertex();\n"
25817                                       "}\n"
25818                                       "\n";
25819     static const GLchar *tcs        = "#version 430 core\n"
25820                                       "#extension GL_ARB_enhanced_layouts : require\n"
25821                                       "\n"
25822                                       "layout(vertices = 1) out;\n"
25823                                       "\n"
25824                                       "in  vec4 vs_any[];\n"
25825                                       "out vec4 tcs_tes[];\n"
25826                                       "\n"
25827                                       "void main()\n"
25828                                       "{\n"
25829                                       "\n"
25830                                       "    tcs_tes[gl_InvocationID] = vs_any[gl_InvocationID];\n"
25831                                       "\n"
25832                                       "    gl_TessLevelOuter[0] = 1.0;\n"
25833                                       "    gl_TessLevelOuter[1] = 1.0;\n"
25834                                       "    gl_TessLevelOuter[2] = 1.0;\n"
25835                                       "    gl_TessLevelOuter[3] = 1.0;\n"
25836                                       "    gl_TessLevelInner[0] = 1.0;\n"
25837                                       "    gl_TessLevelInner[1] = 1.0;\n"
25838                                       "}\n"
25839                                       "\n";
25840     static const GLchar *tes_tested = "#version 430 core\n"
25841                                       "#extension GL_ARB_enhanced_layouts : require\n"
25842                                       "\n"
25843                                       "layout(isolines, point_mode) in;\n"
25844                                       "\n"
25845                                       "VAR_DEFINITION"
25846                                       "\n"
25847                                       "in  vec4 tcs_tes[];\n"
25848                                       "out vec4 any_fs;\n"
25849                                       "\n"
25850                                       "void main()\n"
25851                                       "{\n"
25852                                       "    vec4 result = tcs_tes[0];\n"
25853                                       "\n"
25854                                       "VARIABLE_USE"
25855                                       "\n"
25856                                       "    any_fs += result;\n"
25857                                       "}\n"
25858                                       "\n";
25859     static const GLchar *vs         = "#version 430 core\n"
25860                                       "#extension GL_ARB_enhanced_layouts : require\n"
25861                                       "\n"
25862                                       "in  vec4 in_vs;\n"
25863                                       "out vec4 vs_any;\n"
25864                                       "\n"
25865                                       "void main()\n"
25866                                       "{\n"
25867                                       "    vs_any = in_vs;\n"
25868                                       "}\n"
25869                                       "\n";
25870     static const GLchar *vs_tested  = "#version 430 core\n"
25871                                       "#extension GL_ARB_enhanced_layouts : require\n"
25872                                       "\n"
25873                                       "VAR_DEFINITION"
25874                                       "\n"
25875                                       "in  vec4 in_vs;\n"
25876                                       "out vec4 any_fs;\n"
25877                                       "\n"
25878                                       "void main()\n"
25879                                       "{\n"
25880                                       "    vec4 result = in_vs;\n"
25881                                       "\n"
25882                                       "VARIABLE_USE"
25883                                       "\n"
25884                                       "    any_fs = result;\n"
25885                                       "}\n"
25886                                       "\n";
25887 
25888     std::string source;
25889     testCase &test_case = m_test_cases[test_case_index];
25890 
25891     if (test_case.m_stage == stage)
25892     {
25893         GLchar offset[16];
25894         size_t position         = 0;
25895         const GLchar *type_name = test_case.m_type.GetGLSLTypeName();
25896 
25897         sprintf(offset, "%d", test_case.m_offset);
25898 
25899         switch (stage)
25900         {
25901         case Utils::Shader::GEOMETRY:
25902             source = gs_tested;
25903             break;
25904         case Utils::Shader::TESS_EVAL:
25905             source = tes_tested;
25906             break;
25907         case Utils::Shader::VERTEX:
25908             source = vs_tested;
25909             break;
25910         default:
25911             TCU_FAIL("Invalid enum");
25912         }
25913 
25914         Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
25915         position = 0;
25916         Utils::replaceToken("OFFSET", position, offset, source);
25917         Utils::replaceToken("VARIABLE_USE", position, var_use, source);
25918 
25919         Utils::replaceAllTokens("TYPE", type_name, source);
25920     }
25921     else
25922     {
25923         switch (test_case.m_stage)
25924         {
25925         case Utils::Shader::GEOMETRY:
25926             switch (stage)
25927             {
25928             case Utils::Shader::FRAGMENT:
25929                 source = fs;
25930                 break;
25931             case Utils::Shader::VERTEX:
25932                 source = vs;
25933                 break;
25934             default:
25935                 source = "";
25936             }
25937             break;
25938         case Utils::Shader::TESS_EVAL:
25939             switch (stage)
25940             {
25941             case Utils::Shader::FRAGMENT:
25942                 source = fs;
25943                 break;
25944             case Utils::Shader::TESS_CTRL:
25945                 source = tcs;
25946                 break;
25947             case Utils::Shader::VERTEX:
25948                 source = vs;
25949                 break;
25950             default:
25951                 source = "";
25952             }
25953             break;
25954         case Utils::Shader::VERTEX:
25955             switch (stage)
25956             {
25957             case Utils::Shader::FRAGMENT:
25958                 source = fs;
25959                 break;
25960             default:
25961                 source = "";
25962             }
25963             break;
25964         default:
25965             TCU_FAIL("Invalid enum");
25966         }
25967     }
25968 
25969     return source;
25970 }
25971 
25972 /** Get description of test case
25973  *
25974  * @param test_case_index Index of test case
25975  *
25976  * @return Test case description
25977  **/
25978 std::string XFBInvalidOffsetAlignmentTest::getTestCaseName(GLuint test_case_index)
25979 {
25980     std::stringstream stream;
25981     testCase &test_case = m_test_cases[test_case_index];
25982 
25983     stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
25984            << ", type: " << test_case.m_type.GetGLSLTypeName() << ", offset: " << test_case.m_offset;
25985 
25986     return stream.str();
25987 }
25988 
25989 /** Get number of test cases
25990  *
25991  * @return Number of test cases
25992  **/
25993 GLuint XFBInvalidOffsetAlignmentTest::getTestCaseNumber()
25994 {
25995     return static_cast<GLuint>(m_test_cases.size());
25996 }
25997 
25998 /** Selects if "compute" stage is relevant for test
25999  *
26000  * @param ignored
26001  *
26002  * @return false
26003  **/
26004 bool XFBInvalidOffsetAlignmentTest::isComputeRelevant(GLuint /* test_case_index */)
26005 {
26006     return false;
26007 }
26008 
26009 /** Prepare all test cases
26010  *
26011  **/
26012 void XFBInvalidOffsetAlignmentTest::testInit()
26013 {
26014     const GLuint n_types = getTypesNumber();
26015 
26016     for (GLuint i = 0; i < n_types; ++i)
26017     {
26018         const Utils::Type &type      = getType(i);
26019         const GLuint basic_type_size = Utils::Type::GetTypeSize(type.m_basic_type);
26020 
26021         for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
26022         {
26023             if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
26024                 (Utils::Shader::FRAGMENT == stage))
26025             {
26026                 continue;
26027             }
26028 
26029             for (GLuint offset = basic_type_size + 1; offset < 2 * basic_type_size; ++offset)
26030             {
26031                 testCase test_case = {offset, (Utils::Shader::STAGES)stage, type};
26032 
26033                 m_test_cases.push_back(test_case);
26034             }
26035         }
26036     }
26037 }
26038 
26039 /** Constructor
26040  *
26041  * @param context Test context
26042  **/
26043 XFBCaptureInactiveOutputVariableTest::XFBCaptureInactiveOutputVariableTest(deqp::Context &context)
26044     : BufferTestBase(context, "xfb_capture_inactive_output_variable",
26045                      "Test verifies that inactive variables are captured")
26046 {
26047     /* Nothing to be done here */
26048 }
26049 
26050 /** Execute drawArrays for single vertex
26051  *
26052  * @param test_case_index
26053  *
26054  * @return true
26055  **/
26056 bool XFBCaptureInactiveOutputVariableTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
26057 {
26058     const Functions &gl   = m_context.getRenderContext().getFunctions();
26059     GLenum primitive_type = GL_PATCHES;
26060 
26061     if (TEST_VS == test_case_index)
26062     {
26063         primitive_type = GL_POINTS;
26064     }
26065 
26066     gl.disable(GL_RASTERIZER_DISCARD);
26067     GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
26068 
26069     gl.beginTransformFeedback(GL_POINTS);
26070     GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
26071 
26072     gl.drawArrays(primitive_type, 0 /* first */, 1 /* count */);
26073     GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
26074 
26075     gl.endTransformFeedback();
26076     GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
26077 
26078     return true;
26079 }
26080 
26081 /** Get descriptors of buffers necessary for test
26082  *
26083  * @param ignored
26084  * @param out_descriptors Descriptors of buffers used by test
26085  **/
26086 void XFBCaptureInactiveOutputVariableTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
26087                                                                 bufferDescriptor::Vector &out_descriptors)
26088 {
26089     const Utils::Type &type = Utils::Type::vec4;
26090 
26091     /* Test needs single uniform and xfb */
26092     out_descriptors.resize(2);
26093 
26094     /* Get references */
26095     bufferDescriptor &uniform = out_descriptors[0];
26096     bufferDescriptor &xfb     = out_descriptors[1];
26097 
26098     /* Index */
26099     uniform.m_index = 0;
26100     xfb.m_index     = 0;
26101 
26102     /* Target */
26103     uniform.m_target = Utils::Buffer::Uniform;
26104     xfb.m_target     = Utils::Buffer::Transform_feedback;
26105 
26106     /* Data */
26107     const std::vector<GLubyte> &gohan_data = type.GenerateData();
26108     const std::vector<GLubyte> &goten_data = type.GenerateData();
26109 
26110     const GLuint type_size = static_cast<GLuint>(gohan_data.size());
26111 
26112     /* Uniform data */
26113     uniform.m_initial_data.resize(2 * type_size);
26114     memcpy(&uniform.m_initial_data[0] + 0, &gohan_data[0], type_size);
26115     memcpy(&uniform.m_initial_data[0] + type_size, &goten_data[0], type_size);
26116 
26117     /* XFB data */
26118     xfb.m_initial_data.resize(3 * type_size);
26119     xfb.m_expected_data.resize(3 * type_size);
26120 
26121     for (GLuint i = 0; i < 3 * type_size; ++i)
26122     {
26123         xfb.m_initial_data[i]  = (glw::GLubyte)i;
26124         xfb.m_expected_data[i] = (glw::GLubyte)i;
26125     }
26126 
26127     memcpy(&xfb.m_expected_data[0] + 2 * type_size, &gohan_data[0], type_size);
26128     memcpy(&xfb.m_expected_data[0] + 0 * type_size, &goten_data[0], type_size);
26129 }
26130 
26131 /** Get body of main function for given shader stage
26132  *
26133  * @param test_case_index  Index of test case
26134  * @param stage            Shader stage
26135  * @param out_assignments  Set to empty
26136  * @param out_calculations Set to empty
26137  **/
26138 void XFBCaptureInactiveOutputVariableTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
26139                                                          std::string &out_assignments, std::string &out_calculations)
26140 {
26141     out_calculations = "";
26142 
26143     static const GLchar *vs_tes_gs = "    goten = uni_goten;\n"
26144                                      "    gohan = uni_gohan;\n";
26145     static const GLchar *fs        = "    fs_out = goku + gohan + goten;\n";
26146 
26147     const GLchar *assignments = "";
26148 
26149     switch (stage)
26150     {
26151     case Utils::Shader::FRAGMENT:
26152         assignments = fs;
26153         break;
26154 
26155     case Utils::Shader::GEOMETRY:
26156         if (TEST_GS == test_case_index)
26157         {
26158             assignments = vs_tes_gs;
26159         }
26160         break;
26161 
26162     case Utils::Shader::TESS_CTRL:
26163         break;
26164 
26165     case Utils::Shader::TESS_EVAL:
26166         if (TEST_TES == test_case_index)
26167         {
26168             assignments = vs_tes_gs;
26169         }
26170         break;
26171 
26172     case Utils::Shader::VERTEX:
26173         if (TEST_VS == test_case_index)
26174         {
26175             assignments = vs_tes_gs;
26176         }
26177         break;
26178 
26179     default:
26180         TCU_FAIL("Invalid enum");
26181     }
26182 
26183     out_assignments = assignments;
26184 }
26185 
26186 /** Get interface of shader
26187  *
26188  * @param test_case_index  Index of test case
26189  * @param stage            Shader stage
26190  * @param out_interface    Set to ""
26191  **/
26192 void XFBCaptureInactiveOutputVariableTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
26193                                                               std::string &out_interface)
26194 {
26195     static const GLchar *vs_tes_gs = "const uint sizeof_type = 16;\n"
26196                                      "\n"
26197                                      "layout (xfb_offset = 1 * sizeof_type) out vec4 goku;\n"
26198                                      "layout (xfb_offset = 2 * sizeof_type) out vec4 gohan;\n"
26199                                      "layout (xfb_offset = 0 * sizeof_type) out vec4 goten;\n"
26200                                      "\n"
26201                                      "layout(binding = 0) uniform block {\n"
26202                                      "    vec4 uni_gohan;\n"
26203                                      "    vec4 uni_goten;\n"
26204                                      "};\n";
26205     static const GLchar *fs        = "in vec4 goku;\n"
26206                                      "in vec4 gohan;\n"
26207                                      "in vec4 goten;\n"
26208                                      "out vec4 fs_out;\n";
26209 
26210     const GLchar *interface = "";
26211 
26212     switch (stage)
26213     {
26214     case Utils::Shader::FRAGMENT:
26215         interface = fs;
26216         break;
26217 
26218     case Utils::Shader::GEOMETRY:
26219         if (TEST_GS == test_case_index)
26220         {
26221             interface = vs_tes_gs;
26222         }
26223         break;
26224 
26225     case Utils::Shader::TESS_CTRL:
26226         break;
26227 
26228     case Utils::Shader::TESS_EVAL:
26229         if (TEST_TES == test_case_index)
26230         {
26231             interface = vs_tes_gs;
26232         }
26233         break;
26234 
26235     case Utils::Shader::VERTEX:
26236         if (TEST_VS == test_case_index)
26237         {
26238             interface = vs_tes_gs;
26239         }
26240         break;
26241 
26242     default:
26243         TCU_FAIL("Invalid enum");
26244     }
26245 
26246     out_interface = interface;
26247 }
26248 
26249 /** Get source code of shader
26250  *
26251  * @param test_case_index Index of test case
26252  * @param stage           Shader stage
26253  *
26254  * @return Source
26255  **/
26256 std::string XFBCaptureInactiveOutputVariableTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
26257 {
26258     std::string source;
26259 
26260     switch (test_case_index)
26261     {
26262     case TEST_VS:
26263         switch (stage)
26264         {
26265         case Utils::Shader::FRAGMENT:
26266         case Utils::Shader::VERTEX:
26267             source = BufferTestBase::getShaderSource(test_case_index, stage);
26268             break;
26269         default:
26270             break;
26271         }
26272         break;
26273 
26274     case TEST_TES:
26275         switch (stage)
26276         {
26277         case Utils::Shader::FRAGMENT:
26278         case Utils::Shader::TESS_CTRL:
26279         case Utils::Shader::TESS_EVAL:
26280         case Utils::Shader::VERTEX:
26281             source = BufferTestBase::getShaderSource(test_case_index, stage);
26282             break;
26283         default:
26284             break;
26285         }
26286         break;
26287 
26288     case TEST_GS:
26289         source = BufferTestBase::getShaderSource(test_case_index, stage);
26290         break;
26291 
26292     default:
26293         TCU_FAIL("Invalid enum");
26294     }
26295 
26296     /* */
26297     return source;
26298 }
26299 
26300 /** Get name of test case
26301  *
26302  * @param test_case_index Index of test case
26303  *
26304  * @return Name of tested stage
26305  **/
26306 std::string XFBCaptureInactiveOutputVariableTest::getTestCaseName(glw::GLuint test_case_index)
26307 {
26308     const GLchar *name = 0;
26309 
26310     switch (test_case_index)
26311     {
26312     case TEST_VS:
26313         name = "vertex";
26314         break;
26315     case TEST_TES:
26316         name = "tessellation evaluation";
26317         break;
26318     case TEST_GS:
26319         name = "geometry";
26320         break;
26321     default:
26322         TCU_FAIL("Invalid enum");
26323     }
26324 
26325     return name;
26326 }
26327 
26328 /** Returns number of test cases
26329  *
26330  * @return TEST_MAX
26331  **/
26332 glw::GLuint XFBCaptureInactiveOutputVariableTest::getTestCaseNumber()
26333 {
26334     return TEST_MAX;
26335 }
26336 
26337 /** Inspects program to check if all resources are as expected
26338  *
26339  * @param ignored
26340  * @param program         Program instance
26341  * @param out_stream      Error message
26342  *
26343  * @return true if everything is ok, false otherwise
26344  **/
26345 bool XFBCaptureInactiveOutputVariableTest::inspectProgram(GLuint /* test_case_index */, Utils::Program &program,
26346                                                           std::stringstream &out_stream)
26347 {
26348     GLint stride            = 0;
26349     const Utils::Type &type = Utils::Type::vec4;
26350     const GLuint type_size  = type.GetSize();
26351 
26352     program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE,
26353                         1 /* buf_size */, &stride);
26354 
26355     if ((GLint)(3 * type_size) != stride)
26356     {
26357         out_stream << "Stride is: " << stride << " expected: " << (3 * type_size);
26358 
26359         return false;
26360     }
26361 
26362     return true;
26363 }
26364 
26365 /** Verify contents of buffers
26366  *
26367  * @param buffers Collection of buffers to be verified
26368  *
26369  * @return true if everything is as expected, false otherwise
26370  **/
26371 bool XFBCaptureInactiveOutputVariableTest::verifyBuffers(bufferCollection &buffers)
26372 {
26373     bool result = true;
26374 
26375     bufferCollection::pair &pair = buffers.m_vector[1] /* xfb */;
26376     Utils::Buffer *buffer        = pair.m_buffer;
26377     bufferDescriptor *descriptor = pair.m_descriptor;
26378 
26379     /* Get pointer to contents of buffer */
26380     buffer->Bind();
26381     GLubyte *buffer_data = (GLubyte *)buffer->Map(Utils::Buffer::ReadOnly);
26382 
26383     /* Get pointer to expected data */
26384     GLubyte *expected_data = (GLubyte *)&descriptor->m_expected_data[0];
26385 
26386     /* Compare */
26387     static const GLuint vec4_size = 16;
26388 
26389     int res_gohan = memcmp(buffer_data + 2 * vec4_size, expected_data + 2 * vec4_size, vec4_size);
26390     int res_goten = memcmp(buffer_data + 0 * vec4_size, expected_data + 0 * vec4_size, vec4_size);
26391 
26392     if ((0 != res_gohan) || (0 != res_goten))
26393     {
26394         m_context.getTestContext().getLog()
26395             << tcu::TestLog::Message << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
26396             << ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
26397 
26398         result = false;
26399     }
26400 
26401     /* Release buffer mapping */
26402     buffer->UnMap();
26403 
26404     return result;
26405 }
26406 
26407 /** Constructor
26408  *
26409  * @param context Test context
26410  **/
26411 XFBCaptureInactiveOutputComponentTest::XFBCaptureInactiveOutputComponentTest(deqp::Context &context)
26412     : BufferTestBase(context, "xfb_capture_inactive_output_component",
26413                      "Test verifies that inactive components are not modified")
26414 {
26415     /* Nothing to be done here */
26416 }
26417 
26418 /** Execute drawArrays for single vertex
26419  *
26420  * @param test_case_index
26421  *
26422  * @return true
26423  **/
26424 bool XFBCaptureInactiveOutputComponentTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
26425 {
26426     const Functions &gl   = m_context.getRenderContext().getFunctions();
26427     GLenum primitive_type = GL_PATCHES;
26428 
26429     if (TEST_VS == test_case_index)
26430     {
26431         primitive_type = GL_POINTS;
26432     }
26433 
26434     gl.disable(GL_RASTERIZER_DISCARD);
26435     GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
26436 
26437     gl.beginTransformFeedback(GL_POINTS);
26438     GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
26439 
26440     gl.drawArrays(primitive_type, 0 /* first */, 1 /* count */);
26441     GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
26442 
26443     gl.endTransformFeedback();
26444     GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
26445 
26446     return true;
26447 }
26448 
26449 /** Get descriptors of buffers necessary for test
26450  *
26451  * @param ignored
26452  * @param out_descriptors Descriptors of buffers used by test
26453  **/
26454 void XFBCaptureInactiveOutputComponentTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
26455                                                                  bufferDescriptor::Vector &out_descriptors)
26456 {
26457     const Utils::Type &type = Utils::Type::vec4;
26458 
26459     /* Test needs single uniform and xfb */
26460     out_descriptors.resize(2);
26461 
26462     /* Get references */
26463     bufferDescriptor &uniform = out_descriptors[0];
26464     bufferDescriptor &xfb     = out_descriptors[1];
26465 
26466     /* Index */
26467     uniform.m_index = 0;
26468     xfb.m_index     = 0;
26469 
26470     /* Target */
26471     uniform.m_target = Utils::Buffer::Uniform;
26472     xfb.m_target     = Utils::Buffer::Transform_feedback;
26473 
26474     /* Data */
26475     const std::vector<GLubyte> &goku_data   = type.GenerateData();
26476     const std::vector<GLubyte> &gohan_data  = type.GenerateData();
26477     const std::vector<GLubyte> &goten_data  = type.GenerateData();
26478     const std::vector<GLubyte> &chichi_data = type.GenerateData();
26479     const std::vector<GLubyte> &vegeta_data = type.GenerateData();
26480     const std::vector<GLubyte> &trunks_data = type.GenerateData();
26481     const std::vector<GLubyte> &bra_data    = type.GenerateData();
26482     const std::vector<GLubyte> &bulma_data  = type.GenerateData();
26483 
26484     const GLuint comp_size = Utils::Type::GetTypeSize(type.m_basic_type);
26485     const GLuint type_size = static_cast<GLuint>(gohan_data.size());
26486 
26487     /* Uniform data */
26488     uniform.m_initial_data.resize(8 * type_size);
26489     memcpy(&uniform.m_initial_data[0] + 0 * type_size, &goku_data[0], type_size);
26490     memcpy(&uniform.m_initial_data[0] + 1 * type_size, &gohan_data[0], type_size);
26491     memcpy(&uniform.m_initial_data[0] + 2 * type_size, &goten_data[0], type_size);
26492     memcpy(&uniform.m_initial_data[0] + 3 * type_size, &chichi_data[0], type_size);
26493     memcpy(&uniform.m_initial_data[0] + 4 * type_size, &vegeta_data[0], type_size);
26494     memcpy(&uniform.m_initial_data[0] + 5 * type_size, &trunks_data[0], type_size);
26495     memcpy(&uniform.m_initial_data[0] + 6 * type_size, &bra_data[0], type_size);
26496     memcpy(&uniform.m_initial_data[0] + 7 * type_size, &bulma_data[0], type_size);
26497 
26498     /* XFB data */
26499     xfb.m_initial_data.resize(8 * type_size);
26500     xfb.m_expected_data.resize(8 * type_size);
26501 
26502     for (GLuint i = 0; i < 8 * type_size; ++i)
26503     {
26504         xfb.m_initial_data[i]  = (glw::GLubyte)i;
26505         xfb.m_expected_data[i] = (glw::GLubyte)i;
26506     }
26507 
26508     /* goku - x, z - 32 */
26509     memcpy(&xfb.m_expected_data[0] + 2 * type_size + 0 * comp_size, &goku_data[0] + 0 * comp_size, comp_size);
26510     memcpy(&xfb.m_expected_data[0] + 2 * type_size + 2 * comp_size, &goku_data[0] + 2 * comp_size, comp_size);
26511 
26512     /* gohan - y, w - 0 */
26513     memcpy(&xfb.m_expected_data[0] + 0 * type_size + 1 * comp_size, &gohan_data[0] + 1 * comp_size, comp_size);
26514     memcpy(&xfb.m_expected_data[0] + 0 * type_size + 3 * comp_size, &gohan_data[0] + 3 * comp_size, comp_size);
26515 
26516     /* goten - x, y - 16 */
26517     memcpy(&xfb.m_expected_data[0] + 1 * type_size + 0 * comp_size, &goten_data[0] + 0 * comp_size, comp_size);
26518     memcpy(&xfb.m_expected_data[0] + 1 * type_size + 1 * comp_size, &goten_data[0] + 1 * comp_size, comp_size);
26519 
26520     /* chichi - z, w - 48 */
26521     memcpy(&xfb.m_expected_data[0] + 3 * type_size + 2 * comp_size, &chichi_data[0] + 2 * comp_size, comp_size);
26522     memcpy(&xfb.m_expected_data[0] + 3 * type_size + 3 * comp_size, &chichi_data[0] + 3 * comp_size, comp_size);
26523 
26524     /* vegeta - x - 112 */
26525     memcpy(&xfb.m_expected_data[0] + 7 * type_size + 0 * comp_size, &vegeta_data[0] + 0 * comp_size, comp_size);
26526 
26527     /* trunks - y - 96 */
26528     memcpy(&xfb.m_expected_data[0] + 6 * type_size + 1 * comp_size, &trunks_data[0] + 1 * comp_size, comp_size);
26529 
26530     /* bra - z - 80 */
26531     memcpy(&xfb.m_expected_data[0] + 5 * type_size + 2 * comp_size, &bra_data[0] + 2 * comp_size, comp_size);
26532 
26533     /* bulma - w - 64 */
26534     memcpy(&xfb.m_expected_data[0] + 4 * type_size + 3 * comp_size, &bulma_data[0] + 3 * comp_size, comp_size);
26535 }
26536 
26537 /** Get body of main function for given shader stage
26538  *
26539  * @param test_case_index  Index of test case
26540  * @param stage            Shader stage
26541  * @param out_assignments  Set to empty
26542  * @param out_calculations Set to empty
26543  **/
26544 void XFBCaptureInactiveOutputComponentTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
26545                                                           std::string &out_assignments, std::string &out_calculations)
26546 {
26547     out_calculations = "";
26548 
26549     static const GLchar *vs_tes_gs = "    goku.x    = uni_goku.x   ;\n"
26550                                      "    goku.z    = uni_goku.z   ;\n"
26551                                      "    gohan.y   = uni_gohan.y  ;\n"
26552                                      "    gohan.w   = uni_gohan.w  ;\n"
26553                                      "    goten.x   = uni_goten.x  ;\n"
26554                                      "    goten.y   = uni_goten.y  ;\n"
26555                                      "    chichi.z  = uni_chichi.z ;\n"
26556                                      "    chichi.w  = uni_chichi.w ;\n"
26557                                      "    vegeta.x  = uni_vegeta.x ;\n"
26558                                      "    trunks.y  = uni_trunks.y ;\n"
26559                                      "    bra.z     = uni_bra.z    ;\n"
26560                                      "    bulma.w   = uni_bulma.w  ;\n";
26561     static const GLchar *fs        = "    fs_out = goku + gohan + goten + chichi + vegeta + trunks + bra + bulma;\n";
26562 
26563     const GLchar *assignments = "";
26564 
26565     switch (stage)
26566     {
26567     case Utils::Shader::FRAGMENT:
26568         assignments = fs;
26569         break;
26570 
26571     case Utils::Shader::GEOMETRY:
26572         if (TEST_GS == test_case_index)
26573         {
26574             assignments = vs_tes_gs;
26575         }
26576         break;
26577 
26578     case Utils::Shader::TESS_CTRL:
26579         break;
26580 
26581     case Utils::Shader::TESS_EVAL:
26582         if (TEST_TES == test_case_index)
26583         {
26584             assignments = vs_tes_gs;
26585         }
26586         break;
26587 
26588     case Utils::Shader::VERTEX:
26589         if (TEST_VS == test_case_index)
26590         {
26591             assignments = vs_tes_gs;
26592         }
26593         break;
26594 
26595     default:
26596         TCU_FAIL("Invalid enum");
26597     }
26598 
26599     out_assignments = assignments;
26600 }
26601 
26602 /** Get interface of shader
26603  *
26604  * @param test_case_index  Index of test case
26605  * @param stage            Shader stage
26606  * @param out_interface    Set to ""
26607  **/
26608 void XFBCaptureInactiveOutputComponentTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
26609                                                                std::string &out_interface)
26610 {
26611     static const GLchar *vs_tes_gs = "const uint sizeof_type = 16;\n"
26612                                      "\n"
26613                                      "layout (xfb_offset = 2 * sizeof_type) out vec4 goku;\n"
26614                                      "layout (xfb_offset = 0 * sizeof_type) out vec4 gohan;\n"
26615                                      "layout (xfb_offset = 1 * sizeof_type) out vec4 goten;\n"
26616                                      "layout (xfb_offset = 3 * sizeof_type) out vec4 chichi;\n"
26617                                      "layout (xfb_offset = 7 * sizeof_type) out vec4 vegeta;\n"
26618                                      "layout (xfb_offset = 6 * sizeof_type) out vec4 trunks;\n"
26619                                      "layout (xfb_offset = 5 * sizeof_type) out vec4 bra;\n"
26620                                      "layout (xfb_offset = 4 * sizeof_type) out vec4 bulma;\n"
26621                                      "\n"
26622                                      "layout(binding = 0) uniform block {\n"
26623                                      "    vec4 uni_goku;\n"
26624                                      "    vec4 uni_gohan;\n"
26625                                      "    vec4 uni_goten;\n"
26626                                      "    vec4 uni_chichi;\n"
26627                                      "    vec4 uni_vegeta;\n"
26628                                      "    vec4 uni_trunks;\n"
26629                                      "    vec4 uni_bra;\n"
26630                                      "    vec4 uni_bulma;\n"
26631                                      "};\n";
26632     static const GLchar *fs        = "in vec4 vegeta;\n"
26633                                      "in vec4 trunks;\n"
26634                                      "in vec4 bra;\n"
26635                                      "in vec4 bulma;\n"
26636                                      "in vec4 goku;\n"
26637                                      "in vec4 gohan;\n"
26638                                      "in vec4 goten;\n"
26639                                      "in vec4 chichi;\n"
26640                                      "\n"
26641                                      "out vec4 fs_out;\n";
26642 
26643     const GLchar *interface = "";
26644 
26645     switch (stage)
26646     {
26647     case Utils::Shader::FRAGMENT:
26648         interface = fs;
26649         break;
26650 
26651     case Utils::Shader::GEOMETRY:
26652         if (TEST_GS == test_case_index)
26653         {
26654             interface = vs_tes_gs;
26655         }
26656         break;
26657 
26658     case Utils::Shader::TESS_CTRL:
26659         break;
26660 
26661     case Utils::Shader::TESS_EVAL:
26662         if (TEST_TES == test_case_index)
26663         {
26664             interface = vs_tes_gs;
26665         }
26666         break;
26667 
26668     case Utils::Shader::VERTEX:
26669         if (TEST_VS == test_case_index)
26670         {
26671             interface = vs_tes_gs;
26672         }
26673         break;
26674 
26675     default:
26676         TCU_FAIL("Invalid enum");
26677     }
26678 
26679     out_interface = interface;
26680 }
26681 
26682 /** Get source code of shader
26683  *
26684  * @param test_case_index Index of test case
26685  * @param stage           Shader stage
26686  *
26687  * @return Source
26688  **/
26689 std::string XFBCaptureInactiveOutputComponentTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
26690 {
26691     std::string source;
26692 
26693     switch (test_case_index)
26694     {
26695     case TEST_VS:
26696         switch (stage)
26697         {
26698         case Utils::Shader::FRAGMENT:
26699         case Utils::Shader::VERTEX:
26700             source = BufferTestBase::getShaderSource(test_case_index, stage);
26701             break;
26702         default:
26703             break;
26704         }
26705         break;
26706 
26707     case TEST_TES:
26708         switch (stage)
26709         {
26710         case Utils::Shader::FRAGMENT:
26711         case Utils::Shader::TESS_CTRL:
26712         case Utils::Shader::TESS_EVAL:
26713         case Utils::Shader::VERTEX:
26714             source = BufferTestBase::getShaderSource(test_case_index, stage);
26715             break;
26716         default:
26717             break;
26718         }
26719         break;
26720 
26721     case TEST_GS:
26722         source = BufferTestBase::getShaderSource(test_case_index, stage);
26723         break;
26724 
26725     default:
26726         TCU_FAIL("Invalid enum");
26727     }
26728 
26729     /* */
26730     return source;
26731 }
26732 
26733 /** Get name of test case
26734  *
26735  * @param test_case_index Index of test case
26736  *
26737  * @return Name of tested stage
26738  **/
26739 std::string XFBCaptureInactiveOutputComponentTest::getTestCaseName(glw::GLuint test_case_index)
26740 {
26741     const GLchar *name = 0;
26742 
26743     switch (test_case_index)
26744     {
26745     case TEST_VS:
26746         name = "vertex";
26747         break;
26748     case TEST_TES:
26749         name = "tessellation evaluation";
26750         break;
26751     case TEST_GS:
26752         name = "geometry";
26753         break;
26754     default:
26755         TCU_FAIL("Invalid enum");
26756     }
26757 
26758     return name;
26759 }
26760 
26761 /** Returns number of test cases
26762  *
26763  * @return TEST_MAX
26764  **/
26765 glw::GLuint XFBCaptureInactiveOutputComponentTest::getTestCaseNumber()
26766 {
26767     return TEST_MAX;
26768 }
26769 
26770 /** Verify contents of buffers
26771  *
26772  * @param buffers Collection of buffers to be verified
26773  *
26774  * @return true if everything is as expected, false otherwise
26775  **/
26776 bool XFBCaptureInactiveOutputComponentTest::verifyBuffers(bufferCollection &buffers)
26777 {
26778     bool result = true;
26779 
26780     bufferCollection::pair &pair = buffers.m_vector[1] /* xfb */;
26781     Utils::Buffer *buffer        = pair.m_buffer;
26782     bufferDescriptor *descriptor = pair.m_descriptor;
26783 
26784     /* Get pointer to contents of buffer */
26785     buffer->Bind();
26786     GLubyte *buffer_data = (GLubyte *)buffer->Map(Utils::Buffer::ReadOnly);
26787 
26788     /* Get pointer to expected data */
26789     GLubyte *expected_data = (GLubyte *)&descriptor->m_expected_data[0];
26790 
26791     /* Compare */
26792     static const GLuint comp_size = 4;
26793     static const GLuint vec4_size = 16;
26794 
26795     int res_goku_x =
26796         memcmp(buffer_data + 2 * vec4_size + 0 * comp_size, expected_data + 2 * vec4_size + 0 * comp_size, comp_size);
26797     int res_goku_z =
26798         memcmp(buffer_data + 2 * vec4_size + 2 * comp_size, expected_data + 2 * vec4_size + 2 * comp_size, comp_size);
26799 
26800     int res_gohan_y =
26801         memcmp(buffer_data + 0 * vec4_size + 1 * comp_size, expected_data + 0 * vec4_size + 1 * comp_size, comp_size);
26802     int res_gohan_w =
26803         memcmp(buffer_data + 0 * vec4_size + 3 * comp_size, expected_data + 0 * vec4_size + 3 * comp_size, comp_size);
26804 
26805     int res_goten_x =
26806         memcmp(buffer_data + 1 * vec4_size + 0 * comp_size, expected_data + 1 * vec4_size + 0 * comp_size, comp_size);
26807     int res_goten_y =
26808         memcmp(buffer_data + 1 * vec4_size + 1 * comp_size, expected_data + 1 * vec4_size + 1 * comp_size, comp_size);
26809 
26810     int res_chichi_z =
26811         memcmp(buffer_data + 3 * vec4_size + 2 * comp_size, expected_data + 3 * vec4_size + 2 * comp_size, comp_size);
26812     int res_chichi_w =
26813         memcmp(buffer_data + 3 * vec4_size + 3 * comp_size, expected_data + 3 * vec4_size + 3 * comp_size, comp_size);
26814 
26815     int res_vegeta_x =
26816         memcmp(buffer_data + 7 * vec4_size + 0 * comp_size, expected_data + 7 * vec4_size + 0 * comp_size, comp_size);
26817 
26818     int res_trunks_y =
26819         memcmp(buffer_data + 6 * vec4_size + 1 * comp_size, expected_data + 6 * vec4_size + 1 * comp_size, comp_size);
26820 
26821     int res_bra_z =
26822         memcmp(buffer_data + 5 * vec4_size + 2 * comp_size, expected_data + 5 * vec4_size + 2 * comp_size, comp_size);
26823 
26824     int res_bulma_w =
26825         memcmp(buffer_data + 4 * vec4_size + 3 * comp_size, expected_data + 4 * vec4_size + 3 * comp_size, comp_size);
26826 
26827     if ((0 != res_goku_x) || (0 != res_goku_z) || (0 != res_gohan_y) || (0 != res_gohan_w) || (0 != res_goten_x) ||
26828         (0 != res_goten_y) || (0 != res_chichi_z) || (0 != res_chichi_w) || (0 != res_vegeta_x) ||
26829         (0 != res_trunks_y) || (0 != res_bra_z) || (0 != res_bulma_w))
26830     {
26831         m_context.getTestContext().getLog()
26832             << tcu::TestLog::Message << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
26833             << ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
26834 
26835         result = false;
26836     }
26837 
26838     /* Release buffer mapping */
26839     buffer->UnMap();
26840 
26841     return result;
26842 }
26843 
26844 /** Constructor
26845  *
26846  * @param context Test context
26847  **/
26848 XFBCaptureInactiveOutputBlockMemberTest::XFBCaptureInactiveOutputBlockMemberTest(deqp::Context &context)
26849     : BufferTestBase(context, "xfb_capture_inactive_output_block_member",
26850                      "Test verifies that inactive block members are captured")
26851 {
26852     /* Nothing to be done here */
26853 }
26854 
26855 /** Execute drawArrays for single vertex
26856  *
26857  * @param test_case_index
26858  *
26859  * @return true
26860  **/
26861 bool XFBCaptureInactiveOutputBlockMemberTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
26862 {
26863     const Functions &gl   = m_context.getRenderContext().getFunctions();
26864     GLenum primitive_type = GL_PATCHES;
26865 
26866     if (TEST_VS == test_case_index)
26867     {
26868         primitive_type = GL_POINTS;
26869     }
26870 
26871     gl.disable(GL_RASTERIZER_DISCARD);
26872     GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
26873 
26874     gl.beginTransformFeedback(GL_POINTS);
26875     GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
26876 
26877     gl.drawArrays(primitive_type, 0 /* first */, 1 /* count */);
26878     GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
26879 
26880     gl.endTransformFeedback();
26881     GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
26882 
26883     return true;
26884 }
26885 
26886 /** Get descriptors of buffers necessary for test
26887  *
26888  * @param ignored
26889  * @param out_descriptors Descriptors of buffers used by test
26890  **/
26891 void XFBCaptureInactiveOutputBlockMemberTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
26892                                                                    bufferDescriptor::Vector &out_descriptors)
26893 {
26894     const Utils::Type &type = Utils::Type::vec4;
26895 
26896     /* Test needs single uniform and xfb */
26897     out_descriptors.resize(2);
26898 
26899     /* Get references */
26900     bufferDescriptor &uniform = out_descriptors[0];
26901     bufferDescriptor &xfb     = out_descriptors[1];
26902 
26903     /* Index */
26904     uniform.m_index = 0;
26905     xfb.m_index     = 0;
26906 
26907     /* Target */
26908     uniform.m_target = Utils::Buffer::Uniform;
26909     xfb.m_target     = Utils::Buffer::Transform_feedback;
26910 
26911     /* Data */
26912     const std::vector<GLubyte> &gohan_data  = type.GenerateData();
26913     const std::vector<GLubyte> &chichi_data = type.GenerateData();
26914 
26915     const GLuint type_size = static_cast<GLuint>(gohan_data.size());
26916 
26917     /* Uniform data */
26918     uniform.m_initial_data.resize(2 * type_size);
26919     memcpy(&uniform.m_initial_data[0] + 0, &gohan_data[0], type_size);
26920     memcpy(&uniform.m_initial_data[0] + type_size, &chichi_data[0], type_size);
26921 
26922     /* XFB data */
26923     xfb.m_initial_data.resize(4 * type_size);
26924     xfb.m_expected_data.resize(4 * type_size);
26925 
26926     for (GLuint i = 0; i < 4 * type_size; ++i)
26927     {
26928         xfb.m_initial_data[i]  = (glw::GLubyte)i;
26929         xfb.m_expected_data[i] = (glw::GLubyte)i;
26930     }
26931 
26932     memcpy(&xfb.m_expected_data[0] + 1 * type_size, &gohan_data[0], type_size);
26933     memcpy(&xfb.m_expected_data[0] + 3 * type_size, &chichi_data[0], type_size);
26934 }
26935 
26936 /** Get body of main function for given shader stage
26937  *
26938  * @param test_case_index  Index of test case
26939  * @param stage            Shader stage
26940  * @param out_assignments  Set to empty
26941  * @param out_calculations Set to empty
26942  **/
26943 void XFBCaptureInactiveOutputBlockMemberTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
26944                                                             std::string &out_assignments, std::string &out_calculations)
26945 {
26946     out_calculations = "";
26947 
26948     static const GLchar *vs_tes_gs = "    chichi = uni_chichi;\n"
26949                                      "    gohan  = uni_gohan;\n";
26950     static const GLchar *fs        = "    fs_out = goten + gohan + chichi;\n";
26951 
26952     const GLchar *assignments = "";
26953 
26954     switch (stage)
26955     {
26956     case Utils::Shader::FRAGMENT:
26957         assignments = fs;
26958         break;
26959 
26960     case Utils::Shader::GEOMETRY:
26961         if (TEST_GS == test_case_index)
26962         {
26963             assignments = vs_tes_gs;
26964         }
26965         break;
26966 
26967     case Utils::Shader::TESS_CTRL:
26968         break;
26969 
26970     case Utils::Shader::TESS_EVAL:
26971         if (TEST_TES == test_case_index)
26972         {
26973             assignments = vs_tes_gs;
26974         }
26975         break;
26976 
26977     case Utils::Shader::VERTEX:
26978         if (TEST_VS == test_case_index)
26979         {
26980             assignments = vs_tes_gs;
26981         }
26982         break;
26983 
26984     default:
26985         TCU_FAIL("Invalid enum");
26986     }
26987 
26988     out_assignments = assignments;
26989 }
26990 
26991 /** Get interface of shader
26992  *
26993  * @param test_case_index  Index of test case
26994  * @param stage            Shader stage
26995  * @param out_interface    Set to ""
26996  **/
26997 void XFBCaptureInactiveOutputBlockMemberTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
26998                                                                  std::string &out_interface)
26999 {
27000     static const GLchar *vs_tes_gs = "const uint sizeof_type = 16;\n"
27001                                      "\n"
27002                                      "layout (xfb_offset = 1 * sizeof_type) out Goku {\n"
27003                                      "    vec4 gohan;\n"
27004                                      "    vec4 goten;\n"
27005                                      "    vec4 chichi;\n"
27006                                      "};\n"
27007                                      "\n"
27008                                      "layout(binding = 0) uniform block {\n"
27009                                      "    vec4 uni_gohan;\n"
27010                                      "    vec4 uni_chichi;\n"
27011                                      "};\n";
27012     static const GLchar *fs        = "in Goku {\n"
27013                                      "    vec4 gohan;\n"
27014                                      "    vec4 goten;\n"
27015                                      "    vec4 chichi;\n"
27016                                      "};\n"
27017                                      "out vec4 fs_out;\n";
27018 
27019     const GLchar *interface = "";
27020 
27021     switch (stage)
27022     {
27023     case Utils::Shader::FRAGMENT:
27024         interface = fs;
27025         break;
27026 
27027     case Utils::Shader::GEOMETRY:
27028         if (TEST_GS == test_case_index)
27029         {
27030             interface = vs_tes_gs;
27031         }
27032         break;
27033 
27034     case Utils::Shader::TESS_CTRL:
27035         break;
27036 
27037     case Utils::Shader::TESS_EVAL:
27038         if (TEST_TES == test_case_index)
27039         {
27040             interface = vs_tes_gs;
27041         }
27042         break;
27043 
27044     case Utils::Shader::VERTEX:
27045         if (TEST_VS == test_case_index)
27046         {
27047             interface = vs_tes_gs;
27048         }
27049         break;
27050 
27051     default:
27052         TCU_FAIL("Invalid enum");
27053     }
27054 
27055     out_interface = interface;
27056 }
27057 
27058 /** Get source code of shader
27059  *
27060  * @param test_case_index Index of test case
27061  * @param stage           Shader stage
27062  *
27063  * @return Source
27064  **/
27065 std::string XFBCaptureInactiveOutputBlockMemberTest::getShaderSource(GLuint test_case_index,
27066                                                                      Utils::Shader::STAGES stage)
27067 {
27068     std::string source;
27069 
27070     switch (test_case_index)
27071     {
27072     case TEST_VS:
27073         switch (stage)
27074         {
27075         case Utils::Shader::FRAGMENT:
27076         case Utils::Shader::VERTEX:
27077             source = BufferTestBase::getShaderSource(test_case_index, stage);
27078             break;
27079         default:
27080             break;
27081         }
27082         break;
27083 
27084     case TEST_TES:
27085         switch (stage)
27086         {
27087         case Utils::Shader::FRAGMENT:
27088         case Utils::Shader::TESS_CTRL:
27089         case Utils::Shader::TESS_EVAL:
27090         case Utils::Shader::VERTEX:
27091             source = BufferTestBase::getShaderSource(test_case_index, stage);
27092             break;
27093         default:
27094             break;
27095         }
27096         break;
27097 
27098     case TEST_GS:
27099         source = BufferTestBase::getShaderSource(test_case_index, stage);
27100         break;
27101 
27102     default:
27103         TCU_FAIL("Invalid enum");
27104     }
27105 
27106     /* */
27107     return source;
27108 }
27109 
27110 /** Get name of test case
27111  *
27112  * @param test_case_index Index of test case
27113  *
27114  * @return Name of tested stage
27115  **/
27116 std::string XFBCaptureInactiveOutputBlockMemberTest::getTestCaseName(glw::GLuint test_case_index)
27117 {
27118     const GLchar *name = 0;
27119 
27120     switch (test_case_index)
27121     {
27122     case TEST_VS:
27123         name = "vertex";
27124         break;
27125     case TEST_TES:
27126         name = "tessellation evaluation";
27127         break;
27128     case TEST_GS:
27129         name = "geometry";
27130         break;
27131     default:
27132         TCU_FAIL("Invalid enum");
27133     }
27134 
27135     return name;
27136 }
27137 
27138 /** Returns number of test cases
27139  *
27140  * @return TEST_MAX
27141  **/
27142 glw::GLuint XFBCaptureInactiveOutputBlockMemberTest::getTestCaseNumber()
27143 {
27144     return TEST_MAX;
27145 }
27146 
27147 /** Verify contents of buffers
27148  *
27149  * @param buffers Collection of buffers to be verified
27150  *
27151  * @return true if everything is as expected, false otherwise
27152  **/
27153 bool XFBCaptureInactiveOutputBlockMemberTest::verifyBuffers(bufferCollection &buffers)
27154 {
27155     bool result = true;
27156 
27157     bufferCollection::pair &pair = buffers.m_vector[1] /* xfb */;
27158     Utils::Buffer *buffer        = pair.m_buffer;
27159     bufferDescriptor *descriptor = pair.m_descriptor;
27160 
27161     /* Get pointer to contents of buffer */
27162     buffer->Bind();
27163     GLubyte *buffer_data = (GLubyte *)buffer->Map(Utils::Buffer::ReadOnly);
27164 
27165     /* Get pointer to expected data */
27166     GLubyte *expected_data = (GLubyte *)&descriptor->m_expected_data[0];
27167 
27168     /* Compare */
27169     static const GLuint vec4_size = 16;
27170 
27171     int res_before = memcmp(buffer_data, expected_data, vec4_size);
27172     int res_gohan  = memcmp(buffer_data + 1 * vec4_size, expected_data + 1 * vec4_size, vec4_size);
27173     int res_chichi = memcmp(buffer_data + 3 * vec4_size, expected_data + 3 * vec4_size, vec4_size);
27174 
27175     if ((0 != res_before) || (0 != res_gohan) || (0 != res_chichi))
27176     {
27177         m_context.getTestContext().getLog()
27178             << tcu::TestLog::Message << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
27179             << ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
27180 
27181         result = false;
27182     }
27183 
27184     /* Release buffer mapping */
27185     buffer->UnMap();
27186 
27187     return result;
27188 }
27189 
27190 /** Constructor
27191  *
27192  * @param context Test context
27193  **/
27194 XFBCaptureStructTest::XFBCaptureStructTest(deqp::Context &context)
27195     : BufferTestBase(context, "xfb_capture_struct", "Test verifies that inactive structure members are captured")
27196 {
27197     /* Nothing to be done here */
27198 }
27199 
27200 /** Execute drawArrays for single vertex
27201  *
27202  * @param test_case_index
27203  *
27204  * @return true
27205  **/
27206 bool XFBCaptureStructTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
27207 {
27208     const Functions &gl   = m_context.getRenderContext().getFunctions();
27209     GLenum primitive_type = GL_PATCHES;
27210 
27211     if (TEST_VS == test_case_index)
27212     {
27213         primitive_type = GL_POINTS;
27214     }
27215 
27216     gl.disable(GL_RASTERIZER_DISCARD);
27217     GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
27218 
27219     gl.beginTransformFeedback(GL_POINTS);
27220     GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
27221 
27222     gl.drawArrays(primitive_type, 0 /* first */, 1 /* count */);
27223     GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
27224 
27225     gl.endTransformFeedback();
27226     GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
27227 
27228     return true;
27229 }
27230 
27231 /** Get descriptors of buffers necessary for test
27232  *
27233  * @param ignored
27234  * @param out_descriptors Descriptors of buffers used by test
27235  **/
27236 void XFBCaptureStructTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
27237                                                 bufferDescriptor::Vector &out_descriptors)
27238 {
27239     const Utils::Type &type = Utils::Type::vec4;
27240 
27241     /* Test needs single uniform and xfb */
27242     out_descriptors.resize(2);
27243 
27244     /* Get references */
27245     bufferDescriptor &uniform = out_descriptors[0];
27246     bufferDescriptor &xfb     = out_descriptors[1];
27247 
27248     /* Index */
27249     uniform.m_index = 0;
27250     xfb.m_index     = 0;
27251 
27252     /* Target */
27253     uniform.m_target = Utils::Buffer::Uniform;
27254     xfb.m_target     = Utils::Buffer::Transform_feedback;
27255 
27256     /* Data */
27257     const std::vector<GLubyte> &gohan_data  = type.GenerateData();
27258     const std::vector<GLubyte> &chichi_data = type.GenerateData();
27259 
27260     const GLuint type_size = static_cast<GLuint>(gohan_data.size());
27261 
27262     /* Uniform data */
27263     uniform.m_initial_data.resize(2 * type_size);
27264     memcpy(&uniform.m_initial_data[0] + 0, &gohan_data[0], type_size);
27265     memcpy(&uniform.m_initial_data[0] + type_size, &chichi_data[0], type_size);
27266 
27267     /* XFB data */
27268     xfb.m_initial_data.resize(4 * type_size);
27269     xfb.m_expected_data.resize(4 * type_size);
27270 
27271     for (GLuint i = 0; i < 4 * type_size; ++i)
27272     {
27273         xfb.m_initial_data[i]  = (glw::GLubyte)i;
27274         xfb.m_expected_data[i] = (glw::GLubyte)i;
27275     }
27276 
27277     memcpy(&xfb.m_expected_data[0] + 1 * type_size, &gohan_data[0], type_size);
27278     memcpy(&xfb.m_expected_data[0] + 3 * type_size, &chichi_data[0], type_size);
27279 }
27280 
27281 /** Get body of main function for given shader stage
27282  *
27283  * @param test_case_index  Index of test case
27284  * @param stage            Shader stage
27285  * @param out_assignments  Set to empty
27286  * @param out_calculations Set to empty
27287  **/
27288 void XFBCaptureStructTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
27289                                          std::string &out_assignments, std::string &out_calculations)
27290 {
27291     out_calculations = "";
27292 
27293     static const GLchar *vs_tes_gs = "    goku.chichi = uni_chichi;\n"
27294                                      "    goku.gohan  = uni_gohan;\n";
27295     static const GLchar *fs        = "    fs_out = goku.goten + goku.gohan + goku.chichi;\n";
27296 
27297     const GLchar *assignments = "";
27298 
27299     switch (stage)
27300     {
27301     case Utils::Shader::FRAGMENT:
27302         assignments = fs;
27303         break;
27304 
27305     case Utils::Shader::GEOMETRY:
27306         if (TEST_GS == test_case_index)
27307         {
27308             assignments = vs_tes_gs;
27309         }
27310         break;
27311 
27312     case Utils::Shader::TESS_CTRL:
27313         break;
27314 
27315     case Utils::Shader::TESS_EVAL:
27316         if (TEST_TES == test_case_index)
27317         {
27318             assignments = vs_tes_gs;
27319         }
27320         break;
27321 
27322     case Utils::Shader::VERTEX:
27323         if (TEST_VS == test_case_index)
27324         {
27325             assignments = vs_tes_gs;
27326         }
27327         break;
27328 
27329     default:
27330         TCU_FAIL("Invalid enum");
27331     }
27332 
27333     out_assignments = assignments;
27334 }
27335 
27336 /** Get interface of shader
27337  *
27338  * @param test_case_index  Index of test case
27339  * @param stage            Shader stage
27340  * @param out_interface    Set to ""
27341  **/
27342 void XFBCaptureStructTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
27343                                               std::string &out_interface)
27344 {
27345     static const GLchar *vs_tes_gs = "const uint sizeof_type = 16;\n"
27346                                      "\n"
27347                                      "struct Goku {\n"
27348                                      "    vec4 gohan;\n"
27349                                      "    vec4 goten;\n"
27350                                      "    vec4 chichi;\n"
27351                                      "};\n"
27352                                      "\n"
27353                                      "layout (xfb_offset = sizeof_type) out Goku goku;\n"
27354                                      "\n"
27355                                      "layout(binding = 0, std140) uniform block {\n"
27356                                      "    vec4 uni_gohan;\n"
27357                                      "    vec4 uni_chichi;\n"
27358                                      "};\n";
27359     static const GLchar *fs        = "struct Goku {\n"
27360                                      "    vec4 gohan;\n"
27361                                      "    vec4 goten;\n"
27362                                      "    vec4 chichi;\n"
27363                                      "};\n"
27364                                      "\n"
27365                                      "in Goku goku;\n"
27366                                      "\n"
27367                                      "out vec4 fs_out;\n";
27368 
27369     const GLchar *interface = "";
27370 
27371     switch (stage)
27372     {
27373     case Utils::Shader::FRAGMENT:
27374         interface = fs;
27375         break;
27376 
27377     case Utils::Shader::GEOMETRY:
27378         if (TEST_GS == test_case_index)
27379         {
27380             interface = vs_tes_gs;
27381         }
27382         break;
27383 
27384     case Utils::Shader::TESS_CTRL:
27385         break;
27386 
27387     case Utils::Shader::TESS_EVAL:
27388         if (TEST_TES == test_case_index)
27389         {
27390             interface = vs_tes_gs;
27391         }
27392         break;
27393 
27394     case Utils::Shader::VERTEX:
27395         if (TEST_VS == test_case_index)
27396         {
27397             interface = vs_tes_gs;
27398         }
27399         break;
27400 
27401     default:
27402         TCU_FAIL("Invalid enum");
27403     }
27404 
27405     out_interface = interface;
27406 }
27407 
27408 /** Get source code of shader
27409  *
27410  * @param test_case_index Index of test case
27411  * @param stage           Shader stage
27412  *
27413  * @return Source
27414  **/
27415 std::string XFBCaptureStructTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
27416 {
27417     std::string source;
27418 
27419     switch (test_case_index)
27420     {
27421     case TEST_VS:
27422         switch (stage)
27423         {
27424         case Utils::Shader::FRAGMENT:
27425         case Utils::Shader::VERTEX:
27426             source = BufferTestBase::getShaderSource(test_case_index, stage);
27427             break;
27428         default:
27429             break;
27430         }
27431         break;
27432 
27433     case TEST_TES:
27434         switch (stage)
27435         {
27436         case Utils::Shader::FRAGMENT:
27437         case Utils::Shader::TESS_CTRL:
27438         case Utils::Shader::TESS_EVAL:
27439         case Utils::Shader::VERTEX:
27440             source = BufferTestBase::getShaderSource(test_case_index, stage);
27441             break;
27442         default:
27443             break;
27444         }
27445         break;
27446 
27447     case TEST_GS:
27448         source = BufferTestBase::getShaderSource(test_case_index, stage);
27449         break;
27450 
27451     default:
27452         TCU_FAIL("Invalid enum");
27453     }
27454 
27455     /* */
27456     return source;
27457 }
27458 
27459 /** Get name of test case
27460  *
27461  * @param test_case_index Index of test case
27462  *
27463  * @return Name of tested stage
27464  **/
27465 std::string XFBCaptureStructTest::getTestCaseName(glw::GLuint test_case_index)
27466 {
27467     const GLchar *name = 0;
27468 
27469     switch (test_case_index)
27470     {
27471     case TEST_VS:
27472         name = "vertex";
27473         break;
27474     case TEST_TES:
27475         name = "tessellation evaluation";
27476         break;
27477     case TEST_GS:
27478         name = "geometry";
27479         break;
27480     default:
27481         TCU_FAIL("Invalid enum");
27482     }
27483 
27484     return name;
27485 }
27486 
27487 /** Returns number of test cases
27488  *
27489  * @return TEST_MAX
27490  **/
27491 glw::GLuint XFBCaptureStructTest::getTestCaseNumber()
27492 {
27493     return TEST_MAX;
27494 }
27495 
27496 /** Verify contents of buffers
27497  *
27498  * @param buffers Collection of buffers to be verified
27499  *
27500  * @return true if everything is as expected, false otherwise
27501  **/
27502 bool XFBCaptureStructTest::verifyBuffers(bufferCollection &buffers)
27503 {
27504     bool result = true;
27505 
27506     bufferCollection::pair &pair = buffers.m_vector[1] /* xfb */;
27507     Utils::Buffer *buffer        = pair.m_buffer;
27508     bufferDescriptor *descriptor = pair.m_descriptor;
27509 
27510     /* Get pointer to contents of buffer */
27511     buffer->Bind();
27512     GLubyte *buffer_data = (GLubyte *)buffer->Map(Utils::Buffer::ReadOnly);
27513 
27514     /* Get pointer to expected data */
27515     GLubyte *expected_data = (GLubyte *)&descriptor->m_expected_data[0];
27516 
27517     /* Compare */
27518     static const GLuint vec4_size = 16;
27519 
27520     int res_before = memcmp(buffer_data, expected_data, vec4_size);
27521     int res_gohan  = memcmp(buffer_data + 1 * vec4_size, expected_data + 1 * vec4_size, vec4_size);
27522     int res_chichi = memcmp(buffer_data + 3 * vec4_size, expected_data + 3 * vec4_size, vec4_size);
27523 
27524     if ((0 != res_before) || (0 != res_gohan) || (0 != res_chichi))
27525     {
27526         m_context.getTestContext().getLog()
27527             << tcu::TestLog::Message << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
27528             << ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
27529 
27530         result = false;
27531     }
27532 
27533     /* Release buffer mapping */
27534     buffer->UnMap();
27535 
27536     return result;
27537 }
27538 
27539 /** Constructor
27540  *
27541  * @param context Test framework context
27542  **/
27543 XFBCaptureUnsizedArrayTest::XFBCaptureUnsizedArrayTest(deqp::Context &context)
27544     : NegativeTestBase(context, "xfb_capture_unsized_array",
27545                        "Test verifies that compiler reports error when unsized array is qualified with xfb_offset")
27546 {
27547 }
27548 
27549 /** Source for given test case and stage
27550  *
27551  * @param test_case_index Index of test case
27552  * @param stage           Shader stage
27553  *
27554  * @return Shader source
27555  **/
27556 std::string XFBCaptureUnsizedArrayTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
27557 {
27558 #if DEBUG_NEG_REMOVE_ERROR
27559     static const GLchar *var_definition = "/* layout (xfb_offset = 0) */ out vec4 goku[];\n";
27560 #else
27561     static const GLchar *var_definition = "layout (xfb_offset = 0) out vec4 goku[];\n";
27562 #endif /* DEBUG_NEG_REMOVE_ERROR */
27563     static const GLchar *var_use   = "    goku[0] = result / 2;\n";
27564     static const GLchar *fs        = "#version 430 core\n"
27565                                      "#extension GL_ARB_enhanced_layouts : require\n"
27566                                      "\n"
27567                                      "in  vec4 any_fs;\n"
27568                                      "out vec4 fs_out;\n"
27569                                      "\n"
27570                                      "void main()\n"
27571                                      "{\n"
27572                                      "    fs_out = any_fs;\n"
27573                                      "}\n"
27574                                      "\n";
27575     static const GLchar *vs_tested = "#version 430 core\n"
27576                                      "#extension GL_ARB_enhanced_layouts : require\n"
27577                                      "\n"
27578                                      "VAR_DEFINITION"
27579                                      "\n"
27580                                      "in  vec4 in_vs;\n"
27581                                      "out vec4 any_fs;\n"
27582                                      "\n"
27583                                      "void main()\n"
27584                                      "{\n"
27585                                      "    vec4 result = in_vs;\n"
27586                                      "\n"
27587                                      "VARIABLE_USE"
27588                                      "\n"
27589                                      "    any_fs = result;\n"
27590                                      "}\n"
27591                                      "\n";
27592 
27593     std::string source;
27594     testCase &test_case = m_test_cases[test_case_index];
27595 
27596     if (test_case.m_stage == stage)
27597     {
27598         size_t position = 0;
27599 
27600         switch (stage)
27601         {
27602         case Utils::Shader::VERTEX:
27603             source = vs_tested;
27604             break;
27605         default:
27606             TCU_FAIL("Invalid enum");
27607         }
27608 
27609         Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
27610         position = 0;
27611         Utils::replaceToken("VARIABLE_USE", position, var_use, source);
27612     }
27613     else
27614     {
27615         switch (test_case.m_stage)
27616         {
27617         case Utils::Shader::VERTEX:
27618             switch (stage)
27619             {
27620             case Utils::Shader::FRAGMENT:
27621                 source = fs;
27622                 break;
27623             default:
27624                 source = "";
27625             }
27626             break;
27627         default:
27628             TCU_FAIL("Invalid enum");
27629         }
27630     }
27631 
27632     return source;
27633 }
27634 
27635 /** Get description of test case
27636  *
27637  * @param test_case_index Index of test case
27638  *
27639  * @return Test case description
27640  **/
27641 std::string XFBCaptureUnsizedArrayTest::getTestCaseName(GLuint test_case_index)
27642 {
27643     std::stringstream stream;
27644     testCase &test_case = m_test_cases[test_case_index];
27645 
27646     stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage);
27647 
27648     return stream.str();
27649 }
27650 
27651 /** Get number of test cases
27652  *
27653  * @return Number of test cases
27654  **/
27655 GLuint XFBCaptureUnsizedArrayTest::getTestCaseNumber()
27656 {
27657     return static_cast<GLuint>(m_test_cases.size());
27658 }
27659 
27660 /** Selects if "compute" stage is relevant for test
27661  *
27662  * @param ignored
27663  *
27664  * @return false
27665  **/
27666 bool XFBCaptureUnsizedArrayTest::isComputeRelevant(GLuint /* test_case_index */)
27667 {
27668     return false;
27669 }
27670 
27671 /** Prepare all test cases
27672  *
27673  **/
27674 void XFBCaptureUnsizedArrayTest::testInit()
27675 {
27676     for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
27677     {
27678         /* Not aplicable for */
27679         if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
27680             (Utils::Shader::FRAGMENT == stage) || (Utils::Shader::GEOMETRY == stage) ||
27681             (Utils::Shader::TESS_EVAL == stage))
27682         {
27683             continue;
27684         }
27685 
27686         testCase test_case = {(Utils::Shader::STAGES)stage};
27687 
27688         m_test_cases.push_back(test_case);
27689     }
27690 }
27691 
27692 /** Constructor
27693  *
27694  * @param context Test context
27695  **/
27696 XFBExplicitLocationTest::XFBExplicitLocationTest(deqp::Context &context)
27697     : BufferTestBase(context, "xfb_explicit_location",
27698                      "Test verifies that explicit location on matrices and arrays does not impact xfb output")
27699 {
27700     /* Nothing to be done here */
27701 }
27702 
27703 /** Execute drawArrays for single vertex
27704  *
27705  * @param test_case_index
27706  *
27707  * @return true
27708  **/
27709 bool XFBExplicitLocationTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
27710 {
27711     const Functions &gl       = m_context.getRenderContext().getFunctions();
27712     GLenum primitive_type     = GL_PATCHES;
27713     const testCase &test_case = m_test_cases[test_case_index];
27714 
27715     if (Utils::Shader::VERTEX == test_case.m_stage)
27716     {
27717         primitive_type = GL_POINTS;
27718     }
27719 
27720     gl.disable(GL_RASTERIZER_DISCARD);
27721     GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
27722 
27723     gl.beginTransformFeedback(GL_POINTS);
27724     GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
27725 
27726     gl.drawArrays(primitive_type, 0 /* first */, 2 /* count */);
27727     GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
27728 
27729     gl.endTransformFeedback();
27730     GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
27731 
27732     return true;
27733 }
27734 
27735 /** Get descriptors of buffers necessary for test
27736  *
27737  * @param test_case_index Index of test case
27738  * @param out_descriptors Descriptors of buffers used by test
27739  **/
27740 void XFBExplicitLocationTest::getBufferDescriptors(GLuint test_case_index, bufferDescriptor::Vector &out_descriptors)
27741 {
27742     const testCase &test_case = m_test_cases[test_case_index];
27743     const Utils::Type &type   = test_case.m_type;
27744 
27745     /* Test needs single uniform and xfb */
27746     out_descriptors.resize(2);
27747 
27748     /* Get references */
27749     bufferDescriptor &uniform = out_descriptors[0];
27750     bufferDescriptor &xfb     = out_descriptors[1];
27751 
27752     /* Index */
27753     uniform.m_index = 0;
27754     xfb.m_index     = 0;
27755 
27756     /* Target */
27757     uniform.m_target = Utils::Buffer::Uniform;
27758     xfb.m_target     = Utils::Buffer::Transform_feedback;
27759 
27760     /* Data */
27761     const GLuint rand_start = Utils::s_rand;
27762     std::vector<GLubyte> uniform_data;
27763 
27764     for (GLuint i = 0; i < std::max(test_case.m_array_size, 1u); i++)
27765     {
27766         const std::vector<GLubyte> &type_uniform_data = type.GenerateData();
27767         /**
27768          * Rule 4 of Section 7.6.2.2:
27769          *
27770          * If the member is an array of scalars or vectors, the base alignment and array stride
27771          * are set to match the base alignment of a single array element, according to rules (1),
27772          * (2), and (3), and rounded up to the base alignment of a vec4.
27773          */
27774         uniform_data.resize(Utils::align((glw::GLuint)uniform_data.size(), 16));
27775         uniform_data.insert(uniform_data.end(), type_uniform_data.begin(), type_uniform_data.end());
27776     }
27777 
27778     Utils::s_rand = rand_start;
27779     std::vector<GLubyte> xfb_data;
27780 
27781     for (GLuint i = 0; i < std::max(test_case.m_array_size, 1u); i++)
27782     {
27783         const std::vector<GLubyte> &type_xfb_data = type.GenerateDataPacked();
27784         xfb_data.insert(xfb_data.end(), type_xfb_data.begin(), type_xfb_data.end());
27785     }
27786 
27787     const GLuint uni_type_size = static_cast<GLuint>(uniform_data.size());
27788     const GLuint xfb_type_size = static_cast<GLuint>(xfb_data.size());
27789     /*
27790      Note: If xfb varying output from vertex shader, the variable "goku" will only output once to transform feedback buffer,
27791      if xfb varying output from TES or GS, because the input primitive type in TES is defined as "layout(isolines, point_mode) in;",
27792      the primitive type is line which make the variable "goku" will output twice to transform feedback buffer, so for vertex shader
27793      only one valid data should be initialized in xfb.m_expected_data
27794      */
27795     const GLuint xfb_data_size = (test_case.m_stage == Utils::Shader::VERTEX) ? xfb_type_size : xfb_type_size * 2;
27796     /* Uniform data */
27797     uniform.m_initial_data.resize(uni_type_size);
27798     memcpy(&uniform.m_initial_data[0] + 0 * uni_type_size, &uniform_data[0], uni_type_size);
27799 
27800     /* XFB data */
27801     xfb.m_initial_data.resize(xfb_data_size, 0);
27802     xfb.m_expected_data.resize(xfb_data_size);
27803 
27804     if (test_case.m_stage == Utils::Shader::VERTEX)
27805     {
27806         memcpy(&xfb.m_expected_data[0] + 0 * xfb_type_size, &xfb_data[0], xfb_type_size);
27807     }
27808     else
27809     {
27810         memcpy(&xfb.m_expected_data[0] + 0 * xfb_type_size, &xfb_data[0], xfb_type_size);
27811         memcpy(&xfb.m_expected_data[0] + 1 * xfb_type_size, &xfb_data[0], xfb_type_size);
27812     }
27813 }
27814 
27815 /** Get body of main function for given shader stage
27816  *
27817  * @param test_case_index  Index of test case
27818  * @param stage            Shader stage
27819  * @param out_assignments  Set to empty
27820  * @param out_calculations Set to empty
27821  **/
27822 void XFBExplicitLocationTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
27823                                             std::string &out_assignments, std::string &out_calculations)
27824 {
27825     const testCase &test_case = m_test_cases[test_case_index];
27826 
27827     out_calculations = "";
27828 
27829     static const GLchar *vs_tes_gs = "    goku = uni_goku;\n";
27830 
27831     const GLchar *assignments = "";
27832 
27833     if (test_case.m_stage == stage)
27834     {
27835         switch (stage)
27836         {
27837         case Utils::Shader::GEOMETRY:
27838             assignments = vs_tes_gs;
27839             break;
27840         case Utils::Shader::TESS_EVAL:
27841             assignments = vs_tes_gs;
27842             break;
27843         case Utils::Shader::VERTEX:
27844             assignments = vs_tes_gs;
27845             break;
27846         default:
27847             TCU_FAIL("Invalid enum");
27848         }
27849     }
27850     else
27851     {
27852         switch (stage)
27853         {
27854         case Utils::Shader::FRAGMENT:
27855             assignments = "";
27856             break;
27857         case Utils::Shader::GEOMETRY:
27858         case Utils::Shader::TESS_CTRL:
27859         case Utils::Shader::TESS_EVAL:
27860         case Utils::Shader::VERTEX:
27861             break;
27862         default:
27863             TCU_FAIL("Invalid enum");
27864         }
27865     }
27866 
27867     out_assignments = assignments;
27868 
27869     if (Utils::Shader::FRAGMENT == stage)
27870     {
27871         Utils::replaceAllTokens("TYPE", test_case.m_type.GetGLSLTypeName(), out_assignments);
27872     }
27873 }
27874 
27875 /** Get interface of shader
27876  *
27877  * @param test_case_index  Index of test case
27878  * @param stage            Shader stage
27879  * @param out_interface    Set to ""
27880  **/
27881 void XFBExplicitLocationTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
27882                                                  std::string &out_interface)
27883 {
27884     static const GLchar *vs_tes_gs = "layout (location = 0, xfb_offset = 0) FLAT out TYPE gokuARRAY;\n"
27885                                      "\n"
27886                                      "layout(std140, binding = 0) uniform Goku {\n"
27887                                      "    TYPE uni_gokuARRAY;\n"
27888                                      "};\n";
27889 
27890     const testCase &test_case = m_test_cases[test_case_index];
27891     const GLchar *interface   = "";
27892     const GLchar *flat        = "";
27893 
27894     if (test_case.m_stage == stage)
27895     {
27896         switch (stage)
27897         {
27898         case Utils::Shader::GEOMETRY:
27899             interface = vs_tes_gs;
27900             break;
27901         case Utils::Shader::TESS_EVAL:
27902             interface = vs_tes_gs;
27903             break;
27904         case Utils::Shader::VERTEX:
27905             interface = vs_tes_gs;
27906             break;
27907         default:
27908             TCU_FAIL("Invalid enum");
27909         }
27910     }
27911     else
27912     {
27913         switch (stage)
27914         {
27915         case Utils::Shader::FRAGMENT:
27916             interface = "";
27917             break;
27918         case Utils::Shader::GEOMETRY:
27919         case Utils::Shader::TESS_CTRL:
27920         case Utils::Shader::TESS_EVAL:
27921         case Utils::Shader::VERTEX:
27922             break;
27923         default:
27924             TCU_FAIL("Invalid enum");
27925         }
27926     }
27927 
27928     out_interface = interface;
27929 
27930     if (Utils::Type::Float != test_case.m_type.m_basic_type)
27931     {
27932         flat = "flat";
27933     }
27934 
27935     /* Array size */
27936     if (0 == test_case.m_array_size)
27937     {
27938         Utils::replaceAllTokens("ARRAY", "", out_interface);
27939     }
27940     else
27941     {
27942         char buffer[16];
27943         sprintf(buffer, "[%d]", test_case.m_array_size);
27944 
27945         Utils::replaceAllTokens("ARRAY", buffer, out_interface);
27946     }
27947 
27948     Utils::replaceAllTokens("FLAT", flat, out_interface);
27949     Utils::replaceAllTokens("TYPE", test_case.m_type.GetGLSLTypeName(), out_interface);
27950 }
27951 
27952 /** Get source code of shader
27953  *
27954  * @param test_case_index Index of test case
27955  * @param stage           Shader stage
27956  *
27957  * @return Source
27958  **/
27959 std::string XFBExplicitLocationTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
27960 {
27961     std::string source;
27962     const testCase &test_case = m_test_cases[test_case_index];
27963 
27964     switch (test_case.m_stage)
27965     {
27966     case Utils::Shader::VERTEX:
27967         switch (stage)
27968         {
27969         case Utils::Shader::FRAGMENT:
27970         case Utils::Shader::VERTEX:
27971             source = BufferTestBase::getShaderSource(test_case_index, stage);
27972             break;
27973         default:
27974             break;
27975         }
27976         break;
27977 
27978     case Utils::Shader::TESS_EVAL:
27979         switch (stage)
27980         {
27981         case Utils::Shader::FRAGMENT:
27982         case Utils::Shader::TESS_CTRL:
27983         case Utils::Shader::TESS_EVAL:
27984         case Utils::Shader::VERTEX:
27985             source = BufferTestBase::getShaderSource(test_case_index, stage);
27986             break;
27987         default:
27988             break;
27989         }
27990         break;
27991 
27992     case Utils::Shader::GEOMETRY:
27993         source = BufferTestBase::getShaderSource(test_case_index, stage);
27994         break;
27995 
27996     default:
27997         TCU_FAIL("Invalid enum");
27998     }
27999 
28000     /* */
28001     return source;
28002 }
28003 
28004 /** Get name of test case
28005  *
28006  * @param test_case_index Index of test case
28007  *
28008  * @return Name of tested stage
28009  **/
28010 std::string XFBExplicitLocationTest::getTestCaseName(glw::GLuint test_case_index)
28011 {
28012     std::stringstream stream;
28013     const testCase &test_case = m_test_cases[test_case_index];
28014 
28015     stream << "Type: " << test_case.m_type.GetGLSLTypeName()
28016            << ", stage: " << Utils::Shader::GetStageName(test_case.m_stage);
28017 
28018     return stream.str();
28019 }
28020 
28021 /** Returns number of test cases
28022  *
28023  * @return TEST_MAX
28024  **/
28025 glw::GLuint XFBExplicitLocationTest::getTestCaseNumber()
28026 {
28027     return static_cast<GLuint>(m_test_cases.size());
28028 }
28029 
28030 /** Prepare all test cases
28031  *
28032  **/
28033 void XFBExplicitLocationTest::testInit()
28034 {
28035     const Functions &gl = m_context.getRenderContext().getFunctions();
28036     GLint max_xfb_int;
28037 
28038     gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_xfb_int);
28039     GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
28040 
28041     const GLuint n_types = getTypesNumber();
28042 
28043     for (GLuint i = 0; i < n_types; ++i)
28044     {
28045         const Utils::Type &type = getType(i);
28046 
28047         for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
28048         {
28049             if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::FRAGMENT == stage) ||
28050                 (Utils::Shader::TESS_CTRL == stage))
28051             {
28052                 continue;
28053             }
28054 
28055             if (type.m_n_columns > 1)
28056             {
28057                 testCase test_case = {(Utils::Shader::STAGES)stage, type, 0};
28058 
28059                 m_test_cases.push_back(test_case);
28060             }
28061 
28062             for (GLuint array_size = 3; array_size > 1; array_size--)
28063             {
28064                 if (type.GetNumComponents() * array_size <= GLuint(max_xfb_int))
28065                 {
28066                     testCase test_case = {(Utils::Shader::STAGES)stage, type, array_size};
28067 
28068                     m_test_cases.push_back(test_case);
28069 
28070                     break;
28071                 }
28072             }
28073         }
28074     }
28075 }
28076 
28077 /** Constructor
28078  *
28079  * @param context Test context
28080  **/
28081 XFBExplicitLocationStructTest::XFBExplicitLocationStructTest(deqp::Context &context)
28082     : BufferTestBase(context, "xfb_struct_explicit_location",
28083                      "Test verifies that explicit location on structs does not impact xfb output")
28084 {
28085     /* Nothing to be done here */
28086 }
28087 
28088 /** Execute drawArrays for single vertex
28089  *
28090  * @param test_case_index
28091  *
28092  * @return true
28093  **/
28094 bool XFBExplicitLocationStructTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
28095 {
28096     const Functions &gl       = m_context.getRenderContext().getFunctions();
28097     GLenum primitive_type     = GL_PATCHES;
28098     const testCase &test_case = m_test_cases[test_case_index];
28099 
28100     if (Utils::Shader::VERTEX == test_case.m_stage)
28101     {
28102         primitive_type = GL_POINTS;
28103     }
28104 
28105     gl.disable(GL_RASTERIZER_DISCARD);
28106     GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
28107 
28108     gl.beginTransformFeedback(GL_POINTS);
28109     GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
28110 
28111     gl.drawArrays(primitive_type, 0 /* first */, 2 /* count */);
28112     GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
28113 
28114     gl.endTransformFeedback();
28115     GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
28116 
28117     return true;
28118 }
28119 
28120 /** Get descriptors of buffers necessary for test
28121  *
28122  * @param test_case_index Index of test case
28123  * @param out_descriptors Descriptors of buffers used by test
28124  **/
28125 void XFBExplicitLocationStructTest::getBufferDescriptors(GLuint test_case_index,
28126                                                          bufferDescriptor::Vector &out_descriptors)
28127 {
28128     const testCase &test_case = m_test_cases[test_case_index];
28129 
28130     /* Test needs single uniform and xfb */
28131     out_descriptors.resize(2);
28132 
28133     /* Get references */
28134     bufferDescriptor &uniform = out_descriptors[0];
28135     bufferDescriptor &xfb     = out_descriptors[1];
28136 
28137     /* Index */
28138     uniform.m_index = 0;
28139     xfb.m_index     = 0;
28140 
28141     /* Target */
28142     uniform.m_target = Utils::Buffer::Uniform;
28143     xfb.m_target     = Utils::Buffer::Transform_feedback;
28144 
28145     /* Data */
28146     const GLuint rand_start = Utils::s_rand;
28147     std::vector<GLubyte> uniform_data;
28148     GLuint max_aligment = 1;
28149 
28150     for (const testType &type : test_case.m_types)
28151     {
28152         GLuint base_aligment = type.m_type.GetBaseAlignment(false);
28153         if (type.m_array_size > 0)
28154         {
28155             /**
28156              * Rule 4 of Section 7.6.2.2:
28157              *
28158              * If the member is an array of scalars or vectors, the base alignment and array stride
28159              * are set to match the base alignment of a single array element, according to rules (1),
28160              * (2), and (3), and rounded up to the base alignment of a vec4.
28161              */
28162             base_aligment = Utils::align(base_aligment, Utils::Type::vec4.GetBaseAlignment(false));
28163         }
28164 
28165         max_aligment = std::max(base_aligment, max_aligment);
28166 
28167         uniform_data.resize(Utils::align((glw::GLuint)uniform_data.size(), base_aligment), 0);
28168 
28169         for (GLuint i = 0; i < std::max(type.m_array_size, 1u); i++)
28170         {
28171             const std::vector<GLubyte> &type_uniform_data = type.m_type.GenerateData();
28172             uniform_data.insert(uniform_data.end(), type_uniform_data.begin(), type_uniform_data.end());
28173 
28174             if (type.m_array_size > 0)
28175             {
28176                 uniform_data.resize(Utils::align((glw::GLuint)uniform_data.size(), base_aligment), 0);
28177             }
28178         }
28179     }
28180 
28181     const GLuint struct_aligment = Utils::align(max_aligment, Utils::Type::vec4.GetBaseAlignment(false));
28182 
28183     if (test_case.m_nested_struct)
28184     {
28185         uniform_data.resize(Utils::align((glw::GLuint)uniform_data.size(), struct_aligment), 0);
28186 
28187         const GLuint old_size = (glw::GLuint)uniform_data.size();
28188         uniform_data.resize(2 * old_size);
28189         std::copy_n(uniform_data.begin(), old_size, uniform_data.begin() + old_size);
28190     }
28191 
28192     uniform_data.resize(Utils::align((glw::GLuint)uniform_data.size(), struct_aligment), 0);
28193 
28194     Utils::s_rand = rand_start;
28195     std::vector<GLubyte> xfb_data;
28196 
28197     GLuint max_type_size = 1;
28198     for (const testType &type : test_case.m_types)
28199     {
28200         const GLuint basic_type_size = Utils::Type::GetTypeSize(type.m_type.m_basic_type);
28201         max_type_size                = std::max(max_type_size, basic_type_size);
28202 
28203         /* Align per current type's aligment requirements */
28204         xfb_data.resize(Utils::align((glw::GLuint)xfb_data.size(), basic_type_size), 0);
28205 
28206         for (GLuint i = 0; i < std::max(type.m_array_size, 1u); i++)
28207         {
28208             const std::vector<GLubyte> &type_xfb_data = type.m_type.GenerateDataPacked();
28209             xfb_data.insert(xfb_data.end(), type_xfb_data.begin(), type_xfb_data.end());
28210         }
28211     }
28212 
28213     if (test_case.m_nested_struct)
28214     {
28215         /* Struct has aligment requirement equal to largest requirement of its members */
28216         xfb_data.resize(Utils::align((glw::GLuint)xfb_data.size(), max_type_size), 0);
28217 
28218         const GLuint old_size = (glw::GLuint)xfb_data.size();
28219         xfb_data.resize(2 * old_size);
28220         std::copy_n(xfb_data.begin(), old_size, xfb_data.begin() + old_size);
28221     }
28222 
28223     xfb_data.resize(Utils::align((glw::GLuint)xfb_data.size(), max_type_size), 0);
28224 
28225     const GLuint uni_type_size = static_cast<GLuint>(uniform_data.size());
28226     const GLuint xfb_type_size = static_cast<GLuint>(xfb_data.size());
28227 
28228     /* Do not exceed the minimum value of MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS */
28229     DE_ASSERT(xfb_type_size <= 64 * sizeof(GLuint));
28230 
28231     /*
28232      Note: If xfb varying output from vertex shader, the variable "goku" will only output once to transform feedback buffer,
28233      if xfb varying output from TES or GS, because the input primitive type in TES is defined as "layout(isolines, point_mode) in;",
28234      the primitive type is line which make the variable "goku" will output twice to transform feedback buffer, so for vertex shader
28235      only one valid data should be initialized in xfb.m_expected_data
28236      */
28237     const GLuint xfb_data_size = (test_case.m_stage == Utils::Shader::VERTEX) ? xfb_type_size : xfb_type_size * 2;
28238     /* Uniform data */
28239     uniform.m_initial_data.resize(uni_type_size);
28240     memcpy(&uniform.m_initial_data[0] + 0 * uni_type_size, &uniform_data[0], uni_type_size);
28241 
28242     /* XFB data */
28243     xfb.m_initial_data.resize(xfb_data_size, 0);
28244     xfb.m_expected_data.resize(xfb_data_size);
28245 
28246     if (test_case.m_stage == Utils::Shader::VERTEX)
28247     {
28248         memcpy(&xfb.m_expected_data[0] + 0 * xfb_type_size, &xfb_data[0], xfb_type_size);
28249     }
28250     else
28251     {
28252         memcpy(&xfb.m_expected_data[0] + 0 * xfb_type_size, &xfb_data[0], xfb_type_size);
28253         memcpy(&xfb.m_expected_data[0] + 1 * xfb_type_size, &xfb_data[0], xfb_type_size);
28254     }
28255 }
28256 
28257 /** Get body of main function for given shader stage
28258  *
28259  * @param test_case_index  Index of test case
28260  * @param stage            Shader stage
28261  * @param out_assignments  Set to empty
28262  * @param out_calculations Set to empty
28263  **/
28264 void XFBExplicitLocationStructTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
28265                                                   std::string &out_assignments, std::string &out_calculations)
28266 {
28267     const testCase &test_case = m_test_cases[test_case_index];
28268 
28269     out_calculations = "";
28270 
28271     static const GLchar *vs_tes_gs        = "    goku = uni_goku;\n";
28272     static const GLchar *vs_tes_gs_nested = "    goku.inner_struct_a = uni_goku;\n"
28273                                             "    goku.inner_struct_b = uni_goku;\n";
28274 
28275     const GLchar *assignments = "";
28276 
28277     if (test_case.m_stage == stage)
28278     {
28279         switch (stage)
28280         {
28281         case Utils::Shader::GEOMETRY:
28282         case Utils::Shader::TESS_EVAL:
28283         case Utils::Shader::VERTEX:
28284             if (test_case.m_nested_struct)
28285             {
28286                 assignments = vs_tes_gs_nested;
28287             }
28288             else
28289             {
28290                 assignments = vs_tes_gs;
28291             }
28292             break;
28293         default:
28294             TCU_FAIL("Invalid enum");
28295         }
28296     }
28297     else
28298     {
28299         switch (stage)
28300         {
28301         case Utils::Shader::FRAGMENT:
28302             assignments = "";
28303             break;
28304         case Utils::Shader::GEOMETRY:
28305         case Utils::Shader::TESS_CTRL:
28306         case Utils::Shader::TESS_EVAL:
28307         case Utils::Shader::VERTEX:
28308             break;
28309         default:
28310             TCU_FAIL("Invalid enum");
28311         }
28312     }
28313 
28314     out_assignments = assignments;
28315 }
28316 
28317 /** Get interface of shader
28318  *
28319  * @param test_case_index  Index of test case
28320  * @param stage            Shader stage
28321  * @param out_interface    Set to ""
28322  **/
28323 void XFBExplicitLocationStructTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
28324                                                        std::string &out_interface)
28325 {
28326     static const GLchar *vs_tes_gs = "struct TestStruct {\n"
28327                                      "STRUCT_MEMBERS"
28328                                      "};\n"
28329                                      "layout (location = 0, xfb_offset = 0) flat out TestStruct goku;\n"
28330                                      "\n"
28331                                      "layout(std140, binding = 0) uniform Goku {\n"
28332                                      "    TestStruct uni_goku;\n"
28333                                      "};\n";
28334 
28335     static const GLchar *vs_tes_gs_nested = "struct TestStruct {\n"
28336                                             "STRUCT_MEMBERS"
28337                                             "};\n"
28338                                             "struct OuterStruct {\n"
28339                                             "    TestStruct inner_struct_a;\n"
28340                                             "    TestStruct inner_struct_b;\n"
28341                                             "};\n"
28342                                             "layout (location = 0, xfb_offset = 0) flat out OuterStruct goku;\n"
28343                                             "\n"
28344                                             "layout(std140, binding = 0) uniform Goku {\n"
28345                                             "    TestStruct uni_goku;\n"
28346                                             "};\n";
28347 
28348     const testCase &test_case = m_test_cases[test_case_index];
28349     const GLchar *interface   = "";
28350 
28351     if (test_case.m_stage == stage)
28352     {
28353         switch (stage)
28354         {
28355         case Utils::Shader::GEOMETRY:
28356         case Utils::Shader::TESS_EVAL:
28357         case Utils::Shader::VERTEX:
28358             if (test_case.m_nested_struct)
28359             {
28360                 interface = vs_tes_gs_nested;
28361             }
28362             else
28363             {
28364                 interface = vs_tes_gs;
28365             }
28366             break;
28367         default:
28368             TCU_FAIL("Invalid enum");
28369         }
28370     }
28371     else
28372     {
28373         switch (stage)
28374         {
28375         case Utils::Shader::FRAGMENT:
28376             interface = "";
28377             break;
28378         case Utils::Shader::GEOMETRY:
28379         case Utils::Shader::TESS_CTRL:
28380         case Utils::Shader::TESS_EVAL:
28381         case Utils::Shader::VERTEX:
28382             break;
28383         default:
28384             TCU_FAIL("Invalid enum");
28385         }
28386     }
28387 
28388     out_interface = interface;
28389 
28390     std::stringstream stream;
28391 
28392     char member_name = 'a';
28393     for (const testType &type : test_case.m_types)
28394     {
28395         stream << "   " << type.m_type.GetGLSLTypeName() << " " << member_name++;
28396         if (type.m_array_size > 0)
28397         {
28398             stream << "[" << type.m_array_size << "]";
28399         }
28400         stream << ";\n";
28401     }
28402 
28403     Utils::replaceAllTokens("STRUCT_MEMBERS", stream.str().c_str(), out_interface);
28404 }
28405 
28406 /** Get source code of shader
28407  *
28408  * @param test_case_index Index of test case
28409  * @param stage           Shader stage
28410  *
28411  * @return Source
28412  **/
28413 std::string XFBExplicitLocationStructTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
28414 {
28415     std::string source;
28416     const testCase &test_case = m_test_cases[test_case_index];
28417 
28418     switch (test_case.m_stage)
28419     {
28420     case Utils::Shader::VERTEX:
28421         switch (stage)
28422         {
28423         case Utils::Shader::FRAGMENT:
28424         case Utils::Shader::VERTEX:
28425             source = BufferTestBase::getShaderSource(test_case_index, stage);
28426             break;
28427         default:
28428             break;
28429         }
28430         break;
28431 
28432     case Utils::Shader::TESS_EVAL:
28433         switch (stage)
28434         {
28435         case Utils::Shader::FRAGMENT:
28436         case Utils::Shader::TESS_CTRL:
28437         case Utils::Shader::TESS_EVAL:
28438         case Utils::Shader::VERTEX:
28439             source = BufferTestBase::getShaderSource(test_case_index, stage);
28440             break;
28441         default:
28442             break;
28443         }
28444         break;
28445 
28446     case Utils::Shader::GEOMETRY:
28447         source = BufferTestBase::getShaderSource(test_case_index, stage);
28448         break;
28449 
28450     default:
28451         TCU_FAIL("Invalid enum");
28452     }
28453 
28454     /* */
28455     return source;
28456 }
28457 
28458 /** Get name of test case
28459  *
28460  * @param test_case_index Index of test case
28461  *
28462  * @return Name of tested stage
28463  **/
28464 std::string XFBExplicitLocationStructTest::getTestCaseName(glw::GLuint test_case_index)
28465 {
28466     std::stringstream stream;
28467     const testCase &test_case = m_test_cases[test_case_index];
28468 
28469     stream << "Struct: { ";
28470 
28471     for (const testType &type : test_case.m_types)
28472     {
28473         stream << type.m_type.GetGLSLTypeName() << "@" << type.m_array_size << ", ";
28474     }
28475 
28476     stream << "}, stage: " << Utils::Shader::GetStageName(test_case.m_stage);
28477 
28478     return stream.str();
28479 }
28480 
28481 /** Returns number of test cases
28482  *
28483  * @return TEST_MAX
28484  **/
28485 glw::GLuint XFBExplicitLocationStructTest::getTestCaseNumber()
28486 {
28487     return static_cast<GLuint>(m_test_cases.size());
28488 }
28489 
28490 /** Prepare all test cases
28491  *
28492  **/
28493 void XFBExplicitLocationStructTest::testInit()
28494 {
28495     for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
28496     {
28497         if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::FRAGMENT == stage) ||
28498             (Utils::Shader::TESS_CTRL == stage))
28499         {
28500             continue;
28501         }
28502 
28503         const GLuint n_types = getTypesNumber();
28504 
28505         for (GLuint i = 0; i < n_types; ++i)
28506         {
28507             const Utils::Type &type = getType(i);
28508 
28509             m_test_cases.push_back(
28510                 testCase{(Utils::Shader::STAGES)stage, {{Utils::Type::_float, 0}, {type, 0}}, false});
28511         }
28512 
28513         for (bool is_nested_struct : {false, true})
28514         {
28515             m_test_cases.push_back(
28516                 testCase{(Utils::Shader::STAGES)stage,
28517                          {{Utils::Type::_double, 0}, {Utils::Type::dvec2, 0}, {Utils::Type::dmat3, 0}},
28518                          is_nested_struct});
28519             m_test_cases.push_back(testCase{
28520                 (Utils::Shader::STAGES)stage, {{Utils::Type::_double, 0}, {Utils::Type::vec3, 0}}, is_nested_struct});
28521             m_test_cases.push_back(testCase{
28522                 (Utils::Shader::STAGES)stage, {{Utils::Type::dvec3, 0}, {Utils::Type::mat4x3, 0}}, is_nested_struct});
28523             m_test_cases.push_back(testCase{(Utils::Shader::STAGES)stage,
28524                                             {{Utils::Type::_float, 0},
28525                                              {Utils::Type::dvec3, 0},
28526                                              {Utils::Type::_float, 0},
28527                                              {Utils::Type::_double, 0}},
28528                                             is_nested_struct});
28529             m_test_cases.push_back(testCase{
28530                 (Utils::Shader::STAGES)stage,
28531                 {{Utils::Type::vec2, 0}, {Utils::Type::dvec3, 0}, {Utils::Type::_float, 0}, {Utils::Type::_double, 0}},
28532                 is_nested_struct});
28533             m_test_cases.push_back(testCase{
28534                 (Utils::Shader::STAGES)stage,
28535                 {{Utils::Type::_double, 0}, {Utils::Type::_float, 0}, {Utils::Type::dvec2, 0}, {Utils::Type::vec3, 0}},
28536                 is_nested_struct});
28537             m_test_cases.push_back(testCase{(Utils::Shader::STAGES)stage,
28538                                             {{Utils::Type::dmat3x4, 0},
28539                                              {Utils::Type::_double, 0},
28540                                              {Utils::Type::_float, 0},
28541                                              {Utils::Type::dvec2, 0}},
28542                                             is_nested_struct});
28543 
28544             m_test_cases.push_back(
28545                 testCase{(Utils::Shader::STAGES)stage,
28546                          {{Utils::Type::_float, 3}, {Utils::Type::dvec3, 0}, {Utils::Type::_double, 2}},
28547                          is_nested_struct});
28548             m_test_cases.push_back(testCase{(Utils::Shader::STAGES)stage,
28549                                             {{Utils::Type::_int, 1},
28550                                              {Utils::Type::_double, 1},
28551                                              {Utils::Type::_float, 1},
28552                                              {Utils::Type::dmat2x4, 1}},
28553                                             is_nested_struct});
28554             m_test_cases.push_back(testCase{
28555                 (Utils::Shader::STAGES)stage,
28556                 {{Utils::Type::_int, 5}, {Utils::Type::dvec3, 2}, {Utils::Type::uvec3, 0}, {Utils::Type::_double, 1}},
28557                 is_nested_struct});
28558             m_test_cases.push_back(
28559                 testCase{(Utils::Shader::STAGES)stage,
28560                          {{Utils::Type::mat2x3, 3}, {Utils::Type::uvec4, 1}, {Utils::Type::dvec4, 0}},
28561                          is_nested_struct});
28562         }
28563 
28564         m_test_cases.push_back(testCase{(Utils::Shader::STAGES)stage,
28565                                         {{Utils::Type::dmat2x3, 2}, {Utils::Type::mat2x3, 2}, {Utils::Type::dvec2, 0}},
28566                                         false});
28567     }
28568 }
28569 } // namespace EnhancedLayouts
28570 
28571 /** Constructor.
28572  *
28573  *  @param context Rendering context.
28574  **/
EnhancedLayoutsTests(deqp::Context & context)28575 EnhancedLayoutsTests::EnhancedLayoutsTests(deqp::Context &context)
28576     : TestCaseGroup(context, "enhanced_layouts", "Verifies \"enhanced layouts\" functionality")
28577 {
28578     /* Left blank on purpose */
28579 }
28580 
28581 /** Initializes a texture_storage_multisample test group.
28582  *
28583  **/
init(void)28584 void EnhancedLayoutsTests::init(void)
28585 {
28586     addChild(new EnhancedLayouts::APIConstantValuesTest(m_context));
28587     addChild(new EnhancedLayouts::APIErrorsTest(m_context));
28588     addChild(new EnhancedLayouts::GLSLContantValuesTest(m_context));
28589     addChild(new EnhancedLayouts::GLSLContantImmutablityTest(m_context));
28590     addChild(new EnhancedLayouts::GLSLConstantIntegralExpressionTest(m_context));
28591     addChild(new EnhancedLayouts::UniformBlockLayoutQualifierConflictTest(m_context));
28592     addChild(new EnhancedLayouts::SSBMemberInvalidOffsetAlignmentTest(m_context));
28593     addChild(new EnhancedLayouts::SSBMemberOverlappingOffsetsTest(m_context));
28594     addChild(new EnhancedLayouts::VaryingInvalidValueComponentTest(m_context));
28595     addChild(new EnhancedLayouts::VaryingExceedingComponentsTest(m_context));
28596     addChild(new EnhancedLayouts::VaryingComponentOfInvalidTypeTest(m_context));
28597     addChild(new EnhancedLayouts::OutputComponentAliasingTest(m_context));
28598     addChild(new EnhancedLayouts::VertexAttribLocationAPITest(m_context));
28599     addChild(new EnhancedLayouts::XFBInputTest(m_context));
28600     addChild(new EnhancedLayouts::XFBAllStagesTest(m_context));
28601     addChild(new EnhancedLayouts::XFBCaptureInactiveOutputVariableTest(m_context));
28602     addChild(new EnhancedLayouts::XFBCaptureInactiveOutputComponentTest(m_context));
28603     addChild(new EnhancedLayouts::XFBCaptureInactiveOutputBlockMemberTest(m_context));
28604     addChild(new EnhancedLayouts::XFBStrideTest(m_context));
28605 
28606     addChild(new EnhancedLayouts::UniformBlockMemberOffsetAndAlignTest(m_context));
28607     addChild(new EnhancedLayouts::UniformBlockMemberInvalidOffsetAlignmentTest(m_context));
28608     addChild(new EnhancedLayouts::UniformBlockMemberOverlappingOffsetsTest(m_context));
28609     addChild(new EnhancedLayouts::UniformBlockMemberAlignNonPowerOf2Test(m_context));
28610     addChild(new EnhancedLayouts::SSBLayoutQualifierConflictTest(m_context));
28611     addChild(new EnhancedLayouts::SSBMemberAlignNonPowerOf2Test(m_context));
28612     addChild(new EnhancedLayouts::SSBAlignmentTest(m_context));
28613     addChild(new EnhancedLayouts::VaryingStructureMemberLocationTest(m_context));
28614     addChild(new EnhancedLayouts::VaryingBlockAutomaticMemberLocationsTest(m_context));
28615     addChild(new EnhancedLayouts::VaryingComponentWithoutLocationTest(m_context));
28616     addChild(new EnhancedLayouts::InputComponentAliasingTest(m_context));
28617     addChild(new EnhancedLayouts::VaryingLocationAliasingWithMixedTypesTest(m_context));
28618     addChild(new EnhancedLayouts::VaryingLocationAliasingWithMixedInterpolationTest(m_context));
28619     addChild(new EnhancedLayouts::VaryingLocationAliasingWithMixedAuxiliaryStorageTest(m_context));
28620     addChild(new EnhancedLayouts::XFBStrideOfEmptyListTest(m_context));
28621     addChild(new EnhancedLayouts::XFBStrideOfEmptyListAndAPITest(m_context));
28622     addChild(new EnhancedLayouts::XFBTooSmallStrideTest(m_context));
28623     addChild(new EnhancedLayouts::XFBBlockMemberStrideTest(m_context));
28624     addChild(new EnhancedLayouts::XFBDuplicatedStrideTest(m_context));
28625     addChild(new EnhancedLayouts::XFBGetProgramResourceAPITest(m_context));
28626     addChild(new EnhancedLayouts::XFBMultipleVertexStreamsTest(m_context));
28627     addChild(new EnhancedLayouts::XFBExceedBufferLimitTest(m_context));
28628     addChild(new EnhancedLayouts::XFBExceedOffsetLimitTest(m_context));
28629     addChild(new EnhancedLayouts::XFBBlockMemberBufferTest(m_context));
28630     addChild(new EnhancedLayouts::XFBOutputOverlappingTest(m_context));
28631     addChild(new EnhancedLayouts::XFBInvalidOffsetAlignmentTest(m_context));
28632     addChild(new EnhancedLayouts::XFBCaptureStructTest(m_context));
28633     addChild(new EnhancedLayouts::XFBCaptureUnsizedArrayTest(m_context));
28634     addChild(new EnhancedLayouts::UniformBlockAlignmentTest(m_context));
28635     addChild(new EnhancedLayouts::SSBMemberOffsetAndAlignTest(m_context));
28636     addChild(new EnhancedLayouts::VertexAttribLocationsTest(m_context));
28637     addChild(new EnhancedLayouts::VaryingLocationsTest(m_context));
28638     addChild(new EnhancedLayouts::VaryingArrayLocationsTest(m_context));
28639     addChild(new EnhancedLayouts::VaryingStructureLocationsTest(m_context));
28640     addChild(new EnhancedLayouts::VaryingBlockLocationsTest(m_context));
28641     addChild(new EnhancedLayouts::VaryingBlockMemberLocationsTest(m_context));
28642     addChild(new EnhancedLayouts::XFBVariableStrideTest(m_context));
28643     addChild(new EnhancedLayouts::XFBBlockStrideTest(m_context));
28644     addChild(new EnhancedLayouts::XFBOverrideQualifiersWithAPITest(m_context));
28645     addChild(new EnhancedLayouts::XFBVertexStreamsTest(m_context));
28646     addChild(new EnhancedLayouts::XFBGlobalBufferTest(m_context));
28647     addChild(new EnhancedLayouts::XFBExplicitLocationTest(m_context));
28648     addChild(new EnhancedLayouts::XFBExplicitLocationStructTest(m_context));
28649     addChild(new EnhancedLayouts::FragmentDataLocationAPITest(m_context));
28650     addChild(new EnhancedLayouts::VaryingLocationLimitTest(m_context));
28651     addChild(new EnhancedLayouts::VaryingComponentsTest(m_context));
28652     addChild(new EnhancedLayouts::VaryingArrayComponentsTest(m_context));
28653 }
28654 
28655 } // namespace gl4cts
28656