• 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 "gluShaderUtil.hpp"
34 #include "gluStrUtil.hpp"
35 #include "glwEnums.hpp"
36 #include "glwFunctions.hpp"
37 #include "tcuTestLog.hpp"
38 
39 #include <algorithm>
40 #include <iomanip>
41 #include <string>
42 #include <vector>
43 
44 /* DEBUG */
45 #define USE_NSIGHT 0
46 #define DEBUG_ENBALE_MESSAGE_CALLBACK 0
47 #define DEBUG_NEG_LOG_ERROR 0
48 #define DEBUG_NEG_REMOVE_ERROR 0
49 #define DEBUG_REPLACE_TOKEN 0
50 #define DEBUG_REPEAT_TEST_CASE 0
51 #define DEBUG_REPEATED_TEST_CASE 0
52 
53 /* Texture test base */
54 #define DEBUG_TTB_VERIFICATION_SNIPPET_STAGE 0
55 #define DEBUG_TTB_VERIFICATION_SNIPPET_VARIABLE 0
56 
57 /* Tests */
58 #define DEBUG_VERTEX_ATTRIB_LOCATIONS_TEST_VARIABLE 0
59 
60 /* WORKAROUNDS */
61 #define WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST 0
62 #define WRKARD_UNIFORMBLOCKMEMBERALIGNNONPOWEROF2TEST 0
63 #define WRKARD_UNIFORMBLOCKALIGNMENT 0
64 #define WRKARD_VARYINGLOCATIONSTEST 0
65 
66 using namespace glw;
67 
68 namespace gl4cts
69 {
70 namespace EnhancedLayouts
71 {
72 namespace Utils
73 {
74 /** Constants used by "random" generators **/
75 static const GLuint s_rand_start	= 3;
76 static const GLuint s_rand_max		= 16;
77 static const GLuint s_rand_max_half = s_rand_max / 2;
78 
79 /** Seed used by "random" generators **/
80 static GLuint s_rand = s_rand_start;
81 
82 /** Get "random" unsigned int value
83  *
84  * @return Value
85  **/
GetRandUint()86 static GLuint GetRandUint()
87 {
88 	const GLuint rand = s_rand++;
89 
90 	if (s_rand_max <= s_rand)
91 	{
92 		s_rand = s_rand_start;
93 	}
94 
95 	return rand;
96 }
97 
98 /** Get "random" int value
99  *
100  * @return Value
101  **/
GetRandInt()102 GLint GetRandInt()
103 {
104 	const GLint rand = GetRandUint() - s_rand_max_half;
105 
106 	return rand;
107 }
108 
109 /** Get "random" double value
110  *
111  * @return Value
112  **/
GetRandDouble()113 GLdouble GetRandDouble()
114 {
115 	const GLint rand = GetRandInt();
116 
117 	GLdouble result = (GLfloat)rand / (GLdouble)s_rand_max_half;
118 
119 	return result;
120 }
121 
122 /** Get "random" float value
123  *
124  * @return Value
125  **/
GetRandFloat()126 GLfloat GetRandFloat()
127 {
128 	const GLint rand = GetRandInt();
129 
130 	GLfloat result = (GLfloat)rand / (GLfloat)s_rand_max_half;
131 
132 	return result;
133 }
134 
135 /** String used by list routines **/
136 static const GLchar* const g_list = "LIST";
137 
138 /** Type constants **/
139 const Type Type::_double = Type::GetType(Type::Double, 1, 1);
140 const Type Type::dmat2   = Type::GetType(Type::Double, 2, 2);
141 const Type Type::dmat2x3 = Type::GetType(Type::Double, 2, 3);
142 const Type Type::dmat2x4 = Type::GetType(Type::Double, 2, 4);
143 const Type Type::dmat3x2 = Type::GetType(Type::Double, 3, 2);
144 const Type Type::dmat3   = Type::GetType(Type::Double, 3, 3);
145 const Type Type::dmat3x4 = Type::GetType(Type::Double, 3, 4);
146 const Type Type::dmat4x2 = Type::GetType(Type::Double, 4, 2);
147 const Type Type::dmat4x3 = Type::GetType(Type::Double, 4, 3);
148 const Type Type::dmat4   = Type::GetType(Type::Double, 4, 4);
149 const Type Type::dvec2   = Type::GetType(Type::Double, 1, 2);
150 const Type Type::dvec3   = Type::GetType(Type::Double, 1, 3);
151 const Type Type::dvec4   = Type::GetType(Type::Double, 1, 4);
152 const Type Type::_int	= Type::GetType(Type::Int, 1, 1);
153 const Type Type::ivec2   = Type::GetType(Type::Int, 1, 2);
154 const Type Type::ivec3   = Type::GetType(Type::Int, 1, 3);
155 const Type Type::ivec4   = Type::GetType(Type::Int, 1, 4);
156 const Type Type::_float  = Type::GetType(Type::Float, 1, 1);
157 const Type Type::mat2	= Type::GetType(Type::Float, 2, 2);
158 const Type Type::mat2x3  = Type::GetType(Type::Float, 2, 3);
159 const Type Type::mat2x4  = Type::GetType(Type::Float, 2, 4);
160 const Type Type::mat3x2  = Type::GetType(Type::Float, 3, 2);
161 const Type Type::mat3	= Type::GetType(Type::Float, 3, 3);
162 const Type Type::mat3x4  = Type::GetType(Type::Float, 3, 4);
163 const Type Type::mat4x2  = Type::GetType(Type::Float, 4, 2);
164 const Type Type::mat4x3  = Type::GetType(Type::Float, 4, 3);
165 const Type Type::mat4	= Type::GetType(Type::Float, 4, 4);
166 const Type Type::vec2	= Type::GetType(Type::Float, 1, 2);
167 const Type Type::vec3	= Type::GetType(Type::Float, 1, 3);
168 const Type Type::vec4	= Type::GetType(Type::Float, 1, 4);
169 const Type Type::uint	= Type::GetType(Type::Uint, 1, 1);
170 const Type Type::uvec2   = Type::GetType(Type::Uint, 1, 2);
171 const Type Type::uvec3   = Type::GetType(Type::Uint, 1, 3);
172 const Type Type::uvec4   = Type::GetType(Type::Uint, 1, 4);
173 
174 /** Generate data for type. This routine follows STD140 rules
175  *
176  * @return Vector of bytes filled with data
177  **/
GenerateData() const178 std::vector<GLubyte> Type::GenerateData() const
179 {
180 	const GLuint alignment = GetActualAlignment(0, false);
181 
182 	std::vector<GLubyte> data;
183 	data.resize(alignment * m_n_columns);
184 
185 	for (GLuint column = 0; column < m_n_columns; ++column)
186 	{
187 		GLvoid* ptr = (GLvoid*)&data[column * alignment];
188 
189 		switch (m_basic_type)
190 		{
191 		case Double:
192 		{
193 			GLdouble* d_ptr = (GLdouble*)ptr;
194 
195 			for (GLuint i = 0; i < m_n_rows; ++i)
196 			{
197 				d_ptr[i] = GetRandDouble();
198 			}
199 		}
200 		break;
201 		case Float:
202 		{
203 			GLfloat* f_ptr = (GLfloat*)ptr;
204 
205 			for (GLuint i = 0; i < m_n_rows; ++i)
206 			{
207 				f_ptr[i] = GetRandFloat();
208 			}
209 		}
210 		break;
211 		case Int:
212 		{
213 			GLint* i_ptr = (GLint*)ptr;
214 
215 			for (GLuint i = 0; i < m_n_rows; ++i)
216 			{
217 				i_ptr[i] = GetRandInt();
218 			}
219 		}
220 		break;
221 		case Uint:
222 		{
223 			GLuint* ui_ptr = (GLuint*)ptr;
224 
225 			for (GLuint i = 0; i < m_n_rows; ++i)
226 			{
227 				ui_ptr[i] = GetRandUint();
228 			}
229 		}
230 		break;
231 		}
232 	}
233 
234 	return data;
235 }
236 
237 /** Generate data for type. This routine packs data tightly.
238  *
239  * @return Vector of bytes filled with data
240  **/
GenerateDataPacked() const241 std::vector<GLubyte> Type::GenerateDataPacked() const
242 {
243 	const GLuint basic_size = GetTypeSize(m_basic_type);
244 	const GLuint n_elements = m_n_columns * m_n_rows;
245 	const GLuint size		= basic_size * n_elements;
246 
247 	std::vector<GLubyte> data;
248 	data.resize(size);
249 
250 	GLvoid* ptr = (GLvoid*)&data[0];
251 
252 	switch (m_basic_type)
253 	{
254 	case Double:
255 	{
256 		GLdouble* d_ptr = (GLdouble*)ptr;
257 
258 		for (GLuint i = 0; i < n_elements; ++i)
259 		{
260 			d_ptr[i] = GetRandDouble();
261 		}
262 	}
263 	break;
264 	case Float:
265 	{
266 		GLfloat* f_ptr = (GLfloat*)ptr;
267 
268 		for (GLuint i = 0; i < n_elements; ++i)
269 		{
270 			f_ptr[i] = GetRandFloat();
271 		}
272 	}
273 	break;
274 	case Int:
275 	{
276 		GLint* i_ptr = (GLint*)ptr;
277 
278 		for (GLuint i = 0; i < n_elements; ++i)
279 		{
280 			i_ptr[i] = GetRandInt();
281 		}
282 	}
283 	break;
284 	case Uint:
285 	{
286 		GLuint* ui_ptr = (GLuint*)ptr;
287 
288 		for (GLuint i = 0; i < n_elements; ++i)
289 		{
290 			ui_ptr[i] = GetRandUint();
291 		}
292 	}
293 	break;
294 	}
295 
296 	return data;
297 }
298 
299 /** Calculate "actual alignment". It work under assumption that align value is valid
300  *
301  * @param align    Requested alignment, eg with "align" qualifier
302  * @param is_array Selects if an array of type or single instance should be considered
303  *
304  * @return Calculated value
305  **/
GetActualAlignment(GLuint align,bool is_array) const306 GLuint Type::GetActualAlignment(GLuint align, bool is_array) const
307 {
308 	const GLuint base_alignment = GetBaseAlignment(is_array);
309 
310 	return std::max(align, base_alignment);
311 }
312 
313 /** Align given ofset with specified alignment
314  *
315  * @param offset    Offset
316  * @param alignment Alignment
317  *
318  * @return Calculated value
319  **/
align(GLuint offset,GLuint alignment)320 GLuint align(GLuint offset, GLuint alignment)
321 {
322 	const GLuint rest = offset % alignment;
323 
324 	if (0 != rest)
325 	{
326 		GLuint missing = alignment - rest;
327 		offset += missing;
328 	}
329 
330 	return offset;
331 }
332 
333 /** Calculate "actual offset"
334  *
335  * @param start_offset     Requested offset
336  * @param actual_alignment Actual alignemnt
337  *
338  * @return Calculated value
339  **/
GetActualOffset(GLuint start_offset,GLuint actual_alignment)340 GLuint Type::GetActualOffset(GLuint start_offset, GLuint actual_alignment)
341 {
342 	GLuint offset = align(start_offset, actual_alignment);
343 
344 	return offset;
345 }
346 
347 /** Calculate "base alignment" for given type
348  *
349  * @param is_array Select if array or single instance should be considered
350  *
351  * @return Calculated value
352  **/
GetBaseAlignment(bool is_array) const353 GLuint Type::GetBaseAlignment(bool is_array) const
354 {
355 	GLuint elements = 1;
356 
357 	switch (m_n_rows)
358 	{
359 	case 2:
360 		elements = 2;
361 		break;
362 	case 3:
363 	case 4:
364 		elements = 4;
365 		break;
366 	default:
367 		break;
368 	}
369 
370 	GLuint N		 = GetTypeSize(m_basic_type);
371 	GLuint alignment = N * elements;
372 
373 	if ((true == is_array) || (1 != m_n_columns))
374 	{
375 		alignment = align(alignment, 16 /* vec4 alignment */);
376 	}
377 
378 	return alignment;
379 }
380 
381 /** Returns string representing GLSL constructor of type with arguments provided in data
382  *
383  * @param data Array of values that will be used as construcotr arguments.
384  *             It is interpreted as tightly packed array of type matching this type.
385  *
386  * @return String in form "Type(args)"
387  **/
GetGLSLConstructor(const GLvoid * data) const388 std::string Type::GetGLSLConstructor(const GLvoid* data) const
389 {
390 	const GLchar* type = GetGLSLTypeName();
391 
392 	std::stringstream stream;
393 
394 	stream << type << "(";
395 
396 	/* Scalar or vector */
397 	if (1 == m_n_columns)
398 	{
399 		for (GLuint row = 0; row < m_n_rows; ++row)
400 		{
401 			switch (m_basic_type)
402 			{
403 			case Double:
404 				stream << ((GLdouble*)data)[row];
405 				break;
406 			case Float:
407 				stream << ((GLfloat*)data)[row];
408 				break;
409 			case Int:
410 				stream << ((GLint*)data)[row];
411 				break;
412 			case Uint:
413 				stream << ((GLuint*)data)[row];
414 				break;
415 			}
416 
417 			if (row + 1 != m_n_rows)
418 			{
419 				stream << ", ";
420 			}
421 		}
422 	}
423 	else /* Matrix: mat(vec(), vec() .. ) */
424 	{
425 		const GLuint basic_size = GetTypeSize(m_basic_type);
426 		// 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)
427 		const GLuint column_stride = m_n_rows * basic_size;
428 		const Type   column_type   = GetType(m_basic_type, 1, m_n_rows);
429 
430 		for (GLuint column = 0; column < m_n_columns; ++column)
431 		{
432 			const GLuint  column_offset = column * column_stride;
433 			const GLvoid* column_data   = (GLubyte*)data + column_offset;
434 
435 			stream << column_type.GetGLSLConstructor(column_data);
436 
437 			if (column + 1 != m_n_columns)
438 			{
439 				stream << ", ";
440 			}
441 		}
442 	}
443 
444 	stream << ")";
445 
446 	return stream.str();
447 }
448 
449 /** Get glsl name of the type
450  *
451  * @return Name of glsl type
452  **/
GetGLSLTypeName() const453 const glw::GLchar* Type::GetGLSLTypeName() const
454 {
455 	static const GLchar* float_lut[4][4] = {
456 		{ "float", "vec2", "vec3", "vec4" },
457 		{ 0, "mat2", "mat2x3", "mat2x4" },
458 		{ 0, "mat3x2", "mat3", "mat3x4" },
459 		{ 0, "mat4x2", "mat4x3", "mat4" },
460 	};
461 
462 	static const GLchar* double_lut[4][4] = {
463 		{ "double", "dvec2", "dvec3", "dvec4" },
464 		{ 0, "dmat2", "dmat2x3", "dmat2x4" },
465 		{ 0, "dmat3x2", "dmat3", "dmat3x4" },
466 		{ 0, "dmat4x2", "dmat4x3", "dmat4" },
467 	};
468 
469 	static const GLchar* int_lut[4] = { "int", "ivec2", "ivec3", "ivec4" };
470 
471 	static const GLchar* uint_lut[4] = { "uint", "uvec2", "uvec3", "uvec4" };
472 
473 	const GLchar* result = 0;
474 
475 	if ((1 > m_n_columns) || (1 > m_n_rows) || (4 < m_n_columns) || (4 < m_n_rows))
476 	{
477 		return 0;
478 	}
479 
480 	switch (m_basic_type)
481 	{
482 	case Float:
483 		result = float_lut[m_n_columns - 1][m_n_rows - 1];
484 		break;
485 	case Double:
486 		result = double_lut[m_n_columns - 1][m_n_rows - 1];
487 		break;
488 	case Int:
489 		result = int_lut[m_n_rows - 1];
490 		break;
491 	case Uint:
492 		result = uint_lut[m_n_rows - 1];
493 		break;
494 	default:
495 		TCU_FAIL("Invalid enum");
496 	}
497 
498 	return result;
499 }
500 
501 /** Get number of locations required for the type
502  *
503  * @return Number of columns times:
504  *          - 2 when type is double with 3 or 4 rows,
505  *          - 1 otherwise or if it's a vertex shader input.
506  **/
GetLocations(bool is_vs_input) const507 GLuint Type::GetLocations(bool is_vs_input) const
508 {
509 	GLuint n_loc_per_column;
510 
511 	/* 1 or 2 doubles any for rest */
512 	if ((2 >= m_n_rows) || (Double != m_basic_type) || is_vs_input)
513 	{
514 		n_loc_per_column = 1;
515 	}
516 	else
517 	{
518 		/* 3 and 4 doubles */
519 		n_loc_per_column = 2;
520 	}
521 
522 	return n_loc_per_column * m_n_columns;
523 }
524 
525 /** Get size of the type in bytes.
526  * Note that this routine doesn't consider arrays and assumes
527  * column_major matrices.
528  *
529  * @return Formula:
530  *          - If std140 packaging and matrix; number of columns * base alignment
531  *          - Otherwise; number of elements * sizeof(base_type)
532  **/
GetSize(const bool is_std140) const533 GLuint Type::GetSize(const bool is_std140) const
534 {
535 	const GLuint basic_type_size = GetTypeSize(m_basic_type);
536 	const GLuint n_elements		 = m_n_columns * m_n_rows;
537 
538 	if (is_std140 && m_n_columns > 1)
539 	{
540 		return m_n_columns * GetBaseAlignment(false);
541 	}
542 
543 	return basic_type_size * n_elements;
544 }
545 
546 /** Get GLenum representing the type
547  *
548  * @return GLenum
549  **/
GetTypeGLenum() const550 GLenum Type::GetTypeGLenum() const
551 {
552 	static const GLenum float_lut[4][4] = {
553 		{ GL_FLOAT, GL_FLOAT_VEC2, GL_FLOAT_VEC3, GL_FLOAT_VEC4 },
554 		{ 0, GL_FLOAT_MAT2, GL_FLOAT_MAT2x3, GL_FLOAT_MAT2x4 },
555 		{ 0, GL_FLOAT_MAT3x2, GL_FLOAT_MAT3, GL_FLOAT_MAT3x4 },
556 		{ 0, GL_FLOAT_MAT4x2, GL_FLOAT_MAT4x3, GL_FLOAT_MAT4 },
557 	};
558 
559 	static const GLenum double_lut[4][4] = {
560 		{ GL_DOUBLE, GL_DOUBLE_VEC2, GL_DOUBLE_VEC3, GL_DOUBLE_VEC4 },
561 		{ 0, GL_DOUBLE_MAT2, GL_DOUBLE_MAT2x3, GL_DOUBLE_MAT2x4 },
562 		{ 0, GL_DOUBLE_MAT3x2, GL_DOUBLE_MAT3, GL_DOUBLE_MAT3x4 },
563 		{ 0, GL_DOUBLE_MAT4x2, GL_DOUBLE_MAT4x3, GL_DOUBLE_MAT4 },
564 	};
565 
566 	static const GLenum int_lut[4] = { GL_INT, GL_INT_VEC2, GL_INT_VEC3, GL_INT_VEC4 };
567 
568 	static const GLenum uint_lut[4] = { GL_UNSIGNED_INT, GL_UNSIGNED_INT_VEC2, GL_UNSIGNED_INT_VEC3,
569 										GL_UNSIGNED_INT_VEC4 };
570 
571 	GLenum result = 0;
572 
573 	if ((1 > m_n_columns) || (1 > m_n_rows) || (4 < m_n_columns) || (4 < m_n_rows))
574 	{
575 		return 0;
576 	}
577 
578 	switch (m_basic_type)
579 	{
580 	case Float:
581 		result = float_lut[m_n_columns - 1][m_n_rows - 1];
582 		break;
583 	case Double:
584 		result = double_lut[m_n_columns - 1][m_n_rows - 1];
585 		break;
586 	case Int:
587 		result = int_lut[m_n_rows - 1];
588 		break;
589 	case Uint:
590 		result = uint_lut[m_n_rows - 1];
591 		break;
592 	default:
593 		TCU_FAIL("Invalid enum");
594 	}
595 
596 	return result;
597 }
598 
599 /** Calculate the number of components consumed by a type
600  *   according to 11.1.2.1 Output Variables
601  *
602  * @return Calculated number of components for the type
603  **/
GetNumComponents() const604 GLuint Type::GetNumComponents() const
605 {
606 	// Rule 3 of Section 7.6.2.2
607 	// If the member is a three-component vector with components consuming N
608 	// basic machine units, the base alignment is 4N.
609 	GLuint num_components = (m_n_rows == 3 ? 4 : m_n_rows) * m_n_columns;
610 
611 	if (m_basic_type == Double)
612 	{
613 		num_components *= 2;
614 	}
615 
616 	return num_components;
617 }
618 
619 /** Calculate the valid values to use with the component qualifier
620  *
621  * @return Vector with the valid values, in growing order, or empty if
622  *         the component qualifier is not allowed
623  **/
GetValidComponents() const624 std::vector<GLuint> Type::GetValidComponents() const
625 {
626 	const GLuint		component_size			  = Utils::Type::Double == m_basic_type ? 2 : 1;
627 	const GLuint		n_components_per_location = Utils::Type::Double == m_basic_type ? 2 : 4;
628 	const GLuint		n_req_components		  = m_n_rows;
629 	const GLint			max_valid_component		  = (GLint)n_components_per_location - (GLint)n_req_components;
630 	std::vector<GLuint> data;
631 
632 	/* The component qualifier cannot be used for matrices */
633 	if (1 != m_n_columns)
634 	{
635 		return data;
636 	}
637 
638 	/* The component qualifier cannot be used for dvec3/dvec4 */
639 	if (max_valid_component < 0)
640 	{
641 		return data;
642 	}
643 
644 	for (GLuint i = 0; i <= (GLuint)max_valid_component; ++i)
645 	{
646 		data.push_back(i * component_size);
647 	}
648 
649 	return data;
650 }
651 
652 /** Calculate stride for the type according to std140 rules
653  *
654  * @param alignment        Alignment of type
655  * @param n_columns        Number of columns
656  * @param n_array_elements Number of elements in array
657  *
658  * @return Calculated value
659  **/
CalculateStd140Stride(GLuint alignment,GLuint n_columns,GLuint n_array_elements)660 GLuint Type::CalculateStd140Stride(GLuint alignment, GLuint n_columns, GLuint n_array_elements)
661 {
662 	GLuint stride = alignment * n_columns;
663 	if (0 != n_array_elements)
664 	{
665 		stride *= n_array_elements;
666 	}
667 
668 	return stride;
669 }
670 
671 /** Check if glsl support matrices for specific basic type
672  *
673  * @param type Basic type
674  *
675  * @return true if matrices of <type> are supported, false otherwise
676  **/
DoesTypeSupportMatrix(TYPES type)677 bool Type::DoesTypeSupportMatrix(TYPES type)
678 {
679 	bool result = false;
680 
681 	switch (type)
682 	{
683 	case Float:
684 	case Double:
685 		result = true;
686 		break;
687 	case Int:
688 	case Uint:
689 		result = false;
690 		break;
691 	default:
692 		TCU_FAIL("Invalid enum");
693 	}
694 
695 	return result;
696 }
697 
698 /** Creates instance of Type
699  *
700  * @param basic_type Select basic type of instance
701  * @param n_columns  Number of columns
702  * @param n_rows     Number of rows
703  *
704  * @return Type instance
705  **/
GetType(TYPES basic_type,glw::GLuint n_columns,glw::GLuint n_rows)706 Type Type::GetType(TYPES basic_type, glw::GLuint n_columns, glw::GLuint n_rows)
707 {
708 	Type type = { basic_type, n_columns, n_rows };
709 
710 	return type;
711 }
712 
713 /** Get Size of given type in bytes
714  *
715  * @param type
716  *
717  * @return Size of type
718  **/
GetTypeSize(TYPES type)719 GLuint Type::GetTypeSize(TYPES type)
720 {
721 	GLuint result = 0;
722 
723 	switch (type)
724 	{
725 	case Float:
726 		result = sizeof(GLfloat);
727 		break;
728 	case Double:
729 		result = sizeof(GLdouble);
730 		break;
731 	case Int:
732 		result = sizeof(GLint);
733 		break;
734 	case Uint:
735 		result = sizeof(GLuint);
736 		break;
737 	default:
738 		TCU_FAIL("Invalid enum");
739 	}
740 
741 	return result;
742 }
743 
744 /** Get GLenum representing given type
745  *
746  * @param type
747  *
748  * @return GLenum value
749  **/
GetTypeGLenum(TYPES type)750 GLenum Type::GetTypeGLenum(TYPES type)
751 {
752 	GLenum result = 0;
753 
754 	switch (type)
755 	{
756 	case Float:
757 		result = GL_FLOAT;
758 		break;
759 	case Double:
760 		result = GL_DOUBLE;
761 		break;
762 	case Int:
763 		result = GL_INT;
764 		break;
765 	case Uint:
766 		result = GL_UNSIGNED_INT;
767 		break;
768 	default:
769 		TCU_FAIL("Invalid enum");
770 	}
771 
772 	return result;
773 }
774 
775 /** Check if two types can share the same location, based on the underlying numerical type and bit width
776  *
777  * @param first   First type to compare
778  * @param second  Second type to compare
779  *
780  * @return true if the types can share the same location
781  **/
CanTypesShareLocation(TYPES first,TYPES second)782 bool Type::CanTypesShareLocation(TYPES first, TYPES second)
783 {
784 	if (first == second)
785 	{
786 		return true;
787 	}
788 
789 	if (Float == first || Float == second || Double == first || Double == second)
790 	{
791 		return false;
792 	}
793 
794 	return true;
795 }
796 
797 /** Get proper glUniformNdv routine for vectors with specified number of rows
798  *
799  * @param gl     GL functions
800  * @param n_rows Number of rows
801  *
802  * @return Function address
803  **/
getUniformNdv(const glw::Functions & gl,glw::GLuint n_rows)804 uniformNdv getUniformNdv(const glw::Functions& gl, glw::GLuint n_rows)
805 {
806 	uniformNdv result = 0;
807 
808 	switch (n_rows)
809 	{
810 	case 1:
811 		result = gl.uniform1dv;
812 		break;
813 	case 2:
814 		result = gl.uniform2dv;
815 		break;
816 	case 3:
817 		result = gl.uniform3dv;
818 		break;
819 	case 4:
820 		result = gl.uniform4dv;
821 		break;
822 	default:
823 		TCU_FAIL("Invalid number of rows");
824 	}
825 
826 	return result;
827 }
828 
829 /** Get proper glUniformNfv routine for vectors with specified number of rows
830  *
831  * @param gl     GL functions
832  * @param n_rows Number of rows
833  *
834  * @return Function address
835  **/
getUniformNfv(const glw::Functions & gl,glw::GLuint n_rows)836 uniformNfv getUniformNfv(const glw::Functions& gl, glw::GLuint n_rows)
837 {
838 	uniformNfv result = 0;
839 
840 	switch (n_rows)
841 	{
842 	case 1:
843 		result = gl.uniform1fv;
844 		break;
845 	case 2:
846 		result = gl.uniform2fv;
847 		break;
848 	case 3:
849 		result = gl.uniform3fv;
850 		break;
851 	case 4:
852 		result = gl.uniform4fv;
853 		break;
854 	default:
855 		TCU_FAIL("Invalid number of rows");
856 	}
857 
858 	return result;
859 }
860 
861 /** Get proper glUniformNiv routine for vectors with specified number of rows
862  *
863  * @param gl     GL functions
864  * @param n_rows Number of rows
865  *
866  * @return Function address
867  **/
getUniformNiv(const glw::Functions & gl,glw::GLuint n_rows)868 uniformNiv getUniformNiv(const glw::Functions& gl, glw::GLuint n_rows)
869 {
870 	uniformNiv result = 0;
871 
872 	switch (n_rows)
873 	{
874 	case 1:
875 		result = gl.uniform1iv;
876 		break;
877 	case 2:
878 		result = gl.uniform2iv;
879 		break;
880 	case 3:
881 		result = gl.uniform3iv;
882 		break;
883 	case 4:
884 		result = gl.uniform4iv;
885 		break;
886 	default:
887 		TCU_FAIL("Invalid number of rows");
888 	}
889 
890 	return result;
891 }
892 
893 /** Get proper glUniformNuiv routine for vectors with specified number of rows
894  *
895  * @param gl     GL functions
896  * @param n_rows Number of rows
897  *
898  * @return Function address
899  **/
getUniformNuiv(const glw::Functions & gl,glw::GLuint n_rows)900 uniformNuiv getUniformNuiv(const glw::Functions& gl, glw::GLuint n_rows)
901 {
902 	uniformNuiv result = 0;
903 
904 	switch (n_rows)
905 	{
906 	case 1:
907 		result = gl.uniform1uiv;
908 		break;
909 	case 2:
910 		result = gl.uniform2uiv;
911 		break;
912 	case 3:
913 		result = gl.uniform3uiv;
914 		break;
915 	case 4:
916 		result = gl.uniform4uiv;
917 		break;
918 	default:
919 		TCU_FAIL("Invalid number of rows");
920 	}
921 
922 	return result;
923 }
924 
925 /** Get proper glUniformMatrixNdv routine for matrix with specified number of columns and rows
926  *
927  * @param gl     GL functions
928  * @param n_rows Number of rows
929  *
930  * @return Function address
931  **/
getUniformMatrixNdv(const glw::Functions & gl,glw::GLuint n_columns,glw::GLuint n_rows)932 uniformMatrixNdv getUniformMatrixNdv(const glw::Functions& gl, glw::GLuint n_columns, glw::GLuint n_rows)
933 {
934 	uniformMatrixNdv result = 0;
935 
936 	switch (n_columns)
937 	{
938 	case 2:
939 		switch (n_rows)
940 		{
941 		case 2:
942 			result = gl.uniformMatrix2dv;
943 			break;
944 		case 3:
945 			result = gl.uniformMatrix2x3dv;
946 			break;
947 		case 4:
948 			result = gl.uniformMatrix2x4dv;
949 			break;
950 		default:
951 			TCU_FAIL("Invalid number of rows");
952 		}
953 		break;
954 	case 3:
955 		switch (n_rows)
956 		{
957 		case 2:
958 			result = gl.uniformMatrix3x2dv;
959 			break;
960 		case 3:
961 			result = gl.uniformMatrix3dv;
962 			break;
963 		case 4:
964 			result = gl.uniformMatrix3x4dv;
965 			break;
966 		default:
967 			TCU_FAIL("Invalid number of rows");
968 		}
969 		break;
970 	case 4:
971 		switch (n_rows)
972 		{
973 		case 2:
974 			result = gl.uniformMatrix4x2dv;
975 			break;
976 		case 3:
977 			result = gl.uniformMatrix4x3dv;
978 			break;
979 		case 4:
980 			result = gl.uniformMatrix4dv;
981 			break;
982 		default:
983 			TCU_FAIL("Invalid number of rows");
984 		}
985 		break;
986 	default:
987 		TCU_FAIL("Invalid number of columns");
988 	}
989 
990 	return result;
991 }
992 
993 /** Get proper glUniformMatrixNfv routine for vectors with specified number of columns and rows
994  *
995  * @param gl     GL functions
996  * @param n_rows Number of rows
997  *
998  * @return Function address
999  **/
getUniformMatrixNfv(const glw::Functions & gl,glw::GLuint n_columns,glw::GLuint n_rows)1000 uniformMatrixNfv getUniformMatrixNfv(const glw::Functions& gl, glw::GLuint n_columns, glw::GLuint n_rows)
1001 {
1002 	uniformMatrixNfv result = 0;
1003 
1004 	switch (n_columns)
1005 	{
1006 	case 2:
1007 		switch (n_rows)
1008 		{
1009 		case 2:
1010 			result = gl.uniformMatrix2fv;
1011 			break;
1012 		case 3:
1013 			result = gl.uniformMatrix2x3fv;
1014 			break;
1015 		case 4:
1016 			result = gl.uniformMatrix2x4fv;
1017 			break;
1018 		default:
1019 			TCU_FAIL("Invalid number of rows");
1020 		}
1021 		break;
1022 	case 3:
1023 		switch (n_rows)
1024 		{
1025 		case 2:
1026 			result = gl.uniformMatrix3x2fv;
1027 			break;
1028 		case 3:
1029 			result = gl.uniformMatrix3fv;
1030 			break;
1031 		case 4:
1032 			result = gl.uniformMatrix3x4fv;
1033 			break;
1034 		default:
1035 			TCU_FAIL("Invalid number of rows");
1036 		}
1037 		break;
1038 	case 4:
1039 		switch (n_rows)
1040 		{
1041 		case 2:
1042 			result = gl.uniformMatrix4x2fv;
1043 			break;
1044 		case 3:
1045 			result = gl.uniformMatrix4x3fv;
1046 			break;
1047 		case 4:
1048 			result = gl.uniformMatrix4fv;
1049 			break;
1050 		default:
1051 			TCU_FAIL("Invalid number of rows");
1052 		}
1053 		break;
1054 	default:
1055 		TCU_FAIL("Invalid number of columns");
1056 	}
1057 
1058 	return result;
1059 }
1060 
verifyVarying(Program & program,const std::string & parent_name,const Variable::Descriptor & desc,std::stringstream & stream,bool is_input)1061 bool verifyVarying(Program& program, const std::string& parent_name, const Variable::Descriptor& desc,
1062 				   std::stringstream& stream, bool is_input)
1063 {
1064 	GLint  component = 0;
1065 	GLuint index	 = 0;
1066 	GLenum interface = GL_PROGRAM_INPUT;
1067 	GLint  location  = 0;
1068 
1069 	if (false == is_input)
1070 	{
1071 		interface = GL_PROGRAM_OUTPUT;
1072 	}
1073 
1074 	const std::string& name = Utils::Variable::GetReference(parent_name, desc, Utils::Variable::BASIC, 0);
1075 
1076 	try
1077 	{
1078 		index = program.GetResourceIndex(name, interface);
1079 
1080 		program.GetResource(interface, index, GL_LOCATION, 1 /* size */, &location);
1081 		program.GetResource(interface, index, GL_LOCATION_COMPONENT, 1 /* size */, &component);
1082 	}
1083 	catch (std::exception& exc)
1084 	{
1085 		stream << "Failed to query program for varying: " << desc.m_name << ". Reason: " << exc.what() << "\n";
1086 
1087 		return false;
1088 	}
1089 
1090 	bool result = true;
1091 
1092 	if (location != desc.m_expected_location)
1093 	{
1094 		stream << "Attribute: " << desc.m_name << " - invalid location: " << location
1095 			   << " expected: " << desc.m_expected_location << std::endl;
1096 		result = false;
1097 	}
1098 	if (component != desc.m_expected_component)
1099 	{
1100 		stream << "Attribute: " << desc.m_name << " - invalid component: " << component
1101 			   << " expected: " << desc.m_expected_component << std::endl;
1102 		result = false;
1103 	}
1104 
1105 	return result;
1106 }
1107 
1108 /** Query program resource for given variable and verify that everything is as expected
1109  *
1110  * @param program  Program object
1111  * @param variable Variable object
1112  * @param stream   Stream that will be used to log any error
1113  * @param is_input Selects if varying is input or output
1114  *
1115  * @return true if verification is positive, false otherwise
1116  **/
checkVarying(Program & program,Shader::STAGES stage,const Variable & variable,std::stringstream & stream,bool is_input)1117 bool checkVarying(Program& program, Shader::STAGES stage, const Variable& variable, std::stringstream& stream, bool is_input)
1118 {
1119 	bool result = true;
1120 
1121 	if (variable.IsBlock())
1122 	{
1123 		Utils::Interface* interface = variable.m_descriptor.m_interface;
1124 		const size_t	  n_members = interface->m_members.size();
1125 
1126 		for (size_t i = 0; i < n_members; ++i)
1127 		{
1128 			const Variable::Descriptor& member = interface->m_members[i];
1129 			bool member_result				   = verifyVarying(program, interface->m_name, member, stream, is_input);
1130 
1131 			if (false == member_result)
1132 			{
1133 				result = false;
1134 			}
1135 		}
1136 	}
1137 	/*
1138 	 To query the the location of struct member by glGetProgramResource, we need pass the variable name "gs_fs_output[0].single",
1139 	 but in original implementation, the test pass the name "Data.single", which can't get any valid result.
1140 	 struct Data {
1141 	 dmat2 single;
1142 	 dmat2 array[1];
1143 	 };
1144 	 layout (location = 0) in Data gs_fs_output[1];
1145 	 */
1146 	else if (variable.IsStruct())
1147 	{
1148 		Utils::Interface* interface		 = variable.m_descriptor.m_interface;
1149 		const size_t	  n_members		 = interface->m_members.size();
1150 		std::string		  structVariable = variable.m_descriptor.m_name;
1151 
1152 		switch (Variable::GetFlavour(stage, is_input ? Variable::INPUT : Variable::OUTPUT))
1153 		{
1154 		case Variable::ARRAY:
1155 		case Variable::INDEXED_BY_INVOCATION_ID:
1156 			structVariable.append("[0]");
1157 			break;
1158 		default:
1159 			break;
1160 		}
1161 
1162 		// If struct variable is an array
1163 		if (0 != variable.m_descriptor.m_n_array_elements)
1164 		{
1165 			for (GLuint i = 0; i < variable.m_descriptor.m_n_array_elements; i++)
1166 			{
1167 				GLchar buffer[16];
1168 				sprintf(buffer, "%d", i);
1169 				structVariable.append("[");
1170 				structVariable.append(buffer);
1171 				structVariable.append("]");
1172 				for (size_t j = 0; j < n_members; ++j)
1173 				{
1174 					const Variable::Descriptor& member = interface->m_members[j];
1175 					bool member_result = verifyVarying(program, structVariable, member, stream, is_input);
1176 
1177 					if (false == member_result)
1178 					{
1179 						result = false;
1180 					}
1181 				}
1182 			}
1183 		}
1184 		else
1185 		{
1186 			for (GLuint i = 0; i < n_members; ++i)
1187 			{
1188 				const Variable::Descriptor& member = interface->m_members[i];
1189 				bool member_result				   = verifyVarying(program, structVariable, member, stream, is_input);
1190 
1191 				if (false == member_result)
1192 				{
1193 					result = false;
1194 				}
1195 			}
1196 		}
1197 	}
1198 	else
1199 	{
1200 		result = verifyVarying(program, "", variable.m_descriptor, stream, is_input);
1201 	}
1202 	return result;
1203 }
1204 
1205 /** Query program resource for given variable and verify that everything is as expected
1206  *
1207  * @param program  Program object
1208  * @param variable Variable object
1209  * @param stream   Stream that will be used to log any error
1210  *
1211  * @return true if verification is positive, false otherwise
1212  **/
checkUniform(Program & program,const Utils::Variable & variable,std::stringstream & stream)1213 bool checkUniform(Program& program, const Utils::Variable& variable, std::stringstream& stream)
1214 {
1215 	bool result = true;
1216 
1217 	if (false == variable.IsBlock())
1218 	{
1219 		TCU_FAIL("Not implemented");
1220 	}
1221 	else
1222 	{
1223 		Utils::Interface* interface = variable.m_descriptor.m_interface;
1224 
1225 		size_t size = interface->m_members.size();
1226 
1227 		std::vector<GLuint>		 indices;
1228 		std::vector<const char*> names;
1229 		std::vector<std::string> names_str;
1230 		std::vector<GLint>		 offsets;
1231 
1232 		indices.resize(size);
1233 		names.resize(size);
1234 		names_str.resize(size);
1235 		offsets.resize(size);
1236 
1237 		for (size_t i = 0; i < size; ++i)
1238 		{
1239 			indices[i] = 0;
1240 			offsets[i] = 0;
1241 
1242 			const std::string& name =
1243 				Utils::Variable::GetReference(interface->m_name, interface->m_members[i], Utils::Variable::BASIC, 0);
1244 
1245 			if (Utils::Variable::INTERFACE == interface->m_members[i].m_type)
1246 			{
1247 				const std::string& member_name = Utils::Variable::GetReference(
1248 					name, interface->m_members[i].m_interface->m_members[0], Utils::Variable::BASIC, 0);
1249 
1250 				names_str[i] = member_name;
1251 			}
1252 			else
1253 			{
1254 				names_str[i] = name;
1255 			}
1256 
1257 			names[i] = names_str[i].c_str();
1258 		}
1259 
1260 		try
1261 		{
1262 			program.GetUniformIndices(static_cast<glw::GLsizei>(size), &names[0], &indices[0]);
1263 			program.GetActiveUniformsiv(static_cast<glw::GLsizei>(size), &indices[0], GL_UNIFORM_OFFSET, &offsets[0]);
1264 		}
1265 		catch (std::exception& exc)
1266 		{
1267 			stream << "Failed to query program for uniforms in block: " << variable.m_descriptor.m_name
1268 				   << ". Reason: " << exc.what() << "\n";
1269 
1270 			return false;
1271 		}
1272 
1273 		for (size_t i = 0; i < size; ++i)
1274 		{
1275 			Utils::Variable::Descriptor& desc = interface->m_members[i];
1276 
1277 			if (offsets[i] != (GLint)desc.m_offset)
1278 			{
1279 				stream << "Uniform: " << desc.m_name << " - invalid offset: " << offsets[i]
1280 					   << " expected: " << desc.m_offset << std::endl;
1281 				result = false;
1282 			}
1283 		}
1284 	}
1285 
1286 	return result;
1287 }
1288 
1289 /** Query program resource for given variable and verify that everything is as expected
1290  *
1291  * @param program  Program object
1292  * @param variable Variable object
1293  * @param stream   Stream that will be used to log any error
1294  *
1295  * @return true if verification is positive, false otherwise
1296  **/
checkSSB(Program & program,const Utils::Variable & variable,std::stringstream & stream)1297 bool checkSSB(Program& program, const Utils::Variable& variable, std::stringstream& stream)
1298 {
1299 	bool result = true;
1300 
1301 	if (false == variable.IsBlock())
1302 	{
1303 		TCU_FAIL("Not implemented");
1304 	}
1305 	else
1306 	{
1307 		Utils::Interface* interface = variable.m_descriptor.m_interface;
1308 
1309 		size_t size = interface->m_members.size();
1310 
1311 		for (size_t i = 0; i < size; ++i)
1312 		{
1313 			GLuint		index	= 0;
1314 			std::string name_str = "";
1315 			GLint		offset   = 0;
1316 
1317 			const std::string& name =
1318 				Utils::Variable::GetReference(interface->m_name, interface->m_members[i], Utils::Variable::BASIC, 0);
1319 
1320 			if (Utils::Variable::INTERFACE == interface->m_members[i].m_type)
1321 			{
1322 				const std::string& member_name = Utils::Variable::GetReference(
1323 					name, interface->m_members[i].m_interface->m_members[0], Utils::Variable::BASIC, 0);
1324 
1325 				name_str = member_name;
1326 			}
1327 			else
1328 			{
1329 				name_str = name;
1330 			}
1331 
1332 			try
1333 			{
1334 				index = program.GetResourceIndex(name_str, GL_BUFFER_VARIABLE);
1335 
1336 				program.GetResource(GL_BUFFER_VARIABLE, index, GL_OFFSET, 1, &offset);
1337 			}
1338 			catch (std::exception& exc)
1339 			{
1340 				stream << "Failed to query program for buffer variable: " << variable.m_descriptor.m_name
1341 					   << ". Reason: " << exc.what() << "\n";
1342 
1343 				return false;
1344 			}
1345 
1346 			Utils::Variable::Descriptor& desc = interface->m_members[i];
1347 
1348 			if (offset != (GLint)desc.m_offset)
1349 			{
1350 				stream << "Uniform: " << desc.m_name << " - invalid offset: " << offset
1351 					   << " expected: " << desc.m_offset << std::endl;
1352 				result = false;
1353 			}
1354 		}
1355 	}
1356 
1357 	return result;
1358 }
1359 
1360 /** Query program resources at given stage and verifies results
1361  *
1362  * @param program           Program object
1363  * @param program_interface Definition of program interface
1364  * @param stage             Stage to be verified
1365  * @param check_inputs      Select if inputs should be verified
1366  * @param check_outputs     Select if output should be verified
1367  * @param check_uniforms    Select if uniforms should be verified
1368  * @param check_ssbs        Select if buffers should be verified
1369  * @param stream            Stream that will be used to log any error
1370  *
1371  * @return true if verification is positive, false otherwise
1372  **/
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)1373 bool checkProgramStage(Program& program, const ProgramInterface& program_interface, Utils::Shader::STAGES stage,
1374 					   bool check_inputs, bool check_outputs, bool check_uniforms, bool check_ssbs,
1375 					   std::stringstream& stream)
1376 {
1377 	typedef Variable::PtrVector::const_iterator const_iterator;
1378 
1379 	const ShaderInterface& interface = program_interface.GetShaderInterface(stage);
1380 
1381 	bool result = true;
1382 
1383 	/* Inputs */
1384 	if (true == check_inputs)
1385 	{
1386 		const Variable::PtrVector& inputs = interface.m_inputs;
1387 
1388 		for (const_iterator it = inputs.begin(); it != inputs.end(); ++it)
1389 		{
1390 			if (false == checkVarying(program, stage, **it, stream, true))
1391 			{
1392 				result = false;
1393 			}
1394 		}
1395 	}
1396 
1397 	/* Outputs */
1398 	if (true == check_outputs)
1399 	{
1400 		const Variable::PtrVector& outputs = interface.m_outputs;
1401 
1402 		for (const_iterator it = outputs.begin(); it != outputs.end(); ++it)
1403 		{
1404 			if (false == checkVarying(program, stage, **it, stream, false))
1405 			{
1406 				result = false;
1407 			}
1408 		}
1409 	}
1410 
1411 	/* Uniforms */
1412 	if (true == check_uniforms)
1413 	{
1414 		const Variable::PtrVector& uniforms = interface.m_uniforms;
1415 
1416 		for (const_iterator it = uniforms.begin(); it != uniforms.end(); ++it)
1417 		{
1418 			if (false == checkUniform(program, **it, stream))
1419 			{
1420 				result = false;
1421 			}
1422 		}
1423 	}
1424 
1425 	/* SSBs */
1426 	if (true == check_ssbs)
1427 	{
1428 		const Variable::PtrVector& ssbs = interface.m_ssb_blocks;
1429 
1430 		for (const_iterator it = ssbs.begin(); it != ssbs.end(); ++it)
1431 		{
1432 			if (false == checkSSB(program, **it, stream))
1433 			{
1434 				result = false;
1435 			}
1436 		}
1437 	}
1438 
1439 	return result;
1440 }
1441 
1442 /** Query resources of monolithic compute program and verifies results
1443  *
1444  * @param program           Program object
1445  * @param program_interface Definition of program interface
1446  * @param stream            Stream that will be used to log any error
1447  *
1448  * @return true if verification is positive, false otherwise
1449  **/
checkMonolithicComputeProgramInterface(Program & program,const ProgramInterface & program_interface,std::stringstream & stream)1450 bool checkMonolithicComputeProgramInterface(Program& program, const ProgramInterface& program_interface,
1451 											std::stringstream& stream)
1452 {
1453 	bool result = true;
1454 
1455 	if (false == checkProgramStage(program, program_interface, Shader::COMPUTE, false, false, true, true, stream))
1456 	{
1457 		result = false;
1458 	}
1459 
1460 	/* Done */
1461 	return result;
1462 }
1463 
1464 /** Query resources of monolithic draw program and verifies results
1465  *
1466  * @param program           Program object
1467  * @param program_interface Definition of program interface
1468  * @param stream            Stream that will be used to log any error
1469  *
1470  * @return true if verification is positive, false otherwise
1471  **/
checkMonolithicDrawProgramInterface(Program & program,const ProgramInterface & program_interface,std::stringstream & stream)1472 bool checkMonolithicDrawProgramInterface(Program& program, const ProgramInterface& program_interface,
1473 										 std::stringstream& stream)
1474 {
1475 	bool result = true;
1476 
1477 	if (false == checkProgramStage(program, program_interface, Shader::VERTEX, true, false, true, true, stream))
1478 	{
1479 		result = false;
1480 	}
1481 
1482 	/* Done */
1483 	return result;
1484 }
1485 
1486 /** Query resources of separable draw program and verifies results
1487  *
1488  * @param program           Program object
1489  * @param program_interface Definition of program interface
1490  * @param stream            Stream that will be used to log any error
1491  *
1492  * @return true if verification is positive, false otherwise
1493  **/
checkSeparableDrawProgramInterface(Program & program,const ProgramInterface & program_interface,Utils::Shader::STAGES stage,std::stringstream & stream)1494 bool checkSeparableDrawProgramInterface(Program& program, const ProgramInterface& program_interface,
1495 										Utils::Shader::STAGES stage, std::stringstream& stream)
1496 {
1497 	bool result = true;
1498 
1499 	if (false == checkProgramStage(program, program_interface, stage, true, true, true, true, stream))
1500 	{
1501 		result = false;
1502 	}
1503 
1504 	/* Done */
1505 	return result;
1506 }
1507 
1508 /** Check if extension is supported
1509  *
1510  * @param context        Test context
1511  * @param extension_name Name of extension
1512  *
1513  * @return true if extension is supported, false otherwise
1514  **/
isExtensionSupported(deqp::Context & context,const GLchar * extension_name)1515 bool isExtensionSupported(deqp::Context& context, const GLchar* extension_name)
1516 {
1517 	const std::vector<std::string>& extensions = context.getContextInfo().getExtensions();
1518 
1519 	if (std::find(extensions.begin(), extensions.end(), extension_name) == extensions.end())
1520 	{
1521 		return false;
1522 	}
1523 
1524 	return true;
1525 }
1526 
1527 /** Check if GL context meets version requirements
1528  *
1529  * @param gl             Functions
1530  * @param required_major Minimum required MAJOR_VERSION
1531  * @param required_minor Minimum required MINOR_VERSION
1532  *
1533  * @return true if GL context version is at least as requested, false otherwise
1534  **/
isGLVersionAtLeast(const Functions & gl,GLint required_major,GLint required_minor)1535 bool isGLVersionAtLeast(const Functions& gl, GLint required_major, GLint required_minor)
1536 {
1537 	glw::GLint major = 0;
1538 	glw::GLint minor = 0;
1539 
1540 	gl.getIntegerv(GL_MAJOR_VERSION, &major);
1541 	gl.getIntegerv(GL_MINOR_VERSION, &minor);
1542 
1543 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
1544 
1545 	if (major > required_major)
1546 	{
1547 		/* Major is higher than required one */
1548 		return true;
1549 	}
1550 	else if (major == required_major)
1551 	{
1552 		if (minor >= required_minor)
1553 		{
1554 			/* Major is equal to required one */
1555 			/* Minor is higher than or equal to required one */
1556 			return true;
1557 		}
1558 		else
1559 		{
1560 			/* Major is equal to required one */
1561 			/* Minor is lower than required one */
1562 			return false;
1563 		}
1564 	}
1565 	else
1566 	{
1567 		/* Major is lower than required one */
1568 		return false;
1569 	}
1570 }
1571 
1572 /** Replace first occurance of <token> with <text> in <string> starting at <search_posistion>
1573  *
1574  * @param token           Token string
1575  * @param search_position Position at which find will start, it is updated to position at which replaced text ends
1576  * @param text            String that will be used as replacement for <token>
1577  * @param string          String to work on
1578  **/
replaceToken(const GLchar * token,size_t & search_position,const GLchar * text,std::string & string)1579 void replaceToken(const GLchar* token, size_t& search_position, const GLchar* text, std::string& string)
1580 {
1581 	const size_t text_length	= strlen(text);
1582 	const size_t token_length   = strlen(token);
1583 	const size_t token_position = string.find(token, search_position);
1584 
1585 #if DEBUG_REPLACE_TOKEN
1586 	if (std::string::npos == token_position)
1587 	{
1588 		string.append("\n\nInvalid token: ");
1589 		string.append(token);
1590 
1591 		TCU_FAIL(string.c_str());
1592 	}
1593 #endif /* DEBUG_REPLACE_TOKEN */
1594 
1595 	string.replace(token_position, token_length, text, text_length);
1596 
1597 	search_position = token_position + text_length;
1598 }
1599 
1600 /** Replace all occurances of <token> with <text> in <string>
1601  *
1602  * @param token           Token string
1603  * @param text            String that will be used as replacement for <token>
1604  * @param string          String to work on
1605  **/
replaceAllTokens(const GLchar * token,const GLchar * text,std::string & string)1606 void replaceAllTokens(const GLchar* token, const GLchar* text, std::string& string)
1607 {
1608 	const size_t text_length  = strlen(text);
1609 	const size_t token_length = strlen(token);
1610 
1611 	size_t search_position = 0;
1612 
1613 	while (1)
1614 	{
1615 		const size_t token_position = string.find(token, search_position);
1616 
1617 		if (std::string::npos == token_position)
1618 		{
1619 			break;
1620 		}
1621 
1622 		search_position = token_position + text_length;
1623 
1624 		string.replace(token_position, token_length, text, text_length);
1625 	}
1626 }
1627 
1628 /** Rounds up the value to the next power of 2.
1629  * This routine does not work for 0, see the url for explanations.
1630  *
1631  * @param value Starting point
1632  *
1633  * @return Calculated value
1634  **/
roundUpToPowerOf2(glw::GLuint value)1635 glw::GLuint roundUpToPowerOf2(glw::GLuint value)
1636 {
1637 	/* Taken from: graphics.stanford.edu/~seander/bithacks.html */
1638 	--value;
1639 
1640 	value |= value >> 1;
1641 	value |= value >> 2;
1642 	value |= value >> 4;
1643 	value |= value >> 8;
1644 	value |= value >> 16;
1645 
1646 	++value;
1647 
1648 	return value;
1649 }
1650 
1651 /** Insert elements of list into string.
1652  * List in string is represented either by token "LIST" or "SEPARATORLIST".
1653  * If SEPARATORLIST is available, than SEPARATOR is replaced with <separator>.
1654  * LIST is replaced with <element>SEPARATORLIST
1655  *
1656  * @param element         Element to be inserted
1657  * @param separator       Separator inserted between elements
1658  * @param search_position Position in string, where search for list should start
1659  * @param string          String
1660  **/
insertElementOfList(const GLchar * element,const GLchar * separator,size_t & search_position,std::string & string)1661 void insertElementOfList(const GLchar* element, const GLchar* separator, size_t& search_position, std::string& string)
1662 {
1663 	static const char* list		= g_list;
1664 	static const char* sep_list = "SEPARATORLIST";
1665 
1666 	/* Try to get "list" positions */
1667 	const size_t list_position	 = string.find(list, search_position);
1668 	const size_t sep_list_position = string.find(sep_list, search_position);
1669 
1670 	/* There is no list in string */
1671 	if (std::string::npos == list_position)
1672 	{
1673 		return;
1674 	}
1675 
1676 	if (9 /* strlen(SEPARATOR) */ == list_position - sep_list_position)
1677 	{
1678 		replaceToken("SEPARATOR", search_position, separator, string);
1679 	}
1680 
1681 	/* Save search_position */
1682 	const size_t start_position = search_position;
1683 
1684 	/* Prepare new element */
1685 	replaceToken("LIST", search_position, "ELEMENTSEPARATORLIST", string);
1686 
1687 	/* Restore search_position */
1688 	search_position = start_position;
1689 
1690 	/* Replace element and separator */
1691 	replaceToken("ELEMENT", search_position, element, string);
1692 }
1693 
1694 /** Close list in string.
1695  * If SEPARATORLIST is available, than SEPARATOR is replaced with <separator>
1696  * LIST is replaced with ""
1697  *
1698  * @param separator       Separator inserted between elements
1699  * @param search_position Position in string, where search for list should start
1700  * @param string          String
1701  **/
endList(const glw::GLchar * separator,size_t & search_position,std::string & string)1702 void endList(const glw::GLchar* separator, size_t& search_position, std::string& string)
1703 {
1704 	const size_t sep_position = string.find("SEPARATOR", search_position);
1705 	if (std::string::npos != sep_position)
1706 	{
1707 		replaceToken("SEPARATOR", search_position, separator, string);
1708 	}
1709 
1710 	replaceToken("LIST", search_position, "", string);
1711 }
1712 
1713 /* Buffer constants */
1714 const GLuint Buffer::m_invalid_id = -1;
1715 
1716 /** Constructor.
1717  *
1718  * @param context CTS context.
1719  **/
Buffer(deqp::Context & context)1720 Buffer::Buffer(deqp::Context& context) : m_id(m_invalid_id), m_buffer(Array), m_context(context)
1721 {
1722 }
1723 
1724 /** Destructor
1725  *
1726  **/
~Buffer()1727 Buffer::~Buffer()
1728 {
1729 	Release();
1730 }
1731 
1732 /** Initialize buffer instance
1733  *
1734  * @param buffer Buffer type
1735  * @param usage  Buffer usage enum
1736  * @param size   <size> parameter
1737  * @param data   <data> parameter
1738  **/
Init(BUFFERS buffer,USAGE usage,GLsizeiptr size,GLvoid * data)1739 void Buffer::Init(BUFFERS buffer, USAGE usage, GLsizeiptr size, GLvoid* data)
1740 {
1741 	/* Delete previous buffer instance */
1742 	Release();
1743 
1744 	m_buffer = buffer;
1745 
1746 	const Functions& gl = m_context.getRenderContext().getFunctions();
1747 
1748 	Generate(gl, m_id);
1749 	Bind(gl, m_id, m_buffer);
1750 	Data(gl, m_buffer, usage, size, data);
1751 }
1752 
1753 /** Release buffer instance
1754  *
1755  **/
Release()1756 void Buffer::Release()
1757 {
1758 	if (m_invalid_id != m_id)
1759 	{
1760 		const Functions& gl = m_context.getRenderContext().getFunctions();
1761 
1762 		gl.deleteBuffers(1, &m_id);
1763 		m_id = m_invalid_id;
1764 	}
1765 }
1766 
1767 /** Binds buffer to its target
1768  *
1769  **/
Bind() const1770 void Buffer::Bind() const
1771 {
1772 	const Functions& gl = m_context.getRenderContext().getFunctions();
1773 
1774 	Bind(gl, m_id, m_buffer);
1775 }
1776 
1777 /** Binds indexed buffer
1778  *
1779  * @param index <index> parameter
1780  **/
BindBase(GLuint index) const1781 void Buffer::BindBase(GLuint index) const
1782 {
1783 	const Functions& gl = m_context.getRenderContext().getFunctions();
1784 
1785 	BindBase(gl, m_id, m_buffer, index);
1786 }
1787 
1788 /** Binds range of buffer
1789  *
1790  * @param index  <index> parameter
1791  * @param offset <offset> parameter
1792  * @param size   <size> parameter
1793  **/
BindRange(GLuint index,GLintptr offset,GLsizeiptr size) const1794 void Buffer::BindRange(GLuint index, GLintptr offset, GLsizeiptr size) const
1795 {
1796 	const Functions& gl = m_context.getRenderContext().getFunctions();
1797 
1798 	BindRange(gl, m_id, m_buffer, index, offset, size);
1799 }
1800 
1801 /** Allocate memory for buffer and sends initial content
1802  *
1803  * @param usage  Buffer usage enum
1804  * @param size   <size> parameter
1805  * @param data   <data> parameter
1806  **/
Data(USAGE usage,glw::GLsizeiptr size,glw::GLvoid * data)1807 void Buffer::Data(USAGE usage, glw::GLsizeiptr size, glw::GLvoid* data)
1808 {
1809 	const Functions& gl = m_context.getRenderContext().getFunctions();
1810 
1811 	Data(gl, m_buffer, usage, size, data);
1812 }
1813 
1814 /** Maps contents of buffer into CPU space
1815  *
1816  * @param access Requested access
1817  *
1818  * @return Pointer to memory region available for CPU
1819  **/
Map(ACCESS access)1820 GLvoid* Buffer::Map(ACCESS access)
1821 {
1822 	const Functions& gl = m_context.getRenderContext().getFunctions();
1823 
1824 	return Map(gl, m_buffer, access);
1825 }
1826 
1827 /** Allocate memory for buffer and sends initial content
1828  *
1829  * @param offset Offset in buffer
1830  * @param size   <size> parameter
1831  * @param data   <data> parameter
1832  **/
SubData(glw::GLintptr offset,glw::GLsizeiptr size,glw::GLvoid * data)1833 void Buffer::SubData(glw::GLintptr offset, glw::GLsizeiptr size, glw::GLvoid* data)
1834 {
1835 	const Functions& gl = m_context.getRenderContext().getFunctions();
1836 
1837 	SubData(gl, m_buffer, offset, size, data);
1838 }
1839 
1840 /** Maps contents of buffer into CPU space
1841  **/
UnMap()1842 void Buffer::UnMap()
1843 {
1844 	const Functions& gl = m_context.getRenderContext().getFunctions();
1845 
1846 	return UnMap(gl, m_buffer);
1847 }
1848 
1849 /** Bind buffer to given target
1850  *
1851  * @param gl     GL functions
1852  * @param id     Id of buffer
1853  * @param buffer Buffer enum
1854  **/
Bind(const Functions & gl,GLuint id,BUFFERS buffer)1855 void Buffer::Bind(const Functions& gl, GLuint id, BUFFERS buffer)
1856 {
1857 	GLenum target = GetBufferGLenum(buffer);
1858 
1859 	gl.bindBuffer(target, id);
1860 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffer");
1861 }
1862 
1863 /** Binds indexed buffer
1864  *
1865  * @param gl     GL functions
1866  * @param id     Id of buffer
1867  * @param buffer Buffer enum
1868  * @param index  <index> parameter
1869  **/
BindBase(const Functions & gl,GLuint id,BUFFERS buffer,GLuint index)1870 void Buffer::BindBase(const Functions& gl, GLuint id, BUFFERS buffer, GLuint index)
1871 {
1872 	GLenum target = GetBufferGLenum(buffer);
1873 
1874 	gl.bindBufferBase(target, index, id);
1875 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindBufferBase");
1876 }
1877 
1878 /** Binds buffer range
1879  *
1880  * @param gl     GL functions
1881  * @param id     Id of buffer
1882  * @param buffer Buffer enum
1883  * @param index  <index> parameter
1884  * @param offset <offset> parameter
1885  * @param size   <size> parameter
1886  **/
BindRange(const Functions & gl,GLuint id,BUFFERS buffer,GLuint index,GLintptr offset,GLsizeiptr size)1887 void Buffer::BindRange(const Functions& gl, GLuint id, BUFFERS buffer, GLuint index, GLintptr offset, GLsizeiptr size)
1888 {
1889 	GLenum target = GetBufferGLenum(buffer);
1890 
1891 	gl.bindBufferRange(target, index, id, offset, size);
1892 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindBufferRange");
1893 }
1894 
1895 /** Allocate memory for buffer and sends initial content
1896  *
1897  * @param gl     GL functions
1898  * @param buffer Buffer enum
1899  * @param usage  Buffer usage enum
1900  * @param size   <size> parameter
1901  * @param data   <data> parameter
1902  **/
Data(const glw::Functions & gl,BUFFERS buffer,USAGE usage,glw::GLsizeiptr size,glw::GLvoid * data)1903 void Buffer::Data(const glw::Functions& gl, BUFFERS buffer, USAGE usage, glw::GLsizeiptr size, glw::GLvoid* data)
1904 {
1905 	GLenum target   = GetBufferGLenum(buffer);
1906 	GLenum gl_usage = GetUsageGLenum(usage);
1907 
1908 	gl.bufferData(target, size, data, gl_usage);
1909 	GLU_EXPECT_NO_ERROR(gl.getError(), "BufferData");
1910 }
1911 
1912 /** Allocate memory for buffer and sends initial content
1913  *
1914  * @param gl     GL functions
1915  * @param buffer Buffer enum
1916  * @param offset Offset in buffer
1917  * @param size   <size> parameter
1918  * @param data   <data> parameter
1919  **/
SubData(const glw::Functions & gl,BUFFERS buffer,glw::GLintptr offset,glw::GLsizeiptr size,glw::GLvoid * data)1920 void Buffer::SubData(const glw::Functions& gl, BUFFERS buffer, glw::GLintptr offset, glw::GLsizeiptr size,
1921 					 glw::GLvoid* data)
1922 {
1923 	GLenum target = GetBufferGLenum(buffer);
1924 
1925 	gl.bufferSubData(target, offset, size, data);
1926 	GLU_EXPECT_NO_ERROR(gl.getError(), "BufferSubData");
1927 }
1928 
1929 /** Generate buffer
1930  *
1931  * @param gl     GL functions
1932  * @param out_id Id of buffer
1933  **/
Generate(const Functions & gl,GLuint & out_id)1934 void Buffer::Generate(const Functions& gl, GLuint& out_id)
1935 {
1936 	GLuint id = m_invalid_id;
1937 
1938 	gl.genBuffers(1, &id);
1939 	GLU_EXPECT_NO_ERROR(gl.getError(), "GenBuffers");
1940 
1941 	if (m_invalid_id == id)
1942 	{
1943 		TCU_FAIL("Got invalid id");
1944 	}
1945 
1946 	out_id = id;
1947 }
1948 
1949 /** Maps buffer content
1950  *
1951  * @param gl     GL functions
1952  * @param buffer Buffer enum
1953  * @param access Access rights for mapped region
1954  *
1955  * @return Mapped memory
1956  **/
Map(const Functions & gl,BUFFERS buffer,ACCESS access)1957 void* Buffer::Map(const Functions& gl, BUFFERS buffer, ACCESS access)
1958 {
1959 	GLenum target	= GetBufferGLenum(buffer);
1960 	GLenum gl_access = GetAccessGLenum(access);
1961 
1962 	void* result = gl.mapBuffer(target, gl_access);
1963 	GLU_EXPECT_NO_ERROR(gl.getError(), "MapBuffer");
1964 
1965 	return result;
1966 }
1967 
1968 /** Unmaps buffer
1969  *
1970  **/
UnMap(const Functions & gl,BUFFERS buffer)1971 void Buffer::UnMap(const Functions& gl, BUFFERS buffer)
1972 {
1973 	GLenum target = GetBufferGLenum(buffer);
1974 
1975 	gl.unmapBuffer(target);
1976 	GLU_EXPECT_NO_ERROR(gl.getError(), "UnmapBuffer");
1977 }
1978 
1979 /** Return GLenum representation of requested access
1980  *
1981  * @param access Requested access
1982  *
1983  * @return GLenum value
1984  **/
GetAccessGLenum(ACCESS access)1985 GLenum Buffer::GetAccessGLenum(ACCESS access)
1986 {
1987 	GLenum result = 0;
1988 
1989 	switch (access)
1990 	{
1991 	case ReadOnly:
1992 		result = GL_READ_ONLY;
1993 		break;
1994 	case WriteOnly:
1995 		result = GL_WRITE_ONLY;
1996 		break;
1997 	case ReadWrite:
1998 		result = GL_READ_WRITE;
1999 		break;
2000 	default:
2001 		TCU_FAIL("Invalid enum");
2002 	}
2003 
2004 	return result;
2005 }
2006 
2007 /** Return GLenum representation of requested buffer type
2008  *
2009  * @param buffer Requested buffer type
2010  *
2011  * @return GLenum value
2012  **/
GetBufferGLenum(BUFFERS buffer)2013 GLenum Buffer::GetBufferGLenum(BUFFERS buffer)
2014 {
2015 	GLenum result = 0;
2016 
2017 	switch (buffer)
2018 	{
2019 	case Array:
2020 		result = GL_ARRAY_BUFFER;
2021 		break;
2022 	case Element:
2023 		result = GL_ELEMENT_ARRAY_BUFFER;
2024 		break;
2025 	case Shader_Storage:
2026 		result = GL_SHADER_STORAGE_BUFFER;
2027 		break;
2028 	case Texture:
2029 		result = GL_TEXTURE_BUFFER;
2030 		break;
2031 	case Transform_feedback:
2032 		result = GL_TRANSFORM_FEEDBACK_BUFFER;
2033 		break;
2034 	case Uniform:
2035 		result = GL_UNIFORM_BUFFER;
2036 		break;
2037 	default:
2038 		TCU_FAIL("Invalid enum");
2039 	}
2040 
2041 	return result;
2042 }
2043 
2044 /** Return GLenum representation of requested usage
2045  *
2046  * @param usage Requested usage
2047  *
2048  * @return GLenum value
2049  **/
GetUsageGLenum(USAGE usage)2050 GLenum Buffer::GetUsageGLenum(USAGE usage)
2051 {
2052 	GLenum result = 0;
2053 
2054 	switch (usage)
2055 	{
2056 	case DynamicCopy:
2057 		result = GL_DYNAMIC_COPY;
2058 		break;
2059 	case DynamicDraw:
2060 		result = GL_DYNAMIC_DRAW;
2061 		break;
2062 	case DynamicRead:
2063 		result = GL_DYNAMIC_READ;
2064 		break;
2065 	case StaticCopy:
2066 		result = GL_STATIC_COPY;
2067 		break;
2068 	case StaticDraw:
2069 		result = GL_STATIC_DRAW;
2070 		break;
2071 	case StaticRead:
2072 		result = GL_STATIC_READ;
2073 		break;
2074 	case StreamCopy:
2075 		result = GL_STREAM_COPY;
2076 		break;
2077 	case StreamDraw:
2078 		result = GL_STREAM_DRAW;
2079 		break;
2080 	case StreamRead:
2081 		result = GL_STREAM_READ;
2082 		break;
2083 	default:
2084 		TCU_FAIL("Invalid enum");
2085 	}
2086 
2087 	return result;
2088 }
2089 
2090 /** Returns name of buffer target
2091  *
2092  * @param buffer Target enum
2093  *
2094  * @return Name of target
2095  **/
GetBufferName(BUFFERS buffer)2096 const GLchar* Buffer::GetBufferName(BUFFERS buffer)
2097 {
2098 	const GLchar* name = 0;
2099 
2100 	switch (buffer)
2101 	{
2102 	case Array:
2103 		name = "Array";
2104 		break;
2105 	case Element:
2106 		name = "Element";
2107 		break;
2108 	case Shader_Storage:
2109 		name = "Shader_Storage";
2110 		break;
2111 	case Texture:
2112 		name = "Texture";
2113 		break;
2114 	case Transform_feedback:
2115 		name = "Transform_feedback";
2116 		break;
2117 	case Uniform:
2118 		name = "Uniform";
2119 		break;
2120 	default:
2121 		TCU_FAIL("Invalid enum");
2122 	}
2123 
2124 	return name;
2125 }
2126 
2127 /* Framebuffer constants */
2128 const GLuint Framebuffer::m_invalid_id = -1;
2129 
2130 /** Constructor
2131  *
2132  * @param context CTS context
2133  **/
Framebuffer(deqp::Context & context)2134 Framebuffer::Framebuffer(deqp::Context& context) : m_id(m_invalid_id), m_context(context)
2135 {
2136 	/* Nothing to be done here */
2137 }
2138 
2139 /** Destructor
2140  *
2141  **/
~Framebuffer()2142 Framebuffer::~Framebuffer()
2143 {
2144 	Release();
2145 }
2146 
2147 /** Initialize framebuffer instance
2148  *
2149  **/
Init()2150 void Framebuffer::Init()
2151 {
2152 	/* Delete previous instance */
2153 	Release();
2154 
2155 	const Functions& gl = m_context.getRenderContext().getFunctions();
2156 
2157 	Generate(gl, m_id);
2158 }
2159 
2160 /** Release framebuffer instance
2161  *
2162  **/
Release()2163 void Framebuffer::Release()
2164 {
2165 	if (m_invalid_id != m_id)
2166 	{
2167 		const Functions& gl = m_context.getRenderContext().getFunctions();
2168 
2169 		gl.deleteFramebuffers(1, &m_id);
2170 		m_id = m_invalid_id;
2171 	}
2172 }
2173 
2174 /** Attach texture to specified attachment
2175  *
2176  * @param attachment Attachment
2177  * @param texture_id Texture id
2178  * @param width      Texture width
2179  * @param height     Texture height
2180  **/
AttachTexture(GLenum attachment,GLuint texture_id,GLuint width,GLuint height)2181 void Framebuffer::AttachTexture(GLenum attachment, GLuint texture_id, GLuint width, GLuint height)
2182 {
2183 	const Functions& gl = m_context.getRenderContext().getFunctions();
2184 
2185 	AttachTexture(gl, attachment, texture_id, width, height);
2186 }
2187 
2188 /** Binds framebuffer to DRAW_FRAMEBUFFER
2189  *
2190  **/
Bind()2191 void Framebuffer::Bind()
2192 {
2193 	const Functions& gl = m_context.getRenderContext().getFunctions();
2194 
2195 	Bind(gl, m_id);
2196 }
2197 
2198 /** Clear framebuffer
2199  *
2200  * @param mask <mask> parameter of glClear. Decides which shall be cleared
2201  **/
Clear(GLenum mask)2202 void Framebuffer::Clear(GLenum mask)
2203 {
2204 	const Functions& gl = m_context.getRenderContext().getFunctions();
2205 
2206 	Clear(gl, mask);
2207 }
2208 
2209 /** Specifies clear color
2210  *
2211  * @param red   Red channel
2212  * @param green Green channel
2213  * @param blue  Blue channel
2214  * @param alpha Alpha channel
2215  **/
ClearColor(GLfloat red,GLfloat green,GLfloat blue,GLfloat alpha)2216 void Framebuffer::ClearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
2217 {
2218 	const Functions& gl = m_context.getRenderContext().getFunctions();
2219 
2220 	ClearColor(gl, red, green, blue, alpha);
2221 }
2222 
2223 /** Attach texture to specified attachment
2224  *
2225  * @param gl         GL functions
2226  * @param attachment Attachment
2227  * @param texture_id Texture id
2228  * @param width      Texture width
2229  * @param height     Texture height
2230  **/
AttachTexture(const Functions & gl,GLenum attachment,GLuint texture_id,GLuint width,GLuint height)2231 void Framebuffer::AttachTexture(const Functions& gl, GLenum attachment, GLuint texture_id, GLuint width, GLuint height)
2232 {
2233 	gl.framebufferTexture(GL_DRAW_FRAMEBUFFER, attachment, texture_id, 0 /* level */);
2234 	GLU_EXPECT_NO_ERROR(gl.getError(), "FramebufferTexture");
2235 
2236 	gl.viewport(0 /* x */, 0 /* y */, width, height);
2237 	GLU_EXPECT_NO_ERROR(gl.getError(), "Viewport");
2238 }
2239 
2240 /** Binds framebuffer to DRAW_FRAMEBUFFER
2241  *
2242  * @param gl GL functions
2243  * @param id ID of framebuffer
2244  **/
Bind(const Functions & gl,GLuint id)2245 void Framebuffer::Bind(const Functions& gl, GLuint id)
2246 {
2247 	gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, id);
2248 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer");
2249 }
2250 
2251 /** Clear framebuffer
2252  *
2253  * @param gl   GL functions
2254  * @param mask <mask> parameter of glClear. Decides which shall be cleared
2255  **/
Clear(const Functions & gl,GLenum mask)2256 void Framebuffer::Clear(const Functions& gl, GLenum mask)
2257 {
2258 	gl.clear(mask);
2259 	GLU_EXPECT_NO_ERROR(gl.getError(), "Clear");
2260 }
2261 
2262 /** Specifies clear color
2263  *
2264  * @param gl    GL functions
2265  * @param red   Red channel
2266  * @param green Green channel
2267  * @param blue  Blue channel
2268  * @param alpha Alpha channel
2269  **/
ClearColor(const Functions & gl,GLfloat red,GLfloat green,GLfloat blue,GLfloat alpha)2270 void Framebuffer::ClearColor(const Functions& gl, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
2271 {
2272 	gl.clearColor(red, green, blue, alpha);
2273 	GLU_EXPECT_NO_ERROR(gl.getError(), "ClearColor");
2274 }
2275 
2276 /** Generate framebuffer
2277  *
2278  **/
Generate(const Functions & gl,GLuint & out_id)2279 void Framebuffer::Generate(const Functions& gl, GLuint& out_id)
2280 {
2281 	GLuint id = m_invalid_id;
2282 
2283 	gl.genFramebuffers(1, &id);
2284 	GLU_EXPECT_NO_ERROR(gl.getError(), "GenFramebuffers");
2285 
2286 	if (m_invalid_id == id)
2287 	{
2288 		TCU_FAIL("Invalid id");
2289 	}
2290 
2291 	out_id = id;
2292 }
2293 
2294 /* Shader's constants */
2295 const GLuint Shader::m_invalid_id = 0;
2296 
2297 /** Constructor.
2298  *
2299  * @param context CTS context.
2300  **/
Shader(deqp::Context & context)2301 Shader::Shader(deqp::Context& context) : m_id(m_invalid_id), m_context(context)
2302 {
2303 	/* Nothing to be done here */
2304 }
2305 
2306 /** Destructor
2307  *
2308  **/
~Shader()2309 Shader::~Shader()
2310 {
2311 	Release();
2312 }
2313 
2314 /** Initialize shader instance
2315  *
2316  * @param stage  Shader stage
2317  * @param source Source code
2318  **/
Init(STAGES stage,const std::string & source)2319 void Shader::Init(STAGES stage, const std::string& source)
2320 {
2321 	if (true == source.empty())
2322 	{
2323 		/* No source == no shader */
2324 		return;
2325 	}
2326 
2327 	/* Delete any previous shader */
2328 	Release();
2329 
2330 	/* Create, set source and compile */
2331 	const Functions& gl = m_context.getRenderContext().getFunctions();
2332 
2333 	Create(gl, stage, m_id);
2334 	Source(gl, m_id, source);
2335 
2336 	try
2337 	{
2338 		Compile(gl, m_id);
2339 	}
2340 	catch (const CompilationException& exc)
2341 	{
2342 		throw InvalidSourceException(exc.what(), source, stage);
2343 	}
2344 }
2345 
2346 /** Release shader instance
2347  *
2348  **/
Release()2349 void Shader::Release()
2350 {
2351 	if (m_invalid_id != m_id)
2352 	{
2353 		const Functions& gl = m_context.getRenderContext().getFunctions();
2354 
2355 		gl.deleteShader(m_id);
2356 		m_id = m_invalid_id;
2357 	}
2358 }
2359 
2360 /** Compile shader
2361  *
2362  * @param gl GL functions
2363  * @param id Shader id
2364  **/
Compile(const Functions & gl,GLuint id)2365 void Shader::Compile(const Functions& gl, GLuint id)
2366 {
2367 	GLint status = GL_FALSE;
2368 
2369 	/* Compile */
2370 	gl.compileShader(id);
2371 	GLU_EXPECT_NO_ERROR(gl.getError(), "CompileShader");
2372 
2373 	/* Get compilation status */
2374 	gl.getShaderiv(id, GL_COMPILE_STATUS, &status);
2375 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");
2376 
2377 	/* Log compilation error */
2378 	if (GL_TRUE != status)
2379 	{
2380 		glw::GLint  length = 0;
2381 		std::string message;
2382 
2383 		/* Error log length */
2384 		gl.getShaderiv(id, GL_INFO_LOG_LENGTH, &length);
2385 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");
2386 
2387 		/* Prepare storage */
2388 		message.resize(length, 0);
2389 
2390 		/* Get error log */
2391 		gl.getShaderInfoLog(id, length, 0, &message[0]);
2392 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderInfoLog");
2393 
2394 		throw CompilationException(message.c_str());
2395 	}
2396 }
2397 
2398 /** Create shader
2399  *
2400  * @param gl     GL functions
2401  * @param stage  Shader stage
2402  * @param out_id Shader id
2403  **/
Create(const Functions & gl,STAGES stage,GLuint & out_id)2404 void Shader::Create(const Functions& gl, STAGES stage, GLuint& out_id)
2405 {
2406 	const GLenum shaderType = GetShaderStageGLenum(stage);
2407 	const GLuint id			= gl.createShader(shaderType);
2408 	GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
2409 
2410 	if (m_invalid_id == id)
2411 	{
2412 		TCU_FAIL("Failed to create shader");
2413 	}
2414 
2415 	out_id = id;
2416 }
2417 
2418 /** Set shader's source code
2419  *
2420  * @param gl     GL functions
2421  * @param id     Shader id
2422  * @param source Shader source code
2423  **/
Source(const Functions & gl,GLuint id,const std::string & source)2424 void Shader::Source(const Functions& gl, GLuint id, const std::string& source)
2425 {
2426 	const GLchar* code = source.c_str();
2427 
2428 	gl.shaderSource(id, 1 /* count */, &code, 0 /* lengths */);
2429 	GLU_EXPECT_NO_ERROR(gl.getError(), "ShaderSource");
2430 }
2431 
2432 /** Get GLenum repesenting shader stage
2433  *
2434  * @param stage Shader stage
2435  *
2436  * @return GLenum
2437  **/
GetShaderStageGLenum(STAGES stage)2438 GLenum Shader::GetShaderStageGLenum(STAGES stage)
2439 {
2440 	GLenum result = 0;
2441 
2442 	switch (stage)
2443 	{
2444 	case COMPUTE:
2445 		result = GL_COMPUTE_SHADER;
2446 		break;
2447 	case FRAGMENT:
2448 		result = GL_FRAGMENT_SHADER;
2449 		break;
2450 	case GEOMETRY:
2451 		result = GL_GEOMETRY_SHADER;
2452 		break;
2453 	case TESS_CTRL:
2454 		result = GL_TESS_CONTROL_SHADER;
2455 		break;
2456 	case TESS_EVAL:
2457 		result = GL_TESS_EVALUATION_SHADER;
2458 		break;
2459 	case VERTEX:
2460 		result = GL_VERTEX_SHADER;
2461 		break;
2462 	default:
2463 		TCU_FAIL("Invalid enum");
2464 	}
2465 
2466 	return result;
2467 }
2468 
2469 /** Get string representing name of shader stage
2470  *
2471  * @param stage Shader stage
2472  *
2473  * @return String with name of shader stage
2474  **/
GetStageName(STAGES stage)2475 const glw::GLchar* Shader::GetStageName(STAGES stage)
2476 {
2477 	const GLchar* result = 0;
2478 
2479 	switch (stage)
2480 	{
2481 	case COMPUTE:
2482 		result = "compute";
2483 		break;
2484 	case VERTEX:
2485 		result = "vertex";
2486 		break;
2487 	case TESS_CTRL:
2488 		result = "tessellation control";
2489 		break;
2490 	case TESS_EVAL:
2491 		result = "tessellation evaluation";
2492 		break;
2493 	case GEOMETRY:
2494 		result = "geometry";
2495 		break;
2496 	case FRAGMENT:
2497 		result = "fragment";
2498 		break;
2499 	default:
2500 		TCU_FAIL("Invalid enum");
2501 	}
2502 
2503 	return result;
2504 }
2505 
2506 /** Logs shader source
2507  *
2508  * @param context CTS context
2509  * @param source  Source of shader
2510  * @param stage   Shader stage
2511  **/
LogSource(deqp::Context & context,const std::string & source,STAGES stage)2512 void Shader::LogSource(deqp::Context& context, const std::string& source, STAGES stage)
2513 {
2514 	/* Skip empty shaders */
2515 	if (true == source.empty())
2516 	{
2517 		return;
2518 	}
2519 
2520 	context.getTestContext().getLog() << tcu::TestLog::Message
2521 									  << "Shader source. Stage: " << Shader::GetStageName(stage)
2522 									  << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(source);
2523 }
2524 
2525 /** Constructor
2526  *
2527  * @param message Compilation error message
2528  **/
CompilationException(const GLchar * message)2529 Shader::CompilationException::CompilationException(const GLchar* message)
2530 {
2531 	m_message = message;
2532 }
2533 
2534 /** Returns error messages
2535  *
2536  * @return Compilation error message
2537  **/
what() const2538 const char* Shader::CompilationException::what() const throw()
2539 {
2540 	return m_message.c_str();
2541 }
2542 
2543 /** Constructor
2544  *
2545  * @param message Compilation error message
2546  **/
InvalidSourceException(const GLchar * error_message,const std::string & source,STAGES stage)2547 Shader::InvalidSourceException::InvalidSourceException(const GLchar* error_message, const std::string& source,
2548 													   STAGES stage)
2549 	: m_message(error_message), m_source(source), m_stage(stage)
2550 {
2551 }
2552 
2553 /** Returns error messages
2554  *
2555  * @return Compilation error message
2556  **/
what() const2557 const char* Shader::InvalidSourceException::what() const throw()
2558 {
2559 	return "Compilation error";
2560 }
2561 
2562 /** Logs error message and shader sources **/
log(deqp::Context & context) const2563 void Shader::InvalidSourceException::log(deqp::Context& context) const
2564 {
2565 	context.getTestContext().getLog() << tcu::TestLog::Message << "Failed to compile shader: " << m_message.c_str()
2566 									  << tcu::TestLog::EndMessage;
2567 
2568 	LogSource(context, m_source, m_stage);
2569 }
2570 
2571 /* Program constants */
2572 const GLuint Pipeline::m_invalid_id = 0;
2573 
2574 /** Constructor.
2575  *
2576  * @param context CTS context.
2577  **/
Pipeline(deqp::Context & context)2578 Pipeline::Pipeline(deqp::Context& context) : m_id(m_invalid_id), m_context(context)
2579 {
2580 	/* Nothing to be done here */
2581 }
2582 
2583 /** Destructor
2584  *
2585  **/
~Pipeline()2586 Pipeline::~Pipeline()
2587 {
2588 	Release();
2589 }
2590 
2591 /** Initialize pipline object
2592  *
2593  **/
Init()2594 void Pipeline::Init()
2595 {
2596 	Release();
2597 
2598 	const Functions& gl = m_context.getRenderContext().getFunctions();
2599 
2600 	/* Generate */
2601 	gl.genProgramPipelines(1, &m_id);
2602 	GLU_EXPECT_NO_ERROR(gl.getError(), "GenProgramPipelines");
2603 }
2604 
2605 /** Release pipeline object
2606  *
2607  **/
Release()2608 void Pipeline::Release()
2609 {
2610 	if (m_invalid_id != m_id)
2611 	{
2612 		const Functions& gl = m_context.getRenderContext().getFunctions();
2613 
2614 		/* Generate */
2615 		gl.deleteProgramPipelines(1, &m_id);
2616 		GLU_EXPECT_NO_ERROR(gl.getError(), "DeleteProgramPipelines");
2617 
2618 		m_id = m_invalid_id;
2619 	}
2620 }
2621 
2622 /** Bind pipeline
2623  *
2624  **/
Bind()2625 void Pipeline::Bind()
2626 {
2627 	const Functions& gl = m_context.getRenderContext().getFunctions();
2628 
2629 	Bind(gl, m_id);
2630 }
2631 
2632 /** Set which stages should be active
2633  *
2634  * @param program_id Id of program
2635  * @param stages     Logical combination of enums representing stages
2636  **/
UseProgramStages(GLuint program_id,GLenum stages)2637 void Pipeline::UseProgramStages(GLuint program_id, GLenum stages)
2638 {
2639 	const Functions& gl = m_context.getRenderContext().getFunctions();
2640 
2641 	UseProgramStages(gl, m_id, program_id, stages);
2642 }
2643 
2644 /** Bind pipeline
2645  *
2646  * @param gl Functiions
2647  * @param id Pipeline id
2648  **/
Bind(const Functions & gl,GLuint id)2649 void Pipeline::Bind(const Functions& gl, GLuint id)
2650 {
2651 	gl.bindProgramPipeline(id);
2652 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindProgramPipeline");
2653 }
2654 
2655 /** Set which stages should be active
2656  *
2657  * @param gl         Functiions
2658  * @param id         Pipeline id
2659  * @param program_id Id of program
2660  * @param stages     Logical combination of enums representing stages
2661  **/
UseProgramStages(const Functions & gl,GLuint id,GLuint program_id,GLenum stages)2662 void Pipeline::UseProgramStages(const Functions& gl, GLuint id, GLuint program_id, GLenum stages)
2663 {
2664 	gl.useProgramStages(id, stages, program_id);
2665 	GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgramStages");
2666 }
2667 
2668 /* Program constants */
2669 const GLuint Program::m_invalid_id = 0;
2670 
2671 /** Constructor.
2672  *
2673  * @param context CTS context.
2674  **/
Program(deqp::Context & context)2675 Program::Program(deqp::Context& context)
2676 	: m_id(m_invalid_id)
2677 	, m_compute(context)
2678 	, m_fragment(context)
2679 	, m_geometry(context)
2680 	, m_tess_ctrl(context)
2681 	, m_tess_eval(context)
2682 	, m_vertex(context)
2683 	, m_context(context)
2684 {
2685 	/* Nothing to be done here */
2686 }
2687 
2688 /** Destructor
2689  *
2690  **/
~Program()2691 Program::~Program()
2692 {
2693 	Release();
2694 }
2695 
2696 /** Initialize program instance
2697  *
2698  * @param compute_shader                    Compute shader source code
2699  * @param fragment_shader                   Fragment shader source code
2700  * @param geometry_shader                   Geometry shader source code
2701  * @param tessellation_control_shader       Tessellation control shader source code
2702  * @param tessellation_evaluation_shader    Tessellation evaluation shader source code
2703  * @param vertex_shader                     Vertex shader source code
2704  * @param captured_varyings                 Vector of variables to be captured with transfrom feedback
2705  * @param capture_interleaved               Select mode of transform feedback (separate or interleaved)
2706  * @param is_separable                      Selects if monolithic or separable program should be built. Defaults to false
2707  **/
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)2708 void Program::Init(const std::string& compute_shader, const std::string& fragment_shader,
2709 				   const std::string& geometry_shader, const std::string& tessellation_control_shader,
2710 				   const std::string& tessellation_evaluation_shader, const std::string& vertex_shader,
2711 				   const NameVector& captured_varyings, bool capture_interleaved, bool is_separable)
2712 {
2713 	/* Delete previous program */
2714 	Release();
2715 
2716 	/* GL entry points */
2717 	const Functions& gl = m_context.getRenderContext().getFunctions();
2718 
2719 	/* Initialize shaders */
2720 	m_compute.Init(Shader::COMPUTE, compute_shader);
2721 	m_fragment.Init(Shader::FRAGMENT, fragment_shader);
2722 	m_geometry.Init(Shader::GEOMETRY, geometry_shader);
2723 	m_tess_ctrl.Init(Shader::TESS_CTRL, tessellation_control_shader);
2724 	m_tess_eval.Init(Shader::TESS_EVAL, tessellation_evaluation_shader);
2725 	m_vertex.Init(Shader::VERTEX, vertex_shader);
2726 
2727 	/* Create program, set up transform feedback and attach shaders */
2728 	Create(gl, m_id);
2729 	Capture(gl, m_id, captured_varyings, capture_interleaved);
2730 	Attach(gl, m_id, m_compute.m_id);
2731 	Attach(gl, m_id, m_fragment.m_id);
2732 	Attach(gl, m_id, m_geometry.m_id);
2733 	Attach(gl, m_id, m_tess_ctrl.m_id);
2734 	Attach(gl, m_id, m_tess_eval.m_id);
2735 	Attach(gl, m_id, m_vertex.m_id);
2736 
2737 	/* Set separable parameter */
2738 	if (true == is_separable)
2739 	{
2740 		gl.programParameteri(m_id, GL_PROGRAM_SEPARABLE, GL_TRUE);
2741 		GLU_EXPECT_NO_ERROR(gl.getError(), "ProgramParameteri");
2742 	}
2743 
2744 	try
2745 	{
2746 		/* Link program */
2747 		Link(gl, m_id);
2748 	}
2749 	catch (const LinkageException& exc)
2750 	{
2751 		throw BuildException(exc.what(), compute_shader, fragment_shader, geometry_shader, tessellation_control_shader,
2752 							 tessellation_evaluation_shader, vertex_shader);
2753 	}
2754 }
2755 
2756 /** Initialize program instance
2757  *
2758  * @param compute_shader                    Compute shader source code
2759  * @param fragment_shader                   Fragment shader source code
2760  * @param geometry_shader                   Geometry shader source code
2761  * @param tessellation_control_shader       Tessellation control shader source code
2762  * @param tessellation_evaluation_shader    Tessellation evaluation shader source code
2763  * @param vertex_shader                     Vertex shader source code
2764  * @param is_separable                      Selects if monolithic or separable program should be built. Defaults to false
2765  **/
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)2766 void Program::Init(const std::string& compute_shader, const std::string& fragment_shader,
2767 				   const std::string& geometry_shader, const std::string& tessellation_control_shader,
2768 				   const std::string& tessellation_evaluation_shader, const std::string& vertex_shader,
2769 				   bool is_separable)
2770 {
2771 	NameVector captured_varying;
2772 
2773 	Init(compute_shader, fragment_shader, geometry_shader, tessellation_control_shader, tessellation_evaluation_shader,
2774 		 vertex_shader, captured_varying, true, is_separable);
2775 }
2776 
2777 /** Release program instance
2778  *
2779  **/
Release()2780 void Program::Release()
2781 {
2782 	const Functions& gl = m_context.getRenderContext().getFunctions();
2783 
2784 	if (m_invalid_id != m_id)
2785 	{
2786 		Use(gl, m_invalid_id);
2787 
2788 		gl.deleteProgram(m_id);
2789 		m_id = m_invalid_id;
2790 	}
2791 
2792 	m_compute.Release();
2793 	m_fragment.Release();
2794 	m_geometry.Release();
2795 	m_tess_ctrl.Release();
2796 	m_tess_eval.Release();
2797 	m_vertex.Release();
2798 }
2799 
2800 /** Get <pname> for a set of active uniforms
2801  *
2802  * @param count   Number of indices
2803  * @param indices Indices of uniforms
2804  * @param pname   Queired pname
2805  * @param params  Array that will be filled with values of parameters
2806  **/
GetActiveUniformsiv(GLsizei count,const GLuint * indices,GLenum pname,GLint * params) const2807 void Program::GetActiveUniformsiv(GLsizei count, const GLuint* indices, GLenum pname, GLint* params) const
2808 {
2809 	const Functions& gl = m_context.getRenderContext().getFunctions();
2810 
2811 	GetActiveUniformsiv(gl, m_id, count, indices, pname, params);
2812 }
2813 
2814 /** Get location of attribute
2815  *
2816  * @param name Name of attribute
2817  *
2818  * @return Result of query
2819  **/
GetAttribLocation(const std::string & name) const2820 glw::GLint Program::GetAttribLocation(const std::string& name) const
2821 {
2822 	const Functions& gl = m_context.getRenderContext().getFunctions();
2823 
2824 	return GetAttribLocation(gl, m_id, name);
2825 }
2826 
2827 /** Query resource
2828  *
2829  * @param interface Interface to be queried
2830  * @param index     Index of resource
2831  * @param property  Property to be queried
2832  * @param buf_size  Size of <params> buffer
2833  * @param params    Results of query
2834  **/
GetResource(GLenum interface,GLuint index,GLenum property,GLsizei buf_size,GLint * params) const2835 void Program::GetResource(GLenum interface, GLuint index, GLenum property, GLsizei buf_size, GLint* params) const
2836 {
2837 	const Functions& gl = m_context.getRenderContext().getFunctions();
2838 
2839 	GetResource(gl, m_id, interface, index, property, buf_size, params);
2840 }
2841 
2842 /** Query for index of resource
2843  *
2844  * @param name      Name of resource
2845  * @param interface Interface to be queried
2846  *
2847  * @return Result of query
2848  **/
GetResourceIndex(const std::string & name,GLenum interface) const2849 glw::GLuint Program::GetResourceIndex(const std::string& name, GLenum interface) const
2850 {
2851 	const Functions& gl = m_context.getRenderContext().getFunctions();
2852 
2853 	return GetResourceIndex(gl, m_id, name, interface);
2854 }
2855 
2856 /** Get indices for a set of uniforms
2857  *
2858  * @param count   Count number of uniforms
2859  * @param names   Names of uniforms
2860  * @param indices Buffer that will be filled with indices
2861  **/
GetUniformIndices(GLsizei count,const GLchar ** names,GLuint * indices) const2862 void Program::GetUniformIndices(GLsizei count, const GLchar** names, GLuint* indices) const
2863 {
2864 	const Functions& gl = m_context.getRenderContext().getFunctions();
2865 
2866 	GetUniformIndices(gl, m_id, count, names, indices);
2867 }
2868 
2869 /** Get uniform location
2870  *
2871  * @param name Name of uniform
2872  *
2873  * @return Results of query
2874  **/
GetUniformLocation(const std::string & name) const2875 glw::GLint Program::GetUniformLocation(const std::string& name) const
2876 {
2877 	const Functions& gl = m_context.getRenderContext().getFunctions();
2878 
2879 	return GetUniformLocation(gl, m_id, name);
2880 }
2881 
2882 /** Set program as active
2883  *
2884  **/
Use() const2885 void Program::Use() const
2886 {
2887 	const Functions& gl = m_context.getRenderContext().getFunctions();
2888 
2889 	Use(gl, m_id);
2890 }
2891 
2892 /** Attach shader to program
2893  *
2894  * @param gl         GL functions
2895  * @param program_id Id of program
2896  * @param shader_id  Id of shader
2897  **/
Attach(const Functions & gl,GLuint program_id,GLuint shader_id)2898 void Program::Attach(const Functions& gl, GLuint program_id, GLuint shader_id)
2899 {
2900 	/* Sanity checks */
2901 	if ((m_invalid_id == program_id) || (Shader::m_invalid_id == shader_id))
2902 	{
2903 		return;
2904 	}
2905 
2906 	gl.attachShader(program_id, shader_id);
2907 	GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
2908 }
2909 
2910 /** Set up captured varyings
2911  *
2912  * @param gl                  GL functions
2913  * @param id                  Id of program
2914  * @param captured_varyings   Vector of varyings
2915  * @param capture_interleaved Selects if interleaved or separate mode should be used
2916  **/
Capture(const Functions & gl,GLuint id,const NameVector & captured_varyings,bool capture_interleaved)2917 void Program::Capture(const Functions& gl, GLuint id, const NameVector& captured_varyings, bool capture_interleaved)
2918 {
2919 	const size_t n_varyings = captured_varyings.size();
2920 
2921 	if (0 == n_varyings)
2922 	{
2923 		/* empty list, skip */
2924 		return;
2925 	}
2926 
2927 	std::vector<const GLchar*> varying_names;
2928 	varying_names.resize(n_varyings);
2929 
2930 	for (size_t i = 0; i < n_varyings; ++i)
2931 	{
2932 		varying_names[i] = captured_varyings[i].c_str();
2933 	}
2934 
2935 	GLenum mode = 0;
2936 	if (true == capture_interleaved)
2937 	{
2938 		mode = GL_INTERLEAVED_ATTRIBS;
2939 	}
2940 	else
2941 	{
2942 		mode = GL_SEPARATE_ATTRIBS;
2943 	}
2944 
2945 	gl.transformFeedbackVaryings(id, static_cast<GLsizei>(n_varyings), &varying_names[0], mode);
2946 	GLU_EXPECT_NO_ERROR(gl.getError(), "TransformFeedbackVaryings");
2947 }
2948 
2949 /** Create program instance
2950  *
2951  * @param gl     GL functions
2952  * @param out_id Id of program
2953  **/
Create(const Functions & gl,GLuint & out_id)2954 void Program::Create(const Functions& gl, GLuint& out_id)
2955 {
2956 	const GLuint id = gl.createProgram();
2957 	GLU_EXPECT_NO_ERROR(gl.getError(), "CreateProgram");
2958 
2959 	if (m_invalid_id == id)
2960 	{
2961 		TCU_FAIL("Failed to create program");
2962 	}
2963 
2964 	out_id = id;
2965 }
2966 
2967 /** Get <pname> for a set of active uniforms
2968  *
2969  * @param gl         Functions
2970  * @param program_id Id of program
2971  * @param count      Number of indices
2972  * @param indices    Indices of uniforms
2973  * @param pname      Queired pname
2974  * @param params     Array that will be filled with values of parameters
2975  **/
GetActiveUniformsiv(const Functions & gl,GLuint program_id,GLsizei count,const GLuint * indices,GLenum pname,GLint * params)2976 void Program::GetActiveUniformsiv(const Functions& gl, GLuint program_id, GLsizei count, const GLuint* indices,
2977 								  GLenum pname, GLint* params)
2978 {
2979 	gl.getActiveUniformsiv(program_id, count, indices, pname, params);
2980 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetActiveUniformsiv");
2981 }
2982 
2983 /** Get indices for a set of uniforms
2984  *
2985  * @param gl         Functions
2986  * @param program_id Id of program
2987  * @param count      Count number of uniforms
2988  * @param names      Names of uniforms
2989  * @param indices    Buffer that will be filled with indices
2990  **/
GetUniformIndices(const Functions & gl,GLuint program_id,GLsizei count,const GLchar ** names,GLuint * indices)2991 void Program::GetUniformIndices(const Functions& gl, GLuint program_id, GLsizei count, const GLchar** names,
2992 								GLuint* indices)
2993 {
2994 	gl.getUniformIndices(program_id, count, names, indices);
2995 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformIndices");
2996 }
2997 
2998 /** Link program
2999  *
3000  * @param gl GL functions
3001  * @param id Id of program
3002  **/
Link(const Functions & gl,GLuint id)3003 void Program::Link(const Functions& gl, GLuint id)
3004 {
3005 	GLint status = GL_FALSE;
3006 
3007 	gl.linkProgram(id);
3008 	GLU_EXPECT_NO_ERROR(gl.getError(), "LinkProgram");
3009 
3010 	/* Get link status */
3011 	gl.getProgramiv(id, GL_LINK_STATUS, &status);
3012 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");
3013 
3014 	/* Log link error */
3015 	if (GL_TRUE != status)
3016 	{
3017 		glw::GLint  length = 0;
3018 		std::string message;
3019 
3020 		/* Get error log length */
3021 		gl.getProgramiv(id, GL_INFO_LOG_LENGTH, &length);
3022 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");
3023 
3024 		message.resize(length, 0);
3025 
3026 		/* Get error log */
3027 		gl.getProgramInfoLog(id, length, 0, &message[0]);
3028 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramInfoLog");
3029 
3030 		throw LinkageException(message.c_str());
3031 	}
3032 }
3033 
3034 /** Set generic uniform
3035  *
3036  * @param gl       Functions
3037  * @param type     Type of uniform
3038  * @param count    Length of array
3039  * @param location Location of uniform
3040  * @param data     Data that will be used
3041  **/
Uniform(const Functions & gl,const Type & type,GLsizei count,GLint location,const GLvoid * data)3042 void Program::Uniform(const Functions& gl, const Type& type, GLsizei count, GLint location, const GLvoid* data)
3043 {
3044 	if (-1 == location)
3045 	{
3046 		TCU_FAIL("Uniform is inactive");
3047 	}
3048 
3049 	switch (type.m_basic_type)
3050 	{
3051 	case Type::Double:
3052 		if (1 == type.m_n_columns)
3053 		{
3054 			getUniformNdv(gl, type.m_n_rows)(location, count, (const GLdouble*)data);
3055 			GLU_EXPECT_NO_ERROR(gl.getError(), "UniformNdv");
3056 		}
3057 		else
3058 		{
3059 			getUniformMatrixNdv(gl, type.m_n_columns, type.m_n_rows)(location, count, false, (const GLdouble*)data);
3060 			GLU_EXPECT_NO_ERROR(gl.getError(), "UniformMatrixNdv");
3061 		}
3062 		break;
3063 	case Type::Float:
3064 		if (1 == type.m_n_columns)
3065 		{
3066 			getUniformNfv(gl, type.m_n_rows)(location, count, (const GLfloat*)data);
3067 			GLU_EXPECT_NO_ERROR(gl.getError(), "UniformNfv");
3068 		}
3069 		else
3070 		{
3071 			getUniformMatrixNfv(gl, type.m_n_columns, type.m_n_rows)(location, count, false, (const GLfloat*)data);
3072 			GLU_EXPECT_NO_ERROR(gl.getError(), "UniformMatrixNfv");
3073 		}
3074 		break;
3075 	case Type::Int:
3076 		getUniformNiv(gl, type.m_n_rows)(location, count, (const GLint*)data);
3077 		GLU_EXPECT_NO_ERROR(gl.getError(), "UniformNiv");
3078 		break;
3079 	case Type::Uint:
3080 		getUniformNuiv(gl, type.m_n_rows)(location, count, (const GLuint*)data);
3081 		GLU_EXPECT_NO_ERROR(gl.getError(), "UniformNuiv");
3082 		break;
3083 	default:
3084 		TCU_FAIL("Invalid enum");
3085 	}
3086 }
3087 
3088 /** Use program
3089  *
3090  * @param gl GL functions
3091  * @param id Id of program
3092  **/
Use(const Functions & gl,GLuint id)3093 void Program::Use(const Functions& gl, GLuint id)
3094 {
3095 	gl.useProgram(id);
3096 	GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram");
3097 }
3098 
3099 /** Get location of attribute
3100  *
3101  * @param gl   GL functions
3102  * @param id   Id of program
3103  * @param name Name of attribute
3104  *
3105  * @return Location of attribute
3106  **/
GetAttribLocation(const Functions & gl,GLuint id,const std::string & name)3107 GLint Program::GetAttribLocation(const Functions& gl, GLuint id, const std::string& name)
3108 {
3109 	GLint location = gl.getAttribLocation(id, name.c_str());
3110 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetAttribLocation");
3111 
3112 	return location;
3113 }
3114 
3115 /** Query resource
3116  *
3117  * @param gl        GL functions
3118  * @param id        Id of program
3119  * @param interface Interface to be queried
3120  * @param index     Index of resource
3121  * @param property  Property to be queried
3122  * @param buf_size  Size of <params> buffer
3123  * @param params    Results of query
3124  **/
GetResource(const Functions & gl,GLuint id,GLenum interface,GLuint index,GLenum property,GLsizei buf_size,GLint * params)3125 void Program::GetResource(const Functions& gl, GLuint id, GLenum interface, GLuint index, GLenum property,
3126 						  GLsizei buf_size, GLint* params)
3127 {
3128 	gl.getProgramResourceiv(id, interface, index, 1 /* propCount */, &property, buf_size /* bufSize */, 0 /* length */,
3129 							params);
3130 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramResourceiv");
3131 }
3132 
3133 /** Get index of resource
3134  *
3135  * @param gl        GL functions
3136  * @param id        Id of program
3137  * @param name      Name of resource
3138  * @param interface Program interface to queried
3139  *
3140  * @return Location of attribute
3141  **/
GetResourceIndex(const Functions & gl,GLuint id,const std::string & name,GLenum interface)3142 GLuint Program::GetResourceIndex(const Functions& gl, GLuint id, const std::string& name, GLenum interface)
3143 {
3144 	GLuint index = gl.getProgramResourceIndex(id, interface, name.c_str());
3145 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramResourceIndex");
3146 
3147 	return index;
3148 }
3149 
3150 /** Get location of attribute
3151  *
3152  * @param gl   GL functions
3153  * @param id   Id of program
3154  * @param name Name of attribute
3155  *
3156  * @return Location of uniform
3157  **/
GetUniformLocation(const Functions & gl,GLuint id,const std::string & name)3158 GLint Program::GetUniformLocation(const Functions& gl, GLuint id, const std::string& name)
3159 {
3160 	GLint location = gl.getUniformLocation(id, name.c_str());
3161 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformLocation");
3162 
3163 	return location;
3164 }
3165 
3166 /** Constructor
3167  *
3168  * @param error_message    Error message
3169  * @param compute_shader   Source code for compute stage
3170  * @param fragment_shader  Source code for fragment stage
3171  * @param geometry_shader  Source code for geometry stage
3172  * @param tess_ctrl_shader Source code for tessellation control stage
3173  * @param tess_eval_shader Source code for tessellation evaluation stage
3174  * @param vertex_shader    Source code for vertex stage
3175  **/
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)3176 Program::BuildException::BuildException(const glw::GLchar* error_message, const std::string compute_shader,
3177 										const std::string fragment_shader, const std::string geometry_shader,
3178 										const std::string tess_ctrl_shader, const std::string tess_eval_shader,
3179 										const std::string vertex_shader)
3180 	: m_error_message(error_message)
3181 	, m_compute_shader(compute_shader)
3182 	, m_fragment_shader(fragment_shader)
3183 	, m_geometry_shader(geometry_shader)
3184 	, m_tess_ctrl_shader(tess_ctrl_shader)
3185 	, m_tess_eval_shader(tess_eval_shader)
3186 	, m_vertex_shader(vertex_shader)
3187 {
3188 }
3189 
3190 /** Overwrites std::exception::what method
3191  *
3192  * @return Message compossed from error message and shader sources
3193  **/
what() const3194 const char* Program::BuildException::what() const throw()
3195 {
3196 	return "Failed to link program";
3197 }
3198 
3199 /** Logs error message and shader sources **/
log(deqp::Context & context) const3200 void Program::BuildException::log(deqp::Context& context) const
3201 {
3202 	context.getTestContext().getLog() << tcu::TestLog::Message << "Link failure: " << m_error_message
3203 									  << tcu::TestLog::EndMessage;
3204 
3205 	Shader::LogSource(context, m_vertex_shader, Shader::VERTEX);
3206 	Shader::LogSource(context, m_tess_ctrl_shader, Shader::TESS_CTRL);
3207 	Shader::LogSource(context, m_tess_eval_shader, Shader::TESS_EVAL);
3208 	Shader::LogSource(context, m_geometry_shader, Shader::GEOMETRY);
3209 	Shader::LogSource(context, m_fragment_shader, Shader::FRAGMENT);
3210 	Shader::LogSource(context, m_compute_shader, Shader::COMPUTE);
3211 }
3212 
3213 /** Constructor
3214  *
3215  * @param message Linking error message
3216  **/
LinkageException(const glw::GLchar * message)3217 Program::LinkageException::LinkageException(const glw::GLchar* message) : m_error_message(message)
3218 {
3219 	/* Nothing to be done */
3220 }
3221 
3222 /** Returns error messages
3223  *
3224  * @return Linking error message
3225  **/
what() const3226 const char* Program::LinkageException::what() const throw()
3227 {
3228 	return m_error_message.c_str();
3229 }
3230 
3231 /* Texture constants */
3232 const GLuint Texture::m_invalid_id = -1;
3233 
3234 /** Constructor.
3235  *
3236  * @param context CTS context.
3237  **/
Texture(deqp::Context & context)3238 Texture::Texture(deqp::Context& context) : m_id(m_invalid_id), m_context(context), m_type(TEX_2D)
3239 {
3240 	/* Nothing to done here */
3241 }
3242 
3243 /** Destructor
3244  *
3245  **/
~Texture()3246 Texture::~Texture()
3247 {
3248 	Release();
3249 }
3250 
3251 /** Initialize texture instance
3252  *
3253  * @param tex_type        Type of texture
3254  * @param width           Width of texture
3255  * @param height          Height of texture
3256  * @param depth           Depth of texture
3257  * @param internal_format Internal format of texture
3258  * @param format          Format of texture data
3259  * @param type            Type of texture data
3260  * @param data            Texture data
3261  **/
Init(TYPES tex_type,GLuint width,GLuint height,GLuint depth,GLenum internal_format,GLenum format,GLenum type,GLvoid * data)3262 void Texture::Init(TYPES tex_type, GLuint width, GLuint height, GLuint depth, GLenum internal_format, GLenum format,
3263 				   GLenum type, GLvoid* data)
3264 {
3265 	const Functions& gl = m_context.getRenderContext().getFunctions();
3266 
3267 	/* Delete previous texture */
3268 	Release();
3269 
3270 	m_type = tex_type;
3271 
3272 	/* Generate, bind, allocate storage and upload data */
3273 	Generate(gl, m_id);
3274 	Bind(gl, m_id, tex_type);
3275 	Storage(gl, tex_type, width, height, depth, internal_format);
3276 	Update(gl, tex_type, width, height, depth, format, type, data);
3277 }
3278 
3279 /** Initialize buffer texture
3280  *
3281  * @param internal_format Internal format of texture
3282  * @param buffer_id       Id of buffer that will be used as data source
3283  **/
Init(GLenum internal_format,GLuint buffer_id)3284 void Texture::Init(GLenum internal_format, GLuint buffer_id)
3285 {
3286 	const Functions& gl = m_context.getRenderContext().getFunctions();
3287 
3288 	/* Delete previous texture */
3289 	Release();
3290 
3291 	m_type = TEX_BUFFER;
3292 
3293 	/* Generate, bind and attach buffer */
3294 	Generate(gl, m_id);
3295 	Bind(gl, m_id, TEX_BUFFER);
3296 	TexBuffer(gl, buffer_id, internal_format);
3297 }
3298 
3299 /** Release texture instance
3300  *
3301  **/
Release()3302 void Texture::Release()
3303 {
3304 	if (m_invalid_id != m_id)
3305 	{
3306 		const Functions& gl = m_context.getRenderContext().getFunctions();
3307 
3308 		gl.deleteTextures(1, &m_id);
3309 		m_id = m_invalid_id;
3310 	}
3311 }
3312 
3313 /** Bind texture to its target
3314  *
3315  **/
Bind() const3316 void Texture::Bind() const
3317 {
3318 	const Functions& gl = m_context.getRenderContext().getFunctions();
3319 
3320 	Bind(gl, m_id, m_type);
3321 }
3322 
3323 /** Get texture data
3324  *
3325  * @param format   Format of data
3326  * @param type     Type of data
3327  * @param out_data Buffer for data
3328  **/
Get(GLenum format,GLenum type,GLvoid * out_data) const3329 void Texture::Get(GLenum format, GLenum type, GLvoid* out_data) const
3330 {
3331 	const Functions& gl = m_context.getRenderContext().getFunctions();
3332 
3333 	Bind(gl, m_id, m_type);
3334 	Get(gl, m_type, format, type, out_data);
3335 }
3336 
3337 /** Bind texture to target
3338  *
3339  * @param gl       GL functions
3340  * @param id       Id of texture
3341  * @param tex_type Type of texture
3342  **/
Bind(const Functions & gl,GLuint id,TYPES tex_type)3343 void Texture::Bind(const Functions& gl, GLuint id, TYPES tex_type)
3344 {
3345 	GLenum target = GetTargetGLenum(tex_type);
3346 
3347 	gl.bindTexture(target, id);
3348 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
3349 }
3350 
3351 /** Generate texture instance
3352  *
3353  * @param gl     GL functions
3354  * @param out_id Id of texture
3355  **/
Generate(const Functions & gl,GLuint & out_id)3356 void Texture::Generate(const Functions& gl, GLuint& out_id)
3357 {
3358 	GLuint id = m_invalid_id;
3359 
3360 	gl.genTextures(1, &id);
3361 	GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures");
3362 
3363 	if (m_invalid_id == id)
3364 	{
3365 		TCU_FAIL("Invalid id");
3366 	}
3367 
3368 	out_id = id;
3369 }
3370 
3371 /** Get texture data
3372  *
3373  * @param gl       GL functions
3374  * @param format   Format of data
3375  * @param type     Type of data
3376  * @param out_data Buffer for data
3377  **/
Get(const Functions & gl,TYPES tex_type,GLenum format,GLenum type,GLvoid * out_data)3378 void Texture::Get(const Functions& gl, TYPES tex_type, GLenum format, GLenum type, GLvoid* out_data)
3379 {
3380 	GLenum target = GetTargetGLenum(tex_type);
3381 
3382 	if (TEX_CUBE != tex_type)
3383 	{
3384 		gl.getTexImage(target, 0 /* level */, format, type, out_data);
3385 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexImage");
3386 	}
3387 	else
3388 	{
3389 		GLint width;
3390 		GLint height;
3391 
3392 		if ((GL_RGBA != format) && (GL_UNSIGNED_BYTE != type))
3393 		{
3394 			TCU_FAIL("Not implemented");
3395 		}
3396 
3397 		GLuint texel_size = 4;
3398 
3399 		gl.getTexLevelParameteriv(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0 /* level */, GL_TEXTURE_WIDTH, &width);
3400 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv");
3401 
3402 		gl.getTexLevelParameteriv(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0 /* level */, GL_TEXTURE_HEIGHT, &height);
3403 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv");
3404 
3405 		const GLuint image_size = width * height * texel_size;
3406 
3407 		gl.getTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0 /* level */, format, type,
3408 					   (GLvoid*)((GLchar*)out_data + (image_size * 0)));
3409 		gl.getTexImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0 /* level */, format, type,
3410 					   (GLvoid*)((GLchar*)out_data + (image_size * 1)));
3411 		gl.getTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0 /* level */, format, type,
3412 					   (GLvoid*)((GLchar*)out_data + (image_size * 2)));
3413 		gl.getTexImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0 /* level */, format, type,
3414 					   (GLvoid*)((GLchar*)out_data + (image_size * 3)));
3415 		gl.getTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0 /* level */, format, type,
3416 					   (GLvoid*)((GLchar*)out_data + (image_size * 4)));
3417 		gl.getTexImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0 /* level */, format, type,
3418 					   (GLvoid*)((GLchar*)out_data + (image_size * 5)));
3419 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexImage");
3420 	}
3421 }
3422 
3423 /** Allocate storage for texture
3424  *
3425  * @param gl              GL functions
3426  * @param tex_type        Type of texture
3427  * @param width           Width of texture
3428  * @param height          Height of texture
3429  * @param depth           Depth of texture
3430  * @param internal_format Internal format of texture
3431  **/
Storage(const Functions & gl,TYPES tex_type,GLuint width,GLuint height,GLuint depth,GLenum internal_format)3432 void Texture::Storage(const Functions& gl, TYPES tex_type, GLuint width, GLuint height, GLuint depth,
3433 					  GLenum internal_format)
3434 {
3435 	static const GLuint levels = 1;
3436 
3437 	GLenum target = GetTargetGLenum(tex_type);
3438 
3439 	switch (tex_type)
3440 	{
3441 	case TEX_1D:
3442 		gl.texStorage1D(target, levels, internal_format, width);
3443 		GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage1D");
3444 		break;
3445 	case TEX_2D:
3446 	case TEX_1D_ARRAY:
3447 	case TEX_2D_RECT:
3448 	case TEX_CUBE:
3449 		gl.texStorage2D(target, levels, internal_format, width, height);
3450 		GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2D");
3451 		break;
3452 	case TEX_3D:
3453 	case TEX_2D_ARRAY:
3454 		gl.texStorage3D(target, levels, internal_format, width, height, depth);
3455 		GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage3D");
3456 		break;
3457 	default:
3458 		TCU_FAIL("Invalid enum");
3459 		break;
3460 	}
3461 }
3462 
3463 /** Attach buffer as source of texture buffer data
3464  *
3465  * @param gl              GL functions
3466  * @param internal_format Internal format of texture
3467  * @param buffer_id       Id of buffer that will be used as data source
3468  **/
TexBuffer(const Functions & gl,GLenum internal_format,GLuint & buffer_id)3469 void Texture::TexBuffer(const Functions& gl, GLenum internal_format, GLuint& buffer_id)
3470 {
3471 	gl.texBuffer(GL_TEXTURE_BUFFER, internal_format, buffer_id);
3472 	GLU_EXPECT_NO_ERROR(gl.getError(), "TexBuffer");
3473 }
3474 
3475 /** Update contents of texture
3476  *
3477  * @param gl       GL functions
3478  * @param tex_type Type of texture
3479  * @param width    Width of texture
3480  * @param height   Height of texture
3481  * @param format   Format of data
3482  * @param type     Type of data
3483  * @param data     Buffer with image data
3484  **/
Update(const Functions & gl,TYPES tex_type,GLuint width,GLuint height,GLuint depth,GLenum format,GLenum type,GLvoid * data)3485 void Texture::Update(const Functions& gl, TYPES tex_type, GLuint width, GLuint height, GLuint depth, GLenum format,
3486 					 GLenum type, GLvoid* data)
3487 {
3488 	static const GLuint level = 0;
3489 
3490 	GLenum target = GetTargetGLenum(tex_type);
3491 
3492 	switch (tex_type)
3493 	{
3494 	case TEX_1D:
3495 		gl.texSubImage1D(target, level, 0 /* x */, width, format, type, data);
3496 		GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage1D");
3497 		break;
3498 	case TEX_2D:
3499 	case TEX_1D_ARRAY:
3500 	case TEX_2D_RECT:
3501 		gl.texSubImage2D(target, level, 0 /* x */, 0 /* y */, width, height, format, type, data);
3502 		GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2D");
3503 		break;
3504 	case TEX_CUBE:
3505 		gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, level, 0 /* x */, 0 /* y */, width, height, format, type,
3506 						 data);
3507 		gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, level, 0 /* x */, 0 /* y */, width, height, format, type,
3508 						 data);
3509 		gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, level, 0 /* x */, 0 /* y */, width, height, format, type,
3510 						 data);
3511 		gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, level, 0 /* x */, 0 /* y */, width, height, format, type,
3512 						 data);
3513 		gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, level, 0 /* x */, 0 /* y */, width, height, format, type,
3514 						 data);
3515 		gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, level, 0 /* x */, 0 /* y */, width, height, format, type,
3516 						 data);
3517 		GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2D");
3518 		break;
3519 	case TEX_3D:
3520 	case TEX_2D_ARRAY:
3521 		gl.texSubImage3D(target, level, 0 /* x */, 0 /* y */, 0 /* z */, width, height, depth, format, type, data);
3522 		GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage3D");
3523 		break;
3524 	default:
3525 		TCU_FAIL("Invalid enum");
3526 		break;
3527 	}
3528 }
3529 
3530 /** Get target for given texture type
3531  *
3532  * @param type Type of texture
3533  *
3534  * @return Target
3535  **/
GetTargetGLenum(TYPES type)3536 GLenum Texture::GetTargetGLenum(TYPES type)
3537 {
3538 	GLenum result = 0;
3539 
3540 	switch (type)
3541 	{
3542 	case TEX_BUFFER:
3543 		result = GL_TEXTURE_BUFFER;
3544 		break;
3545 	case TEX_2D:
3546 		result = GL_TEXTURE_2D;
3547 		break;
3548 	case TEX_2D_RECT:
3549 		result = GL_TEXTURE_RECTANGLE;
3550 		break;
3551 	case TEX_2D_ARRAY:
3552 		result = GL_TEXTURE_2D_ARRAY;
3553 		break;
3554 	case TEX_3D:
3555 		result = GL_TEXTURE_3D;
3556 		break;
3557 	case TEX_CUBE:
3558 		result = GL_TEXTURE_CUBE_MAP;
3559 		break;
3560 	case TEX_1D:
3561 		result = GL_TEXTURE_1D;
3562 		break;
3563 	case TEX_1D_ARRAY:
3564 		result = GL_TEXTURE_1D_ARRAY;
3565 		break;
3566 	}
3567 
3568 	return result;
3569 }
3570 
3571 /* VertexArray constants */
3572 const GLuint VertexArray::m_invalid_id = -1;
3573 
3574 /** Constructor.
3575  *
3576  * @param context CTS context.
3577  **/
VertexArray(deqp::Context & context)3578 VertexArray::VertexArray(deqp::Context& context) : m_id(m_invalid_id), m_context(context)
3579 {
3580 }
3581 
3582 /** Destructor
3583  *
3584  **/
~VertexArray()3585 VertexArray::~VertexArray()
3586 {
3587 	Release();
3588 }
3589 
3590 /** Initialize vertex array instance
3591  *
3592  **/
Init()3593 void VertexArray::Init()
3594 {
3595 	/* Delete previous instance */
3596 	Release();
3597 
3598 	const Functions& gl = m_context.getRenderContext().getFunctions();
3599 
3600 	Generate(gl, m_id);
3601 }
3602 
3603 /** Release vertex array object instance
3604  *
3605  **/
Release()3606 void VertexArray::Release()
3607 {
3608 	if (m_invalid_id != m_id)
3609 	{
3610 		const Functions& gl = m_context.getRenderContext().getFunctions();
3611 
3612 		gl.deleteVertexArrays(1, &m_id);
3613 
3614 		m_id = m_invalid_id;
3615 	}
3616 }
3617 
3618 /** Set attribute in VAO
3619  *
3620  * @param index            Index of attribute
3621  * @param type             Type of attribute
3622  * @param n_array_elements Arary length
3623  * @param normalized       Selects if values should be normalized
3624  * @param stride           Stride
3625  * @param pointer          Pointer to data, or offset in buffer
3626  **/
Attribute(GLuint index,const Type & type,GLuint n_array_elements,GLboolean normalized,GLsizei stride,const GLvoid * pointer)3627 void VertexArray::Attribute(GLuint index, const Type& type, GLuint n_array_elements, GLboolean normalized,
3628 							GLsizei stride, const GLvoid* pointer)
3629 {
3630 	const Functions& gl = m_context.getRenderContext().getFunctions();
3631 
3632 	AttribPointer(gl, index, type, n_array_elements, normalized, stride, pointer);
3633 	Enable(gl, index, type, n_array_elements);
3634 }
3635 
3636 /** Binds Vertex array object
3637  *
3638  **/
Bind()3639 void VertexArray::Bind()
3640 {
3641 	const Functions& gl = m_context.getRenderContext().getFunctions();
3642 
3643 	Bind(gl, m_id);
3644 }
3645 
3646 /** Set attribute in VAO
3647  *
3648  * @param gl               Functions
3649  * @param index            Index of attribute
3650  * @param type             Type of attribute
3651  * @param n_array_elements Arary length
3652  * @param normalized       Selects if values should be normalized
3653  * @param stride           Stride
3654  * @param pointer          Pointer to data, or offset in buffer
3655  **/
AttribPointer(const Functions & gl,GLuint index,const Type & type,GLuint n_array_elements,GLboolean normalized,GLsizei stride,const GLvoid * pointer)3656 void VertexArray::AttribPointer(const Functions& gl, GLuint index, const Type& type, GLuint n_array_elements,
3657 								GLboolean normalized, GLsizei stride, const GLvoid* pointer)
3658 {
3659 	const GLuint basic_type_size = Type::GetTypeSize(type.m_basic_type);
3660 	const GLint  size			 = (GLint)type.m_n_rows;
3661 	const GLuint column_size	 = (GLuint)size * basic_type_size;
3662 	const GLenum gl_type		 = Type::GetTypeGLenum(type.m_basic_type);
3663 
3664 	GLuint offset = 0;
3665 
3666 	/* If attribute is not an array */
3667 	if (0 == n_array_elements)
3668 	{
3669 		n_array_elements = 1;
3670 	}
3671 
3672 	/* For each element in array */
3673 	for (GLuint element = 0; element < n_array_elements; ++element)
3674 	{
3675 		/* For each column in matrix */
3676 		for (GLuint column = 1; column <= type.m_n_columns; ++column)
3677 		{
3678 			/* Calculate offset */
3679 			const GLvoid* ptr = (GLubyte*)pointer + offset;
3680 
3681 			/* Set up attribute */
3682 			switch (type.m_basic_type)
3683 			{
3684 			case Type::Float:
3685 				gl.vertexAttribPointer(index, size, gl_type, normalized, stride, ptr);
3686 				GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttribPointer");
3687 				break;
3688 			case Type::Int:
3689 			case Type::Uint:
3690 				gl.vertexAttribIPointer(index, size, gl_type, stride, ptr);
3691 				GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttribIPointer");
3692 				break;
3693 			case Type::Double:
3694 				gl.vertexAttribLPointer(index, size, gl_type, stride, ptr);
3695 				GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttribLPointer");
3696 				break;
3697 			default:
3698 				TCU_FAIL("Invalid enum");
3699 			}
3700 
3701 			/* Next location */
3702 			offset += column_size;
3703 			index += 1;
3704 		}
3705 	}
3706 }
3707 
3708 /** Binds Vertex array object
3709  *
3710  * @param gl GL functions
3711  * @param id ID of vertex array object
3712  **/
Bind(const glw::Functions & gl,glw::GLuint id)3713 void VertexArray::Bind(const glw::Functions& gl, glw::GLuint id)
3714 {
3715 	gl.bindVertexArray(id);
3716 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindVertexArray");
3717 }
3718 
3719 /** Disable attribute in VAO
3720  *
3721  * @param gl               Functions
3722  * @param index            Index of attribute
3723  * @param type             Type of attribute
3724  * @param n_array_elements Arary length
3725  **/
Disable(const Functions & gl,GLuint index,const Type & type,GLuint n_array_elements)3726 void VertexArray::Disable(const Functions& gl, GLuint index, const Type& type, GLuint n_array_elements)
3727 {
3728 	/* If attribute is not an array */
3729 	if (0 == n_array_elements)
3730 	{
3731 		n_array_elements = 1;
3732 	}
3733 
3734 	/* For each element in array */
3735 	for (GLuint element = 0; element < n_array_elements; ++element)
3736 	{
3737 		/* For each column in matrix */
3738 		for (GLuint column = 1; column <= type.m_n_columns; ++column)
3739 		{
3740 			/* Enable attribute array */
3741 			gl.disableVertexAttribArray(index);
3742 			GLU_EXPECT_NO_ERROR(gl.getError(), "DisableVertexAttribArray");
3743 
3744 			/* Next location */
3745 			index += 1;
3746 		}
3747 	}
3748 }
3749 
3750 /** Set divisor for attribute
3751  *
3752  * @param gl               Functions
3753  * @param index            Index of attribute
3754  * @param divisor          New divisor value
3755  **/
Divisor(const Functions & gl,GLuint index,GLuint divisor)3756 void VertexArray::Divisor(const Functions& gl, GLuint index, GLuint divisor)
3757 {
3758 	gl.vertexAttribDivisor(index, divisor);
3759 	GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttribDivisor");
3760 }
3761 
3762 /** Enables attribute in VAO
3763  *
3764  * @param gl               Functions
3765  * @param index            Index of attribute
3766  * @param type             Type of attribute
3767  * @param n_array_elements Arary length
3768  **/
Enable(const Functions & gl,GLuint index,const Type & type,GLuint n_array_elements)3769 void VertexArray::Enable(const Functions& gl, GLuint index, const Type& type, GLuint n_array_elements)
3770 {
3771 	/* If attribute is not an array */
3772 	if (0 == n_array_elements)
3773 	{
3774 		n_array_elements = 1;
3775 	}
3776 
3777 	/* For each element in array */
3778 	for (GLuint element = 0; element < n_array_elements; ++element)
3779 	{
3780 		/* For each column in matrix */
3781 		for (GLuint column = 1; column <= type.m_n_columns; ++column)
3782 		{
3783 			/* Enable attribute array */
3784 			gl.enableVertexAttribArray(index);
3785 			GLU_EXPECT_NO_ERROR(gl.getError(), "EnableVertexAttribArray");
3786 
3787 			/* Next location */
3788 			index += 1;
3789 		}
3790 	}
3791 }
3792 
3793 /** Generates Vertex array object
3794  *
3795  * @param gl     GL functions
3796  * @param out_id ID of vertex array object
3797  **/
Generate(const glw::Functions & gl,glw::GLuint & out_id)3798 void VertexArray::Generate(const glw::Functions& gl, glw::GLuint& out_id)
3799 {
3800 	GLuint id = m_invalid_id;
3801 
3802 	gl.genVertexArrays(1, &id);
3803 	GLU_EXPECT_NO_ERROR(gl.getError(), "GenVertexArrays");
3804 
3805 	if (m_invalid_id == id)
3806 	{
3807 		TCU_FAIL("Invalid id");
3808 	}
3809 
3810 	out_id = id;
3811 }
3812 
3813 /* Constatns used by Variable */
3814 const GLint Variable::m_automatic_location = -1;
3815 
3816 /** Copy constructor
3817  *
3818  **/
Variable(const Variable & var)3819 Variable::Variable(const Variable& var)
3820 	: m_data(var.m_data)
3821 	, m_data_size(var.m_data_size)
3822 	, m_descriptor(var.m_descriptor.m_name.c_str(), var.m_descriptor.m_qualifiers.c_str(),
3823 				   var.m_descriptor.m_expected_component, var.m_descriptor.m_expected_location,
3824 				   var.m_descriptor.m_builtin, var.m_descriptor.m_normalized, var.m_descriptor.m_n_array_elements,
3825 				   var.m_descriptor.m_expected_stride_of_element, var.m_descriptor.m_offset)
3826 	, m_storage(var.m_storage)
3827 {
3828 	m_descriptor.m_type = var.m_descriptor.m_type;
3829 
3830 	if (BUILTIN != var.m_descriptor.m_type)
3831 	{
3832 		m_descriptor.m_interface = var.m_descriptor.m_interface;
3833 	}
3834 }
3835 
3836 /** Get code that defines variable
3837  *
3838  * @param flavour Provides info if variable is array or not
3839  *
3840  * @return String with code
3841  **/
GetDefinition(FLAVOUR flavour) const3842 std::string Variable::GetDefinition(FLAVOUR flavour) const
3843 {
3844 	return m_descriptor.GetDefinition(flavour, m_storage);
3845 }
3846 
3847 /** Calcualtes stride of variable
3848  *
3849  * @return Calculated value
3850  **/
GetStride() const3851 GLuint Variable::GetStride() const
3852 {
3853 	GLint variable_stride = 0;
3854 
3855 	if (0 == m_descriptor.m_n_array_elements)
3856 	{
3857 		variable_stride = m_descriptor.m_expected_stride_of_element;
3858 	}
3859 	else
3860 	{
3861 		variable_stride = m_descriptor.m_expected_stride_of_element * m_descriptor.m_n_array_elements;
3862 	}
3863 
3864 	return variable_stride;
3865 }
3866 
3867 /** Check if variable is block
3868  *
3869  * @return true if variable type is block, false otherwise
3870  **/
IsBlock() const3871 bool Variable::IsBlock() const
3872 {
3873 	if (BUILTIN == m_descriptor.m_type)
3874 	{
3875 		return false;
3876 	}
3877 
3878 	const Interface* interface = m_descriptor.m_interface;
3879 	if (0 == interface)
3880 	{
3881 		TCU_FAIL("Nullptr");
3882 	}
3883 
3884 	return (Interface::BLOCK == interface->m_type);
3885 }
3886 
3887 /** Check if variable is struct
3888  *
3889  * @return true if variable type is struct, false otherwise
3890  **/
IsStruct() const3891 bool Variable::IsStruct() const
3892 {
3893 	if (BUILTIN == m_descriptor.m_type)
3894 	{
3895 		return false;
3896 	}
3897 
3898 	const Interface* interface = m_descriptor.m_interface;
3899 	if (0 == interface)
3900 	{
3901 		TCU_FAIL("Nullptr");
3902 	}
3903 
3904 	return (Interface::STRUCT == interface->m_type);
3905 }
3906 /** Get code that reference variable
3907  *
3908  * @param parent_name Name of parent
3909  * @param variable    Descriptor of variable
3910  * @param flavour     Provides info about how variable should be referenced
3911  * @param array_index Index of array, ignored when variable is not array
3912  *
3913  * @return String with code
3914  **/
GetReference(const std::string & parent_name,const Descriptor & variable,FLAVOUR flavour,GLuint array_index)3915 std::string Variable::GetReference(const std::string& parent_name, const Descriptor& variable, FLAVOUR flavour,
3916 								   GLuint array_index)
3917 {
3918 	std::string name;
3919 
3920 	/* Prepare name */
3921 	if (false == parent_name.empty())
3922 	{
3923 		name = parent_name;
3924 		name.append(".");
3925 		name.append(variable.m_name);
3926 	}
3927 	else
3928 	{
3929 		name = variable.m_name;
3930 	}
3931 
3932 	/* */
3933 	switch (flavour)
3934 	{
3935 	case Utils::Variable::BASIC:
3936 		break;
3937 
3938 	case Utils::Variable::ARRAY:
3939 		name.append("[0]");
3940 		break;
3941 
3942 	case Utils::Variable::INDEXED_BY_INVOCATION_ID:
3943 		name.append("[gl_InvocationID]");
3944 		break;
3945 	}
3946 
3947 	/* Assumption that both variables have same lengths */
3948 	if (0 != variable.m_n_array_elements)
3949 	{
3950 		GLchar buffer[16];
3951 		sprintf(buffer, "%d", array_index);
3952 		name.append("[");
3953 		name.append(buffer);
3954 		name.append("]");
3955 	}
3956 
3957 	return name;
3958 }
3959 
3960 /** Get "flavour" of varying
3961  *
3962  * @param stage     Stage of shader
3963  * @param direction Selects if varying is in or out
3964  *
3965  * @return Flavour
3966  **/
GetFlavour(Shader::STAGES stage,VARYING_DIRECTION direction)3967 Variable::FLAVOUR Variable::GetFlavour(Shader::STAGES stage, VARYING_DIRECTION direction)
3968 {
3969 	FLAVOUR result = BASIC;
3970 
3971 	switch (stage)
3972 	{
3973 	case Shader::GEOMETRY:
3974 	case Shader::TESS_EVAL:
3975 		if (INPUT == direction)
3976 		{
3977 			result = ARRAY;
3978 		}
3979 		break;
3980 	case Shader::TESS_CTRL:
3981 		result = INDEXED_BY_INVOCATION_ID;
3982 		break;
3983 	default:
3984 		break;
3985 	}
3986 
3987 	return result;
3988 }
3989 
3990 /** Constructor, for built-in types
3991  *
3992  * @param name                       Name
3993  * @param qualifiers                 Qualifiers
3994  * @param expected_component         Expected component of variable
3995  * @param expected_location          Expected location
3996  * @param type                       Type
3997  * @param normalized                 Selects if data should be normalized
3998  * @param n_array_elements           Length of array
3999  * @param expected_stride_of_element Expected stride of element
4000  * @param offset                     Offset
4001  **/
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)4002 Variable::Descriptor::Descriptor(const GLchar* name, const GLchar* qualifiers, GLint expected_component,
4003 								 GLint expected_location, const Type& type, GLboolean normalized,
4004 								 GLuint n_array_elements, GLint expected_stride_of_element, GLuint offset)
4005 	: m_expected_component(expected_component)
4006 	, m_expected_location(expected_location)
4007 	, m_expected_stride_of_element(expected_stride_of_element)
4008 	, m_n_array_elements(n_array_elements)
4009 	, m_name(name)
4010 	, m_normalized(normalized)
4011 	, m_offset(offset)
4012 	, m_qualifiers(qualifiers)
4013 	, m_type(BUILTIN)
4014 	, m_builtin(type)
4015 {
4016 }
4017 
4018 /** Constructor, for interface types
4019  *
4020  * @param name                       Name
4021  * @param qualifiers                 Qualifiers
4022  * @param expected_component         Expected component of variable
4023  * @param expected_location          Expected location
4024  * @param interface                  Interface of variable
4025  * @param n_array_elements           Length of array
4026  * @param expected_stride_of_element Expected stride of element
4027  * @param offset                     Offset
4028  **/
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)4029 Variable::Descriptor::Descriptor(const GLchar* name, const GLchar* qualifiers, GLint expected_componenet,
4030 								 GLint expected_location, Interface* interface, GLuint n_array_elements,
4031 								 GLint expected_stride_of_element, GLuint offset)
4032 	: m_expected_component(expected_componenet)
4033 	, m_expected_location(expected_location)
4034 	, m_expected_stride_of_element(expected_stride_of_element)
4035 	, m_n_array_elements(n_array_elements)
4036 	, m_name(name)
4037 	, m_normalized(GL_FALSE)
4038 	, m_offset(offset)
4039 	, m_qualifiers(qualifiers)
4040 	, m_type(INTERFACE)
4041 	, m_interface(interface)
4042 {
4043 }
4044 
4045 /** Get definition of variable
4046  *
4047  * @param flavour Flavour of variable
4048  * @param storage Storage used for variable
4049  *
4050  * @return code with defintion
4051  **/
GetDefinition(FLAVOUR flavour,STORAGE storage) const4052 std::string Variable::Descriptor::GetDefinition(FLAVOUR flavour, STORAGE storage) const
4053 {
4054 	static const GLchar* basic_template = "QUALIFIERS STORAGETYPE NAMEARRAY;";
4055 	static const GLchar* array_template = "QUALIFIERS STORAGETYPE NAME[]ARRAY;";
4056 	const GLchar*		 storage_str	= 0;
4057 
4058 	std::string definition;
4059 	size_t		position = 0;
4060 
4061 	/* Select definition template */
4062 	switch (flavour)
4063 	{
4064 	case BASIC:
4065 		definition = basic_template;
4066 		break;
4067 	case ARRAY:
4068 	case INDEXED_BY_INVOCATION_ID:
4069 		definition = array_template;
4070 		break;
4071 	default:
4072 		TCU_FAIL("Invalid enum");
4073 		break;
4074 	}
4075 
4076 	if (BUILTIN != m_type)
4077 	{
4078 		if (0 == m_interface)
4079 		{
4080 			TCU_FAIL("Nullptr");
4081 		}
4082 	}
4083 
4084 	/* Qualifiers */
4085 	if (true == m_qualifiers.empty())
4086 	{
4087 		replaceToken("QUALIFIERS ", position, "", definition);
4088 	}
4089 	else
4090 	{
4091 		replaceToken("QUALIFIERS", position, m_qualifiers.c_str(), definition);
4092 	}
4093 
4094 	// According to spec: int, uint, and double type must always be declared with flat qualifier
4095 	bool flat_qualifier = false;
4096 	if (m_type != BUILTIN && m_interface != NULL)
4097 	{
4098 		if (m_interface->m_members[0].m_builtin.m_basic_type == Utils::Type::Int ||
4099 			m_interface->m_members[0].m_builtin.m_basic_type == Utils::Type::Uint ||
4100 			m_interface->m_members[0].m_builtin.m_basic_type == Utils::Type::Double)
4101 		{
4102 			flat_qualifier = true;
4103 		}
4104 	}
4105 	/* Storage */
4106 	switch (storage)
4107 	{
4108 	case VARYING_INPUT:
4109 		storage_str = flat_qualifier ? "flat in " : "in ";
4110 		break;
4111 	case VARYING_OUTPUT:
4112 		storage_str = "out ";
4113 		break;
4114 	case UNIFORM:
4115 		storage_str = "uniform ";
4116 		break;
4117 	case SSB:
4118 		storage_str = "buffer ";
4119 		break;
4120 	case MEMBER:
4121 		storage_str = "";
4122 		break;
4123 	default:
4124 		TCU_FAIL("Invalid enum");
4125 		break;
4126 	}
4127 
4128 	replaceToken("STORAGE", position, storage_str, definition);
4129 
4130 	/* Type */
4131 	if (BUILTIN == m_type)
4132 	{
4133 		replaceToken("TYPE", position, m_builtin.GetGLSLTypeName(), definition);
4134 	}
4135 	else
4136 	{
4137 		if (Interface::STRUCT == m_interface->m_type)
4138 		{
4139 			replaceToken("TYPE", position, m_interface->m_name.c_str(), definition);
4140 		}
4141 		else
4142 		{
4143 			const std::string& block_definition = m_interface->GetDefinition();
4144 
4145 			replaceToken("TYPE", position, block_definition.c_str(), definition);
4146 		}
4147 	}
4148 
4149 	/* Name */
4150 	replaceToken("NAME", position, m_name.c_str(), definition);
4151 
4152 	/* Array size */
4153 	if (0 == m_n_array_elements)
4154 	{
4155 		replaceToken("ARRAY", position, "", definition);
4156 	}
4157 	else
4158 	{
4159 		char buffer[16];
4160 		sprintf(buffer, "[%d]", m_n_array_elements);
4161 
4162 		replaceToken("ARRAY", position, buffer, definition);
4163 	}
4164 
4165 	/* Done */
4166 	return definition;
4167 }
4168 
4169 /** Get definitions for variables collected in vector
4170  *
4171  * @param vector  Collection of variables
4172  * @param flavour Flavour of variables
4173  *
4174  * @return Code with definitions
4175  **/
GetDefinitions(const Variable::PtrVector & vector,Variable::FLAVOUR flavour)4176 std::string GetDefinitions(const Variable::PtrVector& vector, Variable::FLAVOUR flavour)
4177 {
4178 	std::string list	 = Utils::g_list;
4179 	size_t		position = 0;
4180 
4181 	for (GLuint i = 0; i < vector.size(); ++i)
4182 	{
4183 		Utils::insertElementOfList(vector[i]->GetDefinition(flavour).c_str(), "\n", position, list);
4184 	}
4185 
4186 	Utils::endList("", position, list);
4187 
4188 	return list;
4189 }
4190 
4191 /** Get definitions for interfaces collected in vector
4192  *
4193  * @param vector Collection of interfaces
4194  *
4195  * @return Code with definitions
4196  **/
GetDefinitions(const Interface::PtrVector & vector)4197 std::string GetDefinitions(const Interface::PtrVector& vector)
4198 {
4199 	std::string list	 = Utils::g_list;
4200 	size_t		position = 0;
4201 
4202 	for (GLuint i = 0; i < vector.size(); ++i)
4203 	{
4204 		Utils::insertElementOfList(vector[i]->GetDefinition().c_str(), "\n", position, list);
4205 	}
4206 
4207 	Utils::endList("", position, list);
4208 
4209 	return list;
4210 }
4211 
4212 /** Constructor
4213  *
4214  * @param name Name
4215  * @param type Type of interface
4216  **/
Interface(const GLchar * name,Interface::TYPE type)4217 Interface::Interface(const GLchar* name, Interface::TYPE type) : m_name(name), m_type(type)
4218 {
4219 }
4220 
4221 /** Adds member to interface
4222  *
4223  * @param member Descriptor of new member
4224  *
4225  * @return Pointer to just created member
4226  **/
AddMember(const Variable::Descriptor & member)4227 Variable::Descriptor* Interface::AddMember(const Variable::Descriptor& member)
4228 {
4229 	m_members.push_back(member);
4230 
4231 	return &m_members.back();
4232 }
4233 
4234 /** Get definition of interface
4235  *
4236  * @param Code with definition
4237  **/
GetDefinition() const4238 std::string Interface::GetDefinition() const
4239 {
4240 	std::string definition;
4241 	size_t		position = 0;
4242 
4243 	const GLchar* member_list = "    MEMBER_DEFINITION\nMEMBER_LIST";
4244 
4245 	if (STRUCT == m_type)
4246 	{
4247 		definition = "struct NAME {\nMEMBER_LIST};";
4248 	}
4249 	else
4250 	{
4251 		definition = "NAME {\nMEMBER_LIST}";
4252 	}
4253 
4254 	/* Name */
4255 	replaceToken("NAME", position, m_name.c_str(), definition);
4256 
4257 	/* Member list */
4258 	for (GLuint i = 0; i < m_members.size(); ++i)
4259 	{
4260 		const size_t	   start_position	= position;
4261 		const std::string& member_definition = m_members[i].GetDefinition(Variable::BASIC, Variable::MEMBER);
4262 
4263 		/* Member list */
4264 		replaceToken("MEMBER_LIST", position, member_list, definition);
4265 
4266 		/* Move back position */
4267 		position = start_position;
4268 
4269 		/* Member definition */
4270 		replaceToken("MEMBER_DEFINITION", position, member_definition.c_str(), definition);
4271 	}
4272 
4273 	/* Remove last member list */
4274 	replaceToken("MEMBER_LIST", position, "", definition);
4275 
4276 	/* Done */
4277 	return definition;
4278 }
4279 
4280 /** Adds member of built-in type to interface
4281  *
4282  * @param name                       Name
4283  * @param qualifiers                 Qualifiers
4284  * @param expected_component         Expected component of variable
4285  * @param expected_location          Expected location
4286  * @param type                       Type
4287  * @param normalized                 Selects if data should be normalized
4288  * @param n_array_elements           Length of array
4289  * @param expected_stride_of_element Expected stride of element
4290  * @param offset                     Offset
4291  *
4292  * @return Pointer to just created member
4293  **/
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)4294 Variable::Descriptor* Interface::Member(const GLchar* name, const GLchar* qualifiers, GLint expected_component,
4295 										GLint expected_location, const Type& type, GLboolean normalized,
4296 										GLuint n_array_elements, GLint expected_stride_of_element, GLuint offset)
4297 {
4298 	return AddMember(Variable::Descriptor(name, qualifiers, expected_component, expected_location, type, normalized,
4299 										  n_array_elements, expected_stride_of_element, offset));
4300 }
4301 
4302 /** Adds member of interface type to interface
4303  *
4304  * @param name                       Name
4305  * @param qualifiers                 Qualifiers
4306  * @param expected_component         Expected component of variable
4307  * @param expected_location          Expected location
4308  * @param type                       Type
4309  * @param normalized                 Selects if data should be normalized
4310  * @param n_array_elements           Length of array
4311  * @param expected_stride_of_element Expected stride of element
4312  * @param offset                     Offset
4313  *
4314  * @return Pointer to just created member
4315  **/
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)4316 Variable::Descriptor* Interface::Member(const GLchar* name, const GLchar* qualifiers, GLint expected_component,
4317 										GLint expected_location, Interface* nterface, GLuint n_array_elements,
4318 										GLint expected_stride_of_element, GLuint offset)
4319 {
4320 	return AddMember(Variable::Descriptor(name, qualifiers, expected_component, expected_location, nterface,
4321 										  n_array_elements, expected_stride_of_element, offset));
4322 }
4323 
4324 /** Clears contents of vector of pointers
4325  *
4326  * @tparam T Type of elements
4327  *
4328  * @param vector Collection to be cleared
4329  **/
4330 template <typename T>
clearPtrVector(std::vector<T * > & vector)4331 void clearPtrVector(std::vector<T*>& vector)
4332 {
4333 	for (size_t i = 0; i < vector.size(); ++i)
4334 	{
4335 		T* t = vector[i];
4336 
4337 		vector[i] = 0;
4338 
4339 		if (0 != t)
4340 		{
4341 			delete t;
4342 		}
4343 	}
4344 
4345 	vector.clear();
4346 }
4347 
4348 /** Constructor
4349  *
4350  * @param stage Stage described by that interface
4351  **/
ShaderInterface(Shader::STAGES stage)4352 ShaderInterface::ShaderInterface(Shader::STAGES stage) : m_stage(stage)
4353 {
4354 	/* Nothing to be done */
4355 }
4356 
4357 /** Get definitions of globals
4358  *
4359  * @return Code with definitions
4360  **/
GetDefinitionsGlobals() const4361 std::string ShaderInterface::GetDefinitionsGlobals() const
4362 {
4363 	return m_globals;
4364 }
4365 
4366 /** Get definitions of inputs
4367  *
4368  * @return Code with definitions
4369  **/
GetDefinitionsInputs() const4370 std::string ShaderInterface::GetDefinitionsInputs() const
4371 {
4372 	Variable::FLAVOUR flavour = Variable::GetFlavour(m_stage, Variable::INPUT);
4373 
4374 	return GetDefinitions(m_inputs, flavour);
4375 }
4376 
4377 /** Get definitions of outputs
4378  *
4379  * @return Code with definitions
4380  **/
GetDefinitionsOutputs() const4381 std::string ShaderInterface::GetDefinitionsOutputs() const
4382 {
4383 	Variable::FLAVOUR flavour = Variable::GetFlavour(m_stage, Variable::OUTPUT);
4384 
4385 	return GetDefinitions(m_outputs, flavour);
4386 }
4387 
4388 /** Get definitions of buffers
4389  *
4390  * @return Code with definitions
4391  **/
GetDefinitionsSSBs() const4392 std::string ShaderInterface::GetDefinitionsSSBs() const
4393 {
4394 	return GetDefinitions(m_ssb_blocks, Variable::BASIC);
4395 }
4396 
4397 /** Get definitions of uniforms
4398  *
4399  * @return Code with definitions
4400  **/
GetDefinitionsUniforms() const4401 std::string ShaderInterface::GetDefinitionsUniforms() const
4402 {
4403 	return GetDefinitions(m_uniforms, Variable::BASIC);
4404 }
4405 
4406 /** Constructor
4407  *
4408  * @param in  Input variable
4409  * @param out Output variable
4410  **/
VaryingConnection(Variable * in,Variable * out)4411 VaryingConnection::VaryingConnection(Variable* in, Variable* out) : m_in(in), m_out(out)
4412 {
4413 	/* NBothing to be done here */
4414 }
4415 
4416 /** Adds new varying connection to given stage
4417  *
4418  * @param stage Shader stage
4419  * @param in    In varying
4420  * @param out   Out varying
4421  **/
Add(Shader::STAGES stage,Variable * in,Variable * out)4422 void VaryingPassthrough::Add(Shader::STAGES stage, Variable* in, Variable* out)
4423 {
4424 	VaryingConnection::Vector& vector = Get(stage);
4425 
4426 	vector.push_back(VaryingConnection(in, out));
4427 }
4428 
4429 /** Get all passthrough connections for given stage
4430  *
4431  * @param stage Shader stage
4432  *
4433  * @return Vector of connections
4434  **/
Get(Shader::STAGES stage)4435 VaryingConnection::Vector& VaryingPassthrough::Get(Shader::STAGES stage)
4436 {
4437 	VaryingConnection::Vector* result = 0;
4438 
4439 	switch (stage)
4440 	{
4441 	case Shader::FRAGMENT:
4442 		result = &m_fragment;
4443 		break;
4444 	case Shader::GEOMETRY:
4445 		result = &m_geometry;
4446 		break;
4447 	case Shader::TESS_CTRL:
4448 		result = &m_tess_ctrl;
4449 		break;
4450 	case Shader::TESS_EVAL:
4451 		result = &m_tess_eval;
4452 		break;
4453 	case Shader::VERTEX:
4454 		result = &m_vertex;
4455 		break;
4456 	default:
4457 		TCU_FAIL("Invalid enum");
4458 	}
4459 
4460 	return *result;
4461 }
4462 
4463 /** Constructor
4464  *
4465  **/
ProgramInterface()4466 ProgramInterface::ProgramInterface()
4467 	: m_compute(Shader::COMPUTE)
4468 	, m_vertex(Shader::VERTEX)
4469 	, m_tess_ctrl(Shader::TESS_CTRL)
4470 	, m_tess_eval(Shader::TESS_EVAL)
4471 	, m_geometry(Shader::GEOMETRY)
4472 	, m_fragment(Shader::FRAGMENT)
4473 {
4474 }
4475 
4476 /** Destructor
4477  *
4478  **/
~ProgramInterface()4479 ProgramInterface::~ProgramInterface()
4480 {
4481 	clearPtrVector(m_blocks);
4482 	clearPtrVector(m_structures);
4483 }
4484 
4485 /** Adds new interface
4486  *
4487  * @param name
4488  * @param type
4489  *
4490  * @return Pointer to created interface
4491  **/
AddInterface(const GLchar * name,Interface::TYPE type)4492 Interface* ProgramInterface::AddInterface(const GLchar* name, Interface::TYPE type)
4493 {
4494 	Interface* interface = 0;
4495 
4496 	if (Interface::STRUCT == type)
4497 	{
4498 		interface = new Interface(name, type);
4499 
4500 		m_structures.push_back(interface);
4501 	}
4502 	else
4503 	{
4504 		interface = new Interface(name, type);
4505 
4506 		m_blocks.push_back(interface);
4507 	}
4508 
4509 	return interface;
4510 }
4511 
4512 /** Adds new block interface
4513  *
4514  * @param name
4515  *
4516  * @return Pointer to created interface
4517  **/
Block(const GLchar * name)4518 Interface* ProgramInterface::Block(const GLchar* name)
4519 {
4520 	return AddInterface(name, Interface::BLOCK);
4521 }
4522 
4523 /** Get interface of given shader stage
4524  *
4525  * @param stage Shader stage
4526  *
4527  * @return Reference to stage interface
4528  **/
GetShaderInterface(Shader::STAGES stage)4529 ShaderInterface& ProgramInterface::GetShaderInterface(Shader::STAGES stage)
4530 {
4531 	ShaderInterface* interface = 0;
4532 
4533 	switch (stage)
4534 	{
4535 	case Shader::COMPUTE:
4536 		interface = &m_compute;
4537 		break;
4538 	case Shader::FRAGMENT:
4539 		interface = &m_fragment;
4540 		break;
4541 	case Shader::GEOMETRY:
4542 		interface = &m_geometry;
4543 		break;
4544 	case Shader::TESS_CTRL:
4545 		interface = &m_tess_ctrl;
4546 		break;
4547 	case Shader::TESS_EVAL:
4548 		interface = &m_tess_eval;
4549 		break;
4550 	case Shader::VERTEX:
4551 		interface = &m_vertex;
4552 		break;
4553 	default:
4554 		TCU_FAIL("Invalid enum");
4555 	}
4556 
4557 	return *interface;
4558 }
4559 
4560 /** Get interface of given shader stage
4561  *
4562  * @param stage Shader stage
4563  *
4564  * @return Reference to stage interface
4565  **/
GetShaderInterface(Shader::STAGES stage) const4566 const ShaderInterface& ProgramInterface::GetShaderInterface(Shader::STAGES stage) const
4567 {
4568 	const ShaderInterface* interface = 0;
4569 
4570 	switch (stage)
4571 	{
4572 	case Shader::COMPUTE:
4573 		interface = &m_compute;
4574 		break;
4575 	case Shader::FRAGMENT:
4576 		interface = &m_fragment;
4577 		break;
4578 	case Shader::GEOMETRY:
4579 		interface = &m_geometry;
4580 		break;
4581 	case Shader::TESS_CTRL:
4582 		interface = &m_tess_ctrl;
4583 		break;
4584 	case Shader::TESS_EVAL:
4585 		interface = &m_tess_eval;
4586 		break;
4587 	case Shader::VERTEX:
4588 		interface = &m_vertex;
4589 		break;
4590 	default:
4591 		TCU_FAIL("Invalid enum");
4592 	}
4593 
4594 	return *interface;
4595 }
4596 
4597 /** Clone interface of Vertex shader stage to other stages
4598  * It creates matching inputs, outputs, uniforms and buffers in other stages.
4599  * There are no additional outputs for FRAGMENT shader generated.
4600  *
4601  * @param varying_passthrough Collection of varyings connections
4602  **/
CloneVertexInterface(VaryingPassthrough & varying_passthrough)4603 void ProgramInterface::CloneVertexInterface(VaryingPassthrough& varying_passthrough)
4604 {
4605 	/* VS outputs >> TCS inputs >> TCS outputs >> ..  >> FS inputs */
4606 	for (size_t i = 0; i < m_vertex.m_outputs.size(); ++i)
4607 	{
4608 		const Variable& vs_var = *m_vertex.m_outputs[i];
4609 		const GLchar*   prefix = GetStagePrefix(Shader::VERTEX, vs_var.m_storage);
4610 
4611 		cloneVariableForStage(vs_var, Shader::TESS_CTRL, prefix, varying_passthrough);
4612 		cloneVariableForStage(vs_var, Shader::TESS_EVAL, prefix, varying_passthrough);
4613 		cloneVariableForStage(vs_var, Shader::GEOMETRY, prefix, varying_passthrough);
4614 		cloneVariableForStage(vs_var, Shader::FRAGMENT, prefix, varying_passthrough);
4615 	}
4616 
4617 	/* Copy uniforms from VS to other stages */
4618 	for (size_t i = 0; i < m_vertex.m_uniforms.size(); ++i)
4619 	{
4620 		Variable&	 vs_var = *m_vertex.m_uniforms[i];
4621 		const GLchar* prefix = GetStagePrefix(Shader::VERTEX, vs_var.m_storage);
4622 
4623 		cloneVariableForStage(vs_var, Shader::COMPUTE, prefix, varying_passthrough);
4624 		cloneVariableForStage(vs_var, Shader::TESS_CTRL, prefix, varying_passthrough);
4625 		cloneVariableForStage(vs_var, Shader::TESS_EVAL, prefix, varying_passthrough);
4626 		cloneVariableForStage(vs_var, Shader::GEOMETRY, prefix, varying_passthrough);
4627 		cloneVariableForStage(vs_var, Shader::FRAGMENT, prefix, varying_passthrough);
4628 
4629 		/* Uniform blocks needs unique binding */
4630 		if (true == vs_var.IsBlock())
4631 		{
4632 			replaceBinding(vs_var, Shader::VERTEX);
4633 		}
4634 	}
4635 
4636 	/* Copy SSBs from VS to other stages */
4637 	for (size_t i = 0; i < m_vertex.m_ssb_blocks.size(); ++i)
4638 	{
4639 		Variable&	 vs_var = *m_vertex.m_ssb_blocks[i];
4640 		const GLchar* prefix = GetStagePrefix(Shader::VERTEX, vs_var.m_storage);
4641 
4642 		cloneVariableForStage(vs_var, Shader::COMPUTE, prefix, varying_passthrough);
4643 		cloneVariableForStage(vs_var, Shader::TESS_CTRL, prefix, varying_passthrough);
4644 		cloneVariableForStage(vs_var, Shader::TESS_EVAL, prefix, varying_passthrough);
4645 		cloneVariableForStage(vs_var, Shader::GEOMETRY, prefix, varying_passthrough);
4646 		cloneVariableForStage(vs_var, Shader::FRAGMENT, prefix, varying_passthrough);
4647 
4648 		/* SSBs blocks needs unique binding */
4649 		if (true == vs_var.IsBlock())
4650 		{
4651 			replaceBinding(vs_var, Shader::VERTEX);
4652 		}
4653 	}
4654 
4655 	m_compute.m_globals   = m_vertex.m_globals;
4656 	m_fragment.m_globals  = m_vertex.m_globals;
4657 	m_geometry.m_globals  = m_vertex.m_globals;
4658 	m_tess_ctrl.m_globals = m_vertex.m_globals;
4659 	m_tess_eval.m_globals = m_vertex.m_globals;
4660 }
4661 
4662 /** Clone variable for specific stage
4663  *
4664  * @param variable            Variable
4665  * @param stage               Requested stage
4666  * @param prefix              Prefix used in variable name that is specific for original stage
4667  * @param varying_passthrough Collection of varyings connections
4668  **/
cloneVariableForStage(const Variable & variable,Shader::STAGES stage,const GLchar * prefix,VaryingPassthrough & varying_passthrough)4669 void ProgramInterface::cloneVariableForStage(const Variable& variable, Shader::STAGES stage, const GLchar* prefix,
4670 											 VaryingPassthrough& varying_passthrough)
4671 {
4672 	switch (variable.m_storage)
4673 	{
4674 	case Variable::VARYING_OUTPUT:
4675 	{
4676 		Variable* in = cloneVariableForStage(variable, stage, Variable::VARYING_INPUT, prefix);
4677 
4678 		if (Shader::FRAGMENT != stage)
4679 		{
4680 			Variable* out = cloneVariableForStage(variable, stage, Variable::VARYING_OUTPUT, prefix);
4681 			varying_passthrough.Add(stage, in, out);
4682 		}
4683 	}
4684 	break;
4685 	case Variable::UNIFORM:
4686 	case Variable::SSB:
4687 		cloneVariableForStage(variable, stage, variable.m_storage, prefix);
4688 		break;
4689 	default:
4690 		TCU_FAIL("Invalid enum");
4691 		break;
4692 	}
4693 }
4694 
4695 /** Clone variable for specific stage
4696  *
4697  * @param variable Variable
4698  * @param stage    Requested stage
4699  * @param storage  Storage used by variable
4700  * @param prefix   Prefix used in variable name that is specific for original stage
4701  *
4702  * @return New variable
4703  **/
cloneVariableForStage(const Variable & variable,Shader::STAGES stage,Variable::STORAGE storage,const GLchar * prefix)4704 Variable* ProgramInterface::cloneVariableForStage(const Variable& variable, Shader::STAGES stage,
4705 												  Variable::STORAGE storage, const GLchar* prefix)
4706 {
4707 	/* Initialize with original variable */
4708 	Variable* var = new Variable(variable);
4709 	if (0 == var)
4710 	{
4711 		TCU_FAIL("Memory allocation");
4712 	}
4713 
4714 	/* Set up storage */
4715 	var->m_storage = storage;
4716 
4717 	/* Get name */
4718 	std::string name = variable.m_descriptor.m_name;
4719 
4720 	/* Prefix name with stage ID, empty means default block */
4721 	if (false == name.empty())
4722 	{
4723 		size_t		  position	 = 0;
4724 		const GLchar* stage_prefix = GetStagePrefix(stage, storage);
4725 		Utils::replaceToken(prefix, position, stage_prefix, name);
4726 	}
4727 	var->m_descriptor.m_name = name;
4728 
4729 	/* Clone block */
4730 	const bool is_block = variable.IsBlock();
4731 	if (true == is_block)
4732 	{
4733 		const Interface* interface = variable.m_descriptor.m_interface;
4734 
4735 		Interface* block = CloneBlockForStage(*interface, stage, storage, prefix);
4736 
4737 		var->m_descriptor.m_interface = block;
4738 	}
4739 
4740 	/* Store variable */
4741 	ShaderInterface& si		= GetShaderInterface(stage);
4742 	Variable*		 result = 0;
4743 
4744 	switch (storage)
4745 	{
4746 	case Variable::VARYING_INPUT:
4747 		si.m_inputs.push_back(var);
4748 		result = si.m_inputs.back();
4749 		break;
4750 	case Variable::VARYING_OUTPUT:
4751 		si.m_outputs.push_back(var);
4752 		result = si.m_outputs.back();
4753 		break;
4754 	case Variable::UNIFORM:
4755 		/* Uniform blocks needs unique binding */
4756 		if (true == is_block)
4757 		{
4758 			replaceBinding(*var, stage);
4759 		}
4760 
4761 		si.m_uniforms.push_back(var);
4762 		result = si.m_uniforms.back();
4763 		break;
4764 	case Variable::SSB:
4765 		/* SSBs needs unique binding */
4766 		if (true == is_block)
4767 		{
4768 			replaceBinding(*var, stage);
4769 		}
4770 
4771 		si.m_ssb_blocks.push_back(var);
4772 		result = si.m_ssb_blocks.back();
4773 		break;
4774 	default:
4775 		TCU_FAIL("Invalid enum");
4776 		break;
4777 	}
4778 
4779 	return result;
4780 }
4781 
4782 /** clone block to specific stage
4783  *
4784  * @param block   Block to be copied
4785  * @param stage   Specific stage
4786  * @param storage Storage used by block
4787  * @param prefix  Prefix used in block name
4788  *
4789  * @return New interface
4790  **/
CloneBlockForStage(const Interface & block,Shader::STAGES stage,Variable::STORAGE storage,const GLchar * prefix)4791 Interface* ProgramInterface::CloneBlockForStage(const Interface& block, Shader::STAGES stage, Variable::STORAGE storage,
4792 												const GLchar* prefix)
4793 {
4794 	/* Get name */
4795 	std::string name = block.m_name;
4796 
4797 	/* Prefix name with stage ID */
4798 	size_t		  position	 = 0;
4799 	const GLchar* stage_prefix = GetStagePrefix(stage, storage);
4800 	Utils::replaceToken(prefix, position, stage_prefix, name);
4801 
4802 	Interface* ptr = GetBlock(name.c_str());
4803 
4804 	if (0 == ptr)
4805 	{
4806 		ptr = AddInterface(name.c_str(), Interface::BLOCK);
4807 	}
4808 
4809 	ptr->m_members = block.m_members;
4810 
4811 	return ptr;
4812 }
4813 
4814 /** Get stage specific prefix used in names
4815  *
4816  * @param stage   Stage
4817  * @param storage Storage class
4818  *
4819  * @return String
4820  **/
GetStagePrefix(Shader::STAGES stage,Variable::STORAGE storage)4821 const GLchar* ProgramInterface::GetStagePrefix(Shader::STAGES stage, Variable::STORAGE storage)
4822 {
4823 	static const GLchar* lut[Shader::STAGE_MAX][Variable::STORAGE_MAX] = {
4824 		/*          IN          OUT         UNIFORM     SSB        MEMBER	*/
4825 		/* CS  */ { 0, 0, "cs_uni_", "cs_buf_", "" },
4826 		/* VS  */ { "in_vs_", "vs_tcs_", "vs_uni_", "vs_buf_", "" },
4827 		/* TCS */ { "vs_tcs_", "tcs_tes_", "tcs_uni_", "tcs_buf_", "" },
4828 		/* TES */ { "tcs_tes_", "tes_gs_", "tes_uni_", "tes_buf_", "" },
4829 		/* GS  */ { "tes_gs_", "gs_fs_", "gs_uni_", "gs_buf_", "" },
4830 		/* FS  */ { "gs_fs_", "fs_out_", "fs_uni_", "fs_buf_", "" },
4831 	};
4832 
4833 	const GLchar* result = 0;
4834 
4835 	result = lut[stage][storage];
4836 
4837 	return result;
4838 }
4839 
4840 /** Get definitions of all structures used in program interface
4841  *
4842  * @return String with code
4843  **/
GetDefinitionsStructures() const4844 std::string ProgramInterface::GetDefinitionsStructures() const
4845 {
4846 	return GetDefinitions(m_structures);
4847 }
4848 
4849 /** Get interface code for stage
4850  *
4851  * @param stage Specific stage
4852  *
4853  * @return String with code
4854  **/
GetInterfaceForStage(Shader::STAGES stage) const4855 std::string ProgramInterface::GetInterfaceForStage(Shader::STAGES stage) const
4856 {
4857 	size_t		position  = 0;
4858 	std::string interface = "/* Globals */\n"
4859 							"GLOBALS\n"
4860 							"\n"
4861 							"/* Structures */\n"
4862 							"STRUCTURES\n"
4863 							"\n"
4864 							"/* Uniforms */\n"
4865 							"UNIFORMS\n"
4866 							"\n"
4867 							"/* Inputs */\n"
4868 							"INPUTS\n"
4869 							"\n"
4870 							"/* Outputs */\n"
4871 							"OUTPUTS\n"
4872 							"\n"
4873 							"/* Storage */\n"
4874 							"STORAGE\n";
4875 
4876 	const ShaderInterface& si = GetShaderInterface(stage);
4877 
4878 	const std::string& structures = GetDefinitionsStructures();
4879 
4880 	const std::string& globals  = si.GetDefinitionsGlobals();
4881 	const std::string& inputs   = si.GetDefinitionsInputs();
4882 	const std::string& outputs  = si.GetDefinitionsOutputs();
4883 	const std::string& uniforms = si.GetDefinitionsUniforms();
4884 	const std::string& ssbs		= si.GetDefinitionsSSBs();
4885 
4886 	replaceToken("GLOBALS", position, globals.c_str(), interface);
4887 	replaceToken("STRUCTURES", position, structures.c_str(), interface);
4888 	replaceToken("UNIFORMS", position, uniforms.c_str(), interface);
4889 	replaceToken("INPUTS", position, inputs.c_str(), interface);
4890 	replaceToken("OUTPUTS", position, outputs.c_str(), interface);
4891 	replaceToken("STORAGE", position, ssbs.c_str(), interface);
4892 
4893 	return interface;
4894 }
4895 
4896 /** Functional object used in find_if algorithm, in search for interface of given name
4897  *
4898  **/
4899 struct matchInterfaceName
4900 {
matchInterfaceNamegl4cts::EnhancedLayouts::Utils::matchInterfaceName4901 	matchInterfaceName(const GLchar* name) : m_name(name)
4902 	{
4903 	}
4904 
operator ()gl4cts::EnhancedLayouts::Utils::matchInterfaceName4905 	bool operator()(const Interface* interface)
4906 	{
4907 		return 0 == interface->m_name.compare(m_name);
4908 	}
4909 
4910 	const GLchar* m_name;
4911 };
4912 
4913 /** Finds interface of given name in given vector of interfaces
4914  *
4915  * @param vector Collection of interfaces
4916  * @param name   Requested name
4917  *
4918  * @return Pointer to interface if available, 0 otherwise
4919  **/
findInterfaceByName(Interface::PtrVector & vector,const GLchar * name)4920 static Interface* findInterfaceByName(Interface::PtrVector& vector, const GLchar* name)
4921 {
4922 	Interface::PtrVector::iterator it = std::find_if(vector.begin(), vector.end(), matchInterfaceName(name));
4923 
4924 	if (vector.end() != it)
4925 	{
4926 		return *it;
4927 	}
4928 	else
4929 	{
4930 		return 0;
4931 	}
4932 }
4933 
4934 /** Search for block of given name
4935  *
4936  * @param name Name of block
4937  *
4938  * @return Pointer to block or 0
4939  **/
GetBlock(const GLchar * name)4940 Interface* ProgramInterface::GetBlock(const GLchar* name)
4941 {
4942 	return findInterfaceByName(m_blocks, name);
4943 }
4944 
4945 /** Search for structure of given name
4946  *
4947  * @param name Name of structure
4948  *
4949  * @return Pointer to structure or 0
4950  **/
GetStructure(const GLchar * name)4951 Interface* ProgramInterface::GetStructure(const GLchar* name)
4952 {
4953 	return findInterfaceByName(m_structures, name);
4954 }
4955 
4956 /** Adds new sturcture to interface
4957  *
4958  * @param name Name of structure
4959  *
4960  * @return Created structure
4961  **/
Structure(const GLchar * name)4962 Interface* ProgramInterface::Structure(const GLchar* name)
4963 {
4964 	return AddInterface(name, Interface::STRUCT);
4965 }
4966 
4967 /** Replace "BINDING" token in qualifiers string to value specific for given stage
4968  *
4969  * @param variable Variable to modify
4970  * @param stage    Requested stage
4971  **/
replaceBinding(Variable & variable,Shader::STAGES stage)4972 void ProgramInterface::replaceBinding(Variable& variable, Shader::STAGES stage)
4973 {
4974 	GLchar binding[16];
4975 	sprintf(binding, "%d", stage);
4976 	replaceAllTokens("BINDING", binding, variable.m_descriptor.m_qualifiers);
4977 }
4978 } /* Utils namespace */
4979 
4980 /** Debuging procedure. Logs parameters.
4981  *
4982  * @param source   As specified in GL spec.
4983  * @param type     As specified in GL spec.
4984  * @param id       As specified in GL spec.
4985  * @param severity As specified in GL spec.
4986  * @param ignored
4987  * @param message  As specified in GL spec.
4988  * @param info     Pointer to instance of Context used by test.
4989  */
debug_proc(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei,const GLchar * message,void * info)4990 void GLW_APIENTRY debug_proc(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei /* length */,
4991 							 const GLchar* message, void* info)
4992 {
4993 	deqp::Context* ctx = (deqp::Context*)info;
4994 
4995 	const GLchar* source_str   = "Unknown";
4996 	const GLchar* type_str	 = "Unknown";
4997 	const GLchar* severity_str = "Unknown";
4998 
4999 	switch (source)
5000 	{
5001 	case GL_DEBUG_SOURCE_API:
5002 		source_str = "API";
5003 		break;
5004 	case GL_DEBUG_SOURCE_APPLICATION:
5005 		source_str = "APP";
5006 		break;
5007 	case GL_DEBUG_SOURCE_OTHER:
5008 		source_str = "OTR";
5009 		break;
5010 	case GL_DEBUG_SOURCE_SHADER_COMPILER:
5011 		source_str = "COM";
5012 		break;
5013 	case GL_DEBUG_SOURCE_THIRD_PARTY:
5014 		source_str = "3RD";
5015 		break;
5016 	case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
5017 		source_str = "WS";
5018 		break;
5019 	default:
5020 		break;
5021 	}
5022 
5023 	switch (type)
5024 	{
5025 	case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
5026 		type_str = "DEPRECATED_BEHAVIOR";
5027 		break;
5028 	case GL_DEBUG_TYPE_ERROR:
5029 		type_str = "ERROR";
5030 		break;
5031 	case GL_DEBUG_TYPE_MARKER:
5032 		type_str = "MARKER";
5033 		break;
5034 	case GL_DEBUG_TYPE_OTHER:
5035 		type_str = "OTHER";
5036 		break;
5037 	case GL_DEBUG_TYPE_PERFORMANCE:
5038 		type_str = "PERFORMANCE";
5039 		break;
5040 	case GL_DEBUG_TYPE_POP_GROUP:
5041 		type_str = "POP_GROUP";
5042 		break;
5043 	case GL_DEBUG_TYPE_PORTABILITY:
5044 		type_str = "PORTABILITY";
5045 		break;
5046 	case GL_DEBUG_TYPE_PUSH_GROUP:
5047 		type_str = "PUSH_GROUP";
5048 		break;
5049 	case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
5050 		type_str = "UNDEFINED_BEHAVIOR";
5051 		break;
5052 	default:
5053 		break;
5054 	}
5055 
5056 	switch (severity)
5057 	{
5058 	case GL_DEBUG_SEVERITY_HIGH:
5059 		severity_str = "H";
5060 		break;
5061 	case GL_DEBUG_SEVERITY_LOW:
5062 		severity_str = "L";
5063 		break;
5064 	case GL_DEBUG_SEVERITY_MEDIUM:
5065 		severity_str = "M";
5066 		break;
5067 	case GL_DEBUG_SEVERITY_NOTIFICATION:
5068 		severity_str = "N";
5069 		break;
5070 	default:
5071 		break;
5072 	}
5073 
5074 	ctx->getTestContext().getLog() << tcu::TestLog::Message << "DEBUG_INFO: " << std::setw(3) << source_str << "|"
5075 								   << severity_str << "|" << std::setw(18) << type_str << "|" << std::setw(12) << id
5076 								   << ": " << message << tcu::TestLog::EndMessage;
5077 }
5078 
5079 /** Constructor
5080  *
5081  * @param context          Test context
5082  * @param test_name        Test name
5083  * @param test_description Test description
5084  **/
TestBase(deqp::Context & context,const GLchar * test_name,const GLchar * test_description)5085 TestBase::TestBase(deqp::Context& context, const GLchar* test_name, const GLchar* test_description)
5086 	: TestCase(context, test_name, test_description)
5087 {
5088 	/* Nothing to be done here */
5089 }
5090 
5091 /** Execute test
5092  *
5093  * @return tcu::TestNode::STOP otherwise
5094  **/
iterate()5095 tcu::TestNode::IterateResult TestBase::iterate()
5096 {
5097 	bool test_result;
5098 
5099 #if DEBUG_ENBALE_MESSAGE_CALLBACK
5100 	const Functions& gl = m_context.getRenderContext().getFunctions();
5101 
5102 	gl.debugMessageCallback(debug_proc, &m_context);
5103 	GLU_EXPECT_NO_ERROR(gl.getError(), "DebugMessageCallback");
5104 #endif /* DEBUG_ENBALE_MESSAGE_CALLBACK */
5105 
5106 	try
5107 	{
5108 		/* Execute test */
5109 		test_result = test();
5110 	}
5111 	catch (std::exception& exc)
5112 	{
5113 		TCU_FAIL(exc.what());
5114 	}
5115 
5116 	/* Set result */
5117 	if (true == test_result)
5118 	{
5119 		m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
5120 	}
5121 	else
5122 	{
5123 		m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
5124 	}
5125 
5126 	/* Done */
5127 	return tcu::TestNode::STOP;
5128 }
5129 
5130 /** Get last input location available for given type at specific stage
5131  *
5132  * @param stage        Shader stage
5133  * @param type         Input type
5134  * @param array_length Length of input array
5135  *
5136  * @return Last location index
5137  **/
getLastInputLocation(Utils::Shader::STAGES stage,const Utils::Type & type,GLuint array_length,bool ignore_prev_stage)5138 GLint TestBase::getLastInputLocation(Utils::Shader::STAGES stage, const Utils::Type& type, GLuint array_length, bool ignore_prev_stage)
5139 {
5140 	GLint  divide		= 4; /* 4 components per location */
5141 	GLint  param		= 0;
5142 	GLenum pname		= 0;
5143 	GLint  paramPrev	= 0;
5144 	GLenum pnamePrev	= 0;
5145 
5146 	/* Select pnmae */
5147 	switch (stage)
5148 	{
5149 	case Utils::Shader::FRAGMENT:
5150 		pname = GL_MAX_FRAGMENT_INPUT_COMPONENTS;
5151 		pnamePrev = GL_MAX_GEOMETRY_OUTPUT_COMPONENTS;
5152 		break;
5153 	case Utils::Shader::GEOMETRY:
5154 		pname = GL_MAX_GEOMETRY_INPUT_COMPONENTS;
5155 		pnamePrev = GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS;
5156 		break;
5157 	case Utils::Shader::TESS_CTRL:
5158 		pname = GL_MAX_TESS_CONTROL_INPUT_COMPONENTS;
5159 		pnamePrev = GL_MAX_VERTEX_OUTPUT_COMPONENTS;
5160 		break;
5161 	case Utils::Shader::TESS_EVAL:
5162 		pname = GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS;
5163 		pnamePrev = GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS;
5164 		break;
5165 	case Utils::Shader::VERTEX:
5166 		pname  = GL_MAX_VERTEX_ATTRIBS;
5167 		divide = 1;
5168 		break;
5169 	default:
5170 		TCU_FAIL("Invalid enum");
5171 		break;
5172 	}
5173 
5174 	/* Zero means no array, but 1 slot is required */
5175 	if (0 == array_length)
5176 	{
5177 		array_length += 1;
5178 	}
5179 
5180 	/* Get MAX */
5181 	const Functions& gl = m_context.getRenderContext().getFunctions();
5182 
5183 	gl.getIntegerv(pname, &param);
5184 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
5185 
5186 	if (pnamePrev && !ignore_prev_stage) {
5187 		gl.getIntegerv(pnamePrev, &paramPrev);
5188 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
5189 
5190 		/* Don't read from a location that doesn't exist in the previous stage */
5191 		param = de::min(param, paramPrev);
5192 	}
5193 
5194 /* Calculate */
5195 #if WRKARD_VARYINGLOCATIONSTEST
5196 
5197 	const GLint n_avl_locations = 16;
5198 
5199 #else
5200 
5201 	const GLint n_avl_locations = param / divide;
5202 
5203 #endif
5204 
5205 	const GLuint n_req_location = type.GetLocations(stage == Utils::Shader::VERTEX) * array_length;
5206 
5207 	return n_avl_locations - n_req_location; /* last is max - 1 */
5208 }
5209 
5210 /** Get last output location available for given type at specific stage
5211  *
5212  * @param stage        Shader stage
5213  * @param type         Input type
5214  * @param array_length Length of input array
5215  *
5216  * @return Last location index
5217  **/
getLastOutputLocation(Utils::Shader::STAGES stage,const Utils::Type & type,GLuint array_length,bool ignore_next_stage)5218 GLint TestBase::getLastOutputLocation(Utils::Shader::STAGES stage, const Utils::Type& type, GLuint array_length, bool ignore_next_stage)
5219 {
5220 	GLint  param		= 0;
5221 	GLenum pname		= 0;
5222 	GLint  paramNext	= 0;
5223 	GLenum pnameNext	= 0;
5224 
5225 	/* Select pname */
5226 	switch (stage)
5227 	{
5228 	case Utils::Shader::GEOMETRY:
5229 		pname = GL_MAX_GEOMETRY_OUTPUT_COMPONENTS;
5230 		pnameNext = GL_MAX_FRAGMENT_INPUT_COMPONENTS;
5231 		break;
5232 	case Utils::Shader::TESS_CTRL:
5233 		pname = GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS;
5234 		pnameNext = GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS;
5235 		break;
5236 	case Utils::Shader::TESS_EVAL:
5237 		pname = GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS;
5238 		pnameNext = GL_MAX_GEOMETRY_INPUT_COMPONENTS;
5239 		break;
5240 	case Utils::Shader::VERTEX:
5241 		pname = GL_MAX_VERTEX_OUTPUT_COMPONENTS;
5242 		pnameNext = GL_MAX_TESS_CONTROL_INPUT_COMPONENTS;
5243 		break;
5244 	default:
5245 		TCU_FAIL("Invalid enum");
5246 		break;
5247 	}
5248 
5249 	/* Zero means no array, but 1 slot is required */
5250 	if (0 == array_length)
5251 	{
5252 		array_length += 1;
5253 	}
5254 
5255 	/* Get MAX */
5256 	const Functions& gl = m_context.getRenderContext().getFunctions();
5257 
5258 	gl.getIntegerv(pname, &param);
5259 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
5260 
5261 /* Calculate */
5262 #if WRKARD_VARYINGLOCATIONSTEST
5263 
5264 	const GLint n_avl_locations = 16;
5265 
5266 #else
5267 
5268 	/* Don't write to a location that doesn't exist in the next stage */
5269 	if (!ignore_next_stage)
5270 	{
5271 		gl.getIntegerv(pnameNext, &paramNext);
5272 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
5273 
5274 		param = de::min(param, paramNext);
5275 	}
5276 
5277 	const GLint n_avl_locations = param / 4; /* 4 components per location */
5278 
5279 #endif
5280 
5281 	const GLuint n_req_location = type.GetLocations() * array_length;
5282 
5283 	return n_avl_locations - n_req_location; /* last is max - 1 */
5284 }
5285 
5286 /** Basic implementation
5287  *
5288  * @param ignored
5289  *
5290  * @return Empty string
5291  **/
getTestCaseName(GLuint)5292 std::string TestBase::getTestCaseName(GLuint /* test_case_index */)
5293 {
5294 	std::string result;
5295 
5296 	return result;
5297 }
5298 
5299 /** Basic implementation
5300  *
5301  * @return 1
5302  **/
getTestCaseNumber()5303 GLuint TestBase::getTestCaseNumber()
5304 {
5305 	return 1;
5306 }
5307 
5308 /** Check if flat qualifier is required for given type, stage and storage
5309  *
5310  * @param stage        Shader stage
5311  * @param type         Input type
5312  * @param storage      Storage of variable
5313  *
5314  * @return Last location index
5315  **/
isFlatRequired(Utils::Shader::STAGES stage,const Utils::Type & type,Utils::Variable::STORAGE storage,const bool coherent) const5316 bool TestBase::isFlatRequired(Utils::Shader::STAGES stage, const Utils::Type& type, Utils::Variable::STORAGE storage,
5317 							  const bool coherent) const
5318 {
5319 	/* Float types do not need flat at all */
5320 	if (Utils::Type::Float == type.m_basic_type)
5321 	{
5322 		return false;
5323 	}
5324 
5325 	/* Inputs to fragment shader */
5326 	if ((Utils::Shader::FRAGMENT == stage) && (Utils::Variable::VARYING_INPUT == storage))
5327 	{
5328 		return true;
5329 	}
5330 
5331 	/* Outputs from geometry shader
5332 	 *
5333 	 * This is not strictly needed since fragment shader input
5334 	 * interpolation qualifiers will override whatever comes from the
5335 	 * previous stage. However, if we want to have a coherent
5336 	 * interface, let's better do it.
5337 	 */
5338 	if ((Utils::Shader::GEOMETRY == stage) && (Utils::Variable::VARYING_OUTPUT == storage) && coherent)
5339 	{
5340 		return true;
5341 	}
5342 
5343 	return false;
5344 }
5345 
5346 /** Basic implementation of testInit method
5347  *
5348  **/
testInit()5349 void TestBase::testInit()
5350 {
5351 }
5352 
5353 /** Calculate stride for interface
5354  *
5355  * @param interface Interface
5356  *
5357  * @return Calculated value
5358  **/
calculateStride(const Utils::Interface & interface) const5359 GLuint TestBase::calculateStride(const Utils::Interface& interface) const
5360 {
5361 	const size_t n_members = interface.m_members.size();
5362 
5363 	GLuint stride = 0;
5364 
5365 	for (size_t i = 0; i < n_members; ++i)
5366 	{
5367 		const Utils::Variable::Descriptor& member		  = interface.m_members[i];
5368 		const GLuint					   member_offset  = member.m_offset;
5369 		const GLuint					   member_stride  = member.m_expected_stride_of_element;
5370 		const GLuint					   member_ends_at = member_offset + member_stride;
5371 
5372 		stride = std::max(stride, member_ends_at);
5373 	}
5374 
5375 	return stride;
5376 }
5377 
5378 /** Generate data for interface. This routine is recursive
5379  *
5380  * @param interface Interface
5381  * @param offset    Offset in out_data
5382  * @param out_data  Buffer to be filled
5383  **/
generateData(const Utils::Interface & interface,GLuint offset,std::vector<GLubyte> & out_data) const5384 void TestBase::generateData(const Utils::Interface& interface, GLuint offset, std::vector<GLubyte>& out_data) const
5385 {
5386 	const size_t n_members = interface.m_members.size();
5387 	GLubyte*	 ptr	   = &out_data[offset];
5388 
5389 	for (size_t i = 0; i < n_members; ++i)
5390 	{
5391 		const Utils::Variable::Descriptor& member		 = interface.m_members[i];
5392 		const GLuint					   member_offset = member.m_offset;
5393 		const GLuint n_elements = (0 == member.m_n_array_elements) ? 1 : member.m_n_array_elements;
5394 
5395 		for (GLuint element = 0; element < n_elements; ++element)
5396 		{
5397 			const GLuint element_offset = element * member.m_expected_stride_of_element;
5398 			const GLuint data_offfset   = member_offset + element_offset;
5399 
5400 			if (Utils::Variable::BUILTIN == member.m_type)
5401 			{
5402 				const std::vector<GLubyte>& data = member.m_builtin.GenerateData();
5403 
5404 				memcpy(ptr + data_offfset, &data[0], data.size());
5405 			}
5406 			else
5407 			{
5408 				generateData(*member.m_interface, offset + data_offfset, out_data);
5409 			}
5410 		}
5411 	}
5412 }
5413 
5414 /** Get type at index
5415  *
5416  * @param index Index of requested type
5417  *
5418  * @return Type
5419  **/
getType(GLuint index) const5420 Utils::Type TestBase::getType(GLuint index) const
5421 {
5422 	Utils::Type type;
5423 
5424 	switch (index)
5425 	{
5426 	case 0:
5427 		type = Utils::Type::_double;
5428 		break;
5429 	case 1:
5430 		type = Utils::Type::dmat2;
5431 		break;
5432 	case 2:
5433 		type = Utils::Type::dmat2x3;
5434 		break;
5435 	case 3:
5436 		type = Utils::Type::dmat2x4;
5437 		break;
5438 	case 4:
5439 		type = Utils::Type::dmat3;
5440 		break;
5441 	case 5:
5442 		type = Utils::Type::dmat3x2;
5443 		break;
5444 	case 6:
5445 		type = Utils::Type::dmat3x4;
5446 		break;
5447 	case 7:
5448 		type = Utils::Type::dmat4;
5449 		break;
5450 	case 8:
5451 		type = Utils::Type::dmat4x2;
5452 		break;
5453 	case 9:
5454 		type = Utils::Type::dmat4x3;
5455 		break;
5456 	case 10:
5457 		type = Utils::Type::dvec2;
5458 		break;
5459 	case 11:
5460 		type = Utils::Type::dvec3;
5461 		break;
5462 	case 12:
5463 		type = Utils::Type::dvec4;
5464 		break;
5465 	case 13:
5466 		type = Utils::Type::_float;
5467 		break;
5468 	case 14:
5469 		type = Utils::Type::mat2;
5470 		break;
5471 	case 15:
5472 		type = Utils::Type::mat2x3;
5473 		break;
5474 	case 16:
5475 		type = Utils::Type::mat2x4;
5476 		break;
5477 	case 17:
5478 		type = Utils::Type::mat3;
5479 		break;
5480 	case 18:
5481 		type = Utils::Type::mat3x2;
5482 		break;
5483 	case 19:
5484 		type = Utils::Type::mat3x4;
5485 		break;
5486 	case 20:
5487 		type = Utils::Type::mat4;
5488 		break;
5489 	case 21:
5490 		type = Utils::Type::mat4x2;
5491 		break;
5492 	case 22:
5493 		type = Utils::Type::mat4x3;
5494 		break;
5495 	case 23:
5496 		type = Utils::Type::vec2;
5497 		break;
5498 	case 24:
5499 		type = Utils::Type::vec3;
5500 		break;
5501 	case 25:
5502 		type = Utils::Type::vec4;
5503 		break;
5504 	case 26:
5505 		type = Utils::Type::_int;
5506 		break;
5507 	case 27:
5508 		type = Utils::Type::ivec2;
5509 		break;
5510 	case 28:
5511 		type = Utils::Type::ivec3;
5512 		break;
5513 	case 29:
5514 		type = Utils::Type::ivec4;
5515 		break;
5516 	case 30:
5517 		type = Utils::Type::uint;
5518 		break;
5519 	case 31:
5520 		type = Utils::Type::uvec2;
5521 		break;
5522 	case 32:
5523 		type = Utils::Type::uvec3;
5524 		break;
5525 	case 33:
5526 		type = Utils::Type::uvec4;
5527 		break;
5528 	default:
5529 		TCU_FAIL("invalid enum");
5530 	}
5531 
5532 	return type;
5533 }
5534 
5535 /** Get name of type at index
5536  *
5537  * @param index Index of type
5538  *
5539  * @return Name
5540  **/
getTypeName(GLuint index) const5541 std::string TestBase::getTypeName(GLuint index) const
5542 {
5543 	std::string name = getType(index).GetGLSLTypeName();
5544 
5545 	return name;
5546 }
5547 
5548 /** Get number of types
5549  *
5550  * @return 34
5551  **/
getTypesNumber() const5552 glw::GLuint TestBase::getTypesNumber() const
5553 {
5554 	return 34;
5555 }
5556 
5557 /** Execute test
5558  *
5559  * @return true if test pass, false otherwise
5560  **/
test()5561 bool TestBase::test()
5562 {
5563 	bool   result		= true;
5564 	GLuint n_test_cases = 0;
5565 
5566 	/* Prepare test */
5567 	testInit();
5568 
5569 	/* GL entry points */
5570 	const Functions& gl = m_context.getRenderContext().getFunctions();
5571 
5572 	/* Tessellation patch set up */
5573 	gl.patchParameteri(GL_PATCH_VERTICES, 1);
5574 	GLU_EXPECT_NO_ERROR(gl.getError(), "PatchParameteri");
5575 
5576 	/* Get number of test cases */
5577 	n_test_cases = getTestCaseNumber();
5578 
5579 #if DEBUG_REPEAT_TEST_CASE
5580 
5581 	while (1)
5582 	{
5583 		GLuint test_case = DEBUG_REPEATED_TEST_CASE;
5584 
5585 #else /* DEBUG_REPEAT_TEST_CASE */
5586 
5587 	for (GLuint test_case = 0; test_case < n_test_cases; ++test_case)
5588 	{
5589 #endif /* DEBUG_REPEAT_TEST_CASE */
5590 
5591 		/* Execute case */
5592 		if (!testCase(test_case))
5593 		{
5594 			const std::string& test_case_name = getTestCaseName(test_case);
5595 
5596 			if (false == test_case_name.empty())
5597 			{
5598 				m_context.getTestContext().getLog() << tcu::TestLog::Message << "Test case (" << test_case_name
5599 													<< ") failed." << tcu::TestLog::EndMessage;
5600 			}
5601 			else
5602 			{
5603 				m_context.getTestContext().getLog() << tcu::TestLog::Message << "Test case (" << test_case
5604 													<< ") failed." << tcu::TestLog::EndMessage;
5605 			}
5606 
5607 			result = false;
5608 		}
5609 	}
5610 
5611 	/* Done */
5612 	return result;
5613 }
5614 
5615 /* Constants used by BufferTestBase */
5616 const GLuint BufferTestBase::bufferDescriptor::m_non_indexed = -1;
5617 
5618 /** Constructor
5619  *
5620  * @param context          Test context
5621  * @param test_name        Name of test
5622  * @param test_description Description of test
5623  **/
5624 BufferTestBase::BufferTestBase(deqp::Context& context, const GLchar* test_name, const GLchar* test_description)
5625 	: TestBase(context, test_name, test_description)
5626 {
5627 }
5628 
5629 /** Execute drawArrays for single vertex
5630  *
5631  * @param ignored
5632  *
5633  * @return true
5634  **/
5635 bool BufferTestBase::executeDrawCall(bool tesEnabled, GLuint /* test_case_index */)
5636 {
5637 	const Functions& gl = m_context.getRenderContext().getFunctions();
5638 
5639 	gl.disable(GL_RASTERIZER_DISCARD);
5640 	GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
5641 
5642 	gl.beginTransformFeedback(GL_POINTS);
5643 	GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
5644 
5645 	// Only TES is existed, glDrawArray can use the parameter GL_PATCHES
5646 	if (tesEnabled == false)
5647 	{
5648 		gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */);
5649 	}
5650 	else
5651 	{
5652 		gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
5653 	}
5654 
5655 	GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
5656 
5657 	gl.endTransformFeedback();
5658 	GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
5659 
5660 	return true;
5661 }
5662 
5663 /** Get descriptors of buffers necessary for test
5664  *
5665  * @param ignored
5666  * @param ignored
5667  **/
5668 void BufferTestBase::getBufferDescriptors(glw::GLuint /* test_case_index */,
5669 										  bufferDescriptor::Vector& /* out_descriptors */)
5670 {
5671 	/* Nothhing to be done */
5672 }
5673 
5674 /** Get list of names of varyings that will be registered with TransformFeedbackVaryings
5675  *
5676  * @param ignored
5677  * @param ignored
5678  **/
5679 void BufferTestBase::getCapturedVaryings(glw::GLuint /* test_case_index */,
5680 										 Utils::Program::NameVector& /* captured_varyings */,
5681 										 GLint* /* xfb_components */)
5682 {
5683 	/* Nothing to be done */
5684 }
5685 
5686 /** Get body of main function for given shader stage
5687  *
5688  * @param ignored
5689  * @param ignored
5690  * @param out_assignments  Set to empty
5691  * @param out_calculations Set to empty
5692  **/
5693 void BufferTestBase::getShaderBody(glw::GLuint /* test_case_index */, Utils::Shader::STAGES /* stage */,
5694 								   std::string& out_assignments, std::string& out_calculations)
5695 {
5696 	out_assignments  = "";
5697 	out_calculations = "";
5698 }
5699 
5700 /** Get interface of shader
5701  *
5702  * @param ignored
5703  * @param ignored
5704  * @param out_interface Set to ""
5705  **/
5706 void BufferTestBase::getShaderInterface(glw::GLuint /* test_case_index */, Utils::Shader::STAGES /* stage */,
5707 										std::string& out_interface)
5708 {
5709 	out_interface = "";
5710 }
5711 
5712 /** Get source code of shader
5713  *
5714  * @param test_case_index Index of test case
5715  * @param stage           Shader stage
5716  *
5717  * @return Source
5718  **/
5719 std::string BufferTestBase::getShaderSource(glw::GLuint test_case_index, Utils::Shader::STAGES stage)
5720 {
5721 	std::string assignments;
5722 	std::string calculations;
5723 	std::string interface;
5724 
5725 	/* */
5726 	getShaderBody(test_case_index, stage, assignments, calculations);
5727 	getShaderInterface(test_case_index, stage, interface);
5728 
5729 	/* */
5730 	std::string source = getShaderTemplate(stage);
5731 
5732 	/* */
5733 	size_t position = 0;
5734 	Utils::replaceToken("INTERFACE", position, interface.c_str(), source);
5735 	Utils::replaceToken("CALCULATIONS", position, calculations.c_str(), source);
5736 	Utils::replaceToken("ASSIGNMENTS", position, assignments.c_str(), source);
5737 
5738 	/* */
5739 	return source;
5740 }
5741 
5742 /** Inspects program to check if all resources are as expected
5743  *
5744  * @param ignored
5745  * @param ignored
5746  * @param ignored
5747  *
5748  * @return true
5749  **/
5750 bool BufferTestBase::inspectProgram(GLuint /* test_case_index */, Utils::Program& /* program */,
5751 									std::stringstream& /* out_stream */)
5752 {
5753 	return true;
5754 }
5755 
5756 /** Runs test case
5757  *
5758  * @param test_case_index Id of test case
5759  *
5760  * @return true if test case pass, false otherwise
5761  **/
5762 bool BufferTestBase::testCase(GLuint test_case_index)
5763 {
5764 	try
5765 	{
5766 		bufferCollection		   buffers;
5767 		Utils::Program::NameVector captured_varyings;
5768 		bufferDescriptor::Vector   descriptors;
5769 		Utils::Program			   program(m_context);
5770 		Utils::VertexArray		   vao(m_context);
5771 
5772 		/* Get captured varyings */
5773 		GLint xfb_components;
5774 		getCapturedVaryings(test_case_index, captured_varyings, &xfb_components);
5775 
5776 		/* Don't generate shaders that try to capture more XFB components than the implementation's limit */
5777 		if (captured_varyings.size() > 0)
5778 		{
5779 			const Functions& gl	= m_context.getRenderContext().getFunctions();
5780 
5781 			GLint max_xfb_components;
5782 			gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_xfb_components);
5783 			GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
5784 
5785 			if (xfb_components > max_xfb_components)
5786 				return true;
5787 		}
5788 
5789 		/* Get shader sources */
5790 		const std::string& fragment_shader  = getShaderSource(test_case_index, Utils::Shader::FRAGMENT);
5791 		const std::string& geometry_shader  = getShaderSource(test_case_index, Utils::Shader::GEOMETRY);
5792 		const std::string& tess_ctrl_shader = getShaderSource(test_case_index, Utils::Shader::TESS_CTRL);
5793 		const std::string& tess_eval_shader = getShaderSource(test_case_index, Utils::Shader::TESS_EVAL);
5794 		const std::string& vertex_shader	= getShaderSource(test_case_index, Utils::Shader::VERTEX);
5795 
5796 		/* Set up program */
5797 		program.Init("" /* compute_shader */, fragment_shader, geometry_shader, tess_ctrl_shader, tess_eval_shader,
5798 					 vertex_shader, captured_varyings, true, false /* is_separable */);
5799 
5800 		/* Inspection */
5801 		{
5802 			std::stringstream stream;
5803 			if (false == inspectProgram(test_case_index, program, stream))
5804 			{
5805 				m_context.getTestContext().getLog()
5806 					<< tcu::TestLog::Message
5807 					<< "Program inspection failed. Test case: " << getTestCaseName(test_case_index)
5808 					<< ". Reason: " << stream.str() << tcu::TestLog::EndMessage
5809 					<< tcu::TestLog::KernelSource(vertex_shader) << tcu::TestLog::KernelSource(tess_ctrl_shader)
5810 					<< tcu::TestLog::KernelSource(tess_eval_shader) << tcu::TestLog::KernelSource(geometry_shader)
5811 					<< tcu::TestLog::KernelSource(fragment_shader);
5812 
5813 				return false;
5814 			}
5815 		}
5816 
5817 		program.Use();
5818 
5819 		/* Set up buffers */
5820 		getBufferDescriptors(test_case_index, descriptors);
5821 		cleanBuffers();
5822 		prepareBuffers(descriptors, buffers);
5823 
5824 		/* Set up vao */
5825 		vao.Init();
5826 		vao.Bind();
5827 
5828 		/* Draw */
5829 		bool result = executeDrawCall((program.m_tess_eval.m_id != 0), test_case_index);
5830 
5831 #if USE_NSIGHT
5832 		m_context.getRenderContext().postIterate();
5833 #endif
5834 
5835 		if (false == result)
5836 		{
5837 			m_context.getTestContext().getLog()
5838 				<< tcu::TestLog::KernelSource(vertex_shader) << tcu::TestLog::KernelSource(tess_ctrl_shader)
5839 				<< tcu::TestLog::KernelSource(tess_eval_shader) << tcu::TestLog::KernelSource(geometry_shader)
5840 				<< tcu::TestLog::KernelSource(fragment_shader);
5841 
5842 			return false;
5843 		}
5844 
5845 		/* Verify result */
5846 		if (false == verifyBuffers(buffers))
5847 		{
5848 			m_context.getTestContext().getLog()
5849 				<< tcu::TestLog::KernelSource(vertex_shader) << tcu::TestLog::KernelSource(tess_ctrl_shader)
5850 				<< tcu::TestLog::KernelSource(tess_eval_shader) << tcu::TestLog::KernelSource(geometry_shader)
5851 				<< tcu::TestLog::KernelSource(fragment_shader);
5852 
5853 			return false;
5854 		}
5855 	}
5856 	catch (Utils::Shader::InvalidSourceException& exc)
5857 	{
5858 		exc.log(m_context);
5859 		TCU_FAIL(exc.what());
5860 	}
5861 	catch (Utils::Program::BuildException& exc)
5862 	{
5863 		exc.log(m_context);
5864 		TCU_FAIL(exc.what());
5865 	}
5866 
5867 	/* Done */
5868 	return true;
5869 }
5870 
5871 /** Verify contents of buffers
5872  *
5873  * @param buffers Collection of buffers to be verified
5874  *
5875  * @return true if everything is as expected, false otherwise
5876  **/
5877 bool BufferTestBase::verifyBuffers(bufferCollection& buffers)
5878 {
5879 	bool result = true;
5880 
5881 	for (bufferCollection::Vector::iterator it = buffers.m_vector.begin(), end = buffers.m_vector.end(); end != it;
5882 		 ++it)
5883 	{
5884 		bufferCollection::pair& pair	   = *it;
5885 		Utils::Buffer*			buffer	 = pair.m_buffer;
5886 		bufferDescriptor*		descriptor = pair.m_descriptor;
5887 		size_t					size	   = descriptor->m_expected_data.size();
5888 
5889 		/* Skip buffers that have no expected data */
5890 		if (0 == size)
5891 		{
5892 			continue;
5893 		}
5894 
5895 		/* Get pointer to contents of buffer */
5896 		buffer->Bind();
5897 		GLvoid* buffer_data = buffer->Map(Utils::Buffer::ReadOnly);
5898 
5899 		/* Get pointer to expected data */
5900 		GLvoid* expected_data = &descriptor->m_expected_data[0];
5901 
5902 		/* Compare */
5903 		int res = memcmp(buffer_data, expected_data, size);
5904 
5905 		if (0 != res)
5906 		{
5907 			m_context.getTestContext().getLog()
5908 				<< tcu::TestLog::Message
5909 				<< "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
5910 				<< ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
5911 
5912 			result = false;
5913 		}
5914 
5915 		/* Release buffer mapping */
5916 		buffer->UnMap();
5917 	}
5918 
5919 	return result;
5920 }
5921 
5922 /** Unbinds all uniforms and xfb
5923  *
5924  **/
5925 void BufferTestBase::cleanBuffers()
5926 {
5927 	const Functions& gl = m_context.getRenderContext().getFunctions();
5928 
5929 	GLint max_uni = 0;
5930 	GLint max_xfb = 0;
5931 
5932 	gl.getIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &max_uni);
5933 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_xfb);
5934 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
5935 
5936 	for (GLint i = 0; i < max_uni; ++i)
5937 	{
5938 		Utils::Buffer::BindBase(gl, 0, Utils::Buffer::Uniform, i);
5939 	}
5940 
5941 	for (GLint i = 0; i < max_xfb; ++i)
5942 	{
5943 		Utils::Buffer::BindBase(gl, 0, Utils::Buffer::Transform_feedback, i);
5944 	}
5945 }
5946 
5947 /** Get template of shader for given stage
5948  *
5949  * @param stage Stage
5950  *
5951  * @return Template of shader source
5952  **/
5953 std::string BufferTestBase::getShaderTemplate(Utils::Shader::STAGES stage)
5954 {
5955 	static const GLchar* compute_shader_template = "#version 430 core\n"
5956 												   "#extension GL_ARB_enhanced_layouts : require\n"
5957 												   "\n"
5958 												   "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
5959 												   "\n"
5960 												   "writeonly uniform uimage2D uni_image;\n"
5961 												   "\n"
5962 												   "INTERFACE"
5963 												   "\n"
5964 												   "void main()\n"
5965 												   "{\n"
5966 												   "CALCULATIONS"
5967 												   "\n"
5968 												   "ASSIGNMENTS"
5969 												   "}\n"
5970 												   "\n";
5971 
5972 	static const GLchar* fragment_shader_template = "#version 430 core\n"
5973 													"#extension GL_ARB_enhanced_layouts : require\n"
5974 													"\n"
5975 													"INTERFACE"
5976 													"\n"
5977 													"void main()\n"
5978 													"{\n"
5979 													"CALCULATIONS"
5980 													"\n"
5981 													"ASSIGNMENTS"
5982 													"}\n"
5983 													"\n";
5984 
5985 	// max_vertices is set to 3 for the test case "xfb_vertex_streams" declares 3 streams in geometry shader,
5986 	// according to spec, max_vertices should be no less than 3 if there are 3 streams in GS.
5987 	static const GLchar* geometry_shader_template = "#version 430 core\n"
5988 													"#extension GL_ARB_enhanced_layouts : require\n"
5989 													"\n"
5990 													"layout(points)                   in;\n"
5991 													"layout(points, max_vertices = 3) out;\n"
5992 													"\n"
5993 													"INTERFACE"
5994 													"\n"
5995 													"void main()\n"
5996 													"{\n"
5997 													"CALCULATIONS"
5998 													"\n"
5999 													"\n"
6000 													"ASSIGNMENTS"
6001 													"    gl_Position  = vec4(0, 0, 0, 1);\n"
6002 													"    EmitVertex();\n"
6003 													"}\n"
6004 													"\n";
6005 
6006 	static const GLchar* tess_ctrl_shader_template = "#version 430 core\n"
6007 													 "#extension GL_ARB_enhanced_layouts : require\n"
6008 													 "\n"
6009 													 "layout(vertices = 1) out;\n"
6010 													 "\n"
6011 													 "INTERFACE"
6012 													 "\n"
6013 													 "void main()\n"
6014 													 "{\n"
6015 													 "CALCULATIONS"
6016 													 "\n"
6017 													 "ASSIGNMENTS"
6018 													 "\n"
6019 													 "    gl_TessLevelOuter[0] = 1.0;\n"
6020 													 "    gl_TessLevelOuter[1] = 1.0;\n"
6021 													 "    gl_TessLevelOuter[2] = 1.0;\n"
6022 													 "    gl_TessLevelOuter[3] = 1.0;\n"
6023 													 "    gl_TessLevelInner[0] = 1.0;\n"
6024 													 "    gl_TessLevelInner[1] = 1.0;\n"
6025 													 "}\n"
6026 													 "\n";
6027 
6028 	static const GLchar* tess_eval_shader_template = "#version 430 core\n"
6029 													 "#extension GL_ARB_enhanced_layouts : require\n"
6030 													 "\n"
6031 													 "layout(isolines, point_mode) in;\n"
6032 													 "\n"
6033 													 "INTERFACE"
6034 													 "\n"
6035 													 "void main()\n"
6036 													 "{\n"
6037 													 "CALCULATIONS"
6038 													 "\n"
6039 													 "ASSIGNMENTS"
6040 													 "}\n"
6041 													 "\n";
6042 
6043 	static const GLchar* vertex_shader_template = "#version 430 core\n"
6044 												  "#extension GL_ARB_enhanced_layouts : require\n"
6045 												  "\n"
6046 												  "INTERFACE"
6047 												  "\n"
6048 												  "void main()\n"
6049 												  "{\n"
6050 												  "CALCULATIONS"
6051 												  "\n"
6052 												  "ASSIGNMENTS"
6053 												  "}\n"
6054 												  "\n";
6055 
6056 	const GLchar* result = 0;
6057 
6058 	switch (stage)
6059 	{
6060 	case Utils::Shader::COMPUTE:
6061 		result = compute_shader_template;
6062 		break;
6063 	case Utils::Shader::FRAGMENT:
6064 		result = fragment_shader_template;
6065 		break;
6066 	case Utils::Shader::GEOMETRY:
6067 		result = geometry_shader_template;
6068 		break;
6069 	case Utils::Shader::TESS_CTRL:
6070 		result = tess_ctrl_shader_template;
6071 		break;
6072 	case Utils::Shader::TESS_EVAL:
6073 		result = tess_eval_shader_template;
6074 		break;
6075 	case Utils::Shader::VERTEX:
6076 		result = vertex_shader_template;
6077 		break;
6078 	default:
6079 		TCU_FAIL("Invalid enum");
6080 	}
6081 
6082 	return result;
6083 }
6084 
6085 /** Prepare buffer according to descriptor
6086  *
6087  * @param buffer Buffer to prepare
6088  * @param desc   Descriptor
6089  **/
6090 void BufferTestBase::prepareBuffer(Utils::Buffer& buffer, bufferDescriptor& desc)
6091 {
6092 	GLsizeiptr size = 0;
6093 	GLvoid*	data = 0;
6094 
6095 	if (false == desc.m_initial_data.empty())
6096 	{
6097 		size = desc.m_initial_data.size();
6098 		data = &desc.m_initial_data[0];
6099 	}
6100 	else if (false == desc.m_expected_data.empty())
6101 	{
6102 		size = desc.m_expected_data.size();
6103 	}
6104 
6105 	buffer.Init(desc.m_target, Utils::Buffer::StaticDraw, size, data);
6106 
6107 	if (bufferDescriptor::m_non_indexed != desc.m_index)
6108 	{
6109 		buffer.BindBase(desc.m_index);
6110 	}
6111 	else
6112 	{
6113 		buffer.Bind();
6114 	}
6115 }
6116 
6117 /** Prepare collection of buffer
6118  *
6119  * @param descriptors Collection of descriptors
6120  * @param out_buffers Collection of buffers
6121  **/
6122 void BufferTestBase::prepareBuffers(bufferDescriptor::Vector& descriptors, bufferCollection& out_buffers)
6123 {
6124 	for (bufferDescriptor::Vector::iterator it = descriptors.begin(), end = descriptors.end(); end != it; ++it)
6125 	{
6126 		bufferCollection::pair pair;
6127 
6128 		pair.m_buffer = new Utils::Buffer(m_context);
6129 		if (0 == pair.m_buffer)
6130 		{
6131 			TCU_FAIL("Memory allocation failed");
6132 		}
6133 
6134 		pair.m_descriptor = &(*it);
6135 
6136 		prepareBuffer(*pair.m_buffer, *pair.m_descriptor);
6137 
6138 		out_buffers.m_vector.push_back(pair);
6139 	}
6140 }
6141 
6142 /** Destructor
6143  *
6144  **/
6145 BufferTestBase::bufferCollection::~bufferCollection()
6146 {
6147 	for (Vector::iterator it = m_vector.begin(), end = m_vector.end(); end != it; ++it)
6148 	{
6149 		if (0 != it->m_buffer)
6150 		{
6151 			delete it->m_buffer;
6152 			it->m_buffer = 0;
6153 		}
6154 	}
6155 }
6156 
6157 /** Constructor
6158  *
6159  * @param context          Test context
6160  * @param test_name        Name of test
6161  * @param test_description Description of test
6162  **/
6163 NegativeTestBase::NegativeTestBase(deqp::Context& context, const GLchar* test_name, const GLchar* test_description)
6164 	: TestBase(context, test_name, test_description)
6165 {
6166 }
6167 
6168 /** Selects if "compute" stage is relevant for test
6169  *
6170  * @param ignored
6171  *
6172  * @return true
6173  **/
6174 bool NegativeTestBase::isComputeRelevant(GLuint /* test_case_index */)
6175 {
6176 	return true;
6177 }
6178 
6179 /** Selects if compilation failure is expected result
6180  *
6181  * @param ignored
6182  *
6183  * @return true
6184  **/
6185 bool NegativeTestBase::isFailureExpected(GLuint /* test_case_index */)
6186 {
6187 	return true;
6188 }
6189 
6190 /** Selects if the test case should use a separable program
6191  *
6192  * @param ignored
6193  *
6194  * @return false
6195  **/
6196 bool NegativeTestBase::isSeparable(const GLuint /* test_case_index */)
6197 {
6198 	return false;
6199 }
6200 
6201 /** Runs test case
6202  *
6203  * @param test_case_index Id of test case
6204  *
6205  * @return true if test case pass, false otherwise
6206  **/
6207 bool NegativeTestBase::testCase(GLuint test_case_index)
6208 {
6209 	bool test_case_result = true;
6210 
6211 	/* Compute */
6212 	if (true == isComputeRelevant(test_case_index))
6213 	{
6214 		const std::string& cs_source		   = getShaderSource(test_case_index, Utils::Shader::COMPUTE);
6215 		bool			   is_build_error	  = false;
6216 		const bool		   is_failure_expected = isFailureExpected(test_case_index);
6217 		Utils::Program	 program(m_context);
6218 
6219 		try
6220 		{
6221 			program.Init(cs_source, "" /* fs */, "" /* gs */, "" /* tcs */, "" /* tes */, "" /* vs */,
6222 						 false /* separable */);
6223 		}
6224 		catch (Utils::Shader::InvalidSourceException& exc)
6225 		{
6226 			if (false == is_failure_expected)
6227 			{
6228 				m_context.getTestContext().getLog()
6229 					<< tcu::TestLog::Message << "Unexpected error in shader compilation: " << tcu::TestLog::EndMessage;
6230 				exc.log(m_context);
6231 			}
6232 
6233 #if DEBUG_NEG_LOG_ERROR
6234 
6235 			else
6236 			{
6237 				m_context.getTestContext().getLog()
6238 					<< tcu::TestLog::Message << "Error in shader compilation was expected, logged for verification: "
6239 					<< tcu::TestLog::EndMessage;
6240 				exc.log(m_context);
6241 			}
6242 
6243 #endif /* DEBUG_NEG_LOG_ERROR */
6244 
6245 			is_build_error = true;
6246 		}
6247 		catch (Utils::Program::BuildException& exc)
6248 		{
6249 			if (false == is_failure_expected)
6250 			{
6251 				m_context.getTestContext().getLog()
6252 					<< tcu::TestLog::Message << "Unexpected error in program linking: " << tcu::TestLog::EndMessage;
6253 				exc.log(m_context);
6254 			}
6255 
6256 #if DEBUG_NEG_LOG_ERROR
6257 
6258 			else
6259 			{
6260 				m_context.getTestContext().getLog()
6261 					<< tcu::TestLog::Message
6262 					<< "Error in program linking was expected, logged for verification: " << tcu::TestLog::EndMessage;
6263 				exc.log(m_context);
6264 			}
6265 
6266 #endif /* DEBUG_NEG_LOG_ERROR */
6267 
6268 			is_build_error = true;
6269 		}
6270 
6271 		if (is_build_error != is_failure_expected)
6272 		{
6273 			if (!is_build_error)
6274 			{
6275 				m_context.getTestContext().getLog()
6276 					<< tcu::TestLog::Message << "Unexpected success: " << tcu::TestLog::EndMessage;
6277 				Utils::Shader::LogSource(m_context, cs_source, Utils::Shader::COMPUTE);
6278 			}
6279 			test_case_result = false;
6280 		}
6281 	}
6282 	else /* Draw */
6283 	{
6284 		const std::string& fs_source		   = getShaderSource(test_case_index, Utils::Shader::FRAGMENT);
6285 		const std::string& gs_source		   = getShaderSource(test_case_index, Utils::Shader::GEOMETRY);
6286 		bool			   is_build_error	  = false;
6287 		const bool		   is_failure_expected = isFailureExpected(test_case_index);
6288 		Utils::Program	 program(m_context);
6289 		const std::string& tcs_source = getShaderSource(test_case_index, Utils::Shader::TESS_CTRL);
6290 		const std::string& tes_source = getShaderSource(test_case_index, Utils::Shader::TESS_EVAL);
6291 		const std::string& vs_source  = getShaderSource(test_case_index, Utils::Shader::VERTEX);
6292 
6293 		try
6294 		{
6295 			if (isSeparable(test_case_index))
6296 			{
6297 				program.Init("" /*cs*/, fs_source, "" /*gs_source*/, "" /*tcs_source*/, "" /*tes_source*/,
6298 							 "" /*vs_source*/, true /* separable */);
6299 				program.Init("" /*cs*/, "" /*fs_source*/, gs_source, "" /*tcs_source*/, "" /*tes_source*/,
6300 							 "" /*vs_source*/, true /* separable */);
6301 				program.Init("" /*cs*/, "" /*fs_source*/, "" /*gs_source*/, tcs_source, "" /*tes_source*/,
6302 							 "" /*vs_source*/, true /* separable */);
6303 				program.Init("" /*cs*/, "" /*fs_source*/, "" /*gs_source*/, "" /*tcs_source*/, tes_source,
6304 							 "" /*vs_source*/, true /* separable */);
6305 				program.Init("" /*cs*/, "" /*fs_source*/, "" /*gs_source*/, "" /*tcs_source*/, "" /*tes_source*/,
6306 							 vs_source, true /* separable */);
6307 			}
6308 			else
6309 			{
6310 				program.Init("" /* cs */, fs_source, gs_source, tcs_source, tes_source, vs_source,
6311 							 false /* separable */);
6312 			}
6313 		}
6314 		catch (Utils::Shader::InvalidSourceException& exc)
6315 		{
6316 			if (false == is_failure_expected)
6317 			{
6318 				m_context.getTestContext().getLog()
6319 					<< tcu::TestLog::Message << "Unexpected error in shader compilation: " << tcu::TestLog::EndMessage;
6320 				exc.log(m_context);
6321 			}
6322 
6323 #if DEBUG_NEG_LOG_ERROR
6324 
6325 			else
6326 			{
6327 				m_context.getTestContext().getLog()
6328 					<< tcu::TestLog::Message << "Error in shader compilation was expected, logged for verification: "
6329 					<< tcu::TestLog::EndMessage;
6330 				exc.log(m_context);
6331 			}
6332 
6333 #endif /* DEBUG_NEG_LOG_ERROR */
6334 
6335 			is_build_error = true;
6336 		}
6337 		catch (Utils::Program::BuildException& exc)
6338 		{
6339 			if (false == is_failure_expected)
6340 			{
6341 				m_context.getTestContext().getLog()
6342 					<< tcu::TestLog::Message << "Unexpected error in program linking: " << tcu::TestLog::EndMessage;
6343 				exc.log(m_context);
6344 			}
6345 
6346 #if DEBUG_NEG_LOG_ERROR
6347 
6348 			else
6349 			{
6350 				m_context.getTestContext().getLog()
6351 					<< tcu::TestLog::Message
6352 					<< "Error in program linking was expected, logged for verification: " << tcu::TestLog::EndMessage;
6353 				exc.log(m_context);
6354 			}
6355 
6356 #endif /* DEBUG_NEG_LOG_ERROR */
6357 
6358 			is_build_error = true;
6359 		}
6360 
6361 		if (is_build_error != is_failure_expected)
6362 		{
6363 			if (!is_build_error)
6364 			{
6365 				m_context.getTestContext().getLog()
6366 					<< tcu::TestLog::Message << "Unexpected success: " << tcu::TestLog::EndMessage;
6367 				Utils::Shader::LogSource(m_context, vs_source, Utils::Shader::VERTEX);
6368 				Utils::Shader::LogSource(m_context, tcs_source, Utils::Shader::TESS_CTRL);
6369 				Utils::Shader::LogSource(m_context, tes_source, Utils::Shader::TESS_EVAL);
6370 				Utils::Shader::LogSource(m_context, gs_source, Utils::Shader::GEOMETRY);
6371 				Utils::Shader::LogSource(m_context, fs_source, Utils::Shader::FRAGMENT);
6372 			}
6373 			test_case_result = false;
6374 		}
6375 	}
6376 
6377 	return test_case_result;
6378 }
6379 
6380 /* Constants used by TextureTestBase */
6381 const glw::GLuint TextureTestBase::m_width  = 16;
6382 const glw::GLuint TextureTestBase::m_height = 16;
6383 
6384 /** Constructor
6385  *
6386  * @param context          Test context
6387  * @param test_name        Name of test
6388  * @param test_description Description of test
6389  **/
6390 TextureTestBase::TextureTestBase(deqp::Context& context, const GLchar* test_name, const GLchar* test_description)
6391 	: TestBase(context, test_name, test_description)
6392 {
6393 }
6394 
6395 /** Get locations for all inputs with automatic_location
6396  *
6397  * @param program           Program object
6398  * @param program_interface Interface of program
6399  **/
6400 void TextureTestBase::prepareAttribLocation(Utils::Program& program, Utils::ProgramInterface& program_interface)
6401 {
6402 	Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
6403 
6404 	Utils::Variable::PtrVector& inputs = si.m_inputs;
6405 
6406 	for (Utils::Variable::PtrVector::iterator it = inputs.begin(); inputs.end() != it; ++it)
6407 	{
6408 		/* Test does not specify location, query value and set */
6409 		if (Utils::Variable::m_automatic_location == (*it)->m_descriptor.m_expected_location)
6410 		{
6411 			GLuint index	= program.GetResourceIndex((*it)->m_descriptor.m_name, GL_PROGRAM_INPUT);
6412 			GLint  location = 0;
6413 
6414 			program.GetResource(GL_PROGRAM_INPUT, index, GL_LOCATION, 1 /* size */, &location);
6415 
6416 			(*it)->m_descriptor.m_expected_location = location;
6417 		}
6418 	}
6419 }
6420 
6421 /** Verifies contents of drawn image
6422  *
6423  * @param ignored
6424  * @param color_0 Verified image
6425  *
6426  * @return true if image is filled with 1, false otherwise
6427  **/
6428 bool TextureTestBase::checkResults(glw::GLuint /* test_case_index */, Utils::Texture& color_0)
6429 {
6430 	static const GLuint size		   = m_width * m_height;
6431 	static const GLuint expected_color = 1;
6432 
6433 	std::vector<GLuint> data;
6434 	data.resize(size);
6435 
6436 	color_0.Get(GL_RED_INTEGER, GL_UNSIGNED_INT, &data[0]);
6437 
6438 	for (GLuint i = 0; i < size; ++i)
6439 	{
6440 		const GLuint color = data[i];
6441 
6442 		if (expected_color != color)
6443 		{
6444 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "R32UI[" << i << "]:" << color
6445 												<< tcu::TestLog::EndMessage;
6446 			return false;
6447 		}
6448 	}
6449 
6450 	return true;
6451 }
6452 
6453 /** Execute dispatch compute for 16x16x1
6454  *
6455  * @param ignored
6456  **/
6457 void TextureTestBase::executeDispatchCall(GLuint /* test_case_index */)
6458 {
6459 	const Functions& gl = m_context.getRenderContext().getFunctions();
6460 
6461 	gl.dispatchCompute(16 /* x */, 16 /* y */, 1 /* z */);
6462 	GLU_EXPECT_NO_ERROR(gl.getError(), "DispatchCompute");
6463 }
6464 
6465 /** Execute drawArrays for single vertex
6466  *
6467  * @param ignored
6468  **/
6469 void TextureTestBase::executeDrawCall(GLuint /* test_case_index */)
6470 {
6471 	const Functions& gl = m_context.getRenderContext().getFunctions();
6472 
6473 	gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
6474 	GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
6475 }
6476 
6477 /** Prepare code snippet that will pass in variables to out variables
6478  *
6479  * @param ignored
6480  * @param varying_passthrough Collection of connections between in and out variables
6481  * @param stage               Shader stage
6482  *
6483  * @return Code that pass in variables to next stage
6484  **/
6485 std::string TextureTestBase::getPassSnippet(GLuint /* test_case_index */,
6486 											Utils::VaryingPassthrough& varying_passthrough, Utils::Shader::STAGES stage)
6487 {
6488 	static const GLchar* separator = "\n    ";
6489 
6490 	/* Skip for compute shader */
6491 	if (Utils::Shader::COMPUTE == stage)
6492 	{
6493 		return "";
6494 	}
6495 
6496 	Utils::VaryingConnection::Vector& vector = varying_passthrough.Get(stage);
6497 
6498 	std::string result   = Utils::g_list;
6499 	size_t		position = 0;
6500 
6501 	for (GLuint i = 0; i < vector.size(); ++i)
6502 	{
6503 
6504 		Utils::VaryingConnection& connection = vector[i];
6505 
6506 		Utils::Variable* in  = connection.m_in;
6507 		Utils::Variable* out = connection.m_out;
6508 
6509 		Utils::Variable::FLAVOUR in_flavour  = Utils::Variable::GetFlavour(stage, Utils::Variable::INPUT);
6510 		Utils::Variable::FLAVOUR out_flavour = Utils::Variable::GetFlavour(stage, Utils::Variable::OUTPUT);
6511 
6512 		const std::string passthrough =
6513 			getVariablePassthrough("", in->m_descriptor, in_flavour, "", out->m_descriptor, out_flavour);
6514 
6515 		Utils::insertElementOfList(passthrough.c_str(), separator, position, result);
6516 	}
6517 
6518 	Utils::endList("", position, result);
6519 
6520 	return result;
6521 }
6522 
6523 /** Basic implementation of method getProgramInterface
6524  *
6525  * @param ignored
6526  * @param ignored
6527  * @param ignored
6528  **/
6529 void TextureTestBase::getProgramInterface(GLuint /* test_case_index */,
6530 										  Utils::ProgramInterface& /* program_interface */,
6531 										  Utils::VaryingPassthrough& /* varying_passthrough */)
6532 {
6533 }
6534 
6535 /** Prepare code snippet that will verify in and uniform variables
6536  *
6537  * @param ignored
6538  * @param program_interface Interface of program
6539  * @param stage             Shader stage
6540  *
6541  * @return Code that verify variables
6542  **/
6543 std::string TextureTestBase::getVerificationSnippet(GLuint /* test_case_index */,
6544 													Utils::ProgramInterface& program_interface,
6545 													Utils::Shader::STAGES	stage)
6546 {
6547 	static const GLchar* separator = " ||\n        ";
6548 
6549 	std::string verification = "if (LIST)\n"
6550 							   "    {\n"
6551 							   "        result = 0u;\n"
6552 							   "    }\n";
6553 
6554 	/* Get flavour of in and out variables */
6555 	Utils::Variable::FLAVOUR in_flavour = Utils::Variable::GetFlavour(stage, Utils::Variable::INPUT);
6556 
6557 	/* Get interface for shader stage */
6558 	Utils::ShaderInterface& si = program_interface.GetShaderInterface(stage);
6559 
6560 	/* There are no varialbes to verify */
6561 	if ((0 == si.m_inputs.size()) && (0 == si.m_uniforms.size()) && (0 == si.m_ssb_blocks.size()))
6562 	{
6563 		return "";
6564 	}
6565 
6566 	/* For each in variable insert verification code */
6567 	size_t position = 0;
6568 
6569 	for (GLuint i = 0; i < si.m_inputs.size(); ++i)
6570 	{
6571 		const Utils::Variable& var				= *si.m_inputs[i];
6572 		const std::string&	 var_verification = getVariableVerification("", var.m_data, var.m_descriptor, in_flavour);
6573 
6574 		Utils::insertElementOfList(var_verification.c_str(), separator, position, verification);
6575 	}
6576 
6577 	/* For each unifrom variable insert verification code */
6578 	for (GLuint i = 0; i < si.m_uniforms.size(); ++i)
6579 	{
6580 		const Utils::Variable& var = *si.m_uniforms[i];
6581 		const std::string&	 var_verification =
6582 			getVariableVerification("", var.m_data, var.m_descriptor, Utils::Variable::BASIC);
6583 
6584 		Utils::insertElementOfList(var_verification.c_str(), separator, position, verification);
6585 	}
6586 
6587 	/* For each ssb variable insert verification code */
6588 	for (GLuint i = 0; i < si.m_ssb_blocks.size(); ++i)
6589 	{
6590 		const Utils::Variable& var = *si.m_ssb_blocks[i];
6591 		const std::string&	 var_verification =
6592 			getVariableVerification("", var.m_data, var.m_descriptor, Utils::Variable::BASIC);
6593 
6594 		Utils::insertElementOfList(var_verification.c_str(), separator, position, verification);
6595 	}
6596 
6597 	Utils::endList("", position, verification);
6598 
6599 #if DEBUG_TTB_VERIFICATION_SNIPPET_STAGE
6600 
6601 	{
6602 		GLchar buffer[16];
6603 		sprintf(buffer, "%d", stage + 10);
6604 		Utils::replaceToken("0u", position, buffer, verification);
6605 	}
6606 
6607 #elif DEBUG_TTB_VERIFICATION_SNIPPET_VARIABLE
6608 
6609 	if (Utils::Shader::VERTEX == stage)
6610 	{
6611 		Utils::replaceToken("0u", position, "in_vs_first.x", verification);
6612 	}
6613 	else
6614 	{
6615 		Utils::replaceToken("0u", position, "31u", verification);
6616 	}
6617 
6618 #endif
6619 
6620 	/* Done */
6621 	return verification;
6622 }
6623 
6624 /** Selects if "compute" stage is relevant for test
6625  *
6626  * @param ignored
6627  *
6628  * @return true
6629  **/
6630 bool TextureTestBase::isComputeRelevant(GLuint /* test_case_index */)
6631 {
6632 	return true;
6633 }
6634 
6635 /** Selects if "draw" stages are relevant for test
6636  *
6637  * @param ignored
6638  *
6639  * @return true
6640  **/
6641 bool TextureTestBase::isDrawRelevant(GLuint /* test_case_index */)
6642 {
6643 	return true;
6644 }
6645 
6646 /** Prepare code that will do assignment of single in to single out
6647  *
6648  * @param in_parent_name  Name of parent in variable
6649  * @param in_variable     Descriptor of in variable
6650  * @param in_flavour      Flavoud of in variable
6651  * @param out_parent_name Name of parent out variable
6652  * @param out_variable    Descriptor of out variable
6653  * @param out_flavour     Flavoud of out variable
6654  *
6655  * @return Code that does OUT = IN
6656  **/
6657 std::string TextureTestBase::getVariablePassthrough(const std::string&				   in_parent_name,
6658 													const Utils::Variable::Descriptor& in_variable,
6659 													Utils::Variable::FLAVOUR		   in_flavour,
6660 													const std::string&				   out_parent_name,
6661 													const Utils::Variable::Descriptor& out_variable,
6662 													Utils::Variable::FLAVOUR		   out_flavour)
6663 {
6664 	bool				 done		  = false;
6665 	GLuint				 index		  = 0;
6666 	GLuint				 member_index = 0;
6667 	size_t				 position	 = 0;
6668 	std::string			 result		  = Utils::g_list;
6669 	static const GLchar* separator	= ";\n    ";
6670 
6671 	/* For each member of each array element */
6672 	do
6673 	{
6674 		const std::string in_name  = Utils::Variable::GetReference(in_parent_name, in_variable, in_flavour, index);
6675 		const std::string out_name = Utils::Variable::GetReference(out_parent_name, out_variable, out_flavour, index);
6676 		std::string		  passthrough;
6677 
6678 		/* Prepare verification */
6679 		if (Utils::Variable::BUILTIN == in_variable.m_type)
6680 		{
6681 			size_t pass_position = 0;
6682 
6683 			passthrough = "OUT = IN;";
6684 
6685 			Utils::replaceToken("OUT", pass_position, out_name.c_str(), passthrough);
6686 			Utils::replaceToken("IN", pass_position, in_name.c_str(), passthrough);
6687 
6688 			/* Increment index */
6689 			++index;
6690 		}
6691 		else
6692 		{
6693 			const Utils::Interface* in_interface  = in_variable.m_interface;
6694 			const Utils::Interface* out_interface = out_variable.m_interface;
6695 
6696 			if ((0 == in_interface) || (0 == out_interface))
6697 			{
6698 				TCU_FAIL("Nullptr");
6699 			}
6700 
6701 			const Utils::Variable::Descriptor& in_member  = in_interface->m_members[member_index];
6702 			const Utils::Variable::Descriptor& out_member = out_interface->m_members[member_index];
6703 
6704 			passthrough = getVariablePassthrough(in_name, in_member, Utils::Variable::BASIC, out_name, out_member,
6705 												 Utils::Variable::BASIC);
6706 
6707 			/* Increment member_index */
6708 			++member_index;
6709 
6710 			/* Increment index and reset member_index if all members were processed */
6711 			if (in_interface->m_members.size() == member_index)
6712 			{
6713 				++index;
6714 				member_index = 0;
6715 			}
6716 		}
6717 
6718 		/* Check if loop should end */
6719 		if ((index >= in_variable.m_n_array_elements) && (0 == member_index))
6720 		{
6721 			done = true;
6722 		}
6723 
6724 		Utils::insertElementOfList(passthrough.c_str(), separator, position, result);
6725 
6726 	} while (true != done);
6727 
6728 	Utils::endList("", position, result);
6729 
6730 	/* Done */
6731 	return result;
6732 }
6733 
6734 /** Get verification of single variable
6735  *
6736  * @param parent_name Name of parent variable
6737  * @param data        Data that should be used as EXPECTED
6738  * @param variable    Descriptor of variable
6739  * @param flavour     Flavour of variable
6740  *
6741  * @return Code that does (EXPECTED != VALUE) ||
6742  **/
6743 std::string TextureTestBase::getVariableVerification(const std::string& parent_name, const GLvoid* data,
6744 													 const Utils::Variable::Descriptor& variable,
6745 													 Utils::Variable::FLAVOUR			flavour)
6746 {
6747 	static const GLchar* logic_op   = " ||\n        ";
6748 	const GLuint		 n_elements = (0 == variable.m_n_array_elements) ? 1 : variable.m_n_array_elements;
6749 	size_t				 position   = 0;
6750 	std::string			 result		= Utils::g_list;
6751 	GLint				 stride		= variable.m_expected_stride_of_element;
6752 
6753 	/* For each each array element */
6754 	for (GLuint element = 0; element < n_elements; ++element)
6755 	{
6756 		const std::string name = Utils::Variable::GetReference(parent_name, variable, flavour, element);
6757 
6758 		/* Calculate data pointer */
6759 		GLvoid* data_ptr = (GLvoid*)((GLubyte*)data + element * stride);
6760 
6761 		/* Prepare verification */
6762 		if (Utils::Variable::BUILTIN == variable.m_type)
6763 		{
6764 			const std::string& expected = variable.m_builtin.GetGLSLConstructor(data_ptr);
6765 			std::string		   verification;
6766 			size_t			   verification_position = 0;
6767 
6768 			verification = "(EXPECTED != NAME)";
6769 
6770 			Utils::replaceToken("EXPECTED", verification_position, expected.c_str(), verification);
6771 			Utils::replaceToken("NAME", verification_position, name.c_str(), verification);
6772 
6773 			Utils::insertElementOfList(verification.c_str(), logic_op, position, result);
6774 		}
6775 		else
6776 		{
6777 			const Utils::Interface* interface = variable.m_interface;
6778 
6779 			if (0 == interface)
6780 			{
6781 				TCU_FAIL("Nullptr");
6782 			}
6783 
6784 			const GLuint n_members = static_cast<GLuint>(interface->m_members.size());
6785 
6786 			/* for each member */
6787 			for (GLuint member_index = 0; member_index < n_members; ++member_index)
6788 			{
6789 				const Utils::Variable::Descriptor& member = interface->m_members[member_index];
6790 
6791 				/* Get verification of member */
6792 				const std::string& verification =
6793 					getVariableVerification(name, (GLubyte*)data_ptr + member.m_offset, member, Utils::Variable::BASIC);
6794 
6795 				Utils::insertElementOfList(verification.c_str(), logic_op, position, result);
6796 			}
6797 		}
6798 	}
6799 
6800 	Utils::endList("", position, result);
6801 
6802 	return result;
6803 }
6804 
6805 /** Prepare attributes, vertex array object and array buffer
6806  *
6807  * @param test_case_index   Index of test case
6808  * @param program_interface Interface of program
6809  * @param buffer            Array buffer
6810  * @param vao               Vertex array object
6811  **/
6812 void TextureTestBase::prepareAttributes(GLuint test_case_index, Utils::ProgramInterface& program_interface,
6813 										Utils::Buffer& buffer, Utils::VertexArray& vao)
6814 {
6815 	const bool use_component_qualifier = useComponentQualifier(test_case_index);
6816 
6817 	/* Get shader interface */
6818 	const Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
6819 
6820 	/* Bind vao and buffer */
6821 	vao.Bind();
6822 	buffer.Bind();
6823 
6824 	/* Skip if there are no input variables in vertex shader */
6825 	if (0 == si.m_inputs.size())
6826 	{
6827 		return;
6828 	}
6829 
6830 	const Functions& gl = m_context.getRenderContext().getFunctions();
6831 
6832 	/* Calculate vertex stride and check */
6833 	GLint max_inputs;
6834 	gl.getIntegerv(GL_MAX_VERTEX_ATTRIBS, &max_inputs);
6835 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
6836 
6837 	/* dvec3/4 vertex inputs use a single location but require 2x16B slots */
6838 	const GLuint max_slots = max_inputs * 2;
6839 
6840 	/* Compute used slots */
6841 	std::vector<GLuint> slot_sizes(max_slots, 0);
6842 	for (GLuint i = 0; i < si.m_inputs.size(); ++i)
6843 	{
6844 		const Utils::Variable& variable = *si.m_inputs[i];
6845 
6846 		const GLuint variable_size = static_cast<GLuint>(variable.m_data_size);
6847 
6848 		const GLuint base_slot = variable.m_descriptor.m_expected_location + variable.m_descriptor.m_offset / 16;
6849 		const GLuint ends_at   = variable.m_descriptor.m_offset % 16 + variable_size;
6850 
6851 		const GLuint array_length = std::max(1u, variable.m_descriptor.m_n_array_elements);
6852 		for (GLuint loc = 0; loc < array_length; loc++)
6853 		{
6854 			const GLuint slot = base_slot + loc;
6855 			slot_sizes[slot] = std::max(slot_sizes[slot], ends_at);
6856 		}
6857 	}
6858 
6859 	/* Compute the offsets where we need to put vertex buffer data for each slot */
6860 	std::vector<GLint> slot_offsets(max_slots, -1);
6861 	GLuint			   buffer_size = 0;
6862 	for (GLuint i = 0; i < max_slots; i++)
6863 	{
6864 		if (slot_sizes[i] == 0)
6865 			continue;
6866 		slot_offsets[i] = buffer_size;
6867 		buffer_size += slot_sizes[i];
6868 	}
6869 
6870 	/* Prepare buffer data and set up vao */
6871 	std::vector<GLubyte> buffer_data(buffer_size);
6872 
6873 	GLubyte* ptr = &buffer_data[0];
6874 
6875 	for (GLuint i = 0; i < si.m_inputs.size(); ++i)
6876 	{
6877 		const Utils::Variable& variable = *si.m_inputs[i];
6878 
6879 		const GLuint base_slot		 = variable.m_descriptor.m_expected_location + variable.m_descriptor.m_offset / 16;
6880 		const GLuint variable_offset = variable.m_descriptor.m_offset % 16;
6881 		const GLuint array_length	= std::max(1u, variable.m_descriptor.m_n_array_elements);
6882 		for (GLuint loc = 0; loc < array_length; loc++)
6883 		{
6884 			const GLuint slot = base_slot + loc;
6885 			memcpy(ptr + slot_offsets[slot] + variable_offset, variable.m_data, variable.m_data_size);
6886 		}
6887 
6888 		if (!use_component_qualifier)
6889 		{
6890 			vao.Attribute(variable.m_descriptor.m_expected_location, variable.m_descriptor.m_builtin,
6891 						  variable.m_descriptor.m_n_array_elements, variable.m_descriptor.m_normalized,
6892 						  variable.GetStride(), (GLvoid*)(intptr_t)(slot_offsets[base_slot] + variable_offset));
6893 		}
6894 		else if (0 == variable.m_descriptor.m_expected_component)
6895 		{
6896 			/* Components can only be applied to types not surpassing
6897 			 * the bounds of a single slot. Therefore, we calculate
6898 			 * the amount of used components in the varying based on
6899 			 * the calculated slot sizes.
6900 			 */
6901 			const GLuint n_component_size = Utils::Type::Double == variable.m_descriptor.m_builtin.m_basic_type ? 8 : 4;
6902 			const GLuint n_rows			  = slot_sizes[base_slot] / n_component_size;
6903 
6904 			const Utils::Type& type = Utils::Type::GetType(variable.m_descriptor.m_builtin.m_basic_type,
6905 														   1 /* n_columns */, n_rows /* n_rows */);
6906 
6907 			vao.Attribute(variable.m_descriptor.m_expected_location, type, variable.m_descriptor.m_n_array_elements,
6908 						  variable.m_descriptor.m_normalized, variable.GetStride(),
6909 						  (GLvoid*)(intptr_t)(slot_offsets[base_slot] + variable_offset));
6910 		}
6911 	}
6912 
6913 	/* Update buffer */
6914 	buffer.Data(Utils::Buffer::StaticDraw, buffer_size, ptr);
6915 }
6916 
6917 /** Get locations for all outputs with automatic_location
6918  *
6919  * @param program           Program object
6920  * @param program_interface Interface of program
6921  **/
6922 void TextureTestBase::prepareFragmentDataLoc(Utils::Program& program, Utils::ProgramInterface& program_interface)
6923 {
6924 	Utils::ShaderInterface&		si		= program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
6925 	Utils::Variable::PtrVector& outputs = si.m_outputs;
6926 
6927 	for (Utils::Variable::PtrVector::iterator it = outputs.begin(); outputs.end() != it; ++it)
6928 	{
6929 		/* Test does not specify location, query value and set */
6930 		if (Utils::Variable::m_automatic_location == (*it)->m_descriptor.m_expected_location)
6931 		{
6932 			GLuint index	= program.GetResourceIndex((*it)->m_descriptor.m_name, GL_PROGRAM_OUTPUT);
6933 			GLint  location = 0;
6934 
6935 			program.GetResource(GL_PROGRAM_OUTPUT, index, GL_LOCATION, 1 /* size */, &location);
6936 
6937 			(*it)->m_descriptor.m_expected_location = location;
6938 		}
6939 	}
6940 }
6941 
6942 /** Prepare framebuffer with single texture as color attachment
6943  *
6944  * @param framebuffer     Framebuffer
6945  * @param color_0_texture Texture that will used as color attachment
6946  **/
6947 void TextureTestBase::prepareFramebuffer(Utils::Framebuffer& framebuffer, Utils::Texture& color_0_texture)
6948 {
6949 	/* Prepare data */
6950 	std::vector<GLuint> texture_data;
6951 	texture_data.resize(m_width * m_height);
6952 
6953 	for (GLuint i = 0; i < texture_data.size(); ++i)
6954 	{
6955 		texture_data[i] = 0x20406080;
6956 	}
6957 
6958 	/* Prepare texture */
6959 	color_0_texture.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT,
6960 						 &texture_data[0]);
6961 
6962 	/* Prepare framebuffer */
6963 	framebuffer.Init();
6964 	framebuffer.Bind();
6965 	framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0, color_0_texture.m_id, m_width, m_height);
6966 
6967 	framebuffer.ClearColor(0.0f, 0.0f, 0.0f, 0.0f);
6968 	framebuffer.Clear(GL_COLOR_BUFFER_BIT);
6969 }
6970 
6971 /** Prepare iamge unit for compute shader
6972  *
6973  * @param location      Uniform location
6974  * @param image_texture Texture that will used as color attachment
6975  **/
6976 void TextureTestBase::prepareImage(GLint location, Utils::Texture& image_texture) const
6977 {
6978 	static const GLuint image_unit = 0;
6979 
6980 	std::vector<GLuint> texture_data;
6981 	texture_data.resize(m_width * m_height);
6982 
6983 	for (GLuint i = 0; i < texture_data.size(); ++i)
6984 	{
6985 		texture_data[i] = 0x20406080;
6986 	}
6987 
6988 	image_texture.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT,
6989 					   &texture_data[0]);
6990 
6991 	const Functions& gl = m_context.getRenderContext().getFunctions();
6992 
6993 	gl.bindImageTexture(image_unit, image_texture.m_id, 0 /* level */, GL_FALSE /* layered */, 0 /* Layer */,
6994 						GL_WRITE_ONLY, GL_R32UI);
6995 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindImageTexture");
6996 
6997 	Utils::Program::Uniform(gl, Utils::Type::_int, 1 /* count */, location, &image_unit);
6998 }
6999 
7000 /** Basic implementation
7001  *
7002  * @param ignored
7003  * @param si        Shader interface
7004  * @param program   Program
7005  * @param cs_buffer Buffer for ssb blocks
7006  **/
7007 void TextureTestBase::prepareSSBs(GLuint /* test_case_index */, Utils::ShaderInterface& si, Utils::Program& program,
7008 								  Utils::Buffer& buffer)
7009 {
7010 	/* Skip if there are no input variables in vertex shader */
7011 	if (0 == si.m_ssb_blocks.size())
7012 	{
7013 		return;
7014 	}
7015 
7016 	/* Calculate vertex stride */
7017 	GLint ssbs_stride = 0;
7018 
7019 	for (GLuint i = 0; i < si.m_ssb_blocks.size(); ++i)
7020 	{
7021 		Utils::Variable& variable = *si.m_ssb_blocks[i];
7022 
7023 		if (false == variable.IsBlock())
7024 		{
7025 			continue;
7026 		}
7027 
7028 		GLint variable_stride = variable.GetStride();
7029 
7030 		GLint ends_at = variable_stride + variable.m_descriptor.m_offset;
7031 
7032 		ssbs_stride = std::max(ssbs_stride, ends_at);
7033 	}
7034 
7035 	/* Set active program */
7036 	program.Use();
7037 
7038 	/* Allocate */
7039 	buffer.Bind();
7040 	buffer.Data(Utils::Buffer::StaticDraw, ssbs_stride, 0);
7041 
7042 	/* Set up uniforms */
7043 	for (GLuint i = 0; i < si.m_ssb_blocks.size(); ++i)
7044 	{
7045 		Utils::Variable& variable = *si.m_ssb_blocks[i];
7046 
7047 		/* prepareUnifor should work fine for ssb blocks */
7048 		prepareUniform(program, variable, buffer);
7049 	}
7050 }
7051 
7052 /** Basic implementation
7053  *
7054  * @param test_case_index   Test case index
7055  * @param program_interface Program interface
7056  * @param program           Program
7057  * @param cs_buffer         Buffer for compute shader stage
7058  **/
7059 void TextureTestBase::prepareSSBs(GLuint test_case_index, Utils::ProgramInterface& program_interface,
7060 								  Utils::Program& program, Utils::Buffer& cs_buffer)
7061 {
7062 	cs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
7063 
7064 	Utils::ShaderInterface& cs = program_interface.GetShaderInterface(Utils::Shader::COMPUTE);
7065 
7066 	prepareSSBs(test_case_index, cs, program, cs_buffer);
7067 
7068 	cs_buffer.BindBase(Utils::Shader::COMPUTE);
7069 }
7070 
7071 /** Basic implementation
7072  *
7073  * @param test_case_index   Test case index
7074  * @param program_interface Program interface
7075  * @param program           Program
7076  * @param fs_buffer         Buffer for fragment shader stage
7077  * @param gs_buffer         Buffer for geometry shader stage
7078  * @param tcs_buffer        Buffer for tessellation control shader stage
7079  * @param tes_buffer        Buffer for tessellation evaluation shader stage
7080  * @param vs_buffer         Buffer for vertex shader stage
7081  **/
7082 void TextureTestBase::prepareSSBs(GLuint test_case_index, Utils::ProgramInterface& program_interface,
7083 								  Utils::Program& program, Utils::Buffer& fs_buffer, Utils::Buffer& gs_buffer,
7084 								  Utils::Buffer& tcs_buffer, Utils::Buffer& tes_buffer, Utils::Buffer& vs_buffer)
7085 {
7086 	fs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
7087 	gs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
7088 	tcs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
7089 	tes_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
7090 	vs_buffer.Init(Utils::Buffer::Shader_Storage, Utils::Buffer::StaticDraw, 0, 0);
7091 
7092 	Utils::ShaderInterface& fs  = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
7093 	Utils::ShaderInterface& gs  = program_interface.GetShaderInterface(Utils::Shader::GEOMETRY);
7094 	Utils::ShaderInterface& tcs = program_interface.GetShaderInterface(Utils::Shader::TESS_CTRL);
7095 	Utils::ShaderInterface& tes = program_interface.GetShaderInterface(Utils::Shader::TESS_EVAL);
7096 	Utils::ShaderInterface& vs  = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
7097 
7098 	prepareSSBs(test_case_index, fs, program, fs_buffer);
7099 	prepareSSBs(test_case_index, gs, program, gs_buffer);
7100 	prepareSSBs(test_case_index, tcs, program, tcs_buffer);
7101 	prepareSSBs(test_case_index, tes, program, tes_buffer);
7102 	prepareSSBs(test_case_index, vs, program, vs_buffer);
7103 
7104 	fs_buffer.BindBase(Utils::Shader::FRAGMENT);
7105 	gs_buffer.BindBase(Utils::Shader::GEOMETRY);
7106 	tcs_buffer.BindBase(Utils::Shader::TESS_CTRL);
7107 	tes_buffer.BindBase(Utils::Shader::TESS_EVAL);
7108 	vs_buffer.BindBase(Utils::Shader::VERTEX);
7109 }
7110 
7111 /** Updates buffer data with variable
7112  *
7113  * @param program  Program object
7114  * @param variable Variable
7115  * @param buffer   Buffer
7116  **/
7117 void TextureTestBase::prepareUniform(Utils::Program& program, Utils::Variable& variable, Utils::Buffer& buffer)
7118 {
7119 	const Functions& gl = m_context.getRenderContext().getFunctions();
7120 
7121 	GLsizei count = variable.m_descriptor.m_n_array_elements;
7122 	if (0 == count)
7123 	{
7124 		count = 1;
7125 	}
7126 
7127 	if (Utils::Variable::BUILTIN == variable.m_descriptor.m_type)
7128 	{
7129 		program.Uniform(gl, variable.m_descriptor.m_builtin, count, variable.m_descriptor.m_expected_location,
7130 						variable.m_data);
7131 	}
7132 	else
7133 	{
7134 		const bool is_block = variable.IsBlock();
7135 
7136 		if (false == is_block)
7137 		{
7138 			TCU_FAIL("Not implemented");
7139 		}
7140 		else
7141 		{
7142 			buffer.SubData(variable.m_descriptor.m_offset, variable.m_descriptor.m_expected_stride_of_element * count,
7143 						   variable.m_data);
7144 		}
7145 	}
7146 }
7147 
7148 /** Basic implementation
7149  *
7150  * @param ignored
7151  * @param si        Shader interface
7152  * @param program   Program
7153  * @param cs_buffer Buffer for uniform blocks
7154  **/
7155 void TextureTestBase::prepareUniforms(GLuint /* test_case_index */, Utils::ShaderInterface& si, Utils::Program& program,
7156 									  Utils::Buffer& buffer)
7157 {
7158 	/* Skip if there are no input variables in vertex shader */
7159 	if (0 == si.m_uniforms.size())
7160 	{
7161 		return;
7162 	}
7163 
7164 	/* Calculate vertex stride */
7165 	GLint uniforms_stride = 0;
7166 
7167 	for (GLuint i = 0; i < si.m_uniforms.size(); ++i)
7168 	{
7169 		Utils::Variable& variable = *si.m_uniforms[i];
7170 
7171 		if (false == variable.IsBlock())
7172 		{
7173 			continue;
7174 		}
7175 
7176 		GLint variable_stride = variable.GetStride();
7177 
7178 		GLint ends_at = variable_stride + variable.m_descriptor.m_offset;
7179 
7180 		uniforms_stride = std::max(uniforms_stride, ends_at);
7181 	}
7182 
7183 	/* Set active program */
7184 	program.Use();
7185 
7186 	/* Allocate */
7187 	buffer.Bind();
7188 	buffer.Data(Utils::Buffer::StaticDraw, uniforms_stride, 0);
7189 
7190 	/* Set up uniforms */
7191 	for (GLuint i = 0; i < si.m_uniforms.size(); ++i)
7192 	{
7193 		Utils::Variable& variable = *si.m_uniforms[i];
7194 
7195 		prepareUniform(program, variable, buffer);
7196 	}
7197 }
7198 
7199 /** Basic implementation
7200  *
7201  * @param test_case_index   Test case index
7202  * @param program_interface Program interface
7203  * @param program           Program
7204  * @param cs_buffer         Buffer for compute shader stage
7205  **/
7206 void TextureTestBase::prepareUniforms(GLuint test_case_index, Utils::ProgramInterface& program_interface,
7207 									  Utils::Program& program, Utils::Buffer& cs_buffer)
7208 {
7209 	cs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7210 
7211 	Utils::ShaderInterface& cs = program_interface.GetShaderInterface(Utils::Shader::COMPUTE);
7212 
7213 	prepareUniforms(test_case_index, cs, program, cs_buffer);
7214 
7215 	cs_buffer.BindBase(Utils::Shader::COMPUTE);
7216 }
7217 
7218 /** Basic implementation
7219  *
7220  * @param test_case_index   Test case index
7221  * @param program_interface Program interface
7222  * @param program           Program
7223  * @param fs_buffer         Buffer for fragment shader stage
7224  * @param gs_buffer         Buffer for geometry shader stage
7225  * @param tcs_buffer        Buffer for tessellation control shader stage
7226  * @param tes_buffer        Buffer for tessellation evaluation shader stage
7227  * @param vs_buffer         Buffer for vertex shader stage
7228  **/
7229 void TextureTestBase::prepareUniforms(GLuint test_case_index, Utils::ProgramInterface& program_interface,
7230 									  Utils::Program& program, Utils::Buffer& fs_buffer, Utils::Buffer& gs_buffer,
7231 									  Utils::Buffer& tcs_buffer, Utils::Buffer& tes_buffer, Utils::Buffer& vs_buffer)
7232 {
7233 	fs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7234 	gs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7235 	tcs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7236 	tes_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7237 	vs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7238 
7239 	Utils::ShaderInterface& fs  = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
7240 	Utils::ShaderInterface& gs  = program_interface.GetShaderInterface(Utils::Shader::GEOMETRY);
7241 	Utils::ShaderInterface& tcs = program_interface.GetShaderInterface(Utils::Shader::TESS_CTRL);
7242 	Utils::ShaderInterface& tes = program_interface.GetShaderInterface(Utils::Shader::TESS_EVAL);
7243 	Utils::ShaderInterface& vs  = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
7244 
7245 	prepareUniforms(test_case_index, fs, program, fs_buffer);
7246 	prepareUniforms(test_case_index, gs, program, gs_buffer);
7247 	prepareUniforms(test_case_index, tcs, program, tcs_buffer);
7248 	prepareUniforms(test_case_index, tes, program, tes_buffer);
7249 	prepareUniforms(test_case_index, vs, program, vs_buffer);
7250 
7251 	fs_buffer.BindBase(Utils::Shader::FRAGMENT);
7252 	gs_buffer.BindBase(Utils::Shader::GEOMETRY);
7253 	tcs_buffer.BindBase(Utils::Shader::TESS_CTRL);
7254 	tes_buffer.BindBase(Utils::Shader::TESS_EVAL);
7255 	vs_buffer.BindBase(Utils::Shader::VERTEX);
7256 }
7257 
7258 /** Basic implementation
7259  *
7260  * @param test_case_index   Test case index
7261  * @param program_interface Program interface
7262  * @param program           Program
7263  * @param fs_buffer         Buffer for fragment shader stage
7264  * @param gs_buffer         Buffer for geometry shader stage
7265  * @param tcs_buffer        Buffer for tessellation control shader stage
7266  * @param tes_buffer        Buffer for tessellation evaluation shader stage
7267  * @param vs_buffer         Buffer for vertex shader stage
7268  **/
7269 void TextureTestBase::prepareUniforms(GLuint test_case_index, Utils::ProgramInterface& program_interface,
7270 									  Utils::Program& fs_program, Utils::Program& gs_program,
7271 									  Utils::Program& tcs_program, Utils::Program& tes_program,
7272 									  Utils::Program& vs_program, Utils::Buffer& fs_buffer, Utils::Buffer& gs_buffer,
7273 									  Utils::Buffer& tcs_buffer, Utils::Buffer& tes_buffer, Utils::Buffer& vs_buffer)
7274 {
7275 	fs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7276 	gs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7277 	tcs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7278 	tes_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7279 	vs_buffer.Init(Utils::Buffer::Uniform, Utils::Buffer::StaticDraw, 0, 0);
7280 
7281 	Utils::ShaderInterface& fs  = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
7282 	Utils::ShaderInterface& gs  = program_interface.GetShaderInterface(Utils::Shader::GEOMETRY);
7283 	Utils::ShaderInterface& tcs = program_interface.GetShaderInterface(Utils::Shader::TESS_CTRL);
7284 	Utils::ShaderInterface& tes = program_interface.GetShaderInterface(Utils::Shader::TESS_EVAL);
7285 	Utils::ShaderInterface& vs  = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
7286 
7287 	prepareUniforms(test_case_index, fs, fs_program, fs_buffer);
7288 	fs_buffer.BindBase(Utils::Shader::FRAGMENT);
7289 
7290 	prepareUniforms(test_case_index, gs, gs_program, gs_buffer);
7291 	gs_buffer.BindBase(Utils::Shader::GEOMETRY);
7292 
7293 	prepareUniforms(test_case_index, tcs, tcs_program, tcs_buffer);
7294 	tcs_buffer.BindBase(Utils::Shader::TESS_CTRL);
7295 
7296 	prepareUniforms(test_case_index, tes, tes_program, tes_buffer);
7297 	tes_buffer.BindBase(Utils::Shader::TESS_EVAL);
7298 
7299 	prepareUniforms(test_case_index, vs, vs_program, vs_buffer);
7300 	vs_buffer.BindBase(Utils::Shader::VERTEX);
7301 }
7302 
7303 /** Prepare source for shader
7304  *
7305  * @param test_case_index     Index of test case
7306  * @param program_interface   Interface of program
7307  * @param varying_passthrough Collection of connection between in and out variables
7308  * @param stage               Shader stage
7309  *
7310  * @return Source of shader
7311  **/
7312 std::string TextureTestBase::getShaderSource(GLuint test_case_index, Utils::ProgramInterface& program_interface,
7313 											 Utils::VaryingPassthrough& varying_passthrough,
7314 											 Utils::Shader::STAGES		stage)
7315 {
7316 	/* Get strings */
7317 	const GLchar*	  shader_template  = getShaderTemplate(stage);
7318 	glu::GLSLVersion   glslVersion		= glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
7319 	const char*		   shader_version   = glu::getGLSLVersionDeclaration(glslVersion);
7320 	const std::string& shader_interface = program_interface.GetInterfaceForStage(stage);
7321 	const std::string& verification = getVerificationSnippet(test_case_index, program_interface, stage);
7322 	const std::string& passthrough = getPassSnippet(test_case_index, varying_passthrough, stage);
7323 
7324 	const GLchar* per_vertex = "";
7325 
7326 	std::string source   = shader_template;
7327 	size_t		position = 0;
7328 
7329 	Utils::replaceToken("VERSION", position, shader_version, source);
7330 
7331 	/* Replace tokens in template */
7332 	if (Utils::Shader::GEOMETRY == stage)
7333 	{
7334 		if (false == useMonolithicProgram(test_case_index))
7335 		{
7336 			per_vertex = "out gl_PerVertex {\n"
7337 						 "vec4 gl_Position;\n"
7338 						 "};\n"
7339 						 "\n";
7340 		}
7341 
7342 		Utils::replaceToken("PERVERTEX", position, per_vertex, source);
7343 	}
7344 
7345 	Utils::replaceToken("INTERFACE", position, shader_interface.c_str(), source);
7346 	Utils::replaceToken("VERIFICATION", position, verification.c_str(), source);
7347 
7348 	if (false == verification.empty())
7349 	{
7350 		Utils::replaceAllTokens("ELSE", "    else ", source);
7351 	}
7352 	else
7353 	{
7354 		Utils::replaceAllTokens("ELSE", "", source);
7355 	}
7356 
7357 	Utils::replaceAllTokens("PASSTHROUGH", passthrough.c_str(), source);
7358 
7359 	/* Done */
7360 	return source;
7361 }
7362 
7363 /** Returns template of shader for given stage
7364  *
7365  * @param stage Shade stage
7366  *
7367  * @return Proper template
7368  **/
7369 const GLchar* TextureTestBase::getShaderTemplate(Utils::Shader::STAGES stage)
7370 {
7371 
7372 	static const GLchar* compute_shader_template =
7373 		"VERSION\n"
7374 		"#extension GL_ARB_enhanced_layouts : require\n"
7375 		"\n"
7376 		"layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
7377 		"\n"
7378 		"writeonly uniform uimage2D uni_image;\n"
7379 		"\n"
7380 		"INTERFACE"
7381 		"\n"
7382 		"void main()\n"
7383 		"{\n"
7384 		"    uint result = 1u;\n"
7385 		"\n"
7386 		"    VERIFICATION"
7387 		"\n"
7388 		"    imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), uvec4(result, 0, 0, 0));\n"
7389 		"}\n"
7390 		"\n";
7391 
7392 	static const GLchar* fragment_shader_template = "VERSION\n"
7393 													"#extension GL_ARB_enhanced_layouts : require\n"
7394 													"\n"
7395 													"flat in  uint gs_fs_result;\n"
7396 													"     out uint fs_out_result;\n"
7397 													"\n"
7398 													"INTERFACE"
7399 													"\n"
7400 													"void main()\n"
7401 													"{\n"
7402 													"    uint result = 1u;\n"
7403 													"\n"
7404 													"    if (1u != gs_fs_result)\n"
7405 													"    {\n"
7406 													"         result = gs_fs_result;\n"
7407 													"    }\n"
7408 													"ELSEVERIFICATION"
7409 													"\n"
7410 													"    fs_out_result = result;\n"
7411 													"    PASSTHROUGH\n"
7412 													"}\n"
7413 													"\n";
7414 
7415 	static const GLchar* geometry_shader_template =
7416 		"VERSION\n"
7417 		"#extension GL_ARB_enhanced_layouts : require\n"
7418 		"\n"
7419 		"layout(points)                           in;\n"
7420 		"layout(triangle_strip, max_vertices = 4) out;\n"
7421 		"\n"
7422 		"     in  uint tes_gs_result[];\n"
7423 		"     flat out uint gs_fs_result;\n"
7424 		"\n"
7425 		"PERVERTEX" /* Separable programs require explicit declaration of gl_PerVertex */
7426 		"INTERFACE"
7427 		"\n"
7428 		"void main()\n"
7429 		"{\n"
7430 		"    uint result = 1u;\n"
7431 		"\n"
7432 		"    if (1u != tes_gs_result[0])\n"
7433 		"    {\n"
7434 		"         result = tes_gs_result[0];\n"
7435 		"    }\n"
7436 		"ELSEVERIFICATION"
7437 		"\n"
7438 		"    gs_fs_result = result;\n"
7439 		"    PASSTHROUGH\n"
7440 		"    gl_Position  = vec4(-1, -1, 0, 1);\n"
7441 		"    EmitVertex();\n"
7442 		"    gs_fs_result = result;\n"
7443 		"    PASSTHROUGH\n"
7444 		"    gl_Position  = vec4(-1, 1, 0, 1);\n"
7445 		"    EmitVertex();\n"
7446 		"    gs_fs_result = result;\n"
7447 		"    PASSTHROUGH\n"
7448 		"    gl_Position  = vec4(1, -1, 0, 1);\n"
7449 		"    EmitVertex();\n"
7450 		"    gs_fs_result = result;\n"
7451 		"    PASSTHROUGH\n"
7452 		"    gl_Position  = vec4(1, 1, 0, 1);\n"
7453 		"    EmitVertex();\n"
7454 		"}\n"
7455 		"\n";
7456 
7457 	static const GLchar* tess_ctrl_shader_template = "VERSION\n"
7458 													 "#extension GL_ARB_enhanced_layouts : require\n"
7459 													 "\n"
7460 													 "layout(vertices = 1) out;\n"
7461 													 "\n"
7462 													 "in  uint vs_tcs_result[];\n"
7463 													 "out uint tcs_tes_result[];\n"
7464 													 "\n"
7465 													 "INTERFACE"
7466 													 "\n"
7467 													 "void main()\n"
7468 													 "{\n"
7469 													 "    uint result = 1u;\n"
7470 													 "\n"
7471 													 "    if (1u != vs_tcs_result[gl_InvocationID])\n"
7472 													 "    {\n"
7473 													 "         result = vs_tcs_result[gl_InvocationID];\n"
7474 													 "    }\n"
7475 													 "ELSEVERIFICATION"
7476 													 "\n"
7477 													 "    tcs_tes_result[gl_InvocationID] = result;\n"
7478 													 "\n"
7479 													 "    PASSTHROUGH\n"
7480 													 "\n"
7481 													 "    gl_TessLevelOuter[0] = 1.0;\n"
7482 													 "    gl_TessLevelOuter[1] = 1.0;\n"
7483 													 "    gl_TessLevelOuter[2] = 1.0;\n"
7484 													 "    gl_TessLevelOuter[3] = 1.0;\n"
7485 													 "    gl_TessLevelInner[0] = 1.0;\n"
7486 													 "    gl_TessLevelInner[1] = 1.0;\n"
7487 													 "}\n"
7488 													 "\n";
7489 
7490 	static const GLchar* tess_eval_shader_template = "VERSION\n"
7491 													 "#extension GL_ARB_enhanced_layouts : require\n"
7492 													 "\n"
7493 													 "layout(isolines, point_mode) in;\n"
7494 													 "\n"
7495 													 "in  uint tcs_tes_result[];\n"
7496 													 "out uint tes_gs_result;\n"
7497 													 "\n"
7498 													 "INTERFACE"
7499 													 "\n"
7500 													 "void main()\n"
7501 													 "{\n"
7502 													 "    uint result = 1u;\n"
7503 													 "\n"
7504 													 "    if (1u != tcs_tes_result[0])\n"
7505 													 "    {\n"
7506 													 "         result = tcs_tes_result[0];\n"
7507 													 "    }\n"
7508 													 "ELSEVERIFICATION"
7509 													 "\n"
7510 													 "    tes_gs_result = result;\n"
7511 													 "\n"
7512 													 "    PASSTHROUGH\n"
7513 													 "}\n"
7514 													 "\n";
7515 
7516 	static const GLchar* vertex_shader_template = "VERSION\n"
7517 												  "#extension GL_ARB_enhanced_layouts : require\n"
7518 												  "\n"
7519 												  "out uint vs_tcs_result;\n"
7520 												  "\n"
7521 												  "INTERFACE"
7522 												  "\n"
7523 												  "void main()\n"
7524 												  "{\n"
7525 												  "    uint result = 1u;\n"
7526 												  "\n"
7527 												  "    VERIFICATION\n"
7528 												  "\n"
7529 												  "    vs_tcs_result = result;\n"
7530 												  "\n"
7531 												  "    PASSTHROUGH\n"
7532 												  "}\n"
7533 												  "\n";
7534 
7535 	const GLchar* result = 0;
7536 
7537 	switch (stage)
7538 	{
7539 	case Utils::Shader::COMPUTE:
7540 		result = compute_shader_template;
7541 		break;
7542 	case Utils::Shader::FRAGMENT:
7543 		result = fragment_shader_template;
7544 		break;
7545 	case Utils::Shader::GEOMETRY:
7546 		result = geometry_shader_template;
7547 		break;
7548 	case Utils::Shader::TESS_CTRL:
7549 		result = tess_ctrl_shader_template;
7550 		break;
7551 	case Utils::Shader::TESS_EVAL:
7552 		result = tess_eval_shader_template;
7553 		break;
7554 	case Utils::Shader::VERTEX:
7555 		result = vertex_shader_template;
7556 		break;
7557 	default:
7558 		TCU_FAIL("Invalid enum");
7559 	}
7560 
7561 	return result;
7562 }
7563 
7564 /** Runs test case
7565  *
7566  * @param test_case_index Id of test case
7567  *
7568  * @return true if test case pass, false otherwise
7569  **/
7570 bool TextureTestBase::testCase(GLuint test_case_index)
7571 {
7572 	try
7573 	{
7574 		if (true == useMonolithicProgram(test_case_index))
7575 		{
7576 			return testMonolithic(test_case_index);
7577 		}
7578 		else
7579 		{
7580 			return testSeparable(test_case_index);
7581 		}
7582 	}
7583 	catch (Utils::Shader::InvalidSourceException& exc)
7584 	{
7585 		exc.log(m_context);
7586 		TCU_FAIL(exc.what());
7587 	}
7588 	catch (Utils::Program::BuildException& exc)
7589 	{
7590 		exc.log(m_context);
7591 		TCU_FAIL(exc.what());
7592 	}
7593 }
7594 
7595 /** Runs "draw" test with monolithic program
7596  *
7597  * @param test_case_index Id of test case
7598  **/
7599 bool TextureTestBase::testMonolithic(GLuint test_case_index)
7600 {
7601 	Utils::ProgramInterface   program_interface;
7602 	Utils::VaryingPassthrough varying_passthrough;
7603 
7604 	/* */
7605 	const std::string& test_name = getTestCaseName(test_case_index);
7606 
7607 	/* */
7608 	getProgramInterface(test_case_index, program_interface, varying_passthrough);
7609 
7610 	bool result = true;
7611 	/* Draw */
7612 	if (true == isDrawRelevant(test_case_index))
7613 	{
7614 		Utils::Buffer	  buffer_attr(m_context);
7615 		Utils::Buffer	  buffer_ssb_fs(m_context);
7616 		Utils::Buffer	  buffer_ssb_gs(m_context);
7617 		Utils::Buffer	  buffer_ssb_tcs(m_context);
7618 		Utils::Buffer	  buffer_ssb_tes(m_context);
7619 		Utils::Buffer	  buffer_ssb_vs(m_context);
7620 		Utils::Buffer	  buffer_u_fs(m_context);
7621 		Utils::Buffer	  buffer_u_gs(m_context);
7622 		Utils::Buffer	  buffer_u_tcs(m_context);
7623 		Utils::Buffer	  buffer_u_tes(m_context);
7624 		Utils::Buffer	  buffer_u_vs(m_context);
7625 		Utils::Framebuffer framebuffer(m_context);
7626 		Utils::Program	 program(m_context);
7627 		Utils::Texture	 texture_fb(m_context);
7628 		Utils::VertexArray vao(m_context);
7629 
7630 		/* */
7631 		const std::string& fragment_shader =
7632 			getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::FRAGMENT);
7633 		const std::string& geometry_shader =
7634 			getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::GEOMETRY);
7635 		const std::string& tess_ctrl_shader =
7636 			getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::TESS_CTRL);
7637 		const std::string& tess_eval_shader =
7638 			getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::TESS_EVAL);
7639 		const std::string& vertex_shader =
7640 			getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::VERTEX);
7641 
7642 		program.Init("" /* compute_shader */, fragment_shader, geometry_shader, tess_ctrl_shader, tess_eval_shader,
7643 					 vertex_shader, false /* is_separable */);
7644 
7645 		/* */
7646 		prepareAttribLocation(program, program_interface);
7647 		prepareFragmentDataLoc(program, program_interface);
7648 
7649 		/* */
7650 		std::stringstream stream;
7651 		if (false == Utils::checkMonolithicDrawProgramInterface(program, program_interface, stream))
7652 		{
7653 			m_context.getTestContext().getLog()
7654 				<< tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7655 				<< ". Inspection of draw program interface failed:\n"
7656 				<< stream.str() << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(vertex_shader)
7657 				<< tcu::TestLog::KernelSource(tess_ctrl_shader) << tcu::TestLog::KernelSource(tess_eval_shader)
7658 				<< tcu::TestLog::KernelSource(geometry_shader) << tcu::TestLog::KernelSource(fragment_shader);
7659 
7660 			return false;
7661 		}
7662 
7663 		/* */
7664 		program.Use();
7665 
7666 		/* */
7667 		buffer_attr.Init(Utils::Buffer::Array, Utils::Buffer::StaticDraw, 0, 0);
7668 		vao.Init();
7669 		prepareAttributes(test_case_index, program_interface, buffer_attr, vao);
7670 
7671 		/* */
7672 		prepareUniforms(test_case_index, program_interface, program, buffer_u_fs, buffer_u_gs, buffer_u_tcs,
7673 						buffer_u_tes, buffer_u_vs);
7674 
7675 		prepareSSBs(test_case_index, program_interface, program, buffer_ssb_fs, buffer_ssb_gs, buffer_ssb_tcs,
7676 					buffer_ssb_tes, buffer_ssb_vs);
7677 
7678 		/* */
7679 		prepareFramebuffer(framebuffer, texture_fb);
7680 
7681 		/* Draw */
7682 		executeDrawCall(test_case_index);
7683 
7684 #if USE_NSIGHT
7685 		m_context.getRenderContext().postIterate();
7686 #endif
7687 
7688 		/* Check results */
7689 		if (false == checkResults(test_case_index, texture_fb))
7690 		{
7691 			m_context.getTestContext().getLog()
7692 				<< tcu::TestLog::Message << "FAILURE. Test case: " << test_name << ". Draw - invalid results."
7693 				<< tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(vertex_shader)
7694 				<< tcu::TestLog::KernelSource(tess_ctrl_shader) << tcu::TestLog::KernelSource(tess_eval_shader)
7695 				<< tcu::TestLog::KernelSource(geometry_shader) << tcu::TestLog::KernelSource(fragment_shader);
7696 
7697 			result = false;
7698 		}
7699 	}
7700 
7701 	/* Compute */
7702 	if (true == isComputeRelevant(test_case_index))
7703 	{
7704 		Utils::Buffer	  buffer_ssb_cs(m_context);
7705 		Utils::Buffer	  buffer_u_cs(m_context);
7706 		Utils::Program	 program(m_context);
7707 		Utils::Texture	 texture_im(m_context);
7708 		Utils::VertexArray vao(m_context);
7709 
7710 		/* */
7711 		const std::string& compute_shader =
7712 			getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::COMPUTE);
7713 
7714 		program.Init(compute_shader, "" /* fragment_shader */, "" /* geometry_shader */, "" /* tess_ctrl_shader */,
7715 					 "" /* tess_eval_shader */, "" /* vertex_shader */, false /* is_separable */);
7716 
7717 		/* */
7718 		{
7719 			std::stringstream stream;
7720 
7721 			if (false == Utils::checkMonolithicComputeProgramInterface(program, program_interface, stream))
7722 			{
7723 				m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7724 													<< ". Inspection of compute program interface failed:\n"
7725 													<< stream.str() << tcu::TestLog::EndMessage;
7726 
7727 				return false;
7728 			}
7729 		}
7730 
7731 		/* */
7732 		program.Use();
7733 
7734 		/* */
7735 		vao.Init();
7736 		vao.Bind();
7737 
7738 		/* */
7739 		prepareUniforms(test_case_index, program_interface, program, buffer_u_cs);
7740 
7741 		prepareSSBs(test_case_index, program_interface, program, buffer_ssb_cs);
7742 
7743 		/* */
7744 		GLint image_location = program.GetUniformLocation("uni_image");
7745 		prepareImage(image_location, texture_im);
7746 
7747 		/* Draw */
7748 		executeDispatchCall(test_case_index);
7749 
7750 #if USE_NSIGHT
7751 		m_context.getRenderContext().postIterate();
7752 #endif
7753 
7754 		/* Check results */
7755 		if (false == checkResults(test_case_index, texture_im))
7756 		{
7757 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7758 												<< ". Compute - invalid results." << tcu::TestLog::EndMessage
7759 												<< tcu::TestLog::KernelSource(compute_shader);
7760 
7761 			result = false;
7762 		}
7763 	}
7764 
7765 	return result;
7766 }
7767 
7768 /** Runs "draw" test with separable program
7769  *
7770  * @param test_case_index Id of test case
7771  **/
7772 bool TextureTestBase::testSeparable(GLuint test_case_index)
7773 {
7774 	Utils::ProgramInterface   program_interface;
7775 	Utils::VaryingPassthrough varying_passthrough;
7776 
7777 	/* */
7778 	const std::string& test_name = getTestCaseName(test_case_index);
7779 
7780 	/* */
7781 	getProgramInterface(test_case_index, program_interface, varying_passthrough);
7782 
7783 	bool result = true;
7784 	/* Draw */
7785 	if (true == isDrawRelevant(test_case_index))
7786 	{
7787 		Utils::Buffer	  buffer_attr(m_context);
7788 		Utils::Buffer	  buffer_u_fs(m_context);
7789 		Utils::Buffer	  buffer_u_gs(m_context);
7790 		Utils::Buffer	  buffer_u_tcs(m_context);
7791 		Utils::Buffer	  buffer_u_tes(m_context);
7792 		Utils::Buffer	  buffer_u_vs(m_context);
7793 		Utils::Framebuffer framebuffer(m_context);
7794 		Utils::Pipeline	pipeline(m_context);
7795 		Utils::Program	 program_fs(m_context);
7796 		Utils::Program	 program_gs(m_context);
7797 		Utils::Program	 program_tcs(m_context);
7798 		Utils::Program	 program_tes(m_context);
7799 		Utils::Program	 program_vs(m_context);
7800 		Utils::Texture	 texture_fb(m_context);
7801 		Utils::VertexArray vao(m_context);
7802 
7803 		/* */
7804 		const std::string& fs =
7805 			getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::FRAGMENT);
7806 		const std::string& gs =
7807 			getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::GEOMETRY);
7808 		const std::string& tcs =
7809 			getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::TESS_CTRL);
7810 		const std::string& tes =
7811 			getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::TESS_EVAL);
7812 		const std::string& vs =
7813 			getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::VERTEX);
7814 
7815 		program_fs.Init("" /*cs*/, fs, "" /*gs*/, "" /*tcs*/, "" /*tes*/, "" /*vs*/, true /* is_separable */);
7816 		program_gs.Init("" /*cs*/, "" /*fs*/, gs, "" /*tcs*/, "" /*tes*/, "" /*vs*/, true /* is_separable */);
7817 		program_tcs.Init("" /*cs*/, "" /*fs*/, "" /*gs*/, tcs, "" /*tes*/, "" /*vs*/, true /* is_separable */);
7818 		program_tes.Init("" /*cs*/, "" /*fs*/, "" /*gs*/, "" /*tcs*/, tes, "" /*vs*/, true /* is_separable */);
7819 		program_vs.Init("" /*cs*/, "" /*fs*/, "" /*gs*/, "" /*tcs*/, "" /*tes*/, vs, true /* is_separable */);
7820 
7821 		/* */
7822 		prepareAttribLocation(program_vs, program_interface);
7823 		prepareFragmentDataLoc(program_vs, program_interface);
7824 
7825 		/* */
7826 		std::stringstream stream;
7827 		if ((false ==
7828 			 Utils::checkSeparableDrawProgramInterface(program_vs, program_interface, Utils::Shader::VERTEX, stream)) ||
7829 			(false == Utils::checkSeparableDrawProgramInterface(program_fs, program_interface, Utils::Shader::FRAGMENT,
7830 																stream)) ||
7831 			(false == Utils::checkSeparableDrawProgramInterface(program_gs, program_interface, Utils::Shader::GEOMETRY,
7832 																stream)) ||
7833 			(false == Utils::checkSeparableDrawProgramInterface(program_tcs, program_interface,
7834 																Utils::Shader::TESS_CTRL, stream)) ||
7835 			(false == Utils::checkSeparableDrawProgramInterface(program_tes, program_interface,
7836 																Utils::Shader::TESS_EVAL, stream)))
7837 		{
7838 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7839 												<< ". Inspection of separable draw program interface failed:\n"
7840 												<< stream.str() << tcu::TestLog::EndMessage
7841 												<< tcu::TestLog::KernelSource(vs) << tcu::TestLog::KernelSource(tcs)
7842 												<< tcu::TestLog::KernelSource(tes) << tcu::TestLog::KernelSource(gs)
7843 												<< tcu::TestLog::KernelSource(fs);
7844 
7845 			return false;
7846 		}
7847 
7848 		/* */
7849 		pipeline.Init();
7850 		pipeline.UseProgramStages(program_fs.m_id, GL_FRAGMENT_SHADER_BIT);
7851 		pipeline.UseProgramStages(program_gs.m_id, GL_GEOMETRY_SHADER_BIT);
7852 		pipeline.UseProgramStages(program_tcs.m_id, GL_TESS_CONTROL_SHADER_BIT);
7853 		pipeline.UseProgramStages(program_tes.m_id, GL_TESS_EVALUATION_SHADER_BIT);
7854 		pipeline.UseProgramStages(program_vs.m_id, GL_VERTEX_SHADER_BIT);
7855 		pipeline.Bind();
7856 
7857 		/* */
7858 
7859 		buffer_attr.Init(Utils::Buffer::Array, Utils::Buffer::StaticDraw, 0, 0);
7860 		vao.Init();
7861 		prepareAttributes(test_case_index, program_interface, buffer_attr, vao);
7862 
7863 		/* */
7864 		prepareUniforms(test_case_index, program_interface, program_fs, program_gs, program_tcs, program_tes,
7865 						program_vs, buffer_u_fs, buffer_u_gs, buffer_u_tcs, buffer_u_tes, buffer_u_vs);
7866 
7867 		Utils::Program::Use(m_context.getRenderContext().getFunctions(), Utils::Program::m_invalid_id);
7868 
7869 		/* */
7870 		prepareFramebuffer(framebuffer, texture_fb);
7871 
7872 		/* Draw */
7873 		executeDrawCall(test_case_index);
7874 
7875 #if USE_NSIGHT
7876 		m_context.getRenderContext().postIterate();
7877 #endif
7878 
7879 		/* Check results */
7880 		if (false == checkResults(test_case_index, texture_fb))
7881 		{
7882 			m_context.getTestContext().getLog()
7883 				<< tcu::TestLog::Message << "FAILURE. Test case: " << test_name << ". Draw - invalid results."
7884 				<< tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(vs) << tcu::TestLog::KernelSource(tcs)
7885 				<< tcu::TestLog::KernelSource(tes) << tcu::TestLog::KernelSource(gs) << tcu::TestLog::KernelSource(fs);
7886 
7887 			result = false;
7888 		}
7889 		else
7890 		{
7891 			m_context.getTestContext().getLog()
7892 				<< tcu::TestLog::Message << "Success." << tcu::TestLog::EndMessage << tcu::TestLog::KernelSource(vs)
7893 				<< tcu::TestLog::KernelSource(tcs) << tcu::TestLog::KernelSource(tes) << tcu::TestLog::KernelSource(gs)
7894 				<< tcu::TestLog::KernelSource(fs);
7895 		}
7896 	}
7897 
7898 	/* Compute */
7899 	if (true == isComputeRelevant(test_case_index))
7900 	{
7901 		Utils::Buffer	  buffer_u_cs(m_context);
7902 		Utils::Program	 program(m_context);
7903 		Utils::Texture	 texture_im(m_context);
7904 		Utils::VertexArray vao(m_context);
7905 
7906 		/* */
7907 		const std::string& compute_shader =
7908 			getShaderSource(test_case_index, program_interface, varying_passthrough, Utils::Shader::COMPUTE);
7909 
7910 		program.Init(compute_shader, "" /* fragment_shader */, "" /* geometry_shader */, "" /* tess_ctrl_shader */,
7911 					 "" /* tess_eval_shader */, "" /* vertex_shader */, false /* is_separable */);
7912 
7913 		/* */
7914 		{
7915 			std::stringstream stream;
7916 
7917 			if (false == Utils::checkMonolithicComputeProgramInterface(program, program_interface, stream))
7918 			{
7919 				m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7920 													<< ". Inspection of compute program interface failed:\n"
7921 													<< stream.str() << tcu::TestLog::EndMessage;
7922 
7923 				return false;
7924 			}
7925 		}
7926 
7927 		/* */
7928 		program.Use();
7929 
7930 		/* */
7931 		vao.Init();
7932 		vao.Bind();
7933 
7934 		/* */
7935 		prepareUniforms(test_case_index, program_interface, program, buffer_u_cs);
7936 
7937 		/* */
7938 		GLint image_location = program.GetUniformLocation("uni_image");
7939 		prepareImage(image_location, texture_im);
7940 
7941 		/* Draw */
7942 		executeDispatchCall(test_case_index);
7943 
7944 #if USE_NSIGHT
7945 		m_context.getRenderContext().postIterate();
7946 #endif
7947 
7948 		/* Check results */
7949 		if (false == checkResults(test_case_index, texture_im))
7950 		{
7951 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "FAILURE. Test case: " << test_name
7952 												<< ". Compute - invalid results." << tcu::TestLog::EndMessage
7953 												<< tcu::TestLog::KernelSource(compute_shader);
7954 
7955 			result = false;
7956 		}
7957 	}
7958 
7959 	return result;
7960 }
7961 
7962 /** Basic implementation
7963  *
7964  * @param ignored
7965  *
7966  * @return false
7967  **/
7968 bool TextureTestBase::useComponentQualifier(glw::GLuint /* test_case_index */)
7969 {
7970 	return false;
7971 }
7972 
7973 /** Basic implementation
7974  *
7975  * @param ignored
7976  *
7977  * @return true
7978  **/
7979 bool TextureTestBase::useMonolithicProgram(GLuint /* test_case_index */)
7980 {
7981 	return true;
7982 }
7983 
7984 /** Constructor
7985  *
7986  * @param context Test framework context
7987  **/
7988 APIConstantValuesTest::APIConstantValuesTest(deqp::Context& context)
7989 	: TestCase(context, "api_constant_values", "Test verifies values of api constants")
7990 {
7991 	/* Nothing to be done here */
7992 }
7993 
7994 /** Execute test
7995  *
7996  * @return tcu::TestNode::STOP otherwise
7997  **/
7998 tcu::TestNode::IterateResult APIConstantValuesTest::iterate()
7999 {
8000 	static const GLuint expected_comp = 64;
8001 	static const GLuint expected_xfb  = 4;
8002 	static const GLuint expected_sep  = 4;
8003 	GLint				max_comp	  = 0;
8004 	GLint				max_xfb		  = 0;
8005 	GLint				max_sep		  = 0;
8006 	bool				test_result   = true;
8007 
8008 	const Functions& gl = m_context.getRenderContext().getFunctions();
8009 
8010 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_xfb);
8011 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8012 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_comp);
8013 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8014 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, &max_sep);
8015 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8016 
8017 	if (expected_xfb > (GLuint)max_xfb)
8018 	{
8019 		m_context.getTestContext().getLog() << tcu::TestLog::Message
8020 											<< "Invalid GL_MAX_TRANSFORM_FEEDBACK_BUFFERS. Got " << max_xfb
8021 											<< " Expected at least " << expected_xfb << tcu::TestLog::EndMessage;
8022 
8023 		test_result = false;
8024 	}
8025 
8026 	if (expected_comp > (GLuint)max_comp)
8027 	{
8028 		m_context.getTestContext().getLog()
8029 			<< tcu::TestLog::Message << "Invalid GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS. Got " << max_comp
8030 			<< " Expected at least " << expected_comp << tcu::TestLog::EndMessage;
8031 
8032 		test_result = false;
8033 	}
8034 
8035 	if (expected_sep > (GLuint)max_sep)
8036 	{
8037 		m_context.getTestContext().getLog() << tcu::TestLog::Message
8038 											<< "Invalid GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS. Got " << max_comp
8039 											<< " Expected at least " << expected_comp << tcu::TestLog::EndMessage;
8040 
8041 		test_result = false;
8042 	}
8043 
8044 	/* Set result */
8045 	if (true == test_result)
8046 	{
8047 		m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
8048 	}
8049 	else
8050 	{
8051 		m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
8052 	}
8053 
8054 	/* Done */
8055 	return tcu::TestNode::STOP;
8056 }
8057 
8058 /** Constructor
8059  *
8060  * @param context Test framework context
8061  **/
8062 APIErrorsTest::APIErrorsTest(deqp::Context& context)
8063 	: TestCase(context, "api_errors", "Test verifies errors reeturned by api")
8064 {
8065 	/* Nothing to be done here */
8066 }
8067 
8068 /** Execute test
8069  *
8070  * @return tcu::TestNode::STOP otherwise
8071  **/
8072 tcu::TestNode::IterateResult APIErrorsTest::iterate()
8073 {
8074 	GLint		   length = 0;
8075 	GLchar		   name[64];
8076 	GLint		   param = 0;
8077 	Utils::Program program(m_context);
8078 	bool		   test_result = true;
8079 
8080 	const Functions& gl = m_context.getRenderContext().getFunctions();
8081 
8082 	try
8083 	{
8084 		program.Init("" /* cs */, "#version 430 core\n"
8085 								  "#extension GL_ARB_enhanced_layouts : require\n"
8086 								  "\n"
8087 								  "in  vec4 vs_fs;\n"
8088 								  "out vec4 fs_out;\n"
8089 								  "\n"
8090 								  "void main()\n"
8091 								  "{\n"
8092 								  "    fs_out = vs_fs;\n"
8093 								  "}\n"
8094 								  "\n" /* fs */,
8095 					 "" /* gs */, "" /* tcs */, "" /* tes */, "#version 430 core\n"
8096 															  "#extension GL_ARB_enhanced_layouts : require\n"
8097 															  "\n"
8098 															  "in  vec4 in_vs;\n"
8099 															  "layout (xfb_offset = 16) out vec4 vs_fs;\n"
8100 															  "\n"
8101 															  "void main()\n"
8102 															  "{\n"
8103 															  "    vs_fs = in_vs;\n"
8104 															  "}\n"
8105 															  "\n" /* vs */,
8106 					 false /* separable */);
8107 	}
8108 	catch (Utils::Shader::InvalidSourceException& exc)
8109 	{
8110 		exc.log(m_context);
8111 		TCU_FAIL(exc.what());
8112 	}
8113 	catch (Utils::Program::BuildException& exc)
8114 	{
8115 		TCU_FAIL(exc.what());
8116 	}
8117 
8118 	/*
8119 	 * - GetProgramInterfaceiv should generate INVALID_OPERATION when
8120 	 * <programInterface> is TRANSFORM_FEEDBACK_BUFFER and <pname> is one of the
8121 	 * following:
8122 	 *   * MAX_NAME_LENGTH,
8123 	 *   * MAX_NUM_ACTIVE_VARIABLES;
8124 	 */
8125 	gl.getProgramInterfaceiv(program.m_id, GL_TRANSFORM_FEEDBACK_BUFFER, GL_MAX_NAME_LENGTH, &param);
8126 	checkError(GL_INVALID_OPERATION, "GetProgramInterfaceiv(GL_TRANSFORM_FEEDBACK_BUFFER, GL_MAX_NAME_LENGTH)",
8127 			   test_result);
8128 
8129 	/*
8130 	 * - GetProgramResourceIndex should generate INVALID_ENUM when
8131 	 * <programInterface> is TRANSFORM_FEEDBACK_BUFFER;
8132 	 */
8133 	gl.getProgramResourceIndex(program.m_id, GL_TRANSFORM_FEEDBACK_BUFFER, "0");
8134 	checkError(GL_INVALID_ENUM, "GetProgramResourceIndex(GL_TRANSFORM_FEEDBACK_BUFFER)", test_result);
8135 	/*
8136 	 * - GetProgramResourceName should generate INVALID_ENUM when
8137 	 * <programInterface> is TRANSFORM_FEEDBACK_BUFFER;
8138 	 */
8139 	gl.getProgramResourceName(program.m_id, GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, 64 /* bufSize */, &length,
8140 							  name);
8141 	checkError(GL_INVALID_ENUM, "GetProgramResourceName(GL_TRANSFORM_FEEDBACK_BUFFER)", test_result);
8142 
8143 	/* Set result */
8144 	if (true == test_result)
8145 	{
8146 		m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
8147 	}
8148 	else
8149 	{
8150 		m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
8151 	}
8152 
8153 	/* Done */
8154 	return tcu::TestNode::STOP;
8155 }
8156 
8157 /** Check if error is the expected one.
8158  *
8159  * @param expected_error Expected error
8160  * @param message        Message to log in case of error
8161  * @param test_result    Test result, set to false in case of invalid error
8162  **/
8163 void APIErrorsTest::checkError(GLenum expected_error, const GLchar* message, bool& test_result)
8164 {
8165 	const Functions& gl = m_context.getRenderContext().getFunctions();
8166 
8167 	GLenum error = gl.getError();
8168 
8169 	if (error != expected_error)
8170 	{
8171 		m_context.getTestContext().getLog()
8172 			<< tcu::TestLog::Message << "Failure. Invalid error. Got " << glu::getErrorStr(error) << " expected "
8173 			<< glu::getErrorStr(expected_error) << " Msg: " << message << tcu::TestLog::EndMessage;
8174 
8175 		test_result = false;
8176 	}
8177 }
8178 
8179 /** Constructor
8180  *
8181  * @param context Test framework context
8182  **/
8183 GLSLContantImmutablityTest::GLSLContantImmutablityTest(deqp::Context& context)
8184 	: NegativeTestBase(context, "glsl_contant_immutablity", "Test verifies that glsl constants cannot be modified")
8185 {
8186 	/* Nothing to be done here */
8187 }
8188 
8189 /** Source for given test case and stage
8190  *
8191  * @param test_case_index Index of test case
8192  * @param stage           Shader stage
8193  *
8194  * @return Shader source
8195  **/
8196 std::string GLSLContantImmutablityTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
8197 {
8198 	static const GLchar* cs = "#version 430 core\n"
8199 							  "#extension GL_ARB_enhanced_layouts : require\n"
8200 							  "\n"
8201 							  "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
8202 							  "\n"
8203 							  "writeonly uniform uimage2D uni_image;\n"
8204 							  "\n"
8205 							  "void main()\n"
8206 							  "{\n"
8207 							  "    uint result = 1u;\n"
8208 							  "    CONSTANT = 3;\n"
8209 							  "\n"
8210 							  "    imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), uvec4(result, 0, 0, 0));\n"
8211 							  "}\n"
8212 							  "\n";
8213 	static const GLchar* fs = "#version 430 core\n"
8214 							  "#extension GL_ARB_enhanced_layouts : require\n"
8215 							  "\n"
8216 							  "in  vec4 gs_fs;\n"
8217 							  "out vec4 fs_out;\n"
8218 							  "\n"
8219 							  "void main()\n"
8220 							  "{\n"
8221 							  "ASSIGNMENT"
8222 							  "    fs_out = gs_fs;\n"
8223 							  "}\n"
8224 							  "\n";
8225 	static const GLchar* gs = "#version 430 core\n"
8226 							  "#extension GL_ARB_enhanced_layouts : require\n"
8227 							  "\n"
8228 							  "layout(points)                           in;\n"
8229 							  "layout(triangle_strip, max_vertices = 4) out;\n"
8230 							  "\n"
8231 							  "in  vec4 tes_gs[];\n"
8232 							  "out vec4 gs_fs;\n"
8233 							  "\n"
8234 							  "void main()\n"
8235 							  "{\n"
8236 							  "ASSIGNMENT"
8237 							  "    gs_fs = tes_gs[0];\n"
8238 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
8239 							  "    EmitVertex();\n"
8240 							  "    gs_fs = tes_gs[0];\n"
8241 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
8242 							  "    EmitVertex();\n"
8243 							  "    gs_fs = tes_gs[0];\n"
8244 							  "    gl_Position  = vec4(1, -1, 0, 1);\n"
8245 							  "    EmitVertex();\n"
8246 							  "    gs_fs = tes_gs[0];\n"
8247 							  "    gl_Position  = vec4(1, 1, 0, 1);\n"
8248 							  "    EmitVertex();\n"
8249 							  "}\n"
8250 							  "\n";
8251 	static const GLchar* tcs = "#version 430 core\n"
8252 							   "#extension GL_ARB_enhanced_layouts : require\n"
8253 							   "\n"
8254 							   "layout(vertices = 1) out;\n"
8255 							   "\n"
8256 							   "in  vec4 vs_tcs[];\n"
8257 							   "out vec4 tcs_tes[];\n"
8258 							   "\n"
8259 							   "void main()\n"
8260 							   "{\n"
8261 							   "\n"
8262 							   "ASSIGNMENT"
8263 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
8264 							   "\n"
8265 							   "    gl_TessLevelOuter[0] = 1.0;\n"
8266 							   "    gl_TessLevelOuter[1] = 1.0;\n"
8267 							   "    gl_TessLevelOuter[2] = 1.0;\n"
8268 							   "    gl_TessLevelOuter[3] = 1.0;\n"
8269 							   "    gl_TessLevelInner[0] = 1.0;\n"
8270 							   "    gl_TessLevelInner[1] = 1.0;\n"
8271 							   "}\n"
8272 							   "\n";
8273 	static const GLchar* tes = "#version 430 core\n"
8274 							   "#extension GL_ARB_enhanced_layouts : require\n"
8275 							   "\n"
8276 							   "layout(isolines, point_mode) in;\n"
8277 							   "\n"
8278 							   "in  vec4 tcs_tes[];\n"
8279 							   "out vec4 tes_gs;\n"
8280 							   "\n"
8281 							   "void main()\n"
8282 							   "{\n"
8283 							   "ASSIGNMENT"
8284 							   "    tes_gs = tcs_tes[0];\n"
8285 							   "}\n"
8286 							   "\n";
8287 	static const GLchar* vs = "#version 430 core\n"
8288 							  "#extension GL_ARB_enhanced_layouts : require\n"
8289 							  "\n"
8290 							  "in  vec4 in_vs;\n"
8291 							  "out vec4 vs_tcs;\n"
8292 							  "\n"
8293 							  "void main()\n"
8294 							  "{\n"
8295 							  "ASSIGNMENT"
8296 							  "    vs_tcs = in_vs;\n"
8297 							  "}\n"
8298 							  "\n";
8299 
8300 	std::string source;
8301 	testCase&   test_case = m_test_cases[test_case_index];
8302 
8303 	if (Utils::Shader::COMPUTE == test_case.m_stage)
8304 	{
8305 		size_t position = 0;
8306 
8307 		source = cs;
8308 
8309 		Utils::replaceToken("CONSTANT", position, getConstantName(test_case.m_constant), source);
8310 	}
8311 	else
8312 	{
8313 		std::string assignment = "    CONSTANT = 3;\n";
8314 		size_t		position   = 0;
8315 
8316 		switch (stage)
8317 		{
8318 		case Utils::Shader::FRAGMENT:
8319 			source = fs;
8320 			break;
8321 		case Utils::Shader::GEOMETRY:
8322 			source = gs;
8323 			break;
8324 		case Utils::Shader::TESS_CTRL:
8325 			source = tcs;
8326 			break;
8327 		case Utils::Shader::TESS_EVAL:
8328 			source = tes;
8329 			break;
8330 		case Utils::Shader::VERTEX:
8331 			source = vs;
8332 			break;
8333 		default:
8334 			TCU_FAIL("Invalid enum");
8335 		}
8336 
8337 		if (test_case.m_stage == stage)
8338 		{
8339 			Utils::replaceToken("CONSTANT", position, getConstantName(test_case.m_constant), assignment);
8340 		}
8341 		else
8342 		{
8343 			assignment = "";
8344 		}
8345 
8346 		position = 0;
8347 		Utils::replaceToken("ASSIGNMENT", position, assignment.c_str(), source);
8348 	}
8349 
8350 	return source;
8351 }
8352 
8353 /** Get description of test case
8354  *
8355  * @param test_case_index Index of test case
8356  *
8357  * @return Constant name
8358  **/
8359 std::string GLSLContantImmutablityTest::getTestCaseName(GLuint test_case_index)
8360 {
8361 	std::string result = getConstantName(m_test_cases[test_case_index].m_constant);
8362 
8363 	return result;
8364 }
8365 
8366 /** Get number of test cases
8367  *
8368  * @return Number of test cases
8369  **/
8370 GLuint GLSLContantImmutablityTest::getTestCaseNumber()
8371 {
8372 	return static_cast<GLuint>(m_test_cases.size());
8373 }
8374 
8375 /** Selects if "compute" stage is relevant for test
8376  *
8377  * @param test_case_index Index of test case
8378  *
8379  * @return true when tested stage is compute
8380  **/
8381 bool GLSLContantImmutablityTest::isComputeRelevant(GLuint test_case_index)
8382 {
8383 	return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
8384 }
8385 
8386 /** Prepare all test cases
8387  *
8388  **/
8389 void GLSLContantImmutablityTest::testInit()
8390 {
8391 	for (GLuint constant = 0; constant < CONSTANTS_MAX; ++constant)
8392 	{
8393 		for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
8394 		{
8395 			testCase test_case = { (CONSTANTS)constant, (Utils::Shader::STAGES)stage };
8396 
8397 			m_test_cases.push_back(test_case);
8398 		}
8399 	}
8400 }
8401 
8402 /** Get name of glsl constant
8403  *
8404  * @param Constant id
8405  *
8406  * @return Name of constant used in GLSL
8407  **/
8408 const GLchar* GLSLContantImmutablityTest::getConstantName(CONSTANTS constant)
8409 {
8410 	const GLchar* name = "";
8411 
8412 	switch (constant)
8413 	{
8414 	case GL_ARB_ENHANCED_LAYOUTS:
8415 		name = "GL_ARB_enhanced_layouts";
8416 		break;
8417 	case GL_MAX_XFB:
8418 		name = "gl_MaxTransformFeedbackBuffers";
8419 		break;
8420 	case GL_MAX_XFB_INT_COMP:
8421 		name = "gl_MaxTransformFeedbackInterleavedComponents";
8422 		break;
8423 	default:
8424 		TCU_FAIL("Invalid enum");
8425 	}
8426 
8427 	return name;
8428 }
8429 
8430 /** Constructor
8431  *
8432  * @param context Test framework context
8433  **/
8434 GLSLContantValuesTest::GLSLContantValuesTest(deqp::Context& context)
8435 	: TextureTestBase(context, "glsl_contant_values", "Test verifies values of constant symbols")
8436 {
8437 }
8438 
8439 /** Selects if "compute" stage is relevant for test
8440  *
8441  * @param ignored
8442  *
8443  * @return false
8444  **/
8445 bool GLSLContantValuesTest::isComputeRelevant(GLuint /* test_case_index */)
8446 {
8447 	return false;
8448 }
8449 
8450 /** Prepare code snippet that will verify in and uniform variables
8451  *
8452  * @param ignored
8453  * @param ignored
8454  * @param stage   Shader stage
8455  *
8456  * @return Code that verify variables
8457  **/
8458 std::string GLSLContantValuesTest::getVerificationSnippet(GLuint /* test_case_index */,
8459 														  Utils::ProgramInterface& /* program_interface */,
8460 														  Utils::Shader::STAGES stage)
8461 {
8462 	/* Get constants */
8463 	const Functions& gl = m_context.getRenderContext().getFunctions();
8464 
8465 	GLint max_transform_feedback_buffers				= 0;
8466 	GLint max_transform_feedback_interleaved_components = 0;
8467 
8468 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_transform_feedback_buffers);
8469 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8470 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_transform_feedback_interleaved_components);
8471 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8472 
8473 	std::string verification;
8474 
8475 	if (Utils::Shader::VERTEX == stage)
8476 	{
8477 		verification = "if (1 != GL_ARB_enhanced_layouts)\n"
8478 					   "    {\n"
8479 					   "        result = 0;\n"
8480 					   "    }\n"
8481 					   "    else if (MAX_TRANSFORM_FEEDBACK_BUFFERS\n"
8482 					   "        != gl_MaxTransformFeedbackBuffers)\n"
8483 					   "    {\n"
8484 					   "        result = 0;\n"
8485 					   "    }\n"
8486 					   "    else if (MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS \n"
8487 					   "        != gl_MaxTransformFeedbackInterleavedComponents)\n"
8488 					   "    {\n"
8489 					   "        result = 0;\n"
8490 					   "    }\n";
8491 
8492 		size_t position = 0;
8493 		GLchar buffer[16];
8494 
8495 		sprintf(buffer, "%d", max_transform_feedback_buffers);
8496 		Utils::replaceToken("MAX_TRANSFORM_FEEDBACK_BUFFERS", position, buffer, verification);
8497 
8498 		sprintf(buffer, "%d", max_transform_feedback_interleaved_components);
8499 		Utils::replaceToken("MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS", position, buffer, verification);
8500 	}
8501 	else
8502 	{
8503 		verification = "";
8504 	}
8505 
8506 	return verification;
8507 }
8508 
8509 /** Constructor
8510  *
8511  * @param context Test framework context
8512  **/
8513 GLSLConstantIntegralExpressionTest::GLSLConstantIntegralExpressionTest(deqp::Context& context)
8514 	: TextureTestBase(context, "glsl_constant_integral_expression",
8515 					  "Test verifies that symbols can be used as constant integral expressions")
8516 {
8517 }
8518 
8519 /** Get interface of program
8520  *
8521  * @param ignored
8522  * @param program_interface Interface of program
8523  * @param ignored
8524  **/
8525 void GLSLConstantIntegralExpressionTest::getProgramInterface(GLuint /* test_case_index */,
8526 															 Utils::ProgramInterface& program_interface,
8527 															 Utils::VaryingPassthrough& /* varying_passthrough */)
8528 {
8529 	/* Get constants */
8530 	const Functions& gl = m_context.getRenderContext().getFunctions();
8531 
8532 	GLint max_transform_feedback_buffers				= 0;
8533 	GLint max_transform_feedback_interleaved_components = 0;
8534 
8535 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_transform_feedback_buffers);
8536 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8537 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_transform_feedback_interleaved_components);
8538 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
8539 
8540 	GLuint gohan_div = std::max(1, max_transform_feedback_buffers / 16);
8541 	GLuint goten_div = std::max(1, max_transform_feedback_interleaved_components / 16);
8542 
8543 	m_gohan_length = max_transform_feedback_buffers / gohan_div;
8544 	m_goten_length = max_transform_feedback_interleaved_components / goten_div;
8545 
8546 	/* Globals */
8547 	std::string globals = "uniform uint goku [GL_ARB_enhanced_layouts / 1];\n"
8548 						  "uniform uint gohan[gl_MaxTransformFeedbackBuffers / GOHAN_DIV];\n"
8549 						  "uniform uint goten[gl_MaxTransformFeedbackInterleavedComponents / GOTEN_DIV];\n";
8550 
8551 	size_t position = 0;
8552 	GLchar buffer[16];
8553 
8554 	sprintf(buffer, "%d", gohan_div);
8555 	Utils::replaceToken("GOHAN_DIV", position, buffer, globals);
8556 
8557 	sprintf(buffer, "%d", goten_div);
8558 	Utils::replaceToken("GOTEN_DIV", position, buffer, globals);
8559 
8560 	program_interface.m_vertex.m_globals	= globals;
8561 	program_interface.m_tess_ctrl.m_globals = globals;
8562 	program_interface.m_tess_eval.m_globals = globals;
8563 	program_interface.m_geometry.m_globals  = globals;
8564 	program_interface.m_fragment.m_globals  = globals;
8565 	program_interface.m_compute.m_globals   = globals;
8566 }
8567 
8568 /** Prepare code snippet that will verify in and uniform variables
8569  *
8570  * @param ignored
8571  * @param ignored
8572  * @param ignored
8573  *
8574  * @return Code that verify variables
8575  **/
8576 std::string GLSLConstantIntegralExpressionTest::getVerificationSnippet(GLuint /* test_case_index */,
8577 																	   Utils::ProgramInterface& /* program_interface */,
8578 																	   Utils::Shader::STAGES /* stage */)
8579 {
8580 	std::string verification = "{\n"
8581 							   "        uint goku_sum = 0;\n"
8582 							   "        uint gohan_sum = 0;\n"
8583 							   "        uint goten_sum = 0;\n"
8584 							   "\n"
8585 							   "        for (uint i = 0u; i < goku.length(); ++i)\n"
8586 							   "        {\n"
8587 							   "            goku_sum += goku[i];\n"
8588 							   "        }\n"
8589 							   "\n"
8590 							   "        for (uint i = 0u; i < gohan.length(); ++i)\n"
8591 							   "        {\n"
8592 							   "            gohan_sum += gohan[i];\n"
8593 							   "        }\n"
8594 							   "\n"
8595 							   "        for (uint i = 0u; i < goten.length(); ++i)\n"
8596 							   "        {\n"
8597 							   "            goten_sum += goten[i];\n"
8598 							   "        }\n"
8599 							   "\n"
8600 							   "        if ( (1u != goku_sum)  &&\n"
8601 							   "             (EXPECTED_GOHAN_SUMu != gohan_sum) ||\n"
8602 							   "             (EXPECTED_GOTEN_SUMu != goten_sum) )\n"
8603 							   "        {\n"
8604 							   "            result = 0u;\n"
8605 							   "        }\n"
8606 							   "    }\n";
8607 
8608 	size_t position = 0;
8609 	GLchar buffer[16];
8610 
8611 	sprintf(buffer, "%d", m_gohan_length);
8612 	Utils::replaceToken("EXPECTED_GOHAN_SUM", position, buffer, verification);
8613 
8614 	sprintf(buffer, "%d", m_goten_length);
8615 	Utils::replaceToken("EXPECTED_GOTEN_SUM", position, buffer, verification);
8616 
8617 	return verification;
8618 }
8619 
8620 /** Prepare unifroms
8621  *
8622  * @param ignored
8623  * @param ignored
8624  * @param program Program object
8625  * @param ignored
8626  **/
8627 void GLSLConstantIntegralExpressionTest::prepareUniforms(GLuint /* test_case_index */,
8628 														 Utils::ProgramInterface& /* program_interface */,
8629 														 Utils::Program& program, Utils::Buffer& /* cs_buffer */)
8630 {
8631 	static const GLuint uniform_data[16] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
8632 
8633 	const Functions& gl = m_context.getRenderContext().getFunctions();
8634 
8635 	GLint goku_location  = program.GetUniformLocation("goku");
8636 	GLint gohan_location = program.GetUniformLocation("gohan");
8637 	GLint goten_location = program.GetUniformLocation("goten");
8638 
8639 	program.Uniform(gl, Utils::Type::uint, 1 /* count */, goku_location, uniform_data);
8640 	program.Uniform(gl, Utils::Type::uint, m_gohan_length, gohan_location, uniform_data);
8641 	program.Uniform(gl, Utils::Type::uint, m_goten_length, goten_location, uniform_data);
8642 }
8643 
8644 /** Prepare unifroms
8645  *
8646  * @param test_case_index   Pass as param to first implemetnation
8647  * @param program_interface Pass as param to first implemetnation
8648  * @param program           Pass as param to first implemetnation
8649  * @param ignored
8650  * @param ignored
8651  * @param ignored
8652  * @param ignored
8653  * @param vs_buffer         Pass as param to first implemetnation
8654  **/
8655 void GLSLConstantIntegralExpressionTest::prepareUniforms(GLuint					  test_case_index,
8656 														 Utils::ProgramInterface& program_interface,
8657 														 Utils::Program& program, Utils::Buffer& /* fs_buffer */,
8658 														 Utils::Buffer& /* gs_buffer */,
8659 														 Utils::Buffer& /* tcs_buffer */,
8660 														 Utils::Buffer& /* tes_buffer */, Utils::Buffer& vs_buffer)
8661 {
8662 	/* Call first implementation */
8663 	prepareUniforms(test_case_index, program_interface, program, vs_buffer);
8664 }
8665 
8666 /** Constructor
8667  *
8668  * @param context Test framework context
8669  **/
8670 UniformBlockMemberOffsetAndAlignTest::UniformBlockMemberOffsetAndAlignTest(deqp::Context& context)
8671 	: TextureTestBase(context, "uniform_block_member_offset_and_align",
8672 					  "Test verifies offsets and alignment of uniform buffer members")
8673 {
8674 }
8675 
8676 /** Get interface of program
8677  *
8678  * @param test_case_index     Test case index
8679  * @param program_interface   Interface of program
8680  * @param varying_passthrough Collection of connections between in and out variables
8681  **/
8682 void UniformBlockMemberOffsetAndAlignTest::getProgramInterface(GLuint					  test_case_index,
8683 															   Utils::ProgramInterface&   program_interface,
8684 															   Utils::VaryingPassthrough& varying_passthrough)
8685 {
8686 	std::string globals = "const int basic_size = BASIC_SIZE;\n"
8687 						  "const int type_align = TYPE_ALIGN;\n"
8688 						  "const int type_size  = TYPE_SIZE;\n";
8689 
8690 	Utils::Type  type		 = getType(test_case_index);
8691 	GLuint		 basic_size  = Utils::Type::GetTypeSize(type.m_basic_type);
8692 	const GLuint base_align  = type.GetBaseAlignment(false);
8693 	const GLuint array_align = type.GetBaseAlignment(true);
8694 	const GLuint base_stride = Utils::Type::CalculateStd140Stride(base_align, type.m_n_columns, 0);
8695 	const GLuint type_align  = Utils::roundUpToPowerOf2(base_stride);
8696 
8697 	/* Calculate offsets */
8698 	const GLuint first_offset  = 0;
8699 	const GLuint second_offset = type.GetActualOffset(base_stride, basic_size / 2);
8700 
8701 #if WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST
8702 
8703 	const GLuint third_offset   = type.GetActualOffset(second_offset + base_stride, base_align);
8704 	const GLuint fourth_offset  = type.GetActualOffset(third_offset + base_stride, base_align);
8705 	const GLuint fifth_offset   = type.GetActualOffset(fourth_offset + base_stride, base_align);
8706 	const GLuint sixth_offset   = type.GetActualOffset(fifth_offset + base_stride, array_align);
8707 	const GLuint seventh_offset = type.GetActualOffset(sixth_offset + base_stride, array_align);
8708 	const GLuint eigth_offset   = type.GetActualOffset(seventh_offset + base_stride, array_align);
8709 
8710 #else /* WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST */
8711 
8712 	const GLuint third_offset   = type.GetActualOffset(second_offset + base_stride, 2 * type_align);
8713 	const GLuint fourth_offset  = type.GetActualOffset(3 * type_align + base_stride, base_align);
8714 	const GLuint fifth_offset   = type.GetActualOffset(fourth_offset + base_stride, base_align);
8715 	const GLuint sixth_offset   = type.GetActualOffset(fifth_offset + base_stride, array_align);
8716 	const GLuint seventh_offset = type.GetActualOffset(sixth_offset + base_stride, array_align);
8717 	const GLuint eigth_offset   = type.GetActualOffset(seventh_offset + base_stride, 8 * basic_size);
8718 
8719 #endif /* WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST */
8720 
8721 	/* Prepare data */
8722 	const std::vector<GLubyte>& first  = type.GenerateData();
8723 	const std::vector<GLubyte>& second = type.GenerateData();
8724 	const std::vector<GLubyte>& third  = type.GenerateData();
8725 	const std::vector<GLubyte>& fourth = type.GenerateData();
8726 
8727 	m_data.resize(eigth_offset + base_stride);
8728 	GLubyte* ptr = &m_data[0];
8729 	memcpy(ptr + first_offset, &first[0], first.size());
8730 	memcpy(ptr + second_offset, &second[0], second.size());
8731 	memcpy(ptr + third_offset, &third[0], third.size());
8732 	memcpy(ptr + fourth_offset, &fourth[0], fourth.size());
8733 	memcpy(ptr + fifth_offset, &fourth[0], fourth.size());
8734 	memcpy(ptr + sixth_offset, &third[0], third.size());
8735 	memcpy(ptr + seventh_offset, &second[0], second.size());
8736 	memcpy(ptr + eigth_offset, &first[0], first.size());
8737 
8738 	/* Prepare globals */
8739 	size_t position = 0;
8740 	GLchar buffer[16];
8741 
8742 	sprintf(buffer, "%d", basic_size);
8743 	Utils::replaceToken("BASIC_SIZE", position, buffer, globals);
8744 
8745 	sprintf(buffer, "%d", type_align);
8746 	Utils::replaceToken("TYPE_ALIGN", position, buffer, globals);
8747 
8748 	sprintf(buffer, "%d", base_stride);
8749 	Utils::replaceToken("TYPE_SIZE", position, buffer, globals);
8750 
8751 	/* Prepare Block */
8752 	Utils::Interface* vs_uni_block = program_interface.Block("vs_uni_Block");
8753 
8754 	vs_uni_block->Member("at_first_offset", "layout(offset = 0, align = 8 * basic_size)", 0 /* expected_component */,
8755 						 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
8756 						 first_offset);
8757 
8758 	vs_uni_block->Member("at_second_offset", "layout(offset = type_size, align = basic_size / 2)",
8759 						 0 /* expected_component */, 0 /* expected_location */, type, false /* normalized */,
8760 						 0 /* n_array_elements */, base_stride, second_offset);
8761 
8762 	vs_uni_block->Member("at_third_offset", "layout(align = 2 * type_align)", 0 /* expected_component */,
8763 						 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
8764 						 third_offset);
8765 
8766 	vs_uni_block->Member("at_fourth_offset", "layout(offset = 3 * type_align + type_size)", 0 /* expected_component */,
8767 						 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
8768 						 fourth_offset);
8769 
8770 	vs_uni_block->Member("at_fifth_offset", "", 0 /* expected_component */, 0 /* expected_location */, type,
8771 						 false /* normalized */, 0 /* n_array_elements */, base_stride, fifth_offset);
8772 
8773 	vs_uni_block->Member("at_sixth_offset", "", 0 /* expected_component */, 0 /* expected_location */, type,
8774 						 false /* normalized */, 2 /* n_array_elements */, array_align * 2, sixth_offset);
8775 
8776 	vs_uni_block->Member("at_eigth_offset", "layout(align = 8 * basic_size)", 0 /* expected_component */,
8777 						 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
8778 						 eigth_offset);
8779 
8780 	Utils::ShaderInterface& vs_si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
8781 
8782 	/* Add globals */
8783 	vs_si.m_globals = globals;
8784 
8785 	/* Add uniform BLOCK */
8786 	vs_si.Uniform("vs_uni_block", "layout (std140, binding = BINDING)", 0, 0, vs_uni_block, 0,
8787 				  static_cast<glw::GLint>(m_data.size()), 0, &m_data[0], m_data.size());
8788 
8789 	/* */
8790 	program_interface.CloneVertexInterface(varying_passthrough);
8791 }
8792 
8793 /** Get type name
8794  *
8795  * @param test_case_index Index of test case
8796  *
8797  * @return Name of type test in test_case_index
8798  **/
8799 std::string UniformBlockMemberOffsetAndAlignTest::getTestCaseName(glw::GLuint test_case_index)
8800 {
8801 	return getTypeName(test_case_index);
8802 }
8803 
8804 /** Returns number of types to test
8805  *
8806  * @return Number of types, 34
8807  **/
8808 glw::GLuint UniformBlockMemberOffsetAndAlignTest::getTestCaseNumber()
8809 {
8810 	return getTypesNumber();
8811 }
8812 
8813 /** Prepare code snippet that will verify in and uniform variables
8814  *
8815  * @param ignored
8816  * @param ignored
8817  * @param stage   Shader stage
8818  *
8819  * @return Code that verify variables
8820  **/
8821 std::string UniformBlockMemberOffsetAndAlignTest::getVerificationSnippet(
8822 	GLuint /* test_case_index */, Utils::ProgramInterface& /* program_interface */, Utils::Shader::STAGES stage)
8823 {
8824 	std::string verification = "if ( (PREFIXblock.at_first_offset  != PREFIXblock.at_eigth_offset   ) ||\n"
8825 							   "         (PREFIXblock.at_second_offset != PREFIXblock.at_sixth_offset[1]) ||\n"
8826 							   "         (PREFIXblock.at_third_offset  != PREFIXblock.at_sixth_offset[0]) ||\n"
8827 							   "         (PREFIXblock.at_fourth_offset != PREFIXblock.at_fifth_offset   )  )\n"
8828 							   "    {\n"
8829 							   "        result = 0;\n"
8830 							   "    }";
8831 
8832 	const GLchar* prefix = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::UNIFORM);
8833 
8834 	Utils::replaceAllTokens("PREFIX", prefix, verification);
8835 
8836 	return verification;
8837 }
8838 
8839 /** Constructor
8840  *
8841  * @param context Test framework context
8842  **/
8843 UniformBlockLayoutQualifierConflictTest::UniformBlockLayoutQualifierConflictTest(deqp::Context& context)
8844 	: NegativeTestBase(
8845 		  context, "uniform_block_layout_qualifier_conflict",
8846 		  "Test verifies that std140 is required when offset and/or align qualifiers are used with uniform block")
8847 {
8848 	/* Nothing to be done here */
8849 }
8850 
8851 /** Source for given test case and stage
8852  *
8853  * @param test_case_index Index of test case
8854  * @param stage           Shader stage
8855  *
8856  * @return Shader source
8857  **/
8858 std::string UniformBlockLayoutQualifierConflictTest::getShaderSource(GLuint				   test_case_index,
8859 																	 Utils::Shader::STAGES stage)
8860 {
8861 	static const GLchar* cs = "#version 430 core\n"
8862 							  "#extension GL_ARB_enhanced_layouts : require\n"
8863 							  "\n"
8864 							  "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
8865 							  "\n"
8866 							  "LAYOUTuniform Block {\n"
8867 							  "    layout(offset = 16) vec4 boy;\n"
8868 							  "    layout(align  = 64) vec4 man;\n"
8869 							  "} uni_block;\n"
8870 							  "\n"
8871 							  "writeonly uniform image2D uni_image;\n"
8872 							  "\n"
8873 							  "void main()\n"
8874 							  "{\n"
8875 							  "    vec4 result = uni_block.boy + uni_block.man;\n"
8876 							  "\n"
8877 							  "    imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
8878 							  "}\n"
8879 							  "\n";
8880 	static const GLchar* fs = "#version 430 core\n"
8881 							  "#extension GL_ARB_enhanced_layouts : require\n"
8882 							  "\n"
8883 							  "LAYOUTuniform Block {\n"
8884 							  "    layout(offset = 16) vec4 boy;\n"
8885 							  "    layout(align  = 64) vec4 man;\n"
8886 							  "} uni_block;\n"
8887 							  "\n"
8888 							  "in  vec4 gs_fs;\n"
8889 							  "out vec4 fs_out;\n"
8890 							  "\n"
8891 							  "void main()\n"
8892 							  "{\n"
8893 							  "    fs_out = gs_fs + uni_block.boy + uni_block.man;\n"
8894 							  "}\n"
8895 							  "\n";
8896 	static const GLchar* gs = "#version 430 core\n"
8897 							  "#extension GL_ARB_enhanced_layouts : require\n"
8898 							  "\n"
8899 							  "layout(points)                           in;\n"
8900 							  "layout(triangle_strip, max_vertices = 4) out;\n"
8901 							  "\n"
8902 							  "LAYOUTuniform Block {\n"
8903 							  "    layout(offset = 16) vec4 boy;\n"
8904 							  "    layout(align  = 64) vec4 man;\n"
8905 							  "} uni_block;\n"
8906 							  "\n"
8907 							  "in  vec4 tes_gs[];\n"
8908 							  "out vec4 gs_fs;\n"
8909 							  "\n"
8910 							  "void main()\n"
8911 							  "{\n"
8912 							  "    gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
8913 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
8914 							  "    EmitVertex();\n"
8915 							  "    gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
8916 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
8917 							  "    EmitVertex();\n"
8918 							  "    gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
8919 							  "    gl_Position  = vec4(1, -1, 0, 1);\n"
8920 							  "    EmitVertex();\n"
8921 							  "    gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
8922 							  "    gl_Position  = vec4(1, 1, 0, 1);\n"
8923 							  "    EmitVertex();\n"
8924 							  "}\n"
8925 							  "\n";
8926 	static const GLchar* tcs =
8927 		"#version 430 core\n"
8928 		"#extension GL_ARB_enhanced_layouts : require\n"
8929 		"\n"
8930 		"layout(vertices = 1) out;\n"
8931 		"\n"
8932 		"LAYOUTuniform Block {\n"
8933 		"    layout(offset = 16) vec4 boy;\n"
8934 		"    layout(align  = 64) vec4 man;\n"
8935 		"} uni_block;\n"
8936 		"\n"
8937 		"in  vec4 vs_tcs[];\n"
8938 		"out vec4 tcs_tes[];\n"
8939 		"\n"
8940 		"void main()\n"
8941 		"{\n"
8942 		"\n"
8943 		"    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID] + uni_block.boy + uni_block.man;\n"
8944 		"\n"
8945 		"    gl_TessLevelOuter[0] = 1.0;\n"
8946 		"    gl_TessLevelOuter[1] = 1.0;\n"
8947 		"    gl_TessLevelOuter[2] = 1.0;\n"
8948 		"    gl_TessLevelOuter[3] = 1.0;\n"
8949 		"    gl_TessLevelInner[0] = 1.0;\n"
8950 		"    gl_TessLevelInner[1] = 1.0;\n"
8951 		"}\n"
8952 		"\n";
8953 	static const GLchar* tes = "#version 430 core\n"
8954 							   "#extension GL_ARB_enhanced_layouts : require\n"
8955 							   "\n"
8956 							   "layout(isolines, point_mode) in;\n"
8957 							   "\n"
8958 							   "LAYOUTuniform Block {\n"
8959 							   "    layout(offset = 16) vec4 boy;\n"
8960 							   "    layout(align  = 64) vec4 man;\n"
8961 							   "} uni_block;\n"
8962 							   "\n"
8963 							   "in  vec4 tcs_tes[];\n"
8964 							   "out vec4 tes_gs;\n"
8965 							   "\n"
8966 							   "void main()\n"
8967 							   "{\n"
8968 							   "    tes_gs = tcs_tes[0] + uni_block.boy + uni_block.man;\n"
8969 							   "}\n"
8970 							   "\n";
8971 	static const GLchar* vs = "#version 430 core\n"
8972 							  "#extension GL_ARB_enhanced_layouts : require\n"
8973 							  "\n"
8974 							  "LAYOUTuniform Block {\n"
8975 							  "    layout(offset = 16) vec4 boy;\n"
8976 							  "    layout(align  = 64) vec4 man;\n"
8977 							  "} uni_block;\n"
8978 							  "\n"
8979 							  "in  vec4 in_vs;\n"
8980 							  "out vec4 vs_tcs;\n"
8981 							  "\n"
8982 							  "void main()\n"
8983 							  "{\n"
8984 							  "    vs_tcs = in_vs + uni_block.boy + uni_block.man;\n"
8985 							  "}\n"
8986 							  "\n";
8987 
8988 	std::string   layout	= "";
8989 	size_t		  position  = 0;
8990 	testCase&	 test_case = m_test_cases[test_case_index];
8991 	const GLchar* qualifier = getQualifierName(test_case.m_qualifier);
8992 	std::string   source;
8993 
8994 	if (0 != qualifier[0])
8995 	{
8996 		size_t layout_position = 0;
8997 
8998 		layout = "layout (QUALIFIER) ";
8999 
9000 		Utils::replaceToken("QUALIFIER", layout_position, qualifier, layout);
9001 	}
9002 
9003 	switch (stage)
9004 	{
9005 	case Utils::Shader::COMPUTE:
9006 		source = cs;
9007 		break;
9008 	case Utils::Shader::FRAGMENT:
9009 		source = fs;
9010 		break;
9011 	case Utils::Shader::GEOMETRY:
9012 		source = gs;
9013 		break;
9014 	case Utils::Shader::TESS_CTRL:
9015 		source = tcs;
9016 		break;
9017 	case Utils::Shader::TESS_EVAL:
9018 		source = tes;
9019 		break;
9020 	case Utils::Shader::VERTEX:
9021 		source = vs;
9022 		break;
9023 	default:
9024 		TCU_FAIL("Invalid enum");
9025 	}
9026 
9027 	if (test_case.m_stage == stage)
9028 	{
9029 		Utils::replaceToken("LAYOUT", position, layout.c_str(), source);
9030 	}
9031 	else
9032 	{
9033 		Utils::replaceToken("LAYOUT", position, "layout (std140) ", source);
9034 	}
9035 
9036 	return source;
9037 }
9038 
9039 /** Get description of test case
9040  *
9041  * @param test_case_index Index of test case
9042  *
9043  * @return Qualifier name
9044  **/
9045 std::string UniformBlockLayoutQualifierConflictTest::getTestCaseName(GLuint test_case_index)
9046 {
9047 	std::string result = getQualifierName(m_test_cases[test_case_index].m_qualifier);
9048 
9049 	return result;
9050 }
9051 
9052 /** Get number of test cases
9053  *
9054  * @return Number of test cases
9055  **/
9056 GLuint UniformBlockLayoutQualifierConflictTest::getTestCaseNumber()
9057 {
9058 	return static_cast<GLuint>(m_test_cases.size());
9059 }
9060 
9061 /** Selects if "compute" stage is relevant for test
9062  *
9063  * @param test_case_index Index of test case
9064  *
9065  * @return true when tested stage is compute
9066  **/
9067 bool UniformBlockLayoutQualifierConflictTest::isComputeRelevant(GLuint test_case_index)
9068 {
9069 	return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
9070 }
9071 
9072 /** Selects if compilation failure is expected result
9073  *
9074  * @param test_case_index Index of test case
9075  *
9076  * @return false for STD140 cases, true otherwise
9077  **/
9078 bool UniformBlockLayoutQualifierConflictTest::isFailureExpected(GLuint test_case_index)
9079 {
9080 	return (STD140 != m_test_cases[test_case_index].m_qualifier);
9081 }
9082 
9083 /** Prepare all test cases
9084  *
9085  **/
9086 void UniformBlockLayoutQualifierConflictTest::testInit()
9087 {
9088 	for (GLuint qualifier = 0; qualifier < QUALIFIERS_MAX; ++qualifier)
9089 	{
9090 		for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
9091 		{
9092 			testCase test_case = { (QUALIFIERS)qualifier, (Utils::Shader::STAGES)stage };
9093 
9094 			m_test_cases.push_back(test_case);
9095 		}
9096 	}
9097 }
9098 
9099 /** Get name of glsl constant
9100  *
9101  * @param Constant id
9102  *
9103  * @return Name of constant used in GLSL
9104  **/
9105 const GLchar* UniformBlockLayoutQualifierConflictTest::getQualifierName(QUALIFIERS qualifier)
9106 {
9107 	const GLchar* name = "";
9108 
9109 	switch (qualifier)
9110 	{
9111 	case DEFAULT:
9112 		name = "";
9113 		break;
9114 	case STD140:
9115 		name = "std140";
9116 		break;
9117 	case SHARED:
9118 		name = "shared";
9119 		break;
9120 	case PACKED:
9121 		name = "packed";
9122 		break;
9123 	default:
9124 		TCU_FAIL("Invalid enum");
9125 	}
9126 
9127 	return name;
9128 }
9129 
9130 /** Constructor
9131  *
9132  * @param context Test framework context
9133  **/
9134 UniformBlockMemberInvalidOffsetAlignmentTest::UniformBlockMemberInvalidOffsetAlignmentTest(deqp::Context& context)
9135 	: NegativeTestBase(context, "uniform_block_member_invalid_offset_alignment",
9136 					   "Test verifies that invalid alignment of offset qualifiers cause compilation failure")
9137 {
9138 	/* Nothing to be done here */
9139 }
9140 
9141 /** Constructor
9142  *
9143  * @param context     Test framework context
9144  * @param name        Test name
9145  * @param description Test description
9146  **/
9147 UniformBlockMemberInvalidOffsetAlignmentTest::UniformBlockMemberInvalidOffsetAlignmentTest(
9148 	deqp::Context& context, const glw::GLchar* name, const glw::GLchar* description)
9149 	: NegativeTestBase(context, name, description)
9150 {
9151 	/* Nothing to be done here */
9152 }
9153 
9154 /** Source for given test case and stage
9155  *
9156  * @param test_case_index Index of test case
9157  * @param stage           Shader stage
9158  *
9159  * @return Shader source
9160  **/
9161 std::string UniformBlockMemberInvalidOffsetAlignmentTest::getShaderSource(GLuint				test_case_index,
9162 																		  Utils::Shader::STAGES stage)
9163 {
9164 	static const GLchar* cs = "#version 430 core\n"
9165 							  "#extension GL_ARB_enhanced_layouts : require\n"
9166 							  "\n"
9167 							  "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
9168 							  "\n"
9169 							  "layout (std140) uniform Block {\n"
9170 							  "    layout (offset = OFFSET) TYPE member;\n"
9171 							  "} block;\n"
9172 							  "\n"
9173 							  "writeonly uniform image2D uni_image;\n"
9174 							  "\n"
9175 							  "void main()\n"
9176 							  "{\n"
9177 							  "    vec4 result = vec4(1, 0, 0.5, 1);\n"
9178 							  "\n"
9179 							  "    if (TYPE(1) == block.member)\n"
9180 							  "    {\n"
9181 							  "        result = vec4(1, 1, 1, 1);\n"
9182 							  "    }\n"
9183 							  "\n"
9184 							  "    imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
9185 							  "}\n"
9186 							  "\n";
9187 	static const GLchar* fs = "#version 430 core\n"
9188 							  "#extension GL_ARB_enhanced_layouts : require\n"
9189 							  "\n"
9190 							  "in  vec4 gs_fs;\n"
9191 							  "out vec4 fs_out;\n"
9192 							  "\n"
9193 							  "void main()\n"
9194 							  "{\n"
9195 							  "    fs_out = gs_fs;\n"
9196 							  "}\n"
9197 							  "\n";
9198 	static const GLchar* fs_tested = "#version 430 core\n"
9199 									 "#extension GL_ARB_enhanced_layouts : require\n"
9200 									 "\n"
9201 									 "layout (std140) uniform Block {\n"
9202 									 "    layout (offset = OFFSET) TYPE member;\n"
9203 									 "} block;\n"
9204 									 "\n"
9205 									 "in  vec4 gs_fs;\n"
9206 									 "out vec4 fs_out;\n"
9207 									 "\n"
9208 									 "void main()\n"
9209 									 "{\n"
9210 									 "    if (TYPE(1) == block.member)\n"
9211 									 "    {\n"
9212 									 "        fs_out = vec4(1, 1, 1, 1);\n"
9213 									 "    }\n"
9214 									 "\n"
9215 									 "    fs_out += gs_fs;\n"
9216 									 "}\n"
9217 									 "\n";
9218 	static const GLchar* gs = "#version 430 core\n"
9219 							  "#extension GL_ARB_enhanced_layouts : require\n"
9220 							  "\n"
9221 							  "layout(points)                           in;\n"
9222 							  "layout(triangle_strip, max_vertices = 4) out;\n"
9223 							  "\n"
9224 							  "in  vec4 tes_gs[];\n"
9225 							  "out vec4 gs_fs;\n"
9226 							  "\n"
9227 							  "void main()\n"
9228 							  "{\n"
9229 							  "    gs_fs = tes_gs[0];\n"
9230 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
9231 							  "    EmitVertex();\n"
9232 							  "    gs_fs = tes_gs[0];\n"
9233 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
9234 							  "    EmitVertex();\n"
9235 							  "    gs_fs = tes_gs[0];\n"
9236 							  "    gl_Position  = vec4(1, -1, 0, 1);\n"
9237 							  "    EmitVertex();\n"
9238 							  "    gs_fs = tes_gs[0];\n"
9239 							  "    gl_Position  = vec4(1, 1, 0, 1);\n"
9240 							  "    EmitVertex();\n"
9241 							  "}\n"
9242 							  "\n";
9243 	static const GLchar* gs_tested = "#version 430 core\n"
9244 									 "#extension GL_ARB_enhanced_layouts : require\n"
9245 									 "\n"
9246 									 "layout(points)                           in;\n"
9247 									 "layout(triangle_strip, max_vertices = 4) out;\n"
9248 									 "\n"
9249 									 "layout (std140) uniform Block {\n"
9250 									 "    layout (offset = OFFSET) TYPE member;\n"
9251 									 "} block;\n"
9252 									 "\n"
9253 									 "in  vec4 tes_gs[];\n"
9254 									 "out vec4 gs_fs;\n"
9255 									 "\n"
9256 									 "void main()\n"
9257 									 "{\n"
9258 									 "    if (TYPE(1) == block.member)\n"
9259 									 "    {\n"
9260 									 "        gs_fs = vec4(1, 1, 1, 1);\n"
9261 									 "    }\n"
9262 									 "\n"
9263 									 "    gs_fs += tes_gs[0];\n"
9264 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
9265 									 "    EmitVertex();\n"
9266 									 "    gs_fs += tes_gs[0];\n"
9267 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
9268 									 "    EmitVertex();\n"
9269 									 "    gs_fs += tes_gs[0];\n"
9270 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
9271 									 "    EmitVertex();\n"
9272 									 "    gs_fs += tes_gs[0];\n"
9273 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
9274 									 "    EmitVertex();\n"
9275 									 "}\n"
9276 									 "\n";
9277 	static const GLchar* tcs = "#version 430 core\n"
9278 							   "#extension GL_ARB_enhanced_layouts : require\n"
9279 							   "\n"
9280 							   "layout(vertices = 1) out;\n"
9281 							   "\n"
9282 							   "in  vec4 vs_tcs[];\n"
9283 							   "out vec4 tcs_tes[];\n"
9284 							   "\n"
9285 							   "void main()\n"
9286 							   "{\n"
9287 							   "\n"
9288 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
9289 							   "\n"
9290 							   "    gl_TessLevelOuter[0] = 1.0;\n"
9291 							   "    gl_TessLevelOuter[1] = 1.0;\n"
9292 							   "    gl_TessLevelOuter[2] = 1.0;\n"
9293 							   "    gl_TessLevelOuter[3] = 1.0;\n"
9294 							   "    gl_TessLevelInner[0] = 1.0;\n"
9295 							   "    gl_TessLevelInner[1] = 1.0;\n"
9296 							   "}\n"
9297 							   "\n";
9298 	static const GLchar* tcs_tested = "#version 430 core\n"
9299 									  "#extension GL_ARB_enhanced_layouts : require\n"
9300 									  "\n"
9301 									  "layout(vertices = 1) out;\n"
9302 									  "\n"
9303 									  "layout (std140) uniform Block {\n"
9304 									  "    layout (offset = OFFSET) TYPE member;\n"
9305 									  "} block;\n"
9306 									  "\n"
9307 									  "in  vec4 vs_tcs[];\n"
9308 									  "out vec4 tcs_tes[];\n"
9309 									  "\n"
9310 									  "void main()\n"
9311 									  "{\n"
9312 									  "    if (TYPE(1) == block.member)\n"
9313 									  "    {\n"
9314 									  "        tcs_tes[gl_InvocationID] = vec4(1, 1, 1, 1);\n"
9315 									  "    }\n"
9316 									  "\n"
9317 									  "\n"
9318 									  "    tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
9319 									  "\n"
9320 									  "    gl_TessLevelOuter[0] = 1.0;\n"
9321 									  "    gl_TessLevelOuter[1] = 1.0;\n"
9322 									  "    gl_TessLevelOuter[2] = 1.0;\n"
9323 									  "    gl_TessLevelOuter[3] = 1.0;\n"
9324 									  "    gl_TessLevelInner[0] = 1.0;\n"
9325 									  "    gl_TessLevelInner[1] = 1.0;\n"
9326 									  "}\n"
9327 									  "\n";
9328 	static const GLchar* tes = "#version 430 core\n"
9329 							   "#extension GL_ARB_enhanced_layouts : require\n"
9330 							   "\n"
9331 							   "layout(isolines, point_mode) in;\n"
9332 							   "\n"
9333 							   "in  vec4 tcs_tes[];\n"
9334 							   "out vec4 tes_gs;\n"
9335 							   "\n"
9336 							   "void main()\n"
9337 							   "{\n"
9338 							   "    tes_gs = tcs_tes[0];\n"
9339 							   "}\n"
9340 							   "\n";
9341 	static const GLchar* tes_tested = "#version 430 core\n"
9342 									  "#extension GL_ARB_enhanced_layouts : require\n"
9343 									  "\n"
9344 									  "layout(isolines, point_mode) in;\n"
9345 									  "\n"
9346 									  "layout (std140) uniform Block {\n"
9347 									  "    layout (offset = OFFSET) TYPE member;\n"
9348 									  "} block;\n"
9349 									  "\n"
9350 									  "in  vec4 tcs_tes[];\n"
9351 									  "out vec4 tes_gs;\n"
9352 									  "\n"
9353 									  "void main()\n"
9354 									  "{\n"
9355 									  "    if (TYPE(1) == block.member)\n"
9356 									  "    {\n"
9357 									  "        tes_gs = vec4(1, 1, 1, 1);\n"
9358 									  "    }\n"
9359 									  "\n"
9360 									  "    tes_gs += tcs_tes[0];\n"
9361 									  "}\n"
9362 									  "\n";
9363 	static const GLchar* vs = "#version 430 core\n"
9364 							  "#extension GL_ARB_enhanced_layouts : require\n"
9365 							  "\n"
9366 							  "in  vec4 in_vs;\n"
9367 							  "out vec4 vs_tcs;\n"
9368 							  "\n"
9369 							  "void main()\n"
9370 							  "{\n"
9371 							  "    vs_tcs = in_vs;\n"
9372 							  "}\n"
9373 							  "\n";
9374 	static const GLchar* vs_tested = "#version 430 core\n"
9375 									 "#extension GL_ARB_enhanced_layouts : require\n"
9376 									 "\n"
9377 									 "layout (std140) uniform Block {\n"
9378 									 "    layout (offset = OFFSET) TYPE member;\n"
9379 									 "} block;\n"
9380 									 "\n"
9381 									 "in  vec4 in_vs;\n"
9382 									 "out vec4 vs_tcs;\n"
9383 									 "\n"
9384 									 "void main()\n"
9385 									 "{\n"
9386 									 "    if (TYPE(1) == block.member)\n"
9387 									 "    {\n"
9388 									 "        vs_tcs = vec4(1, 1, 1, 1);\n"
9389 									 "    }\n"
9390 									 "\n"
9391 									 "    vs_tcs += in_vs;\n"
9392 									 "}\n"
9393 									 "\n";
9394 
9395 	std::string source;
9396 	testCase&   test_case = m_test_cases[test_case_index];
9397 
9398 	if (test_case.m_stage == stage)
9399 	{
9400 		GLchar			   buffer[16];
9401 		const GLuint	   offset	= test_case.m_offset;
9402 		size_t			   position  = 0;
9403 		const Utils::Type& type		 = test_case.m_type;
9404 		const GLchar*	  type_name = type.GetGLSLTypeName();
9405 
9406 		sprintf(buffer, "%d", offset);
9407 
9408 		switch (stage)
9409 		{
9410 		case Utils::Shader::COMPUTE:
9411 			source = cs;
9412 			break;
9413 		case Utils::Shader::FRAGMENT:
9414 			source = fs_tested;
9415 			break;
9416 		case Utils::Shader::GEOMETRY:
9417 			source = gs_tested;
9418 			break;
9419 		case Utils::Shader::TESS_CTRL:
9420 			source = tcs_tested;
9421 			break;
9422 		case Utils::Shader::TESS_EVAL:
9423 			source = tes_tested;
9424 			break;
9425 		case Utils::Shader::VERTEX:
9426 			source = vs_tested;
9427 			break;
9428 		default:
9429 			TCU_FAIL("Invalid enum");
9430 		}
9431 
9432 		Utils::replaceToken("OFFSET", position, buffer, source);
9433 		Utils::replaceToken("TYPE", position, type_name, source);
9434 		Utils::replaceToken("TYPE", position, type_name, source);
9435 	}
9436 	else
9437 	{
9438 		switch (stage)
9439 		{
9440 		case Utils::Shader::FRAGMENT:
9441 			source = fs;
9442 			break;
9443 		case Utils::Shader::GEOMETRY:
9444 			source = gs;
9445 			break;
9446 		case Utils::Shader::TESS_CTRL:
9447 			source = tcs;
9448 			break;
9449 		case Utils::Shader::TESS_EVAL:
9450 			source = tes;
9451 			break;
9452 		case Utils::Shader::VERTEX:
9453 			source = vs;
9454 			break;
9455 		default:
9456 			TCU_FAIL("Invalid enum");
9457 		}
9458 	}
9459 
9460 	return source;
9461 }
9462 
9463 /** Get description of test case
9464  *
9465  * @param test_case_index Index of test case
9466  *
9467  * @return Type name and offset
9468  **/
9469 std::string UniformBlockMemberInvalidOffsetAlignmentTest::getTestCaseName(GLuint test_case_index)
9470 {
9471 	std::stringstream stream;
9472 	testCase&		  test_case = m_test_cases[test_case_index];
9473 
9474 	stream << "Type: " << test_case.m_type.GetGLSLTypeName() << ", offset: " << test_case.m_offset;
9475 
9476 	return stream.str();
9477 }
9478 
9479 /** Get number of test cases
9480  *
9481  * @return Number of test cases
9482  **/
9483 GLuint UniformBlockMemberInvalidOffsetAlignmentTest::getTestCaseNumber()
9484 {
9485 	return static_cast<GLuint>(m_test_cases.size());
9486 }
9487 
9488 /** Get the maximum size for an uniform block
9489  *
9490  * @return The maximum size in basic machine units of a uniform block.
9491  **/
9492 GLint UniformBlockMemberInvalidOffsetAlignmentTest::getMaxBlockSize()
9493 {
9494 	const Functions& gl		  = m_context.getRenderContext().getFunctions();
9495 	GLint			 max_size = 0;
9496 
9497 	gl.getIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &max_size);
9498 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
9499 
9500 	return max_size;
9501 }
9502 
9503 /** Selects if "compute" stage is relevant for test
9504  *
9505  * @param test_case_index Index of test case
9506  *
9507  * @return true when tested stage is compute
9508  **/
9509 bool UniformBlockMemberInvalidOffsetAlignmentTest::isComputeRelevant(GLuint test_case_index)
9510 {
9511 	return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
9512 }
9513 
9514 /** Selects if compilation failure is expected result
9515  *
9516  * @param test_case_index Index of test case
9517  *
9518  * @return should_fail field from testCase
9519  **/
9520 bool UniformBlockMemberInvalidOffsetAlignmentTest::isFailureExpected(GLuint test_case_index)
9521 {
9522 	return m_test_cases[test_case_index].m_should_fail;
9523 }
9524 
9525 /** Checks if stage is supported
9526  *
9527  * @param stage ignored
9528  *
9529  * @return true
9530  **/
9531 bool UniformBlockMemberInvalidOffsetAlignmentTest::isStageSupported(Utils::Shader::STAGES /* stage */)
9532 {
9533 	return true;
9534 }
9535 
9536 /** Prepare all test cases
9537  *
9538  **/
9539 void UniformBlockMemberInvalidOffsetAlignmentTest::testInit()
9540 {
9541 	const GLuint n_types = getTypesNumber();
9542 	bool		 stage_support[Utils::Shader::STAGE_MAX];
9543 
9544 	for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
9545 	{
9546 		stage_support[stage] = isStageSupported((Utils::Shader::STAGES)stage);
9547 	}
9548 
9549 	for (GLuint i = 0; i < n_types; ++i)
9550 	{
9551 		const Utils::Type& type		  = getType(i);
9552 		const GLuint	   alignment  = type.GetBaseAlignment(false);
9553 		const GLuint	   type_size  = type.GetSize(true);
9554 		const GLuint	   sec_to_end = getMaxBlockSize() - 2 * type_size;
9555 
9556 		for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
9557 		{
9558 			if (false == stage_support[stage])
9559 			{
9560 				continue;
9561 			}
9562 
9563 			for (GLuint offset = 0; offset <= type_size; ++offset)
9564 			{
9565 				const GLuint modulo		 = offset % alignment;
9566 				const bool   is_aligned  = (0 == modulo) ? true : false;
9567 				const bool   should_fail = !is_aligned;
9568 
9569 				testCase test_case = { offset, should_fail, (Utils::Shader::STAGES)stage, type };
9570 
9571 				m_test_cases.push_back(test_case);
9572 			}
9573 
9574 			for (GLuint offset = sec_to_end; offset <= sec_to_end + type_size; ++offset)
9575 			{
9576 				const GLuint modulo		 = offset % alignment;
9577 				const bool   is_aligned  = (0 == modulo) ? true : false;
9578 				const bool   should_fail = !is_aligned;
9579 
9580 				testCase test_case = { offset, should_fail, (Utils::Shader::STAGES)stage, type };
9581 
9582 				m_test_cases.push_back(test_case);
9583 			}
9584 		}
9585 	}
9586 }
9587 
9588 /** Constructor
9589  *
9590  * @param context Test framework context
9591  **/
9592 UniformBlockMemberOverlappingOffsetsTest::UniformBlockMemberOverlappingOffsetsTest(deqp::Context& context)
9593 	: NegativeTestBase(context, "uniform_block_member_overlapping_offsets",
9594 					   "Test verifies that overlapping offsets qualifiers cause compilation failure")
9595 {
9596 	/* Nothing to be done here */
9597 }
9598 
9599 /** Constructor
9600  *
9601  * @param context Test framework context
9602  * @param name        Test name
9603  * @param description Test description
9604  **/
9605 UniformBlockMemberOverlappingOffsetsTest::UniformBlockMemberOverlappingOffsetsTest(deqp::Context&	 context,
9606 																				   const glw::GLchar* name,
9607 																				   const glw::GLchar* description)
9608 	: NegativeTestBase(context, name, description)
9609 {
9610 	/* Nothing to be done here */
9611 }
9612 
9613 /** Source for given test case and stage
9614  *
9615  * @param test_case_index Index of test case
9616  * @param stage           Shader stage
9617  *
9618  * @return Shader source
9619  **/
9620 std::string UniformBlockMemberOverlappingOffsetsTest::getShaderSource(GLuint				test_case_index,
9621 																	  Utils::Shader::STAGES stage)
9622 {
9623 	static const GLchar* cs = "#version 430 core\n"
9624 							  "#extension GL_ARB_enhanced_layouts : require\n"
9625 							  "\n"
9626 							  "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
9627 							  "\n"
9628 							  "layout (std140) uniform Block {\n"
9629 							  "    layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9630 							  "    layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9631 							  "} block;\n"
9632 							  "\n"
9633 							  "writeonly uniform image2D uni_image;\n"
9634 							  "\n"
9635 							  "void main()\n"
9636 							  "{\n"
9637 							  "    vec4 result = vec4(1, 0, 0.5, 1);\n"
9638 							  "\n"
9639 							  "    if ((BOY_TYPE(1) == block.boy) ||\n"
9640 							  "        (MAN_TYPE(0) == block.man) )\n"
9641 							  "    {\n"
9642 							  "        result = vec4(1, 1, 1, 1);\n"
9643 							  "    }\n"
9644 							  "\n"
9645 							  "    imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
9646 							  "}\n"
9647 							  "\n";
9648 	static const GLchar* fs = "#version 430 core\n"
9649 							  "#extension GL_ARB_enhanced_layouts : require\n"
9650 							  "\n"
9651 							  "in  vec4 gs_fs;\n"
9652 							  "out vec4 fs_out;\n"
9653 							  "\n"
9654 							  "void main()\n"
9655 							  "{\n"
9656 							  "    fs_out = gs_fs;\n"
9657 							  "}\n"
9658 							  "\n";
9659 	static const GLchar* fs_tested = "#version 430 core\n"
9660 									 "#extension GL_ARB_enhanced_layouts : require\n"
9661 									 "\n"
9662 									 "layout (std140) uniform Block {\n"
9663 									 "    layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9664 									 "    layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9665 									 "} block;\n"
9666 									 "\n"
9667 									 "in  vec4 gs_fs;\n"
9668 									 "out vec4 fs_out;\n"
9669 									 "\n"
9670 									 "void main()\n"
9671 									 "{\n"
9672 									 "    if ((BOY_TYPE(1) == block.boy) ||\n"
9673 									 "        (MAN_TYPE(0) == block.man) )\n"
9674 									 "    {\n"
9675 									 "        fs_out = vec4(1, 1, 1, 1);\n"
9676 									 "    }\n"
9677 									 "\n"
9678 									 "    fs_out += gs_fs;\n"
9679 									 "}\n"
9680 									 "\n";
9681 	static const GLchar* gs = "#version 430 core\n"
9682 							  "#extension GL_ARB_enhanced_layouts : require\n"
9683 							  "\n"
9684 							  "layout(points)                           in;\n"
9685 							  "layout(triangle_strip, max_vertices = 4) out;\n"
9686 							  "\n"
9687 							  "in  vec4 tes_gs[];\n"
9688 							  "out vec4 gs_fs;\n"
9689 							  "\n"
9690 							  "void main()\n"
9691 							  "{\n"
9692 							  "    gs_fs = tes_gs[0];\n"
9693 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
9694 							  "    EmitVertex();\n"
9695 							  "    gs_fs = tes_gs[0];\n"
9696 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
9697 							  "    EmitVertex();\n"
9698 							  "    gs_fs = tes_gs[0];\n"
9699 							  "    gl_Position  = vec4(1, -1, 0, 1);\n"
9700 							  "    EmitVertex();\n"
9701 							  "    gs_fs = tes_gs[0];\n"
9702 							  "    gl_Position  = vec4(1, 1, 0, 1);\n"
9703 							  "    EmitVertex();\n"
9704 							  "}\n"
9705 							  "\n";
9706 	static const GLchar* gs_tested = "#version 430 core\n"
9707 									 "#extension GL_ARB_enhanced_layouts : require\n"
9708 									 "\n"
9709 									 "layout(points)                           in;\n"
9710 									 "layout(triangle_strip, max_vertices = 4) out;\n"
9711 									 "\n"
9712 									 "layout (std140) uniform Block {\n"
9713 									 "    layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9714 									 "    layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9715 									 "} block;\n"
9716 									 "\n"
9717 									 "in  vec4 tes_gs[];\n"
9718 									 "out vec4 gs_fs;\n"
9719 									 "\n"
9720 									 "void main()\n"
9721 									 "{\n"
9722 									 "    if ((BOY_TYPE(1) == block.boy) ||\n"
9723 									 "        (MAN_TYPE(0) == block.man) )\n"
9724 									 "    {\n"
9725 									 "        gs_fs = vec4(1, 1, 1, 1);\n"
9726 									 "    }\n"
9727 									 "\n"
9728 									 "    gs_fs += tes_gs[0];\n"
9729 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
9730 									 "    EmitVertex();\n"
9731 									 "    gs_fs += tes_gs[0];\n"
9732 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
9733 									 "    EmitVertex();\n"
9734 									 "    gs_fs += tes_gs[0];\n"
9735 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
9736 									 "    EmitVertex();\n"
9737 									 "    gs_fs += tes_gs[0];\n"
9738 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
9739 									 "    EmitVertex();\n"
9740 									 "}\n"
9741 									 "\n";
9742 	static const GLchar* tcs = "#version 430 core\n"
9743 							   "#extension GL_ARB_enhanced_layouts : require\n"
9744 							   "\n"
9745 							   "layout(vertices = 1) out;\n"
9746 							   "\n"
9747 							   "in  vec4 vs_tcs[];\n"
9748 							   "out vec4 tcs_tes[];\n"
9749 							   "\n"
9750 							   "void main()\n"
9751 							   "{\n"
9752 							   "\n"
9753 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
9754 							   "\n"
9755 							   "    gl_TessLevelOuter[0] = 1.0;\n"
9756 							   "    gl_TessLevelOuter[1] = 1.0;\n"
9757 							   "    gl_TessLevelOuter[2] = 1.0;\n"
9758 							   "    gl_TessLevelOuter[3] = 1.0;\n"
9759 							   "    gl_TessLevelInner[0] = 1.0;\n"
9760 							   "    gl_TessLevelInner[1] = 1.0;\n"
9761 							   "}\n"
9762 							   "\n";
9763 	static const GLchar* tcs_tested = "#version 430 core\n"
9764 									  "#extension GL_ARB_enhanced_layouts : require\n"
9765 									  "\n"
9766 									  "layout(vertices = 1) out;\n"
9767 									  "\n"
9768 									  "layout (std140) uniform Block {\n"
9769 									  "    layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9770 									  "    layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9771 									  "} block;\n"
9772 									  "\n"
9773 									  "in  vec4 vs_tcs[];\n"
9774 									  "out vec4 tcs_tes[];\n"
9775 									  "\n"
9776 									  "void main()\n"
9777 									  "{\n"
9778 									  "    if ((BOY_TYPE(1) == block.boy) ||\n"
9779 									  "        (MAN_TYPE(0) == block.man) )\n"
9780 									  "    {\n"
9781 									  "        tcs_tes[gl_InvocationID] = vec4(1, 1, 1, 1);\n"
9782 									  "    }\n"
9783 									  "\n"
9784 									  "\n"
9785 									  "    tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
9786 									  "\n"
9787 									  "    gl_TessLevelOuter[0] = 1.0;\n"
9788 									  "    gl_TessLevelOuter[1] = 1.0;\n"
9789 									  "    gl_TessLevelOuter[2] = 1.0;\n"
9790 									  "    gl_TessLevelOuter[3] = 1.0;\n"
9791 									  "    gl_TessLevelInner[0] = 1.0;\n"
9792 									  "    gl_TessLevelInner[1] = 1.0;\n"
9793 									  "}\n"
9794 									  "\n";
9795 	static const GLchar* tes = "#version 430 core\n"
9796 							   "#extension GL_ARB_enhanced_layouts : require\n"
9797 							   "\n"
9798 							   "layout(isolines, point_mode) in;\n"
9799 							   "\n"
9800 							   "in  vec4 tcs_tes[];\n"
9801 							   "out vec4 tes_gs;\n"
9802 							   "\n"
9803 							   "void main()\n"
9804 							   "{\n"
9805 							   "    tes_gs = tcs_tes[0];\n"
9806 							   "}\n"
9807 							   "\n";
9808 	static const GLchar* tes_tested = "#version 430 core\n"
9809 									  "#extension GL_ARB_enhanced_layouts : require\n"
9810 									  "\n"
9811 									  "layout(isolines, point_mode) in;\n"
9812 									  "\n"
9813 									  "layout (std140) uniform Block {\n"
9814 									  "    layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9815 									  "    layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9816 									  "} block;\n"
9817 									  "\n"
9818 									  "in  vec4 tcs_tes[];\n"
9819 									  "out vec4 tes_gs;\n"
9820 									  "\n"
9821 									  "void main()\n"
9822 									  "{\n"
9823 									  "    if ((BOY_TYPE(1) == block.boy) ||\n"
9824 									  "        (MAN_TYPE(0) == block.man) )\n"
9825 									  "    {\n"
9826 									  "        tes_gs = vec4(1, 1, 1, 1);\n"
9827 									  "    }\n"
9828 									  "\n"
9829 									  "    tes_gs += tcs_tes[0];\n"
9830 									  "}\n"
9831 									  "\n";
9832 	static const GLchar* vs = "#version 430 core\n"
9833 							  "#extension GL_ARB_enhanced_layouts : require\n"
9834 							  "\n"
9835 							  "in  vec4 in_vs;\n"
9836 							  "out vec4 vs_tcs;\n"
9837 							  "\n"
9838 							  "void main()\n"
9839 							  "{\n"
9840 							  "    vs_tcs = in_vs;\n"
9841 							  "}\n"
9842 							  "\n";
9843 	static const GLchar* vs_tested = "#version 430 core\n"
9844 									 "#extension GL_ARB_enhanced_layouts : require\n"
9845 									 "\n"
9846 									 "layout (std140) uniform Block {\n"
9847 									 "    layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
9848 									 "    layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
9849 									 "} block;\n"
9850 									 "\n"
9851 									 "in  vec4 in_vs;\n"
9852 									 "out vec4 vs_tcs;\n"
9853 									 "\n"
9854 									 "void main()\n"
9855 									 "{\n"
9856 									 "    if ((BOY_TYPE(1) == block.boy) ||\n"
9857 									 "        (MAN_TYPE(0) == block.man) )\n"
9858 									 "    {\n"
9859 									 "        vs_tcs = vec4(1, 1, 1, 1);\n"
9860 									 "    }\n"
9861 									 "\n"
9862 									 "    vs_tcs += in_vs;\n"
9863 									 "}\n"
9864 									 "\n";
9865 
9866 	std::string source;
9867 	testCase&   test_case = m_test_cases[test_case_index];
9868 
9869 	if (test_case.m_stage == stage)
9870 	{
9871 		GLchar			   buffer[16];
9872 		const GLuint	   boy_offset	= test_case.m_boy_offset;
9873 		const Utils::Type& boy_type		 = test_case.m_boy_type;
9874 		const GLchar*	  boy_type_name = boy_type.GetGLSLTypeName();
9875 		const GLuint	   man_offset	= test_case.m_man_offset;
9876 		const Utils::Type& man_type		 = test_case.m_man_type;
9877 		const GLchar*	  man_type_name = man_type.GetGLSLTypeName();
9878 		size_t			   position		 = 0;
9879 
9880 		switch (stage)
9881 		{
9882 		case Utils::Shader::COMPUTE:
9883 			source = cs;
9884 			break;
9885 		case Utils::Shader::FRAGMENT:
9886 			source = fs_tested;
9887 			break;
9888 		case Utils::Shader::GEOMETRY:
9889 			source = gs_tested;
9890 			break;
9891 		case Utils::Shader::TESS_CTRL:
9892 			source = tcs_tested;
9893 			break;
9894 		case Utils::Shader::TESS_EVAL:
9895 			source = tes_tested;
9896 			break;
9897 		case Utils::Shader::VERTEX:
9898 			source = vs_tested;
9899 			break;
9900 		default:
9901 			TCU_FAIL("Invalid enum");
9902 		}
9903 
9904 		sprintf(buffer, "%d", boy_offset);
9905 		Utils::replaceToken("BOY_OFFSET", position, buffer, source);
9906 		Utils::replaceToken("BOY_TYPE", position, boy_type_name, source);
9907 		sprintf(buffer, "%d", man_offset);
9908 		Utils::replaceToken("MAN_OFFSET", position, buffer, source);
9909 		Utils::replaceToken("MAN_TYPE", position, man_type_name, source);
9910 		Utils::replaceToken("BOY_TYPE", position, boy_type_name, source);
9911 		Utils::replaceToken("MAN_TYPE", position, man_type_name, source);
9912 	}
9913 	else
9914 	{
9915 		switch (stage)
9916 		{
9917 		case Utils::Shader::FRAGMENT:
9918 			source = fs;
9919 			break;
9920 		case Utils::Shader::GEOMETRY:
9921 			source = gs;
9922 			break;
9923 		case Utils::Shader::TESS_CTRL:
9924 			source = tcs;
9925 			break;
9926 		case Utils::Shader::TESS_EVAL:
9927 			source = tes;
9928 			break;
9929 		case Utils::Shader::VERTEX:
9930 			source = vs;
9931 			break;
9932 		default:
9933 			TCU_FAIL("Invalid enum");
9934 		}
9935 	}
9936 
9937 	return source;
9938 }
9939 
9940 /** Get description of test case
9941  *
9942  * @param test_case_index Index of test case
9943  *
9944  * @return Type name and offset
9945  **/
9946 std::string UniformBlockMemberOverlappingOffsetsTest::getTestCaseName(GLuint test_case_index)
9947 {
9948 	std::stringstream stream;
9949 	testCase&		  test_case = m_test_cases[test_case_index];
9950 
9951 	stream << "Type: " << test_case.m_boy_type.GetGLSLTypeName() << ", offset: " << test_case.m_boy_offset
9952 		   << ". Type: " << test_case.m_man_type.GetGLSLTypeName() << ", offset: " << test_case.m_man_offset;
9953 
9954 	return stream.str();
9955 }
9956 
9957 /** Get number of test cases
9958  *
9959  * @return Number of test cases
9960  **/
9961 GLuint UniformBlockMemberOverlappingOffsetsTest::getTestCaseNumber()
9962 {
9963 	return static_cast<GLuint>(m_test_cases.size());
9964 }
9965 
9966 /** Selects if "compute" stage is relevant for test
9967  *
9968  * @param test_case_index Index of test case
9969  *
9970  * @return true when tested stage is compute
9971  **/
9972 bool UniformBlockMemberOverlappingOffsetsTest::isComputeRelevant(GLuint test_case_index)
9973 {
9974 	return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
9975 }
9976 
9977 /** Checks if stage is supported
9978  *
9979  * @param stage ignored
9980  *
9981  * @return true
9982  **/
9983 bool UniformBlockMemberOverlappingOffsetsTest::isStageSupported(Utils::Shader::STAGES /* stage */)
9984 {
9985 	return true;
9986 }
9987 
9988 /** Prepare all test cases
9989  *
9990  **/
9991 void UniformBlockMemberOverlappingOffsetsTest::testInit()
9992 {
9993 	const GLuint n_types = getTypesNumber();
9994 	bool		 stage_support[Utils::Shader::STAGE_MAX];
9995 
9996 	for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
9997 	{
9998 		stage_support[stage] = isStageSupported((Utils::Shader::STAGES)stage);
9999 	}
10000 
10001 	for (GLuint i = 0; i < n_types; ++i)
10002 	{
10003 		const Utils::Type& boy_type = getType(i);
10004 		const GLuint	   boy_size = boy_type.GetActualAlignment(1 /* align */, false /* is_array*/);
10005 
10006 		for (GLuint j = 0; j < n_types; ++j)
10007 		{
10008 			const Utils::Type& man_type  = getType(j);
10009 			const GLuint	   man_align = man_type.GetBaseAlignment(false);
10010 			const GLuint	   man_size  = man_type.GetActualAlignment(1 /* align */, false /* is_array*/);
10011 
10012 			const GLuint boy_offset		  = lcm(boy_size, man_size);
10013 			const GLuint man_after_start  = boy_offset + 1;
10014 			const GLuint man_after_off	= man_type.GetActualOffset(man_after_start, man_size);
10015 			const GLuint man_before_start = boy_offset - man_align;
10016 			const GLuint man_before_off   = man_type.GetActualOffset(man_before_start, man_size);
10017 
10018 			for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
10019 			{
10020 				if (false == stage_support[stage])
10021 				{
10022 					continue;
10023 				}
10024 
10025 				if ((boy_offset > man_before_off) && (boy_offset < man_before_off + man_size))
10026 				{
10027 					testCase test_case = { boy_offset, boy_type, man_before_off, man_type,
10028 										   (Utils::Shader::STAGES)stage };
10029 
10030 					m_test_cases.push_back(test_case);
10031 				}
10032 
10033 				if ((boy_offset < man_after_off) && (boy_offset + boy_size > man_after_off))
10034 				{
10035 					testCase test_case = { boy_offset, boy_type, man_after_off, man_type,
10036 										   (Utils::Shader::STAGES)stage };
10037 
10038 					m_test_cases.push_back(test_case);
10039 				}
10040 
10041 				/* Boy offset, should be fine for both types */
10042 				testCase test_case = { boy_offset, boy_type, boy_offset, man_type, (Utils::Shader::STAGES)stage };
10043 
10044 				m_test_cases.push_back(test_case);
10045 			}
10046 		}
10047 	}
10048 }
10049 
10050 /** Find greatest common divisor for a and b
10051  *
10052  * @param a A argument
10053  * @param b B argument
10054  *
10055  * @return Found gcd value
10056  **/
10057 GLuint UniformBlockMemberOverlappingOffsetsTest::gcd(GLuint a, GLuint b)
10058 {
10059 	if ((0 != a) && (0 == b))
10060 	{
10061 		return a;
10062 	}
10063 	else
10064 	{
10065 		GLuint greater = std::max(a, b);
10066 		GLuint lesser  = std::min(a, b);
10067 
10068 		return gcd(lesser, greater % lesser);
10069 	}
10070 }
10071 
10072 /** Find lowest common multiple for a and b
10073  *
10074  * @param a A argument
10075  * @param b B argument
10076  *
10077  * @return Found gcd value
10078  **/
10079 GLuint UniformBlockMemberOverlappingOffsetsTest::lcm(GLuint a, GLuint b)
10080 {
10081 	return (a * b) / gcd(a, b);
10082 }
10083 
10084 /** Constructor
10085  *
10086  * @param context Test framework context
10087  **/
10088 UniformBlockMemberAlignNonPowerOf2Test::UniformBlockMemberAlignNonPowerOf2Test(deqp::Context& context)
10089 	: NegativeTestBase(context, "uniform_block_member_align_non_power_of_2",
10090 					   "Test verifies that align qualifier requires value that is a power of 2")
10091 {
10092 	/* Nothing to be done here */
10093 }
10094 
10095 /** Constructor
10096  *
10097  * @param context Test framework context
10098  * @param name        Test name
10099  * @param description Test description
10100  **/
10101 UniformBlockMemberAlignNonPowerOf2Test::UniformBlockMemberAlignNonPowerOf2Test(deqp::Context&	 context,
10102 																			   const glw::GLchar* name,
10103 																			   const glw::GLchar* description)
10104 	: NegativeTestBase(context, name, description)
10105 {
10106 	/* Nothing to be done here */
10107 }
10108 
10109 /** Source for given test case and stage
10110  *
10111  * @param test_case_index Index of test case
10112  * @param stage           Shader stage
10113  *
10114  * @return Shader source
10115  **/
10116 std::string UniformBlockMemberAlignNonPowerOf2Test::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
10117 {
10118 	static const GLchar* cs = "#version 430 core\n"
10119 							  "#extension GL_ARB_enhanced_layouts : require\n"
10120 							  "\n"
10121 							  "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
10122 							  "\n"
10123 							  "layout (std140) uniform Block {\n"
10124 							  "    vec4 boy;\n"
10125 							  "    layout (align = ALIGN) TYPE man;\n"
10126 							  "} block;\n"
10127 							  "\n"
10128 							  "writeonly uniform image2D uni_image;\n"
10129 							  "\n"
10130 							  "void main()\n"
10131 							  "{\n"
10132 							  "    vec4 result = vec4(1, 0, 0.5, 1);\n"
10133 							  "\n"
10134 							  "    if (TYPE(0) == block.man)\n"
10135 							  "    {\n"
10136 							  "        result = vec4(1, 1, 1, 1) - block.boy;\n"
10137 							  "    }\n"
10138 							  "\n"
10139 							  "    imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
10140 							  "}\n"
10141 							  "\n";
10142 	static const GLchar* fs = "#version 430 core\n"
10143 							  "#extension GL_ARB_enhanced_layouts : require\n"
10144 							  "\n"
10145 							  "in  vec4 gs_fs;\n"
10146 							  "out vec4 fs_out;\n"
10147 							  "\n"
10148 							  "void main()\n"
10149 							  "{\n"
10150 							  "    fs_out = gs_fs;\n"
10151 							  "}\n"
10152 							  "\n";
10153 	static const GLchar* fs_tested = "#version 430 core\n"
10154 									 "#extension GL_ARB_enhanced_layouts : require\n"
10155 									 "\n"
10156 									 "layout (std140) uniform Block {\n"
10157 									 "    vec4 boy;\n"
10158 									 "    layout (align = ALIGN) TYPE man;\n"
10159 									 "} block;\n"
10160 									 "\n"
10161 									 "in  vec4 gs_fs;\n"
10162 									 "out vec4 fs_out;\n"
10163 									 "\n"
10164 									 "void main()\n"
10165 									 "{\n"
10166 									 "    if (TYPE(0) == block.man)\n"
10167 									 "    {\n"
10168 									 "        fs_out = block.boy;\n"
10169 									 "    }\n"
10170 									 "\n"
10171 									 "    fs_out += gs_fs;\n"
10172 									 "}\n"
10173 									 "\n";
10174 	static const GLchar* gs = "#version 430 core\n"
10175 							  "#extension GL_ARB_enhanced_layouts : require\n"
10176 							  "\n"
10177 							  "layout(points)                           in;\n"
10178 							  "layout(triangle_strip, max_vertices = 4) out;\n"
10179 							  "\n"
10180 							  "in  vec4 tes_gs[];\n"
10181 							  "out vec4 gs_fs;\n"
10182 							  "\n"
10183 							  "void main()\n"
10184 							  "{\n"
10185 							  "    gs_fs = tes_gs[0];\n"
10186 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
10187 							  "    EmitVertex();\n"
10188 							  "    gs_fs = tes_gs[0];\n"
10189 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
10190 							  "    EmitVertex();\n"
10191 							  "    gs_fs = tes_gs[0];\n"
10192 							  "    gl_Position  = vec4(1, -1, 0, 1);\n"
10193 							  "    EmitVertex();\n"
10194 							  "    gs_fs = tes_gs[0];\n"
10195 							  "    gl_Position  = vec4(1, 1, 0, 1);\n"
10196 							  "    EmitVertex();\n"
10197 							  "}\n"
10198 							  "\n";
10199 	static const GLchar* gs_tested = "#version 430 core\n"
10200 									 "#extension GL_ARB_enhanced_layouts : require\n"
10201 									 "\n"
10202 									 "layout(points)                           in;\n"
10203 									 "layout(triangle_strip, max_vertices = 4) out;\n"
10204 									 "\n"
10205 									 "layout (std140) uniform Block {\n"
10206 									 "    vec4 boy;\n"
10207 									 "    layout (align = ALIGN) TYPE man;\n"
10208 									 "} block;\n"
10209 									 "\n"
10210 									 "in  vec4 tes_gs[];\n"
10211 									 "out vec4 gs_fs;\n"
10212 									 "\n"
10213 									 "void main()\n"
10214 									 "{\n"
10215 									 "    if (TYPE(0) == block.man)\n"
10216 									 "    {\n"
10217 									 "        gs_fs = block.boy;\n"
10218 									 "    }\n"
10219 									 "\n"
10220 									 "    gs_fs += tes_gs[0];\n"
10221 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
10222 									 "    EmitVertex();\n"
10223 									 "    gs_fs += tes_gs[0];\n"
10224 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
10225 									 "    EmitVertex();\n"
10226 									 "    gs_fs += tes_gs[0];\n"
10227 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
10228 									 "    EmitVertex();\n"
10229 									 "    gs_fs += tes_gs[0];\n"
10230 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
10231 									 "    EmitVertex();\n"
10232 									 "}\n"
10233 									 "\n";
10234 	static const GLchar* tcs = "#version 430 core\n"
10235 							   "#extension GL_ARB_enhanced_layouts : require\n"
10236 							   "\n"
10237 							   "layout(vertices = 1) out;\n"
10238 							   "\n"
10239 							   "in  vec4 vs_tcs[];\n"
10240 							   "out vec4 tcs_tes[];\n"
10241 							   "\n"
10242 							   "void main()\n"
10243 							   "{\n"
10244 							   "\n"
10245 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
10246 							   "\n"
10247 							   "    gl_TessLevelOuter[0] = 1.0;\n"
10248 							   "    gl_TessLevelOuter[1] = 1.0;\n"
10249 							   "    gl_TessLevelOuter[2] = 1.0;\n"
10250 							   "    gl_TessLevelOuter[3] = 1.0;\n"
10251 							   "    gl_TessLevelInner[0] = 1.0;\n"
10252 							   "    gl_TessLevelInner[1] = 1.0;\n"
10253 							   "}\n"
10254 							   "\n";
10255 	static const GLchar* tcs_tested = "#version 430 core\n"
10256 									  "#extension GL_ARB_enhanced_layouts : require\n"
10257 									  "\n"
10258 									  "layout(vertices = 1) out;\n"
10259 									  "\n"
10260 									  "layout (std140) uniform Block {\n"
10261 									  "    vec4 boy;\n"
10262 									  "    layout (align = ALIGN) TYPE man;\n"
10263 									  "} block;\n"
10264 									  "\n"
10265 									  "in  vec4 vs_tcs[];\n"
10266 									  "out vec4 tcs_tes[];\n"
10267 									  "\n"
10268 									  "void main()\n"
10269 									  "{\n"
10270 									  "    if (TYPE(0) == block.man)\n"
10271 									  "    {\n"
10272 									  "        tcs_tes[gl_InvocationID] = block.boy;\n"
10273 									  "    }\n"
10274 									  "\n"
10275 									  "\n"
10276 									  "    tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
10277 									  "\n"
10278 									  "    gl_TessLevelOuter[0] = 1.0;\n"
10279 									  "    gl_TessLevelOuter[1] = 1.0;\n"
10280 									  "    gl_TessLevelOuter[2] = 1.0;\n"
10281 									  "    gl_TessLevelOuter[3] = 1.0;\n"
10282 									  "    gl_TessLevelInner[0] = 1.0;\n"
10283 									  "    gl_TessLevelInner[1] = 1.0;\n"
10284 									  "}\n"
10285 									  "\n";
10286 	static const GLchar* tes = "#version 430 core\n"
10287 							   "#extension GL_ARB_enhanced_layouts : require\n"
10288 							   "\n"
10289 							   "layout(isolines, point_mode) in;\n"
10290 							   "\n"
10291 							   "in  vec4 tcs_tes[];\n"
10292 							   "out vec4 tes_gs;\n"
10293 							   "\n"
10294 							   "void main()\n"
10295 							   "{\n"
10296 							   "    tes_gs = tcs_tes[0];\n"
10297 							   "}\n"
10298 							   "\n";
10299 	static const GLchar* tes_tested = "#version 430 core\n"
10300 									  "#extension GL_ARB_enhanced_layouts : require\n"
10301 									  "\n"
10302 									  "layout(isolines, point_mode) in;\n"
10303 									  "\n"
10304 									  "layout (std140) uniform Block {\n"
10305 									  "    vec4 boy;\n"
10306 									  "    layout (align = ALIGN) TYPE man;\n"
10307 									  "} block;\n"
10308 									  "\n"
10309 									  "in  vec4 tcs_tes[];\n"
10310 									  "out vec4 tes_gs;\n"
10311 									  "\n"
10312 									  "void main()\n"
10313 									  "{\n"
10314 									  "    if (TYPE(0) == block.man)\n"
10315 									  "    {\n"
10316 									  "        tes_gs = block.boy;\n"
10317 									  "    }\n"
10318 									  "\n"
10319 									  "    tes_gs += tcs_tes[0];\n"
10320 									  "}\n"
10321 									  "\n";
10322 	static const GLchar* vs = "#version 430 core\n"
10323 							  "#extension GL_ARB_enhanced_layouts : require\n"
10324 							  "\n"
10325 							  "in  vec4 in_vs;\n"
10326 							  "out vec4 vs_tcs;\n"
10327 							  "\n"
10328 							  "void main()\n"
10329 							  "{\n"
10330 							  "    vs_tcs = in_vs;\n"
10331 							  "}\n"
10332 							  "\n";
10333 	static const GLchar* vs_tested = "#version 430 core\n"
10334 									 "#extension GL_ARB_enhanced_layouts : require\n"
10335 									 "\n"
10336 									 "layout (std140) uniform Block {\n"
10337 									 "    vec4 boy;\n"
10338 									 "    layout (align = ALIGN) TYPE man;\n"
10339 									 "} block;\n"
10340 									 "\n"
10341 									 "in  vec4 in_vs;\n"
10342 									 "out vec4 vs_tcs;\n"
10343 									 "\n"
10344 									 "void main()\n"
10345 									 "{\n"
10346 									 "    if (TYPE(0) == block.man)\n"
10347 									 "    {\n"
10348 									 "        vs_tcs = block.boy;\n"
10349 									 "    }\n"
10350 									 "\n"
10351 									 "    vs_tcs += in_vs;\n"
10352 									 "}\n"
10353 									 "\n";
10354 
10355 	std::string source;
10356 	testCase&   test_case = m_test_cases[test_case_index];
10357 
10358 	if (test_case.m_stage == stage)
10359 	{
10360 		GLchar			   buffer[16];
10361 		const GLuint	   alignment = test_case.m_alignment;
10362 		const Utils::Type& type		 = test_case.m_type;
10363 		const GLchar*	  type_name = type.GetGLSLTypeName();
10364 		size_t			   position  = 0;
10365 
10366 		switch (stage)
10367 		{
10368 		case Utils::Shader::COMPUTE:
10369 			source = cs;
10370 			break;
10371 		case Utils::Shader::FRAGMENT:
10372 			source = fs_tested;
10373 			break;
10374 		case Utils::Shader::GEOMETRY:
10375 			source = gs_tested;
10376 			break;
10377 		case Utils::Shader::TESS_CTRL:
10378 			source = tcs_tested;
10379 			break;
10380 		case Utils::Shader::TESS_EVAL:
10381 			source = tes_tested;
10382 			break;
10383 		case Utils::Shader::VERTEX:
10384 			source = vs_tested;
10385 			break;
10386 		default:
10387 			TCU_FAIL("Invalid enum");
10388 		}
10389 
10390 		sprintf(buffer, "%d", alignment);
10391 		Utils::replaceToken("ALIGN", position, buffer, source);
10392 		Utils::replaceToken("TYPE", position, type_name, source);
10393 		Utils::replaceToken("TYPE", position, type_name, source);
10394 	}
10395 	else
10396 	{
10397 		switch (stage)
10398 		{
10399 		case Utils::Shader::FRAGMENT:
10400 			source = fs;
10401 			break;
10402 		case Utils::Shader::GEOMETRY:
10403 			source = gs;
10404 			break;
10405 		case Utils::Shader::TESS_CTRL:
10406 			source = tcs;
10407 			break;
10408 		case Utils::Shader::TESS_EVAL:
10409 			source = tes;
10410 			break;
10411 		case Utils::Shader::VERTEX:
10412 			source = vs;
10413 			break;
10414 		default:
10415 			TCU_FAIL("Invalid enum");
10416 		}
10417 	}
10418 
10419 	return source;
10420 }
10421 
10422 /** Get description of test case
10423  *
10424  * @param test_case_index Index of test case
10425  *
10426  * @return Type name and offset
10427  **/
10428 std::string UniformBlockMemberAlignNonPowerOf2Test::getTestCaseName(GLuint test_case_index)
10429 {
10430 	std::stringstream stream;
10431 	testCase&		  test_case = m_test_cases[test_case_index];
10432 
10433 	stream << "Type: " << test_case.m_type.GetGLSLTypeName() << ", align: " << test_case.m_alignment;
10434 
10435 	return stream.str();
10436 }
10437 
10438 /** Get number of test cases
10439  *
10440  * @return Number of test cases
10441  **/
10442 GLuint UniformBlockMemberAlignNonPowerOf2Test::getTestCaseNumber()
10443 {
10444 	return static_cast<GLuint>(m_test_cases.size());
10445 }
10446 
10447 /** Selects if "compute" stage is relevant for test
10448  *
10449  * @param test_case_index Index of test case
10450  *
10451  * @return true when tested stage is compute
10452  **/
10453 bool UniformBlockMemberAlignNonPowerOf2Test::isComputeRelevant(GLuint test_case_index)
10454 {
10455 	return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
10456 }
10457 
10458 /** Checks if stage is supported
10459  *
10460  * @param ignored
10461  *
10462  * @return true
10463  **/
10464 bool UniformBlockMemberAlignNonPowerOf2Test::isStageSupported(Utils::Shader::STAGES /* stage */)
10465 {
10466 	return true;
10467 }
10468 
10469 /** Selects if compilation failure is expected result
10470  *
10471  * @param test_case_index Index of test case
10472  *
10473  * @return should_fail field from testCase
10474  **/
10475 bool UniformBlockMemberAlignNonPowerOf2Test::isFailureExpected(GLuint test_case_index)
10476 {
10477 	return m_test_cases[test_case_index].m_should_fail;
10478 }
10479 
10480 /** Prepare all test cases
10481  *
10482  **/
10483 void UniformBlockMemberAlignNonPowerOf2Test::testInit()
10484 {
10485 	static const GLuint dmat4_size = 128;
10486 	const GLuint		n_types	= getTypesNumber();
10487 	bool				stage_support[Utils::Shader::STAGE_MAX];
10488 
10489 	for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
10490 	{
10491 		stage_support[stage] = isStageSupported((Utils::Shader::STAGES)stage);
10492 	}
10493 
10494 	for (GLuint j = 0; j < n_types; ++j)
10495 	{
10496 		const Utils::Type& type = getType(j);
10497 
10498 		for (GLuint align = 0; align <= dmat4_size; ++align)
10499 		{
10500 
10501 #if WRKARD_UNIFORMBLOCKMEMBERALIGNNONPOWEROF2TEST
10502 
10503 			const bool should_fail = (0 == align) ? false : !isPowerOf2(align);
10504 
10505 #else /* WRKARD_UNIFORMBLOCKMEMBERALIGNNONPOWEROF2TEST */
10506 
10507 			const bool should_fail = !isPowerOf2(align);
10508 
10509 #endif /* WRKARD_UNIFORMBLOCKMEMBERALIGNNONPOWEROF2TEST */
10510 
10511 			for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
10512 			{
10513 				if (false == stage_support[stage])
10514 				{
10515 					continue;
10516 				}
10517 
10518 				testCase test_case = { align, type, should_fail, (Utils::Shader::STAGES)stage };
10519 
10520 				m_test_cases.push_back(test_case);
10521 			}
10522 		}
10523 	}
10524 }
10525 
10526 /** Check if value is power of 2
10527  *
10528  * @param val Tested value
10529  *
10530  * @return true if val is power of 2, false otherwise
10531  **/
10532 bool UniformBlockMemberAlignNonPowerOf2Test::isPowerOf2(GLuint val)
10533 {
10534 	if (0 == val)
10535 	{
10536 		return false;
10537 	}
10538 
10539 	return (0 == (val & (val - 1)));
10540 }
10541 
10542 /** Constructor
10543  *
10544  * @param context Test framework context
10545  **/
10546 UniformBlockAlignmentTest::UniformBlockAlignmentTest(deqp::Context& context)
10547 	: TextureTestBase(context, "uniform_block_alignment", "Test verifies offset and alignment of uniform buffer")
10548 {
10549 }
10550 
10551 /** Get interface of program
10552  *
10553  * @param ignored
10554  * @param program_interface Interface of program
10555  * @param varying_passthrough Collection of connections between in and out variables
10556  **/
10557 void UniformBlockAlignmentTest::getProgramInterface(GLuint /* test_case_index */,
10558 													Utils::ProgramInterface&   program_interface,
10559 													Utils::VaryingPassthrough& varying_passthrough)
10560 {
10561 	static const Utils::Type vec4 = Utils::Type::vec4;
10562 
10563 #if WRKARD_UNIFORMBLOCKALIGNMENT
10564 
10565 	static const GLuint block_align = 16;
10566 
10567 #else /* WRKARD_UNIFORMBLOCKALIGNMENT */
10568 
10569 	static const GLuint block_align = 64;
10570 
10571 #endif /* WRKARD_UNIFORMBLOCKALIGNMENT */
10572 
10573 	static const GLuint vec4_stride = 16;
10574 	static const GLuint data_stride = vec4_stride * 2; /* one vec4 + one scalar aligned to 16 */
10575 
10576 	/*Fixed a test issue, the fifth_offset should be calculated by block_align, instead of fifth_align, according to spec, the actual
10577 	 alignment of a member will be the greater of the specified alignment and the base aligment for the member type
10578 	 */
10579 	const GLuint first_offset  = 0;																		/* vec4 at 0 */
10580 	const GLuint second_offset = Utils::Type::GetActualOffset(first_offset + vec4_stride, block_align); /* Data at 32 */
10581 	const GLuint third_offset =
10582 		Utils::Type::GetActualOffset(second_offset + data_stride, block_align); /* Data[2] at 64 */
10583 	const GLuint fourth_offset =
10584 		Utils::Type::GetActualOffset(third_offset + data_stride * 2, block_align); /* vec4[3] at 96 */
10585 	const GLuint fifth_offset =
10586 		Utils::Type::GetActualOffset(fourth_offset + vec4_stride * 3, block_align); /* vec4[2] at 160 */
10587 	const GLuint sixth_offset =
10588 		Utils::Type::GetActualOffset(fifth_offset + vec4_stride * 2, block_align); /* Data at 192 */
10589 
10590 	Utils::Interface* structure = program_interface.Structure("Data");
10591 
10592 	structure->Member("vector", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::vec4,
10593 					  false /* normalized */, 0 /* n_array_elements */, Utils::Type::vec4.GetSize(), 0 /* offset */);
10594 
10595 	structure->Member("scalar", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::_float,
10596 					  false /* normalized */, 0 /* n_array_elements */, Utils::Type::_float.GetSize(),
10597 					  Utils::Type::vec4.GetSize() /* offset */);
10598 
10599 	/* Prepare Block */
10600 	Utils::Interface* vs_uni_block = program_interface.Block("vs_uni_Block");
10601 
10602 	vs_uni_block->Member("first", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::vec4,
10603 						 false /* normalized */, 0 /* n_array_elements */, vec4_stride, first_offset /* offset */);
10604 
10605 	vs_uni_block->Member("second", "", 0 /* expected_component */, 0 /* expected_location */, structure,
10606 						 0 /* n_array_elements */, data_stride, second_offset);
10607 
10608 	vs_uni_block->Member("third", "", 0 /* expected_component */, 0 /* expected_location */, structure,
10609 						 2 /* n_array_elements */, data_stride, third_offset);
10610 
10611 	vs_uni_block->Member("fourth", "", 0 /* expected_component */, 0 /* expected_location */, vec4,
10612 						 false /* normalized */, 3 /* n_array_elements */, vec4_stride, fourth_offset);
10613 
10614 	vs_uni_block->Member("fifth", "layout(align = 64)", 0 /* expected_component */, 0 /* expected_location */, vec4,
10615 						 false /* normalized */, 2 /* n_array_elements */, vec4_stride, fifth_offset);
10616 
10617 	vs_uni_block->Member("sixth", "", 0 /* expected_component */, 0 /* expected_location */, structure,
10618 						 0 /* n_array_elements */, data_stride, sixth_offset);
10619 
10620 	const GLuint stride = calculateStride(*vs_uni_block);
10621 	m_data.resize(stride);
10622 	generateData(*vs_uni_block, 0, m_data);
10623 
10624 	Utils::ShaderInterface& vs_si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
10625 
10626 /* Add uniform BLOCK */
10627 #if WRKARD_UNIFORMBLOCKALIGNMENT
10628 	vs_si.Uniform("vs_uni_block", "layout (std140, binding = BINDING)", 0, 0, vs_uni_block, 0,
10629 				  static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
10630 #else  /* WRKARD_UNIFORMBLOCKALIGNMENT */
10631 	vs_si.Uniform("vs_uni_block", "layout (std140, binding = BINDING, align = 64)", 0, 0, vs_uni_block, 0,
10632 				  static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
10633 #endif /* WRKARD_UNIFORMBLOCKALIGNMENT */
10634 
10635 	program_interface.CloneVertexInterface(varying_passthrough);
10636 }
10637 
10638 /** Constructor
10639  *
10640  * @param context Test framework context
10641  **/
10642 SSBMemberOffsetAndAlignTest::SSBMemberOffsetAndAlignTest(deqp::Context& context)
10643 	: TextureTestBase(context, "ssb_member_offset_and_align",
10644 					  "Test verifies offsets and alignment of storage buffer members")
10645 {
10646 }
10647 
10648 /** Get interface of program
10649  *
10650  * @param test_case_index     Test case index
10651  * @param program_interface   Interface of program
10652  * @param varying_passthrough Collection of connections between in and out variables
10653  **/
10654 void SSBMemberOffsetAndAlignTest::getProgramInterface(GLuint					 test_case_index,
10655 													  Utils::ProgramInterface&   program_interface,
10656 													  Utils::VaryingPassthrough& varying_passthrough)
10657 {
10658 	std::string globals = "const int basic_size = BASIC_SIZE;\n"
10659 						  "const int type_align = TYPE_ALIGN;\n"
10660 						  "const int type_size  = TYPE_SIZE;\n";
10661 
10662 	Utils::Type  type		 = getType(test_case_index);
10663 	GLuint		 basic_size  = Utils::Type::GetTypeSize(type.m_basic_type);
10664 	const GLuint base_align  = type.GetBaseAlignment(false);
10665 	const GLuint array_align = type.GetBaseAlignment(true);
10666 	const GLuint base_stride = Utils::Type::CalculateStd140Stride(base_align, type.m_n_columns, 0);
10667 	const GLuint type_align  = Utils::roundUpToPowerOf2(base_stride);
10668 
10669 	/* Calculate offsets */
10670 	const GLuint first_offset  = 0;
10671 	const GLuint second_offset = type.GetActualOffset(base_stride, basic_size / 2);
10672 
10673 #if WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST
10674 
10675 	const GLuint third_offset   = type.GetActualOffset(second_offset + base_stride, base_align);
10676 	const GLuint fourth_offset  = type.GetActualOffset(third_offset + base_stride, base_align);
10677 	const GLuint fifth_offset   = type.GetActualOffset(fourth_offset + base_stride, base_align);
10678 	const GLuint sixth_offset   = type.GetActualOffset(fifth_offset + base_stride, array_align);
10679 	const GLuint seventh_offset = type.GetActualOffset(sixth_offset + base_stride, array_align);
10680 	const GLuint eigth_offset   = type.GetActualOffset(seventh_offset + base_stride, array_align);
10681 
10682 #else /* WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST */
10683 
10684 	const GLuint third_offset   = type.GetActualOffset(second_offset + base_stride, 2 * type_align);
10685 	const GLuint fourth_offset  = type.GetActualOffset(3 * type_align + base_stride, base_align);
10686 	const GLuint fifth_offset   = type.GetActualOffset(fourth_offset + base_stride, base_align);
10687 	const GLuint sixth_offset   = type.GetActualOffset(fifth_offset + base_stride, array_align);
10688 	const GLuint seventh_offset = type.GetActualOffset(sixth_offset + base_stride, array_align);
10689 	const GLuint eigth_offset   = type.GetActualOffset(seventh_offset + base_stride, 8 * basic_size);
10690 
10691 #endif /* WRKARD_UNIFORMBLOCKMEMBEROFFSETANDALIGNTEST */
10692 
10693 	/* Prepare data */
10694 	const std::vector<GLubyte>& first  = type.GenerateData();
10695 	const std::vector<GLubyte>& second = type.GenerateData();
10696 	const std::vector<GLubyte>& third  = type.GenerateData();
10697 	const std::vector<GLubyte>& fourth = type.GenerateData();
10698 
10699 	m_data.resize(eigth_offset + base_stride);
10700 	GLubyte* ptr = &m_data[0];
10701 	memcpy(ptr + first_offset, &first[0], first.size());
10702 	memcpy(ptr + second_offset, &second[0], second.size());
10703 	memcpy(ptr + third_offset, &third[0], third.size());
10704 	memcpy(ptr + fourth_offset, &fourth[0], fourth.size());
10705 	memcpy(ptr + fifth_offset, &fourth[0], fourth.size());
10706 	memcpy(ptr + sixth_offset, &third[0], third.size());
10707 	memcpy(ptr + seventh_offset, &second[0], second.size());
10708 	memcpy(ptr + eigth_offset, &first[0], first.size());
10709 
10710 	/* Prepare globals */
10711 	size_t position = 0;
10712 	GLchar buffer[16];
10713 
10714 	sprintf(buffer, "%d", basic_size);
10715 	Utils::replaceToken("BASIC_SIZE", position, buffer, globals);
10716 
10717 	sprintf(buffer, "%d", type_align);
10718 	Utils::replaceToken("TYPE_ALIGN", position, buffer, globals);
10719 
10720 	sprintf(buffer, "%d", base_stride);
10721 	Utils::replaceToken("TYPE_SIZE", position, buffer, globals);
10722 
10723 	/* Prepare Block */
10724 	Utils::Interface* vs_buf_block = program_interface.Block("vs_buf_Block");
10725 
10726 	vs_buf_block->Member("at_first_offset", "layout(offset = 0, align = 8 * basic_size)", 0 /* expected_component */,
10727 						 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
10728 						 first_offset);
10729 
10730 	vs_buf_block->Member("at_second_offset", "layout(offset = type_size, align = basic_size / 2)",
10731 						 0 /* expected_component */, 0 /* expected_location */, type, false /* normalized */,
10732 						 0 /* n_array_elements */, base_stride, second_offset);
10733 
10734 	vs_buf_block->Member("at_third_offset", "layout(align = 2 * type_align)", 0 /* expected_component */,
10735 						 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
10736 						 third_offset);
10737 
10738 	vs_buf_block->Member("at_fourth_offset", "layout(offset = 3 * type_align + type_size)", 0 /* expected_component */,
10739 						 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
10740 						 fourth_offset);
10741 
10742 	vs_buf_block->Member("at_fifth_offset", "", 0 /* expected_component */, 0 /* expected_location */, type,
10743 						 false /* normalized */, 0 /* n_array_elements */, base_stride, fifth_offset);
10744 
10745 	vs_buf_block->Member("at_sixth_offset", "", 0 /* expected_component */, 0 /* expected_location */, type,
10746 						 false /* normalized */, 2 /* n_array_elements */, array_align * 2, sixth_offset);
10747 
10748 	vs_buf_block->Member("at_eigth_offset", "layout(align = 8 * basic_size)", 0 /* expected_component */,
10749 						 0 /* expected_location */, type, false /* normalized */, 0 /* n_array_elements */, base_stride,
10750 						 eigth_offset);
10751 
10752 	Utils::ShaderInterface& vs_si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
10753 
10754 	/* Add globals */
10755 	vs_si.m_globals = globals;
10756 
10757 	/* Add uniform BLOCK */
10758 	vs_si.SSB("vs_buf_block", "layout (std140, binding = BINDING)", 0, 0, vs_buf_block, 0,
10759 			  static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
10760 
10761 	/* */
10762 	program_interface.CloneVertexInterface(varying_passthrough);
10763 }
10764 
10765 /** Get type name
10766  *
10767  * @param test_case_index Index of test case
10768  *
10769  * @return Name of type test in test_case_index
10770  **/
10771 std::string SSBMemberOffsetAndAlignTest::getTestCaseName(glw::GLuint test_case_index)
10772 {
10773 	return getTypeName(test_case_index);
10774 }
10775 
10776 /** Returns number of types to test
10777  *
10778  * @return Number of types, 34
10779  **/
10780 glw::GLuint SSBMemberOffsetAndAlignTest::getTestCaseNumber()
10781 {
10782 	return getTypesNumber();
10783 }
10784 
10785 /** Prepare code snippet that will verify in and uniform variables
10786  *
10787  * @param ignored
10788  * @param ignored
10789  * @param stage   Shader stage
10790  *
10791  * @return Code that verify variables
10792  **/
10793 std::string SSBMemberOffsetAndAlignTest::getVerificationSnippet(GLuint /* test_case_index */,
10794 																Utils::ProgramInterface& /* program_interface */,
10795 																Utils::Shader::STAGES stage)
10796 {
10797 	std::string verification = "if ( (PREFIXblock.at_first_offset  != PREFIXblock.at_eigth_offset   ) ||\n"
10798 							   "         (PREFIXblock.at_second_offset != PREFIXblock.at_sixth_offset[1]) ||\n"
10799 							   "         (PREFIXblock.at_third_offset  != PREFIXblock.at_sixth_offset[0]) ||\n"
10800 							   "         (PREFIXblock.at_fourth_offset != PREFIXblock.at_fifth_offset   )  )\n"
10801 							   "    {\n"
10802 							   "        result = 0;\n"
10803 							   "    }";
10804 
10805 	const GLchar* prefix = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::SSB);
10806 
10807 	Utils::replaceAllTokens("PREFIX", prefix, verification);
10808 
10809 	return verification;
10810 }
10811 
10812 /** Selects if "draw" stages are relevant for test
10813  *
10814  * @param ignored
10815  *
10816  * @return true if all stages support shader storage buffers, false otherwise
10817  **/
10818 bool SSBMemberOffsetAndAlignTest::isDrawRelevant(GLuint /* test_case_index */)
10819 {
10820 	const Functions& gl					   = m_context.getRenderContext().getFunctions();
10821 	GLint			 gs_supported_buffers  = 0;
10822 	GLint			 tcs_supported_buffers = 0;
10823 	GLint			 tes_supported_buffers = 0;
10824 	GLint			 vs_supported_buffers  = 0;
10825 
10826 	gl.getIntegerv(GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS, &gs_supported_buffers);
10827 	gl.getIntegerv(GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS, &tcs_supported_buffers);
10828 	gl.getIntegerv(GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS, &tes_supported_buffers);
10829 	gl.getIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &vs_supported_buffers);
10830 
10831 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
10832 
10833 	return ((1 <= gs_supported_buffers) && (1 <= tcs_supported_buffers) && (1 <= tes_supported_buffers) &&
10834 			(1 <= vs_supported_buffers));
10835 }
10836 
10837 /** Constructor
10838  *
10839  * @param context Test framework context
10840  **/
10841 SSBLayoutQualifierConflictTest::SSBLayoutQualifierConflictTest(deqp::Context& context)
10842 	: NegativeTestBase(context, "ssb_layout_qualifier_conflict", "Test verifies that std140 or std430 is required when "
10843 																 "offset and/or align qualifiers are used with storage "
10844 																 "block")
10845 {
10846 	/* Nothing to be done here */
10847 }
10848 
10849 /** Source for given test case and stage
10850  *
10851  * @param test_case_index Index of test case
10852  * @param stage           Shader stage
10853  *
10854  * @return Shader source
10855  **/
10856 std::string SSBLayoutQualifierConflictTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
10857 {
10858 	static const GLchar* cs = "#version 430 core\n"
10859 							  "#extension GL_ARB_enhanced_layouts : require\n"
10860 							  "\n"
10861 							  "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
10862 							  "\n"
10863 							  "layout (QUALIFIERbinding = BINDING) buffer cs_Block {\n"
10864 							  "    layout(offset = 16) vec4 boy;\n"
10865 							  "    layout(align  = 64) vec4 man;\n"
10866 							  "} uni_block;\n"
10867 							  "\n"
10868 							  "writeonly uniform image2D uni_image;\n"
10869 							  "\n"
10870 							  "void main()\n"
10871 							  "{\n"
10872 							  "    vec4 result = uni_block.boy + uni_block.man;\n"
10873 							  "\n"
10874 							  "    imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
10875 							  "}\n"
10876 							  "\n";
10877 	static const GLchar* fs = "#version 430 core\n"
10878 							  "#extension GL_ARB_enhanced_layouts : require\n"
10879 							  "\n"
10880 							  "layout (QUALIFIERbinding = BINDING) buffer Block {\n"
10881 							  "    layout(offset = 16) vec4 boy;\n"
10882 							  "    layout(align  = 64) vec4 man;\n"
10883 							  "} uni_block;\n"
10884 							  "\n"
10885 							  "in  vec4 gs_fs;\n"
10886 							  "out vec4 fs_out;\n"
10887 							  "\n"
10888 							  "void main()\n"
10889 							  "{\n"
10890 							  "    fs_out = gs_fs + uni_block.boy + uni_block.man;\n"
10891 							  "}\n"
10892 							  "\n";
10893 	static const GLchar* gs = "#version 430 core\n"
10894 							  "#extension GL_ARB_enhanced_layouts : require\n"
10895 							  "\n"
10896 							  "layout(points)                           in;\n"
10897 							  "layout(triangle_strip, max_vertices = 4) out;\n"
10898 							  "\n"
10899 							  "layout (QUALIFIERbinding = BINDING) buffer gs_Block {\n"
10900 							  "    layout(offset = 16) vec4 boy;\n"
10901 							  "    layout(align  = 64) vec4 man;\n"
10902 							  "} uni_block;\n"
10903 							  "\n"
10904 							  "in  vec4 tes_gs[];\n"
10905 							  "out vec4 gs_fs;\n"
10906 							  "\n"
10907 							  "void main()\n"
10908 							  "{\n"
10909 							  "    gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
10910 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
10911 							  "    EmitVertex();\n"
10912 							  "    gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
10913 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
10914 							  "    EmitVertex();\n"
10915 							  "    gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
10916 							  "    gl_Position  = vec4(1, -1, 0, 1);\n"
10917 							  "    EmitVertex();\n"
10918 							  "    gs_fs = tes_gs[0] + uni_block.boy + uni_block.man;\n"
10919 							  "    gl_Position  = vec4(1, 1, 0, 1);\n"
10920 							  "    EmitVertex();\n"
10921 							  "}\n"
10922 							  "\n";
10923 	static const GLchar* tcs =
10924 		"#version 430 core\n"
10925 		"#extension GL_ARB_enhanced_layouts : require\n"
10926 		"\n"
10927 		"layout(vertices = 1) out;\n"
10928 		"\n"
10929 		"layout (QUALIFIERbinding = BINDING) buffer tcs_Block {\n"
10930 		"    layout(offset = 16) vec4 boy;\n"
10931 		"    layout(align  = 64) vec4 man;\n"
10932 		"} uni_block;\n"
10933 		"\n"
10934 		"in  vec4 vs_tcs[];\n"
10935 		"out vec4 tcs_tes[];\n"
10936 		"\n"
10937 		"void main()\n"
10938 		"{\n"
10939 		"\n"
10940 		"    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID] + uni_block.boy + uni_block.man;\n"
10941 		"\n"
10942 		"    gl_TessLevelOuter[0] = 1.0;\n"
10943 		"    gl_TessLevelOuter[1] = 1.0;\n"
10944 		"    gl_TessLevelOuter[2] = 1.0;\n"
10945 		"    gl_TessLevelOuter[3] = 1.0;\n"
10946 		"    gl_TessLevelInner[0] = 1.0;\n"
10947 		"    gl_TessLevelInner[1] = 1.0;\n"
10948 		"}\n"
10949 		"\n";
10950 	static const GLchar* tes = "#version 430 core\n"
10951 							   "#extension GL_ARB_enhanced_layouts : require\n"
10952 							   "\n"
10953 							   "layout(isolines, point_mode) in;\n"
10954 							   "\n"
10955 							   "layout (QUALIFIERbinding = BINDING) buffer tes_Block {\n"
10956 							   "    layout(offset = 16) vec4 boy;\n"
10957 							   "    layout(align  = 64) vec4 man;\n"
10958 							   "} uni_block;\n"
10959 							   "\n"
10960 							   "in  vec4 tcs_tes[];\n"
10961 							   "out vec4 tes_gs;\n"
10962 							   "\n"
10963 							   "void main()\n"
10964 							   "{\n"
10965 							   "    tes_gs = tcs_tes[0] + uni_block.boy + uni_block.man;\n"
10966 							   "}\n"
10967 							   "\n";
10968 	static const GLchar* vs = "#version 430 core\n"
10969 							  "#extension GL_ARB_enhanced_layouts : require\n"
10970 							  "\n"
10971 							  "layout (QUALIFIERbinding = BINDING) buffer vs_Block {\n"
10972 							  "    layout(offset = 16) vec4 boy;\n"
10973 							  "    layout(align  = 64) vec4 man;\n"
10974 							  "} uni_block;\n"
10975 							  "\n"
10976 							  "in  vec4 in_vs;\n"
10977 							  "out vec4 vs_tcs;\n"
10978 							  "\n"
10979 							  "void main()\n"
10980 							  "{\n"
10981 							  "    vs_tcs = in_vs + uni_block.boy + uni_block.man;\n"
10982 							  "}\n"
10983 							  "\n";
10984 
10985 	GLchar		buffer[16];
10986 	size_t		position = 0;
10987 	std::string source;
10988 	testCase&   test_case = m_test_cases[test_case_index];
10989 	std::string qualifier = getQualifierName(test_case.m_qualifier);
10990 
10991 	if (false == qualifier.empty())
10992 	{
10993 		qualifier.append(", ");
10994 	}
10995 
10996 	sprintf(buffer, "%d", stage);
10997 
10998 	switch (stage)
10999 	{
11000 	case Utils::Shader::COMPUTE:
11001 		source = cs;
11002 		break;
11003 	case Utils::Shader::FRAGMENT:
11004 		source = fs;
11005 		break;
11006 	case Utils::Shader::GEOMETRY:
11007 		source = gs;
11008 		break;
11009 	case Utils::Shader::TESS_CTRL:
11010 		source = tcs;
11011 		break;
11012 	case Utils::Shader::TESS_EVAL:
11013 		source = tes;
11014 		break;
11015 	case Utils::Shader::VERTEX:
11016 		source = vs;
11017 		break;
11018 	default:
11019 		TCU_FAIL("Invalid enum");
11020 	}
11021 
11022 	if (test_case.m_stage == stage)
11023 	{
11024 		Utils::replaceToken("QUALIFIER", position, qualifier.c_str(), source);
11025 	}
11026 	else
11027 	{
11028 		Utils::replaceToken("QUALIFIER", position, "std140, ", source);
11029 	}
11030 
11031 	Utils::replaceToken("BINDING", position, buffer, source);
11032 
11033 	return source;
11034 }
11035 
11036 /** Get description of test case
11037  *
11038  * @param test_case_index Index of test case
11039  *
11040  * @return Qualifier name
11041  **/
11042 std::string SSBLayoutQualifierConflictTest::getTestCaseName(GLuint test_case_index)
11043 {
11044 	std::string result = getQualifierName(m_test_cases[test_case_index].m_qualifier);
11045 
11046 	return result;
11047 }
11048 
11049 /** Get number of test cases
11050  *
11051  * @return Number of test cases
11052  **/
11053 GLuint SSBLayoutQualifierConflictTest::getTestCaseNumber()
11054 {
11055 	return static_cast<GLuint>(m_test_cases.size());
11056 }
11057 
11058 /** Selects if "compute" stage is relevant for test
11059  *
11060  * @param test_case_index Index of test case
11061  *
11062  * @return true when tested stage is compute
11063  **/
11064 bool SSBLayoutQualifierConflictTest::isComputeRelevant(GLuint test_case_index)
11065 {
11066 	return (Utils::Shader::COMPUTE == m_test_cases[test_case_index].m_stage);
11067 }
11068 
11069 /** Selects if compilation failure is expected result
11070  *
11071  * @param test_case_index Index of test case
11072  *
11073  * @return false for STD140 and STD430 cases, true otherwise
11074  **/
11075 bool SSBLayoutQualifierConflictTest::isFailureExpected(GLuint test_case_index)
11076 {
11077 	const QUALIFIERS qualifier = m_test_cases[test_case_index].m_qualifier;
11078 
11079 	return !((STD140 == qualifier) || (STD430 == qualifier));
11080 }
11081 
11082 /** Checks if stage is supported
11083  *
11084  * @param stage Shader stage
11085  *
11086  * @return true if supported, false otherwise
11087  **/
11088 bool SSBLayoutQualifierConflictTest::isStageSupported(Utils::Shader::STAGES stage)
11089 {
11090 	const Functions& gl					   = m_context.getRenderContext().getFunctions();
11091 	GLint			 max_supported_buffers = 0;
11092 	GLenum			 pname				   = 0;
11093 
11094 	switch (stage)
11095 	{
11096 	case Utils::Shader::COMPUTE:
11097 		pname = GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS;
11098 		break;
11099 	case Utils::Shader::FRAGMENT:
11100 		pname = GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS;
11101 		break;
11102 	case Utils::Shader::GEOMETRY:
11103 		pname = GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS;
11104 		break;
11105 	case Utils::Shader::TESS_CTRL:
11106 		pname = GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS;
11107 		break;
11108 	case Utils::Shader::TESS_EVAL:
11109 		pname = GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS;
11110 		break;
11111 	case Utils::Shader::VERTEX:
11112 		pname = GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS;
11113 		break;
11114 	default:
11115 		TCU_FAIL("Invalid enum");
11116 	}
11117 
11118 	gl.getIntegerv(pname, &max_supported_buffers);
11119 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
11120 
11121 	return 1 <= max_supported_buffers;
11122 }
11123 
11124 /** Prepare all test cases
11125  *
11126  **/
11127 void SSBLayoutQualifierConflictTest::testInit()
11128 {
11129 	bool stage_support[Utils::Shader::STAGE_MAX];
11130 
11131 	for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
11132 	{
11133 		stage_support[stage] = isStageSupported((Utils::Shader::STAGES)stage);
11134 	}
11135 
11136 	for (GLuint qualifier = 0; qualifier < QUALIFIERS_MAX; ++qualifier)
11137 	{
11138 		for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
11139 		{
11140 			if (false == stage_support[stage])
11141 			{
11142 				continue;
11143 			}
11144 
11145 			testCase test_case = { (QUALIFIERS)qualifier, (Utils::Shader::STAGES)stage };
11146 
11147 			m_test_cases.push_back(test_case);
11148 		}
11149 	}
11150 }
11151 
11152 /** Get name of glsl constant
11153  *
11154  * @param Constant id
11155  *
11156  * @return Name of constant used in GLSL
11157  **/
11158 const GLchar* SSBLayoutQualifierConflictTest::getQualifierName(QUALIFIERS qualifier)
11159 {
11160 	const GLchar* name = "";
11161 
11162 	switch (qualifier)
11163 	{
11164 	case DEFAULT:
11165 		name = "";
11166 		break;
11167 	case STD140:
11168 		name = "std140";
11169 		break;
11170 	case STD430:
11171 		name = "std430";
11172 		break;
11173 	case SHARED:
11174 		name = "shared";
11175 		break;
11176 	case PACKED:
11177 		name = "packed";
11178 		break;
11179 	default:
11180 		TCU_FAIL("Invalid enum");
11181 	}
11182 
11183 	return name;
11184 }
11185 
11186 /** Constructor
11187  *
11188  * @param context Test framework context
11189  **/
11190 SSBMemberInvalidOffsetAlignmentTest::SSBMemberInvalidOffsetAlignmentTest(deqp::Context& context)
11191 	: UniformBlockMemberInvalidOffsetAlignmentTest(
11192 		  context, "ssb_member_invalid_offset_alignment",
11193 		  "Test verifies that invalid alignment of offset qualifiers cause compilation failure")
11194 {
11195 	/* Nothing to be done here */
11196 }
11197 
11198 /** Get the maximum size for a shader storage block
11199  *
11200  * @return The maximum size in basic machine units of a shader storage block.
11201  **/
11202 GLint SSBMemberInvalidOffsetAlignmentTest::getMaxBlockSize()
11203 {
11204 	const Functions& gl		  = m_context.getRenderContext().getFunctions();
11205 	GLint			 max_size = 0;
11206 
11207 	gl.getIntegerv(GL_MAX_SHADER_STORAGE_BLOCK_SIZE, &max_size);
11208 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
11209 
11210 	return max_size;
11211 }
11212 
11213 /** Source for given test case and stage
11214  *
11215  * @param test_case_index Index of test case
11216  * @param stage           Shader stage
11217  *
11218  * @return Shader source
11219  **/
11220 std::string SSBMemberInvalidOffsetAlignmentTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
11221 {
11222 	static const GLchar* cs = "#version 430 core\n"
11223 							  "#extension GL_ARB_enhanced_layouts : require\n"
11224 							  "\n"
11225 							  "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
11226 							  "\n"
11227 							  "layout (std140) buffer Block {\n"
11228 							  "    layout (offset = OFFSET) TYPE member;\n"
11229 							  "} block;\n"
11230 							  "\n"
11231 							  "writeonly uniform image2D uni_image;\n"
11232 							  "\n"
11233 							  "void main()\n"
11234 							  "{\n"
11235 							  "    vec4 result = vec4(1, 0, 0.5, 1);\n"
11236 							  "\n"
11237 							  "    if (TYPE(1) == block.member)\n"
11238 							  "    {\n"
11239 							  "        result = vec4(1, 1, 1, 1);\n"
11240 							  "    }\n"
11241 							  "\n"
11242 							  "    imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
11243 							  "}\n"
11244 							  "\n";
11245 	static const GLchar* fs = "#version 430 core\n"
11246 							  "#extension GL_ARB_enhanced_layouts : require\n"
11247 							  "\n"
11248 							  "in  vec4 gs_fs;\n"
11249 							  "out vec4 fs_out;\n"
11250 							  "\n"
11251 							  "void main()\n"
11252 							  "{\n"
11253 							  "    fs_out = gs_fs;\n"
11254 							  "}\n"
11255 							  "\n";
11256 	static const GLchar* fs_tested = "#version 430 core\n"
11257 									 "#extension GL_ARB_enhanced_layouts : require\n"
11258 									 "\n"
11259 									 "layout (std140) buffer Block {\n"
11260 									 "    layout (offset = OFFSET) TYPE member;\n"
11261 									 "} block;\n"
11262 									 "\n"
11263 									 "in  vec4 gs_fs;\n"
11264 									 "out vec4 fs_out;\n"
11265 									 "\n"
11266 									 "void main()\n"
11267 									 "{\n"
11268 									 "    if (TYPE(1) == block.member)\n"
11269 									 "    {\n"
11270 									 "        fs_out = vec4(1, 1, 1, 1);\n"
11271 									 "    }\n"
11272 									 "\n"
11273 									 "    fs_out += gs_fs;\n"
11274 									 "}\n"
11275 									 "\n";
11276 	static const GLchar* gs = "#version 430 core\n"
11277 							  "#extension GL_ARB_enhanced_layouts : require\n"
11278 							  "\n"
11279 							  "layout(points)                           in;\n"
11280 							  "layout(triangle_strip, max_vertices = 4) out;\n"
11281 							  "\n"
11282 							  "in  vec4 tes_gs[];\n"
11283 							  "out vec4 gs_fs;\n"
11284 							  "\n"
11285 							  "void main()\n"
11286 							  "{\n"
11287 							  "    gs_fs = tes_gs[0];\n"
11288 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
11289 							  "    EmitVertex();\n"
11290 							  "    gs_fs = tes_gs[0];\n"
11291 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
11292 							  "    EmitVertex();\n"
11293 							  "    gs_fs = tes_gs[0];\n"
11294 							  "    gl_Position  = vec4(1, -1, 0, 1);\n"
11295 							  "    EmitVertex();\n"
11296 							  "    gs_fs = tes_gs[0];\n"
11297 							  "    gl_Position  = vec4(1, 1, 0, 1);\n"
11298 							  "    EmitVertex();\n"
11299 							  "}\n"
11300 							  "\n";
11301 	static const GLchar* gs_tested = "#version 430 core\n"
11302 									 "#extension GL_ARB_enhanced_layouts : require\n"
11303 									 "\n"
11304 									 "layout(points)                           in;\n"
11305 									 "layout(triangle_strip, max_vertices = 4) out;\n"
11306 									 "\n"
11307 									 "layout (std140) buffer Block {\n"
11308 									 "    layout (offset = OFFSET) TYPE member;\n"
11309 									 "} block;\n"
11310 									 "\n"
11311 									 "in  vec4 tes_gs[];\n"
11312 									 "out vec4 gs_fs;\n"
11313 									 "\n"
11314 									 "void main()\n"
11315 									 "{\n"
11316 									 "    if (TYPE(1) == block.member)\n"
11317 									 "    {\n"
11318 									 "        gs_fs = vec4(1, 1, 1, 1);\n"
11319 									 "    }\n"
11320 									 "\n"
11321 									 "    gs_fs += tes_gs[0];\n"
11322 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
11323 									 "    EmitVertex();\n"
11324 									 "    gs_fs += tes_gs[0];\n"
11325 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
11326 									 "    EmitVertex();\n"
11327 									 "    gs_fs += tes_gs[0];\n"
11328 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
11329 									 "    EmitVertex();\n"
11330 									 "    gs_fs += tes_gs[0];\n"
11331 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
11332 									 "    EmitVertex();\n"
11333 									 "}\n"
11334 									 "\n";
11335 	static const GLchar* tcs = "#version 430 core\n"
11336 							   "#extension GL_ARB_enhanced_layouts : require\n"
11337 							   "\n"
11338 							   "layout(vertices = 1) out;\n"
11339 							   "\n"
11340 							   "in  vec4 vs_tcs[];\n"
11341 							   "out vec4 tcs_tes[];\n"
11342 							   "\n"
11343 							   "void main()\n"
11344 							   "{\n"
11345 							   "\n"
11346 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
11347 							   "\n"
11348 							   "    gl_TessLevelOuter[0] = 1.0;\n"
11349 							   "    gl_TessLevelOuter[1] = 1.0;\n"
11350 							   "    gl_TessLevelOuter[2] = 1.0;\n"
11351 							   "    gl_TessLevelOuter[3] = 1.0;\n"
11352 							   "    gl_TessLevelInner[0] = 1.0;\n"
11353 							   "    gl_TessLevelInner[1] = 1.0;\n"
11354 							   "}\n"
11355 							   "\n";
11356 	static const GLchar* tcs_tested = "#version 430 core\n"
11357 									  "#extension GL_ARB_enhanced_layouts : require\n"
11358 									  "\n"
11359 									  "layout(vertices = 1) out;\n"
11360 									  "\n"
11361 									  "layout (std140) buffer Block {\n"
11362 									  "    layout (offset = OFFSET) TYPE member;\n"
11363 									  "} block;\n"
11364 									  "\n"
11365 									  "in  vec4 vs_tcs[];\n"
11366 									  "out vec4 tcs_tes[];\n"
11367 									  "\n"
11368 									  "void main()\n"
11369 									  "{\n"
11370 									  "    if (TYPE(1) == block.member)\n"
11371 									  "    {\n"
11372 									  "        tcs_tes[gl_InvocationID] = vec4(1, 1, 1, 1);\n"
11373 									  "    }\n"
11374 									  "\n"
11375 									  "\n"
11376 									  "    tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
11377 									  "\n"
11378 									  "    gl_TessLevelOuter[0] = 1.0;\n"
11379 									  "    gl_TessLevelOuter[1] = 1.0;\n"
11380 									  "    gl_TessLevelOuter[2] = 1.0;\n"
11381 									  "    gl_TessLevelOuter[3] = 1.0;\n"
11382 									  "    gl_TessLevelInner[0] = 1.0;\n"
11383 									  "    gl_TessLevelInner[1] = 1.0;\n"
11384 									  "}\n"
11385 									  "\n";
11386 	static const GLchar* tes = "#version 430 core\n"
11387 							   "#extension GL_ARB_enhanced_layouts : require\n"
11388 							   "\n"
11389 							   "layout(isolines, point_mode) in;\n"
11390 							   "\n"
11391 							   "in  vec4 tcs_tes[];\n"
11392 							   "out vec4 tes_gs;\n"
11393 							   "\n"
11394 							   "void main()\n"
11395 							   "{\n"
11396 							   "    tes_gs = tcs_tes[0];\n"
11397 							   "}\n"
11398 							   "\n";
11399 	static const GLchar* tes_tested = "#version 430 core\n"
11400 									  "#extension GL_ARB_enhanced_layouts : require\n"
11401 									  "\n"
11402 									  "layout(isolines, point_mode) in;\n"
11403 									  "\n"
11404 									  "layout (std140) buffer Block {\n"
11405 									  "    layout (offset = OFFSET) TYPE member;\n"
11406 									  "} block;\n"
11407 									  "\n"
11408 									  "in  vec4 tcs_tes[];\n"
11409 									  "out vec4 tes_gs;\n"
11410 									  "\n"
11411 									  "void main()\n"
11412 									  "{\n"
11413 									  "    if (TYPE(1) == block.member)\n"
11414 									  "    {\n"
11415 									  "        tes_gs = vec4(1, 1, 1, 1);\n"
11416 									  "    }\n"
11417 									  "\n"
11418 									  "    tes_gs += tcs_tes[0];\n"
11419 									  "}\n"
11420 									  "\n";
11421 	static const GLchar* vs = "#version 430 core\n"
11422 							  "#extension GL_ARB_enhanced_layouts : require\n"
11423 							  "\n"
11424 							  "in  vec4 in_vs;\n"
11425 							  "out vec4 vs_tcs;\n"
11426 							  "\n"
11427 							  "void main()\n"
11428 							  "{\n"
11429 							  "    vs_tcs = in_vs;\n"
11430 							  "}\n"
11431 							  "\n";
11432 	static const GLchar* vs_tested = "#version 430 core\n"
11433 									 "#extension GL_ARB_enhanced_layouts : require\n"
11434 									 "\n"
11435 									 "layout (std140) buffer Block {\n"
11436 									 "    layout (offset = OFFSET) TYPE member;\n"
11437 									 "} block;\n"
11438 									 "\n"
11439 									 "in  vec4 in_vs;\n"
11440 									 "out vec4 vs_tcs;\n"
11441 									 "\n"
11442 									 "void main()\n"
11443 									 "{\n"
11444 									 "    if (TYPE(1) == block.member)\n"
11445 									 "    {\n"
11446 									 "        vs_tcs = vec4(1, 1, 1, 1);\n"
11447 									 "    }\n"
11448 									 "\n"
11449 									 "    vs_tcs += in_vs;\n"
11450 									 "}\n"
11451 									 "\n";
11452 
11453 	std::string source;
11454 	testCase&   test_case = m_test_cases[test_case_index];
11455 
11456 	if (test_case.m_stage == stage)
11457 	{
11458 		GLchar			   buffer[16];
11459 		const GLuint	   offset	= test_case.m_offset;
11460 		size_t			   position  = 0;
11461 		const Utils::Type& type		 = test_case.m_type;
11462 		const GLchar*	  type_name = type.GetGLSLTypeName();
11463 
11464 		sprintf(buffer, "%d", offset);
11465 
11466 		switch (stage)
11467 		{
11468 		case Utils::Shader::COMPUTE:
11469 			source = cs;
11470 			break;
11471 		case Utils::Shader::FRAGMENT:
11472 			source = fs_tested;
11473 			break;
11474 		case Utils::Shader::GEOMETRY:
11475 			source = gs_tested;
11476 			break;
11477 		case Utils::Shader::TESS_CTRL:
11478 			source = tcs_tested;
11479 			break;
11480 		case Utils::Shader::TESS_EVAL:
11481 			source = tes_tested;
11482 			break;
11483 		case Utils::Shader::VERTEX:
11484 			source = vs_tested;
11485 			break;
11486 		default:
11487 			TCU_FAIL("Invalid enum");
11488 		}
11489 
11490 		Utils::replaceToken("OFFSET", position, buffer, source);
11491 		Utils::replaceToken("TYPE", position, type_name, source);
11492 		Utils::replaceToken("TYPE", position, type_name, source);
11493 	}
11494 	else
11495 	{
11496 		switch (stage)
11497 		{
11498 		case Utils::Shader::FRAGMENT:
11499 			source = fs;
11500 			break;
11501 		case Utils::Shader::GEOMETRY:
11502 			source = gs;
11503 			break;
11504 		case Utils::Shader::TESS_CTRL:
11505 			source = tcs;
11506 			break;
11507 		case Utils::Shader::TESS_EVAL:
11508 			source = tes;
11509 			break;
11510 		case Utils::Shader::VERTEX:
11511 			source = vs;
11512 			break;
11513 		default:
11514 			TCU_FAIL("Invalid enum");
11515 		}
11516 	}
11517 
11518 	return source;
11519 }
11520 
11521 /** Checks if stage is supported
11522  *
11523  * @param stage Shader stage
11524  *
11525  * @return true if supported, false otherwise
11526  **/
11527 bool SSBMemberInvalidOffsetAlignmentTest::isStageSupported(Utils::Shader::STAGES stage)
11528 {
11529 	const Functions& gl					   = m_context.getRenderContext().getFunctions();
11530 	GLint			 max_supported_buffers = 0;
11531 	GLenum			 pname				   = 0;
11532 
11533 	switch (stage)
11534 	{
11535 	case Utils::Shader::COMPUTE:
11536 		pname = GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS;
11537 		break;
11538 	case Utils::Shader::FRAGMENT:
11539 		pname = GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS;
11540 		break;
11541 	case Utils::Shader::GEOMETRY:
11542 		pname = GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS;
11543 		break;
11544 	case Utils::Shader::TESS_CTRL:
11545 		pname = GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS;
11546 		break;
11547 	case Utils::Shader::TESS_EVAL:
11548 		pname = GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS;
11549 		break;
11550 	case Utils::Shader::VERTEX:
11551 		pname = GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS;
11552 		break;
11553 	default:
11554 		TCU_FAIL("Invalid enum");
11555 	}
11556 
11557 	gl.getIntegerv(pname, &max_supported_buffers);
11558 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
11559 
11560 	return 1 <= max_supported_buffers;
11561 }
11562 
11563 /** Constructor
11564  *
11565  * @param context Test framework context
11566  **/
11567 SSBMemberOverlappingOffsetsTest::SSBMemberOverlappingOffsetsTest(deqp::Context& context)
11568 	: UniformBlockMemberOverlappingOffsetsTest(
11569 		  context, "ssb_member_overlapping_offsets",
11570 		  "Test verifies that overlapping offsets qualifiers cause compilation failure")
11571 {
11572 	/* Nothing to be done here */
11573 }
11574 
11575 /** Source for given test case and stage
11576  *
11577  * @param test_case_index Index of test case
11578  * @param stage           Shader stage
11579  *
11580  * @return Shader source
11581  **/
11582 std::string SSBMemberOverlappingOffsetsTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
11583 {
11584 	static const GLchar* cs = "#version 430 core\n"
11585 							  "#extension GL_ARB_enhanced_layouts : require\n"
11586 							  "\n"
11587 							  "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
11588 							  "\n"
11589 							  "layout (std140) buffer Block {\n"
11590 							  "    layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11591 							  "    layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11592 							  "} block;\n"
11593 							  "\n"
11594 							  "writeonly uniform image2D uni_image;\n"
11595 							  "\n"
11596 							  "void main()\n"
11597 							  "{\n"
11598 							  "    vec4 result = vec4(1, 0, 0.5, 1);\n"
11599 							  "\n"
11600 							  "    if ((BOY_TYPE(1) == block.boy) ||\n"
11601 							  "        (MAN_TYPE(0) == block.man) )\n"
11602 							  "    {\n"
11603 							  "        result = vec4(1, 1, 1, 1);\n"
11604 							  "    }\n"
11605 							  "\n"
11606 							  "    imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
11607 							  "}\n"
11608 							  "\n";
11609 	static const GLchar* fs = "#version 430 core\n"
11610 							  "#extension GL_ARB_enhanced_layouts : require\n"
11611 							  "\n"
11612 							  "in  vec4 gs_fs;\n"
11613 							  "out vec4 fs_out;\n"
11614 							  "\n"
11615 							  "void main()\n"
11616 							  "{\n"
11617 							  "    fs_out = gs_fs;\n"
11618 							  "}\n"
11619 							  "\n";
11620 	static const GLchar* fs_tested = "#version 430 core\n"
11621 									 "#extension GL_ARB_enhanced_layouts : require\n"
11622 									 "\n"
11623 									 "layout (std140) buffer Block {\n"
11624 									 "    layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11625 									 "    layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11626 									 "} block;\n"
11627 									 "\n"
11628 									 "in  vec4 gs_fs;\n"
11629 									 "out vec4 fs_out;\n"
11630 									 "\n"
11631 									 "void main()\n"
11632 									 "{\n"
11633 									 "    if ((BOY_TYPE(1) == block.boy) ||\n"
11634 									 "        (MAN_TYPE(0) == block.man) )\n"
11635 									 "    {\n"
11636 									 "        fs_out = vec4(1, 1, 1, 1);\n"
11637 									 "    }\n"
11638 									 "\n"
11639 									 "    fs_out += gs_fs;\n"
11640 									 "}\n"
11641 									 "\n";
11642 	static const GLchar* gs = "#version 430 core\n"
11643 							  "#extension GL_ARB_enhanced_layouts : require\n"
11644 							  "\n"
11645 							  "layout(points)                           in;\n"
11646 							  "layout(triangle_strip, max_vertices = 4) out;\n"
11647 							  "\n"
11648 							  "in  vec4 tes_gs[];\n"
11649 							  "out vec4 gs_fs;\n"
11650 							  "\n"
11651 							  "void main()\n"
11652 							  "{\n"
11653 							  "    gs_fs = tes_gs[0];\n"
11654 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
11655 							  "    EmitVertex();\n"
11656 							  "    gs_fs = tes_gs[0];\n"
11657 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
11658 							  "    EmitVertex();\n"
11659 							  "    gs_fs = tes_gs[0];\n"
11660 							  "    gl_Position  = vec4(1, -1, 0, 1);\n"
11661 							  "    EmitVertex();\n"
11662 							  "    gs_fs = tes_gs[0];\n"
11663 							  "    gl_Position  = vec4(1, 1, 0, 1);\n"
11664 							  "    EmitVertex();\n"
11665 							  "}\n"
11666 							  "\n";
11667 	static const GLchar* gs_tested = "#version 430 core\n"
11668 									 "#extension GL_ARB_enhanced_layouts : require\n"
11669 									 "\n"
11670 									 "layout(points)                           in;\n"
11671 									 "layout(triangle_strip, max_vertices = 4) out;\n"
11672 									 "\n"
11673 									 "layout (std140) buffer Block {\n"
11674 									 "    layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11675 									 "    layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11676 									 "} block;\n"
11677 									 "\n"
11678 									 "in  vec4 tes_gs[];\n"
11679 									 "out vec4 gs_fs;\n"
11680 									 "\n"
11681 									 "void main()\n"
11682 									 "{\n"
11683 									 "    if ((BOY_TYPE(1) == block.boy) ||\n"
11684 									 "        (MAN_TYPE(0) == block.man) )\n"
11685 									 "    {\n"
11686 									 "        gs_fs = vec4(1, 1, 1, 1);\n"
11687 									 "    }\n"
11688 									 "\n"
11689 									 "    gs_fs += tes_gs[0];\n"
11690 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
11691 									 "    EmitVertex();\n"
11692 									 "    gs_fs += tes_gs[0];\n"
11693 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
11694 									 "    EmitVertex();\n"
11695 									 "    gs_fs += tes_gs[0];\n"
11696 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
11697 									 "    EmitVertex();\n"
11698 									 "    gs_fs += tes_gs[0];\n"
11699 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
11700 									 "    EmitVertex();\n"
11701 									 "}\n"
11702 									 "\n";
11703 	static const GLchar* tcs = "#version 430 core\n"
11704 							   "#extension GL_ARB_enhanced_layouts : require\n"
11705 							   "\n"
11706 							   "layout(vertices = 1) out;\n"
11707 							   "\n"
11708 							   "in  vec4 vs_tcs[];\n"
11709 							   "out vec4 tcs_tes[];\n"
11710 							   "\n"
11711 							   "void main()\n"
11712 							   "{\n"
11713 							   "\n"
11714 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
11715 							   "\n"
11716 							   "    gl_TessLevelOuter[0] = 1.0;\n"
11717 							   "    gl_TessLevelOuter[1] = 1.0;\n"
11718 							   "    gl_TessLevelOuter[2] = 1.0;\n"
11719 							   "    gl_TessLevelOuter[3] = 1.0;\n"
11720 							   "    gl_TessLevelInner[0] = 1.0;\n"
11721 							   "    gl_TessLevelInner[1] = 1.0;\n"
11722 							   "}\n"
11723 							   "\n";
11724 	static const GLchar* tcs_tested = "#version 430 core\n"
11725 									  "#extension GL_ARB_enhanced_layouts : require\n"
11726 									  "\n"
11727 									  "layout(vertices = 1) out;\n"
11728 									  "\n"
11729 									  "layout (std140) buffer Block {\n"
11730 									  "    layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11731 									  "    layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11732 									  "} block;\n"
11733 									  "\n"
11734 									  "in  vec4 vs_tcs[];\n"
11735 									  "out vec4 tcs_tes[];\n"
11736 									  "\n"
11737 									  "void main()\n"
11738 									  "{\n"
11739 									  "    if ((BOY_TYPE(1) == block.boy) ||\n"
11740 									  "        (MAN_TYPE(0) == block.man) )\n"
11741 									  "    {\n"
11742 									  "        tcs_tes[gl_InvocationID] = vec4(1, 1, 1, 1);\n"
11743 									  "    }\n"
11744 									  "\n"
11745 									  "\n"
11746 									  "    tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
11747 									  "\n"
11748 									  "    gl_TessLevelOuter[0] = 1.0;\n"
11749 									  "    gl_TessLevelOuter[1] = 1.0;\n"
11750 									  "    gl_TessLevelOuter[2] = 1.0;\n"
11751 									  "    gl_TessLevelOuter[3] = 1.0;\n"
11752 									  "    gl_TessLevelInner[0] = 1.0;\n"
11753 									  "    gl_TessLevelInner[1] = 1.0;\n"
11754 									  "}\n"
11755 									  "\n";
11756 	static const GLchar* tes = "#version 430 core\n"
11757 							   "#extension GL_ARB_enhanced_layouts : require\n"
11758 							   "\n"
11759 							   "layout(isolines, point_mode) in;\n"
11760 							   "\n"
11761 							   "in  vec4 tcs_tes[];\n"
11762 							   "out vec4 tes_gs;\n"
11763 							   "\n"
11764 							   "void main()\n"
11765 							   "{\n"
11766 							   "    tes_gs = tcs_tes[0];\n"
11767 							   "}\n"
11768 							   "\n";
11769 	static const GLchar* tes_tested = "#version 430 core\n"
11770 									  "#extension GL_ARB_enhanced_layouts : require\n"
11771 									  "\n"
11772 									  "layout(isolines, point_mode) in;\n"
11773 									  "\n"
11774 									  "layout (std140) buffer Block {\n"
11775 									  "    layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11776 									  "    layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11777 									  "} block;\n"
11778 									  "\n"
11779 									  "in  vec4 tcs_tes[];\n"
11780 									  "out vec4 tes_gs;\n"
11781 									  "\n"
11782 									  "void main()\n"
11783 									  "{\n"
11784 									  "    if ((BOY_TYPE(1) == block.boy) ||\n"
11785 									  "        (MAN_TYPE(0) == block.man) )\n"
11786 									  "    {\n"
11787 									  "        tes_gs = vec4(1, 1, 1, 1);\n"
11788 									  "    }\n"
11789 									  "\n"
11790 									  "    tes_gs += tcs_tes[0];\n"
11791 									  "}\n"
11792 									  "\n";
11793 	static const GLchar* vs = "#version 430 core\n"
11794 							  "#extension GL_ARB_enhanced_layouts : require\n"
11795 							  "\n"
11796 							  "in  vec4 in_vs;\n"
11797 							  "out vec4 vs_tcs;\n"
11798 							  "\n"
11799 							  "void main()\n"
11800 							  "{\n"
11801 							  "    vs_tcs = in_vs;\n"
11802 							  "}\n"
11803 							  "\n";
11804 	static const GLchar* vs_tested = "#version 430 core\n"
11805 									 "#extension GL_ARB_enhanced_layouts : require\n"
11806 									 "\n"
11807 									 "layout (std140) buffer Block {\n"
11808 									 "    layout (offset = BOY_OFFSET) BOY_TYPE boy;\n"
11809 									 "    layout (offset = MAN_OFFSET) MAN_TYPE man;\n"
11810 									 "} block;\n"
11811 									 "\n"
11812 									 "in  vec4 in_vs;\n"
11813 									 "out vec4 vs_tcs;\n"
11814 									 "\n"
11815 									 "void main()\n"
11816 									 "{\n"
11817 									 "    if ((BOY_TYPE(1) == block.boy) ||\n"
11818 									 "        (MAN_TYPE(0) == block.man) )\n"
11819 									 "    {\n"
11820 									 "        vs_tcs = vec4(1, 1, 1, 1);\n"
11821 									 "    }\n"
11822 									 "\n"
11823 									 "    vs_tcs += in_vs;\n"
11824 									 "}\n"
11825 									 "\n";
11826 
11827 	std::string source;
11828 	testCase&   test_case = m_test_cases[test_case_index];
11829 
11830 	if (test_case.m_stage == stage)
11831 	{
11832 		GLchar			   buffer[16];
11833 		const GLuint	   boy_offset	= test_case.m_boy_offset;
11834 		const Utils::Type& boy_type		 = test_case.m_boy_type;
11835 		const GLchar*	  boy_type_name = boy_type.GetGLSLTypeName();
11836 		const GLuint	   man_offset	= test_case.m_man_offset;
11837 		const Utils::Type& man_type		 = test_case.m_man_type;
11838 		const GLchar*	  man_type_name = man_type.GetGLSLTypeName();
11839 		size_t			   position		 = 0;
11840 
11841 		switch (stage)
11842 		{
11843 		case Utils::Shader::COMPUTE:
11844 			source = cs;
11845 			break;
11846 		case Utils::Shader::FRAGMENT:
11847 			source = fs_tested;
11848 			break;
11849 		case Utils::Shader::GEOMETRY:
11850 			source = gs_tested;
11851 			break;
11852 		case Utils::Shader::TESS_CTRL:
11853 			source = tcs_tested;
11854 			break;
11855 		case Utils::Shader::TESS_EVAL:
11856 			source = tes_tested;
11857 			break;
11858 		case Utils::Shader::VERTEX:
11859 			source = vs_tested;
11860 			break;
11861 		default:
11862 			TCU_FAIL("Invalid enum");
11863 		}
11864 
11865 		sprintf(buffer, "%d", boy_offset);
11866 		Utils::replaceToken("BOY_OFFSET", position, buffer, source);
11867 		Utils::replaceToken("BOY_TYPE", position, boy_type_name, source);
11868 		sprintf(buffer, "%d", man_offset);
11869 		Utils::replaceToken("MAN_OFFSET", position, buffer, source);
11870 		Utils::replaceToken("MAN_TYPE", position, man_type_name, source);
11871 		Utils::replaceToken("BOY_TYPE", position, boy_type_name, source);
11872 		Utils::replaceToken("MAN_TYPE", position, man_type_name, source);
11873 	}
11874 	else
11875 	{
11876 		switch (stage)
11877 		{
11878 		case Utils::Shader::FRAGMENT:
11879 			source = fs;
11880 			break;
11881 		case Utils::Shader::GEOMETRY:
11882 			source = gs;
11883 			break;
11884 		case Utils::Shader::TESS_CTRL:
11885 			source = tcs;
11886 			break;
11887 		case Utils::Shader::TESS_EVAL:
11888 			source = tes;
11889 			break;
11890 		case Utils::Shader::VERTEX:
11891 			source = vs;
11892 			break;
11893 		default:
11894 			TCU_FAIL("Invalid enum");
11895 		}
11896 	}
11897 
11898 	return source;
11899 }
11900 
11901 /** Checks if stage is supported
11902  *
11903  * @param stage Shader stage
11904  *
11905  * @return true if supported, false otherwise
11906  **/
11907 bool SSBMemberOverlappingOffsetsTest::isStageSupported(Utils::Shader::STAGES stage)
11908 {
11909 	const Functions& gl					   = m_context.getRenderContext().getFunctions();
11910 	GLint			 max_supported_buffers = 0;
11911 	GLenum			 pname				   = 0;
11912 
11913 	switch (stage)
11914 	{
11915 	case Utils::Shader::COMPUTE:
11916 		pname = GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS;
11917 		break;
11918 	case Utils::Shader::FRAGMENT:
11919 		pname = GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS;
11920 		break;
11921 	case Utils::Shader::GEOMETRY:
11922 		pname = GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS;
11923 		break;
11924 	case Utils::Shader::TESS_CTRL:
11925 		pname = GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS;
11926 		break;
11927 	case Utils::Shader::TESS_EVAL:
11928 		pname = GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS;
11929 		break;
11930 	case Utils::Shader::VERTEX:
11931 		pname = GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS;
11932 		break;
11933 	default:
11934 		TCU_FAIL("Invalid enum");
11935 	}
11936 
11937 	gl.getIntegerv(pname, &max_supported_buffers);
11938 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
11939 
11940 	return 1 <= max_supported_buffers;
11941 }
11942 
11943 /** Constructor
11944  *
11945  * @param context Test framework context
11946  **/
11947 SSBMemberAlignNonPowerOf2Test::SSBMemberAlignNonPowerOf2Test(deqp::Context& context)
11948 	: UniformBlockMemberAlignNonPowerOf2Test(context, "ssb_member_align_non_power_of_2",
11949 											 "Test verifies that align qualifier requires value that is a power of 2")
11950 {
11951 	/* Nothing to be done here */
11952 }
11953 
11954 /** Source for given test case and stage
11955  *
11956  * @param test_case_index Index of test case
11957  * @param stage           Shader stage
11958  *
11959  * @return Shader source
11960  **/
11961 std::string SSBMemberAlignNonPowerOf2Test::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
11962 {
11963 	static const GLchar* cs = "#version 430 core\n"
11964 							  "#extension GL_ARB_enhanced_layouts : require\n"
11965 							  "\n"
11966 							  "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
11967 							  "\n"
11968 							  "layout (std140) buffer Block {\n"
11969 							  "    vec4 boy;\n"
11970 							  "    layout (align = ALIGN) TYPE man;\n"
11971 							  "} block;\n"
11972 							  "\n"
11973 							  "writeonly uniform image2D uni_image;\n"
11974 							  "\n"
11975 							  "void main()\n"
11976 							  "{\n"
11977 							  "    vec4 result = vec4(1, 0, 0.5, 1);\n"
11978 							  "\n"
11979 							  "    if (TYPE(0) == block.man)\n"
11980 							  "    {\n"
11981 							  "        result = vec4(1, 1, 1, 1) - block.boy;\n"
11982 							  "    }\n"
11983 							  "\n"
11984 							  "    imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), result);\n"
11985 							  "}\n"
11986 							  "\n";
11987 	static const GLchar* fs = "#version 430 core\n"
11988 							  "#extension GL_ARB_enhanced_layouts : require\n"
11989 							  "\n"
11990 							  "in  vec4 gs_fs;\n"
11991 							  "out vec4 fs_out;\n"
11992 							  "\n"
11993 							  "void main()\n"
11994 							  "{\n"
11995 							  "    fs_out = gs_fs;\n"
11996 							  "}\n"
11997 							  "\n";
11998 	static const GLchar* fs_tested = "#version 430 core\n"
11999 									 "#extension GL_ARB_enhanced_layouts : require\n"
12000 									 "\n"
12001 									 "layout (std140) buffer Block {\n"
12002 									 "    vec4 boy;\n"
12003 									 "    layout (align = ALIGN) TYPE man;\n"
12004 									 "} block;\n"
12005 									 "\n"
12006 									 "in  vec4 gs_fs;\n"
12007 									 "out vec4 fs_out;\n"
12008 									 "\n"
12009 									 "void main()\n"
12010 									 "{\n"
12011 									 "    if (TYPE(0) == block.man)\n"
12012 									 "    {\n"
12013 									 "        fs_out = block.boy;\n"
12014 									 "    }\n"
12015 									 "\n"
12016 									 "    fs_out += gs_fs;\n"
12017 									 "}\n"
12018 									 "\n";
12019 	static const GLchar* gs = "#version 430 core\n"
12020 							  "#extension GL_ARB_enhanced_layouts : require\n"
12021 							  "\n"
12022 							  "layout(points)                           in;\n"
12023 							  "layout(triangle_strip, max_vertices = 4) out;\n"
12024 							  "\n"
12025 							  "in  vec4 tes_gs[];\n"
12026 							  "out vec4 gs_fs;\n"
12027 							  "\n"
12028 							  "void main()\n"
12029 							  "{\n"
12030 							  "    gs_fs = tes_gs[0];\n"
12031 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
12032 							  "    EmitVertex();\n"
12033 							  "    gs_fs = tes_gs[0];\n"
12034 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
12035 							  "    EmitVertex();\n"
12036 							  "    gs_fs = tes_gs[0];\n"
12037 							  "    gl_Position  = vec4(1, -1, 0, 1);\n"
12038 							  "    EmitVertex();\n"
12039 							  "    gs_fs = tes_gs[0];\n"
12040 							  "    gl_Position  = vec4(1, 1, 0, 1);\n"
12041 							  "    EmitVertex();\n"
12042 							  "}\n"
12043 							  "\n";
12044 	static const GLchar* gs_tested = "#version 430 core\n"
12045 									 "#extension GL_ARB_enhanced_layouts : require\n"
12046 									 "\n"
12047 									 "layout(points)                           in;\n"
12048 									 "layout(triangle_strip, max_vertices = 4) out;\n"
12049 									 "\n"
12050 									 "layout (std140) buffer Block {\n"
12051 									 "    vec4 boy;\n"
12052 									 "    layout (align = ALIGN) TYPE man;\n"
12053 									 "} block;\n"
12054 									 "\n"
12055 									 "in  vec4 tes_gs[];\n"
12056 									 "out vec4 gs_fs;\n"
12057 									 "\n"
12058 									 "void main()\n"
12059 									 "{\n"
12060 									 "    if (TYPE(0) == block.man)\n"
12061 									 "    {\n"
12062 									 "        gs_fs = block.boy;\n"
12063 									 "    }\n"
12064 									 "\n"
12065 									 "    gs_fs += tes_gs[0];\n"
12066 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
12067 									 "    EmitVertex();\n"
12068 									 "    gs_fs += tes_gs[0];\n"
12069 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
12070 									 "    EmitVertex();\n"
12071 									 "    gs_fs += tes_gs[0];\n"
12072 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
12073 									 "    EmitVertex();\n"
12074 									 "    gs_fs += tes_gs[0];\n"
12075 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
12076 									 "    EmitVertex();\n"
12077 									 "}\n"
12078 									 "\n";
12079 	static const GLchar* tcs = "#version 430 core\n"
12080 							   "#extension GL_ARB_enhanced_layouts : require\n"
12081 							   "\n"
12082 							   "layout(vertices = 1) out;\n"
12083 							   "\n"
12084 							   "in  vec4 vs_tcs[];\n"
12085 							   "out vec4 tcs_tes[];\n"
12086 							   "\n"
12087 							   "void main()\n"
12088 							   "{\n"
12089 							   "\n"
12090 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
12091 							   "\n"
12092 							   "    gl_TessLevelOuter[0] = 1.0;\n"
12093 							   "    gl_TessLevelOuter[1] = 1.0;\n"
12094 							   "    gl_TessLevelOuter[2] = 1.0;\n"
12095 							   "    gl_TessLevelOuter[3] = 1.0;\n"
12096 							   "    gl_TessLevelInner[0] = 1.0;\n"
12097 							   "    gl_TessLevelInner[1] = 1.0;\n"
12098 							   "}\n"
12099 							   "\n";
12100 	static const GLchar* tcs_tested = "#version 430 core\n"
12101 									  "#extension GL_ARB_enhanced_layouts : require\n"
12102 									  "\n"
12103 									  "layout(vertices = 1) out;\n"
12104 									  "\n"
12105 									  "layout (std140) buffer Block {\n"
12106 									  "    vec4 boy;\n"
12107 									  "    layout (align = ALIGN) TYPE man;\n"
12108 									  "} block;\n"
12109 									  "\n"
12110 									  "in  vec4 vs_tcs[];\n"
12111 									  "out vec4 tcs_tes[];\n"
12112 									  "\n"
12113 									  "void main()\n"
12114 									  "{\n"
12115 									  "    if (TYPE(0) == block.man)\n"
12116 									  "    {\n"
12117 									  "        tcs_tes[gl_InvocationID] = block.boy;\n"
12118 									  "    }\n"
12119 									  "\n"
12120 									  "\n"
12121 									  "    tcs_tes[gl_InvocationID] += vs_tcs[gl_InvocationID];\n"
12122 									  "\n"
12123 									  "    gl_TessLevelOuter[0] = 1.0;\n"
12124 									  "    gl_TessLevelOuter[1] = 1.0;\n"
12125 									  "    gl_TessLevelOuter[2] = 1.0;\n"
12126 									  "    gl_TessLevelOuter[3] = 1.0;\n"
12127 									  "    gl_TessLevelInner[0] = 1.0;\n"
12128 									  "    gl_TessLevelInner[1] = 1.0;\n"
12129 									  "}\n"
12130 									  "\n";
12131 	static const GLchar* tes = "#version 430 core\n"
12132 							   "#extension GL_ARB_enhanced_layouts : require\n"
12133 							   "\n"
12134 							   "layout(isolines, point_mode) in;\n"
12135 							   "\n"
12136 							   "in  vec4 tcs_tes[];\n"
12137 							   "out vec4 tes_gs;\n"
12138 							   "\n"
12139 							   "void main()\n"
12140 							   "{\n"
12141 							   "    tes_gs = tcs_tes[0];\n"
12142 							   "}\n"
12143 							   "\n";
12144 	static const GLchar* tes_tested = "#version 430 core\n"
12145 									  "#extension GL_ARB_enhanced_layouts : require\n"
12146 									  "\n"
12147 									  "layout(isolines, point_mode) in;\n"
12148 									  "\n"
12149 									  "layout (std140) buffer Block {\n"
12150 									  "    vec4 boy;\n"
12151 									  "    layout (align = ALIGN) TYPE man;\n"
12152 									  "} block;\n"
12153 									  "\n"
12154 									  "in  vec4 tcs_tes[];\n"
12155 									  "out vec4 tes_gs;\n"
12156 									  "\n"
12157 									  "void main()\n"
12158 									  "{\n"
12159 									  "    if (TYPE(0) == block.man)\n"
12160 									  "    {\n"
12161 									  "        tes_gs = block.boy;\n"
12162 									  "    }\n"
12163 									  "\n"
12164 									  "    tes_gs += tcs_tes[0];\n"
12165 									  "}\n"
12166 									  "\n";
12167 	static const GLchar* vs = "#version 430 core\n"
12168 							  "#extension GL_ARB_enhanced_layouts : require\n"
12169 							  "\n"
12170 							  "in  vec4 in_vs;\n"
12171 							  "out vec4 vs_tcs;\n"
12172 							  "\n"
12173 							  "void main()\n"
12174 							  "{\n"
12175 							  "    vs_tcs = in_vs;\n"
12176 							  "}\n"
12177 							  "\n";
12178 	static const GLchar* vs_tested = "#version 430 core\n"
12179 									 "#extension GL_ARB_enhanced_layouts : require\n"
12180 									 "\n"
12181 									 "layout (std140) buffer Block {\n"
12182 									 "    vec4 boy;\n"
12183 									 "    layout (align = ALIGN) TYPE man;\n"
12184 									 "} block;\n"
12185 									 "\n"
12186 									 "in  vec4 in_vs;\n"
12187 									 "out vec4 vs_tcs;\n"
12188 									 "\n"
12189 									 "void main()\n"
12190 									 "{\n"
12191 									 "    if (TYPE(0) == block.man)\n"
12192 									 "    {\n"
12193 									 "        vs_tcs = block.boy;\n"
12194 									 "    }\n"
12195 									 "\n"
12196 									 "    vs_tcs += in_vs;\n"
12197 									 "}\n"
12198 									 "\n";
12199 
12200 	std::string source;
12201 	testCase&   test_case = m_test_cases[test_case_index];
12202 
12203 	if (test_case.m_stage == stage)
12204 	{
12205 		GLchar			   buffer[16];
12206 		const GLuint	   alignment = test_case.m_alignment;
12207 		const Utils::Type& type		 = test_case.m_type;
12208 		const GLchar*	  type_name = type.GetGLSLTypeName();
12209 		size_t			   position  = 0;
12210 
12211 		switch (stage)
12212 		{
12213 		case Utils::Shader::COMPUTE:
12214 			source = cs;
12215 			break;
12216 		case Utils::Shader::FRAGMENT:
12217 			source = fs_tested;
12218 			break;
12219 		case Utils::Shader::GEOMETRY:
12220 			source = gs_tested;
12221 			break;
12222 		case Utils::Shader::TESS_CTRL:
12223 			source = tcs_tested;
12224 			break;
12225 		case Utils::Shader::TESS_EVAL:
12226 			source = tes_tested;
12227 			break;
12228 		case Utils::Shader::VERTEX:
12229 			source = vs_tested;
12230 			break;
12231 		default:
12232 			TCU_FAIL("Invalid enum");
12233 		}
12234 
12235 		sprintf(buffer, "%d", alignment);
12236 		Utils::replaceToken("ALIGN", position, buffer, source);
12237 		Utils::replaceToken("TYPE", position, type_name, source);
12238 		Utils::replaceToken("TYPE", position, type_name, source);
12239 	}
12240 	else
12241 	{
12242 		switch (stage)
12243 		{
12244 		case Utils::Shader::FRAGMENT:
12245 			source = fs;
12246 			break;
12247 		case Utils::Shader::GEOMETRY:
12248 			source = gs;
12249 			break;
12250 		case Utils::Shader::TESS_CTRL:
12251 			source = tcs;
12252 			break;
12253 		case Utils::Shader::TESS_EVAL:
12254 			source = tes;
12255 			break;
12256 		case Utils::Shader::VERTEX:
12257 			source = vs;
12258 			break;
12259 		default:
12260 			TCU_FAIL("Invalid enum");
12261 		}
12262 	}
12263 
12264 	return source;
12265 }
12266 
12267 /** Checks if stage is supported
12268  *
12269  * @param stage Shader stage
12270  *
12271  * @return true if supported, false otherwise
12272  **/
12273 bool SSBMemberAlignNonPowerOf2Test::isStageSupported(Utils::Shader::STAGES stage)
12274 {
12275 	const Functions& gl					   = m_context.getRenderContext().getFunctions();
12276 	GLint			 max_supported_buffers = 0;
12277 	GLenum			 pname				   = 0;
12278 
12279 	switch (stage)
12280 	{
12281 	case Utils::Shader::COMPUTE:
12282 		pname = GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS;
12283 		break;
12284 	case Utils::Shader::FRAGMENT:
12285 		pname = GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS;
12286 		break;
12287 	case Utils::Shader::GEOMETRY:
12288 		pname = GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS;
12289 		break;
12290 	case Utils::Shader::TESS_CTRL:
12291 		pname = GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS;
12292 		break;
12293 	case Utils::Shader::TESS_EVAL:
12294 		pname = GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS;
12295 		break;
12296 	case Utils::Shader::VERTEX:
12297 		pname = GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS;
12298 		break;
12299 	default:
12300 		TCU_FAIL("Invalid enum");
12301 	}
12302 
12303 	gl.getIntegerv(pname, &max_supported_buffers);
12304 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
12305 
12306 	return 1 <= max_supported_buffers;
12307 }
12308 
12309 /** Constructor
12310  *
12311  * @param context Test framework context
12312  **/
12313 SSBAlignmentTest::SSBAlignmentTest(deqp::Context& context)
12314 	: TextureTestBase(context, "ssb_alignment", "Test verifies offset and alignment of ssb buffer")
12315 {
12316 }
12317 
12318 /** Get interface of program
12319  *
12320  * @param ignored
12321  * @param program_interface Interface of program
12322  * @param varying_passthrough Collection of connections between in and out variables
12323  **/
12324 void SSBAlignmentTest::getProgramInterface(GLuint /* test_case_index */, Utils::ProgramInterface& program_interface,
12325 										   Utils::VaryingPassthrough& varying_passthrough)
12326 {
12327 	static const Utils::Type vec4 = Utils::Type::vec4;
12328 
12329 #if WRKARD_UNIFORMBLOCKALIGNMENT
12330 
12331 	static const GLuint block_align = 16;
12332 
12333 #else /* WRKARD_UNIFORMBLOCKALIGNMENT */
12334 
12335 	static const GLuint block_align = 64;
12336 
12337 #endif /* WRKARD_UNIFORMBLOCKALIGNMENT */
12338 
12339 	static const GLuint fifth_align = 16;
12340 	static const GLuint vec4_stride = 16;
12341 	static const GLuint data_stride = vec4_stride * 2; /* one vec4 + one scalar aligned to 16 */
12342 
12343 	const GLuint first_offset  = 0;																		/* vec4 at 0 */
12344 	const GLuint second_offset = Utils::Type::GetActualOffset(first_offset + vec4_stride, block_align); /* Data at 32 */
12345 	const GLuint third_offset =
12346 		Utils::Type::GetActualOffset(second_offset + data_stride, block_align); /* Data[2] at 64 */
12347 	const GLuint fourth_offset =
12348 		Utils::Type::GetActualOffset(third_offset + data_stride * 2, block_align); /* vec4[3] at 96 */
12349 	const GLuint fifth_offset =
12350 		Utils::Type::GetActualOffset(fourth_offset + vec4_stride * 3, fifth_align); /* vec4[2] at 160 */
12351 	const GLuint sixth_offset =
12352 		Utils::Type::GetActualOffset(fifth_offset + vec4_stride * 2, block_align); /* Data at 192 */
12353 
12354 	Utils::Interface* structure = program_interface.Structure("Data");
12355 
12356 	structure->Member("vector", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::vec4,
12357 					  false /* normalized */, 0 /* n_array_elements */, Utils::Type::vec4.GetSize(), 0 /* offset */);
12358 
12359 	structure->Member("scalar", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::_float,
12360 					  false /* normalized */, 0 /* n_array_elements */, Utils::Type::_float.GetSize(),
12361 					  Utils::Type::vec4.GetSize() /* offset */);
12362 
12363 	/* Prepare Block */
12364 	Utils::Interface* vs_buf_Block = program_interface.Block("vs_buf_Block");
12365 
12366 	vs_buf_Block->Member("first", "", 0 /* expected_component */, 0 /* expected_location */, Utils::Type::vec4,
12367 						 false /* normalized */, 0 /* n_array_elements */, vec4_stride, first_offset /* offset */);
12368 
12369 	vs_buf_Block->Member("second", "", 0 /* expected_component */, 0 /* expected_location */, structure,
12370 						 0 /* n_array_elements */, data_stride, second_offset);
12371 
12372 	vs_buf_Block->Member("third", "", 0 /* expected_component */, 0 /* expected_location */, structure,
12373 						 2 /* n_array_elements */, data_stride, third_offset);
12374 
12375 	vs_buf_Block->Member("fourth", "", 0 /* expected_component */, 0 /* expected_location */, vec4,
12376 						 false /* normalized */, 3 /* n_array_elements */, vec4_stride, fourth_offset);
12377 
12378 	vs_buf_Block->Member("fifth", "layout(align = 16)", 0 /* expected_component */, 0 /* expected_location */, vec4,
12379 						 false /* normalized */, 2 /* n_array_elements */, vec4_stride, fifth_offset);
12380 
12381 	vs_buf_Block->Member("sixth", "", 0 /* expected_component */, 0 /* expected_location */, structure,
12382 						 0 /* n_array_elements */, data_stride, sixth_offset);
12383 
12384 	const GLuint stride = calculateStride(*vs_buf_Block);
12385 	m_data.resize(stride);
12386 	generateData(*vs_buf_Block, 0, m_data);
12387 
12388 	Utils::ShaderInterface& vs_si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
12389 
12390 /* Add uniform BLOCK */
12391 #if WRKARD_UNIFORMBLOCKALIGNMENT
12392 	vs_si.SSB("vs_buf_block", "layout (std140, binding = BINDING)", 0, 0, vs_buf_Block, 0,
12393 			  static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
12394 #else  /* WRKARD_UNIFORMBLOCKALIGNMENT */
12395 	vs_si.SSB("vs_buf_block", "layout (std140, binding = BINDING, align = 64)", 0, 0, vs_buf_Block, 0,
12396 			  static_cast<GLuint>(m_data.size()), 0, &m_data[0], m_data.size());
12397 #endif /* WRKARD_UNIFORMBLOCKALIGNMENT */
12398 
12399 	program_interface.CloneVertexInterface(varying_passthrough);
12400 }
12401 
12402 /** Selects if "draw" stages are relevant for test
12403  *
12404  * @param ignored
12405  *
12406  * @return true if all stages support shader storage buffers, false otherwise
12407  **/
12408 bool SSBAlignmentTest::isDrawRelevant(GLuint /* test_case_index */)
12409 {
12410 	const Functions& gl					   = m_context.getRenderContext().getFunctions();
12411 	GLint			 gs_supported_buffers  = 0;
12412 	GLint			 tcs_supported_buffers = 0;
12413 	GLint			 tes_supported_buffers = 0;
12414 	GLint			 vs_supported_buffers  = 0;
12415 
12416 	gl.getIntegerv(GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS, &gs_supported_buffers);
12417 	gl.getIntegerv(GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS, &tcs_supported_buffers);
12418 	gl.getIntegerv(GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS, &tes_supported_buffers);
12419 	gl.getIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &vs_supported_buffers);
12420 
12421 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
12422 
12423 	return ((1 <= gs_supported_buffers) && (1 <= tcs_supported_buffers) && (1 <= tes_supported_buffers) &&
12424 			(1 <= vs_supported_buffers));
12425 }
12426 
12427 /** Constructor
12428  *
12429  * @param context Test framework context
12430  **/
12431 VaryingLocationsTest::VaryingLocationsTest(deqp::Context& context)
12432 	: TextureTestBase(context, "varying_locations", "Test verifies that input and output locations are respected")
12433 {
12434 }
12435 
12436 /** Constructor
12437  *
12438  * @param context          Test context
12439  * @param test_name        Name of test
12440  * @param test_description Description of test
12441  **/
12442 VaryingLocationsTest::VaryingLocationsTest(deqp::Context& context, const glw::GLchar* test_name,
12443 										   const glw::GLchar* test_description)
12444 	: TextureTestBase(context, test_name, test_description)
12445 {
12446 }
12447 
12448 /** Get interface of program
12449  *
12450  * @param test_case_index     Test case
12451  * @param program_interface   Interface of program
12452  * @param varying_passthrough Collection of connections between in and out variables
12453  **/
12454 void VaryingLocationsTest::getProgramInterface(GLuint test_case_index, Utils::ProgramInterface& program_interface,
12455 											   Utils::VaryingPassthrough& varying_passthrough)
12456 {
12457 	const Utils::Type type = getType(test_case_index);
12458 
12459 	m_first_data = type.GenerateDataPacked();
12460 	m_last_data  = type.GenerateDataPacked();
12461 
12462 	prepareShaderStage(Utils::Shader::FRAGMENT, type, program_interface, varying_passthrough);
12463 	prepareShaderStage(Utils::Shader::GEOMETRY, type, program_interface, varying_passthrough);
12464 	prepareShaderStage(Utils::Shader::TESS_CTRL, type, program_interface, varying_passthrough);
12465 	prepareShaderStage(Utils::Shader::TESS_EVAL, type, program_interface, varying_passthrough);
12466 	prepareShaderStage(Utils::Shader::VERTEX, type, program_interface, varying_passthrough);
12467 }
12468 
12469 /** Get type name
12470  *
12471  * @param test_case_index Index of test case
12472  *
12473  * @return Name of type test in test_case_index
12474  **/
12475 std::string VaryingLocationsTest::getTestCaseName(glw::GLuint test_case_index)
12476 {
12477 	return getTypeName(test_case_index);
12478 }
12479 
12480 /** Returns number of types to test
12481  *
12482  * @return Number of types, 34
12483  **/
12484 glw::GLuint VaryingLocationsTest::getTestCaseNumber()
12485 {
12486 	return getTypesNumber();
12487 }
12488 
12489 /** Selects if "compute" stage is relevant for test
12490  *
12491  * @param ignored
12492  *
12493  * @return false
12494  **/
12495 bool VaryingLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
12496 {
12497 	return false;
12498 }
12499 
12500 /**
12501  *
12502  *
12503  **/
12504 std::string VaryingLocationsTest::prepareGlobals(GLint last_in_loc, GLint last_out_loc)
12505 {
12506 	GLchar		buffer[16];
12507 	std::string globals = "const uint first_input_location  = 0u;\n"
12508 						  "const uint first_output_location = 0u;\n"
12509 						  "const uint last_input_location   = LAST_INPUTu;\n"
12510 						  "const uint last_output_location  = LAST_OUTPUTu;\n";
12511 	size_t position = 100; /* Skip first part */
12512 
12513 	sprintf(buffer, "%d", last_in_loc);
12514 	Utils::replaceToken("LAST_INPUT", position, buffer, globals);
12515 
12516 	sprintf(buffer, "%d", last_out_loc);
12517 	Utils::replaceToken("LAST_OUTPUT", position, buffer, globals);
12518 
12519 	return globals;
12520 }
12521 
12522 /**
12523  *
12524  **/
12525 void VaryingLocationsTest::prepareShaderStage(Utils::Shader::STAGES stage, const Utils::Type& type,
12526 											  Utils::ProgramInterface&   program_interface,
12527 											  Utils::VaryingPassthrough& varying_passthrough)
12528 {
12529 	const GLuint array_length  = 1;
12530 	const GLuint first_in_loc  = 0;
12531 	const GLuint first_out_loc = 0;
12532 	const GLuint last_in_loc   = getLastInputLocation(stage, type, array_length, false);
12533 	size_t		 position	  = 0;
12534 
12535 	const GLchar* prefix_in = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::VARYING_INPUT);
12536 
12537 	const GLchar* prefix_out = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::VARYING_OUTPUT);
12538 
12539 	const GLchar* qual_first_in  = "layout (location = first_input_location)";
12540 	const GLchar* qual_first_out = "layout (location = first_output_location)";
12541 	const GLchar* qual_last_in   = "layout (location = last_input_location)";
12542 	const GLchar* qual_last_out  = "layout (location = last_output_location)";
12543 
12544 	Utils::ShaderInterface& si		  = program_interface.GetShaderInterface(stage);
12545 	const GLuint			type_size = type.GetSize();
12546 
12547 	std::string first_in_name  = "PREFIXfirst";
12548 	std::string first_out_name = "PREFIXfirst";
12549 	std::string last_in_name   = "PREFIXlast";
12550 	std::string last_out_name  = "PREFIXlast";
12551 
12552 	Utils::replaceToken("PREFIX", position, prefix_in, first_in_name);
12553 	position = 0;
12554 	Utils::replaceToken("PREFIX", position, prefix_out, first_out_name);
12555 	position = 0;
12556 	Utils::replaceToken("PREFIX", position, prefix_in, last_in_name);
12557 	position = 0;
12558 	Utils::replaceToken("PREFIX", position, prefix_out, last_out_name);
12559 
12560 	if (Utils::Shader::FRAGMENT == stage)
12561 	{
12562 		qual_first_in = "layout (location = first_input_location) flat";
12563 		qual_last_in  = "layout (location = last_input_location)  flat";
12564 	}
12565 	if (Utils::Shader::GEOMETRY == stage)
12566 	{
12567 		qual_first_out = "layout (location = first_output_location) flat";
12568 		qual_last_out  = "layout (location = last_output_location)  flat";
12569 	}
12570 
12571 	Utils::Variable* first_in = si.Input(
12572 		first_in_name.c_str(), qual_first_in /* qualifiers */, 0 /* expected_componenet */,
12573 		first_in_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */, 0u /* n_array_elements */,
12574 		0u /* stride */, 0u /* offset */, (GLvoid*)&m_first_data[0] /* data */, m_first_data.size() /* data_size */);
12575 
12576 	Utils::Variable* last_in =
12577 		si.Input(last_in_name.c_str(), qual_last_in /* qualifiers */, 0 /* expected_componenet */,
12578 				 last_in_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12579 				 0u /* n_array_elements */, 0u /* stride */, type_size /* offset */,
12580 				 (GLvoid*)&m_last_data[0] /* data */, m_last_data.size() /* data_size */);
12581 
12582 	if (Utils::Shader::FRAGMENT != stage)
12583 	{
12584 		const GLuint last_out_loc = getLastOutputLocation(stage, type, array_length, false);
12585 
12586 		Utils::Variable* first_out =
12587 			si.Output(first_out_name.c_str(), qual_first_out /* qualifiers */, 0 /* expected_componenet */,
12588 					  first_out_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12589 					  0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)&m_first_data[0] /* data */,
12590 					  m_first_data.size() /* data_size */);
12591 
12592 		Utils::Variable* last_out = si.Output(
12593 			last_out_name.c_str(), qual_last_out /* qualifiers */, 0 /* expected_componenet */,
12594 			last_out_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */, 0u /* n_array_elements */,
12595 			0u /* stride */, 0u /* offset */, (GLvoid*)&m_last_data[0] /* data */, m_last_data.size() /* data_size */);
12596 
12597 		si.m_globals = prepareGlobals(last_in_loc, last_out_loc);
12598 
12599 		varying_passthrough.Add(stage, first_in, first_out);
12600 		varying_passthrough.Add(stage, last_in, last_out);
12601 	}
12602 	else
12603 	{
12604 		/* No outputs for fragment shader, so last_output_location can be 0 */
12605 		si.m_globals = prepareGlobals(last_in_loc, 0);
12606 	}
12607 }
12608 
12609 /** This test should be run with separable programs
12610  *
12611  * @param ignored
12612  *
12613  * @return true
12614  **/
12615 bool VaryingLocationsTest::useMonolithicProgram(GLuint /* test_case_index */)
12616 {
12617 	return false;
12618 }
12619 
12620 /* Constants used by VertexAttribLocationsTest */
12621 const GLuint VertexAttribLocationsTest::m_base_vertex   = 4;
12622 const GLuint VertexAttribLocationsTest::m_base_instance = 2;
12623 const GLuint VertexAttribLocationsTest::m_loc_vertex	= 2;
12624 const GLuint VertexAttribLocationsTest::m_loc_instance  = 5;
12625 const GLuint VertexAttribLocationsTest::m_n_instances   = 4;
12626 
12627 /** Constructor
12628  *
12629  * @param context Test framework context
12630  **/
12631 VertexAttribLocationsTest::VertexAttribLocationsTest(deqp::Context& context)
12632 	: TextureTestBase(context, "vertex_attrib_locations",
12633 					  "Test verifies that attribute locations are respected by drawing operations")
12634 {
12635 }
12636 
12637 /** Execute proper draw command for test case
12638  *
12639  * @param test_case_index Index of test case
12640  **/
12641 void VertexAttribLocationsTest::executeDrawCall(GLuint test_case_index)
12642 {
12643 	const Functions& gl = m_context.getRenderContext().getFunctions();
12644 
12645 	switch (test_case_index)
12646 	{
12647 	case DRAWARRAYS:
12648 		gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
12649 		GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
12650 		break;
12651 	case DRAWARRAYSINSTANCED:
12652 		gl.drawArraysInstanced(GL_PATCHES, 0 /* first */, 1 /* count */, m_n_instances);
12653 		GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArraysInstanced");
12654 		break;
12655 	case DRAWELEMENTS:
12656 		gl.drawElements(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL);
12657 		GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElements");
12658 		break;
12659 	case DRAWELEMENTSBASEVERTEX:
12660 		gl.drawElementsBaseVertex(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL, m_base_vertex);
12661 		GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsBaseVertex");
12662 		break;
12663 	case DRAWELEMENTSINSTANCED:
12664 		gl.drawElementsInstanced(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL, m_n_instances);
12665 		GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsInstanced");
12666 		break;
12667 	case DRAWELEMENTSINSTANCEDBASEINSTANCE:
12668 		gl.drawElementsInstancedBaseInstance(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL, m_n_instances,
12669 											 m_base_instance);
12670 		GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsInstancedBaseInstance");
12671 		break;
12672 	case DRAWELEMENTSINSTANCEDBASEVERTEX:
12673 		gl.drawElementsInstancedBaseVertex(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL, m_n_instances,
12674 										   m_base_vertex);
12675 		GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsInstancedBaseVertex");
12676 		break;
12677 	case DRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCE:
12678 		gl.drawElementsInstancedBaseVertexBaseInstance(GL_PATCHES, 1 /* count */, GL_UNSIGNED_BYTE, DE_NULL,
12679 													   m_n_instances, m_base_vertex, m_base_instance);
12680 		GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsInstancedBaseVertexBaseInstance");
12681 		break;
12682 	default:
12683 		TCU_FAIL("Invalid enum");
12684 	}
12685 }
12686 
12687 /** Get interface of program
12688  *
12689  * @param ignored
12690  * @param program_interface   Interface of program
12691  * @param ignored
12692  **/
12693 void VertexAttribLocationsTest::getProgramInterface(GLuint /* test_case_index */,
12694 													Utils::ProgramInterface& program_interface,
12695 													Utils::VaryingPassthrough& /* varying_passthrough */)
12696 {
12697 	Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
12698 
12699 	/* Globals */
12700 	si.m_globals = "const uint vertex_index_location   = 2;\n"
12701 				   "const uint instance_index_location = 5;\n";
12702 
12703 	/* Attributes */
12704 	si.Input("vertex_index" /* name */, "layout (location = vertex_index_location)" /* qualifiers */,
12705 			 0 /* expected_componenet */, m_loc_vertex /* expected_location */, Utils::Type::uint /* type */,
12706 			 GL_FALSE /* normalized */, 0u /* n_array_elements */, 16 /* stride */, 0u /* offset */,
12707 			 (GLvoid*)0 /* data */, 0 /* data_size */);
12708 	si.Input("instance_index" /* name */, "layout (location = instance_index_location)" /* qualifiers */,
12709 			 0 /* expected_componenet */, m_loc_instance /* expected_location */, Utils::Type::uint /* type */,
12710 			 GL_FALSE /* normalized */, 0u /* n_array_elements */, 16 /* stride */, 16u /* offset */,
12711 			 (GLvoid*)0 /* data */, 0 /* data_size */);
12712 }
12713 
12714 /** Get name of test case
12715  *
12716  * @param test_case_index Index of test case
12717  *
12718  * @return Name of test case
12719  **/
12720 std::string VertexAttribLocationsTest::getTestCaseName(glw::GLuint test_case_index)
12721 {
12722 	std::string result;
12723 
12724 	switch (test_case_index)
12725 	{
12726 	case DRAWARRAYS:
12727 		result = "DrawArrays";
12728 		break;
12729 	case DRAWARRAYSINSTANCED:
12730 		result = "DrawArraysInstanced";
12731 		break;
12732 	case DRAWELEMENTS:
12733 		result = "DrawElements";
12734 		break;
12735 	case DRAWELEMENTSBASEVERTEX:
12736 		result = "DrawElementsBaseVertex";
12737 		break;
12738 	case DRAWELEMENTSINSTANCED:
12739 		result = "DrawElementsInstanced";
12740 		break;
12741 	case DRAWELEMENTSINSTANCEDBASEINSTANCE:
12742 		result = "DrawElementsInstancedBaseInstance";
12743 		break;
12744 	case DRAWELEMENTSINSTANCEDBASEVERTEX:
12745 		result = "DrawElementsInstancedBaseVertex";
12746 		break;
12747 	case DRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCE:
12748 		result = "DrawElementsInstancedBaseVertexBaseInstance";
12749 		break;
12750 	default:
12751 		TCU_FAIL("Invalid enum");
12752 	}
12753 
12754 	return result;
12755 }
12756 
12757 /** Get number of test cases
12758  *
12759  * @return Number of test cases
12760  **/
12761 GLuint VertexAttribLocationsTest::getTestCaseNumber()
12762 {
12763 	return TESTCASES_MAX;
12764 }
12765 
12766 /** Prepare code snippet that will verify in and uniform variables
12767  *
12768  * @param ignored
12769  * @param ignored
12770  * @param stage   Shader stage
12771  *
12772  * @return Code that verify variables
12773  **/
12774 std::string VertexAttribLocationsTest::getVerificationSnippet(GLuint /* test_case_index */,
12775 															  Utils::ProgramInterface& /* program_interface */,
12776 															  Utils::Shader::STAGES stage)
12777 {
12778 	std::string verification;
12779 
12780 	if (Utils::Shader::VERTEX == stage)
12781 	{
12782 
12783 #if DEBUG_VERTEX_ATTRIB_LOCATIONS_TEST_VARIABLE
12784 
12785 		verification = "if (gl_InstanceID != instance_index)\n"
12786 					   "    {\n"
12787 					   "        result = 12u;\n"
12788 					   "    }\n"
12789 					   "    else if (gl_VertexID != vertex_index)\n"
12790 					   "    {\n"
12791 					   "        result = 11u;\n"
12792 					   "    }\n";
12793 
12794 #else
12795 
12796 		verification = "if ((gl_VertexID   != vertex_index)  ||\n"
12797 					   "        (gl_InstanceID != instance_index) )\n"
12798 					   "    {\n"
12799 					   "        result = 0u;\n"
12800 					   "    }\n";
12801 
12802 #endif
12803 	}
12804 	else
12805 	{
12806 		verification = "";
12807 	}
12808 
12809 	return verification;
12810 }
12811 
12812 /** Selects if "compute" stage is relevant for test
12813  *
12814  * @param ignored
12815  *
12816  * @return false
12817  **/
12818 bool VertexAttribLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
12819 {
12820 	return false;
12821 }
12822 
12823 /** Prepare attributes, vertex array object and array buffer
12824  *
12825  * @param ignored
12826  * @param ignored Interface of program
12827  * @param buffer  Array buffer
12828  * @param vao     Vertex array object
12829  **/
12830 void VertexAttribLocationsTest::prepareAttributes(GLuint test_case_index /* test_case_index */,
12831 												  Utils::ProgramInterface& /* program_interface */,
12832 												  Utils::Buffer& buffer, Utils::VertexArray& vao)
12833 {
12834 	static const GLuint vertex_index_data[8]   = { 0, 1, 2, 3, 4, 5, 6, 7 };
12835 	static const GLuint instance_index_data[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
12836 
12837 	std::vector<GLuint> buffer_data;
12838 	buffer_data.resize(8 + 8); /* vertex_index_data + instance_index_data */
12839 
12840 	GLubyte* ptr = (GLubyte*)&buffer_data[0];
12841 
12842 	/*
12843 	 When case index >=2, the test calls glDrawElement*(), such as glDrawElementsBaseVertex(), glDrawElementsInstanced(), glDrawElementsInstancedBaseInstance() and so on,
12844 	 So we need to change the buffer type as GL_ELEMENT_ARRAY_BUFFER
12845 	 */
12846 	if (test_case_index >= 2)
12847 	{
12848 		buffer.m_buffer = Utils::Buffer::Element;
12849 	}
12850 	vao.Bind();
12851 	buffer.Bind();
12852 
12853 	vao.Attribute(m_loc_vertex /* vertex_index */, Utils::Type::uint, 0 /* array_elements */, false /* normalized */,
12854 				  0 /* stride */, 0 /* offset */);
12855 
12856 	vao.Attribute(m_loc_instance /* instance_index */, Utils::Type::uint, 0 /* array_elements */,
12857 				  false /* normalized */, 0 /* stride */, (GLvoid*)sizeof(vertex_index_data) /* offset */);
12858 	// when test_case_index is 5 or 7, the draw call is glDrawElementsInstancedBaseInstance, glDrawElementsInstancedBaseVertexBaseInstance
12859 	// the instancecount is 4, the baseinstance is 2, the divisor should be set 2
12860 	bool isBaseInstanced = (test_case_index == DRAWELEMENTSINSTANCEDBASEINSTANCE ||
12861 							test_case_index == DRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCE);
12862 	vao.Divisor(m_context.getRenderContext().getFunctions() /* gl */, m_loc_instance /* instance_index */,
12863 				isBaseInstanced ? 2 : 1 /* divisor. 1 - advance once per instance */);
12864 
12865 	memcpy(ptr + 0, vertex_index_data, sizeof(vertex_index_data));
12866 	memcpy(ptr + sizeof(vertex_index_data), instance_index_data, sizeof(instance_index_data));
12867 
12868 	buffer.Data(Utils::Buffer::StaticDraw, buffer_data.size() * sizeof(GLuint), ptr);
12869 }
12870 
12871 /** This test should be run with separable programs
12872  *
12873  * @param ignored
12874  *
12875  * @return true
12876  **/
12877 bool VertexAttribLocationsTest::useMonolithicProgram(GLuint /* test_case_index */)
12878 {
12879 	return false;
12880 }
12881 
12882 /** Constructor
12883  *
12884  * @param context Test framework context
12885  **/
12886 VaryingArrayLocationsTest::VaryingArrayLocationsTest(deqp::Context& context)
12887 	: VaryingLocationsTest(context, "varying_array_locations",
12888 						   "Test verifies that input and output locations are respected for arrays")
12889 {
12890 }
12891 
12892 /**
12893  *
12894  **/
12895 void VaryingArrayLocationsTest::prepareShaderStage(Utils::Shader::STAGES stage, const Utils::Type& type,
12896 												   Utils::ProgramInterface&   program_interface,
12897 												   Utils::VaryingPassthrough& varying_passthrough)
12898 {
12899 	const GLuint array_length  = 1u;
12900 	const GLuint first_in_loc  = 0;
12901 	const GLuint first_out_loc = 0;
12902 	const GLuint last_in_loc   = getLastInputLocation(stage, type, array_length, false);
12903 	size_t		 position	  = 0;
12904 
12905 	const GLchar* prefix_in = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::VARYING_INPUT);
12906 
12907 	const GLchar* prefix_out = Utils::ProgramInterface::GetStagePrefix(stage, Utils::Variable::VARYING_OUTPUT);
12908 
12909 	const GLchar* qual_first_in  = "layout (location = first_input_location)";
12910 	const GLchar* qual_first_out = "layout (location = first_output_location)";
12911 	const GLchar* qual_last_in   = "layout (location = last_input_location)";
12912 	const GLchar* qual_last_out  = "layout (location = last_output_location)";
12913 
12914 	Utils::ShaderInterface& si		  = program_interface.GetShaderInterface(stage);
12915 	const GLuint			type_size = type.GetSize();
12916 
12917 	std::string first_in_name  = "PREFIXfirst";
12918 	std::string first_out_name = "PREFIXfirst";
12919 	std::string last_in_name   = "PREFIXlast";
12920 	std::string last_out_name  = "PREFIXlast";
12921 
12922 	Utils::replaceToken("PREFIX", position, prefix_in, first_in_name);
12923 	position = 0;
12924 	Utils::replaceToken("PREFIX", position, prefix_out, first_out_name);
12925 	position = 0;
12926 	Utils::replaceToken("PREFIX", position, prefix_in, last_in_name);
12927 	position = 0;
12928 	Utils::replaceToken("PREFIX", position, prefix_out, last_out_name);
12929 
12930 	if (Utils::Shader::FRAGMENT == stage)
12931 	{
12932 		qual_first_in = "layout (location = first_input_location) flat";
12933 		qual_last_in  = "layout (location = last_input_location)  flat";
12934 	}
12935 	if (Utils::Shader::GEOMETRY == stage)
12936 	{
12937 		qual_first_out = "layout (location = first_output_location) flat";
12938 		qual_last_out  = "layout (location = last_output_location)  flat";
12939 	}
12940 
12941 	Utils::Variable* first_in =
12942 		si.Input(first_in_name.c_str(), qual_first_in /* qualifiers */, 0 /* expected_componenet */,
12943 				 first_in_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12944 				 array_length /* n_array_elements */, 0u /* stride */, 0u /* offset */,
12945 				 (GLvoid*)&m_first_data[0] /* data */, m_first_data.size() /* data_size */);
12946 
12947 	Utils::Variable* last_in =
12948 		si.Input(last_in_name.c_str(), qual_last_in /* qualifiers */, 0 /* expected_componenet */,
12949 				 last_in_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12950 				 array_length /* n_array_elements */, 0u /* stride */, type_size /* offset */,
12951 				 (GLvoid*)&m_last_data[0] /* data */, m_last_data.size() /* data_size */);
12952 
12953 	if (Utils::Shader::FRAGMENT != stage)
12954 	{
12955 		const GLuint last_out_loc = getLastOutputLocation(stage, type, array_length, false);
12956 
12957 		Utils::Variable* first_out =
12958 			si.Output(first_out_name.c_str(), qual_first_out /* qualifiers */, 0 /* expected_componenet */,
12959 					  first_out_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12960 					  array_length /* n_array_elements */, 0u /* stride */, 0u /* offset */,
12961 					  (GLvoid*)&m_first_data[0] /* data */, m_first_data.size() /* data_size */);
12962 
12963 		Utils::Variable* last_out =
12964 			si.Output(last_out_name.c_str(), qual_last_out /* qualifiers */, 0 /* expected_componenet */,
12965 					  last_out_loc /* expected_location */, type /* type */, GL_FALSE /* normalized */,
12966 					  array_length /* n_array_elements */, 0u /* stride */, 0u /* offset */,
12967 					  (GLvoid*)&m_last_data[0] /* data */, m_last_data.size() /* data_size */);
12968 
12969 		si.m_globals = prepareGlobals(last_in_loc, last_out_loc);
12970 
12971 		varying_passthrough.Add(stage, first_in, first_out);
12972 		varying_passthrough.Add(stage, last_in, last_out);
12973 	}
12974 	else
12975 	{
12976 		/* No outputs for fragment shader, so last_output_location can be 0 */
12977 		si.m_globals = prepareGlobals(last_in_loc, 0);
12978 	}
12979 }
12980 
12981 /** Constructor
12982  *
12983  * @param context Test framework context
12984  **/
12985 VaryingStructureLocationsTest::VaryingStructureLocationsTest(deqp::Context& context)
12986 	: TextureTestBase(context, "varying_structure_locations",
12987 					  "Test verifies that locations are respected when structures are used as in and out ")
12988 {
12989 }
12990 
12991 /** Prepare code snippet that will pass in variables to out variables
12992  *
12993  * @param ignored
12994  * @param varying_passthrough Collection of connections between in and out variables
12995  * @param stage               Shader stage
12996  *
12997  * @return Code that pass in variables to next stage
12998  **/
12999 std::string VaryingStructureLocationsTest::getPassSnippet(GLuint /* test_case_index */,
13000 														  Utils::VaryingPassthrough& varying_passthrough,
13001 														  Utils::Shader::STAGES		 stage)
13002 {
13003 	std::string result;
13004 
13005 	if (Utils::Shader::VERTEX != stage)
13006 	{
13007 		result = TextureTestBase::getPassSnippet(0, varying_passthrough, stage);
13008 	}
13009 	else
13010 	{
13011 		result = "    vs_tcs_output[0].single   = vs_in_single[0];\n"
13012 				 "    vs_tcs_output[0].array[0] = vs_in_array[0];\n";
13013 	}
13014 
13015 	return result;
13016 }
13017 
13018 /** Get interface of program
13019  *
13020  * @param test_case_index     Test case
13021  * @param program_interface   Interface of program
13022  * @param varying_passthrough Collection of connections between in and out variables
13023  **/
13024 void VaryingStructureLocationsTest::getProgramInterface(GLuint					   test_case_index,
13025 														Utils::ProgramInterface&   program_interface,
13026 														Utils::VaryingPassthrough& varying_passthrough)
13027 {
13028 	Utils::ShaderInterface& si   = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
13029 	const Utils::Type		type = getType(test_case_index);
13030 
13031 	/* Prepare data */
13032 	// We should call GenerateDataPacked() to generate data, which can make sure the data in shader is correct
13033 	m_single_data = type.GenerateDataPacked();
13034 	m_array_data  = type.GenerateDataPacked();
13035 
13036 	m_data.resize(m_single_data.size() + m_array_data.size());
13037 	GLubyte* ptr = (GLubyte*)&m_data[0];
13038 	memcpy(ptr, &m_single_data[0], m_single_data.size());
13039 	memcpy(ptr + m_single_data.size(), &m_array_data[0], m_array_data.size());
13040 
13041 	Utils::Interface* structure = program_interface.Structure("Data");
13042 
13043 	structure->Member("single", "" /* qualifiers */, 0 /* component */, 0 /* location */, type, false /* normalized */,
13044 					  0u /* n_array_elements */, 0u /* stride */, 0u /* offset */);
13045 
13046 	// the second struct member 's location should not be 0, it is based on by how many the locations the first struct member consumed.
13047 	structure->Member("array", "" /* qualifiers */, 0 /* component */, type.GetLocations() /* location */, type,
13048 					  false /* normalized */, 1u /* n_array_elements */, 0u /* stride */, type.GetSize() /* offset */);
13049 
13050 	si.Input("vs_in_single", "layout (location = 0)", 0 /* component */, 0 /* location */, type, false /* normalized */,
13051 			 1u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)&m_single_data[0] /* data */,
13052 			 m_single_data.size() /* data_size */);
13053 
13054 	si.Input("vs_in_array", "layout (location = 8)", 0 /* component */, 8 /* location */, type, false /* normalized */,
13055 			 1u /* n_array_elements */, 0u /* stride */, type.GetSize() /* offset */,
13056 			 (GLvoid*)&m_array_data[0] /* data */, m_array_data.size() /* data_size */);
13057 
13058 	si.Output("vs_tcs_output", "layout (location = 0)", 0 /* component */, 0 /* location */, structure,
13059 			  1u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)&m_data[0] /* data */,
13060 			  m_data.size() /* data_size */);
13061 
13062 	program_interface.CloneVertexInterface(varying_passthrough);
13063 }
13064 
13065 /** Get type name
13066  *
13067  * @param test_case_index Index of test case
13068  *
13069  * @return Name of type test in test_case_index
13070  **/
13071 std::string VaryingStructureLocationsTest::getTestCaseName(glw::GLuint test_case_index)
13072 {
13073 	return getTypeName(test_case_index);
13074 }
13075 
13076 /** Returns number of types to test
13077  *
13078  * @return Number of types, 34
13079  **/
13080 glw::GLuint VaryingStructureLocationsTest::getTestCaseNumber()
13081 {
13082 	return getTypesNumber();
13083 }
13084 
13085 /** Selects if "compute" stage is relevant for test
13086  *
13087  * @param ignored
13088  *
13089  * @return false
13090  **/
13091 bool VaryingStructureLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
13092 {
13093 	return false;
13094 }
13095 
13096 /** This test should be run with separable programs
13097  *
13098  * @param ignored
13099  *
13100  * @return true
13101  **/
13102 bool VaryingStructureLocationsTest::useMonolithicProgram(GLuint /* test_case_index */)
13103 {
13104 	return false;
13105 }
13106 
13107 /** Constructor
13108  *
13109  * @param context          Test context
13110  * @param test_name        Name of test
13111  * @param test_description Description of test
13112  **/
13113 VaryingStructureMemberLocationTest::VaryingStructureMemberLocationTest(deqp::Context& context)
13114 	: NegativeTestBase(context, "varying_structure_member_location",
13115 					   "Test verifies that compiler does not allow location qualifier on member of structure")
13116 {
13117 }
13118 
13119 /** Source for given test case and stage
13120  *
13121  * @param test_case_index Index of test case
13122  * @param stage           Shader stage
13123  *
13124  * @return Shader source
13125  **/
13126 std::string VaryingStructureMemberLocationTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
13127 {
13128 	static const GLchar* struct_definition = "struct Data {\n"
13129 											 "    vec4 gohan;\n"
13130 #if DEBUG_NEG_REMOVE_ERROR
13131 											 "    /* layout (location = 4) */ vec4 goten;\n"
13132 #else
13133 											 "    layout (location = 4) vec4 goten;\n"
13134 #endif /* DEBUG_NEG_REMOVE_ERROR */
13135 											 "};\n";
13136 	static const GLchar* input_use  = "    result += data.gohan + data.goten;\n";
13137 	static const GLchar* input_var  = "in Data dataARRAY;\n";
13138 	static const GLchar* output_var = "out Data dataARRAY;\n";
13139 	static const GLchar* output_use = "    dataINDEX.gohan = result / 2;\n"
13140 									  "    dataINDEX.goten = result / 4 - dataINDEX.gohan;\n";
13141 	static const GLchar* fs = "#version 430 core\n"
13142 							  "#extension GL_ARB_enhanced_layouts : require\n"
13143 							  "\n"
13144 							  "in  vec4 gs_fs;\n"
13145 							  "out vec4 fs_out;\n"
13146 							  "\n"
13147 							  "void main()\n"
13148 							  "{\n"
13149 							  "    fs_out = gs_fs;\n"
13150 							  "}\n"
13151 							  "\n";
13152 	static const GLchar* fs_tested = "#version 430 core\n"
13153 									 "#extension GL_ARB_enhanced_layouts : require\n"
13154 									 "\n"
13155 									 "STRUCT_DEFINITION"
13156 									 "\n"
13157 									 "VARIABLE_DEFINITION"
13158 									 "\n"
13159 									 "in  vec4 gs_fs;\n"
13160 									 "out vec4 fs_out;\n"
13161 									 "\n"
13162 									 "void main()\n"
13163 									 "{\n"
13164 									 "    vec4 result = gs_fs;\n"
13165 									 "\n"
13166 									 "VARIABLE_USE"
13167 									 "\n"
13168 									 "    fs_out += result;\n"
13169 									 "}\n"
13170 									 "\n";
13171 	static const GLchar* gs = "#version 430 core\n"
13172 							  "#extension GL_ARB_enhanced_layouts : require\n"
13173 							  "\n"
13174 							  "layout(points)                           in;\n"
13175 							  "layout(triangle_strip, max_vertices = 4) out;\n"
13176 							  "\n"
13177 							  "in  vec4 tes_gs[];\n"
13178 							  "out vec4 gs_fs;\n"
13179 							  "\n"
13180 							  "void main()\n"
13181 							  "{\n"
13182 							  "    gs_fs = tes_gs[0];\n"
13183 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
13184 							  "    EmitVertex();\n"
13185 							  "    gs_fs = tes_gs[0];\n"
13186 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
13187 							  "    EmitVertex();\n"
13188 							  "    gs_fs = tes_gs[0];\n"
13189 							  "    gl_Position  = vec4(1, -1, 0, 1);\n"
13190 							  "    EmitVertex();\n"
13191 							  "    gs_fs = tes_gs[0];\n"
13192 							  "    gl_Position  = vec4(1, 1, 0, 1);\n"
13193 							  "    EmitVertex();\n"
13194 							  "}\n"
13195 							  "\n";
13196 	static const GLchar* gs_tested = "#version 430 core\n"
13197 									 "#extension GL_ARB_enhanced_layouts : require\n"
13198 									 "\n"
13199 									 "layout(points)                           in;\n"
13200 									 "layout(triangle_strip, max_vertices = 4) out;\n"
13201 									 "\n"
13202 									 "STRUCT_DEFINITION"
13203 									 "\n"
13204 									 "VARIABLE_DEFINITION"
13205 									 "\n"
13206 									 "in  vec4 tes_gs[];\n"
13207 									 "out vec4 gs_fs;\n"
13208 									 "\n"
13209 									 "void main()\n"
13210 									 "{\n"
13211 									 "    vec4 result = tes_gs[0];\n"
13212 									 "\n"
13213 									 "VARIABLE_USE"
13214 									 "\n"
13215 									 "    gs_fs = result;\n"
13216 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
13217 									 "    EmitVertex();\n"
13218 									 "    gs_fs = result;\n"
13219 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
13220 									 "    EmitVertex();\n"
13221 									 "    gs_fs = result;\n"
13222 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
13223 									 "    EmitVertex();\n"
13224 									 "    gs_fs = result;\n"
13225 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
13226 									 "    EmitVertex();\n"
13227 									 "}\n"
13228 									 "\n";
13229 	static const GLchar* tcs = "#version 430 core\n"
13230 							   "#extension GL_ARB_enhanced_layouts : require\n"
13231 							   "\n"
13232 							   "layout(vertices = 1) out;\n"
13233 							   "\n"
13234 							   "in  vec4 vs_tcs[];\n"
13235 							   "out vec4 tcs_tes[];\n"
13236 							   "\n"
13237 							   "void main()\n"
13238 							   "{\n"
13239 							   "\n"
13240 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
13241 							   "\n"
13242 							   "    gl_TessLevelOuter[0] = 1.0;\n"
13243 							   "    gl_TessLevelOuter[1] = 1.0;\n"
13244 							   "    gl_TessLevelOuter[2] = 1.0;\n"
13245 							   "    gl_TessLevelOuter[3] = 1.0;\n"
13246 							   "    gl_TessLevelInner[0] = 1.0;\n"
13247 							   "    gl_TessLevelInner[1] = 1.0;\n"
13248 							   "}\n"
13249 							   "\n";
13250 	static const GLchar* tcs_tested = "#version 430 core\n"
13251 									  "#extension GL_ARB_enhanced_layouts : require\n"
13252 									  "\n"
13253 									  "layout(vertices = 1) out;\n"
13254 									  "\n"
13255 									  "STRUCT_DEFINITION"
13256 									  "\n"
13257 									  "VARIABLE_DEFINITION"
13258 									  "\n"
13259 									  "in  vec4 vs_tcs[];\n"
13260 									  "out vec4 tcs_tes[];\n"
13261 									  "\n"
13262 									  "void main()\n"
13263 									  "{\n"
13264 									  "    vec4 result = vs_tcs[gl_InvocationID];\n"
13265 									  "\n"
13266 									  "VARIABLE_USE"
13267 									  "\n"
13268 									  "    tcs_tes[gl_InvocationID] = result;\n"
13269 									  "\n"
13270 									  "    gl_TessLevelOuter[0] = 1.0;\n"
13271 									  "    gl_TessLevelOuter[1] = 1.0;\n"
13272 									  "    gl_TessLevelOuter[2] = 1.0;\n"
13273 									  "    gl_TessLevelOuter[3] = 1.0;\n"
13274 									  "    gl_TessLevelInner[0] = 1.0;\n"
13275 									  "    gl_TessLevelInner[1] = 1.0;\n"
13276 									  "}\n"
13277 									  "\n";
13278 	static const GLchar* tes = "#version 430 core\n"
13279 							   "#extension GL_ARB_enhanced_layouts : require\n"
13280 							   "\n"
13281 							   "layout(isolines, point_mode) in;\n"
13282 							   "\n"
13283 							   "in  vec4 tcs_tes[];\n"
13284 							   "out vec4 tes_gs;\n"
13285 							   "\n"
13286 							   "void main()\n"
13287 							   "{\n"
13288 							   "    tes_gs = tcs_tes[0];\n"
13289 							   "}\n"
13290 							   "\n";
13291 	static const GLchar* tes_tested = "#version 430 core\n"
13292 									  "#extension GL_ARB_enhanced_layouts : require\n"
13293 									  "\n"
13294 									  "layout(isolines, point_mode) in;\n"
13295 									  "\n"
13296 									  "STRUCT_DEFINITION"
13297 									  "\n"
13298 									  "VARIABLE_DEFINITION"
13299 									  "\n"
13300 									  "in  vec4 tcs_tes[];\n"
13301 									  "out vec4 tes_gs;\n"
13302 									  "\n"
13303 									  "void main()\n"
13304 									  "{\n"
13305 									  "    vec4 result = tcs_tes[0];\n"
13306 									  "\n"
13307 									  "VARIABLE_USE"
13308 									  "\n"
13309 									  "    tes_gs += result;\n"
13310 									  "}\n"
13311 									  "\n";
13312 	static const GLchar* vs = "#version 430 core\n"
13313 							  "#extension GL_ARB_enhanced_layouts : require\n"
13314 							  "\n"
13315 							  "in  vec4 in_vs;\n"
13316 							  "out vec4 vs_tcs;\n"
13317 							  "\n"
13318 							  "void main()\n"
13319 							  "{\n"
13320 							  "    vs_tcs = in_vs;\n"
13321 							  "}\n"
13322 							  "\n";
13323 	static const GLchar* vs_tested = "#version 430 core\n"
13324 									 "#extension GL_ARB_enhanced_layouts : require\n"
13325 									 "\n"
13326 									 "STRUCT_DEFINITION"
13327 									 "\n"
13328 									 "VARIABLE_DEFINITION"
13329 									 "\n"
13330 									 "in  vec4 in_vs;\n"
13331 									 "out vec4 vs_tcs;\n"
13332 									 "\n"
13333 									 "void main()\n"
13334 									 "{\n"
13335 									 "    vec4 result = in_vs;\n"
13336 									 "\n"
13337 									 "VARIABLE_USE"
13338 									 "\n"
13339 									 "    vs_tcs += result;\n"
13340 									 "}\n"
13341 									 "\n";
13342 
13343 	std::string   source;
13344 	testCase&	 test_case		 = m_test_cases[test_case_index];
13345 	const GLchar* var_definition  = input_var;
13346 	const GLchar* var_use		  = Utils::Shader::VERTEX == test_case.m_stage ? input_use : "\n";
13347 	const GLchar* array			  = "";
13348 	const GLchar* index			  = "";
13349 
13350 	if (!test_case.m_is_input)
13351 	{
13352 		var_definition = output_var;
13353 		var_use		   = output_use;
13354 	}
13355 
13356 	if (test_case.m_stage == stage)
13357 	{
13358 		size_t position = 0;
13359 		size_t temp		= 0;
13360 
13361 		switch (stage)
13362 		{
13363 		case Utils::Shader::FRAGMENT:
13364 			source = fs_tested;
13365 			break;
13366 		case Utils::Shader::GEOMETRY:
13367 			source = gs_tested;
13368 			array  = test_case.m_is_input ? "[]" : "";
13369 			index  = test_case.m_is_input ? "[0]" : "";
13370 			break;
13371 		case Utils::Shader::TESS_CTRL:
13372 			source = tcs_tested;
13373 			array  = "[]";
13374 			index  = "[gl_InvocationID]";
13375 			break;
13376 		case Utils::Shader::TESS_EVAL:
13377 			source = tes_tested;
13378 			array  = test_case.m_is_input ? "[]" : "";
13379 			index  = test_case.m_is_input ? "[0]" : "";
13380 			break;
13381 		case Utils::Shader::VERTEX:
13382 			source = vs_tested;
13383 			break;
13384 		default:
13385 			TCU_FAIL("Invalid enum");
13386 		}
13387 
13388 		Utils::replaceToken("STRUCT_DEFINITION", position, struct_definition, source);
13389 		temp = position;
13390 		Utils::replaceToken("VARIABLE_DEFINITION", position, var_definition, source);
13391 		position = temp;
13392 		Utils::replaceToken("ARRAY", position, array, source);
13393 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
13394 
13395 		Utils::replaceAllTokens("INDEX", index, source);
13396 	}
13397 	else
13398 	{
13399 		switch (stage)
13400 		{
13401 		case Utils::Shader::FRAGMENT:
13402 			source = fs;
13403 			break;
13404 		case Utils::Shader::GEOMETRY:
13405 			source = gs;
13406 			break;
13407 		case Utils::Shader::TESS_CTRL:
13408 			source = tcs;
13409 			break;
13410 		case Utils::Shader::TESS_EVAL:
13411 			source = tes;
13412 			break;
13413 		case Utils::Shader::VERTEX:
13414 			source = vs;
13415 			break;
13416 		default:
13417 			TCU_FAIL("Invalid enum");
13418 		}
13419 	}
13420 
13421 	return source;
13422 }
13423 
13424 /** Get description of test case
13425  *
13426  * @param test_case_index Index of test case
13427  *
13428  * @return Test case description
13429  **/
13430 std::string VaryingStructureMemberLocationTest::getTestCaseName(GLuint test_case_index)
13431 {
13432 	std::stringstream stream;
13433 	testCase&		  test_case = m_test_cases[test_case_index];
13434 
13435 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", direction: ";
13436 
13437 	if (true == test_case.m_is_input)
13438 	{
13439 		stream << "input";
13440 	}
13441 	else
13442 	{
13443 		stream << "output";
13444 	}
13445 
13446 	return stream.str();
13447 }
13448 
13449 /** Get number of test cases
13450  *
13451  * @return Number of test cases
13452  **/
13453 GLuint VaryingStructureMemberLocationTest::getTestCaseNumber()
13454 {
13455 	return static_cast<GLuint>(m_test_cases.size());
13456 }
13457 
13458 /** Selects if "compute" stage is relevant for test
13459  *
13460  * @param ignored
13461  *
13462  * @return false
13463  **/
13464 bool VaryingStructureMemberLocationTest::isComputeRelevant(GLuint /* test_case_index */)
13465 {
13466 	return false;
13467 }
13468 
13469 /** Prepare all test cases
13470  *
13471  **/
13472 void VaryingStructureMemberLocationTest::testInit()
13473 {
13474 	for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
13475 	{
13476 		if (Utils::Shader::COMPUTE == stage)
13477 		{
13478 			continue;
13479 		}
13480 
13481 		testCase test_case_in  = { true, (Utils::Shader::STAGES)stage };
13482 		testCase test_case_out = { false, (Utils::Shader::STAGES)stage };
13483 
13484 		/* It is a compile-time error to declare a struct as a VS input */
13485 		if (Utils::Shader::VERTEX != stage)
13486 		{
13487 			m_test_cases.push_back(test_case_in);
13488 		}
13489 
13490 		if (Utils::Shader::FRAGMENT != stage)
13491 		{
13492 			m_test_cases.push_back(test_case_out);
13493 		}
13494 	}
13495 }
13496 
13497 /** Constructor
13498  *
13499  * @param context Test framework context
13500  **/
13501 VaryingBlockLocationsTest::VaryingBlockLocationsTest(deqp::Context& context)
13502 	: TextureTestBase(context, "varying_block_locations",
13503 					  "Test verifies that locations are respected when blocks are used as in and out ")
13504 {
13505 }
13506 
13507 /** Prepare code snippet that will pass in variables to out variables
13508  *
13509  * @param ignored
13510  * @param varying_passthrough Collection of connections between in and out variables
13511  * @param stage               Shader stage
13512  *
13513  * @return Code that pass in variables to next stage
13514  **/
13515 std::string VaryingBlockLocationsTest::getPassSnippet(GLuint /* test_case_index */,
13516 													  Utils::VaryingPassthrough& varying_passthrough,
13517 													  Utils::Shader::STAGES		 stage)
13518 {
13519 	std::string result;
13520 
13521 	if (Utils::Shader::VERTEX != stage)
13522 	{
13523 		result = TextureTestBase::getPassSnippet(0, varying_passthrough, stage);
13524 	}
13525 	else
13526 	{
13527 		result = "vs_tcs_block.third  = vs_in_third;\n"
13528 				 "    vs_tcs_block.fourth = vs_in_fourth;\n"
13529 				 "    vs_tcs_block.fifth  = vs_in_fifth;\n";
13530 	}
13531 
13532 	return result;
13533 }
13534 
13535 /** Get interface of program
13536  *
13537  * @param ignored
13538  * @param program_interface   Interface of program
13539  * @param varying_passthrough Collection of connections between in and out variables
13540  **/
13541 void VaryingBlockLocationsTest::getProgramInterface(GLuint /* test_case_index */,
13542 													Utils::ProgramInterface&   program_interface,
13543 													Utils::VaryingPassthrough& varying_passthrough)
13544 {
13545 	Utils::ShaderInterface& si   = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
13546 	const Utils::Type		vec4 = Utils::Type::vec4;
13547 
13548 	/* Prepare data */
13549 	m_third_data  = vec4.GenerateData();
13550 	m_fourth_data = vec4.GenerateData();
13551 	m_fifth_data  = vec4.GenerateData();
13552 
13553 	/* Memory layout is different from location layout */
13554 	const GLuint fifth_offset  = 0u;
13555 	const GLuint third_offset  = static_cast<GLuint>(fifth_offset + m_fifth_data.size());
13556 	const GLuint fourth_offset = static_cast<GLuint>(third_offset + m_fourth_data.size());
13557 
13558 	m_data.resize(fourth_offset + m_fourth_data.size());
13559 	GLubyte* ptr = (GLubyte*)&m_data[0];
13560 	memcpy(ptr + third_offset, &m_third_data[0], m_third_data.size());
13561 	memcpy(ptr + fourth_offset, &m_fourth_data[0], m_fourth_data.size());
13562 	memcpy(ptr + fifth_offset, &m_fifth_data[0], m_fifth_data.size());
13563 
13564 	Utils::Interface* block = program_interface.Block("vs_tcs_Block");
13565 
13566 	block->Member("fifth", "" /* qualifiers */, 0 /* component */, 4 /* location */, vec4, false /* normalized */,
13567 				  0u /* n_array_elements */, 0u /* stride */, fifth_offset /* offset */);
13568 
13569 	block->Member("third", "layout (location = 2)" /* qualifiers */, 0 /* component */, 2 /* location */, vec4,
13570 				  false /* normalized */, 0u /* n_array_elements */, 0u /* stride */, third_offset /* offset */);
13571 
13572 	block->Member("fourth", "" /* qualifiers */, 0 /* component */, 3 /* location */, vec4, false /* normalized */,
13573 				  0u /* n_array_elements */, 0u /* stride */, fourth_offset /* offset */);
13574 
13575 	si.Output("vs_tcs_block", "layout (location = 4)", 0 /* component */, 4 /* location */, block,
13576 			  0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)&m_data[0] /* data */,
13577 			  m_data.size() /* data_size */);
13578 
13579 	si.Input("vs_in_third", "layout (location = 0)", 0 /* component */, 0 /* location */, vec4, false /* normalized */,
13580 			 0u /* n_array_elements */, 0u /* stride */, third_offset /* offset */,
13581 			 (GLvoid*)&m_third_data[0] /* data */, m_third_data.size() /* data_size */);
13582 
13583 	si.Input("vs_in_fourth", "layout (location = 1)", 0 /* component */, 1 /* location */, vec4, false /* normalized */,
13584 			 0u /* n_array_elements */, 0u /* stride */, fourth_offset /* offset */,
13585 			 (GLvoid*)&m_fourth_data[0] /* data */, m_fourth_data.size() /* data_size */);
13586 
13587 	si.Input("vs_in_fifth", "layout (location = 2)", 0 /* component */, 2 /* location */, vec4, false /* normalized */,
13588 			 0u /* n_array_elements */, 0u /* stride */, fifth_offset /* offset */,
13589 			 (GLvoid*)&m_fifth_data[0] /* data */, m_fifth_data.size() /* data_size */);
13590 
13591 	program_interface.CloneVertexInterface(varying_passthrough);
13592 }
13593 
13594 /** Selects if "compute" stage is relevant for test
13595  *
13596  * @param ignored
13597  *
13598  * @return false
13599  **/
13600 bool VaryingBlockLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
13601 {
13602 	return false;
13603 }
13604 
13605 /** This test should be run with separable programs
13606  *
13607  * @param ignored
13608  *
13609  * @return true
13610  **/
13611 bool VaryingBlockLocationsTest::useMonolithicProgram(GLuint /* test_case_index */)
13612 {
13613 	return false;
13614 }
13615 
13616 /** Constructor
13617  *
13618  * @param context Test framework context
13619  **/
13620 VaryingBlockMemberLocationsTest::VaryingBlockMemberLocationsTest(deqp::Context& context)
13621 	: NegativeTestBase(
13622 		  context, "varying_block_member_locations",
13623 		  "Test verifies that compilation error is reported when not all members of block are qualified with location")
13624 {
13625 }
13626 
13627 /** Source for given test case and stage
13628  *
13629  * @param test_case_index Index of test case
13630  * @param stage           Shader stage
13631  *
13632  * @return Shader source
13633  **/
13634 std::string VaryingBlockMemberLocationsTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
13635 {
13636 	static const GLchar* block_definition_all = "Goku {\n"
13637 												"    layout (location = 2) vec4 gohan;\n"
13638 												"    layout (location = 4) vec4 goten;\n"
13639 												"    layout (location = 6) vec4 chichi;\n"
13640 												"} gokuARRAY;\n";
13641 	static const GLchar* block_definition_one = "Goku {\n"
13642 												"    vec4 gohan;\n"
13643 #if DEBUG_NEG_REMOVE_ERROR
13644 												"    /* layout (location = 4) */ vec4 goten;\n"
13645 #else
13646 												"    layout (location = 4) vec4 goten;\n"
13647 #endif /* DEBUG_NEG_REMOVE_ERROR */
13648 												"    vec4 chichi;\n"
13649 												"} gokuARRAY;\n";
13650 	static const GLchar* input_use  = "    result += gokuINDEX.gohan + gokuINDEX.goten + gokuINDEX.chichi;\n";
13651 	static const GLchar* output_use = "    gokuINDEX.gohan  = result / 2;\n"
13652 									  "    gokuINDEX.goten  = result / 4 - gokuINDEX.gohan;\n"
13653 									  "    gokuINDEX.chichi = result / 8 - gokuINDEX.goten;\n";
13654 	static const GLchar* fs = "#version 430 core\n"
13655 							  "#extension GL_ARB_enhanced_layouts : require\n"
13656 							  "\n"
13657 							  "in  vec4 gs_fs;\n"
13658 							  "out vec4 fs_out;\n"
13659 							  "\n"
13660 							  "void main()\n"
13661 							  "{\n"
13662 							  "    fs_out = gs_fs;\n"
13663 							  "}\n"
13664 							  "\n";
13665 	static const GLchar* fs_tested = "#version 430 core\n"
13666 									 "#extension GL_ARB_enhanced_layouts : require\n"
13667 									 "\n"
13668 									 "DIRECTION BLOCK_DEFINITION"
13669 									 "\n"
13670 									 "in  vec4 gs_fs;\n"
13671 									 "out vec4 fs_out;\n"
13672 									 "\n"
13673 									 "void main()\n"
13674 									 "{\n"
13675 									 "    vec4 result = gs_fs;\n"
13676 									 "\n"
13677 									 "VARIABLE_USE"
13678 									 "\n"
13679 									 "    fs_out = result;\n"
13680 									 "}\n"
13681 									 "\n";
13682 	static const GLchar* gs = "#version 430 core\n"
13683 							  "#extension GL_ARB_enhanced_layouts : require\n"
13684 							  "\n"
13685 							  "layout(points)                           in;\n"
13686 							  "layout(triangle_strip, max_vertices = 4) out;\n"
13687 							  "\n"
13688 							  "in  vec4 tes_gs[];\n"
13689 							  "out vec4 gs_fs;\n"
13690 							  "\n"
13691 							  "void main()\n"
13692 							  "{\n"
13693 							  "    gs_fs = tes_gs[0];\n"
13694 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
13695 							  "    EmitVertex();\n"
13696 							  "    gs_fs = tes_gs[0];\n"
13697 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
13698 							  "    EmitVertex();\n"
13699 							  "    gs_fs = tes_gs[0];\n"
13700 							  "    gl_Position  = vec4(1, -1, 0, 1);\n"
13701 							  "    EmitVertex();\n"
13702 							  "    gs_fs = tes_gs[0];\n"
13703 							  "    gl_Position  = vec4(1, 1, 0, 1);\n"
13704 							  "    EmitVertex();\n"
13705 							  "}\n"
13706 							  "\n";
13707 	static const GLchar* gs_tested = "#version 430 core\n"
13708 									 "#extension GL_ARB_enhanced_layouts : require\n"
13709 									 "\n"
13710 									 "layout(points)                           in;\n"
13711 									 "layout(triangle_strip, max_vertices = 4) out;\n"
13712 									 "\n"
13713 									 "DIRECTION BLOCK_DEFINITION"
13714 									 "\n"
13715 									 "in  vec4 tes_gs[];\n"
13716 									 "out vec4 gs_fs;\n"
13717 									 "\n"
13718 									 "void main()\n"
13719 									 "{\n"
13720 									 "    vec4 result = tes_gs[0];\n"
13721 									 "\n"
13722 									 "VARIABLE_USE"
13723 									 "\n"
13724 									 "    gs_fs = result;\n"
13725 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
13726 									 "    EmitVertex();\n"
13727 									 "    gs_fs = result;\n"
13728 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
13729 									 "    EmitVertex();\n"
13730 									 "    gs_fs = result;\n"
13731 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
13732 									 "    EmitVertex();\n"
13733 									 "    gs_fs = result;\n"
13734 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
13735 									 "    EmitVertex();\n"
13736 									 "}\n"
13737 									 "\n";
13738 	static const GLchar* tcs = "#version 430 core\n"
13739 							   "#extension GL_ARB_enhanced_layouts : require\n"
13740 							   "\n"
13741 							   "layout(vertices = 1) out;\n"
13742 							   "\n"
13743 							   "in  vec4 vs_tcs[];\n"
13744 							   "out vec4 tcs_tes[];\n"
13745 							   "\n"
13746 							   "void main()\n"
13747 							   "{\n"
13748 							   "\n"
13749 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
13750 							   "\n"
13751 							   "    gl_TessLevelOuter[0] = 1.0;\n"
13752 							   "    gl_TessLevelOuter[1] = 1.0;\n"
13753 							   "    gl_TessLevelOuter[2] = 1.0;\n"
13754 							   "    gl_TessLevelOuter[3] = 1.0;\n"
13755 							   "    gl_TessLevelInner[0] = 1.0;\n"
13756 							   "    gl_TessLevelInner[1] = 1.0;\n"
13757 							   "}\n"
13758 							   "\n";
13759 	static const GLchar* tcs_tested = "#version 430 core\n"
13760 									  "#extension GL_ARB_enhanced_layouts : require\n"
13761 									  "\n"
13762 									  "layout(vertices = 1) out;\n"
13763 									  "\n"
13764 									  "DIRECTION BLOCK_DEFINITION"
13765 									  "\n"
13766 									  "in  vec4 vs_tcs[];\n"
13767 									  "out vec4 tcs_tes[];\n"
13768 									  "\n"
13769 									  "void main()\n"
13770 									  "{\n"
13771 									  "    vec4 result = vs_tcs[gl_InvocationID];\n"
13772 									  "\n"
13773 									  "VARIABLE_USE"
13774 									  "\n"
13775 									  "    tcs_tes[gl_InvocationID] = result;\n"
13776 									  "\n"
13777 									  "    gl_TessLevelOuter[0] = 1.0;\n"
13778 									  "    gl_TessLevelOuter[1] = 1.0;\n"
13779 									  "    gl_TessLevelOuter[2] = 1.0;\n"
13780 									  "    gl_TessLevelOuter[3] = 1.0;\n"
13781 									  "    gl_TessLevelInner[0] = 1.0;\n"
13782 									  "    gl_TessLevelInner[1] = 1.0;\n"
13783 									  "}\n"
13784 									  "\n";
13785 	static const GLchar* tes = "#version 430 core\n"
13786 							   "#extension GL_ARB_enhanced_layouts : require\n"
13787 							   "\n"
13788 							   "layout(isolines, point_mode) in;\n"
13789 							   "\n"
13790 							   "in  vec4 tcs_tes[];\n"
13791 							   "out vec4 tes_gs;\n"
13792 							   "\n"
13793 							   "void main()\n"
13794 							   "{\n"
13795 							   "    tes_gs = tcs_tes[0];\n"
13796 							   "}\n"
13797 							   "\n";
13798 	static const GLchar* tes_tested = "#version 430 core\n"
13799 									  "#extension GL_ARB_enhanced_layouts : require\n"
13800 									  "\n"
13801 									  "layout(isolines, point_mode) in;\n"
13802 									  "\n"
13803 									  "DIRECTION BLOCK_DEFINITION"
13804 									  "\n"
13805 									  "in  vec4 tcs_tes[];\n"
13806 									  "out vec4 tes_gs;\n"
13807 									  "\n"
13808 									  "void main()\n"
13809 									  "{\n"
13810 									  "    vec4 result = tcs_tes[0];\n"
13811 									  "\n"
13812 									  "VARIABLE_USE"
13813 									  "\n"
13814 									  "    tes_gs = result;\n"
13815 									  "}\n"
13816 									  "\n";
13817 	static const GLchar* vs = "#version 430 core\n"
13818 							  "#extension GL_ARB_enhanced_layouts : require\n"
13819 							  "\n"
13820 							  "in  vec4 in_vs;\n"
13821 							  "out vec4 vs_tcs;\n"
13822 							  "\n"
13823 							  "void main()\n"
13824 							  "{\n"
13825 							  "    vs_tcs = in_vs;\n"
13826 							  "}\n"
13827 							  "\n";
13828 	static const GLchar* vs_tested = "#version 430 core\n"
13829 									 "#extension GL_ARB_enhanced_layouts : require\n"
13830 									 "\n"
13831 									 "DIRECTION BLOCK_DEFINITION"
13832 									 "\n"
13833 									 "in  vec4 in_vs;\n"
13834 									 "out vec4 vs_tcs;\n"
13835 									 "\n"
13836 									 "void main()\n"
13837 									 "{\n"
13838 									 "    vec4 result = in_vs;\n"
13839 									 "\n"
13840 									 "VARIABLE_USE"
13841 									 "\n"
13842 									 "    vs_tcs = result;\n"
13843 									 "}\n"
13844 									 "\n";
13845 
13846 	const GLchar* array					= "";
13847 	const GLchar* direction				= "in";
13848 	const GLchar* index					= "";
13849 	std::string   source;
13850 	testCase&	 test_case = m_test_cases[test_case_index];
13851 	const GLchar* var_use	= Utils::Shader::VERTEX == test_case.m_stage ? input_use : "\n";
13852 	const GLchar* definition = test_case.m_qualify_all ? block_definition_all : block_definition_one;
13853 
13854 	if (!test_case.m_is_input)
13855 	{
13856 		direction = "out";
13857 		var_use   = output_use;
13858 	}
13859 
13860 	if (test_case.m_stage == stage)
13861 	{
13862 		size_t position = 0;
13863 		size_t temp		= 0;
13864 
13865 		switch (stage)
13866 		{
13867 		case Utils::Shader::FRAGMENT:
13868 			source = fs_tested;
13869 			break;
13870 		case Utils::Shader::GEOMETRY:
13871 			source = gs_tested;
13872 			array  = test_case.m_is_input ? "[]" : "";
13873 			index  = test_case.m_is_input ? "[0]" : "";
13874 			break;
13875 		case Utils::Shader::TESS_CTRL:
13876 			source = tcs_tested;
13877 			array  = "[]";
13878 			index  = "[gl_InvocationID]";
13879 			break;
13880 		case Utils::Shader::TESS_EVAL:
13881 			source = tes_tested;
13882 			array  = test_case.m_is_input ? "[]" : "";
13883 			index  = test_case.m_is_input ? "[0]" : "";
13884 			break;
13885 		case Utils::Shader::VERTEX:
13886 			source = vs_tested;
13887 			break;
13888 		default:
13889 			TCU_FAIL("Invalid enum");
13890 		}
13891 
13892 		Utils::replaceToken("DIRECTION", position, direction, source);
13893 		temp = position;
13894 		Utils::replaceToken("BLOCK_DEFINITION", position, definition, source);
13895 		position = temp;
13896 		Utils::replaceToken("ARRAY", position, array, source);
13897 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
13898 
13899 		Utils::replaceAllTokens("INDEX", index, source);
13900 	}
13901 	else
13902 	{
13903 		switch (stage)
13904 		{
13905 		case Utils::Shader::FRAGMENT:
13906 			source = fs;
13907 			break;
13908 		case Utils::Shader::GEOMETRY:
13909 			source = gs;
13910 			break;
13911 		case Utils::Shader::TESS_CTRL:
13912 			source = tcs;
13913 			break;
13914 		case Utils::Shader::TESS_EVAL:
13915 			source = tes;
13916 			break;
13917 		case Utils::Shader::VERTEX:
13918 			source = vs;
13919 			break;
13920 		default:
13921 			TCU_FAIL("Invalid enum");
13922 		}
13923 	}
13924 
13925 	return source;
13926 }
13927 
13928 /** Get description of test case
13929  *
13930  * @param test_case_index Index of test case
13931  *
13932  * @return Test case description
13933  **/
13934 std::string VaryingBlockMemberLocationsTest::getTestCaseName(GLuint test_case_index)
13935 {
13936 	std::stringstream stream;
13937 	testCase&		  test_case = m_test_cases[test_case_index];
13938 
13939 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", direction: ";
13940 
13941 	if (true == test_case.m_is_input)
13942 	{
13943 		stream << "input";
13944 	}
13945 	else
13946 	{
13947 		stream << "output";
13948 	}
13949 
13950 	if (true == test_case.m_qualify_all)
13951 	{
13952 		stream << ", all members qualified";
13953 	}
13954 	else
13955 	{
13956 		stream << ", not all members qualified";
13957 	}
13958 
13959 	return stream.str();
13960 }
13961 
13962 /** Get number of test cases
13963  *
13964  * @return Number of test cases
13965  **/
13966 GLuint VaryingBlockMemberLocationsTest::getTestCaseNumber()
13967 {
13968 	return static_cast<GLuint>(m_test_cases.size());
13969 }
13970 
13971 /** Selects if "compute" stage is relevant for test
13972  *
13973  * @param ignored
13974  *
13975  * @return false
13976  **/
13977 bool VaryingBlockMemberLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
13978 {
13979 	return false;
13980 }
13981 
13982 /** Selects if compilation failure is expected result
13983  *
13984  * @param test_case_index Index of test case
13985  *
13986  * @return false when all members are qualified, true otherwise
13987  **/
13988 bool VaryingBlockMemberLocationsTest::isFailureExpected(GLuint test_case_index)
13989 {
13990 	return (true != m_test_cases[test_case_index].m_qualify_all);
13991 }
13992 
13993 /** Prepare all test cases
13994  *
13995  **/
13996 void VaryingBlockMemberLocationsTest::testInit()
13997 {
13998 	for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
13999 	{
14000 		if (Utils::Shader::COMPUTE == stage)
14001 		{
14002 			continue;
14003 		}
14004 
14005 		testCase test_case_in_all  = { true, true, (Utils::Shader::STAGES)stage };
14006 		testCase test_case_in_one  = { true, false, (Utils::Shader::STAGES)stage };
14007 		testCase test_case_out_all = { false, true, (Utils::Shader::STAGES)stage };
14008 		testCase test_case_out_one = { false, false, (Utils::Shader::STAGES)stage };
14009 
14010 		if (Utils::Shader::VERTEX != stage)
14011 		{
14012 			m_test_cases.push_back(test_case_in_all);
14013 			m_test_cases.push_back(test_case_in_one);
14014 		}
14015 
14016 		if (Utils::Shader::FRAGMENT != stage)
14017 		{
14018 			m_test_cases.push_back(test_case_out_all);
14019 			m_test_cases.push_back(test_case_out_one);
14020 		}
14021 	}
14022 }
14023 
14024 /** Constructor
14025  *
14026  * @param context Test framework context
14027  **/
14028 VaryingBlockAutomaticMemberLocationsTest::VaryingBlockAutomaticMemberLocationsTest(deqp::Context& context)
14029 	: NegativeTestBase(
14030 		  context, "varying_block_automatic_member_locations",
14031 		  "Test verifies that compiler assigns subsequent locations to block members, even if this causes errors")
14032 {
14033 }
14034 
14035 /** Source for given test case and stage
14036  *
14037  * @param test_case_index Index of test case
14038  * @param stage           Shader stage
14039  *
14040  * @return Shader source
14041  **/
14042 std::string VaryingBlockAutomaticMemberLocationsTest::getShaderSource(GLuint				test_case_index,
14043 																	  Utils::Shader::STAGES stage)
14044 {
14045 	static const GLchar* block_definition = "layout (location = 2) DIRECTION DBZ {\n"
14046 											"    vec4 goku;\n"
14047 											"    vec4 gohan[4];\n"
14048 											"    vec4 goten;\n"
14049 #if DEBUG_NEG_REMOVE_ERROR
14050 											"    /* layout (location = 1) */ vec4 chichi;\n"
14051 #else
14052 											"    layout (location = 1) vec4 chichi;\n"
14053 #endif /* DEBUG_NEG_REMOVE_ERROR */
14054 											"    vec4 pan;\n"
14055 											"} dbzARRAY;\n";
14056 	static const GLchar* input_use = "    result += dbzINDEX.goku + dbzINDEX.gohan[0] + dbzINDEX.gohan[1] + "
14057 									 "dbzINDEX.gohan[3] + dbzINDEX.gohan[2] + dbzINDEX.goten + dbzINDEX.chichi + "
14058 									 "dbzINDEX.pan;\n";
14059 	static const GLchar* output_use = "    dbzINDEX.goku     = result;\n"
14060 									  "    dbzINDEX.gohan[0] = result / 2;\n"
14061 									  "    dbzINDEX.gohan[1] = result / 2.25;\n"
14062 									  "    dbzINDEX.gohan[2] = result / 2.5;\n"
14063 									  "    dbzINDEX.gohan[3] = result / 2.75;\n"
14064 									  "    dbzINDEX.goten    = result / 4  - dbzINDEX.gohan[0] - dbzINDEX.gohan[1] - "
14065 									  "dbzINDEX.gohan[2] - dbzINDEX.gohan[3];\n"
14066 									  "    dbzINDEX.chichi   = result / 8  - dbzINDEX.goten;\n"
14067 									  "    dbzINDEX.pan      = result / 16 - dbzINDEX.chichi;\n";
14068 	static const GLchar* fs = "#version 430 core\n"
14069 							  "#extension GL_ARB_enhanced_layouts : require\n"
14070 							  "\n"
14071 							  "in  vec4 gs_fs;\n"
14072 							  "out vec4 fs_out;\n"
14073 							  "\n"
14074 							  "void main()\n"
14075 							  "{\n"
14076 							  "    fs_out = gs_fs;\n"
14077 							  "}\n"
14078 							  "\n";
14079 	static const GLchar* fs_tested = "#version 430 core\n"
14080 									 "#extension GL_ARB_enhanced_layouts : require\n"
14081 									 "\n"
14082 									 "BLOCK_DEFINITION"
14083 									 "\n"
14084 									 "in  vec4 gs_fs;\n"
14085 									 "out vec4 fs_out;\n"
14086 									 "\n"
14087 									 "void main()\n"
14088 									 "{\n"
14089 									 "    vec4 result = gs_fs;\n"
14090 									 "\n"
14091 									 "VARIABLE_USE"
14092 									 "\n"
14093 									 "    fs_out += result;\n"
14094 									 "}\n"
14095 									 "\n";
14096 	static const GLchar* gs = "#version 430 core\n"
14097 							  "#extension GL_ARB_enhanced_layouts : require\n"
14098 							  "\n"
14099 							  "layout(points)                           in;\n"
14100 							  "layout(triangle_strip, max_vertices = 4) out;\n"
14101 							  "\n"
14102 							  "in  vec4 tes_gs[];\n"
14103 							  "out vec4 gs_fs;\n"
14104 							  "\n"
14105 							  "void main()\n"
14106 							  "{\n"
14107 							  "    gs_fs = tes_gs[0];\n"
14108 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
14109 							  "    EmitVertex();\n"
14110 							  "    gs_fs = tes_gs[0];\n"
14111 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
14112 							  "    EmitVertex();\n"
14113 							  "    gs_fs = tes_gs[0];\n"
14114 							  "    gl_Position  = vec4(1, -1, 0, 1);\n"
14115 							  "    EmitVertex();\n"
14116 							  "    gs_fs = tes_gs[0];\n"
14117 							  "    gl_Position  = vec4(1, 1, 0, 1);\n"
14118 							  "    EmitVertex();\n"
14119 							  "}\n"
14120 							  "\n";
14121 	static const GLchar* gs_tested = "#version 430 core\n"
14122 									 "#extension GL_ARB_enhanced_layouts : require\n"
14123 									 "\n"
14124 									 "layout(points)                           in;\n"
14125 									 "layout(triangle_strip, max_vertices = 4) out;\n"
14126 									 "\n"
14127 									 "BLOCK_DEFINITION"
14128 									 "\n"
14129 									 "in  vec4 tes_gs[];\n"
14130 									 "out vec4 gs_fs;\n"
14131 									 "\n"
14132 									 "void main()\n"
14133 									 "{\n"
14134 									 "    vec4 result = tes_gs[0];\n"
14135 									 "\n"
14136 									 "VARIABLE_USE"
14137 									 "\n"
14138 									 "    gs_fs = result;\n"
14139 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
14140 									 "    EmitVertex();\n"
14141 									 "    gs_fs = result;\n"
14142 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
14143 									 "    EmitVertex();\n"
14144 									 "    gs_fs = result;\n"
14145 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
14146 									 "    EmitVertex();\n"
14147 									 "    gs_fs = result;\n"
14148 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
14149 									 "    EmitVertex();\n"
14150 									 "}\n"
14151 									 "\n";
14152 	static const GLchar* tcs = "#version 430 core\n"
14153 							   "#extension GL_ARB_enhanced_layouts : require\n"
14154 							   "\n"
14155 							   "layout(vertices = 1) out;\n"
14156 							   "\n"
14157 							   "in  vec4 vs_tcs[];\n"
14158 							   "out vec4 tcs_tes[];\n"
14159 							   "\n"
14160 							   "void main()\n"
14161 							   "{\n"
14162 							   "\n"
14163 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
14164 							   "\n"
14165 							   "    gl_TessLevelOuter[0] = 1.0;\n"
14166 							   "    gl_TessLevelOuter[1] = 1.0;\n"
14167 							   "    gl_TessLevelOuter[2] = 1.0;\n"
14168 							   "    gl_TessLevelOuter[3] = 1.0;\n"
14169 							   "    gl_TessLevelInner[0] = 1.0;\n"
14170 							   "    gl_TessLevelInner[1] = 1.0;\n"
14171 							   "}\n"
14172 							   "\n";
14173 	static const GLchar* tcs_tested = "#version 430 core\n"
14174 									  "#extension GL_ARB_enhanced_layouts : require\n"
14175 									  "\n"
14176 									  "layout(vertices = 1) out;\n"
14177 									  "\n"
14178 									  "BLOCK_DEFINITION"
14179 									  "\n"
14180 									  "in  vec4 vs_tcs[];\n"
14181 									  "out vec4 tcs_tes[];\n"
14182 									  "\n"
14183 									  "void main()\n"
14184 									  "{\n"
14185 									  "    vec4 result = vs_tcs[gl_InvocationID];\n"
14186 									  "\n"
14187 									  "VARIABLE_USE"
14188 									  "\n"
14189 									  "    tcs_tes[gl_InvocationID] = result;\n"
14190 									  "\n"
14191 									  "    gl_TessLevelOuter[0] = 1.0;\n"
14192 									  "    gl_TessLevelOuter[1] = 1.0;\n"
14193 									  "    gl_TessLevelOuter[2] = 1.0;\n"
14194 									  "    gl_TessLevelOuter[3] = 1.0;\n"
14195 									  "    gl_TessLevelInner[0] = 1.0;\n"
14196 									  "    gl_TessLevelInner[1] = 1.0;\n"
14197 									  "}\n"
14198 									  "\n";
14199 	static const GLchar* tes = "#version 430 core\n"
14200 							   "#extension GL_ARB_enhanced_layouts : require\n"
14201 							   "\n"
14202 							   "layout(isolines, point_mode) in;\n"
14203 							   "\n"
14204 							   "in  vec4 tcs_tes[];\n"
14205 							   "out vec4 tes_gs;\n"
14206 							   "\n"
14207 							   "void main()\n"
14208 							   "{\n"
14209 							   "    tes_gs = tcs_tes[0];\n"
14210 							   "}\n"
14211 							   "\n";
14212 	static const GLchar* tes_tested = "#version 430 core\n"
14213 									  "#extension GL_ARB_enhanced_layouts : require\n"
14214 									  "\n"
14215 									  "layout(isolines, point_mode) in;\n"
14216 									  "\n"
14217 									  "BLOCK_DEFINITION"
14218 									  "\n"
14219 									  "in  vec4 tcs_tes[];\n"
14220 									  "out vec4 tes_gs;\n"
14221 									  "\n"
14222 									  "void main()\n"
14223 									  "{\n"
14224 									  "    vec4 result = tcs_tes[0];\n"
14225 									  "\n"
14226 									  "VARIABLE_USE"
14227 									  "\n"
14228 									  "    tes_gs += result;\n"
14229 									  "}\n"
14230 									  "\n";
14231 	static const GLchar* vs = "#version 430 core\n"
14232 							  "#extension GL_ARB_enhanced_layouts : require\n"
14233 							  "\n"
14234 							  "in  vec4 in_vs;\n"
14235 							  "out vec4 vs_tcs;\n"
14236 							  "\n"
14237 							  "void main()\n"
14238 							  "{\n"
14239 							  "    vs_tcs = in_vs;\n"
14240 							  "}\n"
14241 							  "\n";
14242 	static const GLchar* vs_tested = "#version 430 core\n"
14243 									 "#extension GL_ARB_enhanced_layouts : require\n"
14244 									 "\n"
14245 									 "BLOCK_DEFINITION"
14246 									 "\n"
14247 									 "in  vec4 in_vs;\n"
14248 									 "out vec4 vs_tcs;\n"
14249 									 "\n"
14250 									 "void main()\n"
14251 									 "{\n"
14252 									 "    vec4 result = in_vs;\n"
14253 									 "\n"
14254 									 "VARIABLE_USE"
14255 									 "\n"
14256 									 "    vs_tcs += result;\n"
14257 									 "}\n"
14258 									 "\n";
14259 
14260 	const GLchar* array		= "";
14261 	const GLchar* direction = "in";
14262 	const GLchar* index		= "";
14263 	std::string   source;
14264 	testCase&	 test_case = m_test_cases[test_case_index];
14265 	const GLchar* var_use   = Utils::Shader::VERTEX == test_case.m_stage ? input_use : "\n";
14266 
14267 	if (!test_case.m_is_input)
14268 	{
14269 		direction = "out";
14270 		var_use   = output_use;
14271 	}
14272 
14273 	if (test_case.m_stage == stage)
14274 	{
14275 		size_t position = 0;
14276 
14277 		switch (stage)
14278 		{
14279 		case Utils::Shader::FRAGMENT:
14280 			source = fs_tested;
14281 			break;
14282 		case Utils::Shader::GEOMETRY:
14283 			source = gs_tested;
14284 			array  = test_case.m_is_input ? "[]" : "";
14285 			index  = test_case.m_is_input ? "[0]" : "";
14286 			break;
14287 		case Utils::Shader::TESS_CTRL:
14288 			source = tcs_tested;
14289 			array  = "[]";
14290 			index  = "[gl_InvocationID]";
14291 			break;
14292 		case Utils::Shader::TESS_EVAL:
14293 			source = tes_tested;
14294 			array  = test_case.m_is_input ? "[]" : "";
14295 			index  = test_case.m_is_input ? "[0]" : "";
14296 			break;
14297 		case Utils::Shader::VERTEX:
14298 			source = vs_tested;
14299 			break;
14300 		default:
14301 			TCU_FAIL("Invalid enum");
14302 		}
14303 
14304 		Utils::replaceToken("BLOCK_DEFINITION", position, block_definition, source);
14305 		position = 0;
14306 		Utils::replaceToken("DIRECTION", position, direction, source);
14307 		Utils::replaceToken("ARRAY", position, array, source);
14308 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
14309 
14310 		Utils::replaceAllTokens("INDEX", index, source);
14311 	}
14312 	else
14313 	{
14314 		switch (stage)
14315 		{
14316 		case Utils::Shader::FRAGMENT:
14317 			source = fs;
14318 			break;
14319 		case Utils::Shader::GEOMETRY:
14320 			source = gs;
14321 			break;
14322 		case Utils::Shader::TESS_CTRL:
14323 			source = tcs;
14324 			break;
14325 		case Utils::Shader::TESS_EVAL:
14326 			source = tes;
14327 			break;
14328 		case Utils::Shader::VERTEX:
14329 			source = vs;
14330 			break;
14331 		default:
14332 			TCU_FAIL("Invalid enum");
14333 		}
14334 	}
14335 
14336 	return source;
14337 }
14338 
14339 /** Get description of test case
14340  *
14341  * @param test_case_index Index of test case
14342  *
14343  * @return Test case description
14344  **/
14345 std::string VaryingBlockAutomaticMemberLocationsTest::getTestCaseName(GLuint test_case_index)
14346 {
14347 	std::stringstream stream;
14348 	testCase&		  test_case = m_test_cases[test_case_index];
14349 
14350 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", direction: ";
14351 
14352 	if (true == test_case.m_is_input)
14353 	{
14354 		stream << "input";
14355 	}
14356 	else
14357 	{
14358 		stream << "output";
14359 	}
14360 
14361 	return stream.str();
14362 }
14363 
14364 /** Get number of test cases
14365  *
14366  * @return Number of test cases
14367  **/
14368 GLuint VaryingBlockAutomaticMemberLocationsTest::getTestCaseNumber()
14369 {
14370 	return static_cast<GLuint>(m_test_cases.size());
14371 }
14372 
14373 /** Selects if "compute" stage is relevant for test
14374  *
14375  * @param ignored
14376  *
14377  * @return false
14378  **/
14379 bool VaryingBlockAutomaticMemberLocationsTest::isComputeRelevant(GLuint /* test_case_index */)
14380 {
14381 	return false;
14382 }
14383 
14384 /** Prepare all test cases
14385  *
14386  **/
14387 void VaryingBlockAutomaticMemberLocationsTest::testInit()
14388 {
14389 	for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
14390 	{
14391 		if (Utils::Shader::COMPUTE == stage)
14392 		{
14393 			continue;
14394 		}
14395 
14396 		testCase test_case_in  = { true, (Utils::Shader::STAGES)stage };
14397 		testCase test_case_out = { false, (Utils::Shader::STAGES)stage };
14398 
14399 		if (Utils::Shader::VERTEX != stage)
14400 		{
14401 			m_test_cases.push_back(test_case_in);
14402 		}
14403 
14404 		if (Utils::Shader::FRAGMENT != stage)
14405 		{
14406 			m_test_cases.push_back(test_case_out);
14407 		}
14408 	}
14409 }
14410 
14411 /** Constructor
14412  *
14413  * @param context Test framework context
14414  **/
14415 VaryingLocationLimitTest::VaryingLocationLimitTest(deqp::Context& context)
14416 	: NegativeTestBase(context, "varying_location_limit",
14417 					   "Test verifies that compiler reports error when location qualifier exceeds limits")
14418 {
14419 }
14420 
14421 /** Source for given test case and stage
14422  *
14423  * @param test_case_index Index of test case
14424  * @param stage           Shader stage
14425  *
14426  * @return Shader source
14427  **/
14428 std::string VaryingLocationLimitTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
14429 {
14430 #if DEBUG_NEG_REMOVE_ERROR
14431 	static const GLchar* var_definition = "layout (location = LAST /* + 1 */) FLAT DIRECTION TYPE gokuARRAY;\n";
14432 #else
14433 	static const GLchar* var_definition = "layout (location = LAST + 1) FLAT DIRECTION TYPE gokuARRAY;\n";
14434 #endif /* DEBUG_NEG_REMOVE_ERROR */
14435 	static const GLchar* input_use		= "    if (TYPE(0) == gokuINDEX)\n"
14436 									 "    {\n"
14437 									 "        result += vec4(1, 0.5, 0.25, 0.125);\n"
14438 									 "    }\n";
14439 	static const GLchar* output_use = "    gokuINDEX = TYPE(0);\n"
14440 									  "    if (vec4(0) == result)\n"
14441 									  "    {\n"
14442 									  "        gokuINDEX = TYPE(1);\n"
14443 									  "    }\n";
14444 	static const GLchar* fs = "#version 430 core\n"
14445 							  "#extension GL_ARB_enhanced_layouts : require\n"
14446 							  "\n"
14447 							  "in  vec4 gs_fs;\n"
14448 							  "out vec4 fs_out;\n"
14449 							  "\n"
14450 							  "void main()\n"
14451 							  "{\n"
14452 							  "    fs_out = gs_fs;\n"
14453 							  "}\n"
14454 							  "\n";
14455 	static const GLchar* fs_tested = "#version 430 core\n"
14456 									 "#extension GL_ARB_enhanced_layouts : require\n"
14457 									 "\n"
14458 									 "VAR_DEFINITION"
14459 									 "\n"
14460 									 "in  vec4 gs_fs;\n"
14461 									 "out vec4 fs_out;\n"
14462 									 "\n"
14463 									 "void main()\n"
14464 									 "{\n"
14465 									 "    vec4 result = gs_fs;\n"
14466 									 "\n"
14467 									 "VARIABLE_USE"
14468 									 "\n"
14469 									 "    fs_out += result;\n"
14470 									 "}\n"
14471 									 "\n";
14472 	static const GLchar* gs = "#version 430 core\n"
14473 							  "#extension GL_ARB_enhanced_layouts : require\n"
14474 							  "\n"
14475 							  "layout(points)                           in;\n"
14476 							  "layout(triangle_strip, max_vertices = 4) out;\n"
14477 							  "\n"
14478 							  "PERVERTEX" /* Separable programs require explicit declaration of gl_PerVertex */
14479 							  "in  vec4 tes_gs[];\n"
14480 							  "out vec4 gs_fs;\n"
14481 							  "\n"
14482 							  "void main()\n"
14483 							  "{\n"
14484 							  "    gs_fs = tes_gs[0];\n"
14485 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
14486 							  "    EmitVertex();\n"
14487 							  "    gs_fs = tes_gs[0];\n"
14488 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
14489 							  "    EmitVertex();\n"
14490 							  "    gs_fs = tes_gs[0];\n"
14491 							  "    gl_Position  = vec4(1, -1, 0, 1);\n"
14492 							  "    EmitVertex();\n"
14493 							  "    gs_fs = tes_gs[0];\n"
14494 							  "    gl_Position  = vec4(1, 1, 0, 1);\n"
14495 							  "    EmitVertex();\n"
14496 							  "}\n"
14497 							  "\n";
14498 	static const GLchar* gs_tested = "#version 430 core\n"
14499 									 "#extension GL_ARB_enhanced_layouts : require\n"
14500 									 "\n"
14501 									 "layout(points)                           in;\n"
14502 									 "layout(triangle_strip, max_vertices = 4) out;\n"
14503 									 "\n"
14504 									 "PERVERTEX" /* Separable programs require explicit declaration of gl_PerVertex */
14505 									 "VAR_DEFINITION"
14506 									 "\n"
14507 									 "in  vec4 tes_gs[];\n"
14508 									 "out vec4 gs_fs;\n"
14509 									 "\n"
14510 									 "void main()\n"
14511 									 "{\n"
14512 									 "    vec4 result = tes_gs[0];\n"
14513 									 "\n"
14514 									 "VARIABLE_USE"
14515 									 "\n"
14516 									 "    gs_fs = result;\n"
14517 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
14518 									 "    EmitVertex();\n"
14519 									 "    gs_fs = result;\n"
14520 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
14521 									 "    EmitVertex();\n"
14522 									 "    gs_fs = result;\n"
14523 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
14524 									 "    EmitVertex();\n"
14525 									 "    gs_fs = result;\n"
14526 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
14527 									 "    EmitVertex();\n"
14528 									 "}\n"
14529 									 "\n";
14530 	static const GLchar* tcs = "#version 430 core\n"
14531 							   "#extension GL_ARB_enhanced_layouts : require\n"
14532 							   "\n"
14533 							   "layout(vertices = 1) out;\n"
14534 							   "\n"
14535 							   "in  vec4 vs_tcs[];\n"
14536 							   "out vec4 tcs_tes[];\n"
14537 							   "\n"
14538 							   "void main()\n"
14539 							   "{\n"
14540 							   "\n"
14541 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
14542 							   "\n"
14543 							   "    gl_TessLevelOuter[0] = 1.0;\n"
14544 							   "    gl_TessLevelOuter[1] = 1.0;\n"
14545 							   "    gl_TessLevelOuter[2] = 1.0;\n"
14546 							   "    gl_TessLevelOuter[3] = 1.0;\n"
14547 							   "    gl_TessLevelInner[0] = 1.0;\n"
14548 							   "    gl_TessLevelInner[1] = 1.0;\n"
14549 							   "}\n"
14550 							   "\n";
14551 	static const GLchar* tcs_tested = "#version 430 core\n"
14552 									  "#extension GL_ARB_enhanced_layouts : require\n"
14553 									  "\n"
14554 									  "layout(vertices = 1) out;\n"
14555 									  "\n"
14556 									  "VAR_DEFINITION"
14557 									  "\n"
14558 									  "in  vec4 vs_tcs[];\n"
14559 									  "out vec4 tcs_tes[];\n"
14560 									  "\n"
14561 									  "void main()\n"
14562 									  "{\n"
14563 									  "    vec4 result = vs_tcs[gl_InvocationID];\n"
14564 									  "\n"
14565 									  "VARIABLE_USE"
14566 									  "\n"
14567 									  "    tcs_tes[gl_InvocationID] = result;\n"
14568 									  "\n"
14569 									  "    gl_TessLevelOuter[0] = 1.0;\n"
14570 									  "    gl_TessLevelOuter[1] = 1.0;\n"
14571 									  "    gl_TessLevelOuter[2] = 1.0;\n"
14572 									  "    gl_TessLevelOuter[3] = 1.0;\n"
14573 									  "    gl_TessLevelInner[0] = 1.0;\n"
14574 									  "    gl_TessLevelInner[1] = 1.0;\n"
14575 									  "}\n"
14576 									  "\n";
14577 	static const GLchar* tes = "#version 430 core\n"
14578 							   "#extension GL_ARB_enhanced_layouts : require\n"
14579 							   "\n"
14580 							   "layout(isolines, point_mode) in;\n"
14581 							   "\n"
14582 							   "in  vec4 tcs_tes[];\n"
14583 							   "out vec4 tes_gs;\n"
14584 							   "\n"
14585 							   "void main()\n"
14586 							   "{\n"
14587 							   "    tes_gs = tcs_tes[0];\n"
14588 							   "}\n"
14589 							   "\n";
14590 	static const GLchar* tes_tested = "#version 430 core\n"
14591 									  "#extension GL_ARB_enhanced_layouts : require\n"
14592 									  "\n"
14593 									  "layout(isolines, point_mode) in;\n"
14594 									  "\n"
14595 									  "VAR_DEFINITION"
14596 									  "\n"
14597 									  "in  vec4 tcs_tes[];\n"
14598 									  "out vec4 tes_gs;\n"
14599 									  "\n"
14600 									  "void main()\n"
14601 									  "{\n"
14602 									  "    vec4 result = tcs_tes[0];\n"
14603 									  "\n"
14604 									  "VARIABLE_USE"
14605 									  "\n"
14606 									  "    tes_gs += result;\n"
14607 									  "}\n"
14608 									  "\n";
14609 	static const GLchar* vs = "#version 430 core\n"
14610 							  "#extension GL_ARB_enhanced_layouts : require\n"
14611 							  "\n"
14612 							  "in  vec4 in_vs;\n"
14613 							  "out vec4 vs_tcs;\n"
14614 							  "\n"
14615 							  "void main()\n"
14616 							  "{\n"
14617 							  "    vs_tcs = in_vs;\n"
14618 							  "}\n"
14619 							  "\n";
14620 	static const GLchar* vs_tested = "#version 430 core\n"
14621 									 "#extension GL_ARB_enhanced_layouts : require\n"
14622 									 "\n"
14623 									 "VAR_DEFINITION"
14624 									 "\n"
14625 									 "in  vec4 in_vs;\n"
14626 									 "out vec4 vs_tcs;\n"
14627 									 "\n"
14628 									 "void main()\n"
14629 									 "{\n"
14630 									 "    vec4 result = in_vs;\n"
14631 									 "\n"
14632 									 "VARIABLE_USE"
14633 									 "\n"
14634 									 "    vs_tcs += result;\n"
14635 									 "}\n"
14636 									 "\n";
14637 
14638 	std::string source;
14639 	testCase&   test_case = m_test_cases[test_case_index];
14640 	size_t		  position   = 0;
14641 	const GLchar* per_vertex = !isSeparable(test_case_index) ? "" : "out gl_PerVertex {\n"
14642 																	"vec4 gl_Position;\n"
14643 																	"};\n"
14644 																	"\n";
14645 
14646 	if (test_case.m_stage == stage)
14647 	{
14648 		const GLchar*			 array = "";
14649 		GLchar					 buffer[16];
14650 		const GLchar*			 direction = "in ";
14651 		const GLchar*			 flat	  = "";
14652 		const GLchar*			 index	 = "";
14653 		GLuint					 last	  = getLastInputLocation(stage, test_case.m_type, 0, true);
14654 		const GLchar*			 type_name = test_case.m_type.GetGLSLTypeName();
14655 		Utils::Variable::STORAGE storage   = Utils::Variable::VARYING_INPUT;
14656 		const GLchar*			 var_use   = input_use;
14657 
14658 		if (false == test_case.m_is_input)
14659 		{
14660 			direction = "out";
14661 			last	  = getLastOutputLocation(stage, test_case.m_type, 0, true);
14662 			storage   = Utils::Variable::VARYING_OUTPUT;
14663 			var_use   = output_use;
14664 		}
14665 
14666 		if (isFlatRequired(stage, test_case.m_type, storage))
14667 		{
14668 			flat = "flat";
14669 		}
14670 
14671 		sprintf(buffer, "%d", last);
14672 
14673 		switch (stage)
14674 		{
14675 		case Utils::Shader::FRAGMENT:
14676 			source = fs_tested;
14677 			break;
14678 		case Utils::Shader::GEOMETRY:
14679 			source = gs_tested;
14680 			array  = test_case.m_is_input ? "[]" : "";
14681 			index  = test_case.m_is_input ? "[0]" : "";
14682 			Utils::replaceToken("PERVERTEX", position, per_vertex, source);
14683 			break;
14684 		case Utils::Shader::TESS_CTRL:
14685 			source = tcs_tested;
14686 			array  = "[]";
14687 			index  = "[gl_InvocationID]";
14688 			break;
14689 		case Utils::Shader::TESS_EVAL:
14690 			source = tes_tested;
14691 			array  = test_case.m_is_input ? "[]" : "";
14692 			index  = test_case.m_is_input ? "[0]" : "";
14693 			break;
14694 		case Utils::Shader::VERTEX:
14695 			source = vs_tested;
14696 			break;
14697 		default:
14698 			TCU_FAIL("Invalid enum");
14699 		}
14700 
14701 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
14702 		position = 0;
14703 		Utils::replaceToken("LAST", position, buffer, source);
14704 		Utils::replaceToken("FLAT", position, flat, source);
14705 		Utils::replaceToken("DIRECTION", position, direction, source);
14706 		Utils::replaceToken("ARRAY", position, array, source);
14707 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
14708 
14709 		Utils::replaceAllTokens("TYPE", type_name, source);
14710 		Utils::replaceAllTokens("INDEX", index, source);
14711 	}
14712 	else
14713 	{
14714 		switch (stage)
14715 		{
14716 		case Utils::Shader::FRAGMENT:
14717 			source = fs;
14718 			break;
14719 		case Utils::Shader::GEOMETRY:
14720 			source = gs;
14721 			Utils::replaceToken("PERVERTEX", position, per_vertex, source);
14722 			break;
14723 		case Utils::Shader::TESS_CTRL:
14724 			source = tcs;
14725 			break;
14726 		case Utils::Shader::TESS_EVAL:
14727 			source = tes;
14728 			break;
14729 		case Utils::Shader::VERTEX:
14730 			source = vs;
14731 			break;
14732 		default:
14733 			TCU_FAIL("Invalid enum");
14734 		}
14735 	}
14736 
14737 	return source;
14738 }
14739 
14740 /** Get description of test case
14741  *
14742  * @param test_case_index Index of test case
14743  *
14744  * @return Test case description
14745  **/
14746 std::string VaryingLocationLimitTest::getTestCaseName(GLuint test_case_index)
14747 {
14748 	std::stringstream stream;
14749 	testCase&		  test_case = m_test_cases[test_case_index];
14750 
14751 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
14752 		   << " type: " << test_case.m_type.GetGLSLTypeName() << ", direction: ";
14753 
14754 	if (true == test_case.m_is_input)
14755 	{
14756 		stream << "input";
14757 	}
14758 	else
14759 	{
14760 		stream << "output";
14761 	}
14762 
14763 	return stream.str();
14764 }
14765 
14766 /** Get number of test cases
14767  *
14768  * @return Number of test cases
14769  **/
14770 GLuint VaryingLocationLimitTest::getTestCaseNumber()
14771 {
14772 	return static_cast<GLuint>(m_test_cases.size());
14773 }
14774 
14775 /** Selects if "compute" stage is relevant for test
14776  *
14777  * @param ignored
14778  *
14779  * @return false
14780  **/
14781 bool VaryingLocationLimitTest::isComputeRelevant(GLuint /* test_case_index */)
14782 {
14783 	return false;
14784 }
14785 
14786 /** Selects if the test case should use a separable program
14787  *
14788  * @param test_case_index Id of test case
14789  *
14790  * @return whether the test should use separable programs or not
14791  **/
14792 bool VaryingLocationLimitTest::isSeparable(const GLuint test_case_index)
14793 {
14794 	const testCase& test_case = m_test_cases[test_case_index];
14795 
14796 	return test_case.m_is_input && test_case.m_stage != Utils::Shader::VERTEX;
14797 }
14798 
14799 /** Prepare all test cases
14800  *
14801  **/
14802 void VaryingLocationLimitTest::testInit()
14803 {
14804 	const GLuint n_types = getTypesNumber();
14805 
14806 	for (GLuint i = 0; i < n_types; ++i)
14807 	{
14808 		const Utils::Type& type = getType(i);
14809 
14810 		for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
14811 		{
14812 			if (Utils::Shader::COMPUTE == stage)
14813 			{
14814 				continue;
14815 			}
14816 
14817 			testCase test_case_in  = { true, type, (Utils::Shader::STAGES)stage };
14818 			testCase test_case_out = { false, type, (Utils::Shader::STAGES)stage };
14819 
14820 			m_test_cases.push_back(test_case_in);
14821 
14822 			if (Utils::Shader::FRAGMENT != stage)
14823 			{
14824 				m_test_cases.push_back(test_case_out);
14825 			}
14826 		}
14827 	}
14828 }
14829 
14830 /** Constructor
14831  *
14832  * @param context Test framework context
14833  **/
14834 VaryingComponentsTest::VaryingComponentsTest(deqp::Context& context)
14835 	: VaryingLocationsTest(context, "varying_components",
14836 						   "Test verifies that input and output components are respected")
14837 {
14838 }
14839 
14840 /** Constructor
14841  *
14842  * @param context          Test framework context
14843  * @param test_name        Name of test
14844  * @param test_description Description of test
14845  **/
14846 VaryingComponentsTest::VaryingComponentsTest(deqp::Context& context, const glw::GLchar* test_name,
14847 											 const glw::GLchar* test_description)
14848 	: VaryingLocationsTest(context, test_name, test_description)
14849 {
14850 }
14851 
14852 /** Get interface of program
14853  *
14854  * @param test_case_index     Test case
14855  * @param program_interface   Interface of program
14856  * @param varying_passthrough Collection of connections between in and out variables
14857  **/
14858 void VaryingComponentsTest::getProgramInterface(GLuint test_case_index, Utils::ProgramInterface& program_interface,
14859 												Utils::VaryingPassthrough& varying_passthrough)
14860 {
14861 	GLuint				   array_length = getArrayLength();
14862 	const testCase&		   test_case	= m_test_cases[test_case_index];
14863 	const Utils::Type	  vector_type  = Utils::Type::GetType(test_case.m_type, 1, 4);
14864 	Utils::ShaderInterface si			= program_interface.GetShaderInterface(Utils::Shader::VERTEX);
14865 
14866 	/* Zero means no array, however we still need at least 1 slot of data */
14867 	if (0 == array_length)
14868 	{
14869 		array_length += 1;
14870 	}
14871 
14872 	/* Generate data */
14873 	const std::vector<GLubyte>& data	  = vector_type.GenerateDataPacked();
14874 	const size_t				data_size = data.size();
14875 
14876 	/* Prepare data for variables */
14877 	m_data.resize(array_length * data_size);
14878 
14879 	GLubyte*	   dst = &m_data[0];
14880 	const GLubyte* src = &data[0];
14881 
14882 	for (GLuint i = 0; i < array_length; ++i)
14883 	{
14884 		memcpy(dst + data_size * i, src, data_size);
14885 	}
14886 
14887 	/* Prepare interface for each stage */
14888 	prepareShaderStage(Utils::Shader::FRAGMENT, vector_type, program_interface, test_case, varying_passthrough);
14889 	prepareShaderStage(Utils::Shader::GEOMETRY, vector_type, program_interface, test_case, varying_passthrough);
14890 	prepareShaderStage(Utils::Shader::TESS_CTRL, vector_type, program_interface, test_case, varying_passthrough);
14891 	prepareShaderStage(Utils::Shader::TESS_EVAL, vector_type, program_interface, test_case, varying_passthrough);
14892 	prepareShaderStage(Utils::Shader::VERTEX, vector_type, program_interface, test_case, varying_passthrough);
14893 }
14894 
14895 /** Get type name
14896  *
14897  * @param test_case_index Index of test case
14898  *
14899  * @return Name of type test in test_case_index
14900  **/
14901 std::string VaryingComponentsTest::getTestCaseName(glw::GLuint test_case_index)
14902 {
14903 	std::string name;
14904 
14905 	const testCase& test_case = m_test_cases[test_case_index];
14906 
14907 	name = "Type: ";
14908 
14909 	switch (test_case.m_type)
14910 	{
14911 	case Utils::Type::Double:
14912 		name.append(Utils::Type::_double.GetGLSLTypeName());
14913 		break;
14914 	case Utils::Type::Float:
14915 		name.append(Utils::Type::_float.GetGLSLTypeName());
14916 		break;
14917 	case Utils::Type::Int:
14918 		name.append(Utils::Type::_int.GetGLSLTypeName());
14919 		break;
14920 	case Utils::Type::Uint:
14921 		name.append(Utils::Type::uint.GetGLSLTypeName());
14922 		break;
14923 	}
14924 
14925 	name.append(", layout: ");
14926 
14927 	switch (test_case.m_layout)
14928 	{
14929 	case G64VEC2:
14930 		name.append("G64VEC2");
14931 		break;
14932 	case G64SCALAR_G64SCALAR:
14933 		name.append("G64SCALAR_G64SCALAR");
14934 		break;
14935 	case GVEC4:
14936 		name.append("GVEC4");
14937 		break;
14938 	case SCALAR_GVEC3:
14939 		name.append("SCALAR_GVEC3");
14940 		break;
14941 	case GVEC3_SCALAR:
14942 		name.append("GVEC3_SCALAR");
14943 		break;
14944 	case GVEC2_GVEC2:
14945 		name.append("GVEC2_GVEC2");
14946 		break;
14947 	case GVEC2_SCALAR_SCALAR:
14948 		name.append("GVEC2_SCALAR_SCALAR");
14949 		break;
14950 	case SCALAR_GVEC2_SCALAR:
14951 		name.append("SCALAR_GVEC2_SCALAR");
14952 		break;
14953 	case SCALAR_SCALAR_GVEC2:
14954 		name.append("SCALAR_SCALAR_GVEC2");
14955 		break;
14956 	case SCALAR_SCALAR_SCALAR_SCALAR:
14957 		name.append("SCALAR_SCALAR_SCALAR_SCALAR");
14958 		break;
14959 	}
14960 
14961 	return name;
14962 }
14963 
14964 /** Returns number of types to test
14965  *
14966  * @return Number of types
14967  **/
14968 glw::GLuint VaryingComponentsTest::getTestCaseNumber()
14969 {
14970 	return static_cast<GLuint>(m_test_cases.size());
14971 }
14972 
14973 /* Prepare test cases */
14974 void VaryingComponentsTest::testInit()
14975 {
14976 	m_test_cases.push_back(testCase(G64VEC2, Utils::Type::Double));
14977 	m_test_cases.push_back(testCase(G64SCALAR_G64SCALAR, Utils::Type::Double));
14978 
14979 	m_test_cases.push_back(testCase(GVEC4, Utils::Type::Float));
14980 	m_test_cases.push_back(testCase(SCALAR_GVEC3, Utils::Type::Float));
14981 	m_test_cases.push_back(testCase(GVEC3_SCALAR, Utils::Type::Float));
14982 	m_test_cases.push_back(testCase(GVEC2_GVEC2, Utils::Type::Float));
14983 	m_test_cases.push_back(testCase(GVEC2_SCALAR_SCALAR, Utils::Type::Float));
14984 	m_test_cases.push_back(testCase(SCALAR_GVEC2_SCALAR, Utils::Type::Float));
14985 	m_test_cases.push_back(testCase(SCALAR_SCALAR_GVEC2, Utils::Type::Float));
14986 	m_test_cases.push_back(testCase(SCALAR_SCALAR_SCALAR_SCALAR, Utils::Type::Float));
14987 
14988 	m_test_cases.push_back(testCase(GVEC4, Utils::Type::Int));
14989 	m_test_cases.push_back(testCase(SCALAR_GVEC3, Utils::Type::Int));
14990 	m_test_cases.push_back(testCase(GVEC3_SCALAR, Utils::Type::Int));
14991 	m_test_cases.push_back(testCase(GVEC2_GVEC2, Utils::Type::Int));
14992 	m_test_cases.push_back(testCase(GVEC2_SCALAR_SCALAR, Utils::Type::Int));
14993 	m_test_cases.push_back(testCase(SCALAR_GVEC2_SCALAR, Utils::Type::Int));
14994 	m_test_cases.push_back(testCase(SCALAR_SCALAR_GVEC2, Utils::Type::Int));
14995 	m_test_cases.push_back(testCase(SCALAR_SCALAR_SCALAR_SCALAR, Utils::Type::Int));
14996 
14997 	m_test_cases.push_back(testCase(GVEC4, Utils::Type::Uint));
14998 	m_test_cases.push_back(testCase(SCALAR_GVEC3, Utils::Type::Uint));
14999 	m_test_cases.push_back(testCase(GVEC3_SCALAR, Utils::Type::Uint));
15000 	m_test_cases.push_back(testCase(GVEC2_GVEC2, Utils::Type::Uint));
15001 	m_test_cases.push_back(testCase(GVEC2_SCALAR_SCALAR, Utils::Type::Uint));
15002 	m_test_cases.push_back(testCase(SCALAR_GVEC2_SCALAR, Utils::Type::Uint));
15003 	m_test_cases.push_back(testCase(SCALAR_SCALAR_GVEC2, Utils::Type::Uint));
15004 	m_test_cases.push_back(testCase(SCALAR_SCALAR_SCALAR_SCALAR, Utils::Type::Uint));
15005 }
15006 
15007 /** Inform that test use components
15008  *
15009  * @param ignored
15010  *
15011  * @return true
15012  **/
15013 bool VaryingComponentsTest::useComponentQualifier(glw::GLuint /* test_case_index */)
15014 {
15015 	return true;
15016 }
15017 
15018 /** Get length of arrays that should be used during test
15019  *
15020  * @return 0u - no array at all
15021  **/
15022 GLuint VaryingComponentsTest::getArrayLength()
15023 {
15024 	return 0;
15025 }
15026 
15027 std::string VaryingComponentsTest::prepareGlobals(GLuint last_in_location, GLuint last_out_location)
15028 {
15029 	std::string globals = VaryingLocationsTest::prepareGlobals(last_in_location, last_out_location);
15030 
15031 	globals.append("const uint comp_x = 0u;\n"
15032 				   "const uint comp_y = 1u;\n"
15033 				   "const uint comp_z = 2u;\n"
15034 				   "const uint comp_w = 3u;\n");
15035 
15036 	return globals;
15037 }
15038 
15039 /**
15040  *
15041  **/
15042 std::string VaryingComponentsTest::prepareName(const glw::GLchar* name, glw::GLint location, glw::GLint component,
15043 											   Utils::Shader::STAGES stage, Utils::Variable::STORAGE storage)
15044 {
15045 	GLchar		  buffer[16];
15046 	std::string   result   = "PREFIXNAME_lLOCATION_cCOMPONENT";
15047 	size_t		  position = 0;
15048 	const GLchar* prefix   = Utils::ProgramInterface::GetStagePrefix(stage, storage);
15049 
15050 	Utils::replaceToken("PREFIX", position, prefix, result);
15051 	Utils::replaceToken("NAME", position, name, result);
15052 
15053 	sprintf(buffer, "%d", location);
15054 	Utils::replaceToken("LOCATION", position, buffer, result);
15055 
15056 	sprintf(buffer, "%d", component);
15057 	Utils::replaceToken("COMPONENT", position, buffer, result);
15058 
15059 	return result;
15060 }
15061 
15062 std::string VaryingComponentsTest::prepareQualifiers(const glw::GLchar* location, const glw::GLchar* component,
15063 													 const glw::GLchar* interpolation)
15064 {
15065 	size_t		position   = 0;
15066 	std::string qualifiers = "layout (location = LOCATION, component = COMPONENT) INTERPOLATION";
15067 
15068 	Utils::replaceToken("LOCATION", position, location, qualifiers);
15069 	Utils::replaceToken("COMPONENT", position, component, qualifiers);
15070 	Utils::replaceToken("INTERPOLATION", position, interpolation, qualifiers);
15071 
15072 	return qualifiers;
15073 }
15074 
15075 /**
15076  *
15077  **/
15078 void VaryingComponentsTest::prepareShaderStage(Utils::Shader::STAGES stage, const Utils::Type& vector_type,
15079 											   Utils::ProgramInterface& program_interface, const testCase& test_case,
15080 											   Utils::VaryingPassthrough& varying_passthrough)
15081 {
15082 	const GLuint			array_length = getArrayLength();
15083 	const Utils::Type&		basic_type = Utils::Type::GetType(vector_type.m_basic_type, 1 /* n_cols */, 1 /* n_rows */);
15084 	descriptor				desc_in[8];
15085 	descriptor				desc_out[8];
15086 	const GLuint			first_in_loc  = 0;
15087 	const GLuint			first_out_loc = 0;
15088 	const GLchar*			interpolation = "";
15089 	const GLuint			last_in_loc   = getLastInputLocation(stage, vector_type, array_length, false);
15090 	GLuint					last_out_loc  = 0;
15091 	GLuint					n_desc		  = 0;
15092 	Utils::ShaderInterface& si			  = program_interface.GetShaderInterface(stage);
15093 
15094 	/* Select interpolation */
15095 	if ((Utils::Shader::FRAGMENT == stage) || (Utils::Shader::GEOMETRY == stage))
15096 	{
15097 		interpolation = " flat";
15098 	}
15099 
15100 	if (Utils::Shader::FRAGMENT != stage)
15101 	{
15102 		last_out_loc = getLastOutputLocation(stage, vector_type, array_length, false);
15103 	}
15104 
15105 	switch (test_case.m_layout)
15106 	{
15107 	case G64VEC2:
15108 		n_desc = 2;
15109 		desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 2, "g64vec2");
15110 		desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 2, "g64vec2");
15111 
15112 		desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 2, "g64vec2");
15113 		desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 2, "g64vec2");
15114 		break;
15115 
15116 	case G64SCALAR_G64SCALAR:
15117 		n_desc = 4;
15118 		desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "g64scalar");
15119 		desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "g64scalar");
15120 		desc_in[2].assign(2, "comp_z", first_in_loc, "first_input_location", 1, "g64scalar");
15121 		desc_in[3].assign(2, "comp_z", last_in_loc, "last_input_location", 1, "g64scalar");
15122 
15123 		desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "g64scalar");
15124 		desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "g64scalar");
15125 		desc_out[2].assign(2, "comp_z", first_out_loc, "first_output_location", 1, "g64scalar");
15126 		desc_out[3].assign(2, "comp_z", last_out_loc, "last_output_location", 1, "g64scalar");
15127 		break;
15128 	case GVEC4:
15129 		n_desc = 2;
15130 		desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 4, "gvec4");
15131 		desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 4, "gvec4");
15132 
15133 		desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 4, "gvec4");
15134 		desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 4, "gvec4");
15135 		break;
15136 	case SCALAR_GVEC3:
15137 		n_desc = 4;
15138 		desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "scalar");
15139 		desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "scalar");
15140 		desc_in[2].assign(1, "comp_y", first_in_loc, "first_input_location", 3, "gvec3");
15141 		desc_in[3].assign(1, "comp_y", last_in_loc, "last_input_location", 3, "gvec3");
15142 
15143 		desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "scalar");
15144 		desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "scalar");
15145 		desc_out[2].assign(1, "comp_y", first_out_loc, "first_output_location", 3, "gvec3");
15146 		desc_out[3].assign(1, "comp_y", last_out_loc, "last_output_location", 3, "gvec3");
15147 		break;
15148 	case GVEC3_SCALAR:
15149 		n_desc = 4;
15150 		desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 3, "gvec3");
15151 		desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 3, "gvec3");
15152 		desc_in[2].assign(3, "comp_w", first_in_loc, "first_input_location", 1, "scalar");
15153 		desc_in[3].assign(3, "comp_w", last_in_loc, "last_input_location", 1, "scalar");
15154 
15155 		desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 3, "gvec3");
15156 		desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 3, "gvec3");
15157 		desc_out[2].assign(3, "comp_w", first_out_loc, "first_output_location", 1, "scalar");
15158 		desc_out[3].assign(3, "comp_w", last_out_loc, "last_output_location", 1, "scalar");
15159 		break;
15160 	case GVEC2_GVEC2:
15161 		n_desc = 4;
15162 		desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 2, "gvec2");
15163 		desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 2, "gvec2");
15164 		desc_in[2].assign(2, "comp_z", first_in_loc, "first_input_location", 2, "gvec2");
15165 		desc_in[3].assign(2, "comp_z", last_in_loc, "last_input_location", 2, "gvec2");
15166 
15167 		desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 2, "gvec2");
15168 		desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 2, "gvec2");
15169 		desc_out[2].assign(2, "comp_z", first_out_loc, "first_output_location", 2, "gvec2");
15170 		desc_out[3].assign(2, "comp_z", last_out_loc, "last_output_location", 2, "gvec2");
15171 		break;
15172 	case GVEC2_SCALAR_SCALAR:
15173 		n_desc = 6;
15174 		desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 2, "gvec2");
15175 		desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 2, "gvec2");
15176 		desc_in[2].assign(2, "comp_z", first_in_loc, "first_input_location", 1, "scalar");
15177 		desc_in[3].assign(2, "comp_z", last_in_loc, "last_input_location", 1, "scalar");
15178 		desc_in[4].assign(3, "comp_w", first_in_loc, "first_input_location", 1, "scalar");
15179 		desc_in[5].assign(3, "comp_w", last_in_loc, "last_input_location", 1, "scalar");
15180 
15181 		desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 2, "gvec2");
15182 		desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 2, "gvec2");
15183 		desc_out[2].assign(2, "comp_z", first_out_loc, "first_output_location", 1, "scalar");
15184 		desc_out[3].assign(2, "comp_z", last_out_loc, "last_output_location", 1, "scalar");
15185 		desc_out[4].assign(3, "comp_w", first_out_loc, "first_output_location", 1, "scalar");
15186 		desc_out[5].assign(3, "comp_w", last_out_loc, "last_output_location", 1, "scalar");
15187 		break;
15188 	case SCALAR_GVEC2_SCALAR:
15189 		n_desc = 6;
15190 		desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "scalar");
15191 		desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "scalar");
15192 		desc_in[2].assign(1, "comp_y", first_in_loc, "first_input_location", 2, "gvec2");
15193 		desc_in[3].assign(1, "comp_y", last_in_loc, "last_input_location", 2, "gvec2");
15194 		desc_in[4].assign(3, "comp_w", first_in_loc, "first_input_location", 1, "scalar");
15195 		desc_in[5].assign(3, "comp_w", last_in_loc, "last_input_location", 1, "scalar");
15196 
15197 		desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "scalar");
15198 		desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "scalar");
15199 		desc_out[2].assign(1, "comp_y", first_out_loc, "first_output_location", 2, "gvec2");
15200 		desc_out[3].assign(1, "comp_y", last_out_loc, "last_output_location", 2, "gvec2");
15201 		desc_out[4].assign(3, "comp_w", first_out_loc, "first_output_location", 1, "scalar");
15202 		desc_out[5].assign(3, "comp_w", last_out_loc, "last_output_location", 1, "scalar");
15203 		break;
15204 	case SCALAR_SCALAR_GVEC2:
15205 		n_desc = 6;
15206 		desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "scalar");
15207 		desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "scalar");
15208 		desc_in[2].assign(1, "comp_y", first_in_loc, "first_input_location", 1, "scalar");
15209 		desc_in[3].assign(1, "comp_y", last_in_loc, "last_input_location", 1, "scalar");
15210 		desc_in[4].assign(2, "comp_z", first_in_loc, "first_input_location", 2, "gvec2");
15211 		desc_in[5].assign(2, "comp_z", last_in_loc, "last_input_location", 2, "gvec2");
15212 
15213 		desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "scalar");
15214 		desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "scalar");
15215 		desc_out[2].assign(1, "comp_y", first_out_loc, "first_output_location", 1, "scalar");
15216 		desc_out[3].assign(1, "comp_y", last_out_loc, "last_output_location", 1, "scalar");
15217 		desc_out[4].assign(2, "comp_z", first_out_loc, "first_output_location", 2, "gvec2");
15218 		desc_out[5].assign(2, "comp_z", last_out_loc, "last_output_location", 2, "gvec2");
15219 		break;
15220 	case SCALAR_SCALAR_SCALAR_SCALAR:
15221 		n_desc = 8;
15222 		desc_in[0].assign(0, "comp_x", first_in_loc, "first_input_location", 1, "scalar");
15223 		desc_in[1].assign(0, "comp_x", last_in_loc, "last_input_location", 1, "scalar");
15224 		desc_in[2].assign(1, "comp_y", first_in_loc, "first_input_location", 1, "scalar");
15225 		desc_in[3].assign(1, "comp_y", last_in_loc, "last_input_location", 1, "scalar");
15226 		desc_in[4].assign(2, "comp_z", first_in_loc, "first_input_location", 1, "scalar");
15227 		desc_in[5].assign(2, "comp_z", last_in_loc, "last_input_location", 1, "scalar");
15228 		desc_in[6].assign(3, "comp_w", first_in_loc, "first_input_location", 1, "scalar");
15229 		desc_in[7].assign(3, "comp_w", last_in_loc, "last_input_location", 1, "scalar");
15230 
15231 		desc_out[0].assign(0, "comp_x", first_out_loc, "first_output_location", 1, "scalar");
15232 		desc_out[1].assign(0, "comp_x", last_out_loc, "last_output_location", 1, "scalar");
15233 		desc_out[2].assign(1, "comp_y", first_out_loc, "first_output_location", 1, "scalar");
15234 		desc_out[3].assign(1, "comp_y", last_out_loc, "last_output_location", 1, "scalar");
15235 		desc_out[4].assign(2, "comp_z", first_out_loc, "first_output_location", 1, "scalar");
15236 		desc_out[5].assign(2, "comp_z", last_out_loc, "last_output_location", 1, "scalar");
15237 		desc_out[6].assign(3, "comp_w", first_out_loc, "first_output_location", 1, "scalar");
15238 		desc_out[7].assign(3, "comp_w", last_out_loc, "last_output_location", 1, "scalar");
15239 		break;
15240 	}
15241 
15242 	for (GLuint i = 0; i < n_desc; ++i)
15243 	{
15244 		const descriptor& in_desc = desc_in[i];
15245 
15246 		Utils::Variable* in =
15247 			prepareVarying(basic_type, in_desc, interpolation, si, stage, Utils::Variable::VARYING_INPUT);
15248 
15249 		if (Utils::Shader::FRAGMENT != stage)
15250 		{
15251 			const descriptor& out_desc = desc_out[i];
15252 
15253 			Utils::Variable* out =
15254 				prepareVarying(basic_type, out_desc, interpolation, si, stage, Utils::Variable::VARYING_OUTPUT);
15255 
15256 			varying_passthrough.Add(stage, in, out);
15257 		}
15258 	}
15259 
15260 	si.m_globals = prepareGlobals(last_in_loc, last_out_loc);
15261 }
15262 
15263 /**
15264  *
15265  **/
15266 Utils::Variable* VaryingComponentsTest::prepareVarying(const Utils::Type& basic_type, const descriptor& desc,
15267 													   const GLchar* interpolation, Utils::ShaderInterface& si,
15268 													   Utils::Shader::STAGES stage, Utils::Variable::STORAGE storage)
15269 {
15270 	const GLuint	   array_length   = getArrayLength();
15271 	const GLuint	   component_size = Utils::Type::_float.GetSize();
15272 	const std::string& name			  = prepareName(desc.m_name, desc.m_location, desc.m_component, stage, storage);
15273 	const GLuint	   offset		  = desc.m_component * component_size;
15274 	const std::string& qual			  = prepareQualifiers(desc.m_location_str, desc.m_component_str, interpolation);
15275 	const GLuint	   size			  = desc.m_n_rows * basic_type.GetSize();
15276 	const Utils::Type& type			  = Utils::Type::GetType(basic_type.m_basic_type, 1 /* n_columns */, desc.m_n_rows);
15277 	Utils::Variable*   var			  = 0;
15278 
15279 	if (Utils::Variable::VARYING_INPUT == storage)
15280 	{
15281 		var = si.Input(name.c_str(), qual.c_str() /* qualifiers */, desc.m_component /* expected_componenet */,
15282 					   desc.m_location /* expected_location */, type, /* built_in_type */
15283 					   GL_FALSE /* normalized */, array_length /* n_array_elements */, 0u /* stride */,
15284 					   offset /* offset */, (GLvoid*)&m_data[offset] /* data */, size /* data_size */);
15285 	}
15286 	else
15287 	{
15288 		var = si.Output(name.c_str(), qual.c_str() /* qualifiers */, desc.m_component /* expected_componenet */,
15289 						desc.m_location /* expected_location */, type, /* built_in_type */
15290 						GL_FALSE /* normalized */, array_length /* n_array_elements */, 0u /* stride */,
15291 						offset /* offset */, (GLvoid*)&m_data[offset] /* data */, size /* data_size */);
15292 	}
15293 
15294 	return var;
15295 }
15296 
15297 void VaryingComponentsTest::descriptor::assign(glw::GLint component, const glw::GLchar* component_str,
15298 											   glw::GLint location, const glw::GLchar* location_str, glw::GLuint n_rows,
15299 											   const glw::GLchar* name)
15300 {
15301 	m_component		= component;
15302 	m_component_str = component_str;
15303 	m_location		= location;
15304 	m_location_str  = location_str;
15305 	m_n_rows		= n_rows;
15306 	m_name			= name;
15307 }
15308 
15309 VaryingComponentsTest::testCase::testCase(COMPONENTS_LAYOUT layout, Utils::Type::TYPES type)
15310 	: m_layout(layout), m_type(type)
15311 {
15312 }
15313 
15314 /** Constructor
15315  *
15316  * @param context Test framework context
15317  **/
15318 VaryingArrayComponentsTest::VaryingArrayComponentsTest(deqp::Context& context)
15319 	: VaryingComponentsTest(context, "varying_array_components",
15320 							"Test verifies that input and output components are respected for arrays")
15321 {
15322 }
15323 
15324 /** Get length of arrays that should be used during test
15325  *
15326  * @return 4u
15327  **/
15328 GLuint VaryingArrayComponentsTest::getArrayLength()
15329 {
15330 	return 4u;
15331 }
15332 
15333 /** Constructor
15334  *
15335  * @param context Test framework context
15336  **/
15337 VaryingInvalidValueComponentTest::VaryingInvalidValueComponentTest(deqp::Context& context)
15338 	: NegativeTestBase(context, "varying_invalid_value_component", "Test verifies that compiler reports error when "
15339 																   "using an invalid value in the component "
15340 																   "qualification for a specific type")
15341 {
15342 }
15343 
15344 /** Source for given test case and stage
15345  *
15346  * @param test_case_index Index of test case
15347  * @param stage           Shader stage
15348  *
15349  * @return Shader source
15350  **/
15351 std::string VaryingInvalidValueComponentTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
15352 {
15353 #if DEBUG_NEG_REMOVE_ERROR
15354 	static const GLchar* var_definition_arr =
15355 		"layout (location = 1 /*, component = COMPONENT */) FLAT DIRECTION TYPE gokuARRAY[1];\n";
15356 	static const GLchar* var_definition_one =
15357 		"layout (location = 1 /*, component = COMPONENT */) FLAT DIRECTION TYPE gokuARRAY;\n";
15358 #else
15359 	static const GLchar* var_definition_arr =
15360 		"layout (location = 1, component = COMPONENT) FLAT DIRECTION TYPE gokuARRAY[1];\n";
15361 	static const GLchar* var_definition_one =
15362 		"layout (location = 1, component = COMPONENT) FLAT DIRECTION TYPE gokuARRAY;\n";
15363 #endif /* DEBUG_NEG_REMOVE_ERROR */
15364 	static const GLchar* input_use_arr = "    if (TYPE(0) == gokuINDEX[0])\n"
15365 										 "    {\n"
15366 										 "        result += vec4(1, 0.5, 0.25, 0.125);\n"
15367 										 "    }\n";
15368 	static const GLchar* input_use_one = "    if (TYPE(0) == gokuINDEX)\n"
15369 										 "    {\n"
15370 										 "        result += vec4(1, 0.5, 0.25, 0.125);\n"
15371 										 "    }\n";
15372 	static const GLchar* output_use_arr = "    gokuINDEX[0] = TYPE(0);\n"
15373 										  "    if (vec4(0) == result)\n"
15374 										  "    {\n"
15375 										  "        gokuINDEX[0] = TYPE(1);\n"
15376 										  "    }\n";
15377 	static const GLchar* output_use_one = "    gokuINDEX = TYPE(0);\n"
15378 										  "    if (vec4(0) == result)\n"
15379 										  "    {\n"
15380 										  "        gokuINDEX = TYPE(1);\n"
15381 										  "    }\n";
15382 	static const GLchar* fs = "#version 430 core\n"
15383 							  "#extension GL_ARB_enhanced_layouts : require\n"
15384 							  "\n"
15385 							  "in  vec4 gs_fs;\n"
15386 							  "out vec4 fs_out;\n"
15387 							  "\n"
15388 							  "void main()\n"
15389 							  "{\n"
15390 							  "    fs_out = gs_fs;\n"
15391 							  "}\n"
15392 							  "\n";
15393 	static const GLchar* fs_tested = "#version 430 core\n"
15394 									 "#extension GL_ARB_enhanced_layouts : require\n"
15395 									 "\n"
15396 									 "VAR_DEFINITION"
15397 									 "\n"
15398 									 "in  vec4 gs_fs;\n"
15399 									 "out vec4 fs_out;\n"
15400 									 "\n"
15401 									 "void main()\n"
15402 									 "{\n"
15403 									 "    vec4 result = gs_fs;\n"
15404 									 "\n"
15405 									 "VARIABLE_USE"
15406 									 "\n"
15407 									 "    fs_out += result;\n"
15408 									 "}\n"
15409 									 "\n";
15410 	static const GLchar* gs = "#version 430 core\n"
15411 							  "#extension GL_ARB_enhanced_layouts : require\n"
15412 							  "\n"
15413 							  "layout(points)                           in;\n"
15414 							  "layout(triangle_strip, max_vertices = 4) out;\n"
15415 							  "\n"
15416 							  "in  vec4 tes_gs[];\n"
15417 							  "out vec4 gs_fs;\n"
15418 							  "\n"
15419 							  "void main()\n"
15420 							  "{\n"
15421 							  "    gs_fs = tes_gs[0];\n"
15422 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
15423 							  "    EmitVertex();\n"
15424 							  "    gs_fs = tes_gs[0];\n"
15425 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
15426 							  "    EmitVertex();\n"
15427 							  "    gs_fs = tes_gs[0];\n"
15428 							  "    gl_Position  = vec4(1, -1, 0, 1);\n"
15429 							  "    EmitVertex();\n"
15430 							  "    gs_fs = tes_gs[0];\n"
15431 							  "    gl_Position  = vec4(1, 1, 0, 1);\n"
15432 							  "    EmitVertex();\n"
15433 							  "}\n"
15434 							  "\n";
15435 	static const GLchar* gs_tested = "#version 430 core\n"
15436 									 "#extension GL_ARB_enhanced_layouts : require\n"
15437 									 "\n"
15438 									 "layout(points)                           in;\n"
15439 									 "layout(triangle_strip, max_vertices = 4) out;\n"
15440 									 "\n"
15441 									 "VAR_DEFINITION"
15442 									 "\n"
15443 									 "in  vec4 tes_gs[];\n"
15444 									 "out vec4 gs_fs;\n"
15445 									 "\n"
15446 									 "void main()\n"
15447 									 "{\n"
15448 									 "    vec4 result = tes_gs[0];\n"
15449 									 "\n"
15450 									 "VARIABLE_USE"
15451 									 "\n"
15452 									 "    gs_fs = result;\n"
15453 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
15454 									 "    EmitVertex();\n"
15455 									 "    gs_fs = result;\n"
15456 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
15457 									 "    EmitVertex();\n"
15458 									 "    gs_fs = result;\n"
15459 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
15460 									 "    EmitVertex();\n"
15461 									 "    gs_fs = result;\n"
15462 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
15463 									 "    EmitVertex();\n"
15464 									 "}\n"
15465 									 "\n";
15466 	static const GLchar* tcs = "#version 430 core\n"
15467 							   "#extension GL_ARB_enhanced_layouts : require\n"
15468 							   "\n"
15469 							   "layout(vertices = 1) out;\n"
15470 							   "\n"
15471 							   "in  vec4 vs_tcs[];\n"
15472 							   "out vec4 tcs_tes[];\n"
15473 							   "\n"
15474 							   "void main()\n"
15475 							   "{\n"
15476 							   "\n"
15477 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
15478 							   "\n"
15479 							   "    gl_TessLevelOuter[0] = 1.0;\n"
15480 							   "    gl_TessLevelOuter[1] = 1.0;\n"
15481 							   "    gl_TessLevelOuter[2] = 1.0;\n"
15482 							   "    gl_TessLevelOuter[3] = 1.0;\n"
15483 							   "    gl_TessLevelInner[0] = 1.0;\n"
15484 							   "    gl_TessLevelInner[1] = 1.0;\n"
15485 							   "}\n"
15486 							   "\n";
15487 	static const GLchar* tcs_tested = "#version 430 core\n"
15488 									  "#extension GL_ARB_enhanced_layouts : require\n"
15489 									  "\n"
15490 									  "layout(vertices = 1) out;\n"
15491 									  "\n"
15492 									  "VAR_DEFINITION"
15493 									  "\n"
15494 									  "in  vec4 vs_tcs[];\n"
15495 									  "out vec4 tcs_tes[];\n"
15496 									  "\n"
15497 									  "void main()\n"
15498 									  "{\n"
15499 									  "    vec4 result = vs_tcs[gl_InvocationID];\n"
15500 									  "\n"
15501 									  "VARIABLE_USE"
15502 									  "\n"
15503 									  "    tcs_tes[gl_InvocationID] = result;\n"
15504 									  "\n"
15505 									  "    gl_TessLevelOuter[0] = 1.0;\n"
15506 									  "    gl_TessLevelOuter[1] = 1.0;\n"
15507 									  "    gl_TessLevelOuter[2] = 1.0;\n"
15508 									  "    gl_TessLevelOuter[3] = 1.0;\n"
15509 									  "    gl_TessLevelInner[0] = 1.0;\n"
15510 									  "    gl_TessLevelInner[1] = 1.0;\n"
15511 									  "}\n"
15512 									  "\n";
15513 	static const GLchar* tes = "#version 430 core\n"
15514 							   "#extension GL_ARB_enhanced_layouts : require\n"
15515 							   "\n"
15516 							   "layout(isolines, point_mode) in;\n"
15517 							   "\n"
15518 							   "in  vec4 tcs_tes[];\n"
15519 							   "out vec4 tes_gs;\n"
15520 							   "\n"
15521 							   "void main()\n"
15522 							   "{\n"
15523 							   "    tes_gs = tcs_tes[0];\n"
15524 							   "}\n"
15525 							   "\n";
15526 	static const GLchar* tes_tested = "#version 430 core\n"
15527 									  "#extension GL_ARB_enhanced_layouts : require\n"
15528 									  "\n"
15529 									  "layout(isolines, point_mode) in;\n"
15530 									  "\n"
15531 									  "VAR_DEFINITION"
15532 									  "\n"
15533 									  "in  vec4 tcs_tes[];\n"
15534 									  "out vec4 tes_gs;\n"
15535 									  "\n"
15536 									  "void main()\n"
15537 									  "{\n"
15538 									  "    vec4 result = tcs_tes[0];\n"
15539 									  "\n"
15540 									  "VARIABLE_USE"
15541 									  "\n"
15542 									  "    tes_gs += result;\n"
15543 									  "}\n"
15544 									  "\n";
15545 	static const GLchar* vs = "#version 430 core\n"
15546 							  "#extension GL_ARB_enhanced_layouts : require\n"
15547 							  "\n"
15548 							  "in  vec4 in_vs;\n"
15549 							  "out vec4 vs_tcs;\n"
15550 							  "\n"
15551 							  "void main()\n"
15552 							  "{\n"
15553 							  "    vs_tcs = in_vs;\n"
15554 							  "}\n"
15555 							  "\n";
15556 	static const GLchar* vs_tested = "#version 430 core\n"
15557 									 "#extension GL_ARB_enhanced_layouts : require\n"
15558 									 "\n"
15559 									 "VAR_DEFINITION"
15560 									 "\n"
15561 									 "in  vec4 in_vs;\n"
15562 									 "out vec4 vs_tcs;\n"
15563 									 "\n"
15564 									 "void main()\n"
15565 									 "{\n"
15566 									 "    vec4 result = in_vs;\n"
15567 									 "\n"
15568 									 "VARIABLE_USE"
15569 									 "\n"
15570 									 "    vs_tcs += result;\n"
15571 									 "}\n"
15572 									 "\n";
15573 
15574 	std::string source;
15575 	testCase&   test_case = m_test_cases[test_case_index];
15576 
15577 	if (test_case.m_stage == stage)
15578 	{
15579 		const GLchar* array = "";
15580 		GLchar		  buffer[16];
15581 		const GLchar* var_definition = 0;
15582 		const GLchar*			 direction		= "in";
15583 		const GLchar* index			 = "";
15584 		size_t		  position		 = 0;
15585 		const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
15586 		const GLchar* var_use   = 0;
15587 		Utils::Variable::STORAGE storage   = Utils::Variable::VARYING_INPUT;
15588 		const GLchar*			 flat	  = "";
15589 
15590 		if (false == test_case.m_is_input)
15591 		{
15592 			direction = "out";
15593 			storage   = Utils::Variable::VARYING_OUTPUT;
15594 
15595 			if (false == test_case.m_is_array)
15596 			{
15597 				var_definition = var_definition_one;
15598 				var_use		   = output_use_one;
15599 			}
15600 			else
15601 			{
15602 				var_definition = var_definition_arr;
15603 				var_use		   = output_use_arr;
15604 			}
15605 		}
15606 		else
15607 		{
15608 			if (false == test_case.m_is_array)
15609 			{
15610 				var_definition = var_definition_one;
15611 				var_use		   = Utils::Shader::VERTEX == stage ? input_use_one : "\n";
15612 			}
15613 			else
15614 			{
15615 				var_definition = var_definition_arr;
15616 				var_use		   = Utils::Shader::VERTEX == stage ? input_use_arr : "\n";
15617 			}
15618 		}
15619 
15620 		if (isFlatRequired(stage, test_case.m_type, storage, true))
15621 		{
15622 			flat = "flat";
15623 		}
15624 
15625 		sprintf(buffer, "%d", test_case.m_component);
15626 
15627 		switch (stage)
15628 		{
15629 		case Utils::Shader::FRAGMENT:
15630 			source = fs_tested;
15631 			break;
15632 		case Utils::Shader::GEOMETRY:
15633 			source = gs_tested;
15634 			array  = test_case.m_is_input ? "[]" : "";
15635 			index  = test_case.m_is_input ? "[0]" : "";
15636 			break;
15637 		case Utils::Shader::TESS_CTRL:
15638 			source = tcs_tested;
15639 			array  = "[]";
15640 			index  = "[gl_InvocationID]";
15641 			break;
15642 		case Utils::Shader::TESS_EVAL:
15643 			source = tes_tested;
15644 			array  = test_case.m_is_input ? "[]" : "";
15645 			index  = test_case.m_is_input ? "[0]" : "";
15646 			break;
15647 		case Utils::Shader::VERTEX:
15648 			source = vs_tested;
15649 			break;
15650 		default:
15651 			TCU_FAIL("Invalid enum");
15652 		}
15653 
15654 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
15655 		position = 0;
15656 		Utils::replaceToken("COMPONENT", position, buffer, source);
15657 		Utils::replaceToken("FLAT", position, flat, source);
15658 		Utils::replaceToken("DIRECTION", position, direction, source);
15659 		Utils::replaceToken("ARRAY", position, array, source);
15660 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
15661 
15662 		Utils::replaceAllTokens("TYPE", type_name, source);
15663 		Utils::replaceAllTokens("INDEX", index, source);
15664 	}
15665 	else
15666 	{
15667 		switch (stage)
15668 		{
15669 		case Utils::Shader::FRAGMENT:
15670 			source = fs;
15671 			break;
15672 		case Utils::Shader::GEOMETRY:
15673 			source = gs;
15674 			break;
15675 		case Utils::Shader::TESS_CTRL:
15676 			source = tcs;
15677 			break;
15678 		case Utils::Shader::TESS_EVAL:
15679 			source = tes;
15680 			break;
15681 		case Utils::Shader::VERTEX:
15682 			source = vs;
15683 			break;
15684 		default:
15685 			TCU_FAIL("Invalid enum");
15686 		}
15687 	}
15688 
15689 	return source;
15690 }
15691 
15692 /** Get description of test case
15693  *
15694  * @param test_case_index Index of test case
15695  *
15696  * @return Test case description
15697  **/
15698 std::string VaryingInvalidValueComponentTest::getTestCaseName(GLuint test_case_index)
15699 {
15700 	std::stringstream stream;
15701 	testCase&		  test_case = m_test_cases[test_case_index];
15702 
15703 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
15704 		   << " type: " << test_case.m_type.GetGLSLTypeName();
15705 
15706 	if (true == test_case.m_is_array)
15707 	{
15708 		stream << "[1]";
15709 	}
15710 
15711 	stream << ", direction: ";
15712 
15713 	if (true == test_case.m_is_input)
15714 	{
15715 		stream << "input";
15716 	}
15717 	else
15718 	{
15719 		stream << "output";
15720 	}
15721 
15722 	stream << ", component: " << test_case.m_component;
15723 
15724 	return stream.str();
15725 }
15726 
15727 /** Get number of test cases
15728  *
15729  * @return Number of test cases
15730  **/
15731 GLuint VaryingInvalidValueComponentTest::getTestCaseNumber()
15732 {
15733 	return static_cast<GLuint>(m_test_cases.size());
15734 }
15735 
15736 /** Selects if "compute" stage is relevant for test
15737  *
15738  * @param ignored
15739  *
15740  * @return false
15741  **/
15742 bool VaryingInvalidValueComponentTest::isComputeRelevant(GLuint /* test_case_index */)
15743 {
15744 	return false;
15745 }
15746 
15747 /** Prepare all test cases
15748  *
15749  **/
15750 void VaryingInvalidValueComponentTest::testInit()
15751 {
15752 	const GLuint n_types = getTypesNumber();
15753 
15754 	for (GLuint i = 0; i < n_types; ++i)
15755 	{
15756 		const Utils::Type&		   type				= getType(i);
15757 		const std::vector<GLuint>& valid_components = type.GetValidComponents();
15758 
15759 		if (valid_components.empty())
15760 		{
15761 			continue;
15762 		}
15763 
15764 		std::vector<GLuint> every_component(4, 0);
15765 		every_component[1] = 1;
15766 		every_component[2] = 2;
15767 		every_component[3] = 3;
15768 		std::vector<GLuint> invalid_components;
15769 
15770 		std::set_symmetric_difference(every_component.begin(), every_component.end(), valid_components.begin(),
15771 									  valid_components.end(), back_inserter(invalid_components));
15772 
15773 		for (std::vector<GLuint>::const_iterator it_invalid_components = invalid_components.begin();
15774 			 it_invalid_components != invalid_components.end(); ++it_invalid_components)
15775 		{
15776 			for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
15777 			{
15778 				if (Utils::Shader::COMPUTE == stage)
15779 				{
15780 					continue;
15781 				}
15782 
15783 				testCase test_case_in_arr = { *it_invalid_components, true, true, (Utils::Shader::STAGES)stage, type };
15784 				testCase test_case_in_one = { *it_invalid_components, true, false, (Utils::Shader::STAGES)stage, type };
15785 				testCase test_case_out_arr = { *it_invalid_components, false, true, (Utils::Shader::STAGES)stage,
15786 											   type };
15787 				testCase test_case_out_one = { *it_invalid_components, false, false, (Utils::Shader::STAGES)stage,
15788 											   type };
15789 
15790 				m_test_cases.push_back(test_case_in_arr);
15791 				m_test_cases.push_back(test_case_in_one);
15792 
15793 				if (Utils::Shader::FRAGMENT != stage)
15794 				{
15795 					m_test_cases.push_back(test_case_out_arr);
15796 					m_test_cases.push_back(test_case_out_one);
15797 				}
15798 			}
15799 		}
15800 	}
15801 }
15802 
15803 /** Constructor
15804  *
15805  * @param context Test framework context
15806  **/
15807 VaryingExceedingComponentsTest::VaryingExceedingComponentsTest(deqp::Context& context)
15808 	: NegativeTestBase(context, "varying_exceeding_components",
15809 					   "Test verifies that compiler reports error when component qualifier exceeds limits")
15810 {
15811 }
15812 
15813 /** Source for given test case and stage
15814  *
15815  * @param test_case_index Index of test case
15816  * @param stage           Shader stage
15817  *
15818  * @return Shader source
15819  **/
15820 std::string VaryingExceedingComponentsTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
15821 {
15822 #if DEBUG_NEG_REMOVE_ERROR
15823 	static const GLchar* var_definition_arr =
15824 		"layout (location = 1 /*, component = 4 */) FLAT DIRECTION TYPE gokuARRAY[1];\n";
15825 	static const GLchar* var_definition_one =
15826 		"layout (location = 1 /*, component = 4 */) FLAT DIRECTION TYPE gokuARRAY;\n";
15827 #else
15828 	static const GLchar* var_definition_arr =
15829 		"layout (location = 1, component = 4) FLAT DIRECTION TYPE gokuARRAY[1];\n";
15830 	static const GLchar* var_definition_one = "layout (location = 1, component = 4) FLAT DIRECTION TYPE gokuARRAY;\n";
15831 #endif /* DEBUG_NEG_REMOVE_ERROR */
15832 	static const GLchar* input_use_arr = "    if (TYPE(0) == gokuINDEX[0])\n"
15833 										 "    {\n"
15834 										 "        result += vec4(1, 0.5, 0.25, 0.125);\n"
15835 										 "    }\n";
15836 	static const GLchar* input_use_one = "    if (TYPE(0) == gokuINDEX)\n"
15837 										 "    {\n"
15838 										 "        result += vec4(1, 0.5, 0.25, 0.125);\n"
15839 										 "    }\n";
15840 	static const GLchar* output_use_arr = "    gokuINDEX[0] = TYPE(0);\n"
15841 										  "    if (vec4(0) == result)\n"
15842 										  "    {\n"
15843 										  "        gokuINDEX[0] = TYPE(1);\n"
15844 										  "    }\n";
15845 	static const GLchar* output_use_one = "    gokuINDEX = TYPE(0);\n"
15846 										  "    if (vec4(0) == result)\n"
15847 										  "    {\n"
15848 										  "        gokuINDEX = TYPE(1);\n"
15849 										  "    }\n";
15850 	static const GLchar* fs = "#version 430 core\n"
15851 							  "#extension GL_ARB_enhanced_layouts : require\n"
15852 							  "\n"
15853 							  "in  vec4 gs_fs;\n"
15854 							  "out vec4 fs_out;\n"
15855 							  "\n"
15856 							  "void main()\n"
15857 							  "{\n"
15858 							  "    fs_out = gs_fs;\n"
15859 							  "}\n"
15860 							  "\n";
15861 	static const GLchar* fs_tested = "#version 430 core\n"
15862 									 "#extension GL_ARB_enhanced_layouts : require\n"
15863 									 "\n"
15864 									 "VAR_DEFINITION"
15865 									 "\n"
15866 									 "in  vec4 gs_fs;\n"
15867 									 "out vec4 fs_out;\n"
15868 									 "\n"
15869 									 "void main()\n"
15870 									 "{\n"
15871 									 "    vec4 result = gs_fs;\n"
15872 									 "\n"
15873 									 "VARIABLE_USE"
15874 									 "\n"
15875 									 "    fs_out += result;\n"
15876 									 "}\n"
15877 									 "\n";
15878 	static const GLchar* gs = "#version 430 core\n"
15879 							  "#extension GL_ARB_enhanced_layouts : require\n"
15880 							  "\n"
15881 							  "layout(points)                           in;\n"
15882 							  "layout(triangle_strip, max_vertices = 4) out;\n"
15883 							  "\n"
15884 							  "in  vec4 tes_gs[];\n"
15885 							  "out vec4 gs_fs;\n"
15886 							  "\n"
15887 							  "void main()\n"
15888 							  "{\n"
15889 							  "    gs_fs = tes_gs[0];\n"
15890 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
15891 							  "    EmitVertex();\n"
15892 							  "    gs_fs = tes_gs[0];\n"
15893 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
15894 							  "    EmitVertex();\n"
15895 							  "    gs_fs = tes_gs[0];\n"
15896 							  "    gl_Position  = vec4(1, -1, 0, 1);\n"
15897 							  "    EmitVertex();\n"
15898 							  "    gs_fs = tes_gs[0];\n"
15899 							  "    gl_Position  = vec4(1, 1, 0, 1);\n"
15900 							  "    EmitVertex();\n"
15901 							  "}\n"
15902 							  "\n";
15903 	static const GLchar* gs_tested = "#version 430 core\n"
15904 									 "#extension GL_ARB_enhanced_layouts : require\n"
15905 									 "\n"
15906 									 "layout(points)                           in;\n"
15907 									 "layout(triangle_strip, max_vertices = 4) out;\n"
15908 									 "\n"
15909 									 "VAR_DEFINITION"
15910 									 "\n"
15911 									 "in  vec4 tes_gs[];\n"
15912 									 "out vec4 gs_fs;\n"
15913 									 "\n"
15914 									 "void main()\n"
15915 									 "{\n"
15916 									 "    vec4 result = tes_gs[0];\n"
15917 									 "\n"
15918 									 "VARIABLE_USE"
15919 									 "\n"
15920 									 "    gs_fs = result;\n"
15921 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
15922 									 "    EmitVertex();\n"
15923 									 "    gs_fs = result;\n"
15924 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
15925 									 "    EmitVertex();\n"
15926 									 "    gs_fs = result;\n"
15927 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
15928 									 "    EmitVertex();\n"
15929 									 "    gs_fs = result;\n"
15930 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
15931 									 "    EmitVertex();\n"
15932 									 "}\n"
15933 									 "\n";
15934 	static const GLchar* tcs = "#version 430 core\n"
15935 							   "#extension GL_ARB_enhanced_layouts : require\n"
15936 							   "\n"
15937 							   "layout(vertices = 1) out;\n"
15938 							   "\n"
15939 							   "in  vec4 vs_tcs[];\n"
15940 							   "out vec4 tcs_tes[];\n"
15941 							   "\n"
15942 							   "void main()\n"
15943 							   "{\n"
15944 							   "\n"
15945 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
15946 							   "\n"
15947 							   "    gl_TessLevelOuter[0] = 1.0;\n"
15948 							   "    gl_TessLevelOuter[1] = 1.0;\n"
15949 							   "    gl_TessLevelOuter[2] = 1.0;\n"
15950 							   "    gl_TessLevelOuter[3] = 1.0;\n"
15951 							   "    gl_TessLevelInner[0] = 1.0;\n"
15952 							   "    gl_TessLevelInner[1] = 1.0;\n"
15953 							   "}\n"
15954 							   "\n";
15955 	static const GLchar* tcs_tested = "#version 430 core\n"
15956 									  "#extension GL_ARB_enhanced_layouts : require\n"
15957 									  "\n"
15958 									  "layout(vertices = 1) out;\n"
15959 									  "\n"
15960 									  "VAR_DEFINITION"
15961 									  "\n"
15962 									  "in  vec4 vs_tcs[];\n"
15963 									  "out vec4 tcs_tes[];\n"
15964 									  "\n"
15965 									  "void main()\n"
15966 									  "{\n"
15967 									  "    vec4 result = vs_tcs[gl_InvocationID];\n"
15968 									  "\n"
15969 									  "VARIABLE_USE"
15970 									  "\n"
15971 									  "    tcs_tes[gl_InvocationID] = result;\n"
15972 									  "\n"
15973 									  "    gl_TessLevelOuter[0] = 1.0;\n"
15974 									  "    gl_TessLevelOuter[1] = 1.0;\n"
15975 									  "    gl_TessLevelOuter[2] = 1.0;\n"
15976 									  "    gl_TessLevelOuter[3] = 1.0;\n"
15977 									  "    gl_TessLevelInner[0] = 1.0;\n"
15978 									  "    gl_TessLevelInner[1] = 1.0;\n"
15979 									  "}\n"
15980 									  "\n";
15981 	static const GLchar* tes = "#version 430 core\n"
15982 							   "#extension GL_ARB_enhanced_layouts : require\n"
15983 							   "\n"
15984 							   "layout(isolines, point_mode) in;\n"
15985 							   "\n"
15986 							   "in  vec4 tcs_tes[];\n"
15987 							   "out vec4 tes_gs;\n"
15988 							   "\n"
15989 							   "void main()\n"
15990 							   "{\n"
15991 							   "    tes_gs = tcs_tes[0];\n"
15992 							   "}\n"
15993 							   "\n";
15994 	static const GLchar* tes_tested = "#version 430 core\n"
15995 									  "#extension GL_ARB_enhanced_layouts : require\n"
15996 									  "\n"
15997 									  "layout(isolines, point_mode) in;\n"
15998 									  "\n"
15999 									  "VAR_DEFINITION"
16000 									  "\n"
16001 									  "in  vec4 tcs_tes[];\n"
16002 									  "out vec4 tes_gs;\n"
16003 									  "\n"
16004 									  "void main()\n"
16005 									  "{\n"
16006 									  "    vec4 result = tcs_tes[0];\n"
16007 									  "\n"
16008 									  "VARIABLE_USE"
16009 									  "\n"
16010 									  "    tes_gs += result;\n"
16011 									  "}\n"
16012 									  "\n";
16013 	static const GLchar* vs = "#version 430 core\n"
16014 							  "#extension GL_ARB_enhanced_layouts : require\n"
16015 							  "\n"
16016 							  "in  vec4 in_vs;\n"
16017 							  "out vec4 vs_tcs;\n"
16018 							  "\n"
16019 							  "void main()\n"
16020 							  "{\n"
16021 							  "    vs_tcs = in_vs;\n"
16022 							  "}\n"
16023 							  "\n";
16024 	static const GLchar* vs_tested = "#version 430 core\n"
16025 									 "#extension GL_ARB_enhanced_layouts : require\n"
16026 									 "\n"
16027 									 "VAR_DEFINITION"
16028 									 "\n"
16029 									 "in  vec4 in_vs;\n"
16030 									 "out vec4 vs_tcs;\n"
16031 									 "\n"
16032 									 "void main()\n"
16033 									 "{\n"
16034 									 "    vec4 result = in_vs;\n"
16035 									 "\n"
16036 									 "VARIABLE_USE"
16037 									 "\n"
16038 									 "    vs_tcs += result;\n"
16039 									 "}\n"
16040 									 "\n";
16041 
16042 	std::string source;
16043 	testCase&   test_case = m_test_cases[test_case_index];
16044 
16045 	if (test_case.m_stage == stage)
16046 	{
16047 		const GLchar*			 array			= "";
16048 		const GLchar*			 var_definition = 0;
16049 		const GLchar*			 direction		= "in";
16050 		const GLchar*			 index			= "";
16051 		size_t					 position		= 0;
16052 		const GLchar*			 type_name		= test_case.m_type.GetGLSLTypeName();
16053 		const GLchar*			 var_use		= 0;
16054 		Utils::Variable::STORAGE storage		= Utils::Variable::VARYING_INPUT;
16055 		const GLchar*			 flat			= "";
16056 
16057 		if (false == test_case.m_is_input)
16058 		{
16059 			direction = "out";
16060 			storage   = Utils::Variable::VARYING_OUTPUT;
16061 
16062 			if (false == test_case.m_is_array)
16063 			{
16064 				var_definition = var_definition_one;
16065 				var_use		   = output_use_one;
16066 			}
16067 			else
16068 			{
16069 				var_definition = var_definition_arr;
16070 				var_use		   = output_use_arr;
16071 			}
16072 		}
16073 		else
16074 		{
16075 			if (false == test_case.m_is_array)
16076 			{
16077 				var_definition = var_definition_one;
16078 				var_use		   = Utils::Shader::VERTEX == stage ? input_use_one : "\n";
16079 			}
16080 			else
16081 			{
16082 				var_definition = var_definition_arr;
16083 				var_use		   = Utils::Shader::VERTEX == stage ? input_use_arr : "\n";
16084 			}
16085 		}
16086 
16087 		if (isFlatRequired(stage, test_case.m_type, storage, true))
16088 		{
16089 			flat = "flat";
16090 		}
16091 
16092 		switch (stage)
16093 		{
16094 		case Utils::Shader::FRAGMENT:
16095 			source = fs_tested;
16096 			break;
16097 		case Utils::Shader::GEOMETRY:
16098 			source = gs_tested;
16099 			array  = test_case.m_is_input ? "[]" : "";
16100 			index  = test_case.m_is_input ? "[0]" : "";
16101 			break;
16102 		case Utils::Shader::TESS_CTRL:
16103 			source = tcs_tested;
16104 			array  = "[]";
16105 			index  = "[gl_InvocationID]";
16106 			break;
16107 		case Utils::Shader::TESS_EVAL:
16108 			source = tes_tested;
16109 			array  = test_case.m_is_input ? "[]" : "";
16110 			index  = test_case.m_is_input ? "[0]" : "";
16111 			break;
16112 		case Utils::Shader::VERTEX:
16113 			source = vs_tested;
16114 			break;
16115 		default:
16116 			TCU_FAIL("Invalid enum");
16117 		}
16118 
16119 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
16120 		position = 0;
16121 		Utils::replaceToken("FLAT", position, flat, source);
16122 		Utils::replaceToken("DIRECTION", position, direction, source);
16123 		Utils::replaceToken("ARRAY", position, array, source);
16124 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
16125 
16126 		Utils::replaceAllTokens("TYPE", type_name, source);
16127 		Utils::replaceAllTokens("INDEX", index, source);
16128 	}
16129 	else
16130 	{
16131 		switch (stage)
16132 		{
16133 		case Utils::Shader::FRAGMENT:
16134 			source = fs;
16135 			break;
16136 		case Utils::Shader::GEOMETRY:
16137 			source = gs;
16138 			break;
16139 		case Utils::Shader::TESS_CTRL:
16140 			source = tcs;
16141 			break;
16142 		case Utils::Shader::TESS_EVAL:
16143 			source = tes;
16144 			break;
16145 		case Utils::Shader::VERTEX:
16146 			source = vs;
16147 			break;
16148 		default:
16149 			TCU_FAIL("Invalid enum");
16150 		}
16151 	}
16152 
16153 	return source;
16154 }
16155 
16156 /** Get description of test case
16157  *
16158  * @param test_case_index Index of test case
16159  *
16160  * @return Test case description
16161  **/
16162 std::string VaryingExceedingComponentsTest::getTestCaseName(GLuint test_case_index)
16163 {
16164 	std::stringstream stream;
16165 	testCase&		  test_case = m_test_cases[test_case_index];
16166 
16167 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
16168 		   << " type: " << test_case.m_type.GetGLSLTypeName();
16169 
16170 	if (true == test_case.m_is_array)
16171 	{
16172 		stream << "[1]";
16173 	}
16174 
16175 	stream << ", direction: ";
16176 
16177 	if (true == test_case.m_is_input)
16178 	{
16179 		stream << "input";
16180 	}
16181 	else
16182 	{
16183 		stream << "output";
16184 	}
16185 
16186 	return stream.str();
16187 }
16188 
16189 /** Get number of test cases
16190  *
16191  * @return Number of test cases
16192  **/
16193 GLuint VaryingExceedingComponentsTest::getTestCaseNumber()
16194 {
16195 	return static_cast<GLuint>(m_test_cases.size());
16196 }
16197 
16198 /** Selects if "compute" stage is relevant for test
16199  *
16200  * @param ignored
16201  *
16202  * @return false
16203  **/
16204 bool VaryingExceedingComponentsTest::isComputeRelevant(GLuint /* test_case_index */)
16205 {
16206 	return false;
16207 }
16208 
16209 /** Prepare all test cases
16210  *
16211  **/
16212 void VaryingExceedingComponentsTest::testInit()
16213 {
16214 	const GLuint		n_types					  = getTypesNumber();
16215 
16216 	for (GLuint i = 0; i < n_types; ++i)
16217 	{
16218 		const Utils::Type&		   type				= getType(i);
16219 		const std::vector<GLuint>& valid_components = type.GetValidComponents();
16220 
16221 		if (valid_components.empty())
16222 		{
16223 			continue;
16224 		}
16225 
16226 		for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
16227 		{
16228 			if (Utils::Shader::COMPUTE == stage)
16229 			{
16230 				continue;
16231 			}
16232 
16233 			testCase test_case_in_arr  = { true, true, (Utils::Shader::STAGES)stage, type };
16234 			testCase test_case_in_one  = { true, false, (Utils::Shader::STAGES)stage, type };
16235 			testCase test_case_out_arr = { false, true, (Utils::Shader::STAGES)stage, type };
16236 			testCase test_case_out_one = { false, false, (Utils::Shader::STAGES)stage, type };
16237 
16238 			m_test_cases.push_back(test_case_in_arr);
16239 			m_test_cases.push_back(test_case_in_one);
16240 
16241 			if (Utils::Shader::FRAGMENT != stage)
16242 			{
16243 				m_test_cases.push_back(test_case_out_arr);
16244 				m_test_cases.push_back(test_case_out_one);
16245 			}
16246 		}
16247 	}
16248 }
16249 
16250 /** Constructor
16251  *
16252  * @param context Test framework context
16253  **/
16254 VaryingComponentWithoutLocationTest::VaryingComponentWithoutLocationTest(deqp::Context& context)
16255 	: NegativeTestBase(context, "varying_component_without_location",
16256 					   "Test verifies that compiler reports error when component qualifier is used without location")
16257 {
16258 }
16259 
16260 /** Source for given test case and stage
16261  *
16262  * @param test_case_index Index of test case
16263  * @param stage           Shader stage
16264  *
16265  * @return Shader source
16266  **/
16267 std::string VaryingComponentWithoutLocationTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
16268 {
16269 #if DEBUG_NEG_REMOVE_ERROR
16270 	static const GLchar* var_definition = "/* layout (component = COMPONENT) */ FLAT DIRECTION TYPE gokuARRAY;\n";
16271 #else
16272 	static const GLchar* var_definition = "layout (component = COMPONENT) FLAT DIRECTION TYPE gokuARRAY;\n";
16273 #endif /* DEBUG_NEG_REMOVE_ERROR */
16274 	static const GLchar* input_use		= "    if (TYPE(0) == gokuINDEX)\n"
16275 									 "    {\n"
16276 									 "        result += vec4(1, 0.5, 0.25, 0.125);\n"
16277 									 "    }\n";
16278 	static const GLchar* output_use = "    gokuINDEX = TYPE(0);\n"
16279 									  "    if (vec4(0) == result)\n"
16280 									  "    {\n"
16281 									  "        gokuINDEX = TYPE(1);\n"
16282 									  "    }\n";
16283 	static const GLchar* fs = "#version 430 core\n"
16284 							  "#extension GL_ARB_enhanced_layouts : require\n"
16285 							  "\n"
16286 							  "in  vec4 gs_fs;\n"
16287 							  "out vec4 fs_out;\n"
16288 							  "\n"
16289 							  "void main()\n"
16290 							  "{\n"
16291 							  "    fs_out = gs_fs;\n"
16292 							  "}\n"
16293 							  "\n";
16294 	static const GLchar* fs_tested = "#version 430 core\n"
16295 									 "#extension GL_ARB_enhanced_layouts : require\n"
16296 									 "\n"
16297 									 "VAR_DEFINITION"
16298 									 "\n"
16299 									 "in  vec4 gs_fs;\n"
16300 									 "out vec4 fs_out;\n"
16301 									 "\n"
16302 									 "void main()\n"
16303 									 "{\n"
16304 									 "    vec4 result = gs_fs;\n"
16305 									 "\n"
16306 									 "VARIABLE_USE"
16307 									 "\n"
16308 									 "    fs_out = result;\n"
16309 									 "}\n"
16310 									 "\n";
16311 	static const GLchar* gs = "#version 430 core\n"
16312 							  "#extension GL_ARB_enhanced_layouts : require\n"
16313 							  "\n"
16314 							  "layout(points)                           in;\n"
16315 							  "layout(triangle_strip, max_vertices = 4) out;\n"
16316 							  "\n"
16317 							  "in  vec4 tes_gs[];\n"
16318 							  "out vec4 gs_fs;\n"
16319 							  "\n"
16320 							  "void main()\n"
16321 							  "{\n"
16322 							  "    gs_fs = tes_gs[0];\n"
16323 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
16324 							  "    EmitVertex();\n"
16325 							  "    gs_fs = tes_gs[0];\n"
16326 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
16327 							  "    EmitVertex();\n"
16328 							  "    gs_fs = tes_gs[0];\n"
16329 							  "    gl_Position  = vec4(1, -1, 0, 1);\n"
16330 							  "    EmitVertex();\n"
16331 							  "    gs_fs = tes_gs[0];\n"
16332 							  "    gl_Position  = vec4(1, 1, 0, 1);\n"
16333 							  "    EmitVertex();\n"
16334 							  "}\n"
16335 							  "\n";
16336 	static const GLchar* gs_tested = "#version 430 core\n"
16337 									 "#extension GL_ARB_enhanced_layouts : require\n"
16338 									 "\n"
16339 									 "layout(points)                           in;\n"
16340 									 "layout(triangle_strip, max_vertices = 4) out;\n"
16341 									 "\n"
16342 									 "VAR_DEFINITION"
16343 									 "\n"
16344 									 "in  vec4 tes_gs[];\n"
16345 									 "out vec4 gs_fs;\n"
16346 									 "\n"
16347 									 "void main()\n"
16348 									 "{\n"
16349 									 "    vec4 result = tes_gs[0];\n"
16350 									 "\n"
16351 									 "VARIABLE_USE"
16352 									 "\n"
16353 									 "    gs_fs = result;\n"
16354 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
16355 									 "    EmitVertex();\n"
16356 									 "    gs_fs = result;\n"
16357 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
16358 									 "    EmitVertex();\n"
16359 									 "    gs_fs = result;\n"
16360 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
16361 									 "    EmitVertex();\n"
16362 									 "    gs_fs = result;\n"
16363 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
16364 									 "    EmitVertex();\n"
16365 									 "}\n"
16366 									 "\n";
16367 	static const GLchar* tcs = "#version 430 core\n"
16368 							   "#extension GL_ARB_enhanced_layouts : require\n"
16369 							   "\n"
16370 							   "layout(vertices = 1) out;\n"
16371 							   "\n"
16372 							   "in  vec4 vs_tcs[];\n"
16373 							   "out vec4 tcs_tes[];\n"
16374 							   "\n"
16375 							   "void main()\n"
16376 							   "{\n"
16377 							   "\n"
16378 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
16379 							   "\n"
16380 							   "    gl_TessLevelOuter[0] = 1.0;\n"
16381 							   "    gl_TessLevelOuter[1] = 1.0;\n"
16382 							   "    gl_TessLevelOuter[2] = 1.0;\n"
16383 							   "    gl_TessLevelOuter[3] = 1.0;\n"
16384 							   "    gl_TessLevelInner[0] = 1.0;\n"
16385 							   "    gl_TessLevelInner[1] = 1.0;\n"
16386 							   "}\n"
16387 							   "\n";
16388 	static const GLchar* tcs_tested = "#version 430 core\n"
16389 									  "#extension GL_ARB_enhanced_layouts : require\n"
16390 									  "\n"
16391 									  "layout(vertices = 1) out;\n"
16392 									  "\n"
16393 									  "VAR_DEFINITION"
16394 									  "\n"
16395 									  "in  vec4 vs_tcs[];\n"
16396 									  "out vec4 tcs_tes[];\n"
16397 									  "\n"
16398 									  "void main()\n"
16399 									  "{\n"
16400 									  "    vec4 result = vs_tcs[gl_InvocationID];\n"
16401 									  "\n"
16402 									  "VARIABLE_USE"
16403 									  "\n"
16404 									  "    tcs_tes[gl_InvocationID] = result;\n"
16405 									  "\n"
16406 									  "    gl_TessLevelOuter[0] = 1.0;\n"
16407 									  "    gl_TessLevelOuter[1] = 1.0;\n"
16408 									  "    gl_TessLevelOuter[2] = 1.0;\n"
16409 									  "    gl_TessLevelOuter[3] = 1.0;\n"
16410 									  "    gl_TessLevelInner[0] = 1.0;\n"
16411 									  "    gl_TessLevelInner[1] = 1.0;\n"
16412 									  "}\n"
16413 									  "\n";
16414 	static const GLchar* tes = "#version 430 core\n"
16415 							   "#extension GL_ARB_enhanced_layouts : require\n"
16416 							   "\n"
16417 							   "layout(isolines, point_mode) in;\n"
16418 							   "\n"
16419 							   "in  vec4 tcs_tes[];\n"
16420 							   "out vec4 tes_gs;\n"
16421 							   "\n"
16422 							   "void main()\n"
16423 							   "{\n"
16424 							   "    tes_gs = tcs_tes[0];\n"
16425 							   "}\n"
16426 							   "\n";
16427 	static const GLchar* tes_tested = "#version 430 core\n"
16428 									  "#extension GL_ARB_enhanced_layouts : require\n"
16429 									  "\n"
16430 									  "layout(isolines, point_mode) in;\n"
16431 									  "\n"
16432 									  "VAR_DEFINITION"
16433 									  "\n"
16434 									  "in  vec4 tcs_tes[];\n"
16435 									  "out vec4 tes_gs;\n"
16436 									  "\n"
16437 									  "void main()\n"
16438 									  "{\n"
16439 									  "    vec4 result = tcs_tes[0];\n"
16440 									  "\n"
16441 									  "VARIABLE_USE"
16442 									  "\n"
16443 									  "    tes_gs = result;\n"
16444 									  "}\n"
16445 									  "\n";
16446 	static const GLchar* vs = "#version 430 core\n"
16447 							  "#extension GL_ARB_enhanced_layouts : require\n"
16448 							  "\n"
16449 							  "in  vec4 in_vs;\n"
16450 							  "out vec4 vs_tcs;\n"
16451 							  "\n"
16452 							  "void main()\n"
16453 							  "{\n"
16454 							  "    vs_tcs = in_vs;\n"
16455 							  "}\n"
16456 							  "\n";
16457 	static const GLchar* vs_tested = "#version 430 core\n"
16458 									 "#extension GL_ARB_enhanced_layouts : require\n"
16459 									 "\n"
16460 									 "VAR_DEFINITION"
16461 									 "\n"
16462 									 "in  vec4 in_vs;\n"
16463 									 "out vec4 vs_tcs;\n"
16464 									 "\n"
16465 									 "void main()\n"
16466 									 "{\n"
16467 									 "    vec4 result = in_vs;\n"
16468 									 "\n"
16469 									 "VARIABLE_USE"
16470 									 "\n"
16471 									 "    vs_tcs = result;\n"
16472 									 "}\n"
16473 									 "\n";
16474 
16475 	std::string source;
16476 	testCase&   test_case = m_test_cases[test_case_index];
16477 
16478 	if (test_case.m_stage == stage)
16479 	{
16480 		const GLchar* array = "";
16481 		GLchar		  buffer[16];
16482 		const GLchar*			 direction = "in";
16483 		const GLchar* index		= "";
16484 		size_t		  position  = 0;
16485 		const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
16486 		const GLchar*			 var_use   = Utils::Shader::VERTEX == stage ? input_use : "\n";
16487 		Utils::Variable::STORAGE storage   = Utils::Variable::VARYING_INPUT;
16488 		const GLchar*			 flat	  = "";
16489 
16490 		if (false == test_case.m_is_input)
16491 		{
16492 			direction = "out";
16493 			storage   = Utils::Variable::VARYING_OUTPUT;
16494 			var_use   = output_use;
16495 		}
16496 
16497 		if (isFlatRequired(stage, test_case.m_type, storage, true))
16498 		{
16499 			flat = "flat";
16500 		}
16501 
16502 		sprintf(buffer, "%d", test_case.m_component);
16503 
16504 		switch (stage)
16505 		{
16506 		case Utils::Shader::FRAGMENT:
16507 			source = fs_tested;
16508 			break;
16509 		case Utils::Shader::GEOMETRY:
16510 			source = gs_tested;
16511 			array  = test_case.m_is_input ? "[]" : "";
16512 			index  = test_case.m_is_input ? "[0]" : "";
16513 			break;
16514 		case Utils::Shader::TESS_CTRL:
16515 			source = tcs_tested;
16516 			array  = "[]";
16517 			index  = "[gl_InvocationID]";
16518 			break;
16519 		case Utils::Shader::TESS_EVAL:
16520 			source = tes_tested;
16521 			array  = test_case.m_is_input ? "[]" : "";
16522 			index  = test_case.m_is_input ? "[0]" : "";
16523 			break;
16524 		case Utils::Shader::VERTEX:
16525 			source = vs_tested;
16526 			break;
16527 		default:
16528 			TCU_FAIL("Invalid enum");
16529 		}
16530 
16531 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
16532 		position = 0;
16533 		Utils::replaceToken("COMPONENT", position, buffer, source);
16534 		Utils::replaceToken("FLAT", position, flat, source);
16535 		Utils::replaceToken("DIRECTION", position, direction, source);
16536 		Utils::replaceToken("ARRAY", position, array, source);
16537 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
16538 
16539 		Utils::replaceAllTokens("TYPE", type_name, source);
16540 		Utils::replaceAllTokens("INDEX", index, source);
16541 	}
16542 	else
16543 	{
16544 		switch (stage)
16545 		{
16546 		case Utils::Shader::FRAGMENT:
16547 			source = fs;
16548 			break;
16549 		case Utils::Shader::GEOMETRY:
16550 			source = gs;
16551 			break;
16552 		case Utils::Shader::TESS_CTRL:
16553 			source = tcs;
16554 			break;
16555 		case Utils::Shader::TESS_EVAL:
16556 			source = tes;
16557 			break;
16558 		case Utils::Shader::VERTEX:
16559 			source = vs;
16560 			break;
16561 		default:
16562 			TCU_FAIL("Invalid enum");
16563 		}
16564 	}
16565 
16566 	return source;
16567 }
16568 
16569 /** Get description of test case
16570  *
16571  * @param test_case_index Index of test case
16572  *
16573  * @return Test case description
16574  **/
16575 std::string VaryingComponentWithoutLocationTest::getTestCaseName(GLuint test_case_index)
16576 {
16577 	std::stringstream stream;
16578 	testCase&		  test_case = m_test_cases[test_case_index];
16579 
16580 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
16581 		   << " type: " << test_case.m_type.GetGLSLTypeName() << ", direction: ";
16582 
16583 	if (true == test_case.m_is_input)
16584 	{
16585 		stream << "input";
16586 	}
16587 	else
16588 	{
16589 		stream << "output";
16590 	}
16591 
16592 	stream << ", component: " << test_case.m_component;
16593 
16594 	return stream.str();
16595 }
16596 
16597 /** Get number of test cases
16598  *
16599  * @return Number of test cases
16600  **/
16601 GLuint VaryingComponentWithoutLocationTest::getTestCaseNumber()
16602 {
16603 	return static_cast<GLuint>(m_test_cases.size());
16604 }
16605 
16606 /** Selects if "compute" stage is relevant for test
16607  *
16608  * @param ignored
16609  *
16610  * @return false
16611  **/
16612 bool VaryingComponentWithoutLocationTest::isComputeRelevant(GLuint /* test_case_index */)
16613 {
16614 	return false;
16615 }
16616 
16617 /** Prepare all test cases
16618  *
16619  **/
16620 void VaryingComponentWithoutLocationTest::testInit()
16621 {
16622 	const GLuint		n_types					  = getTypesNumber();
16623 
16624 	for (GLuint i = 0; i < n_types; ++i)
16625 	{
16626 		const Utils::Type&		   type				= getType(i);
16627 		const std::vector<GLuint>& valid_components = type.GetValidComponents();
16628 
16629 		if (valid_components.empty())
16630 		{
16631 			continue;
16632 		}
16633 
16634 		for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
16635 		{
16636 			if (Utils::Shader::COMPUTE == stage)
16637 			{
16638 				continue;
16639 			}
16640 
16641 			testCase test_case_in  = { valid_components.back(), true, (Utils::Shader::STAGES)stage, type };
16642 			testCase test_case_out = { valid_components.back(), false, (Utils::Shader::STAGES)stage, type };
16643 
16644 			m_test_cases.push_back(test_case_in);
16645 
16646 			if (Utils::Shader::FRAGMENT != stage)
16647 			{
16648 				m_test_cases.push_back(test_case_out);
16649 			}
16650 		}
16651 	}
16652 }
16653 
16654 /** Constructor
16655  *
16656  * @param context Test framework context
16657  **/
16658 VaryingComponentOfInvalidTypeTest::VaryingComponentOfInvalidTypeTest(deqp::Context& context)
16659 	: NegativeTestBase(context, "varying_component_of_invalid_type",
16660 					   "Test verifies that compiler reports error when component qualifier is used for invalid type")
16661 {
16662 }
16663 
16664 /** Source for given test case and stage
16665  *
16666  * @param test_case_index Index of test case
16667  * @param stage           Shader stage
16668  *
16669  * @return Shader source
16670  **/
16671 std::string VaryingComponentOfInvalidTypeTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
16672 {
16673 	static const GLchar* block_definition_arr = "layout (location = 1COMPONENT) DIRECTION Goku {\n"
16674 												"    FLAT TYPE member;\n"
16675 												"} gokuARRAY[1];\n";
16676 	static const GLchar* block_definition_one = "layout (location = 1COMPONENT) DIRECTION Goku {\n"
16677 												"    FLAT TYPE member;\n"
16678 												"} gokuARRAY;\n";
16679 	static const GLchar* matrix_dvec3_dvec4_definition_arr =
16680 		"layout (location = 1COMPONENT) FLAT DIRECTION TYPE gokuARRAY[1];\n";
16681 	static const GLchar* matrix_dvec3_dvec4_definition_one =
16682 		"layout (location = 1COMPONENT) FLAT DIRECTION TYPE gokuARRAY;\n";
16683 	static const GLchar* struct_definition_arr = "struct Goku {\n"
16684 												 "    TYPE member;\n"
16685 												 "};\n"
16686 												 "\n"
16687 												 "layout (location = 1COMPONENT) FLAT DIRECTION Goku gokuARRAY[1];\n";
16688 	static const GLchar* struct_definition_one = "struct Goku {\n"
16689 												 "    TYPE member;\n"
16690 												 "};\n"
16691 												 "\n"
16692 												 "layout (location = 1COMPONENT) FLAT DIRECTION Goku gokuARRAY;\n";
16693 	static const GLchar* matrix_dvec3_dvec4_input_use_arr = "    if (TYPE(0) == gokuINDEX[0])\n"
16694 															"    {\n"
16695 															"        result += vec4(1, 0.5, 0.25, 0.125);\n"
16696 															"    }\n";
16697 	static const GLchar* matrix_dvec3_dvec4_input_use_one = "    if (TYPE(0) == gokuINDEX)\n"
16698 															"    {\n"
16699 															"        result += vec4(1, 0.5, 0.25, 0.125);\n"
16700 															"    }\n";
16701 	static const GLchar* matrix_dvec3_dvec4_output_use_arr = "    gokuINDEX[0] = TYPE(0);\n"
16702 															 "    if (vec4(0) == result)\n"
16703 															 "    {\n"
16704 															 "        gokuINDEX[0] = TYPE(1);\n"
16705 															 "    }\n";
16706 	static const GLchar* matrix_dvec3_dvec4_output_use_one = "    gokuINDEX = TYPE(0);\n"
16707 															 "    if (vec4(0) == result)\n"
16708 															 "    {\n"
16709 															 "        gokuINDEX = TYPE(1);\n"
16710 															 "    }\n";
16711 	static const GLchar* member_input_use_arr = "    if (TYPE(0) == gokuINDEX[0].member)\n"
16712 												"    {\n"
16713 												"        result += vec4(1, 0.5, 0.25, 0.125);\n"
16714 												"    }\n";
16715 	static const GLchar* member_input_use_one = "    if (TYPE(0) == gokuINDEX.member)\n"
16716 												"    {\n"
16717 												"        result += vec4(1, 0.5, 0.25, 0.125);\n"
16718 												"    }\n";
16719 	static const GLchar* member_output_use_arr = "    gokuINDEX[0].member = TYPE(0);\n"
16720 												 "    if (vec4(0) == result)\n"
16721 												 "    {\n"
16722 												 "        gokuINDEX[0].member = TYPE(1);\n"
16723 												 "    }\n";
16724 	static const GLchar* member_output_use_one = "    gokuINDEX.member = TYPE(0);\n"
16725 												 "    if (vec4(0) == result)\n"
16726 												 "    {\n"
16727 												 "        gokuINDEX.member = TYPE(1);\n"
16728 												 "    }\n";
16729 	static const GLchar* fs = "#version 430 core\n"
16730 							  "#extension GL_ARB_enhanced_layouts : require\n"
16731 							  "\n"
16732 							  "in  vec4 gs_fs;\n"
16733 							  "out vec4 fs_out;\n"
16734 							  "\n"
16735 							  "void main()\n"
16736 							  "{\n"
16737 							  "    fs_out = gs_fs;\n"
16738 							  "}\n"
16739 							  "\n";
16740 	static const GLchar* fs_tested = "#version 430 core\n"
16741 									 "#extension GL_ARB_enhanced_layouts : require\n"
16742 									 "\n"
16743 									 "VAR_DEFINITION"
16744 									 "\n"
16745 									 "in  vec4 gs_fs;\n"
16746 									 "out vec4 fs_out;\n"
16747 									 "\n"
16748 									 "void main()\n"
16749 									 "{\n"
16750 									 "    vec4 result = gs_fs;\n"
16751 									 "\n"
16752 									 "VARIABLE_USE"
16753 									 "\n"
16754 									 "    fs_out += result;\n"
16755 									 "}\n"
16756 									 "\n";
16757 	static const GLchar* gs = "#version 430 core\n"
16758 							  "#extension GL_ARB_enhanced_layouts : require\n"
16759 							  "\n"
16760 							  "layout(points)                           in;\n"
16761 							  "layout(triangle_strip, max_vertices = 4) out;\n"
16762 							  "\n"
16763 							  "in  vec4 tes_gs[];\n"
16764 							  "out vec4 gs_fs;\n"
16765 							  "\n"
16766 							  "void main()\n"
16767 							  "{\n"
16768 							  "    gs_fs = tes_gs[0];\n"
16769 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
16770 							  "    EmitVertex();\n"
16771 							  "    gs_fs = tes_gs[0];\n"
16772 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
16773 							  "    EmitVertex();\n"
16774 							  "    gs_fs = tes_gs[0];\n"
16775 							  "    gl_Position  = vec4(1, -1, 0, 1);\n"
16776 							  "    EmitVertex();\n"
16777 							  "    gs_fs = tes_gs[0];\n"
16778 							  "    gl_Position  = vec4(1, 1, 0, 1);\n"
16779 							  "    EmitVertex();\n"
16780 							  "}\n"
16781 							  "\n";
16782 	static const GLchar* gs_tested = "#version 430 core\n"
16783 									 "#extension GL_ARB_enhanced_layouts : require\n"
16784 									 "\n"
16785 									 "layout(points)                           in;\n"
16786 									 "layout(triangle_strip, max_vertices = 4) out;\n"
16787 									 "\n"
16788 									 "VAR_DEFINITION"
16789 									 "\n"
16790 									 "in  vec4 tes_gs[];\n"
16791 									 "out vec4 gs_fs;\n"
16792 									 "\n"
16793 									 "void main()\n"
16794 									 "{\n"
16795 									 "    vec4 result = tes_gs[0];\n"
16796 									 "\n"
16797 									 "VARIABLE_USE"
16798 									 "\n"
16799 									 "    gs_fs = result;\n"
16800 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
16801 									 "    EmitVertex();\n"
16802 									 "    gs_fs = result;\n"
16803 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
16804 									 "    EmitVertex();\n"
16805 									 "    gs_fs = result;\n"
16806 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
16807 									 "    EmitVertex();\n"
16808 									 "    gs_fs = result;\n"
16809 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
16810 									 "    EmitVertex();\n"
16811 									 "}\n"
16812 									 "\n";
16813 	static const GLchar* tcs = "#version 430 core\n"
16814 							   "#extension GL_ARB_enhanced_layouts : require\n"
16815 							   "\n"
16816 							   "layout(vertices = 1) out;\n"
16817 							   "\n"
16818 							   "in  vec4 vs_tcs[];\n"
16819 							   "out vec4 tcs_tes[];\n"
16820 							   "\n"
16821 							   "void main()\n"
16822 							   "{\n"
16823 							   "\n"
16824 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
16825 							   "\n"
16826 							   "    gl_TessLevelOuter[0] = 1.0;\n"
16827 							   "    gl_TessLevelOuter[1] = 1.0;\n"
16828 							   "    gl_TessLevelOuter[2] = 1.0;\n"
16829 							   "    gl_TessLevelOuter[3] = 1.0;\n"
16830 							   "    gl_TessLevelInner[0] = 1.0;\n"
16831 							   "    gl_TessLevelInner[1] = 1.0;\n"
16832 							   "}\n"
16833 							   "\n";
16834 	static const GLchar* tcs_tested = "#version 430 core\n"
16835 									  "#extension GL_ARB_enhanced_layouts : require\n"
16836 									  "\n"
16837 									  "layout(vertices = 1) out;\n"
16838 									  "\n"
16839 									  "VAR_DEFINITION"
16840 									  "\n"
16841 									  "in  vec4 vs_tcs[];\n"
16842 									  "out vec4 tcs_tes[];\n"
16843 									  "\n"
16844 									  "void main()\n"
16845 									  "{\n"
16846 									  "    vec4 result = vs_tcs[gl_InvocationID];\n"
16847 									  "\n"
16848 									  "VARIABLE_USE"
16849 									  "\n"
16850 									  "    tcs_tes[gl_InvocationID] = result;\n"
16851 									  "\n"
16852 									  "    gl_TessLevelOuter[0] = 1.0;\n"
16853 									  "    gl_TessLevelOuter[1] = 1.0;\n"
16854 									  "    gl_TessLevelOuter[2] = 1.0;\n"
16855 									  "    gl_TessLevelOuter[3] = 1.0;\n"
16856 									  "    gl_TessLevelInner[0] = 1.0;\n"
16857 									  "    gl_TessLevelInner[1] = 1.0;\n"
16858 									  "}\n"
16859 									  "\n";
16860 	static const GLchar* tes = "#version 430 core\n"
16861 							   "#extension GL_ARB_enhanced_layouts : require\n"
16862 							   "\n"
16863 							   "layout(isolines, point_mode) in;\n"
16864 							   "\n"
16865 							   "in  vec4 tcs_tes[];\n"
16866 							   "out vec4 tes_gs;\n"
16867 							   "\n"
16868 							   "void main()\n"
16869 							   "{\n"
16870 							   "    tes_gs = tcs_tes[0];\n"
16871 							   "}\n"
16872 							   "\n";
16873 	static const GLchar* tes_tested = "#version 430 core\n"
16874 									  "#extension GL_ARB_enhanced_layouts : require\n"
16875 									  "\n"
16876 									  "layout(isolines, point_mode) in;\n"
16877 									  "\n"
16878 									  "VAR_DEFINITION"
16879 									  "\n"
16880 									  "in  vec4 tcs_tes[];\n"
16881 									  "out vec4 tes_gs;\n"
16882 									  "\n"
16883 									  "void main()\n"
16884 									  "{\n"
16885 									  "    vec4 result = tcs_tes[0];\n"
16886 									  "\n"
16887 									  "VARIABLE_USE"
16888 									  "\n"
16889 									  "    tes_gs += result;\n"
16890 									  "}\n"
16891 									  "\n";
16892 	static const GLchar* vs = "#version 430 core\n"
16893 							  "#extension GL_ARB_enhanced_layouts : require\n"
16894 							  "\n"
16895 							  "in  vec4 in_vs;\n"
16896 							  "out vec4 vs_tcs;\n"
16897 							  "\n"
16898 							  "void main()\n"
16899 							  "{\n"
16900 							  "    vs_tcs = in_vs;\n"
16901 							  "}\n"
16902 							  "\n";
16903 	static const GLchar* vs_tested = "#version 430 core\n"
16904 									 "#extension GL_ARB_enhanced_layouts : require\n"
16905 									 "\n"
16906 									 "VAR_DEFINITION"
16907 									 "\n"
16908 									 "in  vec4 in_vs;\n"
16909 									 "out vec4 vs_tcs;\n"
16910 									 "\n"
16911 									 "void main()\n"
16912 									 "{\n"
16913 									 "    vec4 result = in_vs;\n"
16914 									 "\n"
16915 									 "VARIABLE_USE"
16916 									 "\n"
16917 									 "    vs_tcs += result;\n"
16918 									 "}\n"
16919 									 "\n";
16920 
16921 	std::string source;
16922 	testCase&   test_case = m_test_cases[test_case_index];
16923 
16924 	if (test_case.m_stage == stage)
16925 	{
16926 		const GLchar* array = "";
16927 		GLchar					 buffer[32];
16928 		const GLchar* var_definition = 0;
16929 		const GLchar* direction		 = "in ";
16930 		const GLchar* index			 = "";
16931 		size_t		  position		 = 0;
16932 		const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
16933 		const GLchar* var_use   = 0;
16934 		Utils::Variable::STORAGE storage   = Utils::Variable::VARYING_INPUT;
16935 		const GLchar*			 flat	  = "";
16936 
16937 		if (false == test_case.m_is_input)
16938 		{
16939 			direction = "out";
16940 			storage   = Utils::Variable::VARYING_OUTPUT;
16941 
16942 			if (false == test_case.m_is_array)
16943 			{
16944 				switch (test_case.m_case)
16945 				{
16946 				case BLOCK:
16947 					var_definition = block_definition_one;
16948 					var_use		   = member_output_use_one;
16949 					break;
16950 				case MATRIX:
16951 				case DVEC3_DVEC4:
16952 					var_definition = matrix_dvec3_dvec4_definition_one;
16953 					var_use		   = matrix_dvec3_dvec4_output_use_one;
16954 					break;
16955 				case STRUCT:
16956 					var_definition = struct_definition_one;
16957 					var_use		   = member_output_use_one;
16958 					break;
16959 				default:
16960 					TCU_FAIL("Invalid enum");
16961 				}
16962 			}
16963 			else
16964 			{
16965 				switch (test_case.m_case)
16966 				{
16967 				case BLOCK:
16968 					var_definition = block_definition_arr;
16969 					var_use		   = member_output_use_arr;
16970 					break;
16971 				case MATRIX:
16972 				case DVEC3_DVEC4:
16973 					var_definition = matrix_dvec3_dvec4_definition_arr;
16974 					var_use		   = matrix_dvec3_dvec4_output_use_arr;
16975 					break;
16976 				case STRUCT:
16977 					var_definition = struct_definition_arr;
16978 					var_use		   = member_output_use_arr;
16979 					break;
16980 				default:
16981 					TCU_FAIL("Invalid enum");
16982 				}
16983 			}
16984 		}
16985 		else
16986 		{
16987 			if (false == test_case.m_is_array)
16988 			{
16989 				switch (test_case.m_case)
16990 				{
16991 				case BLOCK:
16992 					var_definition = block_definition_one;
16993 					var_use		   = Utils::Shader::VERTEX == stage ? member_input_use_one : "\n";
16994 					break;
16995 				case MATRIX:
16996 				case DVEC3_DVEC4:
16997 					var_definition = matrix_dvec3_dvec4_definition_one;
16998 					var_use		   = Utils::Shader::VERTEX == stage ? matrix_dvec3_dvec4_input_use_one : "\n";
16999 					break;
17000 				case STRUCT:
17001 					var_definition = struct_definition_one;
17002 					var_use		   = Utils::Shader::VERTEX == stage ? member_input_use_one : "\n";
17003 					break;
17004 				default:
17005 					TCU_FAIL("Invalid enum");
17006 				}
17007 			}
17008 			else
17009 			{
17010 				switch (test_case.m_case)
17011 				{
17012 				case BLOCK:
17013 					var_definition = block_definition_arr;
17014 					var_use		   = Utils::Shader::VERTEX == stage ? member_input_use_arr : "\n";
17015 					break;
17016 				case MATRIX:
17017 				case DVEC3_DVEC4:
17018 					var_definition = matrix_dvec3_dvec4_definition_arr;
17019 					var_use		   = Utils::Shader::VERTEX == stage ? matrix_dvec3_dvec4_input_use_arr : "\n";
17020 					break;
17021 				case STRUCT:
17022 					var_definition = struct_definition_arr;
17023 					var_use		   = Utils::Shader::VERTEX == stage ? member_input_use_arr : "\n";
17024 					break;
17025 				default:
17026 					TCU_FAIL("Invalid enum");
17027 				}
17028 			}
17029 		}
17030 
17031 		if (isFlatRequired(stage, test_case.m_type, storage))
17032 		{
17033 			flat = "flat";
17034 		}
17035 
17036 #if DEBUG_NEG_REMOVE_ERROR
17037 		sprintf(buffer, " /* , component = %d */", test_case.m_component);
17038 #else
17039 		sprintf(buffer, ", component = %d", test_case.m_component);
17040 #endif /* DEBUG_NEG_REMOVE_ERROR */
17041 
17042 		switch (stage)
17043 		{
17044 		case Utils::Shader::FRAGMENT:
17045 			source = fs_tested;
17046 			break;
17047 		case Utils::Shader::GEOMETRY:
17048 			source = gs_tested;
17049 			array  = test_case.m_is_input ? "[]" : "";
17050 			index  = test_case.m_is_input ? "[0]" : "";
17051 			break;
17052 		case Utils::Shader::TESS_CTRL:
17053 			source = tcs_tested;
17054 			array  = "[]";
17055 			index  = "[gl_InvocationID]";
17056 			break;
17057 		case Utils::Shader::TESS_EVAL:
17058 			source = tes_tested;
17059 			array  = test_case.m_is_input ? "[]" : "";
17060 			index  = test_case.m_is_input ? "[0]" : "";
17061 			break;
17062 		case Utils::Shader::VERTEX:
17063 			source = vs_tested;
17064 			break;
17065 		default:
17066 			TCU_FAIL("Invalid enum");
17067 		}
17068 
17069 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
17070 		position = 0;
17071 		Utils::replaceToken("COMPONENT", position, buffer, source);
17072 		Utils::replaceToken("DIRECTION", position, direction, source);
17073 		Utils::replaceToken("ARRAY", position, array, source);
17074 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
17075 
17076 		Utils::replaceAllTokens("FLAT", flat, source);
17077 		Utils::replaceAllTokens("TYPE", type_name, source);
17078 		Utils::replaceAllTokens("INDEX", index, source);
17079 	}
17080 	else
17081 	{
17082 		switch (stage)
17083 		{
17084 		case Utils::Shader::FRAGMENT:
17085 			source = fs;
17086 			break;
17087 		case Utils::Shader::GEOMETRY:
17088 			source = gs;
17089 			break;
17090 		case Utils::Shader::TESS_CTRL:
17091 			source = tcs;
17092 			break;
17093 		case Utils::Shader::TESS_EVAL:
17094 			source = tes;
17095 			break;
17096 		case Utils::Shader::VERTEX:
17097 			source = vs;
17098 			break;
17099 		default:
17100 			TCU_FAIL("Invalid enum");
17101 		}
17102 	}
17103 
17104 	return source;
17105 }
17106 
17107 /** Get description of test case
17108  *
17109  * @param test_case_index Index of test case
17110  *
17111  * @return Test case description
17112  **/
17113 std::string VaryingComponentOfInvalidTypeTest::getTestCaseName(GLuint test_case_index)
17114 {
17115 	std::stringstream stream;
17116 	testCase&		  test_case = m_test_cases[test_case_index];
17117 
17118 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
17119 		   << " type: " << test_case.m_type.GetGLSLTypeName();
17120 
17121 	if (true == test_case.m_is_array)
17122 	{
17123 		stream << "[1]";
17124 	}
17125 
17126 	stream << ", direction: ";
17127 
17128 	if (true == test_case.m_is_input)
17129 	{
17130 		stream << "input";
17131 	}
17132 	else
17133 	{
17134 		stream << "output";
17135 	}
17136 
17137 	stream << ", component: " << test_case.m_component;
17138 
17139 	return stream.str();
17140 }
17141 
17142 /** Get number of test cases
17143  *
17144  * @return Number of test cases
17145  **/
17146 GLuint VaryingComponentOfInvalidTypeTest::getTestCaseNumber()
17147 {
17148 	return static_cast<GLuint>(m_test_cases.size());
17149 }
17150 
17151 /** Selects if "compute" stage is relevant for test
17152  *
17153  * @param ignored
17154  *
17155  * @return false
17156  **/
17157 bool VaryingComponentOfInvalidTypeTest::isComputeRelevant(GLuint /* test_case_index */)
17158 {
17159 	return false;
17160 }
17161 
17162 /** Prepare all test cases
17163  *
17164  **/
17165 void VaryingComponentOfInvalidTypeTest::testInit()
17166 {
17167 	const GLuint		n_types					  = getTypesNumber();
17168 
17169 	for (GLuint i = 0; i < n_types; ++i)
17170 	{
17171 		const Utils::Type& type				= getType(i);
17172 		const std::vector<GLuint>& valid_components = type.GetValidComponents();
17173 
17174 		for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
17175 		{
17176 			if (Utils::Shader::COMPUTE == stage)
17177 			{
17178 				continue;
17179 			}
17180 
17181 			/* matrices */
17182 			if (1 != type.m_n_columns)
17183 			{
17184 				testCase test_case_in_arr  = { MATRIX, 0, true, true, (Utils::Shader::STAGES)stage, type };
17185 				testCase test_case_in_one  = { MATRIX, 0, false, true, (Utils::Shader::STAGES)stage, type };
17186 				testCase test_case_out_arr = { MATRIX, 0, true, false, (Utils::Shader::STAGES)stage, type };
17187 				testCase test_case_out_one = { MATRIX, 0, false, false, (Utils::Shader::STAGES)stage, type };
17188 
17189 				m_test_cases.push_back(test_case_in_arr);
17190 				m_test_cases.push_back(test_case_in_one);
17191 
17192 				if (Utils::Shader::FRAGMENT != stage)
17193 				{
17194 					m_test_cases.push_back(test_case_out_arr);
17195 					m_test_cases.push_back(test_case_out_one);
17196 				}
17197 			}
17198 			else if (Utils::Type::Double == type.m_basic_type && 2 < type.m_n_rows) /* dvec3 and dvec4 */
17199 			{
17200 				testCase test_case_in_arr  = { DVEC3_DVEC4, 0, true, true, (Utils::Shader::STAGES)stage, type };
17201 				testCase test_case_in_one  = { DVEC3_DVEC4, 0, false, true, (Utils::Shader::STAGES)stage, type };
17202 				testCase test_case_out_arr = { DVEC3_DVEC4, 0, true, false, (Utils::Shader::STAGES)stage, type };
17203 				testCase test_case_out_one = { DVEC3_DVEC4, 0, false, false, (Utils::Shader::STAGES)stage, type };
17204 
17205 				m_test_cases.push_back(test_case_in_arr);
17206 				m_test_cases.push_back(test_case_in_one);
17207 
17208 				if (Utils::Shader::FRAGMENT != stage)
17209 				{
17210 					m_test_cases.push_back(test_case_out_arr);
17211 					m_test_cases.push_back(test_case_out_one);
17212 				}
17213 			}
17214 			else
17215 			{
17216 				if (valid_components.empty())
17217 				{
17218 					TCU_FAIL("Unhandled type");
17219 				}
17220 
17221 				for (GLuint c = BLOCK; c < MAX_CASES; ++c)
17222 				{
17223 					testCase test_case_in_arr = { (CASES)c, valid_components.back(),	  true,
17224 												  true,		(Utils::Shader::STAGES)stage, type };
17225 					testCase test_case_in_one = { (CASES)c, valid_components.back(),	  false,
17226 												  true,		(Utils::Shader::STAGES)stage, type };
17227 					testCase test_case_out_arr = { (CASES)c, valid_components.back(),	  true,
17228 												   false,	(Utils::Shader::STAGES)stage, type };
17229 					testCase test_case_out_one = { (CASES)c, valid_components.back(),	  false,
17230 												   false,	(Utils::Shader::STAGES)stage, type };
17231 
17232 					if (Utils::Shader::VERTEX != stage)
17233 					{
17234 						m_test_cases.push_back(test_case_in_arr);
17235 						m_test_cases.push_back(test_case_in_one);
17236 					}
17237 
17238 					if (Utils::Shader::FRAGMENT != stage)
17239 					{
17240 						m_test_cases.push_back(test_case_out_arr);
17241 						m_test_cases.push_back(test_case_out_one);
17242 					}
17243 				}
17244 			}
17245 		}
17246 	}
17247 }
17248 
17249 /** Constructor
17250  *
17251  * @param context Test framework context
17252  **/
17253 InputComponentAliasingTest::InputComponentAliasingTest(deqp::Context& context)
17254 	: NegativeTestBase(context, "input_component_aliasing",
17255 					   "Test verifies that compiler reports component aliasing as error")
17256 {
17257 }
17258 
17259 /** Source for given test case and stage
17260  *
17261  * @param test_case_index Index of test case
17262  * @param stage           Shader stage
17263  *
17264  * @return Shader source
17265  **/
17266 std::string InputComponentAliasingTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
17267 {
17268 	static const GLchar* var_definition =
17269 		"layout (location = 1, component = COMPONENT) FLAT in TYPE gohanARRAY;\n"
17270 #if DEBUG_NEG_REMOVE_ERROR
17271 		"/* layout (location = 1, component = COMPONENT) */ FLAT in TYPE gotenARRAY;\n";
17272 #else
17273 		"layout (location = 1, component = COMPONENT) FLAT in TYPE gotenARRAY;\n";
17274 #endif /* DEBUG_NEG_REMOVE_ERROR */
17275 	static const GLchar* test_one = "    if (TYPE(0) == gohanINDEX)\n"
17276 									"    {\n"
17277 									"        result += vec4(1, 0.5, 0.25, 0.125);\n"
17278 									"    }\n";
17279 	static const GLchar* fs = "#version 430 core\n"
17280 							  "#extension GL_ARB_enhanced_layouts : require\n"
17281 							  "\n"
17282 							  "in  vec4 gs_fs;\n"
17283 							  "out vec4 fs_out;\n"
17284 							  "\n"
17285 							  "void main()\n"
17286 							  "{\n"
17287 							  "    fs_out = gs_fs;\n"
17288 							  "}\n"
17289 							  "\n";
17290 	static const GLchar* fs_tested = "#version 430 core\n"
17291 									 "#extension GL_ARB_enhanced_layouts : require\n"
17292 									 "\n"
17293 									 "VAR_DEFINITION"
17294 									 "\n"
17295 									 "in  vec4 gs_fs;\n"
17296 									 "out vec4 fs_out;\n"
17297 									 "\n"
17298 									 "void main()\n"
17299 									 "{\n"
17300 									 "    vec4 result = gs_fs;\n"
17301 									 "\n"
17302 									 "VARIABLE_USE"
17303 									 "\n"
17304 									 "    fs_out += result;\n"
17305 									 "}\n"
17306 									 "\n";
17307 	static const GLchar* gs = "#version 430 core\n"
17308 							  "#extension GL_ARB_enhanced_layouts : require\n"
17309 							  "\n"
17310 							  "layout(points)                           in;\n"
17311 							  "layout(triangle_strip, max_vertices = 4) out;\n"
17312 							  "\n"
17313 							  "layout (location = 1, component = COMPONENT) FLAT out TYPE gohan;\n"
17314 							  "\n"
17315 							  "in  vec4 tes_gs[];\n"
17316 							  "out vec4 gs_fs;\n"
17317 							  "\n"
17318 							  "void main()\n"
17319 							  "{\n"
17320 							  "    gohan = TYPE(1);\n"
17321 							  "\n"
17322 							  "    gs_fs = tes_gs[0];\n"
17323 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
17324 							  "    EmitVertex();\n"
17325 							  "    gs_fs = tes_gs[0];\n"
17326 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
17327 							  "    EmitVertex();\n"
17328 							  "    gs_fs = tes_gs[0];\n"
17329 							  "    gl_Position  = vec4(1, -1, 0, 1);\n"
17330 							  "    EmitVertex();\n"
17331 							  "    gs_fs = tes_gs[0];\n"
17332 							  "    gl_Position  = vec4(1, 1, 0, 1);\n"
17333 							  "    EmitVertex();\n"
17334 							  "}\n"
17335 							  "\n";
17336 	static const GLchar* gs_tested = "#version 430 core\n"
17337 									 "#extension GL_ARB_enhanced_layouts : require\n"
17338 									 "\n"
17339 									 "layout(points)                           in;\n"
17340 									 "layout(triangle_strip, max_vertices = 4) out;\n"
17341 									 "\n"
17342 									 "VAR_DEFINITION"
17343 									 "\n"
17344 									 "in  vec4 tes_gs[];\n"
17345 									 "out vec4 gs_fs;\n"
17346 									 "\n"
17347 									 "void main()\n"
17348 									 "{\n"
17349 									 "    vec4 result = tes_gs[0];\n"
17350 									 "\n"
17351 									 "VARIABLE_USE"
17352 									 "\n"
17353 									 "    gs_fs = result;\n"
17354 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
17355 									 "    EmitVertex();\n"
17356 									 "    gs_fs = result;\n"
17357 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
17358 									 "    EmitVertex();\n"
17359 									 "    gs_fs = result;\n"
17360 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
17361 									 "    EmitVertex();\n"
17362 									 "    gs_fs = result;\n"
17363 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
17364 									 "    EmitVertex();\n"
17365 									 "}\n"
17366 									 "\n";
17367 	static const GLchar* tcs = "#version 430 core\n"
17368 							   "#extension GL_ARB_enhanced_layouts : require\n"
17369 							   "\n"
17370 							   "layout(vertices = 1) out;\n"
17371 							   "\n"
17372 							   "layout (location = 1, component = COMPONENT) FLAT out TYPE gohan[];\n"
17373 							   "\n"
17374 							   "in  vec4 vs_tcs[];\n"
17375 							   "out vec4 tcs_tes[];\n"
17376 							   "\n"
17377 							   "void main()\n"
17378 							   "{\n"
17379 							   "    gohan[gl_InvocationID] = TYPE(1);\n"
17380 							   "\n"
17381 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
17382 							   "\n"
17383 							   "    gl_TessLevelOuter[0] = 1.0;\n"
17384 							   "    gl_TessLevelOuter[1] = 1.0;\n"
17385 							   "    gl_TessLevelOuter[2] = 1.0;\n"
17386 							   "    gl_TessLevelOuter[3] = 1.0;\n"
17387 							   "    gl_TessLevelInner[0] = 1.0;\n"
17388 							   "    gl_TessLevelInner[1] = 1.0;\n"
17389 							   "}\n"
17390 							   "\n";
17391 	static const GLchar* tcs_tested = "#version 430 core\n"
17392 									  "#extension GL_ARB_enhanced_layouts : require\n"
17393 									  "\n"
17394 									  "layout(vertices = 1) out;\n"
17395 									  "\n"
17396 									  "VAR_DEFINITION"
17397 									  "\n"
17398 									  "in  vec4 vs_tcs[];\n"
17399 									  "out vec4 tcs_tes[];\n"
17400 									  "\n"
17401 									  "void main()\n"
17402 									  "{\n"
17403 									  "    vec4 result = vs_tcs[gl_InvocationID];\n"
17404 									  "\n"
17405 									  "VARIABLE_USE"
17406 									  "\n"
17407 									  "    tcs_tes[gl_InvocationID] = result;\n"
17408 									  "\n"
17409 									  "    gl_TessLevelOuter[0] = 1.0;\n"
17410 									  "    gl_TessLevelOuter[1] = 1.0;\n"
17411 									  "    gl_TessLevelOuter[2] = 1.0;\n"
17412 									  "    gl_TessLevelOuter[3] = 1.0;\n"
17413 									  "    gl_TessLevelInner[0] = 1.0;\n"
17414 									  "    gl_TessLevelInner[1] = 1.0;\n"
17415 									  "}\n"
17416 									  "\n";
17417 	static const GLchar* tes = "#version 430 core\n"
17418 							   "#extension GL_ARB_enhanced_layouts : require\n"
17419 							   "\n"
17420 							   "layout(isolines, point_mode) in;\n"
17421 							   "\n"
17422 							   "layout (location = 1, component = COMPONENT) FLAT out TYPE gohan;\n"
17423 							   "\n"
17424 							   "in  vec4 tcs_tes[];\n"
17425 							   "out vec4 tes_gs;\n"
17426 							   "\n"
17427 							   "void main()\n"
17428 							   "{\n"
17429 							   "    gohan = TYPE(1);\n"
17430 							   "\n"
17431 							   "    tes_gs = tcs_tes[0];\n"
17432 							   "}\n"
17433 							   "\n";
17434 	static const GLchar* tes_tested = "#version 430 core\n"
17435 									  "#extension GL_ARB_enhanced_layouts : require\n"
17436 									  "\n"
17437 									  "layout(isolines, point_mode) in;\n"
17438 									  "\n"
17439 									  "VAR_DEFINITION"
17440 									  "\n"
17441 									  "in  vec4 tcs_tes[];\n"
17442 									  "out vec4 tes_gs;\n"
17443 									  "\n"
17444 									  "void main()\n"
17445 									  "{\n"
17446 									  "    vec4 result = tcs_tes[0];\n"
17447 									  "\n"
17448 									  "VARIABLE_USE"
17449 									  "\n"
17450 									  "    tes_gs += result;\n"
17451 									  "}\n"
17452 									  "\n";
17453 	static const GLchar* vs = "#version 430 core\n"
17454 							  "#extension GL_ARB_enhanced_layouts : require\n"
17455 							  "\n"
17456 							  "layout (location = 1, component = COMPONENT) FLAT out TYPE gohan;\n"
17457 							  "\n"
17458 							  "in  vec4 in_vs;\n"
17459 							  "out vec4 vs_tcs;\n"
17460 							  "\n"
17461 							  "void main()\n"
17462 							  "{\n"
17463 							  "    gohan = TYPE(1);\n"
17464 							  "\n"
17465 							  "    vs_tcs = in_vs;\n"
17466 							  "}\n"
17467 							  "\n";
17468 	static const GLchar* vs_tested = "#version 430 core\n"
17469 									 "#extension GL_ARB_enhanced_layouts : require\n"
17470 									 "\n"
17471 									 "VAR_DEFINITION"
17472 									 "\n"
17473 									 "in  vec4 in_vs;\n"
17474 									 "out vec4 vs_tcs;\n"
17475 									 "\n"
17476 									 "void main()\n"
17477 									 "{\n"
17478 									 "    vec4 result = in_vs;\n"
17479 									 "\n"
17480 									 "VARIABLE_USE"
17481 									 "\n"
17482 									 "    vs_tcs += result;\n"
17483 									 "}\n"
17484 									 "\n";
17485 
17486 	std::string   source;
17487 	testCase&	 test_case = m_test_cases[test_case_index];
17488 	GLchar		  buffer_gohan[16];
17489 	const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
17490 
17491 	sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
17492 
17493 	if (test_case.m_stage == stage)
17494 	{
17495 		const GLchar* array = "";
17496 		GLchar		  buffer_goten[16];
17497 		const GLchar* flat		  = "";
17498 		const GLchar* index		  = "";
17499 		size_t		  position	= 0;
17500 		const GLchar* var_use   = test_one;
17501 
17502 		if (isFlatRequired(stage, test_case.m_type, Utils::Variable::VARYING_INPUT, true))
17503 		{
17504 			flat = "flat";
17505 		}
17506 
17507 		sprintf(buffer_goten, "%d", test_case.m_component_goten);
17508 
17509 		switch (stage)
17510 		{
17511 		case Utils::Shader::FRAGMENT:
17512 			source = fs_tested;
17513 			break;
17514 		case Utils::Shader::GEOMETRY:
17515 			source = gs_tested;
17516 			array  = "[]";
17517 			index  = "[0]";
17518 			break;
17519 		case Utils::Shader::TESS_CTRL:
17520 			source = tcs_tested;
17521 			array  = "[]";
17522 			index  = "[gl_InvocationID]";
17523 			break;
17524 		case Utils::Shader::TESS_EVAL:
17525 			source = tes_tested;
17526 			array  = "[]";
17527 			index  = "[0]";
17528 			break;
17529 		case Utils::Shader::VERTEX:
17530 			source = vs_tested;
17531 			break;
17532 		default:
17533 			TCU_FAIL("Invalid enum");
17534 		}
17535 
17536 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
17537 		position = 0;
17538 		Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
17539 		Utils::replaceToken("ARRAY", position, array, source);
17540 		Utils::replaceToken("COMPONENT", position, buffer_goten, source);
17541 		Utils::replaceToken("ARRAY", position, array, source);
17542 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
17543 
17544 		Utils::replaceAllTokens("FLAT", flat, source);
17545 		Utils::replaceAllTokens("TYPE", type_name, source);
17546 		Utils::replaceAllTokens("INDEX", index, source);
17547 	}
17548 	else
17549 	{
17550 		const GLchar* flat = "";
17551 
17552 		if (isFlatRequired(stage, test_case.m_type, Utils::Variable::VARYING_OUTPUT, true))
17553 		{
17554 			flat = "flat";
17555 		}
17556 
17557 		switch (stage)
17558 		{
17559 		case Utils::Shader::FRAGMENT:
17560 			source = fs;
17561 			break;
17562 		case Utils::Shader::GEOMETRY:
17563 			source = gs;
17564 			break;
17565 		case Utils::Shader::TESS_CTRL:
17566 			source = tcs;
17567 			break;
17568 		case Utils::Shader::TESS_EVAL:
17569 			source = tes;
17570 			break;
17571 		case Utils::Shader::VERTEX:
17572 			source = vs;
17573 			break;
17574 		default:
17575 			TCU_FAIL("Invalid enum");
17576 		}
17577 
17578 		Utils::replaceAllTokens("FLAT", flat, source);
17579 		Utils::replaceAllTokens("COMPONENT", buffer_gohan, source);
17580 		Utils::replaceAllTokens("TYPE", type_name, source);
17581 	}
17582 
17583 	return source;
17584 }
17585 
17586 /** Get description of test case
17587  *
17588  * @param test_case_index Index of test case
17589  *
17590  * @return Test case description
17591  **/
17592 std::string InputComponentAliasingTest::getTestCaseName(GLuint test_case_index)
17593 {
17594 	std::stringstream stream;
17595 	testCase&		  test_case = m_test_cases[test_case_index];
17596 
17597 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
17598 		   << " type: " << test_case.m_type.GetGLSLTypeName() << ", components: " << test_case.m_component_gohan
17599 		   << " & " << test_case.m_component_goten;
17600 
17601 	return stream.str();
17602 }
17603 
17604 /** Get number of test cases
17605  *
17606  * @return Number of test cases
17607  **/
17608 GLuint InputComponentAliasingTest::getTestCaseNumber()
17609 {
17610 	return static_cast<GLuint>(m_test_cases.size());
17611 }
17612 
17613 /** Selects if "compute" stage is relevant for test
17614  *
17615  * @param ignored
17616  *
17617  * @return false
17618  **/
17619 bool InputComponentAliasingTest::isComputeRelevant(GLuint /* test_case_index */)
17620 {
17621 	return false;
17622 }
17623 
17624 /** Selects if compilation failure is expected result
17625  *
17626  * @param test_case_index Index of test case
17627  *
17628  * @return false for VS that use only single variable, true otherwise
17629  **/
17630 bool InputComponentAliasingTest::isFailureExpected(GLuint test_case_index)
17631 {
17632 	testCase& test_case = m_test_cases[test_case_index];
17633 
17634 	return (Utils::Shader::VERTEX != test_case.m_stage);
17635 }
17636 
17637 /** Prepare all test cases
17638  *
17639  **/
17640 void InputComponentAliasingTest::testInit()
17641 {
17642 	const GLuint		n_types					  = getTypesNumber();
17643 
17644 	for (GLuint i = 0; i < n_types; ++i)
17645 	{
17646 		const Utils::Type& type						 = getType(i);
17647 		const std::vector<GLuint>& valid_components			 = type.GetValidComponents();
17648 
17649 		if (valid_components.empty())
17650 		{
17651 			continue;
17652 		}
17653 
17654 		for (std::vector<GLuint>::const_iterator it_gohan = valid_components.begin();
17655 			 it_gohan != valid_components.end(); ++it_gohan)
17656 		{
17657 			const GLuint max_component = *it_gohan + type.GetNumComponents();
17658 			for (std::vector<GLuint>::const_iterator it_goten = it_gohan;
17659 				 it_goten != valid_components.end() && max_component > *it_goten; ++it_goten)
17660 			{
17661 				for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
17662 				{
17663 					/* Skip compute shader */
17664 					if (Utils::Shader::COMPUTE == stage)
17665 					{
17666 						continue;
17667 					}
17668 
17669 					testCase test_case = { *it_gohan, *it_goten, (Utils::Shader::STAGES)stage, type };
17670 
17671 					m_test_cases.push_back(test_case);
17672 				}
17673 			}
17674 		}
17675 	}
17676 }
17677 
17678 /** Constructor
17679  *
17680  * @param context Test framework context
17681  **/
17682 OutputComponentAliasingTest::OutputComponentAliasingTest(deqp::Context& context)
17683 	: NegativeTestBase(context, "output_component_aliasing",
17684 					   "Test verifies that compiler reports component aliasing as error")
17685 {
17686 }
17687 
17688 /** Source for given test case and stage
17689  *
17690  * @param test_case_index Index of test case
17691  * @param stage           Shader stage
17692  *
17693  * @return Shader source
17694  **/
17695 std::string OutputComponentAliasingTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
17696 {
17697 	static const GLchar* var_definition =
17698 		"layout (location = 1, component = COMPONENT) FLAT out TYPE gohanARRAY;\n"
17699 #if DEBUG_NEG_REMOVE_ERROR
17700 		"/* layout (location = 1, component = COMPONENT) */ FLAT out TYPE gotenARRAY;\n";
17701 #else
17702 		"layout (location = 1, component = COMPONENT) FLAT out TYPE gotenARRAY;\n";
17703 #endif /* DEBUG_NEG_REMOVE_ERROR */
17704 	static const GLchar* l_test = "    gohanINDEX = TYPE(1);\n"
17705 								  "    gotenINDEX = TYPE(0);\n";
17706 	static const GLchar* fs = "#version 430 core\n"
17707 							  "#extension GL_ARB_enhanced_layouts : require\n"
17708 							  "\n"
17709 							  "in  vec4 gs_fs;\n"
17710 							  "out vec4 fs_out;\n"
17711 							  "\n"
17712 							  "void main()\n"
17713 							  "{\n"
17714 							  "    fs_out = gs_fs;\n"
17715 							  "}\n"
17716 							  "\n";
17717 	static const GLchar* fs_tested = "#version 430 core\n"
17718 									 "#extension GL_ARB_enhanced_layouts : require\n"
17719 									 "\n"
17720 									 "VAR_DEFINITION"
17721 									 "\n"
17722 									 "in  vec4 gs_fs;\n"
17723 									 "out vec4 fs_out;\n"
17724 									 "\n"
17725 									 "void main()\n"
17726 									 "{\n"
17727 									 "    vec4 result = gs_fs;\n"
17728 									 "\n"
17729 									 "VARIABLE_USE"
17730 									 "\n"
17731 									 "    fs_out += result;\n"
17732 									 "}\n"
17733 									 "\n";
17734 	static const GLchar* gs = "#version 430 core\n"
17735 							  "#extension GL_ARB_enhanced_layouts : require\n"
17736 							  "\n"
17737 							  "layout(points)                           in;\n"
17738 							  "layout(triangle_strip, max_vertices = 4) out;\n"
17739 							  "\n"
17740 							  "in  vec4 tes_gs[];\n"
17741 							  "out vec4 gs_fs;\n"
17742 							  "\n"
17743 							  "void main()\n"
17744 							  "{\n"
17745 							  "    gs_fs = tes_gs[0];\n"
17746 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
17747 							  "    EmitVertex();\n"
17748 							  "    gs_fs = tes_gs[0];\n"
17749 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
17750 							  "    EmitVertex();\n"
17751 							  "    gs_fs = tes_gs[0];\n"
17752 							  "    gl_Position  = vec4(1, -1, 0, 1);\n"
17753 							  "    EmitVertex();\n"
17754 							  "    gs_fs = tes_gs[0];\n"
17755 							  "    gl_Position  = vec4(1, 1, 0, 1);\n"
17756 							  "    EmitVertex();\n"
17757 							  "}\n"
17758 							  "\n";
17759 	static const GLchar* gs_tested = "#version 430 core\n"
17760 									 "#extension GL_ARB_enhanced_layouts : require\n"
17761 									 "\n"
17762 									 "layout(points)                           in;\n"
17763 									 "layout(triangle_strip, max_vertices = 4) out;\n"
17764 									 "\n"
17765 									 "VAR_DEFINITION"
17766 									 "\n"
17767 									 "in  vec4 tes_gs[];\n"
17768 									 "out vec4 gs_fs;\n"
17769 									 "\n"
17770 									 "void main()\n"
17771 									 "{\n"
17772 									 "    vec4 result = tes_gs[0];\n"
17773 									 "\n"
17774 									 "VARIABLE_USE"
17775 									 "\n"
17776 									 "    gs_fs = result;\n"
17777 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
17778 									 "    EmitVertex();\n"
17779 									 "    gs_fs = result;\n"
17780 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
17781 									 "    EmitVertex();\n"
17782 									 "    gs_fs = result;\n"
17783 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
17784 									 "    EmitVertex();\n"
17785 									 "    gs_fs = result;\n"
17786 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
17787 									 "    EmitVertex();\n"
17788 									 "}\n"
17789 									 "\n";
17790 	static const GLchar* tcs = "#version 430 core\n"
17791 							   "#extension GL_ARB_enhanced_layouts : require\n"
17792 							   "\n"
17793 							   "layout(vertices = 1) out;\n"
17794 							   "\n"
17795 							   "in  vec4 vs_tcs[];\n"
17796 							   "out vec4 tcs_tes[];\n"
17797 							   "\n"
17798 							   "void main()\n"
17799 							   "{\n"
17800 							   "\n"
17801 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
17802 							   "\n"
17803 							   "    gl_TessLevelOuter[0] = 1.0;\n"
17804 							   "    gl_TessLevelOuter[1] = 1.0;\n"
17805 							   "    gl_TessLevelOuter[2] = 1.0;\n"
17806 							   "    gl_TessLevelOuter[3] = 1.0;\n"
17807 							   "    gl_TessLevelInner[0] = 1.0;\n"
17808 							   "    gl_TessLevelInner[1] = 1.0;\n"
17809 							   "}\n"
17810 							   "\n";
17811 	static const GLchar* tcs_tested = "#version 430 core\n"
17812 									  "#extension GL_ARB_enhanced_layouts : require\n"
17813 									  "\n"
17814 									  "layout(vertices = 1) out;\n"
17815 									  "\n"
17816 									  "VAR_DEFINITION"
17817 									  "\n"
17818 									  "in  vec4 vs_tcs[];\n"
17819 									  "out vec4 tcs_tes[];\n"
17820 									  "\n"
17821 									  "void main()\n"
17822 									  "{\n"
17823 									  "    vec4 result = vs_tcs[gl_InvocationID];\n"
17824 									  "\n"
17825 									  "VARIABLE_USE"
17826 									  "\n"
17827 									  "    tcs_tes[gl_InvocationID] = result;\n"
17828 									  "\n"
17829 									  "    gl_TessLevelOuter[0] = 1.0;\n"
17830 									  "    gl_TessLevelOuter[1] = 1.0;\n"
17831 									  "    gl_TessLevelOuter[2] = 1.0;\n"
17832 									  "    gl_TessLevelOuter[3] = 1.0;\n"
17833 									  "    gl_TessLevelInner[0] = 1.0;\n"
17834 									  "    gl_TessLevelInner[1] = 1.0;\n"
17835 									  "}\n"
17836 									  "\n";
17837 	static const GLchar* tes = "#version 430 core\n"
17838 							   "#extension GL_ARB_enhanced_layouts : require\n"
17839 							   "\n"
17840 							   "layout(isolines, point_mode) in;\n"
17841 							   "\n"
17842 							   "in  vec4 tcs_tes[];\n"
17843 							   "out vec4 tes_gs;\n"
17844 							   "\n"
17845 							   "void main()\n"
17846 							   "{\n"
17847 							   "    tes_gs = tcs_tes[0];\n"
17848 							   "}\n"
17849 							   "\n";
17850 	static const GLchar* tes_tested = "#version 430 core\n"
17851 									  "#extension GL_ARB_enhanced_layouts : require\n"
17852 									  "\n"
17853 									  "layout(isolines, point_mode) in;\n"
17854 									  "\n"
17855 									  "VAR_DEFINITION"
17856 									  "\n"
17857 									  "in  vec4 tcs_tes[];\n"
17858 									  "out vec4 tes_gs;\n"
17859 									  "\n"
17860 									  "void main()\n"
17861 									  "{\n"
17862 									  "    vec4 result = tcs_tes[0];\n"
17863 									  "\n"
17864 									  "VARIABLE_USE"
17865 									  "\n"
17866 									  "    tes_gs += result;\n"
17867 									  "}\n"
17868 									  "\n";
17869 	static const GLchar* vs = "#version 430 core\n"
17870 							  "#extension GL_ARB_enhanced_layouts : require\n"
17871 							  "\n"
17872 							  "in  vec4 in_vs;\n"
17873 							  "out vec4 vs_tcs;\n"
17874 							  "\n"
17875 							  "void main()\n"
17876 							  "{\n"
17877 							  "    vs_tcs = in_vs;\n"
17878 							  "}\n"
17879 							  "\n";
17880 	static const GLchar* vs_tested = "#version 430 core\n"
17881 									 "#extension GL_ARB_enhanced_layouts : require\n"
17882 									 "\n"
17883 									 "VAR_DEFINITION"
17884 									 "\n"
17885 									 "in  vec4 in_vs;\n"
17886 									 "out vec4 vs_tcs;\n"
17887 									 "\n"
17888 									 "void main()\n"
17889 									 "{\n"
17890 									 "    vec4 result = in_vs;\n"
17891 									 "\n"
17892 									 "VARIABLE_USE"
17893 									 "\n"
17894 									 "    vs_tcs += result;\n"
17895 									 "}\n"
17896 									 "\n";
17897 
17898 	std::string source;
17899 	testCase&   test_case = m_test_cases[test_case_index];
17900 
17901 	if (test_case.m_stage == stage)
17902 	{
17903 		const GLchar* array = "";
17904 		GLchar		  buffer_gohan[16];
17905 		GLchar		  buffer_goten[16];
17906 		const GLchar* flat	 = "";
17907 		const GLchar* index	= "";
17908 		size_t		  position = 0;
17909 		const GLchar* type_name = test_case.m_type.GetGLSLTypeName();
17910 
17911 		if (isFlatRequired(stage, test_case.m_type, Utils::Variable::VARYING_OUTPUT))
17912 		{
17913 			flat = "flat";
17914 		}
17915 
17916 		sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
17917 		sprintf(buffer_goten, "%d", test_case.m_component_goten);
17918 
17919 		switch (stage)
17920 		{
17921 		case Utils::Shader::FRAGMENT:
17922 			source = fs_tested;
17923 			break;
17924 		case Utils::Shader::GEOMETRY:
17925 			source = gs_tested;
17926 			break;
17927 		case Utils::Shader::TESS_CTRL:
17928 			source = tcs_tested;
17929 			array  = "[]";
17930 			index  = "[gl_InvocationID]";
17931 			break;
17932 		case Utils::Shader::TESS_EVAL:
17933 			source = tes_tested;
17934 			break;
17935 		case Utils::Shader::VERTEX:
17936 			source = vs_tested;
17937 			break;
17938 		default:
17939 			TCU_FAIL("Invalid enum");
17940 		}
17941 
17942 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
17943 		position = 0;
17944 		Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
17945 		Utils::replaceToken("FLAT", position, flat, source);
17946 		Utils::replaceToken("ARRAY", position, array, source);
17947 		Utils::replaceToken("COMPONENT", position, buffer_goten, source);
17948 		Utils::replaceToken("FLAT", position, flat, source);
17949 		Utils::replaceToken("ARRAY", position, array, source);
17950 		Utils::replaceToken("VARIABLE_USE", position, l_test, source);
17951 
17952 		Utils::replaceAllTokens("TYPE", type_name, source);
17953 		Utils::replaceAllTokens("INDEX", index, source);
17954 	}
17955 	else
17956 	{
17957 		switch (stage)
17958 		{
17959 		case Utils::Shader::FRAGMENT:
17960 			source = fs;
17961 			break;
17962 		case Utils::Shader::GEOMETRY:
17963 			source = gs;
17964 			break;
17965 		case Utils::Shader::TESS_CTRL:
17966 			source = tcs;
17967 			break;
17968 		case Utils::Shader::TESS_EVAL:
17969 			source = tes;
17970 			break;
17971 		case Utils::Shader::VERTEX:
17972 			source = vs;
17973 			break;
17974 		default:
17975 			TCU_FAIL("Invalid enum");
17976 		}
17977 	}
17978 
17979 	return source;
17980 }
17981 
17982 /** Get description of test case
17983  *
17984  * @param test_case_index Index of test case
17985  *
17986  * @return Test case description
17987  **/
17988 std::string OutputComponentAliasingTest::getTestCaseName(GLuint test_case_index)
17989 {
17990 	std::stringstream stream;
17991 	testCase&		  test_case = m_test_cases[test_case_index];
17992 
17993 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
17994 		   << " type: " << test_case.m_type.GetGLSLTypeName() << ", components: " << test_case.m_component_gohan
17995 		   << " & " << test_case.m_component_goten;
17996 
17997 	return stream.str();
17998 }
17999 
18000 /** Get number of test cases
18001  *
18002  * @return Number of test cases
18003  **/
18004 GLuint OutputComponentAliasingTest::getTestCaseNumber()
18005 {
18006 	return static_cast<GLuint>(m_test_cases.size());
18007 }
18008 
18009 /** Selects if "compute" stage is relevant for test
18010  *
18011  * @param ignored
18012  *
18013  * @return false
18014  **/
18015 bool OutputComponentAliasingTest::isComputeRelevant(GLuint /* test_case_index */)
18016 {
18017 	return false;
18018 }
18019 
18020 /** Prepare all test cases
18021  *
18022  **/
18023 void OutputComponentAliasingTest::testInit()
18024 {
18025 	const GLuint		n_types					  = getTypesNumber();
18026 
18027 	for (GLuint i = 0; i < n_types; ++i)
18028 	{
18029 		const Utils::Type&		   type				= getType(i);
18030 		const std::vector<GLuint>& valid_components = type.GetValidComponents();
18031 
18032 		if (valid_components.empty())
18033 		{
18034 			continue;
18035 		}
18036 
18037 		for (std::vector<GLuint>::const_iterator it_gohan = valid_components.begin();
18038 			 it_gohan != valid_components.end(); ++it_gohan)
18039 		{
18040 			const GLuint max_component = *it_gohan + type.GetNumComponents();
18041 			for (std::vector<GLuint>::const_iterator it_goten = it_gohan;
18042 				 it_goten != valid_components.end() && max_component > *it_goten; ++it_goten)
18043 			{
18044 				for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
18045 				{
18046 					/* Skip compute shader */
18047 					if (Utils::Shader::COMPUTE == stage)
18048 					{
18049 						continue;
18050 					}
18051 
18052 					if ((Utils::Shader::FRAGMENT == stage) && (Utils::Type::Double == type.m_basic_type))
18053 					{
18054 						continue;
18055 					}
18056 
18057 					testCase test_case = { *it_gohan, *it_goten, (Utils::Shader::STAGES)stage, type };
18058 
18059 					m_test_cases.push_back(test_case);
18060 				}
18061 			}
18062 		}
18063 	}
18064 }
18065 
18066 /** Constructor
18067  *
18068  * @param context Test framework context
18069  **/
18070 VaryingLocationAliasingWithMixedTypesTest::VaryingLocationAliasingWithMixedTypesTest(deqp::Context& context)
18071 	: NegativeTestBase(context, "varying_location_aliasing_with_mixed_types",
18072 					   "Test verifies that compiler reports error when float/int types are mixed at one location")
18073 {
18074 }
18075 
18076 /** Source for given test case and stage
18077  *
18078  * @param test_case_index Index of test case
18079  * @param stage           Shader stage
18080  *
18081  * @return Shader source
18082  **/
18083 std::string VaryingLocationAliasingWithMixedTypesTest::getShaderSource(GLuint				 test_case_index,
18084 																	   Utils::Shader::STAGES stage)
18085 {
18086 	static const GLchar* var_definition =
18087 		"layout (location = 1, component = COMPONENT) FLAT DIRECTION TYPE gohanARRAY;\n"
18088 		"layout (location = 1, component = COMPONENT) FLAT DIRECTION TYPE gotenARRAY;\n";
18089 	static const GLchar* input_use = "    if ((TYPE(0) == gohanINDEX) &&\n"
18090 									 "        (TYPE(1) == gotenINDEX) )\n"
18091 									 "    {\n"
18092 									 "        result += vec4(1, 0.5, 0.25, 0.125);\n"
18093 									 "    }\n";
18094 	static const GLchar* output_use = "    gohanINDEX = TYPE(0);\n"
18095 									  "    gotenINDEX = TYPE(1);\n"
18096 									  "    if (vec4(0) == result)\n"
18097 									  "    {\n"
18098 									  "        gohanINDEX = TYPE(1);\n"
18099 									  "        gotenINDEX = TYPE(0);\n"
18100 									  "    }\n";
18101 	static const GLchar* fs = "#version 430 core\n"
18102 							  "#extension GL_ARB_enhanced_layouts : require\n"
18103 							  "\n"
18104 							  "in  vec4 gs_fs;\n"
18105 							  "out vec4 fs_out;\n"
18106 							  "\n"
18107 							  "void main()\n"
18108 							  "{\n"
18109 							  "    fs_out = gs_fs;\n"
18110 							  "}\n"
18111 							  "\n";
18112 	static const GLchar* fs_tested = "#version 430 core\n"
18113 									 "#extension GL_ARB_enhanced_layouts : require\n"
18114 									 "\n"
18115 									 "VAR_DEFINITION"
18116 									 "\n"
18117 									 "in  vec4 gs_fs;\n"
18118 									 "out vec4 fs_out;\n"
18119 									 "\n"
18120 									 "void main()\n"
18121 									 "{\n"
18122 									 "    vec4 result = gs_fs;\n"
18123 									 "\n"
18124 									 "VARIABLE_USE"
18125 									 "\n"
18126 									 "    fs_out += result;\n"
18127 									 "}\n"
18128 									 "\n";
18129 	static const GLchar* gs = "#version 430 core\n"
18130 							  "#extension GL_ARB_enhanced_layouts : require\n"
18131 							  "\n"
18132 							  "layout(points)                           in;\n"
18133 							  "layout(triangle_strip, max_vertices = 4) out;\n"
18134 							  "\n"
18135 							  "in  vec4 tes_gs[];\n"
18136 							  "out vec4 gs_fs;\n"
18137 							  "\n"
18138 							  "void main()\n"
18139 							  "{\n"
18140 							  "    gs_fs = tes_gs[0];\n"
18141 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
18142 							  "    EmitVertex();\n"
18143 							  "    gs_fs = tes_gs[0];\n"
18144 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
18145 							  "    EmitVertex();\n"
18146 							  "    gs_fs = tes_gs[0];\n"
18147 							  "    gl_Position  = vec4(1, -1, 0, 1);\n"
18148 							  "    EmitVertex();\n"
18149 							  "    gs_fs = tes_gs[0];\n"
18150 							  "    gl_Position  = vec4(1, 1, 0, 1);\n"
18151 							  "    EmitVertex();\n"
18152 							  "}\n"
18153 							  "\n";
18154 	static const GLchar* gs_tested = "#version 430 core\n"
18155 									 "#extension GL_ARB_enhanced_layouts : require\n"
18156 									 "\n"
18157 									 "layout(points)                           in;\n"
18158 									 "layout(triangle_strip, max_vertices = 4) out;\n"
18159 									 "\n"
18160 									 "VAR_DEFINITION"
18161 									 "\n"
18162 									 "in  vec4 tes_gs[];\n"
18163 									 "out vec4 gs_fs;\n"
18164 									 "\n"
18165 									 "void main()\n"
18166 									 "{\n"
18167 									 "    vec4 result = tes_gs[0];\n"
18168 									 "\n"
18169 									 "VARIABLE_USE"
18170 									 "\n"
18171 									 "    gs_fs = result;\n"
18172 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
18173 									 "    EmitVertex();\n"
18174 									 "    gs_fs = result;\n"
18175 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
18176 									 "    EmitVertex();\n"
18177 									 "    gs_fs = result;\n"
18178 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
18179 									 "    EmitVertex();\n"
18180 									 "    gs_fs = result;\n"
18181 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
18182 									 "    EmitVertex();\n"
18183 									 "}\n"
18184 									 "\n";
18185 	static const GLchar* tcs = "#version 430 core\n"
18186 							   "#extension GL_ARB_enhanced_layouts : require\n"
18187 							   "\n"
18188 							   "layout(vertices = 1) out;\n"
18189 							   "\n"
18190 							   "in  vec4 vs_tcs[];\n"
18191 							   "out vec4 tcs_tes[];\n"
18192 							   "\n"
18193 							   "void main()\n"
18194 							   "{\n"
18195 							   "\n"
18196 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
18197 							   "\n"
18198 							   "    gl_TessLevelOuter[0] = 1.0;\n"
18199 							   "    gl_TessLevelOuter[1] = 1.0;\n"
18200 							   "    gl_TessLevelOuter[2] = 1.0;\n"
18201 							   "    gl_TessLevelOuter[3] = 1.0;\n"
18202 							   "    gl_TessLevelInner[0] = 1.0;\n"
18203 							   "    gl_TessLevelInner[1] = 1.0;\n"
18204 							   "}\n"
18205 							   "\n";
18206 	static const GLchar* tcs_tested = "#version 430 core\n"
18207 									  "#extension GL_ARB_enhanced_layouts : require\n"
18208 									  "\n"
18209 									  "layout(vertices = 1) out;\n"
18210 									  "\n"
18211 									  "VAR_DEFINITION"
18212 									  "\n"
18213 									  "in  vec4 vs_tcs[];\n"
18214 									  "out vec4 tcs_tes[];\n"
18215 									  "\n"
18216 									  "void main()\n"
18217 									  "{\n"
18218 									  "    vec4 result = vs_tcs[gl_InvocationID];\n"
18219 									  "\n"
18220 									  "VARIABLE_USE"
18221 									  "\n"
18222 									  "    tcs_tes[gl_InvocationID] = result;\n"
18223 									  "\n"
18224 									  "    gl_TessLevelOuter[0] = 1.0;\n"
18225 									  "    gl_TessLevelOuter[1] = 1.0;\n"
18226 									  "    gl_TessLevelOuter[2] = 1.0;\n"
18227 									  "    gl_TessLevelOuter[3] = 1.0;\n"
18228 									  "    gl_TessLevelInner[0] = 1.0;\n"
18229 									  "    gl_TessLevelInner[1] = 1.0;\n"
18230 									  "}\n"
18231 									  "\n";
18232 	static const GLchar* tes = "#version 430 core\n"
18233 							   "#extension GL_ARB_enhanced_layouts : require\n"
18234 							   "\n"
18235 							   "layout(isolines, point_mode) in;\n"
18236 							   "\n"
18237 							   "in  vec4 tcs_tes[];\n"
18238 							   "out vec4 tes_gs;\n"
18239 							   "\n"
18240 							   "void main()\n"
18241 							   "{\n"
18242 							   "    tes_gs = tcs_tes[0];\n"
18243 							   "}\n"
18244 							   "\n";
18245 	static const GLchar* tes_tested = "#version 430 core\n"
18246 									  "#extension GL_ARB_enhanced_layouts : require\n"
18247 									  "\n"
18248 									  "layout(isolines, point_mode) in;\n"
18249 									  "\n"
18250 									  "VAR_DEFINITION"
18251 									  "\n"
18252 									  "in  vec4 tcs_tes[];\n"
18253 									  "out vec4 tes_gs;\n"
18254 									  "\n"
18255 									  "void main()\n"
18256 									  "{\n"
18257 									  "    vec4 result = tcs_tes[0];\n"
18258 									  "\n"
18259 									  "VARIABLE_USE"
18260 									  "\n"
18261 									  "    tes_gs += result;\n"
18262 									  "}\n"
18263 									  "\n";
18264 	static const GLchar* vs = "#version 430 core\n"
18265 							  "#extension GL_ARB_enhanced_layouts : require\n"
18266 							  "\n"
18267 							  "in  vec4 in_vs;\n"
18268 							  "out vec4 vs_tcs;\n"
18269 							  "\n"
18270 							  "void main()\n"
18271 							  "{\n"
18272 							  "    vs_tcs = in_vs;\n"
18273 							  "}\n"
18274 							  "\n";
18275 	static const GLchar* vs_tested = "#version 430 core\n"
18276 									 "#extension GL_ARB_enhanced_layouts : require\n"
18277 									 "\n"
18278 									 "VAR_DEFINITION"
18279 									 "\n"
18280 									 "in  vec4 in_vs;\n"
18281 									 "out vec4 vs_tcs;\n"
18282 									 "\n"
18283 									 "void main()\n"
18284 									 "{\n"
18285 									 "    vec4 result = in_vs;\n"
18286 									 "\n"
18287 									 "VARIABLE_USE"
18288 									 "\n"
18289 									 "    vs_tcs += result;\n"
18290 									 "}\n"
18291 									 "\n";
18292 
18293 	std::string source;
18294 	testCase&   test_case = m_test_cases[test_case_index];
18295 
18296 	if (test_case.m_stage == stage)
18297 	{
18298 		const GLchar*			 array = "";
18299 		GLchar					 buffer_gohan[16];
18300 		GLchar					 buffer_goten[16];
18301 		const GLchar*			 direction  = "in ";
18302 		const GLchar*			 flat_gohan = "";
18303 		const GLchar*			 flat_goten = "";
18304 		const GLchar*			 index		= "";
18305 		size_t					 position   = 0;
18306 		size_t					 temp;
18307 		const GLchar*			 type_gohan_name = test_case.m_type_gohan.GetGLSLTypeName();
18308 		const GLchar*			 type_goten_name = test_case.m_type_goten.GetGLSLTypeName();
18309 		Utils::Variable::STORAGE storage		 = Utils::Variable::VARYING_INPUT;
18310 		const GLchar*			 var_use		 = Utils::Shader::VERTEX == stage ? input_use : "\n";
18311 
18312 		if (false == test_case.m_is_input)
18313 		{
18314 			direction = "out";
18315 			storage   = Utils::Variable::VARYING_OUTPUT;
18316 			var_use   = output_use;
18317 		}
18318 
18319 		/* If the interpolation qualifier would be different, the test
18320 		 * would fail and we are testing here mixed types, not mixed
18321 		 * interpolation qualifiers.
18322 		 */
18323 		if (isFlatRequired(stage, test_case.m_type_gohan, storage) ||
18324 			isFlatRequired(stage, test_case.m_type_goten, storage))
18325 		{
18326 			flat_gohan = "flat";
18327 			flat_goten = "flat";
18328 		}
18329 
18330 		sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
18331 		sprintf(buffer_goten, "%d", test_case.m_component_goten);
18332 
18333 #if DEBUG_NEG_REMOVE_ERROR
18334 		type_goten_name = Utils::Type::GetType(test_case.m_type_gohan.m_basic_type, 1, 1).GetGLSLTypeName();
18335 		if (Utils::Type::Double == test_case.m_type_gohan.m_basic_type)
18336 		{
18337 			sprintf(buffer_goten, "%d", 0 == test_case.m_component_gohan ? 2 : 0);
18338 		}
18339 #endif /* DEBUG_NEG_REMOVE_ERROR */
18340 
18341 		switch (stage)
18342 		{
18343 		case Utils::Shader::FRAGMENT:
18344 			source = fs_tested;
18345 			break;
18346 		case Utils::Shader::GEOMETRY:
18347 			source = gs_tested;
18348 			array  = test_case.m_is_input ? "[]" : "";
18349 			index  = test_case.m_is_input ? "[0]" : "";
18350 			break;
18351 		case Utils::Shader::TESS_CTRL:
18352 			source = tcs_tested;
18353 			array  = "[]";
18354 			index  = "[gl_InvocationID]";
18355 			break;
18356 		case Utils::Shader::TESS_EVAL:
18357 			source = tes_tested;
18358 			array  = test_case.m_is_input ? "[]" : "";
18359 			index  = test_case.m_is_input ? "[0]" : "";
18360 			break;
18361 		case Utils::Shader::VERTEX:
18362 			source = vs_tested;
18363 			break;
18364 		default:
18365 			TCU_FAIL("Invalid enum");
18366 		}
18367 
18368 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
18369 		position = 0;
18370 		Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
18371 		Utils::replaceToken("FLAT", position, flat_gohan, source);
18372 		Utils::replaceToken("DIRECTION", position, direction, source);
18373 		Utils::replaceToken("TYPE", position, type_gohan_name, source);
18374 		Utils::replaceToken("ARRAY", position, array, source);
18375 		Utils::replaceToken("COMPONENT", position, buffer_goten, source);
18376 		Utils::replaceToken("FLAT", position, flat_goten, source);
18377 		Utils::replaceToken("DIRECTION", position, direction, source);
18378 		Utils::replaceToken("TYPE", position, type_goten_name, source);
18379 		Utils::replaceToken("ARRAY", position, array, source);
18380 
18381 		temp = position;
18382 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
18383 		position = temp;
18384 		if (!test_case.m_is_input)
18385 		{
18386 			Utils::replaceToken("TYPE", position, type_gohan_name, source);
18387 			Utils::replaceToken("TYPE", position, type_goten_name, source);
18388 			Utils::replaceToken("TYPE", position, type_gohan_name, source);
18389 			Utils::replaceToken("TYPE", position, type_goten_name, source);
18390 		}
18391 		else if (Utils::Shader::VERTEX == stage)
18392 		{
18393 			Utils::replaceToken("TYPE", position, type_gohan_name, source);
18394 			Utils::replaceToken("TYPE", position, type_goten_name, source);
18395 		}
18396 
18397 		Utils::replaceAllTokens("INDEX", index, source);
18398 	}
18399 	else
18400 	{
18401 		switch (stage)
18402 		{
18403 		case Utils::Shader::FRAGMENT:
18404 			source = fs;
18405 			break;
18406 		case Utils::Shader::GEOMETRY:
18407 			source = gs;
18408 			break;
18409 		case Utils::Shader::TESS_CTRL:
18410 			source = tcs;
18411 			break;
18412 		case Utils::Shader::TESS_EVAL:
18413 			source = tes;
18414 			break;
18415 		case Utils::Shader::VERTEX:
18416 			source = vs;
18417 			break;
18418 		default:
18419 			TCU_FAIL("Invalid enum");
18420 		}
18421 	}
18422 
18423 	return source;
18424 }
18425 
18426 /** Get description of test case
18427  *
18428  * @param test_case_index Index of test case
18429  *
18430  * @return Test case description
18431  **/
18432 std::string VaryingLocationAliasingWithMixedTypesTest::getTestCaseName(GLuint test_case_index)
18433 {
18434 	std::stringstream stream;
18435 	testCase&		  test_case = m_test_cases[test_case_index];
18436 
18437 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", "
18438 		   << test_case.m_type_gohan.GetGLSLTypeName() << " at " << test_case.m_component_gohan << ", "
18439 		   << test_case.m_type_goten.GetGLSLTypeName() << " at " << test_case.m_component_goten << ". Direction: ";
18440 
18441 	if (true == test_case.m_is_input)
18442 	{
18443 		stream << "input";
18444 	}
18445 	else
18446 	{
18447 		stream << "output";
18448 	}
18449 
18450 	return stream.str();
18451 }
18452 
18453 /** Get number of test cases
18454  *
18455  * @return Number of test cases
18456  **/
18457 GLuint VaryingLocationAliasingWithMixedTypesTest::getTestCaseNumber()
18458 {
18459 	return static_cast<GLuint>(m_test_cases.size());
18460 }
18461 
18462 /** Selects if "compute" stage is relevant for test
18463  *
18464  * @param ignored
18465  *
18466  * @return false
18467  **/
18468 bool VaryingLocationAliasingWithMixedTypesTest::isComputeRelevant(GLuint /* test_case_index */)
18469 {
18470 	return false;
18471 }
18472 
18473 /** Prepare all test cases
18474  *
18475  **/
18476 void VaryingLocationAliasingWithMixedTypesTest::testInit()
18477 {
18478 	const GLuint		n_types					  = getTypesNumber();
18479 
18480 	for (GLuint i = 0; i < n_types; ++i)
18481 	{
18482 		const Utils::Type& type_gohan		   = getType(i);
18483 		const std::vector<GLuint>& valid_components_gohan = type_gohan.GetValidComponents();
18484 
18485 		if (valid_components_gohan.empty())
18486 		{
18487 			continue;
18488 		}
18489 
18490 		for (GLuint j = 0; j < n_types; ++j)
18491 		{
18492 			const Utils::Type& type_goten		   = getType(j);
18493 			const std::vector<GLuint>& valid_components_goten = type_goten.GetValidComponents();
18494 
18495 			if (valid_components_goten.empty())
18496 			{
18497 				continue;
18498 			}
18499 
18500 			/* Skip valid combinations */
18501 			if (Utils::Type::CanTypesShareLocation(type_gohan.m_basic_type, type_goten.m_basic_type))
18502 			{
18503 				continue;
18504 			}
18505 
18506 			for (std::vector<GLuint>::const_iterator it_gohan = valid_components_gohan.begin();
18507 				 it_gohan != valid_components_gohan.end(); ++it_gohan)
18508 			{
18509 				const GLuint min_component = *it_gohan + type_gohan.GetNumComponents();
18510 				for (std::vector<GLuint>::const_iterator it_goten = valid_components_goten.begin();
18511 					 it_goten != valid_components_goten.end(); ++it_goten)
18512 				{
18513 
18514 					if (min_component > *it_goten)
18515 					{
18516 						continue;
18517 					}
18518 
18519 					for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
18520 					{
18521 						/* Skip compute shader */
18522 						if (Utils::Shader::COMPUTE == stage)
18523 						{
18524 							continue;
18525 						}
18526 
18527 						if (Utils::Shader::VERTEX != stage)
18528 						{
18529 							testCase test_case_in = { *it_gohan,  *it_goten, true, (Utils::Shader::STAGES)stage,
18530 													  type_gohan, type_goten };
18531 
18532 							m_test_cases.push_back(test_case_in);
18533 						}
18534 
18535 						/* Skip double outputs in fragment shader */
18536 						if ((Utils::Shader::FRAGMENT != stage) || ((Utils::Type::Double != type_gohan.m_basic_type) &&
18537 																   (Utils::Type::Double != type_goten.m_basic_type)))
18538 						{
18539 							testCase test_case_out = { *it_gohan,  *it_goten, false, (Utils::Shader::STAGES)stage,
18540 													   type_gohan, type_goten };
18541 
18542 							m_test_cases.push_back(test_case_out);
18543 						}
18544 					}
18545 				}
18546 			}
18547 		}
18548 	}
18549 }
18550 
18551 /** Constructor
18552  *
18553  * @param context Test framework context
18554  **/
18555 VaryingLocationAliasingWithMixedInterpolationTest::VaryingLocationAliasingWithMixedInterpolationTest(
18556 	deqp::Context& context)
18557 	: NegativeTestBase(
18558 		  context, "varying_location_aliasing_with_mixed_interpolation",
18559 		  "Test verifies that compiler reports error when interpolation qualifiers are mixed at one location")
18560 {
18561 }
18562 
18563 /** Source for given test case and stage
18564  *
18565  * @param test_case_index Index of test case
18566  * @param stage           Shader stage
18567  *
18568  * @return Shader source
18569  **/
18570 std::string VaryingLocationAliasingWithMixedInterpolationTest::getShaderSource(GLuint				 test_case_index,
18571 																			   Utils::Shader::STAGES stage)
18572 {
18573 	static const GLchar* var_definition =
18574 		"layout (location = 1, component = COMPONENT) INTERPOLATION DIRECTION TYPE gohanARRAY;\n"
18575 		"layout (location = 1, component = COMPONENT) INTERPOLATION DIRECTION TYPE gotenARRAY;\n";
18576 	static const GLchar* input_use = "    if ((TYPE(0) == gohanINDEX) &&\n"
18577 									 "        (TYPE(1) == gotenINDEX) )\n"
18578 									 "    {\n"
18579 									 "        result += vec4(1, 0.5, 0.25, 0.125);\n"
18580 									 "    }\n";
18581 	static const GLchar* output_use = "    gohanINDEX = TYPE(0);\n"
18582 									  "    gotenINDEX = TYPE(1);\n"
18583 									  "    if (vec4(0) == result)\n"
18584 									  "    {\n"
18585 									  "        gohanINDEX = TYPE(1);\n"
18586 									  "        gotenINDEX = TYPE(0);\n"
18587 									  "    }\n";
18588 	static const GLchar* fs = "#version 430 core\n"
18589 							  "#extension GL_ARB_enhanced_layouts : require\n"
18590 							  "\n"
18591 							  "in  vec4 gs_fs;\n"
18592 							  "out vec4 fs_out;\n"
18593 							  "\n"
18594 							  "void main()\n"
18595 							  "{\n"
18596 							  "    fs_out = gs_fs;\n"
18597 							  "}\n"
18598 							  "\n";
18599 	static const GLchar* fs_tested = "#version 430 core\n"
18600 									 "#extension GL_ARB_enhanced_layouts : require\n"
18601 									 "\n"
18602 									 "VAR_DEFINITION"
18603 									 "\n"
18604 									 "in  vec4 gs_fs;\n"
18605 									 "out vec4 fs_out;\n"
18606 									 "\n"
18607 									 "void main()\n"
18608 									 "{\n"
18609 									 "    vec4 result = gs_fs;\n"
18610 									 "\n"
18611 									 "VARIABLE_USE"
18612 									 "\n"
18613 									 "    fs_out = result;\n"
18614 									 "}\n"
18615 									 "\n";
18616 	static const GLchar* gs = "#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 							  "in  vec4 tes_gs[];\n"
18623 							  "out vec4 gs_fs;\n"
18624 							  "\n"
18625 							  "void main()\n"
18626 							  "{\n"
18627 							  "    gs_fs = tes_gs[0];\n"
18628 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
18629 							  "    EmitVertex();\n"
18630 							  "    gs_fs = tes_gs[0];\n"
18631 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
18632 							  "    EmitVertex();\n"
18633 							  "    gs_fs = tes_gs[0];\n"
18634 							  "    gl_Position  = vec4(1, -1, 0, 1);\n"
18635 							  "    EmitVertex();\n"
18636 							  "    gs_fs = tes_gs[0];\n"
18637 							  "    gl_Position  = vec4(1, 1, 0, 1);\n"
18638 							  "    EmitVertex();\n"
18639 							  "}\n"
18640 							  "\n";
18641 	static const GLchar* gs_tested = "#version 430 core\n"
18642 									 "#extension GL_ARB_enhanced_layouts : require\n"
18643 									 "\n"
18644 									 "layout(points)                           in;\n"
18645 									 "layout(triangle_strip, max_vertices = 4) out;\n"
18646 									 "\n"
18647 									 "VAR_DEFINITION"
18648 									 "\n"
18649 									 "in  vec4 tes_gs[];\n"
18650 									 "out vec4 gs_fs;\n"
18651 									 "\n"
18652 									 "void main()\n"
18653 									 "{\n"
18654 									 "    vec4 result = tes_gs[0];\n"
18655 									 "\n"
18656 									 "VARIABLE_USE"
18657 									 "\n"
18658 									 "    gs_fs = result;\n"
18659 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
18660 									 "    EmitVertex();\n"
18661 									 "    gs_fs = result;\n"
18662 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
18663 									 "    EmitVertex();\n"
18664 									 "    gs_fs = result;\n"
18665 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
18666 									 "    EmitVertex();\n"
18667 									 "    gs_fs = result;\n"
18668 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
18669 									 "    EmitVertex();\n"
18670 									 "}\n"
18671 									 "\n";
18672 	static const GLchar* tcs = "#version 430 core\n"
18673 							   "#extension GL_ARB_enhanced_layouts : require\n"
18674 							   "\n"
18675 							   "layout(vertices = 1) out;\n"
18676 							   "\n"
18677 							   "in  vec4 vs_tcs[];\n"
18678 							   "out vec4 tcs_tes[];\n"
18679 							   "\n"
18680 							   "void main()\n"
18681 							   "{\n"
18682 							   "\n"
18683 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
18684 							   "\n"
18685 							   "    gl_TessLevelOuter[0] = 1.0;\n"
18686 							   "    gl_TessLevelOuter[1] = 1.0;\n"
18687 							   "    gl_TessLevelOuter[2] = 1.0;\n"
18688 							   "    gl_TessLevelOuter[3] = 1.0;\n"
18689 							   "    gl_TessLevelInner[0] = 1.0;\n"
18690 							   "    gl_TessLevelInner[1] = 1.0;\n"
18691 							   "}\n"
18692 							   "\n";
18693 	static const GLchar* tcs_tested = "#version 430 core\n"
18694 									  "#extension GL_ARB_enhanced_layouts : require\n"
18695 									  "\n"
18696 									  "layout(vertices = 1) out;\n"
18697 									  "\n"
18698 									  "VAR_DEFINITION"
18699 									  "\n"
18700 									  "in  vec4 vs_tcs[];\n"
18701 									  "out vec4 tcs_tes[];\n"
18702 									  "\n"
18703 									  "void main()\n"
18704 									  "{\n"
18705 									  "    vec4 result = vs_tcs[gl_InvocationID];\n"
18706 									  "\n"
18707 									  "VARIABLE_USE"
18708 									  "\n"
18709 									  "    tcs_tes[gl_InvocationID] = result;\n"
18710 									  "\n"
18711 									  "    gl_TessLevelOuter[0] = 1.0;\n"
18712 									  "    gl_TessLevelOuter[1] = 1.0;\n"
18713 									  "    gl_TessLevelOuter[2] = 1.0;\n"
18714 									  "    gl_TessLevelOuter[3] = 1.0;\n"
18715 									  "    gl_TessLevelInner[0] = 1.0;\n"
18716 									  "    gl_TessLevelInner[1] = 1.0;\n"
18717 									  "}\n"
18718 									  "\n";
18719 	static const GLchar* tes = "#version 430 core\n"
18720 							   "#extension GL_ARB_enhanced_layouts : require\n"
18721 							   "\n"
18722 							   "layout(isolines, point_mode) in;\n"
18723 							   "\n"
18724 							   "in  vec4 tcs_tes[];\n"
18725 							   "out vec4 tes_gs;\n"
18726 							   "\n"
18727 							   "void main()\n"
18728 							   "{\n"
18729 							   "    tes_gs = tcs_tes[0];\n"
18730 							   "}\n"
18731 							   "\n";
18732 	static const GLchar* tes_tested = "#version 430 core\n"
18733 									  "#extension GL_ARB_enhanced_layouts : require\n"
18734 									  "\n"
18735 									  "layout(isolines, point_mode) in;\n"
18736 									  "\n"
18737 									  "VAR_DEFINITION"
18738 									  "\n"
18739 									  "in  vec4 tcs_tes[];\n"
18740 									  "out vec4 tes_gs;\n"
18741 									  "\n"
18742 									  "void main()\n"
18743 									  "{\n"
18744 									  "    vec4 result = tcs_tes[0];\n"
18745 									  "\n"
18746 									  "VARIABLE_USE"
18747 									  "\n"
18748 									  "    tes_gs += result;\n"
18749 									  "}\n"
18750 									  "\n";
18751 	static const GLchar* vs = "#version 430 core\n"
18752 							  "#extension GL_ARB_enhanced_layouts : require\n"
18753 							  "\n"
18754 							  "in  vec4 in_vs;\n"
18755 							  "out vec4 vs_tcs;\n"
18756 							  "\n"
18757 							  "void main()\n"
18758 							  "{\n"
18759 							  "    vs_tcs = in_vs;\n"
18760 							  "}\n"
18761 							  "\n";
18762 	static const GLchar* vs_tested = "#version 430 core\n"
18763 									 "#extension GL_ARB_enhanced_layouts : require\n"
18764 									 "\n"
18765 									 "VAR_DEFINITION"
18766 									 "\n"
18767 									 "in  vec4 in_vs;\n"
18768 									 "out vec4 vs_tcs;\n"
18769 									 "\n"
18770 									 "void main()\n"
18771 									 "{\n"
18772 									 "    vec4 result = in_vs;\n"
18773 									 "\n"
18774 									 "VARIABLE_USE"
18775 									 "\n"
18776 									 "    vs_tcs += result;\n"
18777 									 "}\n"
18778 									 "\n";
18779 
18780 	std::string source;
18781 	testCase&   test_case = m_test_cases[test_case_index];
18782 
18783 	if (test_case.m_stage == stage)
18784 	{
18785 		const GLchar* array = "";
18786 		GLchar		  buffer_gohan[16];
18787 		GLchar		  buffer_goten[16];
18788 		const GLchar* direction = "in ";
18789 		const GLchar* index		= "";
18790 		const GLchar* int_gohan = getInterpolationQualifier(test_case.m_interpolation_gohan);
18791 		const GLchar* int_goten = getInterpolationQualifier(test_case.m_interpolation_goten);
18792 #if DEBUG_NEG_REMOVE_ERROR
18793 		if (FLAT == test_case.m_interpolation_goten)
18794 		{
18795 			int_gohan = int_goten;
18796 		}
18797 		else
18798 		{
18799 			int_goten = int_gohan;
18800 		}
18801 #endif /* DEBUG_NEG_REMOVE_ERROR */
18802 		size_t		  position  = 0;
18803 		size_t		  temp;
18804 		const GLchar* type_gohan_name = test_case.m_type_gohan.GetGLSLTypeName();
18805 		const GLchar* type_goten_name = test_case.m_type_goten.GetGLSLTypeName();
18806 		const GLchar* var_use		  = Utils::Shader::VERTEX == stage ? input_use : "\n";
18807 
18808 		if (false == test_case.m_is_input)
18809 		{
18810 			direction = "out";
18811 
18812 			var_use = output_use;
18813 		}
18814 
18815 		sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
18816 		sprintf(buffer_goten, "%d", test_case.m_component_goten);
18817 
18818 		switch (stage)
18819 		{
18820 		case Utils::Shader::FRAGMENT:
18821 			source = fs_tested;
18822 			break;
18823 		case Utils::Shader::GEOMETRY:
18824 			source = gs_tested;
18825 			array  = test_case.m_is_input ? "[]" : "";
18826 			index  = test_case.m_is_input ? "[0]" : "";
18827 			break;
18828 		case Utils::Shader::TESS_CTRL:
18829 			source = tcs_tested;
18830 			array  = "[]";
18831 			index  = "[gl_InvocationID]";
18832 			break;
18833 		case Utils::Shader::TESS_EVAL:
18834 			source = tes_tested;
18835 			array  = test_case.m_is_input ? "[]" : "";
18836 			index  = test_case.m_is_input ? "[0]" : "";
18837 			break;
18838 		case Utils::Shader::VERTEX:
18839 			source = vs_tested;
18840 			break;
18841 		default:
18842 			TCU_FAIL("Invalid enum");
18843 		}
18844 
18845 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
18846 		position = 0;
18847 		Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
18848 		Utils::replaceToken("INTERPOLATION", position, int_gohan, source);
18849 		Utils::replaceToken("DIRECTION", position, direction, source);
18850 		Utils::replaceToken("TYPE", position, type_gohan_name, source);
18851 		Utils::replaceToken("ARRAY", position, array, source);
18852 		Utils::replaceToken("COMPONENT", position, buffer_goten, source);
18853 		Utils::replaceToken("INTERPOLATION", position, int_goten, source);
18854 		Utils::replaceToken("DIRECTION", position, direction, source);
18855 		Utils::replaceToken("TYPE", position, type_goten_name, source);
18856 		Utils::replaceToken("ARRAY", position, array, source);
18857 
18858 		temp = position;
18859 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
18860 		position = temp;
18861 		if (!test_case.m_is_input)
18862 		{
18863 			Utils::replaceToken("TYPE", position, type_gohan_name, source);
18864 			Utils::replaceToken("TYPE", position, type_goten_name, source);
18865 			Utils::replaceToken("TYPE", position, type_gohan_name, source);
18866 			Utils::replaceToken("TYPE", position, type_goten_name, source);
18867 		}
18868 		else if (Utils::Shader::VERTEX == stage)
18869 		{
18870 			Utils::replaceToken("TYPE", position, type_gohan_name, source);
18871 			Utils::replaceToken("TYPE", position, type_goten_name, source);
18872 		}
18873 
18874 		Utils::replaceAllTokens("INDEX", index, source);
18875 	}
18876 	else
18877 	{
18878 		switch (stage)
18879 		{
18880 		case Utils::Shader::FRAGMENT:
18881 			source = fs;
18882 			break;
18883 		case Utils::Shader::GEOMETRY:
18884 			source = gs;
18885 			break;
18886 		case Utils::Shader::TESS_CTRL:
18887 			source = tcs;
18888 			break;
18889 		case Utils::Shader::TESS_EVAL:
18890 			source = tes;
18891 			break;
18892 		case Utils::Shader::VERTEX:
18893 			source = vs;
18894 			break;
18895 		default:
18896 			TCU_FAIL("Invalid enum");
18897 		}
18898 	}
18899 
18900 	return source;
18901 }
18902 
18903 /** Get description of test case
18904  *
18905  * @param test_case_index Index of test case
18906  *
18907  * @return Test case description
18908  **/
18909 std::string VaryingLocationAliasingWithMixedInterpolationTest::getTestCaseName(GLuint test_case_index)
18910 {
18911 	std::stringstream stream;
18912 	testCase&		  test_case = m_test_cases[test_case_index];
18913 
18914 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", "
18915 		   << getInterpolationQualifier(test_case.m_interpolation_gohan) << " "
18916 		   << test_case.m_type_gohan.GetGLSLTypeName() << " at " << test_case.m_component_gohan << ", "
18917 		   << getInterpolationQualifier(test_case.m_interpolation_goten) << " "
18918 		   << test_case.m_type_goten.GetGLSLTypeName() << " at " << test_case.m_component_goten << ". Direction: ";
18919 
18920 	if (true == test_case.m_is_input)
18921 	{
18922 		stream << "input";
18923 	}
18924 	else
18925 	{
18926 		stream << "output";
18927 	}
18928 
18929 	return stream.str();
18930 }
18931 
18932 /** Get number of test cases
18933  *
18934  * @return Number of test cases
18935  **/
18936 GLuint VaryingLocationAliasingWithMixedInterpolationTest::getTestCaseNumber()
18937 {
18938 	return static_cast<GLuint>(m_test_cases.size());
18939 }
18940 
18941 /** Selects if "compute" stage is relevant for test
18942  *
18943  * @param ignored
18944  *
18945  * @return false
18946  **/
18947 bool VaryingLocationAliasingWithMixedInterpolationTest::isComputeRelevant(GLuint /* test_case_index */)
18948 {
18949 	return false;
18950 }
18951 
18952 /** Prepare all test cases
18953  *
18954  **/
18955 void VaryingLocationAliasingWithMixedInterpolationTest::testInit()
18956 {
18957 	const GLuint		n_types					  = getTypesNumber();
18958 
18959 	for (GLuint i = 0; i < n_types; ++i)
18960 	{
18961 		const Utils::Type& type_gohan		   = getType(i);
18962 		const std::vector<GLuint>& valid_components_gohan = type_gohan.GetValidComponents();
18963 
18964 		if (valid_components_gohan.empty())
18965 		{
18966 			continue;
18967 		}
18968 
18969 		const GLuint gohan = valid_components_gohan.front();
18970 
18971 		for (GLuint j = 0; j < n_types; ++j)
18972 		{
18973 			const Utils::Type& type_goten		   = getType(j);
18974 			const std::vector<GLuint>& valid_components_goten = type_goten.GetValidComponents();
18975 
18976 			if (valid_components_goten.empty())
18977 			{
18978 				continue;
18979 			}
18980 
18981 			/* Just get the highest valid component for goten and
18982 			 * check if we can use it.
18983 			 */
18984 			const GLuint min_component = gohan + type_gohan.GetNumComponents();
18985 			const GLuint goten		   = valid_components_goten.back();
18986 
18987 			if (min_component > goten)
18988 			{
18989 				continue;
18990 			}
18991 
18992 			/* Skip invalid combinations */
18993 			if (!Utils::Type::CanTypesShareLocation(type_gohan.m_basic_type, type_goten.m_basic_type))
18994 			{
18995 				continue;
18996 			}
18997 
18998 			for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
18999 			{
19000 				/* Skip compute shader */
19001 				if (Utils::Shader::COMPUTE == stage)
19002 				{
19003 					continue;
19004 				}
19005 
19006 				for (GLuint int_gohan = 0; int_gohan < INTERPOLATION_MAX; ++int_gohan)
19007 				{
19008 					for (GLuint int_goten = 0; int_goten < INTERPOLATION_MAX; ++int_goten)
19009 					{
19010 						/* Skip when both are the same */
19011 						if (int_gohan == int_goten)
19012 						{
19013 							continue;
19014 						}
19015 
19016 						/* Skip inputs in: vertex shader and whenever
19017 						 * flat is mandatory and is not the chosen
19018 						 * one.
19019 						 */
19020 						bool skip_inputs = Utils::Shader::VERTEX == stage;
19021 						skip_inputs |=
19022 							(FLAT != int_gohan && isFlatRequired(static_cast<Utils::Shader::STAGES>(stage), type_gohan,
19023 																 Utils::Variable::VARYING_INPUT));
19024 						skip_inputs |=
19025 							(FLAT != int_goten && isFlatRequired(static_cast<Utils::Shader::STAGES>(stage), type_goten,
19026 																 Utils::Variable::VARYING_INPUT));
19027 
19028 						if (!skip_inputs)
19029 						{
19030 							testCase test_case_in = { gohan,
19031 													  goten,
19032 													  static_cast<INTERPOLATIONS>(int_gohan),
19033 													  static_cast<INTERPOLATIONS>(int_goten),
19034 													  true,
19035 													  static_cast<Utils::Shader::STAGES>(stage),
19036 													  type_gohan,
19037 													  type_goten };
19038 							m_test_cases.push_back(test_case_in);
19039 						}
19040 
19041 						/* Skip outputs in fragment shader and
19042 						 * whenever flat is mandatory and is not the
19043 						 * chosen one.
19044 						 */
19045 						bool skip_outputs = Utils::Shader::FRAGMENT == stage;
19046 						skip_outputs |=
19047 							(FLAT != int_gohan && isFlatRequired(static_cast<Utils::Shader::STAGES>(stage), type_gohan,
19048 																 Utils::Variable::VARYING_OUTPUT));
19049 						skip_outputs |=
19050 							(FLAT != int_goten && isFlatRequired(static_cast<Utils::Shader::STAGES>(stage), type_goten,
19051 																 Utils::Variable::VARYING_OUTPUT));
19052 
19053 						if (!skip_outputs)
19054 						{
19055 							testCase test_case_out = { gohan,
19056 													   goten,
19057 													   static_cast<INTERPOLATIONS>(int_gohan),
19058 													   static_cast<INTERPOLATIONS>(int_goten),
19059 													   false,
19060 													   static_cast<Utils::Shader::STAGES>(stage),
19061 													   type_gohan,
19062 													   type_goten };
19063 							m_test_cases.push_back(test_case_out);
19064 						}
19065 					}
19066 				}
19067 			}
19068 		}
19069 	}
19070 }
19071 
19072 /** Get interpolation qualifier
19073  *
19074  * @param interpolation Enumeration
19075  *
19076  * @return GLSL qualifier
19077  **/
19078 const GLchar* VaryingLocationAliasingWithMixedInterpolationTest::getInterpolationQualifier(INTERPOLATIONS interpolation)
19079 {
19080 	const GLchar* result = 0;
19081 
19082 	switch (interpolation)
19083 	{
19084 	case SMOOTH:
19085 		result = "smooth";
19086 		break;
19087 	case FLAT:
19088 		result = "flat";
19089 		break;
19090 	case NO_PERSPECTIVE:
19091 		result = "noperspective";
19092 		break;
19093 	default:
19094 		TCU_FAIL("Invalid enum");
19095 	}
19096 
19097 	return result;
19098 }
19099 
19100 /** Constructor
19101  *
19102  * @param context Test framework context
19103  **/
19104 VaryingLocationAliasingWithMixedAuxiliaryStorageTest::VaryingLocationAliasingWithMixedAuxiliaryStorageTest(
19105 	deqp::Context& context)
19106 	: NegativeTestBase(
19107 		  context, "varying_location_aliasing_with_mixed_auxiliary_storage",
19108 		  "Test verifies that compiler reports error when auxiliary storage qualifiers are mixed at one location")
19109 {
19110 }
19111 
19112 /** Source for given test case and stage
19113  *
19114  * @param test_case_index Index of test case
19115  * @param stage           Shader stage
19116  *
19117  * @return Shader source
19118  **/
19119 std::string VaryingLocationAliasingWithMixedAuxiliaryStorageTest::getShaderSource(GLuint				test_case_index,
19120 																				  Utils::Shader::STAGES stage)
19121 {
19122 	static const GLchar* var_definition =
19123 		"layout (location = 1, component = COMPONENT) AUX INTERPOLATION DIRECTION TYPE gohanARRAY;\n"
19124 		"layout (location = 1, component = COMPONENT) AUX INTERPOLATION DIRECTION TYPE gotenARRAY;\n";
19125 	static const GLchar* input_use = "    if ((TYPE(0) == gohanINDEX_GOHAN) &&\n"
19126 									 "        (TYPE(1) == gotenINDEX_GOTEN) )\n"
19127 									 "    {\n"
19128 									 "        result += vec4(1, 0.5, 0.25, 0.125);\n"
19129 									 "    }\n";
19130 	static const GLchar* output_use = "    gohanINDEX_GOHAN = TYPE(0);\n"
19131 									  "    gotenINDEX_GOTEN = TYPE(1);\n"
19132 									  "    if (vec4(0) == result)\n"
19133 									  "    {\n"
19134 									  "        gohanINDEX_GOHAN = TYPE(1);\n"
19135 									  "        gotenINDEX_GOTEN = TYPE(0);\n"
19136 									  "    }\n";
19137 	static const GLchar* fs = "#version 430 core\n"
19138 							  "#extension GL_ARB_enhanced_layouts : require\n"
19139 							  "\n"
19140 							  "in  vec4 gs_fs;\n"
19141 							  "out vec4 fs_out;\n"
19142 							  "\n"
19143 							  "void main()\n"
19144 							  "{\n"
19145 							  "    fs_out = gs_fs;\n"
19146 							  "}\n"
19147 							  "\n";
19148 	static const GLchar* fs_tested = "#version 430 core\n"
19149 									 "#extension GL_ARB_enhanced_layouts : require\n"
19150 									 "\n"
19151 									 "VAR_DEFINITION"
19152 									 "\n"
19153 									 "in  vec4 gs_fs;\n"
19154 									 "out vec4 fs_out;\n"
19155 									 "\n"
19156 									 "void main()\n"
19157 									 "{\n"
19158 									 "    vec4 result = gs_fs;\n"
19159 									 "\n"
19160 									 "VARIABLE_USE"
19161 									 "\n"
19162 									 "    fs_out = result;\n"
19163 									 "}\n"
19164 									 "\n";
19165 	static const GLchar* gs = "#version 430 core\n"
19166 							  "#extension GL_ARB_enhanced_layouts : require\n"
19167 							  "\n"
19168 							  "layout(points)                           in;\n"
19169 							  "layout(triangle_strip, max_vertices = 4) out;\n"
19170 							  "\n"
19171 							  "in  vec4 tes_gs[];\n"
19172 							  "out vec4 gs_fs;\n"
19173 							  "\n"
19174 							  "void main()\n"
19175 							  "{\n"
19176 							  "    gs_fs = tes_gs[0];\n"
19177 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
19178 							  "    EmitVertex();\n"
19179 							  "    gs_fs = tes_gs[0];\n"
19180 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
19181 							  "    EmitVertex();\n"
19182 							  "    gs_fs = tes_gs[0];\n"
19183 							  "    gl_Position  = vec4(1, -1, 0, 1);\n"
19184 							  "    EmitVertex();\n"
19185 							  "    gs_fs = tes_gs[0];\n"
19186 							  "    gl_Position  = vec4(1, 1, 0, 1);\n"
19187 							  "    EmitVertex();\n"
19188 							  "}\n"
19189 							  "\n";
19190 	static const GLchar* gs_tested = "#version 430 core\n"
19191 									 "#extension GL_ARB_enhanced_layouts : require\n"
19192 									 "\n"
19193 									 "layout(points)                           in;\n"
19194 									 "layout(triangle_strip, max_vertices = 4) out;\n"
19195 									 "\n"
19196 									 "VAR_DEFINITION"
19197 									 "\n"
19198 									 "in  vec4 tes_gs[];\n"
19199 									 "out vec4 gs_fs;\n"
19200 									 "\n"
19201 									 "void main()\n"
19202 									 "{\n"
19203 									 "    vec4 result = tes_gs[0];\n"
19204 									 "\n"
19205 									 "VARIABLE_USE"
19206 									 "\n"
19207 									 "    gs_fs = result;\n"
19208 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
19209 									 "    EmitVertex();\n"
19210 									 "    gs_fs = result;\n"
19211 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
19212 									 "    EmitVertex();\n"
19213 									 "    gs_fs = result;\n"
19214 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
19215 									 "    EmitVertex();\n"
19216 									 "    gs_fs = result;\n"
19217 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
19218 									 "    EmitVertex();\n"
19219 									 "}\n"
19220 									 "\n";
19221 	static const GLchar* tcs = "#version 430 core\n"
19222 							   "#extension GL_ARB_enhanced_layouts : require\n"
19223 							   "\n"
19224 							   "layout(vertices = 1) out;\n"
19225 							   "\n"
19226 							   "in  vec4 vs_tcs[];\n"
19227 							   "out vec4 tcs_tes[];\n"
19228 							   "\n"
19229 							   "void main()\n"
19230 							   "{\n"
19231 							   "\n"
19232 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
19233 							   "\n"
19234 							   "    gl_TessLevelOuter[0] = 1.0;\n"
19235 							   "    gl_TessLevelOuter[1] = 1.0;\n"
19236 							   "    gl_TessLevelOuter[2] = 1.0;\n"
19237 							   "    gl_TessLevelOuter[3] = 1.0;\n"
19238 							   "    gl_TessLevelInner[0] = 1.0;\n"
19239 							   "    gl_TessLevelInner[1] = 1.0;\n"
19240 							   "}\n"
19241 							   "\n";
19242 	static const GLchar* tcs_tested = "#version 430 core\n"
19243 									  "#extension GL_ARB_enhanced_layouts : require\n"
19244 									  "\n"
19245 									  "layout(vertices = 1) out;\n"
19246 									  "\n"
19247 									  "VAR_DEFINITION"
19248 									  "\n"
19249 									  "in  vec4 vs_tcs[];\n"
19250 									  "out vec4 tcs_tes[];\n"
19251 									  "\n"
19252 									  "void main()\n"
19253 									  "{\n"
19254 									  "    vec4 result = vs_tcs[gl_InvocationID];\n"
19255 									  "\n"
19256 									  "VARIABLE_USE"
19257 									  "\n"
19258 									  "    tcs_tes[gl_InvocationID] = result;\n"
19259 									  "\n"
19260 									  "    gl_TessLevelOuter[0] = 1.0;\n"
19261 									  "    gl_TessLevelOuter[1] = 1.0;\n"
19262 									  "    gl_TessLevelOuter[2] = 1.0;\n"
19263 									  "    gl_TessLevelOuter[3] = 1.0;\n"
19264 									  "    gl_TessLevelInner[0] = 1.0;\n"
19265 									  "    gl_TessLevelInner[1] = 1.0;\n"
19266 									  "}\n"
19267 									  "\n";
19268 	static const GLchar* tes = "#version 430 core\n"
19269 							   "#extension GL_ARB_enhanced_layouts : require\n"
19270 							   "\n"
19271 							   "layout(isolines, point_mode) in;\n"
19272 							   "\n"
19273 							   "in  vec4 tcs_tes[];\n"
19274 							   "out vec4 tes_gs;\n"
19275 							   "\n"
19276 							   "void main()\n"
19277 							   "{\n"
19278 							   "    tes_gs = tcs_tes[0];\n"
19279 							   "}\n"
19280 							   "\n";
19281 	static const GLchar* tes_tested = "#version 430 core\n"
19282 									  "#extension GL_ARB_enhanced_layouts : require\n"
19283 									  "\n"
19284 									  "layout(isolines, point_mode) in;\n"
19285 									  "\n"
19286 									  "VAR_DEFINITION"
19287 									  "\n"
19288 									  "in  vec4 tcs_tes[];\n"
19289 									  "out vec4 tes_gs;\n"
19290 									  "\n"
19291 									  "void main()\n"
19292 									  "{\n"
19293 									  "    vec4 result = tcs_tes[0];\n"
19294 									  "\n"
19295 									  "VARIABLE_USE"
19296 									  "\n"
19297 									  "    tes_gs += result;\n"
19298 									  "}\n"
19299 									  "\n";
19300 	static const GLchar* vs = "#version 430 core\n"
19301 							  "#extension GL_ARB_enhanced_layouts : require\n"
19302 							  "\n"
19303 							  "in  vec4 in_vs;\n"
19304 							  "out vec4 vs_tcs;\n"
19305 							  "\n"
19306 							  "void main()\n"
19307 							  "{\n"
19308 							  "    vs_tcs = in_vs;\n"
19309 							  "}\n"
19310 							  "\n";
19311 	static const GLchar* vs_tested = "#version 430 core\n"
19312 									 "#extension GL_ARB_enhanced_layouts : require\n"
19313 									 "\n"
19314 									 "VAR_DEFINITION"
19315 									 "\n"
19316 									 "in  vec4 in_vs;\n"
19317 									 "out vec4 vs_tcs;\n"
19318 									 "\n"
19319 									 "void main()\n"
19320 									 "{\n"
19321 									 "    vec4 result = in_vs;\n"
19322 									 "\n"
19323 									 "VARIABLE_USE"
19324 									 "\n"
19325 									 "    vs_tcs += result;\n"
19326 									 "}\n"
19327 									 "\n";
19328 
19329 	std::string source;
19330 	testCase&   test_case = m_test_cases[test_case_index];
19331 
19332 	if (test_case.m_stage == stage)
19333 	{
19334 		const GLchar* array_gohan = "";
19335 		const GLchar* array_goten = "";
19336 		const GLchar* aux_gohan   = getAuxiliaryQualifier(test_case.m_aux_gohan);
19337 #if DEBUG_NEG_REMOVE_ERROR
19338 		const GLchar* aux_goten = aux_gohan;
19339 #else
19340 		const GLchar* aux_goten   = getAuxiliaryQualifier(test_case.m_aux_goten);
19341 #endif /* DEBUG_NEG_REMOVE_ERROR */
19342 		GLchar		  buffer_gohan[16];
19343 		GLchar		  buffer_goten[16];
19344 		const GLchar*			 direction	 = "in";
19345 		const GLchar* index_gohan = "";
19346 		const GLchar* index_goten = "";
19347 		Utils::Variable::STORAGE storage	   = Utils::Variable::VARYING_INPUT;
19348 		const GLchar*			 interpolation = "";
19349 		size_t		  position	= 0;
19350 		size_t		  temp;
19351 		const GLchar* type_gohan_name = test_case.m_type_gohan.GetGLSLTypeName();
19352 		const GLchar* type_goten_name = test_case.m_type_goten.GetGLSLTypeName();
19353 		const GLchar* var_use		  = Utils::Shader::VERTEX == stage ? input_use : "\n";
19354 
19355 		if (false == test_case.m_is_input)
19356 		{
19357 			direction = "out";
19358 			storage   = Utils::Variable::VARYING_OUTPUT;
19359 			var_use = output_use;
19360 		}
19361 
19362 		if (isFlatRequired(stage, test_case.m_type_gohan, storage) ||
19363 			isFlatRequired(stage, test_case.m_type_goten, storage))
19364 		{
19365 			interpolation = "flat";
19366 		}
19367 
19368 		sprintf(buffer_gohan, "%d", test_case.m_component_gohan);
19369 		sprintf(buffer_goten, "%d", test_case.m_component_goten);
19370 
19371 		switch (stage)
19372 		{
19373 		case Utils::Shader::FRAGMENT:
19374 			source = fs_tested;
19375 			break;
19376 		case Utils::Shader::GEOMETRY:
19377 			source		= gs_tested;
19378 			array_gohan = test_case.m_is_input ? "[]" : "";
19379 			index_gohan = test_case.m_is_input ? "[0]" : "";
19380 			array_goten = test_case.m_is_input ? "[]" : "";
19381 			index_goten = test_case.m_is_input ? "[0]" : "";
19382 			break;
19383 		case Utils::Shader::TESS_CTRL:
19384 			source = tcs_tested;
19385 			if (PATCH != test_case.m_aux_gohan)
19386 			{
19387 				array_gohan = "[]";
19388 				index_gohan = "[gl_InvocationID]";
19389 			}
19390 #if DEBUG_NEG_REMOVE_ERROR
19391 			array_goten = array_gohan;
19392 			index_goten = index_gohan;
19393 #else
19394 			if (PATCH != test_case.m_aux_goten)
19395 			{
19396 				array_goten = "[]";
19397 				index_goten = "[gl_InvocationID]";
19398 			}
19399 #endif /* DEBUG_NEG_REMOVE_ERROR */
19400 			break;
19401 		case Utils::Shader::TESS_EVAL:
19402 			source		= tes_tested;
19403 			if (PATCH != test_case.m_aux_gohan)
19404 			{
19405 				array_gohan = test_case.m_is_input ? "[]" : "";
19406 				index_gohan = test_case.m_is_input ? "[0]" : "";
19407 			}
19408 #if DEBUG_NEG_REMOVE_ERROR
19409 			array_goten = array_gohan;
19410 			index_goten = index_gohan;
19411 #else
19412 			if (PATCH != test_case.m_aux_goten)
19413 			{
19414 				array_goten = test_case.m_is_input ? "[]" : "";
19415 				index_goten = test_case.m_is_input ? "[0]" : "";
19416 			}
19417 #endif /* DEBUG_NEG_REMOVE_ERROR */
19418 			break;
19419 		case Utils::Shader::VERTEX:
19420 			source = vs_tested;
19421 			break;
19422 		default:
19423 			TCU_FAIL("Invalid enum");
19424 		}
19425 
19426 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
19427 		position = 0;
19428 		Utils::replaceToken("COMPONENT", position, buffer_gohan, source);
19429 		Utils::replaceToken("AUX", position, aux_gohan, source);
19430 		Utils::replaceToken("INTERPOLATION", position, interpolation, source);
19431 		Utils::replaceToken("DIRECTION", position, direction, source);
19432 		Utils::replaceToken("TYPE", position, type_gohan_name, source);
19433 		Utils::replaceToken("ARRAY", position, array_gohan, source);
19434 		Utils::replaceToken("COMPONENT", position, buffer_goten, source);
19435 		Utils::replaceToken("AUX", position, aux_goten, source);
19436 		Utils::replaceToken("INTERPOLATION", position, interpolation, source);
19437 		Utils::replaceToken("DIRECTION", position, direction, source);
19438 		Utils::replaceToken("TYPE", position, type_goten_name, source);
19439 		Utils::replaceToken("ARRAY", position, array_goten, source);
19440 
19441 		temp = position;
19442 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
19443 		position = temp;
19444 		if (!test_case.m_is_input)
19445 		{
19446 			Utils::replaceToken("TYPE", position, type_gohan_name, source);
19447 			Utils::replaceToken("TYPE", position, type_goten_name, source);
19448 			Utils::replaceToken("TYPE", position, type_gohan_name, source);
19449 			Utils::replaceToken("TYPE", position, type_goten_name, source);
19450 		}
19451 		else if (Utils::Shader::VERTEX == stage)
19452 		{
19453 			Utils::replaceToken("TYPE", position, type_gohan_name, source);
19454 			Utils::replaceToken("TYPE", position, type_goten_name, source);
19455 		}
19456 
19457 		Utils::replaceAllTokens("INDEX_GOHAN", index_gohan, source);
19458 		Utils::replaceAllTokens("INDEX_GOTEN", index_goten, source);
19459 	}
19460 	else
19461 	{
19462 		switch (stage)
19463 		{
19464 		case Utils::Shader::FRAGMENT:
19465 			source = fs;
19466 			break;
19467 		case Utils::Shader::GEOMETRY:
19468 			source = gs;
19469 			break;
19470 		case Utils::Shader::TESS_CTRL:
19471 			source = tcs;
19472 			break;
19473 		case Utils::Shader::TESS_EVAL:
19474 			source = tes;
19475 			break;
19476 		case Utils::Shader::VERTEX:
19477 			source = vs;
19478 			break;
19479 		default:
19480 			TCU_FAIL("Invalid enum");
19481 		}
19482 	}
19483 
19484 	return source;
19485 }
19486 
19487 /** Get description of test case
19488  *
19489  * @param test_case_index Index of test case
19490  *
19491  * @return Test case description
19492  **/
19493 std::string VaryingLocationAliasingWithMixedAuxiliaryStorageTest::getTestCaseName(GLuint test_case_index)
19494 {
19495 	std::stringstream stream;
19496 	testCase&		  test_case = m_test_cases[test_case_index];
19497 
19498 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", "
19499 		   << getAuxiliaryQualifier(test_case.m_aux_gohan) << " " << test_case.m_type_gohan.GetGLSLTypeName() << " at "
19500 		   << test_case.m_component_gohan << ", " << getAuxiliaryQualifier(test_case.m_aux_goten) << " "
19501 		   << test_case.m_type_goten.GetGLSLTypeName() << " at " << test_case.m_component_goten << ". Direction: ";
19502 
19503 	if (true == test_case.m_is_input)
19504 	{
19505 		stream << "input";
19506 	}
19507 	else
19508 	{
19509 		stream << "output";
19510 	}
19511 
19512 	return stream.str();
19513 }
19514 
19515 /** Get number of test cases
19516  *
19517  * @return Number of test cases
19518  **/
19519 GLuint VaryingLocationAliasingWithMixedAuxiliaryStorageTest::getTestCaseNumber()
19520 {
19521 	return static_cast<GLuint>(m_test_cases.size());
19522 }
19523 
19524 /** Selects if "compute" stage is relevant for test
19525  *
19526  * @param ignored
19527  *
19528  * @return false
19529  **/
19530 bool VaryingLocationAliasingWithMixedAuxiliaryStorageTest::isComputeRelevant(GLuint /* test_case_index */)
19531 {
19532 	return false;
19533 }
19534 
19535 /** Prepare all test cases
19536  *
19537  **/
19538 void VaryingLocationAliasingWithMixedAuxiliaryStorageTest::testInit()
19539 {
19540 	const GLuint		n_types					  = getTypesNumber();
19541 
19542 	for (GLuint i = 0; i < n_types; ++i)
19543 	{
19544 		const Utils::Type& type_gohan		   = getType(i);
19545 		const std::vector<GLuint>& valid_components_gohan = type_gohan.GetValidComponents();
19546 
19547 		if (valid_components_gohan.empty())
19548 		{
19549 			continue;
19550 		}
19551 
19552 		const GLuint gohan = valid_components_gohan.front();
19553 
19554 		for (GLuint j = 0; j < n_types; ++j)
19555 		{
19556 			const Utils::Type& type_goten		   = getType(j);
19557 			const std::vector<GLuint>& valid_components_goten = type_goten.GetValidComponents();
19558 
19559 			if (valid_components_goten.empty())
19560 			{
19561 				continue;
19562 			}
19563 
19564 			/* Just get the highest valid component for goten and
19565 			 * check if we can use it.
19566 			 */
19567 			const GLuint min_component = gohan + type_gohan.GetNumComponents();
19568 			const GLuint goten		   = valid_components_goten.back();
19569 
19570 			if (min_component > goten)
19571 			{
19572 				continue;
19573 			}
19574 
19575 			/* Skip invalid combinations */
19576 			if (!Utils::Type::CanTypesShareLocation(type_gohan.m_basic_type, type_goten.m_basic_type))
19577 			{
19578 				continue;
19579 			}
19580 
19581 			for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
19582 			{
19583 				/* Skip compute shader */
19584 				if (Utils::Shader::COMPUTE == stage)
19585 				{
19586 					continue;
19587 				}
19588 
19589 				for (GLuint aux = 0; aux < AUXILIARY_MAX; ++aux)
19590 				{
19591 					Utils::Shader::STAGES const shader_stage = static_cast<Utils::Shader::STAGES>(stage);
19592 					AUXILIARIES const			auxiliary	= static_cast<AUXILIARIES>(aux);
19593 
19594 					if (PATCH == auxiliary)
19595 					{
19596 						if (Utils::Shader::TESS_CTRL == shader_stage || Utils::Shader::TESS_EVAL == shader_stage)
19597 						{
19598 							bool	 direction			   = Utils::Shader::TESS_EVAL == shader_stage;
19599 							testCase test_case_patch_gohan = { gohan,	 goten,		auxiliary,  NONE,
19600 															   direction, shader_stage, type_gohan, type_goten };
19601 							testCase test_case_patch_goten = { gohan,	 goten,		NONE,		auxiliary,
19602 															   direction, shader_stage, type_gohan, type_goten };
19603 
19604 							m_test_cases.push_back(test_case_patch_gohan);
19605 							m_test_cases.push_back(test_case_patch_goten);
19606 						}
19607 						continue;
19608 					}
19609 
19610 					for (GLuint second_aux = 0; second_aux < AUXILIARY_MAX; ++second_aux)
19611 					{
19612 						AUXILIARIES const second_auxiliary = static_cast<AUXILIARIES>(second_aux);
19613 
19614 						if (PATCH == second_auxiliary || auxiliary == second_auxiliary)
19615 						{
19616 							continue;
19617 						}
19618 
19619 						if (Utils::Shader::FRAGMENT != shader_stage)
19620 						{
19621 							testCase test_case_out = { gohan, goten,		auxiliary,  second_auxiliary,
19622 													   false, shader_stage, type_gohan, type_goten };
19623 
19624 							m_test_cases.push_back(test_case_out);
19625 						}
19626 
19627 						if (Utils::Shader::VERTEX != shader_stage)
19628 						{
19629 							testCase test_case_in = { gohan, goten,		   auxiliary,  second_auxiliary,
19630 													  true,  shader_stage, type_gohan, type_goten };
19631 
19632 							m_test_cases.push_back(test_case_in);
19633 						}
19634 					}
19635 				}
19636 			}
19637 		}
19638 	}
19639 }
19640 
19641 /** Get auxiliary storage qualifier
19642  *
19643  * @param aux Enumeration
19644  *
19645  * @return GLSL qualifier
19646  **/
19647 const GLchar* VaryingLocationAliasingWithMixedAuxiliaryStorageTest::getAuxiliaryQualifier(AUXILIARIES aux)
19648 {
19649 	const GLchar* result = 0;
19650 
19651 	switch (aux)
19652 	{
19653 	case NONE:
19654 		result = "";
19655 		break;
19656 	case PATCH:
19657 		result = "patch";
19658 		break;
19659 	case CENTROID:
19660 		result = "centroid";
19661 		break;
19662 	case SAMPLE:
19663 		result = "sample";
19664 		break;
19665 	default:
19666 		TCU_FAIL("Invalid enum");
19667 	}
19668 
19669 	return result;
19670 }
19671 
19672 /* Constants used by VertexAttribLocationAPITest */
19673 const GLuint VertexAttribLocationAPITest::m_goten_location = 6;
19674 
19675 /** Constructor
19676  *
19677  * @param context Test framework context
19678  **/
19679 VertexAttribLocationAPITest::VertexAttribLocationAPITest(deqp::Context& context)
19680 	: TextureTestBase(context, "vertex_attrib_location_api",
19681 					  "Test verifies that attribute locations API works as expected")
19682 {
19683 }
19684 
19685 /** Does BindAttribLocation for "goten" and relink program
19686  *
19687  * @param program           Program object
19688  * @param program_interface Interface of program
19689  **/
19690 void VertexAttribLocationAPITest::prepareAttribLocation(Utils::Program&			 program,
19691 														Utils::ProgramInterface& program_interface)
19692 {
19693 	const Functions& gl = m_context.getRenderContext().getFunctions();
19694 
19695 	gl.bindAttribLocation(program.m_id, m_goten_location, "goten");
19696 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindAttribLocation");
19697 
19698 	program.Link(gl, program.m_id);
19699 
19700 	/* We still need to get locations for gohan and chichi */
19701 	TextureTestBase::prepareAttribLocation(program, program_interface);
19702 }
19703 
19704 /** Get interface of program
19705  *
19706  * @param ignored
19707  * @param program_interface   Interface of program
19708  * @param ignored
19709  **/
19710 void VertexAttribLocationAPITest::getProgramInterface(GLuint /* test_case_index */,
19711 													  Utils::ProgramInterface& program_interface,
19712 													  Utils::VaryingPassthrough& /* varying_passthrough */)
19713 {
19714 	Utils::ShaderInterface& si		  = program_interface.GetShaderInterface(Utils::Shader::VERTEX);
19715 	const Utils::Type&		type	  = Utils::Type::vec4;
19716 	const GLuint			type_size = type.GetSize();
19717 
19718 	/* Offsets */
19719 	const GLuint chichi_offset = 0;
19720 	const GLuint goten_offset  = chichi_offset + type_size;
19721 	const GLuint gohan_offset  = goten_offset + type_size;
19722 	const GLuint goku_offset   = gohan_offset + type_size;
19723 
19724 	/* Locations */
19725 	const GLuint goku_location  = 2;
19726 	const GLuint goten_location = m_goten_location;
19727 
19728 	/* Generate data */
19729 	m_goku_data   = type.GenerateDataPacked();
19730 	m_gohan_data  = type.GenerateDataPacked();
19731 	m_goten_data  = type.GenerateDataPacked();
19732 	m_chichi_data = type.GenerateDataPacked();
19733 
19734 	/* Globals */
19735 	si.m_globals = "const uint GOKU_LOCATION = 2;\n";
19736 
19737 	/* Attributes */
19738 	si.Input("goku" /* name */, "layout (location = GOKU_LOCATION)" /* qualifiers */, 0 /* expected_componenet */,
19739 			 goku_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19740 			 0u /* n_array_elements */, 0u /* stride */, goku_offset /* offset */, (GLvoid*)&m_goku_data[0] /* data */,
19741 			 m_goku_data.size() /* data_size */);
19742 
19743 	si.Input("gohan" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19744 			 Utils::Variable::m_automatic_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19745 			 0u /* n_array_elements */, 0u /* stride */, gohan_offset /* offset */,
19746 			 (GLvoid*)&m_gohan_data[0] /* data */, m_gohan_data.size() /* data_size */);
19747 
19748 	si.Input("goten" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19749 			 goten_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19750 			 0u /* n_array_elements */, 0u /* stride */, goten_offset /* offset */,
19751 			 (GLvoid*)&m_goten_data[0] /* data */, m_goten_data.size() /* data_size */);
19752 
19753 	si.Input("chichi" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19754 			 Utils::Variable::m_automatic_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19755 			 0u /* n_array_elements */, 0u /* stride */, chichi_offset /* offset */,
19756 			 (GLvoid*)&m_chichi_data[0] /* data */, m_chichi_data.size() /* data_size */);
19757 }
19758 
19759 /** Selects if "compute" stage is relevant for test
19760  *
19761  * @param ignored
19762  *
19763  * @return false
19764  **/
19765 bool VertexAttribLocationAPITest::isComputeRelevant(GLuint /* test_case_index */)
19766 {
19767 	return false;
19768 }
19769 
19770 /* Constants used by FragmentDataLocationAPITest */
19771 const GLuint FragmentDataLocationAPITest::m_goten_location = 6;
19772 
19773 /** Constructor
19774  *
19775  * @param context Test framework context
19776  **/
19777 FragmentDataLocationAPITest::FragmentDataLocationAPITest(deqp::Context& context)
19778 	: TextureTestBase(context, "fragment_data_location_api",
19779 					  "Test verifies that fragment data locations API works as expected")
19780 	, m_goku(context)
19781 	, m_gohan(context)
19782 	, m_goten(context)
19783 	, m_chichi(context)
19784 {
19785 }
19786 
19787 /** Verifies contents of drawn images
19788  *
19789  * @param ignored
19790  * @param ignored
19791  *
19792  * @return true if images are filled with expected values, false otherwise
19793  **/
19794 bool FragmentDataLocationAPITest::checkResults(glw::GLuint /* test_case_index */, Utils::Texture& /* color_0 */)
19795 {
19796 	static const GLuint size			= m_width * m_height;
19797 	static const GLuint expected_goku   = 0xff000000;
19798 	static const GLuint expected_gohan  = 0xff0000ff;
19799 	static const GLuint expected_goten  = 0xff00ff00;
19800 	static const GLuint expected_chichi = 0xffff0000;
19801 
19802 	std::vector<GLuint> data;
19803 	data.resize(size);
19804 
19805 	m_goku.Get(GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
19806 
19807 	for (GLuint i = 0; i < size; ++i)
19808 	{
19809 		const GLuint color = data[i];
19810 
19811 		if (expected_goku != color)
19812 		{
19813 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "RGBA8[" << i << "]:" << color
19814 												<< tcu::TestLog::EndMessage;
19815 			return false;
19816 		}
19817 	}
19818 
19819 	m_gohan.Get(GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
19820 
19821 	for (GLuint i = 0; i < size; ++i)
19822 	{
19823 		const GLuint color = data[i];
19824 
19825 		if (expected_gohan != color)
19826 		{
19827 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "RGBA8[" << i << "]:" << color
19828 												<< tcu::TestLog::EndMessage;
19829 			return false;
19830 		}
19831 	}
19832 
19833 	m_goten.Get(GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
19834 
19835 	for (GLuint i = 0; i < size; ++i)
19836 	{
19837 		const GLuint color = data[i];
19838 
19839 		if (expected_goten != color)
19840 		{
19841 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "RGBA8[" << i << "]:" << color
19842 												<< tcu::TestLog::EndMessage;
19843 			return false;
19844 		}
19845 	}
19846 
19847 	m_chichi.Get(GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
19848 
19849 	for (GLuint i = 0; i < size; ++i)
19850 	{
19851 		const GLuint color = data[i];
19852 
19853 		if (expected_chichi != color)
19854 		{
19855 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "RGBA8[" << i << "]:" << color
19856 												<< tcu::TestLog::EndMessage;
19857 			return false;
19858 		}
19859 	}
19860 
19861 	return true;
19862 }
19863 
19864 /** Prepare code snippet that will set out variables
19865  *
19866  * @param ignored
19867  * @param ignored
19868  * @param stage               Shader stage
19869  *
19870  * @return Code that pass in variables to next stage
19871  **/
19872 std::string FragmentDataLocationAPITest::getPassSnippet(GLuint /* test_case_index */,
19873 														Utils::VaryingPassthrough& /* varying_passthrough */,
19874 														Utils::Shader::STAGES stage)
19875 {
19876 	std::string result;
19877 
19878 	/* Skip for compute shader */
19879 	if (Utils::Shader::FRAGMENT != stage)
19880 	{
19881 		result = "";
19882 	}
19883 	else
19884 	{
19885 		result = "chichi = vec4(0, 0, 1, 1);\n"
19886 				 "    goku   = vec4(0, 0, 0, 1);\n"
19887 				 "    goten  = vec4(0, 1, 0, 1);\n"
19888 				 "    gohan  = vec4(1, 0, 0, 1);\n";
19889 	}
19890 
19891 	return result;
19892 }
19893 
19894 /** Get interface of program
19895  *
19896  * @param ignored
19897  * @param program_interface Interface of program
19898  * @param ignored
19899  **/
19900 void FragmentDataLocationAPITest::getProgramInterface(GLuint /* test_case_index */,
19901 													  Utils::ProgramInterface& program_interface,
19902 													  Utils::VaryingPassthrough& /* varying_passthrough */)
19903 {
19904 	Utils::ShaderInterface& si   = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
19905 	const Utils::Type&		type = Utils::Type::vec4;
19906 
19907 	/* Locations */
19908 	m_goku_location = 2;
19909 
19910 	/* Globals */
19911 	si.m_globals = "const uint GOKU_LOCATION = 2;\n";
19912 
19913 	/* Attributes */
19914 	si.Output("goku" /* name */, "layout (location = GOKU_LOCATION)" /* qualifiers */, 0 /* expected_componenet */,
19915 			  m_goku_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19916 			  0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)0 /* data */, 0u /* data_size */);
19917 
19918 	si.Output("gohan" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19919 			  Utils::Variable::m_automatic_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19920 			  0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)0 /* data */, 0u /* data_size */);
19921 
19922 	si.Output("goten" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19923 			  m_goten_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19924 			  0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)0 /* data */, 0u /* data_size */);
19925 
19926 	si.Output("chichi" /* name */, "" /* qualifiers */, 0 /* expected_componenet */,
19927 			  Utils::Variable::m_automatic_location /* expected_location */, type /* type */, GL_FALSE /* normalized */,
19928 			  0u /* n_array_elements */, 0u /* stride */, 0u /* offset */, (GLvoid*)0 /* data */, 0u /* data_size */);
19929 }
19930 
19931 /** Selects if "compute" stage is relevant for test
19932  *
19933  * @param ignored
19934  *
19935  * @return false
19936  **/
19937 bool FragmentDataLocationAPITest::isComputeRelevant(GLuint /* test_case_index */)
19938 {
19939 	return false;
19940 }
19941 
19942 /** Get locations for all outputs with automatic_location
19943  *
19944  * @param program           Program object
19945  * @param program_interface Interface of program
19946  **/
19947 void FragmentDataLocationAPITest::prepareFragmentDataLoc(Utils::Program&		  program,
19948 														 Utils::ProgramInterface& program_interface)
19949 {
19950 	/* Bind location of goten */
19951 	const Functions& gl = m_context.getRenderContext().getFunctions();
19952 
19953 	gl.bindFragDataLocation(program.m_id, m_goten_location, "goten");
19954 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindFragDataLocation");
19955 
19956 	program.Link(gl, program.m_id);
19957 
19958 	/* Prepare locations for gohan and chichi */
19959 	TextureTestBase::prepareFragmentDataLoc(program, program_interface);
19960 
19961 	/* Get all locations */
19962 	Utils::ShaderInterface& si = program_interface.GetShaderInterface(Utils::Shader::FRAGMENT);
19963 
19964 	Utils::Variable::PtrVector& outputs = si.m_outputs;
19965 
19966 	for (Utils::Variable::PtrVector::iterator it = outputs.begin(); outputs.end() != it; ++it)
19967 	{
19968 		const Utils::Variable::Descriptor& desc = (*it)->m_descriptor;
19969 
19970 		if (0 == desc.m_name.compare("gohan"))
19971 		{
19972 			m_gohan_location = desc.m_expected_location;
19973 		}
19974 		else if (0 == desc.m_name.compare("chichi"))
19975 		{
19976 			m_chichi_location = desc.m_expected_location;
19977 		}
19978 
19979 		/* Locations of goku and goten are fixed */
19980 	}
19981 }
19982 
19983 /** Prepare framebuffer with single texture as color attachment
19984  *
19985  * @param framebuffer     Framebuffer
19986  * @param color_0_texture Texture that will used as color attachment
19987  **/
19988 void FragmentDataLocationAPITest::prepareFramebuffer(Utils::Framebuffer& framebuffer, Utils::Texture& color_0_texture)
19989 {
19990 	/* Let parent prepare its stuff */
19991 	TextureTestBase::prepareFramebuffer(framebuffer, color_0_texture);
19992 
19993 	/* Prepare data */
19994 	std::vector<GLuint> texture_data;
19995 	texture_data.resize(m_width * m_height);
19996 
19997 	for (GLuint i = 0; i < texture_data.size(); ++i)
19998 	{
19999 		texture_data[i] = 0x20406080;
20000 	}
20001 
20002 	/* Prepare textures */
20003 	m_goku.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]);
20004 
20005 	m_gohan.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]);
20006 
20007 	m_goten.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]);
20008 
20009 	m_chichi.Init(Utils::Texture::TEX_2D, m_width, m_height, 0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]);
20010 
20011 	/* Attach textures to framebuffer */
20012 	framebuffer.Bind();
20013 	framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0 + m_goku_location, m_goku.m_id, m_width, m_height);
20014 	framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0 + m_gohan_location, m_gohan.m_id, m_width, m_height);
20015 	framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0 + m_goten_location, m_goten.m_id, m_width, m_height);
20016 	framebuffer.AttachTexture(GL_COLOR_ATTACHMENT0 + m_chichi_location, m_chichi.m_id, m_width, m_height);
20017 
20018 	/* Set up drawbuffers */
20019 	const Functions& gl = m_context.getRenderContext().getFunctions();
20020 	// The fragment shader can have more than 4 color outputs, but it only care about 4 (goku, gohan, goten, chichi).
20021 	// We will first initialize all draw buffers to NONE and then set the real value for the 4 outputs we care about
20022 	GLint maxDrawBuffers = 0;
20023 	gl.getIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
20024 
20025 	std::vector<GLenum> buffers(maxDrawBuffers, GL_NONE);
20026 	buffers[m_chichi_location] = GLenum(GL_COLOR_ATTACHMENT0 + m_chichi_location);
20027 	buffers[m_goten_location]  = GLenum(GL_COLOR_ATTACHMENT0 + m_goten_location);
20028 	buffers[m_goku_location]   = GLenum(GL_COLOR_ATTACHMENT0 + m_goku_location);
20029 	buffers[m_gohan_location]  = GLenum(GL_COLOR_ATTACHMENT0 + m_gohan_location);
20030 
20031 	gl.drawBuffers(maxDrawBuffers, buffers.data());
20032 	GLU_EXPECT_NO_ERROR(gl.getError(), "DrawBuffers");
20033 }
20034 
20035 /** Constructor
20036  *
20037  * @param context Test framework context
20038  **/
20039 XFBInputTest::XFBInputTest(deqp::Context& context)
20040 	: NegativeTestBase(context, "xfb_input",
20041 					   "Test verifies that compiler reports error when xfb qualifiers are used with input")
20042 {
20043 }
20044 
20045 /** Source for given test case and stage
20046  *
20047  * @param test_case_index Index of test case
20048  * @param stage           Shader stage
20049  *
20050  * @return Shader source
20051  **/
20052 std::string XFBInputTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
20053 {
20054 #if DEBUG_NEG_REMOVE_ERROR
20055 	static const GLchar* buffer_var_definition = "/* layout (xfb_buffer = 2) */ in vec4 gohanARRAY;\n";
20056 	static const GLchar* offset_var_definition = "/* layout (xfb_offset = 16) */ in vec4 gohanARRAY;\n";
20057 	static const GLchar* stride_var_definition = "/* layout (xfb_stride = 32) */ in vec4 gohanARRAY;\n";
20058 #else
20059 	static const GLchar* buffer_var_definition = "layout (xfb_buffer = 2) in vec4 gohanARRAY;\n";
20060 	static const GLchar* offset_var_definition = "layout (xfb_offset = 16) in vec4 gohanARRAY;\n";
20061 	static const GLchar* stride_var_definition = "layout (xfb_stride = 32) in vec4 gohanARRAY;\n";
20062 #endif /* DEBUG_NEG_REMOVE_ERROR */
20063 	static const GLchar* fs					   = "#version 430 core\n"
20064 							  "#extension GL_ARB_enhanced_layouts : require\n"
20065 							  "\n"
20066 							  "in  vec4 gs_fs;\n"
20067 							  "out vec4 fs_out;\n"
20068 							  "\n"
20069 							  "void main()\n"
20070 							  "{\n"
20071 							  "    fs_out = gs_fs;\n"
20072 							  "}\n"
20073 							  "\n";
20074 	static const GLchar* fs_tested = "#version 430 core\n"
20075 									 "#extension GL_ARB_enhanced_layouts : require\n"
20076 									 "\n"
20077 									 "VAR_DEFINITION"
20078 									 "\n"
20079 									 "in  vec4 gs_fs;\n"
20080 									 "out vec4 fs_out;\n"
20081 									 "\n"
20082 									 "void main()\n"
20083 									 "{\n"
20084 									 "    vec4 result = gs_fs;\n"
20085 									 "\n"
20086 									 "    fs_out = result;\n"
20087 									 "}\n"
20088 									 "\n";
20089 	static const GLchar* gs = "#version 430 core\n"
20090 							  "#extension GL_ARB_enhanced_layouts : require\n"
20091 							  "\n"
20092 							  "layout(points)                           in;\n"
20093 							  "layout(triangle_strip, max_vertices = 4) out;\n"
20094 							  "\n"
20095 							  "in  vec4 tes_gs[];\n"
20096 							  "out vec4 gs_fs;\n"
20097 							  "\n"
20098 							  "void main()\n"
20099 							  "{\n"
20100 							  "    gs_fs = tes_gs[0];\n"
20101 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
20102 							  "    EmitVertex();\n"
20103 							  "    gs_fs = tes_gs[0];\n"
20104 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
20105 							  "    EmitVertex();\n"
20106 							  "    gs_fs = tes_gs[0];\n"
20107 							  "    gl_Position  = vec4(1, -1, 0, 1);\n"
20108 							  "    EmitVertex();\n"
20109 							  "    gs_fs = tes_gs[0];\n"
20110 							  "    gl_Position  = vec4(1, 1, 0, 1);\n"
20111 							  "    EmitVertex();\n"
20112 							  "}\n"
20113 							  "\n";
20114 	static const GLchar* gs_tested = "#version 430 core\n"
20115 									 "#extension GL_ARB_enhanced_layouts : require\n"
20116 									 "\n"
20117 									 "layout(points)                           in;\n"
20118 									 "layout(triangle_strip, max_vertices = 4) out;\n"
20119 									 "\n"
20120 									 "VAR_DEFINITION"
20121 									 "\n"
20122 									 "in  vec4 tes_gs[];\n"
20123 									 "out vec4 gs_fs;\n"
20124 									 "\n"
20125 									 "void main()\n"
20126 									 "{\n"
20127 									 "    vec4 result = tes_gs[0];\n"
20128 									 "\n"
20129 									 "    gs_fs = result;\n"
20130 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
20131 									 "    EmitVertex();\n"
20132 									 "    gs_fs = result;\n"
20133 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
20134 									 "    EmitVertex();\n"
20135 									 "    gs_fs = result;\n"
20136 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
20137 									 "    EmitVertex();\n"
20138 									 "    gs_fs = result;\n"
20139 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
20140 									 "    EmitVertex();\n"
20141 									 "}\n"
20142 									 "\n";
20143 	static const GLchar* tcs = "#version 430 core\n"
20144 							   "#extension GL_ARB_enhanced_layouts : require\n"
20145 							   "\n"
20146 							   "layout(vertices = 1) out;\n"
20147 							   "\n"
20148 							   "in  vec4 vs_tcs[];\n"
20149 							   "out vec4 tcs_tes[];\n"
20150 							   "\n"
20151 							   "void main()\n"
20152 							   "{\n"
20153 							   "\n"
20154 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
20155 							   "\n"
20156 							   "    gl_TessLevelOuter[0] = 1.0;\n"
20157 							   "    gl_TessLevelOuter[1] = 1.0;\n"
20158 							   "    gl_TessLevelOuter[2] = 1.0;\n"
20159 							   "    gl_TessLevelOuter[3] = 1.0;\n"
20160 							   "    gl_TessLevelInner[0] = 1.0;\n"
20161 							   "    gl_TessLevelInner[1] = 1.0;\n"
20162 							   "}\n"
20163 							   "\n";
20164 	static const GLchar* tcs_tested = "#version 430 core\n"
20165 									  "#extension GL_ARB_enhanced_layouts : require\n"
20166 									  "\n"
20167 									  "layout(vertices = 1) out;\n"
20168 									  "\n"
20169 									  "VAR_DEFINITION"
20170 									  "\n"
20171 									  "in  vec4 vs_tcs[];\n"
20172 									  "out vec4 tcs_tes[];\n"
20173 									  "\n"
20174 									  "void main()\n"
20175 									  "{\n"
20176 									  "    vec4 result = vs_tcs[gl_InvocationID];\n"
20177 									  "\n"
20178 									  "    tcs_tes[gl_InvocationID] = result;\n"
20179 									  "\n"
20180 									  "    gl_TessLevelOuter[0] = 1.0;\n"
20181 									  "    gl_TessLevelOuter[1] = 1.0;\n"
20182 									  "    gl_TessLevelOuter[2] = 1.0;\n"
20183 									  "    gl_TessLevelOuter[3] = 1.0;\n"
20184 									  "    gl_TessLevelInner[0] = 1.0;\n"
20185 									  "    gl_TessLevelInner[1] = 1.0;\n"
20186 									  "}\n"
20187 									  "\n";
20188 	static const GLchar* tes = "#version 430 core\n"
20189 							   "#extension GL_ARB_enhanced_layouts : require\n"
20190 							   "\n"
20191 							   "layout(isolines, point_mode) in;\n"
20192 							   "\n"
20193 							   "in  vec4 tcs_tes[];\n"
20194 							   "out vec4 tes_gs;\n"
20195 							   "\n"
20196 							   "void main()\n"
20197 							   "{\n"
20198 							   "    tes_gs = tcs_tes[0];\n"
20199 							   "}\n"
20200 							   "\n";
20201 	static const GLchar* tes_tested = "#version 430 core\n"
20202 									  "#extension GL_ARB_enhanced_layouts : require\n"
20203 									  "\n"
20204 									  "layout(isolines, point_mode) in;\n"
20205 									  "\n"
20206 									  "VAR_DEFINITION"
20207 									  "\n"
20208 									  "in  vec4 tcs_tes[];\n"
20209 									  "out vec4 tes_gs;\n"
20210 									  "\n"
20211 									  "void main()\n"
20212 									  "{\n"
20213 									  "    vec4 result = tcs_tes[0];\n"
20214 									  "\n"
20215 									  "    tes_gs += result;\n"
20216 									  "}\n"
20217 									  "\n";
20218 	static const GLchar* vs = "#version 430 core\n"
20219 							  "#extension GL_ARB_enhanced_layouts : require\n"
20220 							  "\n"
20221 							  "in  vec4 in_vs;\n"
20222 							  "out vec4 vs_tcs;\n"
20223 							  "\n"
20224 							  "void main()\n"
20225 							  "{\n"
20226 							  "    vs_tcs = in_vs;\n"
20227 							  "}\n"
20228 							  "\n";
20229 	static const GLchar* vs_tested = "#version 430 core\n"
20230 									 "#extension GL_ARB_enhanced_layouts : require\n"
20231 									 "\n"
20232 									 "VAR_DEFINITION"
20233 									 "\n"
20234 									 "in  vec4 in_vs;\n"
20235 									 "out vec4 vs_tcs;\n"
20236 									 "\n"
20237 									 "void main()\n"
20238 									 "{\n"
20239 									 "    vec4 result = in_vs;\n"
20240 									 "\n"
20241 									 "    vs_tcs += result;\n"
20242 									 "}\n"
20243 									 "\n";
20244 
20245 	std::string source;
20246 	testCase&   test_case = m_test_cases[test_case_index];
20247 
20248 	if (test_case.m_stage == stage)
20249 	{
20250 		const GLchar* array	= "";
20251 		size_t		  position = 0;
20252 		const GLchar* var_definition = 0;
20253 
20254 		switch (test_case.m_qualifier)
20255 		{
20256 		case BUFFER:
20257 			var_definition = buffer_var_definition;
20258 			break;
20259 		case OFFSET:
20260 			var_definition = offset_var_definition;
20261 			break;
20262 		case STRIDE:
20263 			var_definition = stride_var_definition;
20264 			break;
20265 		default:
20266 			TCU_FAIL("Invalid enum");
20267 		}
20268 
20269 		switch (stage)
20270 		{
20271 		case Utils::Shader::FRAGMENT:
20272 			source = fs_tested;
20273 			break;
20274 		case Utils::Shader::GEOMETRY:
20275 			source = gs_tested;
20276 			array  = "[]";
20277 			break;
20278 		case Utils::Shader::TESS_CTRL:
20279 			source = tcs_tested;
20280 			array  = "[]";
20281 			break;
20282 		case Utils::Shader::TESS_EVAL:
20283 			source = tes_tested;
20284 			array  = "[]";
20285 			break;
20286 		case Utils::Shader::VERTEX:
20287 			source = vs_tested;
20288 			break;
20289 		default:
20290 			TCU_FAIL("Invalid enum");
20291 		}
20292 
20293 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
20294 		position = 0;
20295 		Utils::replaceToken("ARRAY", position, array, source);
20296 	}
20297 	else
20298 	{
20299 		switch (stage)
20300 		{
20301 		case Utils::Shader::FRAGMENT:
20302 			source = fs;
20303 			break;
20304 		case Utils::Shader::GEOMETRY:
20305 			source = gs;
20306 			break;
20307 		case Utils::Shader::TESS_CTRL:
20308 			source = tcs;
20309 			break;
20310 		case Utils::Shader::TESS_EVAL:
20311 			source = tes;
20312 			break;
20313 		case Utils::Shader::VERTEX:
20314 			source = vs;
20315 			break;
20316 		default:
20317 			TCU_FAIL("Invalid enum");
20318 		}
20319 	}
20320 
20321 	return source;
20322 }
20323 
20324 /** Get description of test case
20325  *
20326  * @param test_case_index Index of test case
20327  *
20328  * @return Test case description
20329  **/
20330 std::string XFBInputTest::getTestCaseName(GLuint test_case_index)
20331 {
20332 	std::stringstream stream;
20333 	testCase&		  test_case = m_test_cases[test_case_index];
20334 
20335 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", qualifier: ";
20336 
20337 	switch (test_case.m_qualifier)
20338 	{
20339 	case BUFFER:
20340 		stream << "xfb_buffer";
20341 		break;
20342 	case OFFSET:
20343 		stream << "xfb_offset";
20344 		break;
20345 	case STRIDE:
20346 		stream << "xfb_stride";
20347 		break;
20348 	default:
20349 		TCU_FAIL("Invalid enum");
20350 	}
20351 
20352 	return stream.str();
20353 }
20354 
20355 /** Get number of test cases
20356  *
20357  * @return Number of test cases
20358  **/
20359 GLuint XFBInputTest::getTestCaseNumber()
20360 {
20361 	return static_cast<GLuint>(m_test_cases.size());
20362 }
20363 
20364 /** Selects if "compute" stage is relevant for test
20365  *
20366  * @param ignored
20367  *
20368  * @return false
20369  **/
20370 bool XFBInputTest::isComputeRelevant(GLuint /* test_case_index */)
20371 {
20372 	return false;
20373 }
20374 
20375 /** Prepare all test cases
20376  *
20377  **/
20378 void XFBInputTest::testInit()
20379 {
20380 	for (GLuint qualifier = 0; qualifier < QUALIFIERS_MAX; ++qualifier)
20381 	{
20382 		for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
20383 		{
20384 			if (Utils::Shader::COMPUTE == stage)
20385 			{
20386 				continue;
20387 			}
20388 
20389 			testCase test_case = { (QUALIFIERS)qualifier, (Utils::Shader::STAGES)stage };
20390 
20391 			m_test_cases.push_back(test_case);
20392 		}
20393 	}
20394 }
20395 
20396 /* Constants used by XFBAllStagesTest */
20397 const GLuint XFBAllStagesTest::m_gs_index = 3;
20398 
20399 /** Constructor
20400  *
20401  * @param context Test context
20402  **/
20403 XFBAllStagesTest::XFBAllStagesTest(deqp::Context& context)
20404 	: BufferTestBase(context, "xfb_all_stages",
20405 					 "Test verifies that only last stage in vertex processing can output to transform feedback")
20406 {
20407 	/* Nothing to be done here */
20408 }
20409 
20410 /** Get descriptors of buffers necessary for test
20411  *
20412  * @param ignored
20413  * @param out_descriptors Descriptors of buffers used by test
20414  **/
20415 void XFBAllStagesTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
20416 											bufferDescriptor::Vector& out_descriptors)
20417 {
20418 	static const GLuint n_stages = 4;
20419 	const Utils::Type&  vec4	 = Utils::Type::vec4;
20420 
20421 	/* Data */
20422 	tcu::Vec4 sum;
20423 
20424 	/* Test uses single uniform and xfb per stage + uniform for fragment shader */
20425 	out_descriptors.resize(n_stages * 2 + 1);
20426 
20427 	/* */
20428 	for (GLuint i = 0; i < n_stages; ++i)
20429 	{
20430 		/* Get references */
20431 		bufferDescriptor& uniform = out_descriptors[i + 0];
20432 		bufferDescriptor& xfb	 = out_descriptors[i + n_stages];
20433 
20434 		/* Index */
20435 		uniform.m_index = i;
20436 		xfb.m_index		= i;
20437 
20438 		/* Target */
20439 		uniform.m_target = Utils::Buffer::Uniform;
20440 		xfb.m_target	 = Utils::Buffer::Transform_feedback;
20441 
20442 		/* Data */
20443 		const tcu::Vec4 var(Utils::GetRandFloat(), Utils::GetRandFloat(), Utils::GetRandFloat(), Utils::GetRandFloat());
20444 
20445 		sum += var;
20446 
20447 		uniform.m_initial_data.resize(vec4.GetSize());
20448 		memcpy(&uniform.m_initial_data[0], var.getPtr(), vec4.GetSize());
20449 
20450 		xfb.m_initial_data = vec4.GenerateDataPacked();
20451 
20452 		if (m_gs_index != i)
20453 		{
20454 			xfb.m_expected_data = xfb.m_initial_data;
20455 		}
20456 		else
20457 		{
20458 			xfb.m_expected_data.resize(vec4.GetSize());
20459 			memcpy(&xfb.m_expected_data[0], sum.getPtr(), vec4.GetSize());
20460 		}
20461 	}
20462 
20463 	/* FS */
20464 	{
20465 		/* Get reference */
20466 		bufferDescriptor& uniform = out_descriptors[n_stages * 2];
20467 
20468 		/* Index */
20469 		uniform.m_index = n_stages;
20470 
20471 		/* Target */
20472 		uniform.m_target = Utils::Buffer::Uniform;
20473 
20474 		/* Data */
20475 		const tcu::Vec4 var(Utils::GetRandFloat(), Utils::GetRandFloat(), Utils::GetRandFloat(), Utils::GetRandFloat());
20476 
20477 		uniform.m_initial_data.resize(vec4.GetSize());
20478 		memcpy(&uniform.m_initial_data[0], var.getPtr(), vec4.GetSize());
20479 	}
20480 }
20481 
20482 /** Get body of main function for given shader stage
20483  *
20484  * @param ignored
20485  * @param stage            Shader stage
20486  * @param out_assignments  Set to empty
20487  * @param out_calculations Set to empty
20488  **/
20489 void XFBAllStagesTest::getShaderBody(glw::GLuint /* test_case_index */, Utils::Shader::STAGES stage,
20490 									 std::string& out_assignments, std::string& out_calculations)
20491 {
20492 	out_calculations = "";
20493 
20494 	static const GLchar* vs  = "    vs_tcs  = uni_vs;\n";
20495 	static const GLchar* tcs = "    tcs_tes[gl_InvocationID] = uni_tcs + vs_tcs[gl_InvocationID];\n";
20496 	static const GLchar* tes = "    tes_gs  = uni_tes + tcs_tes[0];\n";
20497 	static const GLchar* gs  = "    gs_fs   = uni_gs  + tes_gs[0];\n";
20498 	static const GLchar* fs  = "    fs_out  = uni_fs  + gs_fs;\n";
20499 
20500 	const GLchar* assignments = 0;
20501 	switch (stage)
20502 	{
20503 	case Utils::Shader::FRAGMENT:
20504 		assignments = fs;
20505 		break;
20506 	case Utils::Shader::GEOMETRY:
20507 		assignments = gs;
20508 		break;
20509 	case Utils::Shader::TESS_CTRL:
20510 		assignments = tcs;
20511 		break;
20512 	case Utils::Shader::TESS_EVAL:
20513 		assignments = tes;
20514 		break;
20515 	case Utils::Shader::VERTEX:
20516 		assignments = vs;
20517 		break;
20518 	default:
20519 		TCU_FAIL("Invalid enum");
20520 	}
20521 
20522 	out_assignments = assignments;
20523 }
20524 
20525 /** Get interface of shader
20526  *
20527  * @param ignored
20528  * @param stage         Shader stage
20529  * @param out_interface Set to ""
20530  **/
20531 void XFBAllStagesTest::getShaderInterface(glw::GLuint /* test_case_index */, Utils::Shader::STAGES stage,
20532 										  std::string& out_interface)
20533 {
20534 	static const GLchar* vs = "layout(xfb_buffer = 0, xfb_offset = 0) out     vec4 vs_tcs;\n"
20535 							  "layout(binding    = 0)                 uniform vs_block {\n"
20536 							  "    vec4 uni_vs;\n"
20537 							  "};\n";
20538 	static const GLchar* tcs = "                                       in      vec4 vs_tcs[];\n"
20539 							   "layout(xfb_buffer = 1, xfb_offset = 0) out     vec4 tcs_tes[1];\n"
20540 							   "layout(binding    = 1)                 uniform tcs_block {\n"
20541 							   "    vec4 uni_tcs;\n"
20542 							   "};\n";
20543 	static const GLchar* tes = "                                       in      vec4 tcs_tes[];\n"
20544 							   "layout(xfb_buffer = 2, xfb_offset = 0) out     vec4 tes_gs;\n"
20545 							   "layout(binding    = 2)                 uniform tes_block {\n"
20546 							   "    vec4 uni_tes;\n"
20547 							   "};\n";
20548 	static const GLchar* gs = "                                       in      vec4 tes_gs[];\n"
20549 							  "layout(xfb_buffer = 3, xfb_offset = 0) out     vec4 gs_fs;\n"
20550 							  "layout(binding    = 3)                 uniform gs_block {\n"
20551 							  "    vec4 uni_gs;\n"
20552 							  "};\n";
20553 	static const GLchar* fs = "                       in      vec4 gs_fs;\n"
20554 							  "                       out     vec4 fs_out;\n"
20555 							  "layout(binding    = 4) uniform fs_block {\n"
20556 							  "    vec4 uni_fs;\n"
20557 							  "};\n";
20558 
20559 	const GLchar* interface = 0;
20560 	switch (stage)
20561 	{
20562 	case Utils::Shader::FRAGMENT:
20563 		interface = fs;
20564 		break;
20565 	case Utils::Shader::GEOMETRY:
20566 		interface = gs;
20567 		break;
20568 	case Utils::Shader::TESS_CTRL:
20569 		interface = tcs;
20570 		break;
20571 	case Utils::Shader::TESS_EVAL:
20572 		interface = tes;
20573 		break;
20574 	case Utils::Shader::VERTEX:
20575 		interface = vs;
20576 		break;
20577 	default:
20578 		TCU_FAIL("Invalid enum");
20579 	}
20580 
20581 	out_interface = interface;
20582 }
20583 
20584 /* Constants used by XFBStrideOfEmptyListTest */
20585 const GLuint XFBStrideOfEmptyListTest::m_stride = 64;
20586 
20587 /** Constructor
20588  *
20589  * @param context Test context
20590  **/
20591 XFBStrideOfEmptyListTest::XFBStrideOfEmptyListTest(deqp::Context& context)
20592 	: BufferTestBase(
20593 		  context, "xfb_stride_of_empty_list",
20594 		  "Test verifies correct behavior when xfb_stride qualifier is specified but no xfb_offset is specified")
20595 {
20596 	/* Nothing to be done here */
20597 }
20598 
20599 /** Execute drawArrays for single vertex
20600  *
20601  * @param test_case_index Index of test case
20602  *
20603  * @return true if proper error is reported
20604  **/
20605 bool XFBStrideOfEmptyListTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
20606 {
20607 	const Functions& gl		= m_context.getRenderContext().getFunctions();
20608 	bool			 result = true;
20609 
20610 	/* Draw */
20611 	gl.disable(GL_RASTERIZER_DISCARD);
20612 	GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
20613 
20614 	gl.beginTransformFeedback(GL_POINTS);
20615 	GLenum error = gl.getError();
20616 	switch (test_case_index)
20617 	{
20618 	case VALID:
20619 		if (GL_NO_ERROR != error)
20620 		{
20621 			gl.endTransformFeedback();
20622 			GLU_EXPECT_NO_ERROR(error, "BeginTransformFeedback");
20623 		}
20624 
20625 		gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
20626 		error = gl.getError();
20627 
20628 		gl.endTransformFeedback();
20629 		GLU_EXPECT_NO_ERROR(error, "DrawArrays");
20630 		GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
20631 
20632 		break;
20633 
20634 	case FIRST_MISSING:
20635 		if (GL_NO_ERROR == error)
20636 		{
20637 			gl.endTransformFeedback();
20638 		}
20639 
20640 		if (GL_INVALID_OPERATION != error)
20641 		{
20642 			m_context.getTestContext().getLog()
20643 				<< tcu::TestLog::Message << "XFB at index 0, that is written by GS, is missing. It was expected that "
20644 											"INVALID_OPERATION will generated by BeginTransformFeedback. Got: "
20645 				<< glu::getErrorStr(error) << tcu::TestLog::EndMessage;
20646 
20647 			result = false;
20648 		}
20649 
20650 		break;
20651 
20652 	case SECOND_MISSING:
20653 		if (GL_NO_ERROR != error)
20654 		{
20655 			gl.endTransformFeedback();
20656 			GLU_EXPECT_NO_ERROR(error, "BeginTransformFeedback");
20657 		}
20658 
20659 		gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
20660 		error = gl.getError();
20661 
20662 		gl.endTransformFeedback();
20663 		GLU_EXPECT_NO_ERROR(error, "DrawArrays");
20664 		GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
20665 
20666 		break;
20667 	}
20668 
20669 	/* Done */
20670 	return result;
20671 }
20672 
20673 /** Get descriptors of buffers necessary for test
20674  *
20675  * @param test_case_index Index of test case
20676  * @param out_descriptors Descriptors of buffers used by test
20677  **/
20678 void XFBStrideOfEmptyListTest::getBufferDescriptors(glw::GLuint				  test_case_index,
20679 													bufferDescriptor::Vector& out_descriptors)
20680 {
20681 	switch (test_case_index)
20682 	{
20683 	case VALID:
20684 	{
20685 		/* Test needs single uniform and two xfbs */
20686 		out_descriptors.resize(3);
20687 
20688 		/* Get references */
20689 		bufferDescriptor& uniform = out_descriptors[0];
20690 		bufferDescriptor& xfb_0   = out_descriptors[1];
20691 		bufferDescriptor& xfb_1   = out_descriptors[2];
20692 
20693 		/* Index */
20694 		uniform.m_index = 0;
20695 		xfb_0.m_index   = 0;
20696 		xfb_1.m_index   = 1;
20697 
20698 		/* Target */
20699 		uniform.m_target = Utils::Buffer::Uniform;
20700 		xfb_0.m_target   = Utils::Buffer::Transform_feedback;
20701 		xfb_1.m_target   = Utils::Buffer::Transform_feedback;
20702 
20703 		/* Data */
20704 		uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20705 
20706 		xfb_0.m_initial_data  = Utils::Type::vec4.GenerateDataPacked();
20707 		xfb_0.m_expected_data = uniform.m_initial_data;
20708 
20709 		/* Data, contents are the same as no modification is expected */
20710 		xfb_1.m_initial_data.resize(m_stride);
20711 		xfb_1.m_expected_data.resize(m_stride);
20712 
20713 		for (GLuint i = 0; i < m_stride; ++i)
20714 		{
20715 			xfb_1.m_initial_data[0]  = (glw::GLubyte)i;
20716 			xfb_1.m_expected_data[0] = (glw::GLubyte)i;
20717 		}
20718 	}
20719 
20720 	break;
20721 
20722 	case FIRST_MISSING:
20723 	{
20724 		/* Test needs single uniform and two xfbs */
20725 		out_descriptors.resize(2);
20726 
20727 		/* Get references */
20728 		bufferDescriptor& uniform = out_descriptors[0];
20729 		bufferDescriptor& xfb_1   = out_descriptors[1];
20730 
20731 		/* Index */
20732 		uniform.m_index = 0;
20733 		xfb_1.m_index   = 1;
20734 
20735 		/* Target */
20736 		uniform.m_target = Utils::Buffer::Uniform;
20737 		xfb_1.m_target   = Utils::Buffer::Transform_feedback;
20738 
20739 		/* Data */
20740 		uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20741 
20742 		/* Draw call will not be executed, contents does not matter */
20743 		xfb_1.m_initial_data.resize(m_stride);
20744 	}
20745 
20746 	break;
20747 
20748 	case SECOND_MISSING:
20749 	{
20750 		/* Test needs single uniform and two xfbs */
20751 		out_descriptors.resize(2);
20752 
20753 		/* Get references */
20754 		bufferDescriptor& uniform = out_descriptors[0];
20755 		bufferDescriptor& xfb_0   = out_descriptors[1];
20756 
20757 		/* Index */
20758 		uniform.m_index = 0;
20759 		xfb_0.m_index   = 0;
20760 
20761 		/* Target */
20762 		uniform.m_target = Utils::Buffer::Uniform;
20763 		xfb_0.m_target   = Utils::Buffer::Transform_feedback;
20764 
20765 		/* Data */
20766 		uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20767 
20768 		xfb_0.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20769 		xfb_0.m_expected_data = uniform.m_initial_data;
20770 	}
20771 
20772 	break;
20773 	}
20774 }
20775 
20776 /** Get body of main function for given shader stage
20777  *
20778  * @param ignored
20779  * @param stage            Shader stage
20780  * @param out_assignments  Set to empty
20781  * @param out_calculations Set to empty
20782  **/
20783 void XFBStrideOfEmptyListTest::getShaderBody(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
20784 											 std::string& out_assignments, std::string& out_calculations)
20785 {
20786 	out_calculations = "";
20787 
20788 	static const GLchar* gs = "    gs_fs  = uni_gs;\n";
20789 	static const GLchar* fs = "    fs_out = vec4(gs_fs);\n";
20790 
20791 	const GLchar* assignments = "";
20792 	switch (stage)
20793 	{
20794 	case Utils::Shader::FRAGMENT:
20795 		assignments = fs;
20796 		break;
20797 	case Utils::Shader::GEOMETRY:
20798 		assignments = gs;
20799 		break;
20800 	default:
20801 		break;
20802 	}
20803 
20804 	out_assignments = assignments;
20805 }
20806 
20807 /** Get interface of shader
20808  *
20809  * @param ignored
20810  * @param stage            Shader stage
20811  * @param out_interface    Set to ""
20812  **/
20813 void XFBStrideOfEmptyListTest::getShaderInterface(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
20814 												  std::string& out_interface)
20815 {
20816 	static const GLchar* gs = "layout (xfb_buffer = 0, xfb_offset = 0)  out     vec4 gs_fs;\n"
20817 							  "layout (xfb_buffer = 1, xfb_stride = 64) out;\n"
20818 							  "\n"
20819 							  "layout (binding    = 0)                  uniform gs_block {\n"
20820 							  "    vec4 uni_gs;\n"
20821 							  "};\n";
20822 	static const GLchar* fs = "in  vec4 gs_fs;\n"
20823 							  "out vec4 fs_out;\n";
20824 
20825 	switch (stage)
20826 	{
20827 	case Utils::Shader::FRAGMENT:
20828 		out_interface = fs;
20829 		break;
20830 	case Utils::Shader::GEOMETRY:
20831 		out_interface = gs;
20832 		break;
20833 	default:
20834 		out_interface = "";
20835 		return;
20836 	}
20837 }
20838 
20839 /** Returns buffer details in human readable form.
20840  *
20841  * @param test_case_index Index of test case
20842  *
20843  * @return Case description
20844  **/
20845 std::string XFBStrideOfEmptyListTest::getTestCaseName(GLuint test_case_index)
20846 {
20847 	std::string result;
20848 
20849 	switch (test_case_index)
20850 	{
20851 	case VALID:
20852 		result = "Valid case";
20853 		break;
20854 	case FIRST_MISSING:
20855 		result = "Missing xfb at index 0";
20856 		break;
20857 	case SECOND_MISSING:
20858 		result = "Missing xfb at index 1";
20859 		break;
20860 	default:
20861 		TCU_FAIL("Invalid enum");
20862 	}
20863 
20864 	return result;
20865 }
20866 
20867 /** Get number of test cases
20868  *
20869  * @return 3
20870  **/
20871 GLuint XFBStrideOfEmptyListTest::getTestCaseNumber()
20872 {
20873 	return 3;
20874 }
20875 
20876 /* Constants used by XFBStrideOfEmptyListTest */
20877 const GLuint XFBStrideOfEmptyListAndAPITest::m_stride = 64;
20878 
20879 /** Constructor
20880  *
20881  * @param context Test context
20882  **/
20883 XFBStrideOfEmptyListAndAPITest::XFBStrideOfEmptyListAndAPITest(deqp::Context& context)
20884 	: BufferTestBase(context, "xfb_stride_of_empty_list_and_api",
20885 					 "Test verifies that xfb_stride qualifier is not overriden by API")
20886 {
20887 	/* Nothing to be done here */
20888 }
20889 
20890 /** Execute drawArrays for single vertex
20891  *
20892  * @param test_case_index Index of test case
20893  *
20894  * @return true if proper error is reported
20895  **/
20896 bool XFBStrideOfEmptyListAndAPITest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
20897 {
20898 	const Functions& gl		= m_context.getRenderContext().getFunctions();
20899 	bool			 result = true;
20900 
20901 	/* Draw */
20902 	gl.disable(GL_RASTERIZER_DISCARD);
20903 	GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
20904 
20905 	gl.beginTransformFeedback(GL_POINTS);
20906 	GLenum error = gl.getError();
20907 	switch (test_case_index)
20908 	{
20909 	case VALID:
20910 		if (GL_NO_ERROR != error)
20911 		{
20912 			gl.endTransformFeedback();
20913 			GLU_EXPECT_NO_ERROR(error, "BeginTransformFeedback");
20914 		}
20915 
20916 		gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
20917 		error = gl.getError();
20918 
20919 		gl.endTransformFeedback();
20920 		GLU_EXPECT_NO_ERROR(error, "DrawArrays");
20921 		GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
20922 
20923 		break;
20924 
20925 	case FIRST_MISSING:
20926 		if (GL_NO_ERROR != error)
20927 		{
20928 			gl.endTransformFeedback();
20929 			GLU_EXPECT_NO_ERROR(error, "BeginTransformFeedback");
20930 		}
20931 
20932 		gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
20933 		error = gl.getError();
20934 
20935 		gl.endTransformFeedback();
20936 		GLU_EXPECT_NO_ERROR(error, "DrawArrays");
20937 		GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
20938 
20939 		break;
20940 
20941 	case SECOND_MISSING:
20942 		if (GL_NO_ERROR == error)
20943 		{
20944 			gl.endTransformFeedback();
20945 		}
20946 
20947 		if (GL_INVALID_OPERATION != error)
20948 		{
20949 			m_context.getTestContext().getLog()
20950 				<< tcu::TestLog::Message << "XFB at index 1, that is declared as empty, is missing. It was expected "
20951 											"that INVALID_OPERATION will generated by BeginTransformFeedback. Got: "
20952 				<< glu::getErrorStr(error) << tcu::TestLog::EndMessage;
20953 
20954 			result = false;
20955 		}
20956 
20957 		break;
20958 	}
20959 
20960 	/* Done */
20961 	return result;
20962 }
20963 
20964 /** Get descriptors of buffers necessary for test
20965  *
20966  * @param test_case_index Index of test case
20967  * @param out_descriptors Descriptors of buffers used by test
20968  **/
20969 void XFBStrideOfEmptyListAndAPITest::getBufferDescriptors(glw::GLuint				test_case_index,
20970 														  bufferDescriptor::Vector& out_descriptors)
20971 {
20972 	switch (test_case_index)
20973 	{
20974 	case VALID:
20975 	{
20976 		/* Test needs single uniform and two xfbs */
20977 		out_descriptors.resize(3);
20978 
20979 		/* Get references */
20980 		bufferDescriptor& uniform = out_descriptors[0];
20981 		bufferDescriptor& xfb_0   = out_descriptors[1];
20982 		bufferDescriptor& xfb_1   = out_descriptors[2];
20983 
20984 		/* Index */
20985 		uniform.m_index = 0;
20986 		xfb_0.m_index   = 0;
20987 		xfb_1.m_index   = 1;
20988 
20989 		/* Target */
20990 		uniform.m_target = Utils::Buffer::Uniform;
20991 		xfb_0.m_target   = Utils::Buffer::Transform_feedback;
20992 		xfb_1.m_target   = Utils::Buffer::Transform_feedback;
20993 
20994 		/* Data */
20995 		uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
20996 
20997 		/* Data, contents are the same as no modification is expected */
20998 		xfb_0.m_initial_data.resize(m_stride);
20999 		xfb_0.m_expected_data.resize(m_stride);
21000 
21001 		for (GLuint i = 0; i < m_stride; ++i)
21002 		{
21003 			xfb_0.m_initial_data[0]  = (glw::GLubyte)i;
21004 			xfb_0.m_expected_data[0] = (glw::GLubyte)i;
21005 		}
21006 
21007 		xfb_1.m_initial_data  = Utils::Type::vec4.GenerateDataPacked();
21008 		xfb_1.m_expected_data = uniform.m_initial_data;
21009 	}
21010 
21011 	break;
21012 
21013 	case FIRST_MISSING:
21014 	{
21015 		/* Test needs single uniform and two xfbs */
21016 		out_descriptors.resize(2);
21017 
21018 		/* Get references */
21019 		bufferDescriptor& uniform = out_descriptors[0];
21020 		bufferDescriptor& xfb_1   = out_descriptors[1];
21021 
21022 		/* Index */
21023 		uniform.m_index = 0;
21024 		xfb_1.m_index   = 1;
21025 
21026 		/* Target */
21027 		uniform.m_target = Utils::Buffer::Uniform;
21028 		xfb_1.m_target   = Utils::Buffer::Transform_feedback;
21029 
21030 		/* Data */
21031 		uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
21032 
21033 		/* Data, contents are the same as no modification is expected */
21034 		xfb_1.m_initial_data  = Utils::Type::vec4.GenerateDataPacked();
21035 		xfb_1.m_expected_data = uniform.m_initial_data;
21036 	}
21037 
21038 	break;
21039 
21040 	case SECOND_MISSING:
21041 	{
21042 		/* Test needs single uniform and two xfbs */
21043 		out_descriptors.resize(2);
21044 
21045 		/* Get references */
21046 		bufferDescriptor& uniform = out_descriptors[0];
21047 		bufferDescriptor& xfb_0   = out_descriptors[1];
21048 
21049 		/* Index */
21050 		uniform.m_index = 0;
21051 		xfb_0.m_index   = 0;
21052 
21053 		/* Target */
21054 		uniform.m_target = Utils::Buffer::Uniform;
21055 		xfb_0.m_target   = Utils::Buffer::Transform_feedback;
21056 
21057 		/* Data */
21058 		uniform.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
21059 
21060 		/* Draw call will not be executed, contents does not matter */
21061 		xfb_0.m_initial_data = Utils::Type::vec4.GenerateDataPacked();
21062 	}
21063 
21064 	break;
21065 	}
21066 }
21067 
21068 /** Get list of names of varyings that will be registered with TransformFeedbackVaryings
21069  *
21070  * @param ignored
21071  * @param captured_varyings Vector of varying names to be captured
21072  **/
21073 void XFBStrideOfEmptyListAndAPITest::getCapturedVaryings(glw::GLuint /* test_case_index */,
21074 														 Utils::Program::NameVector& captured_varyings,
21075 														 GLint* xfb_components)
21076 {
21077 	captured_varyings.push_back("gs_fs1");
21078 	captured_varyings.push_back("gs_fs2");
21079 	*xfb_components	= 4;
21080 }
21081 
21082 /** Get body of main function for given shader stage
21083  *
21084  * @param ignored
21085  * @param stage            Shader stage
21086  * @param out_assignments  Set to empty
21087  * @param out_calculations Set to empty
21088  **/
21089 void XFBStrideOfEmptyListAndAPITest::getShaderBody(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
21090 												   std::string& out_assignments, std::string& out_calculations)
21091 {
21092 	out_calculations = "";
21093 
21094 	static const GLchar* gs = "    gs_fs1 = -uni_gs;\n"
21095 							  "    gs_fs2 = uni_gs;\n";
21096 	static const GLchar* fs = "    fs_out = vec4(gs_fs2);\n";
21097 
21098 	const GLchar* assignments = "";
21099 	switch (stage)
21100 	{
21101 	case Utils::Shader::FRAGMENT:
21102 		assignments = fs;
21103 		break;
21104 	case Utils::Shader::GEOMETRY:
21105 		assignments = gs;
21106 		break;
21107 	default:
21108 		break;
21109 	}
21110 
21111 	out_assignments = assignments;
21112 }
21113 
21114 /** Get interface of shader
21115  *
21116  * @param ignored
21117  * @param stage            Shader stage
21118  * @param out_interface    Set to ""
21119  **/
21120 void XFBStrideOfEmptyListAndAPITest::getShaderInterface(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
21121 														std::string& out_interface)
21122 {
21123 	static const GLchar* gs = "layout (xfb_buffer = 0, xfb_stride = 64) out vec4 gs_fs1;\n"
21124 							  "layout (xfb_buffer = 1, xfb_offset = 0)  out vec4 gs_fs2;\n"
21125 							  "\n"
21126 							  "layout(binding    = 0) uniform gs_block {\n"
21127 							  "    vec4 uni_gs;\n"
21128 							  "};\n";
21129 	static const GLchar* fs = "in  vec4 gs_fs2;\n"
21130 							  "out vec4 fs_out;\n";
21131 
21132 	switch (stage)
21133 	{
21134 	case Utils::Shader::FRAGMENT:
21135 		out_interface = fs;
21136 		break;
21137 	case Utils::Shader::GEOMETRY:
21138 		out_interface = gs;
21139 		break;
21140 	default:
21141 		out_interface = "";
21142 		return;
21143 	}
21144 }
21145 
21146 /** Returns buffer details in human readable form.
21147  *
21148  * @param test_case_index Index of test case
21149  *
21150  * @return Case description
21151  **/
21152 std::string XFBStrideOfEmptyListAndAPITest::getTestCaseName(GLuint test_case_index)
21153 {
21154 	std::string result;
21155 
21156 	switch (test_case_index)
21157 	{
21158 	case VALID:
21159 		result = "Valid case";
21160 		break;
21161 	case FIRST_MISSING:
21162 		result = "Missing xfb at index 0";
21163 		break;
21164 	case SECOND_MISSING:
21165 		result = "Missing xfb at index 1";
21166 		break;
21167 	default:
21168 		TCU_FAIL("Invalid enum");
21169 	}
21170 
21171 	return result;
21172 }
21173 
21174 /** Get number of test cases
21175  *
21176  * @return 2
21177  **/
21178 GLuint XFBStrideOfEmptyListAndAPITest::getTestCaseNumber()
21179 {
21180 	return 3;
21181 }
21182 
21183 /** Constructor
21184  *
21185  * @param context Test framework context
21186  **/
21187 XFBTooSmallStrideTest::XFBTooSmallStrideTest(deqp::Context& context)
21188 	: NegativeTestBase(context, "xfb_too_small_stride",
21189 					   "Test verifies that compiler reports error when xfb_stride sets not enough space")
21190 {
21191 }
21192 
21193 /** Source for given test case and stage
21194  *
21195  * @param test_case_index Index of test case
21196  * @param stage           Shader stage
21197  *
21198  * @return Shader source
21199  **/
21200 std::string XFBTooSmallStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
21201 {
21202 #if DEBUG_NEG_REMOVE_ERROR
21203 	static const GLchar* array_var_definition = "layout (xfb_buffer = 0 /*, xfb_stride = 32 */ ) out;\n"
21204 #else
21205 	static const GLchar* array_var_definition  = "layout (xfb_buffer = 0, xfb_stride = 32) out;\n"
21206 #endif /* DEBUG_NEG_REMOVE_ERROR */
21207 												"\n"
21208 												"layout (xfb_offset = 16) out vec4 gohan[4];\n";
21209 #if DEBUG_NEG_REMOVE_ERROR
21210 	static const GLchar* block_var_definition = "layout (xfb_buffer = 0 /*, xfb_stride = 32 */ ) out;\n"
21211 #else
21212 	static const GLchar* block_var_definition  = "layout (xfb_buffer = 0, xfb_stride = 32) out;\n"
21213 #endif /* DEBUG_NEG_REMOVE_ERROR */
21214 												"\n"
21215 												"layout (xfb_offset = 0) out Goku {\n"
21216 												"    vec4 gohan;\n"
21217 												"    vec4 goten;\n"
21218 												"    vec4 chichi;\n"
21219 												"} goku;\n";
21220 #if DEBUG_NEG_REMOVE_ERROR
21221 	static const GLchar* offset_var_definition = "layout (xfb_buffer = 0 /*, xfb_stride = 40 */ ) out;\n"
21222 #else
21223 	static const GLchar* offset_var_definition = "layout (xfb_buffer = 0, xfb_stride = 40) out;\n"
21224 #endif /* DEBUG_NEG_REMOVE_ERROR */
21225 												 "\n"
21226 												 "layout (xfb_offset = 32) out vec4 gohan;\n";
21227 // 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;"
21228 // To make the shader failed to compile, change xfb_stride to a value that is smaller than 32
21229 #if DEBUG_NEG_REMOVE_ERROR
21230 	static const GLchar* stride_var_definition = "layout (xfb_buffer = 0 /*, xfb_stride = 28 */ ) out;\n"
21231 												 "\n"
21232 												 "layout (xfb_offset = 16 /*, xfb_stride = 28 */ ) out vec4 gohan;\n";
21233 #else
21234 	static const GLchar* stride_var_definition = "layout (xfb_buffer = 0, xfb_stride = 28) out;\n"
21235 												 "\n"
21236 												 "layout (xfb_offset = 16, xfb_stride = 28) out vec4 gohan;\n";
21237 #endif /* DEBUG_NEG_REMOVE_ERROR */
21238 	static const GLchar* array_use = "    gohan[0] = result / 2;\n"
21239 									 "    gohan[1] = result / 4;\n"
21240 									 "    gohan[2] = result / 6;\n"
21241 									 "    gohan[3] = result / 8;\n";
21242 	static const GLchar* block_use = "    goku.gohan  = result / 2;\n"
21243 									 "    goku.goten  = result / 4;\n"
21244 									 "    goku.chichi = result / 6;\n";
21245 	static const GLchar* output_use = "gohan = result / 4;\n";
21246 	static const GLchar* fs			= "#version 430 core\n"
21247 							  "#extension GL_ARB_enhanced_layouts : require\n"
21248 							  "\n"
21249 							  "in  vec4 any_fs;\n"
21250 							  "out vec4 fs_out;\n"
21251 							  "\n"
21252 							  "void main()\n"
21253 							  "{\n"
21254 							  "    fs_out = any_fs;\n"
21255 							  "}\n"
21256 							  "\n";
21257 	static const GLchar* gs_tested = "#version 430 core\n"
21258 									 "#extension GL_ARB_enhanced_layouts : require\n"
21259 									 "\n"
21260 									 "layout(points)                           in;\n"
21261 									 "layout(triangle_strip, max_vertices = 4) out;\n"
21262 									 "\n"
21263 									 "VAR_DEFINITION"
21264 									 "\n"
21265 									 "in  vec4 vs_any[];\n"
21266 									 "out vec4 any_fs;\n"
21267 									 "\n"
21268 									 "void main()\n"
21269 									 "{\n"
21270 									 "    vec4 result = vs_any[0];\n"
21271 									 "\n"
21272 									 "VARIABLE_USE"
21273 									 "\n"
21274 									 "    any_fs = result;\n"
21275 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
21276 									 "    EmitVertex();\n"
21277 									 "    any_fs = result;\n"
21278 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
21279 									 "    EmitVertex();\n"
21280 									 "    any_fs = result;\n"
21281 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
21282 									 "    EmitVertex();\n"
21283 									 "    any_fs = result;\n"
21284 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
21285 									 "    EmitVertex();\n"
21286 									 "}\n"
21287 									 "\n";
21288 	static const GLchar* tcs = "#version 430 core\n"
21289 							   "#extension GL_ARB_enhanced_layouts : require\n"
21290 							   "\n"
21291 							   "layout(vertices = 1) out;\n"
21292 							   "\n"
21293 							   "in  vec4 vs_any[];\n"
21294 							   "out vec4 tcs_tes[];\n"
21295 							   "\n"
21296 							   "void main()\n"
21297 							   "{\n"
21298 							   "\n"
21299 							   "    tcs_tes[gl_InvocationID] = vs_any[gl_InvocationID];\n"
21300 							   "\n"
21301 							   "    gl_TessLevelOuter[0] = 1.0;\n"
21302 							   "    gl_TessLevelOuter[1] = 1.0;\n"
21303 							   "    gl_TessLevelOuter[2] = 1.0;\n"
21304 							   "    gl_TessLevelOuter[3] = 1.0;\n"
21305 							   "    gl_TessLevelInner[0] = 1.0;\n"
21306 							   "    gl_TessLevelInner[1] = 1.0;\n"
21307 							   "}\n"
21308 							   "\n";
21309 	static const GLchar* tes_tested = "#version 430 core\n"
21310 									  "#extension GL_ARB_enhanced_layouts : require\n"
21311 									  "\n"
21312 									  "layout(isolines, point_mode) in;\n"
21313 									  "\n"
21314 									  "VAR_DEFINITION"
21315 									  "\n"
21316 									  "in  vec4 tcs_tes[];\n"
21317 									  "out vec4 any_fs;\n"
21318 									  "\n"
21319 									  "void main()\n"
21320 									  "{\n"
21321 									  "    vec4 result = tcs_tes[0];\n"
21322 									  "\n"
21323 									  "VARIABLE_USE"
21324 									  "\n"
21325 									  "    any_fs += result;\n"
21326 									  "}\n"
21327 									  "\n";
21328 	static const GLchar* vs = "#version 430 core\n"
21329 							  "#extension GL_ARB_enhanced_layouts : require\n"
21330 							  "\n"
21331 							  "in  vec4 in_vs;\n"
21332 							  "out vec4 vs_any;\n"
21333 							  "\n"
21334 							  "void main()\n"
21335 							  "{\n"
21336 							  "    vs_any = in_vs;\n"
21337 							  "}\n"
21338 							  "\n";
21339 	static const GLchar* vs_tested = "#version 430 core\n"
21340 									 "#extension GL_ARB_enhanced_layouts : require\n"
21341 									 "\n"
21342 									 "VAR_DEFINITION"
21343 									 "\n"
21344 									 "in  vec4 in_vs;\n"
21345 									 "out vec4 any_fs;\n"
21346 									 "\n"
21347 									 "void main()\n"
21348 									 "{\n"
21349 									 "    vec4 result = in_vs;\n"
21350 									 "\n"
21351 									 "VARIABLE_USE"
21352 									 "\n"
21353 									 "    any_fs += result;\n"
21354 									 "}\n"
21355 									 "\n";
21356 
21357 	std::string source;
21358 	testCase&   test_case = m_test_cases[test_case_index];
21359 
21360 	if (test_case.m_stage == stage)
21361 	{
21362 		size_t		  position = 0;
21363 		const GLchar* var_definition = 0;
21364 		const GLchar* var_use		 = 0;
21365 
21366 		switch (test_case.m_case)
21367 		{
21368 		case OFFSET:
21369 			var_definition = offset_var_definition;
21370 			var_use		   = output_use;
21371 			break;
21372 		case STRIDE:
21373 			var_definition = stride_var_definition;
21374 			var_use		   = output_use;
21375 			break;
21376 		case BLOCK:
21377 			var_definition = block_var_definition;
21378 			var_use		   = block_use;
21379 			break;
21380 		case ARRAY:
21381 			var_definition = array_var_definition;
21382 			var_use		   = array_use;
21383 			break;
21384 		default:
21385 			TCU_FAIL("Invalid enum");
21386 		}
21387 
21388 		switch (stage)
21389 		{
21390 		case Utils::Shader::GEOMETRY:
21391 			source = gs_tested;
21392 			break;
21393 		case Utils::Shader::TESS_EVAL:
21394 			source = tes_tested;
21395 			break;
21396 		case Utils::Shader::VERTEX:
21397 			source = vs_tested;
21398 			break;
21399 		default:
21400 			TCU_FAIL("Invalid enum");
21401 		}
21402 
21403 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
21404 		position = 0;
21405 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
21406 	}
21407 	else
21408 	{
21409 		switch (test_case.m_stage)
21410 		{
21411 		case Utils::Shader::GEOMETRY:
21412 			switch (stage)
21413 			{
21414 			case Utils::Shader::FRAGMENT:
21415 				source = fs;
21416 				break;
21417 			case Utils::Shader::VERTEX:
21418 				source = vs;
21419 				break;
21420 			default:
21421 				source = "";
21422 			}
21423 			break;
21424 		case Utils::Shader::TESS_EVAL:
21425 			switch (stage)
21426 			{
21427 			case Utils::Shader::FRAGMENT:
21428 				source = fs;
21429 				break;
21430 			case Utils::Shader::TESS_CTRL:
21431 				source = tcs;
21432 				break;
21433 			case Utils::Shader::VERTEX:
21434 				source = vs;
21435 				break;
21436 			default:
21437 				source = "";
21438 			}
21439 			break;
21440 		case Utils::Shader::VERTEX:
21441 			switch (stage)
21442 			{
21443 			case Utils::Shader::FRAGMENT:
21444 				source = fs;
21445 				break;
21446 			default:
21447 				source = "";
21448 			}
21449 			break;
21450 		default:
21451 			TCU_FAIL("Invalid enum");
21452 			break;
21453 		}
21454 	}
21455 
21456 	return source;
21457 }
21458 
21459 /** Get description of test case
21460  *
21461  * @param test_case_index Index of test case
21462  *
21463  * @return Test case description
21464  **/
21465 std::string XFBTooSmallStrideTest::getTestCaseName(GLuint test_case_index)
21466 {
21467 	std::stringstream stream;
21468 	testCase&		  test_case = m_test_cases[test_case_index];
21469 
21470 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", case: ";
21471 
21472 	switch (test_case.m_case)
21473 	{
21474 	case OFFSET:
21475 		stream << "buffer stride: 40, vec4 offset: 32";
21476 		break;
21477 	case STRIDE:
21478 		stream << "buffer stride: 32, vec4 off 16 stride: 32";
21479 		break;
21480 	case BLOCK:
21481 		stream << "buffer stride: 32, block 3xvec4 offset 0";
21482 		break;
21483 	case ARRAY:
21484 		stream << "buffer stride: 32, vec4[4] offset 16";
21485 		break;
21486 	default:
21487 		TCU_FAIL("Invalid enum");
21488 	}
21489 
21490 	return stream.str();
21491 }
21492 
21493 /** Get number of test cases
21494  *
21495  * @return Number of test cases
21496  **/
21497 GLuint XFBTooSmallStrideTest::getTestCaseNumber()
21498 {
21499 	return static_cast<GLuint>(m_test_cases.size());
21500 }
21501 
21502 /** Selects if "compute" stage is relevant for test
21503  *
21504  * @param ignored
21505  *
21506  * @return false
21507  **/
21508 bool XFBTooSmallStrideTest::isComputeRelevant(GLuint /* test_case_index */)
21509 {
21510 	return false;
21511 }
21512 
21513 /** Prepare all test cases
21514  *
21515  **/
21516 void XFBTooSmallStrideTest::testInit()
21517 {
21518 	for (GLuint c = 0; c < CASE_MAX; ++c)
21519 	{
21520 		for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
21521 		{
21522 			/*
21523 			 It is invalid to define transform feedback output in TCS, according to spec:
21524 			 The data captured in transform feedback mode depends on the active programs on each of the shader stages.
21525 			 If a program is active for the geometry shader stage, transform feedback captures the vertices of each
21526 			 primitive emitted by the geometry shader. Otherwise, if a program is active for the tessellation evaluation
21527 			 shader stage, transform feedback captures each primitive produced by the tessellation primitive generator,
21528 			 whose vertices are processed by the tessellation evaluation shader. Otherwise, transform feedback captures
21529 			 each primitive processed by the vertex shader.
21530 			 */
21531 			if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
21532 				(Utils::Shader::FRAGMENT == stage))
21533 			{
21534 				continue;
21535 			}
21536 
21537 			testCase test_case = { (CASES)c, (Utils::Shader::STAGES)stage };
21538 
21539 			m_test_cases.push_back(test_case);
21540 		}
21541 	}
21542 }
21543 
21544 /** Constructor
21545  *
21546  * @param context Test framework context
21547  **/
21548 XFBVariableStrideTest::XFBVariableStrideTest(deqp::Context& context)
21549 	: NegativeTestBase(context, "xfb_variable_stride", "Test verifies that stride qualifier is respected")
21550 {
21551 }
21552 
21553 /** Source for given test case and stage
21554  *
21555  * @param test_case_index Index of test case
21556  * @param stage           Shader stage
21557  *
21558  * @return Shader source
21559  **/
21560 std::string XFBVariableStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
21561 {
21562 	static const GLchar* invalid_var_definition = "const uint type_size = SIZE;\n"
21563 												  "\n"
21564 #if DEBUG_NEG_REMOVE_ERROR
21565 												  "layout (xfb_stride = 2 * type_size) out;\n"
21566 #else
21567 												  "layout (xfb_stride = type_size) out;\n"
21568 #endif /* DEBUG_NEG_REMOVE_ERROR */
21569 												  "\n"
21570 												  "layout (xfb_offset = 0)         out TYPE goku;\n"
21571 												  "layout (xfb_offset = type_size) out TYPE vegeta;\n";
21572 	static const GLchar* valid_var_definition = "const uint type_size = SIZE;\n"
21573 												"\n"
21574 												"layout (xfb_stride = type_size) out;\n"
21575 												"\n"
21576 												"layout (xfb_offset = 0) out TYPE goku;\n";
21577 	static const GLchar* invalid_use = "    goku   = TYPE(1);\n"
21578 									   "    vegeta = TYPE(0);\n"
21579 									   "    if (vec4(0) == result)\n"
21580 									   "    {\n"
21581 									   "        goku   = TYPE(0);\n"
21582 									   "        vegeta = TYPE(1);\n"
21583 									   "    }\n";
21584 	static const GLchar* valid_use = "    goku   = TYPE(1);\n"
21585 									 "    if (vec4(0) == result)\n"
21586 									 "    {\n"
21587 									 "        goku   = TYPE(0);\n"
21588 									 "    }\n";
21589 	static const GLchar* fs = "#version 430 core\n"
21590 							  "#extension GL_ARB_enhanced_layouts : require\n"
21591 							  "\n"
21592 							  "in  vec4 any_fs;\n"
21593 							  "out vec4 fs_out;\n"
21594 							  "\n"
21595 							  "void main()\n"
21596 							  "{\n"
21597 							  "    fs_out = any_fs;\n"
21598 							  "}\n"
21599 							  "\n";
21600 	static const GLchar* gs_tested = "#version 430 core\n"
21601 									 "#extension GL_ARB_enhanced_layouts : require\n"
21602 									 "\n"
21603 									 "layout(points)                           in;\n"
21604 									 "layout(triangle_strip, max_vertices = 4) out;\n"
21605 									 "\n"
21606 									 "VAR_DEFINITION"
21607 									 "\n"
21608 									 "in  vec4 vs_any[];\n"
21609 									 "out vec4 any_fs;\n"
21610 									 "\n"
21611 									 "void main()\n"
21612 									 "{\n"
21613 									 "    vec4 result = vs_any[0];\n"
21614 									 "\n"
21615 									 "VARIABLE_USE"
21616 									 "\n"
21617 									 "    any_fs = result;\n"
21618 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
21619 									 "    EmitVertex();\n"
21620 									 "    any_fs = result;\n"
21621 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
21622 									 "    EmitVertex();\n"
21623 									 "    any_fs = result;\n"
21624 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
21625 									 "    EmitVertex();\n"
21626 									 "    any_fs = result;\n"
21627 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
21628 									 "    EmitVertex();\n"
21629 									 "}\n"
21630 									 "\n";
21631 	static const GLchar* tcs = "#version 430 core\n"
21632 							   "#extension GL_ARB_enhanced_layouts : require\n"
21633 							   "\n"
21634 							   "layout(vertices = 1) out;\n"
21635 							   "\n"
21636 							   "in  vec4 vs_any[];\n"
21637 							   "out vec4 tcs_tes[];\n"
21638 							   "\n"
21639 							   "void main()\n"
21640 							   "{\n"
21641 							   "\n"
21642 							   "    tcs_tes[gl_InvocationID] = vs_any[gl_InvocationID];\n"
21643 							   "\n"
21644 							   "    gl_TessLevelOuter[0] = 1.0;\n"
21645 							   "    gl_TessLevelOuter[1] = 1.0;\n"
21646 							   "    gl_TessLevelOuter[2] = 1.0;\n"
21647 							   "    gl_TessLevelOuter[3] = 1.0;\n"
21648 							   "    gl_TessLevelInner[0] = 1.0;\n"
21649 							   "    gl_TessLevelInner[1] = 1.0;\n"
21650 							   "}\n"
21651 							   "\n";
21652 	static const GLchar* tes_tested = "#version 430 core\n"
21653 									  "#extension GL_ARB_enhanced_layouts : require\n"
21654 									  "\n"
21655 									  "layout(isolines, point_mode) in;\n"
21656 									  "\n"
21657 									  "VAR_DEFINITION"
21658 									  "\n"
21659 									  "in  vec4 tcs_tes[];\n"
21660 									  "out vec4 any_fs;\n"
21661 									  "\n"
21662 									  "void main()\n"
21663 									  "{\n"
21664 									  "    vec4 result = tcs_tes[0];\n"
21665 									  "\n"
21666 									  "VARIABLE_USE"
21667 									  "\n"
21668 									  "    any_fs = result;\n"
21669 									  "}\n"
21670 									  "\n";
21671 	static const GLchar* vs = "#version 430 core\n"
21672 							  "#extension GL_ARB_enhanced_layouts : require\n"
21673 							  "\n"
21674 							  "in  vec4 in_vs;\n"
21675 							  "out vec4 vs_any;\n"
21676 							  "\n"
21677 							  "void main()\n"
21678 							  "{\n"
21679 							  "    vs_any = in_vs;\n"
21680 							  "}\n"
21681 							  "\n";
21682 	static const GLchar* vs_tested = "#version 430 core\n"
21683 									 "#extension GL_ARB_enhanced_layouts : require\n"
21684 									 "\n"
21685 									 "VAR_DEFINITION"
21686 									 "\n"
21687 									 "in  vec4 in_vs;\n"
21688 									 "out vec4 any_fs;\n"
21689 									 "\n"
21690 									 "void main()\n"
21691 									 "{\n"
21692 									 "    vec4 result = in_vs;\n"
21693 									 "\n"
21694 									 "VARIABLE_USE"
21695 									 "\n"
21696 									 "    any_fs = result;\n"
21697 									 "}\n"
21698 									 "\n";
21699 
21700 	std::string source;
21701 	testCase&   test_case = m_test_cases[test_case_index];
21702 
21703 	if (test_case.m_stage == stage)
21704 	{
21705 		GLchar		  buffer[16];
21706 		size_t		  position = 0;
21707 		const GLchar* type_name		 = test_case.m_type.GetGLSLTypeName();
21708 		const GLchar* var_definition = 0;
21709 		const GLchar* var_use		 = 0;
21710 
21711 		sprintf(buffer, "%d", test_case.m_type.GetSize());
21712 
21713 		switch (test_case.m_case)
21714 		{
21715 		case VALID:
21716 			var_definition = valid_var_definition;
21717 			var_use		   = valid_use;
21718 			break;
21719 		case INVALID:
21720 			var_definition = invalid_var_definition;
21721 			var_use		   = invalid_use;
21722 			break;
21723 		default:
21724 			TCU_FAIL("Invalid enum");
21725 		}
21726 
21727 		switch (stage)
21728 		{
21729 		case Utils::Shader::GEOMETRY:
21730 			source = gs_tested;
21731 			break;
21732 		case Utils::Shader::TESS_EVAL:
21733 			source = tes_tested;
21734 			break;
21735 		case Utils::Shader::VERTEX:
21736 			source = vs_tested;
21737 			break;
21738 		default:
21739 			TCU_FAIL("Invalid enum");
21740 		}
21741 
21742 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
21743 		position = 0;
21744 		Utils::replaceToken("SIZE", position, buffer, source);
21745 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
21746 
21747 		Utils::replaceAllTokens("TYPE", type_name, source);
21748 	}
21749 	else
21750 	{
21751 		switch (test_case.m_stage)
21752 		{
21753 		case Utils::Shader::GEOMETRY:
21754 			switch (stage)
21755 			{
21756 			case Utils::Shader::FRAGMENT:
21757 				source = fs;
21758 				break;
21759 			case Utils::Shader::VERTEX:
21760 				source = vs;
21761 				break;
21762 			default:
21763 				source = "";
21764 			}
21765 			break;
21766 		case Utils::Shader::TESS_EVAL:
21767 			switch (stage)
21768 			{
21769 			case Utils::Shader::FRAGMENT:
21770 				source = fs;
21771 				break;
21772 			case Utils::Shader::TESS_CTRL:
21773 				source = tcs;
21774 				break;
21775 			case Utils::Shader::VERTEX:
21776 				source = vs;
21777 				break;
21778 			default:
21779 				source = "";
21780 			}
21781 			break;
21782 		case Utils::Shader::VERTEX:
21783 			switch (stage)
21784 			{
21785 			case Utils::Shader::FRAGMENT:
21786 				source = fs;
21787 				break;
21788 			default:
21789 				source = "";
21790 			}
21791 			break;
21792 		default:
21793 			TCU_FAIL("Invalid enum");
21794 			break;
21795 		}
21796 	}
21797 
21798 	return source;
21799 }
21800 
21801 /** Get description of test case
21802  *
21803  * @param test_case_index Index of test case
21804  *
21805  * @return Test case description
21806  **/
21807 std::string XFBVariableStrideTest::getTestCaseName(GLuint test_case_index)
21808 {
21809 	std::stringstream stream;
21810 	testCase&		  test_case = m_test_cases[test_case_index];
21811 
21812 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
21813 		   << ", type: " << test_case.m_type.GetGLSLTypeName() << ", case: ";
21814 
21815 	switch (test_case.m_case)
21816 	{
21817 	case VALID:
21818 		stream << "valid";
21819 		break;
21820 	case INVALID:
21821 		stream << "invalid";
21822 		break;
21823 	default:
21824 		TCU_FAIL("Invalid enum");
21825 	}
21826 
21827 	return stream.str();
21828 }
21829 
21830 /** Get number of test cases
21831  *
21832  * @return Number of test cases
21833  **/
21834 GLuint XFBVariableStrideTest::getTestCaseNumber()
21835 {
21836 	return static_cast<GLuint>(m_test_cases.size());
21837 }
21838 
21839 /** Selects if "compute" stage is relevant for test
21840  *
21841  * @param ignored
21842  *
21843  * @return false
21844  **/
21845 bool XFBVariableStrideTest::isComputeRelevant(GLuint /* test_case_index */)
21846 {
21847 	return false;
21848 }
21849 
21850 /** Selects if compilation failure is expected result
21851  *
21852  * @param test_case_index Index of test case
21853  *
21854  * @return true
21855  **/
21856 bool XFBVariableStrideTest::isFailureExpected(GLuint test_case_index)
21857 {
21858 	testCase& test_case = m_test_cases[test_case_index];
21859 
21860 	return (INVALID == test_case.m_case);
21861 }
21862 
21863 /** Prepare all test cases
21864  *
21865  **/
21866 void XFBVariableStrideTest::testInit()
21867 {
21868 	const GLuint n_types = getTypesNumber();
21869 
21870 	for (GLuint i = 0; i < n_types; ++i)
21871 	{
21872 		for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
21873 		{
21874 			if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
21875 				(Utils::Shader::FRAGMENT == stage))
21876 			{
21877 				continue;
21878 			}
21879 
21880 			const Utils::Type& type = getType(i);
21881 			for (GLuint c = 0; c < CASE_MAX; ++c)
21882 			{
21883 				testCase test_case = { static_cast<CASES>(c), static_cast<Utils::Shader::STAGES>(stage), type };
21884 
21885 				m_test_cases.push_back(test_case);
21886 			}
21887 		}
21888 	}
21889 }
21890 
21891 /** Constructor
21892  *
21893  * @param context Test framework context
21894  **/
21895 XFBBlockStrideTest::XFBBlockStrideTest(deqp::Context& context)
21896 	: TestBase(context, "xfb_block_stride", "Test verifies that stride qualifier is respected for blocks")
21897 {
21898 }
21899 
21900 /** Source for given test case and stage
21901  *
21902  * @param test_case_index Index of test case
21903  * @param stage           Shader stage
21904  *
21905  * @return Shader source
21906  **/
21907 std::string XFBBlockStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
21908 {
21909 	static const GLchar* var_definition = "layout (xfb_offset = 0, xfb_stride = 128) out Goku {\n"
21910 										  "    vec4 gohan;\n"
21911 										  "    vec4 goten;\n"
21912 										  "    vec4 chichi;\n"
21913 										  "} gokuARRAY;\n";
21914 	static const GLchar* var_use = "    gokuINDEX.gohan  = vec4(1, 0, 0, 0);\n"
21915 								   "    gokuINDEX.goten  = vec4(0, 0, 1, 0);\n"
21916 								   "    gokuINDEX.chichi = vec4(0, 1, 0, 0);\n"
21917 								   "    if (vec4(0) == result)\n"
21918 								   "    {\n"
21919 								   "        gokuINDEX.gohan  = vec4(0, 1, 1, 1);\n"
21920 								   "        gokuINDEX.goten  = vec4(1, 1, 0, 1);\n"
21921 								   "        gokuINDEX.chichi = vec4(1, 0, 1, 1);\n"
21922 								   "    }\n";
21923 	static const GLchar* gs_tested =
21924 		"#version 430 core\n"
21925 		"#extension GL_ARB_enhanced_layouts : require\n"
21926 		"\n"
21927 		"layout(points)                           in;\n"
21928 		"layout(triangle_strip, max_vertices = 4) out;\n"
21929 		"\n"
21930 		"VAR_DEFINITION"
21931 		"\n"
21932 		"out gl_PerVertex \n"
21933 		"{ \n"
21934 		"   vec4  gl_Position; \n" // gl_Position must be redeclared in separable program mode
21935 		"}; \n"
21936 		"in  vec4 tes_gs[];\n"
21937 		"out vec4 gs_fs;\n"
21938 		"\n"
21939 		"void main()\n"
21940 		"{\n"
21941 		"    vec4 result = tes_gs[0];\n"
21942 		"\n"
21943 		"VARIABLE_USE"
21944 		"\n"
21945 		"    gs_fs = result;\n"
21946 		"    gl_Position  = vec4(-1, -1, 0, 1);\n"
21947 		"    EmitVertex();\n"
21948 		"    gs_fs = result;\n"
21949 		"    gl_Position  = vec4(-1, 1, 0, 1);\n"
21950 		"    EmitVertex();\n"
21951 		"    gs_fs = result;\n"
21952 		"    gl_Position  = vec4(1, -1, 0, 1);\n"
21953 		"    EmitVertex();\n"
21954 		"    gs_fs = result;\n"
21955 		"    gl_Position  = vec4(1, 1, 0, 1);\n"
21956 		"    EmitVertex();\n"
21957 		"}\n"
21958 		"\n";
21959 	static const GLchar* tcs = "#version 430 core\n"
21960 							   "#extension GL_ARB_enhanced_layouts : require\n"
21961 							   "\n"
21962 							   "layout(vertices = 1) out;\n"
21963 							   "\n"
21964 							   "in  vec4 vs_tcs[];\n"
21965 							   "out vec4 tcs_tes[];\n"
21966 							   "\n"
21967 							   "void main()\n"
21968 							   "{\n"
21969 							   "\n"
21970 							   "    tcs_tes[gl_InvocationID] = vs_tcs[gl_InvocationID];\n"
21971 							   "\n"
21972 							   "    gl_TessLevelOuter[0] = 1.0;\n"
21973 							   "    gl_TessLevelOuter[1] = 1.0;\n"
21974 							   "    gl_TessLevelOuter[2] = 1.0;\n"
21975 							   "    gl_TessLevelOuter[3] = 1.0;\n"
21976 							   "    gl_TessLevelInner[0] = 1.0;\n"
21977 							   "    gl_TessLevelInner[1] = 1.0;\n"
21978 							   "}\n"
21979 							   "\n";
21980 #if 0
21981 	static const GLchar* tcs_tested =
21982 		"#version 430 core\n"
21983 		"#extension GL_ARB_enhanced_layouts : require\n"
21984 		"\n"
21985 		"layout(vertices = 1) out;\n"
21986 		"\n"
21987 		"VAR_DEFINITION"
21988 		"\n"
21989 		"in  vec4 vs_tcs[];\n"
21990 		"out vec4 tcs_tes[];\n"
21991 		"\n"
21992 		"void main()\n"
21993 		"{\n"
21994 		"    vec4 result = vs_tcs[gl_InvocationID];\n"
21995 		"\n"
21996 		"VARIABLE_USE"
21997 		"\n"
21998 		"    tcs_tes[gl_InvocationID] = result;\n"
21999 		"\n"
22000 		"    gl_TessLevelOuter[0] = 1.0;\n"
22001 		"    gl_TessLevelOuter[1] = 1.0;\n"
22002 		"    gl_TessLevelOuter[2] = 1.0;\n"
22003 		"    gl_TessLevelOuter[3] = 1.0;\n"
22004 		"    gl_TessLevelInner[0] = 1.0;\n"
22005 		"    gl_TessLevelInner[1] = 1.0;\n"
22006 		"}\n"
22007 		"\n";
22008 #endif
22009 	static const GLchar* tes_tested = "#version 430 core\n"
22010 									  "#extension GL_ARB_enhanced_layouts : require\n"
22011 									  "\n"
22012 									  "layout(isolines, point_mode) in;\n"
22013 									  "\n"
22014 									  "VAR_DEFINITION"
22015 									  "\n"
22016 									  "in  vec4 tcs_tes[];\n"
22017 									  "out vec4 tes_gs;\n"
22018 									  "\n"
22019 									  "void main()\n"
22020 									  "{\n"
22021 									  "    vec4 result = tcs_tes[0];\n"
22022 									  "\n"
22023 									  "VARIABLE_USE"
22024 									  "\n"
22025 									  "    tes_gs += result;\n"
22026 									  "}\n"
22027 									  "\n";
22028 	static const GLchar* vs = "#version 430 core\n"
22029 							  "#extension GL_ARB_enhanced_layouts : require\n"
22030 							  "\n"
22031 							  "in  vec4 in_vs;\n"
22032 							  "out vec4 vs_tcs;\n"
22033 							  "out vec4 tes_gs;\n"
22034 							  "\n"
22035 							  "void main()\n"
22036 							  "{\n"
22037 							  "    vs_tcs = tes_gs = in_vs;\n"
22038 							  "}\n"
22039 							  "\n";
22040 	static const GLchar* vs_tested = "#version 430 core\n"
22041 									 "#extension GL_ARB_enhanced_layouts : require\n"
22042 									 "\n"
22043 									 "VAR_DEFINITION"
22044 									 "\n"
22045 									 "in  vec4 in_vs;\n"
22046 									 "out vec4 vs_tcs;\n"
22047 									 "\n"
22048 									 "void main()\n"
22049 									 "{\n"
22050 									 "    vec4 result = in_vs;\n"
22051 									 "\n"
22052 									 "VARIABLE_USE"
22053 									 "\n"
22054 									 "    vs_tcs += result;\n"
22055 									 "}\n"
22056 									 "\n";
22057 
22058 	std::string			  source;
22059 	Utils::Shader::STAGES test_case = m_test_cases[test_case_index];
22060 
22061 	if (test_case == stage)
22062 	{
22063 		const GLchar* array	= "";
22064 		const GLchar* index	= "";
22065 		size_t		  position = 0;
22066 		size_t		  temp;
22067 		// It is a compile time error to apply xfb_offset to the declaration of an unsized array(GLSL4.5 spec: Page73)
22068 		// change array = "[]" to "[1]"
22069 		switch (stage)
22070 		{
22071 		case Utils::Shader::GEOMETRY:
22072 			source = gs_tested;
22073 			array  = "[1]";
22074 			index  = "[0]";
22075 			break;
22076 /*
22077 			 It is invalid to define transform feedback output in HS
22078 			 */
22079 #if 0
22080 			case Utils::Shader::TESS_CTRL:
22081 			source = tcs_tested;
22082 			array = "[]";
22083 			index = "[gl_InvocationID]";
22084 			break;
22085 #endif
22086 		case Utils::Shader::TESS_EVAL:
22087 			source = tes_tested;
22088 			array  = "[1]";
22089 			index  = "[0]";
22090 			break;
22091 		case Utils::Shader::VERTEX:
22092 			source = vs_tested;
22093 			break;
22094 		default:
22095 			TCU_FAIL("Invalid enum");
22096 		}
22097 
22098 		temp = position;
22099 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
22100 		position = temp;
22101 		Utils::replaceToken("ARRAY", position, array, source);
22102 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
22103 
22104 		Utils::replaceAllTokens("INDEX", index, source);
22105 	}
22106 	else
22107 	{
22108 		switch (test_case)
22109 		{
22110 		case Utils::Shader::GEOMETRY:
22111 			switch (stage)
22112 			{
22113 			case Utils::Shader::VERTEX:
22114 				source = vs;
22115 				break;
22116 			default:
22117 				source = "";
22118 			}
22119 			break;
22120 		case Utils::Shader::TESS_CTRL:
22121 			switch (stage)
22122 			{
22123 			case Utils::Shader::VERTEX:
22124 				source = vs;
22125 				break;
22126 			default:
22127 				source = "";
22128 			}
22129 			break;
22130 		case Utils::Shader::TESS_EVAL:
22131 			switch (stage)
22132 			{
22133 			case Utils::Shader::TESS_CTRL:
22134 				source = tcs;
22135 				break;
22136 			case Utils::Shader::VERTEX:
22137 				source = vs;
22138 				break;
22139 			default:
22140 				source = "";
22141 			}
22142 			break;
22143 		case Utils::Shader::VERTEX:
22144 			source = "";
22145 			break;
22146 		default:
22147 			TCU_FAIL("Invalid enum");
22148 			break;
22149 		}
22150 	}
22151 
22152 	return source;
22153 }
22154 
22155 /** Get description of test case
22156  *
22157  * @param test_case_index Index of test case
22158  *
22159  * @return Test case description
22160  **/
22161 std::string XFBBlockStrideTest::getTestCaseName(GLuint test_case_index)
22162 {
22163 	std::stringstream stream;
22164 
22165 	stream << "Stage: " << Utils::Shader::GetStageName(m_test_cases[test_case_index]);
22166 
22167 	return stream.str();
22168 }
22169 
22170 /** Get number of test cases
22171  *
22172  * @return Number of test cases
22173  **/
22174 GLuint XFBBlockStrideTest::getTestCaseNumber()
22175 {
22176 	return static_cast<GLuint>(m_test_cases.size());
22177 }
22178 
22179 /** Inspects program for xfb stride
22180  *
22181  * @param program Program to query
22182  *
22183  * @return true if query results match expected values, false otherwise
22184  **/
22185 bool XFBBlockStrideTest::inspectProgram(Utils::Program& program)
22186 {
22187 	GLint stride = 0;
22188 
22189 	program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE,
22190 						1 /* buf_size */, &stride);
22191 
22192 	return (128 == stride);
22193 }
22194 
22195 /** Runs test case
22196  *
22197  * @param test_case_index Id of test case
22198  *
22199  * @return true if test case pass, false otherwise
22200  **/
22201 bool XFBBlockStrideTest::testCase(GLuint test_case_index)
22202 {
22203 	const std::string& gs_source = getShaderSource(test_case_index, Utils::Shader::GEOMETRY);
22204 	Utils::Program	 program(m_context);
22205 	const std::string& tcs_source		= getShaderSource(test_case_index, Utils::Shader::TESS_CTRL);
22206 	const std::string& tes_source		= getShaderSource(test_case_index, Utils::Shader::TESS_EVAL);
22207 	bool			   test_case_result = true;
22208 	const std::string& vs_source		= getShaderSource(test_case_index, Utils::Shader::VERTEX);
22209 
22210 	program.Init("" /* cs */, "", gs_source, tcs_source, tes_source, vs_source, true /* separable */);
22211 
22212 	test_case_result = inspectProgram(program);
22213 
22214 	return test_case_result;
22215 }
22216 
22217 /** Prepare all test cases
22218  *
22219  **/
22220 void XFBBlockStrideTest::testInit()
22221 {
22222 	for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
22223 	{
22224 		if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
22225 			(Utils::Shader::FRAGMENT == stage))
22226 		{
22227 			continue;
22228 		}
22229 
22230 		m_test_cases.push_back((Utils::Shader::STAGES)stage);
22231 	}
22232 }
22233 
22234 /** Constructor
22235  *
22236  * @param context Test context
22237  **/
22238 XFBBlockMemberStrideTest::XFBBlockMemberStrideTest(deqp::Context& context)
22239 	: BufferTestBase(context, "xfb_block_member_stride",
22240 					 "Test verifies that xfb_stride qualifier is respected for block member")
22241 {
22242 	/* Nothing to be done here */
22243 }
22244 
22245 /** Get descriptors of buffers necessary for test
22246  *
22247  * @param ignored
22248  * @param out_descriptors Descriptors of buffers used by test
22249  **/
22250 void XFBBlockMemberStrideTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
22251 													bufferDescriptor::Vector& out_descriptors)
22252 {
22253 	const Utils::Type& vec4 = Utils::Type::vec4;
22254 
22255 	/* Test needs single uniform and xfb */
22256 	out_descriptors.resize(2);
22257 
22258 	/* Get references */
22259 	bufferDescriptor& uniform = out_descriptors[0];
22260 	bufferDescriptor& xfb	 = out_descriptors[1];
22261 
22262 	/* Index */
22263 	uniform.m_index = 0;
22264 	xfb.m_index		= 0;
22265 
22266 	/* Target */
22267 	uniform.m_target = Utils::Buffer::Uniform;
22268 	xfb.m_target	 = Utils::Buffer::Transform_feedback;
22269 
22270 	/* Data */
22271 	static const GLuint			vec4_size   = 16;
22272 	const std::vector<GLubyte>& gohan_data  = vec4.GenerateDataPacked();
22273 	const std::vector<GLubyte>& goten_data  = vec4.GenerateDataPacked();
22274 	const std::vector<GLubyte>& chichi_data = vec4.GenerateDataPacked();
22275 
22276 	/* Uniform data */
22277 	uniform.m_initial_data.resize(3 * vec4_size);
22278 	memcpy(&uniform.m_initial_data[0] + 0, &gohan_data[0], vec4_size);
22279 	memcpy(&uniform.m_initial_data[0] + vec4_size, &goten_data[0], vec4_size);
22280 	memcpy(&uniform.m_initial_data[0] + 2 * vec4_size, &chichi_data[0], vec4_size);
22281 
22282 	/* XFB data */
22283 	xfb.m_initial_data.resize(4 * vec4_size);
22284 	xfb.m_expected_data.resize(4 * vec4_size);
22285 
22286 	for (GLuint i = 0; i < 4 * vec4_size; ++i)
22287 	{
22288 		xfb.m_initial_data[i]  = (glw::GLubyte)i;
22289 		xfb.m_expected_data[i] = (glw::GLubyte)i;
22290 	}
22291 
22292 	// the xfb_offset of "chichi" should be 32
22293 	memcpy(&xfb.m_expected_data[0] + 0, &gohan_data[0], vec4_size);
22294 	memcpy(&xfb.m_expected_data[0] + vec4_size, &goten_data[0], vec4_size);
22295 	memcpy(&xfb.m_expected_data[0] + 2 * vec4_size, &chichi_data[0], vec4_size);
22296 }
22297 
22298 /** Get body of main function for given shader stage
22299  *
22300  * @param ignored
22301  * @param stage            Shader stage
22302  * @param out_assignments  Set to empty
22303  * @param out_calculations Set to empty
22304  **/
22305 void XFBBlockMemberStrideTest::getShaderBody(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
22306 											 std::string& out_assignments, std::string& out_calculations)
22307 {
22308 	out_calculations = "";
22309 
22310 	static const GLchar* gs = "    gohan  = uni_gohan;\n"
22311 							  "    goten  = uni_goten;\n"
22312 							  "    chichi = uni_chichi;\n";
22313 	static const GLchar* fs = "    fs_out = gohan + goten + chichi;\n";
22314 
22315 	const GLchar* assignments = "";
22316 	switch (stage)
22317 	{
22318 	case Utils::Shader::FRAGMENT:
22319 		assignments = fs;
22320 		break;
22321 	case Utils::Shader::GEOMETRY:
22322 		assignments = gs;
22323 		break;
22324 	default:
22325 		break;
22326 	}
22327 
22328 	out_assignments = assignments;
22329 }
22330 
22331 /** Get interface of shader
22332  *
22333  * @param ignored
22334  * @param stage            Shader stage
22335  * @param out_interface    Set to ""
22336  **/
22337 void XFBBlockMemberStrideTest::getShaderInterface(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
22338 												  std::string& out_interface)
22339 {
22340 	static const GLchar* gs = "layout (xfb_buffer = 0, xfb_offset = 0) out Goku {\n"
22341 							  "                             vec4 gohan;\n"
22342 							  "    layout (xfb_stride = 48) vec4 goten;\n"
22343 							  "                             vec4 chichi;\n"
22344 							  "};\n"
22345 							  "layout(binding = 0) uniform gs_block {\n"
22346 							  "    vec4 uni_gohan;\n"
22347 							  "    vec4 uni_goten;\n"
22348 							  "    vec4 uni_chichi;\n"
22349 							  "};\n";
22350 	static const GLchar* fs = "in Goku {\n"
22351 							  "    vec4 gohan;\n"
22352 							  "    vec4 goten;\n"
22353 							  "    vec4 chichi;\n"
22354 							  "};\n"
22355 							  "out vec4 fs_out;\n";
22356 
22357 	switch (stage)
22358 	{
22359 	case Utils::Shader::FRAGMENT:
22360 		out_interface = fs;
22361 		break;
22362 	case Utils::Shader::GEOMETRY:
22363 		out_interface = gs;
22364 		break;
22365 	default:
22366 		out_interface = "";
22367 		return;
22368 	}
22369 }
22370 
22371 /** Inspects program to check if all resources are as expected
22372  *
22373  * @param ignored
22374  * @param program    Program instance
22375  * @param out_stream Error message
22376  *
22377  * @return true if everything is ok, false otherwise
22378  **/
22379 bool XFBBlockMemberStrideTest::inspectProgram(GLuint /* test_case_index*/, Utils::Program& program,
22380 											  std::stringstream& out_stream)
22381 {
22382 	const GLuint gohan_id  = program.GetResourceIndex("gohan", GL_TRANSFORM_FEEDBACK_VARYING);
22383 	const GLuint goten_id  = program.GetResourceIndex("goten", GL_TRANSFORM_FEEDBACK_VARYING);
22384 	const GLuint chichi_id = program.GetResourceIndex("chichi", GL_TRANSFORM_FEEDBACK_VARYING);
22385 
22386 	GLint gohan_offset  = 0;
22387 	GLint goten_offset  = 0;
22388 	GLint chichi_offset = 0;
22389 
22390 	program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, gohan_id, GL_OFFSET, 1, &gohan_offset);
22391 	program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, goten_id, GL_OFFSET, 1, &goten_offset);
22392 	program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, chichi_id, GL_OFFSET, 1, &chichi_offset);
22393 
22394 	// the xfb_offset of "chichi" should be 32
22395 	if ((0 != gohan_offset) || (16 != goten_offset) || (32 != chichi_offset))
22396 	{
22397 		out_stream << "Got wrong offset: [" << gohan_offset << ", " << goten_offset << ", " << chichi_offset
22398 				   << "] expected: [0, 16, 32]";
22399 		return false;
22400 	}
22401 
22402 	return true;
22403 }
22404 
22405 /** Constructor
22406  *
22407  * @param context Test framework context
22408  **/
22409 XFBDuplicatedStrideTest::XFBDuplicatedStrideTest(deqp::Context& context)
22410 	: NegativeTestBase(context, "xfb_duplicated_stride",
22411 					   "Test verifies that compiler reports error when conflicting stride qualifiers are used")
22412 {
22413 }
22414 
22415 /** Source for given test case and stage
22416  *
22417  * @param test_case_index Index of test case
22418  * @param stage           Shader stage
22419  *
22420  * @return Shader source
22421  **/
22422 std::string XFBDuplicatedStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
22423 {
22424 	static const GLchar* invalid_var_definition = "const uint valid_stride = 64;\n"
22425 #if DEBUG_NEG_REMOVE_ERROR
22426 												  "const uint conflicting_stride = 64;\n"
22427 #else
22428 												  "const uint conflicting_stride = 128;\n"
22429 #endif /* DEBUG_NEG_REMOVE_ERROR */
22430 												  "\n"
22431 												  "layout (xfb_buffer = 0, xfb_stride = valid_stride)       out;\n"
22432 												  "layout (xfb_buffer = 0, xfb_stride = conflicting_stride) out;\n";
22433 	static const GLchar* valid_var_definition = "const uint valid_stride = 64;\n"
22434 												"\n"
22435 												"layout (xfb_buffer = 0, xfb_stride = valid_stride) out;\n"
22436 												"layout (xfb_buffer = 0, xfb_stride = valid_stride) out;\n";
22437 	static const GLchar* fs = "#version 430 core\n"
22438 							  "#extension GL_ARB_enhanced_layouts : require\n"
22439 							  "\n"
22440 							  "in  vec4 any_fs;\n"
22441 							  "out vec4 fs_out;\n"
22442 							  "\n"
22443 							  "void main()\n"
22444 							  "{\n"
22445 							  "    fs_out = any_fs;\n"
22446 							  "}\n"
22447 							  "\n";
22448 	static const GLchar* gs_tested = "#version 430 core\n"
22449 									 "#extension GL_ARB_enhanced_layouts : require\n"
22450 									 "\n"
22451 									 "layout(points)                           in;\n"
22452 									 "layout(triangle_strip, max_vertices = 4) out;\n"
22453 									 "\n"
22454 									 "VAR_DEFINITION"
22455 									 "\n"
22456 									 "in  vec4 vs_any[];\n"
22457 									 "out vec4 any_fs;\n"
22458 									 "\n"
22459 									 "void main()\n"
22460 									 "{\n"
22461 									 "    vec4 result = vs_any[0];\n"
22462 									 "\n"
22463 									 "    any_fs = result;\n"
22464 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
22465 									 "    EmitVertex();\n"
22466 									 "    any_fs = result;\n"
22467 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
22468 									 "    EmitVertex();\n"
22469 									 "    any_fs = result;\n"
22470 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
22471 									 "    EmitVertex();\n"
22472 									 "    any_fs = result;\n"
22473 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
22474 									 "    EmitVertex();\n"
22475 									 "}\n"
22476 									 "\n";
22477 	static const GLchar* tcs = "#version 430 core\n"
22478 							   "#extension GL_ARB_enhanced_layouts : require\n"
22479 							   "\n"
22480 							   "layout(vertices = 1) out;\n"
22481 							   "\n"
22482 							   "in  vec4 vs_any[];\n"
22483 							   "out vec4 tcs_tes[];\n"
22484 							   "\n"
22485 							   "void main()\n"
22486 							   "{\n"
22487 							   "\n"
22488 							   "    tcs_tes[gl_InvocationID] = vs_any[gl_InvocationID];\n"
22489 							   "\n"
22490 							   "    gl_TessLevelOuter[0] = 1.0;\n"
22491 							   "    gl_TessLevelOuter[1] = 1.0;\n"
22492 							   "    gl_TessLevelOuter[2] = 1.0;\n"
22493 							   "    gl_TessLevelOuter[3] = 1.0;\n"
22494 							   "    gl_TessLevelInner[0] = 1.0;\n"
22495 							   "    gl_TessLevelInner[1] = 1.0;\n"
22496 							   "}\n"
22497 							   "\n";
22498 	static const GLchar* tes_tested = "#version 430 core\n"
22499 									  "#extension GL_ARB_enhanced_layouts : require\n"
22500 									  "\n"
22501 									  "layout(isolines, point_mode) in;\n"
22502 									  "\n"
22503 									  "VAR_DEFINITION"
22504 									  "\n"
22505 									  "in  vec4 tcs_tes[];\n"
22506 									  "out vec4 any_fs;\n"
22507 									  "\n"
22508 									  "void main()\n"
22509 									  "{\n"
22510 									  "    vec4 result = tcs_tes[0];\n"
22511 									  "\n"
22512 									  "    any_fs = result;\n"
22513 									  "}\n"
22514 									  "\n";
22515 	static const GLchar* vs = "#version 430 core\n"
22516 							  "#extension GL_ARB_enhanced_layouts : require\n"
22517 							  "\n"
22518 							  "in  vec4 in_vs;\n"
22519 							  "out vec4 vs_any;\n"
22520 							  "\n"
22521 							  "void main()\n"
22522 							  "{\n"
22523 							  "    vs_any = in_vs;\n"
22524 							  "}\n"
22525 							  "\n";
22526 	static const GLchar* vs_tested = "#version 430 core\n"
22527 									 "#extension GL_ARB_enhanced_layouts : require\n"
22528 									 "\n"
22529 									 "VAR_DEFINITION"
22530 									 "\n"
22531 									 "in  vec4 in_vs;\n"
22532 									 "out vec4 any_fs;\n"
22533 									 "\n"
22534 									 "void main()\n"
22535 									 "{\n"
22536 									 "    vec4 result = in_vs;\n"
22537 									 "\n"
22538 									 "    any_fs += result;\n"
22539 									 "}\n"
22540 									 "\n";
22541 
22542 	std::string source;
22543 	testCase&   test_case = m_test_cases[test_case_index];
22544 
22545 	if (test_case.m_stage == stage)
22546 	{
22547 		size_t		  position		 = 0;
22548 		const GLchar* var_definition = 0;
22549 
22550 		switch (test_case.m_case)
22551 		{
22552 		case VALID:
22553 			var_definition = valid_var_definition;
22554 			break;
22555 		case INVALID:
22556 			var_definition = invalid_var_definition;
22557 			break;
22558 		default:
22559 			TCU_FAIL("Invalid enum");
22560 		}
22561 
22562 		switch (stage)
22563 		{
22564 		case Utils::Shader::GEOMETRY:
22565 			source = gs_tested;
22566 			break;
22567 		case Utils::Shader::TESS_EVAL:
22568 			source = tes_tested;
22569 			break;
22570 		case Utils::Shader::VERTEX:
22571 			source = vs_tested;
22572 			break;
22573 		default:
22574 			TCU_FAIL("Invalid enum");
22575 		}
22576 
22577 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
22578 	}
22579 	else
22580 	{
22581 		switch (test_case.m_stage)
22582 		{
22583 		case Utils::Shader::GEOMETRY:
22584 			switch (stage)
22585 			{
22586 			case Utils::Shader::FRAGMENT:
22587 				source = fs;
22588 				break;
22589 			case Utils::Shader::VERTEX:
22590 				source = vs;
22591 				break;
22592 			default:
22593 				source = "";
22594 			}
22595 			break;
22596 		case Utils::Shader::TESS_EVAL:
22597 			switch (stage)
22598 			{
22599 			case Utils::Shader::FRAGMENT:
22600 				source = fs;
22601 				break;
22602 			case Utils::Shader::TESS_CTRL:
22603 				source = tcs;
22604 				break;
22605 			case Utils::Shader::VERTEX:
22606 				source = vs;
22607 				break;
22608 			default:
22609 				source = "";
22610 			}
22611 			break;
22612 		case Utils::Shader::VERTEX:
22613 			switch (stage)
22614 			{
22615 			case Utils::Shader::FRAGMENT:
22616 				source = fs;
22617 				break;
22618 			default:
22619 				source = "";
22620 			}
22621 			break;
22622 		default:
22623 			TCU_FAIL("Invalid enum");
22624 			break;
22625 		}
22626 	}
22627 
22628 	return source;
22629 }
22630 
22631 /** Get description of test case
22632  *
22633  * @param test_case_index Index of test case
22634  *
22635  * @return Test case description
22636  **/
22637 std::string XFBDuplicatedStrideTest::getTestCaseName(GLuint test_case_index)
22638 {
22639 	std::stringstream stream;
22640 	testCase&		  test_case = m_test_cases[test_case_index];
22641 
22642 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", case: ";
22643 
22644 	switch (test_case.m_case)
22645 	{
22646 	case VALID:
22647 		stream << "valid";
22648 		break;
22649 	case INVALID:
22650 		stream << "invalid";
22651 		break;
22652 	default:
22653 		TCU_FAIL("Invalid enum");
22654 	}
22655 
22656 	return stream.str();
22657 }
22658 
22659 /** Get number of test cases
22660  *
22661  * @return Number of test cases
22662  **/
22663 GLuint XFBDuplicatedStrideTest::getTestCaseNumber()
22664 {
22665 	return static_cast<GLuint>(m_test_cases.size());
22666 }
22667 
22668 /** Selects if "compute" stage is relevant for test
22669  *
22670  * @param ignored
22671  *
22672  * @return false
22673  **/
22674 bool XFBDuplicatedStrideTest::isComputeRelevant(GLuint /* test_case_index */)
22675 {
22676 	return false;
22677 }
22678 
22679 /** Selects if compilation failure is expected result
22680  *
22681  * @param test_case_index Index of test case
22682  *
22683  * @return true
22684  **/
22685 bool XFBDuplicatedStrideTest::isFailureExpected(GLuint test_case_index)
22686 {
22687 	testCase& test_case = m_test_cases[test_case_index];
22688 
22689 	return (INVALID == test_case.m_case);
22690 }
22691 
22692 /** Prepare all test cases
22693  *
22694  **/
22695 void XFBDuplicatedStrideTest::testInit()
22696 {
22697 	for (GLuint c = 0; c < CASE_MAX; ++c)
22698 	{
22699 		for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
22700 		{
22701 			if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
22702 				(Utils::Shader::FRAGMENT == stage))
22703 			{
22704 				continue;
22705 			}
22706 
22707 			testCase test_case = { (CASES)c, (Utils::Shader::STAGES)stage };
22708 
22709 			m_test_cases.push_back(test_case);
22710 		}
22711 	}
22712 }
22713 
22714 /** Constructor
22715  *
22716  * @param context Test framework context
22717  **/
22718 XFBGetProgramResourceAPITest::XFBGetProgramResourceAPITest(deqp::Context& context)
22719 	: TestBase(context, "xfb_get_program_resource_api",
22720 			   "Test verifies that get program resource reports correct results for XFB")
22721 {
22722 }
22723 
22724 /** Source for given test case and stage
22725  *
22726  * @param test_case_index Index of test case
22727  * @param stage           Shader stage
22728  *
22729  * @return Shader source
22730  **/
22731 std::string XFBGetProgramResourceAPITest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
22732 {
22733 	static const GLchar* api_var_definition = "out TYPE b0_v1ARRAY;\n"
22734 											  "out TYPE b1_v1ARRAY;\n"
22735 											  "out TYPE b0_v3ARRAY;\n"
22736 											  "out TYPE b0_v0ARRAY;\n";
22737 	static const GLchar* xfb_var_definition =
22738 		"const uint type_size = SIZE;\n"
22739 		"\n"
22740 		"layout (xfb_buffer = 1, xfb_stride = 4 * type_size) out;\n"
22741 		"\n"
22742 		"layout (xfb_buffer = 0, xfb_offset = 1 * type_size) out TYPE b0_v1ARRAY;\n"
22743 		"layout (xfb_buffer = 1, xfb_offset = 1 * type_size) out TYPE b1_v1ARRAY;\n"
22744 		"layout (xfb_buffer = 0, xfb_offset = 3 * type_size) out TYPE b0_v3ARRAY;\n"
22745 		"layout (xfb_buffer = 0, xfb_offset = 0 * type_size) out TYPE b0_v0ARRAY;\n";
22746 	static const GLchar* var_use = "    b0_v1INDEX = TYPE(0);\n"
22747 								   "    b1_v1INDEX = TYPE(1);\n"
22748 								   "    b0_v3INDEX = TYPE(0);\n"
22749 								   "    b0_v0INDEX = TYPE(1);\n"
22750 								   "    if (vec4(0) == result)\n"
22751 								   "    {\n"
22752 								   "        b0_v1INDEX = TYPE(1);\n"
22753 								   "        b1_v1INDEX = TYPE(0);\n"
22754 								   "        b0_v3INDEX = TYPE(1);\n"
22755 								   "        b0_v0INDEX = TYPE(0);\n"
22756 								   "    }\n";
22757 	static const GLchar* gs_tested =
22758 		"#version 430 core\n"
22759 		"#extension GL_ARB_enhanced_layouts : require\n"
22760 		"\n"
22761 		"layout(points)                           in;\n"
22762 		"layout(triangle_strip, max_vertices = 4) out;\n"
22763 		"\n"
22764 		"VAR_DEFINITION"
22765 		"\n"
22766 		"out gl_PerVertex \n"
22767 		"{ \n"
22768 		"   vec4  gl_Position; \n" // gl_Position must be redeclared in separable program mode
22769 		"}; \n"
22770 		"in  vec4 tes_gs[];\n"
22771 		"out vec4 gs_fs;\n"
22772 		"\n"
22773 		"void main()\n"
22774 		"{\n"
22775 		"    vec4 result = tes_gs[0];\n"
22776 		"\n"
22777 		"VARIABLE_USE"
22778 		"\n"
22779 		"    gs_fs = result;\n"
22780 		"    gl_Position  = vec4(-1, -1, 0, 1);\n"
22781 		"    EmitVertex();\n"
22782 		"    gs_fs = result;\n"
22783 		"    gl_Position  = vec4(-1, 1, 0, 1);\n"
22784 		"    EmitVertex();\n"
22785 		"    gs_fs = result;\n"
22786 		"    gl_Position  = vec4(1, -1, 0, 1);\n"
22787 		"    EmitVertex();\n"
22788 		"    gs_fs = result;\n"
22789 		"    gl_Position  = vec4(1, 1, 0, 1);\n"
22790 		"    EmitVertex();\n"
22791 		"}\n"
22792 		"\n";
22793 #if 0
22794 	static const GLchar* tcs_tested =
22795 		"#version 430 core\n"
22796 		"#extension GL_ARB_enhanced_layouts : require\n"
22797 		"\n"
22798 		"layout(vertices = 1) out;\n"
22799 		"\n"
22800 		"VAR_DEFINITION"
22801 		"\n"
22802 		"in  vec4 vs_tcs[];\n"
22803 		"out vec4 tcs_tes[];\n"
22804 		"\n"
22805 		"void main()\n"
22806 		"{\n"
22807 		"    vec4 result = vs_tcs[gl_InvocationID];\n"
22808 		"\n"
22809 		"VARIABLE_USE"
22810 		"\n"
22811 		"    tcs_tes[gl_InvocationID] = result;\n"
22812 		"\n"
22813 		"    gl_TessLevelOuter[0] = 1.0;\n"
22814 		"    gl_TessLevelOuter[1] = 1.0;\n"
22815 		"    gl_TessLevelOuter[2] = 1.0;\n"
22816 		"    gl_TessLevelOuter[3] = 1.0;\n"
22817 		"    gl_TessLevelInner[0] = 1.0;\n"
22818 		"    gl_TessLevelInner[1] = 1.0;\n"
22819 		"}\n"
22820 		"\n";
22821 #endif
22822 	static const GLchar* tes_tested = "#version 430 core\n"
22823 									  "#extension GL_ARB_enhanced_layouts : require\n"
22824 									  "\n"
22825 									  "layout(isolines, point_mode) in;\n"
22826 									  "\n"
22827 									  "VAR_DEFINITION"
22828 									  "\n"
22829 									  "in  vec4 tcs_tes[];\n"
22830 									  "out vec4 tes_gs;\n"
22831 									  "\n"
22832 									  "void main()\n"
22833 									  "{\n"
22834 									  "    vec4 result = tcs_tes[0];\n"
22835 									  "\n"
22836 									  "VARIABLE_USE"
22837 									  "\n"
22838 									  "    tes_gs = result;\n"
22839 									  "}\n"
22840 									  "\n";
22841 	static const GLchar* vs_tested = "#version 430 core\n"
22842 									 "#extension GL_ARB_enhanced_layouts : require\n"
22843 									 "\n"
22844 									 "VAR_DEFINITION"
22845 									 "\n"
22846 									 "in  vec4 in_vs;\n"
22847 									 "out vec4 vs_tcs;\n"
22848 									 "\n"
22849 									 "void main()\n"
22850 									 "{\n"
22851 									 "    vec4 result = in_vs;\n"
22852 									 "\n"
22853 									 "VARIABLE_USE"
22854 									 "\n"
22855 									 "    vs_tcs = result;\n"
22856 									 "}\n"
22857 									 "\n";
22858 
22859 	std::string		 source;
22860 	const test_Case& test_case = m_test_cases[test_case_index];
22861 
22862 	if (test_case.m_stage == stage)
22863 	{
22864 		const GLchar* array = "";
22865 		GLchar		  buffer[16];
22866 		const GLchar* index	= "";
22867 		size_t		  position = 0;
22868 		size_t		  temp;
22869 		const GLchar* type_name		 = test_case.m_type.GetGLSLTypeName();
22870 		const GLchar* var_definition = 0;
22871 
22872 		sprintf(buffer, "%d", test_case.m_type.GetSize());
22873 
22874 		if (XFB == test_case.m_case)
22875 		{
22876 			var_definition = xfb_var_definition;
22877 		}
22878 		else
22879 		{
22880 			var_definition = api_var_definition;
22881 		}
22882 
22883 		// It is a compile time error to apply xfb_offset to the declaration of an unsized array(GLSL4.5 spec: Page73)
22884 		// change array = "[]" to "[1]"
22885 		switch (stage)
22886 		{
22887 		case Utils::Shader::GEOMETRY:
22888 			source = gs_tested;
22889 			array  = "[1]";
22890 			index  = "[0]";
22891 			break;
22892 // It is invalid to output transform feedback varyings in tessellation control shader
22893 #if 0
22894 		case Utils::Shader::TESS_CTRL:
22895 			source = tcs_tested;
22896 			array = "[]";
22897 			index = "[gl_InvocationID]";
22898 			break;
22899 #endif
22900 		case Utils::Shader::TESS_EVAL:
22901 			source = tes_tested;
22902 			array  = "[1]";
22903 			index  = "[0]";
22904 			break;
22905 		case Utils::Shader::VERTEX:
22906 			source = vs_tested;
22907 			break;
22908 		default:
22909 			TCU_FAIL("Invalid enum");
22910 		}
22911 
22912 		temp = position;
22913 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
22914 		if (XFB == test_case.m_case)
22915 		{
22916 			position = temp;
22917 			Utils::replaceToken("SIZE", position, buffer, source);
22918 		}
22919 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
22920 
22921 		Utils::replaceAllTokens("ARRAY", array, source);
22922 		Utils::replaceAllTokens("INDEX", index, source);
22923 		Utils::replaceAllTokens("TYPE", type_name, source);
22924 	}
22925 	else
22926 	{
22927 		source = "";
22928 	}
22929 
22930 	return source;
22931 }
22932 
22933 /** Get description of test case
22934  *
22935  * @param test_case_index Index of test case
22936  *
22937  * @return Test case description
22938  **/
22939 std::string XFBGetProgramResourceAPITest::getTestCaseName(GLuint test_case_index)
22940 {
22941 	std::stringstream stream;
22942 	const test_Case&  test_case = m_test_cases[test_case_index];
22943 
22944 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
22945 		   << ", type: " << test_case.m_type.GetGLSLTypeName() << ", case: ";
22946 
22947 	switch (test_case.m_case)
22948 	{
22949 	case INTERLEAVED:
22950 		stream << "interleaved";
22951 		break;
22952 	case SEPARATED:
22953 		stream << "separated";
22954 		break;
22955 	case XFB:
22956 		stream << "xfb";
22957 		break;
22958 	default:
22959 		TCU_FAIL("Invalid enum");
22960 	}
22961 
22962 	return stream.str();
22963 }
22964 
22965 /** Get number of test cases
22966  *
22967  * @return Number of test cases
22968  **/
22969 GLuint XFBGetProgramResourceAPITest::getTestCaseNumber()
22970 {
22971 	return static_cast<GLuint>(m_test_cases.size());
22972 }
22973 
22974 /** Inspects program for offset, buffer index, buffer stride and type
22975  *
22976  * @param test_case_index Index of test case
22977  * @param program         Program to query
22978  *
22979  * @return true if query results match expected values, false otherwise
22980  **/
22981 bool XFBGetProgramResourceAPITest::inspectProgram(glw::GLuint test_case_index, Utils::Program& program)
22982 {
22983 	GLint			 b0_stride	= 0;
22984 	GLint			 b1_stride	= 0;
22985 	GLint			 b0_v0_buf	= 0;
22986 	GLint			 b0_v0_offset = 0;
22987 	GLint			 b0_v0_type   = 0;
22988 	GLint			 b0_v1_buf	= 0;
22989 	GLint			 b0_v1_offset = 0;
22990 	GLint			 b0_v1_type   = 0;
22991 	GLint			 b0_v3_buf	= 0;
22992 	GLint			 b0_v3_offset = 0;
22993 	GLint			 b0_v3_type   = 0;
22994 	GLint			 b1_v1_buf	= 0;
22995 	GLint			 b1_v1_offset = 0;
22996 	GLint			 b1_v1_type   = 0;
22997 	const test_Case& test_case	= m_test_cases[test_case_index];
22998 	const GLenum	 type_enum	= test_case.m_type.GetTypeGLenum();
22999 	const GLint		 type_size	= test_case.m_type.GetSize();
23000 
23001 	GLuint b0_v0_index = program.GetResourceIndex("b0_v0", GL_TRANSFORM_FEEDBACK_VARYING);
23002 	GLuint b0_v1_index = program.GetResourceIndex("b0_v1", GL_TRANSFORM_FEEDBACK_VARYING);
23003 	GLuint b0_v3_index = program.GetResourceIndex("b0_v3", GL_TRANSFORM_FEEDBACK_VARYING);
23004 	GLuint b1_v1_index = program.GetResourceIndex("b1_v1", GL_TRANSFORM_FEEDBACK_VARYING);
23005 
23006 	program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v0_index, GL_OFFSET, 1 /* buf_size */, &b0_v0_offset);
23007 	program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v1_index, GL_OFFSET, 1 /* buf_size */, &b0_v1_offset);
23008 	program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v3_index, GL_OFFSET, 1 /* buf_size */, &b0_v3_offset);
23009 	program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b1_v1_index, GL_OFFSET, 1 /* buf_size */, &b1_v1_offset);
23010 
23011 	program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v0_index, GL_TYPE, 1 /* buf_size */, &b0_v0_type);
23012 	program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v1_index, GL_TYPE, 1 /* buf_size */, &b0_v1_type);
23013 	program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v3_index, GL_TYPE, 1 /* buf_size */, &b0_v3_type);
23014 	program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b1_v1_index, GL_TYPE, 1 /* buf_size */, &b1_v1_type);
23015 
23016 	program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v0_index, GL_TRANSFORM_FEEDBACK_BUFFER_INDEX,
23017 						1 /* buf_size */, &b0_v0_buf);
23018 	program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v1_index, GL_TRANSFORM_FEEDBACK_BUFFER_INDEX,
23019 						1 /* buf_size */, &b0_v1_buf);
23020 	program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b0_v3_index, GL_TRANSFORM_FEEDBACK_BUFFER_INDEX,
23021 						1 /* buf_size */, &b0_v3_buf);
23022 	program.GetResource(GL_TRANSFORM_FEEDBACK_VARYING, b1_v1_index, GL_TRANSFORM_FEEDBACK_BUFFER_INDEX,
23023 						1 /* buf_size */, &b1_v1_buf);
23024 
23025 	program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, b0_v0_buf, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE, 1 /* buf_size */,
23026 						&b0_stride);
23027 	program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, b1_v1_buf, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE, 1 /* buf_size */,
23028 						&b1_stride);
23029 
23030 	if (SEPARATED != test_case.m_case)
23031 	{
23032 		return (((GLint)(4 * type_size) == b0_stride) && ((GLint)(4 * type_size) == b1_stride) &&
23033 				((GLint)(0) == b0_v0_buf) && ((GLint)(0 * type_size) == b0_v0_offset) &&
23034 				((GLint)(type_enum) == b0_v0_type) && ((GLint)(0) == b0_v1_buf) &&
23035 				((GLint)(1 * type_size) == b0_v1_offset) && ((GLint)(type_enum) == b0_v1_type) &&
23036 				((GLint)(0) == b0_v3_buf) && ((GLint)(3 * type_size) == b0_v3_offset) &&
23037 				((GLint)(type_enum) == b0_v3_type) && ((GLint)(1) == b1_v1_buf) &&
23038 				((GLint)(1 * type_size) == b1_v1_offset) && ((GLint)(type_enum) == b1_v1_type));
23039 	}
23040 	else
23041 	{
23042 		return (((GLint)(1 * type_size) == b0_stride) && ((GLint)(1 * type_size) == b1_stride) &&
23043 				((GLint)(0) == b0_v0_buf) && ((GLint)(0) == b0_v0_offset) && ((GLint)(type_enum) == b0_v0_type) &&
23044 				((GLint)(1) == b0_v1_buf) && ((GLint)(0) == b0_v1_offset) && ((GLint)(type_enum) == b0_v1_type) &&
23045 				((GLint)(2) == b0_v3_buf) && ((GLint)(0) == b0_v3_offset) && ((GLint)(type_enum) == b0_v3_type) &&
23046 				((GLint)(3) == b1_v1_buf) && ((GLint)(0) == b1_v1_offset) && ((GLint)(type_enum) == b1_v1_type));
23047 	}
23048 }
23049 
23050 /** Insert gl_SkipComponents
23051  *
23052  * @param num_components How many gl_SkipComponents1 need to be inserted
23053  * @param varyings The transform feedback varyings string vector
23054  *
23055  **/
23056 void XFBGetProgramResourceAPITest::insertSkipComponents(int num_components, Utils::Program::NameVector& varyings)
23057 {
23058 	int num_component_4 = num_components / 4;
23059 	int num_component_1 = num_components % 4;
23060 	for (int i = 0; i < num_component_4; i++)
23061 	{
23062 		varyings.push_back("gl_SkipComponents4");
23063 	}
23064 	switch (num_component_1)
23065 	{
23066 	case 1:
23067 		varyings.push_back("gl_SkipComponents1");
23068 		break;
23069 	case 2:
23070 		varyings.push_back("gl_SkipComponents2");
23071 		break;
23072 	case 3:
23073 		varyings.push_back("gl_SkipComponents3");
23074 		break;
23075 	default:
23076 		break;
23077 	}
23078 }
23079 
23080 /** Runs test case
23081  *
23082  * @param test_case_index Id of test case
23083  *
23084  * @return true if test case pass, false otherwise
23085  **/
23086 bool XFBGetProgramResourceAPITest::testCase(GLuint test_case_index)
23087 {
23088 	const std::string& gs_source = getShaderSource(test_case_index, Utils::Shader::GEOMETRY);
23089 	Utils::Program	 program(m_context);
23090 	const std::string& tcs_source		= getShaderSource(test_case_index, Utils::Shader::TESS_CTRL);
23091 	const std::string& tes_source		= getShaderSource(test_case_index, Utils::Shader::TESS_EVAL);
23092 	const test_Case&   test_case		= m_test_cases[test_case_index];
23093 	bool			   test_case_result = true;
23094 	const std::string& vs_source		= getShaderSource(test_case_index, Utils::Shader::VERTEX);
23095 
23096 	// According to spec: gl_SkipComponents1 ~ gl_SkipComponents4 is treated as specifying a one- to four-component floating point output variables with undefined values.
23097 	// No data will be recorded for such strings, but the offset assigned to the next variable in varyings and the stride of the assigned bingding point will be affected.
23098 
23099 	if (INTERLEAVED == test_case.m_case)
23100 	{
23101 		/*
23102 		 layout (xfb_buffer = 0, xfb_offset = 1 * type_size) out type b0_v1;
23103 		 layout (xfb_buffer = 1, xfb_offset = 1 * type_size) out type b1_v1;
23104 		 layout (xfb_buffer = 0, xfb_offset = 3 * type_size) out type b0_v3;
23105 		 layout (xfb_buffer = 0, xfb_offset = 0 * type_size) out type b0_v0;
23106 
23107 		 Note: the type can be float, double, mat2, mat3x2, dmat2, dmat3x2..., so to make the each variable of "captured_varyings" has the same xfb_offset with the above shaders,
23108 		 we need to calculate how many "gl_SkipComponents" need to be inserted.
23109 		 */
23110 		Utils::Program::NameVector captured_varyings;
23111 		captured_varyings.push_back("b0_v0");
23112 		captured_varyings.push_back("b0_v1");
23113 		// Compute how many gl_SkipComponents to be inserted
23114 		int numComponents = test_case.m_type.GetSize() / 4;
23115 		insertSkipComponents(numComponents, captured_varyings);
23116 		captured_varyings.push_back("b0_v3");
23117 		captured_varyings.push_back("gl_NextBuffer");
23118 		insertSkipComponents(numComponents, captured_varyings);
23119 		captured_varyings.push_back("b1_v1");
23120 		insertSkipComponents(numComponents * 2, captured_varyings);
23121 
23122 		program.Init("" /* cs */, "", gs_source, tcs_source, tes_source, vs_source, captured_varyings, true,
23123 					 true /* separable */);
23124 	}
23125 	else if (SEPARATED == test_case.m_case)
23126 	{
23127 		Utils::Program::NameVector captured_varyings;
23128 
23129 		captured_varyings.push_back("b0_v0");
23130 		captured_varyings.push_back("b0_v1");
23131 		captured_varyings.push_back("b0_v3");
23132 		captured_varyings.push_back("b1_v1");
23133 
23134 		program.Init("" /* cs */, "", gs_source, tcs_source, tes_source, vs_source, captured_varyings, false,
23135 					 true /* separable */);
23136 	}
23137 	else
23138 	{
23139 
23140 		program.Init("" /* cs */, "", gs_source, tcs_source, tes_source, vs_source, true /* separable */);
23141 	}
23142 
23143 	test_case_result = inspectProgram(test_case_index, program);
23144 
23145 	return test_case_result;
23146 }
23147 
23148 /** Prepare all test cases
23149  *
23150  **/
23151 void XFBGetProgramResourceAPITest::testInit()
23152 {
23153 	const Functions& gl		 = m_context.getRenderContext().getFunctions();
23154 	const GLuint	 n_types = getTypesNumber();
23155 	GLint			 max_xfb_int;
23156 	GLint			 max_xfb_sep;
23157 
23158 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_xfb_int);
23159 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
23160 
23161 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, &max_xfb_sep);
23162 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
23163 
23164 	GLint max_varyings;
23165 	gl.getIntegerv(GL_MAX_VARYING_COMPONENTS, &max_varyings);
23166 
23167 	for (GLuint i = 0; i < n_types; ++i)
23168 	{
23169 		// When i == 7, the type is dmat4, i == 9 the type is dmat4x3, the number of output components exceeds the maximum value that AMD's driver supported,
23170 		// the MAX_VARYING_COMPONENTS is 32 in our driver, but when the variable type is dmat4 or dmat4x3, the number of output component is 33, to make the
23171 		// shader valid, we can either skip the dmat4, dmat4x3 or query the implementation-dependent value MAX_VARYING_COMPONENTS before generating the shader
23172 		// to guarantee the number of varying not exceeded.
23173 		/*
23174 		 layout (xfb_buffer = 1, xfb_stride = 4 * type_size) out;
23175 		 layout (xfb_buffer = 0, xfb_offset = 1 * type_size) out type b0_v1;
23176 		 layout (xfb_buffer = 1, xfb_offset = 1 * type_size) out type b1_v1;
23177 		 layout (xfb_buffer = 0, xfb_offset = 3 * type_size) out type b0_v3;
23178 		 layout (xfb_buffer = 0, xfb_offset = 0 * type_size) out type b0_v0;
23179 		 in  vec4 in_vs;
23180 		 out vec4 vs_tcs;
23181 		 */
23182 		if (i == 7 || i == 9)
23183 			continue;
23184 		const Utils::Type& type = getType(i);
23185 		if (4 * type.GetNumComponents() + 4 > (GLuint)max_varyings)
23186 		{
23187 			continue;
23188 		}
23189 		for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
23190 		{
23191 			/*
23192 			 It is invalid to define transform feedback output in HS
23193 			 */
23194 			if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
23195 				(Utils::Shader::FRAGMENT == stage))
23196 			{
23197 				continue;
23198 			}
23199 
23200 			test_Case test_case_int = { INTERLEAVED, (Utils::Shader::STAGES)stage, type };
23201 			test_Case test_case_sep = { SEPARATED, (Utils::Shader::STAGES)stage, type };
23202 			test_Case test_case_xfb = { XFB, (Utils::Shader::STAGES)stage, type };
23203 
23204 			if ((int)type.GetSize() <= max_xfb_int)
23205 			{
23206 				m_test_cases.push_back(test_case_xfb);
23207 				m_test_cases.push_back(test_case_int);
23208 			}
23209 
23210 			if ((int)type.GetSize() <= max_xfb_sep)
23211 			{
23212 				m_test_cases.push_back(test_case_sep);
23213 			}
23214 		}
23215 	}
23216 }
23217 
23218 /** Constructor
23219  *
23220  * @param context Test context
23221  **/
23222 XFBOverrideQualifiersWithAPITest::XFBOverrideQualifiersWithAPITest(deqp::Context& context)
23223 	: BufferTestBase(context, "xfb_override_qualifiers_with_api",
23224 					 "Test verifies that xfb_offset qualifier is not overriden with API")
23225 {
23226 	/* Nothing to be done here */
23227 }
23228 
23229 /** Get descriptors of buffers necessary for test
23230  *
23231  * @param test_case_index Index of test case
23232  * @param out_descriptors Descriptors of buffers used by test
23233  **/
23234 void XFBOverrideQualifiersWithAPITest::getBufferDescriptors(glw::GLuint				  test_case_index,
23235 															bufferDescriptor::Vector& out_descriptors)
23236 {
23237 	const Utils::Type& type = getType(test_case_index);
23238 
23239 	/* Test needs single uniform and xfb */
23240 	out_descriptors.resize(2);
23241 
23242 	/* Get references */
23243 	bufferDescriptor& uniform = out_descriptors[0];
23244 	bufferDescriptor& xfb	 = out_descriptors[1];
23245 
23246 	/* Index */
23247 	uniform.m_index = 0;
23248 	xfb.m_index		= 0;
23249 
23250 	/* Target */
23251 	uniform.m_target = Utils::Buffer::Uniform;
23252 	xfb.m_target	 = Utils::Buffer::Transform_feedback;
23253 
23254 	/* Data */
23255 	const GLuint				gen_start   = Utils::s_rand;
23256 	const std::vector<GLubyte>& vegeta_data = type.GenerateData();
23257 	const std::vector<GLubyte>& trunks_data = type.GenerateData();
23258 	const std::vector<GLubyte>& goku_data   = type.GenerateData();
23259 
23260 	Utils::s_rand								= gen_start;
23261 	const std::vector<GLubyte>& vegeta_data_pck = type.GenerateDataPacked();
23262 	type.GenerateDataPacked(); // generate the data for trunks
23263 	const std::vector<GLubyte>& goku_data_pck = type.GenerateDataPacked();
23264 
23265 	const GLuint type_size	 = static_cast<GLuint>(vegeta_data.size());
23266 	const GLuint type_size_pck = static_cast<GLuint>(vegeta_data_pck.size());
23267 
23268 	/* Uniform data */
23269 	uniform.m_initial_data.resize(3 * type_size);
23270 	memcpy(&uniform.m_initial_data[0] + 0, &vegeta_data[0], type_size);
23271 	memcpy(&uniform.m_initial_data[0] + type_size, &trunks_data[0], type_size);
23272 	memcpy(&uniform.m_initial_data[0] + 2 * type_size, &goku_data[0], type_size);
23273 
23274 	/* XFB data */
23275 	xfb.m_initial_data.resize(3 * type_size_pck);
23276 	xfb.m_expected_data.resize(3 * type_size_pck);
23277 
23278 	for (GLuint i = 0; i < 3 * type_size_pck; ++i)
23279 	{
23280 		xfb.m_initial_data[i]  = (glw::GLubyte)i;
23281 		xfb.m_expected_data[i] = (glw::GLubyte)i;
23282 	}
23283 
23284 	memcpy(&xfb.m_expected_data[0] + 0, &goku_data_pck[0], type_size_pck);
23285 	memcpy(&xfb.m_expected_data[0] + 2 * type_size_pck, &vegeta_data_pck[0], type_size_pck);
23286 }
23287 
23288 /** Get list of names of varyings that will be registered with TransformFeedbackVaryings
23289  *
23290  * @param ignored
23291  * @param captured_varyings List of names
23292  **/
23293 void XFBOverrideQualifiersWithAPITest::getCapturedVaryings(glw::GLuint test_case_index,
23294 														   Utils::Program::NameVector& captured_varyings,
23295 														   GLint* xfb_components)
23296 {
23297 	captured_varyings.resize(1);
23298 
23299 	captured_varyings[0] = "trunks";
23300 
23301 	/* The test captures 3 varyings of type 'type' */
23302 	Utils::Type	type		= getType(test_case_index);
23303 	GLint		type_size	= type.GetSize(false);
23304 	*xfb_components			= 3 * type_size / 4;
23305 }
23306 
23307 /** Get body of main function for given shader stage
23308  *
23309  * @param test_case_index  Index of test case
23310  * @param stage            Shader stage
23311  * @param out_assignments  Set to empty
23312  * @param out_calculations Set to empty
23313  **/
23314 void XFBOverrideQualifiersWithAPITest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
23315 													 std::string& out_assignments, std::string& out_calculations)
23316 {
23317 	out_calculations = "";
23318 
23319 	static const GLchar* gs = "    vegeta = uni_vegeta;\n"
23320 							  "    trunks = uni_trunks;\n"
23321 							  "    goku   = uni_goku;\n";
23322 	static const GLchar* fs = "    fs_out = vec4(0);\n"
23323 							  "    if (TYPE(1) == goku + trunks + vegeta)\n"
23324 							  "    {\n"
23325 							  "        fs_out = vec4(1);\n"
23326 							  "    }\n";
23327 
23328 	const GLchar* assignments = "";
23329 	switch (stage)
23330 	{
23331 	case Utils::Shader::FRAGMENT:
23332 		assignments = fs;
23333 		break;
23334 	case Utils::Shader::GEOMETRY:
23335 		assignments = gs;
23336 		break;
23337 	default:
23338 		break;
23339 	}
23340 
23341 	out_assignments = assignments;
23342 
23343 	if (Utils::Shader::FRAGMENT == stage)
23344 	{
23345 		const Utils::Type& type = getType(test_case_index);
23346 
23347 		Utils::replaceAllTokens("TYPE", type.GetGLSLTypeName(), out_assignments);
23348 	}
23349 }
23350 
23351 /** Get interface of shader
23352  *
23353  * @param test_case_index  Index of test case
23354  * @param stage            Shader stage
23355  * @param out_interface    Set to ""
23356  **/
23357 void XFBOverrideQualifiersWithAPITest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
23358 														  std::string& out_interface)
23359 {
23360 	static const GLchar* gs = "const uint sizeof_type = SIZE;\n"
23361 							  "\n"
23362 							  "layout (xfb_offset = 2 * sizeof_type) flat out TYPE vegeta;\n"
23363 							  "                                      flat out TYPE trunks;\n"
23364 							  "layout (xfb_offset = 0)               flat out TYPE goku;\n"
23365 							  "\n"
23366 							  /*
23367 		 There is no packing qualifier for uniform block gs_block, according to spec, it should be "shared" by default,
23368 		 the definition equals to "layout(binding=0, shared)", if the block is declared as shared, each block member will
23369 		 not be packed, and each block member's layout in memory is implementation dependent, so we can't use the API
23370 		 glBufferData() to update the UBO directly, we need to query each block member's offset first, then upload the
23371 		 data to the corresponding offset, otherwise we can't get the correct data from UBO; to make the test passed,
23372 		 we need to add the qualifier std140,  and change the declaration as layout(binding=0, std140), which can make
23373 		 sure all the block members are packed and the application can upload the data by glBufferData() directly.
23374 		 */
23375 							  "layout(binding = 0, std140) uniform gs_block {\n"
23376 							  "    TYPE uni_vegeta;\n"
23377 							  "    TYPE uni_trunks;\n"
23378 							  "    TYPE uni_goku;\n"
23379 							  "};\n";
23380 	static const GLchar* fs = "flat in TYPE vegeta;\n"
23381 							  "flat in TYPE trunks;\n"
23382 							  "flat in TYPE goku;\n"
23383 							  "\n"
23384 							  "out vec4 fs_out;\n";
23385 
23386 	const Utils::Type& type = getType(test_case_index);
23387 
23388 	switch (stage)
23389 	{
23390 	case Utils::Shader::FRAGMENT:
23391 		out_interface = fs;
23392 		break;
23393 	case Utils::Shader::GEOMETRY:
23394 		out_interface = gs;
23395 		break;
23396 	default:
23397 		out_interface = "";
23398 		return;
23399 	}
23400 
23401 	if (Utils::Shader::GEOMETRY == stage)
23402 	{
23403 		GLchar		 buffer[16];
23404 		size_t		 position  = 0;
23405 		const GLuint type_size = type.GetSize();
23406 
23407 		sprintf(buffer, "%d", type_size);
23408 
23409 		Utils::replaceToken("SIZE", position, buffer, out_interface);
23410 	}
23411 
23412 	Utils::replaceAllTokens("TYPE", type.GetGLSLTypeName(), out_interface);
23413 }
23414 
23415 /** Get type name
23416  *
23417  * @param test_case_index Index of test case
23418  *
23419  * @return Name of type test in test_case_index
23420  **/
23421 std::string XFBOverrideQualifiersWithAPITest::getTestCaseName(glw::GLuint test_case_index)
23422 {
23423 	return getTypeName(test_case_index);
23424 }
23425 
23426 /** Returns number of types to test
23427  *
23428  * @return Number of types, 34
23429  **/
23430 glw::GLuint XFBOverrideQualifiersWithAPITest::getTestCaseNumber()
23431 {
23432 	return getTypesNumber();
23433 }
23434 
23435 /** Inspects program to check if all resources are as expected
23436  *
23437  * @param test_case_index Index of test case
23438  * @param program         Program instance
23439  * @param out_stream      Error message
23440  *
23441  * @return true if everything is ok, false otherwise
23442  **/
23443 bool XFBOverrideQualifiersWithAPITest::inspectProgram(GLuint test_case_index, Utils::Program& program,
23444 													  std::stringstream& out_stream)
23445 {
23446 	GLint			   stride	= 0;
23447 	const Utils::Type& type		 = getType(test_case_index);
23448 	const GLuint	   type_size = type.GetSize(false);
23449 
23450 	program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE,
23451 						1 /* buf_size */, &stride);
23452 
23453 	if ((GLint)(3 * type_size) != stride)
23454 	{
23455 		out_stream << "Stride is: " << stride << " expected: " << (3 * type_size);
23456 
23457 		return false;
23458 	}
23459 
23460 	return true;
23461 }
23462 
23463 /** Constructor
23464  *
23465  * @param context Test context
23466  **/
23467 XFBVertexStreamsTest::XFBVertexStreamsTest(deqp::Context& context)
23468 	: BufferTestBase(context, "xfb_vertex_streams",
23469 					 "Test verifies that xfb qualifier works with multiple output streams")
23470 {
23471 	/* Nothing to be done here */
23472 }
23473 
23474 /** Get descriptors of buffers necessary for test
23475  *
23476  * @param ignored
23477  * @param out_descriptors Descriptors of buffers used by test
23478  **/
23479 void XFBVertexStreamsTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
23480 												bufferDescriptor::Vector& out_descriptors)
23481 {
23482 	const Utils::Type& type = Utils::Type::vec4;
23483 
23484 	/* Test needs single uniform and three xfbs */
23485 	out_descriptors.resize(4);
23486 
23487 	/* Get references */
23488 	bufferDescriptor& uniform = out_descriptors[0];
23489 	bufferDescriptor& xfb_1   = out_descriptors[1];
23490 	bufferDescriptor& xfb_2   = out_descriptors[2];
23491 	bufferDescriptor& xfb_3   = out_descriptors[3];
23492 
23493 	/* Index */
23494 	uniform.m_index = 0;
23495 	xfb_1.m_index   = 1;
23496 	xfb_2.m_index   = 2;
23497 	xfb_3.m_index   = 3;
23498 
23499 	/* Target */
23500 	uniform.m_target = Utils::Buffer::Uniform;
23501 	xfb_1.m_target   = Utils::Buffer::Transform_feedback;
23502 	xfb_2.m_target   = Utils::Buffer::Transform_feedback;
23503 	xfb_3.m_target   = Utils::Buffer::Transform_feedback;
23504 
23505 	/* Data */
23506 	const std::vector<GLubyte>& goku_data   = type.GenerateData();
23507 	const std::vector<GLubyte>& gohan_data  = type.GenerateData();
23508 	const std::vector<GLubyte>& goten_data  = type.GenerateData();
23509 	const std::vector<GLubyte>& picolo_data = type.GenerateData();
23510 	const std::vector<GLubyte>& vegeta_data = type.GenerateData();
23511 	const std::vector<GLubyte>& bulma_data  = type.GenerateData();
23512 
23513 	const GLuint type_size = static_cast<GLuint>(vegeta_data.size());
23514 
23515 	/* Uniform data */
23516 	uniform.m_initial_data.resize(6 * type_size);
23517 	memcpy(&uniform.m_initial_data[0] + 0, &goku_data[0], type_size);
23518 	memcpy(&uniform.m_initial_data[0] + type_size, &gohan_data[0], type_size);
23519 	memcpy(&uniform.m_initial_data[0] + 2 * type_size, &goten_data[0], type_size);
23520 	memcpy(&uniform.m_initial_data[0] + 3 * type_size, &picolo_data[0], type_size);
23521 	memcpy(&uniform.m_initial_data[0] + 4 * type_size, &vegeta_data[0], type_size);
23522 	memcpy(&uniform.m_initial_data[0] + 5 * type_size, &bulma_data[0], type_size);
23523 
23524 	/* XFB data */
23525 	static const GLuint xfb_stride = 64;
23526 	xfb_1.m_initial_data.resize(xfb_stride);
23527 	xfb_1.m_expected_data.resize(xfb_stride);
23528 	xfb_2.m_initial_data.resize(xfb_stride);
23529 	xfb_2.m_expected_data.resize(xfb_stride);
23530 	xfb_3.m_initial_data.resize(xfb_stride);
23531 	xfb_3.m_expected_data.resize(xfb_stride);
23532 
23533 	for (GLuint i = 0; i < xfb_stride; ++i)
23534 	{
23535 		xfb_1.m_initial_data[i]  = (glw::GLubyte)i;
23536 		xfb_1.m_expected_data[i] = (glw::GLubyte)i;
23537 		xfb_2.m_initial_data[i]  = (glw::GLubyte)i;
23538 		xfb_2.m_expected_data[i] = (glw::GLubyte)i;
23539 		xfb_3.m_initial_data[i]  = (glw::GLubyte)i;
23540 		xfb_3.m_expected_data[i] = (glw::GLubyte)i;
23541 	}
23542 
23543 	memcpy(&xfb_1.m_expected_data[0] + 48, &goku_data[0], type_size);
23544 	memcpy(&xfb_1.m_expected_data[0] + 32, &gohan_data[0], type_size);
23545 	memcpy(&xfb_1.m_expected_data[0] + 16, &goten_data[0], type_size);
23546 	memcpy(&xfb_3.m_expected_data[0] + 48, &picolo_data[0], type_size);
23547 	memcpy(&xfb_3.m_expected_data[0] + 32, &vegeta_data[0], type_size);
23548 	memcpy(&xfb_2.m_expected_data[0] + 32, &bulma_data[0], type_size);
23549 }
23550 
23551 /** Get body of main function for given shader stage
23552  *
23553  * @param ignored
23554  * @param stage            Shader stage
23555  * @param out_assignments  Set to empty
23556  * @param out_calculations Set to empty
23557  **/
23558 void XFBVertexStreamsTest::getShaderBody(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
23559 										 std::string& out_assignments, std::string& out_calculations)
23560 {
23561 	out_calculations = "";
23562 
23563 	// the shader declares the output variables with different "stream" qualifier, to make the data can export to
23564 	// each stream, we must call the function EmitStreamVertex() and EndStreamPrimitive() to make each vertex emitted
23565 	// by the GS is assigned to specific stream.
23566 	static const GLchar* gs = "    goku   = uni_goku;\n"
23567 							  "    gohan  = uni_gohan;\n"
23568 							  "    goten  = uni_goten;\n"
23569 							  "    EmitStreamVertex(0);\n"
23570 							  "    EndStreamPrimitive(0);\n"
23571 							  "    picolo = uni_picolo;\n"
23572 							  "    vegeta = uni_vegeta;\n"
23573 							  "    EmitStreamVertex(1);\n"
23574 							  "    EndStreamPrimitive(1);\n"
23575 							  "    bulma  = uni_bulma;\n"
23576 							  "    EmitStreamVertex(2);\n"
23577 							  "    EndStreamPrimitive(2);\n";
23578 
23579 	static const GLchar* fs = "    fs_out = gohan + goku + goten;\n";
23580 
23581 	const GLchar* assignments = "";
23582 	switch (stage)
23583 	{
23584 	case Utils::Shader::FRAGMENT:
23585 		assignments = fs;
23586 		break;
23587 	case Utils::Shader::GEOMETRY:
23588 		assignments = gs;
23589 		break;
23590 	default:
23591 		break;
23592 	}
23593 
23594 	out_assignments = assignments;
23595 }
23596 
23597 /** Get interface of shader
23598  *
23599  * @param ignored
23600  * @param stage            Shader stage
23601  * @param out_interface    Set to ""
23602  **/
23603 void XFBVertexStreamsTest::getShaderInterface(GLuint /* test_case_index */, Utils::Shader::STAGES stage,
23604 											  std::string& out_interface)
23605 {
23606 	static const GLchar* gs = "layout (xfb_buffer = 1, xfb_stride = 64) out;\n"
23607 							  "layout (xfb_buffer = 2, xfb_stride = 64) out;\n"
23608 							  "layout (xfb_buffer = 3, xfb_stride = 64) out;\n"
23609 							  "\n"
23610 							  "layout (stream = 0, xfb_buffer = 1, xfb_offset = 48) out vec4 goku;\n"
23611 							  "layout (stream = 0, xfb_buffer = 1, xfb_offset = 32) out vec4 gohan;\n"
23612 							  "layout (stream = 0, xfb_buffer = 1, xfb_offset = 16) out vec4 goten;\n"
23613 							  "layout (stream = 1, xfb_buffer = 3, xfb_offset = 48) out vec4 picolo;\n"
23614 							  "layout (stream = 1, xfb_buffer = 3, xfb_offset = 32) out vec4 vegeta;\n"
23615 							  "layout (stream = 2, xfb_buffer = 2, xfb_offset = 32) out vec4 bulma;\n"
23616 							  "\n"
23617 							  "layout(binding = 0) uniform gs_block {\n"
23618 							  "    vec4 uni_goku;\n"
23619 							  "    vec4 uni_gohan;\n"
23620 							  "    vec4 uni_goten;\n"
23621 							  "    vec4 uni_picolo;\n"
23622 							  "    vec4 uni_vegeta;\n"
23623 							  "    vec4 uni_bulma;\n"
23624 							  "};\n";
23625 	/*
23626 	 Fixed incorrect usage of in/out qualifier, the following variable should be input symbols for fragment shader
23627 	 */
23628 	static const GLchar* fs = "in vec4 goku;\n"
23629 							  "in vec4 gohan;\n"
23630 							  "in vec4 goten;\n"
23631 							  "\n"
23632 							  "out vec4 fs_out;\n";
23633 
23634 	switch (stage)
23635 	{
23636 	case Utils::Shader::FRAGMENT:
23637 		out_interface = fs;
23638 		break;
23639 	case Utils::Shader::GEOMETRY:
23640 		out_interface = gs;
23641 		break;
23642 	default:
23643 		out_interface = "";
23644 		return;
23645 	}
23646 }
23647 
23648 /** Constructor
23649  *
23650  * @param context Test framework context
23651  **/
23652 XFBMultipleVertexStreamsTest::XFBMultipleVertexStreamsTest(deqp::Context& context)
23653 	: NegativeTestBase(
23654 		  context, "xfb_multiple_vertex_streams",
23655 		  "Test verifies that compiler reports error when multiple streams are captured with same xfb_buffer")
23656 {
23657 }
23658 
23659 /** Source for given test case and stage
23660  *
23661  * @param ignored
23662  * @param stage           Shader stage
23663  *
23664  * @return Shader source
23665  **/
23666 std::string XFBMultipleVertexStreamsTest::getShaderSource(GLuint /* test_case_index */, Utils::Shader::STAGES stage)
23667 {
23668 	static const GLchar* var_definition = "const uint valid_stride = 64;\n"
23669 										  "\n"
23670 										  "layout (xfb_buffer = 1, xfb_stride = valid_stride) out;\n"
23671 										  "layout (xfb_buffer = 3, xfb_stride = valid_stride) out;\n"
23672 										  "\n"
23673 										  "\n"
23674 #if DEBUG_NEG_REMOVE_ERROR
23675 										  "layout (stream = 0, xfb_buffer = 1, xfb_offset = 48) out vec4 goku;\n"
23676 										  "layout (stream = 1, xfb_buffer = 3, xfb_offset = 32) out vec4 gohan;\n"
23677 										  "layout (stream = 2, xfb_buffer = 2, xfb_offset = 16) out vec4 goten;\n";
23678 #else
23679 										  "layout (stream = 0, xfb_buffer = 1, xfb_offset = 48) out vec4 goku;\n"
23680 										  "layout (stream = 1, xfb_buffer = 1, xfb_offset = 32) out vec4 gohan;\n"
23681 										  "layout (stream = 2, xfb_buffer = 1, xfb_offset = 16) out vec4 goten;\n";
23682 #endif /* DEBUG_NEG_REMOVE_ERROR */
23683 	static const GLchar* var_use = "    goku  = result / 2;\n"
23684 								   "    gohan = result / 4;\n"
23685 								   "    goten = result / 6;\n";
23686 	static const GLchar* fs = "#version 430 core\n"
23687 							  "#extension GL_ARB_enhanced_layouts : require\n"
23688 							  "\n"
23689 							  "in  vec4 gs_fs;\n"
23690 							  "in  vec4 goku;\n"
23691 							  "out vec4 fs_out;\n"
23692 							  "\n"
23693 							  "void main()\n"
23694 							  "{\n"
23695 							  "    fs_out = gs_fs + goku;\n"
23696 							  "}\n"
23697 							  "\n";
23698 	static const GLchar* gs = "#version 430 core\n"
23699 							  "#extension GL_ARB_enhanced_layouts : require\n"
23700 							  "\n"
23701 							  "layout(points)                           in;\n"
23702 							  "layout(triangle_strip, max_vertices = 4) out;\n"
23703 							  "\n"
23704 							  "VAR_DEFINITION"
23705 							  "\n"
23706 							  "in  vec4 vs_gs[];\n"
23707 							  "out vec4 gs_fs;\n"
23708 							  "\n"
23709 							  "void main()\n"
23710 							  "{\n"
23711 							  "    vec4 result = vs_gs[0];\n"
23712 							  "\n"
23713 							  "VARIABLE_USE"
23714 							  "\n"
23715 							  "    gs_fs = result;\n"
23716 							  "    gl_Position  = vec4(-1, -1, 0, 1);\n"
23717 							  "    EmitVertex();\n"
23718 							  "    gs_fs = result;\n"
23719 							  "    gl_Position  = vec4(-1, 1, 0, 1);\n"
23720 							  "    EmitVertex();\n"
23721 							  "    gs_fs = result;\n"
23722 							  "    gl_Position  = vec4(1, -1, 0, 1);\n"
23723 							  "    EmitVertex();\n"
23724 							  "    gs_fs = result;\n"
23725 							  "    gl_Position  = vec4(1, 1, 0, 1);\n"
23726 							  "    EmitVertex();\n"
23727 							  "}\n"
23728 							  "\n";
23729 	static const GLchar* vs = "#version 430 core\n"
23730 							  "#extension GL_ARB_enhanced_layouts : require\n"
23731 							  "\n"
23732 							  "in  vec4 in_vs;\n"
23733 							  "out vec4 vs_gs;\n"
23734 							  "\n"
23735 							  "void main()\n"
23736 							  "{\n"
23737 							  "    vs_gs = in_vs;\n"
23738 							  "}\n"
23739 							  "\n";
23740 
23741 	std::string source;
23742 
23743 	if (Utils::Shader::GEOMETRY == stage)
23744 	{
23745 		size_t position = 0;
23746 
23747 		source = gs;
23748 
23749 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
23750 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
23751 	}
23752 	else
23753 	{
23754 		switch (stage)
23755 		{
23756 		case Utils::Shader::FRAGMENT:
23757 			source = fs;
23758 			break;
23759 		case Utils::Shader::VERTEX:
23760 			source = vs;
23761 			break;
23762 		default:
23763 			source = "";
23764 		}
23765 	}
23766 
23767 	return source;
23768 }
23769 
23770 /** Selects if "compute" stage is relevant for test
23771  *
23772  * @param ignored
23773  *
23774  * @return false
23775  **/
23776 bool XFBMultipleVertexStreamsTest::isComputeRelevant(GLuint /* test_case_index */)
23777 {
23778 	return false;
23779 }
23780 
23781 /** Constructor
23782  *
23783  * @param context Test framework context
23784  **/
23785 XFBExceedBufferLimitTest::XFBExceedBufferLimitTest(deqp::Context& context)
23786 	: NegativeTestBase(context, "xfb_exceed_buffer_limit",
23787 					   "Test verifies that compiler reports error when xfb_buffer qualifier exceeds limit")
23788 {
23789 }
23790 
23791 /** Source for given test case and stage
23792  *
23793  * @param test_case_index Index of test case
23794  * @param stage           Shader stage
23795  *
23796  * @return Shader source
23797  **/
23798 std::string XFBExceedBufferLimitTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
23799 {
23800 	static const GLchar* block_var_definition = "const uint buffer_index = MAX_BUFFER;\n"
23801 												"\n"
23802 #if DEBUG_NEG_REMOVE_ERROR
23803 												"layout (xfb_buffer = 0, xfb_offset = 0) out Goku {\n"
23804 #else
23805 												"layout (xfb_buffer = buffer_index, xfb_offset = 0) out Goku {\n"
23806 #endif /* DEBUG_NEG_REMOVE_ERROR */
23807 												"    vec4 member;\n"
23808 												"} goku;\n";
23809 	static const GLchar* global_var_definition = "const uint buffer_index = MAX_BUFFER;\n"
23810 												 "\n"
23811 #if DEBUG_NEG_REMOVE_ERROR
23812 												 "layout (xfb_buffer = 0) out;\n";
23813 #else
23814 												 "layout (xfb_buffer = buffer_index) out;\n";
23815 #endif /* DEBUG_NEG_REMOVE_ERROR */
23816 	static const GLchar* vector_var_definition = "const uint buffer_index = MAX_BUFFER;\n"
23817 												 "\n"
23818 #if DEBUG_NEG_REMOVE_ERROR
23819 												 "layout (xfb_buffer = 0) out vec4 goku;\n";
23820 #else
23821 												 "layout (xfb_buffer = buffer_index) out vec4 goku;\n";
23822 #endif /* DEBUG_NEG_REMOVE_ERROR */
23823 	static const GLchar* block_use  = "    goku.member = result / 2;\n";
23824 	static const GLchar* global_use = "";
23825 	static const GLchar* vector_use = "    goku = result / 2;\n";
23826 	static const GLchar* fs			= "#version 430 core\n"
23827 							  "#extension GL_ARB_enhanced_layouts : require\n"
23828 							  "\n"
23829 							  "in  vec4 any_fs;\n"
23830 							  "out vec4 fs_out;\n"
23831 							  "\n"
23832 							  "void main()\n"
23833 							  "{\n"
23834 							  "    fs_out = any_fs;\n"
23835 							  "}\n"
23836 							  "\n";
23837 	static const GLchar* gs_tested = "#version 430 core\n"
23838 									 "#extension GL_ARB_enhanced_layouts : require\n"
23839 									 "\n"
23840 									 "layout(points)                           in;\n"
23841 									 "layout(triangle_strip, max_vertices = 4) out;\n"
23842 									 "\n"
23843 									 "VAR_DEFINITION"
23844 									 "\n"
23845 									 "in  vec4 vs_any[];\n"
23846 									 "out vec4 any_fs;\n"
23847 									 "\n"
23848 									 "void main()\n"
23849 									 "{\n"
23850 									 "    vec4 result = vs_any[0];\n"
23851 									 "\n"
23852 									 "VARIABLE_USE"
23853 									 "\n"
23854 									 "    any_fs = result;\n"
23855 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
23856 									 "    EmitVertex();\n"
23857 									 "    any_fs = result;\n"
23858 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
23859 									 "    EmitVertex();\n"
23860 									 "    any_fs = result;\n"
23861 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
23862 									 "    EmitVertex();\n"
23863 									 "    any_fs = result;\n"
23864 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
23865 									 "    EmitVertex();\n"
23866 									 "}\n"
23867 									 "\n";
23868 	static const GLchar* tcs = "#version 430 core\n"
23869 							   "#extension GL_ARB_enhanced_layouts : require\n"
23870 							   "\n"
23871 							   "layout(vertices = 1) out;\n"
23872 							   "\n"
23873 							   "in  vec4 vs_any[];\n"
23874 							   "out vec4 tcs_tes[];\n"
23875 							   "\n"
23876 							   "void main()\n"
23877 							   "{\n"
23878 							   "\n"
23879 							   "    tcs_tes[gl_InvocationID] = vs_any[gl_InvocationID];\n"
23880 							   "\n"
23881 							   "    gl_TessLevelOuter[0] = 1.0;\n"
23882 							   "    gl_TessLevelOuter[1] = 1.0;\n"
23883 							   "    gl_TessLevelOuter[2] = 1.0;\n"
23884 							   "    gl_TessLevelOuter[3] = 1.0;\n"
23885 							   "    gl_TessLevelInner[0] = 1.0;\n"
23886 							   "    gl_TessLevelInner[1] = 1.0;\n"
23887 							   "}\n"
23888 							   "\n";
23889 	static const GLchar* tes_tested = "#version 430 core\n"
23890 									  "#extension GL_ARB_enhanced_layouts : require\n"
23891 									  "\n"
23892 									  "layout(isolines, point_mode) in;\n"
23893 									  "\n"
23894 									  "VAR_DEFINITION"
23895 									  "\n"
23896 									  "in  vec4 tcs_tes[];\n"
23897 									  "out vec4 any_fs;\n"
23898 									  "\n"
23899 									  "void main()\n"
23900 									  "{\n"
23901 									  "    vec4 result = tcs_tes[0];\n"
23902 									  "\n"
23903 									  "VARIABLE_USE"
23904 									  "\n"
23905 									  "    any_fs += result;\n"
23906 									  "}\n"
23907 									  "\n";
23908 	static const GLchar* vs = "#version 430 core\n"
23909 							  "#extension GL_ARB_enhanced_layouts : require\n"
23910 							  "\n"
23911 							  "in  vec4 in_vs;\n"
23912 							  "out vec4 vs_any;\n"
23913 							  "\n"
23914 							  "void main()\n"
23915 							  "{\n"
23916 							  "    vs_any = in_vs;\n"
23917 							  "}\n"
23918 							  "\n";
23919 	static const GLchar* vs_tested = "#version 430 core\n"
23920 									 "#extension GL_ARB_enhanced_layouts : require\n"
23921 									 "\n"
23922 									 "VAR_DEFINITION"
23923 									 "\n"
23924 									 "in  vec4 in_vs;\n"
23925 									 "out vec4 any_fs;\n"
23926 									 "\n"
23927 									 "void main()\n"
23928 									 "{\n"
23929 									 "    vec4 result = in_vs;\n"
23930 									 "\n"
23931 									 "VARIABLE_USE"
23932 									 "\n"
23933 									 "    any_fs = result;\n"
23934 									 "}\n"
23935 									 "\n";
23936 
23937 	std::string source;
23938 	testCase&   test_case = m_test_cases[test_case_index];
23939 
23940 	if (test_case.m_stage == stage)
23941 	{
23942 		GLchar			 buffer[16];
23943 		const Functions& gl		   = m_context.getRenderContext().getFunctions();
23944 		GLint			 max_n_xfb = 0;
23945 		size_t			 position  = 0;
23946 		const GLchar*	var_definition = 0;
23947 		const GLchar*	var_use		= 0;
23948 
23949 		gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_n_xfb);
23950 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
23951 
23952 		sprintf(buffer, "%d", max_n_xfb);
23953 
23954 		switch (test_case.m_case)
23955 		{
23956 		case BLOCK:
23957 			var_definition = block_var_definition;
23958 			var_use		   = block_use;
23959 			break;
23960 		case GLOBAL:
23961 			var_definition = global_var_definition;
23962 			var_use		   = global_use;
23963 			break;
23964 		case VECTOR:
23965 			var_definition = vector_var_definition;
23966 			var_use		   = vector_use;
23967 			break;
23968 		default:
23969 			TCU_FAIL("Invalid enum");
23970 		}
23971 
23972 		switch (stage)
23973 		{
23974 		case Utils::Shader::GEOMETRY:
23975 			source = gs_tested;
23976 			break;
23977 		case Utils::Shader::TESS_EVAL:
23978 			source = tes_tested;
23979 			break;
23980 		case Utils::Shader::VERTEX:
23981 			source = vs_tested;
23982 			break;
23983 		default:
23984 			TCU_FAIL("Invalid enum");
23985 		}
23986 
23987 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
23988 		position = 0;
23989 		Utils::replaceToken("MAX_BUFFER", position, buffer, source);
23990 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
23991 	}
23992 	else
23993 	{
23994 		switch (test_case.m_stage)
23995 		{
23996 		case Utils::Shader::GEOMETRY:
23997 			switch (stage)
23998 			{
23999 			case Utils::Shader::FRAGMENT:
24000 				source = fs;
24001 				break;
24002 			case Utils::Shader::VERTEX:
24003 				source = vs;
24004 				break;
24005 			default:
24006 				source = "";
24007 			}
24008 			break;
24009 		case Utils::Shader::TESS_EVAL:
24010 			switch (stage)
24011 			{
24012 			case Utils::Shader::FRAGMENT:
24013 				source = fs;
24014 				break;
24015 			case Utils::Shader::TESS_CTRL:
24016 				source = tcs;
24017 				break;
24018 			case Utils::Shader::VERTEX:
24019 				source = vs;
24020 				break;
24021 			default:
24022 				source = "";
24023 			}
24024 			break;
24025 		case Utils::Shader::VERTEX:
24026 			switch (stage)
24027 			{
24028 			case Utils::Shader::FRAGMENT:
24029 				source = fs;
24030 				break;
24031 			default:
24032 				source = "";
24033 			}
24034 			break;
24035 		default:
24036 			TCU_FAIL("Invalid enum");
24037 			break;
24038 		}
24039 	}
24040 
24041 	return source;
24042 }
24043 
24044 /** Get description of test case
24045  *
24046  * @param test_case_index Index of test case
24047  *
24048  * @return Test case description
24049  **/
24050 std::string XFBExceedBufferLimitTest::getTestCaseName(GLuint test_case_index)
24051 {
24052 	std::stringstream stream;
24053 	testCase&		  test_case = m_test_cases[test_case_index];
24054 
24055 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", case: ";
24056 
24057 	switch (test_case.m_case)
24058 	{
24059 	case BLOCK:
24060 		stream << "BLOCK";
24061 		break;
24062 	case GLOBAL:
24063 		stream << "GLOBAL";
24064 		break;
24065 	case VECTOR:
24066 		stream << "VECTOR";
24067 		break;
24068 	default:
24069 		TCU_FAIL("Invalid enum");
24070 	}
24071 
24072 	return stream.str();
24073 }
24074 
24075 /** Get number of test cases
24076  *
24077  * @return Number of test cases
24078  **/
24079 GLuint XFBExceedBufferLimitTest::getTestCaseNumber()
24080 {
24081 	return static_cast<GLuint>(m_test_cases.size());
24082 }
24083 
24084 /** Selects if "compute" stage is relevant for test
24085  *
24086  * @param ignored
24087  *
24088  * @return false
24089  **/
24090 bool XFBExceedBufferLimitTest::isComputeRelevant(GLuint /* test_case_index */)
24091 {
24092 	return false;
24093 }
24094 
24095 /** Prepare all test cases
24096  *
24097  **/
24098 void XFBExceedBufferLimitTest::testInit()
24099 {
24100 	for (GLuint c = 0; c < CASE_MAX; ++c)
24101 	{
24102 		for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
24103 		{
24104 			if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
24105 				(Utils::Shader::FRAGMENT == stage))
24106 			{
24107 				continue;
24108 			}
24109 
24110 			testCase test_case = { (CASES)c, (Utils::Shader::STAGES)stage };
24111 
24112 			m_test_cases.push_back(test_case);
24113 		}
24114 	}
24115 }
24116 
24117 /** Constructor
24118  *
24119  * @param context Test framework context
24120  **/
24121 XFBExceedOffsetLimitTest::XFBExceedOffsetLimitTest(deqp::Context& context)
24122 	: NegativeTestBase(context, "xfb_exceed_offset_limit",
24123 					   "Test verifies that compiler reports error when xfb_offset qualifier exceeds limit")
24124 {
24125 }
24126 
24127 /** Source for given test case and stage
24128  *
24129  * @param test_case_index Index of test case
24130  * @param stage           Shader stage
24131  *
24132  * @return Shader source
24133  **/
24134 std::string XFBExceedOffsetLimitTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
24135 {
24136 	static const GLchar* block_var_definition = "const uint overflow_offset = MAX_SIZE + 16;\n"
24137 												"\n"
24138 #if DEBUG_NEG_REMOVE_ERROR
24139 												"layout (xfb_buffer = 0, xfb_offset = 0) out Goku {\n"
24140 #else
24141 												"layout (xfb_buffer = 0, xfb_offset = overflow_offset + 16) out Goku "
24142 												"{\n"
24143 #endif /* DEBUG_NEG_REMOVE_ERROR */
24144 												"    vec4 member;\n"
24145 												"} goku;\n";
24146 	static const GLchar* global_var_definition = "const uint overflow_offset = MAX_SIZE + 16;\n"
24147 												 "\n"
24148 #if DEBUG_NEG_REMOVE_ERROR
24149 												 "layout (xfb_buffer = 0, xfb_stride = 0) out;\n";
24150 #else
24151 												 "layout (xfb_buffer = 0, xfb_stride = overflow_offset) out;\n";
24152 #endif /* DEBUG_NEG_REMOVE_ERROR */
24153 	static const GLchar* vector_var_definition = "const uint overflow_offset = MAX_SIZE + 16;\n"
24154 												 "\n"
24155 #if DEBUG_NEG_REMOVE_ERROR
24156 												 "layout (xfb_buffer = 0, xfb_offset = 0) out vec4 goku;\n";
24157 #else
24158 												 "layout (xfb_buffer = 0, xfb_offset = overflow_offset) out vec4 "
24159 												 "goku;\n";
24160 #endif /* DEBUG_NEG_REMOVE_ERROR */
24161 	static const GLchar* block_use  = "    goku.member = result / 2;\n";
24162 	static const GLchar* global_use = "";
24163 	static const GLchar* vector_use = "    goku = result / 2;\n";
24164 	static const GLchar* fs			= "#version 430 core\n"
24165 							  "#extension GL_ARB_enhanced_layouts : require\n"
24166 							  "\n"
24167 							  "in  vec4 any_fs;\n"
24168 							  "out vec4 fs_out;\n"
24169 							  "\n"
24170 							  "void main()\n"
24171 							  "{\n"
24172 							  "    fs_out = any_fs;\n"
24173 							  "}\n"
24174 							  "\n";
24175 	static const GLchar* gs_tested = "#version 430 core\n"
24176 									 "#extension GL_ARB_enhanced_layouts : require\n"
24177 									 "\n"
24178 									 "layout(points)                           in;\n"
24179 									 "layout(triangle_strip, max_vertices = 4) out;\n"
24180 									 "\n"
24181 									 "VAR_DEFINITION"
24182 									 "\n"
24183 									 "in  vec4 vs_any[];\n"
24184 									 "out vec4 any_fs;\n"
24185 									 "\n"
24186 									 "void main()\n"
24187 									 "{\n"
24188 									 "    vec4 result = vs_any[0];\n"
24189 									 "\n"
24190 									 "VARIABLE_USE"
24191 									 "\n"
24192 									 "    any_fs = result;\n"
24193 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
24194 									 "    EmitVertex();\n"
24195 									 "    any_fs = result;\n"
24196 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
24197 									 "    EmitVertex();\n"
24198 									 "    any_fs = result;\n"
24199 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
24200 									 "    EmitVertex();\n"
24201 									 "    any_fs = result;\n"
24202 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
24203 									 "    EmitVertex();\n"
24204 									 "}\n"
24205 									 "\n";
24206 	static const GLchar* tcs = "#version 430 core\n"
24207 							   "#extension GL_ARB_enhanced_layouts : require\n"
24208 							   "\n"
24209 							   "layout(vertices = 1) out;\n"
24210 							   "\n"
24211 							   "in  vec4 vs_any[];\n"
24212 							   "out vec4 tcs_tes[];\n"
24213 							   "\n"
24214 							   "void main()\n"
24215 							   "{\n"
24216 							   "\n"
24217 							   "    tcs_tes[gl_InvocationID] = vs_any[gl_InvocationID];\n"
24218 							   "\n"
24219 							   "    gl_TessLevelOuter[0] = 1.0;\n"
24220 							   "    gl_TessLevelOuter[1] = 1.0;\n"
24221 							   "    gl_TessLevelOuter[2] = 1.0;\n"
24222 							   "    gl_TessLevelOuter[3] = 1.0;\n"
24223 							   "    gl_TessLevelInner[0] = 1.0;\n"
24224 							   "    gl_TessLevelInner[1] = 1.0;\n"
24225 							   "}\n"
24226 							   "\n";
24227 	static const GLchar* tes_tested = "#version 430 core\n"
24228 									  "#extension GL_ARB_enhanced_layouts : require\n"
24229 									  "\n"
24230 									  "layout(isolines, point_mode) in;\n"
24231 									  "\n"
24232 									  "VAR_DEFINITION"
24233 									  "\n"
24234 									  "in  vec4 tcs_tes[];\n"
24235 									  "out vec4 any_fs;\n"
24236 									  "\n"
24237 									  "void main()\n"
24238 									  "{\n"
24239 									  "    vec4 result = tcs_tes[0];\n"
24240 									  "\n"
24241 									  "VARIABLE_USE"
24242 									  "\n"
24243 									  "    any_fs += result;\n"
24244 									  "}\n"
24245 									  "\n";
24246 	static const GLchar* vs = "#version 430 core\n"
24247 							  "#extension GL_ARB_enhanced_layouts : require\n"
24248 							  "\n"
24249 							  "in  vec4 in_vs;\n"
24250 							  "out vec4 vs_any;\n"
24251 							  "\n"
24252 							  "void main()\n"
24253 							  "{\n"
24254 							  "    vs_any = in_vs;\n"
24255 							  "}\n"
24256 							  "\n";
24257 	static const GLchar* vs_tested = "#version 430 core\n"
24258 									 "#extension GL_ARB_enhanced_layouts : require\n"
24259 									 "\n"
24260 									 "VAR_DEFINITION"
24261 									 "\n"
24262 									 "in  vec4 in_vs;\n"
24263 									 "out vec4 any_fs;\n"
24264 									 "\n"
24265 									 "void main()\n"
24266 									 "{\n"
24267 									 "    vec4 result = in_vs;\n"
24268 									 "\n"
24269 									 "VARIABLE_USE"
24270 									 "\n"
24271 									 "    any_fs = result;\n"
24272 									 "}\n"
24273 									 "\n";
24274 
24275 	std::string source;
24276 	testCase&   test_case = m_test_cases[test_case_index];
24277 
24278 	if (test_case.m_stage == stage)
24279 	{
24280 		GLchar			 buffer[16];
24281 		const Functions& gl				 = m_context.getRenderContext().getFunctions();
24282 		GLint			 max_n_xfb_comp  = 0;
24283 		GLint			 max_n_xfb_bytes = 0;
24284 		size_t			 position		 = 0;
24285 		const GLchar*	var_definition = 0;
24286 		const GLchar*	var_use		= 0;
24287 
24288 		gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_n_xfb_comp);
24289 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
24290 
24291 		max_n_xfb_bytes = max_n_xfb_comp * 4;
24292 
24293 		sprintf(buffer, "%d", max_n_xfb_bytes);
24294 
24295 		switch (test_case.m_case)
24296 		{
24297 		case BLOCK:
24298 			var_definition = block_var_definition;
24299 			var_use		   = block_use;
24300 			break;
24301 		case GLOBAL:
24302 			var_definition = global_var_definition;
24303 			var_use		   = global_use;
24304 			break;
24305 		case VECTOR:
24306 			var_definition = vector_var_definition;
24307 			var_use		   = vector_use;
24308 			break;
24309 		default:
24310 			TCU_FAIL("Invalid enum");
24311 		}
24312 
24313 		switch (stage)
24314 		{
24315 		case Utils::Shader::GEOMETRY:
24316 			source = gs_tested;
24317 			break;
24318 		case Utils::Shader::TESS_EVAL:
24319 			source = tes_tested;
24320 			break;
24321 		case Utils::Shader::VERTEX:
24322 			source = vs_tested;
24323 			break;
24324 		default:
24325 			TCU_FAIL("Invalid enum");
24326 		}
24327 
24328 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
24329 		position = 0;
24330 		Utils::replaceToken("MAX_SIZE", position, buffer, source);
24331 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
24332 	}
24333 	else
24334 	{
24335 		switch (test_case.m_stage)
24336 		{
24337 		case Utils::Shader::GEOMETRY:
24338 			switch (stage)
24339 			{
24340 			case Utils::Shader::FRAGMENT:
24341 				source = fs;
24342 				break;
24343 			case Utils::Shader::VERTEX:
24344 				source = vs;
24345 				break;
24346 			default:
24347 				source = "";
24348 			}
24349 			break;
24350 		case Utils::Shader::TESS_EVAL:
24351 			switch (stage)
24352 			{
24353 			case Utils::Shader::FRAGMENT:
24354 				source = fs;
24355 				break;
24356 			case Utils::Shader::TESS_CTRL:
24357 				source = tcs;
24358 				break;
24359 			case Utils::Shader::VERTEX:
24360 				source = vs;
24361 				break;
24362 			default:
24363 				source = "";
24364 			}
24365 			break;
24366 		case Utils::Shader::VERTEX:
24367 			switch (stage)
24368 			{
24369 			case Utils::Shader::FRAGMENT:
24370 				source = fs;
24371 				break;
24372 			default:
24373 				source = "";
24374 			}
24375 			break;
24376 		default:
24377 			TCU_FAIL("Invalid enum");
24378 			break;
24379 		}
24380 	}
24381 
24382 	return source;
24383 }
24384 
24385 /** Get description of test case
24386  *
24387  * @param test_case_index Index of test case
24388  *
24389  * @return Test case description
24390  **/
24391 std::string XFBExceedOffsetLimitTest::getTestCaseName(GLuint test_case_index)
24392 {
24393 	std::stringstream stream;
24394 	testCase&		  test_case = m_test_cases[test_case_index];
24395 
24396 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage) << ", case: ";
24397 
24398 	switch (test_case.m_case)
24399 	{
24400 	case BLOCK:
24401 		stream << "BLOCK";
24402 		break;
24403 	case GLOBAL:
24404 		stream << "GLOBAL";
24405 		break;
24406 	case VECTOR:
24407 		stream << "VECTOR";
24408 		break;
24409 	default:
24410 		TCU_FAIL("Invalid enum");
24411 	}
24412 
24413 	return stream.str();
24414 }
24415 
24416 /** Get number of test cases
24417  *
24418  * @return Number of test cases
24419  **/
24420 GLuint XFBExceedOffsetLimitTest::getTestCaseNumber()
24421 {
24422 	return static_cast<GLuint>(m_test_cases.size());
24423 }
24424 
24425 /** Selects if "compute" stage is relevant for test
24426  *
24427  * @param ignored
24428  *
24429  * @return false
24430  **/
24431 bool XFBExceedOffsetLimitTest::isComputeRelevant(GLuint /* test_case_index */)
24432 {
24433 	return false;
24434 }
24435 
24436 /** Prepare all test cases
24437  *
24438  **/
24439 void XFBExceedOffsetLimitTest::testInit()
24440 {
24441 	for (GLuint c = 0; c < CASE_MAX; ++c)
24442 	{
24443 		for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
24444 		{
24445 			if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
24446 				(Utils::Shader::FRAGMENT == stage))
24447 			{
24448 				continue;
24449 			}
24450 
24451 			testCase test_case = { (CASES)c, (Utils::Shader::STAGES)stage };
24452 
24453 			m_test_cases.push_back(test_case);
24454 		}
24455 	}
24456 }
24457 
24458 /** Constructor
24459  *
24460  * @param context Test context
24461  **/
24462 XFBGlobalBufferTest::XFBGlobalBufferTest(deqp::Context& context)
24463 	: BufferTestBase(context, "xfb_global_buffer", "Test verifies that global xfb_buffer qualifier is respected")
24464 {
24465 	/* Nothing to be done here */
24466 }
24467 
24468 /** Get descriptors of buffers necessary for test
24469  *
24470  * @param test_case_index Index of test case
24471  * @param out_descriptors Descriptors of buffers used by test
24472  **/
24473 void XFBGlobalBufferTest::getBufferDescriptors(glw::GLuint test_case_index, bufferDescriptor::Vector& out_descriptors)
24474 {
24475 	// the function "getType(test_case_index)" can't return correct data type, so change code as following:
24476 	const Utils::Type& type = m_test_cases[test_case_index].m_type;
24477 
24478 	/* Test needs single uniform and two xfbs */
24479 	out_descriptors.resize(3);
24480 
24481 	/* Get references */
24482 	bufferDescriptor& uniform = out_descriptors[0];
24483 	bufferDescriptor& xfb_1   = out_descriptors[1];
24484 	bufferDescriptor& xfb_3   = out_descriptors[2];
24485 
24486 	/* Index */
24487 	uniform.m_index = 0;
24488 	xfb_1.m_index   = 1;
24489 	xfb_3.m_index   = 3;
24490 
24491 	/* Target */
24492 	uniform.m_target = Utils::Buffer::Uniform;
24493 	xfb_1.m_target   = Utils::Buffer::Transform_feedback;
24494 	xfb_3.m_target   = Utils::Buffer::Transform_feedback;
24495 
24496 	/* Data */
24497 	const GLuint				gen_start   = Utils::s_rand;
24498 	const std::vector<GLubyte>& chichi_data = type.GenerateData();
24499 	const std::vector<GLubyte>& bulma_data  = type.GenerateData();
24500 	const std::vector<GLubyte>& trunks_data = type.GenerateData();
24501 	const std::vector<GLubyte>& bra_data	= type.GenerateData();
24502 	const std::vector<GLubyte>& gohan_data  = type.GenerateData();
24503 	const std::vector<GLubyte>& goten_data  = type.GenerateData();
24504 
24505 	Utils::s_rand								= gen_start;
24506 	const std::vector<GLubyte>& chichi_data_pck = type.GenerateDataPacked();
24507 	const std::vector<GLubyte>& bulma_data_pck  = type.GenerateDataPacked();
24508 	const std::vector<GLubyte>& trunks_data_pck = type.GenerateDataPacked();
24509 	const std::vector<GLubyte>& bra_data_pck	= type.GenerateDataPacked();
24510 	const std::vector<GLubyte>& gohan_data_pck  = type.GenerateDataPacked();
24511 	const std::vector<GLubyte>& goten_data_pck  = type.GenerateDataPacked();
24512 
24513 	const GLuint type_size	 = static_cast<GLuint>(chichi_data.size());
24514 	const GLuint type_size_pck = static_cast<GLuint>(chichi_data_pck.size());
24515 
24516 	/* Uniform data */
24517 	uniform.m_initial_data.resize(6 * type_size);
24518 	memcpy(&uniform.m_initial_data[0] + 0, &chichi_data[0], type_size);
24519 	memcpy(&uniform.m_initial_data[0] + type_size, &bulma_data[0], type_size);
24520 	memcpy(&uniform.m_initial_data[0] + 2 * type_size, &trunks_data[0], type_size);
24521 	memcpy(&uniform.m_initial_data[0] + 3 * type_size, &bra_data[0], type_size);
24522 	memcpy(&uniform.m_initial_data[0] + 4 * type_size, &gohan_data[0], type_size);
24523 	memcpy(&uniform.m_initial_data[0] + 5 * type_size, &goten_data[0], type_size);
24524 
24525 	/* XFB data */
24526 	xfb_1.m_initial_data.resize(3 * type_size_pck);
24527 	xfb_1.m_expected_data.resize(3 * type_size_pck);
24528 	xfb_3.m_initial_data.resize(3 * type_size_pck);
24529 	xfb_3.m_expected_data.resize(3 * type_size_pck);
24530 
24531 	for (GLuint i = 0; i < 3 * type_size_pck; ++i)
24532 	{
24533 		xfb_1.m_initial_data[i]  = (glw::GLubyte)i;
24534 		xfb_1.m_expected_data[i] = (glw::GLubyte)i;
24535 		xfb_3.m_initial_data[i]  = (glw::GLubyte)i;
24536 		xfb_3.m_expected_data[i] = (glw::GLubyte)i;
24537 	}
24538 
24539 	memcpy(&xfb_3.m_expected_data[0] + 2 * type_size_pck, &chichi_data_pck[0], type_size_pck);
24540 	memcpy(&xfb_1.m_expected_data[0] + 0 * type_size_pck, &bulma_data_pck[0], type_size_pck);
24541 	memcpy(&xfb_1.m_expected_data[0] + 1 * type_size_pck, &trunks_data_pck[0], type_size_pck);
24542 	memcpy(&xfb_1.m_expected_data[0] + 2 * type_size_pck, &bra_data_pck[0], type_size_pck);
24543 	memcpy(&xfb_3.m_expected_data[0] + 0 * type_size_pck, &gohan_data_pck[0], type_size_pck);
24544 	memcpy(&xfb_3.m_expected_data[0] + 1 * type_size_pck, &goten_data_pck[0], type_size_pck);
24545 }
24546 
24547 /** Source for given test case and stage
24548  *
24549  * @param test_case_index Index of test case
24550  * @param stage           Shader stage
24551  *
24552  * @return Shader source
24553  **/
24554 std::string XFBGlobalBufferTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
24555 {
24556 	static const GLchar* fs =
24557 		"#version 430 core\n"
24558 		"#extension GL_ARB_enhanced_layouts : require\n"
24559 		"\n"
24560 		"flat in TYPE chichi;\n"
24561 		"flat in TYPE bulma;\n"
24562 		"in Vegeta {\n"
24563 		"    flat TYPE trunk;\n"
24564 		"    flat TYPE bra;\n"
24565 		"} vegeta;\n"
24566 		"in Goku {\n"
24567 		"    flat TYPE gohan;\n"
24568 		"    flat TYPE goten;\n"
24569 		"} goku;\n"
24570 		"\n"
24571 		"out vec4 fs_out;\n"
24572 		"\n"
24573 		"void main()\n"
24574 		"{\n"
24575 		"    fs_out = vec4(1);\n"
24576 		"    if (TYPE(1) != chichi + bulma + vegeta.trunk + vegeta.bra + goku.gohan + goku.goten)\n"
24577 		"    {\n"
24578 		"        fs_out = vec4(0);\n"
24579 		"    }\n"
24580 		"}\n"
24581 		"\n";
24582 
24583 	static const GLchar* gs = "#version 430 core\n"
24584 							  "#extension GL_ARB_enhanced_layouts : require\n"
24585 							  "\n"
24586 							  "layout(points)                   in;\n"
24587 							  "layout(points, max_vertices = 1) out;\n"
24588 							  "\n"
24589 							  "INTERFACE"
24590 							  "\n"
24591 							  "void main()\n"
24592 							  "{\n"
24593 							  "ASSIGNMENTS"
24594 							  "    EmitVertex();\n"
24595 							  "}\n"
24596 							  "\n";
24597 
24598 	static const GLchar* tcs = "#version 430 core\n"
24599 							   "#extension GL_ARB_enhanced_layouts : require\n"
24600 							   "\n"
24601 							   "layout(vertices = 1) out;\n"
24602 							   "\n"
24603 							   "\n"
24604 							   "void main()\n"
24605 							   "{\n"
24606 							   "    gl_TessLevelOuter[0] = 1.0;\n"
24607 							   "    gl_TessLevelOuter[1] = 1.0;\n"
24608 							   "    gl_TessLevelOuter[2] = 1.0;\n"
24609 							   "    gl_TessLevelOuter[3] = 1.0;\n"
24610 							   "    gl_TessLevelInner[0] = 1.0;\n"
24611 							   "    gl_TessLevelInner[1] = 1.0;\n"
24612 							   "}\n"
24613 							   "\n";
24614 
24615 	static const GLchar* tes = "#version 430 core\n"
24616 							   "#extension GL_ARB_enhanced_layouts : require\n"
24617 							   "\n"
24618 							   "layout(isolines, point_mode) in;\n"
24619 							   "\n"
24620 							   "INTERFACE"
24621 							   "\n"
24622 							   "void main()\n"
24623 							   "{\n"
24624 							   "ASSIGNMENTS"
24625 							   "}\n"
24626 							   "\n";
24627 
24628 	static const GLchar* vs = "#version 430 core\n"
24629 							  "#extension GL_ARB_enhanced_layouts : require\n"
24630 							  "\n"
24631 							  "void main()\n"
24632 							  "{\n"
24633 							  "}\n"
24634 							  "\n";
24635 
24636 	static const GLchar* vs_tested = "#version 430 core\n"
24637 									 "#extension GL_ARB_enhanced_layouts : require\n"
24638 									 "\n"
24639 									 "INTERFACE"
24640 									 "\n"
24641 									 "void main()\n"
24642 									 "{\n"
24643 									 "ASSIGNMENTS"
24644 									 "}\n"
24645 									 "\n";
24646 
24647 	std::string		 source;
24648 	const _testCase& test_case = m_test_cases[test_case_index];
24649 	const GLchar*	type_name = test_case.m_type.GetGLSLTypeName();
24650 
24651 	if (test_case.m_stage == stage)
24652 	{
24653 		std::string assignments = "    chichi       = uni_chichi;\n"
24654 								  "    bulma        = uni_bulma;\n"
24655 								  "    vegeta.trunk = uni_trunk;\n"
24656 								  "    vegeta.bra   = uni_bra;\n"
24657 								  "    goku.gohan   = uni_gohan;\n"
24658 								  "    goku.goten   = uni_goten;\n";
24659 
24660 		std::string interface = "layout (xfb_buffer = 3) out;\n"
24661 								"\n"
24662 								"const uint type_size = SIZE;\n"
24663 								"\n"
24664 								"layout (                xfb_offset = 2 * type_size) flat out TYPE chichi;\n"
24665 								"layout (xfb_buffer = 1, xfb_offset = 0)             flat out TYPE bulma;\n"
24666 								"layout (xfb_buffer = 1, xfb_offset = 1 * type_size) out Vegeta {\n"
24667 								"    flat TYPE trunk;\n"
24668 								"    flat TYPE bra;\n"
24669 								"} vegeta;\n"
24670 								"layout (                xfb_offset = 0)             out Goku {\n"
24671 								"    flat TYPE gohan;\n"
24672 								"    flat TYPE goten;\n"
24673 								"} goku;\n"
24674 								"\n"
24675 								// Uniform block must be declared with std140, otherwise each block member is not packed
24676 								"layout(binding = 0, std140) uniform block {\n"
24677 								"    TYPE uni_chichi;\n"
24678 								"    TYPE uni_bulma;\n"
24679 								"    TYPE uni_trunk;\n"
24680 								"    TYPE uni_bra;\n"
24681 								"    TYPE uni_gohan;\n"
24682 								"    TYPE uni_goten;\n"
24683 								"};\n";
24684 
24685 		/* Prepare interface string */
24686 		{
24687 			GLchar		 buffer[16];
24688 			size_t		 position  = 0;
24689 			const GLuint type_size = test_case.m_type.GetSize();
24690 
24691 			sprintf(buffer, "%d", type_size);
24692 
24693 			Utils::replaceToken("SIZE", position, buffer, interface);
24694 			Utils::replaceAllTokens("TYPE", type_name, interface);
24695 		}
24696 
24697 		switch (stage)
24698 		{
24699 		case Utils::Shader::GEOMETRY:
24700 			source = gs;
24701 			break;
24702 		case Utils::Shader::TESS_EVAL:
24703 			source = tes;
24704 			break;
24705 		case Utils::Shader::VERTEX:
24706 			source = vs_tested;
24707 			break;
24708 		default:
24709 			TCU_FAIL("Invalid enum");
24710 		}
24711 
24712 		/* Replace tokens */
24713 		{
24714 			size_t position = 0;
24715 
24716 			Utils::replaceToken("INTERFACE", position, interface.c_str(), source);
24717 			Utils::replaceToken("ASSIGNMENTS", position, assignments.c_str(), source);
24718 		}
24719 	}
24720 	else
24721 	{
24722 		switch (test_case.m_stage)
24723 		{
24724 		case Utils::Shader::GEOMETRY:
24725 			switch (stage)
24726 			{
24727 			case Utils::Shader::FRAGMENT:
24728 				source = fs;
24729 				Utils::replaceAllTokens("TYPE", type_name, source);
24730 				break;
24731 			case Utils::Shader::VERTEX:
24732 				source = vs;
24733 				break;
24734 			default:
24735 				source = "";
24736 			}
24737 			break;
24738 		case Utils::Shader::TESS_EVAL:
24739 			switch (stage)
24740 			{
24741 			case Utils::Shader::FRAGMENT:
24742 				source = fs;
24743 				Utils::replaceAllTokens("TYPE", type_name, source);
24744 				break;
24745 			case Utils::Shader::TESS_CTRL:
24746 				source = tcs;
24747 				break;
24748 			case Utils::Shader::VERTEX:
24749 				source = vs;
24750 				break;
24751 			default:
24752 				source = "";
24753 			}
24754 			break;
24755 		case Utils::Shader::VERTEX:
24756 			switch (stage)
24757 			{
24758 			case Utils::Shader::FRAGMENT:
24759 				source = fs;
24760 				Utils::replaceAllTokens("TYPE", type_name, source);
24761 				break;
24762 			default:
24763 				source = "";
24764 			}
24765 			break;
24766 		default:
24767 			TCU_FAIL("Invalid enum");
24768 			break;
24769 		}
24770 	}
24771 
24772 	return source;
24773 }
24774 
24775 /** Get name of test case
24776  *
24777  * @param test_case_index Index of test case
24778  *
24779  * @return Name of case
24780  **/
24781 std::string XFBGlobalBufferTest::getTestCaseName(GLuint test_case_index)
24782 {
24783 	std::string		 name;
24784 	const _testCase& test_case = m_test_cases[test_case_index];
24785 
24786 	name = "Tested stage: ";
24787 	name.append(Utils::Shader::GetStageName(test_case.m_stage));
24788 	name.append(". Tested type: ");
24789 	name.append(test_case.m_type.GetGLSLTypeName());
24790 
24791 	return name;
24792 }
24793 
24794 /** Get number of cases
24795  *
24796  * @return Number of test cases
24797  **/
24798 GLuint XFBGlobalBufferTest::getTestCaseNumber()
24799 {
24800 	return static_cast<GLuint>(m_test_cases.size());
24801 }
24802 
24803 /** Prepare set of test cases
24804  *
24805  **/
24806 void XFBGlobalBufferTest::testInit()
24807 {
24808 	GLuint n_types = getTypesNumber();
24809 
24810 	for (GLuint i = 0; i < n_types; ++i)
24811 	{
24812 		const Utils::Type& type = getType(i);
24813 		/*
24814 		 When the tfx varying is the following type, the number of output exceeds the gl_MaxVaryingComponents, which will
24815 		 cause a link time error.
24816 		 */
24817 		if (strcmp(type.GetGLSLTypeName(), "dmat3") == 0 || strcmp(type.GetGLSLTypeName(), "dmat4") == 0 ||
24818 			strcmp(type.GetGLSLTypeName(), "dmat3x4") == 0 || strcmp(type.GetGLSLTypeName(), "dmat4x3") == 0)
24819 		{
24820 			continue;
24821 		}
24822 		const _testCase test_cases[] = { { Utils::Shader::VERTEX, type },
24823 										 { Utils::Shader::GEOMETRY, type },
24824 										 { Utils::Shader::TESS_EVAL, type } };
24825 
24826 		m_test_cases.push_back(test_cases[0]);
24827 		m_test_cases.push_back(test_cases[1]);
24828 		m_test_cases.push_back(test_cases[2]);
24829 	}
24830 }
24831 
24832 /** Constructor
24833  *
24834  * @param context Test context
24835  **/
24836 XFBStrideTest::XFBStrideTest(deqp::Context& context)
24837 	: BufferTestBase(context, "xfb_stride", "Test verifies that correct stride is used for all types")
24838 {
24839 	/* Nothing to be done here */
24840 }
24841 
24842 /** Execute drawArrays for single vertex
24843  *
24844  * @param test_case_index
24845  *
24846  * @return true
24847  **/
24848 bool XFBStrideTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
24849 {
24850 	const Functions& gl				= m_context.getRenderContext().getFunctions();
24851 	GLenum			 primitive_type = GL_PATCHES;
24852 	const testCase&  test_case		= m_test_cases[test_case_index];
24853 
24854 	if (Utils::Shader::VERTEX == test_case.m_stage)
24855 	{
24856 		primitive_type = GL_POINTS;
24857 	}
24858 
24859 	gl.disable(GL_RASTERIZER_DISCARD);
24860 	GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
24861 
24862 	gl.beginTransformFeedback(GL_POINTS);
24863 	GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
24864 
24865 	gl.drawArrays(primitive_type, 0 /* first */, 2 /* count */);
24866 	GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
24867 
24868 	gl.endTransformFeedback();
24869 	GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
24870 
24871 	return true;
24872 }
24873 
24874 /** Get descriptors of buffers necessary for test
24875  *
24876  * @param test_case_index Index of test case
24877  * @param out_descriptors Descriptors of buffers used by test
24878  **/
24879 void XFBStrideTest::getBufferDescriptors(GLuint test_case_index, bufferDescriptor::Vector& out_descriptors)
24880 {
24881 	const testCase&	test_case = m_test_cases[test_case_index];
24882 	const Utils::Type& type		 = test_case.m_type;
24883 
24884 	/* Test needs single uniform and xfb */
24885 	out_descriptors.resize(2);
24886 
24887 	/* Get references */
24888 	bufferDescriptor& uniform = out_descriptors[0];
24889 	bufferDescriptor& xfb	 = out_descriptors[1];
24890 
24891 	/* Index */
24892 	uniform.m_index = 0;
24893 	xfb.m_index		= 0;
24894 
24895 	/* Target */
24896 	uniform.m_target = Utils::Buffer::Uniform;
24897 	xfb.m_target	 = Utils::Buffer::Transform_feedback;
24898 
24899 	/* Data */
24900 	const GLuint				rand_start   = Utils::s_rand;
24901 	const std::vector<GLubyte>& uniform_data = type.GenerateData();
24902 
24903 	Utils::s_rand						 = rand_start;
24904 	const std::vector<GLubyte>& xfb_data = type.GenerateDataPacked();
24905 
24906 	const GLuint uni_type_size = static_cast<GLuint>(uniform_data.size());
24907 	const GLuint xfb_type_size = static_cast<GLuint>(xfb_data.size());
24908 	/*
24909 	 Note: If xfb varying output from vertex shader, the variable "goku" will only output once to transform feedback buffer,
24910 	 if xfb varying output from TES or GS, because the input primitive type in TES is defined as "layout(isolines, point_mode) in;",
24911 	 the primitive type is line which make the variable "goku" will output twice to transform feedback buffer, so for vertex shader
24912 	 only one valid data should be initialized in xfb.m_expected_data
24913 	 */
24914 	const GLuint xfb_data_size = (test_case.m_stage == Utils::Shader::VERTEX) ? xfb_type_size : xfb_type_size * 2;
24915 	/* Uniform data */
24916 	uniform.m_initial_data.resize(uni_type_size);
24917 	memcpy(&uniform.m_initial_data[0] + 0 * uni_type_size, &uniform_data[0], uni_type_size);
24918 
24919 	/* XFB data */
24920 	xfb.m_initial_data.resize(xfb_data_size);
24921 	xfb.m_expected_data.resize(xfb_data_size);
24922 
24923 	for (GLuint i = 0; i < xfb_data_size; ++i)
24924 	{
24925 		xfb.m_initial_data[i]  = (glw::GLubyte)i;
24926 		xfb.m_expected_data[i] = (glw::GLubyte)i;
24927 	}
24928 
24929 	if (test_case.m_stage == Utils::Shader::VERTEX)
24930 	{
24931 		memcpy(&xfb.m_expected_data[0] + 0 * xfb_type_size, &xfb_data[0], xfb_type_size);
24932 	}
24933 	else
24934 	{
24935 		memcpy(&xfb.m_expected_data[0] + 0 * xfb_type_size, &xfb_data[0], xfb_type_size);
24936 		memcpy(&xfb.m_expected_data[0] + 1 * xfb_type_size, &xfb_data[0], xfb_type_size);
24937 	}
24938 }
24939 
24940 /** Get body of main function for given shader stage
24941  *
24942  * @param test_case_index  Index of test case
24943  * @param stage            Shader stage
24944  * @param out_assignments  Set to empty
24945  * @param out_calculations Set to empty
24946  **/
24947 void XFBStrideTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage, std::string& out_assignments,
24948 								  std::string& out_calculations)
24949 {
24950 	const testCase& test_case = m_test_cases[test_case_index];
24951 
24952 	out_calculations = "";
24953 
24954 	static const GLchar* vs_tes_gs = "    goku = uni_goku;\n";
24955 	static const GLchar* fs		   = "    fs_out = vec4(1, 0.25, 0.5, 0.75);\n"
24956 							  "    if (TYPE(0) == goku)\n"
24957 							  "    {\n"
24958 							  "         fs_out = vec4(1, 0.75, 0.5, 0.5);\n"
24959 							  "    }\n";
24960 
24961 	const GLchar* assignments = "";
24962 
24963 	if (test_case.m_stage == stage)
24964 	{
24965 		switch (stage)
24966 		{
24967 		case Utils::Shader::GEOMETRY:
24968 			assignments = vs_tes_gs;
24969 			break;
24970 		case Utils::Shader::TESS_EVAL:
24971 			assignments = vs_tes_gs;
24972 			break;
24973 		case Utils::Shader::VERTEX:
24974 			assignments = vs_tes_gs;
24975 			break;
24976 		default:
24977 			TCU_FAIL("Invalid enum");
24978 		}
24979 	}
24980 	else
24981 	{
24982 		switch (stage)
24983 		{
24984 		case Utils::Shader::FRAGMENT:
24985 			assignments = fs;
24986 			break;
24987 		case Utils::Shader::GEOMETRY:
24988 		case Utils::Shader::TESS_CTRL:
24989 		case Utils::Shader::TESS_EVAL:
24990 		case Utils::Shader::VERTEX:
24991 			break;
24992 		default:
24993 			TCU_FAIL("Invalid enum");
24994 		}
24995 	}
24996 
24997 	out_assignments = assignments;
24998 
24999 	if (Utils::Shader::FRAGMENT == stage)
25000 	{
25001 		Utils::replaceAllTokens("TYPE", test_case.m_type.GetGLSLTypeName(), out_assignments);
25002 	}
25003 }
25004 
25005 /** Get interface of shader
25006  *
25007  * @param test_case_index  Index of test case
25008  * @param stage            Shader stage
25009  * @param out_interface    Set to ""
25010  **/
25011 void XFBStrideTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage, std::string& out_interface)
25012 {
25013 	static const GLchar* vs_tes_gs = "layout (xfb_offset = 0) FLAT out TYPE goku;\n"
25014 									 "\n"
25015 									 "layout(std140, binding = 0) uniform Goku {\n"
25016 									 "    TYPE uni_goku;\n"
25017 									 "};\n";
25018 	static const GLchar* fs = "FLAT in TYPE goku;\n"
25019 							  "\n"
25020 							  "out vec4 fs_out;\n";
25021 
25022 	const testCase& test_case = m_test_cases[test_case_index];
25023 	const GLchar*   interface = "";
25024 	const GLchar*   flat	  = "";
25025 
25026 	if (test_case.m_stage == stage)
25027 	{
25028 		switch (stage)
25029 		{
25030 		case Utils::Shader::GEOMETRY:
25031 			interface = vs_tes_gs;
25032 			break;
25033 		case Utils::Shader::TESS_EVAL:
25034 			interface = vs_tes_gs;
25035 			break;
25036 		case Utils::Shader::VERTEX:
25037 			interface = vs_tes_gs;
25038 			break;
25039 		default:
25040 			TCU_FAIL("Invalid enum");
25041 		}
25042 	}
25043 	else
25044 	{
25045 		switch (stage)
25046 		{
25047 		case Utils::Shader::FRAGMENT:
25048 			interface = fs;
25049 			break;
25050 		case Utils::Shader::GEOMETRY:
25051 		case Utils::Shader::TESS_CTRL:
25052 		case Utils::Shader::TESS_EVAL:
25053 		case Utils::Shader::VERTEX:
25054 			break;
25055 		default:
25056 			TCU_FAIL("Invalid enum");
25057 		}
25058 	}
25059 
25060 	out_interface = interface;
25061 
25062 	if (Utils::Type::Float != test_case.m_type.m_basic_type)
25063 	{
25064 		flat = "flat";
25065 	}
25066 
25067 	Utils::replaceAllTokens("FLAT", flat, out_interface);
25068 	Utils::replaceAllTokens("TYPE", test_case.m_type.GetGLSLTypeName(), out_interface);
25069 }
25070 
25071 /** Get source code of shader
25072  *
25073  * @param test_case_index Index of test case
25074  * @param stage           Shader stage
25075  *
25076  * @return Source
25077  **/
25078 std::string XFBStrideTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
25079 {
25080 	std::string		source;
25081 	const testCase& test_case = m_test_cases[test_case_index];
25082 
25083 	switch (test_case.m_stage)
25084 	{
25085 	case Utils::Shader::VERTEX:
25086 		switch (stage)
25087 		{
25088 		case Utils::Shader::FRAGMENT:
25089 		case Utils::Shader::VERTEX:
25090 			source = BufferTestBase::getShaderSource(test_case_index, stage);
25091 			break;
25092 		default:
25093 			break;
25094 		}
25095 		break;
25096 
25097 	case Utils::Shader::TESS_EVAL:
25098 		switch (stage)
25099 		{
25100 		case Utils::Shader::FRAGMENT:
25101 		case Utils::Shader::TESS_CTRL:
25102 		case Utils::Shader::TESS_EVAL:
25103 		case Utils::Shader::VERTEX:
25104 			source = BufferTestBase::getShaderSource(test_case_index, stage);
25105 			break;
25106 		default:
25107 			break;
25108 		}
25109 		break;
25110 
25111 	case Utils::Shader::GEOMETRY:
25112 		source = BufferTestBase::getShaderSource(test_case_index, stage);
25113 		break;
25114 
25115 	default:
25116 		TCU_FAIL("Invalid enum");
25117 		break;
25118 	}
25119 
25120 	/* */
25121 	return source;
25122 }
25123 
25124 /** Get name of test case
25125  *
25126  * @param test_case_index Index of test case
25127  *
25128  * @return Name of tested stage
25129  **/
25130 std::string XFBStrideTest::getTestCaseName(glw::GLuint test_case_index)
25131 {
25132 	std::stringstream stream;
25133 	const testCase&   test_case = m_test_cases[test_case_index];
25134 
25135 	stream << "Type: " << test_case.m_type.GetGLSLTypeName()
25136 		   << ", stage: " << Utils::Shader::GetStageName(test_case.m_stage);
25137 
25138 	return stream.str();
25139 }
25140 
25141 /** Returns number of test cases
25142  *
25143  * @return TEST_MAX
25144  **/
25145 glw::GLuint XFBStrideTest::getTestCaseNumber()
25146 {
25147 	return static_cast<GLuint>(m_test_cases.size());
25148 }
25149 
25150 /** Prepare all test cases
25151  *
25152  **/
25153 void XFBStrideTest::testInit()
25154 {
25155 	const GLuint n_types = getTypesNumber();
25156 
25157 	for (GLuint i = 0; i < n_types; ++i)
25158 	{
25159 		const Utils::Type& type = getType(i);
25160 
25161 		for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
25162 		{
25163 			if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::FRAGMENT == stage) ||
25164 				(Utils::Shader::TESS_CTRL == stage))
25165 			{
25166 				continue;
25167 			}
25168 
25169 			testCase test_case = { (Utils::Shader::STAGES)stage, type };
25170 
25171 			m_test_cases.push_back(test_case);
25172 		}
25173 	}
25174 }
25175 
25176 /** Constructor
25177  *
25178  * @param context Test framework context
25179  **/
25180 XFBBlockMemberBufferTest::XFBBlockMemberBufferTest(deqp::Context& context)
25181 	: NegativeTestBase(
25182 		  context, "xfb_block_member_buffer",
25183 		  "Test verifies that compiler reports error when block member has different xfb_buffer qualifier than buffer")
25184 {
25185 }
25186 
25187 /** Source for given test case and stage
25188  *
25189  * @param test_case_index Index of test case
25190  * @param stage           Shader stage
25191  *
25192  * @return Shader source
25193  **/
25194 std::string XFBBlockMemberBufferTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
25195 {
25196 	static const GLchar* var_definition = "layout (xfb_offset = 0) out Goku {\n"
25197 										  "                            vec4 gohan;\n"
25198 #if DEBUG_NEG_REMOVE_ERROR
25199 										  "    /* layout (xfb_buffer = 1) */ vec4 goten;\n"
25200 #else
25201 										  "    layout (xfb_buffer = 1) vec4 goten;\n"
25202 #endif /* DEBUG_NEG_REMOVE_ERROR */
25203 										  "} goku;\n";
25204 	static const GLchar* var_use = "    goku.gohan = result / 2;\n"
25205 								   "    goku.goten = result / 4;\n";
25206 	static const GLchar* fs = "#version 430 core\n"
25207 							  "#extension GL_ARB_enhanced_layouts : require\n"
25208 							  "\n"
25209 							  "in  vec4 any_fs;\n"
25210 							  "out vec4 fs_out;\n"
25211 							  "\n"
25212 							  "void main()\n"
25213 							  "{\n"
25214 							  "    fs_out = any_fs;\n"
25215 							  "}\n"
25216 							  "\n";
25217 	static const GLchar* gs_tested = "#version 430 core\n"
25218 									 "#extension GL_ARB_enhanced_layouts : require\n"
25219 									 "\n"
25220 									 "layout(points)                           in;\n"
25221 									 "layout(triangle_strip, max_vertices = 4) out;\n"
25222 									 "\n"
25223 									 "VAR_DEFINITION"
25224 									 "\n"
25225 									 "in  vec4 vs_any[];\n"
25226 									 "out vec4 any_fs;\n"
25227 									 "\n"
25228 									 "void main()\n"
25229 									 "{\n"
25230 									 "    vec4 result = vs_any[0];\n"
25231 									 "\n"
25232 									 "VARIABLE_USE"
25233 									 "\n"
25234 									 "    any_fs = result;\n"
25235 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
25236 									 "    EmitVertex();\n"
25237 									 "    any_fs = result;\n"
25238 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
25239 									 "    EmitVertex();\n"
25240 									 "    any_fs = result;\n"
25241 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
25242 									 "    EmitVertex();\n"
25243 									 "    any_fs = result;\n"
25244 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
25245 									 "    EmitVertex();\n"
25246 									 "}\n"
25247 									 "\n";
25248 	static const GLchar* tcs = "#version 430 core\n"
25249 							   "#extension GL_ARB_enhanced_layouts : require\n"
25250 							   "\n"
25251 							   "layout(vertices = 1) out;\n"
25252 							   "\n"
25253 							   "in  vec4 vs_any[];\n"
25254 							   "out vec4 tcs_tes[];\n"
25255 							   "\n"
25256 							   "void main()\n"
25257 							   "{\n"
25258 							   "\n"
25259 							   "    tcs_tes[gl_InvocationID] = vs_any[gl_InvocationID];\n"
25260 							   "\n"
25261 							   "    gl_TessLevelOuter[0] = 1.0;\n"
25262 							   "    gl_TessLevelOuter[1] = 1.0;\n"
25263 							   "    gl_TessLevelOuter[2] = 1.0;\n"
25264 							   "    gl_TessLevelOuter[3] = 1.0;\n"
25265 							   "    gl_TessLevelInner[0] = 1.0;\n"
25266 							   "    gl_TessLevelInner[1] = 1.0;\n"
25267 							   "}\n"
25268 							   "\n";
25269 	static const GLchar* tes_tested = "#version 430 core\n"
25270 									  "#extension GL_ARB_enhanced_layouts : require\n"
25271 									  "\n"
25272 									  "layout(isolines, point_mode) in;\n"
25273 									  "\n"
25274 									  "VAR_DEFINITION"
25275 									  "\n"
25276 									  "in  vec4 tcs_tes[];\n"
25277 									  "out vec4 any_fs;\n"
25278 									  "\n"
25279 									  "void main()\n"
25280 									  "{\n"
25281 									  "    vec4 result = tcs_tes[0];\n"
25282 									  "\n"
25283 									  "VARIABLE_USE"
25284 									  "\n"
25285 									  "    any_fs += result;\n"
25286 									  "}\n"
25287 									  "\n";
25288 	static const GLchar* vs = "#version 430 core\n"
25289 							  "#extension GL_ARB_enhanced_layouts : require\n"
25290 							  "\n"
25291 							  "in  vec4 in_vs;\n"
25292 							  "out vec4 vs_any;\n"
25293 							  "\n"
25294 							  "void main()\n"
25295 							  "{\n"
25296 							  "    vs_any = in_vs;\n"
25297 							  "}\n"
25298 							  "\n";
25299 	static const GLchar* vs_tested = "#version 430 core\n"
25300 									 "#extension GL_ARB_enhanced_layouts : require\n"
25301 									 "\n"
25302 									 "VAR_DEFINITION"
25303 									 "\n"
25304 									 "in  vec4 in_vs;\n"
25305 									 "out vec4 any_fs;\n"
25306 									 "\n"
25307 									 "void main()\n"
25308 									 "{\n"
25309 									 "    vec4 result = in_vs;\n"
25310 									 "\n"
25311 									 "VARIABLE_USE"
25312 									 "\n"
25313 									 "    any_fs = result;\n"
25314 									 "}\n"
25315 									 "\n";
25316 
25317 	std::string source;
25318 	testCase&   test_case = m_test_cases[test_case_index];
25319 
25320 	if (test_case.m_stage == stage)
25321 	{
25322 		size_t		  position = 0;
25323 
25324 		switch (stage)
25325 		{
25326 		case Utils::Shader::GEOMETRY:
25327 			source = gs_tested;
25328 			break;
25329 		case Utils::Shader::TESS_EVAL:
25330 			source = tes_tested;
25331 			break;
25332 		case Utils::Shader::VERTEX:
25333 			source = vs_tested;
25334 			break;
25335 		default:
25336 			TCU_FAIL("Invalid enum");
25337 		}
25338 
25339 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
25340 		position = 0;
25341 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
25342 	}
25343 	else
25344 	{
25345 		switch (test_case.m_stage)
25346 		{
25347 		case Utils::Shader::GEOMETRY:
25348 			switch (stage)
25349 			{
25350 			case Utils::Shader::FRAGMENT:
25351 				source = fs;
25352 				break;
25353 			case Utils::Shader::VERTEX:
25354 				source = vs;
25355 				break;
25356 			default:
25357 				source = "";
25358 			}
25359 			break;
25360 		case Utils::Shader::TESS_EVAL:
25361 			switch (stage)
25362 			{
25363 			case Utils::Shader::FRAGMENT:
25364 				source = fs;
25365 				break;
25366 			case Utils::Shader::TESS_CTRL:
25367 				source = tcs;
25368 				break;
25369 			case Utils::Shader::VERTEX:
25370 				source = vs;
25371 				break;
25372 			default:
25373 				source = "";
25374 			}
25375 			break;
25376 		case Utils::Shader::VERTEX:
25377 			switch (stage)
25378 			{
25379 			case Utils::Shader::FRAGMENT:
25380 				source = fs;
25381 				break;
25382 			default:
25383 				source = "";
25384 			}
25385 			break;
25386 		default:
25387 			TCU_FAIL("Invalid enum");
25388 			break;
25389 		}
25390 	}
25391 
25392 	return source;
25393 }
25394 
25395 /** Get description of test case
25396  *
25397  * @param test_case_index Index of test case
25398  *
25399  * @return Test case description
25400  **/
25401 std::string XFBBlockMemberBufferTest::getTestCaseName(GLuint test_case_index)
25402 {
25403 	std::stringstream stream;
25404 	testCase&		  test_case = m_test_cases[test_case_index];
25405 
25406 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage);
25407 
25408 	return stream.str();
25409 }
25410 
25411 /** Get number of test cases
25412  *
25413  * @return Number of test cases
25414  **/
25415 GLuint XFBBlockMemberBufferTest::getTestCaseNumber()
25416 {
25417 	return static_cast<GLuint>(m_test_cases.size());
25418 }
25419 
25420 /** Selects if "compute" stage is relevant for test
25421  *
25422  * @param ignored
25423  *
25424  * @return false
25425  **/
25426 bool XFBBlockMemberBufferTest::isComputeRelevant(GLuint /* test_case_index */)
25427 {
25428 	return false;
25429 }
25430 
25431 /** Prepare all test cases
25432  *
25433  **/
25434 void XFBBlockMemberBufferTest::testInit()
25435 {
25436 	for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
25437 	{
25438 		if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
25439 			(Utils::Shader::FRAGMENT == stage))
25440 		{
25441 			continue;
25442 		}
25443 
25444 		testCase test_case = { (Utils::Shader::STAGES)stage };
25445 
25446 		m_test_cases.push_back(test_case);
25447 	}
25448 }
25449 
25450 /** Constructor
25451  *
25452  * @param context Test framework context
25453  **/
25454 XFBOutputOverlappingTest::XFBOutputOverlappingTest(deqp::Context& context)
25455 	: NegativeTestBase(context, "xfb_output_overlapping",
25456 					   "Test verifies that compiler reports error when two xfb qualified outputs overlap")
25457 {
25458 }
25459 
25460 /** Source for given test case and stage
25461  *
25462  * @param test_case_index Index of test case
25463  * @param stage           Shader stage
25464  *
25465  * @return Shader source
25466  **/
25467 std::string XFBOutputOverlappingTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
25468 {
25469 	static const GLchar* var_definition = "layout (xfb_offset = 0) out TYPE gohan;\n"
25470 #if DEBUG_NEG_REMOVE_ERROR
25471 										  "/* layout (xfb_offset = OFFSET) */ out TYPE goten;\n";
25472 #else
25473 										  "layout (xfb_offset = OFFSET) out TYPE goten;\n";
25474 #endif /* DEBUG_NEG_REMOVE_ERROR */
25475 	static const GLchar* var_use = "    gohan = TYPE(0);\n"
25476 								   "    goten = TYPE(1);\n"
25477 								   "    if (vec4(0) == result)\n"
25478 								   "    {\n"
25479 								   "        gohan = TYPE(1);\n"
25480 								   "        goten = TYPE(0);\n"
25481 								   "    }\n";
25482 	static const GLchar* fs = "#version 430 core\n"
25483 							  "#extension GL_ARB_enhanced_layouts : require\n"
25484 							  "\n"
25485 							  "in  vec4 any_fs;\n"
25486 							  "out vec4 fs_out;\n"
25487 							  "\n"
25488 							  "void main()\n"
25489 							  "{\n"
25490 							  "    fs_out = any_fs;\n"
25491 							  "}\n"
25492 							  "\n";
25493 	static const GLchar* gs_tested = "#version 430 core\n"
25494 									 "#extension GL_ARB_enhanced_layouts : require\n"
25495 									 "\n"
25496 									 "layout(points)                           in;\n"
25497 									 "layout(triangle_strip, max_vertices = 4) out;\n"
25498 									 "\n"
25499 									 "VAR_DEFINITION"
25500 									 "\n"
25501 									 "in  vec4 vs_any[];\n"
25502 									 "out vec4 any_fs;\n"
25503 									 "\n"
25504 									 "void main()\n"
25505 									 "{\n"
25506 									 "    vec4 result = vs_any[0];\n"
25507 									 "\n"
25508 									 "VARIABLE_USE"
25509 									 "\n"
25510 									 "    any_fs = result;\n"
25511 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
25512 									 "    EmitVertex();\n"
25513 									 "    any_fs = result;\n"
25514 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
25515 									 "    EmitVertex();\n"
25516 									 "    any_fs = result;\n"
25517 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
25518 									 "    EmitVertex();\n"
25519 									 "    any_fs = result;\n"
25520 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
25521 									 "    EmitVertex();\n"
25522 									 "}\n"
25523 									 "\n";
25524 	static const GLchar* tcs = "#version 430 core\n"
25525 							   "#extension GL_ARB_enhanced_layouts : require\n"
25526 							   "\n"
25527 							   "layout(vertices = 1) out;\n"
25528 							   "\n"
25529 							   "in  vec4 vs_any[];\n"
25530 							   "out vec4 tcs_tes[];\n"
25531 							   "\n"
25532 							   "void main()\n"
25533 							   "{\n"
25534 							   "\n"
25535 							   "    tcs_tes[gl_InvocationID] = vs_any[gl_InvocationID];\n"
25536 							   "\n"
25537 							   "    gl_TessLevelOuter[0] = 1.0;\n"
25538 							   "    gl_TessLevelOuter[1] = 1.0;\n"
25539 							   "    gl_TessLevelOuter[2] = 1.0;\n"
25540 							   "    gl_TessLevelOuter[3] = 1.0;\n"
25541 							   "    gl_TessLevelInner[0] = 1.0;\n"
25542 							   "    gl_TessLevelInner[1] = 1.0;\n"
25543 							   "}\n"
25544 							   "\n";
25545 	static const GLchar* tes_tested = "#version 430 core\n"
25546 									  "#extension GL_ARB_enhanced_layouts : require\n"
25547 									  "\n"
25548 									  "layout(isolines, point_mode) in;\n"
25549 									  "\n"
25550 									  "VAR_DEFINITION"
25551 									  "\n"
25552 									  "in  vec4 tcs_tes[];\n"
25553 									  "out vec4 any_fs;\n"
25554 									  "\n"
25555 									  "void main()\n"
25556 									  "{\n"
25557 									  "    vec4 result = tcs_tes[0];\n"
25558 									  "\n"
25559 									  "VARIABLE_USE"
25560 									  "\n"
25561 									  "    any_fs += result;\n"
25562 									  "}\n"
25563 									  "\n";
25564 	static const GLchar* vs = "#version 430 core\n"
25565 							  "#extension GL_ARB_enhanced_layouts : require\n"
25566 							  "\n"
25567 							  "in  vec4 in_vs;\n"
25568 							  "out vec4 vs_any;\n"
25569 							  "\n"
25570 							  "void main()\n"
25571 							  "{\n"
25572 							  "    vs_any = in_vs;\n"
25573 							  "}\n"
25574 							  "\n";
25575 	static const GLchar* vs_tested = "#version 430 core\n"
25576 									 "#extension GL_ARB_enhanced_layouts : require\n"
25577 									 "\n"
25578 									 "VAR_DEFINITION"
25579 									 "\n"
25580 									 "in  vec4 in_vs;\n"
25581 									 "out vec4 any_fs;\n"
25582 									 "\n"
25583 									 "void main()\n"
25584 									 "{\n"
25585 									 "    vec4 result = in_vs;\n"
25586 									 "\n"
25587 									 "VARIABLE_USE"
25588 									 "\n"
25589 									 "    any_fs = result;\n"
25590 									 "}\n"
25591 									 "\n";
25592 
25593 	std::string source;
25594 	testCase&   test_case = m_test_cases[test_case_index];
25595 
25596 	if (test_case.m_stage == stage)
25597 	{
25598 		GLchar		  offset[16];
25599 		size_t		  position		 = 0;
25600 		const GLchar* type_name		 = test_case.m_type.GetGLSLTypeName();
25601 
25602 		sprintf(offset, "%d", test_case.m_offset);
25603 
25604 		switch (stage)
25605 		{
25606 		case Utils::Shader::GEOMETRY:
25607 			source = gs_tested;
25608 			break;
25609 		case Utils::Shader::TESS_EVAL:
25610 			source = tes_tested;
25611 			break;
25612 		case Utils::Shader::VERTEX:
25613 			source = vs_tested;
25614 			break;
25615 		default:
25616 			TCU_FAIL("Invalid enum");
25617 		}
25618 
25619 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
25620 		position = 0;
25621 		Utils::replaceToken("OFFSET", position, offset, source);
25622 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
25623 
25624 		Utils::replaceAllTokens("TYPE", type_name, source);
25625 	}
25626 	else
25627 	{
25628 		switch (test_case.m_stage)
25629 		{
25630 		case Utils::Shader::GEOMETRY:
25631 			switch (stage)
25632 			{
25633 			case Utils::Shader::FRAGMENT:
25634 				source = fs;
25635 				break;
25636 			case Utils::Shader::VERTEX:
25637 				source = vs;
25638 				break;
25639 			default:
25640 				source = "";
25641 			}
25642 			break;
25643 		case Utils::Shader::TESS_EVAL:
25644 			switch (stage)
25645 			{
25646 			case Utils::Shader::FRAGMENT:
25647 				source = fs;
25648 				break;
25649 			case Utils::Shader::TESS_CTRL:
25650 				source = tcs;
25651 				break;
25652 			case Utils::Shader::VERTEX:
25653 				source = vs;
25654 				break;
25655 			default:
25656 				source = "";
25657 			}
25658 			break;
25659 		case Utils::Shader::VERTEX:
25660 			switch (stage)
25661 			{
25662 			case Utils::Shader::FRAGMENT:
25663 				source = fs;
25664 				break;
25665 			default:
25666 				source = "";
25667 			}
25668 			break;
25669 		default:
25670 			TCU_FAIL("Invalid enum");
25671 			break;
25672 		}
25673 	}
25674 
25675 	return source;
25676 }
25677 
25678 /** Get description of test case
25679  *
25680  * @param test_case_index Index of test case
25681  *
25682  * @return Test case description
25683  **/
25684 std::string XFBOutputOverlappingTest::getTestCaseName(GLuint test_case_index)
25685 {
25686 	std::stringstream stream;
25687 	testCase&		  test_case = m_test_cases[test_case_index];
25688 
25689 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
25690 		   << ", type: " << test_case.m_type.GetGLSLTypeName() << ", offset: " << test_case.m_offset;
25691 
25692 	return stream.str();
25693 }
25694 
25695 /** Get number of test cases
25696  *
25697  * @return Number of test cases
25698  **/
25699 GLuint XFBOutputOverlappingTest::getTestCaseNumber()
25700 {
25701 	return static_cast<GLuint>(m_test_cases.size());
25702 }
25703 
25704 /** Selects if "compute" stage is relevant for test
25705  *
25706  * @param ignored
25707  *
25708  * @return false
25709  **/
25710 bool XFBOutputOverlappingTest::isComputeRelevant(GLuint /* test_case_index */)
25711 {
25712 	return false;
25713 }
25714 
25715 /** Prepare all test cases
25716  *
25717  **/
25718 void XFBOutputOverlappingTest::testInit()
25719 {
25720 	const GLuint n_types = getTypesNumber();
25721 
25722 	for (GLuint i = 0; i < n_types; ++i)
25723 	{
25724 		const Utils::Type& type			  = getType(i);
25725 		const GLuint	   basic_type_size = Utils::Type::GetTypeSize(type.m_basic_type);
25726 
25727 		/* Skip scalars, not applicable as:
25728 		 *
25729 		 *     The offset must be a multiple of the size of the first component of the first
25730 		 *     qualified variable or block member, or a compile-time error results.
25731 		 */
25732 		if ((1 == type.m_n_columns) && (1 == type.m_n_rows))
25733 		{
25734 			continue;
25735 		}
25736 
25737 		for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
25738 		{
25739 			if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
25740 				(Utils::Shader::FRAGMENT == stage))
25741 			{
25742 				continue;
25743 			}
25744 
25745 			testCase test_case = { basic_type_size /* offset */, (Utils::Shader::STAGES)stage, type };
25746 
25747 			m_test_cases.push_back(test_case);
25748 		}
25749 	}
25750 }
25751 
25752 /** Constructor
25753  *
25754  * @param context Test framework context
25755  **/
25756 XFBInvalidOffsetAlignmentTest::XFBInvalidOffsetAlignmentTest(deqp::Context& context)
25757 	: NegativeTestBase(context, "xfb_invalid_offset_alignment",
25758 					   "Test verifies that compiler reports error when xfb_offset has invalid alignment")
25759 {
25760 }
25761 
25762 /** Source for given test case and stage
25763  *
25764  * @param test_case_index Index of test case
25765  * @param stage           Shader stage
25766  *
25767  * @return Shader source
25768  **/
25769 std::string XFBInvalidOffsetAlignmentTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
25770 {
25771 #if DEBUG_NEG_REMOVE_ERROR
25772 	static const GLchar* var_definition = "/* layout (xfb_offset = OFFSET) */ out TYPE gohan;\n";
25773 #else
25774 	static const GLchar* var_definition = "layout (xfb_offset = OFFSET) out TYPE gohan;\n";
25775 #endif /* DEBUG_NEG_REMOVE_ERROR */
25776 	static const GLchar* var_use = "    gohan = TYPE(0);\n"
25777 								   "    if (vec4(0) == result)\n"
25778 								   "    {\n"
25779 								   "        gohan = TYPE(1);\n"
25780 								   "    }\n";
25781 	static const GLchar* fs = "#version 430 core\n"
25782 							  "#extension GL_ARB_enhanced_layouts : require\n"
25783 							  "\n"
25784 							  "in  vec4 any_fs;\n"
25785 							  "out vec4 fs_out;\n"
25786 							  "\n"
25787 							  "void main()\n"
25788 							  "{\n"
25789 							  "    fs_out = any_fs;\n"
25790 							  "}\n"
25791 							  "\n";
25792 	static const GLchar* gs_tested = "#version 430 core\n"
25793 									 "#extension GL_ARB_enhanced_layouts : require\n"
25794 									 "\n"
25795 									 "layout(points)                           in;\n"
25796 									 "layout(triangle_strip, max_vertices = 4) out;\n"
25797 									 "\n"
25798 									 "VAR_DEFINITION"
25799 									 "\n"
25800 									 "in  vec4 vs_any[];\n"
25801 									 "out vec4 any_fs;\n"
25802 									 "\n"
25803 									 "void main()\n"
25804 									 "{\n"
25805 									 "    vec4 result = vs_any[0];\n"
25806 									 "\n"
25807 									 "VARIABLE_USE"
25808 									 "\n"
25809 									 "    any_fs = result;\n"
25810 									 "    gl_Position  = vec4(-1, -1, 0, 1);\n"
25811 									 "    EmitVertex();\n"
25812 									 "    any_fs = result;\n"
25813 									 "    gl_Position  = vec4(-1, 1, 0, 1);\n"
25814 									 "    EmitVertex();\n"
25815 									 "    any_fs = result;\n"
25816 									 "    gl_Position  = vec4(1, -1, 0, 1);\n"
25817 									 "    EmitVertex();\n"
25818 									 "    any_fs = result;\n"
25819 									 "    gl_Position  = vec4(1, 1, 0, 1);\n"
25820 									 "    EmitVertex();\n"
25821 									 "}\n"
25822 									 "\n";
25823 	static const GLchar* tcs = "#version 430 core\n"
25824 							   "#extension GL_ARB_enhanced_layouts : require\n"
25825 							   "\n"
25826 							   "layout(vertices = 1) out;\n"
25827 							   "\n"
25828 							   "in  vec4 vs_any[];\n"
25829 							   "out vec4 tcs_tes[];\n"
25830 							   "\n"
25831 							   "void main()\n"
25832 							   "{\n"
25833 							   "\n"
25834 							   "    tcs_tes[gl_InvocationID] = vs_any[gl_InvocationID];\n"
25835 							   "\n"
25836 							   "    gl_TessLevelOuter[0] = 1.0;\n"
25837 							   "    gl_TessLevelOuter[1] = 1.0;\n"
25838 							   "    gl_TessLevelOuter[2] = 1.0;\n"
25839 							   "    gl_TessLevelOuter[3] = 1.0;\n"
25840 							   "    gl_TessLevelInner[0] = 1.0;\n"
25841 							   "    gl_TessLevelInner[1] = 1.0;\n"
25842 							   "}\n"
25843 							   "\n";
25844 	static const GLchar* tes_tested = "#version 430 core\n"
25845 									  "#extension GL_ARB_enhanced_layouts : require\n"
25846 									  "\n"
25847 									  "layout(isolines, point_mode) in;\n"
25848 									  "\n"
25849 									  "VAR_DEFINITION"
25850 									  "\n"
25851 									  "in  vec4 tcs_tes[];\n"
25852 									  "out vec4 any_fs;\n"
25853 									  "\n"
25854 									  "void main()\n"
25855 									  "{\n"
25856 									  "    vec4 result = tcs_tes[0];\n"
25857 									  "\n"
25858 									  "VARIABLE_USE"
25859 									  "\n"
25860 									  "    any_fs += result;\n"
25861 									  "}\n"
25862 									  "\n";
25863 	static const GLchar* vs = "#version 430 core\n"
25864 							  "#extension GL_ARB_enhanced_layouts : require\n"
25865 							  "\n"
25866 							  "in  vec4 in_vs;\n"
25867 							  "out vec4 vs_any;\n"
25868 							  "\n"
25869 							  "void main()\n"
25870 							  "{\n"
25871 							  "    vs_any = in_vs;\n"
25872 							  "}\n"
25873 							  "\n";
25874 	static const GLchar* vs_tested = "#version 430 core\n"
25875 									 "#extension GL_ARB_enhanced_layouts : require\n"
25876 									 "\n"
25877 									 "VAR_DEFINITION"
25878 									 "\n"
25879 									 "in  vec4 in_vs;\n"
25880 									 "out vec4 any_fs;\n"
25881 									 "\n"
25882 									 "void main()\n"
25883 									 "{\n"
25884 									 "    vec4 result = in_vs;\n"
25885 									 "\n"
25886 									 "VARIABLE_USE"
25887 									 "\n"
25888 									 "    any_fs = result;\n"
25889 									 "}\n"
25890 									 "\n";
25891 
25892 	std::string source;
25893 	testCase&   test_case = m_test_cases[test_case_index];
25894 
25895 	if (test_case.m_stage == stage)
25896 	{
25897 		GLchar		  offset[16];
25898 		size_t		  position		 = 0;
25899 		const GLchar* type_name		 = test_case.m_type.GetGLSLTypeName();
25900 
25901 		sprintf(offset, "%d", test_case.m_offset);
25902 
25903 		switch (stage)
25904 		{
25905 		case Utils::Shader::GEOMETRY:
25906 			source = gs_tested;
25907 			break;
25908 		case Utils::Shader::TESS_EVAL:
25909 			source = tes_tested;
25910 			break;
25911 		case Utils::Shader::VERTEX:
25912 			source = vs_tested;
25913 			break;
25914 		default:
25915 			TCU_FAIL("Invalid enum");
25916 		}
25917 
25918 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
25919 		position = 0;
25920 		Utils::replaceToken("OFFSET", position, offset, source);
25921 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
25922 
25923 		Utils::replaceAllTokens("TYPE", type_name, source);
25924 	}
25925 	else
25926 	{
25927 		switch (test_case.m_stage)
25928 		{
25929 		case Utils::Shader::GEOMETRY:
25930 			switch (stage)
25931 			{
25932 			case Utils::Shader::FRAGMENT:
25933 				source = fs;
25934 				break;
25935 			case Utils::Shader::VERTEX:
25936 				source = vs;
25937 				break;
25938 			default:
25939 				source = "";
25940 			}
25941 			break;
25942 		case Utils::Shader::TESS_EVAL:
25943 			switch (stage)
25944 			{
25945 			case Utils::Shader::FRAGMENT:
25946 				source = fs;
25947 				break;
25948 			case Utils::Shader::TESS_CTRL:
25949 				source = tcs;
25950 				break;
25951 			case Utils::Shader::VERTEX:
25952 				source = vs;
25953 				break;
25954 			default:
25955 				source = "";
25956 			}
25957 			break;
25958 		case Utils::Shader::VERTEX:
25959 			switch (stage)
25960 			{
25961 			case Utils::Shader::FRAGMENT:
25962 				source = fs;
25963 				break;
25964 			default:
25965 				source = "";
25966 			}
25967 			break;
25968 		default:
25969 			TCU_FAIL("Invalid enum");
25970 			break;
25971 		}
25972 	}
25973 
25974 	return source;
25975 }
25976 
25977 /** Get description of test case
25978  *
25979  * @param test_case_index Index of test case
25980  *
25981  * @return Test case description
25982  **/
25983 std::string XFBInvalidOffsetAlignmentTest::getTestCaseName(GLuint test_case_index)
25984 {
25985 	std::stringstream stream;
25986 	testCase&		  test_case = m_test_cases[test_case_index];
25987 
25988 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage)
25989 		   << ", type: " << test_case.m_type.GetGLSLTypeName() << ", offset: " << test_case.m_offset;
25990 
25991 	return stream.str();
25992 }
25993 
25994 /** Get number of test cases
25995  *
25996  * @return Number of test cases
25997  **/
25998 GLuint XFBInvalidOffsetAlignmentTest::getTestCaseNumber()
25999 {
26000 	return static_cast<GLuint>(m_test_cases.size());
26001 }
26002 
26003 /** Selects if "compute" stage is relevant for test
26004  *
26005  * @param ignored
26006  *
26007  * @return false
26008  **/
26009 bool XFBInvalidOffsetAlignmentTest::isComputeRelevant(GLuint /* test_case_index */)
26010 {
26011 	return false;
26012 }
26013 
26014 /** Prepare all test cases
26015  *
26016  **/
26017 void XFBInvalidOffsetAlignmentTest::testInit()
26018 {
26019 	const GLuint n_types = getTypesNumber();
26020 
26021 	for (GLuint i = 0; i < n_types; ++i)
26022 	{
26023 		const Utils::Type& type			  = getType(i);
26024 		const GLuint	   basic_type_size = Utils::Type::GetTypeSize(type.m_basic_type);
26025 
26026 		for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
26027 		{
26028 			if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
26029 				(Utils::Shader::FRAGMENT == stage))
26030 			{
26031 				continue;
26032 			}
26033 
26034 			for (GLuint offset = basic_type_size + 1; offset < 2 * basic_type_size; ++offset)
26035 			{
26036 				testCase test_case = { offset, (Utils::Shader::STAGES)stage, type };
26037 
26038 				m_test_cases.push_back(test_case);
26039 			}
26040 		}
26041 	}
26042 }
26043 
26044 /** Constructor
26045  *
26046  * @param context Test context
26047  **/
26048 XFBCaptureInactiveOutputVariableTest::XFBCaptureInactiveOutputVariableTest(deqp::Context& context)
26049 	: BufferTestBase(context, "xfb_capture_inactive_output_variable",
26050 					 "Test verifies that inactive variables are captured")
26051 {
26052 	/* Nothing to be done here */
26053 }
26054 
26055 /** Execute drawArrays for single vertex
26056  *
26057  * @param test_case_index
26058  *
26059  * @return true
26060  **/
26061 bool XFBCaptureInactiveOutputVariableTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
26062 {
26063 	const Functions& gl				= m_context.getRenderContext().getFunctions();
26064 	GLenum			 primitive_type = GL_PATCHES;
26065 
26066 	if (TEST_VS == test_case_index)
26067 	{
26068 		primitive_type = GL_POINTS;
26069 	}
26070 
26071 	gl.disable(GL_RASTERIZER_DISCARD);
26072 	GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
26073 
26074 	gl.beginTransformFeedback(GL_POINTS);
26075 	GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
26076 
26077 	gl.drawArrays(primitive_type, 0 /* first */, 1 /* count */);
26078 	GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
26079 
26080 	gl.endTransformFeedback();
26081 	GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
26082 
26083 	return true;
26084 }
26085 
26086 /** Get descriptors of buffers necessary for test
26087  *
26088  * @param ignored
26089  * @param out_descriptors Descriptors of buffers used by test
26090  **/
26091 void XFBCaptureInactiveOutputVariableTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
26092 																bufferDescriptor::Vector& out_descriptors)
26093 {
26094 	const Utils::Type& type = Utils::Type::vec4;
26095 
26096 	/* Test needs single uniform and xfb */
26097 	out_descriptors.resize(2);
26098 
26099 	/* Get references */
26100 	bufferDescriptor& uniform = out_descriptors[0];
26101 	bufferDescriptor& xfb	 = out_descriptors[1];
26102 
26103 	/* Index */
26104 	uniform.m_index = 0;
26105 	xfb.m_index		= 0;
26106 
26107 	/* Target */
26108 	uniform.m_target = Utils::Buffer::Uniform;
26109 	xfb.m_target	 = Utils::Buffer::Transform_feedback;
26110 
26111 	/* Data */
26112 	const std::vector<GLubyte>& gohan_data = type.GenerateData();
26113 	const std::vector<GLubyte>& goten_data = type.GenerateData();
26114 
26115 	const GLuint type_size = static_cast<GLuint>(gohan_data.size());
26116 
26117 	/* Uniform data */
26118 	uniform.m_initial_data.resize(2 * type_size);
26119 	memcpy(&uniform.m_initial_data[0] + 0, &gohan_data[0], type_size);
26120 	memcpy(&uniform.m_initial_data[0] + type_size, &goten_data[0], type_size);
26121 
26122 	/* XFB data */
26123 	xfb.m_initial_data.resize(3 * type_size);
26124 	xfb.m_expected_data.resize(3 * type_size);
26125 
26126 	for (GLuint i = 0; i < 3 * type_size; ++i)
26127 	{
26128 		xfb.m_initial_data[i]  = (glw::GLubyte)i;
26129 		xfb.m_expected_data[i] = (glw::GLubyte)i;
26130 	}
26131 
26132 	memcpy(&xfb.m_expected_data[0] + 2 * type_size, &gohan_data[0], type_size);
26133 	memcpy(&xfb.m_expected_data[0] + 0 * type_size, &goten_data[0], type_size);
26134 }
26135 
26136 /** Get body of main function for given shader stage
26137  *
26138  * @param test_case_index  Index of test case
26139  * @param stage            Shader stage
26140  * @param out_assignments  Set to empty
26141  * @param out_calculations Set to empty
26142  **/
26143 void XFBCaptureInactiveOutputVariableTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
26144 														 std::string& out_assignments, std::string& out_calculations)
26145 {
26146 	out_calculations = "";
26147 
26148 	static const GLchar* vs_tes_gs = "    goten = uni_goten;\n"
26149 									 "    gohan = uni_gohan;\n";
26150 	static const GLchar* fs = "    fs_out = goku + gohan + goten;\n";
26151 
26152 	const GLchar* assignments = "";
26153 
26154 	switch (stage)
26155 	{
26156 	case Utils::Shader::FRAGMENT:
26157 		assignments = fs;
26158 		break;
26159 
26160 	case Utils::Shader::GEOMETRY:
26161 		if (TEST_GS == test_case_index)
26162 		{
26163 			assignments = vs_tes_gs;
26164 		}
26165 		break;
26166 
26167 	case Utils::Shader::TESS_CTRL:
26168 		break;
26169 
26170 	case Utils::Shader::TESS_EVAL:
26171 		if (TEST_TES == test_case_index)
26172 		{
26173 			assignments = vs_tes_gs;
26174 		}
26175 		break;
26176 
26177 	case Utils::Shader::VERTEX:
26178 		if (TEST_VS == test_case_index)
26179 		{
26180 			assignments = vs_tes_gs;
26181 		}
26182 		break;
26183 
26184 	default:
26185 		TCU_FAIL("Invalid enum");
26186 	}
26187 
26188 	out_assignments = assignments;
26189 }
26190 
26191 /** Get interface of shader
26192  *
26193  * @param test_case_index  Index of test case
26194  * @param stage            Shader stage
26195  * @param out_interface    Set to ""
26196  **/
26197 void XFBCaptureInactiveOutputVariableTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
26198 															  std::string& out_interface)
26199 {
26200 	static const GLchar* vs_tes_gs = "const uint sizeof_type = 16;\n"
26201 									 "\n"
26202 									 "layout (xfb_offset = 1 * sizeof_type) out vec4 goku;\n"
26203 									 "layout (xfb_offset = 2 * sizeof_type) out vec4 gohan;\n"
26204 									 "layout (xfb_offset = 0 * sizeof_type) out vec4 goten;\n"
26205 									 "\n"
26206 									 "layout(binding = 0) uniform block {\n"
26207 									 "    vec4 uni_gohan;\n"
26208 									 "    vec4 uni_goten;\n"
26209 									 "};\n";
26210 	static const GLchar* fs = "in vec4 goku;\n"
26211 							  "in vec4 gohan;\n"
26212 							  "in vec4 goten;\n"
26213 							  "out vec4 fs_out;\n";
26214 
26215 	const GLchar* interface = "";
26216 
26217 	switch (stage)
26218 	{
26219 	case Utils::Shader::FRAGMENT:
26220 		interface = fs;
26221 		break;
26222 
26223 	case Utils::Shader::GEOMETRY:
26224 		if (TEST_GS == test_case_index)
26225 		{
26226 			interface = vs_tes_gs;
26227 		}
26228 		break;
26229 
26230 	case Utils::Shader::TESS_CTRL:
26231 		break;
26232 
26233 	case Utils::Shader::TESS_EVAL:
26234 		if (TEST_TES == test_case_index)
26235 		{
26236 			interface = vs_tes_gs;
26237 		}
26238 		break;
26239 
26240 	case Utils::Shader::VERTEX:
26241 		if (TEST_VS == test_case_index)
26242 		{
26243 			interface = vs_tes_gs;
26244 		}
26245 		break;
26246 
26247 	default:
26248 		TCU_FAIL("Invalid enum");
26249 	}
26250 
26251 	out_interface = interface;
26252 }
26253 
26254 /** Get source code of shader
26255  *
26256  * @param test_case_index Index of test case
26257  * @param stage           Shader stage
26258  *
26259  * @return Source
26260  **/
26261 std::string XFBCaptureInactiveOutputVariableTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
26262 {
26263 	std::string source;
26264 
26265 	switch (test_case_index)
26266 	{
26267 	case TEST_VS:
26268 		switch (stage)
26269 		{
26270 		case Utils::Shader::FRAGMENT:
26271 		case Utils::Shader::VERTEX:
26272 			source = BufferTestBase::getShaderSource(test_case_index, stage);
26273 			break;
26274 		default:
26275 			break;
26276 		}
26277 		break;
26278 
26279 	case TEST_TES:
26280 		switch (stage)
26281 		{
26282 		case Utils::Shader::FRAGMENT:
26283 		case Utils::Shader::TESS_CTRL:
26284 		case Utils::Shader::TESS_EVAL:
26285 		case Utils::Shader::VERTEX:
26286 			source = BufferTestBase::getShaderSource(test_case_index, stage);
26287 			break;
26288 		default:
26289 			break;
26290 		}
26291 		break;
26292 
26293 	case TEST_GS:
26294 		source = BufferTestBase::getShaderSource(test_case_index, stage);
26295 		break;
26296 
26297 	default:
26298 		TCU_FAIL("Invalid enum");
26299 		break;
26300 	}
26301 
26302 	/* */
26303 	return source;
26304 }
26305 
26306 /** Get name of test case
26307  *
26308  * @param test_case_index Index of test case
26309  *
26310  * @return Name of tested stage
26311  **/
26312 std::string XFBCaptureInactiveOutputVariableTest::getTestCaseName(glw::GLuint test_case_index)
26313 {
26314 	const GLchar* name = 0;
26315 
26316 	switch (test_case_index)
26317 	{
26318 	case TEST_VS:
26319 		name = "vertex";
26320 		break;
26321 	case TEST_TES:
26322 		name = "tessellation evaluation";
26323 		break;
26324 	case TEST_GS:
26325 		name = "geometry";
26326 		break;
26327 	default:
26328 		TCU_FAIL("Invalid enum");
26329 	}
26330 
26331 	return name;
26332 }
26333 
26334 /** Returns number of test cases
26335  *
26336  * @return TEST_MAX
26337  **/
26338 glw::GLuint XFBCaptureInactiveOutputVariableTest::getTestCaseNumber()
26339 {
26340 	return TEST_MAX;
26341 }
26342 
26343 /** Inspects program to check if all resources are as expected
26344  *
26345  * @param ignored
26346  * @param program         Program instance
26347  * @param out_stream      Error message
26348  *
26349  * @return true if everything is ok, false otherwise
26350  **/
26351 bool XFBCaptureInactiveOutputVariableTest::inspectProgram(GLuint /* test_case_index */, Utils::Program& program,
26352 														  std::stringstream& out_stream)
26353 {
26354 	GLint			   stride	= 0;
26355 	const Utils::Type& type		 = Utils::Type::vec4;
26356 	const GLuint	   type_size = type.GetSize();
26357 
26358 	program.GetResource(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE,
26359 						1 /* buf_size */, &stride);
26360 
26361 	if ((GLint)(3 * type_size) != stride)
26362 	{
26363 		out_stream << "Stride is: " << stride << " expected: " << (3 * type_size);
26364 
26365 		return false;
26366 	}
26367 
26368 	return true;
26369 }
26370 
26371 /** Verify contents of buffers
26372  *
26373  * @param buffers Collection of buffers to be verified
26374  *
26375  * @return true if everything is as expected, false otherwise
26376  **/
26377 bool XFBCaptureInactiveOutputVariableTest::verifyBuffers(bufferCollection& buffers)
26378 {
26379 	bool result = true;
26380 
26381 	bufferCollection::pair& pair	   = buffers.m_vector[1] /* xfb */;
26382 	Utils::Buffer*			buffer	 = pair.m_buffer;
26383 	bufferDescriptor*		descriptor = pair.m_descriptor;
26384 
26385 	/* Get pointer to contents of buffer */
26386 	buffer->Bind();
26387 	GLubyte* buffer_data = (GLubyte*)buffer->Map(Utils::Buffer::ReadOnly);
26388 
26389 	/* Get pointer to expected data */
26390 	GLubyte* expected_data = (GLubyte*)&descriptor->m_expected_data[0];
26391 
26392 	/* Compare */
26393 	static const GLuint vec4_size = 16;
26394 
26395 	int res_gohan = memcmp(buffer_data + 2 * vec4_size, expected_data + 2 * vec4_size, vec4_size);
26396 	int res_goten = memcmp(buffer_data + 0 * vec4_size, expected_data + 0 * vec4_size, vec4_size);
26397 
26398 	if ((0 != res_gohan) || (0 != res_goten))
26399 	{
26400 		m_context.getTestContext().getLog()
26401 			<< tcu::TestLog::Message << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
26402 			<< ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
26403 
26404 		result = false;
26405 	}
26406 
26407 	/* Release buffer mapping */
26408 	buffer->UnMap();
26409 
26410 	return result;
26411 }
26412 
26413 /** Constructor
26414  *
26415  * @param context Test context
26416  **/
26417 XFBCaptureInactiveOutputComponentTest::XFBCaptureInactiveOutputComponentTest(deqp::Context& context)
26418 	: BufferTestBase(context, "xfb_capture_inactive_output_component",
26419 					 "Test verifies that inactive components are not modified")
26420 {
26421 	/* Nothing to be done here */
26422 }
26423 
26424 /** Execute drawArrays for single vertex
26425  *
26426  * @param test_case_index
26427  *
26428  * @return true
26429  **/
26430 bool XFBCaptureInactiveOutputComponentTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
26431 {
26432 	const Functions& gl				= m_context.getRenderContext().getFunctions();
26433 	GLenum			 primitive_type = GL_PATCHES;
26434 
26435 	if (TEST_VS == test_case_index)
26436 	{
26437 		primitive_type = GL_POINTS;
26438 	}
26439 
26440 	gl.disable(GL_RASTERIZER_DISCARD);
26441 	GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
26442 
26443 	gl.beginTransformFeedback(GL_POINTS);
26444 	GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
26445 
26446 	gl.drawArrays(primitive_type, 0 /* first */, 1 /* count */);
26447 	GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
26448 
26449 	gl.endTransformFeedback();
26450 	GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
26451 
26452 	return true;
26453 }
26454 
26455 /** Get descriptors of buffers necessary for test
26456  *
26457  * @param ignored
26458  * @param out_descriptors Descriptors of buffers used by test
26459  **/
26460 void XFBCaptureInactiveOutputComponentTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
26461 																 bufferDescriptor::Vector& out_descriptors)
26462 {
26463 	const Utils::Type& type = Utils::Type::vec4;
26464 
26465 	/* Test needs single uniform and xfb */
26466 	out_descriptors.resize(2);
26467 
26468 	/* Get references */
26469 	bufferDescriptor& uniform = out_descriptors[0];
26470 	bufferDescriptor& xfb	 = out_descriptors[1];
26471 
26472 	/* Index */
26473 	uniform.m_index = 0;
26474 	xfb.m_index		= 0;
26475 
26476 	/* Target */
26477 	uniform.m_target = Utils::Buffer::Uniform;
26478 	xfb.m_target	 = Utils::Buffer::Transform_feedback;
26479 
26480 	/* Data */
26481 	const std::vector<GLubyte>& goku_data   = type.GenerateData();
26482 	const std::vector<GLubyte>& gohan_data  = type.GenerateData();
26483 	const std::vector<GLubyte>& goten_data  = type.GenerateData();
26484 	const std::vector<GLubyte>& chichi_data = type.GenerateData();
26485 	const std::vector<GLubyte>& vegeta_data = type.GenerateData();
26486 	const std::vector<GLubyte>& trunks_data = type.GenerateData();
26487 	const std::vector<GLubyte>& bra_data	= type.GenerateData();
26488 	const std::vector<GLubyte>& bulma_data  = type.GenerateData();
26489 
26490 	const GLuint comp_size = Utils::Type::GetTypeSize(type.m_basic_type);
26491 	const GLuint type_size = static_cast<GLuint>(gohan_data.size());
26492 
26493 	/* Uniform data */
26494 	uniform.m_initial_data.resize(8 * type_size);
26495 	memcpy(&uniform.m_initial_data[0] + 0 * type_size, &goku_data[0], type_size);
26496 	memcpy(&uniform.m_initial_data[0] + 1 * type_size, &gohan_data[0], type_size);
26497 	memcpy(&uniform.m_initial_data[0] + 2 * type_size, &goten_data[0], type_size);
26498 	memcpy(&uniform.m_initial_data[0] + 3 * type_size, &chichi_data[0], type_size);
26499 	memcpy(&uniform.m_initial_data[0] + 4 * type_size, &vegeta_data[0], type_size);
26500 	memcpy(&uniform.m_initial_data[0] + 5 * type_size, &trunks_data[0], type_size);
26501 	memcpy(&uniform.m_initial_data[0] + 6 * type_size, &bra_data[0], type_size);
26502 	memcpy(&uniform.m_initial_data[0] + 7 * type_size, &bulma_data[0], type_size);
26503 
26504 	/* XFB data */
26505 	xfb.m_initial_data.resize(8 * type_size);
26506 	xfb.m_expected_data.resize(8 * type_size);
26507 
26508 	for (GLuint i = 0; i < 8 * type_size; ++i)
26509 	{
26510 		xfb.m_initial_data[i]  = (glw::GLubyte)i;
26511 		xfb.m_expected_data[i] = (glw::GLubyte)i;
26512 	}
26513 
26514 	/* goku - x, z - 32 */
26515 	memcpy(&xfb.m_expected_data[0] + 2 * type_size + 0 * comp_size, &goku_data[0] + 0 * comp_size, comp_size);
26516 	memcpy(&xfb.m_expected_data[0] + 2 * type_size + 2 * comp_size, &goku_data[0] + 2 * comp_size, comp_size);
26517 
26518 	/* gohan - y, w - 0 */
26519 	memcpy(&xfb.m_expected_data[0] + 0 * type_size + 1 * comp_size, &gohan_data[0] + 1 * comp_size, comp_size);
26520 	memcpy(&xfb.m_expected_data[0] + 0 * type_size + 3 * comp_size, &gohan_data[0] + 3 * comp_size, comp_size);
26521 
26522 	/* goten - x, y - 16 */
26523 	memcpy(&xfb.m_expected_data[0] + 1 * type_size + 0 * comp_size, &goten_data[0] + 0 * comp_size, comp_size);
26524 	memcpy(&xfb.m_expected_data[0] + 1 * type_size + 1 * comp_size, &goten_data[0] + 1 * comp_size, comp_size);
26525 
26526 	/* chichi - z, w - 48 */
26527 	memcpy(&xfb.m_expected_data[0] + 3 * type_size + 2 * comp_size, &chichi_data[0] + 2 * comp_size, comp_size);
26528 	memcpy(&xfb.m_expected_data[0] + 3 * type_size + 3 * comp_size, &chichi_data[0] + 3 * comp_size, comp_size);
26529 
26530 	/* vegeta - x - 112 */
26531 	memcpy(&xfb.m_expected_data[0] + 7 * type_size + 0 * comp_size, &vegeta_data[0] + 0 * comp_size, comp_size);
26532 
26533 	/* trunks - y - 96 */
26534 	memcpy(&xfb.m_expected_data[0] + 6 * type_size + 1 * comp_size, &trunks_data[0] + 1 * comp_size, comp_size);
26535 
26536 	/* bra - z - 80 */
26537 	memcpy(&xfb.m_expected_data[0] + 5 * type_size + 2 * comp_size, &bra_data[0] + 2 * comp_size, comp_size);
26538 
26539 	/* bulma - w - 64 */
26540 	memcpy(&xfb.m_expected_data[0] + 4 * type_size + 3 * comp_size, &bulma_data[0] + 3 * comp_size, comp_size);
26541 }
26542 
26543 /** Get body of main function for given shader stage
26544  *
26545  * @param test_case_index  Index of test case
26546  * @param stage            Shader stage
26547  * @param out_assignments  Set to empty
26548  * @param out_calculations Set to empty
26549  **/
26550 void XFBCaptureInactiveOutputComponentTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
26551 														  std::string& out_assignments, std::string& out_calculations)
26552 {
26553 	out_calculations = "";
26554 
26555 	static const GLchar* vs_tes_gs = "    goku.x    = uni_goku.x   ;\n"
26556 									 "    goku.z    = uni_goku.z   ;\n"
26557 									 "    gohan.y   = uni_gohan.y  ;\n"
26558 									 "    gohan.w   = uni_gohan.w  ;\n"
26559 									 "    goten.x   = uni_goten.x  ;\n"
26560 									 "    goten.y   = uni_goten.y  ;\n"
26561 									 "    chichi.z  = uni_chichi.z ;\n"
26562 									 "    chichi.w  = uni_chichi.w ;\n"
26563 									 "    vegeta.x  = uni_vegeta.x ;\n"
26564 									 "    trunks.y  = uni_trunks.y ;\n"
26565 									 "    bra.z     = uni_bra.z    ;\n"
26566 									 "    bulma.w   = uni_bulma.w  ;\n";
26567 	static const GLchar* fs = "    fs_out = goku + gohan + goten + chichi + vegeta + trunks + bra + bulma;\n";
26568 
26569 	const GLchar* assignments = "";
26570 
26571 	switch (stage)
26572 	{
26573 	case Utils::Shader::FRAGMENT:
26574 		assignments = fs;
26575 		break;
26576 
26577 	case Utils::Shader::GEOMETRY:
26578 		if (TEST_GS == test_case_index)
26579 		{
26580 			assignments = vs_tes_gs;
26581 		}
26582 		break;
26583 
26584 	case Utils::Shader::TESS_CTRL:
26585 		break;
26586 
26587 	case Utils::Shader::TESS_EVAL:
26588 		if (TEST_TES == test_case_index)
26589 		{
26590 			assignments = vs_tes_gs;
26591 		}
26592 		break;
26593 
26594 	case Utils::Shader::VERTEX:
26595 		if (TEST_VS == test_case_index)
26596 		{
26597 			assignments = vs_tes_gs;
26598 		}
26599 		break;
26600 
26601 	default:
26602 		TCU_FAIL("Invalid enum");
26603 	}
26604 
26605 	out_assignments = assignments;
26606 }
26607 
26608 /** Get interface of shader
26609  *
26610  * @param test_case_index  Index of test case
26611  * @param stage            Shader stage
26612  * @param out_interface    Set to ""
26613  **/
26614 void XFBCaptureInactiveOutputComponentTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
26615 															   std::string& out_interface)
26616 {
26617 	static const GLchar* vs_tes_gs = "const uint sizeof_type = 16;\n"
26618 									 "\n"
26619 									 "layout (xfb_offset = 2 * sizeof_type) out vec4 goku;\n"
26620 									 "layout (xfb_offset = 0 * sizeof_type) out vec4 gohan;\n"
26621 									 "layout (xfb_offset = 1 * sizeof_type) out vec4 goten;\n"
26622 									 "layout (xfb_offset = 3 * sizeof_type) out vec4 chichi;\n"
26623 									 "layout (xfb_offset = 7 * sizeof_type) out vec4 vegeta;\n"
26624 									 "layout (xfb_offset = 6 * sizeof_type) out vec4 trunks;\n"
26625 									 "layout (xfb_offset = 5 * sizeof_type) out vec4 bra;\n"
26626 									 "layout (xfb_offset = 4 * sizeof_type) out vec4 bulma;\n"
26627 									 "\n"
26628 									 "layout(binding = 0) uniform block {\n"
26629 									 "    vec4 uni_goku;\n"
26630 									 "    vec4 uni_gohan;\n"
26631 									 "    vec4 uni_goten;\n"
26632 									 "    vec4 uni_chichi;\n"
26633 									 "    vec4 uni_vegeta;\n"
26634 									 "    vec4 uni_trunks;\n"
26635 									 "    vec4 uni_bra;\n"
26636 									 "    vec4 uni_bulma;\n"
26637 									 "};\n";
26638 	static const GLchar* fs = "in vec4 vegeta;\n"
26639 							  "in vec4 trunks;\n"
26640 							  "in vec4 bra;\n"
26641 							  "in vec4 bulma;\n"
26642 							  "in vec4 goku;\n"
26643 							  "in vec4 gohan;\n"
26644 							  "in vec4 goten;\n"
26645 							  "in vec4 chichi;\n"
26646 							  "\n"
26647 							  "out vec4 fs_out;\n";
26648 
26649 	const GLchar* interface = "";
26650 
26651 	switch (stage)
26652 	{
26653 	case Utils::Shader::FRAGMENT:
26654 		interface = fs;
26655 		break;
26656 
26657 	case Utils::Shader::GEOMETRY:
26658 		if (TEST_GS == test_case_index)
26659 		{
26660 			interface = vs_tes_gs;
26661 		}
26662 		break;
26663 
26664 	case Utils::Shader::TESS_CTRL:
26665 		break;
26666 
26667 	case Utils::Shader::TESS_EVAL:
26668 		if (TEST_TES == test_case_index)
26669 		{
26670 			interface = vs_tes_gs;
26671 		}
26672 		break;
26673 
26674 	case Utils::Shader::VERTEX:
26675 		if (TEST_VS == test_case_index)
26676 		{
26677 			interface = vs_tes_gs;
26678 		}
26679 		break;
26680 
26681 	default:
26682 		TCU_FAIL("Invalid enum");
26683 	}
26684 
26685 	out_interface = interface;
26686 }
26687 
26688 /** Get source code of shader
26689  *
26690  * @param test_case_index Index of test case
26691  * @param stage           Shader stage
26692  *
26693  * @return Source
26694  **/
26695 std::string XFBCaptureInactiveOutputComponentTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
26696 {
26697 	std::string source;
26698 
26699 	switch (test_case_index)
26700 	{
26701 	case TEST_VS:
26702 		switch (stage)
26703 		{
26704 		case Utils::Shader::FRAGMENT:
26705 		case Utils::Shader::VERTEX:
26706 			source = BufferTestBase::getShaderSource(test_case_index, stage);
26707 			break;
26708 		default:
26709 			break;
26710 		}
26711 		break;
26712 
26713 	case TEST_TES:
26714 		switch (stage)
26715 		{
26716 		case Utils::Shader::FRAGMENT:
26717 		case Utils::Shader::TESS_CTRL:
26718 		case Utils::Shader::TESS_EVAL:
26719 		case Utils::Shader::VERTEX:
26720 			source = BufferTestBase::getShaderSource(test_case_index, stage);
26721 			break;
26722 		default:
26723 			break;
26724 		}
26725 		break;
26726 
26727 	case TEST_GS:
26728 		source = BufferTestBase::getShaderSource(test_case_index, stage);
26729 		break;
26730 
26731 	default:
26732 		TCU_FAIL("Invalid enum");
26733 		break;
26734 	}
26735 
26736 	/* */
26737 	return source;
26738 }
26739 
26740 /** Get name of test case
26741  *
26742  * @param test_case_index Index of test case
26743  *
26744  * @return Name of tested stage
26745  **/
26746 std::string XFBCaptureInactiveOutputComponentTest::getTestCaseName(glw::GLuint test_case_index)
26747 {
26748 	const GLchar* name = 0;
26749 
26750 	switch (test_case_index)
26751 	{
26752 	case TEST_VS:
26753 		name = "vertex";
26754 		break;
26755 	case TEST_TES:
26756 		name = "tessellation evaluation";
26757 		break;
26758 	case TEST_GS:
26759 		name = "geometry";
26760 		break;
26761 	default:
26762 		TCU_FAIL("Invalid enum");
26763 	}
26764 
26765 	return name;
26766 }
26767 
26768 /** Returns number of test cases
26769  *
26770  * @return TEST_MAX
26771  **/
26772 glw::GLuint XFBCaptureInactiveOutputComponentTest::getTestCaseNumber()
26773 {
26774 	return TEST_MAX;
26775 }
26776 
26777 /** Verify contents of buffers
26778  *
26779  * @param buffers Collection of buffers to be verified
26780  *
26781  * @return true if everything is as expected, false otherwise
26782  **/
26783 bool XFBCaptureInactiveOutputComponentTest::verifyBuffers(bufferCollection& buffers)
26784 {
26785 	bool result = true;
26786 
26787 	bufferCollection::pair& pair	   = buffers.m_vector[1] /* xfb */;
26788 	Utils::Buffer*			buffer	 = pair.m_buffer;
26789 	bufferDescriptor*		descriptor = pair.m_descriptor;
26790 
26791 	/* Get pointer to contents of buffer */
26792 	buffer->Bind();
26793 	GLubyte* buffer_data = (GLubyte*)buffer->Map(Utils::Buffer::ReadOnly);
26794 
26795 	/* Get pointer to expected data */
26796 	GLubyte* expected_data = (GLubyte*)&descriptor->m_expected_data[0];
26797 
26798 	/* Compare */
26799 	static const GLuint comp_size = 4;
26800 	static const GLuint vec4_size = 16;
26801 
26802 	int res_goku_x =
26803 		memcmp(buffer_data + 2 * vec4_size + 0 * comp_size, expected_data + 2 * vec4_size + 0 * comp_size, comp_size);
26804 	int res_goku_z =
26805 		memcmp(buffer_data + 2 * vec4_size + 2 * comp_size, expected_data + 2 * vec4_size + 2 * comp_size, comp_size);
26806 
26807 	int res_gohan_y =
26808 		memcmp(buffer_data + 0 * vec4_size + 1 * comp_size, expected_data + 0 * vec4_size + 1 * comp_size, comp_size);
26809 	int res_gohan_w =
26810 		memcmp(buffer_data + 0 * vec4_size + 3 * comp_size, expected_data + 0 * vec4_size + 3 * comp_size, comp_size);
26811 
26812 	int res_goten_x =
26813 		memcmp(buffer_data + 1 * vec4_size + 0 * comp_size, expected_data + 1 * vec4_size + 0 * comp_size, comp_size);
26814 	int res_goten_y =
26815 		memcmp(buffer_data + 1 * vec4_size + 1 * comp_size, expected_data + 1 * vec4_size + 1 * comp_size, comp_size);
26816 
26817 	int res_chichi_z =
26818 		memcmp(buffer_data + 3 * vec4_size + 2 * comp_size, expected_data + 3 * vec4_size + 2 * comp_size, comp_size);
26819 	int res_chichi_w =
26820 		memcmp(buffer_data + 3 * vec4_size + 3 * comp_size, expected_data + 3 * vec4_size + 3 * comp_size, comp_size);
26821 
26822 	int res_vegeta_x =
26823 		memcmp(buffer_data + 7 * vec4_size + 0 * comp_size, expected_data + 7 * vec4_size + 0 * comp_size, comp_size);
26824 
26825 	int res_trunks_y =
26826 		memcmp(buffer_data + 6 * vec4_size + 1 * comp_size, expected_data + 6 * vec4_size + 1 * comp_size, comp_size);
26827 
26828 	int res_bra_z =
26829 		memcmp(buffer_data + 5 * vec4_size + 2 * comp_size, expected_data + 5 * vec4_size + 2 * comp_size, comp_size);
26830 
26831 	int res_bulma_w =
26832 		memcmp(buffer_data + 4 * vec4_size + 3 * comp_size, expected_data + 4 * vec4_size + 3 * comp_size, comp_size);
26833 
26834 	if ((0 != res_goku_x) || (0 != res_goku_z) || (0 != res_gohan_y) || (0 != res_gohan_w) || (0 != res_goten_x) ||
26835 		(0 != res_goten_y) || (0 != res_chichi_z) || (0 != res_chichi_w) || (0 != res_vegeta_x) ||
26836 		(0 != res_trunks_y) || (0 != res_bra_z) || (0 != res_bulma_w))
26837 	{
26838 		m_context.getTestContext().getLog()
26839 			<< tcu::TestLog::Message << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
26840 			<< ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
26841 
26842 		result = false;
26843 	}
26844 
26845 	/* Release buffer mapping */
26846 	buffer->UnMap();
26847 
26848 	return result;
26849 }
26850 
26851 /** Constructor
26852  *
26853  * @param context Test context
26854  **/
26855 XFBCaptureInactiveOutputBlockMemberTest::XFBCaptureInactiveOutputBlockMemberTest(deqp::Context& context)
26856 	: BufferTestBase(context, "xfb_capture_inactive_output_block_member",
26857 					 "Test verifies that inactive block members are captured")
26858 {
26859 	/* Nothing to be done here */
26860 }
26861 
26862 /** Execute drawArrays for single vertex
26863  *
26864  * @param test_case_index
26865  *
26866  * @return true
26867  **/
26868 bool XFBCaptureInactiveOutputBlockMemberTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
26869 {
26870 	const Functions& gl				= m_context.getRenderContext().getFunctions();
26871 	GLenum			 primitive_type = GL_PATCHES;
26872 
26873 	if (TEST_VS == test_case_index)
26874 	{
26875 		primitive_type = GL_POINTS;
26876 	}
26877 
26878 	gl.disable(GL_RASTERIZER_DISCARD);
26879 	GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
26880 
26881 	gl.beginTransformFeedback(GL_POINTS);
26882 	GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
26883 
26884 	gl.drawArrays(primitive_type, 0 /* first */, 1 /* count */);
26885 	GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
26886 
26887 	gl.endTransformFeedback();
26888 	GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
26889 
26890 	return true;
26891 }
26892 
26893 /** Get descriptors of buffers necessary for test
26894  *
26895  * @param ignored
26896  * @param out_descriptors Descriptors of buffers used by test
26897  **/
26898 void XFBCaptureInactiveOutputBlockMemberTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
26899 																   bufferDescriptor::Vector& out_descriptors)
26900 {
26901 	const Utils::Type& type = Utils::Type::vec4;
26902 
26903 	/* Test needs single uniform and xfb */
26904 	out_descriptors.resize(2);
26905 
26906 	/* Get references */
26907 	bufferDescriptor& uniform = out_descriptors[0];
26908 	bufferDescriptor& xfb	 = out_descriptors[1];
26909 
26910 	/* Index */
26911 	uniform.m_index = 0;
26912 	xfb.m_index		= 0;
26913 
26914 	/* Target */
26915 	uniform.m_target = Utils::Buffer::Uniform;
26916 	xfb.m_target	 = Utils::Buffer::Transform_feedback;
26917 
26918 	/* Data */
26919 	const std::vector<GLubyte>& gohan_data  = type.GenerateData();
26920 	const std::vector<GLubyte>& chichi_data = type.GenerateData();
26921 
26922 	const GLuint type_size = static_cast<GLuint>(gohan_data.size());
26923 
26924 	/* Uniform data */
26925 	uniform.m_initial_data.resize(2 * type_size);
26926 	memcpy(&uniform.m_initial_data[0] + 0, &gohan_data[0], type_size);
26927 	memcpy(&uniform.m_initial_data[0] + type_size, &chichi_data[0], type_size);
26928 
26929 	/* XFB data */
26930 	xfb.m_initial_data.resize(4 * type_size);
26931 	xfb.m_expected_data.resize(4 * type_size);
26932 
26933 	for (GLuint i = 0; i < 4 * type_size; ++i)
26934 	{
26935 		xfb.m_initial_data[i]  = (glw::GLubyte)i;
26936 		xfb.m_expected_data[i] = (glw::GLubyte)i;
26937 	}
26938 
26939 	memcpy(&xfb.m_expected_data[0] + 1 * type_size, &gohan_data[0], type_size);
26940 	memcpy(&xfb.m_expected_data[0] + 3 * type_size, &chichi_data[0], type_size);
26941 }
26942 
26943 /** Get body of main function for given shader stage
26944  *
26945  * @param test_case_index  Index of test case
26946  * @param stage            Shader stage
26947  * @param out_assignments  Set to empty
26948  * @param out_calculations Set to empty
26949  **/
26950 void XFBCaptureInactiveOutputBlockMemberTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
26951 															std::string& out_assignments, std::string& out_calculations)
26952 {
26953 	out_calculations = "";
26954 
26955 	static const GLchar* vs_tes_gs = "    chichi = uni_chichi;\n"
26956 									 "    gohan  = uni_gohan;\n";
26957 	static const GLchar* fs = "    fs_out = goten + gohan + chichi;\n";
26958 
26959 	const GLchar* assignments = "";
26960 
26961 	switch (stage)
26962 	{
26963 	case Utils::Shader::FRAGMENT:
26964 		assignments = fs;
26965 		break;
26966 
26967 	case Utils::Shader::GEOMETRY:
26968 		if (TEST_GS == test_case_index)
26969 		{
26970 			assignments = vs_tes_gs;
26971 		}
26972 		break;
26973 
26974 	case Utils::Shader::TESS_CTRL:
26975 		break;
26976 
26977 	case Utils::Shader::TESS_EVAL:
26978 		if (TEST_TES == test_case_index)
26979 		{
26980 			assignments = vs_tes_gs;
26981 		}
26982 		break;
26983 
26984 	case Utils::Shader::VERTEX:
26985 		if (TEST_VS == test_case_index)
26986 		{
26987 			assignments = vs_tes_gs;
26988 		}
26989 		break;
26990 
26991 	default:
26992 		TCU_FAIL("Invalid enum");
26993 	}
26994 
26995 	out_assignments = assignments;
26996 }
26997 
26998 /** Get interface of shader
26999  *
27000  * @param test_case_index  Index of test case
27001  * @param stage            Shader stage
27002  * @param out_interface    Set to ""
27003  **/
27004 void XFBCaptureInactiveOutputBlockMemberTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
27005 																 std::string& out_interface)
27006 {
27007 	static const GLchar* vs_tes_gs = "const uint sizeof_type = 16;\n"
27008 									 "\n"
27009 									 "layout (xfb_offset = 1 * sizeof_type) out Goku {\n"
27010 									 "    vec4 gohan;\n"
27011 									 "    vec4 goten;\n"
27012 									 "    vec4 chichi;\n"
27013 									 "};\n"
27014 									 "\n"
27015 									 "layout(binding = 0) uniform block {\n"
27016 									 "    vec4 uni_gohan;\n"
27017 									 "    vec4 uni_chichi;\n"
27018 									 "};\n";
27019 	static const GLchar* fs = "in Goku {\n"
27020 							  "    vec4 gohan;\n"
27021 							  "    vec4 goten;\n"
27022 							  "    vec4 chichi;\n"
27023 							  "};\n"
27024 							  "out vec4 fs_out;\n";
27025 
27026 	const GLchar* interface = "";
27027 
27028 	switch (stage)
27029 	{
27030 	case Utils::Shader::FRAGMENT:
27031 		interface = fs;
27032 		break;
27033 
27034 	case Utils::Shader::GEOMETRY:
27035 		if (TEST_GS == test_case_index)
27036 		{
27037 			interface = vs_tes_gs;
27038 		}
27039 		break;
27040 
27041 	case Utils::Shader::TESS_CTRL:
27042 		break;
27043 
27044 	case Utils::Shader::TESS_EVAL:
27045 		if (TEST_TES == test_case_index)
27046 		{
27047 			interface = vs_tes_gs;
27048 		}
27049 		break;
27050 
27051 	case Utils::Shader::VERTEX:
27052 		if (TEST_VS == test_case_index)
27053 		{
27054 			interface = vs_tes_gs;
27055 		}
27056 		break;
27057 
27058 	default:
27059 		TCU_FAIL("Invalid enum");
27060 	}
27061 
27062 	out_interface = interface;
27063 }
27064 
27065 /** Get source code of shader
27066  *
27067  * @param test_case_index Index of test case
27068  * @param stage           Shader stage
27069  *
27070  * @return Source
27071  **/
27072 std::string XFBCaptureInactiveOutputBlockMemberTest::getShaderSource(GLuint				   test_case_index,
27073 																	 Utils::Shader::STAGES stage)
27074 {
27075 	std::string source;
27076 
27077 	switch (test_case_index)
27078 	{
27079 	case TEST_VS:
27080 		switch (stage)
27081 		{
27082 		case Utils::Shader::FRAGMENT:
27083 		case Utils::Shader::VERTEX:
27084 			source = BufferTestBase::getShaderSource(test_case_index, stage);
27085 			break;
27086 		default:
27087 			break;
27088 		}
27089 		break;
27090 
27091 	case TEST_TES:
27092 		switch (stage)
27093 		{
27094 		case Utils::Shader::FRAGMENT:
27095 		case Utils::Shader::TESS_CTRL:
27096 		case Utils::Shader::TESS_EVAL:
27097 		case Utils::Shader::VERTEX:
27098 			source = BufferTestBase::getShaderSource(test_case_index, stage);
27099 			break;
27100 		default:
27101 			break;
27102 		}
27103 		break;
27104 
27105 	case TEST_GS:
27106 		source = BufferTestBase::getShaderSource(test_case_index, stage);
27107 		break;
27108 
27109 	default:
27110 		TCU_FAIL("Invalid enum");
27111 		break;
27112 	}
27113 
27114 	/* */
27115 	return source;
27116 }
27117 
27118 /** Get name of test case
27119  *
27120  * @param test_case_index Index of test case
27121  *
27122  * @return Name of tested stage
27123  **/
27124 std::string XFBCaptureInactiveOutputBlockMemberTest::getTestCaseName(glw::GLuint test_case_index)
27125 {
27126 	const GLchar* name = 0;
27127 
27128 	switch (test_case_index)
27129 	{
27130 	case TEST_VS:
27131 		name = "vertex";
27132 		break;
27133 	case TEST_TES:
27134 		name = "tessellation evaluation";
27135 		break;
27136 	case TEST_GS:
27137 		name = "geometry";
27138 		break;
27139 	default:
27140 		TCU_FAIL("Invalid enum");
27141 	}
27142 
27143 	return name;
27144 }
27145 
27146 /** Returns number of test cases
27147  *
27148  * @return TEST_MAX
27149  **/
27150 glw::GLuint XFBCaptureInactiveOutputBlockMemberTest::getTestCaseNumber()
27151 {
27152 	return TEST_MAX;
27153 }
27154 
27155 /** Verify contents of buffers
27156  *
27157  * @param buffers Collection of buffers to be verified
27158  *
27159  * @return true if everything is as expected, false otherwise
27160  **/
27161 bool XFBCaptureInactiveOutputBlockMemberTest::verifyBuffers(bufferCollection& buffers)
27162 {
27163 	bool result = true;
27164 
27165 	bufferCollection::pair& pair	   = buffers.m_vector[1] /* xfb */;
27166 	Utils::Buffer*			buffer	 = pair.m_buffer;
27167 	bufferDescriptor*		descriptor = pair.m_descriptor;
27168 
27169 	/* Get pointer to contents of buffer */
27170 	buffer->Bind();
27171 	GLubyte* buffer_data = (GLubyte*)buffer->Map(Utils::Buffer::ReadOnly);
27172 
27173 	/* Get pointer to expected data */
27174 	GLubyte* expected_data = (GLubyte*)&descriptor->m_expected_data[0];
27175 
27176 	/* Compare */
27177 	static const GLuint vec4_size = 16;
27178 
27179 	int res_before = memcmp(buffer_data, expected_data, vec4_size);
27180 	int res_gohan  = memcmp(buffer_data + 1 * vec4_size, expected_data + 1 * vec4_size, vec4_size);
27181 	int res_chichi = memcmp(buffer_data + 3 * vec4_size, expected_data + 3 * vec4_size, vec4_size);
27182 
27183 	if ((0 != res_before) || (0 != res_gohan) || (0 != res_chichi))
27184 	{
27185 		m_context.getTestContext().getLog()
27186 			<< tcu::TestLog::Message << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
27187 			<< ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
27188 
27189 		result = false;
27190 	}
27191 
27192 	/* Release buffer mapping */
27193 	buffer->UnMap();
27194 
27195 	return result;
27196 }
27197 
27198 /** Constructor
27199  *
27200  * @param context Test context
27201  **/
27202 XFBCaptureStructTest::XFBCaptureStructTest(deqp::Context& context)
27203 	: BufferTestBase(context, "xfb_capture_struct", "Test verifies that inactive structure members are captured")
27204 {
27205 	/* Nothing to be done here */
27206 }
27207 
27208 /** Execute drawArrays for single vertex
27209  *
27210  * @param test_case_index
27211  *
27212  * @return true
27213  **/
27214 bool XFBCaptureStructTest::executeDrawCall(bool /* tesEnabled */, GLuint test_case_index)
27215 {
27216 	const Functions& gl				= m_context.getRenderContext().getFunctions();
27217 	GLenum			 primitive_type = GL_PATCHES;
27218 
27219 	if (TEST_VS == test_case_index)
27220 	{
27221 		primitive_type = GL_POINTS;
27222 	}
27223 
27224 	gl.disable(GL_RASTERIZER_DISCARD);
27225 	GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
27226 
27227 	gl.beginTransformFeedback(GL_POINTS);
27228 	GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
27229 
27230 	gl.drawArrays(primitive_type, 0 /* first */, 1 /* count */);
27231 	GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
27232 
27233 	gl.endTransformFeedback();
27234 	GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
27235 
27236 	return true;
27237 }
27238 
27239 /** Get descriptors of buffers necessary for test
27240  *
27241  * @param ignored
27242  * @param out_descriptors Descriptors of buffers used by test
27243  **/
27244 void XFBCaptureStructTest::getBufferDescriptors(glw::GLuint /* test_case_index */,
27245 												bufferDescriptor::Vector& out_descriptors)
27246 {
27247 	const Utils::Type& type = Utils::Type::vec4;
27248 
27249 	/* Test needs single uniform and xfb */
27250 	out_descriptors.resize(2);
27251 
27252 	/* Get references */
27253 	bufferDescriptor& uniform = out_descriptors[0];
27254 	bufferDescriptor& xfb	 = out_descriptors[1];
27255 
27256 	/* Index */
27257 	uniform.m_index = 0;
27258 	xfb.m_index		= 0;
27259 
27260 	/* Target */
27261 	uniform.m_target = Utils::Buffer::Uniform;
27262 	xfb.m_target	 = Utils::Buffer::Transform_feedback;
27263 
27264 	/* Data */
27265 	const std::vector<GLubyte>& gohan_data  = type.GenerateData();
27266 	const std::vector<GLubyte>& chichi_data = type.GenerateData();
27267 
27268 	const GLuint type_size = static_cast<GLuint>(gohan_data.size());
27269 
27270 	/* Uniform data */
27271 	uniform.m_initial_data.resize(2 * type_size);
27272 	memcpy(&uniform.m_initial_data[0] + 0, &gohan_data[0], type_size);
27273 	memcpy(&uniform.m_initial_data[0] + type_size, &chichi_data[0], type_size);
27274 
27275 	/* XFB data */
27276 	xfb.m_initial_data.resize(4 * type_size);
27277 	xfb.m_expected_data.resize(4 * type_size);
27278 
27279 	for (GLuint i = 0; i < 4 * type_size; ++i)
27280 	{
27281 		xfb.m_initial_data[i]  = (glw::GLubyte)i;
27282 		xfb.m_expected_data[i] = (glw::GLubyte)i;
27283 	}
27284 
27285 	memcpy(&xfb.m_expected_data[0] + 1 * type_size, &gohan_data[0], type_size);
27286 	memcpy(&xfb.m_expected_data[0] + 3 * type_size, &chichi_data[0], type_size);
27287 }
27288 
27289 /** Get body of main function for given shader stage
27290  *
27291  * @param test_case_index  Index of test case
27292  * @param stage            Shader stage
27293  * @param out_assignments  Set to empty
27294  * @param out_calculations Set to empty
27295  **/
27296 void XFBCaptureStructTest::getShaderBody(GLuint test_case_index, Utils::Shader::STAGES stage,
27297 										 std::string& out_assignments, std::string& out_calculations)
27298 {
27299 	out_calculations = "";
27300 
27301 	static const GLchar* vs_tes_gs = "    goku.chichi = uni_chichi;\n"
27302 									 "    goku.gohan  = uni_gohan;\n";
27303 	static const GLchar* fs = "    fs_out = goku.goten + goku.gohan + goku.chichi;\n";
27304 
27305 	const GLchar* assignments = "";
27306 
27307 	switch (stage)
27308 	{
27309 	case Utils::Shader::FRAGMENT:
27310 		assignments = fs;
27311 		break;
27312 
27313 	case Utils::Shader::GEOMETRY:
27314 		if (TEST_GS == test_case_index)
27315 		{
27316 			assignments = vs_tes_gs;
27317 		}
27318 		break;
27319 
27320 	case Utils::Shader::TESS_CTRL:
27321 		break;
27322 
27323 	case Utils::Shader::TESS_EVAL:
27324 		if (TEST_TES == test_case_index)
27325 		{
27326 			assignments = vs_tes_gs;
27327 		}
27328 		break;
27329 
27330 	case Utils::Shader::VERTEX:
27331 		if (TEST_VS == test_case_index)
27332 		{
27333 			assignments = vs_tes_gs;
27334 		}
27335 		break;
27336 
27337 	default:
27338 		TCU_FAIL("Invalid enum");
27339 	}
27340 
27341 	out_assignments = assignments;
27342 }
27343 
27344 /** Get interface of shader
27345  *
27346  * @param test_case_index  Index of test case
27347  * @param stage            Shader stage
27348  * @param out_interface    Set to ""
27349  **/
27350 void XFBCaptureStructTest::getShaderInterface(GLuint test_case_index, Utils::Shader::STAGES stage,
27351 											  std::string& out_interface)
27352 {
27353 	static const GLchar* vs_tes_gs = "const uint sizeof_type = 16;\n"
27354 									 "\n"
27355 									 "struct Goku {\n"
27356 									 "    vec4 gohan;\n"
27357 									 "    vec4 goten;\n"
27358 									 "    vec4 chichi;\n"
27359 									 "};\n"
27360 									 "\n"
27361 									 "layout (xfb_offset = sizeof_type) out Goku goku;\n"
27362 									 "\n"
27363 									 "layout(binding = 0, std140) uniform block {\n"
27364 									 "    vec4 uni_gohan;\n"
27365 									 "    vec4 uni_chichi;\n"
27366 									 "};\n";
27367 	static const GLchar* fs = "struct Goku {\n"
27368 							  "    vec4 gohan;\n"
27369 							  "    vec4 goten;\n"
27370 							  "    vec4 chichi;\n"
27371 							  "};\n"
27372 							  "\n"
27373 							  "in Goku goku;\n"
27374 							  "\n"
27375 							  "out vec4 fs_out;\n";
27376 
27377 	const GLchar* interface = "";
27378 
27379 	switch (stage)
27380 	{
27381 	case Utils::Shader::FRAGMENT:
27382 		interface = fs;
27383 		break;
27384 
27385 	case Utils::Shader::GEOMETRY:
27386 		if (TEST_GS == test_case_index)
27387 		{
27388 			interface = vs_tes_gs;
27389 		}
27390 		break;
27391 
27392 	case Utils::Shader::TESS_CTRL:
27393 		break;
27394 
27395 	case Utils::Shader::TESS_EVAL:
27396 		if (TEST_TES == test_case_index)
27397 		{
27398 			interface = vs_tes_gs;
27399 		}
27400 		break;
27401 
27402 	case Utils::Shader::VERTEX:
27403 		if (TEST_VS == test_case_index)
27404 		{
27405 			interface = vs_tes_gs;
27406 		}
27407 		break;
27408 
27409 	default:
27410 		TCU_FAIL("Invalid enum");
27411 	}
27412 
27413 	out_interface = interface;
27414 }
27415 
27416 /** Get source code of shader
27417  *
27418  * @param test_case_index Index of test case
27419  * @param stage           Shader stage
27420  *
27421  * @return Source
27422  **/
27423 std::string XFBCaptureStructTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
27424 {
27425 	std::string source;
27426 
27427 	switch (test_case_index)
27428 	{
27429 	case TEST_VS:
27430 		switch (stage)
27431 		{
27432 		case Utils::Shader::FRAGMENT:
27433 		case Utils::Shader::VERTEX:
27434 			source = BufferTestBase::getShaderSource(test_case_index, stage);
27435 			break;
27436 		default:
27437 			break;
27438 		}
27439 		break;
27440 
27441 	case TEST_TES:
27442 		switch (stage)
27443 		{
27444 		case Utils::Shader::FRAGMENT:
27445 		case Utils::Shader::TESS_CTRL:
27446 		case Utils::Shader::TESS_EVAL:
27447 		case Utils::Shader::VERTEX:
27448 			source = BufferTestBase::getShaderSource(test_case_index, stage);
27449 			break;
27450 		default:
27451 			break;
27452 		}
27453 		break;
27454 
27455 	case TEST_GS:
27456 		source = BufferTestBase::getShaderSource(test_case_index, stage);
27457 		break;
27458 
27459 	default:
27460 		TCU_FAIL("Invalid enum");
27461 		break;
27462 	}
27463 
27464 	/* */
27465 	return source;
27466 }
27467 
27468 /** Get name of test case
27469  *
27470  * @param test_case_index Index of test case
27471  *
27472  * @return Name of tested stage
27473  **/
27474 std::string XFBCaptureStructTest::getTestCaseName(glw::GLuint test_case_index)
27475 {
27476 	const GLchar* name = 0;
27477 
27478 	switch (test_case_index)
27479 	{
27480 	case TEST_VS:
27481 		name = "vertex";
27482 		break;
27483 	case TEST_TES:
27484 		name = "tessellation evaluation";
27485 		break;
27486 	case TEST_GS:
27487 		name = "geometry";
27488 		break;
27489 	default:
27490 		TCU_FAIL("Invalid enum");
27491 	}
27492 
27493 	return name;
27494 }
27495 
27496 /** Returns number of test cases
27497  *
27498  * @return TEST_MAX
27499  **/
27500 glw::GLuint XFBCaptureStructTest::getTestCaseNumber()
27501 {
27502 	return TEST_MAX;
27503 }
27504 
27505 /** Verify contents of buffers
27506  *
27507  * @param buffers Collection of buffers to be verified
27508  *
27509  * @return true if everything is as expected, false otherwise
27510  **/
27511 bool XFBCaptureStructTest::verifyBuffers(bufferCollection& buffers)
27512 {
27513 	bool result = true;
27514 
27515 	bufferCollection::pair& pair	   = buffers.m_vector[1] /* xfb */;
27516 	Utils::Buffer*			buffer	 = pair.m_buffer;
27517 	bufferDescriptor*		descriptor = pair.m_descriptor;
27518 
27519 	/* Get pointer to contents of buffer */
27520 	buffer->Bind();
27521 	GLubyte* buffer_data = (GLubyte*)buffer->Map(Utils::Buffer::ReadOnly);
27522 
27523 	/* Get pointer to expected data */
27524 	GLubyte* expected_data = (GLubyte*)&descriptor->m_expected_data[0];
27525 
27526 	/* Compare */
27527 	static const GLuint vec4_size = 16;
27528 
27529 	int res_before = memcmp(buffer_data, expected_data, vec4_size);
27530 	int res_gohan  = memcmp(buffer_data + 1 * vec4_size, expected_data + 1 * vec4_size, vec4_size);
27531 	int res_chichi = memcmp(buffer_data + 3 * vec4_size, expected_data + 3 * vec4_size, vec4_size);
27532 
27533 	if ((0 != res_before) || (0 != res_gohan) || (0 != res_chichi))
27534 	{
27535 		m_context.getTestContext().getLog()
27536 			<< tcu::TestLog::Message << "Invalid result. Buffer: " << Utils::Buffer::GetBufferName(descriptor->m_target)
27537 			<< ". Index: " << descriptor->m_index << tcu::TestLog::EndMessage;
27538 
27539 		result = false;
27540 	}
27541 
27542 	/* Release buffer mapping */
27543 	buffer->UnMap();
27544 
27545 	return result;
27546 }
27547 
27548 /** Constructor
27549  *
27550  * @param context Test framework context
27551  **/
27552 XFBCaptureUnsizedArrayTest::XFBCaptureUnsizedArrayTest(deqp::Context& context)
27553 	: NegativeTestBase(context, "xfb_capture_unsized_array",
27554 					   "Test verifies that compiler reports error when unsized array is qualified with xfb_offset")
27555 {
27556 }
27557 
27558 /** Source for given test case and stage
27559  *
27560  * @param test_case_index Index of test case
27561  * @param stage           Shader stage
27562  *
27563  * @return Shader source
27564  **/
27565 std::string XFBCaptureUnsizedArrayTest::getShaderSource(GLuint test_case_index, Utils::Shader::STAGES stage)
27566 {
27567 #if DEBUG_NEG_REMOVE_ERROR
27568 	static const GLchar* var_definition = "/* layout (xfb_offset = 0) */ out vec4 goku[];\n";
27569 #else
27570 	static const GLchar* var_definition = "layout (xfb_offset = 0) out vec4 goku[];\n";
27571 #endif /* DEBUG_NEG_REMOVE_ERROR */
27572 	static const GLchar* var_use = "    goku[0] = result / 2;\n";
27573 	static const GLchar* fs		 = "#version 430 core\n"
27574 							  "#extension GL_ARB_enhanced_layouts : require\n"
27575 							  "\n"
27576 							  "in  vec4 any_fs;\n"
27577 							  "out vec4 fs_out;\n"
27578 							  "\n"
27579 							  "void main()\n"
27580 							  "{\n"
27581 							  "    fs_out = any_fs;\n"
27582 							  "}\n"
27583 							  "\n";
27584 	static const GLchar* vs_tested = "#version 430 core\n"
27585 									 "#extension GL_ARB_enhanced_layouts : require\n"
27586 									 "\n"
27587 									 "VAR_DEFINITION"
27588 									 "\n"
27589 									 "in  vec4 in_vs;\n"
27590 									 "out vec4 any_fs;\n"
27591 									 "\n"
27592 									 "void main()\n"
27593 									 "{\n"
27594 									 "    vec4 result = in_vs;\n"
27595 									 "\n"
27596 									 "VARIABLE_USE"
27597 									 "\n"
27598 									 "    any_fs = result;\n"
27599 									 "}\n"
27600 									 "\n";
27601 
27602 	std::string source;
27603 	testCase&   test_case = m_test_cases[test_case_index];
27604 
27605 	if (test_case.m_stage == stage)
27606 	{
27607 		size_t		  position = 0;
27608 
27609 		switch (stage)
27610 		{
27611 		case Utils::Shader::VERTEX:
27612 			source = vs_tested;
27613 			break;
27614 		default:
27615 			TCU_FAIL("Invalid enum");
27616 		}
27617 
27618 		Utils::replaceToken("VAR_DEFINITION", position, var_definition, source);
27619 		position = 0;
27620 		Utils::replaceToken("VARIABLE_USE", position, var_use, source);
27621 	}
27622 	else
27623 	{
27624 		switch (test_case.m_stage)
27625 		{
27626 		case Utils::Shader::VERTEX:
27627 			switch (stage)
27628 			{
27629 			case Utils::Shader::FRAGMENT:
27630 				source = fs;
27631 				break;
27632 			default:
27633 				source = "";
27634 			}
27635 			break;
27636 		default:
27637 			TCU_FAIL("Invalid enum");
27638 			break;
27639 		}
27640 	}
27641 
27642 	return source;
27643 }
27644 
27645 /** Get description of test case
27646  *
27647  * @param test_case_index Index of test case
27648  *
27649  * @return Test case description
27650  **/
27651 std::string XFBCaptureUnsizedArrayTest::getTestCaseName(GLuint test_case_index)
27652 {
27653 	std::stringstream stream;
27654 	testCase&		  test_case = m_test_cases[test_case_index];
27655 
27656 	stream << "Stage: " << Utils::Shader::GetStageName(test_case.m_stage);
27657 
27658 	return stream.str();
27659 }
27660 
27661 /** Get number of test cases
27662  *
27663  * @return Number of test cases
27664  **/
27665 GLuint XFBCaptureUnsizedArrayTest::getTestCaseNumber()
27666 {
27667 	return static_cast<GLuint>(m_test_cases.size());
27668 }
27669 
27670 /** Selects if "compute" stage is relevant for test
27671  *
27672  * @param ignored
27673  *
27674  * @return false
27675  **/
27676 bool XFBCaptureUnsizedArrayTest::isComputeRelevant(GLuint /* test_case_index */)
27677 {
27678 	return false;
27679 }
27680 
27681 /** Prepare all test cases
27682  *
27683  **/
27684 void XFBCaptureUnsizedArrayTest::testInit()
27685 {
27686 	for (GLuint stage = 0; stage < Utils::Shader::STAGE_MAX; ++stage)
27687 	{
27688 		/* Not aplicable for */
27689 		if ((Utils::Shader::COMPUTE == stage) || (Utils::Shader::TESS_CTRL == stage) ||
27690 			(Utils::Shader::FRAGMENT == stage) || (Utils::Shader::GEOMETRY == stage) ||
27691 			(Utils::Shader::TESS_EVAL == stage))
27692 		{
27693 			continue;
27694 		}
27695 
27696 		testCase test_case = { (Utils::Shader::STAGES)stage };
27697 
27698 		m_test_cases.push_back(test_case);
27699 	}
27700 }
27701 } /* EnhancedLayouts namespace */
27702 
27703 /** Constructor.
27704  *
27705  *  @param context Rendering context.
27706  **/
EnhancedLayoutsTests(deqp::Context & context)27707 EnhancedLayoutsTests::EnhancedLayoutsTests(deqp::Context& context)
27708 	: TestCaseGroup(context, "enhanced_layouts", "Verifies \"enhanced layouts\" functionality")
27709 {
27710 	/* Left blank on purpose */
27711 }
27712 
27713 /** Initializes a texture_storage_multisample test group.
27714  *
27715  **/
init(void)27716 void EnhancedLayoutsTests::init(void)
27717 {
27718 	addChild(new EnhancedLayouts::APIConstantValuesTest(m_context));
27719 	addChild(new EnhancedLayouts::APIErrorsTest(m_context));
27720 	addChild(new EnhancedLayouts::GLSLContantValuesTest(m_context));
27721 	addChild(new EnhancedLayouts::GLSLContantImmutablityTest(m_context));
27722 	addChild(new EnhancedLayouts::GLSLConstantIntegralExpressionTest(m_context));
27723 	addChild(new EnhancedLayouts::UniformBlockLayoutQualifierConflictTest(m_context));
27724 	addChild(new EnhancedLayouts::SSBMemberInvalidOffsetAlignmentTest(m_context));
27725 	addChild(new EnhancedLayouts::SSBMemberOverlappingOffsetsTest(m_context));
27726 	addChild(new EnhancedLayouts::VaryingInvalidValueComponentTest(m_context));
27727 	addChild(new EnhancedLayouts::VaryingExceedingComponentsTest(m_context));
27728 	addChild(new EnhancedLayouts::VaryingComponentOfInvalidTypeTest(m_context));
27729 	addChild(new EnhancedLayouts::OutputComponentAliasingTest(m_context));
27730 	addChild(new EnhancedLayouts::VertexAttribLocationAPITest(m_context));
27731 	addChild(new EnhancedLayouts::XFBInputTest(m_context));
27732 	addChild(new EnhancedLayouts::XFBAllStagesTest(m_context));
27733 	addChild(new EnhancedLayouts::XFBCaptureInactiveOutputVariableTest(m_context));
27734 	addChild(new EnhancedLayouts::XFBCaptureInactiveOutputComponentTest(m_context));
27735 	addChild(new EnhancedLayouts::XFBCaptureInactiveOutputBlockMemberTest(m_context));
27736 	addChild(new EnhancedLayouts::XFBStrideTest(m_context));
27737 
27738 	addChild(new EnhancedLayouts::UniformBlockMemberOffsetAndAlignTest(m_context));
27739 	addChild(new EnhancedLayouts::UniformBlockMemberInvalidOffsetAlignmentTest(m_context));
27740 	addChild(new EnhancedLayouts::UniformBlockMemberOverlappingOffsetsTest(m_context));
27741 	addChild(new EnhancedLayouts::UniformBlockMemberAlignNonPowerOf2Test(m_context));
27742 	addChild(new EnhancedLayouts::SSBLayoutQualifierConflictTest(m_context));
27743 	addChild(new EnhancedLayouts::SSBMemberAlignNonPowerOf2Test(m_context));
27744 	addChild(new EnhancedLayouts::SSBAlignmentTest(m_context));
27745 	addChild(new EnhancedLayouts::VaryingStructureMemberLocationTest(m_context));
27746 	addChild(new EnhancedLayouts::VaryingBlockAutomaticMemberLocationsTest(m_context));
27747 	addChild(new EnhancedLayouts::VaryingComponentWithoutLocationTest(m_context));
27748 	addChild(new EnhancedLayouts::InputComponentAliasingTest(m_context));
27749 	addChild(new EnhancedLayouts::VaryingLocationAliasingWithMixedTypesTest(m_context));
27750 	addChild(new EnhancedLayouts::VaryingLocationAliasingWithMixedInterpolationTest(m_context));
27751 	addChild(new EnhancedLayouts::VaryingLocationAliasingWithMixedAuxiliaryStorageTest(m_context));
27752 	addChild(new EnhancedLayouts::XFBStrideOfEmptyListTest(m_context));
27753 	addChild(new EnhancedLayouts::XFBStrideOfEmptyListAndAPITest(m_context));
27754 	addChild(new EnhancedLayouts::XFBTooSmallStrideTest(m_context));
27755 	addChild(new EnhancedLayouts::XFBBlockMemberStrideTest(m_context));
27756 	addChild(new EnhancedLayouts::XFBDuplicatedStrideTest(m_context));
27757 	addChild(new EnhancedLayouts::XFBGetProgramResourceAPITest(m_context));
27758 	addChild(new EnhancedLayouts::XFBMultipleVertexStreamsTest(m_context));
27759 	addChild(new EnhancedLayouts::XFBExceedBufferLimitTest(m_context));
27760 	addChild(new EnhancedLayouts::XFBExceedOffsetLimitTest(m_context));
27761 	addChild(new EnhancedLayouts::XFBBlockMemberBufferTest(m_context));
27762 	addChild(new EnhancedLayouts::XFBOutputOverlappingTest(m_context));
27763 	addChild(new EnhancedLayouts::XFBInvalidOffsetAlignmentTest(m_context));
27764 	addChild(new EnhancedLayouts::XFBCaptureStructTest(m_context));
27765 	addChild(new EnhancedLayouts::XFBCaptureUnsizedArrayTest(m_context));
27766 	addChild(new EnhancedLayouts::UniformBlockAlignmentTest(m_context));
27767 	addChild(new EnhancedLayouts::SSBMemberOffsetAndAlignTest(m_context));
27768 	addChild(new EnhancedLayouts::VertexAttribLocationsTest(m_context));
27769 	addChild(new EnhancedLayouts::VaryingLocationsTest(m_context));
27770 	addChild(new EnhancedLayouts::VaryingArrayLocationsTest(m_context));
27771 	addChild(new EnhancedLayouts::VaryingStructureLocationsTest(m_context));
27772 	addChild(new EnhancedLayouts::VaryingBlockLocationsTest(m_context));
27773 	addChild(new EnhancedLayouts::VaryingBlockMemberLocationsTest(m_context));
27774 	addChild(new EnhancedLayouts::XFBVariableStrideTest(m_context));
27775 	addChild(new EnhancedLayouts::XFBBlockStrideTest(m_context));
27776 	addChild(new EnhancedLayouts::XFBOverrideQualifiersWithAPITest(m_context));
27777 	addChild(new EnhancedLayouts::XFBVertexStreamsTest(m_context));
27778 	addChild(new EnhancedLayouts::XFBGlobalBufferTest(m_context));
27779 	addChild(new EnhancedLayouts::FragmentDataLocationAPITest(m_context));
27780 	addChild(new EnhancedLayouts::VaryingLocationLimitTest(m_context));
27781 	addChild(new EnhancedLayouts::VaryingComponentsTest(m_context));
27782 	addChild(new EnhancedLayouts::VaryingArrayComponentsTest(m_context));
27783 }
27784 
27785 } /* gl4cts namespace */
27786