• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "gluStrUtil.hpp"
34 #include "glwEnums.hpp"
35 #include "glwFunctions.hpp"
36 #include "tcuTestLog.hpp"
37 
38 #include <algorithm>
39 #include <iomanip>
40 #include <string>
41 #include <vector>
42 
43 /* DEBUG */
44 #define USE_NSIGHT 0
45 #define DEBUG_ENBALE_MESSAGE_CALLBACK 0
46 #define DEBUG_NEG_LOG_ERROR 0
47 #define DEBUG_REPLACE_TOKEN 0
48 #define DEBUG_REPEAT_TEST_CASE 0
49 #define DEBUG_REPEATED_TEST_CASE 0
50 
51 /* Texture test base */
52 #define DEBUG_TTB_VERIFICATION_SNIPPET_STAGE 0
53 #define DEBUG_TTB_VERIFICATION_SNIPPET_VARIABLE 0
54 
55 /* Tests */
56 #define DEBUG_VERTEX_ATTRIB_LOCATIONS_TEST_VARIABLE 0
57 
58 /* WORKAROUNDS */
59 #define WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST 0
60 #define WRKARD_UNIFORMBLOCKMEMBERALIGNNONPOWEROF2TEST 0
61 #define WRKARD_UNIFORMBLOCKALIGNMENT 0
62 #define WRKARD_VARYINGLOCATIONSTEST 0
63 
64 using namespace glw;
65 
66 namespace gl4cts
67 {
68 namespace EnhancedLayouts
69 {
70 namespace Utils
71 {
72 /** Constants used by "random" generators **/
73 static const GLuint s_rand_start	= 3;
74 static const GLuint s_rand_max		= 16;
75 static const GLuint s_rand_max_half = s_rand_max / 2;
76 
77 /** Seed used by "random" generators **/
78 static GLuint s_rand = s_rand_start;
79 
80 /** Get "random" unsigned int value
81  *
82  * @return Value
83  **/
GetRandUint()84 static GLuint GetRandUint()
85 {
86 	const GLuint rand = s_rand++;
87 
88 	if (s_rand_max <= s_rand)
89 	{
90 		s_rand = s_rand_start;
91 	}
92 
93 	return rand;
94 }
95 
96 /** Get "random" int value
97  *
98  * @return Value
99  **/
GetRandInt()100 GLint GetRandInt()
101 {
102 	const GLint rand = GetRandUint() - s_rand_max_half;
103 
104 	return rand;
105 }
106 
107 /** Get "random" double value
108  *
109  * @return Value
110  **/
GetRandDouble()111 GLdouble GetRandDouble()
112 {
113 	const GLint rand = GetRandInt();
114 
115 	GLdouble result = (GLfloat)rand / (GLdouble)s_rand_max_half;
116 
117 	return result;
118 }
119 
120 /** Get "random" float value
121  *
122  * @return Value
123  **/
GetRandFloat()124 GLfloat GetRandFloat()
125 {
126 	const GLint rand = GetRandInt();
127 
128 	GLfloat result = (GLfloat)rand / (GLfloat)s_rand_max_half;
129 
130 	return result;
131 }
132 
133 /** String used by list routines **/
134 static const GLchar* const g_list = "LIST";
135 
136 /** Type constants **/
137 const Type Type::_double = Type::GetType(Type::Double, 1, 1);
138 const Type Type::dmat2   = Type::GetType(Type::Double, 2, 2);
139 const Type Type::dmat2x3 = Type::GetType(Type::Double, 2, 3);
140 const Type Type::dmat2x4 = Type::GetType(Type::Double, 2, 4);
141 const Type Type::dmat3x2 = Type::GetType(Type::Double, 3, 2);
142 const Type Type::dmat3   = Type::GetType(Type::Double, 3, 3);
143 const Type Type::dmat3x4 = Type::GetType(Type::Double, 3, 4);
144 const Type Type::dmat4x2 = Type::GetType(Type::Double, 4, 2);
145 const Type Type::dmat4x3 = Type::GetType(Type::Double, 4, 3);
146 const Type Type::dmat4   = Type::GetType(Type::Double, 4, 4);
147 const Type Type::dvec2   = Type::GetType(Type::Double, 1, 2);
148 const Type Type::dvec3   = Type::GetType(Type::Double, 1, 3);
149 const Type Type::dvec4   = Type::GetType(Type::Double, 1, 4);
150 const Type Type::_int	= Type::GetType(Type::Int, 1, 1);
151 const Type Type::ivec2   = Type::GetType(Type::Int, 1, 2);
152 const Type Type::ivec3   = Type::GetType(Type::Int, 1, 3);
153 const Type Type::ivec4   = Type::GetType(Type::Int, 1, 4);
154 const Type Type::_float  = Type::GetType(Type::Float, 1, 1);
155 const Type Type::mat2	= Type::GetType(Type::Float, 2, 2);
156 const Type Type::mat2x3  = Type::GetType(Type::Float, 2, 3);
157 const Type Type::mat2x4  = Type::GetType(Type::Float, 2, 4);
158 const Type Type::mat3x2  = Type::GetType(Type::Float, 3, 2);
159 const Type Type::mat3	= Type::GetType(Type::Float, 3, 3);
160 const Type Type::mat3x4  = Type::GetType(Type::Float, 3, 4);
161 const Type Type::mat4x2  = Type::GetType(Type::Float, 4, 2);
162 const Type Type::mat4x3  = Type::GetType(Type::Float, 4, 3);
163 const Type Type::mat4	= Type::GetType(Type::Float, 4, 4);
164 const Type Type::vec2	= Type::GetType(Type::Float, 1, 2);
165 const Type Type::vec3	= Type::GetType(Type::Float, 1, 3);
166 const Type Type::vec4	= Type::GetType(Type::Float, 1, 4);
167 const Type Type::uint	= Type::GetType(Type::Uint, 1, 1);
168 const Type Type::uvec2   = Type::GetType(Type::Uint, 1, 2);
169 const Type Type::uvec3   = Type::GetType(Type::Uint, 1, 3);
170 const Type Type::uvec4   = Type::GetType(Type::Uint, 1, 4);
171 
172 /** Generate data for type. This routine follows STD140 rules
173  *
174  * @return Vector of bytes filled with data
175  **/
GenerateData() const176 std::vector<GLubyte> Type::GenerateData() const
177 {
178 	const GLuint alignment = GetActualAlignment(0, false);
179 
180 	std::vector<GLubyte> data;
181 	data.resize(alignment * m_n_columns);
182 
183 	for (GLuint column = 0; column < m_n_columns; ++column)
184 	{
185 		GLvoid* ptr = (GLvoid*)&data[column * alignment];
186 
187 		switch (m_basic_type)
188 		{
189 		case Double:
190 		{
191 			GLdouble* d_ptr = (GLdouble*)ptr;
192 
193 			for (GLuint i = 0; i < m_n_rows; ++i)
194 			{
195 				d_ptr[i] = GetRandDouble();
196 			}
197 		}
198 		break;
199 		case Float:
200 		{
201 			GLfloat* f_ptr = (GLfloat*)ptr;
202 
203 			for (GLuint i = 0; i < m_n_rows; ++i)
204 			{
205 				f_ptr[i] = GetRandFloat();
206 			}
207 		}
208 		break;
209 		case Int:
210 		{
211 			GLint* i_ptr = (GLint*)ptr;
212 
213 			for (GLuint i = 0; i < m_n_rows; ++i)
214 			{
215 				i_ptr[i] = GetRandInt();
216 			}
217 		}
218 		break;
219 		case Uint:
220 		{
221 			GLuint* ui_ptr = (GLuint*)ptr;
222 
223 			for (GLuint i = 0; i < m_n_rows; ++i)
224 			{
225 				ui_ptr[i] = GetRandUint();
226 			}
227 		}
228 		break;
229 		}
230 	}
231 
232 	return data;
233 }
234 
235 /** Generate data for type. This routine packs data tightly.
236  *
237  * @return Vector of bytes filled with data
238  **/
GenerateDataPacked() const239 std::vector<GLubyte> Type::GenerateDataPacked() const
240 {
241 	const GLuint basic_size = GetTypeSize(m_basic_type);
242 	const GLuint n_elements = m_n_columns * m_n_rows;
243 	const GLuint size		= basic_size * n_elements;
244 
245 	std::vector<GLubyte> data;
246 	data.resize(size);
247 
248 	GLvoid* ptr = (GLvoid*)&data[0];
249 
250 	switch (m_basic_type)
251 	{
252 	case Double:
253 	{
254 		GLdouble* d_ptr = (GLdouble*)ptr;
255 
256 		for (GLuint i = 0; i < n_elements; ++i)
257 		{
258 			d_ptr[i] = GetRandDouble();
259 		}
260 	}
261 	break;
262 	case Float:
263 	{
264 		GLfloat* f_ptr = (GLfloat*)ptr;
265 
266 		for (GLuint i = 0; i < n_elements; ++i)
267 		{
268 			f_ptr[i] = GetRandFloat();
269 		}
270 	}
271 	break;
272 	case Int:
273 	{
274 		GLint* i_ptr = (GLint*)ptr;
275 
276 		for (GLuint i = 0; i < n_elements; ++i)
277 		{
278 			i_ptr[i] = GetRandInt();
279 		}
280 	}
281 	break;
282 	case Uint:
283 	{
284 		GLuint* ui_ptr = (GLuint*)ptr;
285 
286 		for (GLuint i = 0; i < n_elements; ++i)
287 		{
288 			ui_ptr[i] = GetRandUint();
289 		}
290 	}
291 	break;
292 	}
293 
294 	return data;
295 }
296 
297 /** Calculate "actual alignment". It work under assumption that align value is valid
298  *
299  * @param align    Requested alignment, eg with "align" qualifier
300  * @param is_array Selects if an array of type or single instance should be considered
301  *
302  * @return Calculated value
303  **/
GetActualAlignment(GLuint align,bool is_array) const304 GLuint Type::GetActualAlignment(GLuint align, bool is_array) const
305 {
306 	const GLuint base_alignment = GetBaseAlignment(is_array);
307 
308 	return std::max(align, base_alignment);
309 }
310 
311 /** Align given ofset with specified alignment
312  *
313  * @param offset    Offset
314  * @param alignment Alignment
315  *
316  * @return Calculated value
317  **/
align(GLuint offset,GLuint alignment)318 GLuint align(GLuint offset, GLuint alignment)
319 {
320 	const GLuint rest = offset % alignment;
321 
322 	if (0 != rest)
323 	{
324 		GLuint missing = alignment - rest;
325 		offset += missing;
326 	}
327 
328 	return offset;
329 }
330 
331 /** Calculate "actual offset"
332  *
333  * @param start_offset     Requested offset
334  * @param actual_alignment Actual alignemnt
335  *
336  * @return Calculated value
337  **/
GetActualOffset(GLuint start_offset,GLuint actual_alignment)338 GLuint Type::GetActualOffset(GLuint start_offset, GLuint actual_alignment)
339 {
340 	GLuint offset = align(start_offset, actual_alignment);
341 
342 	return offset;
343 }
344 
345 /** Calculate "base alignment" for given type
346  *
347  * @param is_array Select if array or single instance should be considered
348  *
349  * @return Calculated value
350  **/
GetBaseAlignment(bool is_array) const351 GLuint Type::GetBaseAlignment(bool is_array) const
352 {
353 	GLuint elements = 1;
354 
355 	switch (m_n_rows)
356 	{
357 	case 2:
358 		elements = 2;
359 		break;
360 	case 3:
361 	case 4:
362 		elements = 4;
363 		break;
364 	default:
365 		break;
366 	}
367 
368 	GLuint N		 = GetTypeSize(m_basic_type);
369 	GLuint alignment = N * elements;
370 
371 	if ((true == is_array) || (1 != m_n_columns))
372 	{
373 		alignment = align(alignment, 16 /* vec4 alignment */);
374 	}
375 
376 	return alignment;
377 }
378 
379 /** Returns string representing GLSL constructor of type with arguments provided in data
380  *
381  * @param data Array of values that will be used as construcotr arguments.
382  *             It is interpreted as tightly packed array of type matching this type.
383  *
384  * @return String in form "Type(args)"
385  **/
GetGLSLConstructor(const GLvoid * data) const386 std::string Type::GetGLSLConstructor(const GLvoid* data) const
387 {
388 	const GLchar* type = GetGLSLTypeName();
389 
390 	std::stringstream stream;
391 
392 	stream << type << "(";
393 
394 	/* Scalar or vector */
395 	if (1 == m_n_columns)
396 	{
397 		for (GLuint row = 0; row < m_n_rows; ++row)
398 		{
399 			switch (m_basic_type)
400 			{
401 			case Double:
402 				stream << ((GLdouble*)data)[row];
403 				break;
404 			case Float:
405 				stream << ((GLfloat*)data)[row];
406 				break;
407 			case Int:
408 				stream << ((GLint*)data)[row];
409 				break;
410 			case Uint:
411 				stream << ((GLuint*)data)[row];
412 				break;
413 			}
414 
415 			if (row + 1 != m_n_rows)
416 			{
417 				stream << ", ";
418 			}
419 		}
420 	}
421 	else /* Matrix: mat(vec(), vec() .. ) */
422 	{
423 		const GLuint basic_size = GetTypeSize(m_basic_type);
424 		// Very indescoverable defect, the column stride should be calculated by rows, such as mat2x3, which is 2, columns 3 rows, its column stride should be 3 * sizeof(float)
425 		const GLuint column_stride = m_n_rows * basic_size;
426 		const Type   column_type   = GetType(m_basic_type, 1, m_n_rows);
427 
428 		for (GLuint column = 0; column < m_n_columns; ++column)
429 		{
430 			const GLuint  column_offset = column * column_stride;
431 			const GLvoid* column_data   = (GLubyte*)data + column_offset;
432 
433 			stream << column_type.GetGLSLConstructor(column_data);
434 
435 			if (column + 1 != m_n_columns)
436 			{
437 				stream << ", ";
438 			}
439 		}
440 	}
441 
442 	stream << ")";
443 
444 	return stream.str();
445 }
446 
447 /** Get glsl name of the type
448  *
449  * @return Name of glsl type
450  **/
GetGLSLTypeName() const451 const glw::GLchar* Type::GetGLSLTypeName() const
452 {
453 	static const GLchar* float_lut[4][4] = {
454 		{ "float", "vec2", "vec3", "vec4" },
455 		{ 0, "mat2", "mat2x3", "mat2x4" },
456 		{ 0, "mat3x2", "mat3", "mat3x4" },
457 		{ 0, "mat4x2", "mat4x3", "mat4" },
458 	};
459 
460 	static const GLchar* double_lut[4][4] = {
461 		{ "double", "dvec2", "dvec3", "dvec4" },
462 		{ 0, "dmat2", "dmat2x3", "dmat2x4" },
463 		{ 0, "dmat3x2", "dmat3", "dmat3x4" },
464 		{ 0, "dmat4x2", "dmat4x3", "dmat4" },
465 	};
466 
467 	static const GLchar* int_lut[4] = { "int", "ivec2", "ivec3", "ivec4" };
468 
469 	static const GLchar* uint_lut[4] = { "uint", "uvec2", "uvec3", "uvec4" };
470 
471 	const GLchar* result = 0;
472 
473 	if ((1 > m_n_columns) || (1 > m_n_rows) || (4 < m_n_columns) || (4 < m_n_rows))
474 	{
475 		return 0;
476 	}
477 
478 	switch (m_basic_type)
479 	{
480 	case Float:
481 		result = float_lut[m_n_columns - 1][m_n_rows - 1];
482 		break;
483 	case Double:
484 		result = double_lut[m_n_columns - 1][m_n_rows - 1];
485 		break;
486 	case Int:
487 		result = int_lut[m_n_rows - 1];
488 		break;
489 	case Uint:
490 		result = uint_lut[m_n_rows - 1];
491 		break;
492 	default:
493 		TCU_FAIL("Invliad enum");
494 	}
495 
496 	return result;
497 }
498 
499 /** Get number of locations required for the type
500  *
501  * @return Number of columns times:
502  *          - 2 when type is double with 3 or 4 rows,
503  *          - 1 otherwise or if it's a vertex shader input.
504  **/
GetLocations(bool is_vs_input) const505 GLuint Type::GetLocations(bool is_vs_input) const
506 {
507 	GLuint n_loc_per_column;
508 
509 	/* 1 or 2 doubles any for rest */
510 	if ((2 >= m_n_rows) || (Double != m_basic_type) || is_vs_input)
511 	{
512 		n_loc_per_column = 1;
513 	}
514 	else
515 	{
516 		/* 3 and 4 doubles */
517 		n_loc_per_column = 2;
518 	}
519 
520 	return n_loc_per_column * m_n_columns;
521 }
522 
523 /** Get size of the type in bytes.
524  * Note that this routine doesn't consider arrays and assumes
525  * column_major matrices.
526  *
527  * @return Formula:
528  *          - If std140 packaging and matrix; number of columns * base alignment
529  *          - Otherwise; number of elements * sizeof(base_type)
530  **/
GetSize(const bool is_std140) const531 GLuint Type::GetSize(const bool is_std140) const
532 {
533 	const GLuint basic_type_size = GetTypeSize(m_basic_type);
534 	const GLuint n_elements		 = m_n_columns * m_n_rows;
535 
536 	if (is_std140 && m_n_columns > 1)
537 	{
538 		return m_n_columns * GetBaseAlignment(false);
539 	}
540 
541 	return basic_type_size * n_elements;
542 }
543 
544 /** Get GLenum representing the type
545  *
546  * @return GLenum
547  **/
GetTypeGLenum() const548 GLenum Type::GetTypeGLenum() const
549 {
550 	static const GLenum float_lut[4][4] = {
551 		{ GL_FLOAT, GL_FLOAT_VEC2, GL_FLOAT_VEC3, GL_FLOAT_VEC4 },
552 		{ 0, GL_FLOAT_MAT2, GL_FLOAT_MAT2x3, GL_FLOAT_MAT2x4 },
553 		{ 0, GL_FLOAT_MAT3x2, GL_FLOAT_MAT3, GL_FLOAT_MAT3x4 },
554 		{ 0, GL_FLOAT_MAT4x2, GL_FLOAT_MAT4x3, GL_FLOAT_MAT4 },
555 	};
556 
557 	static const GLenum double_lut[4][4] = {
558 		{ GL_DOUBLE, GL_DOUBLE_VEC2, GL_DOUBLE_VEC3, GL_DOUBLE_VEC4 },
559 		{ 0, GL_DOUBLE_MAT2, GL_DOUBLE_MAT2x3, GL_DOUBLE_MAT2x4 },
560 		{ 0, GL_DOUBLE_MAT3x2, GL_DOUBLE_MAT3, GL_DOUBLE_MAT3x4 },
561 		{ 0, GL_DOUBLE_MAT4x2, GL_DOUBLE_MAT4x3, GL_DOUBLE_MAT4 },
562 	};
563 
564 	static const GLenum int_lut[4] = { GL_INT, GL_INT_VEC2, GL_INT_VEC3, GL_INT_VEC4 };
565 
566 	static const GLenum uint_lut[4] = { GL_UNSIGNED_INT, GL_UNSIGNED_INT_VEC2, GL_UNSIGNED_INT_VEC3,
567 										GL_UNSIGNED_INT_VEC4 };
568 
569 	GLenum result = 0;
570 
571 	if ((1 > m_n_columns) || (1 > m_n_rows) || (4 < m_n_columns) || (4 < m_n_rows))
572 	{
573 		return 0;
574 	}
575 
576 	switch (m_basic_type)
577 	{
578 	case Float:
579 		result = float_lut[m_n_columns - 1][m_n_rows - 1];
580 		break;
581 	case Double:
582 		result = double_lut[m_n_columns - 1][m_n_rows - 1];
583 		break;
584 	case Int:
585 		result = int_lut[m_n_rows - 1];
586 		break;
587 	case Uint:
588 		result = uint_lut[m_n_rows - 1];
589 		break;
590 	default:
591 		TCU_FAIL("Invliad enum");
592 	}
593 
594 	return result;
595 }
596 
597 /** Calculate the numbe of components consumed by a type
598  *   according to 11.1.2.1 Output Variables
599  *
600  * @return Calculated number of components for the type
601  **/
GetNumComponents() const602 GLuint Type::GetNumComponents() const
603 {
604 	// Rule 3 of Section 7.6.2.2
605 	// If the member is a three-component vector with components consuming N
606 	// basic machine units, the base alignment is 4N.
607 	GLuint num_components = (m_n_rows == 3 ? 4 : m_n_rows) * m_n_columns;
608 
609 	if (m_basic_type == Double)
610 	{
611 		num_components *= 2;
612 	}
613 
614 	return num_components;
615 }
616 
617 /** Calculate stride for the type according to std140 rules
618  *
619  * @param alignment        Alignment of type
620  * @param n_columns        Number of columns
621  * @param n_array_elements Number of elements in array
622  *
623  * @return Calculated value
624  **/
CalculateStd140Stride(GLuint alignment,GLuint n_columns,GLuint n_array_elements)625 GLuint Type::CalculateStd140Stride(GLuint alignment, GLuint n_columns, GLuint n_array_elements)
626 {
627 	GLuint stride = alignment * n_columns;
628 	if (0 != n_array_elements)
629 	{
630 		stride *= n_array_elements;
631 	}
632 
633 	return stride;
634 }
635 
636 /** Check if glsl support matrices for specific basic type
637  *
638  * @param type Basic type
639  *
640  * @return true if matrices of <type> are supported, false otherwise
641  **/
DoesTypeSupportMatrix(TYPES type)642 bool Type::DoesTypeSupportMatrix(TYPES type)
643 {
644 	bool result = false;
645 
646 	switch (type)
647 	{
648 	case Float:
649 	case Double:
650 		result = true;
651 		break;
652 	case Int:
653 	case Uint:
654 		result = false;
655 		break;
656 	default:
657 		TCU_FAIL("Invliad enum");
658 	}
659 
660 	return result;
661 }
662 
663 /** Creates instance of Type
664  *
665  * @param basic_type Select basic type of instance
666  * @param n_columns  Number of columns
667  * @param n_rows     Number of rows
668  *
669  * @return Type instance
670  **/
GetType(TYPES basic_type,glw::GLuint n_columns,glw::GLuint n_rows)671 Type Type::GetType(TYPES basic_type, glw::GLuint n_columns, glw::GLuint n_rows)
672 {
673 	Type type = { basic_type, n_columns, n_rows };
674 
675 	return type;
676 }
677 
678 /** Get Size of given type in bytes
679  *
680  * @param type
681  *
682  * @return Size of type
683  **/
GetTypeSize(TYPES type)684 GLuint Type::GetTypeSize(TYPES type)
685 {
686 	GLuint result = 0;
687 
688 	switch (type)
689 	{
690 	case Float:
691 		result = sizeof(GLfloat);
692 		break;
693 	case Double:
694 		result = sizeof(GLdouble);
695 		break;
696 	case Int:
697 		result = sizeof(GLint);
698 		break;
699 	case Uint:
700 		result = sizeof(GLuint);
701 		break;
702 	default:
703 		TCU_FAIL("Invalid enum");
704 	}
705 
706 	return result;
707 }
708 
709 /** Get GLenum representing given type
710  *
711  * @param type
712  *
713  * @return GLenum value
714  **/
GetTypeGLenum(TYPES type)715 GLenum Type::GetTypeGLenum(TYPES type)
716 {
717 	GLenum result = 0;
718 
719 	switch (type)
720 	{
721 	case Float:
722 		result = GL_FLOAT;
723 		break;
724 	case Double:
725 		result = GL_DOUBLE;
726 		break;
727 	case Int:
728 		result = GL_INT;
729 		break;
730 	case Uint:
731 		result = GL_UNSIGNED_INT;
732 		break;
733 	default:
734 		TCU_FAIL("Invalid enum");
735 	}
736 
737 	return result;
738 }
739 
740 /** Get proper glUniformNdv routine for vectors with specified number of rows
741  *
742  * @param gl     GL functions
743  * @param n_rows Number of rows
744  *
745  * @return Function address
746  **/
getUniformNdv(const glw::Functions & gl,glw::GLuint n_rows)747 uniformNdv getUniformNdv(const glw::Functions& gl, glw::GLuint n_rows)
748 {
749 	uniformNdv result = 0;
750 
751 	switch (n_rows)
752 	{
753 	case 1:
754 		result = gl.uniform1dv;
755 		break;
756 	case 2:
757 		result = gl.uniform2dv;
758 		break;
759 	case 3:
760 		result = gl.uniform3dv;
761 		break;
762 	case 4:
763 		result = gl.uniform4dv;
764 		break;
765 	default:
766 		TCU_FAIL("Invalid number of rows");
767 	}
768 
769 	return result;
770 }
771 
772 /** Get proper glUniformNfv routine for vectors with specified number of rows
773  *
774  * @param gl     GL functions
775  * @param n_rows Number of rows
776  *
777  * @return Function address
778  **/
getUniformNfv(const glw::Functions & gl,glw::GLuint n_rows)779 uniformNfv getUniformNfv(const glw::Functions& gl, glw::GLuint n_rows)
780 {
781 	uniformNfv result = 0;
782 
783 	switch (n_rows)
784 	{
785 	case 1:
786 		result = gl.uniform1fv;
787 		break;
788 	case 2:
789 		result = gl.uniform2fv;
790 		break;
791 	case 3:
792 		result = gl.uniform3fv;
793 		break;
794 	case 4:
795 		result = gl.uniform4fv;
796 		break;
797 	default:
798 		TCU_FAIL("Invalid number of rows");
799 	}
800 
801 	return result;
802 }
803 
804 /** Get proper glUniformNiv routine for vectors with specified number of rows
805  *
806  * @param gl     GL functions
807  * @param n_rows Number of rows
808  *
809  * @return Function address
810  **/
getUniformNiv(const glw::Functions & gl,glw::GLuint n_rows)811 uniformNiv getUniformNiv(const glw::Functions& gl, glw::GLuint n_rows)
812 {
813 	uniformNiv result = 0;
814 
815 	switch (n_rows)
816 	{
817 	case 1:
818 		result = gl.uniform1iv;
819 		break;
820 	case 2:
821 		result = gl.uniform2iv;
822 		break;
823 	case 3:
824 		result = gl.uniform3iv;
825 		break;
826 	case 4:
827 		result = gl.uniform4iv;
828 		break;
829 	default:
830 		TCU_FAIL("Invalid number of rows");
831 	}
832 
833 	return result;
834 }
835 
836 /** Get proper glUniformNuiv routine for vectors with specified number of rows
837  *
838  * @param gl     GL functions
839  * @param n_rows Number of rows
840  *
841  * @return Function address
842  **/
getUniformNuiv(const glw::Functions & gl,glw::GLuint n_rows)843 uniformNuiv getUniformNuiv(const glw::Functions& gl, glw::GLuint n_rows)
844 {
845 	uniformNuiv result = 0;
846 
847 	switch (n_rows)
848 	{
849 	case 1:
850 		result = gl.uniform1uiv;
851 		break;
852 	case 2:
853 		result = gl.uniform2uiv;
854 		break;
855 	case 3:
856 		result = gl.uniform3uiv;
857 		break;
858 	case 4:
859 		result = gl.uniform4uiv;
860 		break;
861 	default:
862 		TCU_FAIL("Invalid number of rows");
863 	}
864 
865 	return result;
866 }
867 
868 /** Get proper glUniformMatrixNdv routine for matrix with specified number of columns and rows
869  *
870  * @param gl     GL functions
871  * @param n_rows Number of rows
872  *
873  * @return Function address
874  **/
getUniformMatrixNdv(const glw::Functions & gl,glw::GLuint n_columns,glw::GLuint n_rows)875 uniformMatrixNdv getUniformMatrixNdv(const glw::Functions& gl, glw::GLuint n_columns, glw::GLuint n_rows)
876 {
877 	uniformMatrixNdv result = 0;
878 
879 	switch (n_columns)
880 	{
881 	case 2:
882 		switch (n_rows)
883 		{
884 		case 2:
885 			result = gl.uniformMatrix2dv;
886 			break;
887 		case 3:
888 			result = gl.uniformMatrix2x3dv;
889 			break;
890 		case 4:
891 			result = gl.uniformMatrix2x4dv;
892 			break;
893 		default:
894 			TCU_FAIL("Invalid number of rows");
895 		}
896 		break;
897 	case 3:
898 		switch (n_rows)
899 		{
900 		case 2:
901 			result = gl.uniformMatrix3x2dv;
902 			break;
903 		case 3:
904 			result = gl.uniformMatrix3dv;
905 			break;
906 		case 4:
907 			result = gl.uniformMatrix3x4dv;
908 			break;
909 		default:
910 			TCU_FAIL("Invalid number of rows");
911 		}
912 		break;
913 	case 4:
914 		switch (n_rows)
915 		{
916 		case 2:
917 			result = gl.uniformMatrix4x2dv;
918 			break;
919 		case 3:
920 			result = gl.uniformMatrix4x3dv;
921 			break;
922 		case 4:
923 			result = gl.uniformMatrix4dv;
924 			break;
925 		default:
926 			TCU_FAIL("Invalid number of rows");
927 		}
928 		break;
929 	default:
930 		TCU_FAIL("Invalid number of columns");
931 	}
932 
933 	return result;
934 }
935 
936 /** Get proper glUniformMatrixNfv routine for vectors with specified number of columns and rows
937  *
938  * @param gl     GL functions
939  * @param n_rows Number of rows
940  *
941  * @return Function address
942  **/
getUniformMatrixNfv(const glw::Functions & gl,glw::GLuint n_columns,glw::GLuint n_rows)943 uniformMatrixNfv getUniformMatrixNfv(const glw::Functions& gl, glw::GLuint n_columns, glw::GLuint n_rows)
944 {
945 	uniformMatrixNfv result = 0;
946 
947 	switch (n_columns)
948 	{
949 	case 2:
950 		switch (n_rows)
951 		{
952 		case 2:
953 			result = gl.uniformMatrix2fv;
954 			break;
955 		case 3:
956 			result = gl.uniformMatrix2x3fv;
957 			break;
958 		case 4:
959 			result = gl.uniformMatrix2x4fv;
960 			break;
961 		default:
962 			TCU_FAIL("Invalid number of rows");
963 		}
964 		break;
965 	case 3:
966 		switch (n_rows)
967 		{
968 		case 2:
969 			result = gl.uniformMatrix3x2fv;
970 			break;
971 		case 3:
972 			result = gl.uniformMatrix3fv;
973 			break;
974 		case 4:
975 			result = gl.uniformMatrix3x4fv;
976 			break;
977 		default:
978 			TCU_FAIL("Invalid number of rows");
979 		}
980 		break;
981 	case 4:
982 		switch (n_rows)
983 		{
984 		case 2:
985 			result = gl.uniformMatrix4x2fv;
986 			break;
987 		case 3:
988 			result = gl.uniformMatrix4x3fv;
989 			break;
990 		case 4:
991 			result = gl.uniformMatrix4fv;
992 			break;
993 		default:
994 			TCU_FAIL("Invalid number of rows");
995 		}
996 		break;
997 	default:
998 		TCU_FAIL("Invalid number of columns");
999 	}
1000 
1001 	return result;
1002 }
1003 
verifyVarying(Program & program,const std::string & parent_name,const Variable::Descriptor & desc,std::stringstream & stream,bool is_input)1004 bool verifyVarying(Program& program, const std::string& parent_name, const Variable::Descriptor& desc,
1005 				   std::stringstream& stream, bool is_input)
1006 {
1007 	GLint  component = 0;
1008 	GLuint index	 = 0;
1009 	GLenum interface = GL_PROGRAM_INPUT;
1010 	GLint  location  = 0;
1011 
1012 	if (false == is_input)
1013 	{
1014 		interface = GL_PROGRAM_OUTPUT;
1015 	}
1016 
1017 	const std::string& name = Utils::Variable::GetReference(parent_name, desc, Utils::Variable::BASIC, 0);
1018 
1019 	try
1020 	{
1021 		index = program.GetResourceIndex(name, interface);
1022 
1023 		program.GetResource(interface, index, GL_LOCATION, 1 /* size */, &location);
1024 		program.GetResource(interface, index, GL_LOCATION_COMPONENT, 1 /* size */, &component);
1025 	}
1026 	catch (std::exception& exc)
1027 	{
1028 		stream << "Failed to query program for varying: " << desc.m_name << ". Reason: " << exc.what() << "\n";
1029 
1030 		return false;
1031 	}
1032 
1033 	bool result = true;
1034 
1035 	if (location != desc.m_expected_location)
1036 	{
1037 		stream << "Attribute: " << desc.m_name << " - invalid location: " << location
1038 			   << " expected: " << desc.m_expected_location << std::endl;
1039 		result = false;
1040 	}
1041 	if (component != desc.m_expected_component)
1042 	{
1043 		stream << "Attribute: " << desc.m_name << " - invalid component: " << component
1044 			   << " expected: " << desc.m_expected_component << std::endl;
1045 		result = false;
1046 	}
1047 
1048 	return result;
1049 }
1050 
1051 /** Query program resource for given variable and verify that everything is as expected
1052  *
1053  * @param program  Program object
1054  * @param variable Variable object
1055  * @param stream   Stream that will be used to log any error
1056  * @param is_input Selects if varying is input or output
1057  *
1058  * @return true if verification is positive, false otherwise
1059  **/
checkVarying(Program & program,Shader::STAGES stage,const Variable & variable,std::stringstream & stream,bool is_input)1060 bool checkVarying(Program& program, Shader::STAGES stage, const Variable& variable, std::stringstream& stream, bool is_input)
1061 {
1062 	bool result = true;
1063 
1064 	if (variable.IsBlock())
1065 	{
1066 		Utils::Interface* interface = variable.m_descriptor.m_interface;
1067 		const size_t	  n_members = interface->m_members.size();
1068 
1069 		for (size_t i = 0; i < n_members; ++i)
1070 		{
1071 			const Variable::Descriptor& member = interface->m_members[i];
1072 			bool member_result				   = verifyVarying(program, interface->m_name, member, stream, is_input);
1073 
1074 			if (false == member_result)
1075 			{
1076 				result = false;
1077 			}
1078 		}
1079 	}
1080 	/*
1081 	 To query the the location of struct member by glGetProgramResource, we need pass the variable name "gs_fs_output[0].single",
1082 	 but in original implementation, the test pass the name "Data.single", which can't get any valid result.
1083 	 struct Data {
1084 	 dmat2 single;
1085 	 dmat2 array[1];
1086 	 };
1087 	 layout (location = 0) in Data gs_fs_output[1];
1088 	 */
1089 	else if (variable.IsStruct())
1090 	{
1091 		Utils::Interface* interface		 = variable.m_descriptor.m_interface;
1092 		const size_t	  n_members		 = interface->m_members.size();
1093 		std::string		  structVariable = variable.m_descriptor.m_name;
1094 
1095 		switch (Variable::GetFlavour(stage, is_input ? Variable::INPUT : Variable::OUTPUT))
1096 		{
1097 		case Variable::ARRAY:
1098 		case Variable::INDEXED_BY_INVOCATION_ID:
1099 			structVariable.append("[0]");
1100 			break;
1101 		default:
1102 			break;
1103 		}
1104 
1105 		// If struct variable is an array
1106 		if (0 != variable.m_descriptor.m_n_array_elements)
1107 		{
1108 			for (GLuint i = 0; i < variable.m_descriptor.m_n_array_elements; i++)
1109 			{
1110 				GLchar buffer[16];
1111 				sprintf(buffer, "%d", i);
1112 				structVariable.append("[");
1113 				structVariable.append(buffer);
1114 				structVariable.append("]");
1115 				for (size_t j = 0; j < n_members; ++j)
1116 				{
1117 					const Variable::Descriptor& member = interface->m_members[j];
1118 					bool member_result = verifyVarying(program, structVariable, member, stream, is_input);
1119 
1120 					if (false == member_result)
1121 					{
1122 						result = false;
1123 					}
1124 				}
1125 			}
1126 		}
1127 		else
1128 		{
1129 			for (GLuint i = 0; i < n_members; ++i)
1130 			{
1131 				const Variable::Descriptor& member = interface->m_members[i];
1132 				bool member_result				   = verifyVarying(program, structVariable, member, stream, is_input);
1133 
1134 				if (false == member_result)
1135 				{
1136 					result = false;
1137 				}
1138 			}
1139 		}
1140 	}
1141 	else
1142 	{
1143 		result = verifyVarying(program, "", variable.m_descriptor, stream, is_input);
1144 	}
1145 	return result;
1146 }
1147 
1148 /** Query program resource for given variable and verify that everything is as expected
1149  *
1150  * @param program  Program object
1151  * @param variable Variable object
1152  * @param stream   Stream that will be used to log any error
1153  *
1154  * @return true if verification is positive, false otherwise
1155  **/
checkUniform(Program & program,const Utils::Variable & variable,std::stringstream & stream)1156 bool checkUniform(Program& program, const Utils::Variable& variable, std::stringstream& stream)
1157 {
1158 	bool result = true;
1159 
1160 	if (false == variable.IsBlock())
1161 	{
1162 		TCU_FAIL("Not implemented");
1163 	}
1164 	else
1165 	{
1166 		Utils::Interface* interface = variable.m_descriptor.m_interface;
1167 
1168 		size_t size = interface->m_members.size();
1169 
1170 		std::vector<GLuint>		 indices;
1171 		std::vector<const char*> names;
1172 		std::vector<std::string> names_str;
1173 		std::vector<GLint>		 offsets;
1174 
1175 		indices.resize(size);
1176 		names.resize(size);
1177 		names_str.resize(size);
1178 		offsets.resize(size);
1179 
1180 		for (size_t i = 0; i < size; ++i)
1181 		{
1182 			indices[i] = 0;
1183 			offsets[i] = 0;
1184 
1185 			const std::string& name =
1186 				Utils::Variable::GetReference(interface->m_name, interface->m_members[i], Utils::Variable::BASIC, 0);
1187 
1188 			if (Utils::Variable::INTERFACE == interface->m_members[i].m_type)
1189 			{
1190 				const std::string& member_name = Utils::Variable::GetReference(
1191 					name, interface->m_members[i].m_interface->m_members[0], Utils::Variable::BASIC, 0);
1192 
1193 				names_str[i] = member_name;
1194 			}
1195 			else
1196 			{
1197 				names_str[i] = name;
1198 			}
1199 
1200 			names[i] = names_str[i].c_str();
1201 		}
1202 
1203 		try
1204 		{
1205 			program.GetUniformIndices(static_cast<glw::GLsizei>(size), &names[0], &indices[0]);
1206 			program.GetActiveUniformsiv(static_cast<glw::GLsizei>(size), &indices[0], GL_UNIFORM_OFFSET, &offsets[0]);
1207 		}
1208 		catch (std::exception& exc)
1209 		{
1210 			stream << "Failed to query program for uniforms in block: " << variable.m_descriptor.m_name
1211 				   << ". Reason: " << exc.what() << "\n";
1212 
1213 			return false;
1214 		}
1215 
1216 		for (size_t i = 0; i < size; ++i)
1217 		{
1218 			Utils::Variable::Descriptor& desc = interface->m_members[i];
1219 
1220 			if (offsets[i] != (GLint)desc.m_offset)
1221 			{
1222 				stream << "Uniform: " << desc.m_name << " - invalid offset: " << offsets[i]
1223 					   << " expected: " << desc.m_offset << std::endl;
1224 				result = false;
1225 			}
1226 		}
1227 	}
1228 
1229 	return result;
1230 }
1231 
1232 /** Query program resource for given variable and verify that everything is as expected
1233  *
1234  * @param program  Program object
1235  * @param variable Variable object
1236  * @param stream   Stream that will be used to log any error
1237  *
1238  * @return true if verification is positive, false otherwise
1239  **/
checkSSB(Program & program,const Utils::Variable & variable,std::stringstream & stream)1240 bool checkSSB(Program& program, const Utils::Variable& variable, std::stringstream& stream)
1241 {
1242 	bool result = true;
1243 
1244 	if (false == variable.IsBlock())
1245 	{
1246 		TCU_FAIL("Not implemented");
1247 	}
1248 	else
1249 	{
1250 		Utils::Interface* interface = variable.m_descriptor.m_interface;
1251 
1252 		size_t size = interface->m_members.size();
1253 
1254 		for (size_t i = 0; i < size; ++i)
1255 		{
1256 			GLuint		index	= 0;
1257 			std::string name_str = "";
1258 			GLint		offset   = 0;
1259 
1260 			const std::string& name =
1261 				Utils::Variable::GetReference(interface->m_name, interface->m_members[i], Utils::Variable::BASIC, 0);
1262 
1263 			if (Utils::Variable::INTERFACE == interface->m_members[i].m_type)
1264 			{
1265 				const std::string& member_name = Utils::Variable::GetReference(
1266 					name, interface->m_members[i].m_interface->m_members[0], Utils::Variable::BASIC, 0);
1267 
1268 				name_str = member_name;
1269 			}
1270 			else
1271 			{
1272 				name_str = name;
1273 			}
1274 
1275 			try
1276 			{
1277 				index = program.GetResourceIndex(name_str, GL_BUFFER_VARIABLE);
1278 
1279 				program.GetResource(GL_BUFFER_VARIABLE, index, GL_OFFSET, 1, &offset);
1280 			}
1281 			catch (std::exception& exc)
1282 			{
1283 				stream << "Failed to query program for buffer variable: " << variable.m_descriptor.m_name
1284 					   << ". Reason: " << exc.what() << "\n";
1285 
1286 				return false;
1287 			}
1288 
1289 			Utils::Variable::Descriptor& desc = interface->m_members[i];
1290 
1291 			if (offset != (GLint)desc.m_offset)
1292 			{
1293 				stream << "Uniform: " << desc.m_name << " - invalid offset: " << offset
1294 					   << " expected: " << desc.m_offset << std::endl;
1295 				result = false;
1296 			}
1297 		}
1298 	}
1299 
1300 	return result;
1301 }
1302 
1303 /** Query program resources at given stage and verifies results
1304  *
1305  * @param program           Program object
1306  * @param program_interface Definition of program interface
1307  * @param stage             Stage to be verified
1308  * @param check_inputs      Select if inputs should be verified
1309  * @param check_outputs     Select if output should be verified
1310  * @param check_uniforms    Select if uniforms should be verified
1311  * @param check_ssbs        Select if buffers should be verified
1312  * @param stream            Stream that will be used to log any error
1313  *
1314  * @return true if verification is positive, false otherwise
1315  **/
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)1316 bool checkProgramStage(Program& program, const ProgramInterface& program_interface, Utils::Shader::STAGES stage,
1317 					   bool check_inputs, bool check_outputs, bool check_uniforms, bool check_ssbs,
1318 					   std::stringstream& stream)
1319 {
1320 	typedef Variable::PtrVector::const_iterator const_iterator;
1321 
1322 	const ShaderInterface& interface = program_interface.GetShaderInterface(stage);
1323 
1324 	bool result = true;
1325 
1326 	/* Inputs */
1327 	if (true == check_inputs)
1328 	{
1329 		const Variable::PtrVector& inputs = interface.m_inputs;
1330 
1331 		for (const_iterator it = inputs.begin(); it != inputs.end(); ++it)
1332 		{
1333 			if (false == checkVarying(program, stage, **it, stream, true))
1334 			{
1335 				result = false;
1336 			}
1337 		}
1338 	}
1339 
1340 	/* Outputs */
1341 	if (true == check_outputs)
1342 	{
1343 		const Variable::PtrVector& outputs = interface.m_outputs;
1344 
1345 		for (const_iterator it = outputs.begin(); it != outputs.end(); ++it)
1346 		{
1347 			if (false == checkVarying(program, stage, **it, stream, false))
1348 			{
1349 				result = false;
1350 			}
1351 		}
1352 	}
1353 
1354 	/* Uniforms */
1355 	if (true == check_uniforms)
1356 	{
1357 		const Variable::PtrVector& uniforms = interface.m_uniforms;
1358 
1359 		for (const_iterator it = uniforms.begin(); it != uniforms.end(); ++it)
1360 		{
1361 			if (false == checkUniform(program, **it, stream))
1362 			{
1363 				result = false;
1364 			}
1365 		}
1366 	}
1367 
1368 	/* SSBs */
1369 	if (true == check_ssbs)
1370 	{
1371 		const Variable::PtrVector& ssbs = interface.m_ssb_blocks;
1372 
1373 		for (const_iterator it = ssbs.begin(); it != ssbs.end(); ++it)
1374 		{
1375 			if (false == checkSSB(program, **it, stream))
1376 			{
1377 				result = false;
1378 			}
1379 		}
1380 	}
1381 
1382 	return result;
1383 }
1384 
1385 /** Query resources of monolithic compute program and verifies results
1386  *
1387  * @param program           Program object
1388  * @param program_interface Definition of program interface
1389  * @param stream            Stream that will be used to log any error
1390  *
1391  * @return true if verification is positive, false otherwise
1392  **/
checkMonolithicComputeProgramInterface(Program & program,const ProgramInterface & program_interface,std::stringstream & stream)1393 bool checkMonolithicComputeProgramInterface(Program& program, const ProgramInterface& program_interface,
1394 											std::stringstream& stream)
1395 {
1396 	bool result = true;
1397 
1398 	if (false == checkProgramStage(program, program_interface, Shader::COMPUTE, false, false, true, true, stream))
1399 	{
1400 		result = false;
1401 	}
1402 
1403 	/* Done */
1404 	return result;
1405 }
1406 
1407 /** Query resources of monolithic draw program and verifies results
1408  *
1409  * @param program           Program object
1410  * @param program_interface Definition of program interface
1411  * @param stream            Stream that will be used to log any error
1412  *
1413  * @return true if verification is positive, false otherwise
1414  **/
checkMonolithicDrawProgramInterface(Program & program,const ProgramInterface & program_interface,std::stringstream & stream)1415 bool checkMonolithicDrawProgramInterface(Program& program, const ProgramInterface& program_interface,
1416 										 std::stringstream& stream)
1417 {
1418 	bool result = true;
1419 
1420 	if (false == checkProgramStage(program, program_interface, Shader::VERTEX, true, false, true, true, stream))
1421 	{
1422 		result = false;
1423 	}
1424 
1425 	/* Done */
1426 	return result;
1427 }
1428 
1429 /** Query resources of separable draw program and verifies results
1430  *
1431  * @param program           Program object
1432  * @param program_interface Definition of program interface
1433  * @param stream            Stream that will be used to log any error
1434  *
1435  * @return true if verification is positive, false otherwise
1436  **/
checkSeparableDrawProgramInterface(Program & program,const ProgramInterface & program_interface,Utils::Shader::STAGES stage,std::stringstream & stream)1437 bool checkSeparableDrawProgramInterface(Program& program, const ProgramInterface& program_interface,
1438 										Utils::Shader::STAGES stage, std::stringstream& stream)
1439 {
1440 	bool result = true;
1441 
1442 	if (false == checkProgramStage(program, program_interface, stage, true, true, true, true, stream))
1443 	{
1444 		result = false;
1445 	}
1446 
1447 	/* Done */
1448 	return result;
1449 }
1450 
1451 /** Check if extension is supported
1452  *
1453  * @param context        Test context
1454  * @param extension_name Name of extension
1455  *
1456  * @return true if extension is supported, false otherwise
1457  **/
isExtensionSupported(deqp::Context & context,const GLchar * extension_name)1458 bool isExtensionSupported(deqp::Context& context, const GLchar* extension_name)
1459 {
1460 	const std::vector<std::string>& extensions = context.getContextInfo().getExtensions();
1461 
1462 	if (std::find(extensions.begin(), extensions.end(), extension_name) == extensions.end())
1463 	{
1464 		return false;
1465 	}
1466 
1467 	return true;
1468 }
1469 
1470 /** Check if GL context meets version requirements
1471  *
1472  * @param gl             Functions
1473  * @param required_major Minimum required MAJOR_VERSION
1474  * @param required_minor Minimum required MINOR_VERSION
1475  *
1476  * @return true if GL context version is at least as requested, false otherwise
1477  **/
isGLVersionAtLeast(const Functions & gl,GLint required_major,GLint required_minor)1478 bool isGLVersionAtLeast(const Functions& gl, GLint required_major, GLint required_minor)
1479 {
1480 	glw::GLint major = 0;
1481 	glw::GLint minor = 0;
1482 
1483 	gl.getIntegerv(GL_MAJOR_VERSION, &major);
1484 	gl.getIntegerv(GL_MINOR_VERSION, &minor);
1485 
1486 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
1487 
1488 	if (major > required_major)
1489 	{
1490 		/* Major is higher than required one */
1491 		return true;
1492 	}
1493 	else if (major == required_major)
1494 	{
1495 		if (minor >= required_minor)
1496 		{
1497 			/* Major is equal to required one */
1498 			/* Minor is higher than or equal to required one */
1499 			return true;
1500 		}
1501 		else
1502 		{
1503 			/* Major is equal to required one */
1504 			/* Minor is lower than required one */
1505 			return false;
1506 		}
1507 	}
1508 	else
1509 	{
1510 		/* Major is lower than required one */
1511 		return false;
1512 	}
1513 }
1514 
1515 /** Replace first occurance of <token> with <text> in <string> starting at <search_posistion>
1516  *
1517  * @param token           Token string
1518  * @param search_position Position at which find will start, it is updated to position at which replaced text ends
1519  * @param text            String that will be used as replacement for <token>
1520  * @param string          String to work on
1521  **/
replaceToken(const GLchar * token,size_t & search_position,const GLchar * text,std::string & string)1522 void replaceToken(const GLchar* token, size_t& search_position, const GLchar* text, std::string& string)
1523 {
1524 	const size_t text_length	= strlen(text);
1525 	const size_t token_length   = strlen(token);
1526 	const size_t token_position = string.find(token, search_position);
1527 
1528 #if DEBUG_REPLACE_TOKEN
1529 	if (std::string::npos == token_position)
1530 	{
1531 		string.append("\n\nInvalid token: ");
1532 		string.append(token);
1533 
1534 		TCU_FAIL(string.c_str());
1535 	}
1536 #endif /* DEBUG_REPLACE_TOKEN */
1537 
1538 	string.replace(token_position, token_length, text, text_length);
1539 
1540 	search_position = token_position + text_length;
1541 }
1542 
1543 /** Replace all occurances of <token> with <text> in <string>
1544  *
1545  * @param token           Token string
1546  * @param text            String that will be used as replacement for <token>
1547  * @param string          String to work on
1548  **/
replaceAllTokens(const GLchar * token,const GLchar * text,std::string & string)1549 void replaceAllTokens(const GLchar* token, const GLchar* text, std::string& string)
1550 {
1551 	const size_t text_length  = strlen(text);
1552 	const size_t token_length = strlen(token);
1553 
1554 	size_t search_position = 0;
1555 
1556 	while (1)
1557 	{
1558 		const size_t token_position = string.find(token, search_position);
1559 
1560 		if (std::string::npos == token_position)
1561 		{
1562 			break;
1563 		}
1564 
1565 		search_position = token_position + text_length;
1566 
1567 		string.replace(token_position, token_length, text, text_length);
1568 	}
1569 }
1570 
1571 /** Rounds up the value to the next power of 2.
1572  * This routine does not work for 0, see the url for explanations.
1573  *
1574  * @param value Starting point
1575  *
1576  * @return Calculated value
1577  **/
roundUpToPowerOf2(glw::GLuint value)1578 glw::GLuint roundUpToPowerOf2(glw::GLuint value)
1579 {
1580 	/* Taken from: graphics.stanford.edu/~seander/bithacks.html */
1581 	--value;
1582 
1583 	value |= value >> 1;
1584 	value |= value >> 2;
1585 	value |= value >> 4;
1586 	value |= value >> 8;
1587 	value |= value >> 16;
1588 
1589 	++value;
1590 
1591 	return value;
1592 }
1593 
1594 /** Insert elements of list into string.
1595  * List in string is represented either by token "LIST" or "SEPARATORLIST".
1596  * If SEPARATORLIST is available, than SEPARATOR is replaced with <separator>.
1597  * LIST is replaced with <element>SEPARATORLIST
1598  *
1599  * @param element         Element to be inserted
1600  * @param separator       Separator inserted between elements
1601  * @param search_position Position in string, where search for list should start
1602  * @param string          String
1603  **/
insertElementOfList(const GLchar * element,const GLchar * separator,size_t & search_position,std::string & string)1604 void insertElementOfList(const GLchar* element, const GLchar* separator, size_t& search_position, std::string& string)
1605 {
1606 	static const char* list		= g_list;
1607 	static const char* sep_list = "SEPARATORLIST";
1608 
1609 	/* Try to get "list" positions */
1610 	const size_t list_position	 = string.find(list, search_position);
1611 	const size_t sep_list_position = string.find(sep_list, search_position);
1612 
1613 	/* There is no list in string */
1614 	if (std::string::npos == list_position)
1615 	{
1616 		return;
1617 	}
1618 
1619 	if (9 /* strlen(SEPARATOR) */ == list_position - sep_list_position)
1620 	{
1621 		replaceToken("SEPARATOR", search_position, separator, string);
1622 	}
1623 
1624 	/* Save search_position */
1625 	const size_t start_position = search_position;
1626 
1627 	/* Prepare new element */
1628 	replaceToken("LIST", search_position, "ELEMENTSEPARATORLIST", string);
1629 
1630 	/* Restore search_position */
1631 	search_position = start_position;
1632 
1633 	/* Replace element and separator */
1634 	replaceToken("ELEMENT", search_position, element, string);
1635 }
1636 
1637 /** Close list in string.
1638  * If SEPARATORLIST is available, than SEPARATOR is replaced with <separator>
1639  * LIST is replaced with ""
1640  *
1641  * @param separator       Separator inserted between elements
1642  * @param search_position Position in string, where search for list should start
1643  * @param string          String
1644  **/
endList(const glw::GLchar * separator,size_t & search_position,std::string & string)1645 void endList(const glw::GLchar* separator, size_t& search_position, std::string& string)
1646 {
1647 	const size_t sep_position = string.find("SEPARATOR", search_position);
1648 	if (std::string::npos != sep_position)
1649 	{
1650 		replaceToken("SEPARATOR", search_position, separator, string);
1651 	}
1652 
1653 	replaceToken("LIST", search_position, "", string);
1654 }
1655 
1656 /* Buffer constants */
1657 const GLuint Buffer::m_invalid_id = -1;
1658 
1659 /** Constructor.
1660  *
1661  * @param context CTS context.
1662  **/
Buffer(deqp::Context & context)1663 Buffer::Buffer(deqp::Context& context) : m_id(m_invalid_id), m_buffer(Array), m_context(context)
1664 {
1665 }
1666 
1667 /** Destructor
1668  *
1669  **/
~Buffer()1670 Buffer::~Buffer()
1671 {
1672 	Release();
1673 }
1674 
1675 /** Initialize buffer instance
1676  *
1677  * @param buffer Buffer type
1678  * @param usage  Buffer usage enum
1679  * @param size   <size> parameter
1680  * @param data   <data> parameter
1681  **/
Init(BUFFERS buffer,USAGE usage,GLsizeiptr size,GLvoid * data)1682 void Buffer::Init(BUFFERS buffer, USAGE usage, GLsizeiptr size, GLvoid* data)
1683 {
1684 	/* Delete previous buffer instance */
1685 	Release();
1686 
1687 	m_buffer = buffer;
1688 
1689 	const Functions& gl = m_context.getRenderContext().getFunctions();
1690 
1691 	Generate(gl, m_id);
1692 	Bind(gl, m_id, m_buffer);
1693 	Data(gl, m_buffer, usage, size, data);
1694 }
1695 
1696 /** Release buffer instance
1697  *
1698  **/
Release()1699 void Buffer::Release()
1700 {
1701 	if (m_invalid_id != m_id)
1702 	{
1703 		const Functions& gl = m_context.getRenderContext().getFunctions();
1704 
1705 		gl.deleteBuffers(1, &m_id);
1706 		m_id = m_invalid_id;
1707 	}
1708 }
1709 
1710 /** Binds buffer to its target
1711  *
1712  **/
Bind() const1713 void Buffer::Bind() const
1714 {
1715 	const Functions& gl = m_context.getRenderContext().getFunctions();
1716 
1717 	Bind(gl, m_id, m_buffer);
1718 }
1719 
1720 /** Binds indexed buffer
1721  *
1722  * @param index <index> parameter
1723  **/
BindBase(GLuint index) const1724 void Buffer::BindBase(GLuint index) const
1725 {
1726 	const Functions& gl = m_context.getRenderContext().getFunctions();
1727 
1728 	BindBase(gl, m_id, m_buffer, index);
1729 }
1730 
1731 /** Binds range of buffer
1732  *
1733  * @param index  <index> parameter
1734  * @param offset <offset> parameter
1735  * @param size   <size> parameter
1736  **/
BindRange(GLuint index,GLintptr offset,GLsizeiptr size) const1737 void Buffer::BindRange(GLuint index, GLintptr offset, GLsizeiptr size) const
1738 {
1739 	const Functions& gl = m_context.getRenderContext().getFunctions();
1740 
1741 	BindRange(gl, m_id, m_buffer, index, offset, size);
1742 }
1743 
1744 /** Allocate memory for buffer and sends initial content
1745  *
1746  * @param usage  Buffer usage enum
1747  * @param size   <size> parameter
1748  * @param data   <data> parameter
1749  **/
Data(USAGE usage,glw::GLsizeiptr size,glw::GLvoid * data)1750 void Buffer::Data(USAGE usage, glw::GLsizeiptr size, glw::GLvoid* data)
1751 {
1752 	const Functions& gl = m_context.getRenderContext().getFunctions();
1753 
1754 	Data(gl, m_buffer, usage, size, data);
1755 }
1756 
1757 /** Maps contents of buffer into CPU space
1758  *
1759  * @param access Requested access
1760  *
1761  * @return Pointer to memory region available for CPU
1762  **/
Map(ACCESS access)1763 GLvoid* Buffer::Map(ACCESS access)
1764 {
1765 	const Functions& gl = m_context.getRenderContext().getFunctions();
1766 
1767 	return Map(gl, m_buffer, access);
1768 }
1769 
1770 /** Allocate memory for buffer and sends initial content
1771  *
1772  * @param offset Offset in buffer
1773  * @param size   <size> parameter
1774  * @param data   <data> parameter
1775  **/
SubData(glw::GLintptr offset,glw::GLsizeiptr size,glw::GLvoid * data)1776 void Buffer::SubData(glw::GLintptr offset, glw::GLsizeiptr size, glw::GLvoid* data)
1777 {
1778 	const Functions& gl = m_context.getRenderContext().getFunctions();
1779 
1780 	SubData(gl, m_buffer, offset, size, data);
1781 }
1782 
1783 /** Maps contents of buffer into CPU space
1784  **/
UnMap()1785 void Buffer::UnMap()
1786 {
1787 	const Functions& gl = m_context.getRenderContext().getFunctions();
1788 
1789 	return UnMap(gl, m_buffer);
1790 }
1791 
1792 /** Bind buffer to given target
1793  *
1794  * @param gl     GL functions
1795  * @param id     Id of buffer
1796  * @param buffer Buffer enum
1797  **/
Bind(const Functions & gl,GLuint id,BUFFERS buffer)1798 void Buffer::Bind(const Functions& gl, GLuint id, BUFFERS buffer)
1799 {
1800 	GLenum target = GetBufferGLenum(buffer);
1801 
1802 	gl.bindBuffer(target, id);
1803 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffer");
1804 }
1805 
1806 /** Binds indexed buffer
1807  *
1808  * @param gl     GL functions
1809  * @param id     Id of buffer
1810  * @param buffer Buffer enum
1811  * @param index  <index> parameter
1812  **/
BindBase(const Functions & gl,GLuint id,BUFFERS buffer,GLuint index)1813 void Buffer::BindBase(const Functions& gl, GLuint id, BUFFERS buffer, GLuint index)
1814 {
1815 	GLenum target = GetBufferGLenum(buffer);
1816 
1817 	gl.bindBufferBase(target, index, id);
1818 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindBufferBase");
1819 }
1820 
1821 /** Binds buffer range
1822  *
1823  * @param gl     GL functions
1824  * @param id     Id of buffer
1825  * @param buffer Buffer enum
1826  * @param index  <index> parameter
1827  * @param offset <offset> parameter
1828  * @param size   <size> parameter
1829  **/
BindRange(const Functions & gl,GLuint id,BUFFERS buffer,GLuint index,GLintptr offset,GLsizeiptr size)1830 void Buffer::BindRange(const Functions& gl, GLuint id, BUFFERS buffer, GLuint index, GLintptr offset, GLsizeiptr size)
1831 {
1832 	GLenum target = GetBufferGLenum(buffer);
1833 
1834 	gl.bindBufferRange(target, index, id, offset, size);
1835 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindBufferRange");
1836 }
1837 
1838 /** Allocate memory for buffer and sends initial content
1839  *
1840  * @param gl     GL functions
1841  * @param buffer Buffer enum
1842  * @param usage  Buffer usage enum
1843  * @param size   <size> parameter
1844  * @param data   <data> parameter
1845  **/
Data(const glw::Functions & gl,BUFFERS buffer,USAGE usage,glw::GLsizeiptr size,glw::GLvoid * data)1846 void Buffer::Data(const glw::Functions& gl, BUFFERS buffer, USAGE usage, glw::GLsizeiptr size, glw::GLvoid* data)
1847 {
1848 	GLenum target   = GetBufferGLenum(buffer);
1849 	GLenum gl_usage = GetUsageGLenum(usage);
1850 
1851 	gl.bufferData(target, size, data, gl_usage);
1852 	GLU_EXPECT_NO_ERROR(gl.getError(), "BufferData");
1853 }
1854 
1855 /** Allocate memory for buffer and sends initial content
1856  *
1857  * @param gl     GL functions
1858  * @param buffer Buffer enum
1859  * @param offset Offset in buffer
1860  * @param size   <size> parameter
1861  * @param data   <data> parameter
1862  **/
SubData(const glw::Functions & gl,BUFFERS buffer,glw::GLintptr offset,glw::GLsizeiptr size,glw::GLvoid * data)1863 void Buffer::SubData(const glw::Functions& gl, BUFFERS buffer, glw::GLintptr offset, glw::GLsizeiptr size,
1864 					 glw::GLvoid* data)
1865 {
1866 	GLenum target = GetBufferGLenum(buffer);
1867 
1868 	gl.bufferSubData(target, offset, size, data);
1869 	GLU_EXPECT_NO_ERROR(gl.getError(), "BufferSubData");
1870 }
1871 
1872 /** Generate buffer
1873  *
1874  * @param gl     GL functions
1875  * @param out_id Id of buffer
1876  **/
Generate(const Functions & gl,GLuint & out_id)1877 void Buffer::Generate(const Functions& gl, GLuint& out_id)
1878 {
1879 	GLuint id = m_invalid_id;
1880 
1881 	gl.genBuffers(1, &id);
1882 	GLU_EXPECT_NO_ERROR(gl.getError(), "GenBuffers");
1883 
1884 	if (m_invalid_id == id)
1885 	{
1886 		TCU_FAIL("Got invalid id");
1887 	}
1888 
1889 	out_id = id;
1890 }
1891 
1892 /** Maps buffer content
1893  *
1894  * @param gl     GL functions
1895  * @param buffer Buffer enum
1896  * @param access Access rights for mapped region
1897  *
1898  * @return Mapped memory
1899  **/
Map(const Functions & gl,BUFFERS buffer,ACCESS access)1900 void* Buffer::Map(const Functions& gl, BUFFERS buffer, ACCESS access)
1901 {
1902 	GLenum target	= GetBufferGLenum(buffer);
1903 	GLenum gl_access = GetAccessGLenum(access);
1904 
1905 	void* result = gl.mapBuffer(target, gl_access);
1906 	GLU_EXPECT_NO_ERROR(gl.getError(), "MapBuffer");
1907 
1908 	return result;
1909 }
1910 
1911 /** Unmaps buffer
1912  *
1913  **/
UnMap(const Functions & gl,BUFFERS buffer)1914 void Buffer::UnMap(const Functions& gl, BUFFERS buffer)
1915 {
1916 	GLenum target = GetBufferGLenum(buffer);
1917 
1918 	gl.unmapBuffer(target);
1919 	GLU_EXPECT_NO_ERROR(gl.getError(), "UnmapBuffer");
1920 }
1921 
1922 /** Return GLenum representation of requested access
1923  *
1924  * @param access Requested access
1925  *
1926  * @return GLenum value
1927  **/
GetAccessGLenum(ACCESS access)1928 GLenum Buffer::GetAccessGLenum(ACCESS access)
1929 {
1930 	GLenum result = 0;
1931 
1932 	switch (access)
1933 	{
1934 	case ReadOnly:
1935 		result = GL_READ_ONLY;
1936 		break;
1937 	case WriteOnly:
1938 		result = GL_WRITE_ONLY;
1939 		break;
1940 	case ReadWrite:
1941 		result = GL_READ_WRITE;
1942 		break;
1943 	default:
1944 		TCU_FAIL("Invalid enum");
1945 	}
1946 
1947 	return result;
1948 }
1949 
1950 /** Return GLenum representation of requested buffer type
1951  *
1952  * @param buffer Requested buffer type
1953  *
1954  * @return GLenum value
1955  **/
GetBufferGLenum(BUFFERS buffer)1956 GLenum Buffer::GetBufferGLenum(BUFFERS buffer)
1957 {
1958 	GLenum result = 0;
1959 
1960 	switch (buffer)
1961 	{
1962 	case Array:
1963 		result = GL_ARRAY_BUFFER;
1964 		break;
1965 	case Element:
1966 		result = GL_ELEMENT_ARRAY_BUFFER;
1967 		break;
1968 	case Shader_Storage:
1969 		result = GL_SHADER_STORAGE_BUFFER;
1970 		break;
1971 	case Texture:
1972 		result = GL_TEXTURE_BUFFER;
1973 		break;
1974 	case Transform_feedback:
1975 		result = GL_TRANSFORM_FEEDBACK_BUFFER;
1976 		break;
1977 	case Uniform:
1978 		result = GL_UNIFORM_BUFFER;
1979 		break;
1980 	default:
1981 		TCU_FAIL("Invalid enum");
1982 	}
1983 
1984 	return result;
1985 }
1986 
1987 /** Return GLenum representation of requested usage
1988  *
1989  * @param usage Requested usage
1990  *
1991  * @return GLenum value
1992  **/
GetUsageGLenum(USAGE usage)1993 GLenum Buffer::GetUsageGLenum(USAGE usage)
1994 {
1995 	GLenum result = 0;
1996 
1997 	switch (usage)
1998 	{
1999 	case DynamicCopy:
2000 		result = GL_DYNAMIC_COPY;
2001 		break;
2002 	case DynamicDraw:
2003 		result = GL_DYNAMIC_DRAW;
2004 		break;
2005 	case DynamicRead:
2006 		result = GL_DYNAMIC_READ;
2007 		break;
2008 	case StaticCopy:
2009 		result = GL_STATIC_COPY;
2010 		break;
2011 	case StaticDraw:
2012 		result = GL_STATIC_DRAW;
2013 		break;
2014 	case StaticRead:
2015 		result = GL_STATIC_READ;
2016 		break;
2017 	case StreamCopy:
2018 		result = GL_STREAM_COPY;
2019 		break;
2020 	case StreamDraw:
2021 		result = GL_STREAM_DRAW;
2022 		break;
2023 	case StreamRead:
2024 		result = GL_STREAM_READ;
2025 		break;
2026 	default:
2027 		TCU_FAIL("Invalid enum");
2028 	}
2029 
2030 	return result;
2031 }
2032 
2033 /** Returns name of buffer target
2034  *
2035  * @param buffer Target enum
2036  *
2037  * @return Name of target
2038  **/
GetBufferName(BUFFERS buffer)2039 const GLchar* Buffer::GetBufferName(BUFFERS buffer)
2040 {
2041 	const GLchar* name = 0;
2042 
2043 	switch (buffer)
2044 	{
2045 	case Array:
2046 		name = "Array";
2047 		break;
2048 	case Element:
2049 		name = "Element";
2050 		break;
2051 	case Shader_Storage:
2052 		name = "Shader_Storage";
2053 		break;
2054 	case Texture:
2055 		name = "Texture";
2056 		break;
2057 	case Transform_feedback:
2058 		name = "Transform_feedback";
2059 		break;
2060 	case Uniform:
2061 		name = "Uniform";
2062 		break;
2063 	default:
2064 		TCU_FAIL("Invalid enum");
2065 	}
2066 
2067 	return name;
2068 }
2069 
2070 /* Framebuffer constants */
2071 const GLuint Framebuffer::m_invalid_id = -1;
2072 
2073 /** Constructor
2074  *
2075  * @param context CTS context
2076  **/
Framebuffer(deqp::Context & context)2077 Framebuffer::Framebuffer(deqp::Context& context) : m_id(m_invalid_id), m_context(context)
2078 {
2079 	/* Nothing to be done here */
2080 }
2081 
2082 /** Destructor
2083  *
2084  **/
~Framebuffer()2085 Framebuffer::~Framebuffer()
2086 {
2087 	Release();
2088 }
2089 
2090 /** Initialize framebuffer instance
2091  *
2092  **/
Init()2093 void Framebuffer::Init()
2094 {
2095 	/* Delete previous instance */
2096 	Release();
2097 
2098 	const Functions& gl = m_context.getRenderContext().getFunctions();
2099 
2100 	Generate(gl, m_id);
2101 }
2102 
2103 /** Release framebuffer instance
2104  *
2105  **/
Release()2106 void Framebuffer::Release()
2107 {
2108 	if (m_invalid_id != m_id)
2109 	{
2110 		const Functions& gl = m_context.getRenderContext().getFunctions();
2111 
2112 		gl.deleteFramebuffers(1, &m_id);
2113 		m_id = m_invalid_id;
2114 	}
2115 }
2116 
2117 /** Attach texture to specified attachment
2118  *
2119  * @param attachment Attachment
2120  * @param texture_id Texture id
2121  * @param width      Texture width
2122  * @param height     Texture height
2123  **/
AttachTexture(GLenum attachment,GLuint texture_id,GLuint width,GLuint height)2124 void Framebuffer::AttachTexture(GLenum attachment, GLuint texture_id, GLuint width, GLuint height)
2125 {
2126 	const Functions& gl = m_context.getRenderContext().getFunctions();
2127 
2128 	AttachTexture(gl, attachment, texture_id, width, height);
2129 }
2130 
2131 /** Binds framebuffer to DRAW_FRAMEBUFFER
2132  *
2133  **/
Bind()2134 void Framebuffer::Bind()
2135 {
2136 	const Functions& gl = m_context.getRenderContext().getFunctions();
2137 
2138 	Bind(gl, m_id);
2139 }
2140 
2141 /** Clear framebuffer
2142  *
2143  * @param mask <mask> parameter of glClear. Decides which shall be cleared
2144  **/
Clear(GLenum mask)2145 void Framebuffer::Clear(GLenum mask)
2146 {
2147 	const Functions& gl = m_context.getRenderContext().getFunctions();
2148 
2149 	Clear(gl, mask);
2150 }
2151 
2152 /** Specifies clear color
2153  *
2154  * @param red   Red channel
2155  * @param green Green channel
2156  * @param blue  Blue channel
2157  * @param alpha Alpha channel
2158  **/
ClearColor(GLfloat red,GLfloat green,GLfloat blue,GLfloat alpha)2159 void Framebuffer::ClearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
2160 {
2161 	const Functions& gl = m_context.getRenderContext().getFunctions();
2162 
2163 	ClearColor(gl, red, green, blue, alpha);
2164 }
2165 
2166 /** Attach texture to specified attachment
2167  *
2168  * @param gl         GL functions
2169  * @param attachment Attachment
2170  * @param texture_id Texture id
2171  * @param width      Texture width
2172  * @param height     Texture height
2173  **/
AttachTexture(const Functions & gl,GLenum attachment,GLuint texture_id,GLuint width,GLuint height)2174 void Framebuffer::AttachTexture(const Functions& gl, GLenum attachment, GLuint texture_id, GLuint width, GLuint height)
2175 {
2176 	gl.framebufferTexture(GL_DRAW_FRAMEBUFFER, attachment, texture_id, 0 /* level */);
2177 	GLU_EXPECT_NO_ERROR(gl.getError(), "FramebufferTexture");
2178 
2179 	gl.viewport(0 /* x */, 0 /* y */, width, height);
2180 	GLU_EXPECT_NO_ERROR(gl.getError(), "Viewport");
2181 }
2182 
2183 /** Binds framebuffer to DRAW_FRAMEBUFFER
2184  *
2185  * @param gl GL functions
2186  * @param id ID of framebuffer
2187  **/
Bind(const Functions & gl,GLuint id)2188 void Framebuffer::Bind(const Functions& gl, GLuint id)
2189 {
2190 	gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, id);
2191 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer");
2192 }
2193 
2194 /** Clear framebuffer
2195  *
2196  * @param gl   GL functions
2197  * @param mask <mask> parameter of glClear. Decides which shall be cleared
2198  **/
Clear(const Functions & gl,GLenum mask)2199 void Framebuffer::Clear(const Functions& gl, GLenum mask)
2200 {
2201 	gl.clear(mask);
2202 	GLU_EXPECT_NO_ERROR(gl.getError(), "Clear");
2203 }
2204 
2205 /** Specifies clear color
2206  *
2207  * @param gl    GL functions
2208  * @param red   Red channel
2209  * @param green Green channel
2210  * @param blue  Blue channel
2211  * @param alpha Alpha channel
2212  **/
ClearColor(const Functions & gl,GLfloat red,GLfloat green,GLfloat blue,GLfloat alpha)2213 void Framebuffer::ClearColor(const Functions& gl, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
2214 {
2215 	gl.clearColor(red, green, blue, alpha);
2216 	GLU_EXPECT_NO_ERROR(gl.getError(), "ClearColor");
2217 }
2218 
2219 /** Generate framebuffer
2220  *
2221  **/
Generate(const Functions & gl,GLuint & out_id)2222 void Framebuffer::Generate(const Functions& gl, GLuint& out_id)
2223 {
2224 	GLuint id = m_invalid_id;
2225 
2226 	gl.genFramebuffers(1, &id);
2227 	GLU_EXPECT_NO_ERROR(gl.getError(), "GenFramebuffers");
2228 
2229 	if (m_invalid_id == id)
2230 	{
2231 		TCU_FAIL("Invalid id");
2232 	}
2233 
2234 	out_id = id;
2235 }
2236 
2237 /* Shader's constants */
2238 const GLuint Shader::m_invalid_id = 0;
2239 
2240 /** Constructor.
2241  *
2242  * @param context CTS context.
2243  **/
Shader(deqp::Context & context)2244 Shader::Shader(deqp::Context& context) : m_id(m_invalid_id), m_context(context)
2245 {
2246 	/* Nothing to be done here */
2247 }
2248 
2249 /** Destructor
2250  *
2251  **/
~Shader()2252 Shader::~Shader()
2253 {
2254 	Release();
2255 }
2256 
2257 /** Initialize shader instance
2258  *
2259  * @param stage  Shader stage
2260  * @param source Source code
2261  **/
Init(STAGES stage,const std::string & source)2262 void Shader::Init(STAGES stage, const std::string& source)
2263 {
2264 	if (true == source.empty())
2265 	{
2266 		/* No source == no shader */
2267 		return;
2268 	}
2269 
2270 	/* Delete any previous shader */
2271 	Release();
2272 
2273 	/* Create, set source and compile */
2274 	const Functions& gl = m_context.getRenderContext().getFunctions();
2275 
2276 	Create(gl, stage, m_id);
2277 	Source(gl, m_id, source);
2278 
2279 	try
2280 	{
2281 		Compile(gl, m_id);
2282 	}
2283 	catch (const CompilationException& exc)
2284 	{
2285 		throw InvalidSourceException(exc.what(), source, stage);
2286 	}
2287 }
2288 
2289 /** Release shader instance
2290  *
2291  **/
Release()2292 void Shader::Release()
2293 {
2294 	if (m_invalid_id != m_id)
2295 	{
2296 		const Functions& gl = m_context.getRenderContext().getFunctions();
2297 
2298 		gl.deleteShader(m_id);
2299 		m_id = m_invalid_id;
2300 	}
2301 }
2302 
2303 /** Compile shader
2304  *
2305  * @param gl GL functions
2306  * @param id Shader id
2307  **/
Compile(const Functions & gl,GLuint id)2308 void Shader::Compile(const Functions& gl, GLuint id)
2309 {
2310 	GLint status = GL_FALSE;
2311 
2312 	/* Compile */
2313 	gl.compileShader(id);
2314 	GLU_EXPECT_NO_ERROR(gl.getError(), "CompileShader");
2315 
2316 	/* Get compilation status */
2317 	gl.getShaderiv(id, GL_COMPILE_STATUS, &status);
2318 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");
2319 
2320 	/* Log compilation error */
2321 	if (GL_TRUE != status)
2322 	{
2323 		glw::GLint  length = 0;
2324 		std::string message;
2325 
2326 		/* Error log length */
2327 		gl.getShaderiv(id, GL_INFO_LOG_LENGTH, &length);
2328 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");
2329 
2330 		/* Prepare storage */
2331 		message.resize(length, 0);
2332 
2333 		/* Get error log */
2334 		gl.getShaderInfoLog(id, length, 0, &message[0]);
2335 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderInfoLog");
2336 
2337 		throw CompilationException(message.c_str());
2338 	}
2339 }
2340 
2341 /** Create shader
2342  *
2343  * @param gl     GL functions
2344  * @param stage  Shader stage
2345  * @param out_id Shader id
2346  **/
Create(const Functions & gl,STAGES stage,GLuint & out_id)2347 void Shader::Create(const Functions& gl, STAGES stage, GLuint& out_id)
2348 {
2349 	const GLenum shaderType = GetShaderStageGLenum(stage);
2350 	const GLuint id			= gl.createShader(shaderType);
2351 	GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
2352 
2353 	if (m_invalid_id == id)
2354 	{
2355 		TCU_FAIL("Failed to create shader");
2356 	}
2357 
2358 	out_id = id;
2359 }
2360 
2361 /** Set shader's source code
2362  *
2363  * @param gl     GL functions
2364  * @param id     Shader id
2365  * @param source Shader source code
2366  **/
Source(const Functions & gl,GLuint id,const std::string & source)2367 void Shader::Source(const Functions& gl, GLuint id, const std::string& source)
2368 {
2369 	const GLchar* code = source.c_str();
2370 
2371 	gl.shaderSource(id, 1 /* count */, &code, 0 /* lengths */);
2372 	GLU_EXPECT_NO_ERROR(gl.getError(), "ShaderSource");
2373 }
2374 
2375 /** Get GLenum repesenting shader stage
2376  *
2377  * @param stage Shader stage
2378  *
2379  * @return GLenum
2380  **/
GetShaderStageGLenum(STAGES stage)2381 GLenum Shader::GetShaderStageGLenum(STAGES stage)
2382 {
2383 	GLenum result = 0;
2384 
2385 	switch (stage)
2386 	{
2387 	case COMPUTE:
2388 		result = GL_COMPUTE_SHADER;
2389 		break;
2390 	case FRAGMENT:
2391 		result = GL_FRAGMENT_SHADER;
2392 		break;
2393 	case GEOMETRY:
2394 		result = GL_GEOMETRY_SHADER;
2395 		break;
2396 	case TESS_CTRL:
2397 		result = GL_TESS_CONTROL_SHADER;
2398 		break;
2399 	case TESS_EVAL:
2400 		result = GL_TESS_EVALUATION_SHADER;
2401 		break;
2402 	case VERTEX:
2403 		result = GL_VERTEX_SHADER;
2404 		break;
2405 	default:
2406 		TCU_FAIL("Invalid enum");
2407 	}
2408 
2409 	return result;
2410 }
2411 
2412 /** Get string representing name of shader stage
2413  *
2414  * @param stage Shader stage
2415  *
2416  * @return String with name of shader stage
2417  **/
GetStageName(STAGES stage)2418 const glw::GLchar* Shader::GetStageName(STAGES stage)
2419 {
2420 	const GLchar* result = 0;
2421 
2422 	switch (stage)
2423 	{
2424 	case COMPUTE:
2425 		result = "compute";
2426 		break;
2427 	case VERTEX:
2428 		result = "vertex";
2429 		break;
2430 	case TESS_CTRL:
2431 		result = "tessellation control";
2432 		break;
2433 	case TESS_EVAL:
2434 		result = "tessellation evaluation";
2435 		break;
2436 	case GEOMETRY:
2437 		result = "geometry";
2438 		break;
2439 	case FRAGMENT:
2440 		result = "fragment";
2441 		break;
2442 	default:
2443 		TCU_FAIL("Invalid enum");
2444 	}
2445 
2446 	return result;
2447 }
2448 
2449 /** Logs shader source
2450  *
2451  * @param context CTS context
2452  * @param source  Source of shader
2453  * @param stage   Shader stage
2454  **/
LogSource(deqp::Context & context,const std::string & source,STAGES stage)2455 void Shader::LogSource(deqp::Context& context, const std::string& source, STAGES stage)
2456 {
2457 	/* Skip empty shaders */
2458 	if (true == source.empty())
2459 	{
2460 		return;
2461 	}
2462 
2463 	context.getTestContext().getLog() << tcu::TestLog::Message
2464 									  << "Shader source. Stage: " << Shader::GetStageName(stage)
2465 									  << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(source);
2466 }
2467 
2468 /** Constructor
2469  *
2470  * @param message Compilation error message
2471  **/
CompilationException(const GLchar * message)2472 Shader::CompilationException::CompilationException(const GLchar* message)
2473 {
2474 	m_message = message;
2475 }
2476 
2477 /** Returns error messages
2478  *
2479  * @return Compilation error message
2480  **/
what() const2481 const char* Shader::CompilationException::what() const throw()
2482 {
2483 	return m_message.c_str();
2484 }
2485 
2486 /** Constructor
2487  *
2488  * @param message Compilation error message
2489  **/
InvalidSourceException(const GLchar * error_message,const std::string & source,STAGES stage)2490 Shader::InvalidSourceException::InvalidSourceException(const GLchar* error_message, const std::string& source,
2491 													   STAGES stage)
2492 	: m_message(error_message), m_source(source), m_stage(stage)
2493 {
2494 }
2495 
2496 /** Returns error messages
2497  *
2498  * @return Compilation error message
2499  **/
what() const2500 const char* Shader::InvalidSourceException::what() const throw()
2501 {
2502 	return "Compilation error";
2503 }
2504 
2505 /** Logs error message and shader sources **/
log(deqp::Context & context) const2506 void Shader::InvalidSourceException::log(deqp::Context& context) const
2507 {
2508 	context.getTestContext().getLog() << tcu::TestLog::Message << "Failed to compile shader: " << m_message.c_str()
2509 									  << tcu::TestLog::EndMessage;
2510 
2511 	LogSource(context, m_source, m_stage);
2512 }
2513 
2514 /* Program constants */
2515 const GLuint Pipeline::m_invalid_id = 0;
2516 
2517 /** Constructor.
2518  *
2519  * @param context CTS context.
2520  **/
Pipeline(deqp::Context & context)2521 Pipeline::Pipeline(deqp::Context& context) : m_id(m_invalid_id), m_context(context)
2522 {
2523 	/* Nothing to be done here */
2524 }
2525 
2526 /** Destructor
2527  *
2528  **/
~Pipeline()2529 Pipeline::~Pipeline()
2530 {
2531 	Release();
2532 }
2533 
2534 /** Initialize pipline object
2535  *
2536  **/
Init()2537 void Pipeline::Init()
2538 {
2539 	Release();
2540 
2541 	const Functions& gl = m_context.getRenderContext().getFunctions();
2542 
2543 	/* Generate */
2544 	gl.genProgramPipelines(1, &m_id);
2545 	GLU_EXPECT_NO_ERROR(gl.getError(), "GenProgramPipelines");
2546 }
2547 
2548 /** Release pipeline object
2549  *
2550  **/
Release()2551 void Pipeline::Release()
2552 {
2553 	if (m_invalid_id != m_id)
2554 	{
2555 		const Functions& gl = m_context.getRenderContext().getFunctions();
2556 
2557 		/* Generate */
2558 		gl.deleteProgramPipelines(1, &m_id);
2559 		GLU_EXPECT_NO_ERROR(gl.getError(), "DeleteProgramPipelines");
2560 
2561 		m_id = m_invalid_id;
2562 	}
2563 }
2564 
2565 /** Bind pipeline
2566  *
2567  **/
Bind()2568 void Pipeline::Bind()
2569 {
2570 	const Functions& gl = m_context.getRenderContext().getFunctions();
2571 
2572 	Bind(gl, m_id);
2573 }
2574 
2575 /** Set which stages should be active
2576  *
2577  * @param program_id Id of program
2578  * @param stages     Logical combination of enums representing stages
2579  **/
UseProgramStages(GLuint program_id,GLenum stages)2580 void Pipeline::UseProgramStages(GLuint program_id, GLenum stages)
2581 {
2582 	const Functions& gl = m_context.getRenderContext().getFunctions();
2583 
2584 	UseProgramStages(gl, m_id, program_id, stages);
2585 }
2586 
2587 /** Bind pipeline
2588  *
2589  * @param gl Functiions
2590  * @param id Pipeline id
2591  **/
Bind(const Functions & gl,GLuint id)2592 void Pipeline::Bind(const Functions& gl, GLuint id)
2593 {
2594 	gl.bindProgramPipeline(id);
2595 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindProgramPipeline");
2596 }
2597 
2598 /** Set which stages should be active
2599  *
2600  * @param gl         Functiions
2601  * @param id         Pipeline id
2602  * @param program_id Id of program
2603  * @param stages     Logical combination of enums representing stages
2604  **/
UseProgramStages(const Functions & gl,GLuint id,GLuint program_id,GLenum stages)2605 void Pipeline::UseProgramStages(const Functions& gl, GLuint id, GLuint program_id, GLenum stages)
2606 {
2607 	gl.useProgramStages(id, stages, program_id);
2608 	GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgramStages");
2609 }
2610 
2611 /* Program constants */
2612 const GLuint Program::m_invalid_id = 0;
2613 
2614 /** Constructor.
2615  *
2616  * @param context CTS context.
2617  **/
Program(deqp::Context & context)2618 Program::Program(deqp::Context& context)
2619 	: m_id(m_invalid_id)
2620 	, m_compute(context)
2621 	, m_fragment(context)
2622 	, m_geometry(context)
2623 	, m_tess_ctrl(context)
2624 	, m_tess_eval(context)
2625 	, m_vertex(context)
2626 	, m_context(context)
2627 {
2628 	/* Nothing to be done here */
2629 }
2630 
2631 /** Destructor
2632  *
2633  **/
~Program()2634 Program::~Program()
2635 {
2636 	Release();
2637 }
2638 
2639 /** Initialize program instance
2640  *
2641  * @param compute_shader                    Compute shader source code
2642  * @param fragment_shader                   Fragment shader source code
2643  * @param geometry_shader                   Geometry shader source code
2644  * @param tessellation_control_shader       Tessellation control shader source code
2645  * @param tessellation_evaluation_shader    Tessellation evaluation shader source code
2646  * @param vertex_shader                     Vertex shader source code
2647  * @param captured_varyings                 Vector of variables to be captured with transfrom feedback
2648  * @param capture_interleaved               Select mode of transform feedback (separate or interleaved)
2649  * @param is_separable                      Selects if monolithic or separable program should be built. Defaults to false
2650  **/
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)2651 void Program::Init(const std::string& compute_shader, const std::string& fragment_shader,
2652 				   const std::string& geometry_shader, const std::string& tessellation_control_shader,
2653 				   const std::string& tessellation_evaluation_shader, const std::string& vertex_shader,
2654 				   const NameVector& captured_varyings, bool capture_interleaved, bool is_separable)
2655 {
2656 	/* Delete previous program */
2657 	Release();
2658 
2659 	/* GL entry points */
2660 	const Functions& gl = m_context.getRenderContext().getFunctions();
2661 
2662 	/* Initialize shaders */
2663 	m_compute.Init(Shader::COMPUTE, compute_shader);
2664 	m_fragment.Init(Shader::FRAGMENT, fragment_shader);
2665 	m_geometry.Init(Shader::GEOMETRY, geometry_shader);
2666 	m_tess_ctrl.Init(Shader::TESS_CTRL, tessellation_control_shader);
2667 	m_tess_eval.Init(Shader::TESS_EVAL, tessellation_evaluation_shader);
2668 	m_vertex.Init(Shader::VERTEX, vertex_shader);
2669 
2670 	/* Create program, set up transform feedback and attach shaders */
2671 	Create(gl, m_id);
2672 	Capture(gl, m_id, captured_varyings, capture_interleaved);
2673 	Attach(gl, m_id, m_compute.m_id);
2674 	Attach(gl, m_id, m_fragment.m_id);
2675 	Attach(gl, m_id, m_geometry.m_id);
2676 	Attach(gl, m_id, m_tess_ctrl.m_id);
2677 	Attach(gl, m_id, m_tess_eval.m_id);
2678 	Attach(gl, m_id, m_vertex.m_id);
2679 
2680 	/* Set separable parameter */
2681 	if (true == is_separable)
2682 	{
2683 		gl.programParameteri(m_id, GL_PROGRAM_SEPARABLE, GL_TRUE);
2684 		GLU_EXPECT_NO_ERROR(gl.getError(), "ProgramParameteri");
2685 	}
2686 
2687 	try
2688 	{
2689 		/* Link program */
2690 		Link(gl, m_id);
2691 	}
2692 	catch (const LinkageException& exc)
2693 	{
2694 		throw BuildException(exc.what(), compute_shader, fragment_shader, geometry_shader, tessellation_control_shader,
2695 							 tessellation_evaluation_shader, vertex_shader);
2696 	}
2697 }
2698 
2699 /** Initialize program instance
2700  *
2701  * @param compute_shader                    Compute shader source code
2702  * @param fragment_shader                   Fragment shader source code
2703  * @param geometry_shader                   Geometry shader source code
2704  * @param tessellation_control_shader       Tessellation control shader source code
2705  * @param tessellation_evaluation_shader    Tessellation evaluation shader source code
2706  * @param vertex_shader                     Vertex shader source code
2707  * @param is_separable                      Selects if monolithic or separable program should be built. Defaults to false
2708  **/
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)2709 void Program::Init(const std::string& compute_shader, const std::string& fragment_shader,
2710 				   const std::string& geometry_shader, const std::string& tessellation_control_shader,
2711 				   const std::string& tessellation_evaluation_shader, const std::string& vertex_shader,
2712 				   bool is_separable)
2713 {
2714 	NameVector captured_varying;
2715 
2716 	Init(compute_shader, fragment_shader, geometry_shader, tessellation_control_shader, tessellation_evaluation_shader,
2717 		 vertex_shader, captured_varying, true, is_separable);
2718 }
2719 
2720 /** Release program instance
2721  *
2722  **/
Release()2723 void Program::Release()
2724 {
2725 	const Functions& gl = m_context.getRenderContext().getFunctions();
2726 
2727 	if (m_invalid_id != m_id)
2728 	{
2729 		Use(gl, m_invalid_id);
2730 
2731 		gl.deleteProgram(m_id);
2732 		m_id = m_invalid_id;
2733 	}
2734 
2735 	m_compute.Release();
2736 	m_fragment.Release();
2737 	m_geometry.Release();
2738 	m_tess_ctrl.Release();
2739 	m_tess_eval.Release();
2740 	m_vertex.Release();
2741 }
2742 
2743 /** Get <pname> for a set of active uniforms
2744  *
2745  * @param count   Number of indices
2746  * @param indices Indices of uniforms
2747  * @param pname   Queired pname
2748  * @param params  Array that will be filled with values of parameters
2749  **/
GetActiveUniformsiv(GLsizei count,const GLuint * indices,GLenum pname,GLint * params) const2750 void Program::GetActiveUniformsiv(GLsizei count, const GLuint* indices, GLenum pname, GLint* params) const
2751 {
2752 	const Functions& gl = m_context.getRenderContext().getFunctions();
2753 
2754 	GetActiveUniformsiv(gl, m_id, count, indices, pname, params);
2755 }
2756 
2757 /** Get location of attribute
2758  *
2759  * @param name Name of attribute
2760  *
2761  * @return Result of query
2762  **/
GetAttribLocation(const std::string & name) const2763 glw::GLint Program::GetAttribLocation(const std::string& name) const
2764 {
2765 	const Functions& gl = m_context.getRenderContext().getFunctions();
2766 
2767 	return GetAttribLocation(gl, m_id, name);
2768 }
2769 
2770 /** Query resource
2771  *
2772  * @param interface Interface to be queried
2773  * @param index     Index of resource
2774  * @param property  Property to be queried
2775  * @param buf_size  Size of <params> buffer
2776  * @param params    Results of query
2777  **/
GetResource(GLenum interface,GLuint index,GLenum property,GLsizei buf_size,GLint * params) const2778 void Program::GetResource(GLenum interface, GLuint index, GLenum property, GLsizei buf_size, GLint* params) const
2779 {
2780 	const Functions& gl = m_context.getRenderContext().getFunctions();
2781 
2782 	GetResource(gl, m_id, interface, index, property, buf_size, params);
2783 }
2784 
2785 /** Query for index of resource
2786  *
2787  * @param name      Name of resource
2788  * @param interface Interface to be queried
2789  *
2790  * @return Result of query
2791  **/
GetResourceIndex(const std::string & name,GLenum interface) const2792 glw::GLuint Program::GetResourceIndex(const std::string& name, GLenum interface) const
2793 {
2794 	const Functions& gl = m_context.getRenderContext().getFunctions();
2795 
2796 	return GetResourceIndex(gl, m_id, name, interface);
2797 }
2798 
2799 /** Get indices for a set of uniforms
2800  *
2801  * @param count   Count number of uniforms
2802  * @param names   Names of uniforms
2803  * @param indices Buffer that will be filled with indices
2804  **/
GetUniformIndices(GLsizei count,const GLchar ** names,GLuint * indices) const2805 void Program::GetUniformIndices(GLsizei count, const GLchar** names, GLuint* indices) const
2806 {
2807 	const Functions& gl = m_context.getRenderContext().getFunctions();
2808 
2809 	GetUniformIndices(gl, m_id, count, names, indices);
2810 }
2811 
2812 /** Get uniform location
2813  *
2814  * @param name Name of uniform
2815  *
2816  * @return Results of query
2817  **/
GetUniformLocation(const std::string & name) const2818 glw::GLint Program::GetUniformLocation(const std::string& name) const
2819 {
2820 	const Functions& gl = m_context.getRenderContext().getFunctions();
2821 
2822 	return GetUniformLocation(gl, m_id, name);
2823 }
2824 
2825 /** Set program as active
2826  *
2827  **/
Use() const2828 void Program::Use() const
2829 {
2830 	const Functions& gl = m_context.getRenderContext().getFunctions();
2831 
2832 	Use(gl, m_id);
2833 }
2834 
2835 /** Attach shader to program
2836  *
2837  * @param gl         GL functions
2838  * @param program_id Id of program
2839  * @param shader_id  Id of shader
2840  **/
Attach(const Functions & gl,GLuint program_id,GLuint shader_id)2841 void Program::Attach(const Functions& gl, GLuint program_id, GLuint shader_id)
2842 {
2843 	/* Sanity checks */
2844 	if ((m_invalid_id == program_id) || (Shader::m_invalid_id == shader_id))
2845 	{
2846 		return;
2847 	}
2848 
2849 	gl.attachShader(program_id, shader_id);
2850 	GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
2851 }
2852 
2853 /** Set up captured varyings
2854  *
2855  * @param gl                  GL functions
2856  * @param id                  Id of program
2857  * @param captured_varyings   Vector of varyings
2858  * @param capture_interleaved Selects if interleaved or separate mode should be used
2859  **/
Capture(const Functions & gl,GLuint id,const NameVector & captured_varyings,bool capture_interleaved)2860 void Program::Capture(const Functions& gl, GLuint id, const NameVector& captured_varyings, bool capture_interleaved)
2861 {
2862 	const size_t n_varyings = captured_varyings.size();
2863 
2864 	if (0 == n_varyings)
2865 	{
2866 		/* empty list, skip */
2867 		return;
2868 	}
2869 
2870 	std::vector<const GLchar*> varying_names;
2871 	varying_names.resize(n_varyings);
2872 
2873 	for (size_t i = 0; i < n_varyings; ++i)
2874 	{
2875 		varying_names[i] = captured_varyings[i].c_str();
2876 	}
2877 
2878 	GLenum mode = 0;
2879 	if (true == capture_interleaved)
2880 	{
2881 		mode = GL_INTERLEAVED_ATTRIBS;
2882 	}
2883 	else
2884 	{
2885 		mode = GL_SEPARATE_ATTRIBS;
2886 	}
2887 
2888 	gl.transformFeedbackVaryings(id, static_cast<GLsizei>(n_varyings), &varying_names[0], mode);
2889 	GLU_EXPECT_NO_ERROR(gl.getError(), "TransformFeedbackVaryings");
2890 }
2891 
2892 /** Create program instance
2893  *
2894  * @param gl     GL functions
2895  * @param out_id Id of program
2896  **/
Create(const Functions & gl,GLuint & out_id)2897 void Program::Create(const Functions& gl, GLuint& out_id)
2898 {
2899 	const GLuint id = gl.createProgram();
2900 	GLU_EXPECT_NO_ERROR(gl.getError(), "CreateProgram");
2901 
2902 	if (m_invalid_id == id)
2903 	{
2904 		TCU_FAIL("Failed to create program");
2905 	}
2906 
2907 	out_id = id;
2908 }
2909 
2910 /** Get <pname> for a set of active uniforms
2911  *
2912  * @param gl         Functions
2913  * @param program_id Id of program
2914  * @param count      Number of indices
2915  * @param indices    Indices of uniforms
2916  * @param pname      Queired pname
2917  * @param params     Array that will be filled with values of parameters
2918  **/
GetActiveUniformsiv(const Functions & gl,GLuint program_id,GLsizei count,const GLuint * indices,GLenum pname,GLint * params)2919 void Program::GetActiveUniformsiv(const Functions& gl, GLuint program_id, GLsizei count, const GLuint* indices,
2920 								  GLenum pname, GLint* params)
2921 {
2922 	gl.getActiveUniformsiv(program_id, count, indices, pname, params);
2923 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetActiveUniformsiv");
2924 }
2925 
2926 /** Get indices for a set of uniforms
2927  *
2928  * @param gl         Functions
2929  * @param program_id Id of program
2930  * @param count      Count number of uniforms
2931  * @param names      Names of uniforms
2932  * @param indices    Buffer that will be filled with indices
2933  **/
GetUniformIndices(const Functions & gl,GLuint program_id,GLsizei count,const GLchar ** names,GLuint * indices)2934 void Program::GetUniformIndices(const Functions& gl, GLuint program_id, GLsizei count, const GLchar** names,
2935 								GLuint* indices)
2936 {
2937 	gl.getUniformIndices(program_id, count, names, indices);
2938 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformIndices");
2939 }
2940 
2941 /** Link program
2942  *
2943  * @param gl GL functions
2944  * @param id Id of program
2945  **/
Link(const Functions & gl,GLuint id)2946 void Program::Link(const Functions& gl, GLuint id)
2947 {
2948 	GLint status = GL_FALSE;
2949 
2950 	gl.linkProgram(id);
2951 	GLU_EXPECT_NO_ERROR(gl.getError(), "LinkProgram");
2952 
2953 	/* Get link status */
2954 	gl.getProgramiv(id, GL_LINK_STATUS, &status);
2955 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");
2956 
2957 	/* Log link error */
2958 	if (GL_TRUE != status)
2959 	{
2960 		glw::GLint  length = 0;
2961 		std::string message;
2962 
2963 		/* Get error log length */
2964 		gl.getProgramiv(id, GL_INFO_LOG_LENGTH, &length);
2965 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");
2966 
2967 		message.resize(length, 0);
2968 
2969 		/* Get error log */
2970 		gl.getProgramInfoLog(id, length, 0, &message[0]);
2971 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramInfoLog");
2972 
2973 		throw LinkageException(message.c_str());
2974 	}
2975 }
2976 
2977 /** Set generic uniform
2978  *
2979  * @param gl       Functions
2980  * @param type     Type of uniform
2981  * @param count    Length of array
2982  * @param location Location of uniform
2983  * @param data     Data that will be used
2984  **/
Uniform(const Functions & gl,const Type & type,GLsizei count,GLint location,const GLvoid * data)2985 void Program::Uniform(const Functions& gl, const Type& type, GLsizei count, GLint location, const GLvoid* data)
2986 {
2987 	if (-1 == location)
2988 	{
2989 		TCU_FAIL("Uniform is inactive");
2990 	}
2991 
2992 	switch (type.m_basic_type)
2993 	{
2994 	case Type::Double:
2995 		if (1 == type.m_n_columns)
2996 		{
2997 			getUniformNdv(gl, type.m_n_rows)(location, count, (const GLdouble*)data);
2998 			GLU_EXPECT_NO_ERROR(gl.getError(), "UniformNdv");
2999 		}
3000 		else
3001 		{
3002 			getUniformMatrixNdv(gl, type.m_n_columns, type.m_n_rows)(location, count, false, (const GLdouble*)data);
3003 			GLU_EXPECT_NO_ERROR(gl.getError(), "UniformMatrixNdv");
3004 		}
3005 		break;
3006 	case Type::Float:
3007 		if (1 == type.m_n_columns)
3008 		{
3009 			getUniformNfv(gl, type.m_n_rows)(location, count, (const GLfloat*)data);
3010 			GLU_EXPECT_NO_ERROR(gl.getError(), "UniformNfv");
3011 		}
3012 		else
3013 		{
3014 			getUniformMatrixNfv(gl, type.m_n_columns, type.m_n_rows)(location, count, false, (const GLfloat*)data);
3015 			GLU_EXPECT_NO_ERROR(gl.getError(), "UniformMatrixNfv");
3016 		}
3017 		break;
3018 	case Type::Int:
3019 		getUniformNiv(gl, type.m_n_rows)(location, count, (const GLint*)data);
3020 		GLU_EXPECT_NO_ERROR(gl.getError(), "UniformNiv");
3021 		break;
3022 	case Type::Uint:
3023 		getUniformNuiv(gl, type.m_n_rows)(location, count, (const GLuint*)data);
3024 		GLU_EXPECT_NO_ERROR(gl.getError(), "UniformNuiv");
3025 		break;
3026 	default:
3027 		TCU_FAIL("Invalid enum");
3028 	}
3029 }
3030 
3031 /** Use program
3032  *
3033  * @param gl GL functions
3034  * @param id Id of program
3035  **/
Use(const Functions & gl,GLuint id)3036 void Program::Use(const Functions& gl, GLuint id)
3037 {
3038 	gl.useProgram(id);
3039 	GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram");
3040 }
3041 
3042 /** Get location of attribute
3043  *
3044  * @param gl   GL functions
3045  * @param id   Id of program
3046  * @param name Name of attribute
3047  *
3048  * @return Location of attribute
3049  **/
GetAttribLocation(const Functions & gl,GLuint id,const std::string & name)3050 GLint Program::GetAttribLocation(const Functions& gl, GLuint id, const std::string& name)
3051 {
3052 	GLint location = gl.getAttribLocation(id, name.c_str());
3053 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetAttribLocation");
3054 
3055 	return location;
3056 }
3057 
3058 /** Query resource
3059  *
3060  * @param gl        GL functions
3061  * @param id        Id of program
3062  * @param interface Interface to be queried
3063  * @param index     Index of resource
3064  * @param property  Property to be queried
3065  * @param buf_size  Size of <params> buffer
3066  * @param params    Results of query
3067  **/
GetResource(const Functions & gl,GLuint id,GLenum interface,GLuint index,GLenum property,GLsizei buf_size,GLint * params)3068 void Program::GetResource(const Functions& gl, GLuint id, GLenum interface, GLuint index, GLenum property,
3069 						  GLsizei buf_size, GLint* params)
3070 {
3071 	gl.getProgramResourceiv(id, interface, index, 1 /* propCount */, &property, buf_size /* bufSize */, 0 /* length */,
3072 							params);
3073 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramResourceiv");
3074 }
3075 
3076 /** Get index of resource
3077  *
3078  * @param gl        GL functions
3079  * @param id        Id of program
3080  * @param name      Name of resource
3081  * @param interface Program interface to queried
3082  *
3083  * @return Location of attribute
3084  **/
GetResourceIndex(const Functions & gl,GLuint id,const std::string & name,GLenum interface)3085 GLuint Program::GetResourceIndex(const Functions& gl, GLuint id, const std::string& name, GLenum interface)
3086 {
3087 	GLuint index = gl.getProgramResourceIndex(id, interface, name.c_str());
3088 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramResourceIndex");
3089 
3090 	return index;
3091 }
3092 
3093 /** Get location of attribute
3094  *
3095  * @param gl   GL functions
3096  * @param id   Id of program
3097  * @param name Name of attribute
3098  *
3099  * @return Location of uniform
3100  **/
GetUniformLocation(const Functions & gl,GLuint id,const std::string & name)3101 GLint Program::GetUniformLocation(const Functions& gl, GLuint id, const std::string& name)
3102 {
3103 	GLint location = gl.getUniformLocation(id, name.c_str());
3104 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformLocation");
3105 
3106 	return location;
3107 }
3108 
3109 /** Constructor
3110  *
3111  * @param error_message    Error message
3112  * @param compute_shader   Source code for compute stage
3113  * @param fragment_shader  Source code for fragment stage
3114  * @param geometry_shader  Source code for geometry stage
3115  * @param tess_ctrl_shader Source code for tessellation control stage
3116  * @param tess_eval_shader Source code for tessellation evaluation stage
3117  * @param vertex_shader    Source code for vertex stage
3118  **/
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)3119 Program::BuildException::BuildException(const glw::GLchar* error_message, const std::string compute_shader,
3120 										const std::string fragment_shader, const std::string geometry_shader,
3121 										const std::string tess_ctrl_shader, const std::string tess_eval_shader,
3122 										const std::string vertex_shader)
3123 	: m_error_message(error_message)
3124 	, m_compute_shader(compute_shader)
3125 	, m_fragment_shader(fragment_shader)
3126 	, m_geometry_shader(geometry_shader)
3127 	, m_tess_ctrl_shader(tess_ctrl_shader)
3128 	, m_tess_eval_shader(tess_eval_shader)
3129 	, m_vertex_shader(vertex_shader)
3130 {
3131 }
3132 
3133 /** Overwrites std::exception::what method
3134  *
3135  * @return Message compossed from error message and shader sources
3136  **/
what() const3137 const char* Program::BuildException::what() const throw()
3138 {
3139 	return "Failed to link program";
3140 }
3141 
3142 /** Logs error message and shader sources **/
log(deqp::Context & context) const3143 void Program::BuildException::log(deqp::Context& context) const
3144 {
3145 	context.getTestContext().getLog() << tcu::TestLog::Message << "Link failure: " << m_error_message
3146 									  << tcu::TestLog::EndMessage;
3147 
3148 	Shader::LogSource(context, m_vertex_shader, Shader::VERTEX);
3149 	Shader::LogSource(context, m_tess_ctrl_shader, Shader::TESS_CTRL);
3150 	Shader::LogSource(context, m_tess_eval_shader, Shader::TESS_EVAL);
3151 	Shader::LogSource(context, m_geometry_shader, Shader::GEOMETRY);
3152 	Shader::LogSource(context, m_fragment_shader, Shader::FRAGMENT);
3153 	Shader::LogSource(context, m_compute_shader, Shader::COMPUTE);
3154 }
3155 
3156 /** Constructor
3157  *
3158  * @param message Linking error message
3159  **/
LinkageException(const glw::GLchar * message)3160 Program::LinkageException::LinkageException(const glw::GLchar* message) : m_error_message(message)
3161 {
3162 	/* Nothing to be done */
3163 }
3164 
3165 /** Returns error messages
3166  *
3167  * @return Linking error message
3168  **/
what() const3169 const char* Program::LinkageException::what() const throw()
3170 {
3171 	return m_error_message.c_str();
3172 }
3173 
3174 /* Texture constants */
3175 const GLuint Texture::m_invalid_id = -1;
3176 
3177 /** Constructor.
3178  *
3179  * @param context CTS context.
3180  **/
Texture(deqp::Context & context)3181 Texture::Texture(deqp::Context& context) : m_id(m_invalid_id), m_context(context), m_type(TEX_2D)
3182 {
3183 	/* Nothing to done here */
3184 }
3185 
3186 /** Destructor
3187  *
3188  **/
~Texture()3189 Texture::~Texture()
3190 {
3191 	Release();
3192 }
3193 
3194 /** Initialize texture instance
3195  *
3196  * @param tex_type        Type of texture
3197  * @param width           Width of texture
3198  * @param height          Height of texture
3199  * @param depth           Depth of texture
3200  * @param internal_format Internal format of texture
3201  * @param format          Format of texture data
3202  * @param type            Type of texture data
3203  * @param data            Texture data
3204  **/
Init(TYPES tex_type,GLuint width,GLuint height,GLuint depth,GLenum internal_format,GLenum format,GLenum type,GLvoid * data)3205 void Texture::Init(TYPES tex_type, GLuint width, GLuint height, GLuint depth, GLenum internal_format, GLenum format,
3206 				   GLenum type, GLvoid* data)
3207 {
3208 	const Functions& gl = m_context.getRenderContext().getFunctions();
3209 
3210 	/* Delete previous texture */
3211 	Release();
3212 
3213 	m_type = tex_type;
3214 
3215 	/* Generate, bind, allocate storage and upload data */
3216 	Generate(gl, m_id);
3217 	Bind(gl, m_id, tex_type);
3218 	Storage(gl, tex_type, width, height, depth, internal_format);
3219 	Update(gl, tex_type, width, height, depth, format, type, data);
3220 }
3221 
3222 /** Initialize buffer texture
3223  *
3224  * @param internal_format Internal format of texture
3225  * @param buffer_id       Id of buffer that will be used as data source
3226  **/
Init(GLenum internal_format,GLuint buffer_id)3227 void Texture::Init(GLenum internal_format, GLuint buffer_id)
3228 {
3229 	const Functions& gl = m_context.getRenderContext().getFunctions();
3230 
3231 	/* Delete previous texture */
3232 	Release();
3233 
3234 	m_type = TEX_BUFFER;
3235 
3236 	/* Generate, bind and attach buffer */
3237 	Generate(gl, m_id);
3238 	Bind(gl, m_id, TEX_BUFFER);
3239 	TexBuffer(gl, buffer_id, internal_format);
3240 }
3241 
3242 /** Release texture instance
3243  *
3244  **/
Release()3245 void Texture::Release()
3246 {
3247 	if (m_invalid_id != m_id)
3248 	{
3249 		const Functions& gl = m_context.getRenderContext().getFunctions();
3250 
3251 		gl.deleteTextures(1, &m_id);
3252 		m_id = m_invalid_id;
3253 	}
3254 }
3255 
3256 /** Bind texture to its target
3257  *
3258  **/
Bind() const3259 void Texture::Bind() const
3260 {
3261 	const Functions& gl = m_context.getRenderContext().getFunctions();
3262 
3263 	Bind(gl, m_id, m_type);
3264 }
3265 
3266 /** Get texture data
3267  *
3268  * @param format   Format of data
3269  * @param type     Type of data
3270  * @param out_data Buffer for data
3271  **/
Get(GLenum format,GLenum type,GLvoid * out_data) const3272 void Texture::Get(GLenum format, GLenum type, GLvoid* out_data) const
3273 {
3274 	const Functions& gl = m_context.getRenderContext().getFunctions();
3275 
3276 	Bind(gl, m_id, m_type);
3277 	Get(gl, m_type, format, type, out_data);
3278 }
3279 
3280 /** Bind texture to target
3281  *
3282  * @param gl       GL functions
3283  * @param id       Id of texture
3284  * @param tex_type Type of texture
3285  **/
Bind(const Functions & gl,GLuint id,TYPES tex_type)3286 void Texture::Bind(const Functions& gl, GLuint id, TYPES tex_type)
3287 {
3288 	GLenum target = GetTargetGLenum(tex_type);
3289 
3290 	gl.bindTexture(target, id);
3291 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
3292 }
3293 
3294 /** Generate texture instance
3295  *
3296  * @param gl     GL functions
3297  * @param out_id Id of texture
3298  **/
Generate(const Functions & gl,GLuint & out_id)3299 void Texture::Generate(const Functions& gl, GLuint& out_id)
3300 {
3301 	GLuint id = m_invalid_id;
3302 
3303 	gl.genTextures(1, &id);
3304 	GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures");
3305 
3306 	if (m_invalid_id == id)
3307 	{
3308 		TCU_FAIL("Invalid id");
3309 	}
3310 
3311 	out_id = id;
3312 }
3313 
3314 /** Get texture data
3315  *
3316  * @param gl       GL functions
3317  * @param format   Format of data
3318  * @param type     Type of data
3319  * @param out_data Buffer for data
3320  **/
Get(const Functions & gl,TYPES tex_type,GLenum format,GLenum type,GLvoid * out_data)3321 void Texture::Get(const Functions& gl, TYPES tex_type, GLenum format, GLenum type, GLvoid* out_data)
3322 {
3323 	GLenum target = GetTargetGLenum(tex_type);
3324 
3325 	if (TEX_CUBE != tex_type)
3326 	{
3327 		gl.getTexImage(target, 0 /* level */, format, type, out_data);
3328 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexImage");
3329 	}
3330 	else
3331 	{
3332 		GLint width;
3333 		GLint height;
3334 
3335 		if ((GL_RGBA != format) && (GL_UNSIGNED_BYTE != type))
3336 		{
3337 			TCU_FAIL("Not implemented");
3338 		}
3339 
3340 		GLuint texel_size = 4;
3341 
3342 		gl.getTexLevelParameteriv(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0 /* level */, GL_TEXTURE_WIDTH, &width);
3343 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv");
3344 
3345 		gl.getTexLevelParameteriv(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0 /* level */, GL_TEXTURE_HEIGHT, &height);
3346 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv");
3347 
3348 		const GLuint image_size = width * height * texel_size;
3349 
3350 		gl.getTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0 /* level */, format, type,
3351 					   (GLvoid*)((GLchar*)out_data + (image_size * 0)));
3352 		gl.getTexImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0 /* level */, format, type,
3353 					   (GLvoid*)((GLchar*)out_data + (image_size * 1)));
3354 		gl.getTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0 /* level */, format, type,
3355 					   (GLvoid*)((GLchar*)out_data + (image_size * 2)));
3356 		gl.getTexImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0 /* level */, format, type,
3357 					   (GLvoid*)((GLchar*)out_data + (image_size * 3)));
3358 		gl.getTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0 /* level */, format, type,
3359 					   (GLvoid*)((GLchar*)out_data + (image_size * 4)));
3360 		gl.getTexImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0 /* level */, format, type,
3361 					   (GLvoid*)((GLchar*)out_data + (image_size * 5)));
3362 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexImage");
3363 	}
3364 }
3365 
3366 /** Allocate storage for texture
3367  *
3368  * @param gl              GL functions
3369  * @param tex_type        Type of texture
3370  * @param width           Width of texture
3371  * @param height          Height of texture
3372  * @param depth           Depth of texture
3373  * @param internal_format Internal format of texture
3374  **/
Storage(const Functions & gl,TYPES tex_type,GLuint width,GLuint height,GLuint depth,GLenum internal_format)3375 void Texture::Storage(const Functions& gl, TYPES tex_type, GLuint width, GLuint height, GLuint depth,
3376 					  GLenum internal_format)
3377 {
3378 	static const GLuint levels = 1;
3379 
3380 	GLenum target = GetTargetGLenum(tex_type);
3381 
3382 	switch (tex_type)
3383 	{
3384 	case TEX_1D:
3385 		gl.texStorage1D(target, levels, internal_format, width);
3386 		GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage1D");
3387 		break;
3388 	case TEX_2D:
3389 	case TEX_1D_ARRAY:
3390 	case TEX_2D_RECT:
3391 	case TEX_CUBE:
3392 		gl.texStorage2D(target, levels, internal_format, width, height);
3393 		GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2D");
3394 		break;
3395 	case TEX_3D:
3396 	case TEX_2D_ARRAY:
3397 		gl.texStorage3D(target, levels, internal_format, width, height, depth);
3398 		GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage3D");
3399 		break;
3400 	default:
3401 		TCU_FAIL("Invliad enum");
3402 		break;
3403 	}
3404 }
3405 
3406 /** Attach buffer as source of texture buffer data
3407  *
3408  * @param gl              GL functions
3409  * @param internal_format Internal format of texture
3410  * @param buffer_id       Id of buffer that will be used as data source
3411  **/
TexBuffer(const Functions & gl,GLenum internal_format,GLuint & buffer_id)3412 void Texture::TexBuffer(const Functions& gl, GLenum internal_format, GLuint& buffer_id)
3413 {
3414 	gl.texBuffer(GL_TEXTURE_BUFFER, internal_format, buffer_id);
3415 	GLU_EXPECT_NO_ERROR(gl.getError(), "TexBuffer");
3416 }
3417 
3418 /** Update contents of texture
3419  *
3420  * @param gl       GL functions
3421  * @param tex_type Type of texture
3422  * @param width    Width of texture
3423  * @param height   Height of texture
3424  * @param format   Format of data
3425  * @param type     Type of data
3426  * @param data     Buffer with image data
3427  **/
Update(const Functions & gl,TYPES tex_type,GLuint width,GLuint height,GLuint depth,GLenum format,GLenum type,GLvoid * data)3428 void Texture::Update(const Functions& gl, TYPES tex_type, GLuint width, GLuint height, GLuint depth, GLenum format,
3429 					 GLenum type, GLvoid* data)
3430 {
3431 	static const GLuint level = 0;
3432 
3433 	GLenum target = GetTargetGLenum(tex_type);
3434 
3435 	switch (tex_type)
3436 	{
3437 	case TEX_1D:
3438 		gl.texSubImage1D(target, level, 0 /* x */, width, format, type, data);
3439 		GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage1D");
3440 		break;
3441 	case TEX_2D:
3442 	case TEX_1D_ARRAY:
3443 	case TEX_2D_RECT:
3444 		gl.texSubImage2D(target, level, 0 /* x */, 0 /* y */, width, height, format, type, data);
3445 		GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2D");
3446 		break;
3447 	case TEX_CUBE:
3448 		gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, level, 0 /* x */, 0 /* y */, width, height, format, type,
3449 						 data);
3450 		gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, level, 0 /* x */, 0 /* y */, width, height, format, type,
3451 						 data);
3452 		gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, level, 0 /* x */, 0 /* y */, width, height, format, type,
3453 						 data);
3454 		gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, level, 0 /* x */, 0 /* y */, width, height, format, type,
3455 						 data);
3456 		gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, level, 0 /* x */, 0 /* y */, width, height, format, type,
3457 						 data);
3458 		gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, level, 0 /* x */, 0 /* y */, width, height, format, type,
3459 						 data);
3460 		GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2D");
3461 		break;
3462 	case TEX_3D:
3463 	case TEX_2D_ARRAY:
3464 		gl.texSubImage3D(target, level, 0 /* x */, 0 /* y */, 0 /* z */, width, height, depth, format, type, data);
3465 		GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage3D");
3466 		break;
3467 	default:
3468 		TCU_FAIL("Invliad enum");
3469 		break;
3470 	}
3471 }
3472 
3473 /** Get target for given texture type
3474  *
3475  * @param type Type of texture
3476  *
3477  * @return Target
3478  **/
GetTargetGLenum(TYPES type)3479 GLenum Texture::GetTargetGLenum(TYPES type)
3480 {
3481 	GLenum result = 0;
3482 
3483 	switch (type)
3484 	{
3485 	case TEX_BUFFER:
3486 		result = GL_TEXTURE_BUFFER;
3487 		break;
3488 	case TEX_2D:
3489 		result = GL_TEXTURE_2D;
3490 		break;
3491 	case TEX_2D_RECT:
3492 		result = GL_TEXTURE_RECTANGLE;
3493 		break;
3494 	case TEX_2D_ARRAY:
3495 		result = GL_TEXTURE_2D_ARRAY;
3496 		break;
3497 	case TEX_3D:
3498 		result = GL_TEXTURE_3D;
3499 		break;
3500 	case TEX_CUBE:
3501 		result = GL_TEXTURE_CUBE_MAP;
3502 		break;
3503 	case TEX_1D:
3504 		result = GL_TEXTURE_1D;
3505 		break;
3506 	case TEX_1D_ARRAY:
3507 		result = GL_TEXTURE_1D_ARRAY;
3508 		break;
3509 	}
3510 
3511 	return result;
3512 }
3513 
3514 /* VertexArray constants */
3515 const GLuint VertexArray::m_invalid_id = -1;
3516 
3517 /** Constructor.
3518  *
3519  * @param context CTS context.
3520  **/
VertexArray(deqp::Context & context)3521 VertexArray::VertexArray(deqp::Context& context) : m_id(m_invalid_id), m_context(context)
3522 {
3523 }
3524 
3525 /** Destructor
3526  *
3527  **/
~VertexArray()3528 VertexArray::~VertexArray()
3529 {
3530 	Release();
3531 }
3532 
3533 /** Initialize vertex array instance
3534  *
3535  **/
Init()3536 void VertexArray::Init()
3537 {
3538 	/* Delete previous instance */
3539 	Release();
3540 
3541 	const Functions& gl = m_context.getRenderContext().getFunctions();
3542 
3543 	Generate(gl, m_id);
3544 }
3545 
3546 /** Release vertex array object instance
3547  *
3548  **/
Release()3549 void VertexArray::Release()
3550 {
3551 	if (m_invalid_id != m_id)
3552 	{
3553 		const Functions& gl = m_context.getRenderContext().getFunctions();
3554 
3555 		gl.deleteVertexArrays(1, &m_id);
3556 
3557 		m_id = m_invalid_id;
3558 	}
3559 }
3560 
3561 /** Set attribute in VAO
3562  *
3563  * @param index            Index of attribute
3564  * @param type             Type of attribute
3565  * @param n_array_elements Arary length
3566  * @param normalized       Selectis if values should be normalized
3567  * @param stride           Stride
3568  * @param pointer          Pointer to data, or offset in buffer
3569  **/
Attribute(GLuint index,const Type & type,GLuint n_array_elements,GLboolean normalized,GLsizei stride,const GLvoid * pointer)3570 void VertexArray::Attribute(GLuint index, const Type& type, GLuint n_array_elements, GLboolean normalized,
3571 							GLsizei stride, const GLvoid* pointer)
3572 {
3573 	const Functions& gl = m_context.getRenderContext().getFunctions();
3574 
3575 	AttribPointer(gl, index, type, n_array_elements, normalized, stride, pointer);
3576 	Enable(gl, index, type, n_array_elements);
3577 }
3578 
3579 /** Binds Vertex array object
3580  *
3581  **/
Bind()3582 void VertexArray::Bind()
3583 {
3584 	const Functions& gl = m_context.getRenderContext().getFunctions();
3585 
3586 	Bind(gl, m_id);
3587 }
3588 
3589 /** Set attribute in VAO
3590  *
3591  * @param gl               Functions
3592  * @param index            Index of attribute
3593  * @param type             Type of attribute
3594  * @param n_array_elements Arary length
3595  * @param normalized       Selectis if values should be normalized
3596  * @param stride           Stride
3597  * @param pointer          Pointer to data, or offset in buffer
3598  **/
AttribPointer(const Functions & gl,GLuint index,const Type & type,GLuint n_array_elements,GLboolean normalized,GLsizei stride,const GLvoid * pointer)3599 void VertexArray::AttribPointer(const Functions& gl, GLuint index, const Type& type, GLuint n_array_elements,
3600 								GLboolean normalized, GLsizei stride, const GLvoid* pointer)
3601 {
3602 	const GLuint basic_type_size = Type::GetTypeSize(type.m_basic_type);
3603 	const GLint  size			 = (GLint)type.m_n_rows;
3604 	const GLuint column_size	 = (GLuint)size * basic_type_size;
3605 	const GLenum gl_type		 = Type::GetTypeGLenum(type.m_basic_type);
3606 
3607 	GLuint offset = 0;
3608 
3609 	/* If attribute is not an array */
3610 	if (0 == n_array_elements)
3611 	{
3612 		n_array_elements = 1;
3613 	}
3614 
3615 	/* For each element in array */
3616 	for (GLuint element = 0; element < n_array_elements; ++element)
3617 	{
3618 		/* For each column in matrix */
3619 		for (GLuint column = 1; column <= type.m_n_columns; ++column)
3620 		{
3621 			/* Calculate offset */
3622 			const GLvoid* ptr = (GLubyte*)pointer + offset;
3623 
3624 			/* Set up attribute */
3625 			switch (type.m_basic_type)
3626 			{
3627 			case Type::Float:
3628 				gl.vertexAttribPointer(index, size, gl_type, normalized, stride, ptr);
3629 				GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttribPointer");
3630 				break;
3631 			case Type::Int:
3632 			case Type::Uint:
3633 				gl.vertexAttribIPointer(index, size, gl_type, stride, ptr);
3634 				GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttribIPointer");
3635 				break;
3636 			case Type::Double:
3637 				gl.vertexAttribLPointer(index, size, gl_type, stride, ptr);
3638 				GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttribLPointer");
3639 				break;
3640 			default:
3641 				TCU_FAIL("Invalid enum");
3642 			}
3643 
3644 			/* Next location */
3645 			offset += column_size;
3646 			index += 1;
3647 		}
3648 	}
3649 }
3650 
3651 /** Binds Vertex array object
3652  *
3653  * @param gl GL functions
3654  * @param id ID of vertex array object
3655  **/
Bind(const glw::Functions & gl,glw::GLuint id)3656 void VertexArray::Bind(const glw::Functions& gl, glw::GLuint id)
3657 {
3658 	gl.bindVertexArray(id);
3659 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindVertexArray");
3660 }
3661 
3662 /** Disable attribute in VAO
3663  *
3664  * @param gl               Functions
3665  * @param index            Index of attribute
3666  * @param type             Type of attribute
3667  * @param n_array_elements Arary length
3668  **/
Disable(const Functions & gl,GLuint index,const Type & type,GLuint n_array_elements)3669 void VertexArray::Disable(const Functions& gl, GLuint index, const Type& type, GLuint n_array_elements)
3670 {
3671 	/* If attribute is not an array */
3672 	if (0 == n_array_elements)
3673 	{
3674 		n_array_elements = 1;
3675 	}
3676 
3677 	/* For each element in array */
3678 	for (GLuint element = 0; element < n_array_elements; ++element)
3679 	{
3680 		/* For each column in matrix */
3681 		for (GLuint column = 1; column <= type.m_n_columns; ++column)
3682 		{
3683 			/* Enable attribute array */
3684 			gl.disableVertexAttribArray(index);
3685 			GLU_EXPECT_NO_ERROR(gl.getError(), "DisableVertexAttribArray");
3686 
3687 			/* Next location */
3688 			index += 1;
3689 		}
3690 	}
3691 }
3692 
3693 /** Set divisor for attribute
3694  *
3695  * @param gl               Functions
3696  * @param index            Index of attribute
3697  * @param divisor          New divisor value
3698  **/
Divisor(const Functions & gl,GLuint index,GLuint divisor)3699 void VertexArray::Divisor(const Functions& gl, GLuint index, GLuint divisor)
3700 {
3701 	gl.vertexAttribDivisor(index, divisor);
3702 	GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttribDivisor");
3703 }
3704 
3705 /** Enables attribute in VAO
3706  *
3707  * @param gl               Functions
3708  * @param index            Index of attribute
3709  * @param type             Type of attribute
3710  * @param n_array_elements Arary length
3711  **/
Enable(const Functions & gl,GLuint index,const Type & type,GLuint n_array_elements)3712 void VertexArray::Enable(const Functions& gl, GLuint index, const Type& type, GLuint n_array_elements)
3713 {
3714 	/* If attribute is not an array */
3715 	if (0 == n_array_elements)
3716 	{
3717 		n_array_elements = 1;
3718 	}
3719 
3720 	/* For each element in array */
3721 	for (GLuint element = 0; element < n_array_elements; ++element)
3722 	{
3723 		/* For each column in matrix */
3724 		for (GLuint column = 1; column <= type.m_n_columns; ++column)
3725 		{
3726 			/* Enable attribute array */
3727 			gl.enableVertexAttribArray(index);
3728 			GLU_EXPECT_NO_ERROR(gl.getError(), "EnableVertexAttribArray");
3729 
3730 			/* Next location */
3731 			index += 1;
3732 		}
3733 	}
3734 }
3735 
3736 /** Generates Vertex array object
3737  *
3738  * @param gl     GL functions
3739  * @param out_id ID of vertex array object
3740  **/
Generate(const glw::Functions & gl,glw::GLuint & out_id)3741 void VertexArray::Generate(const glw::Functions& gl, glw::GLuint& out_id)
3742 {
3743 	GLuint id = m_invalid_id;
3744 
3745 	gl.genVertexArrays(1, &id);
3746 	GLU_EXPECT_NO_ERROR(gl.getError(), "GenVertexArrays");
3747 
3748 	if (m_invalid_id == id)
3749 	{
3750 		TCU_FAIL("Invalid id");
3751 	}
3752 
3753 	out_id = id;
3754 }
3755 
3756 /* Constatns used by Variable */
3757 const GLint Variable::m_automatic_location = -1;
3758 
3759 /** Copy constructor
3760  *
3761  **/
Variable(const Variable & var)3762 Variable::Variable(const Variable& var)
3763 	: m_data(var.m_data)
3764 	, m_data_size(var.m_data_size)
3765 	, m_descriptor(var.m_descriptor.m_name.c_str(), var.m_descriptor.m_qualifiers.c_str(),
3766 				   var.m_descriptor.m_expected_component, var.m_descriptor.m_expected_location,
3767 				   var.m_descriptor.m_builtin, var.m_descriptor.m_normalized, var.m_descriptor.m_n_array_elements,
3768 				   var.m_descriptor.m_expected_stride_of_element, var.m_descriptor.m_offset)
3769 	, m_storage(var.m_storage)
3770 {
3771 	m_descriptor.m_type = var.m_descriptor.m_type;
3772 
3773 	if (BUILTIN != var.m_descriptor.m_type)
3774 	{
3775 		m_descriptor.m_interface = var.m_descriptor.m_interface;
3776 	}
3777 }
3778 
3779 /** Get code that defines variable
3780  *
3781  * @param flavour Provides info if variable is array or not
3782  *
3783  * @return String with code
3784  **/
GetDefinition(FLAVOUR flavour) const3785 std::string Variable::GetDefinition(FLAVOUR flavour) const
3786 {
3787 	return m_descriptor.GetDefinition(flavour, m_storage);
3788 }
3789 
3790 /** Calcualtes stride of variable
3791  *
3792  * @return Calculated value
3793  **/
GetStride() const3794 GLuint Variable::GetStride() const
3795 {
3796 	GLint variable_stride = 0;
3797 
3798 	if (0 == m_descriptor.m_n_array_elements)
3799 	{
3800 		variable_stride = m_descriptor.m_expected_stride_of_element;
3801 	}
3802 	else
3803 	{
3804 		variable_stride = m_descriptor.m_expected_stride_of_element * m_descriptor.m_n_array_elements;
3805 	}
3806 
3807 	return variable_stride;
3808 }
3809 
3810 /** Check if variable is block
3811  *
3812  * @return true if variable type is block, false otherwise
3813  **/
IsBlock() const3814 bool Variable::IsBlock() const
3815 {
3816 	if (BUILTIN == m_descriptor.m_type)
3817 	{
3818 		return false;
3819 	}
3820 
3821 	const Interface* interface = m_descriptor.m_interface;
3822 	if (0 == interface)
3823 	{
3824 		TCU_FAIL("Nullptr");
3825 	}
3826 
3827 	return (Interface::BLOCK == interface->m_type);
3828 }
3829 
3830 /** Check if variable is struct
3831  *
3832  * @return true if variable type is struct, false otherwise
3833  **/
IsStruct() const3834 bool Variable::IsStruct() const
3835 {
3836 	if (BUILTIN == m_descriptor.m_type)
3837 	{
3838 		return false;
3839 	}
3840 
3841 	const Interface* interface = m_descriptor.m_interface;
3842 	if (0 == interface)
3843 	{
3844 		TCU_FAIL("Nullptr");
3845 	}
3846 
3847 	return (Interface::STRUCT == interface->m_type);
3848 }
3849 /** Get code that reference variable
3850  *
3851  * @param parent_name Name of parent
3852  * @param variable    Descriptor of variable
3853  * @param flavour     Provides info about how variable should be referenced
3854  * @param array_index Index of array, ignored when variable is not array
3855  *
3856  * @return String with code
3857  **/
GetReference(const std::string & parent_name,const Descriptor & variable,FLAVOUR flavour,GLuint array_index)3858 std::string Variable::GetReference(const std::string& parent_name, const Descriptor& variable, FLAVOUR flavour,
3859 								   GLuint array_index)
3860 {
3861 	std::string name;
3862 
3863 	/* Prepare name */
3864 	if (false == parent_name.empty())
3865 	{
3866 		name = parent_name;
3867 		name.append(".");
3868 		name.append(variable.m_name);
3869 	}
3870 	else
3871 	{
3872 		name = variable.m_name;
3873 	}
3874 
3875 	/* */
3876 	switch (flavour)
3877 	{
3878 	case Utils::Variable::BASIC:
3879 		break;
3880 
3881 	case Utils::Variable::ARRAY:
3882 		name.append("[0]");
3883 		break;
3884 
3885 	case Utils::Variable::INDEXED_BY_INVOCATION_ID:
3886 		name.append("[gl_InvocationID]");
3887 		break;
3888 	}
3889 
3890 	/* Assumption that both variables have same lengths */
3891 	if (0 != variable.m_n_array_elements)
3892 	{
3893 		GLchar buffer[16];
3894 		sprintf(buffer, "%d", array_index);
3895 		name.append("[");
3896 		name.append(buffer);
3897 		name.append("]");
3898 	}
3899 
3900 	return name;
3901 }
3902 
3903 /** Get "flavour" of varying
3904  *
3905  * @param stage     Stage of shader
3906  * @param direction Selects if varying is in or out
3907  *
3908  * @return Flavour
3909  **/
GetFlavour(Shader::STAGES stage,VARYING_DIRECTION direction)3910 Variable::FLAVOUR Variable::GetFlavour(Shader::STAGES stage, VARYING_DIRECTION direction)
3911 {
3912 	FLAVOUR result = BASIC;
3913 
3914 	switch (stage)
3915 	{
3916 	case Shader::GEOMETRY:
3917 	case Shader::TESS_EVAL:
3918 		if (INPUT == direction)
3919 		{
3920 			result = ARRAY;
3921 		}
3922 		break;
3923 	case Shader::TESS_CTRL:
3924 		result = INDEXED_BY_INVOCATION_ID;
3925 		break;
3926 	default:
3927 		break;
3928 	}
3929 
3930 	return result;
3931 }
3932 
3933 /** Constructor, for built-in types
3934  *
3935  * @param name                       Name
3936  * @param qualifiers                 Qualifiers
3937  * @param expected_component         Expected component of variable
3938  * @param expected_location          Expected location
3939  * @param type                       Type
3940  * @param normalized                 Selects if data should be normalized
3941  * @param n_array_elements           Length of array
3942  * @param expected_stride_of_element Expected stride of element
3943  * @param offset                     Offset
3944  **/
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)3945 Variable::Descriptor::Descriptor(const GLchar* name, const GLchar* qualifiers, GLint expected_component,
3946 								 GLint expected_location, const Type& type, GLboolean normalized,
3947 								 GLuint n_array_elements, GLint expected_stride_of_element, GLuint offset)
3948 	: m_expected_component(expected_component)
3949 	, m_expected_location(expected_location)
3950 	, m_expected_stride_of_element(expected_stride_of_element)
3951 	, m_n_array_elements(n_array_elements)
3952 	, m_name(name)
3953 	, m_normalized(normalized)
3954 	, m_offset(offset)
3955 	, m_qualifiers(qualifiers)
3956 	, m_type(BUILTIN)
3957 	, m_builtin(type)
3958 {
3959 }
3960 
3961 /** Constructor, for interface types
3962  *
3963  * @param name                       Name
3964  * @param qualifiers                 Qualifiers
3965  * @param expected_component         Expected component of variable
3966  * @param expected_location          Expected location
3967  * @param interface                  Interface of variable
3968  * @param n_array_elements           Length of array
3969  * @param expected_stride_of_element Expected stride of element
3970  * @param offset                     Offset
3971  **/
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)3972 Variable::Descriptor::Descriptor(const GLchar* name, const GLchar* qualifiers, GLint expected_componenet,
3973 								 GLint expected_location, Interface* interface, GLuint n_array_elements,
3974 								 GLint expected_stride_of_element, GLuint offset)
3975 	: m_expected_component(expected_componenet)
3976 	, m_expected_location(expected_location)
3977 	, m_expected_stride_of_element(expected_stride_of_element)
3978 	, m_n_array_elements(n_array_elements)
3979 	, m_name(name)
3980 	, m_normalized(GL_FALSE)
3981 	, m_offset(offset)
3982 	, m_qualifiers(qualifiers)
3983 	, m_type(INTERFACE)
3984 	, m_interface(interface)
3985 {
3986 }
3987 
3988 /** Get definition of variable
3989  *
3990  * @param flavour Flavour of variable
3991  * @param storage Storage used for variable
3992  *
3993  * @return code with defintion
3994  **/
GetDefinition(FLAVOUR flavour,STORAGE storage) const3995 std::string Variable::Descriptor::GetDefinition(FLAVOUR flavour, STORAGE storage) const
3996 {
3997 	static const GLchar* basic_template = "QUALIFIERS STORAGETYPE NAMEARRAY;";
3998 	static const GLchar* array_template = "QUALIFIERS STORAGETYPE NAME[]ARRAY;";
3999 	const GLchar*		 storage_str	= 0;
4000 
4001 	std::string definition;
4002 	size_t		position = 0;
4003 
4004 	/* Select definition template */
4005 	switch (flavour)
4006 	{
4007 	case BASIC:
4008 		definition = basic_template;
4009 		break;
4010 	case ARRAY:
4011 	case INDEXED_BY_INVOCATION_ID:
4012 		definition = array_template;
4013 		break;
4014 	default:
4015 		TCU_FAIL("Invliad enum");
4016 		break;
4017 	}
4018 
4019 	if (BUILTIN != m_type)
4020 	{
4021 		if (0 == m_interface)
4022 		{
4023 			TCU_FAIL("Nullptr");
4024 		}
4025 	}
4026 
4027 	/* Qualifiers */
4028 	if (true == m_qualifiers.empty())
4029 	{
4030 		replaceToken("QUALIFIERS ", position, "", definition);
4031 	}
4032 	else
4033 	{
4034 		replaceToken("QUALIFIERS", position, m_qualifiers.c_str(), definition);
4035 	}
4036 
4037 	// According to spec: int, uint, and double type must always be declared with flat qualifier
4038 	bool flat_qualifier = false;
4039 	if (m_type != BUILTIN && m_interface != NULL)
4040 	{
4041 		if (m_interface->m_members[0].m_builtin.m_basic_type == Utils::Type::Int ||
4042 			m_interface->m_members[0].m_builtin.m_basic_type == Utils::Type::Uint ||
4043 			m_interface->m_members[0].m_builtin.m_basic_type == Utils::Type::Double)
4044 		{
4045 			flat_qualifier = true;
4046 		}
4047 	}
4048 	/* Storage */
4049 	switch (storage)
4050 	{
4051 	case VARYING_INPUT:
4052 		storage_str = flat_qualifier ? "flat in " : "in ";
4053 		break;
4054 	case VARYING_OUTPUT:
4055 		storage_str = "out ";
4056 		break;
4057 	case UNIFORM:
4058 		storage_str = "uniform ";
4059 		break;
4060 	case SSB:
4061 		storage_str = "buffer ";
4062 		break;
4063 	case MEMBER:
4064 		storage_str = "";
4065 		break;
4066 	default:
4067 		TCU_FAIL("Invalid enum");
4068 		break;
4069 	}
4070 
4071 	replaceToken("STORAGE", position, storage_str, definition);
4072 
4073 	/* Type */
4074 	if (BUILTIN == m_type)
4075 	{
4076 		replaceToken("TYPE", position, m_builtin.GetGLSLTypeName(), definition);
4077 	}
4078 	else
4079 	{
4080 		if (Interface::STRUCT == m_interface->m_type)
4081 		{
4082 			replaceToken("TYPE", position, m_interface->m_name.c_str(), definition);
4083 		}
4084 		else
4085 		{
4086 			const std::string& block_definition = m_interface->GetDefinition();
4087 
4088 			replaceToken("TYPE", position, block_definition.c_str(), definition);
4089 		}
4090 	}
4091 
4092 	/* Name */
4093 	replaceToken("NAME", position, m_name.c_str(), definition);
4094 
4095 	/* Array size */
4096 	if (0 == m_n_array_elements)
4097 	{
4098 		replaceToken("ARRAY", position, "", definition);
4099 	}
4100 	else
4101 	{
4102 		char buffer[16];
4103 		sprintf(buffer, "[%d]", m_n_array_elements);
4104 
4105 		replaceToken("ARRAY", position, buffer, definition);
4106 	}
4107 
4108 	/* Done */
4109 	return definition;
4110 }
4111 
4112 /** Get definitions for variables collected in vector
4113  *
4114  * @param vector  Collection of variables
4115  * @param flavour Flavour of variables
4116  *
4117  * @return Code with definitions
4118  **/
GetDefinitions(const Variable::PtrVector & vector,Variable::FLAVOUR flavour)4119 std::string GetDefinitions(const Variable::PtrVector& vector, Variable::FLAVOUR flavour)
4120 {
4121 	std::string list	 = Utils::g_list;
4122 	size_t		position = 0;
4123 
4124 	for (GLuint i = 0; i < vector.size(); ++i)
4125 	{
4126 		Utils::insertElementOfList(vector[i]->GetDefinition(flavour).c_str(), "\n", position, list);
4127 	}
4128 
4129 	Utils::endList("", position, list);
4130 
4131 	return list;
4132 }
4133 
4134 /** Get definitions for interfaces collected in vector
4135  *
4136  * @param vector Collection of interfaces
4137  *
4138  * @return Code with definitions
4139  **/
GetDefinitions(const Interface::PtrVector & vector)4140 std::string GetDefinitions(const Interface::PtrVector& vector)
4141 {
4142 	std::string list	 = Utils::g_list;
4143 	size_t		position = 0;
4144 
4145 	for (GLuint i = 0; i < vector.size(); ++i)
4146 	{
4147 		Utils::insertElementOfList(vector[i]->GetDefinition().c_str(), "\n", position, list);
4148 	}
4149 
4150 	Utils::endList("", position, list);
4151 
4152 	return list;
4153 }
4154 
4155 /** Constructor
4156  *
4157  * @param name Name
4158  * @param type Type of interface
4159  **/
Interface(const GLchar * name,Interface::TYPE type)4160 Interface::Interface(const GLchar* name, Interface::TYPE type) : m_name(name), m_type(type)
4161 {
4162 }
4163 
4164 /** Adds member to interface
4165  *
4166  * @param member Descriptor of new member
4167  *
4168  * @return Pointer to just created member
4169  **/
AddMember(const Variable::Descriptor & member)4170 Variable::Descriptor* Interface::AddMember(const Variable::Descriptor& member)
4171 {
4172 	m_members.push_back(member);
4173 
4174 	return &m_members.back();
4175 }
4176 
4177 /** Get definition of interface
4178  *
4179  * @param Code with definition
4180  **/
GetDefinition() const4181 std::string Interface::GetDefinition() const
4182 {
4183 	std::string definition;
4184 	size_t		position = 0;
4185 
4186 	const GLchar* member_list = "    MEMBER_DEFINITION\nMEMBER_LIST";
4187 
4188 	if (STRUCT == m_type)
4189 	{
4190 		definition = "struct NAME {\nMEMBER_LIST};";
4191 	}
4192 	else
4193 	{
4194 		definition = "NAME {\nMEMBER_LIST}";
4195 	}
4196 
4197 	/* Name */
4198 	replaceToken("NAME", position, m_name.c_str(), definition);
4199 
4200 	/* Member list */
4201 	for (GLuint i = 0; i < m_members.size(); ++i)
4202 	{
4203 		const size_t	   start_position	= position;
4204 		const std::string& member_definition = m_members[i].GetDefinition(Variable::BASIC, Variable::MEMBER);
4205 
4206 		/* Member list */
4207 		replaceToken("MEMBER_LIST", position, member_list, definition);
4208 
4209 		/* Move back position */
4210 		position = start_position;
4211 
4212 		/* Member definition */
4213 		replaceToken("MEMBER_DEFINITION", position, member_definition.c_str(), definition);
4214 	}
4215 
4216 	/* Remove last member list */
4217 	replaceToken("MEMBER_LIST", position, "", definition);
4218 
4219 	/* Done */
4220 	return definition;
4221 }
4222 
4223 /** Adds member of built-in type to interface
4224  *
4225  * @param name                       Name
4226  * @param qualifiers                 Qualifiers
4227  * @param expected_component         Expected component of variable
4228  * @param expected_location          Expected location
4229  * @param type                       Type
4230  * @param normalized                 Selects if data should be normalized
4231  * @param n_array_elements           Length of array
4232  * @param expected_stride_of_element Expected stride of element
4233  * @param offset                     Offset
4234  *
4235  * @return Pointer to just created member
4236  **/
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)4237 Variable::Descriptor* Interface::Member(const GLchar* name, const GLchar* qualifiers, GLint expected_component,
4238 										GLint expected_location, const Type& type, GLboolean normalized,
4239 										GLuint n_array_elements, GLint expected_stride_of_element, GLuint offset)
4240 {
4241 	return AddMember(Variable::Descriptor(name, qualifiers, expected_component, expected_location, type, normalized,
4242 										  n_array_elements, expected_stride_of_element, offset));
4243 }
4244 
4245 /** Adds member of interface type to interface
4246  *
4247  * @param name                       Name
4248  * @param qualifiers                 Qualifiers
4249  * @param expected_component         Expected component of variable
4250  * @param expected_location          Expected location
4251  * @param type                       Type
4252  * @param normalized                 Selects if data should be normalized
4253  * @param n_array_elements           Length of array
4254  * @param expected_stride_of_element Expected stride of element
4255  * @param offset                     Offset
4256  *
4257  * @return Pointer to just created member
4258  **/
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)4259 Variable::Descriptor* Interface::Member(const GLchar* name, const GLchar* qualifiers, GLint expected_component,
4260 										GLint expected_location, Interface* nterface, GLuint n_array_elements,
4261 										GLint expected_stride_of_element, GLuint offset)
4262 {
4263 	return AddMember(Variable::Descriptor(name, qualifiers, expected_component, expected_location, nterface,
4264 										  n_array_elements, expected_stride_of_element, offset));
4265 }
4266 
4267 /** Clears contents of vector of pointers
4268  *
4269  * @tparam T Type of elements
4270  *
4271  * @param vector Collection to be cleared
4272  **/
4273 template <typename T>
clearPtrVector(std::vector<T * > & vector)4274 void clearPtrVector(std::vector<T*>& vector)
4275 {
4276 	for (size_t i = 0; i < vector.size(); ++i)
4277 	{
4278 		T* t = vector[i];
4279 
4280 		vector[i] = 0;
4281 
4282 		if (0 != t)
4283 		{
4284 			delete t;
4285 		}
4286 	}
4287 
4288 	vector.clear();
4289 }
4290 
4291 /** Constructor
4292  *
4293  * @param stage Stage described by that interface
4294  **/
ShaderInterface(Shader::STAGES stage)4295 ShaderInterface::ShaderInterface(Shader::STAGES stage) : m_stage(stage)
4296 {
4297 	/* Nothing to be done */
4298 }
4299 
4300 /** Get definitions of globals
4301  *
4302  * @return Code with definitions
4303  **/
GetDefinitionsGlobals() const4304 std::string ShaderInterface::GetDefinitionsGlobals() const
4305 {
4306 	return m_globals;
4307 }
4308 
4309 /** Get definitions of inputs
4310  *
4311  * @return Code with definitions
4312  **/
GetDefinitionsInputs() const4313 std::string ShaderInterface::GetDefinitionsInputs() const
4314 {
4315 	Variable::FLAVOUR flavour = Variable::GetFlavour(m_stage, Variable::INPUT);
4316 
4317 	return GetDefinitions(m_inputs, flavour);
4318 }
4319 
4320 /** Get definitions of outputs
4321  *
4322  * @return Code with definitions
4323  **/
GetDefinitionsOutputs() const4324 std::string ShaderInterface::GetDefinitionsOutputs() const
4325 {
4326 	Variable::FLAVOUR flavour = Variable::GetFlavour(m_stage, Variable::OUTPUT);
4327 
4328 	return GetDefinitions(m_outputs, flavour);
4329 }
4330 
4331 /** Get definitions of buffers
4332  *
4333  * @return Code with definitions
4334  **/
GetDefinitionsSSBs() const4335 std::string ShaderInterface::GetDefinitionsSSBs() const
4336 {
4337 	return GetDefinitions(m_ssb_blocks, Variable::BASIC);
4338 }
4339 
4340 /** Get definitions of uniforms
4341  *
4342  * @return Code with definitions
4343  **/
GetDefinitionsUniforms() const4344 std::string ShaderInterface::GetDefinitionsUniforms() const
4345 {
4346 	return GetDefinitions(m_uniforms, Variable::BASIC);
4347 }
4348 
4349 /** Constructor
4350  *
4351  * @param in  Input variable
4352  * @param out Output variable
4353  **/
VaryingConnection(Variable * in,Variable * out)4354 VaryingConnection::VaryingConnection(Variable* in, Variable* out) : m_in(in), m_out(out)
4355 {
4356 	/* NBothing to be done here */
4357 }
4358 
4359 /** Adds new varying connection to given stage
4360  *
4361  * @param stage Shader stage
4362  * @param in    In varying
4363  * @param out   Out varying
4364  **/
Add(Shader::STAGES stage,Variable * in,Variable * out)4365 void VaryingPassthrough::Add(Shader::STAGES stage, Variable* in, Variable* out)
4366 {
4367 	VaryingConnection::Vector& vector = Get(stage);
4368 
4369 	vector.push_back(VaryingConnection(in, out));
4370 }
4371 
4372 /** Get all passthrough connections for given stage
4373  *
4374  * @param stage Shader stage
4375  *
4376  * @return Vector of connections
4377  **/
Get(Shader::STAGES stage)4378 VaryingConnection::Vector& VaryingPassthrough::Get(Shader::STAGES stage)
4379 {
4380 	VaryingConnection::Vector* result = 0;
4381 
4382 	switch (stage)
4383 	{
4384 	case Shader::FRAGMENT:
4385 		result = &m_fragment;
4386 		break;
4387 	case Shader::GEOMETRY:
4388 		result = &m_geometry;
4389 		break;
4390 	case Shader::TESS_CTRL:
4391 		result = &m_tess_ctrl;
4392 		break;
4393 	case Shader::TESS_EVAL:
4394 		result = &m_tess_eval;
4395 		break;
4396 	case Shader::VERTEX:
4397 		result = &m_vertex;
4398 		break;
4399 	default:
4400 		TCU_FAIL("Invalid enum");
4401 	}
4402 
4403 	return *result;
4404 }
4405 
4406 /** Constructor
4407  *
4408  **/
ProgramInterface()4409 ProgramInterface::ProgramInterface()
4410 	: m_compute(Shader::COMPUTE)
4411 	, m_vertex(Shader::VERTEX)
4412 	, m_tess_ctrl(Shader::TESS_CTRL)
4413 	, m_tess_eval(Shader::TESS_EVAL)
4414 	, m_geometry(Shader::GEOMETRY)
4415 	, m_fragment(Shader::FRAGMENT)
4416 {
4417 }
4418 
4419 /** Destructor
4420  *
4421  **/
~ProgramInterface()4422 ProgramInterface::~ProgramInterface()
4423 {
4424 	clearPtrVector(m_blocks);
4425 	clearPtrVector(m_structures);
4426 }
4427 
4428 /** Adds new interface
4429  *
4430  * @param name
4431  * @param type
4432  *
4433  * @return Pointer to created interface
4434  **/
AddInterface(const GLchar * name,Interface::TYPE type)4435 Interface* ProgramInterface::AddInterface(const GLchar* name, Interface::TYPE type)
4436 {
4437 	Interface* interface = 0;
4438 
4439 	if (Interface::STRUCT == type)
4440 	{
4441 		interface = new Interface(name, type);
4442 
4443 		m_structures.push_back(interface);
4444 	}
4445 	else
4446 	{
4447 		interface = new Interface(name, type);
4448 
4449 		m_blocks.push_back(interface);
4450 	}
4451 
4452 	return interface;
4453 }
4454 
4455 /** Adds new block interface
4456  *
4457  * @param name
4458  *
4459  * @return Pointer to created interface
4460  **/
Block(const GLchar * name)4461 Interface* ProgramInterface::Block(const GLchar* name)
4462 {
4463 	return AddInterface(name, Interface::BLOCK);
4464 }
4465 
4466 /** Get interface of given shader stage
4467  *
4468  * @param stage Shader stage
4469  *
4470  * @return Reference to stage interface
4471  **/
GetShaderInterface(Shader::STAGES stage)4472 ShaderInterface& ProgramInterface::GetShaderInterface(Shader::STAGES stage)
4473 {
4474 	ShaderInterface* interface = 0;
4475 
4476 	switch (stage)
4477 	{
4478 	case Shader::COMPUTE:
4479 		interface = &m_compute;
4480 		break;
4481 	case Shader::FRAGMENT:
4482 		interface = &m_fragment;
4483 		break;
4484 	case Shader::GEOMETRY:
4485 		interface = &m_geometry;
4486 		break;
4487 	case Shader::TESS_CTRL:
4488 		interface = &m_tess_ctrl;
4489 		break;
4490 	case Shader::TESS_EVAL:
4491 		interface = &m_tess_eval;
4492 		break;
4493 	case Shader::VERTEX:
4494 		interface = &m_vertex;
4495 		break;
4496 	default:
4497 		TCU_FAIL("Invalid enum");
4498 	}
4499 
4500 	return *interface;
4501 }
4502 
4503 /** Get interface of given shader stage
4504  *
4505  * @param stage Shader stage
4506  *
4507  * @return Reference to stage interface
4508  **/
GetShaderInterface(Shader::STAGES stage) const4509 const ShaderInterface& ProgramInterface::GetShaderInterface(Shader::STAGES stage) const
4510 {
4511 	const ShaderInterface* interface = 0;
4512 
4513 	switch (stage)
4514 	{
4515 	case Shader::COMPUTE:
4516 		interface = &m_compute;
4517 		break;
4518 	case Shader::FRAGMENT:
4519 		interface = &m_fragment;
4520 		break;
4521 	case Shader::GEOMETRY:
4522 		interface = &m_geometry;
4523 		break;
4524 	case Shader::TESS_CTRL:
4525 		interface = &m_tess_ctrl;
4526 		break;
4527 	case Shader::TESS_EVAL:
4528 		interface = &m_tess_eval;
4529 		break;
4530 	case Shader::VERTEX:
4531 		interface = &m_vertex;
4532 		break;
4533 	default:
4534 		TCU_FAIL("Invalid enum");
4535 	}
4536 
4537 	return *interface;
4538 }
4539 
4540 /** Clone interface of Vertex shader stage to other stages
4541  * It creates matching inputs, outputs, uniforms and buffers in other stages.
4542  * There are no additional outputs for FRAGMENT shader generated.
4543  *
4544  * @param varying_passthrough Collection of varyings connections
4545  **/
CloneVertexInterface(VaryingPassthrough & varying_passthrough)4546 void ProgramInterface::CloneVertexInterface(VaryingPassthrough& varying_passthrough)
4547 {
4548 	/* VS outputs >> TCS inputs >> TCS outputs >> ..  >> FS inputs */
4549 	for (size_t i = 0; i < m_vertex.m_outputs.size(); ++i)
4550 	{
4551 		const Variable& vs_var = *m_vertex.m_outputs[i];
4552 		const GLchar*   prefix = GetStagePrefix(Shader::VERTEX, vs_var.m_storage);
4553 
4554 		cloneVariableForStage(vs_var, Shader::TESS_CTRL, prefix, varying_passthrough);
4555 		cloneVariableForStage(vs_var, Shader::TESS_EVAL, prefix, varying_passthrough);
4556 		cloneVariableForStage(vs_var, Shader::GEOMETRY, prefix, varying_passthrough);
4557 		cloneVariableForStage(vs_var, Shader::FRAGMENT, prefix, varying_passthrough);
4558 	}
4559 
4560 	/* Copy uniforms from VS to other stages */
4561 	for (size_t i = 0; i < m_vertex.m_uniforms.size(); ++i)
4562 	{
4563 		Variable&	 vs_var = *m_vertex.m_uniforms[i];
4564 		const GLchar* prefix = GetStagePrefix(Shader::VERTEX, vs_var.m_storage);
4565 
4566 		cloneVariableForStage(vs_var, Shader::COMPUTE, prefix, varying_passthrough);
4567 		cloneVariableForStage(vs_var, Shader::TESS_CTRL, prefix, varying_passthrough);
4568 		cloneVariableForStage(vs_var, Shader::TESS_EVAL, prefix, varying_passthrough);
4569 		cloneVariableForStage(vs_var, Shader::GEOMETRY, prefix, varying_passthrough);
4570 		cloneVariableForStage(vs_var, Shader::FRAGMENT, prefix, varying_passthrough);
4571 
4572 		/* Uniform blocks needs unique binding */
4573 		if (true == vs_var.IsBlock())
4574 		{
4575 			replaceBinding(vs_var, Shader::VERTEX);
4576 		}
4577 	}
4578 
4579 	/* Copy SSBs from VS to other stages */
4580 	for (size_t i = 0; i < m_vertex.m_ssb_blocks.size(); ++i)
4581 	{
4582 		Variable&	 vs_var = *m_vertex.m_ssb_blocks[i];
4583 		const GLchar* prefix = GetStagePrefix(Shader::VERTEX, vs_var.m_storage);
4584 
4585 		cloneVariableForStage(vs_var, Shader::COMPUTE, prefix, varying_passthrough);
4586 		cloneVariableForStage(vs_var, Shader::TESS_CTRL, prefix, varying_passthrough);
4587 		cloneVariableForStage(vs_var, Shader::TESS_EVAL, prefix, varying_passthrough);
4588 		cloneVariableForStage(vs_var, Shader::GEOMETRY, prefix, varying_passthrough);
4589 		cloneVariableForStage(vs_var, Shader::FRAGMENT, prefix, varying_passthrough);
4590 
4591 		/* SSBs blocks needs unique binding */
4592 		if (true == vs_var.IsBlock())
4593 		{
4594 			replaceBinding(vs_var, Shader::VERTEX);
4595 		}
4596 	}
4597 
4598 	m_compute.m_globals   = m_vertex.m_globals;
4599 	m_fragment.m_globals  = m_vertex.m_globals;
4600 	m_geometry.m_globals  = m_vertex.m_globals;
4601 	m_tess_ctrl.m_globals = m_vertex.m_globals;
4602 	m_tess_eval.m_globals = m_vertex.m_globals;
4603 }
4604 
4605 /** Clone variable for specific stage
4606  *
4607  * @param variable            Variable
4608  * @param stage               Requested stage
4609  * @param prefix              Prefix used in variable name that is specific for original stage
4610  * @param varying_passthrough Collection of varyings connections
4611  **/
cloneVariableForStage(const Variable & variable,Shader::STAGES stage,const GLchar * prefix,VaryingPassthrough & varying_passthrough)4612 void ProgramInterface::cloneVariableForStage(const Variable& variable, Shader::STAGES stage, const GLchar* prefix,
4613 											 VaryingPassthrough& varying_passthrough)
4614 {
4615 	switch (variable.m_storage)
4616 	{
4617 	case Variable::VARYING_OUTPUT:
4618 	{
4619 		Variable* in = cloneVariableForStage(variable, stage, Variable::VARYING_INPUT, prefix);
4620 
4621 		if (Shader::FRAGMENT != stage)
4622 		{
4623 			Variable* out = cloneVariableForStage(variable, stage, Variable::VARYING_OUTPUT, prefix);
4624 			varying_passthrough.Add(stage, in, out);
4625 		}
4626 	}
4627 	break;
4628 	case Variable::UNIFORM:
4629 	case Variable::SSB:
4630 		cloneVariableForStage(variable, stage, variable.m_storage, prefix);
4631 		break;
4632 	default:
4633 		TCU_FAIL("Invalid enum");
4634 		break;
4635 	}
4636 }
4637 
4638 /** Clone variable for specific stage
4639  *
4640  * @param variable Variable
4641  * @param stage    Requested stage
4642  * @param storage  Storage used by variable
4643  * @param prefix   Prefix used in variable name that is specific for original stage
4644  *
4645  * @return New variable
4646  **/
cloneVariableForStage(const Variable & variable,Shader::STAGES stage,Variable::STORAGE storage,const GLchar * prefix)4647 Variable* ProgramInterface::cloneVariableForStage(const Variable& variable, Shader::STAGES stage,
4648 												  Variable::STORAGE storage, const GLchar* prefix)
4649 {
4650 	/* Initialize with original variable */
4651 	Variable* var = new Variable(variable);
4652 	if (0 == var)
4653 	{
4654 		TCU_FAIL("Memory allocation");
4655 	}
4656 
4657 	/* Set up storage */
4658 	var->m_storage = storage;
4659 
4660 	/* Get name */
4661 	std::string name = variable.m_descriptor.m_name;
4662 
4663 	/* Prefix name with stage ID, empty means default block */
4664 	if (false == name.empty())
4665 	{
4666 		size_t		  position	 = 0;
4667 		const GLchar* stage_prefix = GetStagePrefix(stage, storage);
4668 		Utils::replaceToken(prefix, position, stage_prefix, name);
4669 	}
4670 	var->m_descriptor.m_name = name;
4671 
4672 	/* Clone block */
4673 	const bool is_block = variable.IsBlock();
4674 	if (true == is_block)
4675 	{
4676 		const Interface* interface = variable.m_descriptor.m_interface;
4677 
4678 		Interface* block = CloneBlockForStage(*interface, stage, storage, prefix);
4679 
4680 		var->m_descriptor.m_interface = block;
4681 	}
4682 
4683 	/* Store variable */
4684 	ShaderInterface& si		= GetShaderInterface(stage);
4685 	Variable*		 result = 0;
4686 
4687 	switch (storage)
4688 	{
4689 	case Variable::VARYING_INPUT:
4690 		si.m_inputs.push_back(var);
4691 		result = si.m_inputs.back();
4692 		break;
4693 	case Variable::VARYING_OUTPUT:
4694 		si.m_outputs.push_back(var);
4695 		result = si.m_outputs.back();
4696 		break;
4697 	case Variable::UNIFORM:
4698 		/* Uniform blocks needs unique binding */
4699 		if (true == is_block)
4700 		{
4701 			replaceBinding(*var, stage);
4702 		}
4703 
4704 		si.m_uniforms.push_back(var);
4705 		result = si.m_uniforms.back();
4706 		break;
4707 	case Variable::SSB:
4708 		/* SSBs needs unique binding */
4709 		if (true == is_block)
4710 		{
4711 			replaceBinding(*var, stage);
4712 		}
4713 
4714 		si.m_ssb_blocks.push_back(var);
4715 		result = si.m_ssb_blocks.back();
4716 		break;
4717 	default:
4718 		TCU_FAIL("Invalid enum");
4719 		break;
4720 	}
4721 
4722 	return result;
4723 }
4724 
4725 /** clone block to specific stage
4726  *
4727  * @param block   Block to be copied
4728  * @param stage   Specific stage
4729  * @param storage Storage used by block
4730  * @param prefix  Prefix used in block name
4731  *
4732  * @return New interface
4733  **/
CloneBlockForStage(const Interface & block,Shader::STAGES stage,Variable::STORAGE storage,const GLchar * prefix)4734 Interface* ProgramInterface::CloneBlockForStage(const Interface& block, Shader::STAGES stage, Variable::STORAGE storage,
4735 												const GLchar* prefix)
4736 {
4737 	/* Get name */
4738 	std::string name = block.m_name;
4739 
4740 	/* Prefix name with stage ID */
4741 	size_t		  position	 = 0;
4742 	const GLchar* stage_prefix = GetStagePrefix(stage, storage);
4743 	Utils::replaceToken(prefix, position, stage_prefix, name);
4744 
4745 	Interface* ptr = GetBlock(name.c_str());
4746 
4747 	if (0 == ptr)
4748 	{
4749 		ptr = AddInterface(name.c_str(), Interface::BLOCK);
4750 	}
4751 
4752 	ptr->m_members = block.m_members;
4753 
4754 	return ptr;
4755 }
4756 
4757 /** Get stage specific prefix used in names
4758  *
4759  * @param stage   Stage
4760  * @param storage Storage class
4761  *
4762  * @return String
4763  **/
GetStagePrefix(Shader::STAGES stage,Variable::STORAGE storage)4764 const GLchar* ProgramInterface::GetStagePrefix(Shader::STAGES stage, Variable::STORAGE storage)
4765 {
4766 	static const GLchar* lut[Shader::STAGE_MAX][Variable::STORAGE_MAX] = {
4767 		/*          IN          OUT         UNIFORM     SSB        MEMBER	*/
4768 		/* CS  */ { 0, 0, "cs_uni_", "cs_buf_", "" },
4769 		/* VS  */ { "in_vs_", "vs_tcs_", "vs_uni_", "vs_buf_", "" },
4770 		/* TCS */ { "vs_tcs_", "tcs_tes_", "tcs_uni_", "tcs_buf_", "" },
4771 		/* TES */ { "tcs_tes_", "tes_gs_", "tes_uni_", "tes_buf_", "" },
4772 		/* GS  */ { "tes_gs_", "gs_fs_", "gs_uni_", "gs_buf_", "" },
4773 		/* FS  */ { "gs_fs_", "fs_out_", "fs_uni_", "fs_buf_", "" },
4774 	};
4775 
4776 	const GLchar* result = 0;
4777 
4778 	result = lut[stage][storage];
4779 
4780 	return result;
4781 }
4782 
4783 /** Get definitions of all structures used in program interface
4784  *
4785  * @return String with code
4786  **/
GetDefinitionsStructures() const4787 std::string ProgramInterface::GetDefinitionsStructures() const
4788 {
4789 	return GetDefinitions(m_structures);
4790 }
4791 
4792 /** Get interface code for stage
4793  *
4794  * @param stage Specific stage
4795  *
4796  * @return String with code
4797  **/
GetInterfaceForStage(Shader::STAGES stage) const4798 std::string ProgramInterface::GetInterfaceForStage(Shader::STAGES stage) const
4799 {
4800 	size_t		position  = 0;
4801 	std::string interface = "/* Globals */\n"
4802 							"GLOBALS\n"
4803 							"\n"
4804 							"/* Structures */\n"
4805 							"STRUCTURES\n"
4806 							"\n"
4807 							"/* Uniforms */\n"
4808 							"UNIFORMS\n"
4809 							"\n"
4810 							"/* Inputs */\n"
4811 							"INPUTS\n"
4812 							"\n"
4813 							"/* Outputs */\n"
4814 							"OUTPUTS\n"
4815 							"\n"
4816 							"/* Storage */\n"
4817 							"STORAGE\n";
4818 
4819 	const ShaderInterface& si = GetShaderInterface(stage);
4820 
4821 	const std::string& structures = GetDefinitionsStructures();
4822 
4823 	const std::string& globals  = si.GetDefinitionsGlobals();
4824 	const std::string& inputs   = si.GetDefinitionsInputs();
4825 	const std::string& outputs  = si.GetDefinitionsOutputs();
4826 	const std::string& uniforms = si.GetDefinitionsUniforms();
4827 	const std::string& ssbs		= si.GetDefinitionsSSBs();
4828 
4829 	replaceToken("GLOBALS", position, globals.c_str(), interface);
4830 	replaceToken("STRUCTURES", position, structures.c_str(), interface);
4831 	replaceToken("UNIFORMS", position, uniforms.c_str(), interface);
4832 	replaceToken("INPUTS", position, inputs.c_str(), interface);
4833 	replaceToken("OUTPUTS", position, outputs.c_str(), interface);
4834 	replaceToken("STORAGE", position, ssbs.c_str(), interface);
4835 
4836 	return interface;
4837 }
4838 
4839 /** Functional object used in find_if algorithm, in search for interface of given name
4840  *
4841  **/
4842 struct matchInterfaceName
4843 {
matchInterfaceNamegl4cts::EnhancedLayouts::Utils::matchInterfaceName4844 	matchInterfaceName(const GLchar* name) : m_name(name)
4845 	{
4846 	}
4847 
operator ()gl4cts::EnhancedLayouts::Utils::matchInterfaceName4848 	bool operator()(const Interface* interface)
4849 	{
4850 		return 0 == interface->m_name.compare(m_name);
4851 	}
4852 
4853 	const GLchar* m_name;
4854 };
4855 
4856 /** Finds interface of given name in given vector of interfaces
4857  *
4858  * @param vector Collection of interfaces
4859  * @param name   Requested name
4860  *
4861  * @return Pointer to interface if available, 0 otherwise
4862  **/
findInterfaceByName(Interface::PtrVector & vector,const GLchar * name)4863 static Interface* findInterfaceByName(Interface::PtrVector& vector, const GLchar* name)
4864 {
4865 	Interface::PtrVector::iterator it = std::find_if(vector.begin(), vector.end(), matchInterfaceName(name));
4866 
4867 	if (vector.end() != it)
4868 	{
4869 		return *it;
4870 	}
4871 	else
4872 	{
4873 		return 0;
4874 	}
4875 }
4876 
4877 /** Search for block of given name
4878  *
4879  * @param name Name of block
4880  *
4881  * @return Pointer to block or 0
4882  **/
GetBlock(const GLchar * name)4883 Interface* ProgramInterface::GetBlock(const GLchar* name)
4884 {
4885 	return findInterfaceByName(m_blocks, name);
4886 }
4887 
4888 /** Search for structure of given name
4889  *
4890  * @param name Name of structure
4891  *
4892  * @return Pointer to structure or 0
4893  **/
GetStructure(const GLchar * name)4894 Interface* ProgramInterface::GetStructure(const GLchar* name)
4895 {
4896 	return findInterfaceByName(m_structures, name);
4897 }
4898 
4899 /** Adds new sturcture to interface
4900  *
4901  * @param name Name of structure
4902  *
4903  * @return Created structure
4904  **/
Structure(const GLchar * name)4905 Interface* ProgramInterface::Structure(const GLchar* name)
4906 {
4907 	return AddInterface(name, Interface::STRUCT);
4908 }
4909 
4910 /** Replace "BINDING" token in qualifiers string to value specific for given stage
4911  *
4912  * @param variable Variable to modify
4913  * @param stage    Requested stage
4914  **/
replaceBinding(Variable & variable,Shader::STAGES stage)4915 void ProgramInterface::replaceBinding(Variable& variable, Shader::STAGES stage)
4916 {
4917 	GLchar binding[16];
4918 	sprintf(binding, "%d", stage);
4919 	replaceAllTokens("BINDING", binding, variable.m_descriptor.m_qualifiers);
4920 }
4921 } /* Utils namespace */
4922 
4923 /** Debuging procedure. Logs parameters.
4924  *
4925  * @param source   As specified in GL spec.
4926  * @param type     As specified in GL spec.
4927  * @param id       As specified in GL spec.
4928  * @param severity As specified in GL spec.
4929  * @param ignored
4930  * @param message  As specified in GL spec.
4931  * @param info     Pointer to instance of Context used by test.
4932  */
debug_proc(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei,const GLchar * message,void * info)4933 void GLW_APIENTRY debug_proc(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei /* length */,
4934 							 const GLchar* message, void* info)
4935 {
4936 	deqp::Context* ctx = (deqp::Context*)info;
4937 
4938 	const GLchar* source_str   = "Unknown";
4939 	const GLchar* type_str	 = "Unknown";
4940 	const GLchar* severity_str = "Unknown";
4941 
4942 	switch (source)
4943 	{
4944 	case GL_DEBUG_SOURCE_API:
4945 		source_str = "API";
4946 		break;
4947 	case GL_DEBUG_SOURCE_APPLICATION:
4948 		source_str = "APP";
4949 		break;
4950 	case GL_DEBUG_SOURCE_OTHER:
4951 		source_str = "OTR";
4952 		break;
4953 	case GL_DEBUG_SOURCE_SHADER_COMPILER:
4954 		source_str = "COM";
4955 		break;
4956 	case GL_DEBUG_SOURCE_THIRD_PARTY:
4957 		source_str = "3RD";
4958 		break;
4959 	case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
4960 		source_str = "WS";
4961 		break;
4962 	default:
4963 		break;
4964 	}
4965 
4966 	switch (type)
4967 	{
4968 	case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
4969 		type_str = "DEPRECATED_BEHAVIOR";
4970 		break;
4971 	case GL_DEBUG_TYPE_ERROR:
4972 		type_str = "ERROR";
4973 		break;
4974 	case GL_DEBUG_TYPE_MARKER:
4975 		type_str = "MARKER";
4976 		break;
4977 	case GL_DEBUG_TYPE_OTHER:
4978 		type_str = "OTHER";
4979 		break;
4980 	case GL_DEBUG_TYPE_PERFORMANCE:
4981 		type_str = "PERFORMANCE";
4982 		break;
4983 	case GL_DEBUG_TYPE_POP_GROUP:
4984 		type_str = "POP_GROUP";
4985 		break;
4986 	case GL_DEBUG_TYPE_PORTABILITY:
4987 		type_str = "PORTABILITY";
4988 		break;
4989 	case GL_DEBUG_TYPE_PUSH_GROUP:
4990 		type_str = "PUSH_GROUP";
4991 		break;
4992 	case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
4993 		type_str = "UNDEFINED_BEHAVIOR";
4994 		break;
4995 	default:
4996 		break;
4997 	}
4998 
4999 	switch (severity)
5000 	{
5001 	case GL_DEBUG_SEVERITY_HIGH:
5002 		severity_str = "H";
5003 		break;
5004 	case GL_DEBUG_SEVERITY_LOW:
5005 		severity_str = "L";
5006 		break;
5007 	case GL_DEBUG_SEVERITY_MEDIUM:
5008 		severity_str = "M";
5009 		break;
5010 	case GL_DEBUG_SEVERITY_NOTIFICATION:
5011 		severity_str = "N";
5012 		break;
5013 	default:
5014 		break;
5015 	}
5016 
5017 	ctx->getTestContext().getLog() << tcu::TestLog::Message << "DEBUG_INFO: " << std::setw(3) << source_str << "|"
5018 								   << severity_str << "|" << std::setw(18) << type_str << "|" << std::setw(12) << id
5019 								   << ": " << message << tcu::TestLog::EndMessage;
5020 }
5021 
5022 /** Constructor
5023  *
5024  * @param context          Test context
5025  * @param test_name        Test name
5026  * @param test_description Test description
5027  **/
TestBase(deqp::Context & context,const GLchar * test_name,const GLchar * test_description)5028 TestBase::TestBase(deqp::Context& context, const GLchar* test_name, const GLchar* test_description)
5029 	: TestCase(context, test_name, test_description)
5030 {
5031 	/* Nothing to be done here */
5032 }
5033 
5034 /** Execute test
5035  *
5036  * @return tcu::TestNode::STOP otherwise
5037  **/
iterate()5038 tcu::TestNode::IterateResult TestBase::iterate()
5039 {
5040 	bool test_result;
5041 
5042 #if DEBUG_ENBALE_MESSAGE_CALLBACK
5043 	const Functions& gl = m_context.getRenderContext().getFunctions();
5044 
5045 	gl.debugMessageCallback(debug_proc, &m_context);
5046 	GLU_EXPECT_NO_ERROR(gl.getError(), "DebugMessageCallback");
5047 #endif /* DEBUG_ENBALE_MESSAGE_CALLBACK */
5048 
5049 	try
5050 	{
5051 		/* Execute test */
5052 		test_result = test();
5053 	}
5054 	catch (std::exception& exc)
5055 	{
5056 		TCU_FAIL(exc.what());
5057 	}
5058 
5059 	/* Set result */
5060 	if (true == test_result)
5061 	{
5062 		m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
5063 	}
5064 	else
5065 	{
5066 		m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
5067 	}
5068 
5069 	/* Done */
5070 	return tcu::TestNode::STOP;
5071 }
5072 
5073 /** Get last input location available for given type at specific stage
5074  *
5075  * @param stage        Shader stage
5076  * @param type         Input type
5077  * @param array_length Length of input array
5078  *
5079  * @return Last location index
5080  **/
getLastInputLocation(Utils::Shader::STAGES stage,const Utils::Type & type,GLuint array_length,bool ignore_prev_stage)5081 GLint TestBase::getLastInputLocation(Utils::Shader::STAGES stage, const Utils::Type& type, GLuint array_length, bool ignore_prev_stage)
5082 {
5083 	GLint  divide		= 4; /* 4 components per location */
5084 	GLint  param		= 0;
5085 	GLenum pname		= 0;
5086 	GLint  paramPrev	= 0;
5087 	GLenum pnamePrev	= 0;
5088 
5089 	/* Select pnmae */
5090 	switch (stage)
5091 	{
5092 	case Utils::Shader::FRAGMENT:
5093 		pname = GL_MAX_FRAGMENT_INPUT_COMPONENTS;
5094 		pnamePrev = GL_MAX_GEOMETRY_OUTPUT_COMPONENTS;
5095 		break;
5096 	case Utils::Shader::GEOMETRY:
5097 		pname = GL_MAX_GEOMETRY_INPUT_COMPONENTS;
5098 		pnamePrev = GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS;
5099 		break;
5100 	case Utils::Shader::TESS_CTRL:
5101 		pname = GL_MAX_TESS_CONTROL_INPUT_COMPONENTS;
5102 		pnamePrev = GL_MAX_VERTEX_OUTPUT_COMPONENTS;
5103 		break;
5104 	case Utils::Shader::TESS_EVAL:
5105 		pname = GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS;
5106 		pnamePrev = GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS;
5107 		break;
5108 	case Utils::Shader::VERTEX:
5109 		pname  = GL_MAX_VERTEX_ATTRIBS;
5110 		divide = 1;
5111 		break;
5112 	default:
5113 		TCU_FAIL("Invalid enum");
5114 		break;
5115 	}
5116 
5117 	/* Zero means no array, but 1 slot is required */
5118 	if (0 == array_length)
5119 	{
5120 		array_length += 1;
5121 	}
5122 
5123 	/* Get MAX */
5124 	const Functions& gl = m_context.getRenderContext().getFunctions();
5125 
5126 	gl.getIntegerv(pname, &param);
5127 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
5128 
5129 	if (pnamePrev && !ignore_prev_stage) {
5130 		gl.getIntegerv(pnamePrev, &paramPrev);
5131 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
5132 
5133 		/* Don't read from a location that doesn't exist in the previous stage */
5134 		param = de::min(param, paramPrev);
5135 	}
5136 
5137 /* Calculate */
5138 #if WRKARD_VARYINGLOCATIONSTEST
5139 
5140 	const GLint n_avl_locations = 16;
5141 
5142 #else
5143 
5144 	const GLint n_avl_locations = param / divide;
5145 
5146 #endif
5147 
5148 	const GLuint n_req_location = type.GetLocations(stage == Utils::Shader::VERTEX) * array_length;
5149 
5150 	return n_avl_locations - n_req_location; /* last is max - 1 */
5151 }
5152 
5153 /** Get last output location available for given type at specific stage
5154  *
5155  * @param stage        Shader stage
5156  * @param type         Input type
5157  * @param array_length Length of input array
5158  *
5159  * @return Last location index
5160  **/
getLastOutputLocation(Utils::Shader::STAGES stage,const Utils::Type & type,GLuint array_length,bool ignore_next_stage)5161 GLint TestBase::getLastOutputLocation(Utils::Shader::STAGES stage, const Utils::Type& type, GLuint array_length, bool ignore_next_stage)
5162 {
5163 	GLint  param		= 0;
5164 	GLenum pname		= 0;
5165 	GLint  paramNext	= 0;
5166 	GLenum pnameNext	= 0;
5167 
5168 	/* Select pname */
5169 	switch (stage)
5170 	{
5171 	case Utils::Shader::GEOMETRY:
5172 		pname = GL_MAX_GEOMETRY_OUTPUT_COMPONENTS;
5173 		pnameNext = GL_MAX_FRAGMENT_INPUT_COMPONENTS;
5174 		break;
5175 	case Utils::Shader::TESS_CTRL:
5176 		pname = GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS;
5177 		pnameNext = GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS;
5178 		break;
5179 	case Utils::Shader::TESS_EVAL:
5180 		pname = GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS;
5181 		pnameNext = GL_MAX_GEOMETRY_INPUT_COMPONENTS;
5182 		break;
5183 	case Utils::Shader::VERTEX:
5184 		pname = GL_MAX_VERTEX_OUTPUT_COMPONENTS;
5185 		pnameNext = GL_MAX_TESS_CONTROL_INPUT_COMPONENTS;
5186 		break;
5187 	default:
5188 		TCU_FAIL("Invalid enum");
5189 		break;
5190 	}
5191 
5192 	/* Zero means no array, but 1 slot is required */
5193 	if (0 == array_length)
5194 	{
5195 		array_length += 1;
5196 	}
5197 
5198 	/* Get MAX */
5199 	const Functions& gl = m_context.getRenderContext().getFunctions();
5200 
5201 	gl.getIntegerv(pname, &param);
5202 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
5203 
5204 /* Calculate */
5205 #if WRKARD_VARYINGLOCATIONSTEST
5206 
5207 	const GLint n_avl_locations = 16;
5208 
5209 #else
5210 
5211 	/* Don't write to a location that doesn't exist in the next stage */
5212 	if (!ignore_next_stage)
5213 	{
5214 		gl.getIntegerv(pnameNext, &paramNext);
5215 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
5216 
5217 		param = de::min(param, paramNext);
5218 	}
5219 
5220 	const GLint n_avl_locations = param / 4; /* 4 components per location */
5221 
5222 #endif
5223 
5224 	const GLuint n_req_location = type.GetLocations() * array_length;
5225 
5226 	return n_avl_locations - n_req_location; /* last is max - 1 */
5227 }
5228 
5229 /** Basic implementation
5230  *
5231  * @param ignored
5232  *
5233  * @return Empty string
5234  **/
getTestCaseName(GLuint)5235 std::string TestBase::getTestCaseName(GLuint /* test_case_index */)
5236 {
5237 	std::string result;
5238 
5239 	return result;
5240 }
5241 
5242 /** Basic implementation
5243  *
5244  * @return 1
5245  **/
getTestCaseNumber()5246 GLuint TestBase::getTestCaseNumber()
5247 {
5248 	return 1;
5249 }
5250 
5251 /** Check if flat qualifier is required for given type, stage and storage
5252  *
5253  * @param stage        Shader stage
5254  * @param type         Input type
5255  * @param storage      Storage of variable
5256  *
5257  * @return Last location index
5258  **/
isFlatRequired(Utils::Shader::STAGES stage,const Utils::Type & type,Utils::Variable::STORAGE storage) const5259 bool TestBase::isFlatRequired(Utils::Shader::STAGES stage, const Utils::Type& type,
5260 							  Utils::Variable::STORAGE storage) const
5261 {
5262 	/* Float types do not need flat at all */
5263 	if (Utils::Type::Float == type.m_basic_type)
5264 	{
5265 		return false;
5266 	}
5267 
5268 	/* Inputs to fragment shader */
5269 	if ((Utils::Shader::FRAGMENT == stage) && (Utils::Variable::VARYING_INPUT == storage))
5270 	{
5271 		return true;
5272 	}
5273 
5274 	/* Outputs from geometry shader */
5275 	if ((Utils::Shader::FRAGMENT == stage) && (Utils::Variable::VARYING_OUTPUT == storage))
5276 	{
5277 		return true;
5278 	}
5279 
5280 	return false;
5281 }
5282 
5283 /** Basic implementation of testInit method
5284  *
5285  **/
testInit()5286 void TestBase::testInit()
5287 {
5288 }
5289 
5290 /** Calculate stride for interface
5291  *
5292  * @param interface Interface
5293  *
5294  * @return Calculated value
5295  **/
calculateStride(const Utils::Interface & interface) const5296 GLuint TestBase::calculateStride(const Utils::Interface& interface) const
5297 {
5298 	const size_t n_members = interface.m_members.size();
5299 
5300 	GLuint stride = 0;
5301 
5302 	for (size_t i = 0; i < n_members; ++i)
5303 	{
5304 		const Utils::Variable::Descriptor& member		  = interface.m_members[i];
5305 		const GLuint					   member_offset  = member.m_offset;
5306 		const GLuint					   member_stride  = member.m_expected_stride_of_element;
5307 		const GLuint					   member_ends_at = member_offset + member_stride;
5308 
5309 		stride = std::max(stride, member_ends_at);
5310 	}
5311 
5312 	return stride;
5313 }
5314 
5315 /** Generate data for interface. This routine is recursive
5316  *
5317  * @param interface Interface
5318  * @param offset    Offset in out_data
5319  * @param out_data  Buffer to be filled
5320  **/
generateData(const Utils::Interface & interface,GLuint offset,std::vector<GLubyte> & out_data) const5321 void TestBase::generateData(const Utils::Interface& interface, GLuint offset, std::vector<GLubyte>& out_data) const
5322 {
5323 	const size_t n_members = interface.m_members.size();
5324 	GLubyte*	 ptr	   = &out_data[offset];
5325 
5326 	for (size_t i = 0; i < n_members; ++i)
5327 	{
5328 		const Utils::Variable::Descriptor& member		 = interface.m_members[i];
5329 		const GLuint					   member_offset = member.m_offset;
5330 		const GLuint n_elements = (0 == member.m_n_array_elements) ? 1 : member.m_n_array_elements;
5331 
5332 		for (GLuint element = 0; element < n_elements; ++element)
5333 		{
5334 			const GLuint element_offset = element * member.m_expected_stride_of_element;
5335 			const GLuint data_offfset   = member_offset + element_offset;
5336 
5337 			if (Utils::Variable::BUILTIN == member.m_type)
5338 			{
5339 				const std::vector<GLubyte>& data = member.m_builtin.GenerateData();
5340 
5341 				memcpy(ptr + data_offfset, &data[0], data.size());
5342 			}
5343 			else
5344 			{
5345 				generateData(*member.m_interface, offset + data_offfset, out_data);
5346 			}
5347 		}
5348 	}
5349 }
5350 
5351 /** Get type at index
5352  *
5353  * @param index Index of requested type
5354  *
5355  * @return Type
5356  **/
getType(GLuint index) const5357 Utils::Type TestBase::getType(GLuint index) const
5358 {
5359 	Utils::Type type;
5360 
5361 	switch (index)
5362 	{
5363 	case 0:
5364 		type = Utils::Type::_double;
5365 		break;
5366 	case 1:
5367 		type = Utils::Type::dmat2;
5368 		break;
5369 	case 2:
5370 		type = Utils::Type::dmat2x3;
5371 		break;
5372 	case 3:
5373 		type = Utils::Type::dmat2x4;
5374 		break;
5375 	case 4:
5376 		type = Utils::Type::dmat3;
5377 		break;
5378 	case 5:
5379 		type = Utils::Type::dmat3x2;
5380 		break;
5381 	case 6:
5382 		type = Utils::Type::dmat3x4;
5383 		break;
5384 	case 7:
5385 		type = Utils::Type::dmat4;
5386 		break;
5387 	case 8:
5388 		type = Utils::Type::dmat4x2;
5389 		break;
5390 	case 9:
5391 		type = Utils::Type::dmat4x3;
5392 		break;
5393 	case 10:
5394 		type = Utils::Type::dvec2;
5395 		break;
5396 	case 11:
5397 		type = Utils::Type::dvec3;
5398 		break;
5399 	case 12:
5400 		type = Utils::Type::dvec4;
5401 		break;
5402 	case 13:
5403 		type = Utils::Type::_float;
5404 		break;
5405 	case 14:
5406 		type = Utils::Type::mat2;
5407 		break;
5408 	case 15:
5409 		type = Utils::Type::mat2x3;
5410 		break;
5411 	case 16:
5412 		type = Utils::Type::mat2x4;
5413 		break;
5414 	case 17:
5415 		type = Utils::Type::mat3;
5416 		break;
5417 	case 18:
5418 		type = Utils::Type::mat3x2;
5419 		break;
5420 	case 19:
5421 		type = Utils::Type::mat3x4;
5422 		break;
5423 	case 20:
5424 		type = Utils::Type::mat4;
5425 		break;
5426 	case 21:
5427 		type = Utils::Type::mat4x2;
5428 		break;
5429 	case 22:
5430 		type = Utils::Type::mat4x3;
5431 		break;
5432 	case 23:
5433 		type = Utils::Type::vec2;
5434 		break;
5435 	case 24:
5436 		type = Utils::Type::vec3;
5437 		break;
5438 	case 25:
5439 		type = Utils::Type::vec4;
5440 		break;
5441 	case 26:
5442 		type = Utils::Type::_int;
5443 		break;
5444 	case 27:
5445 		type = Utils::Type::ivec2;
5446 		break;
5447 	case 28:
5448 		type = Utils::Type::ivec3;
5449 		break;
5450 	case 29:
5451 		type = Utils::Type::ivec4;
5452 		break;
5453 	case 30:
5454 		type = Utils::Type::uint;
5455 		break;
5456 	case 31:
5457 		type = Utils::Type::uvec2;
5458 		break;
5459 	case 32:
5460 		type = Utils::Type::uvec3;
5461 		break;
5462 	case 33:
5463 		type = Utils::Type::uvec4;
5464 		break;
5465 	default:
5466 		TCU_FAIL("invalid enum");
5467 	}
5468 
5469 	return type;
5470 }
5471 
5472 /** Get name of type at index
5473  *
5474  * @param index Index of type
5475  *
5476  * @return Name
5477  **/
getTypeName(GLuint index) const5478 std::string TestBase::getTypeName(GLuint index) const
5479 {
5480 	std::string name = getType(index).GetGLSLTypeName();
5481 
5482 	return name;
5483 }
5484 
5485 /** Get number of types
5486  *
5487  * @return 34
5488  **/
getTypesNumber() const5489 glw::GLuint TestBase::getTypesNumber() const
5490 {
5491 	return 34;
5492 }
5493 
5494 /** Execute test
5495  *
5496  * @return true if test pass, false otherwise
5497  **/
test()5498 bool TestBase::test()
5499 {
5500 	bool   result		= true;
5501 	GLuint n_test_cases = 0;
5502 
5503 	/* Prepare test */
5504 	testInit();
5505 
5506 	/* GL entry points */
5507 	const Functions& gl = m_context.getRenderContext().getFunctions();
5508 
5509 	/* Tessellation patch set up */
5510 	gl.patchParameteri(GL_PATCH_VERTICES, 1);
5511 	GLU_EXPECT_NO_ERROR(gl.getError(), "PatchParameteri");
5512 
5513 	/* Get number of test cases */
5514 	n_test_cases = getTestCaseNumber();
5515 
5516 #if DEBUG_REPEAT_TEST_CASE
5517 
5518 	while (1)
5519 	{
5520 		GLuint test_case = DEBUG_REPEATED_TEST_CASE;
5521 
5522 #else /* DEBUG_REPEAT_TEST_CASE */
5523 
5524 	for (GLuint test_case = 0; test_case < n_test_cases; ++test_case)
5525 	{
5526 #endif /* DEBUG_REPEAT_TEST_CASE */
5527 
5528 		bool case_result = true;
5529 
5530 		/* Execute case */
5531 		if (false == testCase(test_case))
5532 		{
5533 			case_result = false;
5534 		}
5535 
5536 		/* Log failure */
5537 		if (false == case_result)
5538 		{
5539 			const std::string& test_case_name = getTestCaseName(test_case);
5540 
5541 			if (false == test_case_name.empty())
5542 			{
5543 				m_context.getTestContext().getLog() << tcu::TestLog::Message << "Test case (" << test_case_name
5544 													<< ") failed." << tcu::TestLog::EndMessage;
5545 			}
5546 			else
5547 			{
5548 				m_context.getTestContext().getLog() << tcu::TestLog::Message << "Test case (" << test_case
5549 													<< ") failed." << tcu::TestLog::EndMessage;
5550 			}
5551 
5552 			result = false;
5553 		}
5554 	}
5555 
5556 	/* Done */
5557 	return result;
5558 }
5559 
5560 /* Constants used by BufferTestBase */
5561 const GLuint BufferTestBase::bufferDescriptor::m_non_indexed = -1;
5562 
5563 /** Constructor
5564  *
5565  * @param context          Test context
5566  * @param test_name        Name of test
5567  * @param test_description Description of test
5568  **/
5569 BufferTestBase::BufferTestBase(deqp::Context& context, const GLchar* test_name, const GLchar* test_description)
5570 	: TestBase(context, test_name, test_description)
5571 {
5572 }
5573 
5574 /** Execute drawArrays for single vertex
5575  *
5576  * @param ignored
5577  *
5578  * @return true
5579  **/
5580 bool BufferTestBase::executeDrawCall(bool tesEnabled, GLuint /* test_case_index */)
5581 {
5582 	const Functions& gl = m_context.getRenderContext().getFunctions();
5583 
5584 	gl.disable(GL_RASTERIZER_DISCARD);
5585 	GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
5586 
5587 	gl.beginTransformFeedback(GL_POINTS);
5588 	GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
5589 
5590 	// Only TES is existed, glDrawArray can use the parameter GL_PATCHES
5591 	if (tesEnabled == false)
5592 	{
5593 		gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */);
5594 	}
5595 	else
5596 	{
5597 		gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
5598 	}
5599 
5600 	GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
5601 
5602 	gl.endTransformFeedback();
5603 	GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
5604 
5605 	return true;
5606 }
5607 
5608 /** Get descriptors of buffers necessary for test
5609  *
5610  * @param ignored
5611  * @param ignored
5612  **/
5613 void BufferTestBase::getBufferDescriptors(glw::GLuint /* test_case_index */,
5614 										  bufferDescriptor::Vector& /* out_descriptors */)
5615 {
5616 	/* Nothhing to be done */
5617 }
5618 
5619 /** Get list of names of varyings that will be registered with TransformFeedbackVaryings
5620  *
5621  * @param ignored
5622  * @param ignored
5623  **/
5624 void BufferTestBase::getCapturedVaryings(glw::GLuint /* test_case_index */,
5625 										 Utils::Program::NameVector& /* captured_varyings */,
5626 										 GLint* /* xfb_components */)
5627 {
5628 	/* Nothing to be done */
5629 }
5630 
5631 /** Get body of main function for given shader stage
5632  *
5633  * @param ignored
5634  * @param ignored
5635  * @param out_assignments  Set to empty
5636  * @param out_calculations Set to empty
5637  **/
5638 void BufferTestBase::getShaderBody(glw::GLuint /* test_case_index */, Utils::Shader::STAGES /* stage */,
5639 								   std::string& out_assignments, std::string& out_calculations)
5640 {
5641 	out_assignments  = "";
5642 	out_calculations = "";
5643 }
5644 
5645 /** Get interface of shader
5646  *
5647  * @param ignored
5648  * @param ignored
5649  * @param out_interface Set to ""
5650  **/
5651 void BufferTestBase::getShaderInterface(glw::GLuint /* test_case_index */, Utils::Shader::STAGES /* stage */,
5652 										std::string& out_interface)
5653 {
5654 	out_interface = "";
5655 }
5656 
5657 /** Get source code of shader
5658  *
5659  * @param test_case_index Index of test case
5660  * @param stage           Shader stage
5661  *
5662  * @return Source
5663  **/
5664 std::string BufferTestBase::getShaderSource(glw::GLuint test_case_index, Utils::Shader::STAGES stage)
5665 {
5666 	std::string assignments;
5667 	std::string calculations;
5668 	std::string interface;
5669 
5670 	/* */
5671 	getShaderBody(test_case_index, stage, assignments, calculations);
5672 	getShaderInterface(test_case_index, stage, interface);
5673 
5674 	/* */
5675 	std::string source = getShaderTemplate(stage);
5676 
5677 	/* */
5678 	size_t position = 0;
5679 	Utils::replaceToken("INTERFACE", position, interface.c_str(), source);
5680 	Utils::replaceToken("CALCULATIONS", position, calculations.c_str(), source);
5681 	Utils::replaceToken("ASSIGNMENTS", position, assignments.c_str(), source);
5682 
5683 	/* */
5684 	return source;
5685 }
5686 
5687 /** Inspects program to check if all resources are as expected
5688  *
5689  * @param ignored
5690  * @param ignored
5691  * @param ignored
5692  *
5693  * @return true
5694  **/
5695 bool BufferTestBase::inspectProgram(GLuint /* test_case_index */, Utils::Program& /* program */,
5696 									std::stringstream& /* out_stream */)
5697 {
5698 	return true;
5699 }
5700 
5701 /** Runs test case
5702  *
5703  * @param test_case_index Id of test case
5704  *
5705  * @return true if test case pass, false otherwise
5706  **/
5707 bool BufferTestBase::testCase(GLuint test_case_index)
5708 {
5709 	try
5710 	{
5711 		bufferCollection		   buffers;
5712 		Utils::Program::NameVector captured_varyings;
5713 		bufferDescriptor::Vector   descriptors;
5714 		Utils::Program			   program(m_context);
5715 		Utils::VertexArray		   vao(m_context);
5716 
5717 		/* Get captured varyings */
5718 		GLint xfb_components;
5719 		getCapturedVaryings(test_case_index, captured_varyings, &xfb_components);
5720 
5721 		/* Don't generate shaders that try to capture more XFB components than the implementation's limit */
5722 		if (captured_varyings.size() > 0)
5723 		{
5724 			const Functions& gl	= m_context.getRenderContext().getFunctions();
5725 
5726 			GLint max_xfb_components;
5727 			gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_xfb_components);
5728 			GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
5729 
5730 			if (xfb_components > max_xfb_components)
5731 				return true;
5732 		}
5733 
5734 		/* Get shader sources */
5735 		const std::string& fragment_shader  = getShaderSource(test_case_index, Utils::Shader::FRAGMENT);
5736 		const std::string& geometry_shader  = getShaderSource(test_case_index, Utils::Shader::GEOMETRY);
5737 		const std::string& tess_ctrl_shader = getShaderSource(test_case_index, Utils::Shader::TESS_CTRL);
5738 		const std::string& tess_eval_shader = getShaderSource(test_case_index, Utils::Shader::TESS_EVAL);
5739 		const std::string& vertex_shader	= getShaderSource(test_case_index, Utils::Shader::VERTEX);
5740 
5741 		/* Set up program */
5742 		program.Init("" /* compute_shader */, fragment_shader, geometry_shader, tess_ctrl_shader, tess_eval_shader,
5743 					 vertex_shader, captured_varyings, true, false /* is_separable */);
5744 
5745 		/* Inspection */
5746 		{
5747 			std::stringstream stream;
5748 			if (false == inspectProgram(test_case_index, program, stream))
5749 			{
5750 				m_context.getTestContext().getLog()
5751 					<< tcu::TestLog::Message
5752 					<< "Program inspection failed. Test case: " << getTestCaseName(test_case_index)
5753 					<< ". Reason: " << stream.str() << tcu::TestLog::EndMessage
5754 					<< tcu::TestLog::KernelSource(vertex_shader) << tcu::TestLog::KernelSource(tess_ctrl_shader)
5755 					<< tcu::TestLog::KernelSource(tess_eval_shader) << tcu::TestLog::KernelSource(geometry_shader)
5756 					<< tcu::TestLog::KernelSource(fragment_shader);
5757 
5758 				return false;
5759 			}
5760 		}
5761 
5762 		program.Use();
5763 
5764 		/* Set up buffers */
5765 		getBufferDescriptors(test_case_index, descriptors);
5766 		cleanBuffers();
5767 		prepareBuffers(descriptors, buffers);
5768 
5769 		/* Set up vao */
5770 		vao.Init();
5771 		vao.Bind();
5772 
5773 		/* Draw */
5774 		bool result = executeDrawCall((program.m_tess_eval.m_id != 0), test_case_index);
5775 
5776 #if USE_NSIGHT
5777 		m_context.getRenderContext().postIterate();
5778 #endif
5779 
5780 		if (false == result)
5781 		{
5782 			m_context.getTestContext().getLog()
5783 				<< tcu::TestLog::KernelSource(vertex_shader) << tcu::TestLog::KernelSource(tess_ctrl_shader)
5784 				<< tcu::TestLog::KernelSource(tess_eval_shader) << tcu::TestLog::KernelSource(geometry_shader)
5785 				<< tcu::TestLog::KernelSource(fragment_shader);
5786 
5787 			return false;
5788 		}
5789 
5790 		/* Verify result */
5791 		if (false == verifyBuffers(buffers))
5792 		{
5793 			m_context.getTestContext().getLog()
5794 				<< tcu::TestLog::KernelSource(vertex_shader) << tcu::TestLog::KernelSource(tess_ctrl_shader)
5795 				<< tcu::TestLog::KernelSource(tess_eval_shader) << tcu::TestLog::KernelSource(geometry_shader)
5796 				<< tcu::TestLog::KernelSource(fragment_shader);
5797 
5798 			return false;
5799 		}
5800 	}
5801 	catch (Utils::Shader::InvalidSourceException& exc)
5802 	{
5803 		exc.log(m_context);
5804 		TCU_FAIL(exc.what());
5805 	}
5806 	catch (Utils::Program::BuildException& exc)
5807 	{
5808 		exc.log(m_context);
5809 		TCU_FAIL(exc.what());
5810 	}
5811 
5812 	/* Done */
5813 	return true;
5814 }
5815 
5816 /** Verify contents of buffers
5817  *
5818  * @param buffers Collection of buffers to be verified
5819  *
5820  * @return true if everything is as expected, false otherwise
5821  **/
5822 bool BufferTestBase::verifyBuffers(bufferCollection& buffers)
5823 {
5824 	bool result = true;
5825 
5826 	for (bufferCollection::Vector::iterator it = buffers.m_vector.begin(), end = buffers.m_vector.end(); end != it;
5827 		 ++it)
5828 	{
5829 		bufferCollection::pair& pair	   = *it;
5830 		Utils::Buffer*			buffer	 = pair.m_buffer;
5831 		bufferDescriptor*		descriptor = pair.m_descriptor;
5832 		size_t					size	   = descriptor->m_expected_data.size();
5833 
5834 		/* Skip buffers that have no expected data */
5835 		if (0 == size)
5836 		{
5837 			continue;
5838 		}
5839 
5840 		/* Get pointer to contents of buffer */
5841 		buffer->Bind();
5842 		GLvoid* buffer_data = buffer->Map(Utils::Buffer::ReadOnly);
5843 
5844 		/* Get pointer to expected data */
5845 		GLvoid* expected_data = &descriptor->m_expected_data[0];
5846 
5847 		/* Compare */
5848 		int res = memcmp(buffer_data, expected_data, size);
5849 
5850 		if (0 != res)
5851 		{
5852 			m_context.getTestContext().getLog()
5853 				<< tcu::TestLog::Message
5854 				<< "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
5855 				<< ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
5856 
5857 			result = false;
5858 		}
5859 
5860 		/* Release buffer mapping */
5861 		buffer->UnMap();
5862 	}
5863 
5864 	return result;
5865 }
5866 
5867 /** Unbinds all uniforms and xfb
5868  *
5869  **/
5870 void BufferTestBase::cleanBuffers()
5871 {
5872 	const Functions& gl = m_context.getRenderContext().getFunctions();
5873 
5874 	GLint max_uni = 0;
5875 	GLint max_xfb = 0;
5876 
5877 	gl.getIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &max_uni);
5878 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_xfb);
5879 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
5880 
5881 	for (GLint i = 0; i < max_uni; ++i)
5882 	{
5883 		Utils::Buffer::BindBase(gl, 0, Utils::Buffer::Uniform, i);
5884 	}
5885 
5886 	for (GLint i = 0; i < max_xfb; ++i)
5887 	{
5888 		Utils::Buffer::BindBase(gl, 0, Utils::Buffer::Transform_feedback, i);
5889 	}
5890 }
5891 
5892 /** Get template of shader for given stage
5893  *
5894  * @param stage Stage
5895  *
5896  * @return Template of shader source
5897  **/
5898 std::string BufferTestBase::getShaderTemplate(Utils::Shader::STAGES stage)
5899 {
5900 	static const GLchar* compute_shader_template = "#version 430 core\n"
5901 												   "#extension GL_ARB_enhanced_layouts : require\n"
5902 												   "\n"
5903 												   "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
5904 												   "\n"
5905 												   "writeonly uniform uimage2D uni_image;\n"
5906 												   "\n"
5907 												   "INTERFACE"
5908 												   "\n"
5909 												   "void main()\n"
5910 												   "{\n"
5911 												   "CALCULATIONS"
5912 												   "\n"
5913 												   "ASSIGNMENTS"
5914 												   "}\n"
5915 												   "\n";
5916 
5917 	static const GLchar* fragment_shader_template = "#version 430 core\n"
5918 													"#extension GL_ARB_enhanced_layouts : require\n"
5919 													"\n"
5920 													"INTERFACE"
5921 													"\n"
5922 													"void main()\n"
5923 													"{\n"
5924 													"CALCULATIONS"
5925 													"\n"
5926 													"ASSIGNMENTS"
5927 													"}\n"
5928 													"\n";
5929 
5930 	// max_vertices is set to 3 for the test case "xfb_vertex_streams" declares 3 streams in geometry shader,
5931 	// according to spec, max_vertices should be no less than 3 if there are 3 streams in GS.
5932 	static const GLchar* geometry_shader_template = "#version 430 core\n"
5933 													"#extension GL_ARB_enhanced_layouts : require\n"
5934 													"\n"
5935 													"layout(points)                   in;\n"
5936 													"layout(points, max_vertices = 3) out;\n"
5937 													"\n"
5938 													"INTERFACE"
5939 													"\n"
5940 													"void main()\n"
5941 													"{\n"
5942 													"CALCULATIONS"
5943 													"\n"
5944 													"\n"
5945 													"ASSIGNMENTS"
5946 													"    gl_Position  = vec4(0, 0, 0, 1);\n"
5947 													"    EmitVertex();\n"
5948 													"}\n"
5949 													"\n";
5950 
5951 	static const GLchar* tess_ctrl_shader_template = "#version 430 core\n"
5952 													 "#extension GL_ARB_enhanced_layouts : require\n"
5953 													 "\n"
5954 													 "layout(vertices = 1) out;\n"
5955 													 "\n"
5956 													 "INTERFACE"
5957 													 "\n"
5958 													 "void main()\n"
5959 													 "{\n"
5960 													 "CALCULATIONS"
5961 													 "\n"
5962 													 "ASSIGNMENTS"
5963 													 "\n"
5964 													 "    gl_TessLevelOuter[0] = 1.0;\n"
5965 													 "    gl_TessLevelOuter[1] = 1.0;\n"
5966 													 "    gl_TessLevelOuter[2] = 1.0;\n"
5967 													 "    gl_TessLevelOuter[3] = 1.0;\n"
5968 													 "    gl_TessLevelInner[0] = 1.0;\n"
5969 													 "    gl_TessLevelInner[1] = 1.0;\n"
5970 													 "}\n"
5971 													 "\n";
5972 
5973 	static const GLchar* tess_eval_shader_template = "#version 430 core\n"
5974 													 "#extension GL_ARB_enhanced_layouts : require\n"
5975 													 "\n"
5976 													 "layout(isolines, point_mode) in;\n"
5977 													 "\n"
5978 													 "INTERFACE"
5979 													 "\n"
5980 													 "void main()\n"
5981 													 "{\n"
5982 													 "CALCULATIONS"
5983 													 "\n"
5984 													 "ASSIGNMENTS"
5985 													 "}\n"
5986 													 "\n";
5987 
5988 	static const GLchar* vertex_shader_template = "#version 430 core\n"
5989 												  "#extension GL_ARB_enhanced_layouts : require\n"
5990 												  "\n"
5991 												  "INTERFACE"
5992 												  "\n"
5993 												  "void main()\n"
5994 												  "{\n"
5995 												  "CALCULATIONS"
5996 												  "\n"
5997 												  "ASSIGNMENTS"
5998 												  "}\n"
5999 												  "\n";
6000 
6001 	const GLchar* result = 0;
6002 
6003 	switch (stage)
6004 	{
6005 	case Utils::Shader::COMPUTE:
6006 		result = compute_shader_template;
6007 		break;
6008 	case Utils::Shader::FRAGMENT:
6009 		result = fragment_shader_template;
6010 		break;
6011 	case Utils::Shader::GEOMETRY:
6012 		result = geometry_shader_template;
6013 		break;
6014 	case Utils::Shader::TESS_CTRL:
6015 		result = tess_ctrl_shader_template;
6016 		break;
6017 	case Utils::Shader::TESS_EVAL:
6018 		result = tess_eval_shader_template;
6019 		break;
6020 	case Utils::Shader::VERTEX:
6021 		result = vertex_shader_template;
6022 		break;
6023 	default:
6024 		TCU_FAIL("Invalid enum");
6025 	}
6026 
6027 	return result;
6028 }
6029 
6030 /** Prepare buffer according to descriptor
6031  *
6032  * @param buffer Buffer to prepare
6033  * @param desc   Descriptor
6034  **/
6035 void BufferTestBase::prepareBuffer(Utils::Buffer& buffer, bufferDescriptor& desc)
6036 {
6037 	GLsizeiptr size = 0;
6038 	GLvoid*	data = 0;
6039 
6040 	if (false == desc.m_initial_data.empty())
6041 	{
6042 		size = desc.m_initial_data.size();
6043 		data = &desc.m_initial_data[0];
6044 	}
6045 	else if (false == desc.m_expected_data.empty())
6046 	{
6047 		size = desc.m_expected_data.size();
6048 	}
6049 
6050 	buffer.Init(desc.m_target, Utils::Buffer::StaticDraw, size, data);
6051 
6052 	if (bufferDescriptor::m_non_indexed != desc.m_index)
6053 	{
6054 		buffer.BindBase(desc.m_index);
6055 	}
6056 	else
6057 	{
6058 		buffer.Bind();
6059 	}
6060 }
6061 
6062 /** Prepare collection of buffer
6063  *
6064  * @param descriptors Collection of descriptors
6065  * @param out_buffers Collection of buffers
6066  **/
6067 void BufferTestBase::prepareBuffers(bufferDescriptor::Vector& descriptors, bufferCollection& out_buffers)
6068 {
6069 	for (bufferDescriptor::Vector::iterator it = descriptors.begin(), end = descriptors.end(); end != it; ++it)
6070 	{
6071 		bufferCollection::pair pair;
6072 
6073 		pair.m_buffer = new Utils::Buffer(m_context);
6074 		if (0 == pair.m_buffer)
6075 		{
6076 			TCU_FAIL("Memory allocation failed");
6077 		}
6078 
6079 		pair.m_descriptor = &(*it);
6080 
6081 		prepareBuffer(*pair.m_buffer, *pair.m_descriptor);
6082 
6083 		out_buffers.m_vector.push_back(pair);
6084 	}
6085 }
6086 
6087 /** Destructor
6088  *
6089  **/
6090 BufferTestBase::bufferCollection::~bufferCollection()
6091 {
6092 	for (Vector::iterator it = m_vector.begin(), end = m_vector.end(); end != it; ++it)
6093 	{
6094 		if (0 != it->m_buffer)
6095 		{
6096 			delete it->m_buffer;
6097 			it->m_buffer = 0;
6098 		}
6099 	}
6100 }
6101 
6102 /** Constructor
6103  *
6104  * @param context          Test context
6105  * @param test_name        Name of test
6106  * @param test_description Description of test
6107  **/
6108 NegativeTestBase::NegativeTestBase(deqp::Context& context, const GLchar* test_name, const GLchar* test_description)
6109 	: TestBase(context, test_name, test_description)
6110 {
6111 }
6112 
6113 /** Selects if "compute" stage is relevant for test
6114  *
6115  * @param ignored
6116  *
6117  * @return true
6118  **/
6119 bool NegativeTestBase::isComputeRelevant(GLuint /* test_case_index */)
6120 {
6121 	return true;
6122 }
6123 
6124 /** Selects if compilation failure is expected result
6125  *
6126  * @param ignored
6127  *
6128  * @return true
6129  **/
6130 bool NegativeTestBase::isFailureExpected(GLuint /* test_case_index */)
6131 {
6132 	return true;
6133 }
6134 
6135 /** Runs test case
6136  *
6137  * @param test_case_index Id of test case
6138  *
6139  * @return true if test case pass, false otherwise
6140  **/
6141 bool NegativeTestBase::testCase(GLuint test_case_index)
6142 {
6143 	bool test_case_result = true;
6144 
6145 	/* Compute */
6146 	if (true == isComputeRelevant(test_case_index))
6147 	{
6148 		const std::string& cs_source		   = getShaderSource(test_case_index, Utils::Shader::COMPUTE);
6149 		bool			   is_build_error	  = false;
6150 		const bool		   is_failure_expected = isFailureExpected(test_case_index);
6151 		Utils::Program	 program(m_context);
6152 
6153 		try
6154 		{
6155 			program.Init(cs_source, "" /* fs */, "" /* gs */, "" /* tcs */, "" /* tes */, "" /* vs */,
6156 						 false /* separable */);
6157 		}
6158 		catch (Utils::Shader::InvalidSourceException& exc)
6159 		{
6160 			if (false == is_failure_expected)
6161 			{
6162 				m_context.getTestContext().getLog()
6163 					<< tcu::TestLog::Message << "Unexpected error in shader compilation: " << tcu::TestLog::EndMessage;
6164 				exc.log(m_context);
6165 			}
6166 
6167 #if DEBUG_NEG_LOG_ERROR
6168 
6169 			else
6170 			{
6171 				m_context.getTestContext().getLog()
6172 					<< tcu::TestLog::Message << "Error in shader compilation was expected, logged for verification: "
6173 					<< tcu::TestLog::EndMessage;
6174 				exc.log(m_context);
6175 			}
6176 
6177 #endif /* DEBUG_NEG_LOG_ERROR */
6178 
6179 			is_build_error = true;
6180 		}
6181 		catch (Utils::Program::BuildException& exc)
6182 		{
6183 			if (false == is_failure_expected)
6184 			{
6185 				m_context.getTestContext().getLog()
6186 					<< tcu::TestLog::Message << "Unexpected error in program linking: " << tcu::TestLog::EndMessage;
6187 				exc.log(m_context);
6188 			}
6189 
6190 #if DEBUG_NEG_LOG_ERROR
6191 
6192 			else
6193 			{
6194 				m_context.getTestContext().getLog()
6195 					<< tcu::TestLog::Message
6196 					<< "Error in program linking was expected, logged for verification: " << tcu::TestLog::EndMessage;
6197 				exc.log(m_context);
6198 			}
6199 
6200 #endif /* DEBUG_NEG_LOG_ERROR */
6201 
6202 			is_build_error = true;
6203 		}
6204 
6205 		if (is_build_error != is_failure_expected)
6206 		{
6207 			if (!is_build_error)
6208 			{
6209 				m_context.getTestContext().getLog()
6210 					<< tcu::TestLog::Message << "Unexpected success: " << tcu::TestLog::EndMessage;
6211 				Utils::Shader::LogSource(m_context, cs_source, Utils::Shader::COMPUTE);
6212 			}
6213 			test_case_result = false;
6214 		}
6215 	}
6216 	else /* Draw */
6217 	{
6218 		const std::string& fs_source		   = getShaderSource(test_case_index, Utils::Shader::FRAGMENT);
6219 		const std::string& gs_source		   = getShaderSource(test_case_index, Utils::Shader::GEOMETRY);
6220 		bool			   is_build_error	  = false;
6221 		const bool		   is_failure_expected = isFailureExpected(test_case_index);
6222 		Utils::Program	 program(m_context);
6223 		const std::string& tcs_source = getShaderSource(test_case_index, Utils::Shader::TESS_CTRL);
6224 		const std::string& tes_source = getShaderSource(test_case_index, Utils::Shader::TESS_EVAL);
6225 		const std::string& vs_source  = getShaderSource(test_case_index, Utils::Shader::VERTEX);
6226 
6227 		try
6228 		{
6229 			program.Init("" /* cs */, fs_source, gs_source, tcs_source, tes_source, vs_source, false /* separable */);
6230 		}
6231 		catch (Utils::Shader::InvalidSourceException& exc)
6232 		{
6233 			if (false == is_failure_expected)
6234 			{
6235 				m_context.getTestContext().getLog()
6236 					<< tcu::TestLog::Message << "Unexpected error in shader compilation: " << tcu::TestLog::EndMessage;
6237 				exc.log(m_context);
6238 			}
6239 
6240 #if DEBUG_NEG_LOG_ERROR
6241 
6242 			else
6243 			{
6244 				m_context.getTestContext().getLog()
6245 					<< tcu::TestLog::Message << "Error in shader compilation was expected, logged for verification: "
6246 					<< tcu::TestLog::EndMessage;
6247 				exc.log(m_context);
6248 			}
6249 
6250 #endif /* DEBUG_NEG_LOG_ERROR */
6251 
6252 			is_build_error = true;
6253 		}
6254 		catch (Utils::Program::BuildException& exc)
6255 		{
6256 			if (false == is_failure_expected)
6257 			{
6258 				m_context.getTestContext().getLog()
6259 					<< tcu::TestLog::Message << "Unexpected error in program linking: " << tcu::TestLog::EndMessage;
6260 				exc.log(m_context);
6261 			}
6262 
6263 #if DEBUG_NEG_LOG_ERROR
6264 
6265 			else
6266 			{
6267 				m_context.getTestContext().getLog()
6268 					<< tcu::TestLog::Message
6269 					<< "Error in program linking was expected, logged for verification: " << tcu::TestLog::EndMessage;
6270 				exc.log(m_context);
6271 			}
6272 
6273 #endif /* DEBUG_NEG_LOG_ERROR */
6274 
6275 			is_build_error = true;
6276 		}
6277 
6278 		if (is_build_error != is_failure_expected)
6279 		{
6280 			if (!is_build_error)
6281 			{
6282 				m_context.getTestContext().getLog()
6283 					<< tcu::TestLog::Message << "Unexpected success: " << tcu::TestLog::EndMessage;
6284 				Utils::Shader::LogSource(m_context, vs_source, Utils::Shader::VERTEX);
6285 				Utils::Shader::LogSource(m_context, tcs_source, Utils::Shader::TESS_CTRL);
6286 				Utils::Shader::LogSource(m_context, tes_source, Utils::Shader::TESS_EVAL);
6287 				Utils::Shader::LogSource(m_context, gs_source, Utils::Shader::GEOMETRY);
6288 				Utils::Shader::LogSource(m_context, fs_source, Utils::Shader::FRAGMENT);
6289 			}
6290 			test_case_result = false;
6291 		}
6292 	}
6293 
6294 	return test_case_result;
6295 }
6296 
6297 /* Constants used by TextureTestBase */
6298 const glw::GLuint TextureTestBase::m_width  = 16;
6299 const glw::GLuint TextureTestBase::m_height = 16;
6300 
6301 /** Constructor
6302  *
6303  * @param context          Test context
6304  * @param test_name        Name of test
6305  * @param test_description Description of test
6306  **/
6307 TextureTestBase::TextureTestBase(deqp::Context& context, const GLchar* test_name, const GLchar* test_description)
6308 	: TestBase(context, test_name, test_description)
6309 {
6310 }
6311 
6312 /** Get locations for all inputs with automatic_location
6313  *
6314  * @param program           Program object
6315  * @param program_interface Interface of program
6316  **/
6317 void TextureTestBase::prepareAttribLocation(Utils::Program& program, Utils::ProgramInterface& program_interface)
6318 {
6319 	Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
6320 
6321 	Utils::Variable::PtrVector& inputs = si.m_inputs;
6322 
6323 	for (Utils::Variable::PtrVector::iterator it = inputs.begin(); inputs.end() != it; ++it)
6324 	{
6325 		/* Test does not specify location, query value and set */
6326 		if (Utils::Variable::m_automatic_location == (*it)->m_descriptor.m_expected_location)
6327 		{
6328 			GLuint index	= program.GetResourceIndex((*it)->m_descriptor.m_name, GL_PROGRAM_INPUT);
6329 			GLint  location = 0;
6330 
6331 			program.GetResource(GL_PROGRAM_INPUT, index, GL_LOCATION, 1 /* size */, &location);
6332 
6333 			(*it)->m_descriptor.m_expected_location = location;
6334 		}
6335 	}
6336 }
6337 
6338 /** Verifies contents of drawn image
6339  *
6340  * @param ignored
6341  * @param color_0 Verified image
6342  *
6343  * @return true if image is filled with 1, false otherwise
6344  **/
6345 bool TextureTestBase::checkResults(glw::GLuint /* test_case_index */, Utils::Texture& color_0)
6346 {
6347 	static const GLuint size		   = m_width * m_height;
6348 	static const GLuint expected_color = 1;
6349 
6350 	std::vector<GLuint> data;
6351 	data.resize(size);
6352 
6353 	color_0.Get(GL_RED_INTEGER, GL_UNSIGNED_INT, &data[0]);
6354 
6355 	for (GLuint i = 0; i < size; ++i)
6356 	{
6357 		const GLuint color = data[i];
6358 
6359 		if (expected_color != color)
6360 		{
6361 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "R32UI[" << i << "]:" << color
6362 												<< tcu::TestLog::EndMessage;
6363 			return false;
6364 		}
6365 	}
6366 
6367 	return true;
6368 }
6369 
6370 /** Execute dispatch compute for 16x16x1
6371  *
6372  * @param ignored
6373  **/
6374 void TextureTestBase::executeDispatchCall(GLuint /* test_case_index */)
6375 {
6376 	const Functions& gl = m_context.getRenderContext().getFunctions();
6377 
6378 	gl.dispatchCompute(16 /* x */, 16 /* y */, 1 /* z */);
6379 	GLU_EXPECT_NO_ERROR(gl.getError(), "DispatchCompute");
6380 }
6381 
6382 /** Execute drawArrays for single vertex
6383  *
6384  * @param ignored
6385  **/
6386 void TextureTestBase::executeDrawCall(GLuint /* test_case_index */)
6387 {
6388 	const Functions& gl = m_context.getRenderContext().getFunctions();
6389 
6390 	gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
6391 	GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
6392 }
6393 
6394 /** Prepare code snippet that will pass in variables to out variables
6395  *
6396  * @param ignored
6397  * @param varying_passthrough Collection of connections between in and out variables
6398  * @param stage               Shader stage
6399  *
6400  * @return Code that pass in variables to next stage
6401  **/
6402 std::string TextureTestBase::getPassSnippet(GLuint /* test_case_index */,
6403 											Utils::VaryingPassthrough& varying_passthrough, Utils::Shader::STAGES stage)
6404 {
6405 	static const GLchar* separator = "\n    ";
6406 
6407 	/* Skip for compute shader */
6408 	if (Utils::Shader::COMPUTE == stage)
6409 	{
6410 		return "";
6411 	}
6412 
6413 	Utils::VaryingConnection::Vector& vector = varying_passthrough.Get(stage);
6414 
6415 	std::string result   = Utils::g_list;
6416 	size_t		position = 0;
6417 
6418 	for (GLuint i = 0; i < vector.size(); ++i)
6419 	{
6420 
6421 		Utils::VaryingConnection& connection = vector[i];
6422 
6423 		Utils::Variable* in  = connection.m_in;
6424 		Utils::Variable* out = connection.m_out;
6425 
6426 		Utils::Variable::FLAVOUR in_flavour  = Utils::Variable::GetFlavour(stage, Utils::Variable::INPUT);
6427 		Utils::Variable::FLAVOUR out_flavour = Utils::Variable::GetFlavour(stage, Utils::Variable::OUTPUT);
6428 
6429 		const std::string passthrough =
6430 			getVariablePassthrough("", in->m_descriptor, in_flavour, "", out->m_descriptor, out_flavour);
6431 
6432 		Utils::insertElementOfList(passthrough.c_str(), separator, position, result);
6433 	}
6434 
6435 	Utils::endList("", position, result);
6436 
6437 	return result;
6438 }
6439 
6440 /** Basic implementation of method getProgramInterface
6441  *
6442  * @param ignored
6443  * @param ignored
6444  * @param ignored
6445  **/
6446 void TextureTestBase::getProgramInterface(GLuint /* test_case_index */,
6447 										  Utils::ProgramInterface& /* program_interface */,
6448 										  Utils::VaryingPassthrough& /* varying_passthrough */)
6449 {
6450 }
6451 
6452 /** Prepare code snippet that will verify in and uniform variables
6453  *
6454  * @param ignored
6455  * @param program_interface Interface of program
6456  * @param stage             Shader stage
6457  *
6458  * @return Code that verify variables
6459  **/
6460 std::string TextureTestBase::getVerificationSnippet(GLuint /* test_case_index */,
6461 													Utils::ProgramInterface& program_interface,
6462 													Utils::Shader::STAGES	stage)
6463 {
6464 	static const GLchar* separator = " ||\n        ";
6465 
6466 	std::string verification = "if (LIST)\n"
6467 							   "    {\n"
6468 							   "        result = 0u;\n"
6469 							   "    }\n";
6470 
6471 	/* Get flavour of in and out variables */
6472 	Utils::Variable::FLAVOUR in_flavour = Utils::Variable::GetFlavour(stage, Utils::Variable::INPUT);
6473 
6474 	/* Get interface for shader stage */
6475 	Utils::ShaderInterface& si = program_interface.GetShaderInterface(stage);
6476 
6477 	/* There are no varialbes to verify */
6478 	if ((0 == si.m_inputs.size()) && (0 == si.m_uniforms.size()) && (0 == si.m_ssb_blocks.size()))
6479 	{
6480 		return "";
6481 	}
6482 
6483 	/* For each in variable insert verification code */
6484 	size_t position = 0;
6485 
6486 	for (GLuint i = 0; i < si.m_inputs.size(); ++i)
6487 	{
6488 		const Utils::Variable& var				= *si.m_inputs[i];
6489 		const std::string&	 var_verification = getVariableVerification("", var.m_data, var.m_descriptor, in_flavour);
6490 
6491 		Utils::insertElementOfList(var_verification.c_str(), separator, position, verification);
6492 	}
6493 
6494 	/* For each unifrom variable insert verification code */
6495 	for (GLuint i = 0; i < si.m_uniforms.size(); ++i)
6496 	{
6497 		const Utils::Variable& var = *si.m_uniforms[i];
6498 		const std::string&	 var_verification =
6499 			getVariableVerification("", var.m_data, var.m_descriptor, Utils::Variable::BASIC);
6500 
6501 		Utils::insertElementOfList(var_verification.c_str(), separator, position, verification);
6502 	}
6503 
6504 	/* For each ssb variable insert verification code */
6505 	for (GLuint i = 0; i < si.m_ssb_blocks.size(); ++i)
6506 	{
6507 		const Utils::Variable& var = *si.m_ssb_blocks[i];
6508 		const std::string&	 var_verification =
6509 			getVariableVerification("", var.m_data, var.m_descriptor, Utils::Variable::BASIC);
6510 
6511 		Utils::insertElementOfList(var_verification.c_str(), separator, position, verification);
6512 	}
6513 
6514 	Utils::endList("", position, verification);
6515 
6516 #if DEBUG_TTB_VERIFICATION_SNIPPET_STAGE
6517 
6518 	{
6519 		GLchar buffer[16];
6520 		sprintf(buffer, "%d", stage + 10);
6521 		Utils::replaceToken("0u", position, buffer, verification);
6522 	}
6523 
6524 #elif DEBUG_TTB_VERIFICATION_SNIPPET_VARIABLE
6525 
6526 	if (Utils::Shader::VERTEX == stage)
6527 	{
6528 		Utils::replaceToken("0u", position, "in_vs_first.x", verification);
6529 	}
6530 	else
6531 	{
6532 		Utils::replaceToken("0u", position, "31u", verification);
6533 	}
6534 
6535 #endif
6536 
6537 	/* Done */
6538 	return verification;
6539 }
6540 
6541 /** Selects if "compute" stage is relevant for test
6542  *
6543  * @param ignored
6544  *
6545  * @return true
6546  **/
6547 bool TextureTestBase::isComputeRelevant(GLuint /* test_case_index */)
6548 {
6549 	return true;
6550 }
6551 
6552 /** Selects if "draw" stages are relevant for test
6553  *
6554  * @param ignored
6555  *
6556  * @return true
6557  **/
6558 bool TextureTestBase::isDrawRelevant(GLuint /* test_case_index */)
6559 {
6560 	return true;
6561 }
6562 
6563 /** Prepare code that will do assignment of single in to single out
6564  *
6565  * @param in_parent_name  Name of parent in variable
6566  * @param in_variable     Descriptor of in variable
6567  * @param in_flavour      Flavoud of in variable
6568  * @param out_parent_name Name of parent out variable
6569  * @param out_variable    Descriptor of out variable
6570  * @param out_flavour     Flavoud of out variable
6571  *
6572  * @return Code that does OUT = IN
6573  **/
6574 std::string TextureTestBase::getVariablePassthrough(const std::string&				   in_parent_name,
6575 													const Utils::Variable::Descriptor& in_variable,
6576 													Utils::Variable::FLAVOUR		   in_flavour,
6577 													const std::string&				   out_parent_name,
6578 													const Utils::Variable::Descriptor& out_variable,
6579 													Utils::Variable::FLAVOUR		   out_flavour)
6580 {
6581 	bool				 done		  = false;
6582 	GLuint				 index		  = 0;
6583 	GLuint				 member_index = 0;
6584 	size_t				 position	 = 0;
6585 	std::string			 result		  = Utils::g_list;
6586 	static const GLchar* separator	= ";\n    ";
6587 
6588 	/* For each member of each array element */
6589 	do
6590 	{
6591 		const std::string in_name  = Utils::Variable::GetReference(in_parent_name, in_variable, in_flavour, index);
6592 		const std::string out_name = Utils::Variable::GetReference(out_parent_name, out_variable, out_flavour, index);
6593 		std::string		  passthrough;
6594 
6595 		/* Prepare verification */
6596 		if (Utils::Variable::BUILTIN == in_variable.m_type)
6597 		{
6598 			size_t pass_position = 0;
6599 
6600 			passthrough = "OUT = IN;";
6601 
6602 			Utils::replaceToken("OUT", pass_position, out_name.c_str(), passthrough);
6603 			Utils::replaceToken("IN", pass_position, in_name.c_str(), passthrough);
6604 
6605 			/* Increment index */
6606 			++index;
6607 		}
6608 		else
6609 		{
6610 			const Utils::Interface* in_interface  = in_variable.m_interface;
6611 			const Utils::Interface* out_interface = out_variable.m_interface;
6612 
6613 			if ((0 == in_interface) || (0 == out_interface))
6614 			{
6615 				TCU_FAIL("Nullptr");
6616 			}
6617 
6618 			const Utils::Variable::Descriptor& in_member  = in_interface->m_members[member_index];
6619 			const Utils::Variable::Descriptor& out_member = out_interface->m_members[member_index];
6620 
6621 			passthrough = getVariablePassthrough(in_name, in_member, Utils::Variable::BASIC, out_name, out_member,
6622 												 Utils::Variable::BASIC);
6623 
6624 			/* Increment member_index */
6625 			++member_index;
6626 
6627 			/* Increment index and reset member_index if all members were processed */
6628 			if (in_interface->m_members.size() == member_index)
6629 			{
6630 				++index;
6631 				member_index = 0;
6632 			}
6633 		}
6634 
6635 		/* Check if loop should end */
6636 		if ((index >= in_variable.m_n_array_elements) && (0 == member_index))
6637 		{
6638 			done = true;
6639 		}
6640 
6641 		Utils::insertElementOfList(passthrough.c_str(), separator, position, result);
6642 
6643 	} while (true != done);
6644 
6645 	Utils::endList("", position, result);
6646 
6647 	/* Done */
6648 	return result;
6649 }
6650 
6651 /** Get verification of single variable
6652  *
6653  * @param parent_name Name of parent variable
6654  * @param data        Data that should be used as EXPECTED
6655  * @param variable    Descriptor of variable
6656  * @param flavour     Flavour of variable
6657  *
6658  * @return Code that does (EXPECTED != VALUE) ||
6659  **/
6660 std::string TextureTestBase::getVariableVerification(const std::string& parent_name, const GLvoid* data,
6661 													 const Utils::Variable::Descriptor& variable,
6662 													 Utils::Variable::FLAVOUR			flavour)
6663 {
6664 	static const GLchar* logic_op   = " ||\n        ";
6665 	const GLuint		 n_elements = (0 == variable.m_n_array_elements) ? 1 : variable.m_n_array_elements;
6666 	size_t				 position   = 0;
6667 	std::string			 result		= Utils::g_list;
6668 	GLint				 stride		= variable.m_expected_stride_of_element;
6669 
6670 	/* For each each array element */
6671 	for (GLuint element = 0; element < n_elements; ++element)
6672 	{
6673 		const std::string name = Utils::Variable::GetReference(parent_name, variable, flavour, element);
6674 
6675 		/* Calculate data pointer */
6676 		GLvoid* data_ptr = (GLvoid*)((GLubyte*)data + element * stride);
6677 
6678 		/* Prepare verification */
6679 		if (Utils::Variable::BUILTIN == variable.m_type)
6680 		{
6681 			const std::string& expected = variable.m_builtin.GetGLSLConstructor(data_ptr);
6682 			std::string		   verification;
6683 			size_t			   verification_position = 0;
6684 
6685 			verification = "(EXPECTED != NAME)";
6686 
6687 			Utils::replaceToken("EXPECTED", verification_position, expected.c_str(), verification);
6688 			Utils::replaceToken("NAME", verification_position, name.c_str(), verification);
6689 
6690 			Utils::insertElementOfList(verification.c_str(), logic_op, position, result);
6691 		}
6692 		else
6693 		{
6694 			const Utils::Interface* interface = variable.m_interface;
6695 
6696 			if (0 == interface)
6697 			{
6698 				TCU_FAIL("Nullptr");
6699 			}
6700 
6701 			const GLuint n_members = static_cast<GLuint>(interface->m_members.size());
6702 
6703 			/* for each member */
6704 			for (GLuint member_index = 0; member_index < n_members; ++member_index)
6705 			{
6706 				const Utils::Variable::Descriptor& member = interface->m_members[member_index];
6707 
6708 				/* Get verification of member */
6709 				const std::string& verification =
6710 					getVariableVerification(name, (GLubyte*)data_ptr + member.m_offset, member, Utils::Variable::BASIC);
6711 
6712 				Utils::insertElementOfList(verification.c_str(), logic_op, position, result);
6713 			}
6714 		}
6715 	}
6716 
6717 	Utils::endList("", position, result);
6718 
6719 	return result;
6720 }
6721 
6722 /** Prepare attributes, vertex array object and array buffer
6723  *
6724  * @param test_case_index   Index of test case
6725  * @param program_interface Interface of program
6726  * @param buffer            Array buffer
6727  * @param vao               Vertex array object
6728  **/
6729 void TextureTestBase::prepareAttributes(GLuint test_case_index, Utils::ProgramInterface& program_interface,
6730 										Utils::Buffer& buffer, Utils::VertexArray& vao)
6731 {
6732 	bool use_component_qualifier = useComponentQualifier(test_case_index);
6733 
6734 	/* Get shader interface */
6735 	Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
6736 
6737 	/* Bind vao and buffer */
6738 	vao.Bind();
6739 	buffer.Bind();
6740 
6741 	/* Skip if there are no input variables in vertex shader */
6742 	if (0 == si.m_inputs.size())
6743 	{
6744 		return;
6745 	}
6746 
6747 	const Functions& gl = m_context.getRenderContext().getFunctions();
6748 
6749 	/* Calculate vertex stride and check */
6750 	GLint max_inputs;
6751 	gl.getIntegerv(GL_MAX_VERTEX_ATTRIBS, &max_inputs);
6752 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
6753 
6754 	/* dvec3/4 vertex inputs use a single location but require 2x16B slots */
6755 	GLint max_slots = max_inputs * 2;
6756 
6757 	/* Compute used slots */
6758 	std::vector<GLint> slot_sizes;
6759 	slot_sizes.resize(max_slots);
6760 	std::fill(slot_sizes.begin(), slot_sizes.end(), 0);
6761 	for (GLuint i = 0; i < si.m_inputs.size(); ++i)
6762 	{
6763 		Utils::Variable& variable = *si.m_inputs[i];
6764 
6765 		GLint variable_size = static_cast<GLuint>(variable.m_data_size);
6766 
6767 		GLint base_slot = variable.m_descriptor.m_expected_location + variable.m_descriptor.m_offset / 16;
6768 		GLint ends_at = variable.m_descriptor.m_offset % 16 + variable_size;
6769 
6770 		GLint array_length = std::max(1u, variable.m_descriptor.m_n_array_elements);
6771 		for (GLint loc = 0; loc < array_length; loc++) {
6772 			GLint slot = base_slot + loc;
6773 			slot_sizes[slot] = std::max(slot_sizes[slot], ends_at);
6774 		}
6775 	}
6776 
6777 	/* Compute the offsets where we need to put vertex buffer data for each slot */
6778 	std::vector<GLint> slot_offsets;
6779 	slot_offsets.resize(max_slots);
6780 	std::fill(slot_offsets.begin(), slot_offsets.end(), -1);
6781 	GLint buffer_size = 0;
6782 	for (GLint i = 0; i < max_slots; i++)
6783 	{
6784 		if (slot_sizes[i] == 0)
6785 			continue;
6786 		slot_offsets[i] = buffer_size;
6787 		buffer_size += slot_sizes[i];
6788 	}
6789 
6790 	/* Prepare buffer data and set up vao */
6791 	std::vector<GLubyte> buffer_data;
6792 	buffer_data.resize(buffer_size);
6793 
6794 	GLubyte* ptr = &buffer_data[0];
6795 
6796 	for (GLuint i = 0; i < si.m_inputs.size(); ++i)
6797 	{
6798 		Utils::Variable& variable = *si.m_inputs[i];
6799 
6800 		GLint base_slot = variable.m_descriptor.m_expected_location + variable.m_descriptor.m_offset / 16;
6801 		GLint variable_offset = variable.m_descriptor.m_offset % 16;
6802 		GLint array_length = std::max(1u, variable.m_descriptor.m_n_array_elements);
6803 		for (GLint loc = 0; loc < array_length; loc++) {
6804 			GLint slot = base_slot + loc;
6805 			memcpy(ptr + slot_offsets[slot] + variable_offset, variable.m_data, variable.m_data_size);
6806 		}
6807 
6808 		if (false == use_component_qualifier)
6809 		{
6810 			vao.Attribute(variable.m_descriptor.m_expected_location, variable.m_descriptor.m_builtin,
6811 						  variable.m_descriptor.m_n_array_elements, variable.m_descriptor.m_normalized,
6812 						  variable.GetStride(), (GLvoid*)(intptr_t)(slot_offsets[base_slot] + variable_offset));
6813 		}
6814 		else if (0 == variable.m_descriptor.m_expected_component)
6815 		{
6816 			/* Components can only be applied to vectors.
6817 			 Assumption that test use all 4 components */
6818 			const Utils::Type& type =
6819 				Utils::Type::GetType(variable.m_descriptor.m_builtin.m_basic_type, 1 /* n_columns */, 4 /* n_rows */);
6820 
6821 			vao.Attribute(variable.m_descriptor.m_expected_location, type, variable.m_descriptor.m_n_array_elements,
6822 						  variable.m_descriptor.m_normalized, variable.GetStride(),
6823 						  (GLvoid*)(intptr_t)(slot_offsets[base_slot] + variable_offset));
6824 		}
6825 	}
6826 
6827 	/* Update buffer */
6828 	buffer.Data(Utils::Buffer::StaticDraw, buffer_size, ptr);
6829 }
6830 
6831 /** Get locations for all outputs with automatic_location
6832  *
6833  * @param program           Program object
6834  * @param program_interface Interface of program
6835  **/
6836 void TextureTestBase::prepareFragmentDataLoc(Utils::Program& program, Utils::ProgramInterface& program_interface)
6837 {
6838 	Utils::ShaderInterface&		si		= program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
6839 	Utils::Variable::PtrVector& outputs = si.m_outputs;
6840 
6841 	for (Utils::Variable::PtrVector::iterator it = outputs.begin(); outputs.end() != it; ++it)
6842 	{
6843 		/* Test does not specify location, query value and set */
6844 		if (Utils::Variable::m_automatic_location == (*it)->m_descriptor.m_expected_location)
6845 		{
6846 			GLuint index	= program.GetResourceIndex((*it)->m_descriptor.m_name, GL_PROGRAM_OUTPUT);
6847 			GLint  location = 0;
6848 
6849 			program.GetResource(GL_PROGRAM_OUTPUT, index, GL_LOCATION, 1 /* size */, &location);
6850 
6851 			(*it)->m_descriptor.m_expected_location = location;
6852 		}
6853 	}
6854 }
6855 
6856 /** Prepare framebuffer with single texture as color attachment
6857  *
6858  * @param framebuffer     Framebuffer
6859  * @param color_0_texture Texture that will used as color attachment
6860  **/
6861 void TextureTestBase::prepareFramebuffer(Utils::Framebuffer& framebuffer, Utils::Texture& color_0_texture)
6862 {
6863 	/* Prepare data */
6864 	std::vector<GLuint> texture_data;
6865 	texture_data.resize(m_width * m_height);
6866 
6867 	for (GLuint i = 0; i < texture_data.size(); ++i)
6868 	{
6869 		texture_data[i] = 0x20406080;
6870 	}
6871 
6872 	/* Prepare texture */
6873 	color_0_texture.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT,
6874 						 &texture_data[0]);
6875 
6876 	/* Prepare framebuffer */
6877 	framebuffer.Init();
6878 	framebuffer.Bind();
6879 	framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0, color_0_texture.m_id, m_width, m_height);
6880 
6881 	framebuffer.ClearColor(0.0f, 0.0f, 0.0f, 0.0f);
6882 	framebuffer.Clear(GL_COLOR_BUFFER_BIT);
6883 }
6884 
6885 /** Prepare iamge unit for compute shader
6886  *
6887  * @param location      Uniform location
6888  * @param image_texture Texture that will used as color attachment
6889  **/
6890 void TextureTestBase::prepareImage(GLint location, Utils::Texture& image_texture) const
6891 {
6892 	static const GLuint image_unit = 0;
6893 
6894 	std::vector<GLuint> texture_data;
6895 	texture_data.resize(m_width * m_height);
6896 
6897 	for (GLuint i = 0; i < texture_data.size(); ++i)
6898 	{
6899 		texture_data[i] = 0x20406080;
6900 	}
6901 
6902 	image_texture.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT,
6903 					   &texture_data[0]);
6904 
6905 	const Functions& gl = m_context.getRenderContext().getFunctions();
6906 
6907 	gl.bindImageTexture(image_unit, image_texture.m_id, 0 /* level */, GL_FALSE /* layered */, 0 /* Layer */,
6908 						GL_WRITE_ONLY, GL_R32UI);
6909 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindImageTexture");
6910 
6911 	Utils::Program::Uniform(gl, Utils::Type::_int, 1 /* count */, location, &image_unit);
6912 }
6913 
6914 /** Basic implementation
6915  *
6916  * @param ignored
6917  * @param si        Shader interface
6918  * @param program   Program
6919  * @param cs_buffer Buffer for ssb blocks
6920  **/
6921 void TextureTestBase::prepareSSBs(GLuint /* test_case_index */, Utils::ShaderInterface& si, Utils::Program& program,
6922 								  Utils::Buffer& buffer)
6923 {
6924 	/* Skip if there are no input variables in vertex shader */
6925 	if (0 == si.m_ssb_blocks.size())
6926 	{
6927 		return;
6928 	}
6929 
6930 	/* Calculate vertex stride */
6931 	GLint ssbs_stride = 0;
6932 
6933 	for (GLuint i = 0; i < si.m_ssb_blocks.size(); ++i)
6934 	{
6935 		Utils::Variable& variable = *si.m_ssb_blocks[i];
6936 
6937 		if (false == variable.IsBlock())
6938 		{
6939 			continue;
6940 		}
6941 
6942 		GLint variable_stride = variable.GetStride();
6943 
6944 		GLint ends_at = variable_stride + variable.m_descriptor.m_offset;
6945 
6946 		ssbs_stride = std::max(ssbs_stride, ends_at);
6947 	}
6948 
6949 	/* Set active program */
6950 	program.Use();
6951 
6952 	/* Allocate */
6953 	buffer.Bind();
6954 	buffer.Data(Utils::Buffer::StaticDraw, ssbs_stride, 0);
6955 
6956 	/* Set up uniforms */
6957 	for (GLuint i = 0; i < si.m_ssb_blocks.size(); ++i)
6958 	{
6959 		Utils::Variable& variable = *si.m_ssb_blocks[i];
6960 
6961 		/* prepareUnifor should work fine for ssb blocks */
6962 		prepareUniform(program, variable, buffer);
6963 	}
6964 }
6965 
6966 /** Basic implementation
6967  *
6968  * @param test_case_index   Test case index
6969  * @param program_interface Program interface
6970  * @param program           Program
6971  * @param cs_buffer         Buffer for compute shader stage
6972  **/
6973 void TextureTestBase::prepareSSBs(GLuint test_case_index, Utils::ProgramInterface& program_interface,
6974 								  Utils::Program& program, Utils::Buffer& cs_buffer)
6975 {
6976 	cs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
6977 
6978 	Utils::ShaderInterface& cs = program_interface.GetShaderInterface(Utils::Shader::COMPUTE);
6979 
6980 	prepareSSBs(test_case_index, cs, program, cs_buffer);
6981 
6982 	cs_buffer.BindBase(Utils::Shader::COMPUTE);
6983 }
6984 
6985 /** Basic implementation
6986  *
6987  * @param test_case_index   Test case index
6988  * @param program_interface Program interface
6989  * @param program           Program
6990  * @param fs_buffer         Buffer for fragment shader stage
6991  * @param gs_buffer         Buffer for geometry shader stage
6992  * @param tcs_buffer        Buffer for tessellation control shader stage
6993  * @param tes_buffer        Buffer for tessellation evaluation shader stage
6994  * @param vs_buffer         Buffer for vertex shader stage
6995  **/
6996 void TextureTestBase::prepareSSBs(GLuint test_case_index, Utils::ProgramInterface& program_interface,
6997 								  Utils::Program& program, Utils::Buffer& fs_buffer, Utils::Buffer& gs_buffer,
6998 								  Utils::Buffer& tcs_buffer, Utils::Buffer& tes_buffer, Utils::Buffer& vs_buffer)
6999 {
7000 	fs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
7001 	gs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
7002 	tcs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
7003 	tes_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
7004 	vs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
7005 
7006 	Utils::ShaderInterface& fs  = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
7007 	Utils::ShaderInterface& gs  = program_interface.GetShaderInterface(Utils::Shader::GEOMETRY);
7008 	Utils::ShaderInterface& tcs = program_interface.GetShaderInterface(Utils::Shader::TESS_CTRL);
7009 	Utils::ShaderInterface& tes = program_interface.GetShaderInterface(Utils::Shader::TESS_EVAL);
7010 	Utils::ShaderInterface& vs  = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
7011 
7012 	prepareSSBs(test_case_index, fs, program, fs_buffer);
7013 	prepareSSBs(test_case_index, gs, program, gs_buffer);
7014 	prepareSSBs(test_case_index, tcs, program, tcs_buffer);
7015 	prepareSSBs(test_case_index, tes, program, tes_buffer);
7016 	prepareSSBs(test_case_index, vs, program, vs_buffer);
7017 
7018 	fs_buffer.BindBase(Utils::Shader::FRAGMENT);
7019 	gs_buffer.BindBase(Utils::Shader::GEOMETRY);
7020 	tcs_buffer.BindBase(Utils::Shader::TESS_CTRL);
7021 	tes_buffer.BindBase(Utils::Shader::TESS_EVAL);
7022 	vs_buffer.BindBase(Utils::Shader::VERTEX);
7023 }
7024 
7025 /** Updates buffer data with variable
7026  *
7027  * @param program  Program object
7028  * @param variable Variable
7029  * @param buffer   Buffer
7030  **/
7031 void TextureTestBase::prepareUniform(Utils::Program& program, Utils::Variable& variable, Utils::Buffer& buffer)
7032 {
7033 	const Functions& gl = m_context.getRenderContext().getFunctions();
7034 
7035 	GLsizei count = variable.m_descriptor.m_n_array_elements;
7036 	if (0 == count)
7037 	{
7038 		count = 1;
7039 	}
7040 
7041 	if (Utils::Variable::BUILTIN == variable.m_descriptor.m_type)
7042 	{
7043 		program.Uniform(gl, variable.m_descriptor.m_builtin, count, variable.m_descriptor.m_expected_location,
7044 						variable.m_data);
7045 	}
7046 	else
7047 	{
7048 		const bool is_block = variable.IsBlock();
7049 
7050 		if (false == is_block)
7051 		{
7052 			TCU_FAIL("Not implemented");
7053 		}
7054 		else
7055 		{
7056 			buffer.SubData(variable.m_descriptor.m_offset, variable.m_descriptor.m_expected_stride_of_element * count,
7057 						   variable.m_data);
7058 		}
7059 	}
7060 }
7061 
7062 /** Basic implementation
7063  *
7064  * @param ignored
7065  * @param si        Shader interface
7066  * @param program   Program
7067  * @param cs_buffer Buffer for uniform blocks
7068  **/
7069 void TextureTestBase::prepareUniforms(GLuint /* test_case_index */, Utils::ShaderInterface& si, Utils::Program& program,
7070 									  Utils::Buffer& buffer)
7071 {
7072 	/* Skip if there are no input variables in vertex shader */
7073 	if (0 == si.m_uniforms.size())
7074 	{
7075 		return;
7076 	}
7077 
7078 	/* Calculate vertex stride */
7079 	GLint uniforms_stride = 0;
7080 
7081 	for (GLuint i = 0; i < si.m_uniforms.size(); ++i)
7082 	{
7083 		Utils::Variable& variable = *si.m_uniforms[i];
7084 
7085 		if (false == variable.IsBlock())
7086 		{
7087 			continue;
7088 		}
7089 
7090 		GLint variable_stride = variable.GetStride();
7091 
7092 		GLint ends_at = variable_stride + variable.m_descriptor.m_offset;
7093 
7094 		uniforms_stride = std::max(uniforms_stride, ends_at);
7095 	}
7096 
7097 	/* Set active program */
7098 	program.Use();
7099 
7100 	/* Allocate */
7101 	buffer.Bind();
7102 	buffer.Data(Utils::Buffer::StaticDraw, uniforms_stride, 0);
7103 
7104 	/* Set up uniforms */
7105 	for (GLuint i = 0; i < si.m_uniforms.size(); ++i)
7106 	{
7107 		Utils::Variable& variable = *si.m_uniforms[i];
7108 
7109 		prepareUniform(program, variable, buffer);
7110 	}
7111 }
7112 
7113 /** Basic implementation
7114  *
7115  * @param test_case_index   Test case index
7116  * @param program_interface Program interface
7117  * @param program           Program
7118  * @param cs_buffer         Buffer for compute shader stage
7119  **/
7120 void TextureTestBase::prepareUniforms(GLuint test_case_index, Utils::ProgramInterface& program_interface,
7121 									  Utils::Program& program, Utils::Buffer& cs_buffer)
7122 {
7123 	cs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7124 
7125 	Utils::ShaderInterface& cs = program_interface.GetShaderInterface(Utils::Shader::COMPUTE);
7126 
7127 	prepareUniforms(test_case_index, cs, program, cs_buffer);
7128 
7129 	cs_buffer.BindBase(Utils::Shader::COMPUTE);
7130 }
7131 
7132 /** Basic implementation
7133  *
7134  * @param test_case_index   Test case index
7135  * @param program_interface Program interface
7136  * @param program           Program
7137  * @param fs_buffer         Buffer for fragment shader stage
7138  * @param gs_buffer         Buffer for geometry shader stage
7139  * @param tcs_buffer        Buffer for tessellation control shader stage
7140  * @param tes_buffer        Buffer for tessellation evaluation shader stage
7141  * @param vs_buffer         Buffer for vertex shader stage
7142  **/
7143 void TextureTestBase::prepareUniforms(GLuint test_case_index, Utils::ProgramInterface& program_interface,
7144 									  Utils::Program& program, Utils::Buffer& fs_buffer, Utils::Buffer& gs_buffer,
7145 									  Utils::Buffer& tcs_buffer, Utils::Buffer& tes_buffer, Utils::Buffer& vs_buffer)
7146 {
7147 	fs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7148 	gs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7149 	tcs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7150 	tes_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7151 	vs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7152 
7153 	Utils::ShaderInterface& fs  = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
7154 	Utils::ShaderInterface& gs  = program_interface.GetShaderInterface(Utils::Shader::GEOMETRY);
7155 	Utils::ShaderInterface& tcs = program_interface.GetShaderInterface(Utils::Shader::TESS_CTRL);
7156 	Utils::ShaderInterface& tes = program_interface.GetShaderInterface(Utils::Shader::TESS_EVAL);
7157 	Utils::ShaderInterface& vs  = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
7158 
7159 	prepareUniforms(test_case_index, fs, program, fs_buffer);
7160 	prepareUniforms(test_case_index, gs, program, gs_buffer);
7161 	prepareUniforms(test_case_index, tcs, program, tcs_buffer);
7162 	prepareUniforms(test_case_index, tes, program, tes_buffer);
7163 	prepareUniforms(test_case_index, vs, program, vs_buffer);
7164 
7165 	fs_buffer.BindBase(Utils::Shader::FRAGMENT);
7166 	gs_buffer.BindBase(Utils::Shader::GEOMETRY);
7167 	tcs_buffer.BindBase(Utils::Shader::TESS_CTRL);
7168 	tes_buffer.BindBase(Utils::Shader::TESS_EVAL);
7169 	vs_buffer.BindBase(Utils::Shader::VERTEX);
7170 }
7171 
7172 /** Basic implementation
7173  *
7174  * @param test_case_index   Test case index
7175  * @param program_interface Program interface
7176  * @param program           Program
7177  * @param fs_buffer         Buffer for fragment shader stage
7178  * @param gs_buffer         Buffer for geometry shader stage
7179  * @param tcs_buffer        Buffer for tessellation control shader stage
7180  * @param tes_buffer        Buffer for tessellation evaluation shader stage
7181  * @param vs_buffer         Buffer for vertex shader stage
7182  **/
7183 void TextureTestBase::prepareUniforms(GLuint test_case_index, Utils::ProgramInterface& program_interface,
7184 									  Utils::Program& fs_program, Utils::Program& gs_program,
7185 									  Utils::Program& tcs_program, Utils::Program& tes_program,
7186 									  Utils::Program& vs_program, Utils::Buffer& fs_buffer, Utils::Buffer& gs_buffer,
7187 									  Utils::Buffer& tcs_buffer, Utils::Buffer& tes_buffer, Utils::Buffer& vs_buffer)
7188 {
7189 	fs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7190 	gs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7191 	tcs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7192 	tes_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7193 	vs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7194 
7195 	Utils::ShaderInterface& fs  = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
7196 	Utils::ShaderInterface& gs  = program_interface.GetShaderInterface(Utils::Shader::GEOMETRY);
7197 	Utils::ShaderInterface& tcs = program_interface.GetShaderInterface(Utils::Shader::TESS_CTRL);
7198 	Utils::ShaderInterface& tes = program_interface.GetShaderInterface(Utils::Shader::TESS_EVAL);
7199 	Utils::ShaderInterface& vs  = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
7200 
7201 	prepareUniforms(test_case_index, fs, fs_program, fs_buffer);
7202 	fs_buffer.BindBase(Utils::Shader::FRAGMENT);
7203 
7204 	prepareUniforms(test_case_index, gs, gs_program, gs_buffer);
7205 	gs_buffer.BindBase(Utils::Shader::GEOMETRY);
7206 
7207 	prepareUniforms(test_case_index, tcs, tcs_program, tcs_buffer);
7208 	tcs_buffer.BindBase(Utils::Shader::TESS_CTRL);
7209 
7210 	prepareUniforms(test_case_index, tes, tes_program, tes_buffer);
7211 	tes_buffer.BindBase(Utils::Shader::TESS_EVAL);
7212 
7213 	prepareUniforms(test_case_index, vs, vs_program, vs_buffer);
7214 	vs_buffer.BindBase(Utils::Shader::VERTEX);
7215 }
7216 
7217 /** Prepare source for shader
7218  *
7219  * @param test_case_index     Index of test case
7220  * @param program_interface   Interface of program
7221  * @param varying_passthrough Collection of connection between in and out variables
7222  * @param stage               Shader stage
7223  *
7224  * @return Source of shader
7225  **/
7226 std::string TextureTestBase::getShaderSource(GLuint test_case_index, Utils::ProgramInterface& program_interface,
7227 											 Utils::VaryingPassthrough& varying_passthrough,
7228 											 Utils::Shader::STAGES		stage)
7229 {
7230 	/* Get strings */
7231 	const GLchar*	  shader_template  = getShaderTemplate(stage);
7232 	const std::string& shader_interface = program_interface.GetInterfaceForStage(stage);
7233 
7234 	const std::string& verification = getVerificationSnippet(test_case_index, program_interface, stage);
7235 
7236 	const std::string& passthrough = getPassSnippet(test_case_index, varying_passthrough, stage);
7237 
7238 	const GLchar* per_vertex = "";
7239 
7240 	std::string source   = shader_template;
7241 	size_t		position = 0;
7242 
7243 	/* Replace tokens in template */
7244 	if (Utils::Shader::GEOMETRY == stage)
7245 	{
7246 		if (false == useMonolithicProgram(test_case_index))
7247 		{
7248 			per_vertex = "out gl_PerVertex {\n"
7249 						 "vec4 gl_Position;\n"
7250 						 "};\n"
7251 						 "\n";
7252 		}
7253 
7254 		Utils::replaceToken("PERVERTEX", position, per_vertex, source);
7255 	}
7256 
7257 	Utils::replaceToken("INTERFACE", position, shader_interface.c_str(), source);
7258 	Utils::replaceToken("VERIFICATION", position, verification.c_str(), source);
7259 
7260 	if (false == verification.empty())
7261 	{
7262 		Utils::replaceAllTokens("ELSE", "    else ", source);
7263 	}
7264 	else
7265 	{
7266 		Utils::replaceAllTokens("ELSE", "", source);
7267 	}
7268 
7269 	Utils::replaceAllTokens("PASSTHROUGH", passthrough.c_str(), source);
7270 
7271 	/* Done */
7272 	return source;
7273 }
7274 
7275 /** Returns template of shader for given stage
7276  *
7277  * @param stage Shade stage
7278  *
7279  * @return Proper template
7280  **/
7281 const GLchar* TextureTestBase::getShaderTemplate(Utils::Shader::STAGES stage)
7282 {
7283 
7284 	static const GLchar* compute_shader_template =
7285 		"#version 430 core\n"
7286 		"#extension GL_ARB_enhanced_layouts : require\n"
7287 		"\n"
7288 		"layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
7289 		"\n"
7290 		"writeonly uniform uimage2D uni_image;\n"
7291 		"\n"
7292 		"INTERFACE"
7293 		"\n"
7294 		"void main()\n"
7295 		"{\n"
7296 		"    uint result = 1u;\n"
7297 		"\n"
7298 		"    VERIFICATION"
7299 		"\n"
7300 		"    imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), uvec4(result, 0, 0, 0));\n"
7301 		"}\n"
7302 		"\n";
7303 
7304 	static const GLchar* fragment_shader_template = "#version 430 core\n"
7305 													"#extension GL_ARB_enhanced_layouts : require\n"
7306 													"\n"
7307 													"flat in  uint gs_fs_result;\n"
7308 													"     out uint fs_out_result;\n"
7309 													"\n"
7310 													"INTERFACE"
7311 													"\n"
7312 													"void main()\n"
7313 													"{\n"
7314 													"    uint result = 1u;\n"
7315 													"\n"
7316 													"    if (1u != gs_fs_result)\n"
7317 													"    {\n"
7318 													"         result = gs_fs_result;\n"
7319 													"    }\n"
7320 													"ELSEVERIFICATION"
7321 													"\n"
7322 													"    fs_out_result = result;\n"
7323 													"    PASSTHROUGH\n"
7324 													"}\n"
7325 													"\n";
7326 
7327 	static const GLchar* geometry_shader_template =
7328 		"#version 430 core\n"
7329 		"#extension GL_ARB_enhanced_layouts : require\n"
7330 		"\n"
7331 		"layout(points)                           in;\n"
7332 		"layout(triangle_strip, max_vertices = 4) out;\n"
7333 		"\n"
7334 		"     in  uint tes_gs_result[];\n"
7335 		"flat out uint gs_fs_result;\n"
7336 		"\n"
7337 		"PERVERTEX" /* Separable programs require explicit declaration of gl_PerVertex */
7338 		"INTERFACE"
7339 		"\n"
7340 		"void main()\n"
7341 		"{\n"
7342 		"    uint result = 1u;\n"
7343 		"\n"
7344 		"    if (1u != tes_gs_result[0])\n"
7345 		"    {\n"
7346 		"         result = tes_gs_result[0];\n"
7347 		"    }\n"
7348 		"ELSEVERIFICATION"
7349 		"\n"
7350 		"    gs_fs_result = result;\n"
7351 		"    PASSTHROUGH\n"
7352 		"    gl_Position  = vec4(-1, -1, 0, 1);\n"
7353 		"    EmitVertex();\n"
7354 		"    gs_fs_result = result;\n"
7355 		"    PASSTHROUGH\n"
7356 		"    gl_Position  = vec4(-1, 1, 0, 1);\n"
7357 		"    EmitVertex();\n"
7358 		"    gs_fs_result = result;\n"
7359 		"    PASSTHROUGH\n"
7360 		"    gl_Position  = vec4(1, -1, 0, 1);\n"
7361 		"    EmitVertex();\n"
7362 		"    gs_fs_result = result;\n"
7363 		"    PASSTHROUGH\n"
7364 		"    gl_Position  = vec4(1, 1, 0, 1);\n"
7365 		"    EmitVertex();\n"
7366 		"}\n"
7367 		"\n";
7368 
7369 	static const GLchar* tess_ctrl_shader_template = "#version 430 core\n"
7370 													 "#extension GL_ARB_enhanced_layouts : require\n"
7371 													 "\n"
7372 													 "layout(vertices = 1) out;\n"
7373 													 "\n"
7374 													 "in  uint vs_tcs_result[];\n"
7375 													 "out uint tcs_tes_result[];\n"
7376 													 "\n"
7377 													 "INTERFACE"
7378 													 "\n"
7379 													 "void main()\n"
7380 													 "{\n"
7381 													 "    uint result = 1u;\n"
7382 													 "\n"
7383 													 "    if (1u != vs_tcs_result[gl_InvocationID])\n"
7384 													 "    {\n"
7385 													 "         result = vs_tcs_result[gl_InvocationID];\n"
7386 													 "    }\n"
7387 													 "ELSEVERIFICATION"
7388 													 "\n"
7389 													 "    tcs_tes_result[gl_InvocationID] = result;\n"
7390 													 "\n"
7391 													 "    PASSTHROUGH\n"
7392 													 "\n"
7393 													 "    gl_TessLevelOuter[0] = 1.0;\n"
7394 													 "    gl_TessLevelOuter[1] = 1.0;\n"
7395 													 "    gl_TessLevelOuter[2] = 1.0;\n"
7396 													 "    gl_TessLevelOuter[3] = 1.0;\n"
7397 													 "    gl_TessLevelInner[0] = 1.0;\n"
7398 													 "    gl_TessLevelInner[1] = 1.0;\n"
7399 													 "}\n"
7400 													 "\n";
7401 
7402 	static const GLchar* tess_eval_shader_template = "#version 430 core\n"
7403 													 "#extension GL_ARB_enhanced_layouts : require\n"
7404 													 "\n"
7405 													 "layout(isolines, point_mode) in;\n"
7406 													 "\n"
7407 													 "in  uint tcs_tes_result[];\n"
7408 													 "out uint tes_gs_result;\n"
7409 													 "\n"
7410 													 "INTERFACE"
7411 													 "\n"
7412 													 "void main()\n"
7413 													 "{\n"
7414 													 "    uint result = 1u;\n"
7415 													 "\n"
7416 													 "    if (1 != tcs_tes_result[0])\n"
7417 													 "    {\n"
7418 													 "         result = tcs_tes_result[0];\n"
7419 													 "    }\n"
7420 													 "ELSEVERIFICATION"
7421 													 "\n"
7422 													 "    tes_gs_result = result;\n"
7423 													 "\n"
7424 													 "    PASSTHROUGH\n"
7425 													 "}\n"
7426 													 "\n";
7427 
7428 	static const GLchar* vertex_shader_template = "#version 430 core\n"
7429 												  "#extension GL_ARB_enhanced_layouts : require\n"
7430 												  "\n"
7431 												  "out uint vs_tcs_result;\n"
7432 												  "\n"
7433 												  "INTERFACE"
7434 												  "\n"
7435 												  "void main()\n"
7436 												  "{\n"
7437 												  "    uint result = 1u;\n"
7438 												  "\n"
7439 												  "    VERIFICATION\n"
7440 												  "\n"
7441 												  "    vs_tcs_result = result;\n"
7442 												  "\n"
7443 												  "    PASSTHROUGH\n"
7444 												  "}\n"
7445 												  "\n";
7446 
7447 	const GLchar* result = 0;
7448 
7449 	switch (stage)
7450 	{
7451 	case Utils::Shader::COMPUTE:
7452 		result = compute_shader_template;
7453 		break;
7454 	case Utils::Shader::FRAGMENT:
7455 		result = fragment_shader_template;
7456 		break;
7457 	case Utils::Shader::GEOMETRY:
7458 		result = geometry_shader_template;
7459 		break;
7460 	case Utils::Shader::TESS_CTRL:
7461 		result = tess_ctrl_shader_template;
7462 		break;
7463 	case Utils::Shader::TESS_EVAL:
7464 		result = tess_eval_shader_template;
7465 		break;
7466 	case Utils::Shader::VERTEX:
7467 		result = vertex_shader_template;
7468 		break;
7469 	default:
7470 		TCU_FAIL("Invalid enum");
7471 	}
7472 
7473 	return result;
7474 }
7475 
7476 /** Runs test case
7477  *
7478  * @param test_case_index Id of test case
7479  *
7480  * @return true if test case pass, false otherwise
7481  **/
7482 bool TextureTestBase::testCase(GLuint test_case_index)
7483 {
7484 	try
7485 	{
7486 		if (true == useMonolithicProgram(test_case_index))
7487 		{
7488 			return testMonolithic(test_case_index);
7489 		}
7490 		else
7491 		{
7492 			return testSeparable(test_case_index);
7493 		}
7494 	}
7495 	catch (Utils::Shader::InvalidSourceException& exc)
7496 	{
7497 		exc.log(m_context);
7498 		TCU_FAIL(exc.what());
7499 	}
7500 	catch (Utils::Program::BuildException& exc)
7501 	{
7502 		TCU_FAIL(exc.what());
7503 	}
7504 }
7505 
7506 /** Runs "draw" test with monolithic program
7507  *
7508  * @param test_case_index Id of test case
7509  **/
7510 bool TextureTestBase::testMonolithic(GLuint test_case_index)
7511 {
7512 	Utils::ProgramInterface   program_interface;
7513 	Utils::VaryingPassthrough varying_passthrough;
7514 
7515 	/* */
7516 	const std::string& test_name = getTestCaseName(test_case_index);
7517 
7518 	/* */
7519 	getProgramInterface(test_case_index, program_interface, varying_passthrough);
7520 
7521 	bool result = true;
7522 	/* Draw */
7523 	if (true == isDrawRelevant(test_case_index))
7524 	{
7525 		Utils::Buffer	  buffer_attr(m_context);
7526 		Utils::Buffer	  buffer_ssb_fs(m_context);
7527 		Utils::Buffer	  buffer_ssb_gs(m_context);
7528 		Utils::Buffer	  buffer_ssb_tcs(m_context);
7529 		Utils::Buffer	  buffer_ssb_tes(m_context);
7530 		Utils::Buffer	  buffer_ssb_vs(m_context);
7531 		Utils::Buffer	  buffer_u_fs(m_context);
7532 		Utils::Buffer	  buffer_u_gs(m_context);
7533 		Utils::Buffer	  buffer_u_tcs(m_context);
7534 		Utils::Buffer	  buffer_u_tes(m_context);
7535 		Utils::Buffer	  buffer_u_vs(m_context);
7536 		Utils::Framebuffer framebuffer(m_context);
7537 		Utils::Program	 program(m_context);
7538 		Utils::Texture	 texture_fb(m_context);
7539 		Utils::VertexArray vao(m_context);
7540 
7541 		/* */
7542 		const std::string& fragment_shader =
7543 			getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::FRAGMENT);
7544 		const std::string& geometry_shader =
7545 			getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::GEOMETRY);
7546 		const std::string& tess_ctrl_shader =
7547 			getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::TESS_CTRL);
7548 		const std::string& tess_eval_shader =
7549 			getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::TESS_EVAL);
7550 		const std::string& vertex_shader =
7551 			getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::VERTEX);
7552 
7553 		program.Init("" /* compute_shader */, fragment_shader, geometry_shader, tess_ctrl_shader, tess_eval_shader,
7554 					 vertex_shader, false /* is_separable */);
7555 
7556 		/* */
7557 		prepareAttribLocation(program, program_interface);
7558 		prepareFragmentDataLoc(program, program_interface);
7559 
7560 		/* */
7561 		std::stringstream stream;
7562 		if (false == Utils::checkMonolithicDrawProgramInterface(program, program_interface, stream))
7563 		{
7564 			m_context.getTestContext().getLog()
7565 				<< tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7566 				<< ". Inspection of draw program interface failed:\n"
7567 				<< stream.str() << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(vertex_shader)
7568 				<< tcu::TestLog::KernelSource(tess_ctrl_shader) << tcu::TestLog::KernelSource(tess_eval_shader)
7569 				<< tcu::TestLog::KernelSource(geometry_shader) << tcu::TestLog::KernelSource(fragment_shader);
7570 
7571 			return false;
7572 		}
7573 
7574 		/* */
7575 		program.Use();
7576 
7577 		/* */
7578 		buffer_attr.Init(Utils::Buffer::Array, Utils::Buffer::StaticDraw, 0, 0);
7579 		vao.Init();
7580 		prepareAttributes(test_case_index, program_interface, buffer_attr, vao);
7581 
7582 		/* */
7583 		prepareUniforms(test_case_index, program_interface, program, buffer_u_fs, buffer_u_gs, buffer_u_tcs,
7584 						buffer_u_tes, buffer_u_vs);
7585 
7586 		prepareSSBs(test_case_index, program_interface, program, buffer_ssb_fs, buffer_ssb_gs, buffer_ssb_tcs,
7587 					buffer_ssb_tes, buffer_ssb_vs);
7588 
7589 		/* */
7590 		prepareFramebuffer(framebuffer, texture_fb);
7591 
7592 		/* Draw */
7593 		executeDrawCall(test_case_index);
7594 
7595 #if USE_NSIGHT
7596 		m_context.getRenderContext().postIterate();
7597 #endif
7598 
7599 		/* Check results */
7600 		if (false == checkResults(test_case_index, texture_fb))
7601 		{
7602 			m_context.getTestContext().getLog()
7603 				<< tcu::TestLog::Message << "FAILURE. Test case: " << test_name << ". Draw - invalid results."
7604 				<< tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(vertex_shader)
7605 				<< tcu::TestLog::KernelSource(tess_ctrl_shader) << tcu::TestLog::KernelSource(tess_eval_shader)
7606 				<< tcu::TestLog::KernelSource(geometry_shader) << tcu::TestLog::KernelSource(fragment_shader);
7607 
7608 			result = false;
7609 		}
7610 	}
7611 
7612 	/* Compute */
7613 	if (true == isComputeRelevant(test_case_index))
7614 	{
7615 		Utils::Buffer	  buffer_ssb_cs(m_context);
7616 		Utils::Buffer	  buffer_u_cs(m_context);
7617 		Utils::Program	 program(m_context);
7618 		Utils::Texture	 texture_im(m_context);
7619 		Utils::VertexArray vao(m_context);
7620 
7621 		/* */
7622 		const std::string& compute_shader =
7623 			getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::COMPUTE);
7624 
7625 		program.Init(compute_shader, "" /* fragment_shader */, "" /* geometry_shader */, "" /* tess_ctrl_shader */,
7626 					 "" /* tess_eval_shader */, "" /* vertex_shader */, false /* is_separable */);
7627 
7628 		/* */
7629 		{
7630 			std::stringstream stream;
7631 
7632 			if (false == Utils::checkMonolithicComputeProgramInterface(program, program_interface, stream))
7633 			{
7634 				m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7635 													<< ". Inspection of compute program interface failed:\n"
7636 													<< stream.str() << tcu::TestLog::EndMessage;
7637 
7638 				return false;
7639 			}
7640 		}
7641 
7642 		/* */
7643 		program.Use();
7644 
7645 		/* */
7646 		vao.Init();
7647 		vao.Bind();
7648 
7649 		/* */
7650 		prepareUniforms(test_case_index, program_interface, program, buffer_u_cs);
7651 
7652 		prepareSSBs(test_case_index, program_interface, program, buffer_ssb_cs);
7653 
7654 		/* */
7655 		GLint image_location = program.GetUniformLocation("uni_image");
7656 		prepareImage(image_location, texture_im);
7657 
7658 		/* Draw */
7659 		executeDispatchCall(test_case_index);
7660 
7661 #if USE_NSIGHT
7662 		m_context.getRenderContext().postIterate();
7663 #endif
7664 
7665 		/* Check results */
7666 		if (false == checkResults(test_case_index, texture_im))
7667 		{
7668 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7669 												<< ". Compute - invalid results." << tcu::TestLog::EndMessage
7670 												<< tcu::TestLog::KernelSource(compute_shader);
7671 
7672 			result = false;
7673 		}
7674 	}
7675 
7676 	return result;
7677 }
7678 
7679 /** Runs "draw" test with separable program
7680  *
7681  * @param test_case_index Id of test case
7682  **/
7683 bool TextureTestBase::testSeparable(GLuint test_case_index)
7684 {
7685 	Utils::ProgramInterface   program_interface;
7686 	Utils::VaryingPassthrough varying_passthrough;
7687 
7688 	/* */
7689 	const std::string& test_name = getTestCaseName(test_case_index);
7690 
7691 	/* */
7692 	getProgramInterface(test_case_index, program_interface, varying_passthrough);
7693 
7694 	bool result = true;
7695 	/* Draw */
7696 	if (true == isDrawRelevant(test_case_index))
7697 	{
7698 		Utils::Buffer	  buffer_attr(m_context);
7699 		Utils::Buffer	  buffer_u_fs(m_context);
7700 		Utils::Buffer	  buffer_u_gs(m_context);
7701 		Utils::Buffer	  buffer_u_tcs(m_context);
7702 		Utils::Buffer	  buffer_u_tes(m_context);
7703 		Utils::Buffer	  buffer_u_vs(m_context);
7704 		Utils::Framebuffer framebuffer(m_context);
7705 		Utils::Pipeline	pipeline(m_context);
7706 		Utils::Program	 program_fs(m_context);
7707 		Utils::Program	 program_gs(m_context);
7708 		Utils::Program	 program_tcs(m_context);
7709 		Utils::Program	 program_tes(m_context);
7710 		Utils::Program	 program_vs(m_context);
7711 		Utils::Texture	 texture_fb(m_context);
7712 		Utils::VertexArray vao(m_context);
7713 
7714 		/* */
7715 		const std::string& fs =
7716 			getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::FRAGMENT);
7717 		const std::string& gs =
7718 			getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::GEOMETRY);
7719 		const std::string& tcs =
7720 			getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::TESS_CTRL);
7721 		const std::string& tes =
7722 			getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::TESS_EVAL);
7723 		const std::string& vs =
7724 			getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::VERTEX);
7725 
7726 		program_fs.Init("" /*cs*/, fs, "" /*gs*/, "" /*tcs*/, "" /*tes*/, "" /*vs*/, true /* is_separable */);
7727 		program_gs.Init("" /*cs*/, "" /*fs*/, gs, "" /*tcs*/, "" /*tes*/, "" /*vs*/, true /* is_separable */);
7728 		program_tcs.Init("" /*cs*/, "" /*fs*/, "" /*gs*/, tcs, "" /*tes*/, "" /*vs*/, true /* is_separable */);
7729 		program_tes.Init("" /*cs*/, "" /*fs*/, "" /*gs*/, "" /*tcs*/, tes, "" /*vs*/, true /* is_separable */);
7730 		program_vs.Init("" /*cs*/, "" /*fs*/, "" /*gs*/, "" /*tcs*/, "" /*tes*/, vs, true /* is_separable */);
7731 
7732 		/* */
7733 		prepareAttribLocation(program_vs, program_interface);
7734 		prepareFragmentDataLoc(program_vs, program_interface);
7735 
7736 		/* */
7737 		std::stringstream stream;
7738 		if ((false ==
7739 			 Utils::checkSeparableDrawProgramInterface(program_vs, program_interface, Utils::Shader::VERTEX, stream)) ||
7740 			(false == Utils::checkSeparableDrawProgramInterface(program_fs, program_interface, Utils::Shader::FRAGMENT,
7741 																stream)) ||
7742 			(false == Utils::checkSeparableDrawProgramInterface(program_gs, program_interface, Utils::Shader::GEOMETRY,
7743 																stream)) ||
7744 			(false == Utils::checkSeparableDrawProgramInterface(program_tcs, program_interface,
7745 																Utils::Shader::TESS_CTRL, stream)) ||
7746 			(false == Utils::checkSeparableDrawProgramInterface(program_tes, program_interface,
7747 																Utils::Shader::TESS_EVAL, stream)))
7748 		{
7749 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7750 												<< ". Inspection of separable draw program interface failed:\n"
7751 												<< stream.str() << tcu::TestLog::EndMessage
7752 												<< tcu::TestLog::KernelSource(vs) << tcu::TestLog::KernelSource(tcs)
7753 												<< tcu::TestLog::KernelSource(tes) << tcu::TestLog::KernelSource(gs)
7754 												<< tcu::TestLog::KernelSource(fs);
7755 
7756 			return false;
7757 		}
7758 
7759 		/* */
7760 		pipeline.Init();
7761 		pipeline.UseProgramStages(program_fs.m_id, GL_FRAGMENT_SHADER_BIT);
7762 		pipeline.UseProgramStages(program_gs.m_id, GL_GEOMETRY_SHADER_BIT);
7763 		pipeline.UseProgramStages(program_tcs.m_id, GL_TESS_CONTROL_SHADER_BIT);
7764 		pipeline.UseProgramStages(program_tes.m_id, GL_TESS_EVALUATION_SHADER_BIT);
7765 		pipeline.UseProgramStages(program_vs.m_id, GL_VERTEX_SHADER_BIT);
7766 		pipeline.Bind();
7767 
7768 		/* */
7769 
7770 		buffer_attr.Init(Utils::Buffer::Array, Utils::Buffer::StaticDraw, 0, 0);
7771 		vao.Init();
7772 		prepareAttributes(test_case_index, program_interface, buffer_attr, vao);
7773 
7774 		/* */
7775 		prepareUniforms(test_case_index, program_interface, program_fs, program_gs, program_tcs, program_tes,
7776 						program_vs, buffer_u_fs, buffer_u_gs, buffer_u_tcs, buffer_u_tes, buffer_u_vs);
7777 
7778 		Utils::Program::Use(m_context.getRenderContext().getFunctions(), Utils::Program::m_invalid_id);
7779 
7780 		/* */
7781 		prepareFramebuffer(framebuffer, texture_fb);
7782 
7783 		/* Draw */
7784 		executeDrawCall(test_case_index);
7785 
7786 #if USE_NSIGHT
7787 		m_context.getRenderContext().postIterate();
7788 #endif
7789 
7790 		/* Check results */
7791 		if (false == checkResults(test_case_index, texture_fb))
7792 		{
7793 			m_context.getTestContext().getLog()
7794 				<< tcu::TestLog::Message << "FAILURE. Test case: " << test_name << ". Draw - invalid results."
7795 				<< tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(vs) << tcu::TestLog::KernelSource(tcs)
7796 				<< tcu::TestLog::KernelSource(tes) << tcu::TestLog::KernelSource(gs) << tcu::TestLog::KernelSource(fs);
7797 
7798 			result = false;
7799 		}
7800 	}
7801 
7802 	/* Compute */
7803 	if (true == isComputeRelevant(test_case_index))
7804 	{
7805 		Utils::Buffer	  buffer_u_cs(m_context);
7806 		Utils::Program	 program(m_context);
7807 		Utils::Texture	 texture_im(m_context);
7808 		Utils::VertexArray vao(m_context);
7809 
7810 		/* */
7811 		const std::string& compute_shader =
7812 			getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::COMPUTE);
7813 
7814 		program.Init(compute_shader, "" /* fragment_shader */, "" /* geometry_shader */, "" /* tess_ctrl_shader */,
7815 					 "" /* tess_eval_shader */, "" /* vertex_shader */, false /* is_separable */);
7816 
7817 		/* */
7818 		{
7819 			std::stringstream stream;
7820 
7821 			if (false == Utils::checkMonolithicComputeProgramInterface(program, program_interface, stream))
7822 			{
7823 				m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7824 													<< ". Inspection of compute program interface failed:\n"
7825 													<< stream.str() << tcu::TestLog::EndMessage;
7826 
7827 				return false;
7828 			}
7829 		}
7830 
7831 		/* */
7832 		program.Use();
7833 
7834 		/* */
7835 		vao.Init();
7836 		vao.Bind();
7837 
7838 		/* */
7839 		prepareUniforms(test_case_index, program_interface, program, buffer_u_cs);
7840 
7841 		/* */
7842 		GLint image_location = program.GetUniformLocation("uni_image");
7843 		prepareImage(image_location, texture_im);
7844 
7845 		/* Draw */
7846 		executeDispatchCall(test_case_index);
7847 
7848 #if USE_NSIGHT
7849 		m_context.getRenderContext().postIterate();
7850 #endif
7851 
7852 		/* Check results */
7853 		if (false == checkResults(test_case_index, texture_im))
7854 		{
7855 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7856 												<< ". Compute - invalid results." << tcu::TestLog::EndMessage
7857 												<< tcu::TestLog::KernelSource(compute_shader);
7858 
7859 			result = false;
7860 		}
7861 	}
7862 
7863 	return result;
7864 }
7865 
7866 /** Basic implementation
7867  *
7868  * @param ignored
7869  *
7870  * @return false
7871  **/
7872 bool TextureTestBase::useComponentQualifier(glw::GLuint /* test_case_index */)
7873 {
7874 	return false;
7875 }
7876 
7877 /** Basic implementation
7878  *
7879  * @param ignored
7880  *
7881  * @return true
7882  **/
7883 bool TextureTestBase::useMonolithicProgram(GLuint /* test_case_index */)
7884 {
7885 	return true;
7886 }
7887 
7888 /** Constructor
7889  *
7890  * @param context Test framework context
7891  **/
7892 APIConstantValuesTest::APIConstantValuesTest(deqp::Context& context)
7893 	: TestCase(context, "api_constant_values", "Test verifies values of api constants")
7894 {
7895 	/* Nothing to be done here */
7896 }
7897 
7898 /** Execute test
7899  *
7900  * @return tcu::TestNode::STOP otherwise
7901  **/
7902 tcu::TestNode::IterateResult APIConstantValuesTest::iterate()
7903 {
7904 	static const GLuint expected_comp = 64;
7905 	static const GLuint expected_xfb  = 4;
7906 	static const GLuint expected_sep  = 4;
7907 	GLint				max_comp	  = 0;
7908 	GLint				max_xfb		  = 0;
7909 	GLint				max_sep		  = 0;
7910 	bool				test_result   = true;
7911 
7912 	const Functions& gl = m_context.getRenderContext().getFunctions();
7913 
7914 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_xfb);
7915 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
7916 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_comp);
7917 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
7918 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, &max_sep);
7919 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
7920 
7921 	if (expected_xfb > (GLuint)max_xfb)
7922 	{
7923 		m_context.getTestContext().getLog() << tcu::TestLog::Message
7924 											<< "Invalid GL_MAX_TRANSFORM_FEEDBACK_BUFFERS. Got " << max_xfb
7925 											<< " Expected at least " << expected_xfb << tcu::TestLog::EndMessage;
7926 
7927 		test_result = false;
7928 	}
7929 
7930 	if (expected_comp > (GLuint)max_comp)
7931 	{
7932 		m_context.getTestContext().getLog()
7933 			<< tcu::TestLog::Message << "Invalid GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS. Got " << max_comp
7934 			<< " Expected at least " << expected_comp << tcu::TestLog::EndMessage;
7935 
7936 		test_result = false;
7937 	}
7938 
7939 	if (expected_sep > (GLuint)max_sep)
7940 	{
7941 		m_context.getTestContext().getLog() << tcu::TestLog::Message
7942 											<< "Invalid GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS. Got " << max_comp
7943 											<< " Expected at least " << expected_comp << tcu::TestLog::EndMessage;
7944 
7945 		test_result = false;
7946 	}
7947 
7948 	/* Set result */
7949 	if (true == test_result)
7950 	{
7951 		m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
7952 	}
7953 	else
7954 	{
7955 		m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
7956 	}
7957 
7958 	/* Done */
7959 	return tcu::TestNode::STOP;
7960 }
7961 
7962 /** Constructor
7963  *
7964  * @param context Test framework context
7965  **/
7966 APIErrorsTest::APIErrorsTest(deqp::Context& context)
7967 	: TestCase(context, "api_errors", "Test verifies errors reeturned by api")
7968 {
7969 	/* Nothing to be done here */
7970 }
7971 
7972 /** Execute test
7973  *
7974  * @return tcu::TestNode::STOP otherwise
7975  **/
7976 tcu::TestNode::IterateResult APIErrorsTest::iterate()
7977 {
7978 	GLint		   length = 0;
7979 	GLchar		   name[64];
7980 	GLint		   param = 0;
7981 	Utils::Program program(m_context);
7982 	bool		   test_result = true;
7983 
7984 	const Functions& gl = m_context.getRenderContext().getFunctions();
7985 
7986 	try
7987 	{
7988 		program.Init("" /* cs */, "#version 430 core\n"
7989 								  "#extension GL_ARB_enhanced_layouts : require\n"
7990 								  "\n"
7991 								  "in  vec4 vs_fs;\n"
7992 								  "out vec4 fs_out;\n"
7993 								  "\n"
7994 								  "void main()\n"
7995 								  "{\n"
7996 								  "    fs_out = vs_fs;\n"
7997 								  "}\n"
7998 								  "\n" /* fs */,
7999 					 "" /* gs */, "" /* tcs */, "" /* tes */, "#version 430 core\n"
8000 															  "#extension GL_ARB_enhanced_layouts : require\n"
8001 															  "\n"
8002 															  "in  vec4 in_vs;\n"
8003 															  "layout (xfb_offset = 16) out vec4 vs_fs;\n"
8004 															  "\n"
8005 															  "void main()\n"
8006 															  "{\n"
8007 															  "    vs_fs = in_vs;\n"
8008 															  "}\n"
8009 															  "\n" /* vs */,
8010 					 false /* separable */);
8011 	}
8012 	catch (Utils::Shader::InvalidSourceException& exc)
8013 	{
8014 		exc.log(m_context);
8015 		TCU_FAIL(exc.what());
8016 	}
8017 	catch (Utils::Program::BuildException& exc)
8018 	{
8019 		TCU_FAIL(exc.what());
8020 	}
8021 
8022 	/*
8023 	 * - GetProgramInterfaceiv should generate INVALID_OPERATION when
8024 	 * <programInterface> is TRANSFORM_FEEDBACK_BUFFER and <pname> is one of the
8025 	 * following:
8026 	 *   * MAX_NAME_LENGTH,
8027 	 *   * MAX_NUM_ACTIVE_VARIABLES;
8028 	 */
8029 	gl.getProgramInterfaceiv(program.m_id, GL_TRANSFORM_FEEDBACK_BUFFER, GL_MAX_NAME_LENGTH, &param);
8030 	checkError(GL_INVALID_OPERATION, "GetProgramInterfaceiv(GL_TRANSFORM_FEEDBACK_BUFFER, GL_MAX_NAME_LENGTH)",
8031 			   test_result);
8032 
8033 	/*
8034 	 * - GetProgramResourceIndex should generate INVALID_ENUM when
8035 	 * <programInterface> is TRANSFORM_FEEDBACK_BUFFER;
8036 	 */
8037 	gl.getProgramResourceIndex(program.m_id, GL_TRANSFORM_FEEDBACK_BUFFER, "0");
8038 	checkError(GL_INVALID_ENUM, "GetProgramResourceIndex(GL_TRANSFORM_FEEDBACK_BUFFER)", test_result);
8039 	/*
8040 	 * - GetProgramResourceName should generate INVALID_ENUM when
8041 	 * <programInterface> is TRANSFORM_FEEDBACK_BUFFER;
8042 	 */
8043 	gl.getProgramResourceName(program.m_id, GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, 64 /* bufSize */, &length,
8044 							  name);
8045 	checkError(GL_INVALID_ENUM, "GetProgramResourceName(GL_TRANSFORM_FEEDBACK_BUFFER)", test_result);
8046 
8047 	/* Set result */
8048 	if (true == test_result)
8049 	{
8050 		m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
8051 	}
8052 	else
8053 	{
8054 		m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
8055 	}
8056 
8057 	/* Done */
8058 	return tcu::TestNode::STOP;
8059 }
8060 
8061 /** Check if error is the expected one.
8062  *
8063  * @param expected_error Expected error
8064  * @param message        Message to log in case of error
8065  * @param test_result    Test result, set to false in case of invalid error
8066  **/
8067 void APIErrorsTest::checkError(GLenum expected_error, const GLchar* message, bool& test_result)
8068 {
8069 	const Functions& gl = m_context.getRenderContext().getFunctions();
8070 
8071 	GLenum error = gl.getError();
8072 
8073 	if (error != expected_error)
8074 	{
8075 		m_context.getTestContext().getLog()
8076 			<< tcu::TestLog::Message << "Failure. Invalid error. Got " << glu::getErrorStr(error) << " expected "
8077 			<< glu::getErrorStr(expected_error) << " Msg: " << message << tcu::TestLog::EndMessage;
8078 
8079 		test_result = false;
8080 	}
8081 }
8082 
8083 /** Constructor
8084  *
8085  * @param context Test framework context
8086  **/
8087 GLSLContantImmutablityTest::GLSLContantImmutablityTest(deqp::Context& context)
8088 	: NegativeTestBase(context, "glsl_contant_immutablity", "Test verifies that glsl constants cannot be modified")
8089 {
8090 	/* Nothing to be done here */
8091 }
8092 
8093 /** Source for given test case and stage
8094  *
8095  * @param test_case_index Index of test case
8096  * @param stage           Shader stage
8097  *
8098  * @return Shader source
8099  **/
8100 std::string GLSLContantImmutablityTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
8101 {
8102 	static const GLchar* cs = "#version 430 core\n"
8103 							  "#extension GL_ARB_enhanced_layouts : require\n"
8104 							  "\n"
8105 							  "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
8106 							  "\n"
8107 							  "writeonly uniform uimage2D uni_image;\n"
8108 							  "\n"
8109 							  "void main()\n"
8110 							  "{\n"
8111 							  "    uint result = 1u;\n"
8112 							  "    CONSTANT = 3;\n"
8113 							  "\n"
8114 							  "    imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), uvec4(result, 0, 0, 0));\n"
8115 							  "}\n"
8116 							  "\n";
8117 	static const GLchar* fs = "#version 430 core\n"
8118 							  "#extension GL_ARB_enhanced_layouts : require\n"
8119 							  "\n"
8120 							  "in  vec4 gs_fs;\n"
8121 							  "out vec4 fs_out;\n"
8122 							  "\n"
8123 							  "void main()\n"
8124 							  "{\n"
8125 							  "ASSIGNMENT"
8126 							  "    fs_out = gs_fs;\n"
8127 							  "}\n"
8128 							  "\n";
8129 	static const GLchar* gs = "#version 430 core\n"
8130 							  "#extension GL_ARB_enhanced_layouts : require\n"
8131 							  "\n"
8132 							  "layout(points)                           in;\n"
8133 							  "layout(triangle_strip, max_vertices = 4) out;\n"
8134 							  "\n"
8135 							  "in  vec4 tes_gs[];\n"
8136 							  "out vec4 gs_fs;\n"
8137 							  "\n"
8138 							  "void main()\n"
8139 							  "{\n"
8140 							  "ASSIGNMENT"
8141 							  "    gs_fs = tes_gs[0];\n"
8142 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
8143 							  "    EmitVertex();\n"
8144 							  "    gs_fs = tes_gs[0];\n"
8145 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
8146 							  "    EmitVertex();\n"
8147 							  "    gs_fs = tes_gs[0];\n"
8148 							  "    gl_Position  = vec4(1, -1, 0, 1);\n"
8149 							  "    EmitVertex();\n"
8150 							  "    gs_fs = tes_gs[0];\n"
8151 							  "    gl_Position  = vec4(1, 1, 0, 1);\n"
8152 							  "    EmitVertex();\n"
8153 							  "}\n"
8154 							  "\n";
8155 	static const GLchar* tcs = "#version 430 core\n"
8156 							   "#extension GL_ARB_enhanced_layouts : require\n"
8157 							   "\n"
8158 							   "layout(vertices = 1) out;\n"
8159 							   "\n"
8160 							   "in  vec4 vs_tcs[];\n"
8161 							   "out vec4 tcs_tes[];\n"
8162 							   "\n"
8163 							   "void main()\n"
8164 							   "{\n"
8165 							   "\n"
8166 							   "ASSIGNMENT"
8167 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
8168 							   "\n"
8169 							   "    gl_TessLevelOuter[0] = 1.0;\n"
8170 							   "    gl_TessLevelOuter[1] = 1.0;\n"
8171 							   "    gl_TessLevelOuter[2] = 1.0;\n"
8172 							   "    gl_TessLevelOuter[3] = 1.0;\n"
8173 							   "    gl_TessLevelInner[0] = 1.0;\n"
8174 							   "    gl_TessLevelInner[1] = 1.0;\n"
8175 							   "}\n"
8176 							   "\n";
8177 	static const GLchar* tes = "#version 430 core\n"
8178 							   "#extension GL_ARB_enhanced_layouts : require\n"
8179 							   "\n"
8180 							   "layout(isolines, point_mode) in;\n"
8181 							   "\n"
8182 							   "in  vec4 tcs_tes[];\n"
8183 							   "out vec4 tes_gs;\n"
8184 							   "\n"
8185 							   "void main()\n"
8186 							   "{\n"
8187 							   "ASSIGNMENT"
8188 							   "    tes_gs = tcs_tes[0];\n"
8189 							   "}\n"
8190 							   "\n";
8191 	static const GLchar* vs = "#version 430 core\n"
8192 							  "#extension GL_ARB_enhanced_layouts : require\n"
8193 							  "\n"
8194 							  "in  vec4 in_vs;\n"
8195 							  "out vec4 vs_tcs;\n"
8196 							  "\n"
8197 							  "void main()\n"
8198 							  "{\n"
8199 							  "ASSIGNMENT"
8200 							  "    vs_tcs = in_vs;\n"
8201 							  "}\n"
8202 							  "\n";
8203 
8204 	std::string source;
8205 	testCase&   test_case = m_test_cases[test_case_index];
8206 
8207 	if (Utils::Shader::COMPUTE == test_case.m_stage)
8208 	{
8209 		size_t position = 0;
8210 
8211 		source = cs;
8212 
8213 		Utils::replaceToken("CONSTANT", position, getConstantName(test_case.m_constant), source);
8214 	}
8215 	else
8216 	{
8217 		std::string assignment = "    CONSTANT = 3;\n";
8218 		size_t		position   = 0;
8219 
8220 		switch (stage)
8221 		{
8222 		case Utils::Shader::FRAGMENT:
8223 			source = fs;
8224 			break;
8225 		case Utils::Shader::GEOMETRY:
8226 			source = gs;
8227 			break;
8228 		case Utils::Shader::TESS_CTRL:
8229 			source = tcs;
8230 			break;
8231 		case Utils::Shader::TESS_EVAL:
8232 			source = tes;
8233 			break;
8234 		case Utils::Shader::VERTEX:
8235 			source = vs;
8236 			break;
8237 		default:
8238 			TCU_FAIL("Invalid enum");
8239 		}
8240 
8241 		if (test_case.m_stage == stage)
8242 		{
8243 			Utils::replaceToken("CONSTANT", position, getConstantName(test_case.m_constant), assignment);
8244 		}
8245 		else
8246 		{
8247 			assignment = "";
8248 		}
8249 
8250 		position = 0;
8251 		Utils::replaceToken("ASSIGNMENT", position, assignment.c_str(), source);
8252 	}
8253 
8254 	return source;
8255 }
8256 
8257 /** Get description of test case
8258  *
8259  * @param test_case_index Index of test case
8260  *
8261  * @return Constant name
8262  **/
8263 std::string GLSLContantImmutablityTest::getTestCaseName(GLuint test_case_index)
8264 {
8265 	std::string result = getConstantName(m_test_cases[test_case_index].m_constant);
8266 
8267 	return result;
8268 }
8269 
8270 /** Get number of test cases
8271  *
8272  * @return Number of test cases
8273  **/
8274 GLuint GLSLContantImmutablityTest::getTestCaseNumber()
8275 {
8276 	return static_cast<GLuint>(m_test_cases.size());
8277 }
8278 
8279 /** Selects if "compute" stage is relevant for test
8280  *
8281  * @param test_case_index Index of test case
8282  *
8283  * @return true when tested stage is compute
8284  **/
8285 bool GLSLContantImmutablityTest::isComputeRelevant(GLuint test_case_index)
8286 {
8287 	return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
8288 }
8289 
8290 /** Prepare all test cases
8291  *
8292  **/
8293 void GLSLContantImmutablityTest::testInit()
8294 {
8295 	for (GLuint constant = 0; constant < CONSTANTS_MAX; ++constant)
8296 	{
8297 		for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
8298 		{
8299 			testCase test_case = { (CONSTANTS)constant, (Utils::Shader::STAGES)stage };
8300 
8301 			m_test_cases.push_back(test_case);
8302 		}
8303 	}
8304 }
8305 
8306 /** Get name of glsl constant
8307  *
8308  * @param Constant id
8309  *
8310  * @return Name of constant used in GLSL
8311  **/
8312 const GLchar* GLSLContantImmutablityTest::getConstantName(CONSTANTS constant)
8313 {
8314 	const GLchar* name = "";
8315 
8316 	switch (constant)
8317 	{
8318 	case GL_ARB_ENHANCED_LAYOUTS:
8319 		name = "GL_ARB_enhanced_layouts";
8320 		break;
8321 	case GL_MAX_XFB:
8322 		name = "gl_MaxTransformFeedbackBuffers";
8323 		break;
8324 	case GL_MAX_XFB_INT_COMP:
8325 		name = "gl_MaxTransformFeedbackInterleavedComponents";
8326 		break;
8327 	default:
8328 		TCU_FAIL("Invalid enum");
8329 	}
8330 
8331 	return name;
8332 }
8333 
8334 /** Constructor
8335  *
8336  * @param context Test framework context
8337  **/
8338 GLSLContantValuesTest::GLSLContantValuesTest(deqp::Context& context)
8339 	: TextureTestBase(context, "glsl_contant_values", "Test verifies values of constant symbols")
8340 {
8341 }
8342 
8343 /** Selects if "compute" stage is relevant for test
8344  *
8345  * @param ignored
8346  *
8347  * @return false
8348  **/
8349 bool GLSLContantValuesTest::isComputeRelevant(GLuint /* test_case_index */)
8350 {
8351 	return false;
8352 }
8353 
8354 /** Prepare code snippet that will verify in and uniform variables
8355  *
8356  * @param ignored
8357  * @param ignored
8358  * @param stage   Shader stage
8359  *
8360  * @return Code that verify variables
8361  **/
8362 std::string GLSLContantValuesTest::getVerificationSnippet(GLuint /* test_case_index */,
8363 														  Utils::ProgramInterface& /* program_interface */,
8364 														  Utils::Shader::STAGES stage)
8365 {
8366 	/* Get constants */
8367 	const Functions& gl = m_context.getRenderContext().getFunctions();
8368 
8369 	GLint max_transform_feedback_buffers				= 0;
8370 	GLint max_transform_feedback_interleaved_components = 0;
8371 
8372 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_transform_feedback_buffers);
8373 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8374 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_transform_feedback_interleaved_components);
8375 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8376 
8377 	std::string verification;
8378 
8379 	if (Utils::Shader::VERTEX == stage)
8380 	{
8381 		verification = "if (1 != GL_ARB_enhanced_layouts)\n"
8382 					   "    {\n"
8383 					   "        result = 0;\n"
8384 					   "    }\n"
8385 					   "    else if (MAX_TRANSFORM_FEEDBACK_BUFFERS\n"
8386 					   "        != gl_MaxTransformFeedbackBuffers)\n"
8387 					   "    {\n"
8388 					   "        result = 0;\n"
8389 					   "    }\n"
8390 					   "    else if (MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS \n"
8391 					   "        != gl_MaxTransformFeedbackInterleavedComponents)\n"
8392 					   "    {\n"
8393 					   "        result = 0;\n"
8394 					   "    }\n";
8395 
8396 		size_t position = 0;
8397 		GLchar buffer[16];
8398 
8399 		sprintf(buffer, "%d", max_transform_feedback_buffers);
8400 		Utils::replaceToken("MAX_TRANSFORM_FEEDBACK_BUFFERS", position, buffer, verification);
8401 
8402 		sprintf(buffer, "%d", max_transform_feedback_interleaved_components);
8403 		Utils::replaceToken("MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS", position, buffer, verification);
8404 	}
8405 	else
8406 	{
8407 		verification = "";
8408 	}
8409 
8410 	return verification;
8411 }
8412 
8413 /** Constructor
8414  *
8415  * @param context Test framework context
8416  **/
8417 GLSLConstantIntegralExpressionTest::GLSLConstantIntegralExpressionTest(deqp::Context& context)
8418 	: TextureTestBase(context, "glsl_constant_integral_expression",
8419 					  "Test verifies that symbols can be used as constant integral expressions")
8420 {
8421 }
8422 
8423 /** Get interface of program
8424  *
8425  * @param ignored
8426  * @param program_interface Interface of program
8427  * @param ignored
8428  **/
8429 void GLSLConstantIntegralExpressionTest::getProgramInterface(GLuint /* test_case_index */,
8430 															 Utils::ProgramInterface& program_interface,
8431 															 Utils::VaryingPassthrough& /* varying_passthrough */)
8432 {
8433 	/* Get constants */
8434 	const Functions& gl = m_context.getRenderContext().getFunctions();
8435 
8436 	GLint max_transform_feedback_buffers				= 0;
8437 	GLint max_transform_feedback_interleaved_components = 0;
8438 
8439 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_transform_feedback_buffers);
8440 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8441 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_transform_feedback_interleaved_components);
8442 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8443 
8444 	GLuint gohan_div = std::max(1, max_transform_feedback_buffers / 16);
8445 	GLuint goten_div = std::max(1, max_transform_feedback_interleaved_components / 16);
8446 
8447 	m_gohan_length = max_transform_feedback_buffers / gohan_div;
8448 	m_goten_length = max_transform_feedback_interleaved_components / goten_div;
8449 
8450 	/* Globals */
8451 	std::string globals = "uniform uint goku [GL_ARB_enhanced_layouts / 1];\n"
8452 						  "uniform uint gohan[gl_MaxTransformFeedbackBuffers / GOHAN_DIV];\n"
8453 						  "uniform uint goten[gl_MaxTransformFeedbackInterleavedComponents / GOTEN_DIV];\n";
8454 
8455 	size_t position = 0;
8456 	GLchar buffer[16];
8457 
8458 	sprintf(buffer, "%d", gohan_div);
8459 	Utils::replaceToken("GOHAN_DIV", position, buffer, globals);
8460 
8461 	sprintf(buffer, "%d", goten_div);
8462 	Utils::replaceToken("GOTEN_DIV", position, buffer, globals);
8463 
8464 	program_interface.m_vertex.m_globals	= globals;
8465 	program_interface.m_tess_ctrl.m_globals = globals;
8466 	program_interface.m_tess_eval.m_globals = globals;
8467 	program_interface.m_geometry.m_globals  = globals;
8468 	program_interface.m_fragment.m_globals  = globals;
8469 	program_interface.m_compute.m_globals   = globals;
8470 }
8471 
8472 /** Prepare code snippet that will verify in and uniform variables
8473  *
8474  * @param ignored
8475  * @param ignored
8476  * @param ignored
8477  *
8478  * @return Code that verify variables
8479  **/
8480 std::string GLSLConstantIntegralExpressionTest::getVerificationSnippet(GLuint /* test_case_index */,
8481 																	   Utils::ProgramInterface& /* program_interface */,
8482 																	   Utils::Shader::STAGES /* stage */)
8483 {
8484 	std::string verification = "{\n"
8485 							   "        uint goku_sum = 0;\n"
8486 							   "        uint gohan_sum = 0;\n"
8487 							   "        uint goten_sum = 0;\n"
8488 							   "\n"
8489 							   "        for (uint i = 0u; i < goku.length(); ++i)\n"
8490 							   "        {\n"
8491 							   "            goku_sum += goku[i];\n"
8492 							   "        }\n"
8493 							   "\n"
8494 							   "        for (uint i = 0u; i < gohan.length(); ++i)\n"
8495 							   "        {\n"
8496 							   "            gohan_sum += gohan[i];\n"
8497 							   "        }\n"
8498 							   "\n"
8499 							   "        for (uint i = 0u; i < goten.length(); ++i)\n"
8500 							   "        {\n"
8501 							   "            goten_sum += goten[i];\n"
8502 							   "        }\n"
8503 							   "\n"
8504 							   "        if ( (1u != goku_sum)  &&\n"
8505 							   "             (EXPECTED_GOHAN_SUMu != gohan_sum) ||\n"
8506 							   "             (EXPECTED_GOTEN_SUMu != goten_sum) )\n"
8507 							   "        {\n"
8508 							   "            result = 0u;\n"
8509 							   "        }\n"
8510 							   "    }\n";
8511 
8512 	size_t position = 0;
8513 	GLchar buffer[16];
8514 
8515 	sprintf(buffer, "%d", m_gohan_length);
8516 	Utils::replaceToken("EXPECTED_GOHAN_SUM", position, buffer, verification);
8517 
8518 	sprintf(buffer, "%d", m_goten_length);
8519 	Utils::replaceToken("EXPECTED_GOTEN_SUM", position, buffer, verification);
8520 
8521 	return verification;
8522 }
8523 
8524 /** Prepare unifroms
8525  *
8526  * @param ignored
8527  * @param ignored
8528  * @param program Program object
8529  * @param ignored
8530  **/
8531 void GLSLConstantIntegralExpressionTest::prepareUniforms(GLuint /* test_case_index */,
8532 														 Utils::ProgramInterface& /* program_interface */,
8533 														 Utils::Program& program, Utils::Buffer& /* cs_buffer */)
8534 {
8535 	static const GLuint uniform_data[16] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
8536 
8537 	const Functions& gl = m_context.getRenderContext().getFunctions();
8538 
8539 	GLint goku_location  = program.GetUniformLocation("goku");
8540 	GLint gohan_location = program.GetUniformLocation("gohan");
8541 	GLint goten_location = program.GetUniformLocation("goten");
8542 
8543 	program.Uniform(gl, Utils::Type::uint, 1 /* count */, goku_location, uniform_data);
8544 	program.Uniform(gl, Utils::Type::uint, m_gohan_length, gohan_location, uniform_data);
8545 	program.Uniform(gl, Utils::Type::uint, m_goten_length, goten_location, uniform_data);
8546 }
8547 
8548 /** Prepare unifroms
8549  *
8550  * @param test_case_index   Pass as param to first implemetnation
8551  * @param program_interface Pass as param to first implemetnation
8552  * @param program           Pass as param to first implemetnation
8553  * @param ignored
8554  * @param ignored
8555  * @param ignored
8556  * @param ignored
8557  * @param vs_buffer         Pass as param to first implemetnation
8558  **/
8559 void GLSLConstantIntegralExpressionTest::prepareUniforms(GLuint					  test_case_index,
8560 														 Utils::ProgramInterface& program_interface,
8561 														 Utils::Program& program, Utils::Buffer& /* fs_buffer */,
8562 														 Utils::Buffer& /* gs_buffer */,
8563 														 Utils::Buffer& /* tcs_buffer */,
8564 														 Utils::Buffer& /* tes_buffer */, Utils::Buffer& vs_buffer)
8565 {
8566 	/* Call first implementation */
8567 	prepareUniforms(test_case_index, program_interface, program, vs_buffer);
8568 }
8569 
8570 /** Constructor
8571  *
8572  * @param context Test framework context
8573  **/
8574 UniformBlockMemberOffsetAndAlignTest::UniformBlockMemberOffsetAndAlignTest(deqp::Context& context)
8575 	: TextureTestBase(context, "uniform_block_member_offset_and_align",
8576 					  "Test verifies offsets and alignment of uniform buffer members")
8577 {
8578 }
8579 
8580 /** Get interface of program
8581  *
8582  * @param test_case_index     Test case index
8583  * @param program_interface   Interface of program
8584  * @param varying_passthrough Collection of connections between in and out variables
8585  **/
8586 void UniformBlockMemberOffsetAndAlignTest::getProgramInterface(GLuint					  test_case_index,
8587 															   Utils::ProgramInterface&   program_interface,
8588 															   Utils::VaryingPassthrough& varying_passthrough)
8589 {
8590 	std::string globals = "const int basic_size = BASIC_SIZE;\n"
8591 						  "const int type_align = TYPE_ALIGN;\n"
8592 						  "const int type_size  = TYPE_SIZE;\n";
8593 
8594 	Utils::Type  type		 = getType(test_case_index);
8595 	GLuint		 basic_size  = Utils::Type::GetTypeSize(type.m_basic_type);
8596 	const GLuint base_align  = type.GetBaseAlignment(false);
8597 	const GLuint array_align = type.GetBaseAlignment(true);
8598 	const GLuint base_stride = Utils::Type::CalculateStd140Stride(base_align, type.m_n_columns, 0);
8599 	const GLuint type_align  = Utils::roundUpToPowerOf2(base_stride);
8600 
8601 	/* Calculate offsets */
8602 	const GLuint first_offset  = 0;
8603 	const GLuint second_offset = type.GetActualOffset(base_stride, basic_size / 2);
8604 
8605 #if WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST
8606 
8607 	const GLuint third_offset   = type.GetActualOffset(second_offset + base_stride, base_align);
8608 	const GLuint fourth_offset  = type.GetActualOffset(third_offset + base_stride, base_align);
8609 	const GLuint fifth_offset   = type.GetActualOffset(fourth_offset + base_stride, base_align);
8610 	const GLuint sixth_offset   = type.GetActualOffset(fifth_offset + base_stride, array_align);
8611 	const GLuint seventh_offset = type.GetActualOffset(sixth_offset + base_stride, array_align);
8612 	const GLuint eigth_offset   = type.GetActualOffset(seventh_offset + base_stride, array_align);
8613 
8614 #else /* WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST */
8615 
8616 	const GLuint third_offset   = type.GetActualOffset(second_offset + base_stride, 2 * type_align);
8617 	const GLuint fourth_offset  = type.GetActualOffset(3 * type_align + base_stride, base_align);
8618 	const GLuint fifth_offset   = type.GetActualOffset(fourth_offset + base_stride, base_align);
8619 	const GLuint sixth_offset   = type.GetActualOffset(fifth_offset + base_stride, array_align);
8620 	const GLuint seventh_offset = type.GetActualOffset(sixth_offset + base_stride, array_align);
8621 	const GLuint eigth_offset   = type.GetActualOffset(seventh_offset + base_stride, 8 * basic_size);
8622 
8623 #endif /* WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST */
8624 
8625 	/* Prepare data */
8626 	const std::vector<GLubyte>& first  = type.GenerateData();
8627 	const std::vector<GLubyte>& second = type.GenerateData();
8628 	const std::vector<GLubyte>& third  = type.GenerateData();
8629 	const std::vector<GLubyte>& fourth = type.GenerateData();
8630 
8631 	m_data.resize(eigth_offset + base_stride);
8632 	GLubyte* ptr = &m_data[0];
8633 	memcpy(ptr + first_offset, &first[0], first.size());
8634 	memcpy(ptr + second_offset, &second[0], second.size());
8635 	memcpy(ptr + third_offset, &third[0], third.size());
8636 	memcpy(ptr + fourth_offset, &fourth[0], fourth.size());
8637 	memcpy(ptr + fifth_offset, &fourth[0], fourth.size());
8638 	memcpy(ptr + sixth_offset, &third[0], third.size());
8639 	memcpy(ptr + seventh_offset, &second[0], second.size());
8640 	memcpy(ptr + eigth_offset, &first[0], first.size());
8641 
8642 	/* Prepare globals */
8643 	size_t position = 0;
8644 	GLchar buffer[16];
8645 
8646 	sprintf(buffer, "%d", basic_size);
8647 	Utils::replaceToken("BASIC_SIZE", position, buffer, globals);
8648 
8649 	sprintf(buffer, "%d", type_align);
8650 	Utils::replaceToken("TYPE_ALIGN", position, buffer, globals);
8651 
8652 	sprintf(buffer, "%d", base_stride);
8653 	Utils::replaceToken("TYPE_SIZE", position, buffer, globals);
8654 
8655 	/* Prepare Block */
8656 	Utils::Interface* vs_uni_block = program_interface.Block("vs_uni_Block");
8657 
8658 	vs_uni_block->Member("at_first_offset", "layout(offset = 0, align = 8 * basic_size)", 0 /* expected_component */,
8659 						 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
8660 						 first_offset);
8661 
8662 	vs_uni_block->Member("at_second_offset", "layout(offset = type_size, align = basic_size / 2)",
8663 						 0 /* expected_component */, 0 /* expected_location */, type, false /* normalized */,
8664 						 0 /* n_array_elements */, base_stride, second_offset);
8665 
8666 	vs_uni_block->Member("at_third_offset", "layout(align = 2 * type_align)", 0 /* expected_component */,
8667 						 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
8668 						 third_offset);
8669 
8670 	vs_uni_block->Member("at_fourth_offset", "layout(offset = 3 * type_align + type_size)", 0 /* expected_component */,
8671 						 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
8672 						 fourth_offset);
8673 
8674 	vs_uni_block->Member("at_fifth_offset", "", 0 /* expected_component */, 0 /* expected_location */, type,
8675 						 false /* normalized */, 0 /* n_array_elements */, base_stride, fifth_offset);
8676 
8677 	vs_uni_block->Member("at_sixth_offset", "", 0 /* expected_component */, 0 /* expected_location */, type,
8678 						 false /* normalized */, 2 /* n_array_elements */, array_align * 2, sixth_offset);
8679 
8680 	vs_uni_block->Member("at_eigth_offset", "layout(align = 8 * basic_size)", 0 /* expected_component */,
8681 						 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
8682 						 eigth_offset);
8683 
8684 	Utils::ShaderInterface& vs_si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
8685 
8686 	/* Add globals */
8687 	vs_si.m_globals = globals;
8688 
8689 	/* Add uniform BLOCK */
8690 	vs_si.Uniform("vs_uni_block", "layout (std140, binding = BINDING)", 0, 0, vs_uni_block, 0,
8691 				  static_cast<glw::GLint>(m_data.size()), 0, &m_data[0], m_data.size());
8692 
8693 	/* */
8694 	program_interface.CloneVertexInterface(varying_passthrough);
8695 }
8696 
8697 /** Get type name
8698  *
8699  * @param test_case_index Index of test case
8700  *
8701  * @return Name of type test in test_case_index
8702  **/
8703 std::string UniformBlockMemberOffsetAndAlignTest::getTestCaseName(glw::GLuint test_case_index)
8704 {
8705 	return getTypeName(test_case_index);
8706 }
8707 
8708 /** Returns number of types to test
8709  *
8710  * @return Number of types, 34
8711  **/
8712 glw::GLuint UniformBlockMemberOffsetAndAlignTest::getTestCaseNumber()
8713 {
8714 	return getTypesNumber();
8715 }
8716 
8717 /** Prepare code snippet that will verify in and uniform variables
8718  *
8719  * @param ignored
8720  * @param ignored
8721  * @param stage   Shader stage
8722  *
8723  * @return Code that verify variables
8724  **/
8725 std::string UniformBlockMemberOffsetAndAlignTest::getVerificationSnippet(
8726 	GLuint /* test_case_index */, Utils::ProgramInterface& /* program_interface */, Utils::Shader::STAGES stage)
8727 {
8728 	std::string verification = "if ( (PREFIXblock.at_first_offset  != PREFIXblock.at_eigth_offset   ) ||\n"
8729 							   "         (PREFIXblock.at_second_offset != PREFIXblock.at_sixth_offset[1]) ||\n"
8730 							   "         (PREFIXblock.at_third_offset  != PREFIXblock.at_sixth_offset[0]) ||\n"
8731 							   "         (PREFIXblock.at_fourth_offset != PREFIXblock.at_fifth_offset   )  )\n"
8732 							   "    {\n"
8733 							   "        result = 0;\n"
8734 							   "    }";
8735 
8736 	const GLchar* prefix = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::UNIFORM);
8737 
8738 	Utils::replaceAllTokens("PREFIX", prefix, verification);
8739 
8740 	return verification;
8741 }
8742 
8743 /** Constructor
8744  *
8745  * @param context Test framework context
8746  **/
8747 UniformBlockLayoutQualifierConflictTest::UniformBlockLayoutQualifierConflictTest(deqp::Context& context)
8748 	: NegativeTestBase(
8749 		  context, "uniform_block_layout_qualifier_conflict",
8750 		  "Test verifies that std140 is required when offset and/or align qualifiers are used with uniform block")
8751 {
8752 	/* Nothing to be done here */
8753 }
8754 
8755 /** Source for given test case and stage
8756  *
8757  * @param test_case_index Index of test case
8758  * @param stage           Shader stage
8759  *
8760  * @return Shader source
8761  **/
8762 std::string UniformBlockLayoutQualifierConflictTest::getShaderSource(GLuint				   test_case_index,
8763 																	 Utils::Shader::STAGES stage)
8764 {
8765 	static const GLchar* cs = "#version 430 core\n"
8766 							  "#extension GL_ARB_enhanced_layouts : require\n"
8767 							  "\n"
8768 							  "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
8769 							  "\n"
8770 							  "LAYOUTuniform Block {\n"
8771 							  "    layout(offset = 16) vec4 boy;\n"
8772 							  "    layout(align  = 64) vec4 man;\n"
8773 							  "} uni_block;\n"
8774 							  "\n"
8775 							  "writeonly uniform image2D uni_image;\n"
8776 							  "\n"
8777 							  "void main()\n"
8778 							  "{\n"
8779 							  "    vec4 result = uni_block.boy + uni_block.man;\n"
8780 							  "\n"
8781 							  "    imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
8782 							  "}\n"
8783 							  "\n";
8784 	static const GLchar* fs = "#version 430 core\n"
8785 							  "#extension GL_ARB_enhanced_layouts : require\n"
8786 							  "\n"
8787 							  "LAYOUTuniform Block {\n"
8788 							  "    layout(offset = 16) vec4 boy;\n"
8789 							  "    layout(align  = 64) vec4 man;\n"
8790 							  "} uni_block;\n"
8791 							  "\n"
8792 							  "in  vec4 gs_fs;\n"
8793 							  "out vec4 fs_out;\n"
8794 							  "\n"
8795 							  "void main()\n"
8796 							  "{\n"
8797 							  "    fs_out = gs_fs + uni_block.boy + uni_block.man;\n"
8798 							  "}\n"
8799 							  "\n";
8800 	static const GLchar* gs = "#version 430 core\n"
8801 							  "#extension GL_ARB_enhanced_layouts : require\n"
8802 							  "\n"
8803 							  "layout(points)                           in;\n"
8804 							  "layout(triangle_strip, max_vertices = 4) out;\n"
8805 							  "\n"
8806 							  "LAYOUTuniform Block {\n"
8807 							  "    layout(offset = 16) vec4 boy;\n"
8808 							  "    layout(align  = 64) vec4 man;\n"
8809 							  "} uni_block;\n"
8810 							  "\n"
8811 							  "in  vec4 tes_gs[];\n"
8812 							  "out vec4 gs_fs;\n"
8813 							  "\n"
8814 							  "void main()\n"
8815 							  "{\n"
8816 							  "    gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
8817 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
8818 							  "    EmitVertex();\n"
8819 							  "    gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
8820 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
8821 							  "    EmitVertex();\n"
8822 							  "    gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
8823 							  "    gl_Position  = vec4(1, -1, 0, 1);\n"
8824 							  "    EmitVertex();\n"
8825 							  "    gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
8826 							  "    gl_Position  = vec4(1, 1, 0, 1);\n"
8827 							  "    EmitVertex();\n"
8828 							  "}\n"
8829 							  "\n";
8830 	static const GLchar* tcs =
8831 		"#version 430 core\n"
8832 		"#extension GL_ARB_enhanced_layouts : require\n"
8833 		"\n"
8834 		"layout(vertices = 1) out;\n"
8835 		"\n"
8836 		"LAYOUTuniform Block {\n"
8837 		"    layout(offset = 16) vec4 boy;\n"
8838 		"    layout(align  = 64) vec4 man;\n"
8839 		"} uni_block;\n"
8840 		"\n"
8841 		"in  vec4 vs_tcs[];\n"
8842 		"out vec4 tcs_tes[];\n"
8843 		"\n"
8844 		"void main()\n"
8845 		"{\n"
8846 		"\n"
8847 		"    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID] + uni_block.boy + uni_block.man;\n"
8848 		"\n"
8849 		"    gl_TessLevelOuter[0] = 1.0;\n"
8850 		"    gl_TessLevelOuter[1] = 1.0;\n"
8851 		"    gl_TessLevelOuter[2] = 1.0;\n"
8852 		"    gl_TessLevelOuter[3] = 1.0;\n"
8853 		"    gl_TessLevelInner[0] = 1.0;\n"
8854 		"    gl_TessLevelInner[1] = 1.0;\n"
8855 		"}\n"
8856 		"\n";
8857 	static const GLchar* tes = "#version 430 core\n"
8858 							   "#extension GL_ARB_enhanced_layouts : require\n"
8859 							   "\n"
8860 							   "layout(isolines, point_mode) in;\n"
8861 							   "\n"
8862 							   "LAYOUTuniform Block {\n"
8863 							   "    layout(offset = 16) vec4 boy;\n"
8864 							   "    layout(align  = 64) vec4 man;\n"
8865 							   "} uni_block;\n"
8866 							   "\n"
8867 							   "in  vec4 tcs_tes[];\n"
8868 							   "out vec4 tes_gs;\n"
8869 							   "\n"
8870 							   "void main()\n"
8871 							   "{\n"
8872 							   "    tes_gs = tcs_tes[0] + uni_block.boy + uni_block.man;\n"
8873 							   "}\n"
8874 							   "\n";
8875 	static const GLchar* vs = "#version 430 core\n"
8876 							  "#extension GL_ARB_enhanced_layouts : require\n"
8877 							  "\n"
8878 							  "LAYOUTuniform Block {\n"
8879 							  "    layout(offset = 16) vec4 boy;\n"
8880 							  "    layout(align  = 64) vec4 man;\n"
8881 							  "} uni_block;\n"
8882 							  "\n"
8883 							  "in  vec4 in_vs;\n"
8884 							  "out vec4 vs_tcs;\n"
8885 							  "\n"
8886 							  "void main()\n"
8887 							  "{\n"
8888 							  "    vs_tcs = in_vs + uni_block.boy + uni_block.man;\n"
8889 							  "}\n"
8890 							  "\n";
8891 
8892 	std::string   layout	= "";
8893 	size_t		  position  = 0;
8894 	testCase&	 test_case = m_test_cases[test_case_index];
8895 	const GLchar* qualifier = getQualifierName(test_case.m_qualifier);
8896 	std::string   source;
8897 
8898 	if (0 != qualifier[0])
8899 	{
8900 		size_t layout_position = 0;
8901 
8902 		layout = "layout (QUALIFIER) ";
8903 
8904 		Utils::replaceToken("QUALIFIER", layout_position, qualifier, layout);
8905 	}
8906 
8907 	switch (stage)
8908 	{
8909 	case Utils::Shader::COMPUTE:
8910 		source = cs;
8911 		break;
8912 	case Utils::Shader::FRAGMENT:
8913 		source = fs;
8914 		break;
8915 	case Utils::Shader::GEOMETRY:
8916 		source = gs;
8917 		break;
8918 	case Utils::Shader::TESS_CTRL:
8919 		source = tcs;
8920 		break;
8921 	case Utils::Shader::TESS_EVAL:
8922 		source = tes;
8923 		break;
8924 	case Utils::Shader::VERTEX:
8925 		source = vs;
8926 		break;
8927 	default:
8928 		TCU_FAIL("Invalid enum");
8929 	}
8930 
8931 	if (test_case.m_stage == stage)
8932 	{
8933 		Utils::replaceToken("LAYOUT", position, layout.c_str(), source);
8934 	}
8935 	else
8936 	{
8937 		Utils::replaceToken("LAYOUT", position, "layout (std140) ", source);
8938 	}
8939 
8940 	return source;
8941 }
8942 
8943 /** Get description of test case
8944  *
8945  * @param test_case_index Index of test case
8946  *
8947  * @return Qualifier name
8948  **/
8949 std::string UniformBlockLayoutQualifierConflictTest::getTestCaseName(GLuint test_case_index)
8950 {
8951 	std::string result = getQualifierName(m_test_cases[test_case_index].m_qualifier);
8952 
8953 	return result;
8954 }
8955 
8956 /** Get number of test cases
8957  *
8958  * @return Number of test cases
8959  **/
8960 GLuint UniformBlockLayoutQualifierConflictTest::getTestCaseNumber()
8961 {
8962 	return static_cast<GLuint>(m_test_cases.size());
8963 }
8964 
8965 /** Selects if "compute" stage is relevant for test
8966  *
8967  * @param test_case_index Index of test case
8968  *
8969  * @return true when tested stage is compute
8970  **/
8971 bool UniformBlockLayoutQualifierConflictTest::isComputeRelevant(GLuint test_case_index)
8972 {
8973 	return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
8974 }
8975 
8976 /** Selects if compilation failure is expected result
8977  *
8978  * @param test_case_index Index of test case
8979  *
8980  * @return false for STD140 cases, true otherwise
8981  **/
8982 bool UniformBlockLayoutQualifierConflictTest::isFailureExpected(GLuint test_case_index)
8983 {
8984 	return (STD140 != m_test_cases[test_case_index].m_qualifier);
8985 }
8986 
8987 /** Prepare all test cases
8988  *
8989  **/
8990 void UniformBlockLayoutQualifierConflictTest::testInit()
8991 {
8992 	for (GLuint qualifier = 0; qualifier < QUALIFIERS_MAX; ++qualifier)
8993 	{
8994 		for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
8995 		{
8996 			testCase test_case = { (QUALIFIERS)qualifier, (Utils::Shader::STAGES)stage };
8997 
8998 			m_test_cases.push_back(test_case);
8999 		}
9000 	}
9001 }
9002 
9003 /** Get name of glsl constant
9004  *
9005  * @param Constant id
9006  *
9007  * @return Name of constant used in GLSL
9008  **/
9009 const GLchar* UniformBlockLayoutQualifierConflictTest::getQualifierName(QUALIFIERS qualifier)
9010 {
9011 	const GLchar* name = "";
9012 
9013 	switch (qualifier)
9014 	{
9015 	case DEFAULT:
9016 		name = "";
9017 		break;
9018 	case STD140:
9019 		name = "std140";
9020 		break;
9021 	case SHARED:
9022 		name = "shared";
9023 		break;
9024 	case PACKED:
9025 		name = "packed";
9026 		break;
9027 	default:
9028 		TCU_FAIL("Invalid enum");
9029 	}
9030 
9031 	return name;
9032 }
9033 
9034 /** Constructor
9035  *
9036  * @param context Test framework context
9037  **/
9038 UniformBlockMemberInvalidOffsetAlignmentTest::UniformBlockMemberInvalidOffsetAlignmentTest(deqp::Context& context)
9039 	: NegativeTestBase(context, "uniform_block_member_invalid_offset_alignment",
9040 					   "Test verifies that invalid alignment of offset qualifiers cause compilation failure")
9041 {
9042 	/* Nothing to be done here */
9043 }
9044 
9045 /** Constructor
9046  *
9047  * @param context     Test framework context
9048  * @param name        Test name
9049  * @param description Test description
9050  **/
9051 UniformBlockMemberInvalidOffsetAlignmentTest::UniformBlockMemberInvalidOffsetAlignmentTest(
9052 	deqp::Context& context, const glw::GLchar* name, const glw::GLchar* description)
9053 	: NegativeTestBase(context, name, description)
9054 {
9055 	/* Nothing to be done here */
9056 }
9057 
9058 /** Source for given test case and stage
9059  *
9060  * @param test_case_index Index of test case
9061  * @param stage           Shader stage
9062  *
9063  * @return Shader source
9064  **/
9065 std::string UniformBlockMemberInvalidOffsetAlignmentTest::getShaderSource(GLuint				test_case_index,
9066 																		  Utils::Shader::STAGES stage)
9067 {
9068 	static const GLchar* cs = "#version 430 core\n"
9069 							  "#extension GL_ARB_enhanced_layouts : require\n"
9070 							  "\n"
9071 							  "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
9072 							  "\n"
9073 							  "layout (std140) uniform Block {\n"
9074 							  "    layout (offset = OFFSET) TYPE member;\n"
9075 							  "} block;\n"
9076 							  "\n"
9077 							  "writeonly uniform image2D uni_image;\n"
9078 							  "\n"
9079 							  "void main()\n"
9080 							  "{\n"
9081 							  "    vec4 result = vec4(1, 0, 0.5, 1);\n"
9082 							  "\n"
9083 							  "    if (TYPE(1) == block.member)\n"
9084 							  "    {\n"
9085 							  "        result = vec4(1, 1, 1, 1);\n"
9086 							  "    }\n"
9087 							  "\n"
9088 							  "    imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
9089 							  "}\n"
9090 							  "\n";
9091 	static const GLchar* fs = "#version 430 core\n"
9092 							  "#extension GL_ARB_enhanced_layouts : require\n"
9093 							  "\n"
9094 							  "in  vec4 gs_fs;\n"
9095 							  "out vec4 fs_out;\n"
9096 							  "\n"
9097 							  "void main()\n"
9098 							  "{\n"
9099 							  "    fs_out = gs_fs;\n"
9100 							  "}\n"
9101 							  "\n";
9102 	static const GLchar* fs_tested = "#version 430 core\n"
9103 									 "#extension GL_ARB_enhanced_layouts : require\n"
9104 									 "\n"
9105 									 "layout (std140) uniform Block {\n"
9106 									 "    layout (offset = OFFSET) TYPE member;\n"
9107 									 "} block;\n"
9108 									 "\n"
9109 									 "in  vec4 gs_fs;\n"
9110 									 "out vec4 fs_out;\n"
9111 									 "\n"
9112 									 "void main()\n"
9113 									 "{\n"
9114 									 "    if (TYPE(1) == block.member)\n"
9115 									 "    {\n"
9116 									 "        fs_out = vec4(1, 1, 1, 1);\n"
9117 									 "    }\n"
9118 									 "\n"
9119 									 "    fs_out += gs_fs;\n"
9120 									 "}\n"
9121 									 "\n";
9122 	static const GLchar* gs = "#version 430 core\n"
9123 							  "#extension GL_ARB_enhanced_layouts : require\n"
9124 							  "\n"
9125 							  "layout(points)                           in;\n"
9126 							  "layout(triangle_strip, max_vertices = 4) out;\n"
9127 							  "\n"
9128 							  "in  vec4 tes_gs[];\n"
9129 							  "out vec4 gs_fs;\n"
9130 							  "\n"
9131 							  "void main()\n"
9132 							  "{\n"
9133 							  "    gs_fs = tes_gs[0];\n"
9134 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
9135 							  "    EmitVertex();\n"
9136 							  "    gs_fs = tes_gs[0];\n"
9137 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
9138 							  "    EmitVertex();\n"
9139 							  "    gs_fs = tes_gs[0];\n"
9140 							  "    gl_Position  = vec4(1, -1, 0, 1);\n"
9141 							  "    EmitVertex();\n"
9142 							  "    gs_fs = tes_gs[0];\n"
9143 							  "    gl_Position  = vec4(1, 1, 0, 1);\n"
9144 							  "    EmitVertex();\n"
9145 							  "}\n"
9146 							  "\n";
9147 	static const GLchar* gs_tested = "#version 430 core\n"
9148 									 "#extension GL_ARB_enhanced_layouts : require\n"
9149 									 "\n"
9150 									 "layout(points)                           in;\n"
9151 									 "layout(triangle_strip, max_vertices = 4) out;\n"
9152 									 "\n"
9153 									 "layout (std140) uniform Block {\n"
9154 									 "    layout (offset = OFFSET) TYPE member;\n"
9155 									 "} block;\n"
9156 									 "\n"
9157 									 "in  vec4 tes_gs[];\n"
9158 									 "out vec4 gs_fs;\n"
9159 									 "\n"
9160 									 "void main()\n"
9161 									 "{\n"
9162 									 "    if (TYPE(1) == block.member)\n"
9163 									 "    {\n"
9164 									 "        gs_fs = vec4(1, 1, 1, 1);\n"
9165 									 "    }\n"
9166 									 "\n"
9167 									 "    gs_fs += tes_gs[0];\n"
9168 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
9169 									 "    EmitVertex();\n"
9170 									 "    gs_fs += tes_gs[0];\n"
9171 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
9172 									 "    EmitVertex();\n"
9173 									 "    gs_fs += tes_gs[0];\n"
9174 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
9175 									 "    EmitVertex();\n"
9176 									 "    gs_fs += tes_gs[0];\n"
9177 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
9178 									 "    EmitVertex();\n"
9179 									 "}\n"
9180 									 "\n";
9181 	static const GLchar* tcs = "#version 430 core\n"
9182 							   "#extension GL_ARB_enhanced_layouts : require\n"
9183 							   "\n"
9184 							   "layout(vertices = 1) out;\n"
9185 							   "\n"
9186 							   "in  vec4 vs_tcs[];\n"
9187 							   "out vec4 tcs_tes[];\n"
9188 							   "\n"
9189 							   "void main()\n"
9190 							   "{\n"
9191 							   "\n"
9192 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
9193 							   "\n"
9194 							   "    gl_TessLevelOuter[0] = 1.0;\n"
9195 							   "    gl_TessLevelOuter[1] = 1.0;\n"
9196 							   "    gl_TessLevelOuter[2] = 1.0;\n"
9197 							   "    gl_TessLevelOuter[3] = 1.0;\n"
9198 							   "    gl_TessLevelInner[0] = 1.0;\n"
9199 							   "    gl_TessLevelInner[1] = 1.0;\n"
9200 							   "}\n"
9201 							   "\n";
9202 	static const GLchar* tcs_tested = "#version 430 core\n"
9203 									  "#extension GL_ARB_enhanced_layouts : require\n"
9204 									  "\n"
9205 									  "layout(vertices = 1) out;\n"
9206 									  "\n"
9207 									  "layout (std140) uniform Block {\n"
9208 									  "    layout (offset = OFFSET) TYPE member;\n"
9209 									  "} block;\n"
9210 									  "\n"
9211 									  "in  vec4 vs_tcs[];\n"
9212 									  "out vec4 tcs_tes[];\n"
9213 									  "\n"
9214 									  "void main()\n"
9215 									  "{\n"
9216 									  "    if (TYPE(1) == block.member)\n"
9217 									  "    {\n"
9218 									  "        tcs_tes[gl_InvocationID] = vec4(1, 1, 1, 1);\n"
9219 									  "    }\n"
9220 									  "\n"
9221 									  "\n"
9222 									  "    tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
9223 									  "\n"
9224 									  "    gl_TessLevelOuter[0] = 1.0;\n"
9225 									  "    gl_TessLevelOuter[1] = 1.0;\n"
9226 									  "    gl_TessLevelOuter[2] = 1.0;\n"
9227 									  "    gl_TessLevelOuter[3] = 1.0;\n"
9228 									  "    gl_TessLevelInner[0] = 1.0;\n"
9229 									  "    gl_TessLevelInner[1] = 1.0;\n"
9230 									  "}\n"
9231 									  "\n";
9232 	static const GLchar* tes = "#version 430 core\n"
9233 							   "#extension GL_ARB_enhanced_layouts : require\n"
9234 							   "\n"
9235 							   "layout(isolines, point_mode) in;\n"
9236 							   "\n"
9237 							   "in  vec4 tcs_tes[];\n"
9238 							   "out vec4 tes_gs;\n"
9239 							   "\n"
9240 							   "void main()\n"
9241 							   "{\n"
9242 							   "    tes_gs = tcs_tes[0];\n"
9243 							   "}\n"
9244 							   "\n";
9245 	static const GLchar* tes_tested = "#version 430 core\n"
9246 									  "#extension GL_ARB_enhanced_layouts : require\n"
9247 									  "\n"
9248 									  "layout(isolines, point_mode) in;\n"
9249 									  "\n"
9250 									  "layout (std140) uniform Block {\n"
9251 									  "    layout (offset = OFFSET) TYPE member;\n"
9252 									  "} block;\n"
9253 									  "\n"
9254 									  "in  vec4 tcs_tes[];\n"
9255 									  "out vec4 tes_gs;\n"
9256 									  "\n"
9257 									  "void main()\n"
9258 									  "{\n"
9259 									  "    if (TYPE(1) == block.member)\n"
9260 									  "    {\n"
9261 									  "        tes_gs = vec4(1, 1, 1, 1);\n"
9262 									  "    }\n"
9263 									  "\n"
9264 									  "    tes_gs += tcs_tes[0];\n"
9265 									  "}\n"
9266 									  "\n";
9267 	static const GLchar* vs = "#version 430 core\n"
9268 							  "#extension GL_ARB_enhanced_layouts : require\n"
9269 							  "\n"
9270 							  "in  vec4 in_vs;\n"
9271 							  "out vec4 vs_tcs;\n"
9272 							  "\n"
9273 							  "void main()\n"
9274 							  "{\n"
9275 							  "    vs_tcs = in_vs;\n"
9276 							  "}\n"
9277 							  "\n";
9278 	static const GLchar* vs_tested = "#version 430 core\n"
9279 									 "#extension GL_ARB_enhanced_layouts : require\n"
9280 									 "\n"
9281 									 "layout (std140) uniform Block {\n"
9282 									 "    layout (offset = OFFSET) TYPE member;\n"
9283 									 "} block;\n"
9284 									 "\n"
9285 									 "in  vec4 in_vs;\n"
9286 									 "out vec4 vs_tcs;\n"
9287 									 "\n"
9288 									 "void main()\n"
9289 									 "{\n"
9290 									 "    if (TYPE(1) == block.member)\n"
9291 									 "    {\n"
9292 									 "        vs_tcs = vec4(1, 1, 1, 1);\n"
9293 									 "    }\n"
9294 									 "\n"
9295 									 "    vs_tcs += in_vs;\n"
9296 									 "}\n"
9297 									 "\n";
9298 
9299 	std::string source;
9300 	testCase&   test_case = m_test_cases[test_case_index];
9301 
9302 	if (test_case.m_stage == stage)
9303 	{
9304 		GLchar			   buffer[16];
9305 		const GLuint	   offset	= test_case.m_offset;
9306 		size_t			   position  = 0;
9307 		const Utils::Type& type		 = test_case.m_type;
9308 		const GLchar*	  type_name = type.GetGLSLTypeName();
9309 
9310 		sprintf(buffer, "%d", offset);
9311 
9312 		switch (stage)
9313 		{
9314 		case Utils::Shader::COMPUTE:
9315 			source = cs;
9316 			break;
9317 		case Utils::Shader::FRAGMENT:
9318 			source = fs_tested;
9319 			break;
9320 		case Utils::Shader::GEOMETRY:
9321 			source = gs_tested;
9322 			break;
9323 		case Utils::Shader::TESS_CTRL:
9324 			source = tcs_tested;
9325 			break;
9326 		case Utils::Shader::TESS_EVAL:
9327 			source = tes_tested;
9328 			break;
9329 		case Utils::Shader::VERTEX:
9330 			source = vs_tested;
9331 			break;
9332 		default:
9333 			TCU_FAIL("Invalid enum");
9334 		}
9335 
9336 		Utils::replaceToken("OFFSET", position, buffer, source);
9337 		Utils::replaceToken("TYPE", position, type_name, source);
9338 		Utils::replaceToken("TYPE", position, type_name, source);
9339 	}
9340 	else
9341 	{
9342 		switch (stage)
9343 		{
9344 		case Utils::Shader::FRAGMENT:
9345 			source = fs;
9346 			break;
9347 		case Utils::Shader::GEOMETRY:
9348 			source = gs;
9349 			break;
9350 		case Utils::Shader::TESS_CTRL:
9351 			source = tcs;
9352 			break;
9353 		case Utils::Shader::TESS_EVAL:
9354 			source = tes;
9355 			break;
9356 		case Utils::Shader::VERTEX:
9357 			source = vs;
9358 			break;
9359 		default:
9360 			TCU_FAIL("Invalid enum");
9361 		}
9362 	}
9363 
9364 	return source;
9365 }
9366 
9367 /** Get description of test case
9368  *
9369  * @param test_case_index Index of test case
9370  *
9371  * @return Type name and offset
9372  **/
9373 std::string UniformBlockMemberInvalidOffsetAlignmentTest::getTestCaseName(GLuint test_case_index)
9374 {
9375 	std::stringstream stream;
9376 	testCase&		  test_case = m_test_cases[test_case_index];
9377 
9378 	stream << "Type: " << test_case.m_type.GetGLSLTypeName() << ", offset: " << test_case.m_offset;
9379 
9380 	return stream.str();
9381 }
9382 
9383 /** Get number of test cases
9384  *
9385  * @return Number of test cases
9386  **/
9387 GLuint UniformBlockMemberInvalidOffsetAlignmentTest::getTestCaseNumber()
9388 {
9389 	return static_cast<GLuint>(m_test_cases.size());
9390 }
9391 
9392 /** Get the maximum size for an uniform block
9393  *
9394  * @return The maximum size in basic machine units of a uniform block.
9395  **/
9396 GLint UniformBlockMemberInvalidOffsetAlignmentTest::getMaxBlockSize()
9397 {
9398 	const Functions& gl		  = m_context.getRenderContext().getFunctions();
9399 	GLint			 max_size = 0;
9400 
9401 	gl.getIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &max_size);
9402 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
9403 
9404 	return max_size;
9405 }
9406 
9407 /** Selects if "compute" stage is relevant for test
9408  *
9409  * @param test_case_index Index of test case
9410  *
9411  * @return true when tested stage is compute
9412  **/
9413 bool UniformBlockMemberInvalidOffsetAlignmentTest::isComputeRelevant(GLuint test_case_index)
9414 {
9415 	return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
9416 }
9417 
9418 /** Selects if compilation failure is expected result
9419  *
9420  * @param test_case_index Index of test case
9421  *
9422  * @return should_fail field from testCase
9423  **/
9424 bool UniformBlockMemberInvalidOffsetAlignmentTest::isFailureExpected(GLuint test_case_index)
9425 {
9426 	return m_test_cases[test_case_index].m_should_fail;
9427 }
9428 
9429 /** Checks if stage is supported
9430  *
9431  * @param stage ignored
9432  *
9433  * @return true
9434  **/
9435 bool UniformBlockMemberInvalidOffsetAlignmentTest::isStageSupported(Utils::Shader::STAGES /* stage */)
9436 {
9437 	return true;
9438 }
9439 
9440 /** Prepare all test cases
9441  *
9442  **/
9443 void UniformBlockMemberInvalidOffsetAlignmentTest::testInit()
9444 {
9445 	const GLuint n_types = getTypesNumber();
9446 	bool		 stage_support[Utils::Shader::STAGE_MAX];
9447 
9448 	for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
9449 	{
9450 		stage_support[stage] = isStageSupported((Utils::Shader::STAGES)stage);
9451 	}
9452 
9453 	for (GLuint i = 0; i < n_types; ++i)
9454 	{
9455 		const Utils::Type& type		  = getType(i);
9456 		const GLuint	   alignment  = type.GetBaseAlignment(false);
9457 		const GLuint	   type_size  = type.GetSize(true);
9458 		const GLuint	   sec_to_end = getMaxBlockSize() - 2 * type_size;
9459 
9460 		for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
9461 		{
9462 			if (false == stage_support[stage])
9463 			{
9464 				continue;
9465 			}
9466 
9467 			for (GLuint offset = 0; offset <= type_size; ++offset)
9468 			{
9469 				const GLuint modulo		 = offset % alignment;
9470 				const bool   is_aligned  = (0 == modulo) ? true : false;
9471 				const bool   should_fail = !is_aligned;
9472 
9473 				testCase test_case = { offset, should_fail, (Utils::Shader::STAGES)stage, type };
9474 
9475 				m_test_cases.push_back(test_case);
9476 			}
9477 
9478 			for (GLuint offset = sec_to_end; offset <= sec_to_end + type_size; ++offset)
9479 			{
9480 				const GLuint modulo		 = offset % alignment;
9481 				const bool   is_aligned  = (0 == modulo) ? true : false;
9482 				const bool   should_fail = !is_aligned;
9483 
9484 				testCase test_case = { offset, should_fail, (Utils::Shader::STAGES)stage, type };
9485 
9486 				m_test_cases.push_back(test_case);
9487 			}
9488 		}
9489 	}
9490 }
9491 
9492 /** Constructor
9493  *
9494  * @param context Test framework context
9495  **/
9496 UniformBlockMemberOverlappingOffsetsTest::UniformBlockMemberOverlappingOffsetsTest(deqp::Context& context)
9497 	: NegativeTestBase(context, "uniform_block_member_overlapping_offsets",
9498 					   "Test verifies that overlapping offsets qualifiers cause compilation failure")
9499 {
9500 	/* Nothing to be done here */
9501 }
9502 
9503 /** Constructor
9504  *
9505  * @param context Test framework context
9506  * @param name        Test name
9507  * @param description Test description
9508  **/
9509 UniformBlockMemberOverlappingOffsetsTest::UniformBlockMemberOverlappingOffsetsTest(deqp::Context&	 context,
9510 																				   const glw::GLchar* name,
9511 																				   const glw::GLchar* description)
9512 	: NegativeTestBase(context, name, description)
9513 {
9514 	/* Nothing to be done here */
9515 }
9516 
9517 /** Source for given test case and stage
9518  *
9519  * @param test_case_index Index of test case
9520  * @param stage           Shader stage
9521  *
9522  * @return Shader source
9523  **/
9524 std::string UniformBlockMemberOverlappingOffsetsTest::getShaderSource(GLuint				test_case_index,
9525 																	  Utils::Shader::STAGES stage)
9526 {
9527 	static const GLchar* cs = "#version 430 core\n"
9528 							  "#extension GL_ARB_enhanced_layouts : require\n"
9529 							  "\n"
9530 							  "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
9531 							  "\n"
9532 							  "layout (std140) uniform Block {\n"
9533 							  "    layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9534 							  "    layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9535 							  "} block;\n"
9536 							  "\n"
9537 							  "writeonly uniform image2D uni_image;\n"
9538 							  "\n"
9539 							  "void main()\n"
9540 							  "{\n"
9541 							  "    vec4 result = vec4(1, 0, 0.5, 1);\n"
9542 							  "\n"
9543 							  "    if ((BOY_TYPE(1) == block.boy) ||\n"
9544 							  "        (MAN_TYPE(0) == block.man) )\n"
9545 							  "    {\n"
9546 							  "        result = vec4(1, 1, 1, 1);\n"
9547 							  "    }\n"
9548 							  "\n"
9549 							  "    imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
9550 							  "}\n"
9551 							  "\n";
9552 	static const GLchar* fs = "#version 430 core\n"
9553 							  "#extension GL_ARB_enhanced_layouts : require\n"
9554 							  "\n"
9555 							  "in  vec4 gs_fs;\n"
9556 							  "out vec4 fs_out;\n"
9557 							  "\n"
9558 							  "void main()\n"
9559 							  "{\n"
9560 							  "    fs_out = gs_fs;\n"
9561 							  "}\n"
9562 							  "\n";
9563 	static const GLchar* fs_tested = "#version 430 core\n"
9564 									 "#extension GL_ARB_enhanced_layouts : require\n"
9565 									 "\n"
9566 									 "layout (std140) uniform Block {\n"
9567 									 "    layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9568 									 "    layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9569 									 "} block;\n"
9570 									 "\n"
9571 									 "in  vec4 gs_fs;\n"
9572 									 "out vec4 fs_out;\n"
9573 									 "\n"
9574 									 "void main()\n"
9575 									 "{\n"
9576 									 "    if ((BOY_TYPE(1) == block.boy) ||\n"
9577 									 "        (MAN_TYPE(0) == block.man) )\n"
9578 									 "    {\n"
9579 									 "        fs_out = vec4(1, 1, 1, 1);\n"
9580 									 "    }\n"
9581 									 "\n"
9582 									 "    fs_out += gs_fs;\n"
9583 									 "}\n"
9584 									 "\n";
9585 	static const GLchar* gs = "#version 430 core\n"
9586 							  "#extension GL_ARB_enhanced_layouts : require\n"
9587 							  "\n"
9588 							  "layout(points)                           in;\n"
9589 							  "layout(triangle_strip, max_vertices = 4) out;\n"
9590 							  "\n"
9591 							  "in  vec4 tes_gs[];\n"
9592 							  "out vec4 gs_fs;\n"
9593 							  "\n"
9594 							  "void main()\n"
9595 							  "{\n"
9596 							  "    gs_fs = tes_gs[0];\n"
9597 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
9598 							  "    EmitVertex();\n"
9599 							  "    gs_fs = tes_gs[0];\n"
9600 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
9601 							  "    EmitVertex();\n"
9602 							  "    gs_fs = tes_gs[0];\n"
9603 							  "    gl_Position  = vec4(1, -1, 0, 1);\n"
9604 							  "    EmitVertex();\n"
9605 							  "    gs_fs = tes_gs[0];\n"
9606 							  "    gl_Position  = vec4(1, 1, 0, 1);\n"
9607 							  "    EmitVertex();\n"
9608 							  "}\n"
9609 							  "\n";
9610 	static const GLchar* gs_tested = "#version 430 core\n"
9611 									 "#extension GL_ARB_enhanced_layouts : require\n"
9612 									 "\n"
9613 									 "layout(points)                           in;\n"
9614 									 "layout(triangle_strip, max_vertices = 4) out;\n"
9615 									 "\n"
9616 									 "layout (std140) uniform Block {\n"
9617 									 "    layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9618 									 "    layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9619 									 "} block;\n"
9620 									 "\n"
9621 									 "in  vec4 tes_gs[];\n"
9622 									 "out vec4 gs_fs;\n"
9623 									 "\n"
9624 									 "void main()\n"
9625 									 "{\n"
9626 									 "    if ((BOY_TYPE(1) == block.boy) ||\n"
9627 									 "        (MAN_TYPE(0) == block.man) )\n"
9628 									 "    {\n"
9629 									 "        gs_fs = vec4(1, 1, 1, 1);\n"
9630 									 "    }\n"
9631 									 "\n"
9632 									 "    gs_fs += tes_gs[0];\n"
9633 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
9634 									 "    EmitVertex();\n"
9635 									 "    gs_fs += tes_gs[0];\n"
9636 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
9637 									 "    EmitVertex();\n"
9638 									 "    gs_fs += tes_gs[0];\n"
9639 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
9640 									 "    EmitVertex();\n"
9641 									 "    gs_fs += tes_gs[0];\n"
9642 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
9643 									 "    EmitVertex();\n"
9644 									 "}\n"
9645 									 "\n";
9646 	static const GLchar* tcs = "#version 430 core\n"
9647 							   "#extension GL_ARB_enhanced_layouts : require\n"
9648 							   "\n"
9649 							   "layout(vertices = 1) out;\n"
9650 							   "\n"
9651 							   "in  vec4 vs_tcs[];\n"
9652 							   "out vec4 tcs_tes[];\n"
9653 							   "\n"
9654 							   "void main()\n"
9655 							   "{\n"
9656 							   "\n"
9657 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
9658 							   "\n"
9659 							   "    gl_TessLevelOuter[0] = 1.0;\n"
9660 							   "    gl_TessLevelOuter[1] = 1.0;\n"
9661 							   "    gl_TessLevelOuter[2] = 1.0;\n"
9662 							   "    gl_TessLevelOuter[3] = 1.0;\n"
9663 							   "    gl_TessLevelInner[0] = 1.0;\n"
9664 							   "    gl_TessLevelInner[1] = 1.0;\n"
9665 							   "}\n"
9666 							   "\n";
9667 	static const GLchar* tcs_tested = "#version 430 core\n"
9668 									  "#extension GL_ARB_enhanced_layouts : require\n"
9669 									  "\n"
9670 									  "layout(vertices = 1) out;\n"
9671 									  "\n"
9672 									  "layout (std140) uniform Block {\n"
9673 									  "    layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9674 									  "    layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9675 									  "} block;\n"
9676 									  "\n"
9677 									  "in  vec4 vs_tcs[];\n"
9678 									  "out vec4 tcs_tes[];\n"
9679 									  "\n"
9680 									  "void main()\n"
9681 									  "{\n"
9682 									  "    if ((BOY_TYPE(1) == block.boy) ||\n"
9683 									  "        (MAN_TYPE(0) == block.man) )\n"
9684 									  "    {\n"
9685 									  "        tcs_tes[gl_InvocationID] = vec4(1, 1, 1, 1);\n"
9686 									  "    }\n"
9687 									  "\n"
9688 									  "\n"
9689 									  "    tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
9690 									  "\n"
9691 									  "    gl_TessLevelOuter[0] = 1.0;\n"
9692 									  "    gl_TessLevelOuter[1] = 1.0;\n"
9693 									  "    gl_TessLevelOuter[2] = 1.0;\n"
9694 									  "    gl_TessLevelOuter[3] = 1.0;\n"
9695 									  "    gl_TessLevelInner[0] = 1.0;\n"
9696 									  "    gl_TessLevelInner[1] = 1.0;\n"
9697 									  "}\n"
9698 									  "\n";
9699 	static const GLchar* tes = "#version 430 core\n"
9700 							   "#extension GL_ARB_enhanced_layouts : require\n"
9701 							   "\n"
9702 							   "layout(isolines, point_mode) in;\n"
9703 							   "\n"
9704 							   "in  vec4 tcs_tes[];\n"
9705 							   "out vec4 tes_gs;\n"
9706 							   "\n"
9707 							   "void main()\n"
9708 							   "{\n"
9709 							   "    tes_gs = tcs_tes[0];\n"
9710 							   "}\n"
9711 							   "\n";
9712 	static const GLchar* tes_tested = "#version 430 core\n"
9713 									  "#extension GL_ARB_enhanced_layouts : require\n"
9714 									  "\n"
9715 									  "layout(isolines, point_mode) in;\n"
9716 									  "\n"
9717 									  "layout (std140) uniform Block {\n"
9718 									  "    layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9719 									  "    layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9720 									  "} block;\n"
9721 									  "\n"
9722 									  "in  vec4 tcs_tes[];\n"
9723 									  "out vec4 tes_gs;\n"
9724 									  "\n"
9725 									  "void main()\n"
9726 									  "{\n"
9727 									  "    if ((BOY_TYPE(1) == block.boy) ||\n"
9728 									  "        (MAN_TYPE(0) == block.man) )\n"
9729 									  "    {\n"
9730 									  "        tes_gs = vec4(1, 1, 1, 1);\n"
9731 									  "    }\n"
9732 									  "\n"
9733 									  "    tes_gs += tcs_tes[0];\n"
9734 									  "}\n"
9735 									  "\n";
9736 	static const GLchar* vs = "#version 430 core\n"
9737 							  "#extension GL_ARB_enhanced_layouts : require\n"
9738 							  "\n"
9739 							  "in  vec4 in_vs;\n"
9740 							  "out vec4 vs_tcs;\n"
9741 							  "\n"
9742 							  "void main()\n"
9743 							  "{\n"
9744 							  "    vs_tcs = in_vs;\n"
9745 							  "}\n"
9746 							  "\n";
9747 	static const GLchar* vs_tested = "#version 430 core\n"
9748 									 "#extension GL_ARB_enhanced_layouts : require\n"
9749 									 "\n"
9750 									 "layout (std140) uniform Block {\n"
9751 									 "    layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9752 									 "    layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9753 									 "} block;\n"
9754 									 "\n"
9755 									 "in  vec4 in_vs;\n"
9756 									 "out vec4 vs_tcs;\n"
9757 									 "\n"
9758 									 "void main()\n"
9759 									 "{\n"
9760 									 "    if ((BOY_TYPE(1) == block.boy) ||\n"
9761 									 "        (MAN_TYPE(0) == block.man) )\n"
9762 									 "    {\n"
9763 									 "        vs_tcs = vec4(1, 1, 1, 1);\n"
9764 									 "    }\n"
9765 									 "\n"
9766 									 "    vs_tcs += in_vs;\n"
9767 									 "}\n"
9768 									 "\n";
9769 
9770 	std::string source;
9771 	testCase&   test_case = m_test_cases[test_case_index];
9772 
9773 	if (test_case.m_stage == stage)
9774 	{
9775 		GLchar			   buffer[16];
9776 		const GLuint	   boy_offset	= test_case.m_boy_offset;
9777 		const Utils::Type& boy_type		 = test_case.m_boy_type;
9778 		const GLchar*	  boy_type_name = boy_type.GetGLSLTypeName();
9779 		const GLuint	   man_offset	= test_case.m_man_offset;
9780 		const Utils::Type& man_type		 = test_case.m_man_type;
9781 		const GLchar*	  man_type_name = man_type.GetGLSLTypeName();
9782 		size_t			   position		 = 0;
9783 
9784 		switch (stage)
9785 		{
9786 		case Utils::Shader::COMPUTE:
9787 			source = cs;
9788 			break;
9789 		case Utils::Shader::FRAGMENT:
9790 			source = fs_tested;
9791 			break;
9792 		case Utils::Shader::GEOMETRY:
9793 			source = gs_tested;
9794 			break;
9795 		case Utils::Shader::TESS_CTRL:
9796 			source = tcs_tested;
9797 			break;
9798 		case Utils::Shader::TESS_EVAL:
9799 			source = tes_tested;
9800 			break;
9801 		case Utils::Shader::VERTEX:
9802 			source = vs_tested;
9803 			break;
9804 		default:
9805 			TCU_FAIL("Invalid enum");
9806 		}
9807 
9808 		sprintf(buffer, "%d", boy_offset);
9809 		Utils::replaceToken("BOY_OFFSET", position, buffer, source);
9810 		Utils::replaceToken("BOY_TYPE", position, boy_type_name, source);
9811 		sprintf(buffer, "%d", man_offset);
9812 		Utils::replaceToken("MAN_OFFSET", position, buffer, source);
9813 		Utils::replaceToken("MAN_TYPE", position, man_type_name, source);
9814 		Utils::replaceToken("BOY_TYPE", position, boy_type_name, source);
9815 		Utils::replaceToken("MAN_TYPE", position, man_type_name, source);
9816 	}
9817 	else
9818 	{
9819 		switch (stage)
9820 		{
9821 		case Utils::Shader::FRAGMENT:
9822 			source = fs;
9823 			break;
9824 		case Utils::Shader::GEOMETRY:
9825 			source = gs;
9826 			break;
9827 		case Utils::Shader::TESS_CTRL:
9828 			source = tcs;
9829 			break;
9830 		case Utils::Shader::TESS_EVAL:
9831 			source = tes;
9832 			break;
9833 		case Utils::Shader::VERTEX:
9834 			source = vs;
9835 			break;
9836 		default:
9837 			TCU_FAIL("Invalid enum");
9838 		}
9839 	}
9840 
9841 	return source;
9842 }
9843 
9844 /** Get description of test case
9845  *
9846  * @param test_case_index Index of test case
9847  *
9848  * @return Type name and offset
9849  **/
9850 std::string UniformBlockMemberOverlappingOffsetsTest::getTestCaseName(GLuint test_case_index)
9851 {
9852 	std::stringstream stream;
9853 	testCase&		  test_case = m_test_cases[test_case_index];
9854 
9855 	stream << "Type: " << test_case.m_boy_type.GetGLSLTypeName() << ", offset: " << test_case.m_boy_offset
9856 		   << ". Type: " << test_case.m_man_type.GetGLSLTypeName() << ", offset: " << test_case.m_man_offset;
9857 
9858 	return stream.str();
9859 }
9860 
9861 /** Get number of test cases
9862  *
9863  * @return Number of test cases
9864  **/
9865 GLuint UniformBlockMemberOverlappingOffsetsTest::getTestCaseNumber()
9866 {
9867 	return static_cast<GLuint>(m_test_cases.size());
9868 }
9869 
9870 /** Selects if "compute" stage is relevant for test
9871  *
9872  * @param test_case_index Index of test case
9873  *
9874  * @return true when tested stage is compute
9875  **/
9876 bool UniformBlockMemberOverlappingOffsetsTest::isComputeRelevant(GLuint test_case_index)
9877 {
9878 	return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
9879 }
9880 
9881 /** Checks if stage is supported
9882  *
9883  * @param stage ignored
9884  *
9885  * @return true
9886  **/
9887 bool UniformBlockMemberOverlappingOffsetsTest::isStageSupported(Utils::Shader::STAGES /* stage */)
9888 {
9889 	return true;
9890 }
9891 
9892 /** Prepare all test cases
9893  *
9894  **/
9895 void UniformBlockMemberOverlappingOffsetsTest::testInit()
9896 {
9897 	const GLuint n_types = getTypesNumber();
9898 	bool		 stage_support[Utils::Shader::STAGE_MAX];
9899 
9900 	for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
9901 	{
9902 		stage_support[stage] = isStageSupported((Utils::Shader::STAGES)stage);
9903 	}
9904 
9905 	for (GLuint i = 0; i < n_types; ++i)
9906 	{
9907 		const Utils::Type& boy_type = getType(i);
9908 		const GLuint	   boy_size = boy_type.GetActualAlignment(1 /* align */, false /* is_array*/);
9909 
9910 		for (GLuint j = 0; j < n_types; ++j)
9911 		{
9912 			const Utils::Type& man_type  = getType(j);
9913 			const GLuint	   man_align = man_type.GetBaseAlignment(false);
9914 			const GLuint	   man_size  = man_type.GetActualAlignment(1 /* align */, false /* is_array*/);
9915 
9916 			const GLuint boy_offset		  = lcm(boy_size, man_size);
9917 			const GLuint man_after_start  = boy_offset + 1;
9918 			const GLuint man_after_off	= man_type.GetActualOffset(man_after_start, man_size);
9919 			const GLuint man_before_start = boy_offset - man_align;
9920 			const GLuint man_before_off   = man_type.GetActualOffset(man_before_start, man_size);
9921 
9922 			for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
9923 			{
9924 				if (false == stage_support[stage])
9925 				{
9926 					continue;
9927 				}
9928 
9929 				if ((boy_offset > man_before_off) && (boy_offset < man_before_off + man_size))
9930 				{
9931 					testCase test_case = { boy_offset, boy_type, man_before_off, man_type,
9932 										   (Utils::Shader::STAGES)stage };
9933 
9934 					m_test_cases.push_back(test_case);
9935 				}
9936 
9937 				if ((boy_offset < man_after_off) && (boy_offset + boy_size > man_after_off))
9938 				{
9939 					testCase test_case = { boy_offset, boy_type, man_after_off, man_type,
9940 										   (Utils::Shader::STAGES)stage };
9941 
9942 					m_test_cases.push_back(test_case);
9943 				}
9944 
9945 				/* Boy offset, should be fine for both types */
9946 				testCase test_case = { boy_offset, boy_type, boy_offset, man_type, (Utils::Shader::STAGES)stage };
9947 
9948 				m_test_cases.push_back(test_case);
9949 			}
9950 		}
9951 	}
9952 }
9953 
9954 /** Find greatest common divisor for a and b
9955  *
9956  * @param a A argument
9957  * @param b B argument
9958  *
9959  * @return Found gcd value
9960  **/
9961 GLuint UniformBlockMemberOverlappingOffsetsTest::gcd(GLuint a, GLuint b)
9962 {
9963 	if ((0 != a) && (0 == b))
9964 	{
9965 		return a;
9966 	}
9967 	else
9968 	{
9969 		GLuint greater = std::max(a, b);
9970 		GLuint lesser  = std::min(a, b);
9971 
9972 		return gcd(lesser, greater % lesser);
9973 	}
9974 }
9975 
9976 /** Find lowest common multiple for a and b
9977  *
9978  * @param a A argument
9979  * @param b B argument
9980  *
9981  * @return Found gcd value
9982  **/
9983 GLuint UniformBlockMemberOverlappingOffsetsTest::lcm(GLuint a, GLuint b)
9984 {
9985 	return (a * b) / gcd(a, b);
9986 }
9987 
9988 /** Constructor
9989  *
9990  * @param context Test framework context
9991  **/
9992 UniformBlockMemberAlignNonPowerOf2Test::UniformBlockMemberAlignNonPowerOf2Test(deqp::Context& context)
9993 	: NegativeTestBase(context, "uniform_block_member_align_non_power_of_2",
9994 					   "Test verifies that align qualifier requires value that is a power of 2")
9995 {
9996 	/* Nothing to be done here */
9997 }
9998 
9999 /** Constructor
10000  *
10001  * @param context Test framework context
10002  * @param name        Test name
10003  * @param description Test description
10004  **/
10005 UniformBlockMemberAlignNonPowerOf2Test::UniformBlockMemberAlignNonPowerOf2Test(deqp::Context&	 context,
10006 																			   const glw::GLchar* name,
10007 																			   const glw::GLchar* description)
10008 	: NegativeTestBase(context, name, description)
10009 {
10010 	/* Nothing to be done here */
10011 }
10012 
10013 /** Source for given test case and stage
10014  *
10015  * @param test_case_index Index of test case
10016  * @param stage           Shader stage
10017  *
10018  * @return Shader source
10019  **/
10020 std::string UniformBlockMemberAlignNonPowerOf2Test::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
10021 {
10022 	static const GLchar* cs = "#version 430 core\n"
10023 							  "#extension GL_ARB_enhanced_layouts : require\n"
10024 							  "\n"
10025 							  "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
10026 							  "\n"
10027 							  "layout (std140) uniform Block {\n"
10028 							  "    vec4 boy;\n"
10029 							  "    layout (align = ALIGN) TYPE man;\n"
10030 							  "} block;\n"
10031 							  "\n"
10032 							  "writeonly uniform image2D uni_image;\n"
10033 							  "\n"
10034 							  "void main()\n"
10035 							  "{\n"
10036 							  "    vec4 result = vec4(1, 0, 0.5, 1);\n"
10037 							  "\n"
10038 							  "    if (TYPE(0) == block.man)\n"
10039 							  "    {\n"
10040 							  "        result = vec4(1, 1, 1, 1) - block.boy;\n"
10041 							  "    }\n"
10042 							  "\n"
10043 							  "    imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
10044 							  "}\n"
10045 							  "\n";
10046 	static const GLchar* fs = "#version 430 core\n"
10047 							  "#extension GL_ARB_enhanced_layouts : require\n"
10048 							  "\n"
10049 							  "in  vec4 gs_fs;\n"
10050 							  "out vec4 fs_out;\n"
10051 							  "\n"
10052 							  "void main()\n"
10053 							  "{\n"
10054 							  "    fs_out = gs_fs;\n"
10055 							  "}\n"
10056 							  "\n";
10057 	static const GLchar* fs_tested = "#version 430 core\n"
10058 									 "#extension GL_ARB_enhanced_layouts : require\n"
10059 									 "\n"
10060 									 "layout (std140) uniform Block {\n"
10061 									 "    vec4 boy;\n"
10062 									 "    layout (align = ALIGN) TYPE man;\n"
10063 									 "} block;\n"
10064 									 "\n"
10065 									 "in  vec4 gs_fs;\n"
10066 									 "out vec4 fs_out;\n"
10067 									 "\n"
10068 									 "void main()\n"
10069 									 "{\n"
10070 									 "    if (TYPE(0) == block.man)\n"
10071 									 "    {\n"
10072 									 "        fs_out = block.boy;\n"
10073 									 "    }\n"
10074 									 "\n"
10075 									 "    fs_out += gs_fs;\n"
10076 									 "}\n"
10077 									 "\n";
10078 	static const GLchar* gs = "#version 430 core\n"
10079 							  "#extension GL_ARB_enhanced_layouts : require\n"
10080 							  "\n"
10081 							  "layout(points)                           in;\n"
10082 							  "layout(triangle_strip, max_vertices = 4) out;\n"
10083 							  "\n"
10084 							  "in  vec4 tes_gs[];\n"
10085 							  "out vec4 gs_fs;\n"
10086 							  "\n"
10087 							  "void main()\n"
10088 							  "{\n"
10089 							  "    gs_fs = tes_gs[0];\n"
10090 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
10091 							  "    EmitVertex();\n"
10092 							  "    gs_fs = tes_gs[0];\n"
10093 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
10094 							  "    EmitVertex();\n"
10095 							  "    gs_fs = tes_gs[0];\n"
10096 							  "    gl_Position  = vec4(1, -1, 0, 1);\n"
10097 							  "    EmitVertex();\n"
10098 							  "    gs_fs = tes_gs[0];\n"
10099 							  "    gl_Position  = vec4(1, 1, 0, 1);\n"
10100 							  "    EmitVertex();\n"
10101 							  "}\n"
10102 							  "\n";
10103 	static const GLchar* gs_tested = "#version 430 core\n"
10104 									 "#extension GL_ARB_enhanced_layouts : require\n"
10105 									 "\n"
10106 									 "layout(points)                           in;\n"
10107 									 "layout(triangle_strip, max_vertices = 4) out;\n"
10108 									 "\n"
10109 									 "layout (std140) uniform Block {\n"
10110 									 "    vec4 boy;\n"
10111 									 "    layout (align = ALIGN) TYPE man;\n"
10112 									 "} block;\n"
10113 									 "\n"
10114 									 "in  vec4 tes_gs[];\n"
10115 									 "out vec4 gs_fs;\n"
10116 									 "\n"
10117 									 "void main()\n"
10118 									 "{\n"
10119 									 "    if (TYPE(0) == block.man)\n"
10120 									 "    {\n"
10121 									 "        gs_fs = block.boy;\n"
10122 									 "    }\n"
10123 									 "\n"
10124 									 "    gs_fs += tes_gs[0];\n"
10125 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
10126 									 "    EmitVertex();\n"
10127 									 "    gs_fs += tes_gs[0];\n"
10128 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
10129 									 "    EmitVertex();\n"
10130 									 "    gs_fs += tes_gs[0];\n"
10131 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
10132 									 "    EmitVertex();\n"
10133 									 "    gs_fs += tes_gs[0];\n"
10134 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
10135 									 "    EmitVertex();\n"
10136 									 "}\n"
10137 									 "\n";
10138 	static const GLchar* tcs = "#version 430 core\n"
10139 							   "#extension GL_ARB_enhanced_layouts : require\n"
10140 							   "\n"
10141 							   "layout(vertices = 1) out;\n"
10142 							   "\n"
10143 							   "in  vec4 vs_tcs[];\n"
10144 							   "out vec4 tcs_tes[];\n"
10145 							   "\n"
10146 							   "void main()\n"
10147 							   "{\n"
10148 							   "\n"
10149 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
10150 							   "\n"
10151 							   "    gl_TessLevelOuter[0] = 1.0;\n"
10152 							   "    gl_TessLevelOuter[1] = 1.0;\n"
10153 							   "    gl_TessLevelOuter[2] = 1.0;\n"
10154 							   "    gl_TessLevelOuter[3] = 1.0;\n"
10155 							   "    gl_TessLevelInner[0] = 1.0;\n"
10156 							   "    gl_TessLevelInner[1] = 1.0;\n"
10157 							   "}\n"
10158 							   "\n";
10159 	static const GLchar* tcs_tested = "#version 430 core\n"
10160 									  "#extension GL_ARB_enhanced_layouts : require\n"
10161 									  "\n"
10162 									  "layout(vertices = 1) out;\n"
10163 									  "\n"
10164 									  "layout (std140) uniform Block {\n"
10165 									  "    vec4 boy;\n"
10166 									  "    layout (align = ALIGN) TYPE man;\n"
10167 									  "} block;\n"
10168 									  "\n"
10169 									  "in  vec4 vs_tcs[];\n"
10170 									  "out vec4 tcs_tes[];\n"
10171 									  "\n"
10172 									  "void main()\n"
10173 									  "{\n"
10174 									  "    if (TYPE(0) == block.man)\n"
10175 									  "    {\n"
10176 									  "        tcs_tes[gl_InvocationID] = block.boy;\n"
10177 									  "    }\n"
10178 									  "\n"
10179 									  "\n"
10180 									  "    tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
10181 									  "\n"
10182 									  "    gl_TessLevelOuter[0] = 1.0;\n"
10183 									  "    gl_TessLevelOuter[1] = 1.0;\n"
10184 									  "    gl_TessLevelOuter[2] = 1.0;\n"
10185 									  "    gl_TessLevelOuter[3] = 1.0;\n"
10186 									  "    gl_TessLevelInner[0] = 1.0;\n"
10187 									  "    gl_TessLevelInner[1] = 1.0;\n"
10188 									  "}\n"
10189 									  "\n";
10190 	static const GLchar* tes = "#version 430 core\n"
10191 							   "#extension GL_ARB_enhanced_layouts : require\n"
10192 							   "\n"
10193 							   "layout(isolines, point_mode) in;\n"
10194 							   "\n"
10195 							   "in  vec4 tcs_tes[];\n"
10196 							   "out vec4 tes_gs;\n"
10197 							   "\n"
10198 							   "void main()\n"
10199 							   "{\n"
10200 							   "    tes_gs = tcs_tes[0];\n"
10201 							   "}\n"
10202 							   "\n";
10203 	static const GLchar* tes_tested = "#version 430 core\n"
10204 									  "#extension GL_ARB_enhanced_layouts : require\n"
10205 									  "\n"
10206 									  "layout(isolines, point_mode) in;\n"
10207 									  "\n"
10208 									  "layout (std140) uniform Block {\n"
10209 									  "    vec4 boy;\n"
10210 									  "    layout (align = ALIGN) TYPE man;\n"
10211 									  "} block;\n"
10212 									  "\n"
10213 									  "in  vec4 tcs_tes[];\n"
10214 									  "out vec4 tes_gs;\n"
10215 									  "\n"
10216 									  "void main()\n"
10217 									  "{\n"
10218 									  "    if (TYPE(0) == block.man)\n"
10219 									  "    {\n"
10220 									  "        tes_gs = block.boy;\n"
10221 									  "    }\n"
10222 									  "\n"
10223 									  "    tes_gs += tcs_tes[0];\n"
10224 									  "}\n"
10225 									  "\n";
10226 	static const GLchar* vs = "#version 430 core\n"
10227 							  "#extension GL_ARB_enhanced_layouts : require\n"
10228 							  "\n"
10229 							  "in  vec4 in_vs;\n"
10230 							  "out vec4 vs_tcs;\n"
10231 							  "\n"
10232 							  "void main()\n"
10233 							  "{\n"
10234 							  "    vs_tcs = in_vs;\n"
10235 							  "}\n"
10236 							  "\n";
10237 	static const GLchar* vs_tested = "#version 430 core\n"
10238 									 "#extension GL_ARB_enhanced_layouts : require\n"
10239 									 "\n"
10240 									 "layout (std140) uniform Block {\n"
10241 									 "    vec4 boy;\n"
10242 									 "    layout (align = ALIGN) TYPE man;\n"
10243 									 "} block;\n"
10244 									 "\n"
10245 									 "in  vec4 in_vs;\n"
10246 									 "out vec4 vs_tcs;\n"
10247 									 "\n"
10248 									 "void main()\n"
10249 									 "{\n"
10250 									 "    if (TYPE(0) == block.man)\n"
10251 									 "    {\n"
10252 									 "        vs_tcs = block.boy;\n"
10253 									 "    }\n"
10254 									 "\n"
10255 									 "    vs_tcs += in_vs;\n"
10256 									 "}\n"
10257 									 "\n";
10258 
10259 	std::string source;
10260 	testCase&   test_case = m_test_cases[test_case_index];
10261 
10262 	if (test_case.m_stage == stage)
10263 	{
10264 		GLchar			   buffer[16];
10265 		const GLuint	   alignment = test_case.m_alignment;
10266 		const Utils::Type& type		 = test_case.m_type;
10267 		const GLchar*	  type_name = type.GetGLSLTypeName();
10268 		size_t			   position  = 0;
10269 
10270 		switch (stage)
10271 		{
10272 		case Utils::Shader::COMPUTE:
10273 			source = cs;
10274 			break;
10275 		case Utils::Shader::FRAGMENT:
10276 			source = fs_tested;
10277 			break;
10278 		case Utils::Shader::GEOMETRY:
10279 			source = gs_tested;
10280 			break;
10281 		case Utils::Shader::TESS_CTRL:
10282 			source = tcs_tested;
10283 			break;
10284 		case Utils::Shader::TESS_EVAL:
10285 			source = tes_tested;
10286 			break;
10287 		case Utils::Shader::VERTEX:
10288 			source = vs_tested;
10289 			break;
10290 		default:
10291 			TCU_FAIL("Invalid enum");
10292 		}
10293 
10294 		sprintf(buffer, "%d", alignment);
10295 		Utils::replaceToken("ALIGN", position, buffer, source);
10296 		Utils::replaceToken("TYPE", position, type_name, source);
10297 		Utils::replaceToken("TYPE", position, type_name, source);
10298 	}
10299 	else
10300 	{
10301 		switch (stage)
10302 		{
10303 		case Utils::Shader::FRAGMENT:
10304 			source = fs;
10305 			break;
10306 		case Utils::Shader::GEOMETRY:
10307 			source = gs;
10308 			break;
10309 		case Utils::Shader::TESS_CTRL:
10310 			source = tcs;
10311 			break;
10312 		case Utils::Shader::TESS_EVAL:
10313 			source = tes;
10314 			break;
10315 		case Utils::Shader::VERTEX:
10316 			source = vs;
10317 			break;
10318 		default:
10319 			TCU_FAIL("Invalid enum");
10320 		}
10321 	}
10322 
10323 	return source;
10324 }
10325 
10326 /** Get description of test case
10327  *
10328  * @param test_case_index Index of test case
10329  *
10330  * @return Type name and offset
10331  **/
10332 std::string UniformBlockMemberAlignNonPowerOf2Test::getTestCaseName(GLuint test_case_index)
10333 {
10334 	std::stringstream stream;
10335 	testCase&		  test_case = m_test_cases[test_case_index];
10336 
10337 	stream << "Type: " << test_case.m_type.GetGLSLTypeName() << ", align: " << test_case.m_alignment;
10338 
10339 	return stream.str();
10340 }
10341 
10342 /** Get number of test cases
10343  *
10344  * @return Number of test cases
10345  **/
10346 GLuint UniformBlockMemberAlignNonPowerOf2Test::getTestCaseNumber()
10347 {
10348 	return static_cast<GLuint>(m_test_cases.size());
10349 }
10350 
10351 /** Selects if "compute" stage is relevant for test
10352  *
10353  * @param test_case_index Index of test case
10354  *
10355  * @return true when tested stage is compute
10356  **/
10357 bool UniformBlockMemberAlignNonPowerOf2Test::isComputeRelevant(GLuint test_case_index)
10358 {
10359 	return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
10360 }
10361 
10362 /** Checks if stage is supported
10363  *
10364  * @param ignored
10365  *
10366  * @return true
10367  **/
10368 bool UniformBlockMemberAlignNonPowerOf2Test::isStageSupported(Utils::Shader::STAGES /* stage */)
10369 {
10370 	return true;
10371 }
10372 
10373 /** Selects if compilation failure is expected result
10374  *
10375  * @param test_case_index Index of test case
10376  *
10377  * @return should_fail field from testCase
10378  **/
10379 bool UniformBlockMemberAlignNonPowerOf2Test::isFailureExpected(GLuint test_case_index)
10380 {
10381 	return m_test_cases[test_case_index].m_should_fail;
10382 }
10383 
10384 /** Prepare all test cases
10385  *
10386  **/
10387 void UniformBlockMemberAlignNonPowerOf2Test::testInit()
10388 {
10389 	static const GLuint dmat4_size = 128;
10390 	const GLuint		n_types	= getTypesNumber();
10391 	bool				stage_support[Utils::Shader::STAGE_MAX];
10392 
10393 	for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
10394 	{
10395 		stage_support[stage] = isStageSupported((Utils::Shader::STAGES)stage);
10396 	}
10397 
10398 	for (GLuint j = 0; j < n_types; ++j)
10399 	{
10400 		const Utils::Type& type = getType(j);
10401 
10402 		for (GLuint align = 0; align <= dmat4_size; ++align)
10403 		{
10404 
10405 #if WRKARD_UNIFORMBLOCKMEMBERALIGNNONPOWEROF2TEST
10406 
10407 			const bool should_fail = (0 == align) ? false : !isPowerOf2(align);
10408 
10409 #else /* WRKARD_UNIFORMBLOCKMEMBERALIGNNONPOWEROF2TEST */
10410 
10411 			const bool should_fail = !isPowerOf2(align);
10412 
10413 #endif /* WRKARD_UNIFORMBLOCKMEMBERALIGNNONPOWEROF2TEST */
10414 
10415 			for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
10416 			{
10417 				if (false == stage_support[stage])
10418 				{
10419 					continue;
10420 				}
10421 
10422 				testCase test_case = { align, type, should_fail, (Utils::Shader::STAGES)stage };
10423 
10424 				m_test_cases.push_back(test_case);
10425 			}
10426 		}
10427 	}
10428 }
10429 
10430 /** Check if value is power of 2
10431  *
10432  * @param val Tested value
10433  *
10434  * @return true if val is power of 2, false otherwise
10435  **/
10436 bool UniformBlockMemberAlignNonPowerOf2Test::isPowerOf2(GLuint val)
10437 {
10438 	if (0 == val)
10439 	{
10440 		return false;
10441 	}
10442 
10443 	return (0 == (val & (val - 1)));
10444 }
10445 
10446 /** Constructor
10447  *
10448  * @param context Test framework context
10449  **/
10450 UniformBlockAlignmentTest::UniformBlockAlignmentTest(deqp::Context& context)
10451 	: TextureTestBase(context, "uniform_block_alignment", "Test verifies offset and alignment of uniform buffer")
10452 {
10453 }
10454 
10455 /** Get interface of program
10456  *
10457  * @param ignored
10458  * @param program_interface Interface of program
10459  * @param varying_passthrough Collection of connections between in and out variables
10460  **/
10461 void UniformBlockAlignmentTest::getProgramInterface(GLuint /* test_case_index */,
10462 													Utils::ProgramInterface&   program_interface,
10463 													Utils::VaryingPassthrough& varying_passthrough)
10464 {
10465 	static const Utils::Type vec4 = Utils::Type::vec4;
10466 
10467 #if WRKARD_UNIFORMBLOCKALIGNMENT
10468 
10469 	static const GLuint block_align = 16;
10470 
10471 #else /* WRKARD_UNIFORMBLOCKALIGNMENT */
10472 
10473 	static const GLuint block_align = 64;
10474 
10475 #endif /* WRKARD_UNIFORMBLOCKALIGNMENT */
10476 
10477 	static const GLuint vec4_stride = 16;
10478 	static const GLuint data_stride = vec4_stride * 2; /* one vec4 + one scalar aligned to 16 */
10479 
10480 	/*Fixed a test issue, the fifth_offset should be calculated by block_align, instead of fifth_align, according to spec, the actual
10481 	 alignment of a member will be the greater of the specified alignment and the base aligment for the member type
10482 	 */
10483 	const GLuint first_offset  = 0;																		/* vec4 at 0 */
10484 	const GLuint second_offset = Utils::Type::GetActualOffset(first_offset + vec4_stride, block_align); /* Data at 32 */
10485 	const GLuint third_offset =
10486 		Utils::Type::GetActualOffset(second_offset + data_stride, block_align); /* Data[2] at 64 */
10487 	const GLuint fourth_offset =
10488 		Utils::Type::GetActualOffset(third_offset + data_stride * 2, block_align); /* vec4[3] at 96 */
10489 	const GLuint fifth_offset =
10490 		Utils::Type::GetActualOffset(fourth_offset + vec4_stride * 3, block_align); /* vec4[2] at 160 */
10491 	const GLuint sixth_offset =
10492 		Utils::Type::GetActualOffset(fifth_offset + vec4_stride * 2, block_align); /* Data at 192 */
10493 
10494 	Utils::Interface* structure = program_interface.Structure("Data");
10495 
10496 	structure->Member("vector", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::vec4,
10497 					  false /* normalized */, 0 /* n_array_elements */, Utils::Type::vec4.GetSize(), 0 /* offset */);
10498 
10499 	structure->Member("scalar", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::_float,
10500 					  false /* normalized */, 0 /* n_array_elements */, Utils::Type::_float.GetSize(),
10501 					  Utils::Type::vec4.GetSize() /* offset */);
10502 
10503 	/* Prepare Block */
10504 	Utils::Interface* vs_uni_block = program_interface.Block("vs_uni_Block");
10505 
10506 	vs_uni_block->Member("first", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::vec4,
10507 						 false /* normalized */, 0 /* n_array_elements */, vec4_stride, first_offset /* offset */);
10508 
10509 	vs_uni_block->Member("second", "", 0 /* expected_component */, 0 /* expected_location */, structure,
10510 						 0 /* n_array_elements */, data_stride, second_offset);
10511 
10512 	vs_uni_block->Member("third", "", 0 /* expected_component */, 0 /* expected_location */, structure,
10513 						 2 /* n_array_elements */, data_stride, third_offset);
10514 
10515 	vs_uni_block->Member("fourth", "", 0 /* expected_component */, 0 /* expected_location */, vec4,
10516 						 false /* normalized */, 3 /* n_array_elements */, vec4_stride, fourth_offset);
10517 
10518 	vs_uni_block->Member("fifth", "layout(align = 64)", 0 /* expected_component */, 0 /* expected_location */, vec4,
10519 						 false /* normalized */, 2 /* n_array_elements */, vec4_stride, fifth_offset);
10520 
10521 	vs_uni_block->Member("sixth", "", 0 /* expected_component */, 0 /* expected_location */, structure,
10522 						 0 /* n_array_elements */, data_stride, sixth_offset);
10523 
10524 	const GLuint stride = calculateStride(*vs_uni_block);
10525 	m_data.resize(stride);
10526 	generateData(*vs_uni_block, 0, m_data);
10527 
10528 	Utils::ShaderInterface& vs_si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
10529 
10530 /* Add uniform BLOCK */
10531 #if WRKARD_UNIFORMBLOCKALIGNMENT
10532 	vs_si.Uniform("vs_uni_block", "layout (std140, binding = BINDING)", 0, 0, vs_uni_block, 0,
10533 				  static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
10534 #else  /* WRKARD_UNIFORMBLOCKALIGNMENT */
10535 	vs_si.Uniform("vs_uni_block", "layout (std140, binding = BINDING, align = 64)", 0, 0, vs_uni_block, 0,
10536 				  static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
10537 #endif /* WRKARD_UNIFORMBLOCKALIGNMENT */
10538 
10539 	program_interface.CloneVertexInterface(varying_passthrough);
10540 }
10541 
10542 /** Constructor
10543  *
10544  * @param context Test framework context
10545  **/
10546 SSBMemberOffsetAndAlignTest::SSBMemberOffsetAndAlignTest(deqp::Context& context)
10547 	: TextureTestBase(context, "ssb_member_offset_and_align",
10548 					  "Test verifies offsets and alignment of storage buffer members")
10549 {
10550 }
10551 
10552 /** Get interface of program
10553  *
10554  * @param test_case_index     Test case index
10555  * @param program_interface   Interface of program
10556  * @param varying_passthrough Collection of connections between in and out variables
10557  **/
10558 void SSBMemberOffsetAndAlignTest::getProgramInterface(GLuint					 test_case_index,
10559 													  Utils::ProgramInterface&   program_interface,
10560 													  Utils::VaryingPassthrough& varying_passthrough)
10561 {
10562 	std::string globals = "const int basic_size = BASIC_SIZE;\n"
10563 						  "const int type_align = TYPE_ALIGN;\n"
10564 						  "const int type_size  = TYPE_SIZE;\n";
10565 
10566 	Utils::Type  type		 = getType(test_case_index);
10567 	GLuint		 basic_size  = Utils::Type::GetTypeSize(type.m_basic_type);
10568 	const GLuint base_align  = type.GetBaseAlignment(false);
10569 	const GLuint array_align = type.GetBaseAlignment(true);
10570 	const GLuint base_stride = Utils::Type::CalculateStd140Stride(base_align, type.m_n_columns, 0);
10571 	const GLuint type_align  = Utils::roundUpToPowerOf2(base_stride);
10572 
10573 	/* Calculate offsets */
10574 	const GLuint first_offset  = 0;
10575 	const GLuint second_offset = type.GetActualOffset(base_stride, basic_size / 2);
10576 
10577 #if WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST
10578 
10579 	const GLuint third_offset   = type.GetActualOffset(second_offset + base_stride, base_align);
10580 	const GLuint fourth_offset  = type.GetActualOffset(third_offset + base_stride, base_align);
10581 	const GLuint fifth_offset   = type.GetActualOffset(fourth_offset + base_stride, base_align);
10582 	const GLuint sixth_offset   = type.GetActualOffset(fifth_offset + base_stride, array_align);
10583 	const GLuint seventh_offset = type.GetActualOffset(sixth_offset + base_stride, array_align);
10584 	const GLuint eigth_offset   = type.GetActualOffset(seventh_offset + base_stride, array_align);
10585 
10586 #else /* WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST */
10587 
10588 	const GLuint third_offset   = type.GetActualOffset(second_offset + base_stride, 2 * type_align);
10589 	const GLuint fourth_offset  = type.GetActualOffset(3 * type_align + base_stride, base_align);
10590 	const GLuint fifth_offset   = type.GetActualOffset(fourth_offset + base_stride, base_align);
10591 	const GLuint sixth_offset   = type.GetActualOffset(fifth_offset + base_stride, array_align);
10592 	const GLuint seventh_offset = type.GetActualOffset(sixth_offset + base_stride, array_align);
10593 	const GLuint eigth_offset   = type.GetActualOffset(seventh_offset + base_stride, 8 * basic_size);
10594 
10595 #endif /* WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST */
10596 
10597 	/* Prepare data */
10598 	const std::vector<GLubyte>& first  = type.GenerateData();
10599 	const std::vector<GLubyte>& second = type.GenerateData();
10600 	const std::vector<GLubyte>& third  = type.GenerateData();
10601 	const std::vector<GLubyte>& fourth = type.GenerateData();
10602 
10603 	m_data.resize(eigth_offset + base_stride);
10604 	GLubyte* ptr = &m_data[0];
10605 	memcpy(ptr + first_offset, &first[0], first.size());
10606 	memcpy(ptr + second_offset, &second[0], second.size());
10607 	memcpy(ptr + third_offset, &third[0], third.size());
10608 	memcpy(ptr + fourth_offset, &fourth[0], fourth.size());
10609 	memcpy(ptr + fifth_offset, &fourth[0], fourth.size());
10610 	memcpy(ptr + sixth_offset, &third[0], third.size());
10611 	memcpy(ptr + seventh_offset, &second[0], second.size());
10612 	memcpy(ptr + eigth_offset, &first[0], first.size());
10613 
10614 	/* Prepare globals */
10615 	size_t position = 0;
10616 	GLchar buffer[16];
10617 
10618 	sprintf(buffer, "%d", basic_size);
10619 	Utils::replaceToken("BASIC_SIZE", position, buffer, globals);
10620 
10621 	sprintf(buffer, "%d", type_align);
10622 	Utils::replaceToken("TYPE_ALIGN", position, buffer, globals);
10623 
10624 	sprintf(buffer, "%d", base_stride);
10625 	Utils::replaceToken("TYPE_SIZE", position, buffer, globals);
10626 
10627 	/* Prepare Block */
10628 	Utils::Interface* vs_buf_block = program_interface.Block("vs_buf_Block");
10629 
10630 	vs_buf_block->Member("at_first_offset", "layout(offset = 0, align = 8 * basic_size)", 0 /* expected_component */,
10631 						 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
10632 						 first_offset);
10633 
10634 	vs_buf_block->Member("at_second_offset", "layout(offset = type_size, align = basic_size / 2)",
10635 						 0 /* expected_component */, 0 /* expected_location */, type, false /* normalized */,
10636 						 0 /* n_array_elements */, base_stride, second_offset);
10637 
10638 	vs_buf_block->Member("at_third_offset", "layout(align = 2 * type_align)", 0 /* expected_component */,
10639 						 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
10640 						 third_offset);
10641 
10642 	vs_buf_block->Member("at_fourth_offset", "layout(offset = 3 * type_align + type_size)", 0 /* expected_component */,
10643 						 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
10644 						 fourth_offset);
10645 
10646 	vs_buf_block->Member("at_fifth_offset", "", 0 /* expected_component */, 0 /* expected_location */, type,
10647 						 false /* normalized */, 0 /* n_array_elements */, base_stride, fifth_offset);
10648 
10649 	vs_buf_block->Member("at_sixth_offset", "", 0 /* expected_component */, 0 /* expected_location */, type,
10650 						 false /* normalized */, 2 /* n_array_elements */, array_align * 2, sixth_offset);
10651 
10652 	vs_buf_block->Member("at_eigth_offset", "layout(align = 8 * basic_size)", 0 /* expected_component */,
10653 						 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
10654 						 eigth_offset);
10655 
10656 	Utils::ShaderInterface& vs_si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
10657 
10658 	/* Add globals */
10659 	vs_si.m_globals = globals;
10660 
10661 	/* Add uniform BLOCK */
10662 	vs_si.SSB("vs_buf_block", "layout (std140, binding = BINDING)", 0, 0, vs_buf_block, 0,
10663 			  static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
10664 
10665 	/* */
10666 	program_interface.CloneVertexInterface(varying_passthrough);
10667 }
10668 
10669 /** Get type name
10670  *
10671  * @param test_case_index Index of test case
10672  *
10673  * @return Name of type test in test_case_index
10674  **/
10675 std::string SSBMemberOffsetAndAlignTest::getTestCaseName(glw::GLuint test_case_index)
10676 {
10677 	return getTypeName(test_case_index);
10678 }
10679 
10680 /** Returns number of types to test
10681  *
10682  * @return Number of types, 34
10683  **/
10684 glw::GLuint SSBMemberOffsetAndAlignTest::getTestCaseNumber()
10685 {
10686 	return getTypesNumber();
10687 }
10688 
10689 /** Prepare code snippet that will verify in and uniform variables
10690  *
10691  * @param ignored
10692  * @param ignored
10693  * @param stage   Shader stage
10694  *
10695  * @return Code that verify variables
10696  **/
10697 std::string SSBMemberOffsetAndAlignTest::getVerificationSnippet(GLuint /* test_case_index */,
10698 																Utils::ProgramInterface& /* program_interface */,
10699 																Utils::Shader::STAGES stage)
10700 {
10701 	std::string verification = "if ( (PREFIXblock.at_first_offset  != PREFIXblock.at_eigth_offset   ) ||\n"
10702 							   "         (PREFIXblock.at_second_offset != PREFIXblock.at_sixth_offset[1]) ||\n"
10703 							   "         (PREFIXblock.at_third_offset  != PREFIXblock.at_sixth_offset[0]) ||\n"
10704 							   "         (PREFIXblock.at_fourth_offset != PREFIXblock.at_fifth_offset   )  )\n"
10705 							   "    {\n"
10706 							   "        result = 0;\n"
10707 							   "    }";
10708 
10709 	const GLchar* prefix = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::SSB);
10710 
10711 	Utils::replaceAllTokens("PREFIX", prefix, verification);
10712 
10713 	return verification;
10714 }
10715 
10716 /** Selects if "draw" stages are relevant for test
10717  *
10718  * @param ignored
10719  *
10720  * @return true if all stages support shader storage buffers, false otherwise
10721  **/
10722 bool SSBMemberOffsetAndAlignTest::isDrawRelevant(GLuint /* test_case_index */)
10723 {
10724 	const Functions& gl					   = m_context.getRenderContext().getFunctions();
10725 	GLint			 gs_supported_buffers  = 0;
10726 	GLint			 tcs_supported_buffers = 0;
10727 	GLint			 tes_supported_buffers = 0;
10728 	GLint			 vs_supported_buffers  = 0;
10729 
10730 	gl.getIntegerv(GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS, &gs_supported_buffers);
10731 	gl.getIntegerv(GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS, &tcs_supported_buffers);
10732 	gl.getIntegerv(GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS, &tes_supported_buffers);
10733 	gl.getIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &vs_supported_buffers);
10734 
10735 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
10736 
10737 	return ((1 <= gs_supported_buffers) && (1 <= tcs_supported_buffers) && (1 <= tes_supported_buffers) &&
10738 			(1 <= vs_supported_buffers));
10739 }
10740 
10741 /** Constructor
10742  *
10743  * @param context Test framework context
10744  **/
10745 SSBLayoutQualifierConflictTest::SSBLayoutQualifierConflictTest(deqp::Context& context)
10746 	: NegativeTestBase(context, "ssb_layout_qualifier_conflict", "Test verifies that std140 or std430 is required when "
10747 																 "offset and/or align qualifiers are used with storage "
10748 																 "block")
10749 {
10750 	/* Nothing to be done here */
10751 }
10752 
10753 /** Source for given test case and stage
10754  *
10755  * @param test_case_index Index of test case
10756  * @param stage           Shader stage
10757  *
10758  * @return Shader source
10759  **/
10760 std::string SSBLayoutQualifierConflictTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
10761 {
10762 	static const GLchar* cs = "#version 430 core\n"
10763 							  "#extension GL_ARB_enhanced_layouts : require\n"
10764 							  "\n"
10765 							  "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
10766 							  "\n"
10767 							  "layout (QUALIFIERbinding = BINDING) buffer cs_Block {\n"
10768 							  "    layout(offset = 16) vec4 boy;\n"
10769 							  "    layout(align  = 64) vec4 man;\n"
10770 							  "} uni_block;\n"
10771 							  "\n"
10772 							  "writeonly uniform image2D uni_image;\n"
10773 							  "\n"
10774 							  "void main()\n"
10775 							  "{\n"
10776 							  "    vec4 result = uni_block.boy + uni_block.man;\n"
10777 							  "\n"
10778 							  "    imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
10779 							  "}\n"
10780 							  "\n";
10781 	static const GLchar* fs = "#version 430 core\n"
10782 							  "#extension GL_ARB_enhanced_layouts : require\n"
10783 							  "\n"
10784 							  "layout (QUALIFIERbinding = BINDING) buffer Block {\n"
10785 							  "    layout(offset = 16) vec4 boy;\n"
10786 							  "    layout(align  = 64) vec4 man;\n"
10787 							  "} uni_block;\n"
10788 							  "\n"
10789 							  "in  vec4 gs_fs;\n"
10790 							  "out vec4 fs_out;\n"
10791 							  "\n"
10792 							  "void main()\n"
10793 							  "{\n"
10794 							  "    fs_out = gs_fs + uni_block.boy + uni_block.man;\n"
10795 							  "}\n"
10796 							  "\n";
10797 	static const GLchar* gs = "#version 430 core\n"
10798 							  "#extension GL_ARB_enhanced_layouts : require\n"
10799 							  "\n"
10800 							  "layout(points)                           in;\n"
10801 							  "layout(triangle_strip, max_vertices = 4) out;\n"
10802 							  "\n"
10803 							  "layout (QUALIFIERbinding = BINDING) buffer gs_Block {\n"
10804 							  "    layout(offset = 16) vec4 boy;\n"
10805 							  "    layout(align  = 64) vec4 man;\n"
10806 							  "} uni_block;\n"
10807 							  "\n"
10808 							  "in  vec4 tes_gs[];\n"
10809 							  "out vec4 gs_fs;\n"
10810 							  "\n"
10811 							  "void main()\n"
10812 							  "{\n"
10813 							  "    gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
10814 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
10815 							  "    EmitVertex();\n"
10816 							  "    gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
10817 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
10818 							  "    EmitVertex();\n"
10819 							  "    gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
10820 							  "    gl_Position  = vec4(1, -1, 0, 1);\n"
10821 							  "    EmitVertex();\n"
10822 							  "    gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
10823 							  "    gl_Position  = vec4(1, 1, 0, 1);\n"
10824 							  "    EmitVertex();\n"
10825 							  "}\n"
10826 							  "\n";
10827 	static const GLchar* tcs =
10828 		"#version 430 core\n"
10829 		"#extension GL_ARB_enhanced_layouts : require\n"
10830 		"\n"
10831 		"layout(vertices = 1) out;\n"
10832 		"\n"
10833 		"layout (QUALIFIERbinding = BINDING) buffer tcs_Block {\n"
10834 		"    layout(offset = 16) vec4 boy;\n"
10835 		"    layout(align  = 64) vec4 man;\n"
10836 		"} uni_block;\n"
10837 		"\n"
10838 		"in  vec4 vs_tcs[];\n"
10839 		"out vec4 tcs_tes[];\n"
10840 		"\n"
10841 		"void main()\n"
10842 		"{\n"
10843 		"\n"
10844 		"    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID] + uni_block.boy + uni_block.man;\n"
10845 		"\n"
10846 		"    gl_TessLevelOuter[0] = 1.0;\n"
10847 		"    gl_TessLevelOuter[1] = 1.0;\n"
10848 		"    gl_TessLevelOuter[2] = 1.0;\n"
10849 		"    gl_TessLevelOuter[3] = 1.0;\n"
10850 		"    gl_TessLevelInner[0] = 1.0;\n"
10851 		"    gl_TessLevelInner[1] = 1.0;\n"
10852 		"}\n"
10853 		"\n";
10854 	static const GLchar* tes = "#version 430 core\n"
10855 							   "#extension GL_ARB_enhanced_layouts : require\n"
10856 							   "\n"
10857 							   "layout(isolines, point_mode) in;\n"
10858 							   "\n"
10859 							   "layout (QUALIFIERbinding = BINDING) buffer tes_Block {\n"
10860 							   "    layout(offset = 16) vec4 boy;\n"
10861 							   "    layout(align  = 64) vec4 man;\n"
10862 							   "} uni_block;\n"
10863 							   "\n"
10864 							   "in  vec4 tcs_tes[];\n"
10865 							   "out vec4 tes_gs;\n"
10866 							   "\n"
10867 							   "void main()\n"
10868 							   "{\n"
10869 							   "    tes_gs = tcs_tes[0] + uni_block.boy + uni_block.man;\n"
10870 							   "}\n"
10871 							   "\n";
10872 	static const GLchar* vs = "#version 430 core\n"
10873 							  "#extension GL_ARB_enhanced_layouts : require\n"
10874 							  "\n"
10875 							  "layout (QUALIFIERbinding = BINDING) buffer vs_Block {\n"
10876 							  "    layout(offset = 16) vec4 boy;\n"
10877 							  "    layout(align  = 64) vec4 man;\n"
10878 							  "} uni_block;\n"
10879 							  "\n"
10880 							  "in  vec4 in_vs;\n"
10881 							  "out vec4 vs_tcs;\n"
10882 							  "\n"
10883 							  "void main()\n"
10884 							  "{\n"
10885 							  "    vs_tcs = in_vs + uni_block.boy + uni_block.man;\n"
10886 							  "}\n"
10887 							  "\n";
10888 
10889 	GLchar		buffer[16];
10890 	size_t		position = 0;
10891 	std::string source;
10892 	testCase&   test_case = m_test_cases[test_case_index];
10893 	std::string qualifier = getQualifierName(test_case.m_qualifier);
10894 
10895 	if (false == qualifier.empty())
10896 	{
10897 		qualifier.append(", ");
10898 	}
10899 
10900 	sprintf(buffer, "%d", stage);
10901 
10902 	switch (stage)
10903 	{
10904 	case Utils::Shader::COMPUTE:
10905 		source = cs;
10906 		break;
10907 	case Utils::Shader::FRAGMENT:
10908 		source = fs;
10909 		break;
10910 	case Utils::Shader::GEOMETRY:
10911 		source = gs;
10912 		break;
10913 	case Utils::Shader::TESS_CTRL:
10914 		source = tcs;
10915 		break;
10916 	case Utils::Shader::TESS_EVAL:
10917 		source = tes;
10918 		break;
10919 	case Utils::Shader::VERTEX:
10920 		source = vs;
10921 		break;
10922 	default:
10923 		TCU_FAIL("Invalid enum");
10924 	}
10925 
10926 	if (test_case.m_stage == stage)
10927 	{
10928 		Utils::replaceToken("QUALIFIER", position, qualifier.c_str(), source);
10929 	}
10930 	else
10931 	{
10932 		Utils::replaceToken("QUALIFIER", position, "std140, ", source);
10933 	}
10934 
10935 	Utils::replaceToken("BINDING", position, buffer, source);
10936 
10937 	return source;
10938 }
10939 
10940 /** Get description of test case
10941  *
10942  * @param test_case_index Index of test case
10943  *
10944  * @return Qualifier name
10945  **/
10946 std::string SSBLayoutQualifierConflictTest::getTestCaseName(GLuint test_case_index)
10947 {
10948 	std::string result = getQualifierName(m_test_cases[test_case_index].m_qualifier);
10949 
10950 	return result;
10951 }
10952 
10953 /** Get number of test cases
10954  *
10955  * @return Number of test cases
10956  **/
10957 GLuint SSBLayoutQualifierConflictTest::getTestCaseNumber()
10958 {
10959 	return static_cast<GLuint>(m_test_cases.size());
10960 }
10961 
10962 /** Selects if "compute" stage is relevant for test
10963  *
10964  * @param test_case_index Index of test case
10965  *
10966  * @return true when tested stage is compute
10967  **/
10968 bool SSBLayoutQualifierConflictTest::isComputeRelevant(GLuint test_case_index)
10969 {
10970 	return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
10971 }
10972 
10973 /** Selects if compilation failure is expected result
10974  *
10975  * @param test_case_index Index of test case
10976  *
10977  * @return false for STD140 and STD430 cases, true otherwise
10978  **/
10979 bool SSBLayoutQualifierConflictTest::isFailureExpected(GLuint test_case_index)
10980 {
10981 	const QUALIFIERS qualifier = m_test_cases[test_case_index].m_qualifier;
10982 
10983 	return !((STD140 == qualifier) || (STD430 == qualifier));
10984 }
10985 
10986 /** Checks if stage is supported
10987  *
10988  * @param stage Shader stage
10989  *
10990  * @return true if supported, false otherwise
10991  **/
10992 bool SSBLayoutQualifierConflictTest::isStageSupported(Utils::Shader::STAGES stage)
10993 {
10994 	const Functions& gl					   = m_context.getRenderContext().getFunctions();
10995 	GLint			 max_supported_buffers = 0;
10996 	GLenum			 pname				   = 0;
10997 
10998 	switch (stage)
10999 	{
11000 	case Utils::Shader::COMPUTE:
11001 		pname = GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS;
11002 		break;
11003 	case Utils::Shader::FRAGMENT:
11004 		pname = GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS;
11005 		break;
11006 	case Utils::Shader::GEOMETRY:
11007 		pname = GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS;
11008 		break;
11009 	case Utils::Shader::TESS_CTRL:
11010 		pname = GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS;
11011 		break;
11012 	case Utils::Shader::TESS_EVAL:
11013 		pname = GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS;
11014 		break;
11015 	case Utils::Shader::VERTEX:
11016 		pname = GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS;
11017 		break;
11018 	default:
11019 		TCU_FAIL("Invalid enum");
11020 	}
11021 
11022 	gl.getIntegerv(pname, &max_supported_buffers);
11023 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
11024 
11025 	return 1 <= max_supported_buffers;
11026 }
11027 
11028 /** Prepare all test cases
11029  *
11030  **/
11031 void SSBLayoutQualifierConflictTest::testInit()
11032 {
11033 	bool stage_support[Utils::Shader::STAGE_MAX];
11034 
11035 	for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
11036 	{
11037 		stage_support[stage] = isStageSupported((Utils::Shader::STAGES)stage);
11038 	}
11039 
11040 	for (GLuint qualifier = 0; qualifier < QUALIFIERS_MAX; ++qualifier)
11041 	{
11042 		for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
11043 		{
11044 			if (false == stage_support[stage])
11045 			{
11046 				continue;
11047 			}
11048 
11049 			testCase test_case = { (QUALIFIERS)qualifier, (Utils::Shader::STAGES)stage };
11050 
11051 			m_test_cases.push_back(test_case);
11052 		}
11053 	}
11054 }
11055 
11056 /** Get name of glsl constant
11057  *
11058  * @param Constant id
11059  *
11060  * @return Name of constant used in GLSL
11061  **/
11062 const GLchar* SSBLayoutQualifierConflictTest::getQualifierName(QUALIFIERS qualifier)
11063 {
11064 	const GLchar* name = "";
11065 
11066 	switch (qualifier)
11067 	{
11068 	case DEFAULT:
11069 		name = "";
11070 		break;
11071 	case STD140:
11072 		name = "std140";
11073 		break;
11074 	case STD430:
11075 		name = "std430";
11076 		break;
11077 	case SHARED:
11078 		name = "shared";
11079 		break;
11080 	case PACKED:
11081 		name = "packed";
11082 		break;
11083 	default:
11084 		TCU_FAIL("Invalid enum");
11085 	}
11086 
11087 	return name;
11088 }
11089 
11090 /** Constructor
11091  *
11092  * @param context Test framework context
11093  **/
11094 SSBMemberInvalidOffsetAlignmentTest::SSBMemberInvalidOffsetAlignmentTest(deqp::Context& context)
11095 	: UniformBlockMemberInvalidOffsetAlignmentTest(
11096 		  context, "ssb_member_invalid_offset_alignment",
11097 		  "Test verifies that invalid alignment of offset qualifiers cause compilation failure")
11098 {
11099 	/* Nothing to be done here */
11100 }
11101 
11102 /** Get the maximum size for a shader storage block
11103  *
11104  * @return The maximum size in basic machine units of a shader storage block.
11105  **/
11106 GLint SSBMemberInvalidOffsetAlignmentTest::getMaxBlockSize()
11107 {
11108 	const Functions& gl		  = m_context.getRenderContext().getFunctions();
11109 	GLint			 max_size = 0;
11110 
11111 	gl.getIntegerv(GL_MAX_SHADER_STORAGE_BLOCK_SIZE, &max_size);
11112 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
11113 
11114 	return max_size;
11115 }
11116 
11117 /** Source for given test case and stage
11118  *
11119  * @param test_case_index Index of test case
11120  * @param stage           Shader stage
11121  *
11122  * @return Shader source
11123  **/
11124 std::string SSBMemberInvalidOffsetAlignmentTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
11125 {
11126 	static const GLchar* cs = "#version 430 core\n"
11127 							  "#extension GL_ARB_enhanced_layouts : require\n"
11128 							  "\n"
11129 							  "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
11130 							  "\n"
11131 							  "layout (std140) buffer Block {\n"
11132 							  "    layout (offset = OFFSET) TYPE member;\n"
11133 							  "} block;\n"
11134 							  "\n"
11135 							  "writeonly uniform image2D uni_image;\n"
11136 							  "\n"
11137 							  "void main()\n"
11138 							  "{\n"
11139 							  "    vec4 result = vec4(1, 0, 0.5, 1);\n"
11140 							  "\n"
11141 							  "    if (TYPE(1) == block.member)\n"
11142 							  "    {\n"
11143 							  "        result = vec4(1, 1, 1, 1);\n"
11144 							  "    }\n"
11145 							  "\n"
11146 							  "    imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
11147 							  "}\n"
11148 							  "\n";
11149 	static const GLchar* fs = "#version 430 core\n"
11150 							  "#extension GL_ARB_enhanced_layouts : require\n"
11151 							  "\n"
11152 							  "in  vec4 gs_fs;\n"
11153 							  "out vec4 fs_out;\n"
11154 							  "\n"
11155 							  "void main()\n"
11156 							  "{\n"
11157 							  "    fs_out = gs_fs;\n"
11158 							  "}\n"
11159 							  "\n";
11160 	static const GLchar* fs_tested = "#version 430 core\n"
11161 									 "#extension GL_ARB_enhanced_layouts : require\n"
11162 									 "\n"
11163 									 "layout (std140) buffer Block {\n"
11164 									 "    layout (offset = OFFSET) TYPE member;\n"
11165 									 "} block;\n"
11166 									 "\n"
11167 									 "in  vec4 gs_fs;\n"
11168 									 "out vec4 fs_out;\n"
11169 									 "\n"
11170 									 "void main()\n"
11171 									 "{\n"
11172 									 "    if (TYPE(1) == block.member)\n"
11173 									 "    {\n"
11174 									 "        fs_out = vec4(1, 1, 1, 1);\n"
11175 									 "    }\n"
11176 									 "\n"
11177 									 "    fs_out += gs_fs;\n"
11178 									 "}\n"
11179 									 "\n";
11180 	static const GLchar* gs = "#version 430 core\n"
11181 							  "#extension GL_ARB_enhanced_layouts : require\n"
11182 							  "\n"
11183 							  "layout(points)                           in;\n"
11184 							  "layout(triangle_strip, max_vertices = 4) out;\n"
11185 							  "\n"
11186 							  "in  vec4 tes_gs[];\n"
11187 							  "out vec4 gs_fs;\n"
11188 							  "\n"
11189 							  "void main()\n"
11190 							  "{\n"
11191 							  "    gs_fs = tes_gs[0];\n"
11192 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
11193 							  "    EmitVertex();\n"
11194 							  "    gs_fs = tes_gs[0];\n"
11195 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
11196 							  "    EmitVertex();\n"
11197 							  "    gs_fs = tes_gs[0];\n"
11198 							  "    gl_Position  = vec4(1, -1, 0, 1);\n"
11199 							  "    EmitVertex();\n"
11200 							  "    gs_fs = tes_gs[0];\n"
11201 							  "    gl_Position  = vec4(1, 1, 0, 1);\n"
11202 							  "    EmitVertex();\n"
11203 							  "}\n"
11204 							  "\n";
11205 	static const GLchar* gs_tested = "#version 430 core\n"
11206 									 "#extension GL_ARB_enhanced_layouts : require\n"
11207 									 "\n"
11208 									 "layout(points)                           in;\n"
11209 									 "layout(triangle_strip, max_vertices = 4) out;\n"
11210 									 "\n"
11211 									 "layout (std140) buffer Block {\n"
11212 									 "    layout (offset = OFFSET) TYPE member;\n"
11213 									 "} block;\n"
11214 									 "\n"
11215 									 "in  vec4 tes_gs[];\n"
11216 									 "out vec4 gs_fs;\n"
11217 									 "\n"
11218 									 "void main()\n"
11219 									 "{\n"
11220 									 "    if (TYPE(1) == block.member)\n"
11221 									 "    {\n"
11222 									 "        gs_fs = vec4(1, 1, 1, 1);\n"
11223 									 "    }\n"
11224 									 "\n"
11225 									 "    gs_fs += tes_gs[0];\n"
11226 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
11227 									 "    EmitVertex();\n"
11228 									 "    gs_fs += tes_gs[0];\n"
11229 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
11230 									 "    EmitVertex();\n"
11231 									 "    gs_fs += tes_gs[0];\n"
11232 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
11233 									 "    EmitVertex();\n"
11234 									 "    gs_fs += tes_gs[0];\n"
11235 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
11236 									 "    EmitVertex();\n"
11237 									 "}\n"
11238 									 "\n";
11239 	static const GLchar* tcs = "#version 430 core\n"
11240 							   "#extension GL_ARB_enhanced_layouts : require\n"
11241 							   "\n"
11242 							   "layout(vertices = 1) out;\n"
11243 							   "\n"
11244 							   "in  vec4 vs_tcs[];\n"
11245 							   "out vec4 tcs_tes[];\n"
11246 							   "\n"
11247 							   "void main()\n"
11248 							   "{\n"
11249 							   "\n"
11250 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
11251 							   "\n"
11252 							   "    gl_TessLevelOuter[0] = 1.0;\n"
11253 							   "    gl_TessLevelOuter[1] = 1.0;\n"
11254 							   "    gl_TessLevelOuter[2] = 1.0;\n"
11255 							   "    gl_TessLevelOuter[3] = 1.0;\n"
11256 							   "    gl_TessLevelInner[0] = 1.0;\n"
11257 							   "    gl_TessLevelInner[1] = 1.0;\n"
11258 							   "}\n"
11259 							   "\n";
11260 	static const GLchar* tcs_tested = "#version 430 core\n"
11261 									  "#extension GL_ARB_enhanced_layouts : require\n"
11262 									  "\n"
11263 									  "layout(vertices = 1) out;\n"
11264 									  "\n"
11265 									  "layout (std140) buffer Block {\n"
11266 									  "    layout (offset = OFFSET) TYPE member;\n"
11267 									  "} block;\n"
11268 									  "\n"
11269 									  "in  vec4 vs_tcs[];\n"
11270 									  "out vec4 tcs_tes[];\n"
11271 									  "\n"
11272 									  "void main()\n"
11273 									  "{\n"
11274 									  "    if (TYPE(1) == block.member)\n"
11275 									  "    {\n"
11276 									  "        tcs_tes[gl_InvocationID] = vec4(1, 1, 1, 1);\n"
11277 									  "    }\n"
11278 									  "\n"
11279 									  "\n"
11280 									  "    tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
11281 									  "\n"
11282 									  "    gl_TessLevelOuter[0] = 1.0;\n"
11283 									  "    gl_TessLevelOuter[1] = 1.0;\n"
11284 									  "    gl_TessLevelOuter[2] = 1.0;\n"
11285 									  "    gl_TessLevelOuter[3] = 1.0;\n"
11286 									  "    gl_TessLevelInner[0] = 1.0;\n"
11287 									  "    gl_TessLevelInner[1] = 1.0;\n"
11288 									  "}\n"
11289 									  "\n";
11290 	static const GLchar* tes = "#version 430 core\n"
11291 							   "#extension GL_ARB_enhanced_layouts : require\n"
11292 							   "\n"
11293 							   "layout(isolines, point_mode) in;\n"
11294 							   "\n"
11295 							   "in  vec4 tcs_tes[];\n"
11296 							   "out vec4 tes_gs;\n"
11297 							   "\n"
11298 							   "void main()\n"
11299 							   "{\n"
11300 							   "    tes_gs = tcs_tes[0];\n"
11301 							   "}\n"
11302 							   "\n";
11303 	static const GLchar* tes_tested = "#version 430 core\n"
11304 									  "#extension GL_ARB_enhanced_layouts : require\n"
11305 									  "\n"
11306 									  "layout(isolines, point_mode) in;\n"
11307 									  "\n"
11308 									  "layout (std140) buffer Block {\n"
11309 									  "    layout (offset = OFFSET) TYPE member;\n"
11310 									  "} block;\n"
11311 									  "\n"
11312 									  "in  vec4 tcs_tes[];\n"
11313 									  "out vec4 tes_gs;\n"
11314 									  "\n"
11315 									  "void main()\n"
11316 									  "{\n"
11317 									  "    if (TYPE(1) == block.member)\n"
11318 									  "    {\n"
11319 									  "        tes_gs = vec4(1, 1, 1, 1);\n"
11320 									  "    }\n"
11321 									  "\n"
11322 									  "    tes_gs += tcs_tes[0];\n"
11323 									  "}\n"
11324 									  "\n";
11325 	static const GLchar* vs = "#version 430 core\n"
11326 							  "#extension GL_ARB_enhanced_layouts : require\n"
11327 							  "\n"
11328 							  "in  vec4 in_vs;\n"
11329 							  "out vec4 vs_tcs;\n"
11330 							  "\n"
11331 							  "void main()\n"
11332 							  "{\n"
11333 							  "    vs_tcs = in_vs;\n"
11334 							  "}\n"
11335 							  "\n";
11336 	static const GLchar* vs_tested = "#version 430 core\n"
11337 									 "#extension GL_ARB_enhanced_layouts : require\n"
11338 									 "\n"
11339 									 "layout (std140) buffer Block {\n"
11340 									 "    layout (offset = OFFSET) TYPE member;\n"
11341 									 "} block;\n"
11342 									 "\n"
11343 									 "in  vec4 in_vs;\n"
11344 									 "out vec4 vs_tcs;\n"
11345 									 "\n"
11346 									 "void main()\n"
11347 									 "{\n"
11348 									 "    if (TYPE(1) == block.member)\n"
11349 									 "    {\n"
11350 									 "        vs_tcs = vec4(1, 1, 1, 1);\n"
11351 									 "    }\n"
11352 									 "\n"
11353 									 "    vs_tcs += in_vs;\n"
11354 									 "}\n"
11355 									 "\n";
11356 
11357 	std::string source;
11358 	testCase&   test_case = m_test_cases[test_case_index];
11359 
11360 	if (test_case.m_stage == stage)
11361 	{
11362 		GLchar			   buffer[16];
11363 		const GLuint	   offset	= test_case.m_offset;
11364 		size_t			   position  = 0;
11365 		const Utils::Type& type		 = test_case.m_type;
11366 		const GLchar*	  type_name = type.GetGLSLTypeName();
11367 
11368 		sprintf(buffer, "%d", offset);
11369 
11370 		switch (stage)
11371 		{
11372 		case Utils::Shader::COMPUTE:
11373 			source = cs;
11374 			break;
11375 		case Utils::Shader::FRAGMENT:
11376 			source = fs_tested;
11377 			break;
11378 		case Utils::Shader::GEOMETRY:
11379 			source = gs_tested;
11380 			break;
11381 		case Utils::Shader::TESS_CTRL:
11382 			source = tcs_tested;
11383 			break;
11384 		case Utils::Shader::TESS_EVAL:
11385 			source = tes_tested;
11386 			break;
11387 		case Utils::Shader::VERTEX:
11388 			source = vs_tested;
11389 			break;
11390 		default:
11391 			TCU_FAIL("Invalid enum");
11392 		}
11393 
11394 		Utils::replaceToken("OFFSET", position, buffer, source);
11395 		Utils::replaceToken("TYPE", position, type_name, source);
11396 		Utils::replaceToken("TYPE", position, type_name, source);
11397 	}
11398 	else
11399 	{
11400 		switch (stage)
11401 		{
11402 		case Utils::Shader::FRAGMENT:
11403 			source = fs;
11404 			break;
11405 		case Utils::Shader::GEOMETRY:
11406 			source = gs;
11407 			break;
11408 		case Utils::Shader::TESS_CTRL:
11409 			source = tcs;
11410 			break;
11411 		case Utils::Shader::TESS_EVAL:
11412 			source = tes;
11413 			break;
11414 		case Utils::Shader::VERTEX:
11415 			source = vs;
11416 			break;
11417 		default:
11418 			TCU_FAIL("Invalid enum");
11419 		}
11420 	}
11421 
11422 	return source;
11423 }
11424 
11425 /** Checks if stage is supported
11426  *
11427  * @param stage Shader stage
11428  *
11429  * @return true if supported, false otherwise
11430  **/
11431 bool SSBMemberInvalidOffsetAlignmentTest::isStageSupported(Utils::Shader::STAGES stage)
11432 {
11433 	const Functions& gl					   = m_context.getRenderContext().getFunctions();
11434 	GLint			 max_supported_buffers = 0;
11435 	GLenum			 pname				   = 0;
11436 
11437 	switch (stage)
11438 	{
11439 	case Utils::Shader::COMPUTE:
11440 		pname = GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS;
11441 		break;
11442 	case Utils::Shader::FRAGMENT:
11443 		pname = GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS;
11444 		break;
11445 	case Utils::Shader::GEOMETRY:
11446 		pname = GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS;
11447 		break;
11448 	case Utils::Shader::TESS_CTRL:
11449 		pname = GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS;
11450 		break;
11451 	case Utils::Shader::TESS_EVAL:
11452 		pname = GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS;
11453 		break;
11454 	case Utils::Shader::VERTEX:
11455 		pname = GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS;
11456 		break;
11457 	default:
11458 		TCU_FAIL("Invalid enum");
11459 	}
11460 
11461 	gl.getIntegerv(pname, &max_supported_buffers);
11462 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
11463 
11464 	return 1 <= max_supported_buffers;
11465 }
11466 
11467 /** Constructor
11468  *
11469  * @param context Test framework context
11470  **/
11471 SSBMemberOverlappingOffsetsTest::SSBMemberOverlappingOffsetsTest(deqp::Context& context)
11472 	: UniformBlockMemberOverlappingOffsetsTest(
11473 		  context, "ssb_member_overlapping_offsets",
11474 		  "Test verifies that overlapping offsets qualifiers cause compilation failure")
11475 {
11476 	/* Nothing to be done here */
11477 }
11478 
11479 /** Source for given test case and stage
11480  *
11481  * @param test_case_index Index of test case
11482  * @param stage           Shader stage
11483  *
11484  * @return Shader source
11485  **/
11486 std::string SSBMemberOverlappingOffsetsTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
11487 {
11488 	static const GLchar* cs = "#version 430 core\n"
11489 							  "#extension GL_ARB_enhanced_layouts : require\n"
11490 							  "\n"
11491 							  "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
11492 							  "\n"
11493 							  "layout (std140) buffer Block {\n"
11494 							  "    layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11495 							  "    layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11496 							  "} block;\n"
11497 							  "\n"
11498 							  "writeonly uniform image2D uni_image;\n"
11499 							  "\n"
11500 							  "void main()\n"
11501 							  "{\n"
11502 							  "    vec4 result = vec4(1, 0, 0.5, 1);\n"
11503 							  "\n"
11504 							  "    if ((BOY_TYPE(1) == block.boy) ||\n"
11505 							  "        (MAN_TYPE(0) == block.man) )\n"
11506 							  "    {\n"
11507 							  "        result = vec4(1, 1, 1, 1);\n"
11508 							  "    }\n"
11509 							  "\n"
11510 							  "    imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
11511 							  "}\n"
11512 							  "\n";
11513 	static const GLchar* fs = "#version 430 core\n"
11514 							  "#extension GL_ARB_enhanced_layouts : require\n"
11515 							  "\n"
11516 							  "in  vec4 gs_fs;\n"
11517 							  "out vec4 fs_out;\n"
11518 							  "\n"
11519 							  "void main()\n"
11520 							  "{\n"
11521 							  "    fs_out = gs_fs;\n"
11522 							  "}\n"
11523 							  "\n";
11524 	static const GLchar* fs_tested = "#version 430 core\n"
11525 									 "#extension GL_ARB_enhanced_layouts : require\n"
11526 									 "\n"
11527 									 "layout (std140) buffer Block {\n"
11528 									 "    layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11529 									 "    layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11530 									 "} block;\n"
11531 									 "\n"
11532 									 "in  vec4 gs_fs;\n"
11533 									 "out vec4 fs_out;\n"
11534 									 "\n"
11535 									 "void main()\n"
11536 									 "{\n"
11537 									 "    if ((BOY_TYPE(1) == block.boy) ||\n"
11538 									 "        (MAN_TYPE(0) == block.man) )\n"
11539 									 "    {\n"
11540 									 "        fs_out = vec4(1, 1, 1, 1);\n"
11541 									 "    }\n"
11542 									 "\n"
11543 									 "    fs_out += gs_fs;\n"
11544 									 "}\n"
11545 									 "\n";
11546 	static const GLchar* gs = "#version 430 core\n"
11547 							  "#extension GL_ARB_enhanced_layouts : require\n"
11548 							  "\n"
11549 							  "layout(points)                           in;\n"
11550 							  "layout(triangle_strip, max_vertices = 4) out;\n"
11551 							  "\n"
11552 							  "in  vec4 tes_gs[];\n"
11553 							  "out vec4 gs_fs;\n"
11554 							  "\n"
11555 							  "void main()\n"
11556 							  "{\n"
11557 							  "    gs_fs = tes_gs[0];\n"
11558 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
11559 							  "    EmitVertex();\n"
11560 							  "    gs_fs = tes_gs[0];\n"
11561 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
11562 							  "    EmitVertex();\n"
11563 							  "    gs_fs = tes_gs[0];\n"
11564 							  "    gl_Position  = vec4(1, -1, 0, 1);\n"
11565 							  "    EmitVertex();\n"
11566 							  "    gs_fs = tes_gs[0];\n"
11567 							  "    gl_Position  = vec4(1, 1, 0, 1);\n"
11568 							  "    EmitVertex();\n"
11569 							  "}\n"
11570 							  "\n";
11571 	static const GLchar* gs_tested = "#version 430 core\n"
11572 									 "#extension GL_ARB_enhanced_layouts : require\n"
11573 									 "\n"
11574 									 "layout(points)                           in;\n"
11575 									 "layout(triangle_strip, max_vertices = 4) out;\n"
11576 									 "\n"
11577 									 "layout (std140) buffer Block {\n"
11578 									 "    layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11579 									 "    layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11580 									 "} block;\n"
11581 									 "\n"
11582 									 "in  vec4 tes_gs[];\n"
11583 									 "out vec4 gs_fs;\n"
11584 									 "\n"
11585 									 "void main()\n"
11586 									 "{\n"
11587 									 "    if ((BOY_TYPE(1) == block.boy) ||\n"
11588 									 "        (MAN_TYPE(0) == block.man) )\n"
11589 									 "    {\n"
11590 									 "        gs_fs = vec4(1, 1, 1, 1);\n"
11591 									 "    }\n"
11592 									 "\n"
11593 									 "    gs_fs += tes_gs[0];\n"
11594 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
11595 									 "    EmitVertex();\n"
11596 									 "    gs_fs += tes_gs[0];\n"
11597 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
11598 									 "    EmitVertex();\n"
11599 									 "    gs_fs += tes_gs[0];\n"
11600 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
11601 									 "    EmitVertex();\n"
11602 									 "    gs_fs += tes_gs[0];\n"
11603 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
11604 									 "    EmitVertex();\n"
11605 									 "}\n"
11606 									 "\n";
11607 	static const GLchar* tcs = "#version 430 core\n"
11608 							   "#extension GL_ARB_enhanced_layouts : require\n"
11609 							   "\n"
11610 							   "layout(vertices = 1) out;\n"
11611 							   "\n"
11612 							   "in  vec4 vs_tcs[];\n"
11613 							   "out vec4 tcs_tes[];\n"
11614 							   "\n"
11615 							   "void main()\n"
11616 							   "{\n"
11617 							   "\n"
11618 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
11619 							   "\n"
11620 							   "    gl_TessLevelOuter[0] = 1.0;\n"
11621 							   "    gl_TessLevelOuter[1] = 1.0;\n"
11622 							   "    gl_TessLevelOuter[2] = 1.0;\n"
11623 							   "    gl_TessLevelOuter[3] = 1.0;\n"
11624 							   "    gl_TessLevelInner[0] = 1.0;\n"
11625 							   "    gl_TessLevelInner[1] = 1.0;\n"
11626 							   "}\n"
11627 							   "\n";
11628 	static const GLchar* tcs_tested = "#version 430 core\n"
11629 									  "#extension GL_ARB_enhanced_layouts : require\n"
11630 									  "\n"
11631 									  "layout(vertices = 1) out;\n"
11632 									  "\n"
11633 									  "layout (std140) buffer Block {\n"
11634 									  "    layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11635 									  "    layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11636 									  "} block;\n"
11637 									  "\n"
11638 									  "in  vec4 vs_tcs[];\n"
11639 									  "out vec4 tcs_tes[];\n"
11640 									  "\n"
11641 									  "void main()\n"
11642 									  "{\n"
11643 									  "    if ((BOY_TYPE(1) == block.boy) ||\n"
11644 									  "        (MAN_TYPE(0) == block.man) )\n"
11645 									  "    {\n"
11646 									  "        tcs_tes[gl_InvocationID] = vec4(1, 1, 1, 1);\n"
11647 									  "    }\n"
11648 									  "\n"
11649 									  "\n"
11650 									  "    tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
11651 									  "\n"
11652 									  "    gl_TessLevelOuter[0] = 1.0;\n"
11653 									  "    gl_TessLevelOuter[1] = 1.0;\n"
11654 									  "    gl_TessLevelOuter[2] = 1.0;\n"
11655 									  "    gl_TessLevelOuter[3] = 1.0;\n"
11656 									  "    gl_TessLevelInner[0] = 1.0;\n"
11657 									  "    gl_TessLevelInner[1] = 1.0;\n"
11658 									  "}\n"
11659 									  "\n";
11660 	static const GLchar* tes = "#version 430 core\n"
11661 							   "#extension GL_ARB_enhanced_layouts : require\n"
11662 							   "\n"
11663 							   "layout(isolines, point_mode) in;\n"
11664 							   "\n"
11665 							   "in  vec4 tcs_tes[];\n"
11666 							   "out vec4 tes_gs;\n"
11667 							   "\n"
11668 							   "void main()\n"
11669 							   "{\n"
11670 							   "    tes_gs = tcs_tes[0];\n"
11671 							   "}\n"
11672 							   "\n";
11673 	static const GLchar* tes_tested = "#version 430 core\n"
11674 									  "#extension GL_ARB_enhanced_layouts : require\n"
11675 									  "\n"
11676 									  "layout(isolines, point_mode) in;\n"
11677 									  "\n"
11678 									  "layout (std140) buffer Block {\n"
11679 									  "    layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11680 									  "    layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11681 									  "} block;\n"
11682 									  "\n"
11683 									  "in  vec4 tcs_tes[];\n"
11684 									  "out vec4 tes_gs;\n"
11685 									  "\n"
11686 									  "void main()\n"
11687 									  "{\n"
11688 									  "    if ((BOY_TYPE(1) == block.boy) ||\n"
11689 									  "        (MAN_TYPE(0) == block.man) )\n"
11690 									  "    {\n"
11691 									  "        tes_gs = vec4(1, 1, 1, 1);\n"
11692 									  "    }\n"
11693 									  "\n"
11694 									  "    tes_gs += tcs_tes[0];\n"
11695 									  "}\n"
11696 									  "\n";
11697 	static const GLchar* vs = "#version 430 core\n"
11698 							  "#extension GL_ARB_enhanced_layouts : require\n"
11699 							  "\n"
11700 							  "in  vec4 in_vs;\n"
11701 							  "out vec4 vs_tcs;\n"
11702 							  "\n"
11703 							  "void main()\n"
11704 							  "{\n"
11705 							  "    vs_tcs = in_vs;\n"
11706 							  "}\n"
11707 							  "\n";
11708 	static const GLchar* vs_tested = "#version 430 core\n"
11709 									 "#extension GL_ARB_enhanced_layouts : require\n"
11710 									 "\n"
11711 									 "layout (std140) buffer Block {\n"
11712 									 "    layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11713 									 "    layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11714 									 "} block;\n"
11715 									 "\n"
11716 									 "in  vec4 in_vs;\n"
11717 									 "out vec4 vs_tcs;\n"
11718 									 "\n"
11719 									 "void main()\n"
11720 									 "{\n"
11721 									 "    if ((BOY_TYPE(1) == block.boy) ||\n"
11722 									 "        (MAN_TYPE(0) == block.man) )\n"
11723 									 "    {\n"
11724 									 "        vs_tcs = vec4(1, 1, 1, 1);\n"
11725 									 "    }\n"
11726 									 "\n"
11727 									 "    vs_tcs += in_vs;\n"
11728 									 "}\n"
11729 									 "\n";
11730 
11731 	std::string source;
11732 	testCase&   test_case = m_test_cases[test_case_index];
11733 
11734 	if (test_case.m_stage == stage)
11735 	{
11736 		GLchar			   buffer[16];
11737 		const GLuint	   boy_offset	= test_case.m_boy_offset;
11738 		const Utils::Type& boy_type		 = test_case.m_boy_type;
11739 		const GLchar*	  boy_type_name = boy_type.GetGLSLTypeName();
11740 		const GLuint	   man_offset	= test_case.m_man_offset;
11741 		const Utils::Type& man_type		 = test_case.m_man_type;
11742 		const GLchar*	  man_type_name = man_type.GetGLSLTypeName();
11743 		size_t			   position		 = 0;
11744 
11745 		switch (stage)
11746 		{
11747 		case Utils::Shader::COMPUTE:
11748 			source = cs;
11749 			break;
11750 		case Utils::Shader::FRAGMENT:
11751 			source = fs_tested;
11752 			break;
11753 		case Utils::Shader::GEOMETRY:
11754 			source = gs_tested;
11755 			break;
11756 		case Utils::Shader::TESS_CTRL:
11757 			source = tcs_tested;
11758 			break;
11759 		case Utils::Shader::TESS_EVAL:
11760 			source = tes_tested;
11761 			break;
11762 		case Utils::Shader::VERTEX:
11763 			source = vs_tested;
11764 			break;
11765 		default:
11766 			TCU_FAIL("Invalid enum");
11767 		}
11768 
11769 		sprintf(buffer, "%d", boy_offset);
11770 		Utils::replaceToken("BOY_OFFSET", position, buffer, source);
11771 		Utils::replaceToken("BOY_TYPE", position, boy_type_name, source);
11772 		sprintf(buffer, "%d", man_offset);
11773 		Utils::replaceToken("MAN_OFFSET", position, buffer, source);
11774 		Utils::replaceToken("MAN_TYPE", position, man_type_name, source);
11775 		Utils::replaceToken("BOY_TYPE", position, boy_type_name, source);
11776 		Utils::replaceToken("MAN_TYPE", position, man_type_name, source);
11777 	}
11778 	else
11779 	{
11780 		switch (stage)
11781 		{
11782 		case Utils::Shader::FRAGMENT:
11783 			source = fs;
11784 			break;
11785 		case Utils::Shader::GEOMETRY:
11786 			source = gs;
11787 			break;
11788 		case Utils::Shader::TESS_CTRL:
11789 			source = tcs;
11790 			break;
11791 		case Utils::Shader::TESS_EVAL:
11792 			source = tes;
11793 			break;
11794 		case Utils::Shader::VERTEX:
11795 			source = vs;
11796 			break;
11797 		default:
11798 			TCU_FAIL("Invalid enum");
11799 		}
11800 	}
11801 
11802 	return source;
11803 }
11804 
11805 /** Checks if stage is supported
11806  *
11807  * @param stage Shader stage
11808  *
11809  * @return true if supported, false otherwise
11810  **/
11811 bool SSBMemberOverlappingOffsetsTest::isStageSupported(Utils::Shader::STAGES stage)
11812 {
11813 	const Functions& gl					   = m_context.getRenderContext().getFunctions();
11814 	GLint			 max_supported_buffers = 0;
11815 	GLenum			 pname				   = 0;
11816 
11817 	switch (stage)
11818 	{
11819 	case Utils::Shader::COMPUTE:
11820 		pname = GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS;
11821 		break;
11822 	case Utils::Shader::FRAGMENT:
11823 		pname = GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS;
11824 		break;
11825 	case Utils::Shader::GEOMETRY:
11826 		pname = GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS;
11827 		break;
11828 	case Utils::Shader::TESS_CTRL:
11829 		pname = GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS;
11830 		break;
11831 	case Utils::Shader::TESS_EVAL:
11832 		pname = GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS;
11833 		break;
11834 	case Utils::Shader::VERTEX:
11835 		pname = GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS;
11836 		break;
11837 	default:
11838 		TCU_FAIL("Invalid enum");
11839 	}
11840 
11841 	gl.getIntegerv(pname, &max_supported_buffers);
11842 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
11843 
11844 	return 1 <= max_supported_buffers;
11845 }
11846 
11847 /** Constructor
11848  *
11849  * @param context Test framework context
11850  **/
11851 SSBMemberAlignNonPowerOf2Test::SSBMemberAlignNonPowerOf2Test(deqp::Context& context)
11852 	: UniformBlockMemberAlignNonPowerOf2Test(context, "ssb_member_align_non_power_of_2",
11853 											 "Test verifies that align qualifier requires value that is a power of 2")
11854 {
11855 	/* Nothing to be done here */
11856 }
11857 
11858 /** Source for given test case and stage
11859  *
11860  * @param test_case_index Index of test case
11861  * @param stage           Shader stage
11862  *
11863  * @return Shader source
11864  **/
11865 std::string SSBMemberAlignNonPowerOf2Test::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
11866 {
11867 	static const GLchar* cs = "#version 430 core\n"
11868 							  "#extension GL_ARB_enhanced_layouts : require\n"
11869 							  "\n"
11870 							  "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
11871 							  "\n"
11872 							  "layout (std140) buffer Block {\n"
11873 							  "    vec4 boy;\n"
11874 							  "    layout (align = ALIGN) TYPE man;\n"
11875 							  "} block;\n"
11876 							  "\n"
11877 							  "writeonly uniform image2D uni_image;\n"
11878 							  "\n"
11879 							  "void main()\n"
11880 							  "{\n"
11881 							  "    vec4 result = vec4(1, 0, 0.5, 1);\n"
11882 							  "\n"
11883 							  "    if (TYPE(0) == block.man)\n"
11884 							  "    {\n"
11885 							  "        result = vec4(1, 1, 1, 1) - block.boy;\n"
11886 							  "    }\n"
11887 							  "\n"
11888 							  "    imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
11889 							  "}\n"
11890 							  "\n";
11891 	static const GLchar* fs = "#version 430 core\n"
11892 							  "#extension GL_ARB_enhanced_layouts : require\n"
11893 							  "\n"
11894 							  "in  vec4 gs_fs;\n"
11895 							  "out vec4 fs_out;\n"
11896 							  "\n"
11897 							  "void main()\n"
11898 							  "{\n"
11899 							  "    fs_out = gs_fs;\n"
11900 							  "}\n"
11901 							  "\n";
11902 	static const GLchar* fs_tested = "#version 430 core\n"
11903 									 "#extension GL_ARB_enhanced_layouts : require\n"
11904 									 "\n"
11905 									 "layout (std140) buffer Block {\n"
11906 									 "    vec4 boy;\n"
11907 									 "    layout (align = ALIGN) TYPE man;\n"
11908 									 "} block;\n"
11909 									 "\n"
11910 									 "in  vec4 gs_fs;\n"
11911 									 "out vec4 fs_out;\n"
11912 									 "\n"
11913 									 "void main()\n"
11914 									 "{\n"
11915 									 "    if (TYPE(0) == block.man)\n"
11916 									 "    {\n"
11917 									 "        fs_out = block.boy;\n"
11918 									 "    }\n"
11919 									 "\n"
11920 									 "    fs_out += gs_fs;\n"
11921 									 "}\n"
11922 									 "\n";
11923 	static const GLchar* gs = "#version 430 core\n"
11924 							  "#extension GL_ARB_enhanced_layouts : require\n"
11925 							  "\n"
11926 							  "layout(points)                           in;\n"
11927 							  "layout(triangle_strip, max_vertices = 4) out;\n"
11928 							  "\n"
11929 							  "in  vec4 tes_gs[];\n"
11930 							  "out vec4 gs_fs;\n"
11931 							  "\n"
11932 							  "void main()\n"
11933 							  "{\n"
11934 							  "    gs_fs = tes_gs[0];\n"
11935 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
11936 							  "    EmitVertex();\n"
11937 							  "    gs_fs = tes_gs[0];\n"
11938 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
11939 							  "    EmitVertex();\n"
11940 							  "    gs_fs = tes_gs[0];\n"
11941 							  "    gl_Position  = vec4(1, -1, 0, 1);\n"
11942 							  "    EmitVertex();\n"
11943 							  "    gs_fs = tes_gs[0];\n"
11944 							  "    gl_Position  = vec4(1, 1, 0, 1);\n"
11945 							  "    EmitVertex();\n"
11946 							  "}\n"
11947 							  "\n";
11948 	static const GLchar* gs_tested = "#version 430 core\n"
11949 									 "#extension GL_ARB_enhanced_layouts : require\n"
11950 									 "\n"
11951 									 "layout(points)                           in;\n"
11952 									 "layout(triangle_strip, max_vertices = 4) out;\n"
11953 									 "\n"
11954 									 "layout (std140) buffer Block {\n"
11955 									 "    vec4 boy;\n"
11956 									 "    layout (align = ALIGN) TYPE man;\n"
11957 									 "} block;\n"
11958 									 "\n"
11959 									 "in  vec4 tes_gs[];\n"
11960 									 "out vec4 gs_fs;\n"
11961 									 "\n"
11962 									 "void main()\n"
11963 									 "{\n"
11964 									 "    if (TYPE(0) == block.man)\n"
11965 									 "    {\n"
11966 									 "        gs_fs = block.boy;\n"
11967 									 "    }\n"
11968 									 "\n"
11969 									 "    gs_fs += tes_gs[0];\n"
11970 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
11971 									 "    EmitVertex();\n"
11972 									 "    gs_fs += tes_gs[0];\n"
11973 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
11974 									 "    EmitVertex();\n"
11975 									 "    gs_fs += tes_gs[0];\n"
11976 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
11977 									 "    EmitVertex();\n"
11978 									 "    gs_fs += tes_gs[0];\n"
11979 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
11980 									 "    EmitVertex();\n"
11981 									 "}\n"
11982 									 "\n";
11983 	static const GLchar* tcs = "#version 430 core\n"
11984 							   "#extension GL_ARB_enhanced_layouts : require\n"
11985 							   "\n"
11986 							   "layout(vertices = 1) out;\n"
11987 							   "\n"
11988 							   "in  vec4 vs_tcs[];\n"
11989 							   "out vec4 tcs_tes[];\n"
11990 							   "\n"
11991 							   "void main()\n"
11992 							   "{\n"
11993 							   "\n"
11994 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
11995 							   "\n"
11996 							   "    gl_TessLevelOuter[0] = 1.0;\n"
11997 							   "    gl_TessLevelOuter[1] = 1.0;\n"
11998 							   "    gl_TessLevelOuter[2] = 1.0;\n"
11999 							   "    gl_TessLevelOuter[3] = 1.0;\n"
12000 							   "    gl_TessLevelInner[0] = 1.0;\n"
12001 							   "    gl_TessLevelInner[1] = 1.0;\n"
12002 							   "}\n"
12003 							   "\n";
12004 	static const GLchar* tcs_tested = "#version 430 core\n"
12005 									  "#extension GL_ARB_enhanced_layouts : require\n"
12006 									  "\n"
12007 									  "layout(vertices = 1) out;\n"
12008 									  "\n"
12009 									  "layout (std140) buffer Block {\n"
12010 									  "    vec4 boy;\n"
12011 									  "    layout (align = ALIGN) TYPE man;\n"
12012 									  "} block;\n"
12013 									  "\n"
12014 									  "in  vec4 vs_tcs[];\n"
12015 									  "out vec4 tcs_tes[];\n"
12016 									  "\n"
12017 									  "void main()\n"
12018 									  "{\n"
12019 									  "    if (TYPE(0) == block.man)\n"
12020 									  "    {\n"
12021 									  "        tcs_tes[gl_InvocationID] = block.boy;\n"
12022 									  "    }\n"
12023 									  "\n"
12024 									  "\n"
12025 									  "    tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
12026 									  "\n"
12027 									  "    gl_TessLevelOuter[0] = 1.0;\n"
12028 									  "    gl_TessLevelOuter[1] = 1.0;\n"
12029 									  "    gl_TessLevelOuter[2] = 1.0;\n"
12030 									  "    gl_TessLevelOuter[3] = 1.0;\n"
12031 									  "    gl_TessLevelInner[0] = 1.0;\n"
12032 									  "    gl_TessLevelInner[1] = 1.0;\n"
12033 									  "}\n"
12034 									  "\n";
12035 	static const GLchar* tes = "#version 430 core\n"
12036 							   "#extension GL_ARB_enhanced_layouts : require\n"
12037 							   "\n"
12038 							   "layout(isolines, point_mode) in;\n"
12039 							   "\n"
12040 							   "in  vec4 tcs_tes[];\n"
12041 							   "out vec4 tes_gs;\n"
12042 							   "\n"
12043 							   "void main()\n"
12044 							   "{\n"
12045 							   "    tes_gs = tcs_tes[0];\n"
12046 							   "}\n"
12047 							   "\n";
12048 	static const GLchar* tes_tested = "#version 430 core\n"
12049 									  "#extension GL_ARB_enhanced_layouts : require\n"
12050 									  "\n"
12051 									  "layout(isolines, point_mode) in;\n"
12052 									  "\n"
12053 									  "layout (std140) buffer Block {\n"
12054 									  "    vec4 boy;\n"
12055 									  "    layout (align = ALIGN) TYPE man;\n"
12056 									  "} block;\n"
12057 									  "\n"
12058 									  "in  vec4 tcs_tes[];\n"
12059 									  "out vec4 tes_gs;\n"
12060 									  "\n"
12061 									  "void main()\n"
12062 									  "{\n"
12063 									  "    if (TYPE(0) == block.man)\n"
12064 									  "    {\n"
12065 									  "        tes_gs = block.boy;\n"
12066 									  "    }\n"
12067 									  "\n"
12068 									  "    tes_gs += tcs_tes[0];\n"
12069 									  "}\n"
12070 									  "\n";
12071 	static const GLchar* vs = "#version 430 core\n"
12072 							  "#extension GL_ARB_enhanced_layouts : require\n"
12073 							  "\n"
12074 							  "in  vec4 in_vs;\n"
12075 							  "out vec4 vs_tcs;\n"
12076 							  "\n"
12077 							  "void main()\n"
12078 							  "{\n"
12079 							  "    vs_tcs = in_vs;\n"
12080 							  "}\n"
12081 							  "\n";
12082 	static const GLchar* vs_tested = "#version 430 core\n"
12083 									 "#extension GL_ARB_enhanced_layouts : require\n"
12084 									 "\n"
12085 									 "layout (std140) buffer Block {\n"
12086 									 "    vec4 boy;\n"
12087 									 "    layout (align = ALIGN) TYPE man;\n"
12088 									 "} block;\n"
12089 									 "\n"
12090 									 "in  vec4 in_vs;\n"
12091 									 "out vec4 vs_tcs;\n"
12092 									 "\n"
12093 									 "void main()\n"
12094 									 "{\n"
12095 									 "    if (TYPE(0) == block.man)\n"
12096 									 "    {\n"
12097 									 "        vs_tcs = block.boy;\n"
12098 									 "    }\n"
12099 									 "\n"
12100 									 "    vs_tcs += in_vs;\n"
12101 									 "}\n"
12102 									 "\n";
12103 
12104 	std::string source;
12105 	testCase&   test_case = m_test_cases[test_case_index];
12106 
12107 	if (test_case.m_stage == stage)
12108 	{
12109 		GLchar			   buffer[16];
12110 		const GLuint	   alignment = test_case.m_alignment;
12111 		const Utils::Type& type		 = test_case.m_type;
12112 		const GLchar*	  type_name = type.GetGLSLTypeName();
12113 		size_t			   position  = 0;
12114 
12115 		switch (stage)
12116 		{
12117 		case Utils::Shader::COMPUTE:
12118 			source = cs;
12119 			break;
12120 		case Utils::Shader::FRAGMENT:
12121 			source = fs_tested;
12122 			break;
12123 		case Utils::Shader::GEOMETRY:
12124 			source = gs_tested;
12125 			break;
12126 		case Utils::Shader::TESS_CTRL:
12127 			source = tcs_tested;
12128 			break;
12129 		case Utils::Shader::TESS_EVAL:
12130 			source = tes_tested;
12131 			break;
12132 		case Utils::Shader::VERTEX:
12133 			source = vs_tested;
12134 			break;
12135 		default:
12136 			TCU_FAIL("Invalid enum");
12137 		}
12138 
12139 		sprintf(buffer, "%d", alignment);
12140 		Utils::replaceToken("ALIGN", position, buffer, source);
12141 		Utils::replaceToken("TYPE", position, type_name, source);
12142 		Utils::replaceToken("TYPE", position, type_name, source);
12143 	}
12144 	else
12145 	{
12146 		switch (stage)
12147 		{
12148 		case Utils::Shader::FRAGMENT:
12149 			source = fs;
12150 			break;
12151 		case Utils::Shader::GEOMETRY:
12152 			source = gs;
12153 			break;
12154 		case Utils::Shader::TESS_CTRL:
12155 			source = tcs;
12156 			break;
12157 		case Utils::Shader::TESS_EVAL:
12158 			source = tes;
12159 			break;
12160 		case Utils::Shader::VERTEX:
12161 			source = vs;
12162 			break;
12163 		default:
12164 			TCU_FAIL("Invalid enum");
12165 		}
12166 	}
12167 
12168 	return source;
12169 }
12170 
12171 /** Checks if stage is supported
12172  *
12173  * @param stage Shader stage
12174  *
12175  * @return true if supported, false otherwise
12176  **/
12177 bool SSBMemberAlignNonPowerOf2Test::isStageSupported(Utils::Shader::STAGES stage)
12178 {
12179 	const Functions& gl					   = m_context.getRenderContext().getFunctions();
12180 	GLint			 max_supported_buffers = 0;
12181 	GLenum			 pname				   = 0;
12182 
12183 	switch (stage)
12184 	{
12185 	case Utils::Shader::COMPUTE:
12186 		pname = GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS;
12187 		break;
12188 	case Utils::Shader::FRAGMENT:
12189 		pname = GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS;
12190 		break;
12191 	case Utils::Shader::GEOMETRY:
12192 		pname = GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS;
12193 		break;
12194 	case Utils::Shader::TESS_CTRL:
12195 		pname = GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS;
12196 		break;
12197 	case Utils::Shader::TESS_EVAL:
12198 		pname = GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS;
12199 		break;
12200 	case Utils::Shader::VERTEX:
12201 		pname = GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS;
12202 		break;
12203 	default:
12204 		TCU_FAIL("Invalid enum");
12205 	}
12206 
12207 	gl.getIntegerv(pname, &max_supported_buffers);
12208 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
12209 
12210 	return 1 <= max_supported_buffers;
12211 }
12212 
12213 /** Constructor
12214  *
12215  * @param context Test framework context
12216  **/
12217 SSBAlignmentTest::SSBAlignmentTest(deqp::Context& context)
12218 	: TextureTestBase(context, "ssb_alignment", "Test verifies offset and alignment of ssb buffer")
12219 {
12220 }
12221 
12222 /** Get interface of program
12223  *
12224  * @param ignored
12225  * @param program_interface Interface of program
12226  * @param varying_passthrough Collection of connections between in and out variables
12227  **/
12228 void SSBAlignmentTest::getProgramInterface(GLuint /* test_case_index */, Utils::ProgramInterface& program_interface,
12229 										   Utils::VaryingPassthrough& varying_passthrough)
12230 {
12231 	static const Utils::Type vec4 = Utils::Type::vec4;
12232 
12233 #if WRKARD_UNIFORMBLOCKALIGNMENT
12234 
12235 	static const GLuint block_align = 16;
12236 
12237 #else /* WRKARD_UNIFORMBLOCKALIGNMENT */
12238 
12239 	static const GLuint block_align = 64;
12240 
12241 #endif /* WRKARD_UNIFORMBLOCKALIGNMENT */
12242 
12243 	static const GLuint fifth_align = 16;
12244 	static const GLuint vec4_stride = 16;
12245 	static const GLuint data_stride = vec4_stride * 2; /* one vec4 + one scalar aligned to 16 */
12246 
12247 	const GLuint first_offset  = 0;																		/* vec4 at 0 */
12248 	const GLuint second_offset = Utils::Type::GetActualOffset(first_offset + vec4_stride, block_align); /* Data at 32 */
12249 	const GLuint third_offset =
12250 		Utils::Type::GetActualOffset(second_offset + data_stride, block_align); /* Data[2] at 64 */
12251 	const GLuint fourth_offset =
12252 		Utils::Type::GetActualOffset(third_offset + data_stride * 2, block_align); /* vec4[3] at 96 */
12253 	const GLuint fifth_offset =
12254 		Utils::Type::GetActualOffset(fourth_offset + vec4_stride * 3, fifth_align); /* vec4[2] at 160 */
12255 	const GLuint sixth_offset =
12256 		Utils::Type::GetActualOffset(fifth_offset + vec4_stride * 2, block_align); /* Data at 192 */
12257 
12258 	Utils::Interface* structure = program_interface.Structure("Data");
12259 
12260 	structure->Member("vector", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::vec4,
12261 					  false /* normalized */, 0 /* n_array_elements */, Utils::Type::vec4.GetSize(), 0 /* offset */);
12262 
12263 	structure->Member("scalar", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::_float,
12264 					  false /* normalized */, 0 /* n_array_elements */, Utils::Type::_float.GetSize(),
12265 					  Utils::Type::vec4.GetSize() /* offset */);
12266 
12267 	/* Prepare Block */
12268 	Utils::Interface* vs_buf_Block = program_interface.Block("vs_buf_Block");
12269 
12270 	vs_buf_Block->Member("first", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::vec4,
12271 						 false /* normalized */, 0 /* n_array_elements */, vec4_stride, first_offset /* offset */);
12272 
12273 	vs_buf_Block->Member("second", "", 0 /* expected_component */, 0 /* expected_location */, structure,
12274 						 0 /* n_array_elements */, data_stride, second_offset);
12275 
12276 	vs_buf_Block->Member("third", "", 0 /* expected_component */, 0 /* expected_location */, structure,
12277 						 2 /* n_array_elements */, data_stride, third_offset);
12278 
12279 	vs_buf_Block->Member("fourth", "", 0 /* expected_component */, 0 /* expected_location */, vec4,
12280 						 false /* normalized */, 3 /* n_array_elements */, vec4_stride, fourth_offset);
12281 
12282 	vs_buf_Block->Member("fifth", "layout(align = 16)", 0 /* expected_component */, 0 /* expected_location */, vec4,
12283 						 false /* normalized */, 2 /* n_array_elements */, vec4_stride, fifth_offset);
12284 
12285 	vs_buf_Block->Member("sixth", "", 0 /* expected_component */, 0 /* expected_location */, structure,
12286 						 0 /* n_array_elements */, data_stride, sixth_offset);
12287 
12288 	const GLuint stride = calculateStride(*vs_buf_Block);
12289 	m_data.resize(stride);
12290 	generateData(*vs_buf_Block, 0, m_data);
12291 
12292 	Utils::ShaderInterface& vs_si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
12293 
12294 /* Add uniform BLOCK */
12295 #if WRKARD_UNIFORMBLOCKALIGNMENT
12296 	vs_si.SSB("vs_buf_block", "layout (std140, binding = BINDING)", 0, 0, vs_buf_Block, 0,
12297 			  static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
12298 #else  /* WRKARD_UNIFORMBLOCKALIGNMENT */
12299 	vs_si.SSB("vs_buf_block", "layout (std140, binding = BINDING, align = 64)", 0, 0, vs_buf_Block, 0,
12300 			  static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
12301 #endif /* WRKARD_UNIFORMBLOCKALIGNMENT */
12302 
12303 	program_interface.CloneVertexInterface(varying_passthrough);
12304 }
12305 
12306 /** Selects if "draw" stages are relevant for test
12307  *
12308  * @param ignored
12309  *
12310  * @return true if all stages support shader storage buffers, false otherwise
12311  **/
12312 bool SSBAlignmentTest::isDrawRelevant(GLuint /* test_case_index */)
12313 {
12314 	const Functions& gl					   = m_context.getRenderContext().getFunctions();
12315 	GLint			 gs_supported_buffers  = 0;
12316 	GLint			 tcs_supported_buffers = 0;
12317 	GLint			 tes_supported_buffers = 0;
12318 	GLint			 vs_supported_buffers  = 0;
12319 
12320 	gl.getIntegerv(GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS, &gs_supported_buffers);
12321 	gl.getIntegerv(GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS, &tcs_supported_buffers);
12322 	gl.getIntegerv(GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS, &tes_supported_buffers);
12323 	gl.getIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &vs_supported_buffers);
12324 
12325 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
12326 
12327 	return ((1 <= gs_supported_buffers) && (1 <= tcs_supported_buffers) && (1 <= tes_supported_buffers) &&
12328 			(1 <= vs_supported_buffers));
12329 }
12330 
12331 /** Constructor
12332  *
12333  * @param context Test framework context
12334  **/
12335 VaryingLocationsTest::VaryingLocationsTest(deqp::Context& context)
12336 	: TextureTestBase(context, "varying_locations", "Test verifies that input and output locations are respected")
12337 {
12338 }
12339 
12340 /** Constructor
12341  *
12342  * @param context          Test context
12343  * @param test_name        Name of test
12344  * @param test_description Description of test
12345  **/
12346 VaryingLocationsTest::VaryingLocationsTest(deqp::Context& context, const glw::GLchar* test_name,
12347 										   const glw::GLchar* test_description)
12348 	: TextureTestBase(context, test_name, test_description)
12349 {
12350 }
12351 
12352 /** Get interface of program
12353  *
12354  * @param test_case_index     Test case
12355  * @param program_interface   Interface of program
12356  * @param varying_passthrough Collection of connections between in and out variables
12357  **/
12358 void VaryingLocationsTest::getProgramInterface(GLuint test_case_index, Utils::ProgramInterface& program_interface,
12359 											   Utils::VaryingPassthrough& varying_passthrough)
12360 {
12361 	const Utils::Type type = getType(test_case_index);
12362 
12363 	m_first_data = type.GenerateDataPacked();
12364 	m_last_data  = type.GenerateDataPacked();
12365 
12366 	prepareShaderStage(Utils::Shader::FRAGMENT, type, program_interface, varying_passthrough);
12367 	prepareShaderStage(Utils::Shader::GEOMETRY, type, program_interface, varying_passthrough);
12368 	prepareShaderStage(Utils::Shader::TESS_CTRL, type, program_interface, varying_passthrough);
12369 	prepareShaderStage(Utils::Shader::TESS_EVAL, type, program_interface, varying_passthrough);
12370 	prepareShaderStage(Utils::Shader::VERTEX, type, program_interface, varying_passthrough);
12371 }
12372 
12373 /** Get type name
12374  *
12375  * @param test_case_index Index of test case
12376  *
12377  * @return Name of type test in test_case_index
12378  **/
12379 std::string VaryingLocationsTest::getTestCaseName(glw::GLuint test_case_index)
12380 {
12381 	return getTypeName(test_case_index);
12382 }
12383 
12384 /** Returns number of types to test
12385  *
12386  * @return Number of types, 34
12387  **/
12388 glw::GLuint VaryingLocationsTest::getTestCaseNumber()
12389 {
12390 	return getTypesNumber();
12391 }
12392 
12393 /** Selects if "compute" stage is relevant for test
12394  *
12395  * @param ignored
12396  *
12397  * @return false
12398  **/
12399 bool VaryingLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
12400 {
12401 	return false;
12402 }
12403 
12404 /**
12405  *
12406  *
12407  **/
12408 std::string VaryingLocationsTest::prepareGlobals(GLint last_in_loc, GLint last_out_loc)
12409 {
12410 	GLchar		buffer[16];
12411 	std::string globals = "const uint first_input_location  = 0u;\n"
12412 						  "const uint first_output_location = 0u;\n"
12413 						  "const uint last_input_location   = LAST_INPUTu;\n"
12414 						  "const uint last_output_location  = LAST_OUTPUTu;\n";
12415 	size_t position = 100; /* Skip first part */
12416 
12417 	sprintf(buffer, "%d", last_in_loc);
12418 	Utils::replaceToken("LAST_INPUT", position, buffer, globals);
12419 
12420 	sprintf(buffer, "%d", last_out_loc);
12421 	Utils::replaceToken("LAST_OUTPUT", position, buffer, globals);
12422 
12423 	return globals;
12424 }
12425 
12426 /**
12427  *
12428  **/
12429 void VaryingLocationsTest::prepareShaderStage(Utils::Shader::STAGES stage, const Utils::Type& type,
12430 											  Utils::ProgramInterface&   program_interface,
12431 											  Utils::VaryingPassthrough& varying_passthrough)
12432 {
12433 	const GLuint array_length  = 1;
12434 	const GLuint first_in_loc  = 0;
12435 	const GLuint first_out_loc = 0;
12436 	const GLuint last_in_loc   = getLastInputLocation(stage, type, array_length, false);
12437 	size_t		 position	  = 0;
12438 
12439 	const GLchar* prefix_in = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::VARYING_INPUT);
12440 
12441 	const GLchar* prefix_out = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::VARYING_OUTPUT);
12442 
12443 	const GLchar* qual_first_in  = "layout (location = first_input_location)";
12444 	const GLchar* qual_first_out = "layout (location = first_output_location)";
12445 	const GLchar* qual_last_in   = "layout (location = last_input_location)";
12446 	const GLchar* qual_last_out  = "layout (location = last_output_location)";
12447 
12448 	Utils::ShaderInterface& si		  = program_interface.GetShaderInterface(stage);
12449 	const GLuint			type_size = type.GetSize();
12450 
12451 	std::string first_in_name  = "PREFIXfirst";
12452 	std::string first_out_name = "PREFIXfirst";
12453 	std::string last_in_name   = "PREFIXlast";
12454 	std::string last_out_name  = "PREFIXlast";
12455 
12456 	Utils::replaceToken("PREFIX", position, prefix_in, first_in_name);
12457 	position = 0;
12458 	Utils::replaceToken("PREFIX", position, prefix_out, first_out_name);
12459 	position = 0;
12460 	Utils::replaceToken("PREFIX", position, prefix_in, last_in_name);
12461 	position = 0;
12462 	Utils::replaceToken("PREFIX", position, prefix_out, last_out_name);
12463 
12464 	if (Utils::Shader::FRAGMENT == stage)
12465 	{
12466 		qual_first_in = "layout (location = first_input_location) flat";
12467 		qual_last_in  = "layout (location = last_input_location)  flat";
12468 	}
12469 	if (Utils::Shader::GEOMETRY == stage)
12470 	{
12471 		qual_first_out = "layout (location = first_output_location) flat";
12472 		qual_last_out  = "layout (location = last_output_location)  flat";
12473 	}
12474 
12475 	Utils::Variable* first_in = si.Input(
12476 		first_in_name.c_str(), qual_first_in /* qualifiers */, 0 /* expected_componenet */,
12477 		first_in_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */, 0u /* n_array_elements */,
12478 		0u /* stride */, 0u /* offset */, (GLvoid*)&m_first_data[0] /* data */, m_first_data.size() /* data_size */);
12479 
12480 	Utils::Variable* last_in =
12481 		si.Input(last_in_name.c_str(), qual_last_in /* qualifiers */, 0 /* expected_componenet */,
12482 				 last_in_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12483 				 0u /* n_array_elements */, 0u /* stride */, type_size /* offset */,
12484 				 (GLvoid*)&m_last_data[0] /* data */, m_last_data.size() /* data_size */);
12485 
12486 	if (Utils::Shader::FRAGMENT != stage)
12487 	{
12488 		const GLuint last_out_loc = getLastOutputLocation(stage, type, array_length, false);
12489 
12490 		Utils::Variable* first_out =
12491 			si.Output(first_out_name.c_str(), qual_first_out /* qualifiers */, 0 /* expected_componenet */,
12492 					  first_out_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12493 					  0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)&m_first_data[0] /* data */,
12494 					  m_first_data.size() /* data_size */);
12495 
12496 		Utils::Variable* last_out = si.Output(
12497 			last_out_name.c_str(), qual_last_out /* qualifiers */, 0 /* expected_componenet */,
12498 			last_out_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */, 0u /* n_array_elements */,
12499 			0u /* stride */, 0u /* offset */, (GLvoid*)&m_last_data[0] /* data */, m_last_data.size() /* data_size */);
12500 
12501 		si.m_globals = prepareGlobals(last_in_loc, last_out_loc);
12502 
12503 		varying_passthrough.Add(stage, first_in, first_out);
12504 		varying_passthrough.Add(stage, last_in, last_out);
12505 	}
12506 	else
12507 	{
12508 		/* No outputs for fragment shader, so last_output_location can be 0 */
12509 		si.m_globals = prepareGlobals(last_in_loc, 0);
12510 	}
12511 }
12512 
12513 /** This test should be run with separable programs
12514  *
12515  * @param ignored
12516  *
12517  * @return true
12518  **/
12519 bool VaryingLocationsTest::useMonolithicProgram(GLuint /* test_case_index */)
12520 {
12521 	return false;
12522 }
12523 
12524 /* Constants used by VertexAttribLocationsTest */
12525 const GLuint VertexAttribLocationsTest::m_base_vertex   = 4;
12526 const GLuint VertexAttribLocationsTest::m_base_instance = 2;
12527 const GLuint VertexAttribLocationsTest::m_loc_vertex	= 2;
12528 const GLuint VertexAttribLocationsTest::m_loc_instance  = 5;
12529 const GLuint VertexAttribLocationsTest::m_n_instances   = 4;
12530 
12531 /** Constructor
12532  *
12533  * @param context Test framework context
12534  **/
12535 VertexAttribLocationsTest::VertexAttribLocationsTest(deqp::Context& context)
12536 	: TextureTestBase(context, "vertex_attrib_locations",
12537 					  "Test verifies that attribute locations are respected by drawing operations")
12538 {
12539 }
12540 
12541 /** Execute proper draw command for test case
12542  *
12543  * @param test_case_index Index of test case
12544  **/
12545 void VertexAttribLocationsTest::executeDrawCall(GLuint test_case_index)
12546 {
12547 	const Functions& gl = m_context.getRenderContext().getFunctions();
12548 
12549 	switch (test_case_index)
12550 	{
12551 	case DRAWARRAYS:
12552 		gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
12553 		GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
12554 		break;
12555 	case DRAWARRAYSINSTANCED:
12556 		gl.drawArraysInstanced(GL_PATCHES, 0 /* first */, 1 /* count */, m_n_instances);
12557 		GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArraysInstanced");
12558 		break;
12559 	case DRAWELEMENTS:
12560 		gl.drawElements(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL);
12561 		GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElements");
12562 		break;
12563 	case DRAWELEMENTSBASEVERTEX:
12564 		gl.drawElementsBaseVertex(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL, m_base_vertex);
12565 		GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsBaseVertex");
12566 		break;
12567 	case DRAWELEMENTSINSTANCED:
12568 		gl.drawElementsInstanced(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL, m_n_instances);
12569 		GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsInstanced");
12570 		break;
12571 	case DRAWELEMENTSINSTANCEDBASEINSTANCE:
12572 		gl.drawElementsInstancedBaseInstance(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL, m_n_instances,
12573 											 m_base_instance);
12574 		GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsInstancedBaseInstance");
12575 		break;
12576 	case DRAWELEMENTSINSTANCEDBASEVERTEX:
12577 		gl.drawElementsInstancedBaseVertex(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL, m_n_instances,
12578 										   m_base_vertex);
12579 		GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsInstancedBaseVertex");
12580 		break;
12581 	case DRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCE:
12582 		gl.drawElementsInstancedBaseVertexBaseInstance(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL,
12583 													   m_n_instances, m_base_vertex, m_base_instance);
12584 		GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsInstancedBaseVertexBaseInstance");
12585 		break;
12586 	default:
12587 		TCU_FAIL("Invalid enum");
12588 	}
12589 }
12590 
12591 /** Get interface of program
12592  *
12593  * @param ignored
12594  * @param program_interface   Interface of program
12595  * @param ignored
12596  **/
12597 void VertexAttribLocationsTest::getProgramInterface(GLuint /* test_case_index */,
12598 													Utils::ProgramInterface& program_interface,
12599 													Utils::VaryingPassthrough& /* varying_passthrough */)
12600 {
12601 	Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
12602 
12603 	/* Globals */
12604 	si.m_globals = "const uint vertex_index_location   = 2;\n"
12605 				   "const uint instance_index_location = 5;\n";
12606 
12607 	/* Attributes */
12608 	si.Input("vertex_index" /* name */, "layout (location = vertex_index_location)" /* qualifiers */,
12609 			 0 /* expected_componenet */, m_loc_vertex /* expected_location */, Utils::Type::uint /* type */,
12610 			 GL_FALSE /* normalized */, 0u /* n_array_elements */, 16 /* stride */, 0u /* offset */,
12611 			 (GLvoid*)0 /* data */, 0 /* data_size */);
12612 	si.Input("instance_index" /* name */, "layout (location = instance_index_location)" /* qualifiers */,
12613 			 0 /* expected_componenet */, m_loc_instance /* expected_location */, Utils::Type::uint /* type */,
12614 			 GL_FALSE /* normalized */, 0u /* n_array_elements */, 16 /* stride */, 16u /* offset */,
12615 			 (GLvoid*)0 /* data */, 0 /* data_size */);
12616 }
12617 
12618 /** Get name of test case
12619  *
12620  * @param test_case_index Index of test case
12621  *
12622  * @return Name of test case
12623  **/
12624 std::string VertexAttribLocationsTest::getTestCaseName(glw::GLuint test_case_index)
12625 {
12626 	std::string result;
12627 
12628 	switch (test_case_index)
12629 	{
12630 	case DRAWARRAYS:
12631 		result = "DrawArrays";
12632 		break;
12633 	case DRAWARRAYSINSTANCED:
12634 		result = "DrawArraysInstanced";
12635 		break;
12636 	case DRAWELEMENTS:
12637 		result = "DrawElements";
12638 		break;
12639 	case DRAWELEMENTSBASEVERTEX:
12640 		result = "DrawElementsBaseVertex";
12641 		break;
12642 	case DRAWELEMENTSINSTANCED:
12643 		result = "DrawElementsInstanced";
12644 		break;
12645 	case DRAWELEMENTSINSTANCEDBASEINSTANCE:
12646 		result = "DrawElementsInstancedBaseInstance";
12647 		break;
12648 	case DRAWELEMENTSINSTANCEDBASEVERTEX:
12649 		result = "DrawElementsInstancedBaseVertex";
12650 		break;
12651 	case DRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCE:
12652 		result = "DrawElementsInstancedBaseVertexBaseInstance";
12653 		break;
12654 	default:
12655 		TCU_FAIL("Invalid enum");
12656 	}
12657 
12658 	return result;
12659 }
12660 
12661 /** Get number of test cases
12662  *
12663  * @return Number of test cases
12664  **/
12665 GLuint VertexAttribLocationsTest::getTestCaseNumber()
12666 {
12667 	return TESTCASES_MAX;
12668 }
12669 
12670 /** Prepare code snippet that will verify in and uniform variables
12671  *
12672  * @param ignored
12673  * @param ignored
12674  * @param stage   Shader stage
12675  *
12676  * @return Code that verify variables
12677  **/
12678 std::string VertexAttribLocationsTest::getVerificationSnippet(GLuint /* test_case_index */,
12679 															  Utils::ProgramInterface& /* program_interface */,
12680 															  Utils::Shader::STAGES stage)
12681 {
12682 	std::string verification;
12683 
12684 	if (Utils::Shader::VERTEX == stage)
12685 	{
12686 
12687 #if DEBUG_VERTEX_ATTRIB_LOCATIONS_TEST_VARIABLE
12688 
12689 		verification = "if (gl_InstanceID != instance_index)\n"
12690 					   "    {\n"
12691 					   "        result = 12u;\n"
12692 					   "    }\n"
12693 					   "    else if (gl_VertexID != vertex_index)\n"
12694 					   "    {\n"
12695 					   "        result = 11u;\n"
12696 					   "    }\n";
12697 
12698 #else
12699 
12700 		verification = "if ((gl_VertexID   != vertex_index)  ||\n"
12701 					   "        (gl_InstanceID != instance_index) )\n"
12702 					   "    {\n"
12703 					   "        result = 0u;\n"
12704 					   "    }\n";
12705 
12706 #endif
12707 	}
12708 	else
12709 	{
12710 		verification = "";
12711 	}
12712 
12713 	return verification;
12714 }
12715 
12716 /** Selects if "compute" stage is relevant for test
12717  *
12718  * @param ignored
12719  *
12720  * @return false
12721  **/
12722 bool VertexAttribLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
12723 {
12724 	return false;
12725 }
12726 
12727 /** Prepare attributes, vertex array object and array buffer
12728  *
12729  * @param ignored
12730  * @param ignored Interface of program
12731  * @param buffer  Array buffer
12732  * @param vao     Vertex array object
12733  **/
12734 void VertexAttribLocationsTest::prepareAttributes(GLuint test_case_index /* test_case_index */,
12735 												  Utils::ProgramInterface& /* program_interface */,
12736 												  Utils::Buffer& buffer, Utils::VertexArray& vao)
12737 {
12738 	static const GLuint vertex_index_data[8]   = { 0, 1, 2, 3, 4, 5, 6, 7 };
12739 	static const GLuint instance_index_data[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
12740 
12741 	std::vector<GLuint> buffer_data;
12742 	buffer_data.resize(8 + 8); /* vertex_index_data + instance_index_data */
12743 
12744 	GLubyte* ptr = (GLubyte*)&buffer_data[0];
12745 
12746 	/*
12747 	 When case index >=2, the test calls glDrawElement*(), such as glDrawElementsBaseVertex(), glDrawElementsInstanced(), glDrawElementsInstancedBaseInstance() and so on,
12748 	 So we need to change the buffer type as GL_ELEMENT_ARRAY_BUFFER
12749 	 */
12750 	if (test_case_index >= 2)
12751 	{
12752 		buffer.m_buffer = Utils::Buffer::Element;
12753 	}
12754 	vao.Bind();
12755 	buffer.Bind();
12756 
12757 	vao.Attribute(m_loc_vertex /* vertex_index */, Utils::Type::uint, 0 /* array_elements */, false /* normalized */,
12758 				  0 /* stride */, 0 /* offset */);
12759 
12760 	vao.Attribute(m_loc_instance /* instance_index */, Utils::Type::uint, 0 /* array_elements */,
12761 				  false /* normalized */, 0 /* stride */, (GLvoid*)sizeof(vertex_index_data) /* offset */);
12762 	// when test_case_index is 5 or 7, the draw call is glDrawElementsInstancedBaseInstance, glDrawElementsInstancedBaseVertexBaseInstance
12763 	// the instancecount is 4, the baseinstance is 2, the divisor should be set 2
12764 	bool isBaseInstanced = (test_case_index == DRAWELEMENTSINSTANCEDBASEINSTANCE ||
12765 							test_case_index == DRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCE);
12766 	vao.Divisor(m_context.getRenderContext().getFunctions() /* gl */, m_loc_instance /* instance_index */,
12767 				isBaseInstanced ? 2 : 1 /* divisor. 1 - advance once per instance */);
12768 
12769 	memcpy(ptr + 0, vertex_index_data, sizeof(vertex_index_data));
12770 	memcpy(ptr + sizeof(vertex_index_data), instance_index_data, sizeof(instance_index_data));
12771 
12772 	buffer.Data(Utils::Buffer::StaticDraw, buffer_data.size() * sizeof(GLuint), ptr);
12773 }
12774 
12775 /** This test should be run with separable programs
12776  *
12777  * @param ignored
12778  *
12779  * @return true
12780  **/
12781 bool VertexAttribLocationsTest::useMonolithicProgram(GLuint /* test_case_index */)
12782 {
12783 	return false;
12784 }
12785 
12786 /** Constructor
12787  *
12788  * @param context Test framework context
12789  **/
12790 VaryingArrayLocationsTest::VaryingArrayLocationsTest(deqp::Context& context)
12791 	: VaryingLocationsTest(context, "varying_array_locations",
12792 						   "Test verifies that input and output locations are respected for arrays")
12793 {
12794 }
12795 
12796 /**
12797  *
12798  **/
12799 void VaryingArrayLocationsTest::prepareShaderStage(Utils::Shader::STAGES stage, const Utils::Type& type,
12800 												   Utils::ProgramInterface&   program_interface,
12801 												   Utils::VaryingPassthrough& varying_passthrough)
12802 {
12803 	const GLuint array_length  = 1u;
12804 	const GLuint first_in_loc  = 0;
12805 	const GLuint first_out_loc = 0;
12806 	const GLuint last_in_loc   = getLastInputLocation(stage, type, array_length, false);
12807 	size_t		 position	  = 0;
12808 
12809 	const GLchar* prefix_in = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::VARYING_INPUT);
12810 
12811 	const GLchar* prefix_out = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::VARYING_OUTPUT);
12812 
12813 	const GLchar* qual_first_in  = "layout (location = first_input_location)";
12814 	const GLchar* qual_first_out = "layout (location = first_output_location)";
12815 	const GLchar* qual_last_in   = "layout (location = last_input_location)";
12816 	const GLchar* qual_last_out  = "layout (location = last_output_location)";
12817 
12818 	Utils::ShaderInterface& si		  = program_interface.GetShaderInterface(stage);
12819 	const GLuint			type_size = type.GetSize();
12820 
12821 	std::string first_in_name  = "PREFIXfirst";
12822 	std::string first_out_name = "PREFIXfirst";
12823 	std::string last_in_name   = "PREFIXlast";
12824 	std::string last_out_name  = "PREFIXlast";
12825 
12826 	Utils::replaceToken("PREFIX", position, prefix_in, first_in_name);
12827 	position = 0;
12828 	Utils::replaceToken("PREFIX", position, prefix_out, first_out_name);
12829 	position = 0;
12830 	Utils::replaceToken("PREFIX", position, prefix_in, last_in_name);
12831 	position = 0;
12832 	Utils::replaceToken("PREFIX", position, prefix_out, last_out_name);
12833 
12834 	if (Utils::Shader::FRAGMENT == stage)
12835 	{
12836 		qual_first_in = "layout (location = first_input_location) flat";
12837 		qual_last_in  = "layout (location = last_input_location)  flat";
12838 	}
12839 	if (Utils::Shader::GEOMETRY == stage)
12840 	{
12841 		qual_first_out = "layout (location = first_output_location) flat";
12842 		qual_last_out  = "layout (location = last_output_location)  flat";
12843 	}
12844 
12845 	Utils::Variable* first_in =
12846 		si.Input(first_in_name.c_str(), qual_first_in /* qualifiers */, 0 /* expected_componenet */,
12847 				 first_in_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12848 				 array_length /* n_array_elements */, 0u /* stride */, 0u /* offset */,
12849 				 (GLvoid*)&m_first_data[0] /* data */, m_first_data.size() /* data_size */);
12850 
12851 	Utils::Variable* last_in =
12852 		si.Input(last_in_name.c_str(), qual_last_in /* qualifiers */, 0 /* expected_componenet */,
12853 				 last_in_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12854 				 array_length /* n_array_elements */, 0u /* stride */, type_size /* offset */,
12855 				 (GLvoid*)&m_last_data[0] /* data */, m_last_data.size() /* data_size */);
12856 
12857 	if (Utils::Shader::FRAGMENT != stage)
12858 	{
12859 		const GLuint last_out_loc = getLastOutputLocation(stage, type, array_length, false);
12860 
12861 		Utils::Variable* first_out =
12862 			si.Output(first_out_name.c_str(), qual_first_out /* qualifiers */, 0 /* expected_componenet */,
12863 					  first_out_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12864 					  array_length /* n_array_elements */, 0u /* stride */, 0u /* offset */,
12865 					  (GLvoid*)&m_first_data[0] /* data */, m_first_data.size() /* data_size */);
12866 
12867 		Utils::Variable* last_out =
12868 			si.Output(last_out_name.c_str(), qual_last_out /* qualifiers */, 0 /* expected_componenet */,
12869 					  last_out_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12870 					  array_length /* n_array_elements */, 0u /* stride */, 0u /* offset */,
12871 					  (GLvoid*)&m_last_data[0] /* data */, m_last_data.size() /* data_size */);
12872 
12873 		si.m_globals = prepareGlobals(last_in_loc, last_out_loc);
12874 
12875 		varying_passthrough.Add(stage, first_in, first_out);
12876 		varying_passthrough.Add(stage, last_in, last_out);
12877 	}
12878 	else
12879 	{
12880 		/* No outputs for fragment shader, so last_output_location can be 0 */
12881 		si.m_globals = prepareGlobals(last_in_loc, 0);
12882 	}
12883 }
12884 
12885 /** Constructor
12886  *
12887  * @param context Test framework context
12888  **/
12889 VaryingStructureLocationsTest::VaryingStructureLocationsTest(deqp::Context& context)
12890 	: TextureTestBase(context, "varying_structure_locations",
12891 					  "Test verifies that locations are respected when structures are used as in and out ")
12892 {
12893 }
12894 
12895 /** Prepare code snippet that will pass in variables to out variables
12896  *
12897  * @param ignored
12898  * @param varying_passthrough Collection of connections between in and out variables
12899  * @param stage               Shader stage
12900  *
12901  * @return Code that pass in variables to next stage
12902  **/
12903 std::string VaryingStructureLocationsTest::getPassSnippet(GLuint /* test_case_index */,
12904 														  Utils::VaryingPassthrough& varying_passthrough,
12905 														  Utils::Shader::STAGES		 stage)
12906 {
12907 	std::string result;
12908 
12909 	if (Utils::Shader::VERTEX != stage)
12910 	{
12911 		result = TextureTestBase::getPassSnippet(0, varying_passthrough, stage);
12912 	}
12913 	else
12914 	{
12915 		result = "    vs_tcs_output[0].single   = vs_in_single[0];\n"
12916 				 "    vs_tcs_output[0].array[0] = vs_in_array[0];\n";
12917 	}
12918 
12919 	return result;
12920 }
12921 
12922 /** Get interface of program
12923  *
12924  * @param test_case_index     Test case
12925  * @param program_interface   Interface of program
12926  * @param varying_passthrough Collection of connections between in and out variables
12927  **/
12928 void VaryingStructureLocationsTest::getProgramInterface(GLuint					   test_case_index,
12929 														Utils::ProgramInterface&   program_interface,
12930 														Utils::VaryingPassthrough& varying_passthrough)
12931 {
12932 	Utils::ShaderInterface& si   = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
12933 	const Utils::Type		type = getType(test_case_index);
12934 
12935 	/* Prepare data */
12936 	// We should call GenerateDataPacked() to generate data, which can make sure the data in shader is correct
12937 	m_single_data = type.GenerateDataPacked();
12938 	m_array_data  = type.GenerateDataPacked();
12939 
12940 	m_data.resize(m_single_data.size() + m_array_data.size());
12941 	GLubyte* ptr = (GLubyte*)&m_data[0];
12942 	memcpy(ptr, &m_single_data[0], m_single_data.size());
12943 	memcpy(ptr + m_single_data.size(), &m_array_data[0], m_array_data.size());
12944 
12945 	Utils::Interface* structure = program_interface.Structure("Data");
12946 
12947 	structure->Member("single", "" /* qualifiers */, 0 /* component */, 0 /* location */, type, false /* normalized */,
12948 					  0u /* n_array_elements */, 0u /* stride */, 0u /* offset */);
12949 
12950 	// the second struct member 's location should not be 0, it is based on by how many the locations the first struct member consumed.
12951 	structure->Member("array", "" /* qualifiers */, 0 /* component */, type.GetLocations() /* location */, type,
12952 					  false /* normalized */, 1u /* n_array_elements */, 0u /* stride */, type.GetSize() /* offset */);
12953 
12954 	si.Input("vs_in_single", "layout (location = 0)", 0 /* component */, 0 /* location */, type, false /* normalized */,
12955 			 1u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)&m_single_data[0] /* data */,
12956 			 m_single_data.size() /* data_size */);
12957 
12958 	si.Input("vs_in_array", "layout (location = 8)", 0 /* component */, 8 /* location */, type, false /* normalized */,
12959 			 1u /* n_array_elements */, 0u /* stride */, type.GetSize() /* offset */,
12960 			 (GLvoid*)&m_array_data[0] /* data */, m_array_data.size() /* data_size */);
12961 
12962 	si.Output("vs_tcs_output", "layout (location = 0)", 0 /* component */, 0 /* location */, structure,
12963 			  1u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)&m_data[0] /* data */,
12964 			  m_data.size() /* data_size */);
12965 
12966 	program_interface.CloneVertexInterface(varying_passthrough);
12967 }
12968 
12969 /** Get type name
12970  *
12971  * @param test_case_index Index of test case
12972  *
12973  * @return Name of type test in test_case_index
12974  **/
12975 std::string VaryingStructureLocationsTest::getTestCaseName(glw::GLuint test_case_index)
12976 {
12977 	return getTypeName(test_case_index);
12978 }
12979 
12980 /** Returns number of types to test
12981  *
12982  * @return Number of types, 34
12983  **/
12984 glw::GLuint VaryingStructureLocationsTest::getTestCaseNumber()
12985 {
12986 	return getTypesNumber();
12987 }
12988 
12989 /** Selects if "compute" stage is relevant for test
12990  *
12991  * @param ignored
12992  *
12993  * @return false
12994  **/
12995 bool VaryingStructureLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
12996 {
12997 	return false;
12998 }
12999 
13000 /** This test should be run with separable programs
13001  *
13002  * @param ignored
13003  *
13004  * @return true
13005  **/
13006 bool VaryingStructureLocationsTest::useMonolithicProgram(GLuint /* test_case_index */)
13007 {
13008 	return false;
13009 }
13010 
13011 /** Constructor
13012  *
13013  * @param context          Test context
13014  * @param test_name        Name of test
13015  * @param test_description Description of test
13016  **/
13017 VaryingStructureMemberLocationTest::VaryingStructureMemberLocationTest(deqp::Context& context)
13018 	: NegativeTestBase(context, "varying_structure_member_location",
13019 					   "Test verifies that compiler does not allow location qualifier on member of strucure")
13020 {
13021 }
13022 
13023 /** Source for given test case and stage
13024  *
13025  * @param test_case_index Index of test case
13026  * @param stage           Shader stage
13027  *
13028  * @return Shader source
13029  **/
13030 std::string VaryingStructureMemberLocationTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
13031 {
13032 	static const GLchar* struct_definition = "struct Data {\n"
13033 											 "    vec4 gohan;\n"
13034 											 "    layout (location = 4) vec4 goten;\n"
13035 											 "};\n";
13036 	static const GLchar* input_var  = "in Data data;\n";
13037 	static const GLchar* output_var = "out Data data;\n";
13038 	static const GLchar* input_use  = "    result += data.gohan + data.goten;\n";
13039 	static const GLchar* output_use = "    data.gohan = result / 2;\n"
13040 									  "    data.goten = result / 4 - data.gohan;\n";
13041 	static const GLchar* fs = "#version 430 core\n"
13042 							  "#extension GL_ARB_enhanced_layouts : require\n"
13043 							  "\n"
13044 							  "in  vec4 gs_fs;\n"
13045 							  "out vec4 fs_out;\n"
13046 							  "\n"
13047 							  "void main()\n"
13048 							  "{\n"
13049 							  "    fs_out = gs_fs;\n"
13050 							  "}\n"
13051 							  "\n";
13052 	static const GLchar* fs_tested = "#version 430 core\n"
13053 									 "#extension GL_ARB_enhanced_layouts : require\n"
13054 									 "\n"
13055 									 "STRUCT_DEFINITION"
13056 									 "\n"
13057 									 "VARIABLE_DEFINITION"
13058 									 "\n"
13059 									 "in  vec4 gs_fs;\n"
13060 									 "out vec4 fs_out;\n"
13061 									 "\n"
13062 									 "void main()\n"
13063 									 "{\n"
13064 									 "    vec4 result = gs_fs;\n"
13065 									 "\n"
13066 									 "VARIABLE_USE"
13067 									 "\n"
13068 									 "    fs_out += result;\n"
13069 									 "}\n"
13070 									 "\n";
13071 	static const GLchar* gs = "#version 430 core\n"
13072 							  "#extension GL_ARB_enhanced_layouts : require\n"
13073 							  "\n"
13074 							  "layout(points)                           in;\n"
13075 							  "layout(triangle_strip, max_vertices = 4) out;\n"
13076 							  "\n"
13077 							  "in  vec4 tes_gs[];\n"
13078 							  "out vec4 gs_fs;\n"
13079 							  "\n"
13080 							  "void main()\n"
13081 							  "{\n"
13082 							  "    gs_fs = tes_gs[0];\n"
13083 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
13084 							  "    EmitVertex();\n"
13085 							  "    gs_fs = tes_gs[0];\n"
13086 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
13087 							  "    EmitVertex();\n"
13088 							  "    gs_fs = tes_gs[0];\n"
13089 							  "    gl_Position  = vec4(1, -1, 0, 1);\n"
13090 							  "    EmitVertex();\n"
13091 							  "    gs_fs = tes_gs[0];\n"
13092 							  "    gl_Position  = vec4(1, 1, 0, 1);\n"
13093 							  "    EmitVertex();\n"
13094 							  "}\n"
13095 							  "\n";
13096 	static const GLchar* gs_tested = "#version 430 core\n"
13097 									 "#extension GL_ARB_enhanced_layouts : require\n"
13098 									 "\n"
13099 									 "layout(points)                           in;\n"
13100 									 "layout(triangle_strip, max_vertices = 4) out;\n"
13101 									 "\n"
13102 									 "STRUCT_DEFINITION"
13103 									 "\n"
13104 									 "VARIABLE_DEFINITION"
13105 									 "\n"
13106 									 "in  vec4 tes_gs[];\n"
13107 									 "out vec4 gs_fs;\n"
13108 									 "\n"
13109 									 "void main()\n"
13110 									 "{\n"
13111 									 "    vec4 result = tes_gs[0];\n"
13112 									 "\n"
13113 									 "VARIABLE_USE"
13114 									 "\n"
13115 									 "    gs_fs = result;\n"
13116 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
13117 									 "    EmitVertex();\n"
13118 									 "    gs_fs = result;\n"
13119 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
13120 									 "    EmitVertex();\n"
13121 									 "    gs_fs = result;\n"
13122 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
13123 									 "    EmitVertex();\n"
13124 									 "    gs_fs = result;\n"
13125 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
13126 									 "    EmitVertex();\n"
13127 									 "}\n"
13128 									 "\n";
13129 	static const GLchar* tcs = "#version 430 core\n"
13130 							   "#extension GL_ARB_enhanced_layouts : require\n"
13131 							   "\n"
13132 							   "layout(vertices = 1) out;\n"
13133 							   "\n"
13134 							   "in  vec4 vs_tcs[];\n"
13135 							   "out vec4 tcs_tes[];\n"
13136 							   "\n"
13137 							   "void main()\n"
13138 							   "{\n"
13139 							   "\n"
13140 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
13141 							   "\n"
13142 							   "    gl_TessLevelOuter[0] = 1.0;\n"
13143 							   "    gl_TessLevelOuter[1] = 1.0;\n"
13144 							   "    gl_TessLevelOuter[2] = 1.0;\n"
13145 							   "    gl_TessLevelOuter[3] = 1.0;\n"
13146 							   "    gl_TessLevelInner[0] = 1.0;\n"
13147 							   "    gl_TessLevelInner[1] = 1.0;\n"
13148 							   "}\n"
13149 							   "\n";
13150 	static const GLchar* tcs_tested = "#version 430 core\n"
13151 									  "#extension GL_ARB_enhanced_layouts : require\n"
13152 									  "\n"
13153 									  "layout(vertices = 1) out;\n"
13154 									  "\n"
13155 									  "STRUCT_DEFINITION"
13156 									  "\n"
13157 									  "VARIABLE_DEFINITION"
13158 									  "\n"
13159 									  "in  vec4 vs_tcs[];\n"
13160 									  "out vec4 tcs_tes[];\n"
13161 									  "\n"
13162 									  "void main()\n"
13163 									  "{\n"
13164 									  "    vec4 result = vs_tcs[gl_InvocationID];\n"
13165 									  "\n"
13166 									  "VARIABLE_USE"
13167 									  "\n"
13168 									  "    tcs_tes[gl_InvocationID] = result;\n"
13169 									  "\n"
13170 									  "    gl_TessLevelOuter[0] = 1.0;\n"
13171 									  "    gl_TessLevelOuter[1] = 1.0;\n"
13172 									  "    gl_TessLevelOuter[2] = 1.0;\n"
13173 									  "    gl_TessLevelOuter[3] = 1.0;\n"
13174 									  "    gl_TessLevelInner[0] = 1.0;\n"
13175 									  "    gl_TessLevelInner[1] = 1.0;\n"
13176 									  "}\n"
13177 									  "\n";
13178 	static const GLchar* tes = "#version 430 core\n"
13179 							   "#extension GL_ARB_enhanced_layouts : require\n"
13180 							   "\n"
13181 							   "layout(isolines, point_mode) in;\n"
13182 							   "\n"
13183 							   "in  vec4 tcs_tes[];\n"
13184 							   "out vec4 tes_gs;\n"
13185 							   "\n"
13186 							   "void main()\n"
13187 							   "{\n"
13188 							   "    tes_gs = tcs_tes[0];\n"
13189 							   "}\n"
13190 							   "\n";
13191 	static const GLchar* tes_tested = "#version 430 core\n"
13192 									  "#extension GL_ARB_enhanced_layouts : require\n"
13193 									  "\n"
13194 									  "layout(isolines, point_mode) in;\n"
13195 									  "\n"
13196 									  "STRUCT_DEFINITION"
13197 									  "\n"
13198 									  "VARIABLE_DEFINITION"
13199 									  "\n"
13200 									  "in  vec4 tcs_tes[];\n"
13201 									  "out vec4 tes_gs;\n"
13202 									  "\n"
13203 									  "void main()\n"
13204 									  "{\n"
13205 									  "    vec4 result = tcs_tes[0];\n"
13206 									  "\n"
13207 									  "VARIABLE_USE"
13208 									  "\n"
13209 									  "    tes_gs += result;\n"
13210 									  "}\n"
13211 									  "\n";
13212 	static const GLchar* vs = "#version 430 core\n"
13213 							  "#extension GL_ARB_enhanced_layouts : require\n"
13214 							  "\n"
13215 							  "in  vec4 in_vs;\n"
13216 							  "out vec4 vs_tcs;\n"
13217 							  "\n"
13218 							  "void main()\n"
13219 							  "{\n"
13220 							  "    vs_tcs = in_vs;\n"
13221 							  "}\n"
13222 							  "\n";
13223 	static const GLchar* vs_tested = "#version 430 core\n"
13224 									 "#extension GL_ARB_enhanced_layouts : require\n"
13225 									 "\n"
13226 									 "STRUCT_DEFINITION"
13227 									 "\n"
13228 									 "VARIABLE_DEFINITION"
13229 									 "\n"
13230 									 "in  vec4 in_vs;\n"
13231 									 "out vec4 vs_tcs;\n"
13232 									 "\n"
13233 									 "void main()\n"
13234 									 "{\n"
13235 									 "    vec4 result = in_vs;\n"
13236 									 "\n"
13237 									 "VARIABLE_USE"
13238 									 "\n"
13239 									 "    vs_tcs += result;\n"
13240 									 "}\n"
13241 									 "\n";
13242 
13243 	std::string   source;
13244 	testCase&	 test_case		 = m_test_cases[test_case_index];
13245 	const GLchar* var_definition = 0;
13246 	const GLchar* var_use		 = 0;
13247 
13248 	if (true == test_case.m_is_input)
13249 	{
13250 		var_definition = input_var;
13251 		var_use		   = input_use;
13252 	}
13253 	else
13254 	{
13255 		var_definition = output_var;
13256 		var_use		   = output_use;
13257 	}
13258 
13259 	if (test_case.m_stage == stage)
13260 	{
13261 		size_t position = 0;
13262 
13263 		switch (stage)
13264 		{
13265 		case Utils::Shader::FRAGMENT:
13266 			source = fs_tested;
13267 			break;
13268 		case Utils::Shader::GEOMETRY:
13269 			source = gs_tested;
13270 			break;
13271 		case Utils::Shader::TESS_CTRL:
13272 			source = tcs_tested;
13273 			break;
13274 		case Utils::Shader::TESS_EVAL:
13275 			source = tes_tested;
13276 			break;
13277 		case Utils::Shader::VERTEX:
13278 			source = vs_tested;
13279 			break;
13280 		default:
13281 			TCU_FAIL("Invalid enum");
13282 		}
13283 
13284 		Utils::replaceToken("STRUCT_DEFINITION", position, struct_definition, source);
13285 		Utils::replaceToken("VARIABLE_DEFINITION", position, var_definition, source);
13286 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
13287 	}
13288 	else
13289 	{
13290 		switch (stage)
13291 		{
13292 		case Utils::Shader::FRAGMENT:
13293 			source = fs;
13294 			break;
13295 		case Utils::Shader::GEOMETRY:
13296 			source = gs;
13297 			break;
13298 		case Utils::Shader::TESS_CTRL:
13299 			source = tcs;
13300 			break;
13301 		case Utils::Shader::TESS_EVAL:
13302 			source = tes;
13303 			break;
13304 		case Utils::Shader::VERTEX:
13305 			source = vs;
13306 			break;
13307 		default:
13308 			TCU_FAIL("Invalid enum");
13309 		}
13310 	}
13311 
13312 	return source;
13313 }
13314 
13315 /** Get description of test case
13316  *
13317  * @param test_case_index Index of test case
13318  *
13319  * @return Test case description
13320  **/
13321 std::string VaryingStructureMemberLocationTest::getTestCaseName(GLuint test_case_index)
13322 {
13323 	std::stringstream stream;
13324 	testCase&		  test_case = m_test_cases[test_case_index];
13325 
13326 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", direction: ";
13327 
13328 	if (true == test_case.m_is_input)
13329 	{
13330 		stream << "input";
13331 	}
13332 	else
13333 	{
13334 		stream << "output";
13335 	}
13336 
13337 	return stream.str();
13338 }
13339 
13340 /** Get number of test cases
13341  *
13342  * @return Number of test cases
13343  **/
13344 GLuint VaryingStructureMemberLocationTest::getTestCaseNumber()
13345 {
13346 	return static_cast<GLuint>(m_test_cases.size());
13347 }
13348 
13349 /** Selects if "compute" stage is relevant for test
13350  *
13351  * @param ignored
13352  *
13353  * @return false
13354  **/
13355 bool VaryingStructureMemberLocationTest::isComputeRelevant(GLuint /* test_case_index */)
13356 {
13357 	return false;
13358 }
13359 
13360 /** Prepare all test cases
13361  *
13362  **/
13363 void VaryingStructureMemberLocationTest::testInit()
13364 {
13365 	for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
13366 	{
13367 		if (Utils::Shader::COMPUTE == stage)
13368 		{
13369 			continue;
13370 		}
13371 
13372 		testCase test_case_in  = { true, (Utils::Shader::STAGES)stage };
13373 		testCase test_case_out = { false, (Utils::Shader::STAGES)stage };
13374 
13375 		m_test_cases.push_back(test_case_in);
13376 
13377 		if (Utils::Shader::FRAGMENT != stage)
13378 		{
13379 			m_test_cases.push_back(test_case_out);
13380 		}
13381 	}
13382 }
13383 
13384 /** Constructor
13385  *
13386  * @param context Test framework context
13387  **/
13388 VaryingBlockLocationsTest::VaryingBlockLocationsTest(deqp::Context& context)
13389 	: TextureTestBase(context, "varying_block_locations",
13390 					  "Test verifies that locations are respected when blocks are used as in and out ")
13391 {
13392 }
13393 
13394 /** Prepare code snippet that will pass in variables to out variables
13395  *
13396  * @param ignored
13397  * @param varying_passthrough Collection of connections between in and out variables
13398  * @param stage               Shader stage
13399  *
13400  * @return Code that pass in variables to next stage
13401  **/
13402 std::string VaryingBlockLocationsTest::getPassSnippet(GLuint /* test_case_index */,
13403 													  Utils::VaryingPassthrough& varying_passthrough,
13404 													  Utils::Shader::STAGES		 stage)
13405 {
13406 	std::string result;
13407 
13408 	if (Utils::Shader::VERTEX != stage)
13409 	{
13410 		result = TextureTestBase::getPassSnippet(0, varying_passthrough, stage);
13411 	}
13412 	else
13413 	{
13414 		result = "vs_tcs_block.third  = vs_in_third;\n"
13415 				 "    vs_tcs_block.fourth = vs_in_fourth;\n"
13416 				 "    vs_tcs_block.fifth  = vs_in_fifth;\n";
13417 	}
13418 
13419 	return result;
13420 }
13421 
13422 /** Get interface of program
13423  *
13424  * @param ignored
13425  * @param program_interface   Interface of program
13426  * @param varying_passthrough Collection of connections between in and out variables
13427  **/
13428 void VaryingBlockLocationsTest::getProgramInterface(GLuint /* test_case_index */,
13429 													Utils::ProgramInterface&   program_interface,
13430 													Utils::VaryingPassthrough& varying_passthrough)
13431 {
13432 	Utils::ShaderInterface& si   = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
13433 	const Utils::Type		vec4 = Utils::Type::vec4;
13434 
13435 	/* Prepare data */
13436 	m_third_data  = vec4.GenerateData();
13437 	m_fourth_data = vec4.GenerateData();
13438 	m_fifth_data  = vec4.GenerateData();
13439 
13440 	/* Memory layout is different from location layout */
13441 	const GLuint fifth_offset  = 0u;
13442 	const GLuint third_offset  = static_cast<GLuint>(fifth_offset + m_fifth_data.size());
13443 	const GLuint fourth_offset = static_cast<GLuint>(third_offset + m_fourth_data.size());
13444 
13445 	m_data.resize(fourth_offset + m_fourth_data.size());
13446 	GLubyte* ptr = (GLubyte*)&m_data[0];
13447 	memcpy(ptr + third_offset, &m_third_data[0], m_third_data.size());
13448 	memcpy(ptr + fourth_offset, &m_fourth_data[0], m_fourth_data.size());
13449 	memcpy(ptr + fifth_offset, &m_fifth_data[0], m_fifth_data.size());
13450 
13451 	Utils::Interface* block = program_interface.Block("vs_tcs_Block");
13452 
13453 	block->Member("fifth", "" /* qualifiers */, 0 /* component */, 4 /* location */, vec4, false /* normalized */,
13454 				  0u /* n_array_elements */, 0u /* stride */, fifth_offset /* offset */);
13455 
13456 	block->Member("third", "layout (location = 2)" /* qualifiers */, 0 /* component */, 2 /* location */, vec4,
13457 				  false /* normalized */, 0u /* n_array_elements */, 0u /* stride */, third_offset /* offset */);
13458 
13459 	block->Member("fourth", "" /* qualifiers */, 0 /* component */, 3 /* location */, vec4, false /* normalized */,
13460 				  0u /* n_array_elements */, 0u /* stride */, fourth_offset /* offset */);
13461 
13462 	si.Output("vs_tcs_block", "layout (location = 4)", 0 /* component */, 4 /* location */, block,
13463 			  0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)&m_data[0] /* data */,
13464 			  m_data.size() /* data_size */);
13465 
13466 	si.Input("vs_in_third", "layout (location = 0)", 0 /* component */, 0 /* location */, vec4, false /* normalized */,
13467 			 0u /* n_array_elements */, 0u /* stride */, third_offset /* offset */,
13468 			 (GLvoid*)&m_third_data[0] /* data */, m_third_data.size() /* data_size */);
13469 
13470 	si.Input("vs_in_fourth", "layout (location = 1)", 0 /* component */, 1 /* location */, vec4, false /* normalized */,
13471 			 0u /* n_array_elements */, 0u /* stride */, fourth_offset /* offset */,
13472 			 (GLvoid*)&m_fourth_data[0] /* data */, m_fourth_data.size() /* data_size */);
13473 
13474 	si.Input("vs_in_fifth", "layout (location = 2)", 0 /* component */, 2 /* location */, vec4, false /* normalized */,
13475 			 0u /* n_array_elements */, 0u /* stride */, fifth_offset /* offset */,
13476 			 (GLvoid*)&m_fifth_data[0] /* data */, m_fifth_data.size() /* data_size */);
13477 
13478 	program_interface.CloneVertexInterface(varying_passthrough);
13479 }
13480 
13481 /** Selects if "compute" stage is relevant for test
13482  *
13483  * @param ignored
13484  *
13485  * @return false
13486  **/
13487 bool VaryingBlockLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
13488 {
13489 	return false;
13490 }
13491 
13492 /** This test should be run with separable programs
13493  *
13494  * @param ignored
13495  *
13496  * @return true
13497  **/
13498 bool VaryingBlockLocationsTest::useMonolithicProgram(GLuint /* test_case_index */)
13499 {
13500 	return false;
13501 }
13502 
13503 /** Constructor
13504  *
13505  * @param context Test framework context
13506  **/
13507 VaryingBlockMemberLocationsTest::VaryingBlockMemberLocationsTest(deqp::Context& context)
13508 	: NegativeTestBase(
13509 		  context, "varying_block_member_locations",
13510 		  "Test verifies that compilation error is reported when not all members of block are qualified with location")
13511 {
13512 }
13513 
13514 /** Source for given test case and stage
13515  *
13516  * @param test_case_index Index of test case
13517  * @param stage           Shader stage
13518  *
13519  * @return Shader source
13520  **/
13521 std::string VaryingBlockMemberLocationsTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
13522 {
13523 	static const GLchar* block_definition_all = "Goku {\n"
13524 												"    layout (location = 2) vec4 gohan;\n"
13525 												"    layout (location = 4) vec4 goten;\n"
13526 												"    layout (location = 6) vec4 chichi;\n"
13527 												"} gokuARRAY;\n";
13528 	static const GLchar* block_definition_default = "Goku {\n"
13529 													"    vec4 gohan;\n"
13530 													"    vec4 goten;\n"
13531 													"    vec4 chichi;\n"
13532 													"} gokuARRAY;\n";
13533 	static const GLchar* block_definition_one = "Goku {\n"
13534 												"    vec4 gohan;\n"
13535 												"    layout (location = 4) vec4 goten;\n"
13536 												"    vec4 chichi;\n"
13537 												"} gokuARRAY;\n";
13538 	static const GLchar* input_use  = "    result += gokuINDEX.gohan + gokuINDEX.goten + gokuINDEX.chichi;\n";
13539 	static const GLchar* output_use = "    gokuINDEX.gohan  = result / 2;\n"
13540 									  "    gokuINDEX.goten  = result / 4 - gokuINDEX.gohan;\n"
13541 									  "    gokuINDEX.chichi = result / 8 - gokuINDEX.goten;\n";
13542 	static const GLchar* fs = "#version 430 core\n"
13543 							  "#extension GL_ARB_enhanced_layouts : require\n"
13544 							  "\n"
13545 							  "in  vec4 gs_fs;\n"
13546 							  "out vec4 fs_out;\n"
13547 							  "\n"
13548 							  "void main()\n"
13549 							  "{\n"
13550 							  "    fs_out = gs_fs;\n"
13551 							  "}\n"
13552 							  "\n";
13553 	static const GLchar* fs_tested = "#version 430 core\n"
13554 									 "#extension GL_ARB_enhanced_layouts : require\n"
13555 									 "\n"
13556 									 "DIRECTION BLOCK_DEFINITION"
13557 									 "\n"
13558 									 "in  vec4 gs_fs;\n"
13559 									 "out vec4 fs_out;\n"
13560 									 "\n"
13561 									 "void main()\n"
13562 									 "{\n"
13563 									 "    vec4 result = gs_fs;\n"
13564 									 "\n"
13565 									 "VARIABLE_USE"
13566 									 "\n"
13567 									 "    fs_out = result;\n"
13568 									 "}\n"
13569 									 "\n";
13570 	static const GLchar* gs = "#version 430 core\n"
13571 							  "#extension GL_ARB_enhanced_layouts : require\n"
13572 							  "\n"
13573 							  "layout(points)                           in;\n"
13574 							  "layout(triangle_strip, max_vertices = 4) out;\n"
13575 							  "\n"
13576 							  "in  vec4 tes_gs[];\n"
13577 							  "out vec4 gs_fs;\n"
13578 							  "\n"
13579 							  "void main()\n"
13580 							  "{\n"
13581 							  "    gs_fs = tes_gs[0];\n"
13582 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
13583 							  "    EmitVertex();\n"
13584 							  "    gs_fs = tes_gs[0];\n"
13585 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
13586 							  "    EmitVertex();\n"
13587 							  "    gs_fs = tes_gs[0];\n"
13588 							  "    gl_Position  = vec4(1, -1, 0, 1);\n"
13589 							  "    EmitVertex();\n"
13590 							  "    gs_fs = tes_gs[0];\n"
13591 							  "    gl_Position  = vec4(1, 1, 0, 1);\n"
13592 							  "    EmitVertex();\n"
13593 							  "}\n"
13594 							  "\n";
13595 	static const GLchar* gs_tested = "#version 430 core\n"
13596 									 "#extension GL_ARB_enhanced_layouts : require\n"
13597 									 "\n"
13598 									 "layout(points)                           in;\n"
13599 									 "layout(triangle_strip, max_vertices = 4) out;\n"
13600 									 "\n"
13601 									 "DIRECTION BLOCK_DEFINITION"
13602 									 "\n"
13603 									 "in  vec4 tes_gs[];\n"
13604 									 "out vec4 gs_fs;\n"
13605 									 "\n"
13606 									 "void main()\n"
13607 									 "{\n"
13608 									 "    vec4 result = tes_gs[0];\n"
13609 									 "\n"
13610 									 "VARIABLE_USE"
13611 									 "\n"
13612 									 "    gs_fs = result;\n"
13613 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
13614 									 "    EmitVertex();\n"
13615 									 "    gs_fs = result;\n"
13616 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
13617 									 "    EmitVertex();\n"
13618 									 "    gs_fs = result;\n"
13619 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
13620 									 "    EmitVertex();\n"
13621 									 "    gs_fs = result;\n"
13622 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
13623 									 "    EmitVertex();\n"
13624 									 "}\n"
13625 									 "\n";
13626 	static const GLchar* tcs = "#version 430 core\n"
13627 							   "#extension GL_ARB_enhanced_layouts : require\n"
13628 							   "\n"
13629 							   "layout(vertices = 1) out;\n"
13630 							   "\n"
13631 							   "in  vec4 vs_tcs[];\n"
13632 							   "out vec4 tcs_tes[];\n"
13633 							   "\n"
13634 							   "void main()\n"
13635 							   "{\n"
13636 							   "\n"
13637 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
13638 							   "\n"
13639 							   "    gl_TessLevelOuter[0] = 1.0;\n"
13640 							   "    gl_TessLevelOuter[1] = 1.0;\n"
13641 							   "    gl_TessLevelOuter[2] = 1.0;\n"
13642 							   "    gl_TessLevelOuter[3] = 1.0;\n"
13643 							   "    gl_TessLevelInner[0] = 1.0;\n"
13644 							   "    gl_TessLevelInner[1] = 1.0;\n"
13645 							   "}\n"
13646 							   "\n";
13647 	static const GLchar* tcs_tested = "#version 430 core\n"
13648 									  "#extension GL_ARB_enhanced_layouts : require\n"
13649 									  "\n"
13650 									  "layout(vertices = 1) out;\n"
13651 									  "\n"
13652 									  "DIRECTION BLOCK_DEFINITION"
13653 									  "\n"
13654 									  "in  vec4 vs_tcs[];\n"
13655 									  "out vec4 tcs_tes[];\n"
13656 									  "\n"
13657 									  "void main()\n"
13658 									  "{\n"
13659 									  "    vec4 result = vs_tcs[gl_InvocationID];\n"
13660 									  "\n"
13661 									  "VARIABLE_USE"
13662 									  "\n"
13663 									  "    tcs_tes[gl_InvocationID] = result;\n"
13664 									  "\n"
13665 									  "    gl_TessLevelOuter[0] = 1.0;\n"
13666 									  "    gl_TessLevelOuter[1] = 1.0;\n"
13667 									  "    gl_TessLevelOuter[2] = 1.0;\n"
13668 									  "    gl_TessLevelOuter[3] = 1.0;\n"
13669 									  "    gl_TessLevelInner[0] = 1.0;\n"
13670 									  "    gl_TessLevelInner[1] = 1.0;\n"
13671 									  "}\n"
13672 									  "\n";
13673 	static const GLchar* tes = "#version 430 core\n"
13674 							   "#extension GL_ARB_enhanced_layouts : require\n"
13675 							   "\n"
13676 							   "layout(isolines, point_mode) in;\n"
13677 							   "\n"
13678 							   "in  vec4 tcs_tes[];\n"
13679 							   "out vec4 tes_gs;\n"
13680 							   "\n"
13681 							   "void main()\n"
13682 							   "{\n"
13683 							   "    tes_gs = tcs_tes[0];\n"
13684 							   "}\n"
13685 							   "\n";
13686 	static const GLchar* tes_tested = "#version 430 core\n"
13687 									  "#extension GL_ARB_enhanced_layouts : require\n"
13688 									  "\n"
13689 									  "layout(isolines, point_mode) in;\n"
13690 									  "\n"
13691 									  "DIRECTION BLOCK_DEFINITION"
13692 									  "\n"
13693 									  "in  vec4 tcs_tes[];\n"
13694 									  "out vec4 tes_gs;\n"
13695 									  "\n"
13696 									  "void main()\n"
13697 									  "{\n"
13698 									  "    vec4 result = tcs_tes[0];\n"
13699 									  "\n"
13700 									  "VARIABLE_USE"
13701 									  "\n"
13702 									  "    tes_gs = result;\n"
13703 									  "}\n"
13704 									  "\n";
13705 	static const GLchar* vs = "#version 430 core\n"
13706 							  "#extension GL_ARB_enhanced_layouts : require\n"
13707 							  "\n"
13708 							  "in  vec4 in_vs;\n"
13709 							  "out vec4 vs_tcs;\n"
13710 							  "\n"
13711 							  "void main()\n"
13712 							  "{\n"
13713 							  "    vs_tcs = in_vs;\n"
13714 							  "}\n"
13715 							  "\n";
13716 	static const GLchar* vs_tested = "#version 430 core\n"
13717 									 "#extension GL_ARB_enhanced_layouts : require\n"
13718 									 "\n"
13719 									 "DIRECTION BLOCK_DEFINITION"
13720 									 "\n"
13721 									 "in  vec4 in_vs;\n"
13722 									 "out vec4 vs_tcs;\n"
13723 									 "\n"
13724 									 "void main()\n"
13725 									 "{\n"
13726 									 "    vec4 result = in_vs;\n"
13727 									 "\n"
13728 									 "VARIABLE_USE"
13729 									 "\n"
13730 									 "    vs_tcs = result;\n"
13731 									 "}\n"
13732 									 "\n";
13733 
13734 	static const GLchar* shaders_in[6][6] = { /* cs  */ { 0, 0, 0, 0, 0, 0 },
13735 											  /* vs  */ { 0, vs_tested, tcs, tes, gs, fs },
13736 											  /* tcs */ { 0, vs_tested, tcs_tested, tes, gs, fs },
13737 											  /* tes */ { 0, vs, tcs_tested, tes_tested, gs, fs },
13738 											  /* gs  */ { 0, vs, tcs, tes_tested, gs_tested, fs },
13739 											  /* fs  */ { 0, vs, tcs, tes, gs_tested, fs_tested } };
13740 
13741 	static const GLchar* shaders_out[6][6] = { /* cs  */ { 0, 0, 0, 0, 0, 0 },
13742 											   /* vs  */ { 0, vs_tested, tcs_tested, tes, gs, fs },
13743 											   /* tcs */ { 0, vs, tcs_tested, tes_tested, gs, fs },
13744 											   /* tes */ { 0, vs, tcs, tes_tested, gs_tested, fs },
13745 											   /* gs  */ { 0, vs, tcs, tes, gs_tested, fs_tested },
13746 											   /* fs  */ { 0, 0, 0, 0, 0, 0 } };
13747 
13748 	static const bool require_modifications_in[6][6] = {
13749 		/* cs  */ { false, false, false, false, false, false },
13750 		/* vs  */ { false, true, false, false, false, false },
13751 		/* tcs */ { false, true, true, false, false, false },
13752 		/* tes */ { false, false, true, true, false, false },
13753 		/* gs  */ { false, false, false, true, true, false },
13754 		/* fs  */ { false, false, false, false, true, true }
13755 	};
13756 
13757 	static const bool require_modifications_out[6][6] = {
13758 		/* cs  */ { false, false, false, false, false, false },
13759 		/* vs  */ { false, true, true, false, false, false },
13760 		/* tcs */ { false, false, true, true, false, false },
13761 		/* tes */ { false, false, false, true, true, false },
13762 		/* gs  */ { false, false, false, false, true, true },
13763 		/* fs  */ { false, false, false, false, false, false }
13764 	};
13765 
13766 	const GLchar* array					= "";
13767 	const GLchar* direction				= "out";
13768 	const GLchar* index					= "";
13769 	bool		  require_modifications = false;
13770 	std::string   source;
13771 	testCase&	 test_case = m_test_cases[test_case_index];
13772 	const GLchar* var_use   = output_use;
13773 
13774 	if (true == test_case.m_is_input)
13775 	{
13776 		require_modifications = require_modifications_in[test_case.m_stage][stage];
13777 		source				  = shaders_in[test_case.m_stage][stage];
13778 
13779 		if (test_case.m_stage == stage)
13780 		{
13781 			direction = "in";
13782 			var_use   = input_use;
13783 		}
13784 	}
13785 	else
13786 	{
13787 		require_modifications = require_modifications_out[test_case.m_stage][stage];
13788 		source				  = shaders_out[test_case.m_stage][stage];
13789 
13790 		if (test_case.m_stage != stage)
13791 		{
13792 			direction = "in";
13793 			var_use   = input_use;
13794 		}
13795 	}
13796 
13797 	const GLchar* definition = test_case.m_qualify_all ? block_definition_all
13798 			: block_definition_default;
13799 
13800 	if (test_case.m_stage == stage)
13801 	{
13802 		if (true == test_case.m_qualify_all)
13803 		{
13804 			definition = block_definition_all;
13805 		}
13806 		else
13807 		{
13808 			definition = block_definition_one;
13809 		}
13810 	}
13811 
13812 	// Geometry shader inputs, tessellation control shader inputs and outputs, and tessellation evaluation
13813 	// inputs all have an additional level of arrayness relative to other shader inputs and outputs.
13814 	switch (stage)
13815 	{
13816 	case Utils::Shader::FRAGMENT:
13817 		break;
13818 	case Utils::Shader::TESS_CTRL:
13819 		array = "[]";
13820 		index = "[gl_InvocationID]";
13821 		break;
13822 	// geometry shader's input must have one more dimension than tessellation evaluation shader's output,
13823 	// the GS input block is an array, so the DS output can't be declared as an array
13824 	case Utils::Shader::GEOMETRY:
13825 	case Utils::Shader::TESS_EVAL:
13826 	{
13827 		if (std::string(direction) == std::string("in")) // match HS output and DS input
13828 		{
13829 			array = "[]";
13830 			index = "[0]";
13831 		}
13832 		else // match DS output and GS input
13833 		{
13834 			array = "";
13835 			index = "";
13836 		}
13837 	}
13838 	break;
13839 	case Utils::Shader::VERTEX:
13840 		break;
13841 	default:
13842 		TCU_FAIL("Invalid enum");
13843 	}
13844 
13845 	if (true == require_modifications)
13846 	{
13847 		size_t position = 0;
13848 		size_t temp;
13849 
13850 		Utils::replaceToken("DIRECTION", position, direction, source);
13851 		temp = position;
13852 		Utils::replaceToken("BLOCK_DEFINITION", position, definition, source);
13853 		position = temp;
13854 		Utils::replaceToken("ARRAY", position, array, source);
13855 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
13856 
13857 		Utils::replaceAllTokens("INDEX", index, source);
13858 	}
13859 	else
13860 	{
13861 		switch (stage)
13862 		{
13863 		case Utils::Shader::FRAGMENT:
13864 			source = fs;
13865 			break;
13866 		case Utils::Shader::GEOMETRY:
13867 			source = gs;
13868 			break;
13869 		case Utils::Shader::TESS_CTRL:
13870 			source = tcs;
13871 			break;
13872 		case Utils::Shader::TESS_EVAL:
13873 			source = tes;
13874 			break;
13875 		case Utils::Shader::VERTEX:
13876 			source = vs;
13877 			break;
13878 		default:
13879 			TCU_FAIL("Invalid enum");
13880 		}
13881 	}
13882 
13883 	return source;
13884 }
13885 
13886 /** Get description of test case
13887  *
13888  * @param test_case_index Index of test case
13889  *
13890  * @return Test case description
13891  **/
13892 std::string VaryingBlockMemberLocationsTest::getTestCaseName(GLuint test_case_index)
13893 {
13894 	std::stringstream stream;
13895 	testCase&		  test_case = m_test_cases[test_case_index];
13896 
13897 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", direction: ";
13898 
13899 	if (true == test_case.m_is_input)
13900 	{
13901 		stream << "input";
13902 	}
13903 	else
13904 	{
13905 		stream << "output";
13906 	}
13907 
13908 	if (true == test_case.m_qualify_all)
13909 	{
13910 		stream << ", all members qualified";
13911 	}
13912 	else
13913 	{
13914 		stream << ", not all members qualified";
13915 	}
13916 
13917 	return stream.str();
13918 }
13919 
13920 /** Get number of test cases
13921  *
13922  * @return Number of test cases
13923  **/
13924 GLuint VaryingBlockMemberLocationsTest::getTestCaseNumber()
13925 {
13926 	return static_cast<GLuint>(m_test_cases.size());
13927 }
13928 
13929 /** Selects if "compute" stage is relevant for test
13930  *
13931  * @param ignored
13932  *
13933  * @return false
13934  **/
13935 bool VaryingBlockMemberLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
13936 {
13937 	return false;
13938 }
13939 
13940 /** Selects if compilation failure is expected result
13941  *
13942  * @param test_case_index Index of test case
13943  *
13944  * @return false when all members are qualified, true otherwise
13945  **/
13946 bool VaryingBlockMemberLocationsTest::isFailureExpected(GLuint test_case_index)
13947 {
13948 	return (true != m_test_cases[test_case_index].m_qualify_all);
13949 }
13950 
13951 /** Prepare all test cases
13952  *
13953  **/
13954 void VaryingBlockMemberLocationsTest::testInit()
13955 {
13956 	for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
13957 	{
13958 		if (Utils::Shader::COMPUTE == stage)
13959 		{
13960 			continue;
13961 		}
13962 
13963 		testCase test_case_in_all  = { true, true, (Utils::Shader::STAGES)stage };
13964 		testCase test_case_in_one  = { true, false, (Utils::Shader::STAGES)stage };
13965 		testCase test_case_out_all = { false, true, (Utils::Shader::STAGES)stage };
13966 		testCase test_case_out_one = { false, false, (Utils::Shader::STAGES)stage };
13967 
13968 		if (Utils::Shader::VERTEX != stage)
13969 		{
13970 			m_test_cases.push_back(test_case_in_all);
13971 			m_test_cases.push_back(test_case_in_one);
13972 		}
13973 
13974 		if (Utils::Shader::FRAGMENT != stage)
13975 		{
13976 			m_test_cases.push_back(test_case_out_all);
13977 			m_test_cases.push_back(test_case_out_one);
13978 		}
13979 	}
13980 }
13981 
13982 /** Constructor
13983  *
13984  * @param context Test framework context
13985  **/
13986 VaryingBlockAutomaticMemberLocationsTest::VaryingBlockAutomaticMemberLocationsTest(deqp::Context& context)
13987 	: NegativeTestBase(
13988 		  context, "varying_block_automatic_member_locations",
13989 		  "Test verifies that compiler assigns subsequent locations to block members, even if this causes errors")
13990 {
13991 }
13992 
13993 /** Source for given test case and stage
13994  *
13995  * @param test_case_index Index of test case
13996  * @param stage           Shader stage
13997  *
13998  * @return Shader source
13999  **/
14000 std::string VaryingBlockAutomaticMemberLocationsTest::getShaderSource(GLuint				test_case_index,
14001 																	  Utils::Shader::STAGES stage)
14002 {
14003 	static const GLchar* block_definition = "layout (location = 2) DIRECTION DBZ {\n"
14004 											"    vec4 goku;\n"
14005 											"    vec4 gohan[4];\n"
14006 											"    vec4 goten;\n"
14007 											"    layout (location = 1) vec4 chichi;\n"
14008 											"    vec4 pan;\n"
14009 											"} dbzARRAY;\n";
14010 	static const GLchar* input_use = "    result += dbzINDEX.goku + dbzINDEX.gohan[0] + dbzINDEX.gohan[1] + "
14011 									 "dbzINDEX.gohan[3] + dbzINDEX.gohan[2] + dbzINDEX.goten + dbzINDEX.chichi + "
14012 									 "dbzINDEX.pan;\n";
14013 	static const GLchar* output_use = "    dbzINDEX.goku     = result;\n"
14014 									  "    dbzINDEX.gohan[0] = result / 2;\n"
14015 									  "    dbzINDEX.gohan[1] = result / 2.25;\n"
14016 									  "    dbzINDEX.gohan[2] = result / 2.5;\n"
14017 									  "    dbzINDEX.gohan[3] = result / 2.75;\n"
14018 									  "    dbzINDEX.goten    = result / 4  - dbzINDEX.gohan[0] - dbzINDEX.gohan[1] - "
14019 									  "dbzINDEX.gohan[2] - dbzINDEX.gohan[3];\n"
14020 									  "    dbzINDEX.chichi   = result / 8  - dbzINDEX.goten;\n"
14021 									  "    dbzINDEX.pan      = result / 16 - dbzINDEX.chichi;\n";
14022 	static const GLchar* fs = "#version 430 core\n"
14023 							  "#extension GL_ARB_enhanced_layouts : require\n"
14024 							  "\n"
14025 							  "in  vec4 gs_fs;\n"
14026 							  "out vec4 fs_out;\n"
14027 							  "\n"
14028 							  "void main()\n"
14029 							  "{\n"
14030 							  "    fs_out = gs_fs;\n"
14031 							  "}\n"
14032 							  "\n";
14033 	static const GLchar* fs_tested = "#version 430 core\n"
14034 									 "#extension GL_ARB_enhanced_layouts : require\n"
14035 									 "\n"
14036 									 "BLOCK_DEFINITION"
14037 									 "\n"
14038 									 "in  vec4 gs_fs;\n"
14039 									 "out vec4 fs_out;\n"
14040 									 "\n"
14041 									 "void main()\n"
14042 									 "{\n"
14043 									 "    vec4 result = gs_fs;\n"
14044 									 "\n"
14045 									 "VARIABLE_USE"
14046 									 "\n"
14047 									 "    fs_out += result;\n"
14048 									 "}\n"
14049 									 "\n";
14050 	static const GLchar* gs = "#version 430 core\n"
14051 							  "#extension GL_ARB_enhanced_layouts : require\n"
14052 							  "\n"
14053 							  "layout(points)                           in;\n"
14054 							  "layout(triangle_strip, max_vertices = 4) out;\n"
14055 							  "\n"
14056 							  "in  vec4 tes_gs[];\n"
14057 							  "out vec4 gs_fs;\n"
14058 							  "\n"
14059 							  "void main()\n"
14060 							  "{\n"
14061 							  "    gs_fs = tes_gs[0];\n"
14062 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
14063 							  "    EmitVertex();\n"
14064 							  "    gs_fs = tes_gs[0];\n"
14065 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
14066 							  "    EmitVertex();\n"
14067 							  "    gs_fs = tes_gs[0];\n"
14068 							  "    gl_Position  = vec4(1, -1, 0, 1);\n"
14069 							  "    EmitVertex();\n"
14070 							  "    gs_fs = tes_gs[0];\n"
14071 							  "    gl_Position  = vec4(1, 1, 0, 1);\n"
14072 							  "    EmitVertex();\n"
14073 							  "}\n"
14074 							  "\n";
14075 	static const GLchar* gs_tested = "#version 430 core\n"
14076 									 "#extension GL_ARB_enhanced_layouts : require\n"
14077 									 "\n"
14078 									 "layout(points)                           in;\n"
14079 									 "layout(triangle_strip, max_vertices = 4) out;\n"
14080 									 "\n"
14081 									 "BLOCK_DEFINITION"
14082 									 "\n"
14083 									 "in  vec4 tes_gs[];\n"
14084 									 "out vec4 gs_fs;\n"
14085 									 "\n"
14086 									 "void main()\n"
14087 									 "{\n"
14088 									 "    vec4 result = tes_gs[0];\n"
14089 									 "\n"
14090 									 "VARIABLE_USE"
14091 									 "\n"
14092 									 "    gs_fs = result;\n"
14093 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
14094 									 "    EmitVertex();\n"
14095 									 "    gs_fs = result;\n"
14096 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
14097 									 "    EmitVertex();\n"
14098 									 "    gs_fs = result;\n"
14099 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
14100 									 "    EmitVertex();\n"
14101 									 "    gs_fs = result;\n"
14102 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
14103 									 "    EmitVertex();\n"
14104 									 "}\n"
14105 									 "\n";
14106 	static const GLchar* tcs = "#version 430 core\n"
14107 							   "#extension GL_ARB_enhanced_layouts : require\n"
14108 							   "\n"
14109 							   "layout(vertices = 1) out;\n"
14110 							   "\n"
14111 							   "in  vec4 vs_tcs[];\n"
14112 							   "out vec4 tcs_tes[];\n"
14113 							   "\n"
14114 							   "void main()\n"
14115 							   "{\n"
14116 							   "\n"
14117 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
14118 							   "\n"
14119 							   "    gl_TessLevelOuter[0] = 1.0;\n"
14120 							   "    gl_TessLevelOuter[1] = 1.0;\n"
14121 							   "    gl_TessLevelOuter[2] = 1.0;\n"
14122 							   "    gl_TessLevelOuter[3] = 1.0;\n"
14123 							   "    gl_TessLevelInner[0] = 1.0;\n"
14124 							   "    gl_TessLevelInner[1] = 1.0;\n"
14125 							   "}\n"
14126 							   "\n";
14127 	static const GLchar* tcs_tested = "#version 430 core\n"
14128 									  "#extension GL_ARB_enhanced_layouts : require\n"
14129 									  "\n"
14130 									  "layout(vertices = 1) out;\n"
14131 									  "\n"
14132 									  "BLOCK_DEFINITION"
14133 									  "\n"
14134 									  "in  vec4 vs_tcs[];\n"
14135 									  "out vec4 tcs_tes[];\n"
14136 									  "\n"
14137 									  "void main()\n"
14138 									  "{\n"
14139 									  "    vec4 result = vs_tcs[gl_InvocationID];\n"
14140 									  "\n"
14141 									  "VARIABLE_USE"
14142 									  "\n"
14143 									  "    tcs_tes[gl_InvocationID] = result;\n"
14144 									  "\n"
14145 									  "    gl_TessLevelOuter[0] = 1.0;\n"
14146 									  "    gl_TessLevelOuter[1] = 1.0;\n"
14147 									  "    gl_TessLevelOuter[2] = 1.0;\n"
14148 									  "    gl_TessLevelOuter[3] = 1.0;\n"
14149 									  "    gl_TessLevelInner[0] = 1.0;\n"
14150 									  "    gl_TessLevelInner[1] = 1.0;\n"
14151 									  "}\n"
14152 									  "\n";
14153 	static const GLchar* tes = "#version 430 core\n"
14154 							   "#extension GL_ARB_enhanced_layouts : require\n"
14155 							   "\n"
14156 							   "layout(isolines, point_mode) in;\n"
14157 							   "\n"
14158 							   "in  vec4 tcs_tes[];\n"
14159 							   "out vec4 tes_gs;\n"
14160 							   "\n"
14161 							   "void main()\n"
14162 							   "{\n"
14163 							   "    tes_gs = tcs_tes[0];\n"
14164 							   "}\n"
14165 							   "\n";
14166 	static const GLchar* tes_tested = "#version 430 core\n"
14167 									  "#extension GL_ARB_enhanced_layouts : require\n"
14168 									  "\n"
14169 									  "layout(isolines, point_mode) in;\n"
14170 									  "\n"
14171 									  "BLOCK_DEFINITION"
14172 									  "\n"
14173 									  "in  vec4 tcs_tes[];\n"
14174 									  "out vec4 tes_gs;\n"
14175 									  "\n"
14176 									  "void main()\n"
14177 									  "{\n"
14178 									  "    vec4 result = tcs_tes[0];\n"
14179 									  "\n"
14180 									  "VARIABLE_USE"
14181 									  "\n"
14182 									  "    tes_gs += result;\n"
14183 									  "}\n"
14184 									  "\n";
14185 	static const GLchar* vs = "#version 430 core\n"
14186 							  "#extension GL_ARB_enhanced_layouts : require\n"
14187 							  "\n"
14188 							  "in  vec4 in_vs;\n"
14189 							  "out vec4 vs_tcs;\n"
14190 							  "\n"
14191 							  "void main()\n"
14192 							  "{\n"
14193 							  "    vs_tcs = in_vs;\n"
14194 							  "}\n"
14195 							  "\n";
14196 	static const GLchar* vs_tested = "#version 430 core\n"
14197 									 "#extension GL_ARB_enhanced_layouts : require\n"
14198 									 "\n"
14199 									 "BLOCK_DEFINITION"
14200 									 "\n"
14201 									 "in  vec4 in_vs;\n"
14202 									 "out vec4 vs_tcs;\n"
14203 									 "\n"
14204 									 "void main()\n"
14205 									 "{\n"
14206 									 "    vec4 result = in_vs;\n"
14207 									 "\n"
14208 									 "VARIABLE_USE"
14209 									 "\n"
14210 									 "    vs_tcs += result;\n"
14211 									 "}\n"
14212 									 "\n";
14213 
14214 	const GLchar* array		= "";
14215 	const GLchar* direction = "out";
14216 	const GLchar* index		= "";
14217 	std::string   source;
14218 	testCase&	 test_case = m_test_cases[test_case_index];
14219 	const GLchar* var_use   = output_use;
14220 
14221 	if (true == test_case.m_is_input)
14222 	{
14223 		direction = "in ";
14224 		var_use   = input_use;
14225 	}
14226 
14227 	if (test_case.m_stage == stage)
14228 	{
14229 		size_t position = 0;
14230 		size_t temp;
14231 
14232 		switch (stage)
14233 		{
14234 		case Utils::Shader::FRAGMENT:
14235 			source = fs_tested;
14236 			break;
14237 		case Utils::Shader::GEOMETRY:
14238 			source = gs_tested;
14239 			array  = "[]";
14240 			index  = "[0]";
14241 			break;
14242 		case Utils::Shader::TESS_CTRL:
14243 			source = tcs_tested;
14244 			array  = "[]";
14245 			index  = "[gl_InvocationID]";
14246 			break;
14247 		case Utils::Shader::TESS_EVAL:
14248 			source = tes_tested;
14249 			array  = "[]";
14250 			index  = "[0]";
14251 			break;
14252 		case Utils::Shader::VERTEX:
14253 			source = vs_tested;
14254 			break;
14255 		default:
14256 			TCU_FAIL("Invalid enum");
14257 		}
14258 
14259 		temp = position;
14260 		Utils::replaceToken("BLOCK_DEFINITION", position, block_definition, source);
14261 		position = temp;
14262 		Utils::replaceToken("DIRECTION", position, direction, source);
14263 		Utils::replaceToken("ARRAY", position, array, source);
14264 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
14265 
14266 		Utils::replaceAllTokens("INDEX", index, source);
14267 	}
14268 	else
14269 	{
14270 		switch (stage)
14271 		{
14272 		case Utils::Shader::FRAGMENT:
14273 			source = fs;
14274 			break;
14275 		case Utils::Shader::GEOMETRY:
14276 			source = gs;
14277 			break;
14278 		case Utils::Shader::TESS_CTRL:
14279 			source = tcs;
14280 			break;
14281 		case Utils::Shader::TESS_EVAL:
14282 			source = tes;
14283 			break;
14284 		case Utils::Shader::VERTEX:
14285 			source = vs;
14286 			break;
14287 		default:
14288 			TCU_FAIL("Invalid enum");
14289 		}
14290 	}
14291 
14292 	return source;
14293 }
14294 
14295 /** Get description of test case
14296  *
14297  * @param test_case_index Index of test case
14298  *
14299  * @return Test case description
14300  **/
14301 std::string VaryingBlockAutomaticMemberLocationsTest::getTestCaseName(GLuint test_case_index)
14302 {
14303 	std::stringstream stream;
14304 	testCase&		  test_case = m_test_cases[test_case_index];
14305 
14306 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", direction: ";
14307 
14308 	if (true == test_case.m_is_input)
14309 	{
14310 		stream << "input";
14311 	}
14312 	else
14313 	{
14314 		stream << "output";
14315 	}
14316 
14317 	return stream.str();
14318 }
14319 
14320 /** Get number of test cases
14321  *
14322  * @return Number of test cases
14323  **/
14324 GLuint VaryingBlockAutomaticMemberLocationsTest::getTestCaseNumber()
14325 {
14326 	return static_cast<GLuint>(m_test_cases.size());
14327 }
14328 
14329 /** Selects if "compute" stage is relevant for test
14330  *
14331  * @param ignored
14332  *
14333  * @return false
14334  **/
14335 bool VaryingBlockAutomaticMemberLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
14336 {
14337 	return false;
14338 }
14339 
14340 /** Prepare all test cases
14341  *
14342  **/
14343 void VaryingBlockAutomaticMemberLocationsTest::testInit()
14344 {
14345 	for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
14346 	{
14347 		if (Utils::Shader::COMPUTE == stage)
14348 		{
14349 			continue;
14350 		}
14351 
14352 		testCase test_case_in  = { true, (Utils::Shader::STAGES)stage };
14353 		testCase test_case_out = { false, (Utils::Shader::STAGES)stage };
14354 
14355 		if (Utils::Shader::VERTEX != stage)
14356 		{
14357 			m_test_cases.push_back(test_case_in);
14358 		}
14359 
14360 		if (Utils::Shader::FRAGMENT != stage)
14361 		{
14362 			m_test_cases.push_back(test_case_out);
14363 		}
14364 	}
14365 }
14366 
14367 /** Constructor
14368  *
14369  * @param context Test framework context
14370  **/
14371 VaryingLocationLimitTest::VaryingLocationLimitTest(deqp::Context& context)
14372 	: NegativeTestBase(context, "varying_location_limit",
14373 					   "Test verifies that compiler reports error when location qualifier exceed limits")
14374 {
14375 }
14376 
14377 /** Source for given test case and stage
14378  *
14379  * @param test_case_index Index of test case
14380  * @param stage           Shader stage
14381  *
14382  * @return Shader source
14383  **/
14384 std::string VaryingLocationLimitTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
14385 {
14386 	static const GLchar* var_definition = "layout (location = LAST + 1) FLAT DIRECTION TYPE gokuARRAY;\n";
14387 	static const GLchar* input_use		= "    if (TYPE(0) == gokuINDEX)\n"
14388 									 "    {\n"
14389 									 "        result += vec4(1, 0.5, 0.25, 0.125);\n"
14390 									 "    }\n";
14391 	static const GLchar* output_use = "    gokuINDEX = TYPE(0);\n"
14392 									  "    if (vec4(0) == result)\n"
14393 									  "    {\n"
14394 									  "        gokuINDEX = TYPE(1);\n"
14395 									  "    }\n";
14396 	static const GLchar* fs = "#version 430 core\n"
14397 							  "#extension GL_ARB_enhanced_layouts : require\n"
14398 							  "\n"
14399 							  "in  vec4 gs_fs;\n"
14400 							  "out vec4 fs_out;\n"
14401 							  "\n"
14402 							  "void main()\n"
14403 							  "{\n"
14404 							  "    fs_out = gs_fs;\n"
14405 							  "}\n"
14406 							  "\n";
14407 	static const GLchar* fs_tested = "#version 430 core\n"
14408 									 "#extension GL_ARB_enhanced_layouts : require\n"
14409 									 "\n"
14410 									 "VAR_DEFINITION"
14411 									 "\n"
14412 									 "in  vec4 gs_fs;\n"
14413 									 "out vec4 fs_out;\n"
14414 									 "\n"
14415 									 "void main()\n"
14416 									 "{\n"
14417 									 "    vec4 result = gs_fs;\n"
14418 									 "\n"
14419 									 "VARIABLE_USE"
14420 									 "\n"
14421 									 "    fs_out += result;\n"
14422 									 "}\n"
14423 									 "\n";
14424 	static const GLchar* gs = "#version 430 core\n"
14425 							  "#extension GL_ARB_enhanced_layouts : require\n"
14426 							  "\n"
14427 							  "layout(points)                           in;\n"
14428 							  "layout(triangle_strip, max_vertices = 4) out;\n"
14429 							  "\n"
14430 							  "in  vec4 tes_gs[];\n"
14431 							  "out vec4 gs_fs;\n"
14432 							  "\n"
14433 							  "void main()\n"
14434 							  "{\n"
14435 							  "    gs_fs = tes_gs[0];\n"
14436 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
14437 							  "    EmitVertex();\n"
14438 							  "    gs_fs = tes_gs[0];\n"
14439 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
14440 							  "    EmitVertex();\n"
14441 							  "    gs_fs = tes_gs[0];\n"
14442 							  "    gl_Position  = vec4(1, -1, 0, 1);\n"
14443 							  "    EmitVertex();\n"
14444 							  "    gs_fs = tes_gs[0];\n"
14445 							  "    gl_Position  = vec4(1, 1, 0, 1);\n"
14446 							  "    EmitVertex();\n"
14447 							  "}\n"
14448 							  "\n";
14449 	static const GLchar* gs_tested = "#version 430 core\n"
14450 									 "#extension GL_ARB_enhanced_layouts : require\n"
14451 									 "\n"
14452 									 "layout(points)                           in;\n"
14453 									 "layout(triangle_strip, max_vertices = 4) out;\n"
14454 									 "\n"
14455 									 "VAR_DEFINITION"
14456 									 "\n"
14457 									 "in  vec4 tes_gs[];\n"
14458 									 "out vec4 gs_fs;\n"
14459 									 "\n"
14460 									 "void main()\n"
14461 									 "{\n"
14462 									 "    vec4 result = tes_gs[0];\n"
14463 									 "\n"
14464 									 "VARIABLE_USE"
14465 									 "\n"
14466 									 "    gs_fs = result;\n"
14467 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
14468 									 "    EmitVertex();\n"
14469 									 "    gs_fs = result;\n"
14470 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
14471 									 "    EmitVertex();\n"
14472 									 "    gs_fs = result;\n"
14473 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
14474 									 "    EmitVertex();\n"
14475 									 "    gs_fs = result;\n"
14476 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
14477 									 "    EmitVertex();\n"
14478 									 "}\n"
14479 									 "\n";
14480 	static const GLchar* tcs = "#version 430 core\n"
14481 							   "#extension GL_ARB_enhanced_layouts : require\n"
14482 							   "\n"
14483 							   "layout(vertices = 1) out;\n"
14484 							   "\n"
14485 							   "in  vec4 vs_tcs[];\n"
14486 							   "out vec4 tcs_tes[];\n"
14487 							   "\n"
14488 							   "void main()\n"
14489 							   "{\n"
14490 							   "\n"
14491 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
14492 							   "\n"
14493 							   "    gl_TessLevelOuter[0] = 1.0;\n"
14494 							   "    gl_TessLevelOuter[1] = 1.0;\n"
14495 							   "    gl_TessLevelOuter[2] = 1.0;\n"
14496 							   "    gl_TessLevelOuter[3] = 1.0;\n"
14497 							   "    gl_TessLevelInner[0] = 1.0;\n"
14498 							   "    gl_TessLevelInner[1] = 1.0;\n"
14499 							   "}\n"
14500 							   "\n";
14501 	static const GLchar* tcs_tested = "#version 430 core\n"
14502 									  "#extension GL_ARB_enhanced_layouts : require\n"
14503 									  "\n"
14504 									  "layout(vertices = 1) out;\n"
14505 									  "\n"
14506 									  "VAR_DEFINITION"
14507 									  "\n"
14508 									  "in  vec4 vs_tcs[];\n"
14509 									  "out vec4 tcs_tes[];\n"
14510 									  "\n"
14511 									  "void main()\n"
14512 									  "{\n"
14513 									  "    vec4 result = vs_tcs[gl_InvocationID];\n"
14514 									  "\n"
14515 									  "VARIABLE_USE"
14516 									  "\n"
14517 									  "    tcs_tes[gl_InvocationID] = result;\n"
14518 									  "\n"
14519 									  "    gl_TessLevelOuter[0] = 1.0;\n"
14520 									  "    gl_TessLevelOuter[1] = 1.0;\n"
14521 									  "    gl_TessLevelOuter[2] = 1.0;\n"
14522 									  "    gl_TessLevelOuter[3] = 1.0;\n"
14523 									  "    gl_TessLevelInner[0] = 1.0;\n"
14524 									  "    gl_TessLevelInner[1] = 1.0;\n"
14525 									  "}\n"
14526 									  "\n";
14527 	static const GLchar* tes = "#version 430 core\n"
14528 							   "#extension GL_ARB_enhanced_layouts : require\n"
14529 							   "\n"
14530 							   "layout(isolines, point_mode) in;\n"
14531 							   "\n"
14532 							   "in  vec4 tcs_tes[];\n"
14533 							   "out vec4 tes_gs;\n"
14534 							   "\n"
14535 							   "void main()\n"
14536 							   "{\n"
14537 							   "    tes_gs = tcs_tes[0];\n"
14538 							   "}\n"
14539 							   "\n";
14540 	static const GLchar* tes_tested = "#version 430 core\n"
14541 									  "#extension GL_ARB_enhanced_layouts : require\n"
14542 									  "\n"
14543 									  "layout(isolines, point_mode) in;\n"
14544 									  "\n"
14545 									  "VAR_DEFINITION"
14546 									  "\n"
14547 									  "in  vec4 tcs_tes[];\n"
14548 									  "out vec4 tes_gs;\n"
14549 									  "\n"
14550 									  "void main()\n"
14551 									  "{\n"
14552 									  "    vec4 result = tcs_tes[0];\n"
14553 									  "\n"
14554 									  "VARIABLE_USE"
14555 									  "\n"
14556 									  "    tes_gs += result;\n"
14557 									  "}\n"
14558 									  "\n";
14559 	static const GLchar* vs = "#version 430 core\n"
14560 							  "#extension GL_ARB_enhanced_layouts : require\n"
14561 							  "\n"
14562 							  "in  vec4 in_vs;\n"
14563 							  "out vec4 vs_tcs;\n"
14564 							  "\n"
14565 							  "void main()\n"
14566 							  "{\n"
14567 							  "    vs_tcs = in_vs;\n"
14568 							  "}\n"
14569 							  "\n";
14570 	static const GLchar* vs_tested = "#version 430 core\n"
14571 									 "#extension GL_ARB_enhanced_layouts : require\n"
14572 									 "\n"
14573 									 "VAR_DEFINITION"
14574 									 "\n"
14575 									 "in  vec4 in_vs;\n"
14576 									 "out vec4 vs_tcs;\n"
14577 									 "\n"
14578 									 "void main()\n"
14579 									 "{\n"
14580 									 "    vec4 result = in_vs;\n"
14581 									 "\n"
14582 									 "VARIABLE_USE"
14583 									 "\n"
14584 									 "    vs_tcs += result;\n"
14585 									 "}\n"
14586 									 "\n";
14587 
14588 	std::string source;
14589 	testCase&   test_case = m_test_cases[test_case_index];
14590 
14591 	if (test_case.m_stage == stage)
14592 	{
14593 		const GLchar*			 array = "";
14594 		GLchar					 buffer[16];
14595 		const GLchar*			 direction = "in ";
14596 		const GLchar*			 flat	  = "";
14597 		const GLchar*			 index	 = "";
14598 		GLuint					 last	  = getLastInputLocation(stage, test_case.m_type, 0, true);
14599 		size_t					 position  = 0;
14600 		size_t					 temp;
14601 		const GLchar*			 type_name = test_case.m_type.GetGLSLTypeName();
14602 		Utils::Variable::STORAGE storage   = Utils::Variable::VARYING_INPUT;
14603 		const GLchar*			 var_use   = input_use;
14604 
14605 		if (false == test_case.m_is_input)
14606 		{
14607 			direction = "out";
14608 			last	  = getLastOutputLocation(stage, test_case.m_type, 0, true);
14609 			storage   = Utils::Variable::VARYING_OUTPUT;
14610 			var_use   = output_use;
14611 		}
14612 
14613 		if (true == isFlatRequired(stage, test_case.m_type, storage))
14614 		{
14615 			flat = "flat";
14616 		}
14617 
14618 		sprintf(buffer, "%d", last);
14619 
14620 		switch (stage)
14621 		{
14622 		case Utils::Shader::FRAGMENT:
14623 			source = fs_tested;
14624 			break;
14625 		case Utils::Shader::GEOMETRY:
14626 			source = gs_tested;
14627 			array  = "[]";
14628 			index  = "[0]";
14629 			break;
14630 		case Utils::Shader::TESS_CTRL:
14631 			source = tcs_tested;
14632 			array  = "[]";
14633 			index  = "[gl_InvocationID]";
14634 			break;
14635 		case Utils::Shader::TESS_EVAL:
14636 			source = tes_tested;
14637 			array  = "[]";
14638 			index  = "[0]";
14639 			break;
14640 		case Utils::Shader::VERTEX:
14641 			source = vs_tested;
14642 			break;
14643 		default:
14644 			TCU_FAIL("Invalid enum");
14645 		}
14646 
14647 		temp = position;
14648 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
14649 		position = temp;
14650 		Utils::replaceToken("LAST", position, buffer, source);
14651 		Utils::replaceToken("FLAT", position, flat, source);
14652 		Utils::replaceToken("DIRECTION", position, direction, source);
14653 		Utils::replaceToken("ARRAY", position, array, source);
14654 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
14655 
14656 		Utils::replaceAllTokens("TYPE", type_name, source);
14657 		Utils::replaceAllTokens("INDEX", index, source);
14658 	}
14659 	else
14660 	{
14661 		switch (stage)
14662 		{
14663 		case Utils::Shader::FRAGMENT:
14664 			source = fs;
14665 			break;
14666 		case Utils::Shader::GEOMETRY:
14667 			source = gs;
14668 			break;
14669 		case Utils::Shader::TESS_CTRL:
14670 			source = tcs;
14671 			break;
14672 		case Utils::Shader::TESS_EVAL:
14673 			source = tes;
14674 			break;
14675 		case Utils::Shader::VERTEX:
14676 			source = vs;
14677 			break;
14678 		default:
14679 			TCU_FAIL("Invalid enum");
14680 		}
14681 	}
14682 
14683 	return source;
14684 }
14685 
14686 /** Get description of test case
14687  *
14688  * @param test_case_index Index of test case
14689  *
14690  * @return Test case description
14691  **/
14692 std::string VaryingLocationLimitTest::getTestCaseName(GLuint test_case_index)
14693 {
14694 	std::stringstream stream;
14695 	testCase&		  test_case = m_test_cases[test_case_index];
14696 
14697 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
14698 		   << " type: " << test_case.m_type.GetGLSLTypeName() << ", direction: ";
14699 
14700 	if (true == test_case.m_is_input)
14701 	{
14702 		stream << "input";
14703 	}
14704 	else
14705 	{
14706 		stream << "output";
14707 	}
14708 
14709 	return stream.str();
14710 }
14711 
14712 /** Get number of test cases
14713  *
14714  * @return Number of test cases
14715  **/
14716 GLuint VaryingLocationLimitTest::getTestCaseNumber()
14717 {
14718 	return static_cast<GLuint>(m_test_cases.size());
14719 }
14720 
14721 /** Selects if "compute" stage is relevant for test
14722  *
14723  * @param ignored
14724  *
14725  * @return false
14726  **/
14727 bool VaryingLocationLimitTest::isComputeRelevant(GLuint /* test_case_index */)
14728 {
14729 	return false;
14730 }
14731 
14732 /** Prepare all test cases
14733  *
14734  **/
14735 void VaryingLocationLimitTest::testInit()
14736 {
14737 	const GLuint n_types = getTypesNumber();
14738 
14739 	for (GLuint i = 0; i < n_types; ++i)
14740 	{
14741 		const Utils::Type& type = getType(i);
14742 
14743 		for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
14744 		{
14745 			if (Utils::Shader::COMPUTE == stage)
14746 			{
14747 				continue;
14748 			}
14749 
14750 			testCase test_case_in  = { true, type, (Utils::Shader::STAGES)stage };
14751 			testCase test_case_out = { false, type, (Utils::Shader::STAGES)stage };
14752 
14753 			m_test_cases.push_back(test_case_in);
14754 
14755 			if (Utils::Shader::FRAGMENT != stage)
14756 			{
14757 				m_test_cases.push_back(test_case_out);
14758 			}
14759 		}
14760 	}
14761 }
14762 
14763 /** Constructor
14764  *
14765  * @param context Test framework context
14766  **/
14767 VaryingComponentsTest::VaryingComponentsTest(deqp::Context& context)
14768 	: VaryingLocationsTest(context, "varying_components",
14769 						   "Test verifies that input and output components are respected")
14770 {
14771 }
14772 
14773 /** Constructor
14774  *
14775  * @param context          Test framework context
14776  * @param test_name        Name of test
14777  * @param test_description Description of test
14778  **/
14779 VaryingComponentsTest::VaryingComponentsTest(deqp::Context& context, const glw::GLchar* test_name,
14780 											 const glw::GLchar* test_description)
14781 	: VaryingLocationsTest(context, test_name, test_description)
14782 {
14783 }
14784 
14785 /** Get interface of program
14786  *
14787  * @param test_case_index     Test case
14788  * @param program_interface   Interface of program
14789  * @param varying_passthrough Collection of connections between in and out variables
14790  **/
14791 void VaryingComponentsTest::getProgramInterface(GLuint test_case_index, Utils::ProgramInterface& program_interface,
14792 												Utils::VaryingPassthrough& varying_passthrough)
14793 {
14794 	GLuint				   array_length = getArrayLength();
14795 	const testCase&		   test_case	= m_test_cases[test_case_index];
14796 	const Utils::Type	  vector_type  = Utils::Type::GetType(test_case.m_type, 1, 4);
14797 	Utils::ShaderInterface si			= program_interface.GetShaderInterface(Utils::Shader::VERTEX);
14798 
14799 	/* Zero means no array, however we still need at least 1 slot of data */
14800 	if (0 == array_length)
14801 	{
14802 		array_length += 1;
14803 	}
14804 
14805 	/* Generate data */
14806 	const std::vector<GLubyte>& data	  = vector_type.GenerateDataPacked();
14807 	const size_t				data_size = data.size();
14808 
14809 	/* Prepare data for variables */
14810 	m_data.resize(array_length * data_size);
14811 
14812 	GLubyte*	   dst = &m_data[0];
14813 	const GLubyte* src = &data[0];
14814 
14815 	for (GLuint i = 0; i < array_length; ++i)
14816 	{
14817 		memcpy(dst + data_size * i, src, data_size);
14818 	}
14819 
14820 	/* Prepare interface for each stage */
14821 	prepareShaderStage(Utils::Shader::FRAGMENT, vector_type, program_interface, test_case, varying_passthrough);
14822 	prepareShaderStage(Utils::Shader::GEOMETRY, vector_type, program_interface, test_case, varying_passthrough);
14823 	prepareShaderStage(Utils::Shader::TESS_CTRL, vector_type, program_interface, test_case, varying_passthrough);
14824 	prepareShaderStage(Utils::Shader::TESS_EVAL, vector_type, program_interface, test_case, varying_passthrough);
14825 	prepareShaderStage(Utils::Shader::VERTEX, vector_type, program_interface, test_case, varying_passthrough);
14826 }
14827 
14828 /** Get type name
14829  *
14830  * @param test_case_index Index of test case
14831  *
14832  * @return Name of type test in test_case_index
14833  **/
14834 std::string VaryingComponentsTest::getTestCaseName(glw::GLuint test_case_index)
14835 {
14836 	std::string name;
14837 
14838 	const testCase& test_case = m_test_cases[test_case_index];
14839 
14840 	name = "Type: ";
14841 
14842 	switch (test_case.m_type)
14843 	{
14844 	case Utils::Type::Double:
14845 		name.append(Utils::Type::_double.GetGLSLTypeName());
14846 		break;
14847 	case Utils::Type::Float:
14848 		name.append(Utils::Type::_float.GetGLSLTypeName());
14849 		break;
14850 	case Utils::Type::Int:
14851 		name.append(Utils::Type::_int.GetGLSLTypeName());
14852 		break;
14853 	case Utils::Type::Uint:
14854 		name.append(Utils::Type::uint.GetGLSLTypeName());
14855 		break;
14856 	}
14857 
14858 	name.append(", layout: ");
14859 
14860 	switch (test_case.m_layout)
14861 	{
14862 	case GVEC4:
14863 		name.append("GVEC4");
14864 		break;
14865 	case SCALAR_GVEC3:
14866 		name.append("SCALAR_GVEC3");
14867 		break;
14868 	case GVEC3_SCALAR:
14869 		name.append("GVEC3_SCALAR");
14870 		break;
14871 	case GVEC2_GVEC2:
14872 		name.append("GVEC2_GVEC2");
14873 		break;
14874 	case GVEC2_SCALAR_SCALAR:
14875 		name.append("GVEC2_SCALAR_SCALAR");
14876 		break;
14877 	case SCALAR_GVEC2_SCALAR:
14878 		name.append("SCALAR_GVEC2_SCALAR");
14879 		break;
14880 	case SCALAR_SCALAR_GVEC2:
14881 		name.append("SCALAR_SCALAR_GVEC2");
14882 		break;
14883 	case SCALAR_SCALAR_SCALAR_SCALAR:
14884 		name.append("SCALAR_SCALAR_SCALAR_SCALAR");
14885 		break;
14886 	}
14887 
14888 	return name;
14889 }
14890 
14891 /** Returns number of types to test
14892  *
14893  * @return Number of types, 34
14894  **/
14895 glw::GLuint VaryingComponentsTest::getTestCaseNumber()
14896 {
14897 	return static_cast<GLuint>(m_test_cases.size());
14898 }
14899 
14900 /* Prepare test cases */
14901 void VaryingComponentsTest::testInit()
14902 {
14903 	// FIXME: add tests for doubles, which have specific rules
14904 
14905 	m_test_cases.push_back(testCase(GVEC4, Utils::Type::Float));
14906 	m_test_cases.push_back(testCase(SCALAR_GVEC3, Utils::Type::Float));
14907 	m_test_cases.push_back(testCase(GVEC3_SCALAR, Utils::Type::Float));
14908 	m_test_cases.push_back(testCase(GVEC2_GVEC2, Utils::Type::Float));
14909 	m_test_cases.push_back(testCase(GVEC2_SCALAR_SCALAR, Utils::Type::Float));
14910 	m_test_cases.push_back(testCase(SCALAR_GVEC2_SCALAR, Utils::Type::Float));
14911 	m_test_cases.push_back(testCase(SCALAR_SCALAR_GVEC2, Utils::Type::Float));
14912 	m_test_cases.push_back(testCase(SCALAR_SCALAR_SCALAR_SCALAR, Utils::Type::Float));
14913 
14914 	m_test_cases.push_back(testCase(GVEC4, Utils::Type::Int));
14915 	m_test_cases.push_back(testCase(SCALAR_GVEC3, Utils::Type::Int));
14916 	m_test_cases.push_back(testCase(GVEC3_SCALAR, Utils::Type::Int));
14917 	m_test_cases.push_back(testCase(GVEC2_GVEC2, Utils::Type::Int));
14918 	m_test_cases.push_back(testCase(GVEC2_SCALAR_SCALAR, Utils::Type::Int));
14919 	m_test_cases.push_back(testCase(SCALAR_GVEC2_SCALAR, Utils::Type::Int));
14920 	m_test_cases.push_back(testCase(SCALAR_SCALAR_GVEC2, Utils::Type::Int));
14921 	m_test_cases.push_back(testCase(SCALAR_SCALAR_SCALAR_SCALAR, Utils::Type::Int));
14922 
14923 	m_test_cases.push_back(testCase(GVEC4, Utils::Type::Uint));
14924 	m_test_cases.push_back(testCase(SCALAR_GVEC3, Utils::Type::Uint));
14925 	m_test_cases.push_back(testCase(GVEC3_SCALAR, Utils::Type::Uint));
14926 	m_test_cases.push_back(testCase(GVEC2_GVEC2, Utils::Type::Uint));
14927 	m_test_cases.push_back(testCase(GVEC2_SCALAR_SCALAR, Utils::Type::Uint));
14928 	m_test_cases.push_back(testCase(SCALAR_GVEC2_SCALAR, Utils::Type::Uint));
14929 	m_test_cases.push_back(testCase(SCALAR_SCALAR_GVEC2, Utils::Type::Uint));
14930 	m_test_cases.push_back(testCase(SCALAR_SCALAR_SCALAR_SCALAR, Utils::Type::Uint));
14931 }
14932 
14933 /** Inform that test use components
14934  *
14935  * @param ignored
14936  *
14937  * @return true
14938  **/
14939 bool VaryingComponentsTest::useComponentQualifier(glw::GLuint /* test_case_index */)
14940 {
14941 	return true;
14942 }
14943 
14944 /** Get length of arrays that should be used during test
14945  *
14946  * @return 0u - no array at all
14947  **/
14948 GLuint VaryingComponentsTest::getArrayLength()
14949 {
14950 	return 0;
14951 }
14952 
14953 std::string VaryingComponentsTest::prepareGlobals(GLuint last_in_location, GLuint last_out_location)
14954 {
14955 	std::string globals = VaryingLocationsTest::prepareGlobals(last_in_location, last_out_location);
14956 
14957 	globals.append("const uint comp_x = 0u;\n"
14958 				   "const uint comp_y = 1u;\n"
14959 				   "const uint comp_z = 2u;\n"
14960 				   "const uint comp_w = 3u;\n");
14961 
14962 	return globals;
14963 }
14964 
14965 /**
14966  *
14967  **/
14968 std::string VaryingComponentsTest::prepareName(const glw::GLchar* name, glw::GLint location, glw::GLint component,
14969 											   Utils::Shader::STAGES stage, Utils::Variable::STORAGE storage)
14970 {
14971 	GLchar		  buffer[16];
14972 	std::string   result   = "PREFIXNAME_lLOCATION_cCOMPONENT";
14973 	size_t		  position = 0;
14974 	const GLchar* prefix   = Utils::ProgramInterface::GetStagePrefix(stage, storage);
14975 
14976 	Utils::replaceToken("PREFIX", position, prefix, result);
14977 	Utils::replaceToken("NAME", position, name, result);
14978 
14979 	sprintf(buffer, "%d", location);
14980 	Utils::replaceToken("LOCATION", position, buffer, result);
14981 
14982 	sprintf(buffer, "%d", component);
14983 	Utils::replaceToken("COMPONENT", position, buffer, result);
14984 
14985 	return result;
14986 }
14987 
14988 std::string VaryingComponentsTest::prepareQualifiers(const glw::GLchar* location, const glw::GLchar* component,
14989 													 const glw::GLchar* interpolation)
14990 {
14991 	size_t		position   = 0;
14992 	std::string qualifiers = "layout (location = LOCATION, component = COMPONENT) INTERPOLATION";
14993 
14994 	Utils::replaceToken("LOCATION", position, location, qualifiers);
14995 	Utils::replaceToken("COMPONENT", position, component, qualifiers);
14996 	Utils::replaceToken("INTERPOLATION", position, interpolation, qualifiers);
14997 
14998 	return qualifiers;
14999 }
15000 
15001 /**
15002  *
15003  **/
15004 void VaryingComponentsTest::prepareShaderStage(Utils::Shader::STAGES stage, const Utils::Type& vector_type,
15005 											   Utils::ProgramInterface& program_interface, const testCase& test_case,
15006 											   Utils::VaryingPassthrough& varying_passthrough)
15007 {
15008 	const GLuint			array_length = getArrayLength();
15009 	const Utils::Type&		basic_type = Utils::Type::GetType(vector_type.m_basic_type, 1 /* n_cols */, 1 /* n_rows */);
15010 	descriptor				desc_in[8];
15011 	descriptor				desc_out[8];
15012 	const GLuint			first_in_loc  = 0;
15013 	const GLuint			first_out_loc = 0;
15014 	const GLchar*			interpolation = "";
15015 	const GLuint			last_in_loc   = getLastInputLocation(stage, vector_type, array_length, false);
15016 	GLuint					last_out_loc  = 0;
15017 	GLuint					n_desc		  = 0;
15018 	Utils::ShaderInterface& si			  = program_interface.GetShaderInterface(stage);
15019 
15020 	/* Select interpolation */
15021 	if ((Utils::Shader::FRAGMENT == stage) || (Utils::Shader::GEOMETRY == stage))
15022 	{
15023 		interpolation = " flat";
15024 	}
15025 
15026 	if (Utils::Shader::FRAGMENT != stage)
15027 	{
15028 		last_out_loc = getLastOutputLocation(stage, vector_type, array_length, false);
15029 	}
15030 
15031 	switch (test_case.m_layout)
15032 	{
15033 	case GVEC4:
15034 		n_desc = 2;
15035 		desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 4, "gvec4");
15036 		desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 4, "gvec4");
15037 
15038 		desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 4, "gvec4");
15039 		desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 4, "gvec4");
15040 		break;
15041 	case SCALAR_GVEC3:
15042 		n_desc = 4;
15043 		desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "scalar");
15044 		desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "scalar");
15045 		desc_in[2].assign(1, "comp_y", first_in_loc, "first_input_location", 3, "gvec3");
15046 		desc_in[3].assign(1, "comp_y", last_in_loc, "last_input_location", 3, "gvec3");
15047 
15048 		desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "scalar");
15049 		desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "scalar");
15050 		desc_out[2].assign(1, "comp_y", first_out_loc, "first_output_location", 3, "gvec3");
15051 		desc_out[3].assign(1, "comp_y", last_out_loc, "last_output_location", 3, "gvec3");
15052 		break;
15053 	case GVEC3_SCALAR:
15054 		n_desc = 4;
15055 		desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 3, "gvec3");
15056 		desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 3, "gvec3");
15057 		desc_in[2].assign(3, "comp_w", first_in_loc, "first_input_location", 1, "scalar");
15058 		desc_in[3].assign(3, "comp_w", last_in_loc, "last_input_location", 1, "scalar");
15059 
15060 		desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 3, "gvec3");
15061 		desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 3, "gvec3");
15062 		desc_out[2].assign(3, "comp_w", first_out_loc, "first_output_location", 1, "scalar");
15063 		desc_out[3].assign(3, "comp_w", last_out_loc, "last_output_location", 1, "scalar");
15064 		break;
15065 	case GVEC2_GVEC2:
15066 		n_desc = 4;
15067 		desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 2, "gvec2");
15068 		desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 2, "gvec2");
15069 		desc_in[2].assign(2, "comp_z", first_in_loc, "first_input_location", 2, "gvec2");
15070 		desc_in[3].assign(2, "comp_z", last_in_loc, "last_input_location", 2, "gvec2");
15071 
15072 		desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 2, "gvec2");
15073 		desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 2, "gvec2");
15074 		desc_out[2].assign(2, "comp_z", first_out_loc, "first_output_location", 2, "gvec2");
15075 		desc_out[3].assign(2, "comp_z", last_out_loc, "last_output_location", 2, "gvec2");
15076 		break;
15077 	case GVEC2_SCALAR_SCALAR:
15078 		n_desc = 6;
15079 		desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 2, "gvec2");
15080 		desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 2, "gvec2");
15081 		desc_in[2].assign(2, "comp_z", first_in_loc, "first_input_location", 1, "scalar");
15082 		desc_in[3].assign(2, "comp_z", last_in_loc, "last_input_location", 1, "scalar");
15083 		desc_in[4].assign(3, "comp_w", first_in_loc, "first_input_location", 1, "scalar");
15084 		desc_in[5].assign(3, "comp_w", last_in_loc, "last_input_location", 1, "scalar");
15085 
15086 		desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 2, "gvec2");
15087 		desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 2, "gvec2");
15088 		desc_out[2].assign(2, "comp_z", first_out_loc, "first_output_location", 1, "scalar");
15089 		desc_out[3].assign(2, "comp_z", last_out_loc, "last_output_location", 1, "scalar");
15090 		desc_out[4].assign(3, "comp_w", first_out_loc, "first_output_location", 1, "scalar");
15091 		desc_out[5].assign(3, "comp_w", last_out_loc, "last_output_location", 1, "scalar");
15092 		break;
15093 	case SCALAR_GVEC2_SCALAR:
15094 		n_desc = 6;
15095 		desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "scalar");
15096 		desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "scalar");
15097 		desc_in[2].assign(1, "comp_y", first_in_loc, "first_input_location", 2, "gvec2");
15098 		desc_in[3].assign(1, "comp_y", last_in_loc, "last_input_location", 2, "gvec2");
15099 		desc_in[4].assign(3, "comp_w", first_in_loc, "first_input_location", 1, "scalar");
15100 		desc_in[5].assign(3, "comp_w", last_in_loc, "last_input_location", 1, "scalar");
15101 
15102 		desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "scalar");
15103 		desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "scalar");
15104 		desc_out[2].assign(1, "comp_y", first_out_loc, "first_output_location", 2, "gvec2");
15105 		desc_out[3].assign(1, "comp_y", last_out_loc, "last_output_location", 2, "gvec2");
15106 		desc_out[4].assign(3, "comp_w", first_out_loc, "first_output_location", 1, "scalar");
15107 		desc_out[5].assign(3, "comp_w", last_out_loc, "last_output_location", 1, "scalar");
15108 		break;
15109 	case SCALAR_SCALAR_GVEC2:
15110 		n_desc = 6;
15111 		desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "scalar");
15112 		desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "scalar");
15113 		desc_in[2].assign(1, "comp_y", first_in_loc, "first_input_location", 1, "scalar");
15114 		desc_in[3].assign(1, "comp_y", last_in_loc, "last_input_location", 1, "scalar");
15115 		desc_in[4].assign(2, "comp_z", first_in_loc, "first_input_location", 2, "gvec2");
15116 		desc_in[5].assign(2, "comp_z", last_in_loc, "last_input_location", 2, "gvec2");
15117 
15118 		desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "scalar");
15119 		desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "scalar");
15120 		desc_out[2].assign(1, "comp_y", first_out_loc, "first_output_location", 1, "scalar");
15121 		desc_out[3].assign(1, "comp_y", last_out_loc, "last_output_location", 1, "scalar");
15122 		desc_out[4].assign(2, "comp_z", first_out_loc, "first_output_location", 2, "gvec2");
15123 		desc_out[5].assign(2, "comp_z", last_out_loc, "last_output_location", 2, "gvec2");
15124 		break;
15125 	case SCALAR_SCALAR_SCALAR_SCALAR:
15126 		n_desc = 8;
15127 		desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "scalar");
15128 		desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "scalar");
15129 		desc_in[2].assign(1, "comp_y", first_in_loc, "first_input_location", 1, "scalar");
15130 		desc_in[3].assign(1, "comp_y", last_in_loc, "last_input_location", 1, "scalar");
15131 		desc_in[4].assign(2, "comp_z", first_in_loc, "first_input_location", 1, "scalar");
15132 		desc_in[5].assign(2, "comp_z", last_in_loc, "last_input_location", 1, "scalar");
15133 		desc_in[6].assign(3, "comp_w", first_in_loc, "first_input_location", 1, "scalar");
15134 		desc_in[7].assign(3, "comp_w", last_in_loc, "last_input_location", 1, "scalar");
15135 
15136 		desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "scalar");
15137 		desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "scalar");
15138 		desc_out[2].assign(1, "comp_y", first_out_loc, "first_output_location", 1, "scalar");
15139 		desc_out[3].assign(1, "comp_y", last_out_loc, "last_output_location", 1, "scalar");
15140 		desc_out[4].assign(2, "comp_z", first_out_loc, "first_output_location", 1, "scalar");
15141 		desc_out[5].assign(2, "comp_z", last_out_loc, "last_output_location", 1, "scalar");
15142 		desc_out[6].assign(3, "comp_w", first_out_loc, "first_output_location", 1, "scalar");
15143 		desc_out[7].assign(3, "comp_w", last_out_loc, "last_output_location", 1, "scalar");
15144 		break;
15145 	}
15146 
15147 	for (GLuint i = 0; i < n_desc; ++i)
15148 	{
15149 		const descriptor& in_desc = desc_in[i];
15150 
15151 		Utils::Variable* in =
15152 			prepareVarying(basic_type, in_desc, interpolation, si, stage, Utils::Variable::VARYING_INPUT);
15153 
15154 		if (Utils::Shader::FRAGMENT != stage)
15155 		{
15156 			const descriptor& out_desc = desc_out[i];
15157 
15158 			Utils::Variable* out =
15159 				prepareVarying(basic_type, out_desc, interpolation, si, stage, Utils::Variable::VARYING_OUTPUT);
15160 
15161 			varying_passthrough.Add(stage, in, out);
15162 		}
15163 	}
15164 
15165 	si.m_globals = prepareGlobals(last_in_loc, last_out_loc);
15166 }
15167 
15168 /**
15169  *
15170  **/
15171 Utils::Variable* VaryingComponentsTest::prepareVarying(const Utils::Type& basic_type, const descriptor& desc,
15172 													   const GLchar* interpolation, Utils::ShaderInterface& si,
15173 													   Utils::Shader::STAGES stage, Utils::Variable::STORAGE storage)
15174 {
15175 	const GLuint	   array_length   = getArrayLength();
15176 	const GLuint	   component_size = basic_type.GetSize();
15177 	const std::string& name			  = prepareName(desc.m_name, desc.m_location, desc.m_component, stage, storage);
15178 	const GLuint	   offset		  = desc.m_component * component_size;
15179 	const std::string& qual			  = prepareQualifiers(desc.m_location_str, desc.m_component_str, interpolation);
15180 	const GLuint	   size			  = desc.m_n_rows * component_size;
15181 	const Utils::Type& type			  = Utils::Type::GetType(basic_type.m_basic_type, 1 /* n_columns */, desc.m_n_rows);
15182 	Utils::Variable*   var			  = 0;
15183 
15184 	if (Utils::Variable::VARYING_INPUT == storage)
15185 	{
15186 		var = si.Input(name.c_str(), qual.c_str() /* qualifiers */, desc.m_component /* expected_componenet */,
15187 					   desc.m_location /* expected_location */, type, /* built_in_type */
15188 					   GL_FALSE /* normalized */, array_length /* n_array_elements */, 0u /* stride */,
15189 					   offset /* offset */, (GLvoid*)&m_data[offset] /* data */, size /* data_size */);
15190 	}
15191 	else
15192 	{
15193 		var = si.Output(name.c_str(), qual.c_str() /* qualifiers */, desc.m_component /* expected_componenet */,
15194 						desc.m_location /* expected_location */, type, /* built_in_type */
15195 						GL_FALSE /* normalized */, array_length /* n_array_elements */, 0u /* stride */,
15196 						offset /* offset */, (GLvoid*)&m_data[offset] /* data */, size /* data_size */);
15197 	}
15198 
15199 	return var;
15200 }
15201 
15202 void VaryingComponentsTest::descriptor::assign(glw::GLint component, const glw::GLchar* component_str,
15203 											   glw::GLint location, const glw::GLchar* location_str, glw::GLuint n_rows,
15204 											   const glw::GLchar* name)
15205 {
15206 	m_component		= component;
15207 	m_component_str = component_str;
15208 	m_location		= location;
15209 	m_location_str  = location_str;
15210 	m_n_rows		= n_rows;
15211 	m_name			= name;
15212 }
15213 
15214 VaryingComponentsTest::testCase::testCase(COMPONENTS_LAYOUT layout, Utils::Type::TYPES type)
15215 	: m_layout(layout), m_type(type)
15216 {
15217 }
15218 
15219 /** Constructor
15220  *
15221  * @param context Test framework context
15222  **/
15223 VaryingArrayComponentsTest::VaryingArrayComponentsTest(deqp::Context& context)
15224 	: VaryingComponentsTest(context, "varying_array_components",
15225 							"Test verifies that input and output components are respected for arrays")
15226 {
15227 }
15228 
15229 /** Get length of arrays that should be used during test
15230  *
15231  * @return 4u
15232  **/
15233 GLuint VaryingArrayComponentsTest::getArrayLength()
15234 {
15235 	return 4u;
15236 }
15237 
15238 /** Constructor
15239  *
15240  * @param context Test framework context
15241  **/
15242 VaryingExceedingComponentsTest::VaryingExceedingComponentsTest(deqp::Context& context)
15243 	: NegativeTestBase(context, "varying_exceeding_components",
15244 					   "Test verifies that compiler reports error when component qualifier exceed limits")
15245 {
15246 }
15247 
15248 /** Source for given test case and stage
15249  *
15250  * @param test_case_index Index of test case
15251  * @param stage           Shader stage
15252  *
15253  * @return Shader source
15254  **/
15255 std::string VaryingExceedingComponentsTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
15256 {
15257 	static const GLchar* var_definition_arr =
15258 		"layout (location = 1, component = COMPONENT) flat DIRECTION TYPE gokuARRAY[1];\n";
15259 	static const GLchar* var_definition_one =
15260 		"layout (location = 1, component = COMPONENT) flat DIRECTION TYPE gokuARRAY;\n";
15261 	static const GLchar* input_use_arr = "    if (TYPE(0) == gokuINDEX[0])\n"
15262 										 "    {\n"
15263 										 "        result += vec4(1, 0.5, 0.25, 0.125);\n"
15264 										 "    }\n";
15265 	static const GLchar* input_use_one = "    if (TYPE(0) == gokuINDEX)\n"
15266 										 "    {\n"
15267 										 "        result += vec4(1, 0.5, 0.25, 0.125);\n"
15268 										 "    }\n";
15269 	static const GLchar* output_use_arr = "    gokuINDEX[0] = TYPE(0);\n"
15270 										  "    if (vec4(0) == result)\n"
15271 										  "    {\n"
15272 										  "        gokuINDEX[0] = TYPE(1);\n"
15273 										  "    }\n";
15274 	static const GLchar* output_use_one = "    gokuINDEX = TYPE(0);\n"
15275 										  "    if (vec4(0) == result)\n"
15276 										  "    {\n"
15277 										  "        gokuINDEX = TYPE(1);\n"
15278 										  "    }\n";
15279 	static const GLchar* fs = "#version 430 core\n"
15280 							  "#extension GL_ARB_enhanced_layouts : require\n"
15281 							  "\n"
15282 							  "in  vec4 gs_fs;\n"
15283 							  "out vec4 fs_out;\n"
15284 							  "\n"
15285 							  "void main()\n"
15286 							  "{\n"
15287 							  "    fs_out = gs_fs;\n"
15288 							  "}\n"
15289 							  "\n";
15290 	static const GLchar* fs_tested = "#version 430 core\n"
15291 									 "#extension GL_ARB_enhanced_layouts : require\n"
15292 									 "\n"
15293 									 "VAR_DEFINITION"
15294 									 "\n"
15295 									 "in  vec4 gs_fs;\n"
15296 									 "out vec4 fs_out;\n"
15297 									 "\n"
15298 									 "void main()\n"
15299 									 "{\n"
15300 									 "    vec4 result = gs_fs;\n"
15301 									 "\n"
15302 									 "VARIABLE_USE"
15303 									 "\n"
15304 									 "    fs_out += result;\n"
15305 									 "}\n"
15306 									 "\n";
15307 	static const GLchar* gs = "#version 430 core\n"
15308 							  "#extension GL_ARB_enhanced_layouts : require\n"
15309 							  "\n"
15310 							  "layout(points)                           in;\n"
15311 							  "layout(triangle_strip, max_vertices = 4) out;\n"
15312 							  "\n"
15313 							  "in  vec4 tes_gs[];\n"
15314 							  "out vec4 gs_fs;\n"
15315 							  "\n"
15316 							  "void main()\n"
15317 							  "{\n"
15318 							  "    gs_fs = tes_gs[0];\n"
15319 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
15320 							  "    EmitVertex();\n"
15321 							  "    gs_fs = tes_gs[0];\n"
15322 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
15323 							  "    EmitVertex();\n"
15324 							  "    gs_fs = tes_gs[0];\n"
15325 							  "    gl_Position  = vec4(1, -1, 0, 1);\n"
15326 							  "    EmitVertex();\n"
15327 							  "    gs_fs = tes_gs[0];\n"
15328 							  "    gl_Position  = vec4(1, 1, 0, 1);\n"
15329 							  "    EmitVertex();\n"
15330 							  "}\n"
15331 							  "\n";
15332 	static const GLchar* gs_tested = "#version 430 core\n"
15333 									 "#extension GL_ARB_enhanced_layouts : require\n"
15334 									 "\n"
15335 									 "layout(points)                           in;\n"
15336 									 "layout(triangle_strip, max_vertices = 4) out;\n"
15337 									 "\n"
15338 									 "VAR_DEFINITION"
15339 									 "\n"
15340 									 "in  vec4 tes_gs[];\n"
15341 									 "out vec4 gs_fs;\n"
15342 									 "\n"
15343 									 "void main()\n"
15344 									 "{\n"
15345 									 "    vec4 result = tes_gs[0];\n"
15346 									 "\n"
15347 									 "VARIABLE_USE"
15348 									 "\n"
15349 									 "    gs_fs = result;\n"
15350 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
15351 									 "    EmitVertex();\n"
15352 									 "    gs_fs = result;\n"
15353 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
15354 									 "    EmitVertex();\n"
15355 									 "    gs_fs = result;\n"
15356 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
15357 									 "    EmitVertex();\n"
15358 									 "    gs_fs = result;\n"
15359 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
15360 									 "    EmitVertex();\n"
15361 									 "}\n"
15362 									 "\n";
15363 	static const GLchar* tcs = "#version 430 core\n"
15364 							   "#extension GL_ARB_enhanced_layouts : require\n"
15365 							   "\n"
15366 							   "layout(vertices = 1) out;\n"
15367 							   "\n"
15368 							   "in  vec4 vs_tcs[];\n"
15369 							   "out vec4 tcs_tes[];\n"
15370 							   "\n"
15371 							   "void main()\n"
15372 							   "{\n"
15373 							   "\n"
15374 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
15375 							   "\n"
15376 							   "    gl_TessLevelOuter[0] = 1.0;\n"
15377 							   "    gl_TessLevelOuter[1] = 1.0;\n"
15378 							   "    gl_TessLevelOuter[2] = 1.0;\n"
15379 							   "    gl_TessLevelOuter[3] = 1.0;\n"
15380 							   "    gl_TessLevelInner[0] = 1.0;\n"
15381 							   "    gl_TessLevelInner[1] = 1.0;\n"
15382 							   "}\n"
15383 							   "\n";
15384 	static const GLchar* tcs_tested = "#version 430 core\n"
15385 									  "#extension GL_ARB_enhanced_layouts : require\n"
15386 									  "\n"
15387 									  "layout(vertices = 1) out;\n"
15388 									  "\n"
15389 									  "VAR_DEFINITION"
15390 									  "\n"
15391 									  "in  vec4 vs_tcs[];\n"
15392 									  "out vec4 tcs_tes[];\n"
15393 									  "\n"
15394 									  "void main()\n"
15395 									  "{\n"
15396 									  "    vec4 result = vs_tcs[gl_InvocationID];\n"
15397 									  "\n"
15398 									  "VARIABLE_USE"
15399 									  "\n"
15400 									  "    tcs_tes[gl_InvocationID] = result;\n"
15401 									  "\n"
15402 									  "    gl_TessLevelOuter[0] = 1.0;\n"
15403 									  "    gl_TessLevelOuter[1] = 1.0;\n"
15404 									  "    gl_TessLevelOuter[2] = 1.0;\n"
15405 									  "    gl_TessLevelOuter[3] = 1.0;\n"
15406 									  "    gl_TessLevelInner[0] = 1.0;\n"
15407 									  "    gl_TessLevelInner[1] = 1.0;\n"
15408 									  "}\n"
15409 									  "\n";
15410 	static const GLchar* tes = "#version 430 core\n"
15411 							   "#extension GL_ARB_enhanced_layouts : require\n"
15412 							   "\n"
15413 							   "layout(isolines, point_mode) in;\n"
15414 							   "\n"
15415 							   "in  vec4 tcs_tes[];\n"
15416 							   "out vec4 tes_gs;\n"
15417 							   "\n"
15418 							   "void main()\n"
15419 							   "{\n"
15420 							   "    tes_gs = tcs_tes[0];\n"
15421 							   "}\n"
15422 							   "\n";
15423 	static const GLchar* tes_tested = "#version 430 core\n"
15424 									  "#extension GL_ARB_enhanced_layouts : require\n"
15425 									  "\n"
15426 									  "layout(isolines, point_mode) in;\n"
15427 									  "\n"
15428 									  "VAR_DEFINITION"
15429 									  "\n"
15430 									  "in  vec4 tcs_tes[];\n"
15431 									  "out vec4 tes_gs;\n"
15432 									  "\n"
15433 									  "void main()\n"
15434 									  "{\n"
15435 									  "    vec4 result = tcs_tes[0];\n"
15436 									  "\n"
15437 									  "VARIABLE_USE"
15438 									  "\n"
15439 									  "    tes_gs += result;\n"
15440 									  "}\n"
15441 									  "\n";
15442 	static const GLchar* vs = "#version 430 core\n"
15443 							  "#extension GL_ARB_enhanced_layouts : require\n"
15444 							  "\n"
15445 							  "in  vec4 in_vs;\n"
15446 							  "out vec4 vs_tcs;\n"
15447 							  "\n"
15448 							  "void main()\n"
15449 							  "{\n"
15450 							  "    vs_tcs = in_vs;\n"
15451 							  "}\n"
15452 							  "\n";
15453 	static const GLchar* vs_tested = "#version 430 core\n"
15454 									 "#extension GL_ARB_enhanced_layouts : require\n"
15455 									 "\n"
15456 									 "VAR_DEFINITION"
15457 									 "\n"
15458 									 "in  vec4 in_vs;\n"
15459 									 "out vec4 vs_tcs;\n"
15460 									 "\n"
15461 									 "void main()\n"
15462 									 "{\n"
15463 									 "    vec4 result = in_vs;\n"
15464 									 "\n"
15465 									 "VARIABLE_USE"
15466 									 "\n"
15467 									 "    vs_tcs += result;\n"
15468 									 "}\n"
15469 									 "\n";
15470 
15471 	std::string source;
15472 	testCase&   test_case = m_test_cases[test_case_index];
15473 
15474 	if (test_case.m_stage == stage)
15475 	{
15476 		const GLchar* array = "";
15477 		GLchar		  buffer[16];
15478 		const GLchar* var_definition = 0;
15479 		const GLchar* direction		 = "in ";
15480 		const GLchar* index			 = "";
15481 		size_t		  position		 = 0;
15482 		size_t		  temp;
15483 		const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
15484 		const GLchar* var_use   = 0;
15485 
15486 		if (false == test_case.m_is_input)
15487 		{
15488 			direction = "out";
15489 
15490 			if (false == test_case.m_is_array)
15491 			{
15492 				var_definition = var_definition_one;
15493 				var_use		   = output_use_one;
15494 			}
15495 			else
15496 			{
15497 				var_definition = var_definition_arr;
15498 				var_use		   = output_use_arr;
15499 			}
15500 		}
15501 		else
15502 		{
15503 			if (false == test_case.m_is_array)
15504 			{
15505 				var_definition = var_definition_one;
15506 				var_use		   = input_use_one;
15507 			}
15508 			else
15509 			{
15510 				var_definition = var_definition_arr;
15511 				var_use		   = input_use_arr;
15512 			}
15513 		}
15514 
15515 		sprintf(buffer, "%d", test_case.m_component);
15516 
15517 		switch (stage)
15518 		{
15519 		case Utils::Shader::FRAGMENT:
15520 			source = fs_tested;
15521 			break;
15522 		case Utils::Shader::GEOMETRY:
15523 			source = gs_tested;
15524 			array  = "[]";
15525 			index  = "[0]";
15526 			break;
15527 		case Utils::Shader::TESS_CTRL:
15528 			source = tcs_tested;
15529 			array  = "[]";
15530 			index  = "[gl_InvocationID]";
15531 			break;
15532 		case Utils::Shader::TESS_EVAL:
15533 			source = tes_tested;
15534 			array  = "[]";
15535 			index  = "[0]";
15536 			break;
15537 		case Utils::Shader::VERTEX:
15538 			source = vs_tested;
15539 			break;
15540 		default:
15541 			TCU_FAIL("Invalid enum");
15542 		}
15543 
15544 		temp = position;
15545 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
15546 		position = temp;
15547 		Utils::replaceToken("COMPONENT", position, buffer, source);
15548 		Utils::replaceToken("DIRECTION", position, direction, source);
15549 		Utils::replaceToken("ARRAY", position, array, source);
15550 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
15551 
15552 		Utils::replaceAllTokens("TYPE", type_name, source);
15553 		Utils::replaceAllTokens("INDEX", index, source);
15554 	}
15555 	else
15556 	{
15557 		switch (stage)
15558 		{
15559 		case Utils::Shader::FRAGMENT:
15560 			source = fs;
15561 			break;
15562 		case Utils::Shader::GEOMETRY:
15563 			source = gs;
15564 			break;
15565 		case Utils::Shader::TESS_CTRL:
15566 			source = tcs;
15567 			break;
15568 		case Utils::Shader::TESS_EVAL:
15569 			source = tes;
15570 			break;
15571 		case Utils::Shader::VERTEX:
15572 			source = vs;
15573 			break;
15574 		default:
15575 			TCU_FAIL("Invalid enum");
15576 		}
15577 	}
15578 
15579 	return source;
15580 }
15581 
15582 /** Get description of test case
15583  *
15584  * @param test_case_index Index of test case
15585  *
15586  * @return Test case description
15587  **/
15588 std::string VaryingExceedingComponentsTest::getTestCaseName(GLuint test_case_index)
15589 {
15590 	std::stringstream stream;
15591 	testCase&		  test_case = m_test_cases[test_case_index];
15592 
15593 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
15594 		   << " type: " << test_case.m_type.GetGLSLTypeName();
15595 
15596 	if (true == test_case.m_is_array)
15597 	{
15598 		stream << "[1]";
15599 	}
15600 
15601 	stream << ", direction: ";
15602 
15603 	if (true == test_case.m_is_input)
15604 	{
15605 		stream << "input";
15606 	}
15607 	else
15608 	{
15609 		stream << "output";
15610 	}
15611 
15612 	stream << ", component: " << test_case.m_component;
15613 
15614 	return stream.str();
15615 }
15616 
15617 /** Get number of test cases
15618  *
15619  * @return Number of test cases
15620  **/
15621 GLuint VaryingExceedingComponentsTest::getTestCaseNumber()
15622 {
15623 	return static_cast<GLuint>(m_test_cases.size());
15624 }
15625 
15626 /** Selects if "compute" stage is relevant for test
15627  *
15628  * @param ignored
15629  *
15630  * @return false
15631  **/
15632 bool VaryingExceedingComponentsTest::isComputeRelevant(GLuint /* test_case_index */)
15633 {
15634 	return false;
15635 }
15636 
15637 /** Prepare all test cases
15638  *
15639  **/
15640 void VaryingExceedingComponentsTest::testInit()
15641 {
15642 	static const GLuint n_components_per_location = 4;
15643 	const GLuint		n_types					  = getTypesNumber();
15644 
15645 	for (GLuint i = 0; i < n_types; ++i)
15646 	{
15647 		const Utils::Type& type				 = getType(i);
15648 		const GLuint	   n_req_components  = type.m_n_rows;
15649 		const GLuint	   valid_component   = n_components_per_location - n_req_components;
15650 		const GLuint	   invalid_component = valid_component + 1;
15651 
15652 		for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
15653 		{
15654 			if (Utils::Shader::COMPUTE == stage)
15655 			{
15656 				continue;
15657 			}
15658 
15659 			/* Component cannot be used for matrices */
15660 			if (1 != type.m_n_columns)
15661 			{
15662 				continue;
15663 			}
15664 
15665 			testCase test_case_in_arr  = { invalid_component, true, true, (Utils::Shader::STAGES)stage, type };
15666 			testCase test_case_in_one  = { invalid_component, true, false, (Utils::Shader::STAGES)stage, type };
15667 			testCase test_case_out_arr = { invalid_component, false, true, (Utils::Shader::STAGES)stage, type };
15668 			testCase test_case_out_one = { invalid_component, false, false, (Utils::Shader::STAGES)stage, type };
15669 
15670 			m_test_cases.push_back(test_case_in_arr);
15671 			m_test_cases.push_back(test_case_in_one);
15672 
15673 			if (Utils::Shader::FRAGMENT != stage)
15674 			{
15675 				m_test_cases.push_back(test_case_out_arr);
15676 				m_test_cases.push_back(test_case_out_one);
15677 			}
15678 		}
15679 	}
15680 }
15681 
15682 /** Constructor
15683  *
15684  * @param context Test framework context
15685  **/
15686 VaryingComponentWithoutLocationTest::VaryingComponentWithoutLocationTest(deqp::Context& context)
15687 	: NegativeTestBase(context, "varying_component_without_location",
15688 					   "Test verifies that compiler reports error when component qualifier is used without location")
15689 {
15690 }
15691 
15692 /** Source for given test case and stage
15693  *
15694  * @param test_case_index Index of test case
15695  * @param stage           Shader stage
15696  *
15697  * @return Shader source
15698  **/
15699 std::string VaryingComponentWithoutLocationTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
15700 {
15701 	static const GLchar* var_definition = "layout (component = COMPONENT) FLAT DIRECTION TYPE gokuARRAY;\n";
15702 	static const GLchar* input_use		= "    if (TYPE(0) == gokuINDEX)\n"
15703 									 "    {\n"
15704 									 "        result += vec4(1, 0.5, 0.25, 0.125);\n"
15705 									 "    }\n";
15706 	static const GLchar* output_use = "    gokuINDEX = TYPE(0);\n"
15707 									  "    if (vec4(0) == result)\n"
15708 									  "    {\n"
15709 									  "        gokuINDEX = TYPE(1);\n"
15710 									  "    }\n";
15711 	static const GLchar* fs = "#version 430 core\n"
15712 							  "#extension GL_ARB_enhanced_layouts : require\n"
15713 							  "\n"
15714 							  "in  vec4 gs_fs;\n"
15715 							  "out vec4 fs_out;\n"
15716 							  "\n"
15717 							  "void main()\n"
15718 							  "{\n"
15719 							  "    fs_out = gs_fs;\n"
15720 							  "}\n"
15721 							  "\n";
15722 	static const GLchar* fs_tested = "#version 430 core\n"
15723 									 "#extension GL_ARB_enhanced_layouts : require\n"
15724 									 "\n"
15725 									 "VAR_DEFINITION"
15726 									 "\n"
15727 									 "in  vec4 gs_fs;\n"
15728 									 "out vec4 fs_out;\n"
15729 									 "\n"
15730 									 "void main()\n"
15731 									 "{\n"
15732 									 "    vec4 result = gs_fs;\n"
15733 									 "\n"
15734 									 "VARIABLE_USE"
15735 									 "\n"
15736 									 "    fs_out = result;\n"
15737 									 "}\n"
15738 									 "\n";
15739 	static const GLchar* gs = "#version 430 core\n"
15740 							  "#extension GL_ARB_enhanced_layouts : require\n"
15741 							  "\n"
15742 							  "layout(points)                           in;\n"
15743 							  "layout(triangle_strip, max_vertices = 4) out;\n"
15744 							  "\n"
15745 							  "in  vec4 tes_gs[];\n"
15746 							  "out vec4 gs_fs;\n"
15747 							  "\n"
15748 							  "void main()\n"
15749 							  "{\n"
15750 							  "    gs_fs = tes_gs[0];\n"
15751 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
15752 							  "    EmitVertex();\n"
15753 							  "    gs_fs = tes_gs[0];\n"
15754 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
15755 							  "    EmitVertex();\n"
15756 							  "    gs_fs = tes_gs[0];\n"
15757 							  "    gl_Position  = vec4(1, -1, 0, 1);\n"
15758 							  "    EmitVertex();\n"
15759 							  "    gs_fs = tes_gs[0];\n"
15760 							  "    gl_Position  = vec4(1, 1, 0, 1);\n"
15761 							  "    EmitVertex();\n"
15762 							  "}\n"
15763 							  "\n";
15764 	static const GLchar* gs_tested = "#version 430 core\n"
15765 									 "#extension GL_ARB_enhanced_layouts : require\n"
15766 									 "\n"
15767 									 "layout(points)                           in;\n"
15768 									 "layout(triangle_strip, max_vertices = 4) out;\n"
15769 									 "\n"
15770 									 "VAR_DEFINITION"
15771 									 "\n"
15772 									 "in  vec4 tes_gs[];\n"
15773 									 "out vec4 gs_fs;\n"
15774 									 "\n"
15775 									 "void main()\n"
15776 									 "{\n"
15777 									 "    vec4 result = tes_gs[0];\n"
15778 									 "\n"
15779 									 "VARIABLE_USE"
15780 									 "\n"
15781 									 "    gs_fs = result;\n"
15782 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
15783 									 "    EmitVertex();\n"
15784 									 "    gs_fs = result;\n"
15785 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
15786 									 "    EmitVertex();\n"
15787 									 "    gs_fs = result;\n"
15788 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
15789 									 "    EmitVertex();\n"
15790 									 "    gs_fs = result;\n"
15791 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
15792 									 "    EmitVertex();\n"
15793 									 "}\n"
15794 									 "\n";
15795 	static const GLchar* tcs = "#version 430 core\n"
15796 							   "#extension GL_ARB_enhanced_layouts : require\n"
15797 							   "\n"
15798 							   "layout(vertices = 1) out;\n"
15799 							   "\n"
15800 							   "in  vec4 vs_tcs[];\n"
15801 							   "out vec4 tcs_tes[];\n"
15802 							   "\n"
15803 							   "void main()\n"
15804 							   "{\n"
15805 							   "\n"
15806 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
15807 							   "\n"
15808 							   "    gl_TessLevelOuter[0] = 1.0;\n"
15809 							   "    gl_TessLevelOuter[1] = 1.0;\n"
15810 							   "    gl_TessLevelOuter[2] = 1.0;\n"
15811 							   "    gl_TessLevelOuter[3] = 1.0;\n"
15812 							   "    gl_TessLevelInner[0] = 1.0;\n"
15813 							   "    gl_TessLevelInner[1] = 1.0;\n"
15814 							   "}\n"
15815 							   "\n";
15816 	static const GLchar* tcs_tested = "#version 430 core\n"
15817 									  "#extension GL_ARB_enhanced_layouts : require\n"
15818 									  "\n"
15819 									  "layout(vertices = 1) out;\n"
15820 									  "\n"
15821 									  "VAR_DEFINITION"
15822 									  "\n"
15823 									  "in  vec4 vs_tcs[];\n"
15824 									  "out vec4 tcs_tes[];\n"
15825 									  "\n"
15826 									  "void main()\n"
15827 									  "{\n"
15828 									  "    vec4 result = vs_tcs[gl_InvocationID];\n"
15829 									  "\n"
15830 									  "VARIABLE_USE"
15831 									  "\n"
15832 									  "    tcs_tes[gl_InvocationID] = result;\n"
15833 									  "\n"
15834 									  "    gl_TessLevelOuter[0] = 1.0;\n"
15835 									  "    gl_TessLevelOuter[1] = 1.0;\n"
15836 									  "    gl_TessLevelOuter[2] = 1.0;\n"
15837 									  "    gl_TessLevelOuter[3] = 1.0;\n"
15838 									  "    gl_TessLevelInner[0] = 1.0;\n"
15839 									  "    gl_TessLevelInner[1] = 1.0;\n"
15840 									  "}\n"
15841 									  "\n";
15842 	static const GLchar* tes = "#version 430 core\n"
15843 							   "#extension GL_ARB_enhanced_layouts : require\n"
15844 							   "\n"
15845 							   "layout(isolines, point_mode) in;\n"
15846 							   "\n"
15847 							   "in  vec4 tcs_tes[];\n"
15848 							   "out vec4 tes_gs;\n"
15849 							   "\n"
15850 							   "void main()\n"
15851 							   "{\n"
15852 							   "    tes_gs = tcs_tes[0];\n"
15853 							   "}\n"
15854 							   "\n";
15855 	static const GLchar* tes_tested = "#version 430 core\n"
15856 									  "#extension GL_ARB_enhanced_layouts : require\n"
15857 									  "\n"
15858 									  "layout(isolines, point_mode) in;\n"
15859 									  "\n"
15860 									  "VAR_DEFINITION"
15861 									  "\n"
15862 									  "in  vec4 tcs_tes[];\n"
15863 									  "out vec4 tes_gs;\n"
15864 									  "\n"
15865 									  "void main()\n"
15866 									  "{\n"
15867 									  "    vec4 result = tcs_tes[0];\n"
15868 									  "\n"
15869 									  "VARIABLE_USE"
15870 									  "\n"
15871 									  "    tes_gs = result;\n"
15872 									  "}\n"
15873 									  "\n";
15874 	static const GLchar* vs = "#version 430 core\n"
15875 							  "#extension GL_ARB_enhanced_layouts : require\n"
15876 							  "\n"
15877 							  "in  vec4 in_vs;\n"
15878 							  "out vec4 vs_tcs;\n"
15879 							  "\n"
15880 							  "void main()\n"
15881 							  "{\n"
15882 							  "    vs_tcs = in_vs;\n"
15883 							  "}\n"
15884 							  "\n";
15885 	static const GLchar* vs_tested = "#version 430 core\n"
15886 									 "#extension GL_ARB_enhanced_layouts : require\n"
15887 									 "\n"
15888 									 "VAR_DEFINITION"
15889 									 "\n"
15890 									 "in  vec4 in_vs;\n"
15891 									 "out vec4 vs_tcs;\n"
15892 									 "\n"
15893 									 "void main()\n"
15894 									 "{\n"
15895 									 "    vec4 result = in_vs;\n"
15896 									 "\n"
15897 									 "VARIABLE_USE"
15898 									 "\n"
15899 									 "    vs_tcs = result;\n"
15900 									 "}\n"
15901 									 "\n";
15902 
15903 	std::string source;
15904 	testCase&   test_case = m_test_cases[test_case_index];
15905 
15906 	if (test_case.m_stage == stage)
15907 	{
15908 		const GLchar* array = "";
15909 		GLchar		  buffer[16];
15910 		const GLchar* direction = "in ";
15911 		const GLchar* index		= "";
15912 		size_t		  position  = 0;
15913 		size_t		  temp;
15914 		const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
15915 		const GLchar* var_use   = input_use;
15916 		const GLchar* flat		= "flat";
15917 
15918 		if (false == test_case.m_is_input)
15919 		{
15920 			direction = "out";
15921 			var_use   = output_use;
15922 		}
15923 
15924 		sprintf(buffer, "%d", test_case.m_component);
15925 
15926 		switch (stage)
15927 		{
15928 		case Utils::Shader::FRAGMENT:
15929 			source = fs_tested;
15930 			break;
15931 		case Utils::Shader::GEOMETRY:
15932 			source = gs_tested;
15933 			array  = "[]";
15934 			index  = "[0]";
15935 			break;
15936 		case Utils::Shader::TESS_CTRL:
15937 			source = tcs_tested;
15938 			array  = "[]";
15939 			index  = "[gl_InvocationID]";
15940 			break;
15941 		case Utils::Shader::TESS_EVAL:
15942 			source = tes_tested;
15943 			array  = "[]";
15944 			index  = "[0]";
15945 			break;
15946 		case Utils::Shader::VERTEX:
15947 			source = vs_tested;
15948 			flat   = "";
15949 			break;
15950 		default:
15951 			TCU_FAIL("Invalid enum");
15952 		}
15953 
15954 		temp = position;
15955 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
15956 		position = temp;
15957 		Utils::replaceToken("COMPONENT", position, buffer, source);
15958 		Utils::replaceToken("FLAT", position, flat, source);
15959 		Utils::replaceToken("DIRECTION", position, direction, source);
15960 		Utils::replaceToken("ARRAY", position, array, source);
15961 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
15962 
15963 		Utils::replaceAllTokens("TYPE", type_name, source);
15964 		Utils::replaceAllTokens("INDEX", index, source);
15965 	}
15966 	else
15967 	{
15968 		switch (stage)
15969 		{
15970 		case Utils::Shader::FRAGMENT:
15971 			source = fs;
15972 			break;
15973 		case Utils::Shader::GEOMETRY:
15974 			source = gs;
15975 			break;
15976 		case Utils::Shader::TESS_CTRL:
15977 			source = tcs;
15978 			break;
15979 		case Utils::Shader::TESS_EVAL:
15980 			source = tes;
15981 			break;
15982 		case Utils::Shader::VERTEX:
15983 			source = vs;
15984 			break;
15985 		default:
15986 			TCU_FAIL("Invalid enum");
15987 		}
15988 	}
15989 
15990 	return source;
15991 }
15992 
15993 /** Get description of test case
15994  *
15995  * @param test_case_index Index of test case
15996  *
15997  * @return Test case description
15998  **/
15999 std::string VaryingComponentWithoutLocationTest::getTestCaseName(GLuint test_case_index)
16000 {
16001 	std::stringstream stream;
16002 	testCase&		  test_case = m_test_cases[test_case_index];
16003 
16004 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
16005 		   << " type: " << test_case.m_type.GetGLSLTypeName() << ", direction: ";
16006 
16007 	if (true == test_case.m_is_input)
16008 	{
16009 		stream << "input";
16010 	}
16011 	else
16012 	{
16013 		stream << "output";
16014 	}
16015 
16016 	stream << ", component: " << test_case.m_component;
16017 
16018 	return stream.str();
16019 }
16020 
16021 /** Get number of test cases
16022  *
16023  * @return Number of test cases
16024  **/
16025 GLuint VaryingComponentWithoutLocationTest::getTestCaseNumber()
16026 {
16027 	return static_cast<GLuint>(m_test_cases.size());
16028 }
16029 
16030 /** Selects if "compute" stage is relevant for test
16031  *
16032  * @param ignored
16033  *
16034  * @return false
16035  **/
16036 bool VaryingComponentWithoutLocationTest::isComputeRelevant(GLuint /* test_case_index */)
16037 {
16038 	return false;
16039 }
16040 
16041 /** Prepare all test cases
16042  *
16043  **/
16044 void VaryingComponentWithoutLocationTest::testInit()
16045 {
16046 	static const GLuint n_components_per_location = 4;
16047 	const GLuint		n_types					  = getTypesNumber();
16048 
16049 	for (GLuint i = 0; i < n_types; ++i)
16050 	{
16051 		const Utils::Type& type				= getType(i);
16052 		const GLuint	   n_req_components = type.m_n_rows;
16053 		const GLuint	   valid_component  = n_components_per_location - n_req_components;
16054 
16055 		for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
16056 		{
16057 			if (Utils::Shader::COMPUTE == stage)
16058 			{
16059 				continue;
16060 			}
16061 
16062 			/* Component cannot be used for matrices */
16063 			if (1 != type.m_n_columns)
16064 			{
16065 				continue;
16066 			}
16067 
16068 			testCase test_case_in  = { valid_component, true, (Utils::Shader::STAGES)stage, type };
16069 			testCase test_case_out = { valid_component, false, (Utils::Shader::STAGES)stage, type };
16070 
16071 			m_test_cases.push_back(test_case_in);
16072 
16073 			if (Utils::Shader::FRAGMENT != stage)
16074 			{
16075 				m_test_cases.push_back(test_case_out);
16076 			}
16077 		}
16078 	}
16079 }
16080 
16081 /** Constructor
16082  *
16083  * @param context Test framework context
16084  **/
16085 VaryingComponentOfInvalidTypeTest::VaryingComponentOfInvalidTypeTest(deqp::Context& context)
16086 	: NegativeTestBase(context, "varying_component_of_invalid_type",
16087 					   "Test verifies that compiler reports error when component qualifier is used for invalid type")
16088 {
16089 }
16090 
16091 /** Source for given test case and stage
16092  *
16093  * @param test_case_index Index of test case
16094  * @param stage           Shader stage
16095  *
16096  * @return Shader source
16097  **/
16098 std::string VaryingComponentOfInvalidTypeTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
16099 {
16100 	static const GLchar* block_definition_arr = "layout (location = 1, component = COMPONENT) flat DIRECTION Goku {\n"
16101 												"    TYPE member;\n"
16102 												"} gokuARRAY[1];\n";
16103 	static const GLchar* block_definition_one = "layout (location = 1, component = COMPONENT) flat DIRECTION Goku {\n"
16104 												"    TYPE member;\n"
16105 												"} gokuARRAY;\n";
16106 	static const GLchar* matrix_definition_arr =
16107 		"layout (location = 1, component = COMPONENT) flat DIRECTION TYPE gokuARRAY[1];\n";
16108 	static const GLchar* matrix_definition_one =
16109 		"layout (location = 1, component = COMPONENT) flat DIRECTION TYPE gokuARRAY;\n";
16110 	static const GLchar* struct_definition_arr =
16111 		"struct Goku {\n"
16112 		"    TYPE member;\n"
16113 		"};\n"
16114 		"\n"
16115 		"layout (location = 1, component = COMPONENT) flat DIRECTION Goku gokuARRAY[1];\n";
16116 	static const GLchar* struct_definition_one =
16117 		"struct Goku {\n"
16118 		"    TYPE member;\n"
16119 		"};\n"
16120 		"\n"
16121 		"layout (location = 1, component = COMPONENT) flat DIRECTION Goku gokuARRAY;\n";
16122 	static const GLchar* matrix_input_use_arr = "    if (TYPE(0) == gokuINDEX[0])\n"
16123 												"    {\n"
16124 												"        result += vec4(1, 0.5, 0.25, 0.125);\n"
16125 												"    }\n";
16126 	static const GLchar* matrix_input_use_one = "    if (TYPE(0) == gokuINDEX)\n"
16127 												"    {\n"
16128 												"        result += vec4(1, 0.5, 0.25, 0.125);\n"
16129 												"    }\n";
16130 	static const GLchar* matrix_output_use_arr = "    gokuINDEX[0] = TYPE(0);\n"
16131 												 "    if (vec4(0) == result)\n"
16132 												 "    {\n"
16133 												 "        gokuINDEX[0] = TYPE(1);\n"
16134 												 "    }\n";
16135 	static const GLchar* matrix_output_use_one = "    gokuINDEX = TYPE(0);\n"
16136 												 "    if (vec4(0) == result)\n"
16137 												 "    {\n"
16138 												 "        gokuINDEX = TYPE(1);\n"
16139 												 "    }\n";
16140 	static const GLchar* member_input_use_arr = "    if (TYPE(0) == gokuINDEX[0].member)\n"
16141 												"    {\n"
16142 												"        result += vec4(1, 0.5, 0.25, 0.125);\n"
16143 												"    }\n";
16144 	static const GLchar* member_input_use_one = "    if (TYPE(0) == gokuINDEX.member)\n"
16145 												"    {\n"
16146 												"        result += vec4(1, 0.5, 0.25, 0.125);\n"
16147 												"    }\n";
16148 	static const GLchar* member_output_use_arr = "    gokuINDEX[0].member = TYPE(0);\n"
16149 												 "    if (vec4(0) == result)\n"
16150 												 "    {\n"
16151 												 "        gokuINDEX[0].member = TYPE(1);\n"
16152 												 "    }\n";
16153 	static const GLchar* member_output_use_one = "    gokuINDEX.member = TYPE(0);\n"
16154 												 "    if (vec4(0) == result)\n"
16155 												 "    {\n"
16156 												 "        gokuINDEX.member = TYPE(1);\n"
16157 												 "    }\n";
16158 	static const GLchar* fs = "#version 430 core\n"
16159 							  "#extension GL_ARB_enhanced_layouts : require\n"
16160 							  "\n"
16161 							  "in  vec4 gs_fs;\n"
16162 							  "out vec4 fs_out;\n"
16163 							  "\n"
16164 							  "void main()\n"
16165 							  "{\n"
16166 							  "    fs_out = gs_fs;\n"
16167 							  "}\n"
16168 							  "\n";
16169 	static const GLchar* fs_tested = "#version 430 core\n"
16170 									 "#extension GL_ARB_enhanced_layouts : require\n"
16171 									 "\n"
16172 									 "VAR_DEFINITION"
16173 									 "\n"
16174 									 "in  vec4 gs_fs;\n"
16175 									 "out vec4 fs_out;\n"
16176 									 "\n"
16177 									 "void main()\n"
16178 									 "{\n"
16179 									 "    vec4 result = gs_fs;\n"
16180 									 "\n"
16181 									 "VARIABLE_USE"
16182 									 "\n"
16183 									 "    fs_out += result;\n"
16184 									 "}\n"
16185 									 "\n";
16186 	static const GLchar* gs = "#version 430 core\n"
16187 							  "#extension GL_ARB_enhanced_layouts : require\n"
16188 							  "\n"
16189 							  "layout(points)                           in;\n"
16190 							  "layout(triangle_strip, max_vertices = 4) out;\n"
16191 							  "\n"
16192 							  "in  vec4 tes_gs[];\n"
16193 							  "out vec4 gs_fs;\n"
16194 							  "\n"
16195 							  "void main()\n"
16196 							  "{\n"
16197 							  "    gs_fs = tes_gs[0];\n"
16198 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
16199 							  "    EmitVertex();\n"
16200 							  "    gs_fs = tes_gs[0];\n"
16201 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
16202 							  "    EmitVertex();\n"
16203 							  "    gs_fs = tes_gs[0];\n"
16204 							  "    gl_Position  = vec4(1, -1, 0, 1);\n"
16205 							  "    EmitVertex();\n"
16206 							  "    gs_fs = tes_gs[0];\n"
16207 							  "    gl_Position  = vec4(1, 1, 0, 1);\n"
16208 							  "    EmitVertex();\n"
16209 							  "}\n"
16210 							  "\n";
16211 	static const GLchar* gs_tested = "#version 430 core\n"
16212 									 "#extension GL_ARB_enhanced_layouts : require\n"
16213 									 "\n"
16214 									 "layout(points)                           in;\n"
16215 									 "layout(triangle_strip, max_vertices = 4) out;\n"
16216 									 "\n"
16217 									 "VAR_DEFINITION"
16218 									 "\n"
16219 									 "in  vec4 tes_gs[];\n"
16220 									 "out vec4 gs_fs;\n"
16221 									 "\n"
16222 									 "void main()\n"
16223 									 "{\n"
16224 									 "    vec4 result = tes_gs[0];\n"
16225 									 "\n"
16226 									 "VARIABLE_USE"
16227 									 "\n"
16228 									 "    gs_fs = result;\n"
16229 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
16230 									 "    EmitVertex();\n"
16231 									 "    gs_fs = result;\n"
16232 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
16233 									 "    EmitVertex();\n"
16234 									 "    gs_fs = result;\n"
16235 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
16236 									 "    EmitVertex();\n"
16237 									 "    gs_fs = result;\n"
16238 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
16239 									 "    EmitVertex();\n"
16240 									 "}\n"
16241 									 "\n";
16242 	static const GLchar* tcs = "#version 430 core\n"
16243 							   "#extension GL_ARB_enhanced_layouts : require\n"
16244 							   "\n"
16245 							   "layout(vertices = 1) out;\n"
16246 							   "\n"
16247 							   "in  vec4 vs_tcs[];\n"
16248 							   "out vec4 tcs_tes[];\n"
16249 							   "\n"
16250 							   "void main()\n"
16251 							   "{\n"
16252 							   "\n"
16253 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
16254 							   "\n"
16255 							   "    gl_TessLevelOuter[0] = 1.0;\n"
16256 							   "    gl_TessLevelOuter[1] = 1.0;\n"
16257 							   "    gl_TessLevelOuter[2] = 1.0;\n"
16258 							   "    gl_TessLevelOuter[3] = 1.0;\n"
16259 							   "    gl_TessLevelInner[0] = 1.0;\n"
16260 							   "    gl_TessLevelInner[1] = 1.0;\n"
16261 							   "}\n"
16262 							   "\n";
16263 	static const GLchar* tcs_tested = "#version 430 core\n"
16264 									  "#extension GL_ARB_enhanced_layouts : require\n"
16265 									  "\n"
16266 									  "layout(vertices = 1) out;\n"
16267 									  "\n"
16268 									  "VAR_DEFINITION"
16269 									  "\n"
16270 									  "in  vec4 vs_tcs[];\n"
16271 									  "out vec4 tcs_tes[];\n"
16272 									  "\n"
16273 									  "void main()\n"
16274 									  "{\n"
16275 									  "    vec4 result = vs_tcs[gl_InvocationID];\n"
16276 									  "\n"
16277 									  "VARIABLE_USE"
16278 									  "\n"
16279 									  "    tcs_tes[gl_InvocationID] = result;\n"
16280 									  "\n"
16281 									  "    gl_TessLevelOuter[0] = 1.0;\n"
16282 									  "    gl_TessLevelOuter[1] = 1.0;\n"
16283 									  "    gl_TessLevelOuter[2] = 1.0;\n"
16284 									  "    gl_TessLevelOuter[3] = 1.0;\n"
16285 									  "    gl_TessLevelInner[0] = 1.0;\n"
16286 									  "    gl_TessLevelInner[1] = 1.0;\n"
16287 									  "}\n"
16288 									  "\n";
16289 	static const GLchar* tes = "#version 430 core\n"
16290 							   "#extension GL_ARB_enhanced_layouts : require\n"
16291 							   "\n"
16292 							   "layout(isolines, point_mode) in;\n"
16293 							   "\n"
16294 							   "in  vec4 tcs_tes[];\n"
16295 							   "out vec4 tes_gs;\n"
16296 							   "\n"
16297 							   "void main()\n"
16298 							   "{\n"
16299 							   "    tes_gs = tcs_tes[0];\n"
16300 							   "}\n"
16301 							   "\n";
16302 	static const GLchar* tes_tested = "#version 430 core\n"
16303 									  "#extension GL_ARB_enhanced_layouts : require\n"
16304 									  "\n"
16305 									  "layout(isolines, point_mode) in;\n"
16306 									  "\n"
16307 									  "VAR_DEFINITION"
16308 									  "\n"
16309 									  "in  vec4 tcs_tes[];\n"
16310 									  "out vec4 tes_gs;\n"
16311 									  "\n"
16312 									  "void main()\n"
16313 									  "{\n"
16314 									  "    vec4 result = tcs_tes[0];\n"
16315 									  "\n"
16316 									  "VARIABLE_USE"
16317 									  "\n"
16318 									  "    tes_gs += result;\n"
16319 									  "}\n"
16320 									  "\n";
16321 	static const GLchar* vs = "#version 430 core\n"
16322 							  "#extension GL_ARB_enhanced_layouts : require\n"
16323 							  "\n"
16324 							  "in  vec4 in_vs;\n"
16325 							  "out vec4 vs_tcs;\n"
16326 							  "\n"
16327 							  "void main()\n"
16328 							  "{\n"
16329 							  "    vs_tcs = in_vs;\n"
16330 							  "}\n"
16331 							  "\n";
16332 	static const GLchar* vs_tested = "#version 430 core\n"
16333 									 "#extension GL_ARB_enhanced_layouts : require\n"
16334 									 "\n"
16335 									 "VAR_DEFINITION"
16336 									 "\n"
16337 									 "in  vec4 in_vs;\n"
16338 									 "out vec4 vs_tcs;\n"
16339 									 "\n"
16340 									 "void main()\n"
16341 									 "{\n"
16342 									 "    vec4 result = in_vs;\n"
16343 									 "\n"
16344 									 "VARIABLE_USE"
16345 									 "\n"
16346 									 "    vs_tcs += result;\n"
16347 									 "}\n"
16348 									 "\n";
16349 
16350 	std::string source;
16351 	testCase&   test_case = m_test_cases[test_case_index];
16352 
16353 	if (test_case.m_stage == stage)
16354 	{
16355 		const GLchar* array = "";
16356 		GLchar		  buffer[16];
16357 		const GLchar* var_definition = 0;
16358 		const GLchar* direction		 = "in ";
16359 		const GLchar* index			 = "";
16360 		size_t		  position		 = 0;
16361 		size_t		  temp;
16362 		const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
16363 		const GLchar* var_use   = 0;
16364 
16365 		if (false == test_case.m_is_input)
16366 		{
16367 			direction = "out";
16368 
16369 			if (false == test_case.m_is_array)
16370 			{
16371 				switch (test_case.m_case)
16372 				{
16373 				case BLOCK:
16374 					var_definition = block_definition_one;
16375 					var_use		   = member_output_use_one;
16376 					break;
16377 				case MATRIX:
16378 					var_definition = matrix_definition_one;
16379 					var_use		   = matrix_output_use_one;
16380 					break;
16381 				case STRUCT:
16382 					var_definition = struct_definition_one;
16383 					var_use		   = member_output_use_one;
16384 					break;
16385 				default:
16386 					TCU_FAIL("Invalid enum");
16387 				}
16388 			}
16389 			else
16390 			{
16391 				switch (test_case.m_case)
16392 				{
16393 				case BLOCK:
16394 					var_definition = block_definition_arr;
16395 					var_use		   = member_output_use_arr;
16396 					break;
16397 				case MATRIX:
16398 					var_definition = matrix_definition_arr;
16399 					var_use		   = matrix_output_use_arr;
16400 					break;
16401 				case STRUCT:
16402 					var_definition = struct_definition_arr;
16403 					var_use		   = member_output_use_arr;
16404 					break;
16405 				default:
16406 					TCU_FAIL("Invalid enum");
16407 				}
16408 			}
16409 		}
16410 		else
16411 		{
16412 			if (false == test_case.m_is_array)
16413 			{
16414 				switch (test_case.m_case)
16415 				{
16416 				case BLOCK:
16417 					var_definition = block_definition_one;
16418 					var_use		   = member_input_use_one;
16419 					break;
16420 				case MATRIX:
16421 					var_definition = matrix_definition_one;
16422 					var_use		   = matrix_input_use_one;
16423 					break;
16424 				case STRUCT:
16425 					var_definition = struct_definition_one;
16426 					var_use		   = member_input_use_one;
16427 					break;
16428 				default:
16429 					TCU_FAIL("Invalid enum");
16430 				}
16431 			}
16432 			else
16433 			{
16434 				switch (test_case.m_case)
16435 				{
16436 				case BLOCK:
16437 					var_definition = block_definition_arr;
16438 					var_use		   = member_input_use_arr;
16439 					break;
16440 				case MATRIX:
16441 					var_definition = matrix_definition_arr;
16442 					var_use		   = matrix_input_use_arr;
16443 					break;
16444 				case STRUCT:
16445 					var_definition = struct_definition_arr;
16446 					var_use		   = member_input_use_arr;
16447 					break;
16448 				default:
16449 					TCU_FAIL("Invalid enum");
16450 				}
16451 			}
16452 		}
16453 
16454 		sprintf(buffer, "%d", test_case.m_component);
16455 
16456 		switch (stage)
16457 		{
16458 		case Utils::Shader::FRAGMENT:
16459 			source = fs_tested;
16460 			break;
16461 		case Utils::Shader::GEOMETRY:
16462 			source = gs_tested;
16463 			array  = "[]";
16464 			index  = "[0]";
16465 			break;
16466 		case Utils::Shader::TESS_CTRL:
16467 			source = tcs_tested;
16468 			array  = "[]";
16469 			index  = "[gl_InvocationID]";
16470 			break;
16471 		case Utils::Shader::TESS_EVAL:
16472 			source = tes_tested;
16473 			array  = "[]";
16474 			index  = "[0]";
16475 			break;
16476 		case Utils::Shader::VERTEX:
16477 			source = vs_tested;
16478 			break;
16479 		default:
16480 			TCU_FAIL("Invalid enum");
16481 		}
16482 
16483 		temp = position;
16484 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
16485 		position = temp;
16486 		Utils::replaceToken("COMPONENT", position, buffer, source);
16487 		Utils::replaceToken("DIRECTION", position, direction, source);
16488 		Utils::replaceToken("ARRAY", position, array, source);
16489 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
16490 
16491 		Utils::replaceAllTokens("TYPE", type_name, source);
16492 		Utils::replaceAllTokens("INDEX", index, source);
16493 	}
16494 	else
16495 	{
16496 		switch (stage)
16497 		{
16498 		case Utils::Shader::FRAGMENT:
16499 			source = fs;
16500 			break;
16501 		case Utils::Shader::GEOMETRY:
16502 			source = gs;
16503 			break;
16504 		case Utils::Shader::TESS_CTRL:
16505 			source = tcs;
16506 			break;
16507 		case Utils::Shader::TESS_EVAL:
16508 			source = tes;
16509 			break;
16510 		case Utils::Shader::VERTEX:
16511 			source = vs;
16512 			break;
16513 		default:
16514 			TCU_FAIL("Invalid enum");
16515 		}
16516 	}
16517 
16518 	return source;
16519 }
16520 
16521 /** Get description of test case
16522  *
16523  * @param test_case_index Index of test case
16524  *
16525  * @return Test case description
16526  **/
16527 std::string VaryingComponentOfInvalidTypeTest::getTestCaseName(GLuint test_case_index)
16528 {
16529 	std::stringstream stream;
16530 	testCase&		  test_case = m_test_cases[test_case_index];
16531 
16532 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
16533 		   << " type: " << test_case.m_type.GetGLSLTypeName();
16534 
16535 	if (true == test_case.m_is_array)
16536 	{
16537 		stream << "[1]";
16538 	}
16539 
16540 	stream << ", direction: ";
16541 
16542 	if (true == test_case.m_is_input)
16543 	{
16544 		stream << "input";
16545 	}
16546 	else
16547 	{
16548 		stream << "output";
16549 	}
16550 
16551 	stream << ", component: " << test_case.m_component;
16552 
16553 	return stream.str();
16554 }
16555 
16556 /** Get number of test cases
16557  *
16558  * @return Number of test cases
16559  **/
16560 GLuint VaryingComponentOfInvalidTypeTest::getTestCaseNumber()
16561 {
16562 	return static_cast<GLuint>(m_test_cases.size());
16563 }
16564 
16565 /** Selects if "compute" stage is relevant for test
16566  *
16567  * @param ignored
16568  *
16569  * @return false
16570  **/
16571 bool VaryingComponentOfInvalidTypeTest::isComputeRelevant(GLuint /* test_case_index */)
16572 {
16573 	return false;
16574 }
16575 
16576 /** Prepare all test cases
16577  *
16578  **/
16579 void VaryingComponentOfInvalidTypeTest::testInit()
16580 {
16581 	static const GLuint n_components_per_location = 4;
16582 	const GLuint		n_types					  = getTypesNumber();
16583 
16584 	for (GLuint i = 0; i < n_types; ++i)
16585 	{
16586 		const Utils::Type& type				= getType(i);
16587 		const GLuint	   n_req_components = type.m_n_rows;
16588 		const GLuint	   valid_component  = n_components_per_location - n_req_components;
16589 
16590 		for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
16591 		{
16592 			if (Utils::Shader::COMPUTE == stage)
16593 			{
16594 				continue;
16595 			}
16596 
16597 			/* Use different CASE for matrices */
16598 			if (1 != type.m_n_columns)
16599 			{
16600 				testCase test_case_in_arr = { MATRIX, valid_component, true, true, (Utils::Shader::STAGES)stage, type };
16601 				testCase test_case_in_one = {
16602 					MATRIX, valid_component, false, true, (Utils::Shader::STAGES)stage, type
16603 				};
16604 				testCase test_case_out_arr = {
16605 					MATRIX, valid_component, true, false, (Utils::Shader::STAGES)stage, type
16606 				};
16607 				testCase test_case_out_one = {
16608 					MATRIX, valid_component, false, false, (Utils::Shader::STAGES)stage, type
16609 				};
16610 
16611 				m_test_cases.push_back(test_case_in_arr);
16612 				m_test_cases.push_back(test_case_in_one);
16613 
16614 				if (Utils::Shader::FRAGMENT != stage)
16615 				{
16616 					m_test_cases.push_back(test_case_out_arr);
16617 					m_test_cases.push_back(test_case_out_one);
16618 				}
16619 			}
16620 			else
16621 			{
16622 				for (GLuint c = BLOCK; c < MAX_CASES; ++c)
16623 				{
16624 					testCase test_case_in_arr = { (CASES)c, valid_component, true, true, (Utils::Shader::STAGES)stage,
16625 												  type };
16626 					testCase test_case_in_one = { (CASES)c, valid_component, false, true, (Utils::Shader::STAGES)stage,
16627 												  type };
16628 					testCase test_case_out_arr = { (CASES)c, valid_component, true, false, (Utils::Shader::STAGES)stage,
16629 												   type };
16630 					testCase test_case_out_one = {
16631 						(CASES)c, valid_component, false, false, (Utils::Shader::STAGES)stage, type
16632 					};
16633 
16634 					if (Utils::Shader::VERTEX != stage)
16635 					{
16636 						m_test_cases.push_back(test_case_in_arr);
16637 						m_test_cases.push_back(test_case_in_one);
16638 					}
16639 
16640 					if (Utils::Shader::FRAGMENT != stage)
16641 					{
16642 						m_test_cases.push_back(test_case_out_arr);
16643 						m_test_cases.push_back(test_case_out_one);
16644 					}
16645 				}
16646 			}
16647 		}
16648 	}
16649 }
16650 
16651 /** Constructor
16652  *
16653  * @param context Test framework context
16654  **/
16655 InputComponentAliasingTest::InputComponentAliasingTest(deqp::Context& context)
16656 	: NegativeTestBase(context, "input_component_aliasing",
16657 					   "Test verifies that compiler reports component aliasing as error")
16658 {
16659 }
16660 
16661 /** Source for given test case and stage
16662  *
16663  * @param test_case_index Index of test case
16664  * @param stage           Shader stage
16665  *
16666  * @return Shader source
16667  **/
16668 std::string InputComponentAliasingTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
16669 {
16670 	static const GLchar* var_definition = "layout (location = 1, component = COMPONENT) FLAT in TYPE gohanARRAY;\n"
16671 										  "layout (location = 1, component = COMPONENT) FLAT in TYPE gotenARRAY;\n";
16672 	static const GLchar* test_one = "    if (TYPE(0) == gohanINDEX)\n"
16673 									"    {\n"
16674 									"        result += vec4(1, 0.5, 0.25, 0.125);\n"
16675 									"    }\n";
16676 	static const GLchar* fs = "#version 430 core\n"
16677 							  "#extension GL_ARB_enhanced_layouts : require\n"
16678 							  "\n"
16679 							  "in  vec4 gs_fs;\n"
16680 							  "out vec4 fs_out;\n"
16681 							  "\n"
16682 							  "void main()\n"
16683 							  "{\n"
16684 							  "    fs_out = gs_fs;\n"
16685 							  "}\n"
16686 							  "\n";
16687 	static const GLchar* fs_tested = "#version 430 core\n"
16688 									 "#extension GL_ARB_enhanced_layouts : require\n"
16689 									 "\n"
16690 									 "VAR_DEFINITION"
16691 									 "\n"
16692 									 "in  vec4 gs_fs;\n"
16693 									 "out vec4 fs_out;\n"
16694 									 "\n"
16695 									 "void main()\n"
16696 									 "{\n"
16697 									 "    vec4 result = gs_fs;\n"
16698 									 "\n"
16699 									 "VARIABLE_USE"
16700 									 "\n"
16701 									 "    fs_out += result;\n"
16702 									 "}\n"
16703 									 "\n";
16704 	static const GLchar* gs = "#version 430 core\n"
16705 							  "#extension GL_ARB_enhanced_layouts : require\n"
16706 							  "\n"
16707 							  "layout(points)                           in;\n"
16708 							  "layout(triangle_strip, max_vertices = 4) out;\n"
16709 							  "\n"
16710 							  "in  vec4 tes_gs[];\n"
16711 							  "out vec4 gs_fs;\n"
16712 							  "\n"
16713 							  "void main()\n"
16714 							  "{\n"
16715 							  "    gs_fs = tes_gs[0];\n"
16716 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
16717 							  "    EmitVertex();\n"
16718 							  "    gs_fs = tes_gs[0];\n"
16719 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
16720 							  "    EmitVertex();\n"
16721 							  "    gs_fs = tes_gs[0];\n"
16722 							  "    gl_Position  = vec4(1, -1, 0, 1);\n"
16723 							  "    EmitVertex();\n"
16724 							  "    gs_fs = tes_gs[0];\n"
16725 							  "    gl_Position  = vec4(1, 1, 0, 1);\n"
16726 							  "    EmitVertex();\n"
16727 							  "}\n"
16728 							  "\n";
16729 	static const GLchar* gs_tested = "#version 430 core\n"
16730 									 "#extension GL_ARB_enhanced_layouts : require\n"
16731 									 "\n"
16732 									 "layout(points)                           in;\n"
16733 									 "layout(triangle_strip, max_vertices = 4) out;\n"
16734 									 "\n"
16735 									 "VAR_DEFINITION"
16736 									 "\n"
16737 									 "in  vec4 tes_gs[];\n"
16738 									 "out vec4 gs_fs;\n"
16739 									 "\n"
16740 									 "void main()\n"
16741 									 "{\n"
16742 									 "    vec4 result = tes_gs[0];\n"
16743 									 "\n"
16744 									 "VARIABLE_USE"
16745 									 "\n"
16746 									 "    gs_fs = result;\n"
16747 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
16748 									 "    EmitVertex();\n"
16749 									 "    gs_fs = result;\n"
16750 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
16751 									 "    EmitVertex();\n"
16752 									 "    gs_fs = result;\n"
16753 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
16754 									 "    EmitVertex();\n"
16755 									 "    gs_fs = result;\n"
16756 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
16757 									 "    EmitVertex();\n"
16758 									 "}\n"
16759 									 "\n";
16760 	static const GLchar* tcs = "#version 430 core\n"
16761 							   "#extension GL_ARB_enhanced_layouts : require\n"
16762 							   "\n"
16763 							   "layout(vertices = 1) out;\n"
16764 							   "\n"
16765 							   "in  vec4 vs_tcs[];\n"
16766 							   "out vec4 tcs_tes[];\n"
16767 							   "\n"
16768 							   "void main()\n"
16769 							   "{\n"
16770 							   "\n"
16771 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
16772 							   "\n"
16773 							   "    gl_TessLevelOuter[0] = 1.0;\n"
16774 							   "    gl_TessLevelOuter[1] = 1.0;\n"
16775 							   "    gl_TessLevelOuter[2] = 1.0;\n"
16776 							   "    gl_TessLevelOuter[3] = 1.0;\n"
16777 							   "    gl_TessLevelInner[0] = 1.0;\n"
16778 							   "    gl_TessLevelInner[1] = 1.0;\n"
16779 							   "}\n"
16780 							   "\n";
16781 	static const GLchar* tcs_tested = "#version 430 core\n"
16782 									  "#extension GL_ARB_enhanced_layouts : require\n"
16783 									  "\n"
16784 									  "layout(vertices = 1) out;\n"
16785 									  "\n"
16786 									  "VAR_DEFINITION"
16787 									  "\n"
16788 									  "in  vec4 vs_tcs[];\n"
16789 									  "out vec4 tcs_tes[];\n"
16790 									  "\n"
16791 									  "void main()\n"
16792 									  "{\n"
16793 									  "    vec4 result = vs_tcs[gl_InvocationID];\n"
16794 									  "\n"
16795 									  "VARIABLE_USE"
16796 									  "\n"
16797 									  "    tcs_tes[gl_InvocationID] = result;\n"
16798 									  "\n"
16799 									  "    gl_TessLevelOuter[0] = 1.0;\n"
16800 									  "    gl_TessLevelOuter[1] = 1.0;\n"
16801 									  "    gl_TessLevelOuter[2] = 1.0;\n"
16802 									  "    gl_TessLevelOuter[3] = 1.0;\n"
16803 									  "    gl_TessLevelInner[0] = 1.0;\n"
16804 									  "    gl_TessLevelInner[1] = 1.0;\n"
16805 									  "}\n"
16806 									  "\n";
16807 	static const GLchar* tes = "#version 430 core\n"
16808 							   "#extension GL_ARB_enhanced_layouts : require\n"
16809 							   "\n"
16810 							   "layout(isolines, point_mode) in;\n"
16811 							   "\n"
16812 							   "in  vec4 tcs_tes[];\n"
16813 							   "out vec4 tes_gs;\n"
16814 							   "\n"
16815 							   "void main()\n"
16816 							   "{\n"
16817 							   "    tes_gs = tcs_tes[0];\n"
16818 							   "}\n"
16819 							   "\n";
16820 	static const GLchar* tes_tested = "#version 430 core\n"
16821 									  "#extension GL_ARB_enhanced_layouts : require\n"
16822 									  "\n"
16823 									  "layout(isolines, point_mode) in;\n"
16824 									  "\n"
16825 									  "VAR_DEFINITION"
16826 									  "\n"
16827 									  "in  vec4 tcs_tes[];\n"
16828 									  "out vec4 tes_gs;\n"
16829 									  "\n"
16830 									  "void main()\n"
16831 									  "{\n"
16832 									  "    vec4 result = tcs_tes[0];\n"
16833 									  "\n"
16834 									  "VARIABLE_USE"
16835 									  "\n"
16836 									  "    tes_gs += result;\n"
16837 									  "}\n"
16838 									  "\n";
16839 	static const GLchar* vs = "#version 430 core\n"
16840 							  "#extension GL_ARB_enhanced_layouts : require\n"
16841 							  "\n"
16842 							  "in  vec4 in_vs;\n"
16843 							  "out vec4 vs_tcs;\n"
16844 							  "\n"
16845 							  "void main()\n"
16846 							  "{\n"
16847 							  "    vs_tcs = in_vs;\n"
16848 							  "}\n"
16849 							  "\n";
16850 	static const GLchar* vs_tested = "#version 430 core\n"
16851 									 "#extension GL_ARB_enhanced_layouts : require\n"
16852 									 "\n"
16853 									 "VAR_DEFINITION"
16854 									 "\n"
16855 									 "in  vec4 in_vs;\n"
16856 									 "out vec4 vs_tcs;\n"
16857 									 "\n"
16858 									 "void main()\n"
16859 									 "{\n"
16860 									 "    vec4 result = in_vs;\n"
16861 									 "\n"
16862 									 "VARIABLE_USE"
16863 									 "\n"
16864 									 "    vs_tcs += result;\n"
16865 									 "}\n"
16866 									 "\n";
16867 
16868 	std::string source;
16869 	testCase&   test_case = m_test_cases[test_case_index];
16870 
16871 	if (test_case.m_stage == stage)
16872 	{
16873 		const GLchar* array = "";
16874 		GLchar		  buffer_gohan[16];
16875 		GLchar		  buffer_goten[16];
16876 		const GLchar* flat		  = "";
16877 		const GLchar* index		  = "";
16878 		const bool	is_flat_req = isFlatRequired(stage, test_case.m_type, Utils::Variable::VARYING_INPUT);
16879 		size_t		  position	= 0;
16880 		size_t		  temp;
16881 		const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
16882 		const GLchar* var_use   = test_one;
16883 
16884 		if (true == is_flat_req)
16885 		{
16886 			flat = "flat";
16887 		}
16888 
16889 		sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
16890 		sprintf(buffer_goten, "%d", test_case.m_component_goten);
16891 
16892 		switch (stage)
16893 		{
16894 		case Utils::Shader::FRAGMENT:
16895 			source = fs_tested;
16896 			break;
16897 		case Utils::Shader::GEOMETRY:
16898 			source = gs_tested;
16899 			array  = "[]";
16900 			index  = "[0]";
16901 			break;
16902 		case Utils::Shader::TESS_CTRL:
16903 			source = tcs_tested;
16904 			array  = "[]";
16905 			index  = "[gl_InvocationID]";
16906 			break;
16907 		case Utils::Shader::TESS_EVAL:
16908 			source = tes_tested;
16909 			array  = "[]";
16910 			index  = "[0]";
16911 			break;
16912 		case Utils::Shader::VERTEX:
16913 			source = vs_tested;
16914 			break;
16915 		default:
16916 			TCU_FAIL("Invalid enum");
16917 		}
16918 
16919 		temp = position;
16920 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
16921 		position = temp;
16922 		Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
16923 		Utils::replaceToken("ARRAY", position, array, source);
16924 		Utils::replaceToken("COMPONENT", position, buffer_goten, source);
16925 		Utils::replaceToken("ARRAY", position, array, source);
16926 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
16927 
16928 		Utils::replaceAllTokens("FLAT", flat, source);
16929 		Utils::replaceAllTokens("TYPE", type_name, source);
16930 		Utils::replaceAllTokens("INDEX", index, source);
16931 	}
16932 	else
16933 	{
16934 		switch (stage)
16935 		{
16936 		case Utils::Shader::FRAGMENT:
16937 			source = fs;
16938 			break;
16939 		case Utils::Shader::GEOMETRY:
16940 			source = gs;
16941 			break;
16942 		case Utils::Shader::TESS_CTRL:
16943 			source = tcs;
16944 			break;
16945 		case Utils::Shader::TESS_EVAL:
16946 			source = tes;
16947 			break;
16948 		case Utils::Shader::VERTEX:
16949 			source = vs;
16950 			break;
16951 		default:
16952 			TCU_FAIL("Invalid enum");
16953 		}
16954 	}
16955 
16956 	return source;
16957 }
16958 
16959 /** Get description of test case
16960  *
16961  * @param test_case_index Index of test case
16962  *
16963  * @return Test case description
16964  **/
16965 std::string InputComponentAliasingTest::getTestCaseName(GLuint test_case_index)
16966 {
16967 	std::stringstream stream;
16968 	testCase&		  test_case = m_test_cases[test_case_index];
16969 
16970 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
16971 		   << " type: " << test_case.m_type.GetGLSLTypeName() << ", components: " << test_case.m_component_gohan
16972 		   << " & " << test_case.m_component_goten;
16973 
16974 	return stream.str();
16975 }
16976 
16977 /** Get number of test cases
16978  *
16979  * @return Number of test cases
16980  **/
16981 GLuint InputComponentAliasingTest::getTestCaseNumber()
16982 {
16983 	return static_cast<GLuint>(m_test_cases.size());
16984 }
16985 
16986 /** Selects if "compute" stage is relevant for test
16987  *
16988  * @param ignored
16989  *
16990  * @return false
16991  **/
16992 bool InputComponentAliasingTest::isComputeRelevant(GLuint /* test_case_index */)
16993 {
16994 	return false;
16995 }
16996 
16997 /** Selects if compilation failure is expected result
16998  *
16999  * @param test_case_index Index of test case
17000  *
17001  * @return false for VS that use only single variable, true otherwise
17002  **/
17003 bool InputComponentAliasingTest::isFailureExpected(GLuint test_case_index)
17004 {
17005 	testCase& test_case = m_test_cases[test_case_index];
17006 
17007 	return (Utils::Shader::VERTEX != test_case.m_stage);
17008 }
17009 
17010 /** Prepare all test cases
17011  *
17012  **/
17013 void InputComponentAliasingTest::testInit()
17014 {
17015 	const GLuint		n_types					  = getTypesNumber();
17016 
17017 	for (GLuint i = 0; i < n_types; ++i)
17018 	{
17019 		const Utils::Type& type						 = getType(i);
17020 		const bool		   use_double				 = (Utils::Type::Double == type.m_basic_type);
17021 		const GLuint	   n_components_per_location = use_double ? 2 : 4;
17022 		const GLuint	   n_req_components			 = type.m_n_rows;
17023 		const GLint		   valid_component			 = (GLint)n_components_per_location - (GLint)n_req_components;
17024 		const GLuint	   component_size			 = use_double ? 2 : 1;
17025 		/* Skip matrices */
17026 		if (1 != type.m_n_columns)
17027 		{
17028 			continue;
17029 		}
17030 		/* Skip dvec3/dvec4 which doesn't support the component qualifier */
17031 		if (valid_component < 0)
17032 		{
17033 			continue;
17034 		}
17035 
17036 		for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
17037 		{
17038 			if (Utils::Shader::COMPUTE == stage)
17039 			{
17040 				continue;
17041 			}
17042 
17043 			for (GLuint gohan = 0; gohan <= (GLuint)valid_component; ++gohan)
17044 			{
17045 				const GLint first_aliasing = gohan - n_req_components + 1;
17046 				const GLint last_aliasing  = gohan + n_req_components - 1;
17047 
17048 				const GLuint goten_start = std::max(0, first_aliasing);
17049 				const GLuint goten_stop  = std::min(valid_component, last_aliasing);
17050 
17051 				for (GLuint goten = goten_start; goten <= goten_stop; ++goten)
17052 				{
17053 					testCase test_case = { gohan * component_size, goten * component_size, (Utils::Shader::STAGES)stage,
17054 										   type };
17055 
17056 					m_test_cases.push_back(test_case);
17057 				}
17058 			}
17059 		}
17060 	}
17061 }
17062 
17063 /** Constructor
17064  *
17065  * @param context Test framework context
17066  **/
17067 OutputComponentAliasingTest::OutputComponentAliasingTest(deqp::Context& context)
17068 	: NegativeTestBase(context, "output_component_aliasing",
17069 					   "Test verifies that compiler reports component aliasing as error")
17070 {
17071 }
17072 
17073 /** Source for given test case and stage
17074  *
17075  * @param test_case_index Index of test case
17076  * @param stage           Shader stage
17077  *
17078  * @return Shader source
17079  **/
17080 std::string OutputComponentAliasingTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
17081 {
17082 	static const GLchar* var_definition = "layout (location = 1, component = COMPONENT) flat out TYPE gohanARRAY;\n"
17083 										  "layout (location = 1, component = COMPONENT) flat out TYPE gotenARRAY;\n";
17084 	static const GLchar* l_test = "    gohanINDEX = TYPE(1);\n"
17085 								  "    gotenINDEX = TYPE(0);\n";
17086 	static const GLchar* fs = "#version 430 core\n"
17087 							  "#extension GL_ARB_enhanced_layouts : require\n"
17088 							  "\n"
17089 							  "in  vec4 gs_fs;\n"
17090 							  "out vec4 fs_out;\n"
17091 							  "\n"
17092 							  "void main()\n"
17093 							  "{\n"
17094 							  "    fs_out = gs_fs;\n"
17095 							  "}\n"
17096 							  "\n";
17097 	static const GLchar* fs_tested = "#version 430 core\n"
17098 									 "#extension GL_ARB_enhanced_layouts : require\n"
17099 									 "\n"
17100 									 "VAR_DEFINITION"
17101 									 "\n"
17102 									 "in  vec4 gs_fs;\n"
17103 									 "out vec4 fs_out;\n"
17104 									 "\n"
17105 									 "void main()\n"
17106 									 "{\n"
17107 									 "    vec4 result = gs_fs;\n"
17108 									 "\n"
17109 									 "VARIABLE_USE"
17110 									 "\n"
17111 									 "    fs_out += result;\n"
17112 									 "}\n"
17113 									 "\n";
17114 	static const GLchar* gs = "#version 430 core\n"
17115 							  "#extension GL_ARB_enhanced_layouts : require\n"
17116 							  "\n"
17117 							  "layout(points)                           in;\n"
17118 							  "layout(triangle_strip, max_vertices = 4) out;\n"
17119 							  "\n"
17120 							  "in  vec4 tes_gs[];\n"
17121 							  "out vec4 gs_fs;\n"
17122 							  "\n"
17123 							  "void main()\n"
17124 							  "{\n"
17125 							  "    gs_fs = tes_gs[0];\n"
17126 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
17127 							  "    EmitVertex();\n"
17128 							  "    gs_fs = tes_gs[0];\n"
17129 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
17130 							  "    EmitVertex();\n"
17131 							  "    gs_fs = tes_gs[0];\n"
17132 							  "    gl_Position  = vec4(1, -1, 0, 1);\n"
17133 							  "    EmitVertex();\n"
17134 							  "    gs_fs = tes_gs[0];\n"
17135 							  "    gl_Position  = vec4(1, 1, 0, 1);\n"
17136 							  "    EmitVertex();\n"
17137 							  "}\n"
17138 							  "\n";
17139 	static const GLchar* gs_tested = "#version 430 core\n"
17140 									 "#extension GL_ARB_enhanced_layouts : require\n"
17141 									 "\n"
17142 									 "layout(points)                           in;\n"
17143 									 "layout(triangle_strip, max_vertices = 4) out;\n"
17144 									 "\n"
17145 									 "VAR_DEFINITION"
17146 									 "\n"
17147 									 "in  vec4 tes_gs[];\n"
17148 									 "out vec4 gs_fs;\n"
17149 									 "\n"
17150 									 "void main()\n"
17151 									 "{\n"
17152 									 "    vec4 result = tes_gs[0];\n"
17153 									 "\n"
17154 									 "VARIABLE_USE"
17155 									 "\n"
17156 									 "    gs_fs = result;\n"
17157 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
17158 									 "    EmitVertex();\n"
17159 									 "    gs_fs = result;\n"
17160 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
17161 									 "    EmitVertex();\n"
17162 									 "    gs_fs = result;\n"
17163 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
17164 									 "    EmitVertex();\n"
17165 									 "    gs_fs = result;\n"
17166 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
17167 									 "    EmitVertex();\n"
17168 									 "}\n"
17169 									 "\n";
17170 	static const GLchar* tcs = "#version 430 core\n"
17171 							   "#extension GL_ARB_enhanced_layouts : require\n"
17172 							   "\n"
17173 							   "layout(vertices = 1) out;\n"
17174 							   "\n"
17175 							   "in  vec4 vs_tcs[];\n"
17176 							   "out vec4 tcs_tes[];\n"
17177 							   "\n"
17178 							   "void main()\n"
17179 							   "{\n"
17180 							   "\n"
17181 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
17182 							   "\n"
17183 							   "    gl_TessLevelOuter[0] = 1.0;\n"
17184 							   "    gl_TessLevelOuter[1] = 1.0;\n"
17185 							   "    gl_TessLevelOuter[2] = 1.0;\n"
17186 							   "    gl_TessLevelOuter[3] = 1.0;\n"
17187 							   "    gl_TessLevelInner[0] = 1.0;\n"
17188 							   "    gl_TessLevelInner[1] = 1.0;\n"
17189 							   "}\n"
17190 							   "\n";
17191 	static const GLchar* tcs_tested = "#version 430 core\n"
17192 									  "#extension GL_ARB_enhanced_layouts : require\n"
17193 									  "\n"
17194 									  "layout(vertices = 1) out;\n"
17195 									  "\n"
17196 									  "VAR_DEFINITION"
17197 									  "\n"
17198 									  "in  vec4 vs_tcs[];\n"
17199 									  "out vec4 tcs_tes[];\n"
17200 									  "\n"
17201 									  "void main()\n"
17202 									  "{\n"
17203 									  "    vec4 result = vs_tcs[gl_InvocationID];\n"
17204 									  "\n"
17205 									  "VARIABLE_USE"
17206 									  "\n"
17207 									  "    tcs_tes[gl_InvocationID] = result;\n"
17208 									  "\n"
17209 									  "    gl_TessLevelOuter[0] = 1.0;\n"
17210 									  "    gl_TessLevelOuter[1] = 1.0;\n"
17211 									  "    gl_TessLevelOuter[2] = 1.0;\n"
17212 									  "    gl_TessLevelOuter[3] = 1.0;\n"
17213 									  "    gl_TessLevelInner[0] = 1.0;\n"
17214 									  "    gl_TessLevelInner[1] = 1.0;\n"
17215 									  "}\n"
17216 									  "\n";
17217 	static const GLchar* tes = "#version 430 core\n"
17218 							   "#extension GL_ARB_enhanced_layouts : require\n"
17219 							   "\n"
17220 							   "layout(isolines, point_mode) in;\n"
17221 							   "\n"
17222 							   "in  vec4 tcs_tes[];\n"
17223 							   "out vec4 tes_gs;\n"
17224 							   "\n"
17225 							   "void main()\n"
17226 							   "{\n"
17227 							   "    tes_gs = tcs_tes[0];\n"
17228 							   "}\n"
17229 							   "\n";
17230 	static const GLchar* tes_tested = "#version 430 core\n"
17231 									  "#extension GL_ARB_enhanced_layouts : require\n"
17232 									  "\n"
17233 									  "layout(isolines, point_mode) in;\n"
17234 									  "\n"
17235 									  "VAR_DEFINITION"
17236 									  "\n"
17237 									  "in  vec4 tcs_tes[];\n"
17238 									  "out vec4 tes_gs;\n"
17239 									  "\n"
17240 									  "void main()\n"
17241 									  "{\n"
17242 									  "    vec4 result = tcs_tes[0];\n"
17243 									  "\n"
17244 									  "VARIABLE_USE"
17245 									  "\n"
17246 									  "    tes_gs += result;\n"
17247 									  "}\n"
17248 									  "\n";
17249 	static const GLchar* vs = "#version 430 core\n"
17250 							  "#extension GL_ARB_enhanced_layouts : require\n"
17251 							  "\n"
17252 							  "in  vec4 in_vs;\n"
17253 							  "out vec4 vs_tcs;\n"
17254 							  "\n"
17255 							  "void main()\n"
17256 							  "{\n"
17257 							  "    vs_tcs = in_vs;\n"
17258 							  "}\n"
17259 							  "\n";
17260 	static const GLchar* vs_tested = "#version 430 core\n"
17261 									 "#extension GL_ARB_enhanced_layouts : require\n"
17262 									 "\n"
17263 									 "VAR_DEFINITION"
17264 									 "\n"
17265 									 "in  vec4 in_vs;\n"
17266 									 "out vec4 vs_tcs;\n"
17267 									 "\n"
17268 									 "void main()\n"
17269 									 "{\n"
17270 									 "    vec4 result = in_vs;\n"
17271 									 "\n"
17272 									 "VARIABLE_USE"
17273 									 "\n"
17274 									 "    vs_tcs += result;\n"
17275 									 "}\n"
17276 									 "\n";
17277 
17278 	std::string source;
17279 	testCase&   test_case = m_test_cases[test_case_index];
17280 
17281 	if (test_case.m_stage == stage)
17282 	{
17283 		const GLchar* array = "";
17284 		GLchar		  buffer_gohan[16];
17285 		GLchar		  buffer_goten[16];
17286 		const GLchar* index	= "";
17287 		size_t		  position = 0;
17288 		size_t		  temp;
17289 		const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
17290 
17291 		sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
17292 		sprintf(buffer_goten, "%d", test_case.m_component_goten);
17293 
17294 		switch (stage)
17295 		{
17296 		case Utils::Shader::FRAGMENT:
17297 			source = fs_tested;
17298 			break;
17299 		case Utils::Shader::GEOMETRY:
17300 			source = gs_tested;
17301 			array  = "[]";
17302 			index  = "[0]";
17303 			break;
17304 		case Utils::Shader::TESS_CTRL:
17305 			source = tcs_tested;
17306 			array  = "[]";
17307 			index  = "[gl_InvocationID]";
17308 			break;
17309 		case Utils::Shader::TESS_EVAL:
17310 			source = tes_tested;
17311 			array  = "[]";
17312 			index  = "[0]";
17313 			break;
17314 		case Utils::Shader::VERTEX:
17315 			source = vs_tested;
17316 			break;
17317 		default:
17318 			TCU_FAIL("Invalid enum");
17319 		}
17320 
17321 		temp = position;
17322 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
17323 		position = temp;
17324 		Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
17325 		Utils::replaceToken("ARRAY", position, array, source);
17326 		Utils::replaceToken("COMPONENT", position, buffer_goten, source);
17327 		Utils::replaceToken("ARRAY", position, array, source);
17328 		Utils::replaceToken("VARIABLE_USE", position, l_test, source);
17329 
17330 		Utils::replaceAllTokens("TYPE", type_name, source);
17331 		Utils::replaceAllTokens("INDEX", index, source);
17332 	}
17333 	else
17334 	{
17335 		switch (stage)
17336 		{
17337 		case Utils::Shader::FRAGMENT:
17338 			source = fs;
17339 			break;
17340 		case Utils::Shader::GEOMETRY:
17341 			source = gs;
17342 			break;
17343 		case Utils::Shader::TESS_CTRL:
17344 			source = tcs;
17345 			break;
17346 		case Utils::Shader::TESS_EVAL:
17347 			source = tes;
17348 			break;
17349 		case Utils::Shader::VERTEX:
17350 			source = vs;
17351 			break;
17352 		default:
17353 			TCU_FAIL("Invalid enum");
17354 		}
17355 	}
17356 
17357 	return source;
17358 }
17359 
17360 /** Get description of test case
17361  *
17362  * @param test_case_index Index of test case
17363  *
17364  * @return Test case description
17365  **/
17366 std::string OutputComponentAliasingTest::getTestCaseName(GLuint test_case_index)
17367 {
17368 	std::stringstream stream;
17369 	testCase&		  test_case = m_test_cases[test_case_index];
17370 
17371 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
17372 		   << " type: " << test_case.m_type.GetGLSLTypeName() << ", components: " << test_case.m_component_gohan
17373 		   << " & " << test_case.m_component_goten;
17374 
17375 	return stream.str();
17376 }
17377 
17378 /** Get number of test cases
17379  *
17380  * @return Number of test cases
17381  **/
17382 GLuint OutputComponentAliasingTest::getTestCaseNumber()
17383 {
17384 	return static_cast<GLuint>(m_test_cases.size());
17385 }
17386 
17387 /** Selects if "compute" stage is relevant for test
17388  *
17389  * @param ignored
17390  *
17391  * @return false
17392  **/
17393 bool OutputComponentAliasingTest::isComputeRelevant(GLuint /* test_case_index */)
17394 {
17395 	return false;
17396 }
17397 
17398 /** Prepare all test cases
17399  *
17400  **/
17401 void OutputComponentAliasingTest::testInit()
17402 {
17403 	static const GLuint n_components_per_location = 4;
17404 	const GLuint		n_types					  = getTypesNumber();
17405 
17406 	for (GLuint i = 0; i < n_types; ++i)
17407 	{
17408 		const Utils::Type& type				= getType(i);
17409 		const GLuint	   n_req_components = type.m_n_rows;
17410 		const GLuint	   valid_component  = n_components_per_location - n_req_components;
17411 
17412 		/* Skip matrices */
17413 		if (1 != type.m_n_columns)
17414 		{
17415 			continue;
17416 		}
17417 
17418 		for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
17419 		{
17420 			if (Utils::Shader::COMPUTE == stage)
17421 			{
17422 				continue;
17423 			}
17424 
17425 			if ((Utils::Shader::FRAGMENT == stage) && (Utils::Type::Double == type.m_basic_type))
17426 			{
17427 				continue;
17428 			}
17429 
17430 			for (GLuint gohan = 0; gohan <= valid_component; ++gohan)
17431 			{
17432 				const GLint first_aliasing = gohan - n_req_components + 1;
17433 				const GLint last_aliasing  = gohan + n_req_components - 1;
17434 
17435 				const GLuint goten_start = std::max(0, first_aliasing);
17436 				const GLuint goten_stop  = std::min((GLint)valid_component, last_aliasing);
17437 
17438 				for (GLuint goten = goten_start; goten <= goten_stop; ++goten)
17439 				{
17440 					testCase test_case = { gohan, goten, (Utils::Shader::STAGES)stage, type };
17441 
17442 					m_test_cases.push_back(test_case);
17443 				}
17444 			}
17445 		}
17446 	}
17447 }
17448 
17449 /** Constructor
17450  *
17451  * @param context Test framework context
17452  **/
17453 VaryingLocationAliasingWithMixedTypesTest::VaryingLocationAliasingWithMixedTypesTest(deqp::Context& context)
17454 	: NegativeTestBase(context, "varying_location_aliasing_with_mixed_types",
17455 					   "Test verifies that compiler reports error when float/int types are mixed at one location")
17456 {
17457 }
17458 
17459 /** Source for given test case and stage
17460  *
17461  * @param test_case_index Index of test case
17462  * @param stage           Shader stage
17463  *
17464  * @return Shader source
17465  **/
17466 std::string VaryingLocationAliasingWithMixedTypesTest::getShaderSource(GLuint				 test_case_index,
17467 																	   Utils::Shader::STAGES stage)
17468 {
17469 	static const GLchar* var_definition =
17470 		"layout (location = 1, component = COMPONENT) FLAT DIRECTION TYPE gohanARRAY;\n"
17471 		"layout (location = 1, component = COMPONENT) FLAT DIRECTION TYPE gotenARRAY;\n";
17472 	static const GLchar* input_use = "    if ((TYPE(0) == gohanINDEX) &&\n"
17473 									 "        (TYPE(1) == gotenINDEX) )\n"
17474 									 "    {\n"
17475 									 "        result += vec4(1, 0.5, 0.25, 0.125);\n"
17476 									 "    }\n";
17477 	static const GLchar* output_use = "    gohanINDEX = TYPE(0);\n"
17478 									  "    gotenINDEX = TYPE(1);\n"
17479 									  "    if (vec4(0) == result)\n"
17480 									  "    {\n"
17481 									  "        gohanINDEX = TYPE(1);\n"
17482 									  "        gotenINDEX = TYPE(0);\n"
17483 									  "    }\n";
17484 	static const GLchar* fs = "#version 430 core\n"
17485 							  "#extension GL_ARB_enhanced_layouts : require\n"
17486 							  "\n"
17487 							  "in  vec4 gs_fs;\n"
17488 							  "out vec4 fs_out;\n"
17489 							  "\n"
17490 							  "void main()\n"
17491 							  "{\n"
17492 							  "    fs_out = gs_fs;\n"
17493 							  "}\n"
17494 							  "\n";
17495 	static const GLchar* fs_tested = "#version 430 core\n"
17496 									 "#extension GL_ARB_enhanced_layouts : require\n"
17497 									 "\n"
17498 									 "VAR_DEFINITION"
17499 									 "\n"
17500 									 "in  vec4 gs_fs;\n"
17501 									 "out vec4 fs_out;\n"
17502 									 "\n"
17503 									 "void main()\n"
17504 									 "{\n"
17505 									 "    vec4 result = gs_fs;\n"
17506 									 "\n"
17507 									 "VARIABLE_USE"
17508 									 "\n"
17509 									 "    fs_out += result;\n"
17510 									 "}\n"
17511 									 "\n";
17512 	static const GLchar* gs = "#version 430 core\n"
17513 							  "#extension GL_ARB_enhanced_layouts : require\n"
17514 							  "\n"
17515 							  "layout(points)                           in;\n"
17516 							  "layout(triangle_strip, max_vertices = 4) out;\n"
17517 							  "\n"
17518 							  "in  vec4 tes_gs[];\n"
17519 							  "out vec4 gs_fs;\n"
17520 							  "\n"
17521 							  "void main()\n"
17522 							  "{\n"
17523 							  "    gs_fs = tes_gs[0];\n"
17524 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
17525 							  "    EmitVertex();\n"
17526 							  "    gs_fs = tes_gs[0];\n"
17527 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
17528 							  "    EmitVertex();\n"
17529 							  "    gs_fs = tes_gs[0];\n"
17530 							  "    gl_Position  = vec4(1, -1, 0, 1);\n"
17531 							  "    EmitVertex();\n"
17532 							  "    gs_fs = tes_gs[0];\n"
17533 							  "    gl_Position  = vec4(1, 1, 0, 1);\n"
17534 							  "    EmitVertex();\n"
17535 							  "}\n"
17536 							  "\n";
17537 	static const GLchar* gs_tested = "#version 430 core\n"
17538 									 "#extension GL_ARB_enhanced_layouts : require\n"
17539 									 "\n"
17540 									 "layout(points)                           in;\n"
17541 									 "layout(triangle_strip, max_vertices = 4) out;\n"
17542 									 "\n"
17543 									 "VAR_DEFINITION"
17544 									 "\n"
17545 									 "in  vec4 tes_gs[];\n"
17546 									 "out vec4 gs_fs;\n"
17547 									 "\n"
17548 									 "void main()\n"
17549 									 "{\n"
17550 									 "    vec4 result = tes_gs[0];\n"
17551 									 "\n"
17552 									 "VARIABLE_USE"
17553 									 "\n"
17554 									 "    gs_fs = result;\n"
17555 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
17556 									 "    EmitVertex();\n"
17557 									 "    gs_fs = result;\n"
17558 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
17559 									 "    EmitVertex();\n"
17560 									 "    gs_fs = result;\n"
17561 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
17562 									 "    EmitVertex();\n"
17563 									 "    gs_fs = result;\n"
17564 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
17565 									 "    EmitVertex();\n"
17566 									 "}\n"
17567 									 "\n";
17568 	static const GLchar* tcs = "#version 430 core\n"
17569 							   "#extension GL_ARB_enhanced_layouts : require\n"
17570 							   "\n"
17571 							   "layout(vertices = 1) out;\n"
17572 							   "\n"
17573 							   "in  vec4 vs_tcs[];\n"
17574 							   "out vec4 tcs_tes[];\n"
17575 							   "\n"
17576 							   "void main()\n"
17577 							   "{\n"
17578 							   "\n"
17579 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
17580 							   "\n"
17581 							   "    gl_TessLevelOuter[0] = 1.0;\n"
17582 							   "    gl_TessLevelOuter[1] = 1.0;\n"
17583 							   "    gl_TessLevelOuter[2] = 1.0;\n"
17584 							   "    gl_TessLevelOuter[3] = 1.0;\n"
17585 							   "    gl_TessLevelInner[0] = 1.0;\n"
17586 							   "    gl_TessLevelInner[1] = 1.0;\n"
17587 							   "}\n"
17588 							   "\n";
17589 	static const GLchar* tcs_tested = "#version 430 core\n"
17590 									  "#extension GL_ARB_enhanced_layouts : require\n"
17591 									  "\n"
17592 									  "layout(vertices = 1) out;\n"
17593 									  "\n"
17594 									  "VAR_DEFINITION"
17595 									  "\n"
17596 									  "in  vec4 vs_tcs[];\n"
17597 									  "out vec4 tcs_tes[];\n"
17598 									  "\n"
17599 									  "void main()\n"
17600 									  "{\n"
17601 									  "    vec4 result = vs_tcs[gl_InvocationID];\n"
17602 									  "\n"
17603 									  "VARIABLE_USE"
17604 									  "\n"
17605 									  "    tcs_tes[gl_InvocationID] = result;\n"
17606 									  "\n"
17607 									  "    gl_TessLevelOuter[0] = 1.0;\n"
17608 									  "    gl_TessLevelOuter[1] = 1.0;\n"
17609 									  "    gl_TessLevelOuter[2] = 1.0;\n"
17610 									  "    gl_TessLevelOuter[3] = 1.0;\n"
17611 									  "    gl_TessLevelInner[0] = 1.0;\n"
17612 									  "    gl_TessLevelInner[1] = 1.0;\n"
17613 									  "}\n"
17614 									  "\n";
17615 	static const GLchar* tes = "#version 430 core\n"
17616 							   "#extension GL_ARB_enhanced_layouts : require\n"
17617 							   "\n"
17618 							   "layout(isolines, point_mode) in;\n"
17619 							   "\n"
17620 							   "in  vec4 tcs_tes[];\n"
17621 							   "out vec4 tes_gs;\n"
17622 							   "\n"
17623 							   "void main()\n"
17624 							   "{\n"
17625 							   "    tes_gs = tcs_tes[0];\n"
17626 							   "}\n"
17627 							   "\n";
17628 	static const GLchar* tes_tested = "#version 430 core\n"
17629 									  "#extension GL_ARB_enhanced_layouts : require\n"
17630 									  "\n"
17631 									  "layout(isolines, point_mode) in;\n"
17632 									  "\n"
17633 									  "VAR_DEFINITION"
17634 									  "\n"
17635 									  "in  vec4 tcs_tes[];\n"
17636 									  "out vec4 tes_gs;\n"
17637 									  "\n"
17638 									  "void main()\n"
17639 									  "{\n"
17640 									  "    vec4 result = tcs_tes[0];\n"
17641 									  "\n"
17642 									  "VARIABLE_USE"
17643 									  "\n"
17644 									  "    tes_gs += result;\n"
17645 									  "}\n"
17646 									  "\n";
17647 	static const GLchar* vs = "#version 430 core\n"
17648 							  "#extension GL_ARB_enhanced_layouts : require\n"
17649 							  "\n"
17650 							  "in  vec4 in_vs;\n"
17651 							  "out vec4 vs_tcs;\n"
17652 							  "\n"
17653 							  "void main()\n"
17654 							  "{\n"
17655 							  "    vs_tcs = in_vs;\n"
17656 							  "}\n"
17657 							  "\n";
17658 	static const GLchar* vs_tested = "#version 430 core\n"
17659 									 "#extension GL_ARB_enhanced_layouts : require\n"
17660 									 "\n"
17661 									 "VAR_DEFINITION"
17662 									 "\n"
17663 									 "in  vec4 in_vs;\n"
17664 									 "out vec4 vs_tcs;\n"
17665 									 "\n"
17666 									 "void main()\n"
17667 									 "{\n"
17668 									 "    vec4 result = in_vs;\n"
17669 									 "\n"
17670 									 "VARIABLE_USE"
17671 									 "\n"
17672 									 "    vs_tcs += result;\n"
17673 									 "}\n"
17674 									 "\n";
17675 
17676 	std::string source;
17677 	testCase&   test_case = m_test_cases[test_case_index];
17678 
17679 	if (test_case.m_stage == stage)
17680 	{
17681 		const GLchar*			 array = "";
17682 		GLchar					 buffer_gohan[16];
17683 		GLchar					 buffer_goten[16];
17684 		const GLchar*			 direction  = "in ";
17685 		const GLchar*			 flat_gohan = "";
17686 		const GLchar*			 flat_goten = "";
17687 		const GLchar*			 index		= "";
17688 		size_t					 position   = 0;
17689 		size_t					 temp;
17690 		const GLchar*			 type_gohan_name = test_case.m_type_gohan.GetGLSLTypeName();
17691 		const GLchar*			 type_goten_name = test_case.m_type_goten.GetGLSLTypeName();
17692 		Utils::Variable::STORAGE storage		 = Utils::Variable::VARYING_INPUT;
17693 		const GLchar*			 var_use		 = input_use;
17694 
17695 		if (false == test_case.m_is_input)
17696 		{
17697 			direction = "out";
17698 			storage   = Utils::Variable::VARYING_OUTPUT;
17699 			var_use   = output_use;
17700 		}
17701 
17702 		if (true == isFlatRequired(stage, test_case.m_type_gohan, storage))
17703 		{
17704 			flat_gohan = "flat";
17705 		}
17706 
17707 		if (true == isFlatRequired(stage, test_case.m_type_goten, storage))
17708 		{
17709 			flat_goten = "flat";
17710 		}
17711 
17712 		sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
17713 		sprintf(buffer_goten, "%d", test_case.m_component_goten);
17714 
17715 		switch (stage)
17716 		{
17717 		case Utils::Shader::FRAGMENT:
17718 			source = fs_tested;
17719 			break;
17720 		case Utils::Shader::GEOMETRY:
17721 			source = gs_tested;
17722 			array  = "[]";
17723 			index  = "[0]";
17724 			break;
17725 		case Utils::Shader::TESS_CTRL:
17726 			source = tcs_tested;
17727 			array  = "[]";
17728 			index  = "[gl_InvocationID]";
17729 			break;
17730 		case Utils::Shader::TESS_EVAL:
17731 			source = tes_tested;
17732 			array  = "[]";
17733 			index  = "[0]";
17734 			break;
17735 		case Utils::Shader::VERTEX:
17736 			source = vs_tested;
17737 			break;
17738 		default:
17739 			TCU_FAIL("Invalid enum");
17740 		}
17741 
17742 		temp = position;
17743 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
17744 		position = temp;
17745 		Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
17746 		Utils::replaceToken("FLAT", position, flat_gohan, source);
17747 		Utils::replaceToken("DIRECTION", position, direction, source);
17748 		Utils::replaceToken("TYPE", position, type_gohan_name, source);
17749 		Utils::replaceToken("ARRAY", position, array, source);
17750 		Utils::replaceToken("COMPONENT", position, buffer_goten, source);
17751 		Utils::replaceToken("FLAT", position, flat_goten, source);
17752 		Utils::replaceToken("DIRECTION", position, direction, source);
17753 		Utils::replaceToken("TYPE", position, type_goten_name, source);
17754 		Utils::replaceToken("ARRAY", position, array, source);
17755 
17756 		temp = position;
17757 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
17758 		position = temp;
17759 		if (true == test_case.m_is_input)
17760 		{
17761 			Utils::replaceToken("TYPE", position, type_gohan_name, source);
17762 			Utils::replaceToken("TYPE", position, type_goten_name, source);
17763 		}
17764 		else
17765 		{
17766 			Utils::replaceToken("TYPE", position, type_gohan_name, source);
17767 			Utils::replaceToken("TYPE", position, type_goten_name, source);
17768 			Utils::replaceToken("TYPE", position, type_gohan_name, source);
17769 			Utils::replaceToken("TYPE", position, type_goten_name, source);
17770 		}
17771 
17772 		Utils::replaceAllTokens("INDEX", index, source);
17773 	}
17774 	else
17775 	{
17776 		switch (stage)
17777 		{
17778 		case Utils::Shader::FRAGMENT:
17779 			source = fs;
17780 			break;
17781 		case Utils::Shader::GEOMETRY:
17782 			source = gs;
17783 			break;
17784 		case Utils::Shader::TESS_CTRL:
17785 			source = tcs;
17786 			break;
17787 		case Utils::Shader::TESS_EVAL:
17788 			source = tes;
17789 			break;
17790 		case Utils::Shader::VERTEX:
17791 			source = vs;
17792 			break;
17793 		default:
17794 			TCU_FAIL("Invalid enum");
17795 		}
17796 	}
17797 
17798 	return source;
17799 }
17800 
17801 /** Get description of test case
17802  *
17803  * @param test_case_index Index of test case
17804  *
17805  * @return Test case description
17806  **/
17807 std::string VaryingLocationAliasingWithMixedTypesTest::getTestCaseName(GLuint test_case_index)
17808 {
17809 	std::stringstream stream;
17810 	testCase&		  test_case = m_test_cases[test_case_index];
17811 
17812 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", "
17813 		   << test_case.m_type_gohan.GetGLSLTypeName() << " at " << test_case.m_component_gohan << ", "
17814 		   << test_case.m_type_goten.GetGLSLTypeName() << " at " << test_case.m_component_goten << ". Direction: ";
17815 
17816 	if (true == test_case.m_is_input)
17817 	{
17818 		stream << "input";
17819 	}
17820 	else
17821 	{
17822 		stream << "output";
17823 	}
17824 
17825 	return stream.str();
17826 }
17827 
17828 /** Get number of test cases
17829  *
17830  * @return Number of test cases
17831  **/
17832 GLuint VaryingLocationAliasingWithMixedTypesTest::getTestCaseNumber()
17833 {
17834 	return static_cast<GLuint>(m_test_cases.size());
17835 }
17836 
17837 /** Selects if "compute" stage is relevant for test
17838  *
17839  * @param ignored
17840  *
17841  * @return false
17842  **/
17843 bool VaryingLocationAliasingWithMixedTypesTest::isComputeRelevant(GLuint /* test_case_index */)
17844 {
17845 	return false;
17846 }
17847 
17848 /** Prepare all test cases
17849  *
17850  **/
17851 void VaryingLocationAliasingWithMixedTypesTest::testInit()
17852 {
17853 	static const GLuint n_components_per_location = 4;
17854 	const GLuint		n_types					  = getTypesNumber();
17855 
17856 	for (GLuint i = 0; i < n_types; ++i)
17857 	{
17858 		const Utils::Type& type_gohan		   = getType(i);
17859 		const bool		   is_float_type_gohan = isFloatType(type_gohan);
17860 
17861 		/* Skip matrices */
17862 		if (1 != type_gohan.m_n_columns)
17863 		{
17864 			continue;
17865 		}
17866 
17867 		for (GLuint j = 0; j < n_types; ++j)
17868 		{
17869 			const Utils::Type& type_goten		   = getType(j);
17870 			const bool		   is_float_type_goten = isFloatType(type_goten);
17871 
17872 			/* Skip matrices */
17873 			if (1 != type_goten.m_n_columns)
17874 			{
17875 				continue;
17876 			}
17877 
17878 			/* Skip valid combinations */
17879 			if (is_float_type_gohan == is_float_type_goten)
17880 			{
17881 				continue;
17882 			}
17883 
17884 			const GLuint n_req_components_gohan = type_gohan.m_n_rows;
17885 			const GLuint n_req_components_goten = type_goten.m_n_rows;
17886 			const GLuint valid_component_gohan  = n_components_per_location - n_req_components_gohan;
17887 			const GLuint valid_component_goten  = n_components_per_location - n_req_components_goten;
17888 
17889 			/* Skip pairs that cannot fit into one location */
17890 			if (n_components_per_location < (n_req_components_gohan + n_req_components_goten))
17891 			{
17892 				continue;
17893 			}
17894 
17895 			for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
17896 			{
17897 				/* Skip compute shader */
17898 				if (Utils::Shader::COMPUTE == stage)
17899 				{
17900 					continue;
17901 				}
17902 
17903 				for (GLuint gohan = 0; gohan <= valid_component_gohan; ++gohan)
17904 				{
17905 					const GLint first_aliasing = gohan - n_req_components_goten + 1;
17906 					const GLint last_aliasing  = gohan + n_req_components_gohan - 1;
17907 
17908 					const GLuint goten_lower_limit = std::max(0, first_aliasing);
17909 					const GLuint goten_upper_limit = last_aliasing + 1;
17910 
17911 					/* Compoennets before gohan */
17912 					for (GLuint goten = 0; goten < goten_lower_limit; ++goten)
17913 					{
17914 						testCase test_case_in = { gohan,	  goten,	 true, (Utils::Shader::STAGES)stage,
17915 												  type_gohan, type_goten };
17916 						testCase test_case_out = { gohan,	  goten,	 false, (Utils::Shader::STAGES)stage,
17917 												   type_gohan, type_goten };
17918 
17919 						if (Utils::Shader::VERTEX != stage)
17920 							m_test_cases.push_back(test_case_in);
17921 
17922 						/* Skip double outputs in fragment shader */
17923 						if ((Utils::Shader::FRAGMENT != stage) || ((Utils::Type::Double != type_gohan.m_basic_type) &&
17924 																   (Utils::Type::Double != type_goten.m_basic_type)))
17925 						{
17926 							m_test_cases.push_back(test_case_out);
17927 						}
17928 					}
17929 
17930 					/* Components after gohan */
17931 					for (GLuint goten = goten_upper_limit; goten <= valid_component_goten; ++goten)
17932 					{
17933 						testCase test_case_in = { gohan,	  goten,	 true, (Utils::Shader::STAGES)stage,
17934 												  type_gohan, type_goten };
17935 						testCase test_case_out = { gohan,	  goten,	 false, (Utils::Shader::STAGES)stage,
17936 												   type_gohan, type_goten };
17937 
17938 						if (Utils::Shader::VERTEX != stage)
17939 							m_test_cases.push_back(test_case_in);
17940 
17941 						/* Skip double outputs in fragment shader */
17942 						if ((Utils::Shader::FRAGMENT != stage) || ((Utils::Type::Double != type_gohan.m_basic_type) &&
17943 																   (Utils::Type::Double != type_goten.m_basic_type)))
17944 						{
17945 							m_test_cases.push_back(test_case_out);
17946 						}
17947 					}
17948 				}
17949 			}
17950 		}
17951 	}
17952 }
17953 
17954 /** Check if given type is float
17955  *
17956  * @param type Type in question
17957  *
17958  * @return true if tpye is float, false otherwise
17959  **/
17960 bool VaryingLocationAliasingWithMixedTypesTest::isFloatType(const Utils::Type& type)
17961 {
17962 	bool is_float = false;
17963 
17964 	if ((Utils::Type::Double == type.m_basic_type) || (Utils::Type::Float == type.m_basic_type))
17965 	{
17966 		is_float = true;
17967 	}
17968 
17969 	return is_float;
17970 }
17971 
17972 /** Constructor
17973  *
17974  * @param context Test framework context
17975  **/
17976 VaryingLocationAliasingWithMixedInterpolationTest::VaryingLocationAliasingWithMixedInterpolationTest(
17977 	deqp::Context& context)
17978 	: NegativeTestBase(
17979 		  context, "varying_location_aliasing_with_mixed_interpolation",
17980 		  "Test verifies that compiler reports error when interpolation qualifiers are mixed at one location")
17981 {
17982 }
17983 
17984 /** Source for given test case and stage
17985  *
17986  * @param test_case_index Index of test case
17987  * @param stage           Shader stage
17988  *
17989  * @return Shader source
17990  **/
17991 std::string VaryingLocationAliasingWithMixedInterpolationTest::getShaderSource(GLuint				 test_case_index,
17992 																			   Utils::Shader::STAGES stage)
17993 {
17994 	static const GLchar* var_definition =
17995 		"layout (location = 1, component = COMPONENT) INTERPOLATION DIRECTION TYPE gohanARRAY;\n"
17996 		"layout (location = 1, component = COMPONENT) INTERPOLATION DIRECTION TYPE gotenARRAY;\n";
17997 	static const GLchar* input_use = "    if ((TYPE(0) == gohanINDEX) &&\n"
17998 									 "        (TYPE(1) == gotenINDEX) )\n"
17999 									 "    {\n"
18000 									 "        result += vec4(1, 0.5, 0.25, 0.125);\n"
18001 									 "    }\n";
18002 	static const GLchar* output_use = "    gohanINDEX = TYPE(0);\n"
18003 									  "    gotenINDEX = TYPE(1);\n"
18004 									  "    if (vec4(0) == result)\n"
18005 									  "    {\n"
18006 									  "        gohanINDEX = TYPE(1);\n"
18007 									  "        gotenINDEX = TYPE(0);\n"
18008 									  "    }\n";
18009 	static const GLchar* fs = "#version 430 core\n"
18010 							  "#extension GL_ARB_enhanced_layouts : require\n"
18011 							  "\n"
18012 							  "in  vec4 gs_fs;\n"
18013 							  "out vec4 fs_out;\n"
18014 							  "\n"
18015 							  "void main()\n"
18016 							  "{\n"
18017 							  "    fs_out = gs_fs;\n"
18018 							  "}\n"
18019 							  "\n";
18020 	static const GLchar* fs_tested = "#version 430 core\n"
18021 									 "#extension GL_ARB_enhanced_layouts : require\n"
18022 									 "\n"
18023 									 "VAR_DEFINITION"
18024 									 "\n"
18025 									 "in  vec4 gs_fs;\n"
18026 									 "out vec4 fs_out;\n"
18027 									 "\n"
18028 									 "void main()\n"
18029 									 "{\n"
18030 									 "    vec4 result = gs_fs;\n"
18031 									 "\n"
18032 									 "VARIABLE_USE"
18033 									 "\n"
18034 									 "    fs_out = result;\n"
18035 									 "}\n"
18036 									 "\n";
18037 	static const GLchar* gs = "#version 430 core\n"
18038 							  "#extension GL_ARB_enhanced_layouts : require\n"
18039 							  "\n"
18040 							  "layout(points)                           in;\n"
18041 							  "layout(triangle_strip, max_vertices = 4) out;\n"
18042 							  "\n"
18043 							  "in  vec4 tes_gs[];\n"
18044 							  "out vec4 gs_fs;\n"
18045 							  "\n"
18046 							  "void main()\n"
18047 							  "{\n"
18048 							  "    gs_fs = tes_gs[0];\n"
18049 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
18050 							  "    EmitVertex();\n"
18051 							  "    gs_fs = tes_gs[0];\n"
18052 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
18053 							  "    EmitVertex();\n"
18054 							  "    gs_fs = tes_gs[0];\n"
18055 							  "    gl_Position  = vec4(1, -1, 0, 1);\n"
18056 							  "    EmitVertex();\n"
18057 							  "    gs_fs = tes_gs[0];\n"
18058 							  "    gl_Position  = vec4(1, 1, 0, 1);\n"
18059 							  "    EmitVertex();\n"
18060 							  "}\n"
18061 							  "\n";
18062 	static const GLchar* gs_tested = "#version 430 core\n"
18063 									 "#extension GL_ARB_enhanced_layouts : require\n"
18064 									 "\n"
18065 									 "layout(points)                           in;\n"
18066 									 "layout(triangle_strip, max_vertices = 4) out;\n"
18067 									 "\n"
18068 									 "VAR_DEFINITION"
18069 									 "\n"
18070 									 "in  vec4 tes_gs[];\n"
18071 									 "out vec4 gs_fs;\n"
18072 									 "\n"
18073 									 "void main()\n"
18074 									 "{\n"
18075 									 "    vec4 result = tes_gs[0];\n"
18076 									 "\n"
18077 									 "VARIABLE_USE"
18078 									 "\n"
18079 									 "    gs_fs = result;\n"
18080 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
18081 									 "    EmitVertex();\n"
18082 									 "    gs_fs = result;\n"
18083 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
18084 									 "    EmitVertex();\n"
18085 									 "    gs_fs = result;\n"
18086 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
18087 									 "    EmitVertex();\n"
18088 									 "    gs_fs = result;\n"
18089 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
18090 									 "    EmitVertex();\n"
18091 									 "}\n"
18092 									 "\n";
18093 	static const GLchar* tcs = "#version 430 core\n"
18094 							   "#extension GL_ARB_enhanced_layouts : require\n"
18095 							   "\n"
18096 							   "layout(vertices = 1) out;\n"
18097 							   "\n"
18098 							   "in  vec4 vs_tcs[];\n"
18099 							   "out vec4 tcs_tes[];\n"
18100 							   "\n"
18101 							   "void main()\n"
18102 							   "{\n"
18103 							   "\n"
18104 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
18105 							   "\n"
18106 							   "    gl_TessLevelOuter[0] = 1.0;\n"
18107 							   "    gl_TessLevelOuter[1] = 1.0;\n"
18108 							   "    gl_TessLevelOuter[2] = 1.0;\n"
18109 							   "    gl_TessLevelOuter[3] = 1.0;\n"
18110 							   "    gl_TessLevelInner[0] = 1.0;\n"
18111 							   "    gl_TessLevelInner[1] = 1.0;\n"
18112 							   "}\n"
18113 							   "\n";
18114 	static const GLchar* tcs_tested = "#version 430 core\n"
18115 									  "#extension GL_ARB_enhanced_layouts : require\n"
18116 									  "\n"
18117 									  "layout(vertices = 1) out;\n"
18118 									  "\n"
18119 									  "VAR_DEFINITION"
18120 									  "\n"
18121 									  "in  vec4 vs_tcs[];\n"
18122 									  "out vec4 tcs_tes[];\n"
18123 									  "\n"
18124 									  "void main()\n"
18125 									  "{\n"
18126 									  "    vec4 result = vs_tcs[gl_InvocationID];\n"
18127 									  "\n"
18128 									  "VARIABLE_USE"
18129 									  "\n"
18130 									  "    tcs_tes[gl_InvocationID] = result;\n"
18131 									  "\n"
18132 									  "    gl_TessLevelOuter[0] = 1.0;\n"
18133 									  "    gl_TessLevelOuter[1] = 1.0;\n"
18134 									  "    gl_TessLevelOuter[2] = 1.0;\n"
18135 									  "    gl_TessLevelOuter[3] = 1.0;\n"
18136 									  "    gl_TessLevelInner[0] = 1.0;\n"
18137 									  "    gl_TessLevelInner[1] = 1.0;\n"
18138 									  "}\n"
18139 									  "\n";
18140 	static const GLchar* tes = "#version 430 core\n"
18141 							   "#extension GL_ARB_enhanced_layouts : require\n"
18142 							   "\n"
18143 							   "layout(isolines, point_mode) in;\n"
18144 							   "\n"
18145 							   "in  vec4 tcs_tes[];\n"
18146 							   "out vec4 tes_gs;\n"
18147 							   "\n"
18148 							   "void main()\n"
18149 							   "{\n"
18150 							   "    tes_gs = tcs_tes[0];\n"
18151 							   "}\n"
18152 							   "\n";
18153 	static const GLchar* tes_tested = "#version 430 core\n"
18154 									  "#extension GL_ARB_enhanced_layouts : require\n"
18155 									  "\n"
18156 									  "layout(isolines, point_mode) in;\n"
18157 									  "\n"
18158 									  "VAR_DEFINITION"
18159 									  "\n"
18160 									  "in  vec4 tcs_tes[];\n"
18161 									  "out vec4 tes_gs;\n"
18162 									  "\n"
18163 									  "void main()\n"
18164 									  "{\n"
18165 									  "    vec4 result = tcs_tes[0];\n"
18166 									  "\n"
18167 									  "VARIABLE_USE"
18168 									  "\n"
18169 									  "    tes_gs += result;\n"
18170 									  "}\n"
18171 									  "\n";
18172 	static const GLchar* vs = "#version 430 core\n"
18173 							  "#extension GL_ARB_enhanced_layouts : require\n"
18174 							  "\n"
18175 							  "in  vec4 in_vs;\n"
18176 							  "out vec4 vs_tcs;\n"
18177 							  "\n"
18178 							  "void main()\n"
18179 							  "{\n"
18180 							  "    vs_tcs = in_vs;\n"
18181 							  "}\n"
18182 							  "\n";
18183 	static const GLchar* vs_tested = "#version 430 core\n"
18184 									 "#extension GL_ARB_enhanced_layouts : require\n"
18185 									 "\n"
18186 									 "VAR_DEFINITION"
18187 									 "\n"
18188 									 "in  vec4 in_vs;\n"
18189 									 "out vec4 vs_tcs;\n"
18190 									 "\n"
18191 									 "void main()\n"
18192 									 "{\n"
18193 									 "    vec4 result = in_vs;\n"
18194 									 "\n"
18195 									 "VARIABLE_USE"
18196 									 "\n"
18197 									 "    vs_tcs += result;\n"
18198 									 "}\n"
18199 									 "\n";
18200 
18201 	std::string source;
18202 	testCase&   test_case = m_test_cases[test_case_index];
18203 
18204 	if (test_case.m_stage == stage)
18205 	{
18206 		const GLchar* array = "";
18207 		GLchar		  buffer_gohan[16];
18208 		GLchar		  buffer_goten[16];
18209 		const GLchar* direction = "in ";
18210 		const GLchar* index		= "";
18211 		const GLchar* int_gohan = getInterpolationQualifier(test_case.m_interpolation_gohan);
18212 		const GLchar* int_goten = getInterpolationQualifier(test_case.m_interpolation_goten);
18213 		size_t		  position  = 0;
18214 		size_t		  temp;
18215 		const GLchar* type_gohan_name = test_case.m_type_gohan.GetGLSLTypeName();
18216 		const GLchar* type_goten_name = test_case.m_type_goten.GetGLSLTypeName();
18217 		const GLchar* var_use		  = input_use;
18218 
18219 		if (false == test_case.m_is_input)
18220 		{
18221 			direction = "out";
18222 
18223 			var_use = output_use;
18224 		}
18225 
18226 		sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
18227 		sprintf(buffer_goten, "%d", test_case.m_component_goten);
18228 
18229 		switch (stage)
18230 		{
18231 		case Utils::Shader::FRAGMENT:
18232 			source = fs_tested;
18233 			break;
18234 		case Utils::Shader::GEOMETRY:
18235 			source = gs_tested;
18236 			array  = "[]";
18237 			index  = "[0]";
18238 			break;
18239 		case Utils::Shader::TESS_CTRL:
18240 			source = tcs_tested;
18241 			array  = "[]";
18242 			index  = "[gl_InvocationID]";
18243 			break;
18244 		case Utils::Shader::TESS_EVAL:
18245 			source = tes_tested;
18246 			array  = "[]";
18247 			index  = "[0]";
18248 			break;
18249 		case Utils::Shader::VERTEX:
18250 			source = vs_tested;
18251 			break;
18252 		default:
18253 			TCU_FAIL("Invalid enum");
18254 		}
18255 
18256 		temp = position;
18257 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
18258 		position = temp;
18259 		Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
18260 		Utils::replaceToken("INTERPOLATION", position, int_gohan, source);
18261 		Utils::replaceToken("DIRECTION", position, direction, source);
18262 		Utils::replaceToken("TYPE", position, type_gohan_name, source);
18263 		Utils::replaceToken("ARRAY", position, array, source);
18264 		Utils::replaceToken("COMPONENT", position, buffer_goten, source);
18265 		Utils::replaceToken("INTERPOLATION", position, int_goten, source);
18266 		Utils::replaceToken("DIRECTION", position, direction, source);
18267 		Utils::replaceToken("TYPE", position, type_goten_name, source);
18268 		Utils::replaceToken("ARRAY", position, array, source);
18269 
18270 		temp = position;
18271 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
18272 		position = temp;
18273 		if (true == test_case.m_is_input)
18274 		{
18275 			Utils::replaceToken("TYPE", position, type_gohan_name, source);
18276 			Utils::replaceToken("TYPE", position, type_goten_name, source);
18277 		}
18278 		else
18279 		{
18280 			Utils::replaceToken("TYPE", position, type_gohan_name, source);
18281 			Utils::replaceToken("TYPE", position, type_goten_name, source);
18282 			Utils::replaceToken("TYPE", position, type_gohan_name, source);
18283 			Utils::replaceToken("TYPE", position, type_goten_name, source);
18284 		}
18285 
18286 		Utils::replaceAllTokens("INDEX", index, source);
18287 	}
18288 	else
18289 	{
18290 		switch (stage)
18291 		{
18292 		case Utils::Shader::FRAGMENT:
18293 			source = fs;
18294 			break;
18295 		case Utils::Shader::GEOMETRY:
18296 			source = gs;
18297 			break;
18298 		case Utils::Shader::TESS_CTRL:
18299 			source = tcs;
18300 			break;
18301 		case Utils::Shader::TESS_EVAL:
18302 			source = tes;
18303 			break;
18304 		case Utils::Shader::VERTEX:
18305 			source = vs;
18306 			break;
18307 		default:
18308 			TCU_FAIL("Invalid enum");
18309 		}
18310 	}
18311 
18312 	return source;
18313 }
18314 
18315 /** Get description of test case
18316  *
18317  * @param test_case_index Index of test case
18318  *
18319  * @return Test case description
18320  **/
18321 std::string VaryingLocationAliasingWithMixedInterpolationTest::getTestCaseName(GLuint test_case_index)
18322 {
18323 	std::stringstream stream;
18324 	testCase&		  test_case = m_test_cases[test_case_index];
18325 
18326 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", "
18327 		   << getInterpolationQualifier(test_case.m_interpolation_gohan) << " "
18328 		   << test_case.m_type_gohan.GetGLSLTypeName() << " at " << test_case.m_component_gohan << ", "
18329 		   << getInterpolationQualifier(test_case.m_interpolation_goten) << " "
18330 		   << test_case.m_type_goten.GetGLSLTypeName() << " at " << test_case.m_component_goten << ". Direction: ";
18331 
18332 	if (true == test_case.m_is_input)
18333 	{
18334 		stream << "input";
18335 	}
18336 	else
18337 	{
18338 		stream << "output";
18339 	}
18340 
18341 	return stream.str();
18342 }
18343 
18344 /** Get number of test cases
18345  *
18346  * @return Number of test cases
18347  **/
18348 GLuint VaryingLocationAliasingWithMixedInterpolationTest::getTestCaseNumber()
18349 {
18350 	return static_cast<GLuint>(m_test_cases.size());
18351 }
18352 
18353 /** Selects if "compute" stage is relevant for test
18354  *
18355  * @param ignored
18356  *
18357  * @return false
18358  **/
18359 bool VaryingLocationAliasingWithMixedInterpolationTest::isComputeRelevant(GLuint /* test_case_index */)
18360 {
18361 	return false;
18362 }
18363 
18364 /** Prepare all test cases
18365  *
18366  **/
18367 void VaryingLocationAliasingWithMixedInterpolationTest::testInit()
18368 {
18369 	static const GLuint n_components_per_location = 4;
18370 	const GLuint		n_types					  = getTypesNumber();
18371 
18372 	for (GLuint i = 0; i < n_types; ++i)
18373 	{
18374 		const Utils::Type& type_gohan		   = getType(i);
18375 		const bool		   is_float_type_gohan = isFloatType(type_gohan);
18376 
18377 		/* Skip matrices */
18378 		if (1 != type_gohan.m_n_columns)
18379 		{
18380 			continue;
18381 		}
18382 
18383 		for (GLuint j = 0; j < n_types; ++j)
18384 		{
18385 			const Utils::Type& type_goten		   = getType(j);
18386 			const bool		   is_float_type_goten = isFloatType(type_goten);
18387 
18388 			/* Skip matrices */
18389 			if (1 != type_goten.m_n_columns)
18390 			{
18391 				continue;
18392 			}
18393 
18394 			/* Skip invalid combinations */
18395 			if (is_float_type_gohan != is_float_type_goten)
18396 			{
18397 				continue;
18398 			}
18399 
18400 			const GLuint n_req_components_gohan = type_gohan.m_n_rows;
18401 			const GLuint n_req_components_goten = type_goten.m_n_rows;
18402 
18403 			/* Skip pairs that cannot fit into one location */
18404 			if (n_components_per_location < (n_req_components_gohan + n_req_components_goten))
18405 			{
18406 				continue;
18407 			}
18408 
18409 			for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
18410 			{
18411 				/* Skip compute shader */
18412 				if (Utils::Shader::COMPUTE == stage)
18413 				{
18414 					continue;
18415 				}
18416 
18417 				const GLuint gohan = 0;
18418 				const GLuint goten = gohan + n_req_components_gohan;
18419 
18420 				for (GLuint int_gohan = 0; int_gohan < INTERPOLATION_MAX; ++int_gohan)
18421 				{
18422 					for (GLuint int_goten = 0; int_goten < INTERPOLATION_MAX; ++int_goten)
18423 					{
18424 						const bool is_gohan_double = (Utils::Type::Double == type_gohan.m_basic_type) ? true : false;
18425 						const bool is_goten_double = (Utils::Type::Double == type_goten.m_basic_type) ? true : false;
18426 						const bool is_gohan_flat   = (FLAT == int_gohan) ? true : false;
18427 						const bool is_goten_flat   = (FLAT == int_goten) ? true : false;
18428 						const bool is_gohan_accepted_as_fs_in =
18429 							(is_gohan_double && is_gohan_flat) || (!is_gohan_double);
18430 						const bool is_goten_accepted_as_fs_in =
18431 							(is_goten_double && is_goten_flat) || (!is_goten_double);
18432 						const bool is_comb_accepted_as_fs_in = is_gohan_accepted_as_fs_in && is_goten_accepted_as_fs_in;
18433 
18434 						/* Skip when both are the same */
18435 						if (int_gohan == int_goten)
18436 						{
18437 							continue;
18438 						}
18439 
18440 						testCase test_case_in = { gohan,
18441 												  goten,
18442 												  (INTERPOLATIONS)int_gohan,
18443 												  (INTERPOLATIONS)int_goten,
18444 												  true,
18445 												  (Utils::Shader::STAGES)stage,
18446 												  type_gohan,
18447 												  type_goten };
18448 
18449 						testCase test_case_out = { gohan,
18450 												   goten,
18451 												   (INTERPOLATIONS)int_gohan,
18452 												   (INTERPOLATIONS)int_goten,
18453 												   false,
18454 												   (Utils::Shader::STAGES)stage,
18455 												   type_gohan,
18456 												   type_goten };
18457 
18458 						/* Skip inputs in:
18459 						 * vertex shader,
18460 						 * fragment shader when not flat double is used
18461 						 */
18462 						if ((Utils::Shader::VERTEX != stage) &&
18463 							((Utils::Shader::FRAGMENT != stage) || (true == is_comb_accepted_as_fs_in)))
18464 						{
18465 							m_test_cases.push_back(test_case_in);
18466 						}
18467 
18468 						/* Skip outputs in fragment shader */
18469 						if (Utils::Shader::FRAGMENT != stage)
18470 						{
18471 							m_test_cases.push_back(test_case_out);
18472 						}
18473 					}
18474 				}
18475 			}
18476 		}
18477 	}
18478 }
18479 
18480 /** Get interpolation qualifier
18481  *
18482  * @param interpolation Enumeration
18483  *
18484  * @return GLSL qualifier
18485  **/
18486 const GLchar* VaryingLocationAliasingWithMixedInterpolationTest::getInterpolationQualifier(INTERPOLATIONS interpolation)
18487 {
18488 	const GLchar* result = 0;
18489 
18490 	switch (interpolation)
18491 	{
18492 	case SMOOTH:
18493 		result = "smooth";
18494 		break;
18495 	case FLAT:
18496 		result = "flat";
18497 		break;
18498 	case NO_PERSPECTIVE:
18499 		result = "noperspective";
18500 		break;
18501 	default:
18502 		TCU_FAIL("Invalid enum");
18503 	}
18504 
18505 	return result;
18506 }
18507 
18508 /** Check if given type is float
18509  *
18510  * @param type Type in question
18511  *
18512  * @return true if tpye is float, false otherwise
18513  **/
18514 bool VaryingLocationAliasingWithMixedInterpolationTest::isFloatType(const Utils::Type& type)
18515 {
18516 	bool is_float = false;
18517 
18518 	if ((Utils::Type::Double == type.m_basic_type) || (Utils::Type::Float == type.m_basic_type))
18519 	{
18520 		is_float = true;
18521 	}
18522 
18523 	return is_float;
18524 }
18525 
18526 /** Constructor
18527  *
18528  * @param context Test framework context
18529  **/
18530 VaryingLocationAliasingWithMixedAuxiliaryStorageTest::VaryingLocationAliasingWithMixedAuxiliaryStorageTest(
18531 	deqp::Context& context)
18532 	: NegativeTestBase(
18533 		  context, "varying_location_aliasing_with_mixed_auxiliary_storage",
18534 		  "Test verifies that compiler reports error when auxiliary storage qualifiers are mixed at one location")
18535 {
18536 }
18537 
18538 /** Source for given test case and stage
18539  *
18540  * @param test_case_index Index of test case
18541  * @param stage           Shader stage
18542  *
18543  * @return Shader source
18544  **/
18545 std::string VaryingLocationAliasingWithMixedAuxiliaryStorageTest::getShaderSource(GLuint				test_case_index,
18546 																				  Utils::Shader::STAGES stage)
18547 {
18548 	static const GLchar* var_definition =
18549 		"layout (location = 1, component = COMPONENT) AUX INTERPOLATION DIRECTION TYPE gohanARRAY;\n"
18550 		"layout (location = 1, component = COMPONENT) AUX INTERPOLATION DIRECTION TYPE gotenARRAY;\n";
18551 	static const GLchar* input_use = "    if ((TYPE(0) == gohanINDEX_GOHAN) &&\n"
18552 									 "        (TYPE(1) == gotenINDEX_GOTEN) )\n"
18553 									 "    {\n"
18554 									 "        result += vec4(1, 0.5, 0.25, 0.125);\n"
18555 									 "    }\n";
18556 	static const GLchar* output_use = "    gohanINDEX_GOHAN = TYPE(0);\n"
18557 									  "    gotenINDEX_GOTEN = TYPE(1);\n"
18558 									  "    if (vec4(0) == result)\n"
18559 									  "    {\n"
18560 									  "        gohanINDEX_GOHAN = TYPE(1);\n"
18561 									  "        gotenINDEX_GOTEN = TYPE(0);\n"
18562 									  "    }\n";
18563 	static const GLchar* fs = "#version 430 core\n"
18564 							  "#extension GL_ARB_enhanced_layouts : require\n"
18565 							  "\n"
18566 							  "in  vec4 gs_fs;\n"
18567 							  "out vec4 fs_out;\n"
18568 							  "\n"
18569 							  "void main()\n"
18570 							  "{\n"
18571 							  "    fs_out = gs_fs;\n"
18572 							  "}\n"
18573 							  "\n";
18574 	static const GLchar* fs_tested = "#version 430 core\n"
18575 									 "#extension GL_ARB_enhanced_layouts : require\n"
18576 									 "\n"
18577 									 "VAR_DEFINITION"
18578 									 "\n"
18579 									 "in  vec4 gs_fs;\n"
18580 									 "out vec4 fs_out;\n"
18581 									 "\n"
18582 									 "void main()\n"
18583 									 "{\n"
18584 									 "    vec4 result = gs_fs;\n"
18585 									 "\n"
18586 									 "VARIABLE_USE"
18587 									 "\n"
18588 									 "    fs_out = result;\n"
18589 									 "}\n"
18590 									 "\n";
18591 	static const GLchar* gs = "#version 430 core\n"
18592 							  "#extension GL_ARB_enhanced_layouts : require\n"
18593 							  "\n"
18594 							  "layout(points)                           in;\n"
18595 							  "layout(triangle_strip, max_vertices = 4) out;\n"
18596 							  "\n"
18597 							  "in  vec4 tes_gs[];\n"
18598 							  "out vec4 gs_fs;\n"
18599 							  "\n"
18600 							  "void main()\n"
18601 							  "{\n"
18602 							  "    gs_fs = tes_gs[0];\n"
18603 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
18604 							  "    EmitVertex();\n"
18605 							  "    gs_fs = tes_gs[0];\n"
18606 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
18607 							  "    EmitVertex();\n"
18608 							  "    gs_fs = tes_gs[0];\n"
18609 							  "    gl_Position  = vec4(1, -1, 0, 1);\n"
18610 							  "    EmitVertex();\n"
18611 							  "    gs_fs = tes_gs[0];\n"
18612 							  "    gl_Position  = vec4(1, 1, 0, 1);\n"
18613 							  "    EmitVertex();\n"
18614 							  "}\n"
18615 							  "\n";
18616 	static const GLchar* gs_tested = "#version 430 core\n"
18617 									 "#extension GL_ARB_enhanced_layouts : require\n"
18618 									 "\n"
18619 									 "layout(points)                           in;\n"
18620 									 "layout(triangle_strip, max_vertices = 4) out;\n"
18621 									 "\n"
18622 									 "VAR_DEFINITION"
18623 									 "\n"
18624 									 "in  vec4 tes_gs[];\n"
18625 									 "out vec4 gs_fs;\n"
18626 									 "\n"
18627 									 "void main()\n"
18628 									 "{\n"
18629 									 "    vec4 result = tes_gs[0];\n"
18630 									 "\n"
18631 									 "VARIABLE_USE"
18632 									 "\n"
18633 									 "    gs_fs = result;\n"
18634 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
18635 									 "    EmitVertex();\n"
18636 									 "    gs_fs = result;\n"
18637 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
18638 									 "    EmitVertex();\n"
18639 									 "    gs_fs = result;\n"
18640 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
18641 									 "    EmitVertex();\n"
18642 									 "    gs_fs = result;\n"
18643 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
18644 									 "    EmitVertex();\n"
18645 									 "}\n"
18646 									 "\n";
18647 	static const GLchar* tcs = "#version 430 core\n"
18648 							   "#extension GL_ARB_enhanced_layouts : require\n"
18649 							   "\n"
18650 							   "layout(vertices = 1) out;\n"
18651 							   "\n"
18652 							   "in  vec4 vs_tcs[];\n"
18653 							   "out vec4 tcs_tes[];\n"
18654 							   "\n"
18655 							   "void main()\n"
18656 							   "{\n"
18657 							   "\n"
18658 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
18659 							   "\n"
18660 							   "    gl_TessLevelOuter[0] = 1.0;\n"
18661 							   "    gl_TessLevelOuter[1] = 1.0;\n"
18662 							   "    gl_TessLevelOuter[2] = 1.0;\n"
18663 							   "    gl_TessLevelOuter[3] = 1.0;\n"
18664 							   "    gl_TessLevelInner[0] = 1.0;\n"
18665 							   "    gl_TessLevelInner[1] = 1.0;\n"
18666 							   "}\n"
18667 							   "\n";
18668 	static const GLchar* tcs_tested = "#version 430 core\n"
18669 									  "#extension GL_ARB_enhanced_layouts : require\n"
18670 									  "\n"
18671 									  "layout(vertices = 1) out;\n"
18672 									  "\n"
18673 									  "VAR_DEFINITION"
18674 									  "\n"
18675 									  "in  vec4 vs_tcs[];\n"
18676 									  "out vec4 tcs_tes[];\n"
18677 									  "\n"
18678 									  "void main()\n"
18679 									  "{\n"
18680 									  "    vec4 result = vs_tcs[gl_InvocationID];\n"
18681 									  "\n"
18682 									  "VARIABLE_USE"
18683 									  "\n"
18684 									  "    tcs_tes[gl_InvocationID] = result;\n"
18685 									  "\n"
18686 									  "    gl_TessLevelOuter[0] = 1.0;\n"
18687 									  "    gl_TessLevelOuter[1] = 1.0;\n"
18688 									  "    gl_TessLevelOuter[2] = 1.0;\n"
18689 									  "    gl_TessLevelOuter[3] = 1.0;\n"
18690 									  "    gl_TessLevelInner[0] = 1.0;\n"
18691 									  "    gl_TessLevelInner[1] = 1.0;\n"
18692 									  "}\n"
18693 									  "\n";
18694 	static const GLchar* tes = "#version 430 core\n"
18695 							   "#extension GL_ARB_enhanced_layouts : require\n"
18696 							   "\n"
18697 							   "layout(isolines, point_mode) in;\n"
18698 							   "\n"
18699 							   "in  vec4 tcs_tes[];\n"
18700 							   "out vec4 tes_gs;\n"
18701 							   "\n"
18702 							   "void main()\n"
18703 							   "{\n"
18704 							   "    tes_gs = tcs_tes[0];\n"
18705 							   "}\n"
18706 							   "\n";
18707 	static const GLchar* tes_tested = "#version 430 core\n"
18708 									  "#extension GL_ARB_enhanced_layouts : require\n"
18709 									  "\n"
18710 									  "layout(isolines, point_mode) in;\n"
18711 									  "\n"
18712 									  "VAR_DEFINITION"
18713 									  "\n"
18714 									  "in  vec4 tcs_tes[];\n"
18715 									  "out vec4 tes_gs;\n"
18716 									  "\n"
18717 									  "void main()\n"
18718 									  "{\n"
18719 									  "    vec4 result = tcs_tes[0];\n"
18720 									  "\n"
18721 									  "VARIABLE_USE"
18722 									  "\n"
18723 									  "    tes_gs += result;\n"
18724 									  "}\n"
18725 									  "\n";
18726 	static const GLchar* vs = "#version 430 core\n"
18727 							  "#extension GL_ARB_enhanced_layouts : require\n"
18728 							  "\n"
18729 							  "in  vec4 in_vs;\n"
18730 							  "out vec4 vs_tcs;\n"
18731 							  "\n"
18732 							  "void main()\n"
18733 							  "{\n"
18734 							  "    vs_tcs = in_vs;\n"
18735 							  "}\n"
18736 							  "\n";
18737 	static const GLchar* vs_tested = "#version 430 core\n"
18738 									 "#extension GL_ARB_enhanced_layouts : require\n"
18739 									 "\n"
18740 									 "VAR_DEFINITION"
18741 									 "\n"
18742 									 "in  vec4 in_vs;\n"
18743 									 "out vec4 vs_tcs;\n"
18744 									 "\n"
18745 									 "void main()\n"
18746 									 "{\n"
18747 									 "    vec4 result = in_vs;\n"
18748 									 "\n"
18749 									 "VARIABLE_USE"
18750 									 "\n"
18751 									 "    vs_tcs += result;\n"
18752 									 "}\n"
18753 									 "\n";
18754 
18755 	std::string source;
18756 	testCase&   test_case = m_test_cases[test_case_index];
18757 
18758 	if (test_case.m_stage == stage)
18759 	{
18760 		const GLchar* array_gohan = "";
18761 		const GLchar* array_goten = "";
18762 		const GLchar* aux_gohan   = getAuxiliaryQualifier(test_case.m_aux_gohan);
18763 		const GLchar* aux_goten   = getAuxiliaryQualifier(test_case.m_aux_goten);
18764 		GLchar		  buffer_gohan[16];
18765 		GLchar		  buffer_goten[16];
18766 		const GLchar* direction   = "in ";
18767 		const GLchar* index_gohan = "";
18768 		const GLchar* index_goten = "";
18769 		const GLchar* int_gohan   = test_case.m_int_gohan;
18770 		const GLchar* int_goten   = test_case.m_int_goten;
18771 		size_t		  position	= 0;
18772 		size_t		  temp;
18773 		const GLchar* type_gohan_name = test_case.m_type_gohan.GetGLSLTypeName();
18774 		const GLchar* type_goten_name = test_case.m_type_goten.GetGLSLTypeName();
18775 		const GLchar* var_use		  = input_use;
18776 
18777 		if (false == test_case.m_is_input)
18778 		{
18779 			direction = "out";
18780 
18781 			var_use = output_use;
18782 		}
18783 
18784 		sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
18785 		sprintf(buffer_goten, "%d", test_case.m_component_goten);
18786 
18787 		switch (stage)
18788 		{
18789 		case Utils::Shader::FRAGMENT:
18790 			source = fs_tested;
18791 			break;
18792 		case Utils::Shader::GEOMETRY:
18793 			source		= gs_tested;
18794 			array_gohan = "[]";
18795 			index_gohan = "[0]";
18796 			array_goten = "[]";
18797 			index_goten = "[0]";
18798 			break;
18799 		case Utils::Shader::TESS_CTRL:
18800 			source = tcs_tested;
18801 			if (PATCH != test_case.m_aux_gohan)
18802 			{
18803 				array_gohan = "[]";
18804 				index_gohan = "[gl_InvocationID]";
18805 			}
18806 			if (PATCH != test_case.m_aux_goten)
18807 			{
18808 				array_goten = "[]";
18809 				index_goten = "[gl_InvocationID]";
18810 			}
18811 			break;
18812 		case Utils::Shader::TESS_EVAL:
18813 			source		= tes_tested;
18814 			array_gohan = "[]";
18815 			index_gohan = "[0]";
18816 			array_goten = "[]";
18817 			index_goten = "[0]";
18818 			break;
18819 		case Utils::Shader::VERTEX:
18820 			source = vs_tested;
18821 			break;
18822 		default:
18823 			TCU_FAIL("Invalid enum");
18824 		}
18825 
18826 		temp = position;
18827 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
18828 		position = temp;
18829 		Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
18830 		Utils::replaceToken("AUX", position, aux_gohan, source);
18831 		Utils::replaceToken("INTERPOLATION", position, int_gohan, source);
18832 		Utils::replaceToken("DIRECTION", position, direction, source);
18833 		Utils::replaceToken("TYPE", position, type_gohan_name, source);
18834 		Utils::replaceToken("ARRAY", position, array_gohan, source);
18835 		Utils::replaceToken("COMPONENT", position, buffer_goten, source);
18836 		Utils::replaceToken("AUX", position, aux_goten, source);
18837 		Utils::replaceToken("INTERPOLATION", position, int_goten, source);
18838 		Utils::replaceToken("DIRECTION", position, direction, source);
18839 		Utils::replaceToken("TYPE", position, type_goten_name, source);
18840 		Utils::replaceToken("ARRAY", position, array_goten, source);
18841 
18842 		temp = position;
18843 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
18844 		position = temp;
18845 		if (true == test_case.m_is_input)
18846 		{
18847 			Utils::replaceToken("TYPE", position, type_gohan_name, source);
18848 			Utils::replaceToken("TYPE", position, type_goten_name, source);
18849 		}
18850 		else
18851 		{
18852 			Utils::replaceToken("TYPE", position, type_gohan_name, source);
18853 			Utils::replaceToken("TYPE", position, type_goten_name, source);
18854 			Utils::replaceToken("TYPE", position, type_gohan_name, source);
18855 			Utils::replaceToken("TYPE", position, type_goten_name, source);
18856 		}
18857 
18858 		Utils::replaceAllTokens("INDEX_GOHAN", index_gohan, source);
18859 		Utils::replaceAllTokens("INDEX_GOTEN", index_goten, source);
18860 	}
18861 	else
18862 	{
18863 		switch (stage)
18864 		{
18865 		case Utils::Shader::FRAGMENT:
18866 			source = fs;
18867 			break;
18868 		case Utils::Shader::GEOMETRY:
18869 			source = gs;
18870 			break;
18871 		case Utils::Shader::TESS_CTRL:
18872 			source = tcs;
18873 			break;
18874 		case Utils::Shader::TESS_EVAL:
18875 			source = tes;
18876 			break;
18877 		case Utils::Shader::VERTEX:
18878 			source = vs;
18879 			break;
18880 		default:
18881 			TCU_FAIL("Invalid enum");
18882 		}
18883 	}
18884 
18885 	return source;
18886 }
18887 
18888 /** Get description of test case
18889  *
18890  * @param test_case_index Index of test case
18891  *
18892  * @return Test case description
18893  **/
18894 std::string VaryingLocationAliasingWithMixedAuxiliaryStorageTest::getTestCaseName(GLuint test_case_index)
18895 {
18896 	std::stringstream stream;
18897 	testCase&		  test_case = m_test_cases[test_case_index];
18898 
18899 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", "
18900 		   << getAuxiliaryQualifier(test_case.m_aux_gohan) << " " << test_case.m_type_gohan.GetGLSLTypeName() << " at "
18901 		   << test_case.m_component_gohan << ", " << getAuxiliaryQualifier(test_case.m_aux_goten) << " "
18902 		   << test_case.m_type_goten.GetGLSLTypeName() << " at " << test_case.m_component_goten << ". Direction: ";
18903 
18904 	if (true == test_case.m_is_input)
18905 	{
18906 		stream << "input";
18907 	}
18908 	else
18909 	{
18910 		stream << "output";
18911 	}
18912 
18913 	return stream.str();
18914 }
18915 
18916 /** Get number of test cases
18917  *
18918  * @return Number of test cases
18919  **/
18920 GLuint VaryingLocationAliasingWithMixedAuxiliaryStorageTest::getTestCaseNumber()
18921 {
18922 	return static_cast<GLuint>(m_test_cases.size());
18923 }
18924 
18925 /** Selects if "compute" stage is relevant for test
18926  *
18927  * @param ignored
18928  *
18929  * @return false
18930  **/
18931 bool VaryingLocationAliasingWithMixedAuxiliaryStorageTest::isComputeRelevant(GLuint /* test_case_index */)
18932 {
18933 	return false;
18934 }
18935 
18936 /** Prepare all test cases
18937  *
18938  **/
18939 void VaryingLocationAliasingWithMixedAuxiliaryStorageTest::testInit()
18940 {
18941 	static const GLuint n_components_per_location = 4;
18942 	const GLuint		n_types					  = getTypesNumber();
18943 
18944 	for (GLuint i = 0; i < n_types; ++i)
18945 	{
18946 		const Utils::Type& type_gohan		   = getType(i);
18947 		const bool		   is_float_type_gohan = isFloatType(type_gohan);
18948 
18949 		/* Skip matrices */
18950 		if (1 != type_gohan.m_n_columns)
18951 		{
18952 			continue;
18953 		}
18954 
18955 		for (GLuint j = 0; j < n_types; ++j)
18956 		{
18957 			const Utils::Type& type_goten		   = getType(j);
18958 			const bool		   is_flat_req_gohan   = (Utils::Type::Float == type_gohan.m_basic_type) ? false : true;
18959 			const bool		   is_flat_req_goten   = (Utils::Type::Float == type_goten.m_basic_type) ? false : true;
18960 			const bool		   is_float_type_goten = isFloatType(type_goten);
18961 
18962 			/* Skip matrices */
18963 			if (1 != type_goten.m_n_columns)
18964 			{
18965 				continue;
18966 			}
18967 
18968 			/* Skip invalid combinations */
18969 			if (is_float_type_gohan != is_float_type_goten)
18970 			{
18971 				continue;
18972 			}
18973 
18974 			const GLuint n_req_components_gohan = type_gohan.m_n_rows;
18975 			const GLuint n_req_components_goten = type_goten.m_n_rows;
18976 
18977 			/* Skip pairs that cannot fit into one location */
18978 			if (n_components_per_location < (n_req_components_gohan + n_req_components_goten))
18979 			{
18980 				continue;
18981 			}
18982 
18983 			const GLuint gohan = 0;
18984 			const GLuint goten = gohan + n_req_components_gohan;
18985 
18986 			const GLchar* fs_int_gohan = is_flat_req_gohan ? "flat" : "";
18987 			const GLchar* fs_int_goten = is_flat_req_goten ? "flat" : "";
18988 
18989 			testCase test_case_tcs_np = { gohan,	  goten,	 NONE, PATCH, "", "", false, Utils::Shader::TESS_CTRL,
18990 										  type_gohan, type_goten };
18991 
18992 			testCase test_case_tcs_pn = { gohan,	  goten,	 PATCH, NONE, "", "", false, Utils::Shader::TESS_CTRL,
18993 										  type_gohan, type_goten };
18994 
18995 			testCase test_case_tes_np = { gohan,	  goten,	 NONE, PATCH, "", "", true, Utils::Shader::TESS_EVAL,
18996 										  type_gohan, type_goten };
18997 
18998 			testCase test_case_tes_pn = { gohan,	  goten,	 PATCH, NONE, "", "", true, Utils::Shader::TESS_EVAL,
18999 										  type_gohan, type_goten };
19000 
19001 			testCase test_case_fs_nc = { gohan,		   goten,		 NONE, CENTROID,
19002 										 fs_int_gohan, fs_int_goten, true, Utils::Shader::FRAGMENT,
19003 										 type_gohan,   type_goten };
19004 
19005 			testCase test_case_fs_cn = { gohan,		   goten,		 CENTROID, NONE,
19006 										 fs_int_gohan, fs_int_goten, true,	 Utils::Shader::FRAGMENT,
19007 										 type_gohan,   type_goten };
19008 
19009 			testCase test_case_fs_ns = { gohan,		   goten,		 NONE, SAMPLE,
19010 										 fs_int_gohan, fs_int_goten, true, Utils::Shader::FRAGMENT,
19011 										 type_gohan,   type_goten };
19012 
19013 			testCase test_case_fs_sn = { gohan,		   goten,		 SAMPLE, NONE,
19014 										 fs_int_gohan, fs_int_goten, true,   Utils::Shader::FRAGMENT,
19015 										 type_gohan,   type_goten };
19016 
19017 			testCase test_case_fs_cs = { gohan,		   goten,		 CENTROID, SAMPLE,
19018 										 fs_int_gohan, fs_int_goten, true,	 Utils::Shader::FRAGMENT,
19019 										 type_gohan,   type_goten };
19020 
19021 			testCase test_case_fs_sc = { gohan,		   goten,		 SAMPLE, CENTROID,
19022 										 fs_int_gohan, fs_int_goten, true,   Utils::Shader::FRAGMENT,
19023 										 type_gohan,   type_goten };
19024 
19025 			m_test_cases.push_back(test_case_tcs_np);
19026 			m_test_cases.push_back(test_case_tcs_pn);
19027 			m_test_cases.push_back(test_case_tes_np);
19028 			m_test_cases.push_back(test_case_tes_pn);
19029 			m_test_cases.push_back(test_case_fs_nc);
19030 			m_test_cases.push_back(test_case_fs_cn);
19031 			m_test_cases.push_back(test_case_fs_ns);
19032 			m_test_cases.push_back(test_case_fs_sn);
19033 			m_test_cases.push_back(test_case_fs_cs);
19034 			m_test_cases.push_back(test_case_fs_sc);
19035 		}
19036 	}
19037 }
19038 
19039 /** Get auxiliary storage qualifier
19040  *
19041  * @param aux Enumeration
19042  *
19043  * @return GLSL qualifier
19044  **/
19045 const GLchar* VaryingLocationAliasingWithMixedAuxiliaryStorageTest::getAuxiliaryQualifier(AUXILIARIES aux)
19046 {
19047 	const GLchar* result = 0;
19048 
19049 	switch (aux)
19050 	{
19051 	case NONE:
19052 		result = "";
19053 		break;
19054 	case PATCH:
19055 		result = "patch";
19056 		break;
19057 	case CENTROID:
19058 		result = "centroid";
19059 		break;
19060 	case SAMPLE:
19061 		result = "sample";
19062 		break;
19063 	default:
19064 		TCU_FAIL("Invalid enum");
19065 	}
19066 
19067 	return result;
19068 }
19069 
19070 /** Check if given type is float
19071  *
19072  * @param type Type in question
19073  *
19074  * @return true if tpye is float, false otherwise
19075  **/
19076 bool VaryingLocationAliasingWithMixedAuxiliaryStorageTest::isFloatType(const Utils::Type& type)
19077 {
19078 	bool is_float = false;
19079 
19080 	if ((Utils::Type::Double == type.m_basic_type) || (Utils::Type::Float == type.m_basic_type))
19081 	{
19082 		is_float = true;
19083 	}
19084 
19085 	return is_float;
19086 }
19087 
19088 /* Constants used by VertexAttribLocationAPITest */
19089 const GLuint VertexAttribLocationAPITest::m_goten_location = 6;
19090 
19091 /** Constructor
19092  *
19093  * @param context Test framework context
19094  **/
19095 VertexAttribLocationAPITest::VertexAttribLocationAPITest(deqp::Context& context)
19096 	: TextureTestBase(context, "vertex_attrib_location_api",
19097 					  "Test verifies that attribute locations API works as expected")
19098 {
19099 }
19100 
19101 /** Does BindAttribLocation for "goten" and relink program
19102  *
19103  * @param program           Program object
19104  * @param program_interface Interface of program
19105  **/
19106 void VertexAttribLocationAPITest::prepareAttribLocation(Utils::Program&			 program,
19107 														Utils::ProgramInterface& program_interface)
19108 {
19109 	const Functions& gl = m_context.getRenderContext().getFunctions();
19110 
19111 	gl.bindAttribLocation(program.m_id, m_goten_location, "goten");
19112 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindAttribLocation");
19113 
19114 	program.Link(gl, program.m_id);
19115 
19116 	/* We still need to get locations for gohan and chichi */
19117 	TextureTestBase::prepareAttribLocation(program, program_interface);
19118 }
19119 
19120 /** Get interface of program
19121  *
19122  * @param ignored
19123  * @param program_interface   Interface of program
19124  * @param ignored
19125  **/
19126 void VertexAttribLocationAPITest::getProgramInterface(GLuint /* test_case_index */,
19127 													  Utils::ProgramInterface& program_interface,
19128 													  Utils::VaryingPassthrough& /* varying_passthrough */)
19129 {
19130 	Utils::ShaderInterface& si		  = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
19131 	const Utils::Type&		type	  = Utils::Type::vec4;
19132 	const GLuint			type_size = type.GetSize();
19133 
19134 	/* Offsets */
19135 	const GLuint chichi_offset = 0;
19136 	const GLuint goten_offset  = chichi_offset + type_size;
19137 	const GLuint gohan_offset  = goten_offset + type_size;
19138 	const GLuint goku_offset   = gohan_offset + type_size;
19139 
19140 	/* Locations */
19141 	const GLuint goku_location  = 2;
19142 	const GLuint goten_location = m_goten_location;
19143 
19144 	/* Generate data */
19145 	m_goku_data   = type.GenerateDataPacked();
19146 	m_gohan_data  = type.GenerateDataPacked();
19147 	m_goten_data  = type.GenerateDataPacked();
19148 	m_chichi_data = type.GenerateDataPacked();
19149 
19150 	/* Globals */
19151 	si.m_globals = "const uint GOKU_LOCATION = 2;\n";
19152 
19153 	/* Attributes */
19154 	si.Input("goku" /* name */, "layout (location = GOKU_LOCATION)" /* qualifiers */, 0 /* expected_componenet */,
19155 			 goku_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19156 			 0u /* n_array_elements */, 0u /* stride */, goku_offset /* offset */, (GLvoid*)&m_goku_data[0] /* data */,
19157 			 m_goku_data.size() /* data_size */);
19158 
19159 	si.Input("gohan" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19160 			 Utils::Variable::m_automatic_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19161 			 0u /* n_array_elements */, 0u /* stride */, gohan_offset /* offset */,
19162 			 (GLvoid*)&m_gohan_data[0] /* data */, m_gohan_data.size() /* data_size */);
19163 
19164 	si.Input("goten" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19165 			 goten_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19166 			 0u /* n_array_elements */, 0u /* stride */, goten_offset /* offset */,
19167 			 (GLvoid*)&m_goten_data[0] /* data */, m_goten_data.size() /* data_size */);
19168 
19169 	si.Input("chichi" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19170 			 Utils::Variable::m_automatic_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19171 			 0u /* n_array_elements */, 0u /* stride */, chichi_offset /* offset */,
19172 			 (GLvoid*)&m_chichi_data[0] /* data */, m_chichi_data.size() /* data_size */);
19173 }
19174 
19175 /** Selects if "compute" stage is relevant for test
19176  *
19177  * @param ignored
19178  *
19179  * @return false
19180  **/
19181 bool VertexAttribLocationAPITest::isComputeRelevant(GLuint /* test_case_index */)
19182 {
19183 	return false;
19184 }
19185 
19186 /* Constants used by FragmentDataLocationAPITest */
19187 const GLuint FragmentDataLocationAPITest::m_goten_location = 6;
19188 
19189 /** Constructor
19190  *
19191  * @param context Test framework context
19192  **/
19193 FragmentDataLocationAPITest::FragmentDataLocationAPITest(deqp::Context& context)
19194 	: TextureTestBase(context, "fragment_data_location_api",
19195 					  "Test verifies that fragment data locations API works as expected")
19196 	, m_goku(context)
19197 	, m_gohan(context)
19198 	, m_goten(context)
19199 	, m_chichi(context)
19200 {
19201 }
19202 
19203 /** Verifies contents of drawn images
19204  *
19205  * @param ignored
19206  * @param ignored
19207  *
19208  * @return true if images are filled with expected values, false otherwise
19209  **/
19210 bool FragmentDataLocationAPITest::checkResults(glw::GLuint /* test_case_index */, Utils::Texture& /* color_0 */)
19211 {
19212 	static const GLuint size			= m_width * m_height;
19213 	static const GLuint expected_goku   = 0xff000000;
19214 	static const GLuint expected_gohan  = 0xff0000ff;
19215 	static const GLuint expected_goten  = 0xff00ff00;
19216 	static const GLuint expected_chichi = 0xffff0000;
19217 
19218 	std::vector<GLuint> data;
19219 	data.resize(size);
19220 
19221 	m_goku.Get(GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
19222 
19223 	for (GLuint i = 0; i < size; ++i)
19224 	{
19225 		const GLuint color = data[i];
19226 
19227 		if (expected_goku != color)
19228 		{
19229 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "RGBA8[" << i << "]:" << color
19230 												<< tcu::TestLog::EndMessage;
19231 			return false;
19232 		}
19233 	}
19234 
19235 	m_gohan.Get(GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
19236 
19237 	for (GLuint i = 0; i < size; ++i)
19238 	{
19239 		const GLuint color = data[i];
19240 
19241 		if (expected_gohan != color)
19242 		{
19243 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "RGBA8[" << i << "]:" << color
19244 												<< tcu::TestLog::EndMessage;
19245 			return false;
19246 		}
19247 	}
19248 
19249 	m_goten.Get(GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
19250 
19251 	for (GLuint i = 0; i < size; ++i)
19252 	{
19253 		const GLuint color = data[i];
19254 
19255 		if (expected_goten != color)
19256 		{
19257 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "RGBA8[" << i << "]:" << color
19258 												<< tcu::TestLog::EndMessage;
19259 			return false;
19260 		}
19261 	}
19262 
19263 	m_chichi.Get(GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
19264 
19265 	for (GLuint i = 0; i < size; ++i)
19266 	{
19267 		const GLuint color = data[i];
19268 
19269 		if (expected_chichi != color)
19270 		{
19271 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "RGBA8[" << i << "]:" << color
19272 												<< tcu::TestLog::EndMessage;
19273 			return false;
19274 		}
19275 	}
19276 
19277 	return true;
19278 }
19279 
19280 /** Prepare code snippet that will set out variables
19281  *
19282  * @param ignored
19283  * @param ignored
19284  * @param stage               Shader stage
19285  *
19286  * @return Code that pass in variables to next stage
19287  **/
19288 std::string FragmentDataLocationAPITest::getPassSnippet(GLuint /* test_case_index */,
19289 														Utils::VaryingPassthrough& /* varying_passthrough */,
19290 														Utils::Shader::STAGES stage)
19291 {
19292 	std::string result;
19293 
19294 	/* Skip for compute shader */
19295 	if (Utils::Shader::FRAGMENT != stage)
19296 	{
19297 		result = "";
19298 	}
19299 	else
19300 	{
19301 		result = "chichi = vec4(0, 0, 1, 1);\n"
19302 				 "    goku   = vec4(0, 0, 0, 1);\n"
19303 				 "    goten  = vec4(0, 1, 0, 1);\n"
19304 				 "    gohan  = vec4(1, 0, 0, 1);\n";
19305 	}
19306 
19307 	return result;
19308 }
19309 
19310 /** Get interface of program
19311  *
19312  * @param ignored
19313  * @param program_interface Interface of program
19314  * @param ignored
19315  **/
19316 void FragmentDataLocationAPITest::getProgramInterface(GLuint /* test_case_index */,
19317 													  Utils::ProgramInterface& program_interface,
19318 													  Utils::VaryingPassthrough& /* varying_passthrough */)
19319 {
19320 	Utils::ShaderInterface& si   = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
19321 	const Utils::Type&		type = Utils::Type::vec4;
19322 
19323 	/* Locations */
19324 	m_goku_location = 2;
19325 
19326 	/* Globals */
19327 	si.m_globals = "const uint GOKU_LOCATION = 2;\n";
19328 
19329 	/* Attributes */
19330 	si.Output("goku" /* name */, "layout (location = GOKU_LOCATION)" /* qualifiers */, 0 /* expected_componenet */,
19331 			  m_goku_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19332 			  0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)0 /* data */, 0u /* data_size */);
19333 
19334 	si.Output("gohan" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19335 			  Utils::Variable::m_automatic_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19336 			  0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)0 /* data */, 0u /* data_size */);
19337 
19338 	si.Output("goten" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19339 			  m_goten_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19340 			  0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)0 /* data */, 0u /* data_size */);
19341 
19342 	si.Output("chichi" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19343 			  Utils::Variable::m_automatic_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19344 			  0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)0 /* data */, 0u /* data_size */);
19345 }
19346 
19347 /** Selects if "compute" stage is relevant for test
19348  *
19349  * @param ignored
19350  *
19351  * @return false
19352  **/
19353 bool FragmentDataLocationAPITest::isComputeRelevant(GLuint /* test_case_index */)
19354 {
19355 	return false;
19356 }
19357 
19358 /** Get locations for all outputs with automatic_location
19359  *
19360  * @param program           Program object
19361  * @param program_interface Interface of program
19362  **/
19363 void FragmentDataLocationAPITest::prepareFragmentDataLoc(Utils::Program&		  program,
19364 														 Utils::ProgramInterface& program_interface)
19365 {
19366 	/* Bind location of goten */
19367 	const Functions& gl = m_context.getRenderContext().getFunctions();
19368 
19369 	gl.bindFragDataLocation(program.m_id, m_goten_location, "goten");
19370 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindFragDataLocation");
19371 
19372 	program.Link(gl, program.m_id);
19373 
19374 	/* Prepare locations for gohan and chichi */
19375 	TextureTestBase::prepareFragmentDataLoc(program, program_interface);
19376 
19377 	/* Get all locations */
19378 	Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
19379 
19380 	Utils::Variable::PtrVector& outputs = si.m_outputs;
19381 
19382 	for (Utils::Variable::PtrVector::iterator it = outputs.begin(); outputs.end() != it; ++it)
19383 	{
19384 		const Utils::Variable::Descriptor& desc = (*it)->m_descriptor;
19385 
19386 		if (0 == desc.m_name.compare("gohan"))
19387 		{
19388 			m_gohan_location = desc.m_expected_location;
19389 		}
19390 		else if (0 == desc.m_name.compare("chichi"))
19391 		{
19392 			m_chichi_location = desc.m_expected_location;
19393 		}
19394 
19395 		/* Locations of goku and goten are fixed */
19396 	}
19397 }
19398 
19399 /** Prepare framebuffer with single texture as color attachment
19400  *
19401  * @param framebuffer     Framebuffer
19402  * @param color_0_texture Texture that will used as color attachment
19403  **/
19404 void FragmentDataLocationAPITest::prepareFramebuffer(Utils::Framebuffer& framebuffer, Utils::Texture& color_0_texture)
19405 {
19406 	/* Let parent prepare its stuff */
19407 	TextureTestBase::prepareFramebuffer(framebuffer, color_0_texture);
19408 
19409 	/* Prepare data */
19410 	std::vector<GLuint> texture_data;
19411 	texture_data.resize(m_width * m_height);
19412 
19413 	for (GLuint i = 0; i < texture_data.size(); ++i)
19414 	{
19415 		texture_data[i] = 0x20406080;
19416 	}
19417 
19418 	/* Prepare textures */
19419 	m_goku.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]);
19420 
19421 	m_gohan.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]);
19422 
19423 	m_goten.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]);
19424 
19425 	m_chichi.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]);
19426 
19427 	/* Attach textures to framebuffer */
19428 	framebuffer.Bind();
19429 	framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0 + m_goku_location, m_goku.m_id, m_width, m_height);
19430 	framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0 + m_gohan_location, m_gohan.m_id, m_width, m_height);
19431 	framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0 + m_goten_location, m_goten.m_id, m_width, m_height);
19432 	framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0 + m_chichi_location, m_chichi.m_id, m_width, m_height);
19433 
19434 	/* Set up drawbuffers */
19435 	const Functions& gl = m_context.getRenderContext().getFunctions();
19436 	// The fragment shader can have more than 4 color outputs, but it only care about 4 (goku, gohan, goten, chichi).
19437 	// We will first initialize all draw buffers to NONE and then set the real value for the 4 outputs we care about
19438 	GLint maxDrawBuffers = 0;
19439 	gl.getIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
19440 
19441 	std::vector<GLenum> buffers(maxDrawBuffers, GL_NONE);
19442 	buffers[m_chichi_location] = GLenum(GL_COLOR_ATTACHMENT0 + m_chichi_location);
19443 	buffers[m_goten_location]  = GLenum(GL_COLOR_ATTACHMENT0 + m_goten_location);
19444 	buffers[m_goku_location]   = GLenum(GL_COLOR_ATTACHMENT0 + m_goku_location);
19445 	buffers[m_gohan_location]  = GLenum(GL_COLOR_ATTACHMENT0 + m_gohan_location);
19446 
19447 	gl.drawBuffers(maxDrawBuffers, buffers.data());
19448 	GLU_EXPECT_NO_ERROR(gl.getError(), "DrawBuffers");
19449 }
19450 
19451 /** Constructor
19452  *
19453  * @param context Test framework context
19454  **/
19455 XFBInputTest::XFBInputTest(deqp::Context& context)
19456 	: NegativeTestBase(context, "xfb_input",
19457 					   "Test verifies that compiler reports error when xfb qualifiers are used with input")
19458 {
19459 }
19460 
19461 /** Source for given test case and stage
19462  *
19463  * @param test_case_index Index of test case
19464  * @param stage           Shader stage
19465  *
19466  * @return Shader source
19467  **/
19468 std::string XFBInputTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
19469 {
19470 	static const GLchar* buffer_var_definition = "layout (xfb_buffer = 2) in vec4 gohanARRAY;\n";
19471 	static const GLchar* offset_var_definition = "layout (xfb_offset = 16) in vec4 gohanARRAY;\n";
19472 	static const GLchar* stride_var_definition = "layout (xfb_stride = 32) in vec4 gohanARRAY;\n";
19473 	static const GLchar* input_use			   = "    result += gohanINDEX;\n";
19474 	static const GLchar* fs					   = "#version 430 core\n"
19475 							  "#extension GL_ARB_enhanced_layouts : require\n"
19476 							  "\n"
19477 							  "in  vec4 gs_fs;\n"
19478 							  "out vec4 fs_out;\n"
19479 							  "\n"
19480 							  "void main()\n"
19481 							  "{\n"
19482 							  "    fs_out = gs_fs;\n"
19483 							  "}\n"
19484 							  "\n";
19485 	static const GLchar* fs_tested = "#version 430 core\n"
19486 									 "#extension GL_ARB_enhanced_layouts : require\n"
19487 									 "\n"
19488 									 "VAR_DEFINITION"
19489 									 "\n"
19490 									 "in  vec4 gs_fs;\n"
19491 									 "out vec4 fs_out;\n"
19492 									 "\n"
19493 									 "void main()\n"
19494 									 "{\n"
19495 									 "    vec4 result = gs_fs;\n"
19496 									 "\n"
19497 									 "VARIABLE_USE"
19498 									 "\n"
19499 									 "    fs_out = result;\n"
19500 									 "}\n"
19501 									 "\n";
19502 	static const GLchar* gs = "#version 430 core\n"
19503 							  "#extension GL_ARB_enhanced_layouts : require\n"
19504 							  "\n"
19505 							  "layout(points)                           in;\n"
19506 							  "layout(triangle_strip, max_vertices = 4) out;\n"
19507 							  "\n"
19508 							  "in  vec4 tes_gs[];\n"
19509 							  "out vec4 gs_fs;\n"
19510 							  "\n"
19511 							  "void main()\n"
19512 							  "{\n"
19513 							  "    gs_fs = tes_gs[0];\n"
19514 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
19515 							  "    EmitVertex();\n"
19516 							  "    gs_fs = tes_gs[0];\n"
19517 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
19518 							  "    EmitVertex();\n"
19519 							  "    gs_fs = tes_gs[0];\n"
19520 							  "    gl_Position  = vec4(1, -1, 0, 1);\n"
19521 							  "    EmitVertex();\n"
19522 							  "    gs_fs = tes_gs[0];\n"
19523 							  "    gl_Position  = vec4(1, 1, 0, 1);\n"
19524 							  "    EmitVertex();\n"
19525 							  "}\n"
19526 							  "\n";
19527 	static const GLchar* gs_tested = "#version 430 core\n"
19528 									 "#extension GL_ARB_enhanced_layouts : require\n"
19529 									 "\n"
19530 									 "layout(points)                           in;\n"
19531 									 "layout(triangle_strip, max_vertices = 4) out;\n"
19532 									 "\n"
19533 									 "VAR_DEFINITION"
19534 									 "\n"
19535 									 "in  vec4 tes_gs[];\n"
19536 									 "out vec4 gs_fs;\n"
19537 									 "\n"
19538 									 "void main()\n"
19539 									 "{\n"
19540 									 "    vec4 result = tes_gs[0];\n"
19541 									 "\n"
19542 									 "VARIABLE_USE"
19543 									 "\n"
19544 									 "    gs_fs = result;\n"
19545 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
19546 									 "    EmitVertex();\n"
19547 									 "    gs_fs = result;\n"
19548 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
19549 									 "    EmitVertex();\n"
19550 									 "    gs_fs = result;\n"
19551 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
19552 									 "    EmitVertex();\n"
19553 									 "    gs_fs = result;\n"
19554 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
19555 									 "    EmitVertex();\n"
19556 									 "}\n"
19557 									 "\n";
19558 	static const GLchar* tcs = "#version 430 core\n"
19559 							   "#extension GL_ARB_enhanced_layouts : require\n"
19560 							   "\n"
19561 							   "layout(vertices = 1) out;\n"
19562 							   "\n"
19563 							   "in  vec4 vs_tcs[];\n"
19564 							   "out vec4 tcs_tes[];\n"
19565 							   "\n"
19566 							   "void main()\n"
19567 							   "{\n"
19568 							   "\n"
19569 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
19570 							   "\n"
19571 							   "    gl_TessLevelOuter[0] = 1.0;\n"
19572 							   "    gl_TessLevelOuter[1] = 1.0;\n"
19573 							   "    gl_TessLevelOuter[2] = 1.0;\n"
19574 							   "    gl_TessLevelOuter[3] = 1.0;\n"
19575 							   "    gl_TessLevelInner[0] = 1.0;\n"
19576 							   "    gl_TessLevelInner[1] = 1.0;\n"
19577 							   "}\n"
19578 							   "\n";
19579 	static const GLchar* tcs_tested = "#version 430 core\n"
19580 									  "#extension GL_ARB_enhanced_layouts : require\n"
19581 									  "\n"
19582 									  "layout(vertices = 1) out;\n"
19583 									  "\n"
19584 									  "VAR_DEFINITION"
19585 									  "\n"
19586 									  "in  vec4 vs_tcs[];\n"
19587 									  "out vec4 tcs_tes[];\n"
19588 									  "\n"
19589 									  "void main()\n"
19590 									  "{\n"
19591 									  "    vec4 result = vs_tcs[gl_InvocationID];\n"
19592 									  "\n"
19593 									  "VARIABLE_USE"
19594 									  "\n"
19595 									  "    tcs_tes[gl_InvocationID] = result;\n"
19596 									  "\n"
19597 									  "    gl_TessLevelOuter[0] = 1.0;\n"
19598 									  "    gl_TessLevelOuter[1] = 1.0;\n"
19599 									  "    gl_TessLevelOuter[2] = 1.0;\n"
19600 									  "    gl_TessLevelOuter[3] = 1.0;\n"
19601 									  "    gl_TessLevelInner[0] = 1.0;\n"
19602 									  "    gl_TessLevelInner[1] = 1.0;\n"
19603 									  "}\n"
19604 									  "\n";
19605 	static const GLchar* tes = "#version 430 core\n"
19606 							   "#extension GL_ARB_enhanced_layouts : require\n"
19607 							   "\n"
19608 							   "layout(isolines, point_mode) in;\n"
19609 							   "\n"
19610 							   "in  vec4 tcs_tes[];\n"
19611 							   "out vec4 tes_gs;\n"
19612 							   "\n"
19613 							   "void main()\n"
19614 							   "{\n"
19615 							   "    tes_gs = tcs_tes[0];\n"
19616 							   "}\n"
19617 							   "\n";
19618 	static const GLchar* tes_tested = "#version 430 core\n"
19619 									  "#extension GL_ARB_enhanced_layouts : require\n"
19620 									  "\n"
19621 									  "layout(isolines, point_mode) in;\n"
19622 									  "\n"
19623 									  "VAR_DEFINITION"
19624 									  "\n"
19625 									  "in  vec4 tcs_tes[];\n"
19626 									  "out vec4 tes_gs;\n"
19627 									  "\n"
19628 									  "void main()\n"
19629 									  "{\n"
19630 									  "    vec4 result = tcs_tes[0];\n"
19631 									  "\n"
19632 									  "VARIABLE_USE"
19633 									  "\n"
19634 									  "    tes_gs += result;\n"
19635 									  "}\n"
19636 									  "\n";
19637 	static const GLchar* vs = "#version 430 core\n"
19638 							  "#extension GL_ARB_enhanced_layouts : require\n"
19639 							  "\n"
19640 							  "in  vec4 in_vs;\n"
19641 							  "out vec4 vs_tcs;\n"
19642 							  "\n"
19643 							  "void main()\n"
19644 							  "{\n"
19645 							  "    vs_tcs = in_vs;\n"
19646 							  "}\n"
19647 							  "\n";
19648 	static const GLchar* vs_tested = "#version 430 core\n"
19649 									 "#extension GL_ARB_enhanced_layouts : require\n"
19650 									 "\n"
19651 									 "VAR_DEFINITION"
19652 									 "\n"
19653 									 "in  vec4 in_vs;\n"
19654 									 "out vec4 vs_tcs;\n"
19655 									 "\n"
19656 									 "void main()\n"
19657 									 "{\n"
19658 									 "    vec4 result = in_vs;\n"
19659 									 "\n"
19660 									 "VARIABLE_USE"
19661 									 "\n"
19662 									 "    vs_tcs += result;\n"
19663 									 "}\n"
19664 									 "\n";
19665 
19666 	std::string source;
19667 	testCase&   test_case = m_test_cases[test_case_index];
19668 
19669 	if (test_case.m_stage == stage)
19670 	{
19671 		const GLchar* array	= "";
19672 		const GLchar* index	= "";
19673 		size_t		  position = 0;
19674 		size_t		  temp;
19675 		const GLchar* var_definition = 0;
19676 		const GLchar* var_use		 = input_use;
19677 
19678 		switch (test_case.m_qualifier)
19679 		{
19680 		case BUFFER:
19681 			var_definition = buffer_var_definition;
19682 			break;
19683 		case OFFSET:
19684 			var_definition = offset_var_definition;
19685 			break;
19686 		case STRIDE:
19687 			var_definition = stride_var_definition;
19688 			break;
19689 		default:
19690 			TCU_FAIL("Invalid enum");
19691 		}
19692 
19693 		switch (stage)
19694 		{
19695 		case Utils::Shader::FRAGMENT:
19696 			source = fs_tested;
19697 			break;
19698 		case Utils::Shader::GEOMETRY:
19699 			source = gs_tested;
19700 			array  = "[]";
19701 			index  = "[0]";
19702 			break;
19703 		case Utils::Shader::TESS_CTRL:
19704 			source = tcs_tested;
19705 			array  = "[]";
19706 			index  = "[gl_InvocationID]";
19707 			break;
19708 		case Utils::Shader::TESS_EVAL:
19709 			source = tes_tested;
19710 			array  = "[]";
19711 			index  = "[0]";
19712 			break;
19713 		case Utils::Shader::VERTEX:
19714 			source = vs_tested;
19715 			break;
19716 		default:
19717 			TCU_FAIL("Invalid enum");
19718 		}
19719 
19720 		temp = position;
19721 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
19722 		position = temp;
19723 		Utils::replaceToken("ARRAY", position, array, source);
19724 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
19725 
19726 		Utils::replaceAllTokens("INDEX", index, source);
19727 	}
19728 	else
19729 	{
19730 		switch (stage)
19731 		{
19732 		case Utils::Shader::FRAGMENT:
19733 			source = fs;
19734 			break;
19735 		case Utils::Shader::GEOMETRY:
19736 			source = gs;
19737 			break;
19738 		case Utils::Shader::TESS_CTRL:
19739 			source = tcs;
19740 			break;
19741 		case Utils::Shader::TESS_EVAL:
19742 			source = tes;
19743 			break;
19744 		case Utils::Shader::VERTEX:
19745 			source = vs;
19746 			break;
19747 		default:
19748 			TCU_FAIL("Invalid enum");
19749 		}
19750 	}
19751 
19752 	return source;
19753 }
19754 
19755 /** Get description of test case
19756  *
19757  * @param test_case_index Index of test case
19758  *
19759  * @return Test case description
19760  **/
19761 std::string XFBInputTest::getTestCaseName(GLuint test_case_index)
19762 {
19763 	std::stringstream stream;
19764 	testCase&		  test_case = m_test_cases[test_case_index];
19765 
19766 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", qualifier: ";
19767 
19768 	switch (test_case.m_qualifier)
19769 	{
19770 	case BUFFER:
19771 		stream << "xfb_buffer";
19772 		break;
19773 	case OFFSET:
19774 		stream << "xfb_offset";
19775 		break;
19776 	case STRIDE:
19777 		stream << "xfb_stride";
19778 		break;
19779 	default:
19780 		TCU_FAIL("Invalid enum");
19781 	}
19782 
19783 	return stream.str();
19784 }
19785 
19786 /** Get number of test cases
19787  *
19788  * @return Number of test cases
19789  **/
19790 GLuint XFBInputTest::getTestCaseNumber()
19791 {
19792 	return static_cast<GLuint>(m_test_cases.size());
19793 }
19794 
19795 /** Selects if "compute" stage is relevant for test
19796  *
19797  * @param ignored
19798  *
19799  * @return false
19800  **/
19801 bool XFBInputTest::isComputeRelevant(GLuint /* test_case_index */)
19802 {
19803 	return false;
19804 }
19805 
19806 /** Prepare all test cases
19807  *
19808  **/
19809 void XFBInputTest::testInit()
19810 {
19811 	for (GLuint qualifier = 0; qualifier < QUALIFIERS_MAX; ++qualifier)
19812 	{
19813 		for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
19814 		{
19815 			if (Utils::Shader::COMPUTE == stage)
19816 			{
19817 				continue;
19818 			}
19819 
19820 			testCase test_case = { (QUALIFIERS)qualifier, (Utils::Shader::STAGES)stage };
19821 
19822 			m_test_cases.push_back(test_case);
19823 		}
19824 	}
19825 }
19826 
19827 /* Constants used by XFBAllStagesTest */
19828 const GLuint XFBAllStagesTest::m_gs_index = 3;
19829 
19830 /** Constructor
19831  *
19832  * @param context Test context
19833  **/
19834 XFBAllStagesTest::XFBAllStagesTest(deqp::Context& context)
19835 	: BufferTestBase(context, "xfb_all_stages",
19836 					 "Test verifies that only last stage in vertex processing can output to transform feedback")
19837 {
19838 	/* Nothing to be done here */
19839 }
19840 
19841 /** Get descriptors of buffers necessary for test
19842  *
19843  * @param ignored
19844  * @param out_descriptors Descriptors of buffers used by test
19845  **/
19846 void XFBAllStagesTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
19847 											bufferDescriptor::Vector& out_descriptors)
19848 {
19849 	static const GLuint n_stages = 4;
19850 	const Utils::Type&  vec4	 = Utils::Type::vec4;
19851 
19852 	/* Data */
19853 	tcu::Vec4 sum;
19854 
19855 	/* Test uses single uniform and xfb per stage + uniform for fragment shader */
19856 	out_descriptors.resize(n_stages * 2 + 1);
19857 
19858 	/* */
19859 	for (GLuint i = 0; i < n_stages; ++i)
19860 	{
19861 		/* Get references */
19862 		bufferDescriptor& uniform = out_descriptors[i + 0];
19863 		bufferDescriptor& xfb	 = out_descriptors[i + n_stages];
19864 
19865 		/* Index */
19866 		uniform.m_index = i;
19867 		xfb.m_index		= i;
19868 
19869 		/* Target */
19870 		uniform.m_target = Utils::Buffer::Uniform;
19871 		xfb.m_target	 = Utils::Buffer::Transform_feedback;
19872 
19873 		/* Data */
19874 		const tcu::Vec4 var(Utils::GetRandFloat(), Utils::GetRandFloat(), Utils::GetRandFloat(), Utils::GetRandFloat());
19875 
19876 		sum += var;
19877 
19878 		uniform.m_initial_data.resize(vec4.GetSize());
19879 		memcpy(&uniform.m_initial_data[0], var.getPtr(), vec4.GetSize());
19880 
19881 		xfb.m_initial_data = vec4.GenerateDataPacked();
19882 
19883 		if (m_gs_index != i)
19884 		{
19885 			xfb.m_expected_data = xfb.m_initial_data;
19886 		}
19887 		else
19888 		{
19889 			xfb.m_expected_data.resize(vec4.GetSize());
19890 			memcpy(&xfb.m_expected_data[0], sum.getPtr(), vec4.GetSize());
19891 		}
19892 	}
19893 
19894 	/* FS */
19895 	{
19896 		/* Get reference */
19897 		bufferDescriptor& uniform = out_descriptors[n_stages * 2];
19898 
19899 		/* Index */
19900 		uniform.m_index = n_stages;
19901 
19902 		/* Target */
19903 		uniform.m_target = Utils::Buffer::Uniform;
19904 
19905 		/* Data */
19906 		const tcu::Vec4 var(Utils::GetRandFloat(), Utils::GetRandFloat(), Utils::GetRandFloat(), Utils::GetRandFloat());
19907 
19908 		uniform.m_initial_data.resize(vec4.GetSize());
19909 		memcpy(&uniform.m_initial_data[0], var.getPtr(), vec4.GetSize());
19910 	}
19911 }
19912 
19913 /** Get body of main function for given shader stage
19914  *
19915  * @param ignored
19916  * @param stage            Shader stage
19917  * @param out_assignments  Set to empty
19918  * @param out_calculations Set to empty
19919  **/
19920 void XFBAllStagesTest::getShaderBody(glw::GLuint /* test_case_index */, Utils::Shader::STAGES stage,
19921 									 std::string& out_assignments, std::string& out_calculations)
19922 {
19923 	out_calculations = "";
19924 
19925 	static const GLchar* vs  = "    vs_tcs  = uni_vs;\n";
19926 	static const GLchar* tcs = "    tcs_tes[gl_InvocationID] = uni_tcs + vs_tcs[gl_InvocationID];\n";
19927 	static const GLchar* tes = "    tes_gs  = uni_tes + tcs_tes[0];\n";
19928 	static const GLchar* gs  = "    gs_fs   = uni_gs  + tes_gs[0];\n";
19929 	static const GLchar* fs  = "    fs_out  = uni_fs  + gs_fs;\n";
19930 
19931 	const GLchar* assignments = 0;
19932 	switch (stage)
19933 	{
19934 	case Utils::Shader::FRAGMENT:
19935 		assignments = fs;
19936 		break;
19937 	case Utils::Shader::GEOMETRY:
19938 		assignments = gs;
19939 		break;
19940 	case Utils::Shader::TESS_CTRL:
19941 		assignments = tcs;
19942 		break;
19943 	case Utils::Shader::TESS_EVAL:
19944 		assignments = tes;
19945 		break;
19946 	case Utils::Shader::VERTEX:
19947 		assignments = vs;
19948 		break;
19949 	default:
19950 		TCU_FAIL("Invalid enum");
19951 	}
19952 
19953 	out_assignments = assignments;
19954 }
19955 
19956 /** Get interface of shader
19957  *
19958  * @param ignored
19959  * @param stage         Shader stage
19960  * @param out_interface Set to ""
19961  **/
19962 void XFBAllStagesTest::getShaderInterface(glw::GLuint /* test_case_index */, Utils::Shader::STAGES stage,
19963 										  std::string& out_interface)
19964 {
19965 	static const GLchar* vs = "layout(xfb_buffer = 0, xfb_offset = 0) out     vec4 vs_tcs;\n"
19966 							  "layout(binding    = 0)                 uniform vs_block {\n"
19967 							  "    vec4 uni_vs;\n"
19968 							  "};\n";
19969 	static const GLchar* tcs = "                                       in      vec4 vs_tcs[];\n"
19970 							   "layout(xfb_buffer = 1, xfb_offset = 0) out     vec4 tcs_tes[1];\n"
19971 							   "layout(binding    = 1)                 uniform tcs_block {\n"
19972 							   "    vec4 uni_tcs;\n"
19973 							   "};\n";
19974 	static const GLchar* tes = "                                       in      vec4 tcs_tes[];\n"
19975 							   "layout(xfb_buffer = 2, xfb_offset = 0) out     vec4 tes_gs;\n"
19976 							   "layout(binding    = 2)                 uniform tes_block {\n"
19977 							   "    vec4 uni_tes;\n"
19978 							   "};\n";
19979 	static const GLchar* gs = "                                       in      vec4 tes_gs[];\n"
19980 							  "layout(xfb_buffer = 3, xfb_offset = 0) out     vec4 gs_fs;\n"
19981 							  "layout(binding    = 3)                 uniform gs_block {\n"
19982 							  "    vec4 uni_gs;\n"
19983 							  "};\n";
19984 	static const GLchar* fs = "                       in      vec4 gs_fs;\n"
19985 							  "                       out     vec4 fs_out;\n"
19986 							  "layout(binding    = 4) uniform fs_block {\n"
19987 							  "    vec4 uni_fs;\n"
19988 							  "};\n";
19989 
19990 	const GLchar* interface = 0;
19991 	switch (stage)
19992 	{
19993 	case Utils::Shader::FRAGMENT:
19994 		interface = fs;
19995 		break;
19996 	case Utils::Shader::GEOMETRY:
19997 		interface = gs;
19998 		break;
19999 	case Utils::Shader::TESS_CTRL:
20000 		interface = tcs;
20001 		break;
20002 	case Utils::Shader::TESS_EVAL:
20003 		interface = tes;
20004 		break;
20005 	case Utils::Shader::VERTEX:
20006 		interface = vs;
20007 		break;
20008 	default:
20009 		TCU_FAIL("Invalid enum");
20010 	}
20011 
20012 	out_interface = interface;
20013 }
20014 
20015 /* Constants used by XFBStrideOfEmptyListTest */
20016 const GLuint XFBStrideOfEmptyListTest::m_stride = 64;
20017 
20018 /** Constructor
20019  *
20020  * @param context Test context
20021  **/
20022 XFBStrideOfEmptyListTest::XFBStrideOfEmptyListTest(deqp::Context& context)
20023 	: BufferTestBase(
20024 		  context, "xfb_stride_of_empty_list",
20025 		  "Test verifies correct behavior when xfb_stride qualifier is specified but no xfb_offset is specified")
20026 {
20027 	/* Nothing to be done here */
20028 }
20029 
20030 /** Execute drawArrays for single vertex
20031  *
20032  * @param test_case_index Index of test case
20033  *
20034  * @return true if proper error is reported
20035  **/
20036 bool XFBStrideOfEmptyListTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
20037 {
20038 	const Functions& gl		= m_context.getRenderContext().getFunctions();
20039 	bool			 result = true;
20040 
20041 	/* Draw */
20042 	gl.disable(GL_RASTERIZER_DISCARD);
20043 	GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
20044 
20045 	gl.beginTransformFeedback(GL_POINTS);
20046 	GLenum error = gl.getError();
20047 	switch (test_case_index)
20048 	{
20049 	case VALID:
20050 		if (GL_NO_ERROR != error)
20051 		{
20052 			gl.endTransformFeedback();
20053 			GLU_EXPECT_NO_ERROR(error, "BeginTransformFeedback");
20054 		}
20055 
20056 		gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
20057 		error = gl.getError();
20058 
20059 		gl.endTransformFeedback();
20060 		GLU_EXPECT_NO_ERROR(error, "DrawArrays");
20061 		GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
20062 
20063 		break;
20064 
20065 	case FIRST_MISSING:
20066 		if (GL_NO_ERROR == error)
20067 		{
20068 			gl.endTransformFeedback();
20069 		}
20070 
20071 		if (GL_INVALID_OPERATION != error)
20072 		{
20073 			m_context.getTestContext().getLog()
20074 				<< tcu::TestLog::Message << "XFB at index 0, that is written by GS, is missing. It was expected that "
20075 											"INVALID_OPERATION will generated by BeginTransformFeedback. Got: "
20076 				<< glu::getErrorStr(error) << tcu::TestLog::EndMessage;
20077 
20078 			result = false;
20079 		}
20080 
20081 		break;
20082 
20083 	case SECOND_MISSING:
20084 		if (GL_NO_ERROR != error)
20085 		{
20086 			gl.endTransformFeedback();
20087 			GLU_EXPECT_NO_ERROR(error, "BeginTransformFeedback");
20088 		}
20089 
20090 		gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
20091 		error = gl.getError();
20092 
20093 		gl.endTransformFeedback();
20094 		GLU_EXPECT_NO_ERROR(error, "DrawArrays");
20095 		GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
20096 
20097 		break;
20098 	}
20099 
20100 	/* Done */
20101 	return result;
20102 }
20103 
20104 /** Get descriptors of buffers necessary for test
20105  *
20106  * @param test_case_index Index of test case
20107  * @param out_descriptors Descriptors of buffers used by test
20108  **/
20109 void XFBStrideOfEmptyListTest::getBufferDescriptors(glw::GLuint				  test_case_index,
20110 													bufferDescriptor::Vector& out_descriptors)
20111 {
20112 	switch (test_case_index)
20113 	{
20114 	case VALID:
20115 	{
20116 		/* Test needs single uniform and two xfbs */
20117 		out_descriptors.resize(3);
20118 
20119 		/* Get references */
20120 		bufferDescriptor& uniform = out_descriptors[0];
20121 		bufferDescriptor& xfb_0   = out_descriptors[1];
20122 		bufferDescriptor& xfb_1   = out_descriptors[2];
20123 
20124 		/* Index */
20125 		uniform.m_index = 0;
20126 		xfb_0.m_index   = 0;
20127 		xfb_1.m_index   = 1;
20128 
20129 		/* Target */
20130 		uniform.m_target = Utils::Buffer::Uniform;
20131 		xfb_0.m_target   = Utils::Buffer::Transform_feedback;
20132 		xfb_1.m_target   = Utils::Buffer::Transform_feedback;
20133 
20134 		/* Data */
20135 		uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20136 
20137 		xfb_0.m_initial_data  = Utils::Type::vec4.GenerateDataPacked();
20138 		xfb_0.m_expected_data = uniform.m_initial_data;
20139 
20140 		/* Data, contents are the same as no modification is expected */
20141 		xfb_1.m_initial_data.resize(m_stride);
20142 		xfb_1.m_expected_data.resize(m_stride);
20143 
20144 		for (GLuint i = 0; i < m_stride; ++i)
20145 		{
20146 			xfb_1.m_initial_data[0]  = (glw::GLubyte)i;
20147 			xfb_1.m_expected_data[0] = (glw::GLubyte)i;
20148 		}
20149 	}
20150 
20151 	break;
20152 
20153 	case FIRST_MISSING:
20154 	{
20155 		/* Test needs single uniform and two xfbs */
20156 		out_descriptors.resize(2);
20157 
20158 		/* Get references */
20159 		bufferDescriptor& uniform = out_descriptors[0];
20160 		bufferDescriptor& xfb_1   = out_descriptors[1];
20161 
20162 		/* Index */
20163 		uniform.m_index = 0;
20164 		xfb_1.m_index   = 1;
20165 
20166 		/* Target */
20167 		uniform.m_target = Utils::Buffer::Uniform;
20168 		xfb_1.m_target   = Utils::Buffer::Transform_feedback;
20169 
20170 		/* Data */
20171 		uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20172 
20173 		/* Draw call will not be executed, contents does not matter */
20174 		xfb_1.m_initial_data.resize(m_stride);
20175 	}
20176 
20177 	break;
20178 
20179 	case SECOND_MISSING:
20180 	{
20181 		/* Test needs single uniform and two xfbs */
20182 		out_descriptors.resize(2);
20183 
20184 		/* Get references */
20185 		bufferDescriptor& uniform = out_descriptors[0];
20186 		bufferDescriptor& xfb_0   = out_descriptors[1];
20187 
20188 		/* Index */
20189 		uniform.m_index = 0;
20190 		xfb_0.m_index   = 0;
20191 
20192 		/* Target */
20193 		uniform.m_target = Utils::Buffer::Uniform;
20194 		xfb_0.m_target   = Utils::Buffer::Transform_feedback;
20195 
20196 		/* Data */
20197 		uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20198 
20199 		xfb_0.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20200 		xfb_0.m_expected_data = uniform.m_initial_data;
20201 	}
20202 
20203 	break;
20204 	}
20205 }
20206 
20207 /** Get body of main function for given shader stage
20208  *
20209  * @param ignored
20210  * @param stage            Shader stage
20211  * @param out_assignments  Set to empty
20212  * @param out_calculations Set to empty
20213  **/
20214 void XFBStrideOfEmptyListTest::getShaderBody(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
20215 											 std::string& out_assignments, std::string& out_calculations)
20216 {
20217 	out_calculations = "";
20218 
20219 	static const GLchar* gs = "    gs_fs  = uni_gs;\n";
20220 	static const GLchar* fs = "    fs_out = vec4(gs_fs);\n";
20221 
20222 	const GLchar* assignments = "";
20223 	switch (stage)
20224 	{
20225 	case Utils::Shader::FRAGMENT:
20226 		assignments = fs;
20227 		break;
20228 	case Utils::Shader::GEOMETRY:
20229 		assignments = gs;
20230 		break;
20231 	default:
20232 		break;
20233 	}
20234 
20235 	out_assignments = assignments;
20236 }
20237 
20238 /** Get interface of shader
20239  *
20240  * @param ignored
20241  * @param stage            Shader stage
20242  * @param out_interface    Set to ""
20243  **/
20244 void XFBStrideOfEmptyListTest::getShaderInterface(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
20245 												  std::string& out_interface)
20246 {
20247 	static const GLchar* gs = "layout (xfb_buffer = 0, xfb_offset = 0)  out     vec4 gs_fs;\n"
20248 							  "layout (xfb_buffer = 1, xfb_stride = 64) out;\n"
20249 							  "\n"
20250 							  "layout (binding    = 0)                  uniform gs_block {\n"
20251 							  "    vec4 uni_gs;\n"
20252 							  "};\n";
20253 	static const GLchar* fs = "in  vec4 gs_fs;\n"
20254 							  "out vec4 fs_out;\n";
20255 
20256 	switch (stage)
20257 	{
20258 	case Utils::Shader::FRAGMENT:
20259 		out_interface = fs;
20260 		break;
20261 	case Utils::Shader::GEOMETRY:
20262 		out_interface = gs;
20263 		break;
20264 	default:
20265 		out_interface = "";
20266 		return;
20267 	}
20268 }
20269 
20270 /** Returns buffer details in human readable form.
20271  *
20272  * @param test_case_index Index of test case
20273  *
20274  * @return Case description
20275  **/
20276 std::string XFBStrideOfEmptyListTest::getTestCaseName(GLuint test_case_index)
20277 {
20278 	std::string result;
20279 
20280 	switch (test_case_index)
20281 	{
20282 	case VALID:
20283 		result = "Valid case";
20284 		break;
20285 	case FIRST_MISSING:
20286 		result = "Missing xfb at index 0";
20287 		break;
20288 	case SECOND_MISSING:
20289 		result = "Missing xfb at index 1";
20290 		break;
20291 	default:
20292 		TCU_FAIL("Invalid enum");
20293 	}
20294 
20295 	return result;
20296 }
20297 
20298 /** Get number of test cases
20299  *
20300  * @return 3
20301  **/
20302 GLuint XFBStrideOfEmptyListTest::getTestCaseNumber()
20303 {
20304 	return 3;
20305 }
20306 
20307 /* Constants used by XFBStrideOfEmptyListTest */
20308 const GLuint XFBStrideOfEmptyListAndAPITest::m_stride = 64;
20309 
20310 /** Constructor
20311  *
20312  * @param context Test context
20313  **/
20314 XFBStrideOfEmptyListAndAPITest::XFBStrideOfEmptyListAndAPITest(deqp::Context& context)
20315 	: BufferTestBase(context, "xfb_stride_of_empty_list_and_api",
20316 					 "Test verifies that xfb_stride qualifier is not overriden by API")
20317 {
20318 	/* Nothing to be done here */
20319 }
20320 
20321 /** Execute drawArrays for single vertex
20322  *
20323  * @param test_case_index Index of test case
20324  *
20325  * @return true if proper error is reported
20326  **/
20327 bool XFBStrideOfEmptyListAndAPITest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
20328 {
20329 	const Functions& gl		= m_context.getRenderContext().getFunctions();
20330 	bool			 result = true;
20331 
20332 	/* Draw */
20333 	gl.disable(GL_RASTERIZER_DISCARD);
20334 	GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
20335 
20336 	gl.beginTransformFeedback(GL_POINTS);
20337 	GLenum error = gl.getError();
20338 	switch (test_case_index)
20339 	{
20340 	case VALID:
20341 		if (GL_NO_ERROR != error)
20342 		{
20343 			gl.endTransformFeedback();
20344 			GLU_EXPECT_NO_ERROR(error, "BeginTransformFeedback");
20345 		}
20346 
20347 		gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
20348 		error = gl.getError();
20349 
20350 		gl.endTransformFeedback();
20351 		GLU_EXPECT_NO_ERROR(error, "DrawArrays");
20352 		GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
20353 
20354 		break;
20355 
20356 	case FIRST_MISSING:
20357 		if (GL_NO_ERROR != error)
20358 		{
20359 			gl.endTransformFeedback();
20360 			GLU_EXPECT_NO_ERROR(error, "BeginTransformFeedback");
20361 		}
20362 
20363 		gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
20364 		error = gl.getError();
20365 
20366 		gl.endTransformFeedback();
20367 		GLU_EXPECT_NO_ERROR(error, "DrawArrays");
20368 		GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
20369 
20370 		break;
20371 
20372 	case SECOND_MISSING:
20373 		if (GL_NO_ERROR == error)
20374 		{
20375 			gl.endTransformFeedback();
20376 		}
20377 
20378 		if (GL_INVALID_OPERATION != error)
20379 		{
20380 			m_context.getTestContext().getLog()
20381 				<< tcu::TestLog::Message << "XFB at index 1, that is declared as empty, is missing. It was expected "
20382 											"that INVALID_OPERATION will generated by BeginTransformFeedback. Got: "
20383 				<< glu::getErrorStr(error) << tcu::TestLog::EndMessage;
20384 
20385 			result = false;
20386 		}
20387 
20388 		break;
20389 	}
20390 
20391 	/* Done */
20392 	return result;
20393 }
20394 
20395 /** Get descriptors of buffers necessary for test
20396  *
20397  * @param test_case_index Index of test case
20398  * @param out_descriptors Descriptors of buffers used by test
20399  **/
20400 void XFBStrideOfEmptyListAndAPITest::getBufferDescriptors(glw::GLuint				test_case_index,
20401 														  bufferDescriptor::Vector& out_descriptors)
20402 {
20403 	switch (test_case_index)
20404 	{
20405 	case VALID:
20406 	{
20407 		/* Test needs single uniform and two xfbs */
20408 		out_descriptors.resize(3);
20409 
20410 		/* Get references */
20411 		bufferDescriptor& uniform = out_descriptors[0];
20412 		bufferDescriptor& xfb_0   = out_descriptors[1];
20413 		bufferDescriptor& xfb_1   = out_descriptors[2];
20414 
20415 		/* Index */
20416 		uniform.m_index = 0;
20417 		xfb_0.m_index   = 0;
20418 		xfb_1.m_index   = 1;
20419 
20420 		/* Target */
20421 		uniform.m_target = Utils::Buffer::Uniform;
20422 		xfb_0.m_target   = Utils::Buffer::Transform_feedback;
20423 		xfb_1.m_target   = Utils::Buffer::Transform_feedback;
20424 
20425 		/* Data */
20426 		uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20427 
20428 		/* Data, contents are the same as no modification is expected */
20429 		xfb_0.m_initial_data.resize(m_stride);
20430 		xfb_0.m_expected_data.resize(m_stride);
20431 
20432 		for (GLuint i = 0; i < m_stride; ++i)
20433 		{
20434 			xfb_0.m_initial_data[0]  = (glw::GLubyte)i;
20435 			xfb_0.m_expected_data[0] = (glw::GLubyte)i;
20436 		}
20437 
20438 		xfb_1.m_initial_data  = Utils::Type::vec4.GenerateDataPacked();
20439 		xfb_1.m_expected_data = uniform.m_initial_data;
20440 	}
20441 
20442 	break;
20443 
20444 	case FIRST_MISSING:
20445 	{
20446 		/* Test needs single uniform and two xfbs */
20447 		out_descriptors.resize(2);
20448 
20449 		/* Get references */
20450 		bufferDescriptor& uniform = out_descriptors[0];
20451 		bufferDescriptor& xfb_1   = out_descriptors[1];
20452 
20453 		/* Index */
20454 		uniform.m_index = 0;
20455 		xfb_1.m_index   = 1;
20456 
20457 		/* Target */
20458 		uniform.m_target = Utils::Buffer::Uniform;
20459 		xfb_1.m_target   = Utils::Buffer::Transform_feedback;
20460 
20461 		/* Data */
20462 		uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20463 
20464 		/* Data, contents are the same as no modification is expected */
20465 		xfb_1.m_initial_data  = Utils::Type::vec4.GenerateDataPacked();
20466 		xfb_1.m_expected_data = uniform.m_initial_data;
20467 	}
20468 
20469 	break;
20470 
20471 	case SECOND_MISSING:
20472 	{
20473 		/* Test needs single uniform and two xfbs */
20474 		out_descriptors.resize(2);
20475 
20476 		/* Get references */
20477 		bufferDescriptor& uniform = out_descriptors[0];
20478 		bufferDescriptor& xfb_0   = out_descriptors[1];
20479 
20480 		/* Index */
20481 		uniform.m_index = 0;
20482 		xfb_0.m_index   = 0;
20483 
20484 		/* Target */
20485 		uniform.m_target = Utils::Buffer::Uniform;
20486 		xfb_0.m_target   = Utils::Buffer::Transform_feedback;
20487 
20488 		/* Data */
20489 		uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20490 
20491 		/* Draw call will not be executed, contents does not matter */
20492 		xfb_0.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20493 	}
20494 
20495 	break;
20496 	}
20497 }
20498 
20499 /** Get list of names of varyings that will be registered with TransformFeedbackVaryings
20500  *
20501  * @param ignored
20502  * @param captured_varyings Vector of varying names to be captured
20503  **/
20504 void XFBStrideOfEmptyListAndAPITest::getCapturedVaryings(glw::GLuint /* test_case_index */,
20505 														 Utils::Program::NameVector& captured_varyings,
20506 														 GLint* xfb_components)
20507 {
20508 	captured_varyings.push_back("gs_fs1");
20509 	captured_varyings.push_back("gs_fs2");
20510 	*xfb_components	= 4;
20511 }
20512 
20513 /** Get body of main function for given shader stage
20514  *
20515  * @param ignored
20516  * @param stage            Shader stage
20517  * @param out_assignments  Set to empty
20518  * @param out_calculations Set to empty
20519  **/
20520 void XFBStrideOfEmptyListAndAPITest::getShaderBody(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
20521 												   std::string& out_assignments, std::string& out_calculations)
20522 {
20523 	out_calculations = "";
20524 
20525 	static const GLchar* gs = "    gs_fs1 = -uni_gs;\n"
20526 							  "    gs_fs2 = uni_gs;\n";
20527 	static const GLchar* fs = "    fs_out = vec4(gs_fs2);\n";
20528 
20529 	const GLchar* assignments = "";
20530 	switch (stage)
20531 	{
20532 	case Utils::Shader::FRAGMENT:
20533 		assignments = fs;
20534 		break;
20535 	case Utils::Shader::GEOMETRY:
20536 		assignments = gs;
20537 		break;
20538 	default:
20539 		break;
20540 	}
20541 
20542 	out_assignments = assignments;
20543 }
20544 
20545 /** Get interface of shader
20546  *
20547  * @param ignored
20548  * @param stage            Shader stage
20549  * @param out_interface    Set to ""
20550  **/
20551 void XFBStrideOfEmptyListAndAPITest::getShaderInterface(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
20552 														std::string& out_interface)
20553 {
20554 	static const GLchar* gs = "layout (xfb_buffer = 0, xfb_stride = 64) out vec4 gs_fs1;\n"
20555 							  "layout (xfb_buffer = 1, xfb_offset = 0)  out vec4 gs_fs2;\n"
20556 							  "\n"
20557 							  "layout(binding    = 0) uniform gs_block {\n"
20558 							  "    vec4 uni_gs;\n"
20559 							  "};\n";
20560 	static const GLchar* fs = "in  vec4 gs_fs2;\n"
20561 							  "out vec4 fs_out;\n";
20562 
20563 	switch (stage)
20564 	{
20565 	case Utils::Shader::FRAGMENT:
20566 		out_interface = fs;
20567 		break;
20568 	case Utils::Shader::GEOMETRY:
20569 		out_interface = gs;
20570 		break;
20571 	default:
20572 		out_interface = "";
20573 		return;
20574 	}
20575 }
20576 
20577 /** Returns buffer details in human readable form.
20578  *
20579  * @param test_case_index Index of test case
20580  *
20581  * @return Case description
20582  **/
20583 std::string XFBStrideOfEmptyListAndAPITest::getTestCaseName(GLuint test_case_index)
20584 {
20585 	std::string result;
20586 
20587 	switch (test_case_index)
20588 	{
20589 	case VALID:
20590 		result = "Valid case";
20591 		break;
20592 	case FIRST_MISSING:
20593 		result = "Missing xfb at index 0";
20594 		break;
20595 	case SECOND_MISSING:
20596 		result = "Missing xfb at index 1";
20597 		break;
20598 	default:
20599 		TCU_FAIL("Invalid enum");
20600 	}
20601 
20602 	return result;
20603 }
20604 
20605 /** Get number of test cases
20606  *
20607  * @return 2
20608  **/
20609 GLuint XFBStrideOfEmptyListAndAPITest::getTestCaseNumber()
20610 {
20611 	return 3;
20612 }
20613 
20614 /** Constructor
20615  *
20616  * @param context Test framework context
20617  **/
20618 XFBTooSmallStrideTest::XFBTooSmallStrideTest(deqp::Context& context)
20619 	: NegativeTestBase(context, "xfb_too_small_stride",
20620 					   "Test verifies that compiler reports error when xfb_stride sets not enough space")
20621 {
20622 }
20623 
20624 /** Source for given test case and stage
20625  *
20626  * @param test_case_index Index of test case
20627  * @param stage           Shader stage
20628  *
20629  * @return Shader source
20630  **/
20631 std::string XFBTooSmallStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
20632 {
20633 	static const GLchar* array_var_definition = "layout (xfb_buffer = 0, xfb_stride = 32) out;\n"
20634 												"\n"
20635 												"layout (xfb_offset = 16) out vec4 gohanARRAY[4];\n";
20636 	static const GLchar* block_var_definition = "layout (xfb_buffer = 0, xfb_stride = 32) out;\n"
20637 												"\n"
20638 												"layout (xfb_offset = 0) out Goku {\n"
20639 												"    vec4 gohan;\n"
20640 												"    vec4 goten;\n"
20641 												"    vec4 chichi;\n"
20642 												"} gokuARRAY;\n";
20643 	static const GLchar* offset_var_definition = "layout (xfb_buffer = 0, xfb_stride = 40) out;\n"
20644 												 "\n"
20645 												 "layout (xfb_offset = 32) out vec4 gohanARRAY;\n";
20646 	// 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;"
20647 	// To make the shader failed to compile, change xfb_stride to a value that is smaller than 32
20648 	static const GLchar* stride_var_definition = "layout (xfb_buffer = 0, xfb_stride = 28) out;\n"
20649 												 "\n"
20650 												 "layout (xfb_offset = 16, xfb_stride = 28) out vec4 gohanARRAY;\n";
20651 	static const GLchar* array_use = "    gohanINDEX[0] = result / 2;\n"
20652 									 "    gohanINDEX[1] = result / 4;\n"
20653 									 "    gohanINDEX[2] = result / 6;\n"
20654 									 "    gohanINDEX[3] = result / 8;\n";
20655 	static const GLchar* block_use = "    gokuINDEX.gohan  = result / 2;\n"
20656 									 "    gokuINDEX.goten  = result / 4;\n"
20657 									 "    gokuINDEX.chichi = result / 6;\n";
20658 	static const GLchar* output_use = "gohanINDEX = result / 4;\n";
20659 	static const GLchar* fs			= "#version 430 core\n"
20660 							  "#extension GL_ARB_enhanced_layouts : require\n"
20661 							  "\n"
20662 							  "in  vec4 gs_fs;\n"
20663 							  "out vec4 fs_out;\n"
20664 							  "\n"
20665 							  "void main()\n"
20666 							  "{\n"
20667 							  "    fs_out = gs_fs;\n"
20668 							  "}\n"
20669 							  "\n";
20670 	static const GLchar* gs_tested = "#version 430 core\n"
20671 									 "#extension GL_ARB_enhanced_layouts : require\n"
20672 									 "\n"
20673 									 "layout(points)                           in;\n"
20674 									 "layout(triangle_strip, max_vertices = 4) out;\n"
20675 									 "\n"
20676 									 "VAR_DEFINITION"
20677 									 "\n"
20678 									 "in  vec4 tes_gs[];\n"
20679 									 "out vec4 gs_fs;\n"
20680 									 "\n"
20681 									 "void main()\n"
20682 									 "{\n"
20683 									 "    vec4 result = tes_gs[0];\n"
20684 									 "\n"
20685 									 "VARIABLE_USE"
20686 									 "\n"
20687 									 "    gs_fs = result;\n"
20688 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
20689 									 "    EmitVertex();\n"
20690 									 "    gs_fs = result;\n"
20691 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
20692 									 "    EmitVertex();\n"
20693 									 "    gs_fs = result;\n"
20694 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
20695 									 "    EmitVertex();\n"
20696 									 "    gs_fs = result;\n"
20697 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
20698 									 "    EmitVertex();\n"
20699 									 "}\n"
20700 									 "\n";
20701 	static const GLchar* tcs = "#version 430 core\n"
20702 							   "#extension GL_ARB_enhanced_layouts : require\n"
20703 							   "\n"
20704 							   "layout(vertices = 1) out;\n"
20705 							   "\n"
20706 							   "in  vec4 vs_tcs[];\n"
20707 							   "out vec4 tcs_tes[];\n"
20708 							   "\n"
20709 							   "void main()\n"
20710 							   "{\n"
20711 							   "\n"
20712 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
20713 							   "\n"
20714 							   "    gl_TessLevelOuter[0] = 1.0;\n"
20715 							   "    gl_TessLevelOuter[1] = 1.0;\n"
20716 							   "    gl_TessLevelOuter[2] = 1.0;\n"
20717 							   "    gl_TessLevelOuter[3] = 1.0;\n"
20718 							   "    gl_TessLevelInner[0] = 1.0;\n"
20719 							   "    gl_TessLevelInner[1] = 1.0;\n"
20720 							   "}\n"
20721 							   "\n";
20722 	static const GLchar* tcs_tested = "#version 430 core\n"
20723 									  "#extension GL_ARB_enhanced_layouts : require\n"
20724 									  "\n"
20725 									  "layout(vertices = 1) out;\n"
20726 									  "\n"
20727 									  "VAR_DEFINITION"
20728 									  "\n"
20729 									  "in  vec4 vs_tcs[];\n"
20730 									  "out vec4 tcs_tes[];\n"
20731 									  "\n"
20732 									  "void main()\n"
20733 									  "{\n"
20734 									  "    vec4 result = vs_tcs[gl_InvocationID];\n"
20735 									  "\n"
20736 									  "VARIABLE_USE"
20737 									  "\n"
20738 									  "    tcs_tes[gl_InvocationID] = result;\n"
20739 									  "\n"
20740 									  "    gl_TessLevelOuter[0] = 1.0;\n"
20741 									  "    gl_TessLevelOuter[1] = 1.0;\n"
20742 									  "    gl_TessLevelOuter[2] = 1.0;\n"
20743 									  "    gl_TessLevelOuter[3] = 1.0;\n"
20744 									  "    gl_TessLevelInner[0] = 1.0;\n"
20745 									  "    gl_TessLevelInner[1] = 1.0;\n"
20746 									  "}\n"
20747 									  "\n";
20748 	static const GLchar* tes_tested = "#version 430 core\n"
20749 									  "#extension GL_ARB_enhanced_layouts : require\n"
20750 									  "\n"
20751 									  "layout(isolines, point_mode) in;\n"
20752 									  "\n"
20753 									  "VAR_DEFINITION"
20754 									  "\n"
20755 									  "in  vec4 tcs_tes[];\n"
20756 									  "out vec4 tes_gs;\n"
20757 									  "\n"
20758 									  "void main()\n"
20759 									  "{\n"
20760 									  "    vec4 result = tcs_tes[0];\n"
20761 									  "\n"
20762 									  "VARIABLE_USE"
20763 									  "\n"
20764 									  "    tes_gs += result;\n"
20765 									  "}\n"
20766 									  "\n";
20767 	static const GLchar* vs = "#version 430 core\n"
20768 							  "#extension GL_ARB_enhanced_layouts : require\n"
20769 							  "\n"
20770 							  "in  vec4 in_vs;\n"
20771 							  "out vec4 vs_tcs;\n"
20772 							  "\n"
20773 							  "void main()\n"
20774 							  "{\n"
20775 							  "    vs_tcs = in_vs;\n"
20776 							  "}\n"
20777 							  "\n";
20778 	static const GLchar* vs_tested = "#version 430 core\n"
20779 									 "#extension GL_ARB_enhanced_layouts : require\n"
20780 									 "\n"
20781 									 "VAR_DEFINITION"
20782 									 "\n"
20783 									 "in  vec4 in_vs;\n"
20784 									 "out vec4 vs_tcs;\n"
20785 									 "\n"
20786 									 "void main()\n"
20787 									 "{\n"
20788 									 "    vec4 result = in_vs;\n"
20789 									 "\n"
20790 									 "VARIABLE_USE"
20791 									 "\n"
20792 									 "    vs_tcs += result;\n"
20793 									 "}\n"
20794 									 "\n";
20795 
20796 	std::string source;
20797 	testCase&   test_case = m_test_cases[test_case_index];
20798 
20799 	if (test_case.m_stage == stage)
20800 	{
20801 		const GLchar* array	= "";
20802 		const GLchar* index	= "";
20803 		size_t		  position = 0;
20804 		size_t		  temp;
20805 		const GLchar* var_definition = 0;
20806 		const GLchar* var_use		 = 0;
20807 
20808 		switch (test_case.m_case)
20809 		{
20810 		case OFFSET:
20811 			var_definition = offset_var_definition;
20812 			var_use		   = output_use;
20813 			break;
20814 		case STRIDE:
20815 			var_definition = stride_var_definition;
20816 			var_use		   = output_use;
20817 			break;
20818 		case BLOCK:
20819 			var_definition = block_var_definition;
20820 			var_use		   = block_use;
20821 			break;
20822 		case ARRAY:
20823 			var_definition = array_var_definition;
20824 			var_use		   = array_use;
20825 			break;
20826 		default:
20827 			TCU_FAIL("Invalid enum");
20828 		}
20829 
20830 		switch (stage)
20831 		{
20832 		case Utils::Shader::GEOMETRY:
20833 			source = gs_tested;
20834 			array  = "[]";
20835 			index  = "[0]";
20836 			break;
20837 		case Utils::Shader::TESS_CTRL:
20838 			source = tcs_tested;
20839 			array  = "[]";
20840 			index  = "[gl_InvocationID]";
20841 			break;
20842 		case Utils::Shader::TESS_EVAL:
20843 			source = tes_tested;
20844 			array  = "[]";
20845 			index  = "[0]";
20846 			break;
20847 		case Utils::Shader::VERTEX:
20848 			source = vs_tested;
20849 			break;
20850 		default:
20851 			TCU_FAIL("Invalid enum");
20852 		}
20853 
20854 		temp = position;
20855 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
20856 		position = temp;
20857 		Utils::replaceToken("ARRAY", position, array, source);
20858 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
20859 
20860 		Utils::replaceAllTokens("INDEX", index, source);
20861 	}
20862 	else
20863 	{
20864 		switch (test_case.m_stage)
20865 		{
20866 		case Utils::Shader::GEOMETRY:
20867 			switch (stage)
20868 			{
20869 			case Utils::Shader::FRAGMENT:
20870 				source = fs;
20871 				break;
20872 			case Utils::Shader::VERTEX:
20873 				source = vs;
20874 				break;
20875 			default:
20876 				source = "";
20877 			}
20878 			break;
20879 		case Utils::Shader::TESS_CTRL:
20880 			switch (stage)
20881 			{
20882 			case Utils::Shader::FRAGMENT:
20883 				source = fs;
20884 				break;
20885 			case Utils::Shader::VERTEX:
20886 				source = vs;
20887 				break;
20888 			default:
20889 				source = "";
20890 			}
20891 			break;
20892 		case Utils::Shader::TESS_EVAL:
20893 			switch (stage)
20894 			{
20895 			case Utils::Shader::FRAGMENT:
20896 				source = fs;
20897 				break;
20898 			case Utils::Shader::TESS_CTRL:
20899 				source = tcs;
20900 				break;
20901 			case Utils::Shader::VERTEX:
20902 				source = vs;
20903 				break;
20904 			default:
20905 				source = "";
20906 			}
20907 			break;
20908 		case Utils::Shader::VERTEX:
20909 			switch (stage)
20910 			{
20911 			case Utils::Shader::FRAGMENT:
20912 				source = fs;
20913 				break;
20914 			default:
20915 				source = "";
20916 			}
20917 			break;
20918 		default:
20919 			TCU_FAIL("Invalid enum");
20920 			break;
20921 		}
20922 	}
20923 
20924 	return source;
20925 }
20926 
20927 /** Get description of test case
20928  *
20929  * @param test_case_index Index of test case
20930  *
20931  * @return Test case description
20932  **/
20933 std::string XFBTooSmallStrideTest::getTestCaseName(GLuint test_case_index)
20934 {
20935 	std::stringstream stream;
20936 	testCase&		  test_case = m_test_cases[test_case_index];
20937 
20938 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", case: ";
20939 
20940 	switch (test_case.m_case)
20941 	{
20942 	case OFFSET:
20943 		stream << "buffer stride: 40, vec4 offset: 32";
20944 		break;
20945 	case STRIDE:
20946 		stream << "buffer stride: 32, vec4 off 16 stride: 32";
20947 		break;
20948 	case BLOCK:
20949 		stream << "buffer stride: 32, block 3xvec4 offset 0";
20950 		break;
20951 	case ARRAY:
20952 		stream << "buffer stride: 32, vec4[4] offset 16";
20953 		break;
20954 	default:
20955 		TCU_FAIL("Invalid enum");
20956 	}
20957 
20958 	return stream.str();
20959 }
20960 
20961 /** Get number of test cases
20962  *
20963  * @return Number of test cases
20964  **/
20965 GLuint XFBTooSmallStrideTest::getTestCaseNumber()
20966 {
20967 	return static_cast<GLuint>(m_test_cases.size());
20968 }
20969 
20970 /** Selects if "compute" stage is relevant for test
20971  *
20972  * @param ignored
20973  *
20974  * @return false
20975  **/
20976 bool XFBTooSmallStrideTest::isComputeRelevant(GLuint /* test_case_index */)
20977 {
20978 	return false;
20979 }
20980 
20981 /** Prepare all test cases
20982  *
20983  **/
20984 void XFBTooSmallStrideTest::testInit()
20985 {
20986 	for (GLuint c = 0; c < CASE_MAX; ++c)
20987 	{
20988 		for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
20989 		{
20990 			/*
20991 			 It is invalid to define transform feedback output in TCS, according to spec:
20992 			 The data captured in transform feedback mode depends on the active programs on each of the shader stages.
20993 			 If a program is active for the geometry shader stage, transform feedback captures the vertices of each
20994 			 primitive emitted by the geometry shader. Otherwise, if a program is active for the tessellation evaluation
20995 			 shader stage, transform feedback captures each primitive produced by the tessellation primitive generator,
20996 			 whose vertices are processed by the tessellation evaluation shader. Otherwise, transform feedback captures
20997 			 each primitive processed by the vertex shader.
20998 			 */
20999 			if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
21000 				(Utils::Shader::FRAGMENT == stage))
21001 			{
21002 				continue;
21003 			}
21004 
21005 			testCase test_case = { (CASES)c, (Utils::Shader::STAGES)stage };
21006 
21007 			m_test_cases.push_back(test_case);
21008 		}
21009 	}
21010 }
21011 
21012 /** Constructor
21013  *
21014  * @param context Test framework context
21015  **/
21016 XFBVariableStrideTest::XFBVariableStrideTest(deqp::Context& context)
21017 	: NegativeTestBase(context, "xfb_variable_stride", "Test verifies that stride qualifier is respected")
21018 {
21019 }
21020 
21021 /** Source for given test case and stage
21022  *
21023  * @param test_case_index Index of test case
21024  * @param stage           Shader stage
21025  *
21026  * @return Shader source
21027  **/
21028 std::string XFBVariableStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
21029 {
21030 	static const GLchar* invalid_var_definition =
21031 		"const uint type_size = SIZE;\n"
21032 		"\n"
21033 		"layout (xfb_offset = 0, xfb_stride = 2 * type_size) out TYPE gokuARRAY;\n"
21034 		"layout (xfb_offset = type_size)                     out TYPE vegetaARRAY;\n";
21035 	static const GLchar* valid_var_definition =
21036 		"const uint type_size = SIZE;\n"
21037 		"\n"
21038 		"layout (xfb_offset = 0, xfb_stride = 2 * type_size) out TYPE gokuARRAY;\n";
21039 	static const GLchar* invalid_use = "    gokuINDEX   = TYPE(1);\n"
21040 									   "    vegetaINDEX = TYPE(0);\n"
21041 									   "    if (vec4(0) == result)\n"
21042 									   "    {\n"
21043 									   "        gokuINDEX   = TYPE(0);\n"
21044 									   "        vegetaINDEX = TYPE(1);\n"
21045 									   "    }\n";
21046 	static const GLchar* valid_use = "    gokuINDEX   = TYPE(1);\n"
21047 									 "    if (vec4(0) == result)\n"
21048 									 "    {\n"
21049 									 "        gokuINDEX   = TYPE(0);\n"
21050 									 "    }\n";
21051 	static const GLchar* fs = "#version 430 core\n"
21052 							  "#extension GL_ARB_enhanced_layouts : require\n"
21053 							  "\n"
21054 							  "in  vec4 any_fs;\n"
21055 							  "out vec4 fs_out;\n"
21056 							  "\n"
21057 							  "void main()\n"
21058 							  "{\n"
21059 							  "    fs_out = any_fs;\n"
21060 							  "}\n"
21061 							  "\n";
21062 	static const GLchar* gs_tested = "#version 430 core\n"
21063 									 "#extension GL_ARB_enhanced_layouts : require\n"
21064 									 "\n"
21065 									 "layout(points)                           in;\n"
21066 									 "layout(triangle_strip, max_vertices = 4) out;\n"
21067 									 "\n"
21068 									 "VAR_DEFINITION"
21069 									 "\n"
21070 									 "in  vec4 vs_any[];\n"
21071 									 "out vec4 any_fs;\n"
21072 									 "\n"
21073 									 "void main()\n"
21074 									 "{\n"
21075 									 "    vec4 result = vs_any[0];\n"
21076 									 "\n"
21077 									 "VARIABLE_USE"
21078 									 "\n"
21079 									 "    any_fs = result;\n"
21080 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
21081 									 "    EmitVertex();\n"
21082 									 "    any_fs = result;\n"
21083 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
21084 									 "    EmitVertex();\n"
21085 									 "    any_fs = result;\n"
21086 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
21087 									 "    EmitVertex();\n"
21088 									 "    any_fs = result;\n"
21089 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
21090 									 "    EmitVertex();\n"
21091 									 "}\n"
21092 									 "\n";
21093 	static const GLchar* tcs = "#version 430 core\n"
21094 							   "#extension GL_ARB_enhanced_layouts : require\n"
21095 							   "\n"
21096 							   "layout(vertices = 1) out;\n"
21097 							   "\n"
21098 							   "in  vec4 vs_any[];\n"
21099 							   "out vec4 tcs_tes[];\n"
21100 							   "\n"
21101 							   "void main()\n"
21102 							   "{\n"
21103 							   "\n"
21104 							   "    tcs_tes[gl_InvocationID] = vs_any[gl_InvocationID];\n"
21105 							   "\n"
21106 							   "    gl_TessLevelOuter[0] = 1.0;\n"
21107 							   "    gl_TessLevelOuter[1] = 1.0;\n"
21108 							   "    gl_TessLevelOuter[2] = 1.0;\n"
21109 							   "    gl_TessLevelOuter[3] = 1.0;\n"
21110 							   "    gl_TessLevelInner[0] = 1.0;\n"
21111 							   "    gl_TessLevelInner[1] = 1.0;\n"
21112 							   "}\n"
21113 							   "\n";
21114 	static const GLchar* tcs_tested = "#version 430 core\n"
21115 									  "#extension GL_ARB_enhanced_layouts : require\n"
21116 									  "\n"
21117 									  "layout(vertices = 1) out;\n"
21118 									  "\n"
21119 									  "VAR_DEFINITION"
21120 									  "\n"
21121 									  "in  vec4 vs_any[];\n"
21122 									  "out vec4 any_fs[];\n"
21123 									  "\n"
21124 									  "void main()\n"
21125 									  "{\n"
21126 									  "    vec4 result = vs_any[gl_InvocationID];\n"
21127 									  "\n"
21128 									  "VARIABLE_USE"
21129 									  "\n"
21130 									  "    any_fs[gl_InvocationID] = result;\n"
21131 									  "\n"
21132 									  "    gl_TessLevelOuter[0] = 1.0;\n"
21133 									  "    gl_TessLevelOuter[1] = 1.0;\n"
21134 									  "    gl_TessLevelOuter[2] = 1.0;\n"
21135 									  "    gl_TessLevelOuter[3] = 1.0;\n"
21136 									  "    gl_TessLevelInner[0] = 1.0;\n"
21137 									  "    gl_TessLevelInner[1] = 1.0;\n"
21138 									  "}\n"
21139 									  "\n";
21140 	static const GLchar* tes_tested = "#version 430 core\n"
21141 									  "#extension GL_ARB_enhanced_layouts : require\n"
21142 									  "\n"
21143 									  "layout(isolines, point_mode) in;\n"
21144 									  "\n"
21145 									  "VAR_DEFINITION"
21146 									  "\n"
21147 									  "in  vec4 tcs_tes[];\n"
21148 									  "out vec4 any_fs;\n"
21149 									  "\n"
21150 									  "void main()\n"
21151 									  "{\n"
21152 									  "    vec4 result = tcs_tes[0];\n"
21153 									  "\n"
21154 									  "VARIABLE_USE"
21155 									  "\n"
21156 									  "    any_fs = result;\n"
21157 									  "}\n"
21158 									  "\n";
21159 	static const GLchar* vs = "#version 430 core\n"
21160 							  "#extension GL_ARB_enhanced_layouts : require\n"
21161 							  "\n"
21162 							  "in  vec4 in_vs;\n"
21163 							  "out vec4 vs_any;\n"
21164 							  "\n"
21165 							  "void main()\n"
21166 							  "{\n"
21167 							  "    vs_any = in_vs;\n"
21168 							  "}\n"
21169 							  "\n";
21170 	static const GLchar* vs_tested = "#version 430 core\n"
21171 									 "#extension GL_ARB_enhanced_layouts : require\n"
21172 									 "\n"
21173 									 "VAR_DEFINITION"
21174 									 "\n"
21175 									 "in  vec4 in_vs;\n"
21176 									 "out vec4 any_fs;\n"
21177 									 "\n"
21178 									 "void main()\n"
21179 									 "{\n"
21180 									 "    vec4 result = in_vs;\n"
21181 									 "\n"
21182 									 "VARIABLE_USE"
21183 									 "\n"
21184 									 "    any_fs = result;\n"
21185 									 "}\n"
21186 									 "\n";
21187 
21188 	std::string source;
21189 	testCase&   test_case = m_test_cases[test_case_index];
21190 
21191 	if (test_case.m_stage == stage)
21192 	{
21193 		const GLchar* array = "";
21194 		GLchar		  buffer[16];
21195 		const GLchar* index	= "";
21196 		size_t		  position = 0;
21197 		size_t		  temp;
21198 		const GLchar* type_name		 = test_case.m_type.GetGLSLTypeName();
21199 		const GLchar* var_definition = 0;
21200 		const GLchar* var_use		 = 0;
21201 
21202 		sprintf(buffer, "%d", test_case.m_type.GetSize());
21203 
21204 		switch (test_case.m_case)
21205 		{
21206 		case VALID:
21207 			var_definition = valid_var_definition;
21208 			var_use		   = valid_use;
21209 			break;
21210 		case INVALID:
21211 			var_definition = invalid_var_definition;
21212 			var_use		   = invalid_use;
21213 			break;
21214 		default:
21215 			TCU_FAIL("Invalid enum");
21216 		}
21217 
21218 		switch (stage)
21219 		{
21220 		case Utils::Shader::GEOMETRY:
21221 			source = gs_tested;
21222 			array  = "[1]";
21223 			index  = "[0]";
21224 			break;
21225 		case Utils::Shader::TESS_CTRL:
21226 			source = tcs_tested;
21227 			array  = "[1]";
21228 			index  = "[gl_InvocationID]";
21229 			break;
21230 		case Utils::Shader::TESS_EVAL:
21231 			source = tes_tested;
21232 			array  = "[1]";
21233 			index  = "[0]";
21234 			break;
21235 		case Utils::Shader::VERTEX:
21236 			source = vs_tested;
21237 			break;
21238 		default:
21239 			TCU_FAIL("Invalid enum");
21240 		}
21241 
21242 		temp = position;
21243 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
21244 		position = temp;
21245 		Utils::replaceToken("SIZE", position, buffer, source);
21246 		Utils::replaceToken("ARRAY", position, array, source);
21247 		if (INVALID == test_case.m_case)
21248 		{
21249 			Utils::replaceToken("ARRAY", position, array, source);
21250 		}
21251 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
21252 
21253 		Utils::replaceAllTokens("TYPE", type_name, source);
21254 		Utils::replaceAllTokens("INDEX", index, source);
21255 	}
21256 	else
21257 	{
21258 		switch (test_case.m_stage)
21259 		{
21260 		case Utils::Shader::GEOMETRY:
21261 			switch (stage)
21262 			{
21263 			case Utils::Shader::FRAGMENT:
21264 				source = fs;
21265 				break;
21266 			case Utils::Shader::VERTEX:
21267 				source = vs;
21268 				break;
21269 			default:
21270 				source = "";
21271 			}
21272 			break;
21273 		case Utils::Shader::TESS_CTRL:
21274 			switch (stage)
21275 			{
21276 			case Utils::Shader::FRAGMENT:
21277 				source = fs;
21278 				break;
21279 			case Utils::Shader::VERTEX:
21280 				source = vs;
21281 				break;
21282 			default:
21283 				source = "";
21284 			}
21285 			break;
21286 		case Utils::Shader::TESS_EVAL:
21287 			switch (stage)
21288 			{
21289 			case Utils::Shader::FRAGMENT:
21290 				source = fs;
21291 				break;
21292 			case Utils::Shader::TESS_CTRL:
21293 				source = tcs;
21294 				break;
21295 			case Utils::Shader::VERTEX:
21296 				source = vs;
21297 				break;
21298 			default:
21299 				source = "";
21300 			}
21301 			break;
21302 		case Utils::Shader::VERTEX:
21303 			switch (stage)
21304 			{
21305 			case Utils::Shader::FRAGMENT:
21306 				source = fs;
21307 				break;
21308 			default:
21309 				source = "";
21310 			}
21311 			break;
21312 		default:
21313 			TCU_FAIL("Invalid enum");
21314 			break;
21315 		}
21316 	}
21317 
21318 	return source;
21319 }
21320 
21321 /** Get description of test case
21322  *
21323  * @param test_case_index Index of test case
21324  *
21325  * @return Test case description
21326  **/
21327 std::string XFBVariableStrideTest::getTestCaseName(GLuint test_case_index)
21328 {
21329 	std::stringstream stream;
21330 	testCase&		  test_case = m_test_cases[test_case_index];
21331 
21332 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
21333 		   << ", type: " << test_case.m_type.GetGLSLTypeName() << ", case: ";
21334 
21335 	switch (test_case.m_case)
21336 	{
21337 	case VALID:
21338 		stream << "valid";
21339 		break;
21340 	case INVALID:
21341 		stream << "invalid";
21342 		break;
21343 	default:
21344 		TCU_FAIL("Invalid enum");
21345 	}
21346 
21347 	return stream.str();
21348 }
21349 
21350 /** Get number of test cases
21351  *
21352  * @return Number of test cases
21353  **/
21354 GLuint XFBVariableStrideTest::getTestCaseNumber()
21355 {
21356 	return static_cast<GLuint>(m_test_cases.size());
21357 }
21358 
21359 /** Selects if "compute" stage is relevant for test
21360  *
21361  * @param ignored
21362  *
21363  * @return false
21364  **/
21365 bool XFBVariableStrideTest::isComputeRelevant(GLuint /* test_case_index */)
21366 {
21367 	return false;
21368 }
21369 
21370 /** Selects if compilation failure is expected result
21371  *
21372  * @param test_case_index Index of test case
21373  *
21374  * @return true
21375  **/
21376 bool XFBVariableStrideTest::isFailureExpected(GLuint test_case_index)
21377 {
21378 	testCase& test_case = m_test_cases[test_case_index];
21379 
21380 	return (INVALID == test_case.m_case);
21381 }
21382 
21383 /** Prepare all test cases
21384  *
21385  **/
21386 void XFBVariableStrideTest::testInit()
21387 {
21388 	const GLuint n_types = getTypesNumber();
21389 
21390 	for (GLuint i = 0; i < n_types; ++i)
21391 	{
21392 		const Utils::Type& type = getType(i);
21393 
21394 		/*
21395 		 Some of the cases are declared as following are considered as invalid,
21396 		 but accoring to spec, the following declaration is valid: shaders in the
21397 		 transform feedback capturing mode have an initial global default of layout(xfb_buffer=0) out,
21398 		 so for the first variable's declaration, the xfb_stride = 16 is applied on buffer 0,  for the
21399 		 second variable, its buffer is also inherited from global buffer 0, and its offset does not overflows
21400 		 the stride.
21401 
21402 		 The xfb_stride is the memory width of given buffer, not for variable even though xfb_stride
21403 		 is declared on the variable. It seems that the writter of this case misunderstand the concept of
21404 		 xfb_stride, because spec describes that xfb_stride can be declared multiple times for the same buffer,
21405 		 it is a compile or link-time error to have different values specified for the stride for the same buffer.
21406 
21407 		 int type_size = 8;
21408 		 layout (xfb_offset = 0, xfb_stride = 2 * type_size) out double goku;
21409 		 layout (xfb_offset = type_size)                     out double vegeta;
21410 		 */
21411 		// all the shaders are valid, so remove the following loop(it contains CASE_MAX is enum of valid and invalid)
21412 		// for (GLuint c = 0; c < CASE_MAX; ++c)
21413 		{
21414 			for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
21415 			{
21416 				if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
21417 					(Utils::Shader::FRAGMENT == stage))
21418 				{
21419 					continue;
21420 				}
21421 
21422 				testCase test_case = { (CASES)VALID, (Utils::Shader::STAGES)stage, type };
21423 
21424 				m_test_cases.push_back(test_case);
21425 			}
21426 		}
21427 	}
21428 }
21429 
21430 /** Constructor
21431  *
21432  * @param context Test framework context
21433  **/
21434 XFBBlockStrideTest::XFBBlockStrideTest(deqp::Context& context)
21435 	: TestBase(context, "xfb_block_stride", "Test verifies that stride qualifier is respected for blocks")
21436 {
21437 }
21438 
21439 /** Source for given test case and stage
21440  *
21441  * @param test_case_index Index of test case
21442  * @param stage           Shader stage
21443  *
21444  * @return Shader source
21445  **/
21446 std::string XFBBlockStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
21447 {
21448 	static const GLchar* var_definition = "layout (xfb_offset = 0, xfb_stride = 128) out Goku {\n"
21449 										  "    vec4 gohan;\n"
21450 										  "    vec4 goten;\n"
21451 										  "    vec4 chichi;\n"
21452 										  "} gokuARRAY;\n";
21453 	static const GLchar* var_use = "    gokuINDEX.gohan  = vec4(1, 0, 0, 0);\n"
21454 								   "    gokuINDEX.goten  = vec4(0, 0, 1, 0);\n"
21455 								   "    gokuINDEX.chichi = vec4(0, 1, 0, 0);\n"
21456 								   "    if (vec4(0) == result)\n"
21457 								   "    {\n"
21458 								   "        gokuINDEX.gohan  = vec4(0, 1, 1, 1);\n"
21459 								   "        gokuINDEX.goten  = vec4(1, 1, 0, 1);\n"
21460 								   "        gokuINDEX.chichi = vec4(1, 0, 1, 1);\n"
21461 								   "    }\n";
21462 	static const GLchar* gs_tested =
21463 		"#version 430 core\n"
21464 		"#extension GL_ARB_enhanced_layouts : require\n"
21465 		"\n"
21466 		"layout(points)                           in;\n"
21467 		"layout(triangle_strip, max_vertices = 4) out;\n"
21468 		"\n"
21469 		"VAR_DEFINITION"
21470 		"\n"
21471 		"out gl_PerVertex \n"
21472 		"{ \n"
21473 		"   vec4  gl_Position; \n" // gl_Position must be redeclared in separable program mode
21474 		"}; \n"
21475 		"in  vec4 tes_gs[];\n"
21476 		"out vec4 gs_fs;\n"
21477 		"\n"
21478 		"void main()\n"
21479 		"{\n"
21480 		"    vec4 result = tes_gs[0];\n"
21481 		"\n"
21482 		"VARIABLE_USE"
21483 		"\n"
21484 		"    gs_fs = result;\n"
21485 		"    gl_Position  = vec4(-1, -1, 0, 1);\n"
21486 		"    EmitVertex();\n"
21487 		"    gs_fs = result;\n"
21488 		"    gl_Position  = vec4(-1, 1, 0, 1);\n"
21489 		"    EmitVertex();\n"
21490 		"    gs_fs = result;\n"
21491 		"    gl_Position  = vec4(1, -1, 0, 1);\n"
21492 		"    EmitVertex();\n"
21493 		"    gs_fs = result;\n"
21494 		"    gl_Position  = vec4(1, 1, 0, 1);\n"
21495 		"    EmitVertex();\n"
21496 		"}\n"
21497 		"\n";
21498 	static const GLchar* tcs = "#version 430 core\n"
21499 							   "#extension GL_ARB_enhanced_layouts : require\n"
21500 							   "\n"
21501 							   "layout(vertices = 1) out;\n"
21502 							   "\n"
21503 							   "in  vec4 vs_tcs[];\n"
21504 							   "out vec4 tcs_tes[];\n"
21505 							   "\n"
21506 							   "void main()\n"
21507 							   "{\n"
21508 							   "\n"
21509 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
21510 							   "\n"
21511 							   "    gl_TessLevelOuter[0] = 1.0;\n"
21512 							   "    gl_TessLevelOuter[1] = 1.0;\n"
21513 							   "    gl_TessLevelOuter[2] = 1.0;\n"
21514 							   "    gl_TessLevelOuter[3] = 1.0;\n"
21515 							   "    gl_TessLevelInner[0] = 1.0;\n"
21516 							   "    gl_TessLevelInner[1] = 1.0;\n"
21517 							   "}\n"
21518 							   "\n";
21519 #if 0
21520 	static const GLchar* tcs_tested =
21521 		"#version 430 core\n"
21522 		"#extension GL_ARB_enhanced_layouts : require\n"
21523 		"\n"
21524 		"layout(vertices = 1) out;\n"
21525 		"\n"
21526 		"VAR_DEFINITION"
21527 		"\n"
21528 		"in  vec4 vs_tcs[];\n"
21529 		"out vec4 tcs_tes[];\n"
21530 		"\n"
21531 		"void main()\n"
21532 		"{\n"
21533 		"    vec4 result = vs_tcs[gl_InvocationID];\n"
21534 		"\n"
21535 		"VARIABLE_USE"
21536 		"\n"
21537 		"    tcs_tes[gl_InvocationID] = result;\n"
21538 		"\n"
21539 		"    gl_TessLevelOuter[0] = 1.0;\n"
21540 		"    gl_TessLevelOuter[1] = 1.0;\n"
21541 		"    gl_TessLevelOuter[2] = 1.0;\n"
21542 		"    gl_TessLevelOuter[3] = 1.0;\n"
21543 		"    gl_TessLevelInner[0] = 1.0;\n"
21544 		"    gl_TessLevelInner[1] = 1.0;\n"
21545 		"}\n"
21546 		"\n";
21547 #endif
21548 	static const GLchar* tes_tested = "#version 430 core\n"
21549 									  "#extension GL_ARB_enhanced_layouts : require\n"
21550 									  "\n"
21551 									  "layout(isolines, point_mode) in;\n"
21552 									  "\n"
21553 									  "VAR_DEFINITION"
21554 									  "\n"
21555 									  "in  vec4 tcs_tes[];\n"
21556 									  "out vec4 tes_gs;\n"
21557 									  "\n"
21558 									  "void main()\n"
21559 									  "{\n"
21560 									  "    vec4 result = tcs_tes[0];\n"
21561 									  "\n"
21562 									  "VARIABLE_USE"
21563 									  "\n"
21564 									  "    tes_gs += result;\n"
21565 									  "}\n"
21566 									  "\n";
21567 	static const GLchar* vs = "#version 430 core\n"
21568 							  "#extension GL_ARB_enhanced_layouts : require\n"
21569 							  "\n"
21570 							  "in  vec4 in_vs;\n"
21571 							  "out vec4 vs_tcs;\n"
21572 							  "out vec4 tes_gs;\n"
21573 							  "\n"
21574 							  "void main()\n"
21575 							  "{\n"
21576 							  "    vs_tcs = tes_gs = in_vs;\n"
21577 							  "}\n"
21578 							  "\n";
21579 	static const GLchar* vs_tested = "#version 430 core\n"
21580 									 "#extension GL_ARB_enhanced_layouts : require\n"
21581 									 "\n"
21582 									 "VAR_DEFINITION"
21583 									 "\n"
21584 									 "in  vec4 in_vs;\n"
21585 									 "out vec4 vs_tcs;\n"
21586 									 "\n"
21587 									 "void main()\n"
21588 									 "{\n"
21589 									 "    vec4 result = in_vs;\n"
21590 									 "\n"
21591 									 "VARIABLE_USE"
21592 									 "\n"
21593 									 "    vs_tcs += result;\n"
21594 									 "}\n"
21595 									 "\n";
21596 
21597 	std::string			  source;
21598 	Utils::Shader::STAGES test_case = m_test_cases[test_case_index];
21599 
21600 	if (test_case == stage)
21601 	{
21602 		const GLchar* array	= "";
21603 		const GLchar* index	= "";
21604 		size_t		  position = 0;
21605 		size_t		  temp;
21606 		// It is a compile time error to apply xfb_offset to the declaration of an unsized array(GLSL4.5 spec: Page73)
21607 		// change array = "[]" to "[1]"
21608 		switch (stage)
21609 		{
21610 		case Utils::Shader::GEOMETRY:
21611 			source = gs_tested;
21612 			array  = "[1]";
21613 			index  = "[0]";
21614 			break;
21615 /*
21616 			 It is invalid to define transform feedback output in HS
21617 			 */
21618 #if 0
21619 			case Utils::Shader::TESS_CTRL:
21620 			source = tcs_tested;
21621 			array = "[]";
21622 			index = "[gl_InvocationID]";
21623 			break;
21624 #endif
21625 		case Utils::Shader::TESS_EVAL:
21626 			source = tes_tested;
21627 			array  = "[1]";
21628 			index  = "[0]";
21629 			break;
21630 		case Utils::Shader::VERTEX:
21631 			source = vs_tested;
21632 			break;
21633 		default:
21634 			TCU_FAIL("Invalid enum");
21635 		}
21636 
21637 		temp = position;
21638 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
21639 		position = temp;
21640 		Utils::replaceToken("ARRAY", position, array, source);
21641 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
21642 
21643 		Utils::replaceAllTokens("INDEX", index, source);
21644 	}
21645 	else
21646 	{
21647 		switch (test_case)
21648 		{
21649 		case Utils::Shader::GEOMETRY:
21650 			switch (stage)
21651 			{
21652 			case Utils::Shader::VERTEX:
21653 				source = vs;
21654 				break;
21655 			default:
21656 				source = "";
21657 			}
21658 			break;
21659 		case Utils::Shader::TESS_CTRL:
21660 			switch (stage)
21661 			{
21662 			case Utils::Shader::VERTEX:
21663 				source = vs;
21664 				break;
21665 			default:
21666 				source = "";
21667 			}
21668 			break;
21669 		case Utils::Shader::TESS_EVAL:
21670 			switch (stage)
21671 			{
21672 			case Utils::Shader::TESS_CTRL:
21673 				source = tcs;
21674 				break;
21675 			case Utils::Shader::VERTEX:
21676 				source = vs;
21677 				break;
21678 			default:
21679 				source = "";
21680 			}
21681 			break;
21682 		case Utils::Shader::VERTEX:
21683 			source = "";
21684 			break;
21685 		default:
21686 			TCU_FAIL("Invalid enum");
21687 			break;
21688 		}
21689 	}
21690 
21691 	return source;
21692 }
21693 
21694 /** Get description of test case
21695  *
21696  * @param test_case_index Index of test case
21697  *
21698  * @return Test case description
21699  **/
21700 std::string XFBBlockStrideTest::getTestCaseName(GLuint test_case_index)
21701 {
21702 	std::stringstream stream;
21703 
21704 	stream << "Stage: " << Utils::Shader::GetStageName(m_test_cases[test_case_index]);
21705 
21706 	return stream.str();
21707 }
21708 
21709 /** Get number of test cases
21710  *
21711  * @return Number of test cases
21712  **/
21713 GLuint XFBBlockStrideTest::getTestCaseNumber()
21714 {
21715 	return static_cast<GLuint>(m_test_cases.size());
21716 }
21717 
21718 /** Inspects program for xfb stride
21719  *
21720  * @param program Program to query
21721  *
21722  * @return true if query results match expected values, false otherwise
21723  **/
21724 bool XFBBlockStrideTest::inspectProgram(Utils::Program& program)
21725 {
21726 	GLint stride = 0;
21727 
21728 	program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE,
21729 						1 /* buf_size */, &stride);
21730 
21731 	return (128 == stride);
21732 }
21733 
21734 /** Runs test case
21735  *
21736  * @param test_case_index Id of test case
21737  *
21738  * @return true if test case pass, false otherwise
21739  **/
21740 bool XFBBlockStrideTest::testCase(GLuint test_case_index)
21741 {
21742 	const std::string& gs_source = getShaderSource(test_case_index, Utils::Shader::GEOMETRY);
21743 	Utils::Program	 program(m_context);
21744 	const std::string& tcs_source		= getShaderSource(test_case_index, Utils::Shader::TESS_CTRL);
21745 	const std::string& tes_source		= getShaderSource(test_case_index, Utils::Shader::TESS_EVAL);
21746 	bool			   test_case_result = true;
21747 	const std::string& vs_source		= getShaderSource(test_case_index, Utils::Shader::VERTEX);
21748 
21749 	program.Init("" /* cs */, "", gs_source, tcs_source, tes_source, vs_source, true /* separable */);
21750 
21751 	test_case_result = inspectProgram(program);
21752 
21753 	return test_case_result;
21754 }
21755 
21756 /** Prepare all test cases
21757  *
21758  **/
21759 void XFBBlockStrideTest::testInit()
21760 {
21761 	for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
21762 	{
21763 		if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
21764 			(Utils::Shader::FRAGMENT == stage))
21765 		{
21766 			continue;
21767 		}
21768 
21769 		m_test_cases.push_back((Utils::Shader::STAGES)stage);
21770 	}
21771 }
21772 
21773 /** Constructor
21774  *
21775  * @param context Test context
21776  **/
21777 XFBBlockMemberStrideTest::XFBBlockMemberStrideTest(deqp::Context& context)
21778 	: BufferTestBase(context, "xfb_block_member_stride",
21779 					 "Test verifies that xfb_stride qualifier is respected for block member")
21780 {
21781 	/* Nothing to be done here */
21782 }
21783 
21784 /** Get descriptors of buffers necessary for test
21785  *
21786  * @param ignored
21787  * @param out_descriptors Descriptors of buffers used by test
21788  **/
21789 void XFBBlockMemberStrideTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
21790 													bufferDescriptor::Vector& out_descriptors)
21791 {
21792 	const Utils::Type& vec4 = Utils::Type::vec4;
21793 
21794 	/* Test needs single uniform and xfb */
21795 	out_descriptors.resize(2);
21796 
21797 	/* Get references */
21798 	bufferDescriptor& uniform = out_descriptors[0];
21799 	bufferDescriptor& xfb	 = out_descriptors[1];
21800 
21801 	/* Index */
21802 	uniform.m_index = 0;
21803 	xfb.m_index		= 0;
21804 
21805 	/* Target */
21806 	uniform.m_target = Utils::Buffer::Uniform;
21807 	xfb.m_target	 = Utils::Buffer::Transform_feedback;
21808 
21809 	/* Data */
21810 	static const GLuint			vec4_size   = 16;
21811 	const std::vector<GLubyte>& gohan_data  = vec4.GenerateDataPacked();
21812 	const std::vector<GLubyte>& goten_data  = vec4.GenerateDataPacked();
21813 	const std::vector<GLubyte>& chichi_data = vec4.GenerateDataPacked();
21814 
21815 	/* Uniform data */
21816 	uniform.m_initial_data.resize(3 * vec4_size);
21817 	memcpy(&uniform.m_initial_data[0] + 0, &gohan_data[0], vec4_size);
21818 	memcpy(&uniform.m_initial_data[0] + vec4_size, &goten_data[0], vec4_size);
21819 	memcpy(&uniform.m_initial_data[0] + 2 * vec4_size, &chichi_data[0], vec4_size);
21820 
21821 	/* XFB data */
21822 	xfb.m_initial_data.resize(4 * vec4_size);
21823 	xfb.m_expected_data.resize(4 * vec4_size);
21824 
21825 	for (GLuint i = 0; i < 4 * vec4_size; ++i)
21826 	{
21827 		xfb.m_initial_data[i]  = (glw::GLubyte)i;
21828 		xfb.m_expected_data[i] = (glw::GLubyte)i;
21829 	}
21830 
21831 	// the xfb_offset of "chichi" should be 32
21832 	memcpy(&xfb.m_expected_data[0] + 0, &gohan_data[0], vec4_size);
21833 	memcpy(&xfb.m_expected_data[0] + vec4_size, &goten_data[0], vec4_size);
21834 	memcpy(&xfb.m_expected_data[0] + 2 * vec4_size, &chichi_data[0], vec4_size);
21835 }
21836 
21837 /** Get body of main function for given shader stage
21838  *
21839  * @param ignored
21840  * @param stage            Shader stage
21841  * @param out_assignments  Set to empty
21842  * @param out_calculations Set to empty
21843  **/
21844 void XFBBlockMemberStrideTest::getShaderBody(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
21845 											 std::string& out_assignments, std::string& out_calculations)
21846 {
21847 	out_calculations = "";
21848 
21849 	static const GLchar* gs = "    gohan  = uni_gohan;\n"
21850 							  "    goten  = uni_goten;\n"
21851 							  "    chichi = uni_chichi;\n";
21852 	static const GLchar* fs = "    fs_out = gohan + goten + chichi;\n";
21853 
21854 	const GLchar* assignments = "";
21855 	switch (stage)
21856 	{
21857 	case Utils::Shader::FRAGMENT:
21858 		assignments = fs;
21859 		break;
21860 	case Utils::Shader::GEOMETRY:
21861 		assignments = gs;
21862 		break;
21863 	default:
21864 		break;
21865 	}
21866 
21867 	out_assignments = assignments;
21868 }
21869 
21870 /** Get interface of shader
21871  *
21872  * @param ignored
21873  * @param stage            Shader stage
21874  * @param out_interface    Set to ""
21875  **/
21876 void XFBBlockMemberStrideTest::getShaderInterface(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
21877 												  std::string& out_interface)
21878 {
21879 	static const GLchar* gs = "layout (xfb_buffer = 0, xfb_offset = 0) out Goku {\n"
21880 							  "                             vec4 gohan;\n"
21881 							  "    layout (xfb_stride = 48) vec4 goten;\n"
21882 							  "                             vec4 chichi;\n"
21883 							  "};\n"
21884 							  "layout(binding = 0) uniform gs_block {\n"
21885 							  "    vec4 uni_gohan;\n"
21886 							  "    vec4 uni_goten;\n"
21887 							  "    vec4 uni_chichi;\n"
21888 							  "};\n";
21889 	static const GLchar* fs = "in Goku {\n"
21890 							  "    vec4 gohan;\n"
21891 							  "    vec4 goten;\n"
21892 							  "    vec4 chichi;\n"
21893 							  "};\n"
21894 							  "out vec4 fs_out;\n";
21895 
21896 	switch (stage)
21897 	{
21898 	case Utils::Shader::FRAGMENT:
21899 		out_interface = fs;
21900 		break;
21901 	case Utils::Shader::GEOMETRY:
21902 		out_interface = gs;
21903 		break;
21904 	default:
21905 		out_interface = "";
21906 		return;
21907 	}
21908 }
21909 
21910 /** Inspects program to check if all resources are as expected
21911  *
21912  * @param ignored
21913  * @param program    Program instance
21914  * @param out_stream Error message
21915  *
21916  * @return true if everything is ok, false otherwise
21917  **/
21918 bool XFBBlockMemberStrideTest::inspectProgram(GLuint /* test_case_index*/, Utils::Program& program,
21919 											  std::stringstream& out_stream)
21920 {
21921 	const GLuint gohan_id  = program.GetResourceIndex("gohan", GL_TRANSFORM_FEEDBACK_VARYING);
21922 	const GLuint goten_id  = program.GetResourceIndex("goten", GL_TRANSFORM_FEEDBACK_VARYING);
21923 	const GLuint chichi_id = program.GetResourceIndex("chichi", GL_TRANSFORM_FEEDBACK_VARYING);
21924 
21925 	GLint gohan_offset  = 0;
21926 	GLint goten_offset  = 0;
21927 	GLint chichi_offset = 0;
21928 
21929 	program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, gohan_id, GL_OFFSET, 1, &gohan_offset);
21930 	program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, goten_id, GL_OFFSET, 1, &goten_offset);
21931 	program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, chichi_id, GL_OFFSET, 1, &chichi_offset);
21932 
21933 	// the xfb_offset of "chichi" should be 32
21934 	if ((0 != gohan_offset) || (16 != goten_offset) || (32 != chichi_offset))
21935 	{
21936 		out_stream << "Got wrong offset: [" << gohan_offset << ", " << goten_offset << ", " << chichi_offset
21937 				   << "] expected: [0, 16, 32]";
21938 		return false;
21939 	}
21940 
21941 	return true;
21942 }
21943 
21944 /** Constructor
21945  *
21946  * @param context Test framework context
21947  **/
21948 XFBDuplicatedStrideTest::XFBDuplicatedStrideTest(deqp::Context& context)
21949 	: NegativeTestBase(context, "xfb_duplicated_stride",
21950 					   "Test verifies that compiler reports error when conflicting stride qualifiers are used")
21951 {
21952 }
21953 
21954 /** Source for given test case and stage
21955  *
21956  * @param test_case_index Index of test case
21957  * @param stage           Shader stage
21958  *
21959  * @return Shader source
21960  **/
21961 std::string XFBDuplicatedStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
21962 {
21963 	static const GLchar* invalid_var_definition = "const uint valid_stride = 64;\n"
21964 												  "const uint conflicting_stride = 128;\n"
21965 												  "\n"
21966 												  "layout (xfb_buffer = 0, xfb_stride = valid_stride)       out;\n"
21967 												  "layout (xfb_buffer = 0, xfb_stride = conflicting_stride) out;\n";
21968 	static const GLchar* valid_var_definition = "const uint valid_stride = 64;\n"
21969 												"\n"
21970 												"layout (xfb_buffer = 0, xfb_stride = valid_stride) out;\n"
21971 												"layout (xfb_buffer = 0, xfb_stride = valid_stride) out;\n";
21972 	static const GLchar* fs = "#version 430 core\n"
21973 							  "#extension GL_ARB_enhanced_layouts : require\n"
21974 							  "\n"
21975 							  "in  vec4 any_fs;\n"
21976 							  "out vec4 fs_out;\n"
21977 							  "\n"
21978 							  "void main()\n"
21979 							  "{\n"
21980 							  "    fs_out = any_fs;\n"
21981 							  "}\n"
21982 							  "\n";
21983 	static const GLchar* gs_tested = "#version 430 core\n"
21984 									 "#extension GL_ARB_enhanced_layouts : require\n"
21985 									 "\n"
21986 									 "layout(points)                           in;\n"
21987 									 "layout(triangle_strip, max_vertices = 4) out;\n"
21988 									 "\n"
21989 									 "VAR_DEFINITION"
21990 									 "\n"
21991 									 "in  vec4 vs_any[];\n"
21992 									 "out vec4 any_fs;\n"
21993 									 "\n"
21994 									 "void main()\n"
21995 									 "{\n"
21996 									 "    vec4 result = vs_any[0];\n"
21997 									 "\n"
21998 									 "VARIABLE_USE"
21999 									 "\n"
22000 									 "    any_fs = result;\n"
22001 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
22002 									 "    EmitVertex();\n"
22003 									 "    any_fs = result;\n"
22004 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
22005 									 "    EmitVertex();\n"
22006 									 "    any_fs = result;\n"
22007 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
22008 									 "    EmitVertex();\n"
22009 									 "    any_fs = result;\n"
22010 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
22011 									 "    EmitVertex();\n"
22012 									 "}\n"
22013 									 "\n";
22014 	static const GLchar* tcs = "#version 430 core\n"
22015 							   "#extension GL_ARB_enhanced_layouts : require\n"
22016 							   "\n"
22017 							   "layout(vertices = 1) out;\n"
22018 							   "\n"
22019 							   "in  vec4 vs_any[];\n"
22020 							   "out vec4 tcs_tes[];\n"
22021 							   "\n"
22022 							   "void main()\n"
22023 							   "{\n"
22024 							   "\n"
22025 							   "    tcs_tes[gl_InvocationID] = vs_any[gl_InvocationID];\n"
22026 							   "\n"
22027 							   "    gl_TessLevelOuter[0] = 1.0;\n"
22028 							   "    gl_TessLevelOuter[1] = 1.0;\n"
22029 							   "    gl_TessLevelOuter[2] = 1.0;\n"
22030 							   "    gl_TessLevelOuter[3] = 1.0;\n"
22031 							   "    gl_TessLevelInner[0] = 1.0;\n"
22032 							   "    gl_TessLevelInner[1] = 1.0;\n"
22033 							   "}\n"
22034 							   "\n";
22035 	static const GLchar* tcs_tested = "#version 430 core\n"
22036 									  "#extension GL_ARB_enhanced_layouts : require\n"
22037 									  "\n"
22038 									  "layout(vertices = 1) out;\n"
22039 									  "\n"
22040 									  "VAR_DEFINITION"
22041 									  "\n"
22042 									  "in  vec4 vs_any[];\n"
22043 									  "out vec4 any_fs[];\n"
22044 									  "\n"
22045 									  "void main()\n"
22046 									  "{\n"
22047 									  "    vec4 result = vs_any[gl_InvocationID];\n"
22048 									  "\n"
22049 									  "VARIABLE_USE"
22050 									  "\n"
22051 									  "    any_fs[gl_InvocationID] = result;\n"
22052 									  "\n"
22053 									  "    gl_TessLevelOuter[0] = 1.0;\n"
22054 									  "    gl_TessLevelOuter[1] = 1.0;\n"
22055 									  "    gl_TessLevelOuter[2] = 1.0;\n"
22056 									  "    gl_TessLevelOuter[3] = 1.0;\n"
22057 									  "    gl_TessLevelInner[0] = 1.0;\n"
22058 									  "    gl_TessLevelInner[1] = 1.0;\n"
22059 									  "}\n"
22060 									  "\n";
22061 	static const GLchar* tes_tested = "#version 430 core\n"
22062 									  "#extension GL_ARB_enhanced_layouts : require\n"
22063 									  "\n"
22064 									  "layout(isolines, point_mode) in;\n"
22065 									  "\n"
22066 									  "VAR_DEFINITION"
22067 									  "\n"
22068 									  "in  vec4 tcs_tes[];\n"
22069 									  "out vec4 any_fs;\n"
22070 									  "\n"
22071 									  "void main()\n"
22072 									  "{\n"
22073 									  "    vec4 result = tcs_tes[0];\n"
22074 									  "\n"
22075 									  "VARIABLE_USE"
22076 									  "\n"
22077 									  "    any_fs = result;\n"
22078 									  "}\n"
22079 									  "\n";
22080 	static const GLchar* vs = "#version 430 core\n"
22081 							  "#extension GL_ARB_enhanced_layouts : require\n"
22082 							  "\n"
22083 							  "in  vec4 in_vs;\n"
22084 							  "out vec4 vs_any;\n"
22085 							  "\n"
22086 							  "void main()\n"
22087 							  "{\n"
22088 							  "    vs_any = in_vs;\n"
22089 							  "}\n"
22090 							  "\n";
22091 	static const GLchar* vs_tested = "#version 430 core\n"
22092 									 "#extension GL_ARB_enhanced_layouts : require\n"
22093 									 "\n"
22094 									 "VAR_DEFINITION"
22095 									 "\n"
22096 									 "in  vec4 in_vs;\n"
22097 									 "out vec4 any_fs;\n"
22098 									 "\n"
22099 									 "void main()\n"
22100 									 "{\n"
22101 									 "    vec4 result = in_vs;\n"
22102 									 "\n"
22103 									 "VARIABLE_USE"
22104 									 "\n"
22105 									 "    any_fs += result;\n"
22106 									 "}\n"
22107 									 "\n";
22108 
22109 	std::string source;
22110 	testCase&   test_case = m_test_cases[test_case_index];
22111 
22112 	if (test_case.m_stage == stage)
22113 	{
22114 		size_t		  position		 = 0;
22115 		const GLchar* var_definition = 0;
22116 		const GLchar* var_use		 = "";
22117 
22118 		switch (test_case.m_case)
22119 		{
22120 		case VALID:
22121 			var_definition = valid_var_definition;
22122 			break;
22123 		case INVALID:
22124 			var_definition = invalid_var_definition;
22125 			break;
22126 		default:
22127 			TCU_FAIL("Invalid enum");
22128 		}
22129 
22130 		switch (stage)
22131 		{
22132 		case Utils::Shader::GEOMETRY:
22133 			source = gs_tested;
22134 			break;
22135 		case Utils::Shader::TESS_CTRL:
22136 			source = tcs_tested;
22137 			break;
22138 		case Utils::Shader::TESS_EVAL:
22139 			source = tes_tested;
22140 			break;
22141 		case Utils::Shader::VERTEX:
22142 			source = vs_tested;
22143 			break;
22144 		default:
22145 			TCU_FAIL("Invalid enum");
22146 		}
22147 
22148 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
22149 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
22150 	}
22151 	else
22152 	{
22153 		switch (test_case.m_stage)
22154 		{
22155 		case Utils::Shader::GEOMETRY:
22156 			switch (stage)
22157 			{
22158 			case Utils::Shader::FRAGMENT:
22159 				source = fs;
22160 				break;
22161 			case Utils::Shader::VERTEX:
22162 				source = vs;
22163 				break;
22164 			default:
22165 				source = "";
22166 			}
22167 			break;
22168 		case Utils::Shader::TESS_CTRL:
22169 			switch (stage)
22170 			{
22171 			case Utils::Shader::FRAGMENT:
22172 				source = fs;
22173 				break;
22174 			case Utils::Shader::VERTEX:
22175 				source = vs;
22176 				break;
22177 			default:
22178 				source = "";
22179 			}
22180 			break;
22181 		case Utils::Shader::TESS_EVAL:
22182 			switch (stage)
22183 			{
22184 			case Utils::Shader::FRAGMENT:
22185 				source = fs;
22186 				break;
22187 			case Utils::Shader::TESS_CTRL:
22188 				source = tcs;
22189 				break;
22190 			case Utils::Shader::VERTEX:
22191 				source = vs;
22192 				break;
22193 			default:
22194 				source = "";
22195 			}
22196 			break;
22197 		case Utils::Shader::VERTEX:
22198 			switch (stage)
22199 			{
22200 			case Utils::Shader::FRAGMENT:
22201 				source = fs;
22202 				break;
22203 			default:
22204 				source = "";
22205 			}
22206 			break;
22207 		default:
22208 			TCU_FAIL("Invalid enum");
22209 			break;
22210 		}
22211 	}
22212 
22213 	return source;
22214 }
22215 
22216 /** Get description of test case
22217  *
22218  * @param test_case_index Index of test case
22219  *
22220  * @return Test case description
22221  **/
22222 std::string XFBDuplicatedStrideTest::getTestCaseName(GLuint test_case_index)
22223 {
22224 	std::stringstream stream;
22225 	testCase&		  test_case = m_test_cases[test_case_index];
22226 
22227 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", case: ";
22228 
22229 	switch (test_case.m_case)
22230 	{
22231 	case VALID:
22232 		stream << "valid";
22233 		break;
22234 	case INVALID:
22235 		stream << "invalid";
22236 		break;
22237 	default:
22238 		TCU_FAIL("Invalid enum");
22239 	}
22240 
22241 	return stream.str();
22242 }
22243 
22244 /** Get number of test cases
22245  *
22246  * @return Number of test cases
22247  **/
22248 GLuint XFBDuplicatedStrideTest::getTestCaseNumber()
22249 {
22250 	return static_cast<GLuint>(m_test_cases.size());
22251 }
22252 
22253 /** Selects if "compute" stage is relevant for test
22254  *
22255  * @param ignored
22256  *
22257  * @return false
22258  **/
22259 bool XFBDuplicatedStrideTest::isComputeRelevant(GLuint /* test_case_index */)
22260 {
22261 	return false;
22262 }
22263 
22264 /** Selects if compilation failure is expected result
22265  *
22266  * @param test_case_index Index of test case
22267  *
22268  * @return true
22269  **/
22270 bool XFBDuplicatedStrideTest::isFailureExpected(GLuint test_case_index)
22271 {
22272 	testCase& test_case = m_test_cases[test_case_index];
22273 
22274 	return (INVALID == test_case.m_case);
22275 }
22276 
22277 /** Prepare all test cases
22278  *
22279  **/
22280 void XFBDuplicatedStrideTest::testInit()
22281 {
22282 	for (GLuint c = 0; c < CASE_MAX; ++c)
22283 	{
22284 		for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
22285 		{
22286 			if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
22287 				(Utils::Shader::FRAGMENT == stage))
22288 			{
22289 				continue;
22290 			}
22291 
22292 			testCase test_case = { (CASES)c, (Utils::Shader::STAGES)stage };
22293 
22294 			m_test_cases.push_back(test_case);
22295 		}
22296 	}
22297 }
22298 
22299 /** Constructor
22300  *
22301  * @param context Test framework context
22302  **/
22303 XFBGetProgramResourceAPITest::XFBGetProgramResourceAPITest(deqp::Context& context)
22304 	: TestBase(context, "xfb_get_program_resource_api",
22305 			   "Test verifies that get program resource reports correct results for XFB")
22306 {
22307 }
22308 
22309 /** Source for given test case and stage
22310  *
22311  * @param test_case_index Index of test case
22312  * @param stage           Shader stage
22313  *
22314  * @return Shader source
22315  **/
22316 std::string XFBGetProgramResourceAPITest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
22317 {
22318 	static const GLchar* api_var_definition = "out TYPE b0_v1ARRAY;\n"
22319 											  "out TYPE b1_v1ARRAY;\n"
22320 											  "out TYPE b0_v3ARRAY;\n"
22321 											  "out TYPE b0_v0ARRAY;\n";
22322 	static const GLchar* xfb_var_definition =
22323 		"const uint type_size = SIZE;\n"
22324 		"\n"
22325 		"layout (xfb_buffer = 1, xfb_stride = 4 * type_size) out;\n"
22326 		"\n"
22327 		"layout (xfb_buffer = 0, xfb_offset = 1 * type_size) out TYPE b0_v1ARRAY;\n"
22328 		"layout (xfb_buffer = 1, xfb_offset = 1 * type_size) out TYPE b1_v1ARRAY;\n"
22329 		"layout (xfb_buffer = 0, xfb_offset = 3 * type_size) out TYPE b0_v3ARRAY;\n"
22330 		"layout (xfb_buffer = 0, xfb_offset = 0 * type_size) out TYPE b0_v0ARRAY;\n";
22331 	static const GLchar* var_use = "    b0_v1INDEX = TYPE(0);\n"
22332 								   "    b1_v1INDEX = TYPE(1);\n"
22333 								   "    b0_v3INDEX = TYPE(0);\n"
22334 								   "    b0_v0INDEX = TYPE(1);\n"
22335 								   "    if (vec4(0) == result)\n"
22336 								   "    {\n"
22337 								   "        b0_v1INDEX = TYPE(1);\n"
22338 								   "        b1_v1INDEX = TYPE(0);\n"
22339 								   "        b0_v3INDEX = TYPE(1);\n"
22340 								   "        b0_v0INDEX = TYPE(0);\n"
22341 								   "    }\n";
22342 	static const GLchar* gs_tested =
22343 		"#version 430 core\n"
22344 		"#extension GL_ARB_enhanced_layouts : require\n"
22345 		"\n"
22346 		"layout(points)                           in;\n"
22347 		"layout(triangle_strip, max_vertices = 4) out;\n"
22348 		"\n"
22349 		"VAR_DEFINITION"
22350 		"\n"
22351 		"out gl_PerVertex \n"
22352 		"{ \n"
22353 		"   vec4  gl_Position; \n" // gl_Position must be redeclared in separable program mode
22354 		"}; \n"
22355 		"in  vec4 tes_gs[];\n"
22356 		"out vec4 gs_fs;\n"
22357 		"\n"
22358 		"void main()\n"
22359 		"{\n"
22360 		"    vec4 result = tes_gs[0];\n"
22361 		"\n"
22362 		"VARIABLE_USE"
22363 		"\n"
22364 		"    gs_fs = result;\n"
22365 		"    gl_Position  = vec4(-1, -1, 0, 1);\n"
22366 		"    EmitVertex();\n"
22367 		"    gs_fs = result;\n"
22368 		"    gl_Position  = vec4(-1, 1, 0, 1);\n"
22369 		"    EmitVertex();\n"
22370 		"    gs_fs = result;\n"
22371 		"    gl_Position  = vec4(1, -1, 0, 1);\n"
22372 		"    EmitVertex();\n"
22373 		"    gs_fs = result;\n"
22374 		"    gl_Position  = vec4(1, 1, 0, 1);\n"
22375 		"    EmitVertex();\n"
22376 		"}\n"
22377 		"\n";
22378 #if 0
22379 	static const GLchar* tcs_tested =
22380 		"#version 430 core\n"
22381 		"#extension GL_ARB_enhanced_layouts : require\n"
22382 		"\n"
22383 		"layout(vertices = 1) out;\n"
22384 		"\n"
22385 		"VAR_DEFINITION"
22386 		"\n"
22387 		"in  vec4 vs_tcs[];\n"
22388 		"out vec4 tcs_tes[];\n"
22389 		"\n"
22390 		"void main()\n"
22391 		"{\n"
22392 		"    vec4 result = vs_tcs[gl_InvocationID];\n"
22393 		"\n"
22394 		"VARIABLE_USE"
22395 		"\n"
22396 		"    tcs_tes[gl_InvocationID] = result;\n"
22397 		"\n"
22398 		"    gl_TessLevelOuter[0] = 1.0;\n"
22399 		"    gl_TessLevelOuter[1] = 1.0;\n"
22400 		"    gl_TessLevelOuter[2] = 1.0;\n"
22401 		"    gl_TessLevelOuter[3] = 1.0;\n"
22402 		"    gl_TessLevelInner[0] = 1.0;\n"
22403 		"    gl_TessLevelInner[1] = 1.0;\n"
22404 		"}\n"
22405 		"\n";
22406 #endif
22407 	static const GLchar* tes_tested = "#version 430 core\n"
22408 									  "#extension GL_ARB_enhanced_layouts : require\n"
22409 									  "\n"
22410 									  "layout(isolines, point_mode) in;\n"
22411 									  "\n"
22412 									  "VAR_DEFINITION"
22413 									  "\n"
22414 									  "in  vec4 tcs_tes[];\n"
22415 									  "out vec4 tes_gs;\n"
22416 									  "\n"
22417 									  "void main()\n"
22418 									  "{\n"
22419 									  "    vec4 result = tcs_tes[0];\n"
22420 									  "\n"
22421 									  "VARIABLE_USE"
22422 									  "\n"
22423 									  "    tes_gs = result;\n"
22424 									  "}\n"
22425 									  "\n";
22426 	static const GLchar* vs_tested = "#version 430 core\n"
22427 									 "#extension GL_ARB_enhanced_layouts : require\n"
22428 									 "\n"
22429 									 "VAR_DEFINITION"
22430 									 "\n"
22431 									 "in  vec4 in_vs;\n"
22432 									 "out vec4 vs_tcs;\n"
22433 									 "\n"
22434 									 "void main()\n"
22435 									 "{\n"
22436 									 "    vec4 result = in_vs;\n"
22437 									 "\n"
22438 									 "VARIABLE_USE"
22439 									 "\n"
22440 									 "    vs_tcs = result;\n"
22441 									 "}\n"
22442 									 "\n";
22443 
22444 	std::string		 source;
22445 	const test_Case& test_case = m_test_cases[test_case_index];
22446 
22447 	if (test_case.m_stage == stage)
22448 	{
22449 		const GLchar* array = "";
22450 		GLchar		  buffer[16];
22451 		const GLchar* index	= "";
22452 		size_t		  position = 0;
22453 		size_t		  temp;
22454 		const GLchar* type_name		 = test_case.m_type.GetGLSLTypeName();
22455 		const GLchar* var_definition = 0;
22456 
22457 		sprintf(buffer, "%d", test_case.m_type.GetSize());
22458 
22459 		if (XFB == test_case.m_case)
22460 		{
22461 			var_definition = xfb_var_definition;
22462 		}
22463 		else
22464 		{
22465 			var_definition = api_var_definition;
22466 		}
22467 
22468 		// It is a compile time error to apply xfb_offset to the declaration of an unsized array(GLSL4.5 spec: Page73)
22469 		// change array = "[]" to "[1]"
22470 		switch (stage)
22471 		{
22472 		case Utils::Shader::GEOMETRY:
22473 			source = gs_tested;
22474 			array  = "[1]";
22475 			index  = "[0]";
22476 			break;
22477 // It is invalid to output transform feedback varyings in tessellation control shader
22478 #if 0
22479 		case Utils::Shader::TESS_CTRL:
22480 			source = tcs_tested;
22481 			array = "[]";
22482 			index = "[gl_InvocationID]";
22483 			break;
22484 #endif
22485 		case Utils::Shader::TESS_EVAL:
22486 			source = tes_tested;
22487 			array  = "[1]";
22488 			index  = "[0]";
22489 			break;
22490 		case Utils::Shader::VERTEX:
22491 			source = vs_tested;
22492 			break;
22493 		default:
22494 			TCU_FAIL("Invalid enum");
22495 		}
22496 
22497 		temp = position;
22498 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
22499 		if (XFB == test_case.m_case)
22500 		{
22501 			position = temp;
22502 			Utils::replaceToken("SIZE", position, buffer, source);
22503 		}
22504 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
22505 
22506 		Utils::replaceAllTokens("ARRAY", array, source);
22507 		Utils::replaceAllTokens("INDEX", index, source);
22508 		Utils::replaceAllTokens("TYPE", type_name, source);
22509 	}
22510 	else
22511 	{
22512 		source = "";
22513 	}
22514 
22515 	return source;
22516 }
22517 
22518 /** Get description of test case
22519  *
22520  * @param test_case_index Index of test case
22521  *
22522  * @return Test case description
22523  **/
22524 std::string XFBGetProgramResourceAPITest::getTestCaseName(GLuint test_case_index)
22525 {
22526 	std::stringstream stream;
22527 	const test_Case&  test_case = m_test_cases[test_case_index];
22528 
22529 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
22530 		   << ", type: " << test_case.m_type.GetGLSLTypeName() << ", case: ";
22531 
22532 	switch (test_case.m_case)
22533 	{
22534 	case INTERLEAVED:
22535 		stream << "interleaved";
22536 		break;
22537 	case SEPARATED:
22538 		stream << "separated";
22539 		break;
22540 	case XFB:
22541 		stream << "xfb";
22542 		break;
22543 	default:
22544 		TCU_FAIL("Invalid enum");
22545 	}
22546 
22547 	return stream.str();
22548 }
22549 
22550 /** Get number of test cases
22551  *
22552  * @return Number of test cases
22553  **/
22554 GLuint XFBGetProgramResourceAPITest::getTestCaseNumber()
22555 {
22556 	return static_cast<GLuint>(m_test_cases.size());
22557 }
22558 
22559 /** Inspects program for offset, buffer index, buffer stride and type
22560  *
22561  * @param test_case_index Index of test case
22562  * @param program         Program to query
22563  *
22564  * @return true if query results match expected values, false otherwise
22565  **/
22566 bool XFBGetProgramResourceAPITest::inspectProgram(glw::GLuint test_case_index, Utils::Program& program)
22567 {
22568 	GLint			 b0_stride	= 0;
22569 	GLint			 b1_stride	= 0;
22570 	GLint			 b0_v0_buf	= 0;
22571 	GLint			 b0_v0_offset = 0;
22572 	GLint			 b0_v0_type   = 0;
22573 	GLint			 b0_v1_buf	= 0;
22574 	GLint			 b0_v1_offset = 0;
22575 	GLint			 b0_v1_type   = 0;
22576 	GLint			 b0_v3_buf	= 0;
22577 	GLint			 b0_v3_offset = 0;
22578 	GLint			 b0_v3_type   = 0;
22579 	GLint			 b1_v1_buf	= 0;
22580 	GLint			 b1_v1_offset = 0;
22581 	GLint			 b1_v1_type   = 0;
22582 	const test_Case& test_case	= m_test_cases[test_case_index];
22583 	const GLenum	 type_enum	= test_case.m_type.GetTypeGLenum();
22584 	const GLint		 type_size	= test_case.m_type.GetSize();
22585 
22586 	GLuint b0_v0_index = program.GetResourceIndex("b0_v0", GL_TRANSFORM_FEEDBACK_VARYING);
22587 	GLuint b0_v1_index = program.GetResourceIndex("b0_v1", GL_TRANSFORM_FEEDBACK_VARYING);
22588 	GLuint b0_v3_index = program.GetResourceIndex("b0_v3", GL_TRANSFORM_FEEDBACK_VARYING);
22589 	GLuint b1_v1_index = program.GetResourceIndex("b1_v1", GL_TRANSFORM_FEEDBACK_VARYING);
22590 
22591 	program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v0_index, GL_OFFSET, 1 /* buf_size */, &b0_v0_offset);
22592 	program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v1_index, GL_OFFSET, 1 /* buf_size */, &b0_v1_offset);
22593 	program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v3_index, GL_OFFSET, 1 /* buf_size */, &b0_v3_offset);
22594 	program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b1_v1_index, GL_OFFSET, 1 /* buf_size */, &b1_v1_offset);
22595 
22596 	program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v0_index, GL_TYPE, 1 /* buf_size */, &b0_v0_type);
22597 	program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v1_index, GL_TYPE, 1 /* buf_size */, &b0_v1_type);
22598 	program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v3_index, GL_TYPE, 1 /* buf_size */, &b0_v3_type);
22599 	program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b1_v1_index, GL_TYPE, 1 /* buf_size */, &b1_v1_type);
22600 
22601 	program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v0_index, GL_TRANSFORM_FEEDBACK_BUFFER_INDEX,
22602 						1 /* buf_size */, &b0_v0_buf);
22603 	program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v1_index, GL_TRANSFORM_FEEDBACK_BUFFER_INDEX,
22604 						1 /* buf_size */, &b0_v1_buf);
22605 	program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v3_index, GL_TRANSFORM_FEEDBACK_BUFFER_INDEX,
22606 						1 /* buf_size */, &b0_v3_buf);
22607 	program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b1_v1_index, GL_TRANSFORM_FEEDBACK_BUFFER_INDEX,
22608 						1 /* buf_size */, &b1_v1_buf);
22609 
22610 	program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, b0_v0_buf, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE, 1 /* buf_size */,
22611 						&b0_stride);
22612 	program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, b1_v1_buf, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE, 1 /* buf_size */,
22613 						&b1_stride);
22614 
22615 	if (SEPARATED != test_case.m_case)
22616 	{
22617 		return (((GLint)(4 * type_size) == b0_stride) && ((GLint)(4 * type_size) == b1_stride) &&
22618 				((GLint)(0) == b0_v0_buf) && ((GLint)(0 * type_size) == b0_v0_offset) &&
22619 				((GLint)(type_enum) == b0_v0_type) && ((GLint)(0) == b0_v1_buf) &&
22620 				((GLint)(1 * type_size) == b0_v1_offset) && ((GLint)(type_enum) == b0_v1_type) &&
22621 				((GLint)(0) == b0_v3_buf) && ((GLint)(3 * type_size) == b0_v3_offset) &&
22622 				((GLint)(type_enum) == b0_v3_type) && ((GLint)(1) == b1_v1_buf) &&
22623 				((GLint)(1 * type_size) == b1_v1_offset) && ((GLint)(type_enum) == b1_v1_type));
22624 	}
22625 	else
22626 	{
22627 		return (((GLint)(1 * type_size) == b0_stride) && ((GLint)(1 * type_size) == b1_stride) &&
22628 				((GLint)(0) == b0_v0_buf) && ((GLint)(0) == b0_v0_offset) && ((GLint)(type_enum) == b0_v0_type) &&
22629 				((GLint)(1) == b0_v1_buf) && ((GLint)(0) == b0_v1_offset) && ((GLint)(type_enum) == b0_v1_type) &&
22630 				((GLint)(2) == b0_v3_buf) && ((GLint)(0) == b0_v3_offset) && ((GLint)(type_enum) == b0_v3_type) &&
22631 				((GLint)(3) == b1_v1_buf) && ((GLint)(0) == b1_v1_offset) && ((GLint)(type_enum) == b1_v1_type));
22632 	}
22633 }
22634 
22635 /** Insert gl_SkipComponents
22636  *
22637  * @param num_components How many gl_SkipComponents1 need to be inserted
22638  * @param varyings The transform feedback varyings string vector
22639  *
22640  **/
22641 void XFBGetProgramResourceAPITest::insertSkipComponents(int num_components, Utils::Program::NameVector& varyings)
22642 {
22643 	int num_component_4 = num_components / 4;
22644 	int num_component_1 = num_components % 4;
22645 	for (int i = 0; i < num_component_4; i++)
22646 	{
22647 		varyings.push_back("gl_SkipComponents4");
22648 	}
22649 	switch (num_component_1)
22650 	{
22651 	case 1:
22652 		varyings.push_back("gl_SkipComponents1");
22653 		break;
22654 	case 2:
22655 		varyings.push_back("gl_SkipComponents2");
22656 		break;
22657 	case 3:
22658 		varyings.push_back("gl_SkipComponents3");
22659 		break;
22660 	default:
22661 		break;
22662 	}
22663 }
22664 
22665 /** Runs test case
22666  *
22667  * @param test_case_index Id of test case
22668  *
22669  * @return true if test case pass, false otherwise
22670  **/
22671 bool XFBGetProgramResourceAPITest::testCase(GLuint test_case_index)
22672 {
22673 	const std::string& gs_source = getShaderSource(test_case_index, Utils::Shader::GEOMETRY);
22674 	Utils::Program	 program(m_context);
22675 	const std::string& tcs_source		= getShaderSource(test_case_index, Utils::Shader::TESS_CTRL);
22676 	const std::string& tes_source		= getShaderSource(test_case_index, Utils::Shader::TESS_EVAL);
22677 	const test_Case&   test_case		= m_test_cases[test_case_index];
22678 	bool			   test_case_result = true;
22679 	const std::string& vs_source		= getShaderSource(test_case_index, Utils::Shader::VERTEX);
22680 
22681 	// According to spec: gl_SkipComponents1 ~ gl_SkipComponents4 is treated as specifying a one- to four-component floating point output variables with undefined values.
22682 	// 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.
22683 
22684 	if (INTERLEAVED == test_case.m_case)
22685 	{
22686 		/*
22687 		 layout (xfb_buffer = 0, xfb_offset = 1 * type_size) out type b0_v1;
22688 		 layout (xfb_buffer = 1, xfb_offset = 1 * type_size) out type b1_v1;
22689 		 layout (xfb_buffer = 0, xfb_offset = 3 * type_size) out type b0_v3;
22690 		 layout (xfb_buffer = 0, xfb_offset = 0 * type_size) out type b0_v0;
22691 
22692 		 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,
22693 		 we need to calculate how many "gl_SkipComponents" need to be inserted.
22694 		 */
22695 		Utils::Program::NameVector captured_varyings;
22696 		captured_varyings.push_back("b0_v0");
22697 		captured_varyings.push_back("b0_v1");
22698 		// Compute how many gl_SkipComponents to be inserted
22699 		int numComponents = test_case.m_type.GetSize() / 4;
22700 		insertSkipComponents(numComponents, captured_varyings);
22701 		captured_varyings.push_back("b0_v3");
22702 		captured_varyings.push_back("gl_NextBuffer");
22703 		insertSkipComponents(numComponents, captured_varyings);
22704 		captured_varyings.push_back("b1_v1");
22705 		insertSkipComponents(numComponents * 2, captured_varyings);
22706 
22707 		program.Init("" /* cs */, "", gs_source, tcs_source, tes_source, vs_source, captured_varyings, true,
22708 					 true /* separable */);
22709 	}
22710 	else if (SEPARATED == test_case.m_case)
22711 	{
22712 		Utils::Program::NameVector captured_varyings;
22713 
22714 		captured_varyings.push_back("b0_v0");
22715 		captured_varyings.push_back("b0_v1");
22716 		captured_varyings.push_back("b0_v3");
22717 		captured_varyings.push_back("b1_v1");
22718 
22719 		program.Init("" /* cs */, "", gs_source, tcs_source, tes_source, vs_source, captured_varyings, false,
22720 					 true /* separable */);
22721 	}
22722 	else
22723 	{
22724 
22725 		program.Init("" /* cs */, "", gs_source, tcs_source, tes_source, vs_source, true /* separable */);
22726 	}
22727 
22728 	test_case_result = inspectProgram(test_case_index, program);
22729 
22730 	return test_case_result;
22731 }
22732 
22733 /** Prepare all test cases
22734  *
22735  **/
22736 void XFBGetProgramResourceAPITest::testInit()
22737 {
22738 	const Functions& gl		 = m_context.getRenderContext().getFunctions();
22739 	const GLuint	 n_types = getTypesNumber();
22740 	GLint			 max_xfb_int;
22741 	GLint			 max_xfb_sep;
22742 
22743 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_xfb_int);
22744 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
22745 
22746 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, &max_xfb_sep);
22747 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
22748 
22749 	GLint max_varyings;
22750 	gl.getIntegerv(GL_MAX_VARYING_COMPONENTS, &max_varyings);
22751 
22752 	for (GLuint i = 0; i < n_types; ++i)
22753 	{
22754 		// 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,
22755 		// 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
22756 		// shader valid, we can either skip the dmat4, dmat4x3 or query the implementation-dependent value MAX_VARYING_COMPONENTS before generating the shader
22757 		// to guarantee the number of varying not exceeded.
22758 		/*
22759 		 layout (xfb_buffer = 1, xfb_stride = 4 * type_size) out;
22760 		 layout (xfb_buffer = 0, xfb_offset = 1 * type_size) out type b0_v1;
22761 		 layout (xfb_buffer = 1, xfb_offset = 1 * type_size) out type b1_v1;
22762 		 layout (xfb_buffer = 0, xfb_offset = 3 * type_size) out type b0_v3;
22763 		 layout (xfb_buffer = 0, xfb_offset = 0 * type_size) out type b0_v0;
22764 		 in  vec4 in_vs;
22765 		 out vec4 vs_tcs;
22766 		 */
22767 		if (i == 7 || i == 9)
22768 			continue;
22769 		const Utils::Type& type = getType(i);
22770 		if (4 * type.GetNumComponents() + 4 > (GLuint)max_varyings)
22771 		{
22772 			continue;
22773 		}
22774 		for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
22775 		{
22776 			/*
22777 			 It is invalid to define transform feedback output in HS
22778 			 */
22779 			if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
22780 				(Utils::Shader::FRAGMENT == stage))
22781 			{
22782 				continue;
22783 			}
22784 
22785 			test_Case test_case_int = { INTERLEAVED, (Utils::Shader::STAGES)stage, type };
22786 			test_Case test_case_sep = { SEPARATED, (Utils::Shader::STAGES)stage, type };
22787 			test_Case test_case_xfb = { XFB, (Utils::Shader::STAGES)stage, type };
22788 
22789 			if ((int)type.GetSize() <= max_xfb_int)
22790 			{
22791 				m_test_cases.push_back(test_case_xfb);
22792 				m_test_cases.push_back(test_case_int);
22793 			}
22794 
22795 			if ((int)type.GetSize() <= max_xfb_sep)
22796 			{
22797 				m_test_cases.push_back(test_case_sep);
22798 			}
22799 		}
22800 	}
22801 }
22802 
22803 /** Constructor
22804  *
22805  * @param context Test context
22806  **/
22807 XFBOverrideQualifiersWithAPITest::XFBOverrideQualifiersWithAPITest(deqp::Context& context)
22808 	: BufferTestBase(context, "xfb_override_qualifiers_with_api",
22809 					 "Test verifies that xfb_offset qualifier is not overriden with API")
22810 {
22811 	/* Nothing to be done here */
22812 }
22813 
22814 /** Get descriptors of buffers necessary for test
22815  *
22816  * @param test_case_index Index of test case
22817  * @param out_descriptors Descriptors of buffers used by test
22818  **/
22819 void XFBOverrideQualifiersWithAPITest::getBufferDescriptors(glw::GLuint				  test_case_index,
22820 															bufferDescriptor::Vector& out_descriptors)
22821 {
22822 	const Utils::Type& type = getType(test_case_index);
22823 
22824 	/* Test needs single uniform and xfb */
22825 	out_descriptors.resize(2);
22826 
22827 	/* Get references */
22828 	bufferDescriptor& uniform = out_descriptors[0];
22829 	bufferDescriptor& xfb	 = out_descriptors[1];
22830 
22831 	/* Index */
22832 	uniform.m_index = 0;
22833 	xfb.m_index		= 0;
22834 
22835 	/* Target */
22836 	uniform.m_target = Utils::Buffer::Uniform;
22837 	xfb.m_target	 = Utils::Buffer::Transform_feedback;
22838 
22839 	/* Data */
22840 	const GLuint				gen_start   = Utils::s_rand;
22841 	const std::vector<GLubyte>& vegeta_data = type.GenerateData();
22842 	const std::vector<GLubyte>& trunks_data = type.GenerateData();
22843 	const std::vector<GLubyte>& goku_data   = type.GenerateData();
22844 
22845 	Utils::s_rand								= gen_start;
22846 	const std::vector<GLubyte>& vegeta_data_pck = type.GenerateDataPacked();
22847 	type.GenerateDataPacked(); // generate the data for trunks
22848 	const std::vector<GLubyte>& goku_data_pck = type.GenerateDataPacked();
22849 
22850 	const GLuint type_size	 = static_cast<GLuint>(vegeta_data.size());
22851 	const GLuint type_size_pck = static_cast<GLuint>(vegeta_data_pck.size());
22852 
22853 	/* Uniform data */
22854 	uniform.m_initial_data.resize(3 * type_size);
22855 	memcpy(&uniform.m_initial_data[0] + 0, &vegeta_data[0], type_size);
22856 	memcpy(&uniform.m_initial_data[0] + type_size, &trunks_data[0], type_size);
22857 	memcpy(&uniform.m_initial_data[0] + 2 * type_size, &goku_data[0], type_size);
22858 
22859 	/* XFB data */
22860 	xfb.m_initial_data.resize(3 * type_size_pck);
22861 	xfb.m_expected_data.resize(3 * type_size_pck);
22862 
22863 	for (GLuint i = 0; i < 3 * type_size_pck; ++i)
22864 	{
22865 		xfb.m_initial_data[i]  = (glw::GLubyte)i;
22866 		xfb.m_expected_data[i] = (glw::GLubyte)i;
22867 	}
22868 
22869 	memcpy(&xfb.m_expected_data[0] + 0, &goku_data_pck[0], type_size_pck);
22870 	memcpy(&xfb.m_expected_data[0] + 2 * type_size_pck, &vegeta_data_pck[0], type_size_pck);
22871 }
22872 
22873 /** Get list of names of varyings that will be registered with TransformFeedbackVaryings
22874  *
22875  * @param ignored
22876  * @param captured_varyings List of names
22877  **/
22878 void XFBOverrideQualifiersWithAPITest::getCapturedVaryings(glw::GLuint test_case_index,
22879 														   Utils::Program::NameVector& captured_varyings,
22880 														   GLint* xfb_components)
22881 {
22882 	captured_varyings.resize(1);
22883 
22884 	captured_varyings[0] = "trunks";
22885 
22886 	/* The test captures 3 varyings of type 'type' */
22887 	Utils::Type	type		= getType(test_case_index);
22888 	GLint		type_size	= type.GetSize(false);
22889 	*xfb_components			= 3 * type_size / 4;
22890 }
22891 
22892 /** Get body of main function for given shader stage
22893  *
22894  * @param test_case_index  Index of test case
22895  * @param stage            Shader stage
22896  * @param out_assignments  Set to empty
22897  * @param out_calculations Set to empty
22898  **/
22899 void XFBOverrideQualifiersWithAPITest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
22900 													 std::string& out_assignments, std::string& out_calculations)
22901 {
22902 	out_calculations = "";
22903 
22904 	static const GLchar* gs = "    vegeta = uni_vegeta;\n"
22905 							  "    trunks = uni_trunks;\n"
22906 							  "    goku   = uni_goku;\n";
22907 	static const GLchar* fs = "    fs_out = vec4(0);\n"
22908 							  "    if (TYPE(1) == goku + trunks + vegeta)\n"
22909 							  "    {\n"
22910 							  "        fs_out = vec4(1);\n"
22911 							  "    }\n";
22912 
22913 	const GLchar* assignments = "";
22914 	switch (stage)
22915 	{
22916 	case Utils::Shader::FRAGMENT:
22917 		assignments = fs;
22918 		break;
22919 	case Utils::Shader::GEOMETRY:
22920 		assignments = gs;
22921 		break;
22922 	default:
22923 		break;
22924 	}
22925 
22926 	out_assignments = assignments;
22927 
22928 	if (Utils::Shader::FRAGMENT == stage)
22929 	{
22930 		const Utils::Type& type = getType(test_case_index);
22931 
22932 		Utils::replaceAllTokens("TYPE", type.GetGLSLTypeName(), out_assignments);
22933 	}
22934 }
22935 
22936 /** Get interface of shader
22937  *
22938  * @param test_case_index  Index of test case
22939  * @param stage            Shader stage
22940  * @param out_interface    Set to ""
22941  **/
22942 void XFBOverrideQualifiersWithAPITest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
22943 														  std::string& out_interface)
22944 {
22945 	static const GLchar* gs = "const uint sizeof_type = SIZE;\n"
22946 							  "\n"
22947 							  "layout (xfb_offset = 2 * sizeof_type) flat out TYPE vegeta;\n"
22948 							  "                                      flat out TYPE trunks;\n"
22949 							  "layout (xfb_offset = 0)               flat out TYPE goku;\n"
22950 							  "\n"
22951 							  /*
22952 		 There is no packing qualifier for uniform block gs_block, according to spec, it should be "shared" by default,
22953 		 the definition equals to "layout(binding=0, shared)", if the block is declared as shared, each block member will
22954 		 not be packed, and each block member's layout in memory is implementation dependent, so we can't use the API
22955 		 glBufferData() to update the UBO directly, we need to query each block member's offset first, then upload the
22956 		 data to the corresponding offset, otherwise we can't get the correct data from UBO; to make the test passed,
22957 		 we need to add the qualifier std140,  and change the declaration as layout(binding=0, std140), which can make
22958 		 sure all the block members are packed and the application can upload the data by glBufferData() directly.
22959 		 */
22960 							  "layout(binding = 0, std140) uniform gs_block {\n"
22961 							  "    TYPE uni_vegeta;\n"
22962 							  "    TYPE uni_trunks;\n"
22963 							  "    TYPE uni_goku;\n"
22964 							  "};\n";
22965 	static const GLchar* fs = "flat in TYPE vegeta;\n"
22966 							  "flat in TYPE trunks;\n"
22967 							  "flat in TYPE goku;\n"
22968 							  "\n"
22969 							  "out vec4 fs_out;\n";
22970 
22971 	const Utils::Type& type = getType(test_case_index);
22972 
22973 	switch (stage)
22974 	{
22975 	case Utils::Shader::FRAGMENT:
22976 		out_interface = fs;
22977 		break;
22978 	case Utils::Shader::GEOMETRY:
22979 		out_interface = gs;
22980 		break;
22981 	default:
22982 		out_interface = "";
22983 		return;
22984 	}
22985 
22986 	if (Utils::Shader::GEOMETRY == stage)
22987 	{
22988 		GLchar		 buffer[16];
22989 		size_t		 position  = 0;
22990 		const GLuint type_size = type.GetSize();
22991 
22992 		sprintf(buffer, "%d", type_size);
22993 
22994 		Utils::replaceToken("SIZE", position, buffer, out_interface);
22995 	}
22996 
22997 	Utils::replaceAllTokens("TYPE", type.GetGLSLTypeName(), out_interface);
22998 }
22999 
23000 /** Get type name
23001  *
23002  * @param test_case_index Index of test case
23003  *
23004  * @return Name of type test in test_case_index
23005  **/
23006 std::string XFBOverrideQualifiersWithAPITest::getTestCaseName(glw::GLuint test_case_index)
23007 {
23008 	return getTypeName(test_case_index);
23009 }
23010 
23011 /** Returns number of types to test
23012  *
23013  * @return Number of types, 34
23014  **/
23015 glw::GLuint XFBOverrideQualifiersWithAPITest::getTestCaseNumber()
23016 {
23017 	return getTypesNumber();
23018 }
23019 
23020 /** Inspects program to check if all resources are as expected
23021  *
23022  * @param test_case_index Index of test case
23023  * @param program         Program instance
23024  * @param out_stream      Error message
23025  *
23026  * @return true if everything is ok, false otherwise
23027  **/
23028 bool XFBOverrideQualifiersWithAPITest::inspectProgram(GLuint test_case_index, Utils::Program& program,
23029 													  std::stringstream& out_stream)
23030 {
23031 	GLint			   stride	= 0;
23032 	const Utils::Type& type		 = getType(test_case_index);
23033 	const GLuint	   type_size = type.GetSize(false);
23034 
23035 	program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE,
23036 						1 /* buf_size */, &stride);
23037 
23038 	if ((GLint)(3 * type_size) != stride)
23039 	{
23040 		out_stream << "Stride is: " << stride << " expected: " << (3 * type_size);
23041 
23042 		return false;
23043 	}
23044 
23045 	return true;
23046 }
23047 
23048 /** Constructor
23049  *
23050  * @param context Test context
23051  **/
23052 XFBVertexStreamsTest::XFBVertexStreamsTest(deqp::Context& context)
23053 	: BufferTestBase(context, "xfb_vertex_streams",
23054 					 "Test verifies that xfb qualifier works with multiple output streams")
23055 {
23056 	/* Nothing to be done here */
23057 }
23058 
23059 /** Get descriptors of buffers necessary for test
23060  *
23061  * @param ignored
23062  * @param out_descriptors Descriptors of buffers used by test
23063  **/
23064 void XFBVertexStreamsTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
23065 												bufferDescriptor::Vector& out_descriptors)
23066 {
23067 	const Utils::Type& type = Utils::Type::vec4;
23068 
23069 	/* Test needs single uniform and three xfbs */
23070 	out_descriptors.resize(4);
23071 
23072 	/* Get references */
23073 	bufferDescriptor& uniform = out_descriptors[0];
23074 	bufferDescriptor& xfb_1   = out_descriptors[1];
23075 	bufferDescriptor& xfb_2   = out_descriptors[2];
23076 	bufferDescriptor& xfb_3   = out_descriptors[3];
23077 
23078 	/* Index */
23079 	uniform.m_index = 0;
23080 	xfb_1.m_index   = 1;
23081 	xfb_2.m_index   = 2;
23082 	xfb_3.m_index   = 3;
23083 
23084 	/* Target */
23085 	uniform.m_target = Utils::Buffer::Uniform;
23086 	xfb_1.m_target   = Utils::Buffer::Transform_feedback;
23087 	xfb_2.m_target   = Utils::Buffer::Transform_feedback;
23088 	xfb_3.m_target   = Utils::Buffer::Transform_feedback;
23089 
23090 	/* Data */
23091 	const std::vector<GLubyte>& goku_data   = type.GenerateData();
23092 	const std::vector<GLubyte>& gohan_data  = type.GenerateData();
23093 	const std::vector<GLubyte>& goten_data  = type.GenerateData();
23094 	const std::vector<GLubyte>& picolo_data = type.GenerateData();
23095 	const std::vector<GLubyte>& vegeta_data = type.GenerateData();
23096 	const std::vector<GLubyte>& bulma_data  = type.GenerateData();
23097 
23098 	const GLuint type_size = static_cast<GLuint>(vegeta_data.size());
23099 
23100 	/* Uniform data */
23101 	uniform.m_initial_data.resize(6 * type_size);
23102 	memcpy(&uniform.m_initial_data[0] + 0, &goku_data[0], type_size);
23103 	memcpy(&uniform.m_initial_data[0] + type_size, &gohan_data[0], type_size);
23104 	memcpy(&uniform.m_initial_data[0] + 2 * type_size, &goten_data[0], type_size);
23105 	memcpy(&uniform.m_initial_data[0] + 3 * type_size, &picolo_data[0], type_size);
23106 	memcpy(&uniform.m_initial_data[0] + 4 * type_size, &vegeta_data[0], type_size);
23107 	memcpy(&uniform.m_initial_data[0] + 5 * type_size, &bulma_data[0], type_size);
23108 
23109 	/* XFB data */
23110 	static const GLuint xfb_stride = 64;
23111 	xfb_1.m_initial_data.resize(xfb_stride);
23112 	xfb_1.m_expected_data.resize(xfb_stride);
23113 	xfb_2.m_initial_data.resize(xfb_stride);
23114 	xfb_2.m_expected_data.resize(xfb_stride);
23115 	xfb_3.m_initial_data.resize(xfb_stride);
23116 	xfb_3.m_expected_data.resize(xfb_stride);
23117 
23118 	for (GLuint i = 0; i < xfb_stride; ++i)
23119 	{
23120 		xfb_1.m_initial_data[i]  = (glw::GLubyte)i;
23121 		xfb_1.m_expected_data[i] = (glw::GLubyte)i;
23122 		xfb_2.m_initial_data[i]  = (glw::GLubyte)i;
23123 		xfb_2.m_expected_data[i] = (glw::GLubyte)i;
23124 		xfb_3.m_initial_data[i]  = (glw::GLubyte)i;
23125 		xfb_3.m_expected_data[i] = (glw::GLubyte)i;
23126 	}
23127 
23128 	memcpy(&xfb_1.m_expected_data[0] + 48, &goku_data[0], type_size);
23129 	memcpy(&xfb_1.m_expected_data[0] + 32, &gohan_data[0], type_size);
23130 	memcpy(&xfb_1.m_expected_data[0] + 16, &goten_data[0], type_size);
23131 	memcpy(&xfb_3.m_expected_data[0] + 48, &picolo_data[0], type_size);
23132 	memcpy(&xfb_3.m_expected_data[0] + 32, &vegeta_data[0], type_size);
23133 	memcpy(&xfb_2.m_expected_data[0] + 32, &bulma_data[0], type_size);
23134 }
23135 
23136 /** Get body of main function for given shader stage
23137  *
23138  * @param ignored
23139  * @param stage            Shader stage
23140  * @param out_assignments  Set to empty
23141  * @param out_calculations Set to empty
23142  **/
23143 void XFBVertexStreamsTest::getShaderBody(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
23144 										 std::string& out_assignments, std::string& out_calculations)
23145 {
23146 	out_calculations = "";
23147 
23148 	// the shader declares the output variables with different "stream" qualifier, to make the data can export to
23149 	// each stream, we must call the function EmitStreamVertex() and EndStreamPrimitive() to make each vertex emitted
23150 	// by the GS is assigned to specific stream.
23151 	static const GLchar* gs = "    goku   = uni_goku;\n"
23152 							  "    gohan  = uni_gohan;\n"
23153 							  "    goten  = uni_goten;\n"
23154 							  "    EmitStreamVertex(0);\n"
23155 							  "    EndStreamPrimitive(0);\n"
23156 							  "    picolo = uni_picolo;\n"
23157 							  "    vegeta = uni_vegeta;\n"
23158 							  "    EmitStreamVertex(1);\n"
23159 							  "    EndStreamPrimitive(1);\n"
23160 							  "    bulma  = uni_bulma;\n"
23161 							  "    EmitStreamVertex(2);\n"
23162 							  "    EndStreamPrimitive(2);\n";
23163 
23164 	static const GLchar* fs = "    fs_out = gohan + goku + goten;\n";
23165 
23166 	const GLchar* assignments = "";
23167 	switch (stage)
23168 	{
23169 	case Utils::Shader::FRAGMENT:
23170 		assignments = fs;
23171 		break;
23172 	case Utils::Shader::GEOMETRY:
23173 		assignments = gs;
23174 		break;
23175 	default:
23176 		break;
23177 	}
23178 
23179 	out_assignments = assignments;
23180 }
23181 
23182 /** Get interface of shader
23183  *
23184  * @param ignored
23185  * @param stage            Shader stage
23186  * @param out_interface    Set to ""
23187  **/
23188 void XFBVertexStreamsTest::getShaderInterface(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
23189 											  std::string& out_interface)
23190 {
23191 	static const GLchar* gs = "layout (xfb_buffer = 1, xfb_stride = 64) out;\n"
23192 							  "layout (xfb_buffer = 2, xfb_stride = 64) out;\n"
23193 							  "layout (xfb_buffer = 3, xfb_stride = 64) out;\n"
23194 							  "\n"
23195 							  "layout (stream = 0, xfb_buffer = 1, xfb_offset = 48) out vec4 goku;\n"
23196 							  "layout (stream = 0, xfb_buffer = 1, xfb_offset = 32) out vec4 gohan;\n"
23197 							  "layout (stream = 0, xfb_buffer = 1, xfb_offset = 16) out vec4 goten;\n"
23198 							  "layout (stream = 1, xfb_buffer = 3, xfb_offset = 48) out vec4 picolo;\n"
23199 							  "layout (stream = 1, xfb_buffer = 3, xfb_offset = 32) out vec4 vegeta;\n"
23200 							  "layout (stream = 2, xfb_buffer = 2, xfb_offset = 32) out vec4 bulma;\n"
23201 							  "\n"
23202 							  "layout(binding = 0) uniform gs_block {\n"
23203 							  "    vec4 uni_goku;\n"
23204 							  "    vec4 uni_gohan;\n"
23205 							  "    vec4 uni_goten;\n"
23206 							  "    vec4 uni_picolo;\n"
23207 							  "    vec4 uni_vegeta;\n"
23208 							  "    vec4 uni_bulma;\n"
23209 							  "};\n";
23210 	/*
23211 	 Fixed incorrect usage of in/out qualifier, the following variable should be input symbols for fragment shader
23212 	 */
23213 	static const GLchar* fs = "in vec4 goku;\n"
23214 							  "in vec4 gohan;\n"
23215 							  "in vec4 goten;\n"
23216 							  "\n"
23217 							  "out vec4 fs_out;\n";
23218 
23219 	switch (stage)
23220 	{
23221 	case Utils::Shader::FRAGMENT:
23222 		out_interface = fs;
23223 		break;
23224 	case Utils::Shader::GEOMETRY:
23225 		out_interface = gs;
23226 		break;
23227 	default:
23228 		out_interface = "";
23229 		return;
23230 	}
23231 }
23232 
23233 /** Constructor
23234  *
23235  * @param context Test framework context
23236  **/
23237 XFBMultipleVertexStreamsTest::XFBMultipleVertexStreamsTest(deqp::Context& context)
23238 	: NegativeTestBase(
23239 		  context, "xfb_multiple_vertex_streams",
23240 		  "Test verifies that compiler reports error when multiple streams are captured with same xfb_buffer")
23241 {
23242 }
23243 
23244 /** Source for given test case and stage
23245  *
23246  * @param ignored
23247  * @param stage           Shader stage
23248  *
23249  * @return Shader source
23250  **/
23251 std::string XFBMultipleVertexStreamsTest::getShaderSource(GLuint /* test_case_index */, Utils::Shader::STAGES stage)
23252 {
23253 	static const GLchar* var_definition = "const uint valid_stride = 64;\n"
23254 										  "\n"
23255 										  "layout (xfb_buffer = 1, xfb_stride = valid_stride) out;\n"
23256 										  "layout (xfb_buffer = 3, xfb_stride = valid_stride) out;\n"
23257 										  "\n"
23258 										  "\n"
23259 										  "layout (stream = 0, xfb_buffer = 1, xfb_offset = 48) out vec4 goku;\n"
23260 										  "layout (stream = 1, xfb_buffer = 1, xfb_offset = 32) out vec4 gohan;\n"
23261 										  "layout (stream = 2, xfb_buffer = 1, xfb_offset = 16) out vec4 goten;\n";
23262 	static const GLchar* var_use = "    goku  = result / 2;\n"
23263 								   "    gohan = result / 4;\n"
23264 								   "    goten = result / 6;\n";
23265 	static const GLchar* fs = "#version 430 core\n"
23266 							  "#extension GL_ARB_enhanced_layouts : require\n"
23267 							  "\n"
23268 							  "in  vec4 gs_fs;\n"
23269 							  "in  vec4 goku;\n"
23270 							  "out vec4 fs_out;\n"
23271 							  "\n"
23272 							  "void main()\n"
23273 							  "{\n"
23274 							  "    fs_out = gs_fs + goku;\n"
23275 							  "}\n"
23276 							  "\n";
23277 	static const GLchar* gs = "#version 430 core\n"
23278 							  "#extension GL_ARB_enhanced_layouts : require\n"
23279 							  "\n"
23280 							  "layout(points)                           in;\n"
23281 							  "layout(triangle_strip, max_vertices = 4) out;\n"
23282 							  "\n"
23283 							  "VAR_DEFINITION"
23284 							  "\n"
23285 							  "in  vec4 tes_gs[];\n"
23286 							  "out vec4 gs_fs;\n"
23287 							  "\n"
23288 							  "void main()\n"
23289 							  "{\n"
23290 							  "    vec4 result = tes_gs[0];\n"
23291 							  "\n"
23292 							  "VARIABLE_USE"
23293 							  "\n"
23294 							  "    gs_fs = result;\n"
23295 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
23296 							  "    EmitVertex();\n"
23297 							  "    gs_fs = result;\n"
23298 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
23299 							  "    EmitVertex();\n"
23300 							  "    gs_fs = result;\n"
23301 							  "    gl_Position  = vec4(1, -1, 0, 1);\n"
23302 							  "    EmitVertex();\n"
23303 							  "    gs_fs = result;\n"
23304 							  "    gl_Position  = vec4(1, 1, 0, 1);\n"
23305 							  "    EmitVertex();\n"
23306 							  "}\n"
23307 							  "\n";
23308 	static const GLchar* vs = "#version 430 core\n"
23309 							  "#extension GL_ARB_enhanced_layouts : require\n"
23310 							  "\n"
23311 							  "in  vec4 in_vs;\n"
23312 							  "out vec4 vs_tcs;\n"
23313 							  "\n"
23314 							  "void main()\n"
23315 							  "{\n"
23316 							  "    vs_tcs = in_vs;\n"
23317 							  "}\n"
23318 							  "\n";
23319 
23320 	std::string source;
23321 
23322 	if (Utils::Shader::GEOMETRY == stage)
23323 	{
23324 		size_t position = 0;
23325 
23326 		source = gs;
23327 
23328 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
23329 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
23330 	}
23331 	else
23332 	{
23333 		switch (stage)
23334 		{
23335 		case Utils::Shader::FRAGMENT:
23336 			source = fs;
23337 			break;
23338 		case Utils::Shader::VERTEX:
23339 			source = vs;
23340 			break;
23341 		default:
23342 			source = "";
23343 		}
23344 	}
23345 
23346 	return source;
23347 }
23348 
23349 /** Selects if "compute" stage is relevant for test
23350  *
23351  * @param ignored
23352  *
23353  * @return false
23354  **/
23355 bool XFBMultipleVertexStreamsTest::isComputeRelevant(GLuint /* test_case_index */)
23356 {
23357 	return false;
23358 }
23359 
23360 /** Constructor
23361  *
23362  * @param context Test framework context
23363  **/
23364 XFBExceedBufferLimitTest::XFBExceedBufferLimitTest(deqp::Context& context)
23365 	: NegativeTestBase(context, "xfb_exceed_buffer_limit",
23366 					   "Test verifies that compiler reports error when xfb_buffer qualifier exceeds limit")
23367 {
23368 }
23369 
23370 /** Source for given test case and stage
23371  *
23372  * @param test_case_index Index of test case
23373  * @param stage           Shader stage
23374  *
23375  * @return Shader source
23376  **/
23377 std::string XFBExceedBufferLimitTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
23378 {
23379 	static const GLchar* block_var_definition = "const uint buffer_index = BUFFER;\n"
23380 												"\n"
23381 												"layout (xfb_buffer = buffer_index, xfb_offset = 0) out Goku {\n"
23382 												"    vec4 member;\n"
23383 												"} gokuARRAY;\n";
23384 	static const GLchar* global_var_definition = "const uint buffer_index = BUFFER;\n"
23385 												 "\n"
23386 												 "layout (xfb_buffer = buffer_index) out;\n";
23387 	static const GLchar* vector_var_definition = "const uint buffer_index = BUFFER;\n"
23388 												 "\n"
23389 												 "layout (xfb_buffer = buffer_index) out vec4 gokuARRAY;\n";
23390 	static const GLchar* block_use  = "    gokuINDEX.member = result / 2;\n";
23391 	static const GLchar* global_use = "";
23392 	static const GLchar* vector_use = "    gokuINDEX = result / 2;\n";
23393 	static const GLchar* fs			= "#version 430 core\n"
23394 							  "#extension GL_ARB_enhanced_layouts : require\n"
23395 							  "\n"
23396 							  "in  vec4 gs_fs;\n"
23397 							  "out vec4 fs_out;\n"
23398 							  "\n"
23399 							  "void main()\n"
23400 							  "{\n"
23401 							  "    fs_out = gs_fs;\n"
23402 							  "}\n"
23403 							  "\n";
23404 	static const GLchar* gs_tested = "#version 430 core\n"
23405 									 "#extension GL_ARB_enhanced_layouts : require\n"
23406 									 "\n"
23407 									 "layout(points)                           in;\n"
23408 									 "layout(triangle_strip, max_vertices = 4) out;\n"
23409 									 "\n"
23410 									 "VAR_DEFINITION"
23411 									 "\n"
23412 									 "in  vec4 tes_gs[];\n"
23413 									 "out vec4 gs_fs;\n"
23414 									 "\n"
23415 									 "void main()\n"
23416 									 "{\n"
23417 									 "    vec4 result = tes_gs[0];\n"
23418 									 "\n"
23419 									 "VARIABLE_USE"
23420 									 "\n"
23421 									 "    gs_fs = result;\n"
23422 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
23423 									 "    EmitVertex();\n"
23424 									 "    gs_fs = result;\n"
23425 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
23426 									 "    EmitVertex();\n"
23427 									 "    gs_fs = result;\n"
23428 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
23429 									 "    EmitVertex();\n"
23430 									 "    gs_fs = result;\n"
23431 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
23432 									 "    EmitVertex();\n"
23433 									 "}\n"
23434 									 "\n";
23435 	static const GLchar* tcs = "#version 430 core\n"
23436 							   "#extension GL_ARB_enhanced_layouts : require\n"
23437 							   "\n"
23438 							   "layout(vertices = 1) out;\n"
23439 							   "\n"
23440 							   "in  vec4 vs_tcs[];\n"
23441 							   "out vec4 tcs_tes[];\n"
23442 							   "\n"
23443 							   "void main()\n"
23444 							   "{\n"
23445 							   "\n"
23446 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
23447 							   "\n"
23448 							   "    gl_TessLevelOuter[0] = 1.0;\n"
23449 							   "    gl_TessLevelOuter[1] = 1.0;\n"
23450 							   "    gl_TessLevelOuter[2] = 1.0;\n"
23451 							   "    gl_TessLevelOuter[3] = 1.0;\n"
23452 							   "    gl_TessLevelInner[0] = 1.0;\n"
23453 							   "    gl_TessLevelInner[1] = 1.0;\n"
23454 							   "}\n"
23455 							   "\n";
23456 	static const GLchar* tcs_tested = "#version 430 core\n"
23457 									  "#extension GL_ARB_enhanced_layouts : require\n"
23458 									  "\n"
23459 									  "layout(vertices = 1) out;\n"
23460 									  "\n"
23461 									  "VAR_DEFINITION"
23462 									  "\n"
23463 									  "in  vec4 vs_tcs[];\n"
23464 									  "out vec4 tcs_tes[];\n"
23465 									  "\n"
23466 									  "void main()\n"
23467 									  "{\n"
23468 									  "    vec4 result = vs_tcs[gl_InvocationID];\n"
23469 									  "\n"
23470 									  "VARIABLE_USE"
23471 									  "\n"
23472 									  "    tcs_tes[gl_InvocationID] = result;\n"
23473 									  "\n"
23474 									  "    gl_TessLevelOuter[0] = 1.0;\n"
23475 									  "    gl_TessLevelOuter[1] = 1.0;\n"
23476 									  "    gl_TessLevelOuter[2] = 1.0;\n"
23477 									  "    gl_TessLevelOuter[3] = 1.0;\n"
23478 									  "    gl_TessLevelInner[0] = 1.0;\n"
23479 									  "    gl_TessLevelInner[1] = 1.0;\n"
23480 									  "}\n"
23481 									  "\n";
23482 	static const GLchar* tes_tested = "#version 430 core\n"
23483 									  "#extension GL_ARB_enhanced_layouts : require\n"
23484 									  "\n"
23485 									  "layout(isolines, point_mode) in;\n"
23486 									  "\n"
23487 									  "VAR_DEFINITION"
23488 									  "\n"
23489 									  "in  vec4 tcs_tes[];\n"
23490 									  "out vec4 tes_gs;\n"
23491 									  "\n"
23492 									  "void main()\n"
23493 									  "{\n"
23494 									  "    vec4 result = tcs_tes[0];\n"
23495 									  "\n"
23496 									  "VARIABLE_USE"
23497 									  "\n"
23498 									  "    tes_gs += result;\n"
23499 									  "}\n"
23500 									  "\n";
23501 	static const GLchar* vs = "#version 430 core\n"
23502 							  "#extension GL_ARB_enhanced_layouts : require\n"
23503 							  "\n"
23504 							  "in  vec4 in_vs;\n"
23505 							  "out vec4 vs_tcs;\n"
23506 							  "\n"
23507 							  "void main()\n"
23508 							  "{\n"
23509 							  "    vs_tcs = in_vs;\n"
23510 							  "}\n"
23511 							  "\n";
23512 	static const GLchar* vs_tested = "#version 430 core\n"
23513 									 "#extension GL_ARB_enhanced_layouts : require\n"
23514 									 "\n"
23515 									 "VAR_DEFINITION"
23516 									 "\n"
23517 									 "in  vec4 in_vs;\n"
23518 									 "out vec4 vs_tcs;\n"
23519 									 "\n"
23520 									 "void main()\n"
23521 									 "{\n"
23522 									 "    vec4 result = in_vs;\n"
23523 									 "\n"
23524 									 "VARIABLE_USE"
23525 									 "\n"
23526 									 "    vs_tcs = result;\n"
23527 									 "}\n"
23528 									 "\n";
23529 
23530 	std::string source;
23531 	testCase&   test_case = m_test_cases[test_case_index];
23532 
23533 	if (test_case.m_stage == stage)
23534 	{
23535 		const GLchar*	array = "";
23536 		GLchar			 buffer[16];
23537 		const Functions& gl		   = m_context.getRenderContext().getFunctions();
23538 		const GLchar*	index	 = "";
23539 		GLint			 max_n_xfb = 0;
23540 		size_t			 position  = 0;
23541 		size_t			 temp;
23542 		const GLchar*	var_definition = 0;
23543 		const GLchar*	var_use		= 0;
23544 
23545 		gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_n_xfb);
23546 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
23547 
23548 		sprintf(buffer, "%d", max_n_xfb);
23549 
23550 		switch (test_case.m_case)
23551 		{
23552 		case BLOCK:
23553 			var_definition = block_var_definition;
23554 			var_use		   = block_use;
23555 			break;
23556 		case GLOBAL:
23557 			var_definition = global_var_definition;
23558 			var_use		   = global_use;
23559 			break;
23560 		case VECTOR:
23561 			var_definition = vector_var_definition;
23562 			var_use		   = vector_use;
23563 			break;
23564 		default:
23565 			TCU_FAIL("Invalid enum");
23566 		}
23567 
23568 		switch (stage)
23569 		{
23570 		case Utils::Shader::GEOMETRY:
23571 			source = gs_tested;
23572 			array  = "[]";
23573 			index  = "[0]";
23574 			break;
23575 		case Utils::Shader::TESS_CTRL:
23576 			source = tcs_tested;
23577 			array  = "[]";
23578 			index  = "[gl_InvocationID]";
23579 			break;
23580 		case Utils::Shader::TESS_EVAL:
23581 			source = tes_tested;
23582 			array  = "[]";
23583 			index  = "[0]";
23584 			break;
23585 		case Utils::Shader::VERTEX:
23586 			source = vs_tested;
23587 			break;
23588 		default:
23589 			TCU_FAIL("Invalid enum");
23590 		}
23591 
23592 		temp = position;
23593 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
23594 		position = temp;
23595 		Utils::replaceToken("BUFFER", position, buffer, source);
23596 		if (GLOBAL != test_case.m_case)
23597 		{
23598 			Utils::replaceToken("ARRAY", position, array, source);
23599 		}
23600 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
23601 
23602 		Utils::replaceAllTokens("INDEX", index, source);
23603 	}
23604 	else
23605 	{
23606 		switch (test_case.m_stage)
23607 		{
23608 		case Utils::Shader::GEOMETRY:
23609 			switch (stage)
23610 			{
23611 			case Utils::Shader::FRAGMENT:
23612 				source = fs;
23613 				break;
23614 			case Utils::Shader::VERTEX:
23615 				source = vs;
23616 				break;
23617 			default:
23618 				source = "";
23619 			}
23620 			break;
23621 		case Utils::Shader::TESS_CTRL:
23622 			switch (stage)
23623 			{
23624 			case Utils::Shader::FRAGMENT:
23625 				source = fs;
23626 				break;
23627 			case Utils::Shader::VERTEX:
23628 				source = vs;
23629 				break;
23630 			default:
23631 				source = "";
23632 			}
23633 			break;
23634 		case Utils::Shader::TESS_EVAL:
23635 			switch (stage)
23636 			{
23637 			case Utils::Shader::FRAGMENT:
23638 				source = fs;
23639 				break;
23640 			case Utils::Shader::TESS_CTRL:
23641 				source = tcs;
23642 				break;
23643 			case Utils::Shader::VERTEX:
23644 				source = vs;
23645 				break;
23646 			default:
23647 				source = "";
23648 			}
23649 			break;
23650 		case Utils::Shader::VERTEX:
23651 			switch (stage)
23652 			{
23653 			case Utils::Shader::FRAGMENT:
23654 				source = fs;
23655 				break;
23656 			default:
23657 				source = "";
23658 			}
23659 			break;
23660 		default:
23661 			TCU_FAIL("Invalid enum");
23662 			break;
23663 		}
23664 	}
23665 
23666 	return source;
23667 }
23668 
23669 /** Get description of test case
23670  *
23671  * @param test_case_index Index of test case
23672  *
23673  * @return Test case description
23674  **/
23675 std::string XFBExceedBufferLimitTest::getTestCaseName(GLuint test_case_index)
23676 {
23677 	std::stringstream stream;
23678 	testCase&		  test_case = m_test_cases[test_case_index];
23679 
23680 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", case: ";
23681 
23682 	switch (test_case.m_case)
23683 	{
23684 	case BLOCK:
23685 		stream << "BLOCK";
23686 		break;
23687 	case GLOBAL:
23688 		stream << "GLOBAL";
23689 		break;
23690 	case VECTOR:
23691 		stream << "VECTOR";
23692 		break;
23693 	default:
23694 		TCU_FAIL("Invalid enum");
23695 	}
23696 
23697 	return stream.str();
23698 }
23699 
23700 /** Get number of test cases
23701  *
23702  * @return Number of test cases
23703  **/
23704 GLuint XFBExceedBufferLimitTest::getTestCaseNumber()
23705 {
23706 	return static_cast<GLuint>(m_test_cases.size());
23707 }
23708 
23709 /** Selects if "compute" stage is relevant for test
23710  *
23711  * @param ignored
23712  *
23713  * @return false
23714  **/
23715 bool XFBExceedBufferLimitTest::isComputeRelevant(GLuint /* test_case_index */)
23716 {
23717 	return false;
23718 }
23719 
23720 /** Prepare all test cases
23721  *
23722  **/
23723 void XFBExceedBufferLimitTest::testInit()
23724 {
23725 	for (GLuint c = 0; c < CASE_MAX; ++c)
23726 	{
23727 		for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
23728 		{
23729 			if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
23730 				(Utils::Shader::FRAGMENT == stage))
23731 			{
23732 				continue;
23733 			}
23734 
23735 			testCase test_case = { (CASES)c, (Utils::Shader::STAGES)stage };
23736 
23737 			m_test_cases.push_back(test_case);
23738 		}
23739 	}
23740 }
23741 
23742 /** Constructor
23743  *
23744  * @param context Test framework context
23745  **/
23746 XFBExceedOffsetLimitTest::XFBExceedOffsetLimitTest(deqp::Context& context)
23747 	: NegativeTestBase(context, "xfb_exceed_offset_limit",
23748 					   "Test verifies that compiler reports error when xfb_offset qualifier exceeds limit")
23749 {
23750 }
23751 
23752 /** Source for given test case and stage
23753  *
23754  * @param test_case_index Index of test case
23755  * @param stage           Shader stage
23756  *
23757  * @return Shader source
23758  **/
23759 std::string XFBExceedOffsetLimitTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
23760 {
23761 	static const GLchar* block_var_definition = "const uint max_size = SIZE;\n"
23762 												"\n"
23763 												"layout (xfb_buffer = 0, xfb_offset = max_size + 16) out Goku {\n"
23764 												"    vec4 member;\n"
23765 												"} gokuARRAY;\n";
23766 	static const GLchar* global_var_definition = "const uint max_size = SIZE;\n"
23767 												 "\n"
23768 												 "layout (xfb_buffer = 0, xfb_stride = max_size + 16) out;\n";
23769 	static const GLchar* vector_var_definition =
23770 		"const uint max_size = SIZE;\n"
23771 		"\n"
23772 		"layout (xfb_buffer = 0, xfb_offset = max_size + 16) out vec4 gokuARRAY;\n";
23773 	static const GLchar* block_use  = "    gokuINDEX.member = result / 2;\n";
23774 	static const GLchar* global_use = "";
23775 	static const GLchar* vector_use = "    gokuINDEX = result / 2;\n";
23776 	static const GLchar* fs			= "#version 430 core\n"
23777 							  "#extension GL_ARB_enhanced_layouts : require\n"
23778 							  "\n"
23779 							  "in  vec4 gs_fs;\n"
23780 							  "out vec4 fs_out;\n"
23781 							  "\n"
23782 							  "void main()\n"
23783 							  "{\n"
23784 							  "    fs_out = gs_fs;\n"
23785 							  "}\n"
23786 							  "\n";
23787 	static const GLchar* gs_tested = "#version 430 core\n"
23788 									 "#extension GL_ARB_enhanced_layouts : require\n"
23789 									 "\n"
23790 									 "layout(points)                           in;\n"
23791 									 "layout(triangle_strip, max_vertices = 4) out;\n"
23792 									 "\n"
23793 									 "VAR_DEFINITION"
23794 									 "\n"
23795 									 "in  vec4 tes_gs[];\n"
23796 									 "out vec4 gs_fs;\n"
23797 									 "\n"
23798 									 "void main()\n"
23799 									 "{\n"
23800 									 "    vec4 result = tes_gs[0];\n"
23801 									 "\n"
23802 									 "VARIABLE_USE"
23803 									 "\n"
23804 									 "    gs_fs = result;\n"
23805 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
23806 									 "    EmitVertex();\n"
23807 									 "    gs_fs = result;\n"
23808 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
23809 									 "    EmitVertex();\n"
23810 									 "    gs_fs = result;\n"
23811 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
23812 									 "    EmitVertex();\n"
23813 									 "    gs_fs = result;\n"
23814 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
23815 									 "    EmitVertex();\n"
23816 									 "}\n"
23817 									 "\n";
23818 	static const GLchar* tcs = "#version 430 core\n"
23819 							   "#extension GL_ARB_enhanced_layouts : require\n"
23820 							   "\n"
23821 							   "layout(vertices = 1) out;\n"
23822 							   "\n"
23823 							   "in  vec4 vs_tcs[];\n"
23824 							   "out vec4 tcs_tes[];\n"
23825 							   "\n"
23826 							   "void main()\n"
23827 							   "{\n"
23828 							   "\n"
23829 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
23830 							   "\n"
23831 							   "    gl_TessLevelOuter[0] = 1.0;\n"
23832 							   "    gl_TessLevelOuter[1] = 1.0;\n"
23833 							   "    gl_TessLevelOuter[2] = 1.0;\n"
23834 							   "    gl_TessLevelOuter[3] = 1.0;\n"
23835 							   "    gl_TessLevelInner[0] = 1.0;\n"
23836 							   "    gl_TessLevelInner[1] = 1.0;\n"
23837 							   "}\n"
23838 							   "\n";
23839 	static const GLchar* tcs_tested = "#version 430 core\n"
23840 									  "#extension GL_ARB_enhanced_layouts : require\n"
23841 									  "\n"
23842 									  "layout(vertices = 1) out;\n"
23843 									  "\n"
23844 									  "VAR_DEFINITION"
23845 									  "\n"
23846 									  "in  vec4 vs_tcs[];\n"
23847 									  "out vec4 tcs_tes[];\n"
23848 									  "\n"
23849 									  "void main()\n"
23850 									  "{\n"
23851 									  "    vec4 result = vs_tcs[gl_InvocationID];\n"
23852 									  "\n"
23853 									  "VARIABLE_USE"
23854 									  "\n"
23855 									  "    tcs_tes[gl_InvocationID] = result;\n"
23856 									  "\n"
23857 									  "    gl_TessLevelOuter[0] = 1.0;\n"
23858 									  "    gl_TessLevelOuter[1] = 1.0;\n"
23859 									  "    gl_TessLevelOuter[2] = 1.0;\n"
23860 									  "    gl_TessLevelOuter[3] = 1.0;\n"
23861 									  "    gl_TessLevelInner[0] = 1.0;\n"
23862 									  "    gl_TessLevelInner[1] = 1.0;\n"
23863 									  "}\n"
23864 									  "\n";
23865 	static const GLchar* tes_tested = "#version 430 core\n"
23866 									  "#extension GL_ARB_enhanced_layouts : require\n"
23867 									  "\n"
23868 									  "layout(isolines, point_mode) in;\n"
23869 									  "\n"
23870 									  "VAR_DEFINITION"
23871 									  "\n"
23872 									  "in  vec4 tcs_tes[];\n"
23873 									  "out vec4 tes_gs;\n"
23874 									  "\n"
23875 									  "void main()\n"
23876 									  "{\n"
23877 									  "    vec4 result = tcs_tes[0];\n"
23878 									  "\n"
23879 									  "VARIABLE_USE"
23880 									  "\n"
23881 									  "    tes_gs += result;\n"
23882 									  "}\n"
23883 									  "\n";
23884 	static const GLchar* vs = "#version 430 core\n"
23885 							  "#extension GL_ARB_enhanced_layouts : require\n"
23886 							  "\n"
23887 							  "in  vec4 in_vs;\n"
23888 							  "out vec4 vs_tcs;\n"
23889 							  "\n"
23890 							  "void main()\n"
23891 							  "{\n"
23892 							  "    vs_tcs = in_vs;\n"
23893 							  "}\n"
23894 							  "\n";
23895 	static const GLchar* vs_tested = "#version 430 core\n"
23896 									 "#extension GL_ARB_enhanced_layouts : require\n"
23897 									 "\n"
23898 									 "VAR_DEFINITION"
23899 									 "\n"
23900 									 "in  vec4 in_vs;\n"
23901 									 "out vec4 vs_tcs;\n"
23902 									 "\n"
23903 									 "void main()\n"
23904 									 "{\n"
23905 									 "    vec4 result = in_vs;\n"
23906 									 "\n"
23907 									 "VARIABLE_USE"
23908 									 "\n"
23909 									 "    vs_tcs = result;\n"
23910 									 "}\n"
23911 									 "\n";
23912 
23913 	std::string source;
23914 	testCase&   test_case = m_test_cases[test_case_index];
23915 
23916 	if (test_case.m_stage == stage)
23917 	{
23918 		const GLchar*	array = "";
23919 		GLchar			 buffer[16];
23920 		const Functions& gl				 = m_context.getRenderContext().getFunctions();
23921 		const GLchar*	index			 = "";
23922 		GLint			 max_n_xfb_comp  = 0;
23923 		GLint			 max_n_xfb_bytes = 0;
23924 		size_t			 position		 = 0;
23925 		size_t			 temp;
23926 		const GLchar*	var_definition = 0;
23927 		const GLchar*	var_use		= 0;
23928 
23929 		gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_n_xfb_comp);
23930 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
23931 
23932 		max_n_xfb_bytes = max_n_xfb_comp * 4;
23933 
23934 		sprintf(buffer, "%d", max_n_xfb_bytes);
23935 
23936 		switch (test_case.m_case)
23937 		{
23938 		case BLOCK:
23939 			var_definition = block_var_definition;
23940 			var_use		   = block_use;
23941 			break;
23942 		case GLOBAL:
23943 			var_definition = global_var_definition;
23944 			var_use		   = global_use;
23945 			break;
23946 		case VECTOR:
23947 			var_definition = vector_var_definition;
23948 			var_use		   = vector_use;
23949 			break;
23950 		default:
23951 			TCU_FAIL("Invalid enum");
23952 		}
23953 		// It is a compile time error to apply xfb_offset to the declaration of an unsized array(GLSL4.5 spec: Page73)
23954 		// change array = "[]" to "[1]"
23955 		switch (stage)
23956 		{
23957 		case Utils::Shader::GEOMETRY:
23958 			source = gs_tested;
23959 			array  = "[1]";
23960 			index  = "[0]";
23961 			break;
23962 		case Utils::Shader::TESS_CTRL:
23963 			source = tcs_tested;
23964 			array  = "[1]";
23965 			index  = "[gl_InvocationID]";
23966 			break;
23967 		case Utils::Shader::TESS_EVAL:
23968 			source = tes_tested;
23969 			array  = "[1]";
23970 			index  = "[0]";
23971 			break;
23972 		case Utils::Shader::VERTEX:
23973 			source = vs_tested;
23974 			break;
23975 		default:
23976 			TCU_FAIL("Invalid enum");
23977 		}
23978 
23979 		temp = position;
23980 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
23981 		position = temp;
23982 		Utils::replaceToken("SIZE", position, buffer, source);
23983 		if (GLOBAL != test_case.m_case)
23984 		{
23985 			Utils::replaceToken("ARRAY", position, array, source);
23986 		}
23987 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
23988 
23989 		Utils::replaceAllTokens("INDEX", index, source);
23990 	}
23991 	else
23992 	{
23993 		switch (test_case.m_stage)
23994 		{
23995 		case Utils::Shader::GEOMETRY:
23996 			switch (stage)
23997 			{
23998 			case Utils::Shader::FRAGMENT:
23999 				source = fs;
24000 				break;
24001 			case Utils::Shader::VERTEX:
24002 				source = vs;
24003 				break;
24004 			default:
24005 				source = "";
24006 			}
24007 			break;
24008 		case Utils::Shader::TESS_CTRL:
24009 			switch (stage)
24010 			{
24011 			case Utils::Shader::FRAGMENT:
24012 				source = fs;
24013 				break;
24014 			case Utils::Shader::VERTEX:
24015 				source = vs;
24016 				break;
24017 			default:
24018 				source = "";
24019 			}
24020 			break;
24021 		case Utils::Shader::TESS_EVAL:
24022 			switch (stage)
24023 			{
24024 			case Utils::Shader::FRAGMENT:
24025 				source = fs;
24026 				break;
24027 			case Utils::Shader::TESS_CTRL:
24028 				source = tcs;
24029 				break;
24030 			case Utils::Shader::VERTEX:
24031 				source = vs;
24032 				break;
24033 			default:
24034 				source = "";
24035 			}
24036 			break;
24037 		case Utils::Shader::VERTEX:
24038 			switch (stage)
24039 			{
24040 			case Utils::Shader::FRAGMENT:
24041 				source = fs;
24042 				break;
24043 			default:
24044 				source = "";
24045 			}
24046 			break;
24047 		default:
24048 			TCU_FAIL("Invalid enum");
24049 			break;
24050 		}
24051 	}
24052 
24053 	return source;
24054 }
24055 
24056 /** Get description of test case
24057  *
24058  * @param test_case_index Index of test case
24059  *
24060  * @return Test case description
24061  **/
24062 std::string XFBExceedOffsetLimitTest::getTestCaseName(GLuint test_case_index)
24063 {
24064 	std::stringstream stream;
24065 	testCase&		  test_case = m_test_cases[test_case_index];
24066 
24067 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", case: ";
24068 
24069 	switch (test_case.m_case)
24070 	{
24071 	case BLOCK:
24072 		stream << "BLOCK";
24073 		break;
24074 	case GLOBAL:
24075 		stream << "GLOBAL";
24076 		break;
24077 	case VECTOR:
24078 		stream << "VECTOR";
24079 		break;
24080 	default:
24081 		TCU_FAIL("Invalid enum");
24082 	}
24083 
24084 	return stream.str();
24085 }
24086 
24087 /** Get number of test cases
24088  *
24089  * @return Number of test cases
24090  **/
24091 GLuint XFBExceedOffsetLimitTest::getTestCaseNumber()
24092 {
24093 	return static_cast<GLuint>(m_test_cases.size());
24094 }
24095 
24096 /** Selects if "compute" stage is relevant for test
24097  *
24098  * @param ignored
24099  *
24100  * @return false
24101  **/
24102 bool XFBExceedOffsetLimitTest::isComputeRelevant(GLuint /* test_case_index */)
24103 {
24104 	return false;
24105 }
24106 
24107 /** Prepare all test cases
24108  *
24109  **/
24110 void XFBExceedOffsetLimitTest::testInit()
24111 {
24112 	for (GLuint c = 0; c < CASE_MAX; ++c)
24113 	{
24114 		for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
24115 		{
24116 			if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
24117 				(Utils::Shader::FRAGMENT == stage))
24118 			{
24119 				continue;
24120 			}
24121 
24122 			testCase test_case = { (CASES)c, (Utils::Shader::STAGES)stage };
24123 
24124 			m_test_cases.push_back(test_case);
24125 		}
24126 	}
24127 }
24128 
24129 /** Constructor
24130  *
24131  * @param context Test context
24132  **/
24133 XFBGlobalBufferTest::XFBGlobalBufferTest(deqp::Context& context)
24134 	: BufferTestBase(context, "xfb_global_buffer", "Test verifies that global xfb_buffer qualifier is respected")
24135 {
24136 	/* Nothing to be done here */
24137 }
24138 
24139 /** Get descriptors of buffers necessary for test
24140  *
24141  * @param test_case_index Index of test case
24142  * @param out_descriptors Descriptors of buffers used by test
24143  **/
24144 void XFBGlobalBufferTest::getBufferDescriptors(glw::GLuint test_case_index, bufferDescriptor::Vector& out_descriptors)
24145 {
24146 	// the function "getType(test_case_index)" can't return correct data type, so change code as following:
24147 	const Utils::Type& type = m_test_cases[test_case_index].m_type;
24148 
24149 	/* Test needs single uniform and two xfbs */
24150 	out_descriptors.resize(3);
24151 
24152 	/* Get references */
24153 	bufferDescriptor& uniform = out_descriptors[0];
24154 	bufferDescriptor& xfb_1   = out_descriptors[1];
24155 	bufferDescriptor& xfb_3   = out_descriptors[2];
24156 
24157 	/* Index */
24158 	uniform.m_index = 0;
24159 	xfb_1.m_index   = 1;
24160 	xfb_3.m_index   = 3;
24161 
24162 	/* Target */
24163 	uniform.m_target = Utils::Buffer::Uniform;
24164 	xfb_1.m_target   = Utils::Buffer::Transform_feedback;
24165 	xfb_3.m_target   = Utils::Buffer::Transform_feedback;
24166 
24167 	/* Data */
24168 	const GLuint				gen_start   = Utils::s_rand;
24169 	const std::vector<GLubyte>& chichi_data = type.GenerateData();
24170 	const std::vector<GLubyte>& bulma_data  = type.GenerateData();
24171 	const std::vector<GLubyte>& trunks_data = type.GenerateData();
24172 	const std::vector<GLubyte>& bra_data	= type.GenerateData();
24173 	const std::vector<GLubyte>& gohan_data  = type.GenerateData();
24174 	const std::vector<GLubyte>& goten_data  = type.GenerateData();
24175 
24176 	Utils::s_rand								= gen_start;
24177 	const std::vector<GLubyte>& chichi_data_pck = type.GenerateDataPacked();
24178 	const std::vector<GLubyte>& bulma_data_pck  = type.GenerateDataPacked();
24179 	const std::vector<GLubyte>& trunks_data_pck = type.GenerateDataPacked();
24180 	const std::vector<GLubyte>& bra_data_pck	= type.GenerateDataPacked();
24181 	const std::vector<GLubyte>& gohan_data_pck  = type.GenerateDataPacked();
24182 	const std::vector<GLubyte>& goten_data_pck  = type.GenerateDataPacked();
24183 
24184 	const GLuint type_size	 = static_cast<GLuint>(chichi_data.size());
24185 	const GLuint type_size_pck = static_cast<GLuint>(chichi_data_pck.size());
24186 
24187 	/* Uniform data */
24188 	uniform.m_initial_data.resize(6 * type_size);
24189 	memcpy(&uniform.m_initial_data[0] + 0, &chichi_data[0], type_size);
24190 	memcpy(&uniform.m_initial_data[0] + type_size, &bulma_data[0], type_size);
24191 	memcpy(&uniform.m_initial_data[0] + 2 * type_size, &trunks_data[0], type_size);
24192 	memcpy(&uniform.m_initial_data[0] + 3 * type_size, &bra_data[0], type_size);
24193 	memcpy(&uniform.m_initial_data[0] + 4 * type_size, &gohan_data[0], type_size);
24194 	memcpy(&uniform.m_initial_data[0] + 5 * type_size, &goten_data[0], type_size);
24195 
24196 	/* XFB data */
24197 	xfb_1.m_initial_data.resize(3 * type_size_pck);
24198 	xfb_1.m_expected_data.resize(3 * type_size_pck);
24199 	xfb_3.m_initial_data.resize(3 * type_size_pck);
24200 	xfb_3.m_expected_data.resize(3 * type_size_pck);
24201 
24202 	for (GLuint i = 0; i < 3 * type_size_pck; ++i)
24203 	{
24204 		xfb_1.m_initial_data[i]  = (glw::GLubyte)i;
24205 		xfb_1.m_expected_data[i] = (glw::GLubyte)i;
24206 		xfb_3.m_initial_data[i]  = (glw::GLubyte)i;
24207 		xfb_3.m_expected_data[i] = (glw::GLubyte)i;
24208 	}
24209 
24210 	memcpy(&xfb_3.m_expected_data[0] + 2 * type_size_pck, &chichi_data_pck[0], type_size_pck);
24211 	memcpy(&xfb_1.m_expected_data[0] + 0 * type_size_pck, &bulma_data_pck[0], type_size_pck);
24212 	memcpy(&xfb_1.m_expected_data[0] + 1 * type_size_pck, &trunks_data_pck[0], type_size_pck);
24213 	memcpy(&xfb_1.m_expected_data[0] + 2 * type_size_pck, &bra_data_pck[0], type_size_pck);
24214 	memcpy(&xfb_3.m_expected_data[0] + 0 * type_size_pck, &gohan_data_pck[0], type_size_pck);
24215 	memcpy(&xfb_3.m_expected_data[0] + 1 * type_size_pck, &goten_data_pck[0], type_size_pck);
24216 }
24217 
24218 /** Source for given test case and stage
24219  *
24220  * @param test_case_index Index of test case
24221  * @param stage           Shader stage
24222  *
24223  * @return Shader source
24224  **/
24225 std::string XFBGlobalBufferTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
24226 {
24227 	static const GLchar* fs =
24228 		"#version 430 core\n"
24229 		"#extension GL_ARB_enhanced_layouts : require\n"
24230 		"\n"
24231 		"flat in TYPE chichi;\n"
24232 		"flat in TYPE bulma;\n"
24233 		"in Vegeta {\n"
24234 		"    flat TYPE trunk;\n"
24235 		"    flat TYPE bra;\n"
24236 		"} vegeta;\n"
24237 		"in Goku {\n"
24238 		"    flat TYPE gohan;\n"
24239 		"    flat TYPE goten;\n"
24240 		"} goku;\n"
24241 		"\n"
24242 		"out vec4 fs_out;\n"
24243 		"\n"
24244 		"void main()\n"
24245 		"{\n"
24246 		"    fs_out = vec4(1);\n"
24247 		"    if (TYPE(1) != chichi + bulma + vegeta.trunk + vegeta.bra + goku.gohan + goku.goten)\n"
24248 		"    {\n"
24249 		"        fs_out = vec4(0);\n"
24250 		"    }\n"
24251 		"}\n"
24252 		"\n";
24253 
24254 	static const GLchar* gs = "#version 430 core\n"
24255 							  "#extension GL_ARB_enhanced_layouts : require\n"
24256 							  "\n"
24257 							  "layout(points)                   in;\n"
24258 							  "layout(points, max_vertices = 1) out;\n"
24259 							  "\n"
24260 							  "INTERFACE"
24261 							  "\n"
24262 							  "void main()\n"
24263 							  "{\n"
24264 							  "ASSIGNMENTS"
24265 							  "    EmitVertex();\n"
24266 							  "}\n"
24267 							  "\n";
24268 
24269 	static const GLchar* tcs = "#version 430 core\n"
24270 							   "#extension GL_ARB_enhanced_layouts : require\n"
24271 							   "\n"
24272 							   "layout(vertices = 1) out;\n"
24273 							   "\n"
24274 							   "\n"
24275 							   "void main()\n"
24276 							   "{\n"
24277 							   "    gl_TessLevelOuter[0] = 1.0;\n"
24278 							   "    gl_TessLevelOuter[1] = 1.0;\n"
24279 							   "    gl_TessLevelOuter[2] = 1.0;\n"
24280 							   "    gl_TessLevelOuter[3] = 1.0;\n"
24281 							   "    gl_TessLevelInner[0] = 1.0;\n"
24282 							   "    gl_TessLevelInner[1] = 1.0;\n"
24283 							   "}\n"
24284 							   "\n";
24285 
24286 	static const GLchar* tes = "#version 430 core\n"
24287 							   "#extension GL_ARB_enhanced_layouts : require\n"
24288 							   "\n"
24289 							   "layout(isolines, point_mode) in;\n"
24290 							   "\n"
24291 							   "INTERFACE"
24292 							   "\n"
24293 							   "void main()\n"
24294 							   "{\n"
24295 							   "ASSIGNMENTS"
24296 							   "}\n"
24297 							   "\n";
24298 
24299 	static const GLchar* vs = "#version 430 core\n"
24300 							  "#extension GL_ARB_enhanced_layouts : require\n"
24301 							  "\n"
24302 							  "void main()\n"
24303 							  "{\n"
24304 							  "}\n"
24305 							  "\n";
24306 
24307 	static const GLchar* vs_tested = "#version 430 core\n"
24308 									 "#extension GL_ARB_enhanced_layouts : require\n"
24309 									 "\n"
24310 									 "INTERFACE"
24311 									 "\n"
24312 									 "void main()\n"
24313 									 "{\n"
24314 									 "ASSIGNMENTS"
24315 									 "}\n"
24316 									 "\n";
24317 
24318 	std::string		 source;
24319 	const _testCase& test_case = m_test_cases[test_case_index];
24320 	const GLchar*	type_name = test_case.m_type.GetGLSLTypeName();
24321 
24322 	if (test_case.m_stage == stage)
24323 	{
24324 		std::string assignments = "    chichi       = uni_chichi;\n"
24325 								  "    bulma        = uni_bulma;\n"
24326 								  "    vegeta.trunk = uni_trunk;\n"
24327 								  "    vegeta.bra   = uni_bra;\n"
24328 								  "    goku.gohan   = uni_gohan;\n"
24329 								  "    goku.goten   = uni_goten;\n";
24330 
24331 		std::string interface = "layout (xfb_buffer = 3) out;\n"
24332 								"\n"
24333 								"const uint type_size = SIZE;\n"
24334 								"\n"
24335 								"layout (                xfb_offset = 2 * type_size) flat out TYPE chichi;\n"
24336 								"layout (xfb_buffer = 1, xfb_offset = 0)             flat out TYPE bulma;\n"
24337 								"layout (xfb_buffer = 1, xfb_offset = 1 * type_size) out Vegeta {\n"
24338 								"    flat TYPE trunk;\n"
24339 								"    flat TYPE bra;\n"
24340 								"} vegeta;\n"
24341 								"layout (                xfb_offset = 0)             out Goku {\n"
24342 								"    flat TYPE gohan;\n"
24343 								"    flat TYPE goten;\n"
24344 								"} goku;\n"
24345 								"\n"
24346 								// Uniform block must be declared with std140, otherwise each block member is not packed
24347 								"layout(binding = 0, std140) uniform block {\n"
24348 								"    TYPE uni_chichi;\n"
24349 								"    TYPE uni_bulma;\n"
24350 								"    TYPE uni_trunk;\n"
24351 								"    TYPE uni_bra;\n"
24352 								"    TYPE uni_gohan;\n"
24353 								"    TYPE uni_goten;\n"
24354 								"};\n";
24355 
24356 		/* Prepare interface string */
24357 		{
24358 			GLchar		 buffer[16];
24359 			size_t		 position  = 0;
24360 			const GLuint type_size = test_case.m_type.GetSize();
24361 
24362 			sprintf(buffer, "%d", type_size);
24363 
24364 			Utils::replaceToken("SIZE", position, buffer, interface);
24365 			Utils::replaceAllTokens("TYPE", type_name, interface);
24366 		}
24367 
24368 		switch (stage)
24369 		{
24370 		case Utils::Shader::GEOMETRY:
24371 			source = gs;
24372 			break;
24373 		case Utils::Shader::TESS_EVAL:
24374 			source = tes;
24375 			break;
24376 		case Utils::Shader::VERTEX:
24377 			source = vs_tested;
24378 			break;
24379 		default:
24380 			TCU_FAIL("Invalid enum");
24381 		}
24382 
24383 		/* Replace tokens */
24384 		{
24385 			size_t position = 0;
24386 
24387 			Utils::replaceToken("INTERFACE", position, interface.c_str(), source);
24388 			Utils::replaceToken("ASSIGNMENTS", position, assignments.c_str(), source);
24389 		}
24390 	}
24391 	else
24392 	{
24393 		switch (test_case.m_stage)
24394 		{
24395 		case Utils::Shader::GEOMETRY:
24396 			switch (stage)
24397 			{
24398 			case Utils::Shader::FRAGMENT:
24399 				source = fs;
24400 				Utils::replaceAllTokens("TYPE", type_name, source);
24401 				break;
24402 			case Utils::Shader::VERTEX:
24403 				source = vs;
24404 				break;
24405 			default:
24406 				source = "";
24407 			}
24408 			break;
24409 		case Utils::Shader::TESS_EVAL:
24410 			switch (stage)
24411 			{
24412 			case Utils::Shader::FRAGMENT:
24413 				source = fs;
24414 				Utils::replaceAllTokens("TYPE", type_name, source);
24415 				break;
24416 			case Utils::Shader::TESS_CTRL:
24417 				source = tcs;
24418 				break;
24419 			case Utils::Shader::VERTEX:
24420 				source = vs;
24421 				break;
24422 			default:
24423 				source = "";
24424 			}
24425 			break;
24426 		case Utils::Shader::VERTEX:
24427 			switch (stage)
24428 			{
24429 			case Utils::Shader::FRAGMENT:
24430 				source = fs;
24431 				Utils::replaceAllTokens("TYPE", type_name, source);
24432 				break;
24433 			default:
24434 				source = "";
24435 			}
24436 			break;
24437 		default:
24438 			TCU_FAIL("Invalid enum");
24439 			break;
24440 		}
24441 	}
24442 
24443 	return source;
24444 }
24445 
24446 /** Get name of test case
24447  *
24448  * @param test_case_index Index of test case
24449  *
24450  * @return Name of case
24451  **/
24452 std::string XFBGlobalBufferTest::getTestCaseName(GLuint test_case_index)
24453 {
24454 	std::string		 name;
24455 	const _testCase& test_case = m_test_cases[test_case_index];
24456 
24457 	name = "Tested stage: ";
24458 	name.append(Utils::Shader::GetStageName(test_case.m_stage));
24459 	name.append(". Tested type: ");
24460 	name.append(test_case.m_type.GetGLSLTypeName());
24461 
24462 	return name;
24463 }
24464 
24465 /** Get number of cases
24466  *
24467  * @return Number of test cases
24468  **/
24469 GLuint XFBGlobalBufferTest::getTestCaseNumber()
24470 {
24471 	return static_cast<GLuint>(m_test_cases.size());
24472 }
24473 
24474 /** Prepare set of test cases
24475  *
24476  **/
24477 void XFBGlobalBufferTest::testInit()
24478 {
24479 	GLuint n_types = getTypesNumber();
24480 
24481 	for (GLuint i = 0; i < n_types; ++i)
24482 	{
24483 		const Utils::Type& type = getType(i);
24484 		/*
24485 		 When the tfx varying is the following type, the number of output exceeds the gl_MaxVaryingComponents, which will
24486 		 cause a link time error.
24487 		 */
24488 		if (strcmp(type.GetGLSLTypeName(), "dmat3") == 0 || strcmp(type.GetGLSLTypeName(), "dmat4") == 0 ||
24489 			strcmp(type.GetGLSLTypeName(), "dmat3x4") == 0 || strcmp(type.GetGLSLTypeName(), "dmat4x3") == 0)
24490 		{
24491 			continue;
24492 		}
24493 		const _testCase test_cases[] = { { Utils::Shader::VERTEX, type },
24494 										 { Utils::Shader::GEOMETRY, type },
24495 										 { Utils::Shader::TESS_EVAL, type } };
24496 
24497 		m_test_cases.push_back(test_cases[0]);
24498 		m_test_cases.push_back(test_cases[1]);
24499 		m_test_cases.push_back(test_cases[2]);
24500 	}
24501 }
24502 
24503 /** Constructor
24504  *
24505  * @param context Test context
24506  **/
24507 XFBStrideTest::XFBStrideTest(deqp::Context& context)
24508 	: BufferTestBase(context, "xfb_stride", "Test verifies that correct stride is used for all types")
24509 {
24510 	/* Nothing to be done here */
24511 }
24512 
24513 /** Execute drawArrays for single vertex
24514  *
24515  * @param test_case_index
24516  *
24517  * @return true
24518  **/
24519 bool XFBStrideTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
24520 {
24521 	const Functions& gl				= m_context.getRenderContext().getFunctions();
24522 	GLenum			 primitive_type = GL_PATCHES;
24523 	const testCase&  test_case		= m_test_cases[test_case_index];
24524 
24525 	if (Utils::Shader::VERTEX == test_case.m_stage)
24526 	{
24527 		primitive_type = GL_POINTS;
24528 	}
24529 
24530 	gl.disable(GL_RASTERIZER_DISCARD);
24531 	GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
24532 
24533 	gl.beginTransformFeedback(GL_POINTS);
24534 	GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
24535 
24536 	gl.drawArrays(primitive_type, 0 /* first */, 2 /* count */);
24537 	GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
24538 
24539 	gl.endTransformFeedback();
24540 	GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
24541 
24542 	return true;
24543 }
24544 
24545 /** Get descriptors of buffers necessary for test
24546  *
24547  * @param test_case_index Index of test case
24548  * @param out_descriptors Descriptors of buffers used by test
24549  **/
24550 void XFBStrideTest::getBufferDescriptors(GLuint test_case_index, bufferDescriptor::Vector& out_descriptors)
24551 {
24552 	const testCase&	test_case = m_test_cases[test_case_index];
24553 	const Utils::Type& type		 = test_case.m_type;
24554 
24555 	/* Test needs single uniform and xfb */
24556 	out_descriptors.resize(2);
24557 
24558 	/* Get references */
24559 	bufferDescriptor& uniform = out_descriptors[0];
24560 	bufferDescriptor& xfb	 = out_descriptors[1];
24561 
24562 	/* Index */
24563 	uniform.m_index = 0;
24564 	xfb.m_index		= 0;
24565 
24566 	/* Target */
24567 	uniform.m_target = Utils::Buffer::Uniform;
24568 	xfb.m_target	 = Utils::Buffer::Transform_feedback;
24569 
24570 	/* Data */
24571 	const GLuint				rand_start   = Utils::s_rand;
24572 	const std::vector<GLubyte>& uniform_data = type.GenerateData();
24573 
24574 	Utils::s_rand						 = rand_start;
24575 	const std::vector<GLubyte>& xfb_data = type.GenerateDataPacked();
24576 
24577 	const GLuint uni_type_size = static_cast<GLuint>(uniform_data.size());
24578 	const GLuint xfb_type_size = static_cast<GLuint>(xfb_data.size());
24579 	/*
24580 	 Note: If xfb varying output from vertex shader, the variable "goku" will only output once to transform feedback buffer,
24581 	 if xfb varying output from TES or GS, because the input primitive type in TES is defined as "layout(isolines, point_mode) in;",
24582 	 the primitive type is line which make the variable "goku" will output twice to transform feedback buffer, so for vertex shader
24583 	 only one valid data should be initialized in xfb.m_expected_data
24584 	 */
24585 	const GLuint xfb_data_size = (test_case.m_stage == Utils::Shader::VERTEX) ? xfb_type_size : xfb_type_size * 2;
24586 	/* Uniform data */
24587 	uniform.m_initial_data.resize(uni_type_size);
24588 	memcpy(&uniform.m_initial_data[0] + 0 * uni_type_size, &uniform_data[0], uni_type_size);
24589 
24590 	/* XFB data */
24591 	xfb.m_initial_data.resize(xfb_data_size);
24592 	xfb.m_expected_data.resize(xfb_data_size);
24593 
24594 	for (GLuint i = 0; i < xfb_data_size; ++i)
24595 	{
24596 		xfb.m_initial_data[i]  = (glw::GLubyte)i;
24597 		xfb.m_expected_data[i] = (glw::GLubyte)i;
24598 	}
24599 
24600 	if (test_case.m_stage == Utils::Shader::VERTEX)
24601 	{
24602 		memcpy(&xfb.m_expected_data[0] + 0 * xfb_type_size, &xfb_data[0], xfb_type_size);
24603 	}
24604 	else
24605 	{
24606 		memcpy(&xfb.m_expected_data[0] + 0 * xfb_type_size, &xfb_data[0], xfb_type_size);
24607 		memcpy(&xfb.m_expected_data[0] + 1 * xfb_type_size, &xfb_data[0], xfb_type_size);
24608 	}
24609 }
24610 
24611 /** Get body of main function for given shader stage
24612  *
24613  * @param test_case_index  Index of test case
24614  * @param stage            Shader stage
24615  * @param out_assignments  Set to empty
24616  * @param out_calculations Set to empty
24617  **/
24618 void XFBStrideTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage, std::string& out_assignments,
24619 								  std::string& out_calculations)
24620 {
24621 	const testCase& test_case = m_test_cases[test_case_index];
24622 
24623 	out_calculations = "";
24624 
24625 	static const GLchar* vs_tes_gs = "    goku = uni_goku;\n";
24626 	static const GLchar* fs		   = "    fs_out = vec4(1, 0.25, 0.5, 0.75);\n"
24627 							  "    if (TYPE(0) == goku)\n"
24628 							  "    {\n"
24629 							  "         fs_out = vec4(1, 0.75, 0.5, 0.5);\n"
24630 							  "    }\n";
24631 
24632 	const GLchar* assignments = "";
24633 
24634 	if (test_case.m_stage == stage)
24635 	{
24636 		switch (stage)
24637 		{
24638 		case Utils::Shader::GEOMETRY:
24639 			assignments = vs_tes_gs;
24640 			break;
24641 		case Utils::Shader::TESS_EVAL:
24642 			assignments = vs_tes_gs;
24643 			break;
24644 		case Utils::Shader::VERTEX:
24645 			assignments = vs_tes_gs;
24646 			break;
24647 		default:
24648 			TCU_FAIL("Invalid enum");
24649 		}
24650 	}
24651 	else
24652 	{
24653 		switch (stage)
24654 		{
24655 		case Utils::Shader::FRAGMENT:
24656 			assignments = fs;
24657 			break;
24658 		case Utils::Shader::GEOMETRY:
24659 		case Utils::Shader::TESS_CTRL:
24660 		case Utils::Shader::TESS_EVAL:
24661 		case Utils::Shader::VERTEX:
24662 			break;
24663 		default:
24664 			TCU_FAIL("Invalid enum");
24665 		}
24666 	}
24667 
24668 	out_assignments = assignments;
24669 
24670 	if (Utils::Shader::FRAGMENT == stage)
24671 	{
24672 		Utils::replaceAllTokens("TYPE", test_case.m_type.GetGLSLTypeName(), out_assignments);
24673 	}
24674 }
24675 
24676 /** Get interface of shader
24677  *
24678  * @param test_case_index  Index of test case
24679  * @param stage            Shader stage
24680  * @param out_interface    Set to ""
24681  **/
24682 void XFBStrideTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage, std::string& out_interface)
24683 {
24684 	static const GLchar* vs_tes_gs = "layout (xfb_offset = 0) FLAT out TYPE goku;\n"
24685 									 "\n"
24686 									 "layout(std140, binding = 0) uniform Goku {\n"
24687 									 "    TYPE uni_goku;\n"
24688 									 "};\n";
24689 	static const GLchar* fs = "FLAT in TYPE goku;\n"
24690 							  "\n"
24691 							  "out vec4 fs_out;\n";
24692 
24693 	const testCase& test_case = m_test_cases[test_case_index];
24694 	const GLchar*   interface = "";
24695 	const GLchar*   flat	  = "";
24696 
24697 	if (test_case.m_stage == stage)
24698 	{
24699 		switch (stage)
24700 		{
24701 		case Utils::Shader::GEOMETRY:
24702 			interface = vs_tes_gs;
24703 			break;
24704 		case Utils::Shader::TESS_EVAL:
24705 			interface = vs_tes_gs;
24706 			break;
24707 		case Utils::Shader::VERTEX:
24708 			interface = vs_tes_gs;
24709 			break;
24710 		default:
24711 			TCU_FAIL("Invalid enum");
24712 		}
24713 	}
24714 	else
24715 	{
24716 		switch (stage)
24717 		{
24718 		case Utils::Shader::FRAGMENT:
24719 			interface = fs;
24720 			break;
24721 		case Utils::Shader::GEOMETRY:
24722 		case Utils::Shader::TESS_CTRL:
24723 		case Utils::Shader::TESS_EVAL:
24724 		case Utils::Shader::VERTEX:
24725 			break;
24726 		default:
24727 			TCU_FAIL("Invalid enum");
24728 		}
24729 	}
24730 
24731 	out_interface = interface;
24732 
24733 	if (Utils::Type::Float != test_case.m_type.m_basic_type)
24734 	{
24735 		flat = "flat";
24736 	}
24737 
24738 	Utils::replaceAllTokens("FLAT", flat, out_interface);
24739 	Utils::replaceAllTokens("TYPE", test_case.m_type.GetGLSLTypeName(), out_interface);
24740 }
24741 
24742 /** Get source code of shader
24743  *
24744  * @param test_case_index Index of test case
24745  * @param stage           Shader stage
24746  *
24747  * @return Source
24748  **/
24749 std::string XFBStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
24750 {
24751 	std::string		source;
24752 	const testCase& test_case = m_test_cases[test_case_index];
24753 
24754 	switch (test_case.m_stage)
24755 	{
24756 	case Utils::Shader::VERTEX:
24757 		switch (stage)
24758 		{
24759 		case Utils::Shader::FRAGMENT:
24760 		case Utils::Shader::VERTEX:
24761 			source = BufferTestBase::getShaderSource(test_case_index, stage);
24762 			break;
24763 		default:
24764 			break;
24765 		}
24766 		break;
24767 
24768 	case Utils::Shader::TESS_EVAL:
24769 		switch (stage)
24770 		{
24771 		case Utils::Shader::FRAGMENT:
24772 		case Utils::Shader::TESS_CTRL:
24773 		case Utils::Shader::TESS_EVAL:
24774 		case Utils::Shader::VERTEX:
24775 			source = BufferTestBase::getShaderSource(test_case_index, stage);
24776 			break;
24777 		default:
24778 			break;
24779 		}
24780 		break;
24781 
24782 	case Utils::Shader::GEOMETRY:
24783 		source = BufferTestBase::getShaderSource(test_case_index, stage);
24784 		break;
24785 
24786 	default:
24787 		TCU_FAIL("Invalid enum");
24788 		break;
24789 	}
24790 
24791 	/* */
24792 	return source;
24793 }
24794 
24795 /** Get name of test case
24796  *
24797  * @param test_case_index Index of test case
24798  *
24799  * @return Name of tested stage
24800  **/
24801 std::string XFBStrideTest::getTestCaseName(glw::GLuint test_case_index)
24802 {
24803 	std::stringstream stream;
24804 	const testCase&   test_case = m_test_cases[test_case_index];
24805 
24806 	stream << "Type: " << test_case.m_type.GetGLSLTypeName()
24807 		   << ", stage: " << Utils::Shader::GetStageName(test_case.m_stage);
24808 
24809 	return stream.str();
24810 }
24811 
24812 /** Returns number of test cases
24813  *
24814  * @return TEST_MAX
24815  **/
24816 glw::GLuint XFBStrideTest::getTestCaseNumber()
24817 {
24818 	return static_cast<GLuint>(m_test_cases.size());
24819 }
24820 
24821 /** Prepare all test cases
24822  *
24823  **/
24824 void XFBStrideTest::testInit()
24825 {
24826 	const GLuint n_types = getTypesNumber();
24827 
24828 	for (GLuint i = 0; i < n_types; ++i)
24829 	{
24830 		const Utils::Type& type = getType(i);
24831 
24832 		for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
24833 		{
24834 			if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::FRAGMENT == stage) ||
24835 				(Utils::Shader::TESS_CTRL == stage))
24836 			{
24837 				continue;
24838 			}
24839 
24840 			testCase test_case = { (Utils::Shader::STAGES)stage, type };
24841 
24842 			m_test_cases.push_back(test_case);
24843 		}
24844 	}
24845 }
24846 
24847 /** Constructor
24848  *
24849  * @param context Test framework context
24850  **/
24851 XFBBlockMemberBufferTest::XFBBlockMemberBufferTest(deqp::Context& context)
24852 	: NegativeTestBase(
24853 		  context, "xfb_block_member_buffer",
24854 		  "Test verifies that compiler reports error when block member has different xfb_buffer qualifier than buffer")
24855 {
24856 }
24857 
24858 /** Source for given test case and stage
24859  *
24860  * @param test_case_index Index of test case
24861  * @param stage           Shader stage
24862  *
24863  * @return Shader source
24864  **/
24865 std::string XFBBlockMemberBufferTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
24866 {
24867 	static const GLchar* var_definition = "layout (xfb_offset = 0) out Goku {\n"
24868 										  "                            vec4 gohan;\n"
24869 										  "    layout (xfb_buffer = 1) vec4 goten;\n"
24870 										  "} gokuARRAY;\n";
24871 	static const GLchar* var_use = "    gokuINDEX.gohan = result / 2;\n"
24872 								   "    gokuINDEX.goten = result / 4;\n";
24873 	static const GLchar* fs = "#version 430 core\n"
24874 							  "#extension GL_ARB_enhanced_layouts : require\n"
24875 							  "\n"
24876 							  "in  vec4 gs_fs;\n"
24877 							  "out vec4 fs_out;\n"
24878 							  "\n"
24879 							  "void main()\n"
24880 							  "{\n"
24881 							  "    fs_out = gs_fs;\n"
24882 							  "}\n"
24883 							  "\n";
24884 	static const GLchar* gs_tested = "#version 430 core\n"
24885 									 "#extension GL_ARB_enhanced_layouts : require\n"
24886 									 "\n"
24887 									 "layout(points)                           in;\n"
24888 									 "layout(triangle_strip, max_vertices = 4) out;\n"
24889 									 "\n"
24890 									 "VAR_DEFINITION"
24891 									 "\n"
24892 									 "in  vec4 tes_gs[];\n"
24893 									 "out vec4 gs_fs;\n"
24894 									 "\n"
24895 									 "void main()\n"
24896 									 "{\n"
24897 									 "    vec4 result = tes_gs[0];\n"
24898 									 "\n"
24899 									 "VARIABLE_USE"
24900 									 "\n"
24901 									 "    gs_fs = result;\n"
24902 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
24903 									 "    EmitVertex();\n"
24904 									 "    gs_fs = result;\n"
24905 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
24906 									 "    EmitVertex();\n"
24907 									 "    gs_fs = result;\n"
24908 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
24909 									 "    EmitVertex();\n"
24910 									 "    gs_fs = result;\n"
24911 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
24912 									 "    EmitVertex();\n"
24913 									 "}\n"
24914 									 "\n";
24915 	static const GLchar* tcs = "#version 430 core\n"
24916 							   "#extension GL_ARB_enhanced_layouts : require\n"
24917 							   "\n"
24918 							   "layout(vertices = 1) out;\n"
24919 							   "\n"
24920 							   "in  vec4 vs_tcs[];\n"
24921 							   "out vec4 tcs_tes[];\n"
24922 							   "\n"
24923 							   "void main()\n"
24924 							   "{\n"
24925 							   "\n"
24926 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
24927 							   "\n"
24928 							   "    gl_TessLevelOuter[0] = 1.0;\n"
24929 							   "    gl_TessLevelOuter[1] = 1.0;\n"
24930 							   "    gl_TessLevelOuter[2] = 1.0;\n"
24931 							   "    gl_TessLevelOuter[3] = 1.0;\n"
24932 							   "    gl_TessLevelInner[0] = 1.0;\n"
24933 							   "    gl_TessLevelInner[1] = 1.0;\n"
24934 							   "}\n"
24935 							   "\n";
24936 	static const GLchar* tcs_tested = "#version 430 core\n"
24937 									  "#extension GL_ARB_enhanced_layouts : require\n"
24938 									  "\n"
24939 									  "layout(vertices = 1) out;\n"
24940 									  "\n"
24941 									  "VAR_DEFINITION"
24942 									  "\n"
24943 									  "in  vec4 vs_tcs[];\n"
24944 									  "out vec4 tcs_tes[];\n"
24945 									  "\n"
24946 									  "void main()\n"
24947 									  "{\n"
24948 									  "    vec4 result = vs_tcs[gl_InvocationID];\n"
24949 									  "\n"
24950 									  "VARIABLE_USE"
24951 									  "\n"
24952 									  "    tcs_tes[gl_InvocationID] = result;\n"
24953 									  "\n"
24954 									  "    gl_TessLevelOuter[0] = 1.0;\n"
24955 									  "    gl_TessLevelOuter[1] = 1.0;\n"
24956 									  "    gl_TessLevelOuter[2] = 1.0;\n"
24957 									  "    gl_TessLevelOuter[3] = 1.0;\n"
24958 									  "    gl_TessLevelInner[0] = 1.0;\n"
24959 									  "    gl_TessLevelInner[1] = 1.0;\n"
24960 									  "}\n"
24961 									  "\n";
24962 	static const GLchar* tes_tested = "#version 430 core\n"
24963 									  "#extension GL_ARB_enhanced_layouts : require\n"
24964 									  "\n"
24965 									  "layout(isolines, point_mode) in;\n"
24966 									  "\n"
24967 									  "VAR_DEFINITION"
24968 									  "\n"
24969 									  "in  vec4 tcs_tes[];\n"
24970 									  "out vec4 tes_gs;\n"
24971 									  "\n"
24972 									  "void main()\n"
24973 									  "{\n"
24974 									  "    vec4 result = tcs_tes[0];\n"
24975 									  "\n"
24976 									  "VARIABLE_USE"
24977 									  "\n"
24978 									  "    tes_gs += result;\n"
24979 									  "}\n"
24980 									  "\n";
24981 	static const GLchar* vs = "#version 430 core\n"
24982 							  "#extension GL_ARB_enhanced_layouts : require\n"
24983 							  "\n"
24984 							  "in  vec4 in_vs;\n"
24985 							  "out vec4 vs_tcs;\n"
24986 							  "\n"
24987 							  "void main()\n"
24988 							  "{\n"
24989 							  "    vs_tcs = in_vs;\n"
24990 							  "}\n"
24991 							  "\n";
24992 	static const GLchar* vs_tested = "#version 430 core\n"
24993 									 "#extension GL_ARB_enhanced_layouts : require\n"
24994 									 "\n"
24995 									 "VAR_DEFINITION"
24996 									 "\n"
24997 									 "in  vec4 in_vs;\n"
24998 									 "out vec4 vs_tcs;\n"
24999 									 "\n"
25000 									 "void main()\n"
25001 									 "{\n"
25002 									 "    vec4 result = in_vs;\n"
25003 									 "\n"
25004 									 "VARIABLE_USE"
25005 									 "\n"
25006 									 "    vs_tcs = result;\n"
25007 									 "}\n"
25008 									 "\n";
25009 
25010 	std::string source;
25011 	testCase&   test_case = m_test_cases[test_case_index];
25012 
25013 	if (test_case.m_stage == stage)
25014 	{
25015 		const GLchar* array	= "";
25016 		const GLchar* index	= "";
25017 		size_t		  position = 0;
25018 
25019 		switch (stage)
25020 		{
25021 		case Utils::Shader::GEOMETRY:
25022 			source = gs_tested;
25023 			array  = "[]";
25024 			index  = "[0]";
25025 			break;
25026 		case Utils::Shader::TESS_CTRL:
25027 			source = tcs_tested;
25028 			array  = "[]";
25029 			index  = "[gl_InvocationID]";
25030 			break;
25031 		case Utils::Shader::TESS_EVAL:
25032 			source = tes_tested;
25033 			array  = "[]";
25034 			index  = "[0]";
25035 			break;
25036 		case Utils::Shader::VERTEX:
25037 			source = vs_tested;
25038 			break;
25039 		default:
25040 			TCU_FAIL("Invalid enum");
25041 		}
25042 
25043 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
25044 		position = 0;
25045 		Utils::replaceToken("ARRAY", position, array, source);
25046 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
25047 
25048 		Utils::replaceAllTokens("INDEX", index, source);
25049 	}
25050 	else
25051 	{
25052 		switch (test_case.m_stage)
25053 		{
25054 		case Utils::Shader::GEOMETRY:
25055 			switch (stage)
25056 			{
25057 			case Utils::Shader::FRAGMENT:
25058 				source = fs;
25059 				break;
25060 			case Utils::Shader::VERTEX:
25061 				source = vs;
25062 				break;
25063 			default:
25064 				source = "";
25065 			}
25066 			break;
25067 		case Utils::Shader::TESS_CTRL:
25068 			switch (stage)
25069 			{
25070 			case Utils::Shader::FRAGMENT:
25071 				source = fs;
25072 				break;
25073 			case Utils::Shader::VERTEX:
25074 				source = vs;
25075 				break;
25076 			default:
25077 				source = "";
25078 			}
25079 			break;
25080 		case Utils::Shader::TESS_EVAL:
25081 			switch (stage)
25082 			{
25083 			case Utils::Shader::FRAGMENT:
25084 				source = fs;
25085 				break;
25086 			case Utils::Shader::TESS_CTRL:
25087 				source = tcs;
25088 				break;
25089 			case Utils::Shader::VERTEX:
25090 				source = vs;
25091 				break;
25092 			default:
25093 				source = "";
25094 			}
25095 			break;
25096 		case Utils::Shader::VERTEX:
25097 			switch (stage)
25098 			{
25099 			case Utils::Shader::FRAGMENT:
25100 				source = fs;
25101 				break;
25102 			default:
25103 				source = "";
25104 			}
25105 			break;
25106 		default:
25107 			TCU_FAIL("Invalid enum");
25108 			break;
25109 		}
25110 	}
25111 
25112 	return source;
25113 }
25114 
25115 /** Get description of test case
25116  *
25117  * @param test_case_index Index of test case
25118  *
25119  * @return Test case description
25120  **/
25121 std::string XFBBlockMemberBufferTest::getTestCaseName(GLuint test_case_index)
25122 {
25123 	std::stringstream stream;
25124 	testCase&		  test_case = m_test_cases[test_case_index];
25125 
25126 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage);
25127 
25128 	return stream.str();
25129 }
25130 
25131 /** Get number of test cases
25132  *
25133  * @return Number of test cases
25134  **/
25135 GLuint XFBBlockMemberBufferTest::getTestCaseNumber()
25136 {
25137 	return static_cast<GLuint>(m_test_cases.size());
25138 }
25139 
25140 /** Selects if "compute" stage is relevant for test
25141  *
25142  * @param ignored
25143  *
25144  * @return false
25145  **/
25146 bool XFBBlockMemberBufferTest::isComputeRelevant(GLuint /* test_case_index */)
25147 {
25148 	return false;
25149 }
25150 
25151 /** Prepare all test cases
25152  *
25153  **/
25154 void XFBBlockMemberBufferTest::testInit()
25155 {
25156 	for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
25157 	{
25158 		if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
25159 			(Utils::Shader::FRAGMENT == stage))
25160 		{
25161 			continue;
25162 		}
25163 
25164 		testCase test_case = { (Utils::Shader::STAGES)stage };
25165 
25166 		m_test_cases.push_back(test_case);
25167 	}
25168 }
25169 
25170 /** Constructor
25171  *
25172  * @param context Test framework context
25173  **/
25174 XFBOutputOverlappingTest::XFBOutputOverlappingTest(deqp::Context& context)
25175 	: NegativeTestBase(context, "xfb_output_overlapping",
25176 					   "Test verifies that compiler reports error when two xfb qualified outputs overlap")
25177 {
25178 }
25179 
25180 /** Source for given test case and stage
25181  *
25182  * @param test_case_index Index of test case
25183  * @param stage           Shader stage
25184  *
25185  * @return Shader source
25186  **/
25187 std::string XFBOutputOverlappingTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
25188 {
25189 	static const GLchar* var_definition = "layout (xfb_offset = OFFSET) out TYPE gohanARRAY;\n"
25190 										  "layout (xfb_offset = OFFSET) out TYPE gotenARRAY;\n";
25191 	static const GLchar* var_use = "    gohanINDEX = TYPE(0);\n"
25192 								   "    gotenINDEX = TYPE(1);\n"
25193 								   "    if (vec4(0) == result)\n"
25194 								   "    {\n"
25195 								   "        gohanINDEX = TYPE(1);\n"
25196 								   "        gotenINDEX = TYPE(0);\n"
25197 								   "    }\n";
25198 	static const GLchar* fs = "#version 430 core\n"
25199 							  "#extension GL_ARB_enhanced_layouts : require\n"
25200 							  "\n"
25201 							  "in  vec4 gs_fs;\n"
25202 							  "out vec4 fs_out;\n"
25203 							  "\n"
25204 							  "void main()\n"
25205 							  "{\n"
25206 							  "    fs_out = gs_fs;\n"
25207 							  "}\n"
25208 							  "\n";
25209 	static const GLchar* gs_tested = "#version 430 core\n"
25210 									 "#extension GL_ARB_enhanced_layouts : require\n"
25211 									 "\n"
25212 									 "layout(points)                           in;\n"
25213 									 "layout(triangle_strip, max_vertices = 4) out;\n"
25214 									 "\n"
25215 									 "VAR_DEFINITION"
25216 									 "\n"
25217 									 "in  vec4 tes_gs[];\n"
25218 									 "out vec4 gs_fs;\n"
25219 									 "\n"
25220 									 "void main()\n"
25221 									 "{\n"
25222 									 "    vec4 result = tes_gs[0];\n"
25223 									 "\n"
25224 									 "VARIABLE_USE"
25225 									 "\n"
25226 									 "    gs_fs = result;\n"
25227 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
25228 									 "    EmitVertex();\n"
25229 									 "    gs_fs = result;\n"
25230 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
25231 									 "    EmitVertex();\n"
25232 									 "    gs_fs = result;\n"
25233 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
25234 									 "    EmitVertex();\n"
25235 									 "    gs_fs = result;\n"
25236 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
25237 									 "    EmitVertex();\n"
25238 									 "}\n"
25239 									 "\n";
25240 	static const GLchar* tcs = "#version 430 core\n"
25241 							   "#extension GL_ARB_enhanced_layouts : require\n"
25242 							   "\n"
25243 							   "layout(vertices = 1) out;\n"
25244 							   "\n"
25245 							   "in  vec4 vs_tcs[];\n"
25246 							   "out vec4 tcs_tes[];\n"
25247 							   "\n"
25248 							   "void main()\n"
25249 							   "{\n"
25250 							   "\n"
25251 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
25252 							   "\n"
25253 							   "    gl_TessLevelOuter[0] = 1.0;\n"
25254 							   "    gl_TessLevelOuter[1] = 1.0;\n"
25255 							   "    gl_TessLevelOuter[2] = 1.0;\n"
25256 							   "    gl_TessLevelOuter[3] = 1.0;\n"
25257 							   "    gl_TessLevelInner[0] = 1.0;\n"
25258 							   "    gl_TessLevelInner[1] = 1.0;\n"
25259 							   "}\n"
25260 							   "\n";
25261 	static const GLchar* tcs_tested = "#version 430 core\n"
25262 									  "#extension GL_ARB_enhanced_layouts : require\n"
25263 									  "\n"
25264 									  "layout(vertices = 1) out;\n"
25265 									  "\n"
25266 									  "VAR_DEFINITION"
25267 									  "\n"
25268 									  "in  vec4 vs_tcs[];\n"
25269 									  "out vec4 tcs_tes[];\n"
25270 									  "\n"
25271 									  "void main()\n"
25272 									  "{\n"
25273 									  "    vec4 result = vs_tcs[gl_InvocationID];\n"
25274 									  "\n"
25275 									  "VARIABLE_USE"
25276 									  "\n"
25277 									  "    tcs_tes[gl_InvocationID] = result;\n"
25278 									  "\n"
25279 									  "    gl_TessLevelOuter[0] = 1.0;\n"
25280 									  "    gl_TessLevelOuter[1] = 1.0;\n"
25281 									  "    gl_TessLevelOuter[2] = 1.0;\n"
25282 									  "    gl_TessLevelOuter[3] = 1.0;\n"
25283 									  "    gl_TessLevelInner[0] = 1.0;\n"
25284 									  "    gl_TessLevelInner[1] = 1.0;\n"
25285 									  "}\n"
25286 									  "\n";
25287 	static const GLchar* tes_tested = "#version 430 core\n"
25288 									  "#extension GL_ARB_enhanced_layouts : require\n"
25289 									  "\n"
25290 									  "layout(isolines, point_mode) in;\n"
25291 									  "\n"
25292 									  "VAR_DEFINITION"
25293 									  "\n"
25294 									  "in  vec4 tcs_tes[];\n"
25295 									  "out vec4 tes_gs;\n"
25296 									  "\n"
25297 									  "void main()\n"
25298 									  "{\n"
25299 									  "    vec4 result = tcs_tes[0];\n"
25300 									  "\n"
25301 									  "VARIABLE_USE"
25302 									  "\n"
25303 									  "    tes_gs += result;\n"
25304 									  "}\n"
25305 									  "\n";
25306 	static const GLchar* vs = "#version 430 core\n"
25307 							  "#extension GL_ARB_enhanced_layouts : require\n"
25308 							  "\n"
25309 							  "in  vec4 in_vs;\n"
25310 							  "out vec4 vs_tcs;\n"
25311 							  "\n"
25312 							  "void main()\n"
25313 							  "{\n"
25314 							  "    vs_tcs = in_vs;\n"
25315 							  "}\n"
25316 							  "\n";
25317 	static const GLchar* vs_tested = "#version 430 core\n"
25318 									 "#extension GL_ARB_enhanced_layouts : require\n"
25319 									 "\n"
25320 									 "VAR_DEFINITION"
25321 									 "\n"
25322 									 "in  vec4 in_vs;\n"
25323 									 "out vec4 vs_tcs;\n"
25324 									 "\n"
25325 									 "void main()\n"
25326 									 "{\n"
25327 									 "    vec4 result = in_vs;\n"
25328 									 "\n"
25329 									 "VARIABLE_USE"
25330 									 "\n"
25331 									 "    vs_tcs = result;\n"
25332 									 "}\n"
25333 									 "\n";
25334 
25335 	std::string source;
25336 	testCase&   test_case = m_test_cases[test_case_index];
25337 
25338 	if (test_case.m_stage == stage)
25339 	{
25340 		const GLchar* array = "";
25341 		GLchar		  buffer_gohan[16];
25342 		GLchar		  buffer_goten[16];
25343 		const GLchar* index			 = "";
25344 		size_t		  position		 = 0;
25345 		size_t		  position_start = 0;
25346 		const GLchar* type_name		 = test_case.m_type.GetGLSLTypeName();
25347 
25348 		sprintf(buffer_gohan, "%d", test_case.m_offset_gohan);
25349 		sprintf(buffer_goten, "%d", test_case.m_offset_goten);
25350 
25351 		switch (stage)
25352 		{
25353 		case Utils::Shader::GEOMETRY:
25354 			source = gs_tested;
25355 			array  = "[]";
25356 			index  = "[0]";
25357 			break;
25358 		case Utils::Shader::TESS_CTRL:
25359 			source = tcs_tested;
25360 			array  = "[]";
25361 			index  = "[gl_InvocationID]";
25362 			break;
25363 		case Utils::Shader::TESS_EVAL:
25364 			source = tes_tested;
25365 			array  = "[]";
25366 			index  = "[0]";
25367 			break;
25368 		case Utils::Shader::VERTEX:
25369 			source = vs_tested;
25370 			break;
25371 		default:
25372 			TCU_FAIL("Invalid enum");
25373 		}
25374 
25375 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
25376 		position = 0;
25377 		Utils::replaceToken("OFFSET", position, buffer_gohan, source);
25378 		Utils::replaceToken("TYPE", position, type_name, source);
25379 		Utils::replaceToken("ARRAY", position, array, source);
25380 		Utils::replaceToken("OFFSET", position, buffer_goten, source);
25381 		Utils::replaceToken("TYPE", position, type_name, source);
25382 		Utils::replaceToken("ARRAY", position, array, source);
25383 		position_start = position;
25384 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
25385 		position = position_start;
25386 		Utils::replaceToken("INDEX", position, index, source);
25387 		Utils::replaceToken("TYPE", position, type_name, source);
25388 		Utils::replaceToken("INDEX", position, index, source);
25389 		Utils::replaceToken("TYPE", position, type_name, source);
25390 		Utils::replaceToken("INDEX", position, index, source);
25391 		Utils::replaceToken("TYPE", position, type_name, source);
25392 		Utils::replaceToken("INDEX", position, index, source);
25393 		Utils::replaceToken("TYPE", position, type_name, source);
25394 	}
25395 	else
25396 	{
25397 		switch (test_case.m_stage)
25398 		{
25399 		case Utils::Shader::GEOMETRY:
25400 			switch (stage)
25401 			{
25402 			case Utils::Shader::FRAGMENT:
25403 				source = fs;
25404 				break;
25405 			case Utils::Shader::VERTEX:
25406 				source = vs;
25407 				break;
25408 			default:
25409 				source = "";
25410 			}
25411 			break;
25412 		case Utils::Shader::TESS_CTRL:
25413 			switch (stage)
25414 			{
25415 			case Utils::Shader::FRAGMENT:
25416 				source = fs;
25417 				break;
25418 			case Utils::Shader::VERTEX:
25419 				source = vs;
25420 				break;
25421 			default:
25422 				source = "";
25423 			}
25424 			break;
25425 		case Utils::Shader::TESS_EVAL:
25426 			switch (stage)
25427 			{
25428 			case Utils::Shader::FRAGMENT:
25429 				source = fs;
25430 				break;
25431 			case Utils::Shader::TESS_CTRL:
25432 				source = tcs;
25433 				break;
25434 			case Utils::Shader::VERTEX:
25435 				source = vs;
25436 				break;
25437 			default:
25438 				source = "";
25439 			}
25440 			break;
25441 		case Utils::Shader::VERTEX:
25442 			switch (stage)
25443 			{
25444 			case Utils::Shader::FRAGMENT:
25445 				source = fs;
25446 				break;
25447 			default:
25448 				source = "";
25449 			}
25450 			break;
25451 		default:
25452 			TCU_FAIL("Invalid enum");
25453 			break;
25454 		}
25455 	}
25456 
25457 	return source;
25458 }
25459 
25460 /** Get description of test case
25461  *
25462  * @param test_case_index Index of test case
25463  *
25464  * @return Test case description
25465  **/
25466 std::string XFBOutputOverlappingTest::getTestCaseName(GLuint test_case_index)
25467 {
25468 	std::stringstream stream;
25469 	testCase&		  test_case = m_test_cases[test_case_index];
25470 
25471 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
25472 		   << ", type: " << test_case.m_type.GetGLSLTypeName() << ", offsets: " << test_case.m_offset_gohan << " & "
25473 		   << test_case.m_offset_goten;
25474 
25475 	return stream.str();
25476 }
25477 
25478 /** Get number of test cases
25479  *
25480  * @return Number of test cases
25481  **/
25482 GLuint XFBOutputOverlappingTest::getTestCaseNumber()
25483 {
25484 	return static_cast<GLuint>(m_test_cases.size());
25485 }
25486 
25487 /** Selects if "compute" stage is relevant for test
25488  *
25489  * @param ignored
25490  *
25491  * @return false
25492  **/
25493 bool XFBOutputOverlappingTest::isComputeRelevant(GLuint /* test_case_index */)
25494 {
25495 	return false;
25496 }
25497 
25498 /** Prepare all test cases
25499  *
25500  **/
25501 void XFBOutputOverlappingTest::testInit()
25502 {
25503 	const GLuint n_types = getTypesNumber();
25504 
25505 	for (GLuint i = 0; i < n_types; ++i)
25506 	{
25507 		const Utils::Type& type			  = getType(i);
25508 		const GLuint	   base_alingment = Utils::Type::GetTypeSize(type.m_basic_type);
25509 
25510 		/* Skip scalars, not applicable as:
25511 		 *
25512 		 *     The offset must be a multiple of the size of the first component of the first
25513 		 *     qualified variable or block member, or a compile-time error results.
25514 		 */
25515 		if ((1 == type.m_n_columns) && (1 == type.m_n_rows))
25516 		{
25517 			continue;
25518 		}
25519 
25520 		for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
25521 		{
25522 			if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
25523 				(Utils::Shader::FRAGMENT == stage))
25524 			{
25525 				continue;
25526 			}
25527 
25528 			testCase test_case = { 0 /* gohan offset */, base_alingment /* goten_offset */,
25529 								   (Utils::Shader::STAGES)stage, type };
25530 
25531 			m_test_cases.push_back(test_case);
25532 		}
25533 	}
25534 }
25535 
25536 /** Constructor
25537  *
25538  * @param context Test framework context
25539  **/
25540 XFBInvalidOffsetAlignmentTest::XFBInvalidOffsetAlignmentTest(deqp::Context& context)
25541 	: NegativeTestBase(context, "xfb_invalid_offset_alignment",
25542 					   "Test verifies that compiler reports error when xfb_offset has invalid alignment")
25543 {
25544 }
25545 
25546 /** Source for given test case and stage
25547  *
25548  * @param test_case_index Index of test case
25549  * @param stage           Shader stage
25550  *
25551  * @return Shader source
25552  **/
25553 std::string XFBInvalidOffsetAlignmentTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
25554 {
25555 	static const GLchar* var_definition = "layout (xfb_offset = OFFSET) out TYPE gohanARRAY;\n";
25556 	static const GLchar* var_use		= "    gohanINDEX = TYPE(0);\n"
25557 								   "    if (vec4(0) == result)\n"
25558 								   "    {\n"
25559 								   "        gohanINDEX = TYPE(1);\n"
25560 								   "    }\n";
25561 	static const GLchar* fs = "#version 430 core\n"
25562 							  "#extension GL_ARB_enhanced_layouts : require\n"
25563 							  "\n"
25564 							  "in  vec4 gs_fs;\n"
25565 							  "out vec4 fs_out;\n"
25566 							  "\n"
25567 							  "void main()\n"
25568 							  "{\n"
25569 							  "    fs_out = gs_fs;\n"
25570 							  "}\n"
25571 							  "\n";
25572 	static const GLchar* gs_tested = "#version 430 core\n"
25573 									 "#extension GL_ARB_enhanced_layouts : require\n"
25574 									 "\n"
25575 									 "layout(points)                           in;\n"
25576 									 "layout(triangle_strip, max_vertices = 4) out;\n"
25577 									 "\n"
25578 									 "VAR_DEFINITION"
25579 									 "\n"
25580 									 "in  vec4 tes_gs[];\n"
25581 									 "out vec4 gs_fs;\n"
25582 									 "\n"
25583 									 "void main()\n"
25584 									 "{\n"
25585 									 "    vec4 result = tes_gs[0];\n"
25586 									 "\n"
25587 									 "VARIABLE_USE"
25588 									 "\n"
25589 									 "    gs_fs = result;\n"
25590 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
25591 									 "    EmitVertex();\n"
25592 									 "    gs_fs = result;\n"
25593 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
25594 									 "    EmitVertex();\n"
25595 									 "    gs_fs = result;\n"
25596 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
25597 									 "    EmitVertex();\n"
25598 									 "    gs_fs = result;\n"
25599 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
25600 									 "    EmitVertex();\n"
25601 									 "}\n"
25602 									 "\n";
25603 	static const GLchar* tcs = "#version 430 core\n"
25604 							   "#extension GL_ARB_enhanced_layouts : require\n"
25605 							   "\n"
25606 							   "layout(vertices = 1) out;\n"
25607 							   "\n"
25608 							   "in  vec4 vs_tcs[];\n"
25609 							   "out vec4 tcs_tes[];\n"
25610 							   "\n"
25611 							   "void main()\n"
25612 							   "{\n"
25613 							   "\n"
25614 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
25615 							   "\n"
25616 							   "    gl_TessLevelOuter[0] = 1.0;\n"
25617 							   "    gl_TessLevelOuter[1] = 1.0;\n"
25618 							   "    gl_TessLevelOuter[2] = 1.0;\n"
25619 							   "    gl_TessLevelOuter[3] = 1.0;\n"
25620 							   "    gl_TessLevelInner[0] = 1.0;\n"
25621 							   "    gl_TessLevelInner[1] = 1.0;\n"
25622 							   "}\n"
25623 							   "\n";
25624 	static const GLchar* tcs_tested = "#version 430 core\n"
25625 									  "#extension GL_ARB_enhanced_layouts : require\n"
25626 									  "\n"
25627 									  "layout(vertices = 1) out;\n"
25628 									  "\n"
25629 									  "VAR_DEFINITION"
25630 									  "\n"
25631 									  "in  vec4 vs_tcs[];\n"
25632 									  "out vec4 tcs_tes[];\n"
25633 									  "\n"
25634 									  "void main()\n"
25635 									  "{\n"
25636 									  "    vec4 result = vs_tcs[gl_InvocationID];\n"
25637 									  "\n"
25638 									  "VARIABLE_USE"
25639 									  "\n"
25640 									  "    tcs_tes[gl_InvocationID] = result;\n"
25641 									  "\n"
25642 									  "    gl_TessLevelOuter[0] = 1.0;\n"
25643 									  "    gl_TessLevelOuter[1] = 1.0;\n"
25644 									  "    gl_TessLevelOuter[2] = 1.0;\n"
25645 									  "    gl_TessLevelOuter[3] = 1.0;\n"
25646 									  "    gl_TessLevelInner[0] = 1.0;\n"
25647 									  "    gl_TessLevelInner[1] = 1.0;\n"
25648 									  "}\n"
25649 									  "\n";
25650 	static const GLchar* tes_tested = "#version 430 core\n"
25651 									  "#extension GL_ARB_enhanced_layouts : require\n"
25652 									  "\n"
25653 									  "layout(isolines, point_mode) in;\n"
25654 									  "\n"
25655 									  "VAR_DEFINITION"
25656 									  "\n"
25657 									  "in  vec4 tcs_tes[];\n"
25658 									  "out vec4 tes_gs;\n"
25659 									  "\n"
25660 									  "void main()\n"
25661 									  "{\n"
25662 									  "    vec4 result = tcs_tes[0];\n"
25663 									  "\n"
25664 									  "VARIABLE_USE"
25665 									  "\n"
25666 									  "    tes_gs += result;\n"
25667 									  "}\n"
25668 									  "\n";
25669 	static const GLchar* vs = "#version 430 core\n"
25670 							  "#extension GL_ARB_enhanced_layouts : require\n"
25671 							  "\n"
25672 							  "in  vec4 in_vs;\n"
25673 							  "out vec4 vs_tcs;\n"
25674 							  "\n"
25675 							  "void main()\n"
25676 							  "{\n"
25677 							  "    vs_tcs = in_vs;\n"
25678 							  "}\n"
25679 							  "\n";
25680 	static const GLchar* vs_tested = "#version 430 core\n"
25681 									 "#extension GL_ARB_enhanced_layouts : require\n"
25682 									 "\n"
25683 									 "VAR_DEFINITION"
25684 									 "\n"
25685 									 "in  vec4 in_vs;\n"
25686 									 "out vec4 vs_tcs;\n"
25687 									 "\n"
25688 									 "void main()\n"
25689 									 "{\n"
25690 									 "    vec4 result = in_vs;\n"
25691 									 "\n"
25692 									 "VARIABLE_USE"
25693 									 "\n"
25694 									 "    vs_tcs = result;\n"
25695 									 "}\n"
25696 									 "\n";
25697 
25698 	std::string source;
25699 	testCase&   test_case = m_test_cases[test_case_index];
25700 
25701 	if (test_case.m_stage == stage)
25702 	{
25703 		const GLchar* array = "";
25704 		GLchar		  buffer[16];
25705 		const GLchar* index			 = "";
25706 		size_t		  position		 = 0;
25707 		size_t		  position_start = 0;
25708 		const GLchar* type_name		 = test_case.m_type.GetGLSLTypeName();
25709 
25710 		sprintf(buffer, "%d", test_case.m_offset);
25711 
25712 		switch (stage)
25713 		{
25714 		case Utils::Shader::GEOMETRY:
25715 			source = gs_tested;
25716 			array  = "[]";
25717 			index  = "[0]";
25718 			break;
25719 		case Utils::Shader::TESS_CTRL:
25720 			source = tcs_tested;
25721 			array  = "[]";
25722 			index  = "[gl_InvocationID]";
25723 			break;
25724 		case Utils::Shader::TESS_EVAL:
25725 			source = tes_tested;
25726 			array  = "[]";
25727 			index  = "[0]";
25728 			break;
25729 		case Utils::Shader::VERTEX:
25730 			source = vs_tested;
25731 			break;
25732 		default:
25733 			TCU_FAIL("Invalid enum");
25734 		}
25735 
25736 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
25737 		position = 0;
25738 		Utils::replaceToken("OFFSET", position, buffer, source);
25739 		Utils::replaceToken("TYPE", position, type_name, source);
25740 		Utils::replaceToken("ARRAY", position, array, source);
25741 		position_start = position;
25742 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
25743 		position = position_start;
25744 		Utils::replaceToken("INDEX", position, index, source);
25745 		Utils::replaceToken("TYPE", position, type_name, source);
25746 		Utils::replaceToken("INDEX", position, index, source);
25747 		Utils::replaceToken("TYPE", position, type_name, source);
25748 	}
25749 	else
25750 	{
25751 		switch (test_case.m_stage)
25752 		{
25753 		case Utils::Shader::GEOMETRY:
25754 			switch (stage)
25755 			{
25756 			case Utils::Shader::FRAGMENT:
25757 				source = fs;
25758 				break;
25759 			case Utils::Shader::VERTEX:
25760 				source = vs;
25761 				break;
25762 			default:
25763 				source = "";
25764 			}
25765 			break;
25766 		case Utils::Shader::TESS_CTRL:
25767 			switch (stage)
25768 			{
25769 			case Utils::Shader::FRAGMENT:
25770 				source = fs;
25771 				break;
25772 			case Utils::Shader::VERTEX:
25773 				source = vs;
25774 				break;
25775 			default:
25776 				source = "";
25777 			}
25778 			break;
25779 		case Utils::Shader::TESS_EVAL:
25780 			switch (stage)
25781 			{
25782 			case Utils::Shader::FRAGMENT:
25783 				source = fs;
25784 				break;
25785 			case Utils::Shader::TESS_CTRL:
25786 				source = tcs;
25787 				break;
25788 			case Utils::Shader::VERTEX:
25789 				source = vs;
25790 				break;
25791 			default:
25792 				source = "";
25793 			}
25794 			break;
25795 		case Utils::Shader::VERTEX:
25796 			switch (stage)
25797 			{
25798 			case Utils::Shader::FRAGMENT:
25799 				source = fs;
25800 				break;
25801 			default:
25802 				source = "";
25803 			}
25804 			break;
25805 		default:
25806 			TCU_FAIL("Invalid enum");
25807 			break;
25808 		}
25809 	}
25810 
25811 	return source;
25812 }
25813 
25814 /** Get description of test case
25815  *
25816  * @param test_case_index Index of test case
25817  *
25818  * @return Test case description
25819  **/
25820 std::string XFBInvalidOffsetAlignmentTest::getTestCaseName(GLuint test_case_index)
25821 {
25822 	std::stringstream stream;
25823 	testCase&		  test_case = m_test_cases[test_case_index];
25824 
25825 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
25826 		   << ", type: " << test_case.m_type.GetGLSLTypeName() << ", offset: " << test_case.m_offset;
25827 
25828 	return stream.str();
25829 }
25830 
25831 /** Get number of test cases
25832  *
25833  * @return Number of test cases
25834  **/
25835 GLuint XFBInvalidOffsetAlignmentTest::getTestCaseNumber()
25836 {
25837 	return static_cast<GLuint>(m_test_cases.size());
25838 }
25839 
25840 /** Selects if "compute" stage is relevant for test
25841  *
25842  * @param ignored
25843  *
25844  * @return false
25845  **/
25846 bool XFBInvalidOffsetAlignmentTest::isComputeRelevant(GLuint /* test_case_index */)
25847 {
25848 	return false;
25849 }
25850 
25851 /** Prepare all test cases
25852  *
25853  **/
25854 void XFBInvalidOffsetAlignmentTest::testInit()
25855 {
25856 	const GLuint n_types = getTypesNumber();
25857 
25858 	for (GLuint i = 0; i < n_types; ++i)
25859 	{
25860 		const Utils::Type& type			  = getType(i);
25861 		const GLuint	   base_alingment = Utils::Type::GetTypeSize(type.m_basic_type);
25862 
25863 		for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
25864 		{
25865 			if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
25866 				(Utils::Shader::FRAGMENT == stage))
25867 			{
25868 				continue;
25869 			}
25870 
25871 			for (GLuint offset = base_alingment + 1; offset < 2 * base_alingment; ++offset)
25872 			{
25873 				testCase test_case = { offset, (Utils::Shader::STAGES)stage, type };
25874 
25875 				m_test_cases.push_back(test_case);
25876 			}
25877 		}
25878 	}
25879 }
25880 
25881 /** Constructor
25882  *
25883  * @param context Test context
25884  **/
25885 XFBCaptureInactiveOutputVariableTest::XFBCaptureInactiveOutputVariableTest(deqp::Context& context)
25886 	: BufferTestBase(context, "xfb_capture_inactive_output_variable",
25887 					 "Test verifies that inactive variables are captured")
25888 {
25889 	/* Nothing to be done here */
25890 }
25891 
25892 /** Execute drawArrays for single vertex
25893  *
25894  * @param test_case_index
25895  *
25896  * @return true
25897  **/
25898 bool XFBCaptureInactiveOutputVariableTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
25899 {
25900 	const Functions& gl				= m_context.getRenderContext().getFunctions();
25901 	GLenum			 primitive_type = GL_PATCHES;
25902 
25903 	if (TEST_VS == test_case_index)
25904 	{
25905 		primitive_type = GL_POINTS;
25906 	}
25907 
25908 	gl.disable(GL_RASTERIZER_DISCARD);
25909 	GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
25910 
25911 	gl.beginTransformFeedback(GL_POINTS);
25912 	GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
25913 
25914 	gl.drawArrays(primitive_type, 0 /* first */, 1 /* count */);
25915 	GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
25916 
25917 	gl.endTransformFeedback();
25918 	GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
25919 
25920 	return true;
25921 }
25922 
25923 /** Get descriptors of buffers necessary for test
25924  *
25925  * @param ignored
25926  * @param out_descriptors Descriptors of buffers used by test
25927  **/
25928 void XFBCaptureInactiveOutputVariableTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
25929 																bufferDescriptor::Vector& out_descriptors)
25930 {
25931 	const Utils::Type& type = Utils::Type::vec4;
25932 
25933 	/* Test needs single uniform and xfb */
25934 	out_descriptors.resize(2);
25935 
25936 	/* Get references */
25937 	bufferDescriptor& uniform = out_descriptors[0];
25938 	bufferDescriptor& xfb	 = out_descriptors[1];
25939 
25940 	/* Index */
25941 	uniform.m_index = 0;
25942 	xfb.m_index		= 0;
25943 
25944 	/* Target */
25945 	uniform.m_target = Utils::Buffer::Uniform;
25946 	xfb.m_target	 = Utils::Buffer::Transform_feedback;
25947 
25948 	/* Data */
25949 	const std::vector<GLubyte>& gohan_data = type.GenerateData();
25950 	const std::vector<GLubyte>& goten_data = type.GenerateData();
25951 
25952 	const GLuint type_size = static_cast<GLuint>(gohan_data.size());
25953 
25954 	/* Uniform data */
25955 	uniform.m_initial_data.resize(2 * type_size);
25956 	memcpy(&uniform.m_initial_data[0] + 0, &gohan_data[0], type_size);
25957 	memcpy(&uniform.m_initial_data[0] + type_size, &goten_data[0], type_size);
25958 
25959 	/* XFB data */
25960 	xfb.m_initial_data.resize(3 * type_size);
25961 	xfb.m_expected_data.resize(3 * type_size);
25962 
25963 	for (GLuint i = 0; i < 3 * type_size; ++i)
25964 	{
25965 		xfb.m_initial_data[i]  = (glw::GLubyte)i;
25966 		xfb.m_expected_data[i] = (glw::GLubyte)i;
25967 	}
25968 
25969 	memcpy(&xfb.m_expected_data[0] + 2 * type_size, &gohan_data[0], type_size);
25970 	memcpy(&xfb.m_expected_data[0] + 0 * type_size, &goten_data[0], type_size);
25971 }
25972 
25973 /** Get body of main function for given shader stage
25974  *
25975  * @param test_case_index  Index of test case
25976  * @param stage            Shader stage
25977  * @param out_assignments  Set to empty
25978  * @param out_calculations Set to empty
25979  **/
25980 void XFBCaptureInactiveOutputVariableTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
25981 														 std::string& out_assignments, std::string& out_calculations)
25982 {
25983 	out_calculations = "";
25984 
25985 	static const GLchar* vs_tes_gs = "    goten = uni_goten;\n"
25986 									 "    gohan = uni_gohan;\n";
25987 	static const GLchar* fs = "    fs_out = goku + gohan + goten;\n";
25988 
25989 	const GLchar* assignments = "";
25990 
25991 	switch (stage)
25992 	{
25993 	case Utils::Shader::FRAGMENT:
25994 		assignments = fs;
25995 		break;
25996 
25997 	case Utils::Shader::GEOMETRY:
25998 		if (TEST_GS == test_case_index)
25999 		{
26000 			assignments = vs_tes_gs;
26001 		}
26002 		break;
26003 
26004 	case Utils::Shader::TESS_CTRL:
26005 		break;
26006 
26007 	case Utils::Shader::TESS_EVAL:
26008 		if (TEST_TES == test_case_index)
26009 		{
26010 			assignments = vs_tes_gs;
26011 		}
26012 		break;
26013 
26014 	case Utils::Shader::VERTEX:
26015 		if (TEST_VS == test_case_index)
26016 		{
26017 			assignments = vs_tes_gs;
26018 		}
26019 		break;
26020 
26021 	default:
26022 		TCU_FAIL("Invalid enum");
26023 	}
26024 
26025 	out_assignments = assignments;
26026 }
26027 
26028 /** Get interface of shader
26029  *
26030  * @param test_case_index  Index of test case
26031  * @param stage            Shader stage
26032  * @param out_interface    Set to ""
26033  **/
26034 void XFBCaptureInactiveOutputVariableTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
26035 															  std::string& out_interface)
26036 {
26037 	static const GLchar* vs_tes_gs = "const uint sizeof_type = 16;\n"
26038 									 "\n"
26039 									 "layout (xfb_offset = 1 * sizeof_type) out vec4 goku;\n"
26040 									 "layout (xfb_offset = 2 * sizeof_type) out vec4 gohan;\n"
26041 									 "layout (xfb_offset = 0 * sizeof_type) out vec4 goten;\n"
26042 									 "\n"
26043 									 "layout(binding = 0) uniform block {\n"
26044 									 "    vec4 uni_gohan;\n"
26045 									 "    vec4 uni_goten;\n"
26046 									 "};\n";
26047 	static const GLchar* fs = "in vec4 goku;\n"
26048 							  "in vec4 gohan;\n"
26049 							  "in vec4 goten;\n"
26050 							  "out vec4 fs_out;\n";
26051 
26052 	const GLchar* interface = "";
26053 
26054 	switch (stage)
26055 	{
26056 	case Utils::Shader::FRAGMENT:
26057 		interface = fs;
26058 		break;
26059 
26060 	case Utils::Shader::GEOMETRY:
26061 		if (TEST_GS == test_case_index)
26062 		{
26063 			interface = vs_tes_gs;
26064 		}
26065 		break;
26066 
26067 	case Utils::Shader::TESS_CTRL:
26068 		break;
26069 
26070 	case Utils::Shader::TESS_EVAL:
26071 		if (TEST_TES == test_case_index)
26072 		{
26073 			interface = vs_tes_gs;
26074 		}
26075 		break;
26076 
26077 	case Utils::Shader::VERTEX:
26078 		if (TEST_VS == test_case_index)
26079 		{
26080 			interface = vs_tes_gs;
26081 		}
26082 		break;
26083 
26084 	default:
26085 		TCU_FAIL("Invalid enum");
26086 	}
26087 
26088 	out_interface = interface;
26089 }
26090 
26091 /** Get source code of shader
26092  *
26093  * @param test_case_index Index of test case
26094  * @param stage           Shader stage
26095  *
26096  * @return Source
26097  **/
26098 std::string XFBCaptureInactiveOutputVariableTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
26099 {
26100 	std::string source;
26101 
26102 	switch (test_case_index)
26103 	{
26104 	case TEST_VS:
26105 		switch (stage)
26106 		{
26107 		case Utils::Shader::FRAGMENT:
26108 		case Utils::Shader::VERTEX:
26109 			source = BufferTestBase::getShaderSource(test_case_index, stage);
26110 			break;
26111 		default:
26112 			break;
26113 		}
26114 		break;
26115 
26116 	case TEST_TES:
26117 		switch (stage)
26118 		{
26119 		case Utils::Shader::FRAGMENT:
26120 		case Utils::Shader::TESS_CTRL:
26121 		case Utils::Shader::TESS_EVAL:
26122 		case Utils::Shader::VERTEX:
26123 			source = BufferTestBase::getShaderSource(test_case_index, stage);
26124 			break;
26125 		default:
26126 			break;
26127 		}
26128 		break;
26129 
26130 	case TEST_GS:
26131 		source = BufferTestBase::getShaderSource(test_case_index, stage);
26132 		break;
26133 
26134 	default:
26135 		TCU_FAIL("Invalid enum");
26136 		break;
26137 	}
26138 
26139 	/* */
26140 	return source;
26141 }
26142 
26143 /** Get name of test case
26144  *
26145  * @param test_case_index Index of test case
26146  *
26147  * @return Name of tested stage
26148  **/
26149 std::string XFBCaptureInactiveOutputVariableTest::getTestCaseName(glw::GLuint test_case_index)
26150 {
26151 	const GLchar* name = 0;
26152 
26153 	switch (test_case_index)
26154 	{
26155 	case TEST_VS:
26156 		name = "vertex";
26157 		break;
26158 	case TEST_TES:
26159 		name = "tessellation evaluation";
26160 		break;
26161 	case TEST_GS:
26162 		name = "geometry";
26163 		break;
26164 	default:
26165 		TCU_FAIL("Invalid enum");
26166 	}
26167 
26168 	return name;
26169 }
26170 
26171 /** Returns number of test cases
26172  *
26173  * @return TEST_MAX
26174  **/
26175 glw::GLuint XFBCaptureInactiveOutputVariableTest::getTestCaseNumber()
26176 {
26177 	return TEST_MAX;
26178 }
26179 
26180 /** Inspects program to check if all resources are as expected
26181  *
26182  * @param ignored
26183  * @param program         Program instance
26184  * @param out_stream      Error message
26185  *
26186  * @return true if everything is ok, false otherwise
26187  **/
26188 bool XFBCaptureInactiveOutputVariableTest::inspectProgram(GLuint /* test_case_index */, Utils::Program& program,
26189 														  std::stringstream& out_stream)
26190 {
26191 	GLint			   stride	= 0;
26192 	const Utils::Type& type		 = Utils::Type::vec4;
26193 	const GLuint	   type_size = type.GetSize();
26194 
26195 	program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE,
26196 						1 /* buf_size */, &stride);
26197 
26198 	if ((GLint)(3 * type_size) != stride)
26199 	{
26200 		out_stream << "Stride is: " << stride << " expected: " << (3 * type_size);
26201 
26202 		return false;
26203 	}
26204 
26205 	return true;
26206 }
26207 
26208 /** Verify contents of buffers
26209  *
26210  * @param buffers Collection of buffers to be verified
26211  *
26212  * @return true if everything is as expected, false otherwise
26213  **/
26214 bool XFBCaptureInactiveOutputVariableTest::verifyBuffers(bufferCollection& buffers)
26215 {
26216 	bool result = true;
26217 
26218 	bufferCollection::pair& pair	   = buffers.m_vector[1] /* xfb */;
26219 	Utils::Buffer*			buffer	 = pair.m_buffer;
26220 	bufferDescriptor*		descriptor = pair.m_descriptor;
26221 
26222 	/* Get pointer to contents of buffer */
26223 	buffer->Bind();
26224 	GLubyte* buffer_data = (GLubyte*)buffer->Map(Utils::Buffer::ReadOnly);
26225 
26226 	/* Get pointer to expected data */
26227 	GLubyte* expected_data = (GLubyte*)&descriptor->m_expected_data[0];
26228 
26229 	/* Compare */
26230 	static const GLuint vec4_size = 16;
26231 
26232 	int res_gohan = memcmp(buffer_data + 2 * vec4_size, expected_data + 2 * vec4_size, vec4_size);
26233 	int res_goten = memcmp(buffer_data + 0 * vec4_size, expected_data + 0 * vec4_size, vec4_size);
26234 
26235 	if ((0 != res_gohan) || (0 != res_goten))
26236 	{
26237 		m_context.getTestContext().getLog()
26238 			<< tcu::TestLog::Message << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
26239 			<< ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
26240 
26241 		result = false;
26242 	}
26243 
26244 	/* Release buffer mapping */
26245 	buffer->UnMap();
26246 
26247 	return result;
26248 }
26249 
26250 /** Constructor
26251  *
26252  * @param context Test context
26253  **/
26254 XFBCaptureInactiveOutputComponentTest::XFBCaptureInactiveOutputComponentTest(deqp::Context& context)
26255 	: BufferTestBase(context, "xfb_capture_inactive_output_component",
26256 					 "Test verifies that inactive components are not modified")
26257 {
26258 	/* Nothing to be done here */
26259 }
26260 
26261 /** Execute drawArrays for single vertex
26262  *
26263  * @param test_case_index
26264  *
26265  * @return true
26266  **/
26267 bool XFBCaptureInactiveOutputComponentTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
26268 {
26269 	const Functions& gl				= m_context.getRenderContext().getFunctions();
26270 	GLenum			 primitive_type = GL_PATCHES;
26271 
26272 	if (TEST_VS == test_case_index)
26273 	{
26274 		primitive_type = GL_POINTS;
26275 	}
26276 
26277 	gl.disable(GL_RASTERIZER_DISCARD);
26278 	GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
26279 
26280 	gl.beginTransformFeedback(GL_POINTS);
26281 	GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
26282 
26283 	gl.drawArrays(primitive_type, 0 /* first */, 1 /* count */);
26284 	GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
26285 
26286 	gl.endTransformFeedback();
26287 	GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
26288 
26289 	return true;
26290 }
26291 
26292 /** Get descriptors of buffers necessary for test
26293  *
26294  * @param ignored
26295  * @param out_descriptors Descriptors of buffers used by test
26296  **/
26297 void XFBCaptureInactiveOutputComponentTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
26298 																 bufferDescriptor::Vector& out_descriptors)
26299 {
26300 	const Utils::Type& type = Utils::Type::vec4;
26301 
26302 	/* Test needs single uniform and xfb */
26303 	out_descriptors.resize(2);
26304 
26305 	/* Get references */
26306 	bufferDescriptor& uniform = out_descriptors[0];
26307 	bufferDescriptor& xfb	 = out_descriptors[1];
26308 
26309 	/* Index */
26310 	uniform.m_index = 0;
26311 	xfb.m_index		= 0;
26312 
26313 	/* Target */
26314 	uniform.m_target = Utils::Buffer::Uniform;
26315 	xfb.m_target	 = Utils::Buffer::Transform_feedback;
26316 
26317 	/* Data */
26318 	const std::vector<GLubyte>& goku_data   = type.GenerateData();
26319 	const std::vector<GLubyte>& gohan_data  = type.GenerateData();
26320 	const std::vector<GLubyte>& goten_data  = type.GenerateData();
26321 	const std::vector<GLubyte>& chichi_data = type.GenerateData();
26322 	const std::vector<GLubyte>& vegeta_data = type.GenerateData();
26323 	const std::vector<GLubyte>& trunks_data = type.GenerateData();
26324 	const std::vector<GLubyte>& bra_data	= type.GenerateData();
26325 	const std::vector<GLubyte>& bulma_data  = type.GenerateData();
26326 
26327 	const GLuint comp_size = Utils::Type::GetTypeSize(type.m_basic_type);
26328 	const GLuint type_size = static_cast<GLuint>(gohan_data.size());
26329 
26330 	/* Uniform data */
26331 	uniform.m_initial_data.resize(8 * type_size);
26332 	memcpy(&uniform.m_initial_data[0] + 0 * type_size, &goku_data[0], type_size);
26333 	memcpy(&uniform.m_initial_data[0] + 1 * type_size, &gohan_data[0], type_size);
26334 	memcpy(&uniform.m_initial_data[0] + 2 * type_size, &goten_data[0], type_size);
26335 	memcpy(&uniform.m_initial_data[0] + 3 * type_size, &chichi_data[0], type_size);
26336 	memcpy(&uniform.m_initial_data[0] + 4 * type_size, &vegeta_data[0], type_size);
26337 	memcpy(&uniform.m_initial_data[0] + 5 * type_size, &trunks_data[0], type_size);
26338 	memcpy(&uniform.m_initial_data[0] + 6 * type_size, &bra_data[0], type_size);
26339 	memcpy(&uniform.m_initial_data[0] + 7 * type_size, &bulma_data[0], type_size);
26340 
26341 	/* XFB data */
26342 	xfb.m_initial_data.resize(8 * type_size);
26343 	xfb.m_expected_data.resize(8 * type_size);
26344 
26345 	for (GLuint i = 0; i < 8 * type_size; ++i)
26346 	{
26347 		xfb.m_initial_data[i]  = (glw::GLubyte)i;
26348 		xfb.m_expected_data[i] = (glw::GLubyte)i;
26349 	}
26350 
26351 	/* goku - x, z - 32 */
26352 	memcpy(&xfb.m_expected_data[0] + 2 * type_size + 0 * comp_size, &goku_data[0] + 0 * comp_size, comp_size);
26353 	memcpy(&xfb.m_expected_data[0] + 2 * type_size + 2 * comp_size, &goku_data[0] + 2 * comp_size, comp_size);
26354 
26355 	/* gohan - y, w - 0 */
26356 	memcpy(&xfb.m_expected_data[0] + 0 * type_size + 1 * comp_size, &gohan_data[0] + 1 * comp_size, comp_size);
26357 	memcpy(&xfb.m_expected_data[0] + 0 * type_size + 3 * comp_size, &gohan_data[0] + 3 * comp_size, comp_size);
26358 
26359 	/* goten - x, y - 16 */
26360 	memcpy(&xfb.m_expected_data[0] + 1 * type_size + 0 * comp_size, &goten_data[0] + 0 * comp_size, comp_size);
26361 	memcpy(&xfb.m_expected_data[0] + 1 * type_size + 1 * comp_size, &goten_data[0] + 1 * comp_size, comp_size);
26362 
26363 	/* chichi - z, w - 48 */
26364 	memcpy(&xfb.m_expected_data[0] + 3 * type_size + 2 * comp_size, &chichi_data[0] + 2 * comp_size, comp_size);
26365 	memcpy(&xfb.m_expected_data[0] + 3 * type_size + 3 * comp_size, &chichi_data[0] + 3 * comp_size, comp_size);
26366 
26367 	/* vegeta - x - 112 */
26368 	memcpy(&xfb.m_expected_data[0] + 7 * type_size + 0 * comp_size, &vegeta_data[0] + 0 * comp_size, comp_size);
26369 
26370 	/* trunks - y - 96 */
26371 	memcpy(&xfb.m_expected_data[0] + 6 * type_size + 1 * comp_size, &trunks_data[0] + 1 * comp_size, comp_size);
26372 
26373 	/* bra - z - 80 */
26374 	memcpy(&xfb.m_expected_data[0] + 5 * type_size + 2 * comp_size, &bra_data[0] + 2 * comp_size, comp_size);
26375 
26376 	/* bulma - w - 64 */
26377 	memcpy(&xfb.m_expected_data[0] + 4 * type_size + 3 * comp_size, &bulma_data[0] + 3 * comp_size, comp_size);
26378 }
26379 
26380 /** Get body of main function for given shader stage
26381  *
26382  * @param test_case_index  Index of test case
26383  * @param stage            Shader stage
26384  * @param out_assignments  Set to empty
26385  * @param out_calculations Set to empty
26386  **/
26387 void XFBCaptureInactiveOutputComponentTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
26388 														  std::string& out_assignments, std::string& out_calculations)
26389 {
26390 	out_calculations = "";
26391 
26392 	static const GLchar* vs_tes_gs = "    goku.x    = uni_goku.x   ;\n"
26393 									 "    goku.z    = uni_goku.z   ;\n"
26394 									 "    gohan.y   = uni_gohan.y  ;\n"
26395 									 "    gohan.w   = uni_gohan.w  ;\n"
26396 									 "    goten.x   = uni_goten.x  ;\n"
26397 									 "    goten.y   = uni_goten.y  ;\n"
26398 									 "    chichi.z  = uni_chichi.z ;\n"
26399 									 "    chichi.w  = uni_chichi.w ;\n"
26400 									 "    vegeta.x  = uni_vegeta.x ;\n"
26401 									 "    trunks.y  = uni_trunks.y ;\n"
26402 									 "    bra.z     = uni_bra.z    ;\n"
26403 									 "    bulma.w   = uni_bulma.w  ;\n";
26404 	static const GLchar* fs = "    fs_out = goku + gohan + goten + chichi + vegeta + trunks + bra + bulma;\n";
26405 
26406 	const GLchar* assignments = "";
26407 
26408 	switch (stage)
26409 	{
26410 	case Utils::Shader::FRAGMENT:
26411 		assignments = fs;
26412 		break;
26413 
26414 	case Utils::Shader::GEOMETRY:
26415 		if (TEST_GS == test_case_index)
26416 		{
26417 			assignments = vs_tes_gs;
26418 		}
26419 		break;
26420 
26421 	case Utils::Shader::TESS_CTRL:
26422 		break;
26423 
26424 	case Utils::Shader::TESS_EVAL:
26425 		if (TEST_TES == test_case_index)
26426 		{
26427 			assignments = vs_tes_gs;
26428 		}
26429 		break;
26430 
26431 	case Utils::Shader::VERTEX:
26432 		if (TEST_VS == test_case_index)
26433 		{
26434 			assignments = vs_tes_gs;
26435 		}
26436 		break;
26437 
26438 	default:
26439 		TCU_FAIL("Invalid enum");
26440 	}
26441 
26442 	out_assignments = assignments;
26443 }
26444 
26445 /** Get interface of shader
26446  *
26447  * @param test_case_index  Index of test case
26448  * @param stage            Shader stage
26449  * @param out_interface    Set to ""
26450  **/
26451 void XFBCaptureInactiveOutputComponentTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
26452 															   std::string& out_interface)
26453 {
26454 	static const GLchar* vs_tes_gs = "const uint sizeof_type = 16;\n"
26455 									 "\n"
26456 									 "layout (xfb_offset = 2 * sizeof_type) out vec4 goku;\n"
26457 									 "layout (xfb_offset = 0 * sizeof_type) out vec4 gohan;\n"
26458 									 "layout (xfb_offset = 1 * sizeof_type) out vec4 goten;\n"
26459 									 "layout (xfb_offset = 3 * sizeof_type) out vec4 chichi;\n"
26460 									 "layout (xfb_offset = 7 * sizeof_type) out vec4 vegeta;\n"
26461 									 "layout (xfb_offset = 6 * sizeof_type) out vec4 trunks;\n"
26462 									 "layout (xfb_offset = 5 * sizeof_type) out vec4 bra;\n"
26463 									 "layout (xfb_offset = 4 * sizeof_type) out vec4 bulma;\n"
26464 									 "\n"
26465 									 "layout(binding = 0) uniform block {\n"
26466 									 "    vec4 uni_goku;\n"
26467 									 "    vec4 uni_gohan;\n"
26468 									 "    vec4 uni_goten;\n"
26469 									 "    vec4 uni_chichi;\n"
26470 									 "    vec4 uni_vegeta;\n"
26471 									 "    vec4 uni_trunks;\n"
26472 									 "    vec4 uni_bra;\n"
26473 									 "    vec4 uni_bulma;\n"
26474 									 "};\n";
26475 	static const GLchar* fs = "in vec4 vegeta;\n"
26476 							  "in vec4 trunks;\n"
26477 							  "in vec4 bra;\n"
26478 							  "in vec4 bulma;\n"
26479 							  "in vec4 goku;\n"
26480 							  "in vec4 gohan;\n"
26481 							  "in vec4 goten;\n"
26482 							  "in vec4 chichi;\n"
26483 							  "\n"
26484 							  "out vec4 fs_out;\n";
26485 
26486 	const GLchar* interface = "";
26487 
26488 	switch (stage)
26489 	{
26490 	case Utils::Shader::FRAGMENT:
26491 		interface = fs;
26492 		break;
26493 
26494 	case Utils::Shader::GEOMETRY:
26495 		if (TEST_GS == test_case_index)
26496 		{
26497 			interface = vs_tes_gs;
26498 		}
26499 		break;
26500 
26501 	case Utils::Shader::TESS_CTRL:
26502 		break;
26503 
26504 	case Utils::Shader::TESS_EVAL:
26505 		if (TEST_TES == test_case_index)
26506 		{
26507 			interface = vs_tes_gs;
26508 		}
26509 		break;
26510 
26511 	case Utils::Shader::VERTEX:
26512 		if (TEST_VS == test_case_index)
26513 		{
26514 			interface = vs_tes_gs;
26515 		}
26516 		break;
26517 
26518 	default:
26519 		TCU_FAIL("Invalid enum");
26520 	}
26521 
26522 	out_interface = interface;
26523 }
26524 
26525 /** Get source code of shader
26526  *
26527  * @param test_case_index Index of test case
26528  * @param stage           Shader stage
26529  *
26530  * @return Source
26531  **/
26532 std::string XFBCaptureInactiveOutputComponentTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
26533 {
26534 	std::string source;
26535 
26536 	switch (test_case_index)
26537 	{
26538 	case TEST_VS:
26539 		switch (stage)
26540 		{
26541 		case Utils::Shader::FRAGMENT:
26542 		case Utils::Shader::VERTEX:
26543 			source = BufferTestBase::getShaderSource(test_case_index, stage);
26544 			break;
26545 		default:
26546 			break;
26547 		}
26548 		break;
26549 
26550 	case TEST_TES:
26551 		switch (stage)
26552 		{
26553 		case Utils::Shader::FRAGMENT:
26554 		case Utils::Shader::TESS_CTRL:
26555 		case Utils::Shader::TESS_EVAL:
26556 		case Utils::Shader::VERTEX:
26557 			source = BufferTestBase::getShaderSource(test_case_index, stage);
26558 			break;
26559 		default:
26560 			break;
26561 		}
26562 		break;
26563 
26564 	case TEST_GS:
26565 		source = BufferTestBase::getShaderSource(test_case_index, stage);
26566 		break;
26567 
26568 	default:
26569 		TCU_FAIL("Invalid enum");
26570 		break;
26571 	}
26572 
26573 	/* */
26574 	return source;
26575 }
26576 
26577 /** Get name of test case
26578  *
26579  * @param test_case_index Index of test case
26580  *
26581  * @return Name of tested stage
26582  **/
26583 std::string XFBCaptureInactiveOutputComponentTest::getTestCaseName(glw::GLuint test_case_index)
26584 {
26585 	const GLchar* name = 0;
26586 
26587 	switch (test_case_index)
26588 	{
26589 	case TEST_VS:
26590 		name = "vertex";
26591 		break;
26592 	case TEST_TES:
26593 		name = "tessellation evaluation";
26594 		break;
26595 	case TEST_GS:
26596 		name = "geometry";
26597 		break;
26598 	default:
26599 		TCU_FAIL("Invalid enum");
26600 	}
26601 
26602 	return name;
26603 }
26604 
26605 /** Returns number of test cases
26606  *
26607  * @return TEST_MAX
26608  **/
26609 glw::GLuint XFBCaptureInactiveOutputComponentTest::getTestCaseNumber()
26610 {
26611 	return TEST_MAX;
26612 }
26613 
26614 /** Verify contents of buffers
26615  *
26616  * @param buffers Collection of buffers to be verified
26617  *
26618  * @return true if everything is as expected, false otherwise
26619  **/
26620 bool XFBCaptureInactiveOutputComponentTest::verifyBuffers(bufferCollection& buffers)
26621 {
26622 	bool result = true;
26623 
26624 	bufferCollection::pair& pair	   = buffers.m_vector[1] /* xfb */;
26625 	Utils::Buffer*			buffer	 = pair.m_buffer;
26626 	bufferDescriptor*		descriptor = pair.m_descriptor;
26627 
26628 	/* Get pointer to contents of buffer */
26629 	buffer->Bind();
26630 	GLubyte* buffer_data = (GLubyte*)buffer->Map(Utils::Buffer::ReadOnly);
26631 
26632 	/* Get pointer to expected data */
26633 	GLubyte* expected_data = (GLubyte*)&descriptor->m_expected_data[0];
26634 
26635 	/* Compare */
26636 	static const GLuint comp_size = 4;
26637 	static const GLuint vec4_size = 16;
26638 
26639 	int res_goku_x =
26640 		memcmp(buffer_data + 2 * vec4_size + 0 * comp_size, expected_data + 2 * vec4_size + 0 * comp_size, comp_size);
26641 	int res_goku_z =
26642 		memcmp(buffer_data + 2 * vec4_size + 2 * comp_size, expected_data + 2 * vec4_size + 2 * comp_size, comp_size);
26643 
26644 	int res_gohan_y =
26645 		memcmp(buffer_data + 0 * vec4_size + 1 * comp_size, expected_data + 0 * vec4_size + 1 * comp_size, comp_size);
26646 	int res_gohan_w =
26647 		memcmp(buffer_data + 0 * vec4_size + 3 * comp_size, expected_data + 0 * vec4_size + 3 * comp_size, comp_size);
26648 
26649 	int res_goten_x =
26650 		memcmp(buffer_data + 1 * vec4_size + 0 * comp_size, expected_data + 1 * vec4_size + 0 * comp_size, comp_size);
26651 	int res_goten_y =
26652 		memcmp(buffer_data + 1 * vec4_size + 1 * comp_size, expected_data + 1 * vec4_size + 1 * comp_size, comp_size);
26653 
26654 	int res_chichi_z =
26655 		memcmp(buffer_data + 3 * vec4_size + 2 * comp_size, expected_data + 3 * vec4_size + 2 * comp_size, comp_size);
26656 	int res_chichi_w =
26657 		memcmp(buffer_data + 3 * vec4_size + 3 * comp_size, expected_data + 3 * vec4_size + 3 * comp_size, comp_size);
26658 
26659 	int res_vegeta_x =
26660 		memcmp(buffer_data + 7 * vec4_size + 0 * comp_size, expected_data + 7 * vec4_size + 0 * comp_size, comp_size);
26661 
26662 	int res_trunks_y =
26663 		memcmp(buffer_data + 6 * vec4_size + 1 * comp_size, expected_data + 6 * vec4_size + 1 * comp_size, comp_size);
26664 
26665 	int res_bra_z =
26666 		memcmp(buffer_data + 5 * vec4_size + 2 * comp_size, expected_data + 5 * vec4_size + 2 * comp_size, comp_size);
26667 
26668 	int res_bulma_w =
26669 		memcmp(buffer_data + 4 * vec4_size + 3 * comp_size, expected_data + 4 * vec4_size + 3 * comp_size, comp_size);
26670 
26671 	if ((0 != res_goku_x) || (0 != res_goku_z) || (0 != res_gohan_y) || (0 != res_gohan_w) || (0 != res_goten_x) ||
26672 		(0 != res_goten_y) || (0 != res_chichi_z) || (0 != res_chichi_w) || (0 != res_vegeta_x) ||
26673 		(0 != res_trunks_y) || (0 != res_bra_z) || (0 != res_bulma_w))
26674 	{
26675 		m_context.getTestContext().getLog()
26676 			<< tcu::TestLog::Message << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
26677 			<< ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
26678 
26679 		result = false;
26680 	}
26681 
26682 	/* Release buffer mapping */
26683 	buffer->UnMap();
26684 
26685 	return result;
26686 }
26687 
26688 /** Constructor
26689  *
26690  * @param context Test context
26691  **/
26692 XFBCaptureInactiveOutputBlockMemberTest::XFBCaptureInactiveOutputBlockMemberTest(deqp::Context& context)
26693 	: BufferTestBase(context, "xfb_capture_inactive_output_block_member",
26694 					 "Test verifies that inactive block members are captured")
26695 {
26696 	/* Nothing to be done here */
26697 }
26698 
26699 /** Execute drawArrays for single vertex
26700  *
26701  * @param test_case_index
26702  *
26703  * @return true
26704  **/
26705 bool XFBCaptureInactiveOutputBlockMemberTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
26706 {
26707 	const Functions& gl				= m_context.getRenderContext().getFunctions();
26708 	GLenum			 primitive_type = GL_PATCHES;
26709 
26710 	if (TEST_VS == test_case_index)
26711 	{
26712 		primitive_type = GL_POINTS;
26713 	}
26714 
26715 	gl.disable(GL_RASTERIZER_DISCARD);
26716 	GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
26717 
26718 	gl.beginTransformFeedback(GL_POINTS);
26719 	GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
26720 
26721 	gl.drawArrays(primitive_type, 0 /* first */, 1 /* count */);
26722 	GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
26723 
26724 	gl.endTransformFeedback();
26725 	GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
26726 
26727 	return true;
26728 }
26729 
26730 /** Get descriptors of buffers necessary for test
26731  *
26732  * @param ignored
26733  * @param out_descriptors Descriptors of buffers used by test
26734  **/
26735 void XFBCaptureInactiveOutputBlockMemberTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
26736 																   bufferDescriptor::Vector& out_descriptors)
26737 {
26738 	const Utils::Type& type = Utils::Type::vec4;
26739 
26740 	/* Test needs single uniform and xfb */
26741 	out_descriptors.resize(2);
26742 
26743 	/* Get references */
26744 	bufferDescriptor& uniform = out_descriptors[0];
26745 	bufferDescriptor& xfb	 = out_descriptors[1];
26746 
26747 	/* Index */
26748 	uniform.m_index = 0;
26749 	xfb.m_index		= 0;
26750 
26751 	/* Target */
26752 	uniform.m_target = Utils::Buffer::Uniform;
26753 	xfb.m_target	 = Utils::Buffer::Transform_feedback;
26754 
26755 	/* Data */
26756 	const std::vector<GLubyte>& gohan_data  = type.GenerateData();
26757 	const std::vector<GLubyte>& chichi_data = type.GenerateData();
26758 
26759 	const GLuint type_size = static_cast<GLuint>(gohan_data.size());
26760 
26761 	/* Uniform data */
26762 	uniform.m_initial_data.resize(2 * type_size);
26763 	memcpy(&uniform.m_initial_data[0] + 0, &gohan_data[0], type_size);
26764 	memcpy(&uniform.m_initial_data[0] + type_size, &chichi_data[0], type_size);
26765 
26766 	/* XFB data */
26767 	xfb.m_initial_data.resize(4 * type_size);
26768 	xfb.m_expected_data.resize(4 * type_size);
26769 
26770 	for (GLuint i = 0; i < 4 * type_size; ++i)
26771 	{
26772 		xfb.m_initial_data[i]  = (glw::GLubyte)i;
26773 		xfb.m_expected_data[i] = (glw::GLubyte)i;
26774 	}
26775 
26776 	memcpy(&xfb.m_expected_data[0] + 1 * type_size, &gohan_data[0], type_size);
26777 	memcpy(&xfb.m_expected_data[0] + 3 * type_size, &chichi_data[0], type_size);
26778 }
26779 
26780 /** Get body of main function for given shader stage
26781  *
26782  * @param test_case_index  Index of test case
26783  * @param stage            Shader stage
26784  * @param out_assignments  Set to empty
26785  * @param out_calculations Set to empty
26786  **/
26787 void XFBCaptureInactiveOutputBlockMemberTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
26788 															std::string& out_assignments, std::string& out_calculations)
26789 {
26790 	out_calculations = "";
26791 
26792 	static const GLchar* vs_tes_gs = "    chichi = uni_chichi;\n"
26793 									 "    gohan  = uni_gohan;\n";
26794 	static const GLchar* fs = "    fs_out = goten + gohan + chichi;\n";
26795 
26796 	const GLchar* assignments = "";
26797 
26798 	switch (stage)
26799 	{
26800 	case Utils::Shader::FRAGMENT:
26801 		assignments = fs;
26802 		break;
26803 
26804 	case Utils::Shader::GEOMETRY:
26805 		if (TEST_GS == test_case_index)
26806 		{
26807 			assignments = vs_tes_gs;
26808 		}
26809 		break;
26810 
26811 	case Utils::Shader::TESS_CTRL:
26812 		break;
26813 
26814 	case Utils::Shader::TESS_EVAL:
26815 		if (TEST_TES == test_case_index)
26816 		{
26817 			assignments = vs_tes_gs;
26818 		}
26819 		break;
26820 
26821 	case Utils::Shader::VERTEX:
26822 		if (TEST_VS == test_case_index)
26823 		{
26824 			assignments = vs_tes_gs;
26825 		}
26826 		break;
26827 
26828 	default:
26829 		TCU_FAIL("Invalid enum");
26830 	}
26831 
26832 	out_assignments = assignments;
26833 }
26834 
26835 /** Get interface of shader
26836  *
26837  * @param test_case_index  Index of test case
26838  * @param stage            Shader stage
26839  * @param out_interface    Set to ""
26840  **/
26841 void XFBCaptureInactiveOutputBlockMemberTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
26842 																 std::string& out_interface)
26843 {
26844 	static const GLchar* vs_tes_gs = "const uint sizeof_type = 16;\n"
26845 									 "\n"
26846 									 "layout (xfb_offset = 1 * sizeof_type) out Goku {\n"
26847 									 "    vec4 gohan;\n"
26848 									 "    vec4 goten;\n"
26849 									 "    vec4 chichi;\n"
26850 									 "};\n"
26851 									 "\n"
26852 									 "layout(binding = 0) uniform block {\n"
26853 									 "    vec4 uni_gohan;\n"
26854 									 "    vec4 uni_chichi;\n"
26855 									 "};\n";
26856 	static const GLchar* fs = "in Goku {\n"
26857 							  "    vec4 gohan;\n"
26858 							  "    vec4 goten;\n"
26859 							  "    vec4 chichi;\n"
26860 							  "};\n"
26861 							  "out vec4 fs_out;\n";
26862 
26863 	const GLchar* interface = "";
26864 
26865 	switch (stage)
26866 	{
26867 	case Utils::Shader::FRAGMENT:
26868 		interface = fs;
26869 		break;
26870 
26871 	case Utils::Shader::GEOMETRY:
26872 		if (TEST_GS == test_case_index)
26873 		{
26874 			interface = vs_tes_gs;
26875 		}
26876 		break;
26877 
26878 	case Utils::Shader::TESS_CTRL:
26879 		break;
26880 
26881 	case Utils::Shader::TESS_EVAL:
26882 		if (TEST_TES == test_case_index)
26883 		{
26884 			interface = vs_tes_gs;
26885 		}
26886 		break;
26887 
26888 	case Utils::Shader::VERTEX:
26889 		if (TEST_VS == test_case_index)
26890 		{
26891 			interface = vs_tes_gs;
26892 		}
26893 		break;
26894 
26895 	default:
26896 		TCU_FAIL("Invalid enum");
26897 	}
26898 
26899 	out_interface = interface;
26900 }
26901 
26902 /** Get source code of shader
26903  *
26904  * @param test_case_index Index of test case
26905  * @param stage           Shader stage
26906  *
26907  * @return Source
26908  **/
26909 std::string XFBCaptureInactiveOutputBlockMemberTest::getShaderSource(GLuint				   test_case_index,
26910 																	 Utils::Shader::STAGES stage)
26911 {
26912 	std::string source;
26913 
26914 	switch (test_case_index)
26915 	{
26916 	case TEST_VS:
26917 		switch (stage)
26918 		{
26919 		case Utils::Shader::FRAGMENT:
26920 		case Utils::Shader::VERTEX:
26921 			source = BufferTestBase::getShaderSource(test_case_index, stage);
26922 			break;
26923 		default:
26924 			break;
26925 		}
26926 		break;
26927 
26928 	case TEST_TES:
26929 		switch (stage)
26930 		{
26931 		case Utils::Shader::FRAGMENT:
26932 		case Utils::Shader::TESS_CTRL:
26933 		case Utils::Shader::TESS_EVAL:
26934 		case Utils::Shader::VERTEX:
26935 			source = BufferTestBase::getShaderSource(test_case_index, stage);
26936 			break;
26937 		default:
26938 			break;
26939 		}
26940 		break;
26941 
26942 	case TEST_GS:
26943 		source = BufferTestBase::getShaderSource(test_case_index, stage);
26944 		break;
26945 
26946 	default:
26947 		TCU_FAIL("Invalid enum");
26948 		break;
26949 	}
26950 
26951 	/* */
26952 	return source;
26953 }
26954 
26955 /** Get name of test case
26956  *
26957  * @param test_case_index Index of test case
26958  *
26959  * @return Name of tested stage
26960  **/
26961 std::string XFBCaptureInactiveOutputBlockMemberTest::getTestCaseName(glw::GLuint test_case_index)
26962 {
26963 	const GLchar* name = 0;
26964 
26965 	switch (test_case_index)
26966 	{
26967 	case TEST_VS:
26968 		name = "vertex";
26969 		break;
26970 	case TEST_TES:
26971 		name = "tessellation evaluation";
26972 		break;
26973 	case TEST_GS:
26974 		name = "geometry";
26975 		break;
26976 	default:
26977 		TCU_FAIL("Invalid enum");
26978 	}
26979 
26980 	return name;
26981 }
26982 
26983 /** Returns number of test cases
26984  *
26985  * @return TEST_MAX
26986  **/
26987 glw::GLuint XFBCaptureInactiveOutputBlockMemberTest::getTestCaseNumber()
26988 {
26989 	return TEST_MAX;
26990 }
26991 
26992 /** Verify contents of buffers
26993  *
26994  * @param buffers Collection of buffers to be verified
26995  *
26996  * @return true if everything is as expected, false otherwise
26997  **/
26998 bool XFBCaptureInactiveOutputBlockMemberTest::verifyBuffers(bufferCollection& buffers)
26999 {
27000 	bool result = true;
27001 
27002 	bufferCollection::pair& pair	   = buffers.m_vector[1] /* xfb */;
27003 	Utils::Buffer*			buffer	 = pair.m_buffer;
27004 	bufferDescriptor*		descriptor = pair.m_descriptor;
27005 
27006 	/* Get pointer to contents of buffer */
27007 	buffer->Bind();
27008 	GLubyte* buffer_data = (GLubyte*)buffer->Map(Utils::Buffer::ReadOnly);
27009 
27010 	/* Get pointer to expected data */
27011 	GLubyte* expected_data = (GLubyte*)&descriptor->m_expected_data[0];
27012 
27013 	/* Compare */
27014 	static const GLuint vec4_size = 16;
27015 
27016 	int res_before = memcmp(buffer_data, expected_data, vec4_size);
27017 	int res_gohan  = memcmp(buffer_data + 1 * vec4_size, expected_data + 1 * vec4_size, vec4_size);
27018 	int res_chichi = memcmp(buffer_data + 3 * vec4_size, expected_data + 3 * vec4_size, vec4_size);
27019 
27020 	if ((0 != res_before) || (0 != res_gohan) || (0 != res_chichi))
27021 	{
27022 		m_context.getTestContext().getLog()
27023 			<< tcu::TestLog::Message << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
27024 			<< ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
27025 
27026 		result = false;
27027 	}
27028 
27029 	/* Release buffer mapping */
27030 	buffer->UnMap();
27031 
27032 	return result;
27033 }
27034 
27035 /** Constructor
27036  *
27037  * @param context Test context
27038  **/
27039 XFBCaptureStructTest::XFBCaptureStructTest(deqp::Context& context)
27040 	: BufferTestBase(context, "xfb_capture_struct", "Test verifies that inactive structure members are captured")
27041 {
27042 	/* Nothing to be done here */
27043 }
27044 
27045 /** Execute drawArrays for single vertex
27046  *
27047  * @param test_case_index
27048  *
27049  * @return true
27050  **/
27051 bool XFBCaptureStructTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
27052 {
27053 	const Functions& gl				= m_context.getRenderContext().getFunctions();
27054 	GLenum			 primitive_type = GL_PATCHES;
27055 
27056 	if (TEST_VS == test_case_index)
27057 	{
27058 		primitive_type = GL_POINTS;
27059 	}
27060 
27061 	gl.disable(GL_RASTERIZER_DISCARD);
27062 	GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
27063 
27064 	gl.beginTransformFeedback(GL_POINTS);
27065 	GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
27066 
27067 	gl.drawArrays(primitive_type, 0 /* first */, 1 /* count */);
27068 	GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
27069 
27070 	gl.endTransformFeedback();
27071 	GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
27072 
27073 	return true;
27074 }
27075 
27076 /** Get descriptors of buffers necessary for test
27077  *
27078  * @param ignored
27079  * @param out_descriptors Descriptors of buffers used by test
27080  **/
27081 void XFBCaptureStructTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
27082 												bufferDescriptor::Vector& out_descriptors)
27083 {
27084 	const Utils::Type& type = Utils::Type::vec4;
27085 
27086 	/* Test needs single uniform and xfb */
27087 	out_descriptors.resize(2);
27088 
27089 	/* Get references */
27090 	bufferDescriptor& uniform = out_descriptors[0];
27091 	bufferDescriptor& xfb	 = out_descriptors[1];
27092 
27093 	/* Index */
27094 	uniform.m_index = 0;
27095 	xfb.m_index		= 0;
27096 
27097 	/* Target */
27098 	uniform.m_target = Utils::Buffer::Uniform;
27099 	xfb.m_target	 = Utils::Buffer::Transform_feedback;
27100 
27101 	/* Data */
27102 	const std::vector<GLubyte>& gohan_data  = type.GenerateData();
27103 	const std::vector<GLubyte>& chichi_data = type.GenerateData();
27104 
27105 	const GLuint type_size = static_cast<GLuint>(gohan_data.size());
27106 
27107 	/* Uniform data */
27108 	uniform.m_initial_data.resize(2 * type_size);
27109 	memcpy(&uniform.m_initial_data[0] + 0, &gohan_data[0], type_size);
27110 	memcpy(&uniform.m_initial_data[0] + type_size, &chichi_data[0], type_size);
27111 
27112 	/* XFB data */
27113 	xfb.m_initial_data.resize(4 * type_size);
27114 	xfb.m_expected_data.resize(4 * type_size);
27115 
27116 	for (GLuint i = 0; i < 4 * type_size; ++i)
27117 	{
27118 		xfb.m_initial_data[i]  = (glw::GLubyte)i;
27119 		xfb.m_expected_data[i] = (glw::GLubyte)i;
27120 	}
27121 
27122 	memcpy(&xfb.m_expected_data[0] + 1 * type_size, &gohan_data[0], type_size);
27123 	memcpy(&xfb.m_expected_data[0] + 3 * type_size, &chichi_data[0], type_size);
27124 }
27125 
27126 /** Get body of main function for given shader stage
27127  *
27128  * @param test_case_index  Index of test case
27129  * @param stage            Shader stage
27130  * @param out_assignments  Set to empty
27131  * @param out_calculations Set to empty
27132  **/
27133 void XFBCaptureStructTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
27134 										 std::string& out_assignments, std::string& out_calculations)
27135 {
27136 	out_calculations = "";
27137 
27138 	static const GLchar* vs_tes_gs = "    goku.chichi = uni_chichi;\n"
27139 									 "    goku.gohan  = uni_gohan;\n";
27140 	static const GLchar* fs = "    fs_out = goku.goten + goku.gohan + goku.chichi;\n";
27141 
27142 	const GLchar* assignments = "";
27143 
27144 	switch (stage)
27145 	{
27146 	case Utils::Shader::FRAGMENT:
27147 		assignments = fs;
27148 		break;
27149 
27150 	case Utils::Shader::GEOMETRY:
27151 		if (TEST_GS == test_case_index)
27152 		{
27153 			assignments = vs_tes_gs;
27154 		}
27155 		break;
27156 
27157 	case Utils::Shader::TESS_CTRL:
27158 		break;
27159 
27160 	case Utils::Shader::TESS_EVAL:
27161 		if (TEST_TES == test_case_index)
27162 		{
27163 			assignments = vs_tes_gs;
27164 		}
27165 		break;
27166 
27167 	case Utils::Shader::VERTEX:
27168 		if (TEST_VS == test_case_index)
27169 		{
27170 			assignments = vs_tes_gs;
27171 		}
27172 		break;
27173 
27174 	default:
27175 		TCU_FAIL("Invalid enum");
27176 	}
27177 
27178 	out_assignments = assignments;
27179 }
27180 
27181 /** Get interface of shader
27182  *
27183  * @param test_case_index  Index of test case
27184  * @param stage            Shader stage
27185  * @param out_interface    Set to ""
27186  **/
27187 void XFBCaptureStructTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
27188 											  std::string& out_interface)
27189 {
27190 	static const GLchar* vs_tes_gs = "const uint sizeof_type = 16;\n"
27191 									 "\n"
27192 									 "struct Goku {\n"
27193 									 "    vec4 gohan;\n"
27194 									 "    vec4 goten;\n"
27195 									 "    vec4 chichi;\n"
27196 									 "};\n"
27197 									 "\n"
27198 									 "layout (xfb_offset = sizeof_type) out Goku goku;\n"
27199 									 "\n"
27200 									 "layout(binding = 0, std140) uniform block {\n"
27201 									 "    vec4 uni_gohan;\n"
27202 									 "    vec4 uni_chichi;\n"
27203 									 "};\n";
27204 	static const GLchar* fs = "struct Goku {\n"
27205 							  "    vec4 gohan;\n"
27206 							  "    vec4 goten;\n"
27207 							  "    vec4 chichi;\n"
27208 							  "};\n"
27209 							  "\n"
27210 							  "in Goku goku;\n"
27211 							  "\n"
27212 							  "out vec4 fs_out;\n";
27213 
27214 	const GLchar* interface = "";
27215 
27216 	switch (stage)
27217 	{
27218 	case Utils::Shader::FRAGMENT:
27219 		interface = fs;
27220 		break;
27221 
27222 	case Utils::Shader::GEOMETRY:
27223 		if (TEST_GS == test_case_index)
27224 		{
27225 			interface = vs_tes_gs;
27226 		}
27227 		break;
27228 
27229 	case Utils::Shader::TESS_CTRL:
27230 		break;
27231 
27232 	case Utils::Shader::TESS_EVAL:
27233 		if (TEST_TES == test_case_index)
27234 		{
27235 			interface = vs_tes_gs;
27236 		}
27237 		break;
27238 
27239 	case Utils::Shader::VERTEX:
27240 		if (TEST_VS == test_case_index)
27241 		{
27242 			interface = vs_tes_gs;
27243 		}
27244 		break;
27245 
27246 	default:
27247 		TCU_FAIL("Invalid enum");
27248 	}
27249 
27250 	out_interface = interface;
27251 }
27252 
27253 /** Get source code of shader
27254  *
27255  * @param test_case_index Index of test case
27256  * @param stage           Shader stage
27257  *
27258  * @return Source
27259  **/
27260 std::string XFBCaptureStructTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
27261 {
27262 	std::string source;
27263 
27264 	switch (test_case_index)
27265 	{
27266 	case TEST_VS:
27267 		switch (stage)
27268 		{
27269 		case Utils::Shader::FRAGMENT:
27270 		case Utils::Shader::VERTEX:
27271 			source = BufferTestBase::getShaderSource(test_case_index, stage);
27272 			break;
27273 		default:
27274 			break;
27275 		}
27276 		break;
27277 
27278 	case TEST_TES:
27279 		switch (stage)
27280 		{
27281 		case Utils::Shader::FRAGMENT:
27282 		case Utils::Shader::TESS_CTRL:
27283 		case Utils::Shader::TESS_EVAL:
27284 		case Utils::Shader::VERTEX:
27285 			source = BufferTestBase::getShaderSource(test_case_index, stage);
27286 			break;
27287 		default:
27288 			break;
27289 		}
27290 		break;
27291 
27292 	case TEST_GS:
27293 		source = BufferTestBase::getShaderSource(test_case_index, stage);
27294 		break;
27295 
27296 	default:
27297 		TCU_FAIL("Invalid enum");
27298 		break;
27299 	}
27300 
27301 	/* */
27302 	return source;
27303 }
27304 
27305 /** Get name of test case
27306  *
27307  * @param test_case_index Index of test case
27308  *
27309  * @return Name of tested stage
27310  **/
27311 std::string XFBCaptureStructTest::getTestCaseName(glw::GLuint test_case_index)
27312 {
27313 	const GLchar* name = 0;
27314 
27315 	switch (test_case_index)
27316 	{
27317 	case TEST_VS:
27318 		name = "vertex";
27319 		break;
27320 	case TEST_TES:
27321 		name = "tessellation evaluation";
27322 		break;
27323 	case TEST_GS:
27324 		name = "geometry";
27325 		break;
27326 	default:
27327 		TCU_FAIL("Invalid enum");
27328 	}
27329 
27330 	return name;
27331 }
27332 
27333 /** Returns number of test cases
27334  *
27335  * @return TEST_MAX
27336  **/
27337 glw::GLuint XFBCaptureStructTest::getTestCaseNumber()
27338 {
27339 	return TEST_MAX;
27340 }
27341 
27342 /** Verify contents of buffers
27343  *
27344  * @param buffers Collection of buffers to be verified
27345  *
27346  * @return true if everything is as expected, false otherwise
27347  **/
27348 bool XFBCaptureStructTest::verifyBuffers(bufferCollection& buffers)
27349 {
27350 	bool result = true;
27351 
27352 	bufferCollection::pair& pair	   = buffers.m_vector[1] /* xfb */;
27353 	Utils::Buffer*			buffer	 = pair.m_buffer;
27354 	bufferDescriptor*		descriptor = pair.m_descriptor;
27355 
27356 	/* Get pointer to contents of buffer */
27357 	buffer->Bind();
27358 	GLubyte* buffer_data = (GLubyte*)buffer->Map(Utils::Buffer::ReadOnly);
27359 
27360 	/* Get pointer to expected data */
27361 	GLubyte* expected_data = (GLubyte*)&descriptor->m_expected_data[0];
27362 
27363 	/* Compare */
27364 	static const GLuint vec4_size = 16;
27365 
27366 	int res_before = memcmp(buffer_data, expected_data, vec4_size);
27367 	int res_gohan  = memcmp(buffer_data + 1 * vec4_size, expected_data + 1 * vec4_size, vec4_size);
27368 	int res_chichi = memcmp(buffer_data + 3 * vec4_size, expected_data + 3 * vec4_size, vec4_size);
27369 
27370 	if ((0 != res_before) || (0 != res_gohan) || (0 != res_chichi))
27371 	{
27372 		m_context.getTestContext().getLog()
27373 			<< tcu::TestLog::Message << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
27374 			<< ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
27375 
27376 		result = false;
27377 	}
27378 
27379 	/* Release buffer mapping */
27380 	buffer->UnMap();
27381 
27382 	return result;
27383 }
27384 
27385 /** Constructor
27386  *
27387  * @param context Test framework context
27388  **/
27389 XFBCaptureUnsizedArrayTest::XFBCaptureUnsizedArrayTest(deqp::Context& context)
27390 	: NegativeTestBase(context, "xfb_capture_unsized_array",
27391 					   "Test verifies that compiler reports error when unsized array is qualified with xfb_offset")
27392 {
27393 }
27394 
27395 /** Source for given test case and stage
27396  *
27397  * @param test_case_index Index of test case
27398  * @param stage           Shader stage
27399  *
27400  * @return Shader source
27401  **/
27402 std::string XFBCaptureUnsizedArrayTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
27403 {
27404 	static const GLchar* var_definition = "layout (xfb_offset = 0) out vec4 gokuARRAY[];\n";
27405 	static const GLchar* var_use		= "    gokuINDEX[0] = result / 2;\n";
27406 	static const GLchar* fs				= "#version 430 core\n"
27407 							  "#extension GL_ARB_enhanced_layouts : require\n"
27408 							  "\n"
27409 							  "in  vec4 gs_fs;\n"
27410 							  "out vec4 fs_out;\n"
27411 							  "\n"
27412 							  "void main()\n"
27413 							  "{\n"
27414 							  "    fs_out = gs_fs;\n"
27415 							  "}\n"
27416 							  "\n";
27417 	static const GLchar* gs_tested = "#version 430 core\n"
27418 									 "#extension GL_ARB_enhanced_layouts : require\n"
27419 									 "\n"
27420 									 "layout(points)                           in;\n"
27421 									 "layout(triangle_strip, max_vertices = 4) out;\n"
27422 									 "\n"
27423 									 "VAR_DEFINITION"
27424 									 "\n"
27425 									 "in  vec4 tes_gs[];\n"
27426 									 "out vec4 gs_fs;\n"
27427 									 "\n"
27428 									 "void main()\n"
27429 									 "{\n"
27430 									 "    vec4 result = tes_gs[0];\n"
27431 									 "\n"
27432 									 "VARIABLE_USE"
27433 									 "\n"
27434 									 "    gs_fs = result;\n"
27435 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
27436 									 "    EmitVertex();\n"
27437 									 "    gs_fs = result;\n"
27438 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
27439 									 "    EmitVertex();\n"
27440 									 "    gs_fs = result;\n"
27441 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
27442 									 "    EmitVertex();\n"
27443 									 "    gs_fs = result;\n"
27444 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
27445 									 "    EmitVertex();\n"
27446 									 "}\n"
27447 									 "\n";
27448 	static const GLchar* tcs = "#version 430 core\n"
27449 							   "#extension GL_ARB_enhanced_layouts : require\n"
27450 							   "\n"
27451 							   "layout(vertices = 1) out;\n"
27452 							   "\n"
27453 							   "in  vec4 vs_tcs[];\n"
27454 							   "out vec4 tcs_tes[];\n"
27455 							   "\n"
27456 							   "void main()\n"
27457 							   "{\n"
27458 							   "\n"
27459 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
27460 							   "\n"
27461 							   "    gl_TessLevelOuter[0] = 1.0;\n"
27462 							   "    gl_TessLevelOuter[1] = 1.0;\n"
27463 							   "    gl_TessLevelOuter[2] = 1.0;\n"
27464 							   "    gl_TessLevelOuter[3] = 1.0;\n"
27465 							   "    gl_TessLevelInner[0] = 1.0;\n"
27466 							   "    gl_TessLevelInner[1] = 1.0;\n"
27467 							   "}\n"
27468 							   "\n";
27469 	static const GLchar* tcs_tested = "#version 430 core\n"
27470 									  "#extension GL_ARB_enhanced_layouts : require\n"
27471 									  "\n"
27472 									  "layout(vertices = 1) out;\n"
27473 									  "\n"
27474 									  "VAR_DEFINITION"
27475 									  "\n"
27476 									  "in  vec4 vs_tcs[];\n"
27477 									  "out vec4 tcs_tes[];\n"
27478 									  "\n"
27479 									  "void main()\n"
27480 									  "{\n"
27481 									  "    vec4 result = vs_tcs[gl_InvocationID];\n"
27482 									  "\n"
27483 									  "VARIABLE_USE"
27484 									  "\n"
27485 									  "    tcs_tes[gl_InvocationID] = result;\n"
27486 									  "\n"
27487 									  "    gl_TessLevelOuter[0] = 1.0;\n"
27488 									  "    gl_TessLevelOuter[1] = 1.0;\n"
27489 									  "    gl_TessLevelOuter[2] = 1.0;\n"
27490 									  "    gl_TessLevelOuter[3] = 1.0;\n"
27491 									  "    gl_TessLevelInner[0] = 1.0;\n"
27492 									  "    gl_TessLevelInner[1] = 1.0;\n"
27493 									  "}\n"
27494 									  "\n";
27495 	static const GLchar* tes_tested = "#version 430 core\n"
27496 									  "#extension GL_ARB_enhanced_layouts : require\n"
27497 									  "\n"
27498 									  "layout(isolines, point_mode) in;\n"
27499 									  "\n"
27500 									  "VAR_DEFINITION"
27501 									  "\n"
27502 									  "in  vec4 tcs_tes[];\n"
27503 									  "out vec4 tes_gs;\n"
27504 									  "\n"
27505 									  "void main()\n"
27506 									  "{\n"
27507 									  "    vec4 result = tcs_tes[0];\n"
27508 									  "\n"
27509 									  "VARIABLE_USE"
27510 									  "\n"
27511 									  "    tes_gs += result;\n"
27512 									  "}\n"
27513 									  "\n";
27514 	static const GLchar* vs = "#version 430 core\n"
27515 							  "#extension GL_ARB_enhanced_layouts : require\n"
27516 							  "\n"
27517 							  "in  vec4 in_vs;\n"
27518 							  "out vec4 vs_tcs;\n"
27519 							  "\n"
27520 							  "void main()\n"
27521 							  "{\n"
27522 							  "    vs_tcs = in_vs;\n"
27523 							  "}\n"
27524 							  "\n";
27525 	static const GLchar* vs_tested = "#version 430 core\n"
27526 									 "#extension GL_ARB_enhanced_layouts : require\n"
27527 									 "\n"
27528 									 "VAR_DEFINITION"
27529 									 "\n"
27530 									 "in  vec4 in_vs;\n"
27531 									 "out vec4 vs_tcs;\n"
27532 									 "\n"
27533 									 "void main()\n"
27534 									 "{\n"
27535 									 "    vec4 result = in_vs;\n"
27536 									 "\n"
27537 									 "VARIABLE_USE"
27538 									 "\n"
27539 									 "    vs_tcs = result;\n"
27540 									 "}\n"
27541 									 "\n";
27542 
27543 	std::string source;
27544 	testCase&   test_case = m_test_cases[test_case_index];
27545 
27546 	if (test_case.m_stage == stage)
27547 	{
27548 		const GLchar* array	= "";
27549 		const GLchar* index	= "";
27550 		size_t		  position = 0;
27551 
27552 		switch (stage)
27553 		{
27554 		case Utils::Shader::GEOMETRY:
27555 			source = gs_tested;
27556 			array  = "[]";
27557 			index  = "[0]";
27558 			break;
27559 		case Utils::Shader::TESS_CTRL:
27560 			source = tcs_tested;
27561 			array  = "[]";
27562 			index  = "[gl_InvocationID]";
27563 			break;
27564 		case Utils::Shader::TESS_EVAL:
27565 			source = tes_tested;
27566 			array  = "[]";
27567 			index  = "[0]";
27568 			break;
27569 		case Utils::Shader::VERTEX:
27570 			source = vs_tested;
27571 			break;
27572 		default:
27573 			TCU_FAIL("Invalid enum");
27574 		}
27575 
27576 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
27577 		position = 0;
27578 		Utils::replaceToken("ARRAY", position, array, source);
27579 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
27580 
27581 		Utils::replaceAllTokens("INDEX", index, source);
27582 	}
27583 	else
27584 	{
27585 		switch (test_case.m_stage)
27586 		{
27587 		case Utils::Shader::GEOMETRY:
27588 			switch (stage)
27589 			{
27590 			case Utils::Shader::FRAGMENT:
27591 				source = fs;
27592 				break;
27593 			case Utils::Shader::VERTEX:
27594 				source = vs;
27595 				break;
27596 			default:
27597 				source = "";
27598 			}
27599 			break;
27600 		case Utils::Shader::TESS_CTRL:
27601 			switch (stage)
27602 			{
27603 			case Utils::Shader::FRAGMENT:
27604 				source = fs;
27605 				break;
27606 			case Utils::Shader::VERTEX:
27607 				source = vs;
27608 				break;
27609 			default:
27610 				source = "";
27611 			}
27612 			break;
27613 		case Utils::Shader::TESS_EVAL:
27614 			switch (stage)
27615 			{
27616 			case Utils::Shader::FRAGMENT:
27617 				source = fs;
27618 				break;
27619 			case Utils::Shader::TESS_CTRL:
27620 				source = tcs;
27621 				break;
27622 			case Utils::Shader::VERTEX:
27623 				source = vs;
27624 				break;
27625 			default:
27626 				source = "";
27627 			}
27628 			break;
27629 		case Utils::Shader::VERTEX:
27630 			switch (stage)
27631 			{
27632 			case Utils::Shader::FRAGMENT:
27633 				source = fs;
27634 				break;
27635 			default:
27636 				source = "";
27637 			}
27638 			break;
27639 		default:
27640 			TCU_FAIL("Invalid enum");
27641 			break;
27642 		}
27643 	}
27644 
27645 	return source;
27646 }
27647 
27648 /** Get description of test case
27649  *
27650  * @param test_case_index Index of test case
27651  *
27652  * @return Test case description
27653  **/
27654 std::string XFBCaptureUnsizedArrayTest::getTestCaseName(GLuint test_case_index)
27655 {
27656 	std::stringstream stream;
27657 	testCase&		  test_case = m_test_cases[test_case_index];
27658 
27659 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage);
27660 
27661 	return stream.str();
27662 }
27663 
27664 /** Get number of test cases
27665  *
27666  * @return Number of test cases
27667  **/
27668 GLuint XFBCaptureUnsizedArrayTest::getTestCaseNumber()
27669 {
27670 	return static_cast<GLuint>(m_test_cases.size());
27671 }
27672 
27673 /** Selects if "compute" stage is relevant for test
27674  *
27675  * @param ignored
27676  *
27677  * @return false
27678  **/
27679 bool XFBCaptureUnsizedArrayTest::isComputeRelevant(GLuint /* test_case_index */)
27680 {
27681 	return false;
27682 }
27683 
27684 /** Prepare all test cases
27685  *
27686  **/
27687 void XFBCaptureUnsizedArrayTest::testInit()
27688 {
27689 	for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
27690 	{
27691 		/* Not aplicable for */
27692 		if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::FRAGMENT == stage) ||
27693 			(Utils::Shader::GEOMETRY == stage) || (Utils::Shader::TESS_EVAL == stage))
27694 		{
27695 			continue;
27696 		}
27697 
27698 		testCase test_case = { (Utils::Shader::STAGES)stage };
27699 
27700 		m_test_cases.push_back(test_case);
27701 	}
27702 }
27703 } /* EnhancedLayouts namespace */
27704 
27705 /** Constructor.
27706  *
27707  *  @param context Rendering context.
27708  **/
EnhancedLayoutsTests(deqp::Context & context)27709 EnhancedLayoutsTests::EnhancedLayoutsTests(deqp::Context& context)
27710 	: TestCaseGroup(context, "enhanced_layouts", "Verifies \"enhanced layouts\" functionality")
27711 {
27712 	/* Left blank on purpose */
27713 }
27714 
27715 /** Initializes a texture_storage_multisample test group.
27716  *
27717  **/
init(void)27718 void EnhancedLayoutsTests::init(void)
27719 {
27720 	addChild(new EnhancedLayouts::APIConstantValuesTest(m_context));
27721 	addChild(new EnhancedLayouts::APIErrorsTest(m_context));
27722 	addChild(new EnhancedLayouts::GLSLContantValuesTest(m_context));
27723 	addChild(new EnhancedLayouts::GLSLContantImmutablityTest(m_context));
27724 	addChild(new EnhancedLayouts::GLSLConstantIntegralExpressionTest(m_context));
27725 	addChild(new EnhancedLayouts::UniformBlockLayoutQualifierConflictTest(m_context));
27726 	addChild(new EnhancedLayouts::SSBMemberInvalidOffsetAlignmentTest(m_context));
27727 	addChild(new EnhancedLayouts::SSBMemberOverlappingOffsetsTest(m_context));
27728 	addChild(new EnhancedLayouts::VaryingExceedingComponentsTest(m_context));
27729 	addChild(new EnhancedLayouts::VaryingComponentOfInvalidTypeTest(m_context));
27730 	addChild(new EnhancedLayouts::OutputComponentAliasingTest(m_context));
27731 	addChild(new EnhancedLayouts::VertexAttribLocationAPITest(m_context));
27732 	addChild(new EnhancedLayouts::XFBInputTest(m_context));
27733 	addChild(new EnhancedLayouts::XFBAllStagesTest(m_context));
27734 	addChild(new EnhancedLayouts::XFBCaptureInactiveOutputVariableTest(m_context));
27735 	addChild(new EnhancedLayouts::XFBCaptureInactiveOutputComponentTest(m_context));
27736 	addChild(new EnhancedLayouts::XFBCaptureInactiveOutputBlockMemberTest(m_context));
27737 	addChild(new EnhancedLayouts::XFBStrideTest(m_context));
27738 
27739 	addChild(new EnhancedLayouts::UniformBlockMemberOffsetAndAlignTest(m_context));
27740 	addChild(new EnhancedLayouts::UniformBlockMemberInvalidOffsetAlignmentTest(m_context));
27741 	addChild(new EnhancedLayouts::UniformBlockMemberOverlappingOffsetsTest(m_context));
27742 	addChild(new EnhancedLayouts::UniformBlockMemberAlignNonPowerOf2Test(m_context));
27743 	addChild(new EnhancedLayouts::SSBLayoutQualifierConflictTest(m_context));
27744 	addChild(new EnhancedLayouts::SSBMemberAlignNonPowerOf2Test(m_context));
27745 	addChild(new EnhancedLayouts::SSBAlignmentTest(m_context));
27746 	addChild(new EnhancedLayouts::VaryingStructureMemberLocationTest(m_context));
27747 	addChild(new EnhancedLayouts::VaryingBlockAutomaticMemberLocationsTest(m_context));
27748 	addChild(new EnhancedLayouts::VaryingComponentWithoutLocationTest(m_context));
27749 	addChild(new EnhancedLayouts::InputComponentAliasingTest(m_context));
27750 	addChild(new EnhancedLayouts::VaryingLocationAliasingWithMixedTypesTest(m_context));
27751 	addChild(new EnhancedLayouts::VaryingLocationAliasingWithMixedInterpolationTest(m_context));
27752 	addChild(new EnhancedLayouts::VaryingLocationAliasingWithMixedAuxiliaryStorageTest(m_context));
27753 	addChild(new EnhancedLayouts::XFBStrideOfEmptyListTest(m_context));
27754 	addChild(new EnhancedLayouts::XFBStrideOfEmptyListAndAPITest(m_context));
27755 	addChild(new EnhancedLayouts::XFBTooSmallStrideTest(m_context));
27756 	addChild(new EnhancedLayouts::XFBBlockMemberStrideTest(m_context));
27757 	addChild(new EnhancedLayouts::XFBDuplicatedStrideTest(m_context));
27758 	addChild(new EnhancedLayouts::XFBGetProgramResourceAPITest(m_context));
27759 	addChild(new EnhancedLayouts::XFBMultipleVertexStreamsTest(m_context));
27760 	addChild(new EnhancedLayouts::XFBExceedBufferLimitTest(m_context));
27761 	addChild(new EnhancedLayouts::XFBExceedOffsetLimitTest(m_context));
27762 	addChild(new EnhancedLayouts::XFBBlockMemberBufferTest(m_context));
27763 	addChild(new EnhancedLayouts::XFBOutputOverlappingTest(m_context));
27764 	addChild(new EnhancedLayouts::XFBInvalidOffsetAlignmentTest(m_context));
27765 	addChild(new EnhancedLayouts::XFBCaptureStructTest(m_context));
27766 	addChild(new EnhancedLayouts::XFBCaptureUnsizedArrayTest(m_context));
27767 	addChild(new EnhancedLayouts::UniformBlockAlignmentTest(m_context));
27768 	addChild(new EnhancedLayouts::SSBMemberOffsetAndAlignTest(m_context));
27769 	addChild(new EnhancedLayouts::VertexAttribLocationsTest(m_context));
27770 	addChild(new EnhancedLayouts::VaryingLocationsTest(m_context));
27771 	addChild(new EnhancedLayouts::VaryingArrayLocationsTest(m_context));
27772 	addChild(new EnhancedLayouts::VaryingStructureLocationsTest(m_context));
27773 	addChild(new EnhancedLayouts::VaryingBlockLocationsTest(m_context));
27774 	addChild(new EnhancedLayouts::VaryingBlockMemberLocationsTest(m_context));
27775 	addChild(new EnhancedLayouts::XFBVariableStrideTest(m_context));
27776 	addChild(new EnhancedLayouts::XFBBlockStrideTest(m_context));
27777 	addChild(new EnhancedLayouts::XFBOverrideQualifiersWithAPITest(m_context));
27778 	addChild(new EnhancedLayouts::XFBVertexStreamsTest(m_context));
27779 	addChild(new EnhancedLayouts::XFBGlobalBufferTest(m_context));
27780 	addChild(new EnhancedLayouts::FragmentDataLocationAPITest(m_context));
27781 	addChild(new EnhancedLayouts::VaryingLocationLimitTest(m_context));
27782 	addChild(new EnhancedLayouts::VaryingComponentsTest(m_context));
27783 	addChild(new EnhancedLayouts::VaryingArrayComponentsTest(m_context));
27784 }
27785 
27786 } /* gl4cts namespace */
27787